Compare commits

...
177 Commits
Author SHA1 Message Date
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
72 changed files with 3500 additions and 3127 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 \
+553 -551
View File
File diff suppressed because it is too large. Load diff
+7 -6
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
@@ -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 \
+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);
+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);
+107 -76
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
//
}
@@ -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)];
+41 -43
View File
@@ -568,7 +568,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 +654,7 @@ static boolean D_Display(void)
// =========================================================================
tic_t rendergametic;
static int menuInputDelayTimer = 0;
static SINT8 menuInputDelayTimer = 0;
void D_SRB2Loop(void)
{
@@ -780,6 +780,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 +826,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 +863,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();
@@ -1677,6 +1671,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
//
+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);
+72 -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");
}
}
@@ -3175,6 +3209,8 @@ static void Got_Pause(UINT8 **cp, INT32 playernum)
else
S_ResumeAudio();
}
G_ResetAllDeviceRumbles();
}
static void Command_ReplayMarker(void)
@@ -3192,7 +3228,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
+5
View File
@@ -9216,6 +9216,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.1"
#define VERSIONSTRINGW L"Saturn v7.1"
// 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 -1
View File
@@ -192,7 +192,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;
+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);
+73 -194
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);
@@ -1513,61 +1496,11 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
}
// 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 +1509,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 +1517,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 +1525,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 +1600,8 @@ void G_DoLoadLevel(boolean resetplayer)
// clear hud messages remains (usually from game startup)
CON_ClearHUD();
G_ResetAllDeviceRumbles();
}
static INT32 pausedelay = 0;
@@ -1952,7 +1860,6 @@ boolean G_Responder(event_t *ev)
|| ev->data1 == gamecontrol[gc_director][1])
{
K_ToggleDirector();
directortoggletimer = 0;
}
return true;
@@ -2084,6 +1991,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 +2026,6 @@ void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive)
UINT8 viewd;
INT32 *displayplayerp;
camera_t *camerap;
INT32 olddisplayplayer;
INT32 playersviewable;
@@ -2133,31 +2062,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 +2157,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 +2469,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 +2489,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 +2522,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 +3045,8 @@ void G_AddPlayer(INT32 playernum)
void G_ExitLevel(void)
{
G_ResetAllDeviceRumbles();
if (gamestate == GS_LEVEL)
{
gameaction = ga_completed;
@@ -3167,13 +3075,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 +3136,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 +4171,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 +4380,7 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool
else
{
LUAh_MapChange(gamemap);
S_CheckMap();
G_DoLoadLevel(resetplayer);
}
@@ -4740,6 +4634,8 @@ INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep)
{
if (mapname[0] == '*') // current map
return gamemap;
else if (mapname[0] == '?')
return G_RandMap(G_TOLFlag(gametype), prevmap, false, 0, false, NULL);
else if (mapname[0] == '+' && mapheaderinfo[gamemap-1]) // next map
{
newmapnum = mapheaderinfo[gamemap-1]->nextlevel;
@@ -6491,8 +6387,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 +7768,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 +8388,6 @@ void G_SaveDemo(void)
boolean G_DemoTitleResponder(event_t *ev)
{
size_t len;
INT32 ch;
if (ev->type != ev_keydown)
@@ -8506,28 +8408,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 +8421,6 @@ boolean G_DemoTitleResponder(event_t *ev)
void G_SetGamestate(gamestate_t newstate)
{
gamestate = newstate;
#ifdef HAVE_DISCORDRPC
DRPC_UpdatePresence();
#endif
@@ -8613,4 +8493,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);
+1 -1
View File
@@ -156,7 +156,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
+91 -95
View File
@@ -12,7 +12,6 @@
/// \brief hardware renderer, using the standard HardWareRender driver DLL for SRB2
#include <math.h>
#include <stdlib.h> // qsort
#include "../doomstat.h"
@@ -195,7 +194,7 @@ static void CV_grshaders_OnChange(void)
{
ONLY_IF_GL_LOADED
HWR_SetShaderState();
if ((cv_grpaletterendering.value))
if (cv_grpaletterendering.value)
{
// can't do palette rendering without shaders, so update the state if needed
HWR_TogglePaletteRendering();
@@ -205,7 +204,6 @@ static void CV_grshaders_OnChange(void)
static void CV_grpaletterendering_OnChange(void)
{
ONLY_IF_GL_LOADED
if (cv_grscreentextures.value != 2) // can't do palette rendering without screen textures
CV_Set(&cv_grpaletterendering, "Off");
@@ -311,9 +309,10 @@ FTransform atransform;
// Float variants of viewx, viewy, viewz, etc.
static float gr_viewx, gr_viewy, gr_viewz;
float gr_viewsin, gr_viewcos;
static float gr_viewludsin, gr_viewludcos;
static angle_t gr_aimingangle;
static float gr_viewludsin, gr_viewludcos;
static void HWR_SetTransformAiming(FTransform *trans);
// ==========================================================================
// Visual portals (attr. Hannu Hanhi)
@@ -573,11 +572,7 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col
Surface->LightInfo.light_level = light_level;
Surface->LightInfo.fade_start = (colormap != NULL) ? colormap->fadestart : 0;
Surface->LightInfo.fade_end = (colormap != NULL) ? colormap->fadeend : 31;
if (HWR_ShouldUsePaletteRendering())
Surface->LightTableId = HWR_GetLightTableID(colormap);
else
Surface->LightTableId = 0;
Surface->LightTableId = HWR_ShouldUsePaletteRendering() ? HWR_GetLightTableID(colormap) : 0;
}
UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap) // Let's see if this can work
@@ -846,7 +841,7 @@ void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isc
{
if (PolyFlags & PF_Fog)
shader = SHADER_FOG;
else if (PolyFlags & PF_Ripple)
else if (cv_ripplewater.value && (PolyFlags & PF_Ripple))
shader = SHADER_WATER;
else
shader = SHADER_FLOOR;
@@ -3382,13 +3377,13 @@ static gr_vissprite_t gr_overflowsprite;
static gr_vissprite_t *HWR_GetVisSprite(UINT32 num)
{
UINT32 chunk = num >> VISSPRITECHUNKBITS;
UINT32 chunk = num >> VISSPRITECHUNKBITS;
// Allocate chunk if necessary
if (!gr_visspritechunks[chunk])
Z_Malloc(sizeof(gr_vissprite_t) * VISSPRITESPERCHUNK, PU_LEVEL, &gr_visspritechunks[chunk]);
// Allocate chunk if necessary
if (!gr_visspritechunks[chunk])
Z_Malloc(sizeof(gr_vissprite_t) * VISSPRITESPERCHUNK, PU_LEVEL, &gr_visspritechunks[chunk]);
return gr_visspritechunks[chunk] + (num & VISSPRITEINDEXMASK);
return gr_visspritechunks[chunk] + (num & VISSPRITEINDEXMASK);
}
static gr_vissprite_t *HWR_NewVisSprite(void)
@@ -3764,15 +3759,13 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
HWR_RotateSpritePolyToAim(spr, baseWallVerts, false);
// push it toward the camera to mitigate floor-clipping sprites
float sprdist = sqrtf((spr->x1 - gr_viewx)*(spr->x1 - gr_viewx) + (spr->z1 - gr_viewy)*(spr->z1 - gr_viewy) + (spr->gzt - gr_viewz)*(spr->gzt - gr_viewz));
float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist;
for (i = 0; i < 4; i++)
{
float sprdist = sqrtf((spr->x1 - gr_viewx)*(spr->x1 - gr_viewx) + (spr->z1 - gr_viewy)*(spr->z1 - gr_viewy) + (spr->gzt - gr_viewz)*(spr->gzt - gr_viewz));
float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist;
for (i = 0; i < 4; i++)
{
baseWallVerts[i].x += (gr_viewx - baseWallVerts[i].x)*distfact;
baseWallVerts[i].z += (gr_viewy - baseWallVerts[i].z)*distfact;
baseWallVerts[i].y += (gr_viewz - baseWallVerts[i].y)*distfact;
}
baseWallVerts[i].x += (gr_viewx - baseWallVerts[i].x)*distfact;
baseWallVerts[i].z += (gr_viewy - baseWallVerts[i].z)*distfact;
baseWallVerts[i].y += (gr_viewz - baseWallVerts[i].y)*distfact;
}
realtop = top = baseWallVerts[3].y;
@@ -3957,6 +3950,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
FOutVector wallVerts[4];
GLPatch_t *gpatch; // sprite patch converted to hardware
FSurfaceInfo Surf;
FBITFIELD blend = 0;
INT32 shader = SHADER_NONE;
@@ -4039,16 +4033,14 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
HWR_RotateSpritePolyToAim(spr, wallVerts, false);
// push it toward the camera to mitigate floor-clipping sprites
float sprdist = sqrtf((spr->x1 - gr_viewx)*(spr->x1 - gr_viewx) + (spr->z1 - gr_viewy)*(spr->z1 - gr_viewy) + (spr->gzt - gr_viewz)*(spr->gzt - gr_viewz));
float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist;
size_t i;
for (i = 0; i < 4; i++)
{
float sprdist = sqrtf((spr->x1 - gr_viewx)*(spr->x1 - gr_viewx) + (spr->z1 - gr_viewy)*(spr->z1 - gr_viewy) + (spr->gzt - gr_viewz)*(spr->gzt - gr_viewz));
float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist;
size_t i;
for (i = 0; i < 4; i++)
{
wallVerts[i].x += (gr_viewx - wallVerts[i].x)*distfact;
wallVerts[i].z += (gr_viewy - wallVerts[i].z)*distfact;
wallVerts[i].y += (gr_viewz - wallVerts[i].y)*distfact;
}
wallVerts[i].x += (gr_viewx - wallVerts[i].x)*distfact;
wallVerts[i].z += (gr_viewy - wallVerts[i].z)*distfact;
wallVerts[i].y += (gr_viewz - wallVerts[i].y)*distfact;
}
// This needs to be AFTER the shadows so that the regular sprites aren't drawn completely black.
@@ -4065,38 +4057,35 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
HWR_Lighting(&Surf, lightlevel, colormap);
if (!cv_translucency.value) // translucency disabled
{
FBITFIELD blend = 0;
if (!cv_translucency.value) // translucency disabled
{
Surf.PolyColor.s.alpha = 0xFF;
blend = PF_Translucent|PF_Occlude;
}
else if (spr->mobj->flags2 & MF2_SHADOW)
{
Surf.PolyColor.s.alpha = 0x40;
blend = PF_Translucent;
}
else if (spr->mobj->frame & FF_TRANSMASK)
blend = HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
else
{
// BP: i agree that is little better in environement but it don't
// work properly under glide nor with fogcolor to ffffff :(
// Hurdler: PF_Environement would be cool, but we need to fix
// the issue with the fog before
Surf.PolyColor.s.alpha = 0xFF;
blend = PF_Translucent|PF_Occlude;
}
if (HWR_UseShader())
{
shader = SHADER_SPRITE;
blend |= PF_ColorMapped;
}
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, shader, false);
Surf.PolyColor.s.alpha = 0xFF;
blend = PF_Translucent|PF_Occlude;
}
else if (spr->mobj->flags2 & MF2_SHADOW)
{
Surf.PolyColor.s.alpha = 0x40;
blend = PF_Translucent;
}
else if (spr->mobj->frame & FF_TRANSMASK)
blend = HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
else
{
// BP: i agree that is little better in environement but it don't
// work properly under glide nor with fogcolor to ffffff :(
// Hurdler: PF_Environement would be cool, but we need to fix
// the issue with the fog before
Surf.PolyColor.s.alpha = 0xFF;
blend = PF_Translucent|PF_Occlude;
}
if (HWR_UseShader())
{
shader = SHADER_SPRITE;
blend |= PF_ColorMapped;
}
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, shader, false);
}
// Sprite drawer for precipitation
@@ -4238,7 +4227,7 @@ static void HWR_SortVisSprites(void)
gr_vsprorder[i] = HWR_GetVisSprite(i);
}
qsort(gr_vsprorder, gr_visspritecount, sizeof(gr_vissprite_t*), CompareVisSprites);
qs22j(gr_vsprorder, gr_visspritecount, sizeof(gr_vissprite_t*), CompareVisSprites);
}
// A drawnode is something that points to a 3D floor, 3D side, or masked
@@ -4357,9 +4346,7 @@ void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean
planeinfo->isceiling = isceiling;
planeinfo->fixedheight = fixedheight;
planeinfo->lightlevel = (HWR_ShouldUsePaletteRendering() && (planecolormap && (planecolormap->fog & 1))) ? 255 : lightlevel;
planeinfo->lightlevel = (HWR_ShouldUsePaletteRendering() && (planecolormap && (planecolormap->fog & 2))) ? 255 : lightlevel;
planeinfo->lumpnum = lumpnum;
planeinfo->xsub = xsub;
planeinfo->alpha = alpha;
@@ -4377,9 +4364,7 @@ void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector,
polyplaneinfo->isceiling = isceiling;
polyplaneinfo->fixedheight = fixedheight;
polyplaneinfo->lightlevel = (HWR_ShouldUsePaletteRendering() && (planecolormap && (planecolormap->fog & 1))) ? 255 : lightlevel;
polyplaneinfo->lightlevel = (HWR_ShouldUsePaletteRendering() && (planecolormap && (planecolormap->fog & 2))) ? 255 : lightlevel;
polyplaneinfo->lumpnum = lumpnum;
polyplaneinfo->polysector = polysector;
polyplaneinfo->alpha = alpha;
@@ -4471,8 +4456,9 @@ static void HWR_RenderDrawNodes(void)
if (!(plane->blend & PF_NoTexture))
HWR_GetFlat(plane->lumpnum, R_NoEncore(plane->FOFSector, plane->isceiling));
HWR_RenderPlane(NULL, plane->xsub, plane->isceiling, plane->fixedheight, plane->blend, plane->lightlevel,
plane->lumpnum, plane->FOFSector, plane->alpha, plane->planecolormap);
plane->lumpnum, plane->FOFSector, plane->alpha, plane->planecolormap);
}
else if (drawnode->type == DRAWNODE_POLYOBJECT_PLANE)
{
@@ -4483,8 +4469,9 @@ static void HWR_RenderDrawNodes(void)
if (!(polyplane->blend & PF_NoTexture))
HWR_GetFlat(polyplane->lumpnum, R_NoEncore(polyplane->FOFSector, polyplane->isceiling));
HWR_RenderPolyObjectPlane(polyplane->polysector, polyplane->isceiling, polyplane->fixedheight, polyplane->blend, polyplane->lightlevel,
polyplane->lumpnum, polyplane->FOFSector, polyplane->alpha, polyplane->planecolormap);
polyplane->lumpnum, polyplane->FOFSector, polyplane->alpha, polyplane->planecolormap);
}
else if (drawnode->type == DRAWNODE_WALL)
{
@@ -4492,8 +4479,9 @@ static void HWR_RenderDrawNodes(void)
if (!(wall->blend & PF_NoTexture))
HWR_GetTexture(wall->texnum, wall->noencore);
HWR_RenderWall(wall->wallVerts, &wall->Surf, wall->blend, wall->fogwall,
wall->lightlevel, wall->wallcolormap);
wall->lightlevel, wall->wallcolormap);
}
}
@@ -4614,7 +4602,7 @@ static void HWR_AddPrecipitationSprites(void)
drawdist = (fixed_t)(cv_drawdist_precip.value) * precipscale;
// No to infinite precipitation draw distance.
if (drawdist == 0)
if (drawdist == 0 || curWeather == PRECIP_BLANK || curWeather == PRECIP_STORM_NORAIN)
{
return;
}
@@ -4803,8 +4791,8 @@ void HWR_ProjectSprite(mobj_t *thing)
flip ^= (1<<rot);
}
if (thing->skin && ((skin_t *)( (thing->localskin) ? thing->localskin : thing->skin ))->flags & SF_HIRES)
this_scale *= FIXED_TO_FLOAT(((skin_t *)( (thing->localskin) ? thing->localskin : thing->skin ))->highresscale);
if (thing->skin && ((skin_t *)(thing->localskin ? thing->localskin : thing->skin))->flags & SF_HIRES)
this_scale *= FIXED_TO_FLOAT(((skin_t *)(thing->localskin ? thing->localskin : thing->skin))->highresscale);
spr_width = spritecachedinfo[lumpoff].width;
spr_height = spritecachedinfo[lumpoff].height;
@@ -4925,6 +4913,7 @@ void HWR_ProjectSprite(mobj_t *thing)
FIXED_TO_FLOAT(interp.z) >= FIXED_TO_FLOAT(sectors[heightsec].floorheight) :
gzt < FIXED_TO_FLOAT(sectors[heightsec].floorheight))
return;
if (gr_viewz > FIXED_TO_FLOAT(sectors[phs].ceilingheight) ?
gzt < FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) && gr_viewz >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) :
FIXED_TO_FLOAT(interp.z) >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight))
@@ -5142,15 +5131,12 @@ void HWR_DrawSkyBackground(float fpov)
//04/01/2000: Hurdler: added for T&L
// It should replace all other gr_viewxxx when finished
if (!atransform.shearing)
dometransform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
HWR_SetTransformAiming(&dometransform);
dometransform.angley = (float)((viewangle-ANGLE_270)>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
dometransform.flip = atransform.flip;
dometransform.mirror = atransform.mirror;
dometransform.mirrorflip = atransform.mirrorflip;
dometransform.shearing = atransform.shearing;
dometransform.viewaiming = atransform.viewaiming;
dometransform.scalex = 1;
dometransform.scaley = (float)vid.width/vid.height;
@@ -5211,6 +5197,25 @@ void HWR_SetViewSize(void)
HWD.pfnFlushScreenTextures();
}
// Set view aiming, for the sky dome, the skybox,
// and the normal view, all with a single function.
static void HWR_SetTransformAiming(FTransform *trans)
{
if (cv_grshearing.value)
{
fixed_t fixedaiming = AIMINGTODY(aimingangle);
trans->viewaiming = FIXED_TO_FLOAT(fixedaiming);
trans->shearing = true;
gr_aimingangle = 0;
}
else
{
trans->shearing = false;
gr_aimingangle = aimingangle;
}
trans->anglex = (float)(gr_aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
}
void HWR_SetTransform(float fpov, player_t *player)
{
postimg_t *postprocessor = &postimgtype[0];
@@ -5233,23 +5238,12 @@ void HWR_SetTransform(float fpov, player_t *player)
atransform.scaley = (float)vid.width/vid.height;
atransform.scalez = 1;
// 14042019
gr_aimingangle = aimingangle;
atransform.shearing = false;
atransform.viewaiming = aimingangle;
if (cv_grshearing.value)
{
gr_aimingangle = 0;
atransform.shearing = true;
}
HWR_SetTransformAiming(&atransform);
atransform.angley = (float)(viewangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
gr_viewludsin = FIXED_TO_FLOAT(FINECOSINE(gr_aimingangle>>ANGLETOFINESHIFT));
gr_viewludcos = FIXED_TO_FLOAT(-FINESINE(gr_aimingangle>>ANGLETOFINESHIFT));
atransform.anglex = (float)(gr_aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
atransform.angley = (float)(viewangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
atransform.fovxangle = fpov; // Tails
atransform.fovyangle = fpov; // Tails
HWR_RollTransform(&atransform, viewroll);
@@ -5381,9 +5375,10 @@ static void HWR_RenderViewpoint(gl_portal_t *rootportal, const float fpov, playe
gl_portallist_t portallist;
gl_portal_t *portal;
gl_portal_t *gl_portal_temp;
portallist.base = portallist.cap = NULL;
const boolean skybox = (skyboxmo[0] && cv_skybox.value);
boolean useportals = gr_maphasportals && cv_grportals.value && allow_portals;
const boolean useportals = cv_grportals.value && gr_maphasportals && allow_portals;
portallist.base = portallist.cap = NULL;
if (useportals && stencil_level < cv_maxportals.value) // if recursion limit is not reached
{
@@ -5392,6 +5387,7 @@ static void HWR_RenderViewpoint(gl_portal_t *rootportal, const float fpov, playe
gr_portal = GRPORTAL_SEARCH;
HWR_ClearClipper();
if (!rootportal)
portalclipline = NULL;
else
@@ -5849,7 +5845,7 @@ void HWR_DoPostProcessor(player_t *player)
// Armageddon Blast Flash!
// Could this even be considered postprocessor?
if ((player->flashcount) && (!HWR_PalRenderFlashpal()))
if (!HWR_PalRenderFlashpal() && player->flashcount)
{
FOutVector v[4];
FSurfaceInfo Surf;
+1 -1
View File
@@ -2984,7 +2984,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);
+146 -274
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)
{
@@ -2748,10 +2633,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 +2690,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 +2762,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
+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 && (((stplyr && !stplyr->spectator) && (!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");
}
+26 -77
View File
@@ -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;
@@ -5360,12 +5359,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)
@@ -6553,10 +6549,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.
@@ -9370,6 +9363,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;
@@ -9622,7 +9618,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.
@@ -9637,60 +9633,17 @@ static void K_drawKartMinimapHead(mobj_t *mo, INT32 x, INT32 y, INT32 flags, pat
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;
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 (!mo->color) // 'default' color
V_DrawSciencePatch(amxpos, amypos, flags, ( (skinlocal) ? localfacemmapprefix : facemmapprefix )[skin], FRACUNIT);
@@ -9728,8 +9681,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 +9695,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 +9724,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 +9736,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 +9751,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 +9792,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 +9804,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);
}
}
+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
+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:
+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)
+335 -183
View File
@@ -37,9 +37,8 @@
/*
* Sacrifice very little compression quality in favour of compression speed.
* This gives almost the same compression as the default code, and is
* (very roughly) 15% faster. This is the preferable mode of operation.
* (very roughly) 15% faster. This is the preferred mode of operation.
*/
#ifndef VERY_FAST
# define VERY_FAST 1
#endif
@@ -48,7 +47,7 @@
* Sacrifice some more compression quality in favour of compression speed.
* (roughly 1-2% worse compression for large blocks and
* 9-10% for small, redundant, blocks and >>20% better speed in both cases)
* In INT16: when in need for speed, enable this for binary data,
* In short: when in need for speed, enable this for binary data,
* possibly disable this for text data.
*/
#ifndef ULTRA_FAST
@@ -66,21 +65,10 @@
#endif
#endif
/*
* Use string functions to copy memory.
* this is usually a loss, even with glibc's optimized memcpy
*/
#ifndef USE_MEMCPY
#ifdef _MSC_VER
# define USE_MEMCPY 0
#else
# define USE_MEMCPY 1
#endif
#endif
/*
* You may choose to pre-set the hash table (might be faster on some
* modern cpus and large (>>64k) blocks)
* modern cpus and large (>>64k) blocks, and also makes compression
* deterministic/repeatable when the configuration otherwise is the same).
*/
#ifndef INIT_HTAB
# define INIT_HTAB 1
@@ -88,15 +76,15 @@
/*
* Avoid assigning values to errno variable? for some embedding purposes
* (linux kernel for example), this is neccessary. NOTE: this breaks
* the documentation in lzf.h.
* (linux kernel for example), this is necessary. NOTE: this breaks
* the documentation in lzf.h. Avoiding errno has no speed impact.
*/
#ifndef AVOID_ERRNO
# define AVOID_ERRNO 0
#endif
/*
* Wether to pass the LZF_STATE variable as argument, or allocate it
* Whether to pass the LZF_STATE variable as argument, or allocate it
* on the stack. For small-stack environments, define this to 1.
* NOTE: this breaks the prototype in lzf.h.
*/
@@ -105,51 +93,109 @@
#endif
/*
* Wether to add extra checks for input validity in lzf_decompress
* Whether to add extra checks for input validity in lzf_decompress
* and return EINVAL if the input stream has been corrupted. This
* only shields against overflowing the input buffer and will not
* detect most corrupted streams.
* This check is not normally noticable on modern hardware
* This check is not normally noticeable on modern hardware
* (<1% slowdown), but might slow down older cpus considerably.
*/
#ifndef CHECK_INPUT
# define CHECK_INPUT 1
#endif
/*
* Whether the target CPU has a slow multiplication. This affects
* the default hash function for the compressor, and enables a slightly
* worse hash function that needs only shifts.
*/
#ifndef MULTIPLICATION_IS_SLOW
# define MULTIPLICATION_IS_SLOW 0
#endif
/*
* If defined, then this data type will be used for storing offsets.
* This can be useful if you want to use a huge hashtable, want to
* conserve memory, or both, and your data fits into e.g. 64kb.
* If instead you want to compress data > 4GB, then it's better to
* to "#define LZF_USE_OFFSETS 0" instead.
*/
/*#define LZF_HSLOT unsigned short*/
/*
* Whether to store pointers or offsets inside the hash table. On
* 64 bit architetcures, pointers take up twice as much space,
* and might also be slower. Default is to autodetect.
*/
/*#define LZF_USE_OFFSETS autodetect */
/*
* Whether to optimise code for size, at the expense of speed. Use
* this when you are extremely tight on memory, perhaps in combination
* with AVOID_ERRNO 1 and CHECK_INPUT 0.
*/
#ifndef OPTIMISE_SIZE
# ifdef __OPTIMIZE_SIZE__
# define OPTIMISE_SIZE 1
# else
# define OPTIMISE_SIZE 0
# endif
#endif
/*****************************************************************************/
/* nothing should be changed below */
typedef unsigned char u8;
typedef const u8 *LZF_STATE[1 << (HLOG)];
#if !STRICT_ALIGN
/* for unaligned accesses we need a 16 bit datatype. */
# include <string.h>
# include <limits.h>
# if USHRT_MAX == 65535
typedef unsigned short u16;
# elif UINT_MAX == 65535
typedef unsigned int u16;
# else
# undef STRICT_ALIGN
# define STRICT_ALIGN 1
# endif
#endif
#if ULTRA_FAST
# if defined(VERY_FAST)
# undef VERY_FAST
# undef VERY_FAST
#endif
#ifndef LZF_USE_OFFSETS
# ifdef _WIN32
# define LZF_USE_OFFSETS defined(_M_X64)
# else
# include <stdint.h>
# define LZF_USE_OFFSETS (UINTPTR_MAX > 0xffffffffU)
# endif
#endif
#if USE_MEMCPY || INIT_HTAB
# ifdef __cplusplus
# include <cstring>
typedef unsigned char u8;
#ifdef LZF_HSLOT
# define LZF_HSLOT_BIAS ((const u8 *)in_data)
#else
# ifdef LZF_USE_OFFSETS
# define LZF_HSLOT_BIAS ((const u8 *)in_data)
typedef unsigned int LZF_HSLOT;
# else
# include <string.h>
# define LZF_HSLOT_BIAS 0
typedef const u8 *LZF_HSLOT;
# endif
#endif
#if USHRT_MAX == 65535
typedef unsigned short u16;
#elif UINT_MAX == 65535
typedef unsigned int u16;
#else
# undef STRICT_ALIGN
# define STRICT_ALIGN 1
#endif
#define LZF_MAX_LIT (1 << 5)
#define LZF_MAX_OFF (1 << 13)
#define LZF_MAX_REF ((1 << 8) + (1 << 3))
typedef LZF_HSLOT LZF_STATE[1 << (HLOG)];
typedef struct
{
const u8 *first [1 << (6+8)]; /* most recent occurance of a match */
u16 prev [LZF_MAX_OFF]; /* how many bytes to go backwards for the next match */
} LZF_STATE_BEST[1];
#endif
@@ -164,14 +210,31 @@ typedef const u8 *LZF_STATE[1 << (HLOG)];
# define SET_ERRNO(n) errno = (n)
#endif
#ifndef USE_REP_MOVSB
#if (defined (__i386) || defined (__amd64)) && __GNUC__ >= 3
#define USE_REP_MOVSB 1
#else
#define USE_REP_MOVSB 0 // Default to 0 if not defined elsewhere
#endif
#endif
#if USE_REP_MOVSB /* small win on amd, big loss on intel */
#if (defined (__i386) || defined (__amd64)) && __GNUC__ >= 3
# define lzf_movsb(dst, src, len) \
asm ("rep movsb" \
: "=D" (dst), "=S" (src), "=c" (len) \
: "0" (dst), "1" (src), "2" (len));
#endif
#endif
size_t
lzf_decompress (const void *const in_data, size_t in_len,
void *out_data, size_t out_len)
void *out_data, size_t out_len)
{
u8 const *ip = (const u8 *)in_data;
u8 *op = (u8 *)out_data;
u8 *op = (u8 *)out_data;
u8 const *const in_end = ip + in_len;
u8 *const out_end = op + out_len;
u8 *const out_end = op + out_len;
do
{
@@ -195,14 +258,23 @@ lzf_decompress (const void *const in_data, size_t in_len,
}
#endif
#if USE_MEMCPY
M_Memcpy (op, ip, ctrl);
op += ctrl;
ip += ctrl;
#else
do
#ifdef lzf_movsb
lzf_movsb (op, ip, ctrl);
#elif OPTIMISE_SIZE
while (ctrl--)
*op++ = *ip++;
while (--ctrl);
#else
switch (ctrl)
{
case 32: *op++ = *ip++; case 31: *op++ = *ip++; case 30: *op++ = *ip++; case 29: *op++ = *ip++;
case 28: *op++ = *ip++; case 27: *op++ = *ip++; case 26: *op++ = *ip++; case 25: *op++ = *ip++;
case 24: *op++ = *ip++; case 23: *op++ = *ip++; case 22: *op++ = *ip++; case 21: *op++ = *ip++;
case 20: *op++ = *ip++; case 19: *op++ = *ip++; case 18: *op++ = *ip++; case 17: *op++ = *ip++;
case 16: *op++ = *ip++; case 15: *op++ = *ip++; case 14: *op++ = *ip++; case 13: *op++ = *ip++;
case 12: *op++ = *ip++; case 11: *op++ = *ip++; case 10: *op++ = *ip++; case 9: *op++ = *ip++;
case 8: *op++ = *ip++; case 7: *op++ = *ip++; case 6: *op++ = *ip++; case 5: *op++ = *ip++;
case 4: *op++ = *ip++; case 3: *op++ = *ip++; case 2: *op++ = *ip++; case 1: *op++ = *ip++;
}
#endif
}
else /* back reference */
@@ -244,12 +316,49 @@ lzf_decompress (const void *const in_data, size_t in_len,
return 0;
}
*op++ = *ref++;
*op++ = *ref++;
#ifdef lzf_movsb
len += 2;
lzf_movsb (op, ref, len);
#elif OPTIMISE_SIZE
len += 2;
do
*op++ = *ref++;
while (--len);
#else
switch (len)
{
default:
len += 2;
if (op >= ref + len)
{
/* disjunct areas */
memcpy (op, ref, len);
op += len;
}
else
{
/* overlapping, use octet by octet copying */
do
*op++ = *ref++;
while (--len);
}
break;
case 9: *op++ = *ref++;
case 8: *op++ = *ref++;
case 7: *op++ = *ref++;
case 6: *op++ = *ref++;
case 5: *op++ = *ref++;
case 4: *op++ = *ref++;
case 3: *op++ = *ref++;
case 2: *op++ = *ref++;
case 1: *op++ = *ref++;
case 0: *op++ = *ref++; /* two octets more */
*op++ = *ref++;
}
#endif
}
}
while (ip < in_end);
@@ -266,23 +375,29 @@ lzf_decompress (const void *const in_data, size_t in_len,
/*
* don't play with this unless you benchmark!
* decompression is not dependent on the hash function
* the hashing function might seem strange, just believe me
* the data format is not dependent on the hash function.
* the hash function might seem strange, just believe me,
* it works ;)
*/
#ifndef FRST
# define FRST(p) (((p[0]) << 8) | p[1])
# define NEXT(v,p) (((v) << 8) | p[2])
# define IDX(h) ((((h ^ (h << 5)) >> (3*8 - HLOG)) - h*5) & (HSIZE - 1))
#endif
/*
* IDX works because it is very similar to a multiplicative hash, e.g.
* ((h * 57321 >> (3*8 - HLOG)) & (HSIZE - 1))
* the latter is also quite fast on newer CPUs, and sligthly better
*
* the next one is also quite good, albeit slow ;)
* (int)(cos(h & 0xffffff) * 1e6)
# if MULTIPLICATION_IS_SLOW
# if ULTRA_FAST
# define IDX(h) ((( h >> (3*8 - HLOG)) - h ) & (HSIZE - 1))
# elif VERY_FAST
# define IDX(h) ((( h >> (3*8 - HLOG)) - h*5) & (HSIZE - 1))
# else
# define IDX(h) ((((h ^ (h << 5)) >> (3*8 - HLOG)) - h*5) & (HSIZE - 1))
# endif
# else
/* this one was developed with sesse,
* and is very similar to the one in snappy.
* it does need a modern enough cpu with a fast multiplication.
*/
# define IDX(h) (((h * 0x1e35a7bdU) >> (32 - HLOG - 8)) & (HSIZE - 1))
# endif
#endif
#if 0
/* original lzv-like hash function, much worse and thus slower */
@@ -291,177 +406,214 @@ lzf_decompress (const void *const in_data, size_t in_len,
# define IDX(h) ((h) & (HSIZE - 1))
#endif
#define MAX_LIT (1 << 5)
#define MAX_OFF (1 << 13)
#define MAX_REF ((1 << 8) + (1 << 3))
#if __GNUC__ >= 3
# define expect(expr,value) __builtin_expect ((expr),(value))
# define inline inline
#else
# define expect(expr,value) (expr)
# define inline static
#endif
#define expect_false(expr) expect ((expr) != 0, 0)
#define expect_true(expr) expect ((expr) != 0, 1)
/*
* compressed format
*
* 000LLLLL <L+1> ; literal
* LLLooooo oooooooo ; backref L
* 111ooooo LLLLLLLL oooooooo ; backref L+7
* 000LLLLL <L+1> ; literal, L+1=1..33 octets
* LLLooooo oooooooo ; backref L+1=1..7 octets, o+1=1..4096 offset
* 111ooooo LLLLLLLL oooooooo ; backref L+8 octets, o+1=1..4096 offset
*
*/
size_t
lzf_compress (const void *const in_data,size_t in_len,
void *out_data, size_t out_len
lzf_compress (const void *const in_data, size_t in_len,
void *out_data, size_t out_len
#if LZF_STATE_ARG
, LZF_STATE *htab
, LZF_STATE htab
#endif
)
)
{
#if !LZF_STATE_ARG
LZF_STATE htab;
#endif
const u8 **hslot;
const u8 *ip = (const u8 *)in_data;
u8 *op = (u8 *)out_data;
u8 *op = (u8 *)out_data;
const u8 *in_end = ip + in_len;
u8 *out_end = op + out_len;
const u8 *ref = NULL;
u8 *out_end = op + out_len;
const u8 *ref;
/*
* off requires a type wide enough to hold a general pointer difference.
* ISO C doesn't have that (size_t might not be enough and ptrdiff_t only
* works for differences within a single object). We also assume that
* no bit pattern traps. Since the only platform that is both non-POSIX
* and fails to support both assumptions is windows 64 bit, we make a
* special workaround for it.
*/
unsigned int hval = FRST (ip);
size_t off;
int lit = 0;
unsigned int hval;
int lit;
if (!in_len || !out_len)
return 0;
#if INIT_HTAB
# if USE_MEMCPY
memset (htab, 0, sizeof (htab));
# else
for (hslot = htab; hslot < htab + HSIZE; hslot++)
*hslot++ = ip;
# endif
#endif
for (;;)
lit = 0; op++; /* start run */
hval = FRST (ip);
while (ip < in_end - 2)
{
if (ip < in_end - 2)
{
hval = NEXT (hval, ip);
hslot = htab + IDX (hval);
ref = *hslot; *hslot = ip;
LZF_HSLOT *hslot;
if (
#if INIT_HTAB && !USE_MEMCPY
ref < ip /* the next test will actually take care of this, but this is faster */
&&
hval = NEXT (hval, ip);
hslot = htab + IDX (hval);
ref = *hslot + LZF_HSLOT_BIAS; *hslot = ip - LZF_HSLOT_BIAS;
if (1
#if INIT_HTAB
&& ref < ip /* the next test will actually take care of this, but this is faster */
#endif
(off = ip - ref - 1) < MAX_OFF
&& ip + 4 < in_end
&& ref > (const u8 *)in_data
&& (off = ip - ref - 1) < LZF_MAX_OFF
&& ref > (const u8 *)in_data
&& ref[2] == ip[2]
#if STRICT_ALIGN
&& ref[0] == ip[0]
&& ref[1] == ip[1]
&& ref[2] == ip[2]
&& ((ref[1] << 8) | ref[0]) == ((ip[1] << 8) | ip[0])
#else
&& *(const u16 *)ref == *(const u16 *)ip
&& ref[2] == ip[2]
&& *(const u16 *)ref == *(const u16 *)ip
#endif
)
{
/* match found at *ref++ */
unsigned int len = 2;
size_t maxlen = in_end - ip - len;
maxlen = maxlen > MAX_REF ? MAX_REF : maxlen;
)
{
/* match found at *ref++ */
unsigned int len = 2;
size_t maxlen = in_end - ip - len;
maxlen = maxlen > LZF_MAX_REF ? LZF_MAX_REF : maxlen;
if (op + lit + 1 + 3 >= out_end)
if (expect_false (op + 3 + 1 >= out_end)) /* first a faster conservative test */
if (op - !lit + 3 + 1 >= out_end) /* second the exact but rare test */
return 0;
op [- lit - 1] = lit - 1; /* stop run */
op -= !lit; /* undo run if length is zero */
for (;;)
{
if (expect_true (maxlen > 16))
{
len++; if (ref [len] != ip [len]) break;
len++; if (ref [len] != ip [len]) break;
len++; if (ref [len] != ip [len]) break;
len++; if (ref [len] != ip [len]) break;
len++; if (ref [len] != ip [len]) break;
len++; if (ref [len] != ip [len]) break;
len++; if (ref [len] != ip [len]) break;
len++; if (ref [len] != ip [len]) break;
len++; if (ref [len] != ip [len]) break;
len++; if (ref [len] != ip [len]) break;
len++; if (ref [len] != ip [len]) break;
len++; if (ref [len] != ip [len]) break;
len++; if (ref [len] != ip [len]) break;
len++; if (ref [len] != ip [len]) break;
len++; if (ref [len] != ip [len]) break;
len++; if (ref [len] != ip [len]) break;
}
do
len++;
while (len < maxlen && ref[len] == ip[len]);
if (lit)
{
*op++ = (u8)(lit - 1);
lit = -lit;
do
*op++ = ip[lit];
while (++lit);
}
break;
}
len -= 2;
ip++;
len -= 2; /* len is now #octets - 1 */
ip++;
if (len < 7)
{
*op++ = (u8)((off >> 8) + (len << 5));
}
else
{
*op++ = (u8)((off >> 8) + ( 7 << 5));
*op++ = (u8)(len - 7);
}
if (len < 7)
{
*op++ = (off >> 8) + (len << 5);
}
else
{
*op++ = (off >> 8) + ( 7 << 5);
*op++ = len - 7;
}
*op++ = (u8)off;
*op++ = off;
lit = 0; op++; /* start run */
ip += len + 1;
if (expect_false (ip >= in_end - 2))
break;
#if ULTRA_FAST || VERY_FAST
ip += len;
#if VERY_FAST && !ULTRA_FAST
--ip;
#endif
hval = FRST (ip);
--ip;
# if VERY_FAST && !ULTRA_FAST
--ip;
# endif
hval = FRST (ip);
hval = NEXT (hval, ip);
htab[IDX (hval)] = ip;
ip++;
hval = NEXT (hval, ip);
htab[IDX (hval)] = ip - LZF_HSLOT_BIAS;
ip++;
#if VERY_FAST && !ULTRA_FAST
hval = NEXT (hval, ip);
htab[IDX (hval)] = ip;
ip++;
#endif
# if VERY_FAST && !ULTRA_FAST
hval = NEXT (hval, ip);
htab[IDX (hval)] = ip - LZF_HSLOT_BIAS;
ip++;
# endif
#else
do
{
hval = NEXT (hval, ip);
htab[IDX (hval)] = ip;
ip++;
}
while (len--);
#endif
continue;
ip -= len + 1;
do
{
hval = NEXT (hval, ip);
htab[IDX (hval)] = ip - LZF_HSLOT_BIAS;
ip++;
}
while (len--);
#endif
}
else if (ip == in_end)
break;
/* one more literal byte we must copy */
lit++;
ip++;
if (lit == MAX_LIT)
else
{
if (op + 1 + MAX_LIT >= out_end)
/* one more literal byte we must copy */
if (expect_false (op >= out_end))
return 0;
*op++ = MAX_LIT - 1;
#if USE_MEMCPY
M_Memcpy (op, ip - MAX_LIT, MAX_LIT);
op += MAX_LIT;
lit = 0;
#else
lit = -lit;
do
*op++ = ip[lit];
while (++lit);
#endif
lit++; *op++ = *ip++;
if (expect_false (lit == LZF_MAX_LIT))
{
op [- lit - 1] = lit - 1; /* stop run */
lit = 0; op++; /* start run */
}
}
}
if (lit)
{
if (op + lit + 1 >= out_end)
return 0;
if (op + 3 > out_end) /* at most 3 bytes can be missing here */
return 0;
*op++ = (u8)(lit - 1);
lit = -lit;
do
*op++ = ip[lit];
while (++lit);
while (ip < in_end)
{
lit++; *op++ = *ip++;
if (expect_false (lit == LZF_MAX_LIT))
{
op [- lit - 1] = lit - 1; /* stop run */
lit = 0; op++; /* start run */
}
}
return op - (u8 *) out_data;
op [- lit - 1] = lit - 1; /* end run */
op -= !lit; /* undo run if length is zero */
return op - (u8 *)out_data;
}
+2 -2
View File
@@ -1,6 +1,6 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2000-2005 by Marc Alexander Lehmann <schmorp@schmorp.de>
// Copyright (c) 2000-2010 Marc Alexander Lehmann <schmorp@schmorp.de>
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@@ -22,7 +22,7 @@
**
***********************************************************************/
#define LZF_VERSION 0x0105 /* 1.5 */
#define LZF_VERSION 0x0106 /* 1.6 */
/*
* Compress in_len bytes stored at the memory block starting at
+222 -240
View File
@@ -30,6 +30,7 @@
#include "g_game.h"
#include "g_input.h"
#include "m_argv.h"
#include "m_textinput.h"
// Data.
#include "sounds.h"
@@ -159,6 +160,9 @@ boolean fromlevelselect = false;
boolean menu_text_input = false;
char menu_text_input_buf[MAXSTRINGLENGTH];
static textinput_t menuinput;
static INT32 coolalphatimer = 9;
typedef enum
@@ -245,6 +249,7 @@ menu_t SR_MainDef, SR_UnlockChecklistDef;
// Misc. Main Menu
static void M_Options(INT32 choice);
static void M_Multiplayer(INT32 choice);
static void M_LocalSkinMenu(INT32 choice);
static void M_LocalSkinChange(INT32 choice);
static void M_Manual(INT32 choice);
@@ -591,7 +596,7 @@ static menuitem_t MainMenu[] =
{
{IT_SUBMENU|IT_STRING, NULL, "Extras", &SR_MainDef, 76},
{IT_CALL |IT_STRING, NULL, "Time Attack", M_TimeAttack, 84},
{IT_SUBMENU|IT_STRING, NULL, "Multiplayer", &MP_MainDef, 92},
{IT_CALL |IT_STRING, NULL, "Multiplayer", M_Multiplayer, 92},
{IT_CALL |IT_STRING, NULL, "Options", M_Options, 100},
{IT_CALL |IT_STRING, NULL, "Addons", M_Addons, 108},
{IT_CALL |IT_STRING, NULL, "Quit Game", M_QuitSRB2, 116},
@@ -1598,7 +1603,20 @@ static menuitem_t OP_SoundOptionsMenu[] =
//{IT_STRING|IT_CALL, NULL, "Restart Audio System", M_RestartAudio, 50},
#ifdef NO_MIDI
{IT_STRING|IT_CVAR, NULL, "Reverse L/R Channels", &stereoreverse, 50},
{IT_STRING|IT_CVAR, NULL, "Surround Sound", &surround, 60},
{IT_STRING|IT_CVAR, NULL, "Chat Notifications", &cv_chatnotifications, 65},
{IT_STRING|IT_CVAR, NULL, "Character voices", &cv_kartvoices, 75},
{IT_STRING|IT_CVAR, NULL, "Hit Em Delay", &cv_karthitemdialog, 85},
{IT_STRING|IT_CVAR, NULL, "Powerup Warning", &cv_kartinvinsfx, 95},
{IT_KEYHANDLER|IT_STRING, NULL, "Sound Test", M_HandleSoundTest, 105},
{IT_STRING|IT_CALL, NULL, "Music Test", M_MusicTest, 115},
{IT_STRING|IT_CVAR, NULL, "Play Music While Unfocused", &cv_playmusicifunfocused, 125},
{IT_STRING|IT_CVAR, NULL, "Play SFX While Unfocused", &cv_playsoundifunfocused, 135},
{IT_STRING|IT_SUBMENU, NULL, "Advanced Settings...", &OP_SoundAdvancedDef, 145}
#else
{IT_STRING|IT_CVAR, NULL, "Reverse L/R Channels", &stereoreverse, 60},
{IT_STRING|IT_CVAR, NULL, "Chat Notifications", &cv_chatnotifications, 75},
{IT_STRING|IT_CVAR, NULL, "Character voices", &cv_kartvoices, 85},
@@ -1611,21 +1629,6 @@ static menuitem_t OP_SoundOptionsMenu[] =
{IT_STRING|IT_CVAR, NULL, "Play Music While Unfocused", &cv_playmusicifunfocused, 135},
{IT_STRING|IT_CVAR, NULL, "Play SFX While Unfocused", &cv_playsoundifunfocused, 145},
{IT_STRING|IT_SUBMENU, NULL, "Advanced Settings...", &OP_SoundAdvancedDef, 155}
#else
{IT_STRING|IT_CVAR, NULL, "Reverse L/R Channels", &stereoreverse, 60},
{IT_STRING|IT_CVAR, NULL, "Surround Sound", &surround, 70},
{IT_STRING|IT_CVAR, NULL, "Chat Notifications", &cv_chatnotifications, 85},
{IT_STRING|IT_CVAR, NULL, "Character voices", &cv_kartvoices, 95},
{IT_STRING|IT_CVAR, NULL, "Hit Em Delay", &cv_karthitemdialog, 105},
{IT_STRING|IT_CVAR, NULL, "Powerup Warning", &cv_kartinvinsfx, 115},
{IT_KEYHANDLER|IT_STRING, NULL, "Sound Test", M_HandleSoundTest, 125},
{IT_STRING|IT_CALL, NULL, "Music Test", M_MusicTest, 135},
{IT_STRING|IT_CVAR, NULL, "Play Music While Unfocused", &cv_playmusicifunfocused, 145},
{IT_STRING|IT_CVAR, NULL, "Play SFX While Unfocused", &cv_playsoundifunfocused, 155},
{IT_STRING|IT_SUBMENU, NULL, "Advanced Settings...", &OP_SoundAdvancedDef, 165}
#endif
};
@@ -1640,7 +1643,6 @@ static const char* OP_SoundTooltips[] =
"Volume of Midi Music.",
#endif
"Reverse left and right channels of audio.",
"Surround Sound.",
"Chat notification sound.",
"Frequency of character voice lines.",
"Play 'Hit Em' character line after other player's hurt line.",
@@ -1656,21 +1658,25 @@ static const char* OP_SoundTooltips[] =
static menuitem_t OP_SoundAdvancedMenu[] =
{
#ifdef HAVE_OPENMPT
{IT_HEADER, NULL, "Tracker Module Options", NULL, 10},
{IT_HEADER, NULL, "Tracker Module Options", NULL, 0},
{IT_STRING | IT_CVAR, NULL, "Instrument Filter", &cv_modfilter, 22},
{IT_STRING | IT_CVAR, NULL, "Amiga Resampler", &cv_amigafilter, 42},
{IT_STRING | IT_CVAR, NULL, "Instrument Filter", &cv_modfilter, 20},
{IT_STRING | IT_CVAR, NULL, "Amiga Resampler", &cv_amigafilter, 30},
#if OPENMPT_API_VERSION_MAJOR < 1 && OPENMPT_API_VERSION_MINOR > 4
{IT_STRING | IT_CVAR, NULL, "Amiga Type", &cv_amigatype, 62},
{IT_STRING | IT_CVAR, NULL, "Amiga Type", &cv_amigatype, 40},
#endif
{IT_STRING | IT_CVAR, NULL, "Stereo Seperation", &cv_stereosep, 82},
{IT_STRING | IT_CVAR, NULL, "Stereo Seperation", &cv_stereosep, 50},
#endif
{IT_HEADER, NULL, "Misc", NULL, 105},
{IT_STRING | IT_CVAR, NULL, "Grow Music", &cv_growmusic, 117},
{IT_STRING | IT_CVAR, NULL, "Invulnerability Music", &cv_supermusic, 127},
{IT_HEADER, NULL, "Misc", NULL, 70},
{IT_STRING | IT_CVAR, NULL, "Audio Buffer Size", &cv_audbuffersize, 147},
{IT_STRING | IT_CVAR, NULL, "Grow Music", &cv_growmusic, 90},
{IT_STRING | IT_CVAR, NULL, "Invulnerability Music", &cv_supermusic, 100},
{IT_STRING | IT_CVAR, NULL, "Keep Map Music", &cv_keepmusic, 120},
{IT_STRING | IT_CVAR, NULL, "Skip Intro Music", &cv_skipintromusic, 130},
{IT_STRING | IT_CVAR, NULL, "Audio Buffer Size", &cv_audbuffersize, 150},
};
static const char* OP_SoundAdvancedTooltips[] =
@@ -1688,6 +1694,8 @@ static const char* OP_SoundAdvancedTooltips[] =
NULL,
"Should the Grow music be on or off?",
"Should the Invulnerability music be on or off?",
"Should music be kept when restarting the map?",
"Should the Intro fanfare be skipped\nand map music be played on map start?",
"Size of the Audio Buffer\nreducing it will result in less sound latency\nbut may cause issues such as crackling or distorted Sound.",
};
@@ -2580,6 +2588,7 @@ static menuitem_t OP_AdvancedBirdMenu[] =
{IT_STRING | IT_CVAR, NULL, "Fade Back In While Respawning", &cv_respawnfademusicback, 40},
{IT_STRING | IT_CVAR, NULL, "Resync Threshold", &cv_music_resync_threshold, 60},
{IT_STRING | IT_CVAR, NULL, "Resync Special Music Only", &cv_music_resync_powerups_only, 70},
};
static const char* OP_AdvancedBirdTooltips[] =
@@ -3327,8 +3336,6 @@ static void Newgametype_OnChange(void)
}
CV_SetValue(&cv_nextmap, M_FindFirstMap(value));
//CV_AddValue(&cv_nextmap, -1);
//CV_AddValue(&cv_nextmap, 1);
}
}
}
@@ -3504,46 +3511,15 @@ static void M_ChangeCvar(INT32 choice)
static boolean M_ChangeStringCvar(INT32 choice)
{
consvar_t *cv = (consvar_t *)currentMenu->menuitems[itemOn].itemaction;
char buf[MAXSTRINGLENGTH];
size_t len;
choice = M_ShiftChar(choice);
switch (choice)
if (M_TextInputHandle(&menuinput, choice))
{
case KEY_BACKSPACE:
len = strlen(cv->string);
if (len > 0)
{
S_StartSound(NULL,sfx_menu1); // Tails
M_Memcpy(buf, cv->string, len);
buf[len-1] = 0;
CV_Set(cv, buf);
}
return true;
case KEY_DEL:
if (cv->string[0])
{
S_StartSound(NULL,sfx_menu1); // Tails
CV_Set(cv, "");
}
return true;
default:
if ((cv_keyboardlayout.value != 3 && choice >= 32 && choice <= 127) || (cv_keyboardlayout.value == 3 && choice >= 32 && choice <= 141))
{
len = strlen(cv->string);
if (len < MAXSTRINGLENGTH - 1)
{
S_StartSound(NULL,sfx_menu1); // Tails
M_Memcpy(buf, cv->string, len);
buf[len++] = (char)choice;
buf[len] = 0;
CV_Set(cv, buf);
}
return true;
}
break;
S_StartSound(NULL,sfx_menu1); // Tails
CV_Set(cv, menuinput.buffer);
return true;
}
return false;
}
@@ -3560,6 +3536,21 @@ static void M_ResetCvars(void)
}
}
// If current menu item is IT_CV_STRING, setup menuinput
static void M_CheckStringItem(void)
{
if (itemOn < currentMenu->numitems && (currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_STRING)
{
consvar_t *cv = (consvar_t *)currentMenu->menuitems[itemOn].itemaction;
// Just in case
memset(menu_text_input_buf, 0, sizeof menu_text_input_buf);
M_TextInputInit(&menuinput, menu_text_input_buf, sizeof menu_text_input_buf);
M_TextInputSetString(&menuinput, cv->string);
}
}
static void M_NextOpt(void)
{
INT16 oldItemOn = itemOn; // prevent infinite loop
@@ -3571,6 +3562,8 @@ static void M_NextOpt(void)
else
itemOn++;
} while (oldItemOn != itemOn && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_SPACE);
M_CheckStringItem();
}
static void M_PrevOpt(void)
@@ -3584,6 +3577,8 @@ static void M_PrevOpt(void)
else
itemOn--;
} while (oldItemOn != itemOn && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_SPACE);
M_CheckStringItem();
}
// lock out further input in a tic when important buttons are pressed
@@ -3944,7 +3939,6 @@ boolean M_Responder(event_t *ev)
if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_STRING)
{
menu_text_input = true;
ch = M_ShiftChar(ch);
if (M_ChangeStringCvar(ch))
return true;
else
@@ -4295,7 +4289,9 @@ void M_Drawer(void)
{
// now that's more readable with a faded background (yeah like Quake...)
if (ShouldDrawMenuBG())
{
V_DrawFadeScreen(0xFF00, 16);
}
if (currentMenu->drawroutine)
{
@@ -4603,6 +4599,8 @@ void M_SetupNextMenu(menu_t *menudef)
}
}
}
M_CheckStringItem();
}
//
@@ -4942,6 +4940,33 @@ void M_DrawTextBoxFlags(INT32 x, INT32 y, INT32 width, INT32 boxlines, INT32 fla
V_DrawFill(x+5, y+5, width*8+6, boxlines*8+6, 239|flags);
}
void M_DrawTextInput(INT32 x, INT32 y, textinput_t *input, INT32 flags)
{
INT32 skullx = x;
V_DrawString(x, y, V_ALLOWLOWERCASE|flags, input->buffer);
// draw text cursor for name
if (input->length)
skullx = x+V_SubStringWidth(input->buffer, input->cursor, V_ALLOWLOWERCASE);
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);
size_t len = end - start;
INT32 startx = V_SubStringWidth(input->buffer, start, V_ALLOWLOWERCASE);
V_DrawFill(x+startx, y, V_SubStringWidth(input->buffer+start, len, V_ALLOWLOWERCASE), 8, 103|V_TRANSLUCENT|flags);
}
}
// horizontally centered text
static void M_CentreText(INT32 y, const char *string)
{
@@ -5143,10 +5168,12 @@ static void M_DrawGenericMenu(void)
break;
case IT_CV_STRING:
M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1);
V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string);
if (skullAnimCounter < 4 && i == itemOn)
V_DrawCharacter(x + 8 + V_StringWidth(cv->string, 0), y + 12,
'_' | 0x80, false);
if (itemOn == i)
M_DrawTextInput(x + 8, y + 12, &menuinput, 0);
else
V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string);
y += 16;
break;
default:
@@ -5330,10 +5357,12 @@ static void M_DrawGenericScrollMenu(void)
if (y + 12 > (currentMenu->y + 2*scrollareaheight))
break;
M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1);
V_DrawString(x + 8, y + 12, lowercase, cv->string);
if (skullAnimCounter < 4 && i == itemOn)
V_DrawCharacter(x + 8 + V_StringWidth(cv->string, 0), y + 12,
'_' | 0x80, false);
if (itemOn == i)
M_DrawTextInput(x + 8, y + 12, &menuinput, 0);
else
V_DrawString(x + 8, y + 12, lowercase, cv->string);
break;
default:
V_DrawRightAlignedString(BASEVIDWIDTH - x, y,
@@ -5469,10 +5498,12 @@ static void M_DrawCenteredMenu(void)
break;
case IT_CV_STRING:
M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1);
V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string);
if (skullAnimCounter < 4 && i == itemOn)
V_DrawCharacter(x + 8 + V_StringWidth(cv->string, 0), y + 12,
'_' | 0x80, false);
if (itemOn == i)
M_DrawTextInput(x + 8, y + 12, &menuinput, 0);
else
V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string);
y += 16;
break;
default:
@@ -5608,27 +5639,13 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt)
switch (levellistmode)
{
case LLM_CREATESERVER:
// Should the map be hidden?
//if (mapheaderinfo[mapnum]->menuflags & LF2_HIDEINMENU && mapnum+1 != gamemap)
//return false;
// Should the map be hidden? <-- well imma wanna toggle it, its just annoying being unable to select hell maps in mapselect
if ((mapheaderinfo[mapnum]->menuflags & LF2_HIDEINMENU && mapnum+1 != gamemap) && (gt == GT_RACE && (mapheaderinfo[mapnum]->typeoflevel & TOL_RACE))) // map hell
{
if (cv_showallmaps.value)
return true;
else
return false;
}
return cv_showallmaps.value;
// same goes here, just show every map if i want to
if (M_MapLocked(mapnum+1)) // not unlocked
{
if (cv_showallmaps.value)
return true;
else
return false;
}
return cv_showallmaps.value;
if ((gt == GT_MATCH || gt == GT_TEAMMATCH) && (mapheaderinfo[mapnum]->typeoflevel & TOL_MATCH))
return true;
@@ -5638,18 +5655,7 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt)
return false;
/*case LLM_LEVELSELECT:
if (mapheaderinfo[mapnum]->levelselect != maplistoption)
return false;
if (M_MapLocked(mapnum+1))
return false; // not unlocked
return true;*/
case LLM_RECORDATTACK:
/*if (!(mapheaderinfo[mapnum]->menuflags & LF2_RECORDATTACK))
return false;*/
if (!(mapheaderinfo[mapnum]->typeoflevel & TOL_RACE))
return false;
@@ -5662,12 +5668,6 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt)
if (mapheaderinfo[mapnum]->menuflags & LF2_HIDEINMENU)
return false; // map hell
/*if (mapheaderinfo[mapnum]->menuflags & LF2_NOVISITNEEDED)
return true;
if (!mapvisited[mapnum])
return false;*/
return true;
default:
return false;
@@ -6679,11 +6679,11 @@ I_mutex replayquerymutex;
#define MAXREPLAYQUERY 40
char replayqueryinput[MAXREPLAYQUERY+1]; // The input typed
size_t replayquerypos = 0; // Position in input window
static char replayqueryinput_buffer[MAXREPLAYQUERY+1]; // The input typed
static textinput_t replayqueryinput;
size_t replayqueryfound = 0; // Number of checked replay entries
size_t replayquerycheck = 0; // Index of next replay entry to check in demolist_all
static size_t replayqueryfound = 0; // Number of checked replay entries
static size_t replayquerycheck = 0; // Index of next replay entry to check in demolist_all
#define DF_ENCORE 0x40
static INT16 replayScrollTitle = 0;
@@ -6738,8 +6738,8 @@ static void LoadReplayNames(void)
static void ResetReplayQuery(void)
{
memset(replayqueryinput, 0, MAXREPLAYQUERY);
replayquerypos = 0;
memset(replayqueryinput_buffer, 0, MAXREPLAYQUERY);
M_TextInputInit(&replayqueryinput, replayqueryinput_buffer, MAXREPLAYQUERY);
replayqueryfound = 0;
replayquerycheck = 0;
@@ -6763,7 +6763,7 @@ static void M_HutCheckReplays(size_t maxnum)
return;
// If we don't have any query, just copy all demos and consider them checked
if (replayquerypos == 0)
if (replayqueryinput.length == 0)
{
// Mark as done
replayqueryfound = replayquerycheck = sizedirmenu;
@@ -6787,7 +6787,7 @@ static void M_HutCheckReplays(size_t maxnum)
case MD_NOTLOADED:
case MD_OUTDATED:
case MD_LOADED:
if (demolist_all[replayquerycheck].title[0] && strcasestr(demolist_all[replayquerycheck].title, replayqueryinput) != NULL)
if (demolist_all[replayquerycheck].title[0] && strcasestr(demolist_all[replayquerycheck].title, replayqueryinput.buffer) != NULL)
AddCheckedReplay(); // It matches, add it!
else
replayquerycheck++; // Doesn't match, moving on...
@@ -6886,41 +6886,23 @@ void M_ReplayHut(INT32 choice)
static boolean M_HandleReplayHutQuery(INT32 choice)
{
switch (choice)
// Yea gonna copy buffer and check if it changed, thats better than checking for specific keys i think
char tmp[MAXREPLAYQUERY+1];
memcpy(tmp, replayqueryinput_buffer, MAXREPLAYQUERY+1);
if (M_TextInputHandle(&replayqueryinput, choice))
{
case KEY_BACKSPACE:
if (replayquerypos == 0)
break;
S_StartSound(NULL,sfx_menu1);
replayquerypos--;
replayqueryinput[replayquerypos] = 0;
S_StartSound(NULL,sfx_menu1);
// Restart search only if we actually modified input and not just moved in it
if (memcmp(tmp, replayqueryinput_buffer, MAXREPLAYQUERY+1))
{
preparefilemenu(false, true);
dir_on[menudepthleft] = 0;
PrepReplayList(false);
}
return true;
default:
if (choice < 32 || choice > 127)
break;
if (replayquerypos < MAXREPLAYQUERY)
{
S_StartSound(NULL,sfx_menu1);
replayqueryinput[replayquerypos] = choice;
replayqueryinput[replayquerypos+1] = 0;
++replayquerypos;
preparefilemenu(false, true);
dir_on[menudepthleft] = 0;
PrepReplayList(false);
}
return true;
return true;
}
return false;
@@ -7351,15 +7333,11 @@ static void M_DrawReplayHut(void)
// Draw search query
M_DrawTextBoxFlags(x, 200 - 22, MAXREPLAYQUERY, 1, V_SNAPTOBOTTOM);
if (replayquerypos)
V_DrawString(x + 8, 200 - 14, V_ALLOWLOWERCASE|V_SNAPTOBOTTOM, replayqueryinput);
if (replayqueryinput.length)
M_DrawTextInput(x + 8, 200 - 14, &replayqueryinput, V_SNAPTOBOTTOM);
else
V_DrawString(x + 8, 200 - 14, V_ALLOWLOWERCASE|V_SNAPTOBOTTOM, "\x86Type to search...");
// draw text cursor for name
if (replayquerypos && skullAnimCounter < 4) // blink cursor
V_DrawCharacter(x + 8 + V_StringWidth(replayqueryinput, V_ALLOWLOWERCASE), 200 - 14, '_'|V_SNAPTOBOTTOM, false);
if (replaynamesloaded && replayquerycheck < sizedirmenu)
V_DrawString(x + 8, 200 - 30, V_ALLOWLOWERCASE|V_SNAPTOBOTTOM, va("Searching %u/%u...", (unsigned)replayquerycheck, (unsigned)sizedirmenu));
}
@@ -8937,9 +8915,11 @@ void M_DrawTimeAttackMenu(void)
if (currentMenu->menuitems[i].status & IT_CV_STRING)
{
M_DrawTextBox(x + 32, y - 8, MAXPLAYERNAME, 1);
V_DrawString(x + 40, y, V_ALLOWLOWERCASE, cv->string);
if (itemOn == i && skullAnimCounter < 4) // blink cursor
V_DrawCharacter(x + 40 + V_StringWidth(cv->string, V_ALLOWLOWERCASE), y, '_',false);
if (itemOn != i)
V_DrawString(x + 40, y, V_ALLOWLOWERCASE, cv->string);
else
M_DrawTextInput(x + 40, y, &menuinput, 0);
}
else
{
@@ -10011,16 +9991,19 @@ static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade)
patch_t *PictureOfLevel;
INT32 x, y, w, i, oldval, trans, dupadjust = ((vid.width/vid.dupx) - BASEVIDWIDTH)>>1;
char encoretoggle[32] = {0};
const char *item1 = gamecontrol[gc_fire][0] != 0 ? G_KeynumToString(gamecontrol[gc_fire][0]) : NULL;
const char *item2 = gamecontrol[gc_fire][1] != 0 ? G_KeynumToString(gamecontrol[gc_fire][1]) : NULL;
if (levellistmode != LLM_RECORDATTACK) // so it doesent show in record attack menu
{
char encoretoggle[32] = {0};
const char *item1 = gamecontrol[gc_fire][0] != 0 ? G_KeynumToString(gamecontrol[gc_fire][0]) : NULL;
const char *item2 = gamecontrol[gc_fire][1] != 0 ? G_KeynumToString(gamecontrol[gc_fire][1]) : NULL;
if (item1 != NULL && item2 != NULL)
snprintf(encoretoggle, 32, "%s/%s: Toggle Encore", item1, item2);
else
snprintf(encoretoggle, 32, "%s: Toggle Encore", item1 != NULL ? item1 : item2 != NULL ? item2 : "Item");
if (item1 != NULL && item2 != NULL)
snprintf(encoretoggle, 32, "%s/%s: Toggle Encore", item1, item2);
else
snprintf(encoretoggle, 32, "%s: Toggle Encore", item1 != NULL ? item1 : item2 != NULL ? item2 : "Item");
V_DrawThinString(1, BASEVIDHEIGHT-8-1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_TRANSLUCENT|V_ALLOWLOWERCASE, encoretoggle);
V_DrawThinString(1, BASEVIDHEIGHT-8-1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_TRANSLUCENT|V_ALLOWLOWERCASE, encoretoggle);
}
// A 160x100 image of the level as entry MAPxxP
if (cv_nextmap.value)
@@ -10216,7 +10199,19 @@ static void M_StartServerMenu(INT32 choice)
// ==============
static char setupm_ip[28];
static textinput_t setupm_input_ip;
#endif
void M_Multiplayer(INT32 choice)
{
(void)choice;
#ifndef NONET
memset(setupm_ip, 0, 28);
M_TextInputInit(&setupm_input_ip, setupm_ip, 28);
#endif
M_SetupNextMenu(&MP_MainDef);
}
static UINT8 setupm_pselect = 1;
// Draw the funky Connect IP menu. Tails 11-19-2002
@@ -10250,12 +10245,10 @@ Update the maxplayers label...
V_DrawFill(x+5, y+4+5, /*16*8 + 6,*/ BASEVIDWIDTH - 2*(x+5), 8+6, 239);
// draw name string
V_DrawString(x+8,y+12, V_ALLOWLOWERCASE, setupm_ip);
// draw text cursor for name
if (itemOn == 9
&& skullAnimCounter < 4) //blink cursor
V_DrawCharacter(x+8+V_StringWidth(setupm_ip, V_ALLOWLOWERCASE),y+12,'_',false);
if (itemOn != 9)
V_DrawString(x+8,y+12, V_ALLOWLOWERCASE, setupm_ip);
else
M_DrawTextInput(x+8, y+12, &setupm_input_ip, 0);
#endif
// character bar, ripped off the color bar :V
@@ -10443,7 +10436,6 @@ static void M_ConnectLastServer(INT32 choice)
// Tails 11-19-2002
static void M_HandleConnectIP(INT32 choice)
{
size_t l;
boolean exitmenu = false; // exit to previous menu and send name change
switch (choice)
@@ -10468,41 +10460,21 @@ static void M_HandleConnectIP(INT32 choice)
exitmenu = true;
break;
case KEY_LEFTARROW:
case KEY_RIGHTARROW:
case KEY_BACKSPACE:
if ((l = strlen(setupm_ip)) != 0)
{
S_StartSound(NULL,sfx_menu1); // Tails
setupm_ip[l-1] = 0;
}
break;
case KEY_DEL:
if (setupm_ip[0])
{
if (M_TextInputHandle(&setupm_input_ip, choice))
S_StartSound(NULL,sfx_menu1); // Tails
setupm_ip[0] = 0;
}
break;
default:
l = strlen(setupm_ip);
if (l >= 28-1)
break;
// Rudimentary number and period enforcing - also allows letters so hostnames can be used instead
if ((choice >= '-' && choice <= ':') || (choice >= 'A' && choice <= 'Z') || (choice >= 'a' && choice <= 'z'))
if ((choice >= '-' && choice <= ':') || (choice >= 'A' && choice <= 'Z') || (choice >= 'a' && choice <= 'z')
|| (choice >= 199 && choice <= 211 && choice != 202 && choice != 206)) //numpad too!
{
S_StartSound(NULL,sfx_menu1); // Tails
setupm_ip[l] = (char)choice;
setupm_ip[l+1] = 0;
}
else if (choice >= 199 && choice <= 211 && choice != 202 && choice != 206) //numpad too!
{
char keypad_translation[] = {'7','8','9','-','4','5','6','+','1','2','3','0','.'};
choice = keypad_translation[choice - 199];
S_StartSound(NULL,sfx_menu1); // Tails
setupm_ip[l] = (char)choice;
setupm_ip[l+1] = 0;
if (M_TextInputHandle(&setupm_input_ip, choice))
S_StartSound(NULL,sfx_menu1); // Tails
}
break;
}
@@ -10527,14 +10499,15 @@ static state_t *multi_state;
// this is set before entering the MultiPlayer setup menu,
// for either player 1 or 2
static char setupm_name[MAXPLAYERNAME+1];
static player_t *setupm_player;
static consvar_t *setupm_cvskin;
static consvar_t *setupm_cvcolor;
static consvar_t *setupm_cvname;
static UINT8 setupm_skinxpos;
static INT32 setupm_fakeskin;
static INT32 setupm_fakecolor;
static char setupm_name[MAXPLAYERNAME+1];
static textinput_t setupm_input;
static player_t *setupm_player;
static consvar_t *setupm_cvskin;
static consvar_t *setupm_cvcolor;
static consvar_t *setupm_cvname;
static UINT8 setupm_skinxpos;
static INT32 setupm_fakeskin;
static INT32 setupm_fakecolor;
//variables used for other skin select menus
static UINT8 setupm_skinypos;
@@ -10610,11 +10583,11 @@ static void M_DrawSetupMultiPlayerMenu(void)
}
M_DrawTextBox(mx + 32, my - 8 + nameboxaddy, MAXPLAYERNAME, 1);
V_DrawString(mx + 40, my + nameboxaddy, V_ALLOWLOWERCASE, setupm_name);
// draw text cursor for name
if (!itemOn && skullAnimCounter < 4) // blink cursor
V_DrawCharacter(mx + 40 + V_StringWidth(setupm_name, V_ALLOWLOWERCASE), my + nameboxaddy, '_', false);
if (itemOn != 0)
V_DrawString(mx + 40, my + nameboxaddy, V_ALLOWLOWERCASE, setupm_input.buffer);
else
M_DrawTextInput(mx + 40, my + nameboxaddy, &setupm_input, 0);
// draw skin string
st = V_StringWidth(skins[setupm_fakeskin].realname, 0);
@@ -11213,7 +11186,6 @@ static void M_DrawSetupMultiPlayerMenu(void)
// Handle 1P/2P MP Setup
static void M_HandleSetupMultiPlayer(INT32 choice)
{
size_t l;
boolean exitmenu = false; // exit to previous menu and send name change
if ((choice == gamecontrol[gc_fire][0] || choice == gamecontrol[gc_fire][1]) && itemOn == 2)
@@ -11335,7 +11307,12 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
break;
case KEY_LEFTARROW:
if (cv_skinselectmenu.value == SKINMENUTYPE_2D && itemOn == 1)
if (itemOn == 0)
{
M_TextInputHandle(&setupm_input, choice);
S_StartSound(NULL,sfx_menu1); // Tails
}
else if (cv_skinselectmenu.value == SKINMENUTYPE_2D && itemOn == 1)
{
if (setupm_skinlockedselect)
{
@@ -11389,7 +11366,12 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
break;
case KEY_RIGHTARROW:
if (cv_skinselectmenu.value == SKINMENUTYPE_2D && itemOn == 1)
if (itemOn == 0)
{
M_TextInputHandle(&setupm_input, choice);
S_StartSound(NULL,sfx_menu1); // Tails
}
else if (cv_skinselectmenu.value == SKINMENUTYPE_2D && itemOn == 1)
{
if (setupm_skinlockedselect)
{
@@ -11420,7 +11402,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
}
else if (cv_skinselectmenu.value == SKINMENUTYPE_EXTENDED){
if (setupm_skinselect >= ((setupm_skinypos-1)+SKINGRIDHEIGHT)*8+24 && setupm_skinypos < (ROUNDSKINSUPTO8/8)-SKINGRIDHEIGHT+24)
setupm_skinypos++;
setupm_skinypos++;
}
}
else
@@ -11458,11 +11440,8 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
BREAKWHENLOCKED
if (itemOn == 0)
{
if ((l = strlen(setupm_name))!=0)
{
S_StartSound(NULL,sfx_menu1); // Tails
setupm_name[l-1] =0;
}
M_TextInputHandle(&setupm_input, choice);
S_StartSound(NULL,sfx_menu1); // Tails
}
else if ((cv_skinselectmenu.value == SKINMENUTYPE_GRID || cv_skinselectmenu.value == SKINMENUTYPE_EXTENDED) && itemOn == 1)
{
@@ -11487,10 +11466,10 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
case KEY_DEL:
if (cv_skinselectmenu.value)
BREAKWHENLOCKED
if (itemOn == 0 && (l = strlen(setupm_name))!=0)
if (itemOn == 0)
{
M_TextInputHandle(&setupm_input, choice);
S_StartSound(NULL,sfx_menu1); // Tails
setupm_name[0] = 0;
}
break;
@@ -11527,17 +11506,10 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
break;
default:
if (choice < 32 || choice > 127)
break;
if (itemOn == 0)
{
l = strlen(setupm_name);
if (l < MAXPLAYERNAME)
{
if (M_TextInputHandle(&setupm_input, choice))
S_StartSound(NULL,sfx_menu1); // Tails
setupm_name[l] =(char)choice;
setupm_name[l+1] =0;
}
}
break;
}
@@ -11602,7 +11574,9 @@ static void M_SetupMultiPlayer(INT32 choice)
multi_state = cv_skinselectspin.value == SKINSELECTSPIN_PAIN ? &states[S_KART_PAIN] : &states[mobjinfo[MT_PLAYER].seestate];
multi_tics = multi_state->tics*FRACUNIT;
strcpy(setupm_name, cv_playername.string);
M_TextInputInit(&setupm_input, setupm_name, sizeof(setupm_name));
M_TextInputSetString(&setupm_input, cv_playername.string);
// set for player 1
setupm_player = &players[consoleplayer];
@@ -11644,7 +11618,9 @@ static void M_SetupMultiPlayer2(INT32 choice)
multi_state = cv_skinselectspin.value == SKINSELECTSPIN_PAIN ? &states[S_KART_PAIN] : &states[mobjinfo[MT_PLAYER].seestate];
multi_tics = multi_state->tics*FRACUNIT;
strcpy (setupm_name, cv_playername2.string);
M_TextInputInit(&setupm_input, setupm_name, sizeof(setupm_name));
M_TextInputSetString(&setupm_input, cv_playername2.string);
// set for splitscreen secondary player
setupm_player = &players[displayplayers[1]];
@@ -11685,7 +11661,9 @@ static void M_SetupMultiPlayer3(INT32 choice)
multi_state = cv_skinselectspin.value == SKINSELECTSPIN_PAIN ? &states[S_KART_PAIN] : &states[mobjinfo[MT_PLAYER].seestate];
multi_tics = multi_state->tics;
strcpy(setupm_name, cv_playername3.string);
M_TextInputInit(&setupm_input, setupm_name, sizeof(setupm_name));
M_TextInputSetString(&setupm_input, cv_playername3.string);
// set for splitscreen third player
setupm_player = &players[displayplayers[2]];
@@ -11726,7 +11704,9 @@ static void M_SetupMultiPlayer4(INT32 choice)
multi_state = cv_skinselectspin.value == SKINSELECTSPIN_PAIN ? &states[S_KART_PAIN] : &states[mobjinfo[MT_PLAYER].seestate];
multi_tics = multi_state->tics;
strcpy(setupm_name, cv_playername4.string);
M_TextInputInit(&setupm_input, setupm_name, sizeof(setupm_name));
M_TextInputSetString(&setupm_input, cv_playername4.string);
// set for splitscreen fourth player
setupm_player = &players[displayplayers[3]];
@@ -11753,7 +11733,7 @@ static void M_SetupMultiPlayer4(INT32 choice)
//change the y offsets of the menu depending on cvar settings
SKINSELECTMENUEDIT
sortSkinGrid();
MP_PlayerSetupDef.prevMenu = currentMenu;
@@ -12910,10 +12890,12 @@ static void M_DrawColorMenu(void)
if (y + 12 > (currentMenu->y + 2*scrollareaheight))
break;
M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1);
V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string);
if (skullAnimCounter < 4 && i == itemOn)
V_DrawCharacter(x + 8 + V_StringWidth(cv->string, 0), y + 12,
'_' | 0x80, false);
if (itemOn == i)
M_DrawTextInput(x + 8, y + 12, &menuinput, 0);
else
V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string);
y += 16;
break;
default:
+4
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);
-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)
+9 -1
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}
@@ -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++;
}
+303
View File
@@ -0,0 +1,303 @@
#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;
}
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 ((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')
{
const char *paste = I_ClipboardPaste();
if (input->select != input->cursor)
M_TextInputDelSelection(input);
if (paste != NULL)
M_TextInputAddString(input, paste);
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
+1 -2
View File
@@ -2564,8 +2564,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
+22 -3
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);
@@ -392,6 +399,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
//
+66 -84
View File
@@ -592,7 +592,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 +608,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 +622,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 +669,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 +685,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 +699,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 +748,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 +764,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 +778,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 +826,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 +842,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 +856,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]
@@ -6034,7 +6038,7 @@ void P_RollPitchMobj(mobj_t* mobj)
if (cv_sloperolldist.value > 0)
usedist = true;
if ((cv_spriteroll.value) && (cv_sloperoll.value == 2))
if (cv_spriteroll.value && cv_sloperoll.value == 2)
{
K_RollMobjBySlopes(mobj, usedist);
}
@@ -6260,7 +6264,7 @@ void P_MobjThinker(mobj_t *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;
@@ -10136,13 +10140,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 +10202,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 +10216,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 +10235,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;
}
}
}
@@ -10395,10 +10380,7 @@ void P_PrecipitationEffects(void)
volume = 255 - (closedist>>(FRACBITS+2));
}
if (volume < 0)
volume = 0;
else if (volume > 255)
volume = 255;
volume = CLAMP(volume, 0, 255);
if (sounds_rain && (!leveltime || leveltime % 80 == 1))
S_StartSoundAtVolume(players[displayplayers[0]].mo, sfx_rainin, volume);
+6 -6
View File
@@ -266,15 +266,15 @@ 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
@@ -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
+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);
}
}
+60 -2
View File
@@ -2487,6 +2487,61 @@ 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];
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.
@@ -2628,7 +2683,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 +2793,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 +3005,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 -23
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!
@@ -583,24 +619,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 +683,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 +700,6 @@ void P_Ticker(boolean run)
if (demo.playback)
G_StoreRewindInfo();
// Z_CheckMemCleanup();
}
// Abbreviated ticker for pre-loading, calls thinkers and assorted things
+12 -17
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))
{
+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
+3 -4
View File
@@ -28,7 +28,7 @@ side_t *sidedef;
line_t *linedef;
sector_t *frontsector;
sector_t *backsector;
boolean portalline; // is curline a portal seg?
portal_pair *g_portal; // 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 +417,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;
@@ -1333,8 +1333,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;
}
+3 -1
View File
@@ -18,12 +18,14 @@
#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?
extern portal_pair *g_portal; // is curline a portal seg?
// drawsegs are allocated on the fly... see r_segs.c
+168 -243
View File
@@ -94,12 +94,16 @@ void R_DrawColumn_8(void)
*dest = colormap[source[(frac>>FRACBITS) & heightmask]];
dest += vid.width;
frac += fracstep;
*dest = colormap[source[(frac>>FRACBITS) & heightmask]];
dest += vid.width;
frac += fracstep;
}
if (count & 1)
{
*dest = colormap[source[(frac>>FRACBITS) & heightmask]];
}
}
}
}
@@ -162,7 +166,9 @@ void R_Draw2sMultiPatchColumn_8(void)
val = source[frac>>FRACBITS];
if (val != TRANSPARENTPIXEL)
{
*dest = colormap[val];
}
dest += vid.width;
@@ -182,20 +188,30 @@ void R_Draw2sMultiPatchColumn_8(void)
{
val = source[(frac>>FRACBITS) & heightmask];
if (val != TRANSPARENTPIXEL)
{
*dest = colormap[val];
}
dest += vid.width;
frac += fracstep;
val = source[(frac>>FRACBITS) & heightmask];
if (val != TRANSPARENTPIXEL)
{
*dest = colormap[val];
}
dest += vid.width;
frac += fracstep;
}
if (count & 1)
{
val = source[(frac>>FRACBITS) & heightmask];
if (val != TRANSPARENTPIXEL)
{
*dest = colormap[val];
}
}
}
}
@@ -259,7 +275,9 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void)
val = source[frac>>FRACBITS];
if (val != TRANSPARENTPIXEL)
{
*dest = *(transmap + (colormap[val]<<8) + (*dest));
}
dest += vid.width;
@@ -279,20 +297,30 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void)
{
val = source[(frac>>FRACBITS) & heightmask];
if (val != TRANSPARENTPIXEL)
{
*dest = *(transmap + (colormap[val]<<8) + (*dest));
}
dest += vid.width;
frac += fracstep;
val = source[(frac>>FRACBITS) & heightmask];
if (val != TRANSPARENTPIXEL)
{
*dest = *(transmap + (colormap[val]<<8) + (*dest));
}
dest += vid.width;
frac += fracstep;
}
if (count & 1)
{
val = source[(frac>>FRACBITS) & heightmask];
if (val != TRANSPARENTPIXEL)
{
*dest = *(transmap + (colormap[val]<<8) + (*dest));
}
}
}
}
@@ -394,6 +422,7 @@ void R_DrawTranslucentColumn_8(void)
// heightmask is the Tutti-Frutti fix
*dest = *(transmap + (colormap[source[frac>>FRACBITS]]<<8) + (*dest));
dest += vid.width;
if ((frac += fracstep) >= heightmask)
frac -= heightmask;
}
@@ -406,12 +435,16 @@ void R_DrawTranslucentColumn_8(void)
*dest = *(transmap + (colormap[source[(frac>>FRACBITS)&heightmask]]<<8) + (*dest));
dest += vid.width;
frac += fracstep;
*dest = *(transmap + (colormap[source[(frac>>FRACBITS)&heightmask]]<<8) + (*dest));
dest += vid.width;
frac += fracstep;
}
if (count & 1)
{
*dest = *(transmap + (colormap[source[(frac>>FRACBITS)&heightmask]]<<8) + (*dest));
}
}
}
}
@@ -461,10 +494,9 @@ void R_DrawTranslatedTranslucentColumn_8(void)
// Re-map color indices from wall texture column
// using a lighting/special effects LUT.
// heightmask is the Tutti-Frutti fix
*dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]<<8) + (*dest));
dest += vid.width;
if ((frac += fracstep) >= heightmask)
frac -= heightmask;
}
@@ -477,12 +509,16 @@ void R_DrawTranslatedTranslucentColumn_8(void)
*dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest));
dest += vid.width;
frac += fracstep;
*dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest));
dest += vid.width;
frac += fracstep;
}
if (count & 1)
{
*dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest));
}
}
}
}
@@ -536,6 +572,12 @@ void R_DrawTranslatedColumn_8(void)
// SPANS
// ==========================================================================
#define SPANSIZE 16
#define INVSPAN 0.0625f
// <Callum> 4194303 = (2048x2048)-1 (2048x2048 is maximum flat size)
#define MAXFLATBYTES 4194303
/** \brief The R_DrawSpan_8 function
Draws the actual span.
*/
@@ -544,6 +586,7 @@ void R_DrawSpan_8 (void)
fixed_t xposition;
fixed_t yposition;
fixed_t xstep, ystep;
UINT32 bit;
UINT8 *source;
UINT8 *colormap;
@@ -551,6 +594,7 @@ void R_DrawSpan_8 (void)
const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height;
size_t count = (ds_x2 - ds_x1 + 1);
size_t i;
xposition = ds_xfrac; yposition = ds_yfrac;
xstep = ds_xstep; ystep = ds_ystep;
@@ -577,44 +621,23 @@ void R_DrawSpan_8 (void)
// SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't
// have the uber complicated math to calculate it now, so that was a memory write we didn't
// need!
dest[0] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]];
xposition += xstep;
yposition += ystep;
for (i = 0; i < 8; i++)
{
bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift);
dest[i] = colormap[source[bit]];
dest[1] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]];
xposition += xstep;
yposition += ystep;
dest[2] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]];
xposition += xstep;
yposition += ystep;
dest[3] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]];
xposition += xstep;
yposition += ystep;
dest[4] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]];
xposition += xstep;
yposition += ystep;
dest[5] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]];
xposition += xstep;
yposition += ystep;
dest[6] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]];
xposition += xstep;
yposition += ystep;
dest[7] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]];
xposition += xstep;
yposition += ystep;
xposition += xstep;
yposition += ystep;
}
dest += 8;
count -= 8;
}
while (count-- && dest <= deststop)
{
*dest++ = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]];
bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift);
*dest++ = colormap[source[bit]];
xposition += xstep;
yposition += ystep;
}
@@ -664,6 +687,7 @@ void R_DrawTiltedSpan_8(void)
double izstep, uzstep, vzstep;
double endz, endu, endv;
UINT32 stepu, stepv;
UINT32 bit;
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
@@ -683,6 +707,7 @@ void R_DrawTiltedSpan_8(void)
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1];
source = ds_source;
//colormap = ds_colormap;
@@ -695,18 +720,16 @@ void R_DrawTiltedSpan_8(void)
u = (INT64)(uz*z) + viewx;
v = (INT64)(vz*z) + viewy;
bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[source[bit]];
*dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
dest++;
iz += ds_szp->x;
uz += ds_sup->x;
vz += ds_svp->x;
} while (--width >= 0);
#else
#define SPANSIZE 16
#define INVSPAN 0.0625f
startz = 1.f/iz;
startu = uz*startz;
startv = vz*startz;
@@ -733,8 +756,10 @@ void R_DrawTiltedSpan_8(void)
for (i = SPANSIZE-1; i >= 0; i--)
{
bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
*dest = colormap[source[bit]];
dest++;
u += stepu;
v += stepv;
@@ -749,8 +774,9 @@ void R_DrawTiltedSpan_8(void)
{
u = (INT64)(startu);
v = (INT64)(startv);
bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
*dest = colormap[source[bit]];
}
else
{
@@ -770,8 +796,10 @@ void R_DrawTiltedSpan_8(void)
for (; width != 0; width--)
{
bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
*dest = colormap[source[bit]];
dest++;
u += stepu;
v += stepv;
@@ -800,6 +828,7 @@ void R_DrawTiltedTranslucentSpan_8(void)
double izstep, uzstep, vzstep;
double endz, endu, endv;
UINT32 stepu, stepv;
UINT32 bit;
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
@@ -819,6 +848,7 @@ void R_DrawTiltedTranslucentSpan_8(void)
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1];
source = ds_source;
//colormap = ds_colormap;
@@ -831,17 +861,16 @@ void R_DrawTiltedTranslucentSpan_8(void)
u = (INT64)(uz*z) + viewx;
v = (INT64)(vz*z) + viewy;
bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest);
*dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dest);
dest++;
iz += ds_szp->x;
uz += ds_sup->x;
vz += ds_svp->x;
} while (--width >= 0);
#else
#define SPANSIZE 16
#define INVSPAN 0.0625f
startz = 1.f/iz;
startu = uz*startz;
startv = vz*startz;
@@ -868,8 +897,10 @@ void R_DrawTiltedTranslucentSpan_8(void)
for (i = SPANSIZE-1; i >= 0; i--)
{
bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest);
*dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dest);
dest++;
u += stepu;
v += stepv;
@@ -884,8 +915,9 @@ void R_DrawTiltedTranslucentSpan_8(void)
{
u = (INT64)(startu);
v = (INT64)(startv);
bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest);
*dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dest);
}
else
{
@@ -905,8 +937,10 @@ void R_DrawTiltedTranslucentSpan_8(void)
for (; width != 0; width--)
{
bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest);
*dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dest);
dest++;
u += stepu;
v += stepv;
@@ -937,6 +971,7 @@ void R_DrawTiltedTranslucentWaterSpan_8(void)
double izstep, uzstep, vzstep;
double endz, endu, endv;
UINT32 stepu, stepv;
UINT32 bit;
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
@@ -957,6 +992,7 @@ void R_DrawTiltedTranslucentWaterSpan_8(void)
dest = ylookup[ds_y] + columnofs[ds_x1];
dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1;
source = ds_source;
//colormap = ds_colormap;
@@ -969,17 +1005,16 @@ void R_DrawTiltedTranslucentWaterSpan_8(void)
u = (INT64)(uz*z) + viewx;
v = (INT64)(vz*z) + viewy;
bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dsrc++);
*dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dsrc++);
dest++;
iz += ds_szp->x;
uz += ds_sup->x;
vz += ds_svp->x;
} while (--width >= 0);
#else
#define SPANSIZE 16
#define INVSPAN 0.0625f
startz = 1.f/iz;
startu = uz*startz;
startv = vz*startz;
@@ -1006,8 +1041,10 @@ void R_DrawTiltedTranslucentWaterSpan_8(void)
for (i = SPANSIZE-1; i >= 0; i--)
{
bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dsrc++);
*dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dsrc++);
dest++;
u += stepu;
v += stepv;
@@ -1022,8 +1059,9 @@ void R_DrawTiltedTranslucentWaterSpan_8(void)
{
u = (INT64)(startu);
v = (INT64)(startv);
bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dsrc++);
*dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dsrc++);
}
else
{
@@ -1043,8 +1081,10 @@ void R_DrawTiltedTranslucentWaterSpan_8(void)
for (; width != 0; width--)
{
bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dsrc++);
*dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dsrc++);
dest++;
u += stepu;
v += stepv;
@@ -1073,6 +1113,7 @@ void R_DrawTiltedSplat_8(void)
double izstep, uzstep, vzstep;
double endz, endu, endv;
UINT32 stepu, stepv;
UINT32 bit;
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
@@ -1092,6 +1133,7 @@ void R_DrawTiltedSplat_8(void)
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1];
source = ds_source;
//colormap = ds_colormap;
@@ -1104,20 +1146,20 @@ void R_DrawTiltedSplat_8(void)
u = (INT64)(uz*z) + viewx;
v = (INT64)(vz*z) + viewy;
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift);
val = source[bit];
val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[val];
}
dest++;
iz += ds_szp->x;
uz += ds_sup->x;
vz += ds_svp->x;
} while (--width >= 0);
#else
#define SPANSIZE 16
#define INVSPAN 0.0625f
startz = 1.f/iz;
startu = uz*startz;
startv = vz*startz;
@@ -1144,10 +1186,13 @@ void R_DrawTiltedSplat_8(void)
for (i = SPANSIZE-1; i >= 0; i--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift);
val = source[bit];
if (val != TRANSPARENTPIXEL)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[val];
}
dest++;
u += stepu;
v += stepv;
@@ -1162,10 +1207,13 @@ void R_DrawTiltedSplat_8(void)
{
u = (INT64)(startu);
v = (INT64)(startv);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift);
val = source[bit];
if (val != TRANSPARENTPIXEL)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[val];
}
}
else
{
@@ -1185,10 +1233,13 @@ void R_DrawTiltedSplat_8(void)
for (; width != 0; width--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift);
val = source[bit];
if (val != TRANSPARENTPIXEL)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[val];
}
dest++;
u += stepu;
v += stepv;
@@ -1206,12 +1257,14 @@ void R_DrawSplat_8 (void)
UINT32 xposition;
UINT32 yposition;
UINT32 xstep, ystep;
UINT32 bit;
UINT8 *source;
UINT8 *colormap;
UINT8 *dest;
size_t count;
size_t i;
UINT32 val;
// SoM: we only need 6 bits for the integer part (0 thru 63) so the rest
@@ -1236,80 +1289,29 @@ void R_DrawSplat_8 (void)
// need!
//
// <Callum> 4194303 = (2048x2048)-1 (2048x2048 is maximum flat size)
val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift);
val &= 4194303;
val = source[val];
if (val != TRANSPARENTPIXEL)
dest[0] = colormap[val];
xposition += xstep;
yposition += ystep;
for (i = 0; i < 8; i++)
{
bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift);
bit &= MAXFLATBYTES;
val = source[bit];
if (val != TRANSPARENTPIXEL)
dest[i] = colormap[val];
val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift);
val &= 4194303;
val = source[val];
if (val != TRANSPARENTPIXEL)
dest[1] = colormap[val];
xposition += xstep;
yposition += ystep;
val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift);
val &= 4194303;
val = source[val];
if (val != TRANSPARENTPIXEL)
dest[2] = colormap[val];
xposition += xstep;
yposition += ystep;
val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift);
val &= 4194303;
val = source[val];
if (val != TRANSPARENTPIXEL)
dest[3] = colormap[val];
xposition += xstep;
yposition += ystep;
val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift);
val &= 4194303;
val = source[val];
if (val != TRANSPARENTPIXEL)
dest[4] = colormap[val];
xposition += xstep;
yposition += ystep;
val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift);
val &= 4194303;
val = source[val];
if (val != TRANSPARENTPIXEL)
dest[5] = colormap[val];
xposition += xstep;
yposition += ystep;
val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift);
val &= 4194303;
val = source[val];
if (val != TRANSPARENTPIXEL)
dest[6] = colormap[val];
xposition += xstep;
yposition += ystep;
val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift);
val &= 4194303;
val = source[val];
if (val != TRANSPARENTPIXEL)
dest[7] = colormap[val];
xposition += xstep;
yposition += ystep;
xposition += xstep;
yposition += ystep;
}
dest += 8;
count -= 8;
}
while (count--)
{
val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift);
val &= 4194303;
val = source[val];
bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift);
val = source[bit];
if (val != TRANSPARENTPIXEL)
{
*dest = colormap[val];
}
dest++;
xposition += xstep;
@@ -1325,12 +1327,14 @@ void R_DrawTranslucentSplat_8 (void)
UINT32 xposition;
UINT32 yposition;
UINT32 xstep, ystep;
UINT32 bit;
UINT8 *source;
UINT8 *colormap;
UINT8 *dest;
size_t count;
size_t i;
UINT8 val;
// SoM: we only need 6 bits for the integer part (0 thru 63) so the rest
@@ -1353,60 +1357,24 @@ void R_DrawTranslucentSplat_8 (void)
// SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't
// have the uber complicated math to calculate it now, so that was a memory write we didn't
// need!
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
dest[0] = *(ds_transmap + (colormap[val] << 8) + dest[0]);
xposition += xstep;
yposition += ystep;
for (i = 0; i < 8; i++)
{
bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift);
val = source[bit];
if (val != TRANSPARENTPIXEL)
dest[i] = *(ds_transmap + (colormap[val] << 8) + dest[i]);
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
dest[1] = *(ds_transmap + (colormap[val] << 8) + dest[1]);
xposition += xstep;
yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
dest[2] = *(ds_transmap + (colormap[val] << 8) + dest[2]);
xposition += xstep;
yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
dest[3] = *(ds_transmap + (colormap[val] << 8) + dest[3]);
xposition += xstep;
yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
dest[4] = *(ds_transmap + (colormap[val] << 8) + dest[4]);
xposition += xstep;
yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
dest[5] = *(ds_transmap + (colormap[val] << 8) + dest[5]);
xposition += xstep;
yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
dest[6] = *(ds_transmap + (colormap[val] << 8) + dest[6]);
xposition += xstep;
yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
dest[7] = *(ds_transmap + (colormap[val] << 8) + dest[7]);
xposition += xstep;
yposition += ystep;
xposition += xstep;
yposition += ystep;
}
dest += 8;
count -= 8;
}
while (count--)
{
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift);
val = source[bit];
if (val != TRANSPARENTPIXEL)
*dest = *(ds_transmap + (colormap[val] << 8) + *dest);
@@ -1424,6 +1392,7 @@ void R_DrawTranslucentSpan_8 (void)
fixed_t xposition;
fixed_t yposition;
fixed_t xstep, ystep;
UINT32 bit;
UINT8 *source;
UINT8 *colormap;
@@ -1431,7 +1400,7 @@ void R_DrawTranslucentSpan_8 (void)
const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height;
size_t count = (ds_x2 - ds_x1 + 1);
UINT32 val;
size_t i;
xposition = ds_xfrac; yposition = ds_yfrac;
xstep = ds_xstep; ystep = ds_ystep;
@@ -1455,45 +1424,21 @@ void R_DrawTranslucentSpan_8 (void)
// SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't
// have the uber complicated math to calculate it now, so that was a memory write we didn't
// need!
dest[0] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[0]);
xposition += xstep;
yposition += ystep;
dest[1] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[1]);
xposition += xstep;
yposition += ystep;
dest[2] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[2]);
xposition += xstep;
yposition += ystep;
dest[3] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[3]);
xposition += xstep;
yposition += ystep;
dest[4] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[4]);
xposition += xstep;
yposition += ystep;
dest[5] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[5]);
xposition += xstep;
yposition += ystep;
dest[6] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[6]);
xposition += xstep;
yposition += ystep;
dest[7] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[7]);
xposition += xstep;
yposition += ystep;
for (i = 0; i < 8; i++)
{
bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift);
dest[i] = *(ds_transmap + (colormap[source[bit]] << 8) + dest[i]);
xposition += xstep;
yposition += ystep;
}
dest += 8;
count -= 8;
}
while (count-- && dest <= deststop)
{
val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift);
*dest = *(ds_transmap + (colormap[source[val]] << 8) + *dest);
bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift);
*dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dest);
dest++;
xposition += xstep;
yposition += ystep;
@@ -1506,6 +1451,7 @@ void R_DrawTranslucentWaterSpan_8(void)
UINT32 xposition;
UINT32 yposition;
UINT32 xstep, ystep;
UINT32 bit;
UINT8 *source;
UINT8 *colormap;
@@ -1513,6 +1459,7 @@ void R_DrawTranslucentWaterSpan_8(void)
UINT8 *dsrc;
size_t count;
size_t i;
// SoM: we only need 6 bits for the integer part (0 thru 63) so the rest
// can be used for the fraction part. This allows calculation of the memory address in the
@@ -1535,44 +1482,22 @@ void R_DrawTranslucentWaterSpan_8(void)
// SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't
// have the uber complicated math to calculate it now, so that was a memory write we didn't
// need!
dest[0] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)];
xposition += xstep;
yposition += ystep;
dest[1] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)];
xposition += xstep;
yposition += ystep;
dest[2] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)];
xposition += xstep;
yposition += ystep;
dest[3] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)];
xposition += xstep;
yposition += ystep;
dest[4] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)];
xposition += xstep;
yposition += ystep;
dest[5] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)];
xposition += xstep;
yposition += ystep;
dest[6] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)];
xposition += xstep;
yposition += ystep;
dest[7] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)];
xposition += xstep;
yposition += ystep;
for (i = 0; i < 8; i++)
{
bit = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift);
dest[i] = colormap[*(ds_transmap + (source[bit] << 8) + *dsrc++)];
xposition += xstep;
yposition += ystep;
}
dest += 8;
count -= 8;
}
while (count--)
{
*dest++ = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)];
bit = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift);
*dest++ = colormap[*(ds_transmap + (source[bit] << 8) + *dsrc++)];
xposition += xstep;
yposition += ystep;
}
+47 -104
View File
@@ -70,29 +70,12 @@ player_t *viewplayer;
// 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 +156,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 +168,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};
@@ -217,6 +196,8 @@ consvar_t cv_mobjscaleprecip = {"scaleprecipmobjscale", "Off", CV_SAVE|CV_CALL|C
consvar_t cv_grmaxinterpdist = {"gr_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 +253,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();
@@ -516,6 +459,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 +985,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 +1003,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 +1042,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 +1356,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 +1423,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,10 +1501,7 @@ 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
@@ -1653,7 +1594,7 @@ void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2)
portal->start = x1;
portal->end = x2;
portalline = true; // this tells R_StoreWallRange that curline is a portal seg
g_portal = portal; // this tells R_StoreWallRange that curline is a portal seg
portal->viewx = viewx;
portal->viewy = viewy;
@@ -1931,6 +1872,8 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_grmaxinterpdist);
CV_RegisterVar(&cv_ripplewater);
// Default viewheight is changeable,
// initialized to standard viewheight
//CV_RegisterVar(&cv_viewheight);
+26
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
@@ -88,6 +90,27 @@ subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y);
boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixed_t bottomh, fixed_t toph);
void R_GetRenderBlockMapDimensions(fixed_t drawdist, INT32 *xl, INT32 *xh, INT32 *yl, INT32 *yh);
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;
// Performance stats
extern precise_t ps_prevframetime;// time when previous frame was rendered
extern ps_metric_t ps_rendercalltime;
@@ -124,6 +147,7 @@ extern consvar_t cv_fov;
extern consvar_t cv_skybox;
extern consvar_t cv_tailspickup;
extern consvar_t cv_grmaxinterpdist;
extern consvar_t cv_ripplewater;
// Called by startup code.
void R_Init(void);
@@ -150,4 +174,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
+30 -23
View File
@@ -910,34 +910,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
+1 -1
View File
@@ -2840,7 +2840,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;
+12 -14
View File
@@ -609,12 +609,13 @@ 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_texturemid = basetexturemid - (topdelta<<FRACBITS);
@@ -625,6 +626,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,7 +679,7 @@ 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);
for (s = (UINT8 *)column+2+column->length, d = dc_source; d < dc_source+column->length; --s)
@@ -837,22 +842,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
@@ -1987,7 +1985,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;
}
@@ -2450,8 +2448,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)
{
+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);
+29 -12
View File
@@ -366,15 +366,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 +381,6 @@ static precise_t fps_enter = 0;
void SCR_CalculateFPS(void)
{
precise_t fps_finish = 0;
int i;
double frameElapsed = 0.0;
@@ -398,10 +395,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 +408,33 @@ 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;
int i;
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 (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.
+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
+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));
}
/// ------------------------
+82 -16
View File
@@ -155,6 +155,8 @@ static patch_t *envelope;
player_t *stplyr;
UINT8 stplyrnum;
boolean directortextactive = false;
// SRB2kart
hudinfo_t hudinfo[NUMHUDITEMS] =
@@ -662,23 +664,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 +704,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)
{
@@ -799,25 +808,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
+73 -29
View File
@@ -528,7 +528,7 @@ const char *GetPalette(void)
return "PLAYPAL";
}
static void LoadMapPalette(void)
void V_ReloadPalette(void)
{
LoadPalette(GetPalette());
}
@@ -540,7 +540,7 @@ static void LoadMapPalette(void)
void V_SetPalette(INT32 palettenum)
{
if (!pLocalPalette)
LoadMapPalette();
V_ReloadPalette();
#ifdef HWRENDER
if (rendermode == render_opengl)
@@ -575,7 +575,7 @@ static void CV_palette_OnChange(void)
if (loaded_config == false)
return;
// reload palette
LoadMapPalette();
V_ReloadPalette();
V_SetPalette(0);
}
@@ -1611,21 +1611,19 @@ void V_DrawFadeScreen(UINT16 color, UINT8 strength)
}
#endif
{
const UINT8 *fadetable =
(color > 0xFFF0) // Grab a specific colormap palette?
? R_GetTranslationColormap(color | 0xFFFF0000, strength, GTC_CACHE)
: ((color & 0xFF00) // Color is not palette index?
? ((UINT8 *)colormaps + strength*256) // Do COLORMAP fade.
: ((UINT8 *)transtables + ((9-strength)<<FF_TRANSSHIFT) + color*256)); // Else, do TRANSMAP** fade.
const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height;
UINT8 *buf = screens[0];
const UINT8 *fadetable =
(color > 0xFFF0) // Grab a specific colormap palette?
? R_GetTranslationColormap(color | 0xFFFF0000, strength, GTC_CACHE)
: ((color & 0xFF00) // Color is not palette index?
? ((UINT8 *)colormaps + strength*256) // Do COLORMAP fade.
: ((UINT8 *)transtables + ((9-strength)<<FF_TRANSSHIFT) + color*256)); // Else, do TRANSMAP** fade.
const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height;
UINT8 *buf = screens[0];
// heavily simplified -- we don't need to know x or y
// position when we're doing a full screen fade
for (; buf < deststop; ++buf)
*buf = fadetable[*buf];
}
// heavily simplified -- we don't need to know x or y
// position when we're doing a full screen fade
for (; buf < deststop; ++buf)
*buf = fadetable[*buf];
}
// Simple translucency with one color, over a set number of lines starting from the top.
@@ -2845,11 +2843,14 @@ INT32 V_LevelNameHeight(const char *string)
//
// Find string width from hu_font chars
//
INT32 V_StringWidth(const char *string, INT32 option)
INT32 V_SubStringWidth(const char *string, INT32 length, INT32 option)
{
INT32 c, w = 0;
INT32 spacewidth = 4, charwidth = 0;
size_t i;
ssize_t i;
if (length < 0)
length = strlen(string);
switch (option & V_SPACINGMASK)
{
@@ -2865,7 +2866,7 @@ INT32 V_StringWidth(const char *string, INT32 option)
break;
}
for (i = 0; i < strlen(string); i++)
for (i = 0; string[i] && i < length; i++)
{
c = string[i];
if ((UINT8)c >= 0x80 && (UINT8)c <= 0x8F) //color parsing! -Inuyasha 2.16.09
@@ -2884,11 +2885,14 @@ INT32 V_StringWidth(const char *string, INT32 option)
//
// Find string width from hu_font chars, 0.5x scale
//
INT32 V_SmallStringWidth(const char *string, INT32 option)
INT32 V_SmallSubStringWidth(const char *string, INT32 length, INT32 option)
{
INT32 c, w = 0;
INT32 spacewidth = 2, charwidth = 0;
size_t i;
ssize_t i;
if (length < 0)
length = strlen(string);
switch (option & V_SPACINGMASK)
{
@@ -2904,7 +2908,7 @@ INT32 V_SmallStringWidth(const char *string, INT32 option)
break;
}
for (i = 0; i < strlen(string); i++)
for (i = 0; string[i] && i < length; i++)
{
c = string[i];
if ((UINT8)c >= 0x80 && (UINT8)c <= 0x8F) //color parsing! -Inuyasha 2.16.09
@@ -2923,12 +2927,15 @@ INT32 V_SmallStringWidth(const char *string, INT32 option)
//
// Find string width from tny_font chars
//
INT32 V_ThinStringWidth(const char *string, INT32 option)
INT32 V_ThinSubStringWidth(const char *string, INT32 length, INT32 option)
{
INT32 c, w = 0;
INT32 spacewidth = 2, charwidth = 0;
boolean lowercase = (option & V_ALLOWLOWERCASE);
size_t i;
ssize_t i;
if (length < 0)
length = strlen(string);
switch (option & V_SPACINGMASK)
{
@@ -2945,7 +2952,7 @@ INT32 V_ThinStringWidth(const char *string, INT32 option)
break;
}
for (i = 0; i < strlen(string); i++)
for (i = 0; string[i] && i < length; i++)
{
c = string[i];
if ((UINT8)c >= 0x80 && (UINT8)c <= 0x8F) //color parsing! -Inuyasha 2.16.09
@@ -2963,7 +2970,7 @@ INT32 V_ThinStringWidth(const char *string, INT32 option)
else
{
w += (charwidth ? charwidth
: ((option & V_6WIDTHSPACE && i < strlen(string)-1) ? max(1, SHORT(tny_font[c]->width)-1) // Reuse this flag for the alternate bunched-up spacing
: ((option & V_6WIDTHSPACE && i < length-1) ? max(1, SHORT(tny_font[c]->width)-1) // Reuse this flag for the alternate bunched-up spacing
: SHORT(tny_font[c]->width)));
}
}
@@ -2972,6 +2979,45 @@ INT32 V_ThinStringWidth(const char *string, INT32 option)
return w;
}
//
// Find maximum length for substring taken from current string to fit into given width
//
INT32 V_SubStringLengthToFit(const char *string, INT32 width, INT32 option)
{
INT32 c, w = 0;
INT32 spacewidth = 4, charwidth = 0;
INT32 i;
switch (option & V_SPACINGMASK)
{
case V_MONOSPACE:
spacewidth = 8;
/* FALLTHRU */
case V_OLDSPACING:
charwidth = 8;
break;
case V_6WIDTHSPACE:
spacewidth = 6;
default:
break;
}
for (i = 0; string[i] && w < width; i++)
{
c = string[i];
if ((UINT8)c >= 0x80 && (UINT8)c <= 0x8F) //color parsing! -Inuyasha 2.16.09
continue;
c = toupper(c) - HU_FONTSTART;
if (c < 0 || c >= HU_FONTSIZE || !hu_font[c])
w += spacewidth;
else
w += (charwidth ? charwidth : SHORT(hu_font[c]->width));
}
return max(i-1, 0);
}
char V_GetSkincolorChar(INT32 color)
{
char cstart = 0x80;
@@ -3373,8 +3419,6 @@ void V_Init(void)
UINT8 *base = vid.buffer;
const INT32 screensize = vid.rowbytes * vid.height;
LoadMapPalette();
for (i = 0; i < NUMSCREENS; i++)
screens[i] = NULL;
+12 -3
View File
@@ -49,6 +49,9 @@ extern UINT8 colorlookup[CLUTSIZE][CLUTSIZE][CLUTSIZE];
void InitColorLUT(void);
// Loads the correct palette into memory
void V_ReloadPalette(void);
// Set the current RGB palette lookup to use for palettized graphics
void V_SetPalette(INT32 palettenum);
@@ -234,11 +237,17 @@ void V_DrawCreditString(fixed_t x, fixed_t y, INT32 option, const char *string);
INT32 V_CreditStringWidth(const char *string);
// Find string width from hu_font chars
INT32 V_StringWidth(const char *string, INT32 option);
INT32 V_SubStringWidth(const char *string, INT32 length, INT32 option);
#define V_StringWidth(string, option) V_SubStringWidth(string, -1, option)
// Find string width from hu_font chars, 0.5x scale
INT32 V_SmallStringWidth(const char *string, INT32 option);
INT32 V_SmallSubStringWidth(const char *string, INT32 length, INT32 option);
#define V_SmallStringWidth(string, option) V_SmallSubStringWidth(string, -1, option)
// Find string width from tny_font chars
INT32 V_ThinStringWidth(const char *string, INT32 option);
INT32 V_ThinSubStringWidth(const char *string, INT32 length, INT32 option);
#define V_ThinStringWidth(string, option) V_ThinSubStringWidth(string, -1, option)
// Find maximum length for substring taken from current string to fit into given width
INT32 V_SubStringLengthToFit(const char *string, INT32 width, INT32 option);
char V_GetSkincolorChar(INT32 color);
+35 -10
View File
@@ -2145,11 +2145,11 @@ virtres_t* vres_GetMap(lumpnum_t lumpnum)
size_t *vsizecache;
// Remember that we're assuming that the WAD will have a specific set of lumps in a specific order.
UINT8 *wadData = W_CacheLumpNum(lumpnum, PU_LEVEL);
UINT8 *wadData = (UINT8*)(W_CacheLumpNum(lumpnum, PU_LEVEL));
filelump_t *fileinfo = (filelump_t *)(wadData + LONG(((wadinfo_t *)wadData)->infotableofs));
i = LONG(((wadinfo_t *)wadData)->numlumps);
vsizecache = Z_Malloc(sizeof(size_t)*i, PU_LEVEL, NULL);
vsizecache = (size_t*)(Z_Malloc(sizeof(size_t)*i, PU_LEVEL, NULL));
for (realentry = 0; realentry < i; realentry++)
{
@@ -2161,7 +2161,7 @@ virtres_t* vres_GetMap(lumpnum_t lumpnum)
numlumps++;
}
vlumps = Z_Malloc(sizeof(virtlump_t)*numlumps, PU_LEVEL, NULL);
vlumps = (virtlump_t*)(Z_Malloc(sizeof(virtlump_t)*numlumps, PU_LEVEL, NULL));
// Build the lumps, skipping over empty entries.
for (i = 0, realentry = 0; i < numlumps; realentry++)
@@ -2169,10 +2169,20 @@ virtres_t* vres_GetMap(lumpnum_t lumpnum)
if (vsizecache[realentry] == 0)
continue;
vlumps[i].size = vsizecache[realentry];
const char *name = (fileinfo + realentry)->name;
if (strlen(name) == 5 && memcmp(name, "MAP", 3) == 0)
{
numlumps--; // We skip map marker, so 1 of entries becomes empty
continue; // This will skip i++ so we will write to same entry
}
// Play it safe with the name in this case.
memcpy(vlumps[i].name, (fileinfo + realentry)->name, 8);
memcpy(vlumps[i].name, name, 8);
vlumps[i].name[8] = '\0';
vlumps[i].data = Z_Malloc(vlumps[i].size, PU_LEVEL, NULL); // This is memory inefficient, sorry about that.
vlumps[i].data = (UINT8*)(
Z_Malloc(vlumps[i].size, PU_LEVEL, NULL) // This is memory inefficient, sorry about that.
);
memcpy(vlumps[i].data, wadData + LONG((fileinfo + realentry)->filepos), vlumps[i].size);
i++;
}
@@ -2193,16 +2203,25 @@ virtres_t* vres_GetMap(lumpnum_t lumpnum)
}
numlumps++;
vlumps = Z_Malloc(sizeof(virtlump_t)*numlumps, PU_LEVEL, NULL);
vlumps = (virtlump_t*)(Z_Malloc(sizeof(virtlump_t)*numlumps, PU_LEVEL, NULL));
for (i = 0; i < numlumps; i++, lumpnum++)
{
// Check if it is map marker. It is not always first lump sadly, so we need to expect it anywhere
const char *name = W_CheckNameForNum(lumpnum);
if (strlen(name) == 5 && memcmp(name, "MAP", 3) == 0)
{
--i; // Decrement so on next iteration we write on same i, so we don't leave corrupted vlumps entry
numlumps--; // Just so we don't try to access the leftover vlumps entry
continue;
}
vlumps[i].size = W_LumpLength(lumpnum);
memcpy(vlumps[i].name, W_CheckNameForNum(lumpnum), 8);
memcpy(vlumps[i].name, name, 8);
vlumps[i].name[8] = '\0';
vlumps[i].data = W_CacheLumpNum(lumpnum, PU_LEVEL);
vlumps[i].data = (UINT8*)(W_CacheLumpNum(lumpnum, PU_LEVEL));
}
}
vres = Z_Malloc(sizeof(virtres_t), PU_LEVEL, NULL);
vres = (virtres_t*)(Z_Malloc(sizeof(virtres_t), PU_LEVEL, NULL));
vres->vlumps = vlumps;
vres->numlumps = numlumps;
@@ -2222,7 +2241,13 @@ void vres_Free(virtres_t* vres)
}
while (vres->numlumps--)
Z_Free(vres->vlumps[vres->numlumps].data);
{
if (vres->vlumps[vres->numlumps].data)
{
Z_Free(vres->vlumps[vres->numlumps].data);
}
}
Z_Free(vres->vlumps);
Z_Free(vres);
}