Compare commits

..

321 commits

Author SHA1 Message Date
NepDisk
30c789bfc2 Don't additive position num normally 2026-02-21 12:48:37 -05:00
NepDisk
3b298c2a25 Vendoring Tracy again
Having this as a submodule is causing issues
2026-02-21 12:36:05 -05:00
NepDisk
cef1583521 Downgrade Tracy
The newest one is being memory leaky on the software renderer
2026-02-21 10:14:38 -05:00
toaster
4847282eeb sdl/i_system.cpp: Remove FUNCNORETURN on signal_handler()
Fixes ERRORMODE compliation after !2372
2026-02-21 10:00:26 -05:00
NepDisk
10e11ba5ce Default waterskip bricks on 2026-02-21 09:23:39 -05:00
NepDisk
a3f34f11df Cast this so compiler shuts up 2026-02-21 07:29:00 -05:00
minenice55
385a20058f Update i_video.cpp 2026-02-21 02:59:07 -05:00
minenice55
9669192e10 what the fuck were these sdl memsets for
only ones in the entire codebase btw
2026-02-21 02:31:43 -05:00
minenice55
f70327f68d Update miniupnp 2026-02-21 00:39:56 -05:00
minenice55
247dd4a437 turns out this needs its own pickup type (due to op order) 2026-02-21 00:26:09 -05:00
NepDisk
24fed48281 Merge pull request 'Fix FreeBSD build' (#217) from Hanicef/blankart:fix-freebsd-build into next
Reviewed-on: https://codeberg.org/NepDisk/blankart/pulls/217
2026-02-21 00:26:07 +01:00
Gustaf Alhäll
47ed04d864
Fix FreeBSD build 2026-02-20 23:45:26 +01:00
NepDisk
085ffd8185 Redo keyboardlayout
Based on this commit from Saturn: 423ca0eca0
2026-02-20 16:30:29 -05:00
NepDisk
516a05c4bf Add improved requried flags for each san 2026-02-20 10:58:32 -05:00
NepDisk
752548e7ca Add other sanitizers 2026-02-20 10:50:05 -05:00
NepDisk
2e147367eb Add lsan cmake flag 2026-02-20 10:41:56 -05:00
NepDisk
c9c5c89c81 Mention people pull the submodules 2026-02-20 08:20:54 -05:00
minenice55
d031a9a3e7 use the added sounds 2026-02-20 01:23:14 -05:00
NepDisk
6fb8ddf82e Don't sink cam on exiting players 2026-02-19 22:23:00 -05:00
NepDisk
de772ea0a9 No longer have libbacktrace as a submodule
Unfornately we need to vender our own.
2026-02-19 18:43:45 -05:00
minenice55
8a892ac4e5 this is inverted 2026-02-19 16:31:42 -05:00
NepDisk
b4ffbe8ba4 Move tracy and libbacktrace to submodules 2026-02-19 16:06:24 -05:00
minenice55
b681e00287 oh cool it builds 2026-02-19 14:01:29 -05:00
NepDisk
20972323a2 Add minipnpc find script 2026-02-19 13:27:45 -05:00
NepDisk
649523e4c8 Get miniupnpc working 2026-02-19 13:09:36 -05:00
NepDisk
76314d2f8c Update UPnP implementation
Based on code by Logan A, SteelT and Sphere
2026-02-19 13:09:36 -05:00
minenice55
83977e0c98 add actually damaged check for egg mine damage 2026-02-19 12:06:52 -05:00
minenice55
478a94a66f make recovery spin a bit easier to start when in wipeout 2026-02-19 11:29:57 -05:00
NepDisk
98e69a5217 Remove extraneous parentheses 2026-02-19 09:07:51 -05:00
yamamama
388e359821 Decrease S-Monitor force threshold
17000 is a ridiculous overcorrection; 12000 felt nicer in testing
2026-02-18 23:36:37 -05:00
minenice55
4c53b83d5a let flame shield offroad burn build drift sparks 2026-02-18 23:23:11 -05:00
minenice55
d3917cf2d2 should be a resist not complete immunity 💀 2026-02-18 23:15:56 -05:00
minenice55
6442dc8907 fix flame shield applying offroad resist wrong 2026-02-18 22:50:49 -05:00
minenice55
12801df6f2 don't push empty sensor events 2026-02-18 22:08:47 -05:00
minenice55
92f3ecdd83 allow configuring thundershield radius 2026-02-18 17:13:35 -05:00
NepDisk
41cfd0d722 Revert "Experiment test"
This reverts commit 39052a7e21.
2026-02-18 15:33:17 -05:00
NepDisk
39052a7e21 Experiment test 2026-02-18 15:16:47 -05:00
NepDisk
2651395a5a Reapply "Reset OGL attributes"
This reverts commit 4a36c0e0fe.
2026-02-18 15:05:45 -05:00
NepDisk
bbc78cf557 Reapply "Use in pixels since this is supposed to be the correct way of doing this"
This reverts commit a594bd37bd.
2026-02-18 15:05:26 -05:00
NepDisk
4a36c0e0fe Revert "Reset OGL attributes"
This reverts commit 75da203704.
2026-02-18 14:31:58 -05:00
minenice55
506efaa247 Update d_main.cpp 2026-02-18 14:23:21 -05:00
NepDisk
a594bd37bd Revert "Use in pixels since this is supposed to be the correct way of doing this"
This reverts commit 8b28f97e81.
2026-02-18 08:59:05 -05:00
yamamama
7817062ead Append Saturn's color profile system, rename gamma to brightness 2026-02-18 06:09:53 -05:00
minenice55
bd0c8867a2 fix weird inconsistencies with bubble shield 2026-02-18 00:05:48 -05:00
minenice55
7ba3d008f2 put bubble shield reflect sooner 2026-02-17 21:52:47 -05:00
Alug
660ffd9383 init superactions global
was missed before
2026-02-17 21:49:24 -05:00
minenice55
f8d2e149c1 enable Egg Brick by default (without enabling the cooldown) 2026-02-17 18:41:55 -05:00
minenice55
50b7e41ae0 quick bugfixes 2026-02-17 18:25:39 -05:00
NepDisk
935fee6472 Update hashes for new dev build 2026-02-17 16:17:33 -05:00
minenice55
9fd51bfdff put forced top speed under doboostpower 2026-02-17 14:53:21 -05:00
NepDisk
eda7780b79 Moved items.md changse to wiki 2026-02-17 14:39:18 -05:00
NepDisk
d46f74ea7e This isn't needed the lua func already has an option for this 2026-02-17 14:19:36 -05:00
NepDisk
cebf4301d0 Add missing library for appimage file 2026-02-17 13:46:53 -05:00
James R
6c0306a501 Polyobjects: add po_movecount member to mobj_t instead of using lastlook
- Polyobject carrying set lastlook on mobjs for internal
  tracking
- lastlook is used by some objects to track their own
  state
- Ring Shooter uses lastlook to remember which player
  summoned it
- A Ring Shooter spawned right next to a polyobject would
  become buggy; If its owner player pressed the respawn
  button again before the Ring Shooter despawned, that
  player would be teleported back to the Ring Shooter
  instead of spawning a new Ring Shooter (which would be
  the correct behavior)

Nep: We don't have a ring shooter but this would still be a useful fix
2026-02-17 13:21:38 -05:00
minenice55
0ef5f82b60 hash 2026-02-17 13:19:33 -05:00
NepDisk
7be815369f Fix gamemap hooks returning the wrong mapid because of compatmode check
Thanks Indev!!!!!!!!
2026-02-17 11:40:46 -05:00
NepDisk
f8316526ee Just in case lua sets it and bypasses the alt item system 2026-02-17 10:59:50 -05:00
NepDisk
df3209281e Remerge S-Monitor back into Invin 2026-02-17 10:52:01 -05:00
yamamama
4bc810207e Add a customizable decay timer to the S-Monitor 2026-02-16 20:45:58 -05:00
yamamama
e036028948 Invincibility damage toggle, bring back S-Monitor's distance check 2026-02-16 19:59:35 -05:00
yamamama
fb6066dea9 Fix up some uncaught issues with the S-Monitor split
- Cancel-music is fixed
- Offroad gradienting is fixed
- Introduced the "slot-unhog" system (decaying power lets you pick up items again)
- Renamed some more internal variables
2026-02-16 18:44:09 -05:00
yamamama
542648e948 Add KIF_HYUCANTSTEAL
- Prevents the given item from ever being stolen by Hyudoro
- Useful for those extra-special items that you really want the player to use
2026-02-16 18:40:48 -05:00
yamamama
d5ca5516de Split Classic and Alt. Invincibility
- It's what the people want, why bother to complain?
- Alt is now its own separate item titled the S-Monitor
- Several variables, macros, functions, and comments have been renamed to fit this change
2026-02-16 18:40:48 -05:00
NepDisk
a719adb4e6 Don't allow superring rolling with rings mode off 2026-02-16 16:40:19 -05:00
minenice55
77cd1ac7e5 let rolled eggmine pierce through traps and missiles 2026-02-16 16:01:18 -05:00
NepDisk
e409d91949 static_castma(balls) 2026-02-16 00:08:47 -05:00
NepDisk
3dab43cbcc Rumble on wall hit 2026-02-15 23:58:10 -05:00
minenice55
c8a5142593 fix spacing 2026-02-15 23:41:21 -05:00
minenice55
a5de10fce6 these need to be differentiatable lol 2026-02-15 23:40:38 -05:00
NepDisk
9748cb3839 Merge pull request 'Migrate to SDL3' (#216) from sdl3-again into next
Reviewed-on: https://codeberg.org/NepDisk/blankart/pulls/216
2026-02-16 05:36:22 +01:00
minenice55
ca9abfc9f8 prelim work for sensors and other outputs 2026-02-15 23:27:46 -05:00
minenice55
f770b5c8f5 make stick keyrepeat speed based on tilt
hat keyrepeat still is non-existent
2026-02-15 22:32:47 -05:00
yamamama
b568e040ec Attempts to salvage Alt. Invin
What do people see in this thing...

* A player's invincibility is now permanently active until they get past the cluster player
* Speed boost has been buffed
* Cluster calculations now use an average-distance between players
* The odds system now uses a binary "force or not" format, instead of the gradienting system used prior.
  This should ensure that the item is rolled only when players need it the most.
2026-02-15 19:12:58 -05:00
minenice55
0a6e66ae12 fix menu button 2026-02-15 18:06:48 -05:00
NepDisk
ead335b1fd Fix keyboard input
Thanks once again Alug!
2026-02-15 17:27:24 -05:00
minenice55
fb5287f335 fix keyrepeat for gamepad sticks
hats are still broken
2026-02-15 16:02:07 -05:00
NepDisk
30f564398e OGL on windows 2026-02-15 15:14:32 -05:00
NepDisk
75da203704 Reset OGL attributes 2026-02-15 15:02:28 -05:00
NepDisk
61e934e1c6 Match Classic a little big cloeser 2026-02-15 14:33:11 -05:00
NepDisk
6393dd6bcc Revert "Try hack to fix windows renderer freeze during gl->software"
This reverts commit 528a5eb218.
2026-02-15 14:10:41 -05:00
NepDisk
528a5eb218 Try hack to fix windows renderer freeze during gl->software 2026-02-15 14:01:06 -05:00
NepDisk
3ed99e27ef Fix evalmath not properly getting sound effects 2026-02-15 10:16:49 -05:00
NepDisk
04059a42e5 Revert "Hacky garbage to fix map sfx playback until evalmath fix"
This reverts commit 842e4e50c2.
2026-02-15 09:26:28 -05:00
NepDisk
d13bb699de Give water panels their unique sound back 2026-02-15 01:11:32 -05:00
NepDisk
842e4e50c2 Hacky garbage to fix map sfx playback until evalmath fix 2026-02-14 21:06:23 -05:00
GenericHeroGuy
0c0680d2f3 Fix controller name display in menu (and a segfault) 2026-02-15 00:12:40 +01:00
GenericHeroGuy
584157277f Fix incorrect face button layout on Nintendo controllers 2026-02-14 23:36:01 +01:00
GenericHeroGuy
15d89f5ef5 No, stop freezing my X11 server 2026-02-14 22:54:45 +01:00
NepDisk
418f345971 Lower maxdevices down to save some memory 2026-02-14 16:34:58 -05:00
NepDisk
8a9683542b Fix Gamepads
Thanks thanks thanks thanks so much Alug for the time working on this!!!!!
2026-02-14 16:27:53 -05:00
NepDisk
359e30dba6 Use direct3d11 on windows for software 2026-02-14 15:20:09 -05:00
NepDisk
53898bc08b Merge branch 'next' into sdl3-again 2026-02-14 08:24:03 -05:00
NepDisk
2b503fbb5a Make flame store ignore friction 2026-02-14 08:04:06 -05:00
NepDisk
56b63b6ce1 Merge branch 'next' into sdl3-again 2026-02-14 00:24:34 -05:00
NepDisk
ddbd052fd0 Oops forgot auto existed for a second 2026-02-14 00:11:07 -05:00
NepDisk
a8fa69237f Fix encore votes being broken 2026-02-14 00:05:59 -05:00
NepDisk
c5eecba48b Merge branch 'next' into sdl3-again 2026-02-13 23:48:39 -05:00
NepDisk
e9cdbf97c3 Add flag that always forces the timer to the end of the list 2026-02-13 23:37:35 -05:00
NepDisk
d2ddf2a27a Use hudtranshalf for splitscreen timers
Why not make this respect player choice
2026-02-13 23:26:17 -05:00
NepDisk
e96b1bfdce Make flags field of timers act like a bitfield and add new flags 2026-02-13 23:15:42 -05:00
Indev
cf1ac5f864 Expose item timers to lua 2026-02-13 22:29:26 -05:00
NepDisk
0a0c6d938d Merge branch 'next' into sdl3-again 2026-02-13 21:47:37 -05:00
NepDisk
d989cfa370 rename the rest of the kart files 2026-02-13 20:22:16 -05:00
NepDisk
2449164f79 Use a different file for blan savefiles 2026-02-13 15:58:38 -05:00
minenice55
4fd9e1e155 say no to variable charge caps 2026-02-13 15:38:55 -05:00
minenice55
7c1104d7d6 this is supposed to be 0 2026-02-13 15:37:12 -05:00
minenice55
04601f0004 this doesn't stack so don't lie 2026-02-13 15:33:32 -05:00
minenice55
f2bb0bdfef bring this back 2026-02-13 15:31:04 -05:00
minenice55
1324e59203 only play charged sound when grounded 2026-02-13 15:28:59 -05:00
minenice55
010b3d83c6 build faster in hi mode
and kill existing boosts when starting
2026-02-13 15:26:41 -05:00
minenice55
02a06848e4 re-tune when low and high mode recovery dash start 2026-02-13 15:17:45 -05:00
minenice55
e3f098b736 add the new buttons to keynames 2026-02-13 13:58:35 -05:00
minenice55
04d68a1d37 26 buttons instead of 21
is this a bad idea
2026-02-13 13:32:25 -05:00
NepDisk
af933c086a remove duped gamepad init from merge 2026-02-12 23:17:00 -05:00
minenice55
55646fadab enable libusb (to support switch 2 gamepads etc) 2026-02-12 22:40:35 -05:00
minenice55
dadbdfe5a3 ce n'est pas si simple 2026-02-12 21:00:18 -05:00
NepDisk
553a2507ae Remove unused SDL headers 2026-02-12 20:50:19 -05:00
NepDisk
c5fe606343 Attempt to fix gamepad input pt1 2026-02-12 16:53:32 -05:00
NepDisk
1ca56d100a Rename joystick index related things to joystick id
Since SDL3 doesn't use indexes this should make it less confusing when I start working on this
2026-02-12 16:14:47 -05:00
NepDisk
8b28f97e81 Use in pixels since this is supposed to be the correct way of doing this 2026-02-12 14:16:37 -05:00
NepDisk
c89be92461 Set wayland scale hint if on Linux
Thanks Alug!
2026-02-12 13:09:22 -05:00
Gustaf Alhäll
c093fdce8e Fix resolution being forced back to 320x200 (again) 2026-02-12 12:52:57 -05:00
Gustaf Alhäll
aff75e6624 Fix resolution occationally resetting on startup 2026-02-12 12:39:28 -05:00
Gustaf Alhäll
5cbfb20298 Remove realwidth and realheight 2026-02-12 12:31:33 -05:00
NepDisk
bcc5d6a205 Clean up comments 2026-02-12 10:48:11 -05:00
NepDisk
60e7563168 Put joystick add/remove event into seperate functions 2026-02-12 10:44:39 -05:00
NepDisk
cdeaa583dd Do not register controllers under camera lmao 2026-02-12 03:45:11 -05:00
NepDisk
b85887f0f1 Attempt to fix the joystick being lost midgame 2026-02-12 03:35:00 -05:00
NepDisk
156e07d02c More cmake stuff 2026-02-12 03:01:51 -05:00
NepDisk
1dcd44458d Remove debian-template dir
Will put this back later if we need it.
2026-02-12 01:50:45 -05:00
NepDisk
54992c8d43 Rename rest of SDL2 refs and remove even more unused thirdparty libs 2026-02-12 01:43:36 -05:00
NepDisk
2059a99a44 Fix software using linear filter by default 2026-02-12 01:17:37 -05:00
NepDisk
656ad85a8f Port to SDL3
Thanks to SRB2Classic for refernce!!!
2026-02-12 00:39:19 -05:00
NepDisk
47bcd68596 edit required backend files and remove unused libs 2026-02-11 23:07:09 -05:00
NepDisk
177343594e Kill Support for mixer sound
SDL3 doesn't have a public mixer yet anyway so its probably fine :)
2026-02-11 22:50:56 -05:00
NepDisk
277131a5a3 Rename SRB2SDL to BLANKART 2026-02-11 22:44:28 -05:00
NepDisk
651ceae556 AAAAAAAA
Thanks SDL2-Compat
2026-02-11 21:12:27 -05:00
NepDisk
4593b44db3 Disable more mouse stuff if its been disabled 2026-02-11 20:58:43 -05:00
NepDisk
1fc21e1286 Lowercase instead of uppercase the string 2026-02-11 19:56:16 -05:00
NepDisk
eed7625a45 Use alloca instead of a c++ vla for W_HashLumpName 2026-02-11 19:39:42 -05:00
NepDisk
1e0ee984ee Fix warnings 2026-02-11 17:07:19 -05:00
NepDisk
6b4081663a Revert "Fix map hooks not providing the current maps in compatmode"
This reverts commit 5de81eb62b.
2026-02-11 15:34:06 -05:00
minenice55
4d1454a299 why was different from kart 2026-02-11 15:25:32 -05:00
NepDisk
229d5cd564 Don't Draw flame meter when exiting
You are no longer playing so lets clean up the screen
2026-02-11 12:51:01 -05:00
NepDisk
26fe00f1e8 Fix invalid items or itemamount from displaying SAD in the item slot 2026-02-11 12:42:59 -05:00
NepDisk
e30774477f Package SDL2 with appimage
The fact SDL2 has been killed off makes this super annoying as SDL2-compat is pretty buggy and breaks all the time
2026-02-11 12:21:16 -05:00
minenice55
c70c22efe6 still doesn't work
but use K_BotDefaultSpectator more
2026-02-11 01:42:46 -05:00
minenice55
5fd1955845 doesn't work for what we need but...
implement K_BotDefaultSpectator
2026-02-10 23:25:51 -05:00
minenice55
c9755c9712 getting somewhere? 2026-02-10 22:54:06 -05:00
NepDisk
46e9d659a9 AppImage building support 2026-02-10 20:21:16 -05:00
minenice55
8feb843c11 remove the nuke 2026-02-10 18:45:14 -05:00
minenice55
86e47fe1ae I went to war on the bots and got nuked
DOESN'T FULLY WORK
2026-02-10 18:14:08 -05:00
minenice55
968b6642d8 this is probably a bad idea 2026-02-10 17:26:58 -05:00
minenice55
40d566f607 UNTESTED stop bots from spawning in item breaker 2026-02-10 17:04:51 -05:00
NepDisk
5de81eb62b Fix map hooks not providing the current maps in compatmode 2026-02-10 11:35:42 -05:00
Alug
adce4197e0 make lumpnumcache case sensitive + optimize + replace quickncase hash with FNV1a
lumpnumcache can be case sensitive W_CheckNumForName should also look for uppercase stuff and W_LumpExists is case sensitive anyways
this avoids having to always account for case (toupper/tolower) during hash and string comparisons and even allows us to even directly compare our strings instead of using fastcmp (std::strings allow this!)
from some benchmarking externally this makes this faster quite a bit
2026-02-10 09:22:02 -05:00
NepDisk
71175d82ca Don't allow bots to do grip turns in the air 2026-02-09 22:41:22 -05:00
NepDisk
21000c7969 Refactor and Clean up various respawn related functions 2026-02-09 22:18:49 -05:00
minenice55
fbbb3c543e make non-overheating flame shield unable to damage players
and tweak visuals to convey overheating a bit more
also raises the flamometer up a bit
2026-02-09 21:05:03 -05:00
NepDisk
bfa0569815 Make burn out boosting less strong 2026-02-09 18:30:56 -05:00
Alug
018ba7be55 HWR_CreateBlendedTexture: init a bunch of stuff 2026-02-09 17:46:04 -05:00
Alug
f4120fe776 move gamepad led ticker after render logic
this does not really matter but save a tiny little amount of time before rendering a frame
2026-02-09 17:39:42 -05:00
NepDisk
b2ee66cffb Tweak around recovery dash numbers a bit 2026-02-09 14:29:17 -05:00
NepDisk
89d2fd24f6 Reset Flamedash when flamestore expires
This makes it so that the turning loss given by the flameshield resets when you use up your flameshield, rather then lingering.
2026-02-09 13:17:19 -05:00
NepDisk
739c449745 Kick this down for reworked numbers 2026-02-08 23:49:42 -05:00
minenice55
a38c3a843a UNTESTED; cut flame shield temperature and fuel by 10% 2026-02-08 22:02:35 -05:00
minenice55
f5928880b3 enable fast fuel by default (and make it burn faster) 2026-02-08 21:51:59 -05:00
Alug
f36e166796 add "vid.udup" same as vid.dup but not scaled with "highreshudscale" 2026-02-08 11:29:17 -05:00
NepDisk
14bf52af43 Combine vid.dupx and vid.dupy 2026-02-08 11:25:09 -05:00
NepDisk
60a19aaf61 Various openGL vhs effect changes
Thanks Alug!
2026-02-08 10:18:56 -05:00
NepDisk
1750ed1863 Update gld_FrustumAngle 2026-02-08 10:02:08 -05:00
Alug
5d1f03b77f delet all the Z_Free checks
Z_Free already checks its input internally!
2026-02-08 09:51:17 -05:00
NepDisk
557166ccef Init more stuff 2026-02-08 09:51:17 -05:00
minenice55
5082409aec try to fix tapping recovery spin input keeping boosted acceleration 2026-02-08 02:32:42 -05:00
minenice55
38eb41940b heavy drop acceleration assist when turning
also restore some of the heavy drop feel tuning when heavy-only is used (it should still be fun 🥹)
 to keep light and heavy in balance we unfortunately need to sack the feel-tuning in fusion so it should stay like it is in d738ad595 there
 as an additional measure hi-power heavy drop is now much shorter in fusion
2026-02-08 01:07:07 -05:00
minenice55
dd1022b18c implement the egg brick proper 2026-02-07 23:11:52 -05:00
GenericHeroGuy
d738ad5957 Alright, take it or leave it 2026-02-08 01:07:20 +01:00
NepDisk
38f9419fc2 Merge pull request 'Heavy Airdrop and Fusion Air drop' (#215) from heavyairdrop into next
Reviewed-on: https://codeberg.org/NepDisk/blankart/pulls/215
2026-02-07 20:49:09 +01:00
NepDisk
54feed7c60 Merge branch 'next' into heavyairdrop 2026-02-07 14:48:51 -05:00
NepDisk
a13028b4f9 Merge Deez 2026-02-07 14:48:18 -05:00
NepDisk
819e7b6919 Merge branch 'next' into heavyairdrop 2026-02-07 03:12:40 -05:00
minenice55
3306c276a1 make null drift tilt "feel" influenced by momentum 2026-02-07 00:41:30 -05:00
NepDisk
524a61266c Merge branch 'next' into heavyairdrop 2026-02-06 18:51:31 -05:00
yamamama
d35c8c37d6 Add some effects for null-drifting 2026-02-06 17:52:32 -05:00
NepDisk
487d0d87bc Merge branch 'next' into heavyairdrop 2026-02-06 16:44:49 -05:00
NepDisk
66defc522b Fix Speedcap removal vars being broken 2026-02-06 16:44:14 -05:00
NepDisk
0db1160835 Don't allow heavy airdrop to waterskip 2026-02-06 16:13:47 -05:00
NepDisk
acedad42e4 Merge branch 'next' into heavyairdrop 2026-02-06 16:03:39 -05:00
NepDisk
1c1a7998e2 Move wallspikes to 5022 2026-02-06 15:55:55 -05:00
NepDisk
06d9a6f3f7 Merge branch 'next' into heavyairdrop 2026-02-06 15:32:54 -05:00
NepDisk
d9ec74dea7 Fix missing null drift effect
oops!!!!!!
2026-02-06 15:31:31 -05:00
NepDisk
485a54479f Expose new player airdrop fields to Lua 2026-02-06 14:40:12 -05:00
NepDisk
c13f92a3b9 Expose airdrop stuff to Lua 2026-02-06 14:34:58 -05:00
NepDisk
fb9f0dc0de Merge branch 'next' into heavyairdrop 2026-02-06 14:28:07 -05:00
NepDisk
9e54882b59 Fix up mod displays for airdrop 2026-02-06 14:26:42 -05:00
minenice55
922bb9b873 fix air drop time being constantly reset in fusion 2026-02-06 12:15:02 -05:00
minenice55
d59c1060c7 separate light drop delay and heavy drop high power 2026-02-06 11:22:23 -05:00
NepDisk
cc146b5021 Fix stiffness feeling of airdrop inputs and fix landingboost timer 2026-02-06 01:24:57 -05:00
NepDisk
74338f1996 Use a more impactful sound for heavyairdrop 2026-02-06 00:40:11 -05:00
minenice55
de2e58204d scaling heavy drop boost 2026-02-05 22:25:32 -05:00
minenice55
d915af3cb5 "fusion" air drop 2026-02-05 21:33:45 -05:00
minenice55
fc455e9079 make holding brake while grounded not trigger airdrop 2026-02-05 20:50:38 -05:00
minenice55
667616ed0c feel-tuning
todo: make holding brake before going airborne not activate heavy drop (maybe allow 2 ticks of leeway?)
2026-02-04 20:55:35 -05:00
yamamama
1306a70107 Left in a fucking debug print 2026-02-04 19:44:44 -05:00
yamamama
ff639004d4 HUD rescaling for larger resolutions
Lifted from Saturn: 2348e3b73e
2026-02-04 19:38:02 -05:00
Alug
e369d1a090 dont reload palette until config was loaded 2026-02-04 19:38:02 -05:00
yamamama
0d7d6a60eb Almost forgot the bitflags 2026-02-04 18:23:40 -05:00
yamamama
5895959265 Kill bouncy air drop
Too contentious of a mechanic to hardcode
2026-02-04 13:07:12 -05:00
yamamama
f719824f37 Revise Heavy Air Drop's sound design, add ringspill to PAF_BOUNCYAIRDROP 2026-02-04 12:11:24 -05:00
GenericHeroGuy
a098e22907 Fix skywall appearing for some invisible FOFs
Fixes bellbridge and secret slide

Context:
first flat in srb2.srb is F_SKY1
first texture is - aka PIT~
Vanilla kart doesn't have the 2.2 texture refactor aka wallflats, so flats aren't loaded into the textures array but
then wallflats came along and lacto just decided to load flats before textures
2026-02-04 12:10:07 -05:00
yamamama
1e868d6bfa Make this consistent with bumpspark 2026-02-04 11:31:45 -05:00
yamamama
f2f9ad98f2 Fix some errors with KartAirDrop_OnChange 2026-02-04 11:21:41 -05:00
yamamama
bf6f86a5fb Expose airdrop flags to Lua 2026-02-04 11:21:25 -05:00
Alug
4f1f81cea5 rename "ffloor" global to "visffloor"
prevent name conflicts with a bunch of local variables named "ffloor"
2026-02-04 11:01:24 -05:00
Alug
6b0d4af9a0 fix R_MakeSpans accessing spanstart out of bounds when in splitscreen
it gets allocated for viewheight not vid.height!
2026-02-04 10:57:55 -05:00
NepDisk
dfeddbfe86 Also the planes 2026-02-04 10:53:38 -05:00
NepDisk
78c527675f Init some stuff in software renderer 2026-02-04 10:52:24 -05:00
NepDisk
ed26b6272b Don't generate textures in R_GetColumn
Based on a commit by lactozilla
2026-02-04 10:52:23 -05:00
yamamama
2a84eda311 Move airdrop-related flags to its own variable 2026-02-04 10:38:06 -05:00
yamamama
c87c5fd8cd Allow (U)INT64 savebuffer read+write and netsync
Sincerely hoping there's a valid reason this codebase is allergic to 64-bit integers like this
2026-02-04 10:38:06 -05:00
yamamama
ac280f78f3 Refactor v.getDrawInfo
Pushes draw info as a Lua table instead of a set of integers, and also includes the new datafields
2026-02-04 10:38:06 -05:00
yamamama
d880abe8ea Clean up and make safe some hudcode
* Un-shadowed the two hudtrans variables
* Zero-initialized the trackingResult_t in K_getRoulettePositionForTrackingPlayer
* Zero-initialized the drawinfo_t and rouletteinfo_t in libd_getDrawInfo
* Removed really gross trailing whitespaces from ported RadioRacers code
2026-02-04 10:34:14 -05:00
yamamama
80898a0607 Allow (U)INT64 savebuffer read+write and netsync
Sincerely hoping there's a valid reason this codebase is allergic to 64-bit integers like this
2026-02-04 10:10:19 -05:00
yamamama
0c2d8a8e36 Shove bouncy fastfalling into a pflag
Reduce headaches about fastfall bounce by obfuscating its existence a decent bit
2026-02-04 01:47:33 -05:00
minenice55
45ae657dec add poomf sound to heavy too 2026-02-04 01:09:46 -05:00
minenice55
657bbf8521 Revert "disable bouncy fastfall via directive"
This reverts commit bdbf388072.
2026-02-04 01:08:57 -05:00
minenice55
bdbf388072 disable bouncy fastfall via directive
should check light fast fall again
2026-02-04 01:06:51 -05:00
yamamama
76f17ca97b Bounce sound 2026-02-04 00:51:07 -05:00
minenice55
1bb3df7435 two(!!) new modes for airdrop
bouncy = a-la ring racers
heavy = even faster and gives a small boost on landing
2026-02-03 23:39:05 -05:00
yamamama
305ef7b9a5 Refactor v.getDrawInfo
Pushes draw info as a Lua table instead of a set of integers, and also includes the new datafields
2026-02-03 21:43:08 -05:00
minenice55
ca2420fb0f add some newer features to server mods 2026-02-03 20:55:28 -05:00
NepDisk
4c20e919c3 Update header headers 2026-02-03 18:19:30 -05:00
NepDisk
75483f92e8 Kill off most of HWRAPI
Based on 25f1e504c9
2026-02-03 18:15:51 -05:00
yamamama
ed5b67c399 RadioRacers' player-tracking roulette
Original commit: f79b5cc51a
2026-02-03 16:40:53 -05:00
NepDisk
27428e8b9f Hack to fix infitely tall software double sided linedefs flicker bug on some maps
Thanks Alug for looking into this.

Unfornately not easy to fix unless convert a bunch of code to use 64bit math or floats.
2026-02-03 15:00:09 -05:00
Alug
0648916c4a plug a potential memory leak in M_SaveConfig 2026-02-03 12:03:52 -05:00
minenice55
8e025b97c2 put this in the wrong place too 2026-02-01 18:36:29 -05:00
minenice55
c1666cb4e3 no it's not 2026-02-01 18:26:27 -05:00
minenice55
383a83e76e actually this is better 2026-02-01 18:25:36 -05:00
minenice55
1413efea77 oh I'm stupid 2026-02-01 18:24:48 -05:00
minenice55
0c325433a4 experiment: put spinning player that want recovery dash in wipeout 2026-02-01 18:16:13 -05:00
NepDisk
bd299f1ad5 Just respawn at next waypoint unconditionally for now 2026-02-01 17:42:11 -05:00
yamamama
16d2789a15 Merge pull request 'Follower horns' (#214) from universally-hated-in-dev into next
Reviewed-on: https://codeberg.org/NepDisk/blankart/pulls/214
2026-02-01 22:20:34 +01:00
yamamama
598f974fdc Follower mood system
* Followers get happy when you hit others, and angry when others hit you
* The mood doesn't do much beyond change the horn's symbol
2026-02-01 16:16:03 -05:00
yamamama
5efbc22a01 Expose horn sounds to Lua 2026-02-01 16:16:03 -05:00
yamamama
d4bd7b68cf Fix up some inconsistencies and errors, update the credits (again, again)
About TIME I get an excuse to chip at my credits backlog!
2026-02-01 16:16:02 -05:00
yamamama
addcb2b853 Update the credits 2026-02-01 16:16:02 -05:00
Superstarxalien
2221d6b027 Add "horn" state for followers 2026-02-01 16:16:02 -05:00
yamamama
055a93b654 Dedicated horn button
From indev talks: it'd be better to bind horns to a dedicated button,
than for it to occupy more "important" inputs like item/ring usage and looking backwards
2026-02-01 16:16:02 -05:00
yamamama
ee89cc251d I_Error(): 1 warning in the SOC lump 2026-02-01 16:16:02 -05:00
toaster
21849ef1ce Horncode
A much more focused replacement for Hornmod, specc'd out by Tyron and Oni working together and implemented by the author of this commit because it's pretty funny.

- Followers have `hornsound` in their SOC configuration.
    - The default sound for all followers without a provided one is sfx_horn00.
- They'll play this sound if you use lookback with one following you, and there's nearby players to get the player looking all the way around.
    - Only the players who are successfully considered for lookback will hear it.
- Has a v1-like visual with less randomisation, but still netsynced.
- Also controlled by the cvar `taunthorns`, which, like `tauntvoices`, takes "Tasteful" (default), "Meme", and "Off".

TODO: make the condition for horn a little delayed, so you have to hold lookback for a little bit.
2026-02-01 16:16:02 -05:00
NepDisk
2c08cf3301 Revert "Reallow doomednum overriding"
This reverts commit 10671fff5a.
2026-02-01 09:59:49 -05:00
NepDisk
03b26a0723 Always reload texture arrays on renderer switch and bring back ingame renderer hotswapping
All this texture load blocking var does is cause issues due to order of operations and what not. Lets just kill it.

Thanks Alug for looking at this stuff for me!
2026-01-31 12:00:49 -05:00
NepDisk
0115ac230d Update readme to reflect added stuff overtime. 2026-01-30 21:48:15 +01:00
NepDisk
bddb56681b Add flipover to SD_LIST 2026-01-30 12:29:51 -05:00
yamamama
3626b4ac1c Color profile menudef 2026-01-30 02:02:55 -05:00
yamamama
e261471743 Fix up how the palette color cube is applied
You fed it into a tempvalue and never actually USED the tempvalue?!
2026-01-30 02:02:06 -05:00
NepDisk
f3767c5e77 Disable Ring drop for now
We can discuss its fate later.
2026-01-30 00:07:11 -05:00
NepDisk
300ffd94ea Also don't fade other players in freecam 2026-01-29 23:30:19 -05:00
NepDisk
70699740cc This is beyond dumb but what can you do.
Please remove this crap when we multithread netupdate please...
2026-01-29 23:07:08 -05:00
NepDisk
b49a210e85 disable playerfade after crossing the line 2026-01-29 22:50:01 -05:00
minenice55
7d82c72092 Merge pull request '[FEAT] Recovery Dash / Recovery Spin' (#213) from ssmt into next
Reviewed-on: https://codeberg.org/NepDisk/blankart/pulls/213
2026-01-29 23:46:23 +01:00
minenice55
92c4c8c21a skid overlay
note: needs cleaning up, overlay doesn't seem to position itself correctly?
2026-01-28 21:44:05 -05:00
minenice55
7696bb37cc fix friction related issues 2026-01-28 18:49:06 -05:00
minenice55
7a3b3407b5 final(?) tuning 2026-01-28 16:52:51 -05:00
minenice55
6a43983da6 bro 🥲 2026-01-28 15:56:13 -05:00
minenice55
52aa5543b1 time to be semantically correct 2026-01-28 15:26:29 -05:00
minenice55
7ae5065b61 synch this too 2026-01-28 14:08:45 -05:00
minenice55
70966222b7 Merge branch 'next' into ssmt 2026-01-28 08:19:30 +01:00
minenice55
030fc99099 netsync and expose to lua 2026-01-28 02:19:16 -05:00
minenice55
dd15f7cc67 billion config cvars, add recovery dash to menus 2026-01-28 02:00:11 -05:00
minenice55
92e74dca27 lots of performance tuning for recovery dash
crawling: accelerates faster when in flashtics, capped at a fixed 22 fu/t for all stats, is slipperier
recovery dash: accelerates much slower, lasts longer
ssmt charge is maintained when going airborne instead of being completely lost
2026-01-27 21:45:10 -05:00
minenice55
a536af526e some adjustment
need to do more but will have to hold
2026-01-27 18:46:07 -05:00
minenice55
21e1ebc0bc reorder some logic, more effects and visual cues 2026-01-27 18:13:54 -05:00
NepDisk
9ac1edb681 Properly block off creative's DLL from loading 2026-01-27 10:13:30 -05:00
NepDisk
be3f759534 Mostly Port my OpenAL EFX patch
Based on some stuff from https://github.com/kcat/openal-soft/blob/master/examples/alreverb.c
2026-01-27 09:49:17 -05:00
minenice55
d068c1dfc5 control tweaks, give boost values 2026-01-27 03:21:42 -05:00
minenice55
d2062ae680 make ssmt boost ignore offroad, charging ssmt resist offroad 2026-01-27 02:21:05 -05:00
minenice55
0beaae5f55 start spindash/ssmt 2026-01-27 02:07:47 -05:00
NepDisk
ce74d4012d Update openAL-Soft 2026-01-26 23:44:20 -05:00
minenice55
9278b9e0d0 register the cvar 2026-01-26 18:21:14 -05:00
minenice55
a2c6efb86e configurable item amount display 2026-01-26 18:12:03 -05:00
minenice55
fe6825ccf4 oh goodness I might die soon 2026-01-26 13:54:20 -05:00
minenice55
3fbd7e06ce and register it too 2026-01-26 13:48:58 -05:00
minenice55
2c0bf7de51 I do this professionally trust me 2026-01-26 13:47:34 -05:00
minenice55
616d1e4587 oops 2026-01-26 13:46:05 -05:00
yamamama
fbf82b9875 Who said anything about fixing conflicts?
We're gonna start some... on PAC-MAN. PA-PA-PA-PAC-MAN.
2026-01-26 13:44:08 -05:00
yamamama
bcb247dc14 Start a bit of work on input threads 2026-01-26 13:40:23 -05:00
minenice55
905ebe528a client-determined drift mode? 2026-01-26 13:36:35 -05:00
minenice55
ea408ff188 bring back snapshot system 2026-01-26 13:12:13 -05:00
minenice55
2327f02529 make this change operation order instead of use snapshots 2026-01-25 18:34:27 -05:00
minenice55
c6b875b336 experiment: drift turn snapshot
adds a cvar that makes starting a drift use the turn input from when the button is pressed to determine direction
2026-01-25 18:23:15 -05:00
NepDisk
4ba5fa5ef3 Attempt to fix flipover wrongdrift 2026-01-25 17:57:16 -05:00
NepDisk
3f6736b47e Clean up and colorized restat text in chat 2026-01-25 12:23:49 -05:00
NepDisk
62fb7b665b move restat stuff to server registration 2026-01-24 20:18:33 -05:00
NepDisk
6db9a16a48 Update hashes 2026-01-24 19:56:04 -05:00
NepDisk
2279180d5c Remove extra branch from R_GetThingFade 2026-01-24 19:50:49 -05:00
NepDisk
5939daa639 Merge pull request '[ENHANCEMENT] v1 Hitconfirm Toggle' (#212) from hitconfirm into next
Reviewed-on: https://codeberg.org/NepDisk/blankart/pulls/212
2026-01-25 01:29:51 +01:00
minenice55
04924745ef Merge branch 'next' into hitconfirm 2026-01-24 22:29:08 +01:00
NepDisk
533d3b0ce6 Use a switch statement for this check 2026-01-24 16:08:53 -05:00
NepDisk
a7196d0106 Add more indication for restated players 2026-01-24 16:01:42 -05:00
minenice55
772ad54efc fix swapping skins mid-game removing restat 2026-01-24 15:44:33 -05:00
minenice55
fa596d321d client side v1 hitem sound 2026-01-24 15:38:16 -05:00
minenice55
36037bc8dd move hitem victim and timer to client side effects 2026-01-24 15:33:57 -05:00
NepDisk
96e81b1807 Also apply player fading to followers 2026-01-24 15:26:55 -05:00
minenice55
90fdec38dc Merge pull request '[FEAT] Hardcoded Restat' (#211) from hardcode-restat into next
Reviewed-on: https://codeberg.org/NepDisk/blankart/pulls/211
2026-01-24 21:10:48 +01:00
minenice55
ca173bdd91 Merge branch 'next' into hardcode-restat 2026-01-24 20:55:35 +01:00
minenice55
60e5fc65ca move restat logging elsewhere to fix cond 2026-01-24 14:51:24 -05:00
minenice55
81ce7d0087 check jointime here by suggestion 2026-01-24 12:37:33 -05:00
minenice55
543b454978 fix notify printing lterally everyone's stats
also add a toggle for server hosts to disable the message
2026-01-23 20:02:22 -05:00
minenice55
30815b240d apparently this runs even when the player slot is vacant 2026-01-23 18:38:44 -05:00
minenice55
7bd4c0195b broadcast stat changes in chat (make this a server toggle) 2026-01-23 18:30:06 -05:00
minenice55
9411c90b79 kick players that send illegal restat commands 2026-01-23 18:17:01 -05:00
minenice55
d7ab39bc4e Merge branch 'next' into hardcode-restat 2026-01-23 18:26:40 +01:00
minenice55
9eb0b6fd2d Merge branch 'next' into hardcode-restat 2026-01-12 00:05:35 +01:00
minenice55
4c83617de2 make restat and allowrestat functional 2026-01-10 21:55:39 -05:00
minenice55
74a5212c8d get this buildable 2026-01-10 20:32:08 -05:00
minenice55
4b2f9bf839 set the restat stats 2026-01-07 02:12:11 -05:00
minenice55
c408f6963e rough command implementation
haven't tested yet will need to actually implement the restat
2026-01-07 01:57:29 -05:00
minenice55
2a1e8b54f0 cmd 2026-01-06 02:23:40 -05:00
minenice55
74295638e3 start this while I can 2026-01-05 22:17:50 -05:00
1245 changed files with 7036 additions and 367611 deletions

4
.gitmodules vendored Normal file
View file

@ -0,0 +1,4 @@
[submodule "thirdparty/miniupnp"]
path = thirdparty/miniupnp
url = https://github.com/miniupnp/miniupnp.git

View file

@ -748,7 +748,7 @@ before_script:
-DSRB2_ASSET_DIRECTORY="${SRB2_ASSET_DIRECTORY}"
-DCPACK_PACKAGE_DESCRIPTION_SUMMARY="${PROGRAM_NAME}"
-DCPACK_PACKAGE_VENDOR="${PROGRAM_VENDOR}"
-DSRB2_SDL2_EXE_NAME="${PROGRAM_FILENAME}"
-DBLANKART_EXE_NAME="${PROGRAM_FILENAME}"
script:
# Build our Makefile from Cmake!

View file

@ -1,5 +1,10 @@
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9")
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
endif()
if("${CMAKE_CURRENT_BINARY_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
message(FATAL_ERROR "In-source builds are blocked. Please build from a separate directory.")
endif()
@ -39,8 +44,8 @@ if("${SRB2_CPACK_GENERATOR}" STREQUAL "")
endif()
set(CPACK_GENERATOR ${SRB2_CPACK_GENERATOR})
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "SRB2Kart" CACHE STRING "Program name for display purposes")
set(CPACK_PACKAGE_VENDOR "Kart Krew" CACHE STRING "Vendor name for display purposes")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "BlanKart" CACHE STRING "Program name for display purposes")
set(CPACK_PACKAGE_VENDOR "Team BlanKart" CACHE STRING "Vendor name for display purposes")
#set(CPACK_PACKAGE_DESCRIPTION_FILE )
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
set(CPACK_PACKAGE_VERSION_MAJOR ${SRB2_VERSION_MAJOR})
@ -75,7 +80,6 @@ option(SRB2_CONFIG_ENABLE_DISCORDRPC "Enable Discord RPC features" ON)
option(SRB2_CONFIG_STATIC_STDLIB "Link static version of standard library. All dependencies must also be static" ON)
option(SRB2_CONFIG_HWRENDER "Enable hardware render (OpenGL) support" ON)
option(SRB2_CONFIG_USE_GME "Enable GME playback support" ON)
option(SRB2_CONFIG_USE_OPENAL "Enable OpenAL audio backend support" ON)
option(SRB2_CONFIG_STATIC_OPENGL "Enable static linking GL (do not do this)" OFF)
option(SRB2_CONFIG_ERRORMODE "Compile C code with warnings treated as errors." OFF)
option(SRB2_CONFIG_DEBUGMODE "Compile with PARANOIA, ZDEBUG, RANGECHECK and PACKETDROP defined." OFF)
@ -87,10 +91,14 @@ option(SRB2_CONFIG_PROFILEMODE "Compile for profiling (GCC only)." OFF)
option(SRB2_CONFIG_TRACY "Compile with Tracy profiling enabled" OFF)
option(SRB2_CONFIG_ASAN "Compile with AddressSanitizer (libasan)." OFF)
option(SRB2_CONFIG_UBSAN "Compile with UndefinedBehaviorSanitizer (libubsan)." OFF)
option(SRB2_CONFIG_LSAN "Compile with LeakSanitizer (liblsan)." OFF)
option(SRB2_CONFIG_TSAN "Compile with ThreadSanitizer (libtsan)." OFF)
option(SRB2_CONFIG_MSAN "Compile with MemorySanitizer (libmsan)." OFF)
option(SRB2_CONFIG_NOVERIFYIWADS "Compile with IWAD verification turned off." OFF)
set(SRB2_CONFIG_ASSET_DIRECTORY "" CACHE PATH "Path to directory that contains all asset files for the installer. If set, assets will be part of installation and cpack.")
option(SRB2_CONFIG_LTO "Enable link time optimizations, improves performance at the cost of longer link times." ON)
option(SRB2_CONFIG_TIDY "Enable clang tiny, checks compiled code for issues at the cost of longer compile times." OFF)
option(SRB2_CONFIG_UPNP "Enable UPnP support for networking." ON)
if(SRB2_CONFIG_ENABLE_TESTS)
# https://github.com/catchorg/Catch2
@ -139,16 +147,15 @@ add_subdirectory(thirdparty)
if("${SRB2_CONFIG_SYSTEM_LIBRARIES}")
find_package(ZLIB REQUIRED)
find_package(PNG REQUIRED)
find_package(SDL2 REQUIRED)
if (NOT "${SRB2_CONFIG_USE_OPENAL}")
find_package(SDL2_mixer REQUIRED)
endif()
find_package(SDL3 REQUIRED)
find_package(CURL REQUIRED)
find_package(OPENMPT REQUIRED)
if("${SRB2_CONFIG_USE_GME}")
find_package(libgme QUIET)
endif()
find_package(DiscordRPC REQUIRED)
if("${SRB2_CONFIG_UPNP}")
find_package(miniupnpc REQUIRED)
endif()
endif()
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
@ -177,15 +184,14 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
set(CMAKE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
# Set EXE names so the assets CMakeLists can refer to its target
set(SRB2_SDL2_EXE_NAME "" CACHE STRING "Override executable binary output name")
set(SRB2_SDL2_EXE_SUFFIX "" CACHE STRING "Optional executable suffix, separated by an underscore")
set(BLANKART_EXE_NAME "" CACHE STRING "Override executable binary output name")
set(BLANKART_EXE_SUFFIX "" CACHE STRING "Optional executable suffix, separated by an underscore")
include_directories(${CMAKE_CURRENT_BINARY_DIR}/src)
add_subdirectory(src)
add_subdirectory(assets)
## config.h generation
set(GIT_EXECUTABLE "git" CACHE FILEPATH "Path to git binary")
include(GitUtilities)
@ -197,17 +203,21 @@ set(SRB2_COMP_REVISION "${SRB2_COMP_COMMIT}")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/src/config.h)
if("${SRB2_SDL2_EXE_NAME}" STREQUAL "")
if("${BLANKART_EXE_NAME}" STREQUAL "")
list(APPEND EXE_NAME_PARTS "blankart")
if(NOT "${SRB2_GIT_BRANCH}" STREQUAL "master")
if(NOT "${SRB2_GIT_BRANCH}" STREQUAL "master" AND NOT SRB2_CONFIG_COMPILEAPPIMAGE)
list(APPEND EXE_NAME_PARTS ${SRB2_GIT_BRANCH})
endif()
if(SRB2_CONFIG_COMPILEAPPIMAGE AND "${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
list(APPEND EXE_NAME_PARTS "appimagebuild")
endif()
else()
list(APPEND EXE_NAME_PARTS ${SRB2_SDL2_EXE_NAME})
list(APPEND EXE_NAME_PARTS ${BLANKART_EXE_NAME})
endif()
list(APPEND EXE_NAME_PARTS ${SRB2_SDL2_EXE_SUFFIX})
list(APPEND EXE_NAME_PARTS ${BLANKART_EXE_SUFFIX})
list(JOIN EXE_NAME_PARTS "_" EXE_NAME)
set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME ${EXE_NAME})
set_target_properties(BLANKART PROPERTIES OUTPUT_NAME ${EXE_NAME})

View file

@ -1621,10 +1621,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
Public Domain
applies to:
- win_iconv
Yukihiro Nakadaira <yukihiro.nakadaira@gmail.com>
win_iconv is placed in the public domain.
https://github.com/win-iconv/win-iconv
- libmodplug
ModPlug-XMMS and libmodplug are now in the public domain.
@ -1635,13 +1631,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
zlib License
applies to:
- Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
https://www.libsdl.org/hg.php
- SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
https://www.libsdl.org/projects/SDL_mixer/
- zlib-ng
Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler
https://github.com/zlib-ng/zlib-ng

View file

@ -9,13 +9,15 @@ If you're interested in helping out, theres a matrix room located [here](https:/
This is still in active development and things are going to change. If you find any bugs besure to report to the [issue tracker](https://codeberg.org/NepDisk/blankart/issues)!
## Techincal Features
- Entire refactorings of internal systems such as the item system, the menu system, the demo system and many more for easier maintainability.
- Full Support for UDMF, Terrain, Bots, ACS, New Waypoints and many other technical features backported from Ring Racers. Also includes some extensions to these features such as bot drifting, new terrain effects and map header toggles.
- Ring Racers' software renderer and its multithreading.
- Native support for both SRB2Kart and Ring Racers custom skins.
- Ring Racers' software renderer and its multithreading as a base for the software renderer with many additions ported from SRB2Kart Saturn and SRB2Classic.
- Improved OpenGL Renderer based on some changes from SRB2Kart Saturn with support for features such as palette rendering.
- Native support for both SRB2Kart and Ring Racers custom skins and followers.
- Backwards compatiblity with most SRB2Kart maps, assets* and scripts\*.
- A map patching system to allow custom map things to be patched onto maps. Useful for adding rings, waypoints and other objects to existing maps.
- Support for many SRB2Kart v1 custom client extensions from Saturn and other clients such as vote themes.
- A hardcoded Lua library for adding custom boosts and boost chains to the game.
- Many Lua and SOC additions for things such as adding custom boosts, custom boost chains, custom items+odds, custom menus, and many more things.
*Art assets are remapped from the SRB2Kart v1 palette to the SRB2 2.2 palette automatically based on addon file name. This also affects scripts as well making them run as they would in SRB2Kart v1. Having the K prefix or the .kart extension triggers this. You can also do addfile -c to enable it or addfile -n to disable it.
@ -25,28 +27,33 @@ This is still in active development and things are going to change. If you find
- Many features ported from Saturn
## Optional Gameplay Features
- Rings (Based on how they were in v2 Indev and then further rebalanced)
- New items (Such as the as a rebalanced Flame Shield and a rebalanced Bubble Shield)
- Rings (Based on how they were in Indev v2 and then further rebalanced)
- New items (Such as the as a reworked Flame Shield and a reworked Bubble Shield)
- Alternative Item system that allows new varients of specfic items (Such as Eggman and Invincibility)
- 4 tier drifts (Blue, Red, Purple, Rainbow)
- Boost Stacking
- Boost Chaining
- Boost Stacking + Boost Chaining
- Slipdashing
- Drafting
- Air Thrust
- Air Drop
- Recovery Dash
## Dependencies
- SDL2 (Linux/OS X only)
- SDL3 (Linux/OS X only)
- libsndfile (Linux/OS X only)
- openAL/openAL-Soft (Linux/OS X only)
- OpenAL-Soft (Linux/OS X only)
- libupnp (Linux/OS X only)
- libgme (Linux/OS X only)
- libopenmpt (Linux/OS X only)
## Compiling
Notice: MSVC is unsupported!
### Notice
MSVC is unsupported, so please use GCC, Clang or Zig as your compiler.
Linux:
```
git clone https://codeberg.org/NepDisk/blankart.git
git clone --recursive https://codeberg.org/NepDisk/blankart.git
cd blankart
mkdir build
cd build
@ -57,7 +64,7 @@ make -j$(nproc)
Windows MSYS2:
```
git clone https://codeberg.org/NepDisk/blankart.git
git clone --recursive https://codeberg.org/NepDisk/blankart.git
cd blankart
mkdir build
cd build

340
appimage_build.sh Executable file
View file

@ -0,0 +1,340 @@
#!/bin/bash
set -e # Enable auto-exit for debugging :))
# Make Linux AppImage program data
# https://docs.appimage.org/reference/appdir.html
# PWD: {repo_root}/build
# See deployer.sh for usage
# Terminal stuff
RESET="$(tput sgr0)" #"\e[0m" # Resets terminal colors
# Colors for various information types
FAILURE="$(tput setaf 1)" #"\e[91m"
SUCCESS="$(tput setaf 2)" #"\e[92m"
NOTICE="$(tput setaf 3)" #"\e[93m"
VERBOSE="$(tput setaf 4)" #"\e[94m"
verbosity=0 # By default don't print anything unless it's *ultra* important.
quiet=0 # Also don't print anything if they supplied the quiet argument
# URL from which to download appimagetool if there isn't one available in your $PATH
# at time of writing only aarch64, armhf, i686, and x86_64 versions are available via this method
# in those cases, and honestly even outside of those cases, it's better to just put a working one in your $PATH yourself..
url="https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-$(uname -m).AppImage"
# A whitelist of libraries to include into BlanKart's AppImage if BlanKart is dynamically linked.
# please don't add a newline at the end of this or i will cry :(
libraryWhitelist="
libSDL3
libopenal
libgme
libopenmpt
libpng
libpng16
libFLAC
libmpg123
libmp3lame
libogg
libvorbis
libvorbisfile
libvorbisenc
libopus
libsndfile
libjson
libreadline
libwrap
libtinfo
libtirpc"
# these kinda look like macros don't they
function print { (( "$quiet" == 0 )) && echo "$@" || :; } # echo if not quiet
function coloredText { printf "$1"; print "${@:2}"; printf "$RESET"; } # use print to inherit quiet
function success { coloredText "$SUCCESS" "$@"; } # use coloredText to inherit quiet
function important { coloredText "$NOTICE" "$@"; } # use coloredText to inherit quiet
function verboseOnly { (( "$verbosity" >= $1 )) && (coloredText "$VERBOSE" "${@:2}") || :; } # use coloredText to inherit quiet
# Parses an argument with a single dash
function parseSingleDashArg() {
while read -n 1 char; do
if [[ "$char" == '-' || "$char" == '' ]]; then
:
elif [[ "$char" == 'h' ]]; then
helppassed=1
elif [[ "$char" == 'q' ]]; then
quiet=1
elif [[ "$char" == 'v' ]]; then
verbosity="$((verbosity + 1))"
elif [[ "$char" == 'd' ]]; then
dry=1
elif [[ "$char" == 's' ]]; then
small=1
else
echo "$0: invalid option -- '$1'"
echo "Try '$0 --help' for more information."
return 1
fi
done <<<"$1"
}
# Simple help argument checker.
currentarg=1; # Which argument is --help...
# For $arg in the argument array...
for arg in "$@"; do
# Is it a help argument?
if [[ "$arg" == "--help" ]]; then
helppassed=1; # Help is passed, set $helppassed!
set -- "${@:1:$currentarg-1}" "${@:$currentarg+1}" # Remove argument from list
elif [[ "$arg" == "--quiet" ]]; then
quiet=1
set -- "${@:1:$currentarg-1}" "${@:$currentarg+1}"
elif [[ "$arg" == "--verbose" ]]; then
verbosity="$((verbosity + 1))" # Increase verbosity!
set -- "${@:1:$currentarg-1}" "${@:$currentarg+1}"
elif [[ "$arg" == "--dry" ]]; then
dry=1; # Show parameters instead of using them.
set -- "${@:1:$currentarg-1}" "${@:$currentarg+1}"
elif [[ "$arg" == "--small" ]]; then
small=1; # Don't copy assets to save on bandwidth.
set -- "${@:1:$currentarg-1}" "${@:$currentarg+1}"
elif [[ ! "$arg" == *'--'* && "$arg" == *'-'* ]]; then
parseSingleDashArg "$arg"
if [[ "$?" == 0 ]]; then
set -- "${@:1:$currentarg-1}" "${@:$currentarg+1}" # Remove argument from list
fi
elif [[ $arg == *'--'* ]]; then
print "$0: invalid option -- '$1'"
print "Try '$0 --help' for more information."
return 1
else
currentarg="$((currentarg+1))" # Increment current argument number otherwise...
fi
done
important "BlanKart AppImage Packager v1.0."
important "Modified by Team BlanKart."
important "Original for SRB2 my mazmazz and Golden."
# Get root directory from the full path of this script.
__ROOT_DIR="$3"
if [[ -z "$3" ]]; then
# finds out where this script is and goes to that directory and goes up one for the root
scriptdir="$(dirname "${BASH_SOURCE[0]}")"
scriptbase="$(basename "${BASH_SOURCE[0]}")"
__ROOT_DIR="$(cd "$scriptdir" && pwd -P)"
fi
# If it starts with '.', put the current working directory behind it so things work.
if [[ "$__ROOT_DIR" == '.' || "$__ROOT_DIR" == '..' ]]; then
__ROOT_DIR="$PWD/$__ROOT_DIR"
fi
# Set up defaults
__PROGRAM_NAME="${PROGRAM_NAME:-"BlanKart"}"
__PROGRAM_DESCRIPTION="${PROGRAM_DESCRIPTION:-"BlanKart"}"
__PROGRAM_FILENAME="${PROGRAM_FILENAME:-"blankart_appimagebuild"}"
__PROGRAM_ASSETS="${PROGRAM_ASSETS:-"$__ROOT_DIR/assets/installer"}"
__BUILD_DIR="${1:-"$__ROOT_DIR/build/bin"}"
__OUTPUT_FILENAME="${2:-"$__PROGRAM_FILENAME.AppImage"}"
__APPIMAGETOOL="${4:-"appimagetool"}"
if (! command -v "$__APPIMAGETOOL" &> /dev/null); then
__APPIMAGETOOL=
fi
# Stuff that prints and exits.
# Prints setup text using method given by arguments.
# Example: printSetup "print" # print "Setup for AppImage...
function printSetup {
$@ "Setup for AppImage in BUILD_DIR: '$__BUILD_DIR'..."
$@ "With the OUTPUT_FILENAME: '$__OUTPUT_FILENAME'"
$@ "And BlanKart Repository Root ROOT_DIR: '$__ROOT_DIR'"
$@ "Using APPIMAGETOOL: '$([ -z "$__APPIMAGETOOL" ] && echo '(download)' || echo $__APPIMAGETOOL)'"
$@ ""
$@ "This should be run from a Makefile or from the directory of the build. If it is not, then change to that directory or specify that directory as an argument."
$@ "If ROOT_DIR isn't BlanKart's repository root, specify that as an argument too."
$@ "Make must have built the program before you run this script."
$@ ""
$@ "Make sure these Environment Variables are correct."
$@ "If not, then enter: export PROGRAM_VARIABLE=value"
$@ "PROGRAM_NAME: $__PROGRAM_NAME"
$@ "PROGRAM_DESCRIPTION: $__PROGRAM_DESCRIPTION"
$@ "PROGRAM_FILENAME: $__PROGRAM_FILENAME"
$@ "PROGRAM_ASSETS: $__PROGRAM_ASSETS"
}
if [[ "$helppassed" ]]; then
print "Usage: $(basename "$0") [OPTION]... [BUILD_DIR] [OUTPUT_NAME] [ROOT_DIR] [APPIMAGETOOL]"
print "Packages a BlanKart binary into an AppImage."
print "OPTIONs may be included anywhere within the arguments."
print ""
print "Arguments:"
print " -h, --help display this help and exit."
print " -q, --quiet don't display any text."
print " -v, --verbose make commands more verbose, will always print."
print " -s, --small don't copy BlanKart assets to save on bandwidth."
print " parameters regardless of --dry."
print " -d, --dry print parameters and exit."
print ""
if (( "$verbosity" > 0 )) || [[ "$dry" ]]; then
printSetup "print"
else
print "This should be run from a Makefile or from the directory of the build."
print "Make must have built the program before you run this script."
fi
exit;
fi
if (( "$verbosity" > 0 )) || [[ "$dry" ]]; then
printSetup "verboseOnly" "0"
verboseOnly 0 ""
if [[ "$dry" ]]; then
set -n # Enable debug mode and verbose for dry run.
fi
fi
# End stuff that prints and exits.
if (( "$verbosity" >= 4 )); then
set -v # Really verbose? Print *everything*!
fi
# Define AppDir structure
mkdir -p "$__BUILD_DIR/AppDir/usr/bin"
mkdir -p "$__BUILD_DIR/AppDir/lib"
mkdir -p "$__BUILD_DIR/AppDir/usr/share/applications"
mkdir -p "$__BUILD_DIR/AppDir/usr/share/icons/hicolor/256x256/apps"
# Copy program data
if [[ ! $small ]]; then
verboseOnly 1 "Packaging program assets..."
cp -r "$__PROGRAM_ASSETS"/* "$__BUILD_DIR/AppDir/usr/bin/"
cp -r "$__BUILD_DIR/$__PROGRAM_FILENAME" "$__BUILD_DIR/AppDir/usr/bin"
else
verboseOnly 1 "Skipping program asset packing, --small or -s passed..."
fi
verboseOnly 1 "Packaging BlanKart..."
verboseOnly 1 "Assuming executable name $__PROGRAM_FILENAME"
cp -r "$__BUILD_DIR/$__PROGRAM_FILENAME" "$__BUILD_DIR/AppDir/usr/bin"
# Copy required dependencies, but only if the program is dynamically linked.
verboseOnly 1 "Testing if this build is dynamically linked..."
set +e # Disable auto-exit for ldd.
srb2Libraries="$(ldd "$__BUILD_DIR/$__PROGRAM_FILENAME")"
exitcode="$?"
set -e # Enable it again!
if (( $exitcode == 0 )); then
verboseOnly 1 "This build *is* dynamically linked! Packaging dependencies."
# read the dynamic libraries of blankart, trim off beginning whitespace, and get the third field seperated by spaces
# this gives us a newline-seperated list of libraries with their full paths.
srb2Libraries="$(echo "$srb2Libraries" | cut -f 2 | cut -d ' ' -f 3)"
# remove any extraneous newlines around the string
libraryWhitelist="$(echo $libraryWhitelist | head -c -1 | tr ' ' '\n')"
# replace e.g. 'abc' with '(/abc\b)', and replace newlines with '|'.
# this converts it into a grep regular expression to check for any whitelisted library names.
libraryWhitelist="$(printf "%s" "$libraryWhitelist" | sed 's|.*|(/\0\\b)|' | tr '\n' '|')"
# grab only the entries that match the regex
__LDD_LIST="$(printf "%s" "$srb2Libraries" | grep -E "$libraryWhitelist")"
# use echo to convert the newline-seperated list into an argument list
__LDD_LIST="$(echo $__LDD_LIST)"
# read into an array because i can't be bothered iterating the lines of a string today
# there's so many other things in this file that'd need to be adjusted to be POSIX-compliant anyway
IFS=' ' read -r -a paths <<< "$__LDD_LIST"
for path in "${paths[@]}"; do
if [ -f "$path" ]; then
verboseOnly 2 "Packaging dependency $(basename "$path")..."
cp "$path" $__BUILD_DIR/AppDir/lib/
else
verboseOnly 2 "Dependency $(basename "$path") not found"
fi
done
else
verboseOnly 1 "This BlanKart build is statically linked, skipping dependency packing."
fi
cd "$__BUILD_DIR/AppDir"
# Copy icons
verboseOnly 1 "Packaging resources..."
cp "$__ROOT_DIR/srb2.png" "./usr/share/icons/hicolor/256x256/apps/$__PROGRAM_FILENAME.png"
ln -sf "./usr/share/icons/hicolor/256x256/apps/$__PROGRAM_FILENAME.png" "./.DirIcon"
ln -sf "./usr/share/icons/hicolor/256x256/apps/$__PROGRAM_FILENAME.png" "./$__PROGRAM_FILENAME.png"
# Make desktop descriptor
cat > "./usr/share/applications/$__PROGRAM_FILENAME.desktop" <<EOF
[Desktop Entry]
Type=Application
Name=$__PROGRAM_NAME
Comment=$__PROGRAM_DESCRIPTION
Icon=$__PROGRAM_FILENAME
Exec=AppRun %F
Categories=Game;
EOF
ln -sf "./usr/share/applications/$__PROGRAM_FILENAME.desktop" "./$__PROGRAM_FILENAME.desktop"
# Make entry point
echo -e '#!'"$(dirname "$SHELL")/sh" > ./AppRun
echo -e 'HERE="$(dirname "$(readlink -f "${0}")")"' >> ./AppRun
echo -e 'SRB2WADDIR=$HERE/usr/bin LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HERE/lib exec $HERE/usr/bin/'"$__PROGRAM_FILENAME"' "$@"' >> ./AppRun
chmod +x ./AppRun
cd .. # now in $__BUILD_DIR
# Package AppImage
if [ -z "$__APPIMAGETOOL" ]; then
verboseOnly 1 "No valid appimagetool path given or detected, downloading appimagetool..."
# Print notice for internet connection.
important "If the command hangs here, check your internet connection, or download appimagetool and add it to your \$PATH and try compiling again."
(( "$verbosity" >= 3 )) && wget "$url" || wget -q "$url"
APPIMAGETOOL="./$(basename "$url")"
chmod a+x "$APPIMAGETOOL"
else
verboseOnly 1 "appimagetool path given or detected, no download required."
APPIMAGETOOL="$__APPIMAGETOOL"
fi
verboseOnly 1 "Packing AppImage $__OUTPUT_FILENAME"
if (( verbosity >= 3 )); then
"$APPIMAGETOOL" ./AppDir "$__OUTPUT_FILENAME"
elif (( verbosity >= 2 )); then
"$APPIMAGETOOL" ./AppDir "$__OUTPUT_FILENAME" >/dev/null
else
"$APPIMAGETOOL" ./AppDir "$__OUTPUT_FILENAME" >/dev/null 2>&1
fi
success "AppImage ready!"
verboseOnly 1 "Cleaning up files..."
rm -r ./AppDir
if [ -z "$__APPIMAGETOOL" ]; then
rm "$APPIMAGETOOL"
fi
cd "$__ROOT_DIR" # snap back to reality

View file

@ -43,7 +43,7 @@ set(SRB2_ASSETS ${SRB2_ASSET_DOCS} ${SRB2_ASSETS_GAME})
# Installation
if(${CMAKE_SYSTEM} MATCHES Darwin)
get_target_property(outname SRB2SDL2 OUTPUT_NAME)
get_target_property(outname BLANKART OUTPUT_NAME)
install(FILES ${SRB2_ASSETS} DESTINATION "${outname}.app/Contents/Resources")
install(DIRECTORY "${SRB2_ASSET_DIRECTORY_ABSOLUTE}/models" DESTINATION "${outname}.app/Contents/Resources")
install(FILES ${SRB2_ASSETS_DOCS} DESTINATION .)

View file

@ -1,33 +0,0 @@
include(LibFindMacros)
libfind_pkg_check_modules(DISCORDRPC_PKGCONF DISCORDRPC)
find_path(DISCORDRPC_INCLUDE_DIR
NAMES discord_rpc.h
PATHS
${DISCORDRPC_PKGCONF_INCLUDE_DIRS}
"/usr/include"
"/usr/local/include"
)
find_library(DISCORDRPC_LIBRARY
NAMES discord-rpc
PATHS
${DISCORDRPC_PKGCONF_LIBRARY_DIRS}
"/usr/lib"
"/usr/local/lib"
)
set(DISCORDRPC_PROCESS_INCLUDES DISCORDRPC_INCLUDE_DIR)
set(DISCORDRPC_PROCESS_LIBS DISCORDRPC_LIBRARY)
libfind_process(DISCORDRPC)
if(DISCORDRPC_FOUND AND NOT TARGET DiscordRPC::DiscordRPC)
add_library(DiscordRPC::DiscordRPC UNKNOWN IMPORTED)
set_target_properties(
DiscordRPC::DiscordRPC
PROPERTIES
IMPORTED_LOCATION "${DISCORDRPC_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${DISCORDRPC_INCLUDE_DIR}"
)
endif()

View file

@ -1,43 +0,0 @@
# Find SDL2
# Once done, this will define
#
# SDL2_FOUND - system has SDL2
# SDL2_INCLUDE_DIRS - SDL2 include directories
# SDL2_LIBRARIES - link libraries
include(LibFindMacros)
libfind_pkg_check_modules(SDL2_PKGCONF SDL2)
# includes
find_path(SDL2_INCLUDE_DIR
NAMES SDL.h
PATHS
${SDL2_PKGCONF_INCLUDE_DIRS}
"/usr/include/SDL2"
"/usr/local/include/SDL2"
)
# library
find_library(SDL2_LIBRARY
NAMES SDL2
PATHS
${SDL2_PKGCONF_LIBRARY_DIRS}
"/usr/lib"
"/usr/local/lib"
)
# set include dir variables
set(SDL2_PROCESS_INCLUDES SDL2_INCLUDE_DIR)
set(SDL2_PROCESS_LIBS SDL2_LIBRARY)
libfind_process(SDL2)
if(SDL2_FOUND AND NOT TARGET SDL2::SDL2)
add_library(SDL2::SDL2 UNKNOWN IMPORTED)
set_target_properties(
SDL2::SDL2
PROPERTIES
IMPORTED_LOCATION "${SDL2_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIR}"
)
endif()

View file

@ -1,34 +0,0 @@
# Find SDL2
# Once done, this will define
#
# SDL2_MAIN_FOUND - system has SDL2
# SDL2_MAIN_INCLUDE_DIRS - SDL2 include directories
# SDL2_MAIN_LIBRARIES - link libraries
include(LibFindMacros)
libfind_pkg_check_modules(SDL2_MAIN_PKGCONF SDL2)
# includes
find_path(SDL2_MAIN_INCLUDE_DIR
NAMES SDL.h
PATHS
${SDL2_MAIN_PKGCONF_INCLUDE_DIRS}
"/usr/include/SDL2"
"/usr/local/include/SDL2"
)
# library
find_library(SDL2_MAIN_LIBRARY
NAMES SDL2_main
PATHS
${SDL2_MAIN_PKGCONF_LIBRARY_DIRS}
"/usr/lib"
"/usr/local/lib"
)
# set include dir variables
set(SDL2_MAIN_PROCESS_INCLUDES SDL2_MAIN_INCLUDE_DIR)
set(SDL2_MAIN_PROCESS_LIBS SDL2_MAIN_LIBRARY)
libfind_process(SDL2_MAIN)

View file

@ -1,44 +0,0 @@
# Find SDL2
# Once done, this will define
#
# SDL2_MIXER_FOUND - system has SDL2
# SDL2_MIXER_INCLUDE_DIRS - SDL2 include directories
# SDL2_MIXER_LIBRARIES - link libraries
include(LibFindMacros)
libfind_pkg_check_modules(SDL2_MIXER_PKGCONF SDL2_mixer)
# includes
find_path(SDL2_MIXER_INCLUDE_DIR
NAMES SDL_mixer.h
PATHS
${SDL2_MIXER_PKGCONF_INCLUDE_DIRS}
"/usr/include/SDL2"
"/usr/local/include/SDL2"
)
# library
find_library(SDL2_MIXER_LIBRARY
NAMES SDL2_mixer
PATHS
${SDL2_MIXER_PKGCONF_LIBRARY_DIRS}
"/usr/lib"
"/usr/local/lib"
)
# set include dir variables
set(SDL2_MIXER_PROCESS_INCLUDES SDL2_MIXER_INCLUDE_DIR)
set(SDL2_MIXER_PROCESS_LIBS SDL2_MIXER_LIBRARY)
libfind_process(SDL2_MIXER)
if(SDL2_MIXER_FOUND AND NOT TARGET SDL2_mixer::SDL2_mixer)
add_library(SDL2_mixer::SDL2_mixer UNKNOWN IMPORTED)
set_target_properties(
SDL2_mixer::SDL2_mixer
PROPERTIES
IMPORTED_LOCATION "${SDL2_MIXER_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${SDL2_MIXER_INCLUDE_DIR}"
)
endif()

View file

@ -0,0 +1,43 @@
# Find SDL3
# Once done, this will define
#
# SDL3_FOUND - system has SDL3
# SDL3_INCLUDE_DIRS - SDL3 include directories
# SDL3_LIBRARIES - link libraries
include(LibFindMacros)
libfind_pkg_check_modules(SDL3_PKGCONF SDL3)
# includes
find_path(SDL3_INCLUDE_DIR
NAMES SDL.h
PATHS
${SDL3_PKGCONF_INCLUDE_DIRS}
"/usr/include/SDL3"
"/usr/local/include/SDL3"
)
# library
find_library(SDL3_LIBRARY
NAMES SDL3
PATHS
${SDL2_PKGCONF_LIBRARY_DIRS}
"/usr/lib"
"/usr/local/lib"
)
# set include dir variables
set(SDL3_PROCESS_INCLUDES SDL3_INCLUDE_DIR)
set(SDL3_PROCESS_LIBS SDL3_LIBRARY)
libfind_process(SDL3)
if(SDL3_FOUND AND NOT TARGET SDL3::SDL3)
add_library(SDL3::SDL3 UNKNOWN IMPORTED)
set_target_properties(
SDL3::SDL3
PROPERTIES
IMPORTED_LOCATION "${SDL3_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${SDL3_INCLUDE_DIR}"
)
endif()

View file

@ -0,0 +1,34 @@
# Find SDL3
# Once done, this will define
#
# SDL3_MAIN_FOUND - system has SDL3
# SDL3_MAIN_INCLUDE_DIRS - SDL3 include directories
# SDL3_MAIN_LIBRARIES - link libraries
include(LibFindMacros)
libfind_pkg_check_modules(SDL3_MAIN_PKGCONF SDL3)
# includes
find_path(SDL3_MAIN_INCLUDE_DIR
NAMES SDL.h
PATHS
${SDL3_MAIN_PKGCONF_INCLUDE_DIRS}
"/usr/include/SDL3"
"/usr/local/include/SDL3"
)
# library
find_library(SDL3_MAIN_LIBRARY
NAMES SDL3_main
PATHS
${SDL3_MAIN_PKGCONF_LIBRARY_DIRS}
"/usr/lib"
"/usr/local/lib"
)
# set include dir variables
set(SDL3_MAIN_PROCESS_INCLUDES SDL3_MAIN_INCLUDE_DIR)
set(SDL3_MAIN_PROCESS_LIBS SDL3_MAIN_LIBRARY)
libfind_process(SDL3_MAIN)

View file

@ -0,0 +1,33 @@
include(LibFindMacros)
libfind_pkg_check_modules(Vorbis_PKGCONF Vorbis)
find_path(Vorbis_INCLUDE_DIR
NAMES vorbis/codec.h
PATHS
${Vorbis_PKGCONF_INCLUDE_DIRS}
"/usr/include"
"/usr/local/include"
)
find_library(Vorbis_LIBRARY
NAMES vorbis
PATHS
${Vorbis_PKGCONF_LIBRARY_DIRS}
"/usr/lib"
"/usr/local/lib"
)
set(Vorbis_PROCESS_INCLUDES Vorbis_INCLUDE_DIR)
set(Vorbis_PROCESS_LIBS Vorbis_LIBRARY)
libfind_process(Vorbis)
if(Vorbis_FOUND AND NOT TARGET Vorbis::vorbis)
add_library(Vorbis::vorbis UNKNOWN IMPORTED)
set_target_properties(
Vorbis::vorbis
PROPERTIES
IMPORTED_LOCATION "${Vorbis_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${Vorbis_INCLUDE_DIR}"
)
endif()

View file

@ -0,0 +1,39 @@
include(LibFindMacros)
libfind_pkg_check_modules(libminiupnpc_PKGCONF miniupnpc libminiupnpc)
find_path(libminiupnpc_INCLUDE_DIR
NAMES miniupnpc.h
PATHS
${libminiupnpc_PKGCONF_INCLUDE_DIRS}
"${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include"
"/usr/include"
"/usr/local/include"
PATH_SUFFIXES
miniupnpc
)
find_library(libminiupnpc_LIBRARY
NAMES miniupnpc
PATHS
${libminiupnpc_PKGCONF_LIBRARY_DIRS}
"/usr/lib"
"/usr/local/lib"
)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(miniupnpc
REQUIRED_VARS libminiupnpc_LIBRARY libminiupnpc_INCLUDE_DIR)
if(miniupnpc_FOUND AND NOT TARGET miniupnpc)
add_library(miniupnpc UNKNOWN IMPORTED)
set_target_properties(
miniupnpc
PROPERTIES
IMPORTED_LOCATION "${libminiupnpc_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${libminiupnpc_INCLUDE_DIR}"
)
add_library(miniupnpc::miniupnpc ALIAS miniupnpc)
endif()
mark_as_advanced(libminiupnpc_LIBRARY libminiupnpc_INCLUDE_DIR)

View file

@ -1,70 +0,0 @@
srb2 for Debian
---------------
SRB2 Debian package!
Hi there, to rebuild these packages just use debuild in the root source directory (not /src!).
You can build these with or without a key if you want, but if you want to put these on a repo,
generate your own GnuPG key as per the https://help.ubuntu.com/community/GnuPrivacyGuardHowto
instructions and pass the -k<keyid> command to debuild. Make sure you export the key footprint
and give them to your users to install with apt-key add. Thanks!
-- Callum Dickinson <gcfreak_ag20@hotmail.com> Fri, 26 Nov 2010 18:25:31 +1300
---------------
Templating
Note that you MUST run [repo-root]/debian_template.sh before running debuild
on these scripts! debian_template.sh fills these template files with working values.
You should also set PACKAGE_NAME_EMAIL="John Doe <jdoe@example.com>" to match
the identity of the key you will use to sign the package.
Building for Launchpad PPA
Use these steps to prepare building a source package for Launchpad:
1. cd [repo-root]
2. git reset --hard; git clean -fd; git clean -fx;
* Resets your repo folder to a committed state and removes untracked files
* If you built srb2-data in the assets/ folder, MAKE SURE THAT FOLDER DOES NOT HAVE ASSETS,
OR THEY MAY BE INCLUDED IN THE MAIN SOURCE PACKAGE!
Build the source package:
1. source [repo-root]/debian_template.sh
* Initializes defaults for the package variables and fills in templates.
2. debuild -S (builds the source package for Launchpad)
Signing for Launchpad PPA
First, follow Callum's instructions to generate a GnuPG key with your identity. You will need
to publish the fingerprint of that key to Ubuntu's key server.
https://help.ubuntu.com/community/GnuPrivacyGuardHowto#Uploading_the_key_to_Ubuntu_keyserver
Next, you will have to add that key fingerprint to your Launchpad account. Go to your Launchpad
profile and click the yellow Edit button next to "OpenPGP keys". Once you add the key, you can
upload signed source packages and publish them onto your PPA.
IF YOU UPLOAD A PACKAGE and Launchpad does NOT send you a confirmation or rejection email, that
means your key is not set up correctly with your Launchpad account.
Finally, if your packages have not already been signed, follow these steps:
1. cd ..
* Packages are located in the parent folder of where debuild was called
2. debsign "srb2_[version]_source.changes"
* You may need to specify -k [key-fingerprint]
Uploading for Launchpad PPA
Follow the instructions at <https://help.launchpad.net/Packaging/PPA/Uploading> to upload
to your PPA and have Launchpad build your binary deb packages.
-- Marco Zafra <marco.a.zafra@gmail.com> Mon, 26 Nov 2018 21:13:00 -0500

View file

@ -1,45 +0,0 @@
srb2 for Debian
---------------
Here it is! SRB2 v2.1.2 source code!
GNU/Linux
~~~
Dependencies:
SDL 1.2.7 or better (from libsdl.org)
SDL_Mixer 1.2.2(.7 for file-less music playback) (from libsdl.org)
libPNG 1.2.7
Zlib 1.2.3
The Xiph.org libogg and libvorbis libraries
The OpenGL headers (from Mesa, usually shipped with your X.org or XFree
installation, so you needn't worry, most likely)
GCC 3.x toolchain and binutils
GNU Make
Build instructions:
make -C src LINUX=1
Build instructions for non-X86 devices (such as X64):
make -C src LINUX=1 NONX86=1
Build instructions to build for Wii Linux/SRB2Wii on a PowerPC system,
follow cross-compiling instructions for cross-compiling on a x86 system:
make -C src LINUX=1 WIILINUX=1
Build instructions to build for Pandora (Linux) on a ARM system,
follow cross-compiling instructions for cross-compiling on a x86 system:
make -C src PANDORA=1
-------------------------------------------------------------------------------
binaries will turn in up in bin/
note: read the src/makefile for more options
- Sonic Team Junior
http://www.srb2.org

View file

@ -1,5 +0,0 @@
${PACKAGE_NAME} (${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}) ${PACKAGE_DISTRO}; urgency=${PACKAGE_URGENCY}
* ${PROGRAM_NAME} v${PROGRAM_VERSION} program build
-- ${PACKAGE_NAME_EMAIL} ${__PACKAGE_DATETIME}

View file

@ -1 +0,0 @@
7

View file

@ -1,53 +0,0 @@
# SRB2 Debian package control file.
Source: ${PACKAGE_NAME}
Section: games
Priority: extra
Maintainer: ${PACKAGE_GROUP_NAME_EMAIL}
Build-Depends: debhelper (>= 7.0.50~),
libsdl2-dev,
libsdl2-mixer-dev,
libpng-dev | libpng16-dev | libpng12-dev (>= 1.2.7),
zlib1g-dev,
libgme-dev,
libcurl4-openssl-dev,
libopenmpt-dev,
libglu1-dev | libglu-dev,
libosmesa6-dev | libgl-dev,
nasm [i386]
Standards-Version: 3.8.4
Homepage: ${PACKAGE_WEBSITE}
Package: ${PACKAGE_NAME}
Architecture: any
Depends: ${SHLIBS_DEPENDS}, ${MISC_DEPENDS},
${PACKAGE_NAME}-data (>> ${PACKAGE_ASSET_MINVERSION}), ${PACKAGE_NAME}-data (<< ${PACKAGE_ASSET_MAXVERSION}),
libsdl2-2.0-0,
libsdl2-mixer-2.0-0,
zlib1g,
libgme0,
libcurl4,
libopenmpt | libopenmpt0,
libpng | libpng16-16 | libpng12-0
Description: A cross-platform 3D Sonic fangame
Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog
fangame built using a modified version of the Doom Legacy
port of Doom. SRB2 is closely inspired by the original
Sonic games from the Sega Genesis, and attempts to recreate
the design in 3D. It features tons of levels, enemies, speed,
and quite a lot of the fun that the original Sonic games provided.
Package: ${PACKAGE_NAME}-dbg
Architecture: any
# FIXME: should be Depends: ${SHLIBS_DEPENDS}, ${MISC_DEPENDS}, srb2-data (= 2.1.14), srb2 but dh_shlibdeps is being an asshat
Depends: libc6, ${MISC_DEPENDS}, ${PACKAGE_NAME}-data (>> ${PACKAGE_ASSET_MINVERSION}), ${PACKAGE_NAME}-data (<< ${PACKAGE_ASSET_MAXVERSION}), ${PACKAGE_NAME}
Description: A cross-platform 3D Sonic fangame
Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog
fangame built using a modified version of the Doom Legacy
port of Doom. SRB2 is closely inspired by the original
Sonic games from the Sega Genesis, and attempts to recreate
the design in 3D. It features tons of levels, enemies, speed,
and quite a lot of the fun that the original Sonic games provided.
This is a debug binary; its symbols will be loaded by gdb
when the user starts the game with gdb for debugging.

View file

@ -1,27 +0,0 @@
This work was packaged for Debian by:
${PACKAGE_NAME_EMAIL} ${__PACKAGE_DATETIME}
It was downloaded from:
${PACKAGE_WEBSITE}
Upstream Author(s):
${PACKAGE_GROUP_NAME_EMAIL}
Copyright:
Copyright (C) 1998-2018 by Sonic Team Junior
License:
GNU General Public License, version 2
The Debian packaging is:
Copyright (C) 2010 Callum Dickinson <gcfreak_ag20@hotmail.com>
Copyright (C) 2010-2018 by Sonic Team Junior <stjr@srb2.org>
and is licensed under the GPL version 2,
see "/usr/share/common-licenses/GPL-2".

View file

@ -1,4 +0,0 @@
README.md
assets/README.txt
assets/LICENSE.txt
assets/LICENSE-3RD-PARTY.txt

View file

@ -1,172 +0,0 @@
#!/usr/bin/make -f
# -*- makefile -*-
#############################################################################
#
# GNU Make Debian package makefile for SRB2
#
# Copyright (C) 1998-2010 by Callum Dickinson
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# This file most likely will not need to be modified to make
# branches of SRB2 capable of making their own Debian packages,
# instead look at the /debian/control file for configuration.
#
#############################################################################
#############################################################################
#
# !!!!!!!!!! DEPLOYER NOTE !!!!!!!!!!
#
# Variables to be templated are curly-braced ${PACKAGE_INSTALL_PATH}
# Variables used by the rules script are parenthese'd $(PKGDIR)
# See [repo-root]/debian_template.sh
#
#############################################################################
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
# user/group of to-be-installed files
ROOT_USER := 0
ROOT_GROUP := 0
# determine cross-compile (may need some work)
CROSS_COMPILE_BUILD := $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
CROSS_COMPILE_HOST := $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
CROSS_COMPILE := $(shell test "$(CROSS_COMPILE_BUILD)" != "$(CROSS_COMPILE_HOST)" && echo "$(CROSS_COMPILE_HOST)")
MKDIR = mkdir -p
MAKE = make
INSTALL = install -o $(ROOT_USER) -g $(ROOT_GROUP) -m 644
MV = mv
RM = rm -rf
STRIPARGS = --strip-unneeded
ifdef CROSS_COMPILE
STRIP = $(CROSS_COMPILE_HOST)-strip $(STRIPARGS)
else
STRIP = strip $(STRIPARGS)
endif
DIR := $(shell pwd)
# FIXME: hate hate hate head/tail hack :(
CONTROLF = $(DIR)/debian/control
PACKAGE = ${PACKAGE_NAME}
DBGPKG = ${PACKAGE}-dbg
TITLE = ${PROGRAM_NAME}
SECTION = Games/Action
EXENAME = ${PROGRAM_FILENAME}
DBGNAME = debug/$(EXENAME)
PKGDIR = $(shell echo "${PACKAGE_INSTALL_PATH}" | sed -e 's/^\///')
DBGDIR = usr/lib/debug/$(PKGDIR)
LINKDIR = $(shell echo "${PACKAGE_LINK_PATH}" | sed -e 's/^\///')
PIXMAPS_DIR = usr/share/pixmaps
DESKTOP_DIR = usr/share/applications
PREFIX = $(shell test "$(CROSS_COMPILE_BUILD)" != "$(CROSS_COMPILE_HOST)" && echo "PREFIX=$(CROSS_COMPILE_HOST)")
OS = LINUX=1
NONX86 = $(shell test "`echo $(CROSS_COMPILE_HOST) | grep 'i[3-6]86'`" || echo "NONX86=1")
MAKEARGS = $(OS) $(NONX86) $(PREFIX) EXENAME=$(EXENAME) DBGNAME=$(DBGNAME) NOOBJDUMP=1 # SDL_PKGCONFIG=sdl2 PNG_PKGCONFIG=libpng
MENUFILE1 = ?package($(PACKAGE)):needs="X11" section="$(SECTION)"
MENUFILE2 = title="$(TITLE)" command="/$(PKGDIR)/$(PACKAGE)"
BINDIR := $(DIR)/bin/
# FIXME pkg-config dir hacks
# Launchpad doesn't need this; it actually makes i386 builds fail due to cross-compile
# export PKG_CONFIG_LIBDIR = /usr/lib/$(CROSS_COMPILE_HOST)/pkgconfig
LDFLAGS += "-Wl,-rpath=/usr/lib/$(CROSS_COMPILE_HOST)"
# Some libgme-dev packages don't use pkg-config yet, so include the linker flag ourselves
PKG_CONFIG?=pkg-config
LIBGME_PKGCONFIG?=libgme
LIBGME_LDFLAGS?=$(shell $(PKG_CONFIG) $(LIBGME_PKGCONFIG) --libs)
ifeq ($(LIBGME_LDFLAGS),)
MAKEARGS += LIBGME_LDFLAGS=-lgme
endif
build:
$(MKDIR) $(BINDIR)/debug
$(MAKE) -C $(DIR)/src $(MAKEARGS)
$(STRIP) $(BINDIR)/$(EXENAME)
binary-indep:
# only here to kill Lintian warning
echo "no need to do any arch-independent stuff"
binary-arch:
# create ddirs
$(MKDIR) $(DIR)/debian/tmp/$(PKGDIR) $(DIR)/debian/tmp/$(DBGDIR)
$(MKDIR) $(DIR)/debian/tmp/$(PKGDIR) $(DIR)/debian/tmp/$(DESKTOP_DIR)
$(MKDIR) $(DIR)/debian/tmp/$(PKGDIR) $(DIR)/debian/tmp/$(PIXMAPS_DIR)
# install main binaries
$(INSTALL) $(BINDIR)/$(EXENAME) $(DIR)/debian/tmp/$(PKGDIR)/$(PACKAGE)
$(INSTALL) $(BINDIR)/$(DBGNAME) $(DIR)/debian/tmp/$(DBGDIR)/$(PACKAGE)
# Install desktop file and banner image
$(INSTALL) $(DIR)/srb2.png $(DIR)/debian/tmp/usr/share/pixmaps/${PROGRAM_FILENAME}.png
$(INSTALL) $(DIR)/debian/srb2.desktop $(DIR)/debian/tmp/usr/share/applications/${PROGRAM_FILENAME}.desktop
# add compiled binaries to include-binaries
echo $(BINDIR)/$(EXENAME) >> $(DIR)/debian/source/include-binaries
echo $(BINDIR)/$(EXENAME) >> $(DIR)/debian/source/include-binaries
# Generate install folder files
echo $(PKGDIR) > $(DIR)/debian/$(PACKAGE).install
echo $(DESKTOP_DIR) >> $(DIR)/debian/$(PACKAGE).install
echo $(PIXMAPS_DIR) >> $(DIR)/debian/$(PACKAGE).install
echo $(DBGDIR) > $(DIR)/debian/$(DBGPKG).install
# Launchpad only calls binary-arch, so just move everything up
#binary: binary-arch
# Generate .desktop specifications
echo "`echo '$(MENUFILE1)\\'`" > $(DIR)/debian/menu
echo " `echo '$(MENUFILE2)'`" >> $(DIR)/debian/menu
dh_testdir
dh_testroot
dh_installchangelogs
dh_installdocs
# dh_installexamples
dh_install --sourcedir=$(DIR)/debian/tmp
dh_installmenu
# dh_installdebconf
# dh_installlogrotate
# dh_installemacsen
# dh_installpam
# dh_installmime
# dh_python
# dh_installinit
# dh_installcron
# dh_installinfo
# dh_installman
dh_link $(PKGDIR)/$(EXENAME) $(LINKDIR)/$(EXENAME)
dh_compress
dh_fixperms
# dh_perl
# dh_makeshlibs
dh_installdeb
-dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
binary: binary-arch
clean:
$(MAKE) -C $(DIR)/src $(MAKEARGS) clean cleandep
$(RM) $(BINDIR)/*
$(RM) $(DIR)/debian/$(PACKAGE)/*
$(RM) $(DIR)/debian/$(DBGPKG)/*
$(RM) $(DIR)/debian/tmp/*
$(RM) $(DIR)/debian/$(PACKAGE).install
$(RM) $(DIR)/debian/$(DBGPKG).install
$(RM) $(DIR)/debian/menu
$(RM) $(DIR)/debian/files
$(RM) $(DIR)/debian/source/include-binaries
.PHONY: all clean binary binary-indep build

View file

@ -1 +0,0 @@
3.0 (native)

View file

@ -1,11 +0,0 @@
tar-ignore = "assets/*.srb"
tar-ignore = "assets/*.pk3"
tar-ignore = "assets/*.dta"
tar-ignore = "assets/*.wad"
tar-ignore = "assets/*.kart"
tar-ignore = "assets/debian/${PACKAGE_NAME}-data/*"
tar-ignore = "assets/debian/tmp/*"
tar-ignore = "*.obj"
tar-ignore = "*.dep"
tar-ignore = ".git/*"
tar-ignore = ".git*"

View file

@ -1,10 +0,0 @@
[Desktop Entry]
Name=${PROGRAM_NAME}
Comment=${PROGRAM_DESCRIPTION}
Encoding=UTF-8
Exec=${PACKAGE_INSTALL_PATH}/${PROGRAM_FILENAME}
Icon=/usr/share/pixmaps/${PROGRAM_FILENAME}.png
Terminal=false
Type=Application
StartupNotify=false
Categories=Application;Game;

View file

@ -1,64 +0,0 @@
# Items
BlanKart features its own collection of both new items and toggleable alternate takes on existing SRB2Kart v1 items. Most new items also appear in Ring Racers, but function significantly differently. This wiki page will cover all necessary information for these items.
## Alternate Items
Alternative items are secondary versions of existing SRB2Kart items that **reinterpret them in (mostly) unique ways**. As BlanKart develops further, more alternate items may appear.
To toggle on/off these alternate versions, you can do so with the following commands:
- ``altitem_invincibility`` (for Invincibility)
- ``altitem_shrink`` (for Shrink)
### Alt. Invincibility (Power: Occupies Slot)
Invincibility, in its normal form, is a power item that appears in the lower ranks, letting players cut through offroad and spin out opponents with prejudice. **Alt. Invincibility** works significantly different, trading its aggression for speed and optimized recovery.
To begin, Alt. Invincibility's item odds work as an inversion of the Self-Propelled Bomb's: Like how the S.P.B. only appears when first is extremely far ahead of the pack, Alt. Invincibility only reveals itself to players who are **extremely far behind the pack**. In some extreme cases, Alt. Invincibilty will override the race-start cooldown to power-up players already left in the dust.
Unlike the standard Invincibility, **you can't damage players with Alt. Invincibility**, instead bumping them like you would normally.
Its time limit (and power) is directly tied to your distance from the "cluster player", the player closest to the largest collection on the map of (losing) players. If you notice yourself falling super far behind on the minimap, you're likely to roll Alt. Invincibility. **The further the distance, the stronger your invincibility**, and the faster you'll go. Think of it like a non-autopilot version of Mario Kart's Bullet Bill, or Sonic Racing's Drill Wisp. _Make huge comebacks, and don't lose hope!_
Do note, though: Alt. Invincibility is designed as a "gap closer", and not traditional catchup. Once you pass the cluster player, the timer **decreases at an exponentially fast rate**; don't count on it to let you steal wins from the leader!
As you run out of power (your Invincibility drops below 5 seconds), **offroad will gradually begin to affect you again**. A warning signal usually sounds as your invincibility is about to run out, as well. Be careful when you see the rainbow color begin to fade!
If you want something else, or your invincibility is running low, hold ITEM to cancel your Invincibility; the same as you would Grow.
### Alt. Shrink (Power)
Shrink, in its normal form, functions much like Mario Kart's Lightning item. Most servers keep it off due to how frequent and disruptive it is to races.
**Alt. Shrink** forgoes that and turns it into an inversion of Grow! In its alternate form, Shrink appears as a **midpack power item**, shrinking you to a dimunitive size and increasing your acceleration and top speed, whilist **doubling the amount of nearly every item** you roll while under its effects. With some luck, you can roll impressive items and put pressure on first!
Be careful, though: running into anyone while in this state **will flip you over** and significantly cut your speed. Nimble dodging is required to make the most of this item!
## New Items
### Bubble Shield (Defense: Occupies Slot)
This is an item that appears around the upper-midpack of any race. This item's focus is **defense**.
When a player holds onto this shield, they can inflate the shield to protect themselves from items.
As the shield is used more, and takes damage from items and player bumps, it **cracks more and more until finally shattering**. Some item interactions, like a snipe from a Banana or Orbinaut, make it **shatter right away**!
Hold down ITEM to inflate the shield. Once you let go, it slowly deflates. As long as it's in an inflated state--be it inflating or deflating--you can **protect yourself from items** without spinning out.
While in an _uninflated_ state, however, the Bubble Shield can let you **nullify only one item hit**, shattering itself in the process.
If you hold ITEM for too long, you'll **overinflate the shield**, causing it to shatter, no matter the amount of health it still had. That's not all bad, though; you'll get a nice speed boost, and be temporarily invulnerable to hazards and items; proximity mines are no match!
The Bubble Shield also makes your bumps stronger: if you bump into another player, you won't rebound, but they will. If your shield isn't inflated while bumping other players, it'll **take severe damage** from the bump. Careful play is key with this shield!
### Flame Shield (Offense+Boost: Occupies Slot)
This is an item that appears around the lower-midpack of any race.
The Flame Shield can be used by holding down ITEM.
When in use, a **Flamometer** appears next to your character. The Flamometer shows how much you're charging the shield, and how much fuel you have left.
The fuel gauge is constantly depleting once the Flame Shield is first used. As you hold ITEM; you'll increase the Flame Shield's boost power, but it'll **use up whatever fuel you have** at the moment.
If you overcharge the Flame Shield, the Flamometer **catches fire**, and you'll gain no extra boost power, but can more easily cut through offroad. If you pace yourself, you can make this item last very long.
If you run into players while charging your Flame Shield, **you'll flip them over**, making them lose a significant amount of speed. You however, rush right through them.
### Land Mine (Drop Behind)
This is an item exclusive to first. Drop a discreet mine onto the track; anyone who runs into it **flips over and loses speed**.

View file

@ -1,4 +1,4 @@
add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
add_executable(BLANKART MACOSX_BUNDLE WIN32
comptime.c
config.h.in
cxxutil.hpp
@ -156,36 +156,49 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
)
if(("${CMAKE_COMPILER_IS_GNUCC}" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND "${CMAKE_SYSTEM_NAME}" MATCHES "Windows")
target_link_options(SRB2SDL2 PRIVATE "-Wl,--disable-dynamicbase")
target_link_options(BLANKART PRIVATE "-Wl,--disable-dynamicbase")
if("${SRB2_CONFIG_STATIC_STDLIB}")
# On MinGW with internal libraries, link the standard library statically
if(CMAKE_LINKER_TYPE STREQUAL "LLD")
target_link_options(SRB2SDL2 PRIVATE -Wl, -static-libgcc -static-libstdc++ -static -lpthread)
target_link_options(BLANKART PRIVATE -Wl, -static-libgcc -static-libstdc++ -static -lpthread)
else()
target_link_options(SRB2SDL2 PRIVATE -Wl,--add-stdcall-alias -static-libgcc -static-libstdc++ -static -lpthread)
target_link_options(BLANKART PRIVATE -Wl,--add-stdcall-alias -static-libgcc -static-libstdc++ -static -lpthread)
endif()
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads REQUIRED)
target_link_libraries(SRB2SDL2 PRIVATE Threads::Threads)
target_link_libraries(BLANKART PRIVATE Threads::Threads)
endif()
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
target_link_options(SRB2SDL2 PRIVATE "-Wl,--large-address-aware")
target_link_options(BLANKART PRIVATE "-Wl,--large-address-aware")
endif()
endif()
set(SRB2_CONFIG_STD23 OFF CACHE BOOL
"Compiles the game under c23 and cxx23 instead c11 and cxx17.")
set(SRB2_CONFIG_COMPILEAPPIMAGE OFF CACHE BOOL
"Compiles the game then attempts turning it into an appimage.")
if(SRB2_CONFIG_COMPILEAPPIMAGE AND "${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
message("-- Generating Appimage at build time.")
add_custom_command(
TARGET BLANKART
POST_BUILD
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin/
COMMAND ${CMAKE_SOURCE_DIR}/appimage_build.sh -s
)
endif()
if(SRB2_CONFIG_STD23)
message("-- Compiling game with C23 and CXX23.")
target_compile_features(SRB2SDL2 PRIVATE c_std_23 cxx_std_23)
set_property(TARGET SRB2SDL2 PROPERTY C_STANDARD 23)
set_property(TARGET SRB2SDL2 PROPERTY CXX_STANDARD 23)
target_compile_features(BLANKART PRIVATE c_std_23 cxx_std_23)
set_property(TARGET BLANKART PROPERTY C_STANDARD 23)
set_property(TARGET BLANKART PROPERTY CXX_STANDARD 23)
else()
message("-- Compiling game with C11 and CXX17.")
target_compile_features(SRB2SDL2 PRIVATE c_std_11 cxx_std_17)
set_property(TARGET SRB2SDL2 PROPERTY C_STANDARD 11)
set_property(TARGET SRB2SDL2 PROPERTY CXX_STANDARD 17)
target_compile_features(BLANKART PRIVATE c_std_11 cxx_std_17)
set_property(TARGET BLANKART PROPERTY C_STANDARD 11)
set_property(TARGET BLANKART PROPERTY CXX_STANDARD 17)
endif()
### Configuration
@ -208,7 +221,7 @@ if(NOT SRB2_CONFIG_SKIP_COMPTIME)
# information known at build time, must be told to rebuild
# before that information can be ascertained.
add_custom_command(
TARGET SRB2SDL2
TARGET BLANKART
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E touch_nocreate ${CMAKE_CURRENT_SOURCE_DIR}/comptime.c
)
@ -219,16 +232,31 @@ add_custom_target(_SRB2_reconf ALL
COMMAND ${CMAKE_COMMAND} -DGIT_EXECUTABLE=${GIT_EXECUTABLE} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DBINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}/.. -P ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/Comptime.cmake
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.."
)
add_dependencies(SRB2SDL2 _SRB2_reconf)
add_dependencies(BLANKART _SRB2_reconf)
if(SRB2_CONFIG_ASAN)
target_compile_options(SRB2SDL2 PRIVATE -fsanitize=address)
target_link_options(SRB2SDL2 PRIVATE -fsanitize=address)
target_compile_options(BLANKART PRIVATE -fsanitize=address -fno-omit-frame-pointer)
target_link_options(BLANKART PRIVATE -fsanitize=address -fno-omit-frame-pointer)
endif()
if(SRB2_CONFIG_UBSAN)
target_compile_options(SRB2SDL2 PRIVATE -fsanitize=undefined)
target_link_options(SRB2SDL2 PRIVATE -fsanitize=undefined)
target_compile_options(BLANKART PRIVATE -fsanitize=undefined)
target_link_options(BLANKART PRIVATE -fsanitize=undefined)
endif()
if(SRB2_CONFIG_LSAN)
target_compile_options(BLANKART PRIVATE -fsanitize=leak)
target_link_options(BLANKART PRIVATE -fsanitize=leak)
endif()
if(SRB2_CONFIG_TSAN)
target_compile_options(BLANKART PRIVATE -fsanitize=thread)
target_link_options(BLANKART PRIVATE -fsanitize=thread)
endif()
if(SRB2_CONFIG_MSAN)
target_compile_options(BLANKART PRIVATE -fsanitize=memory -fPIE -fno-omit-frame-pointer)
target_link_options(BLANKART PRIVATE -fsanitize=memory -fPIE -pie -fno-omit-frame-pointer)
endif()
if(SRB2_CONFIG_TIDY)
@ -236,7 +264,7 @@ if(SRB2_CONFIG_TIDY)
endif()
if(SRB2_CONFIG_NOVERIFYIWADS)
target_compile_definitions(SRB2SDL2 PRIVATE -DNOVERIFYIWADS)
target_compile_definitions(BLANKART PRIVATE -DNOVERIFYIWADS)
endif()
add_subdirectory(blua)
@ -248,7 +276,7 @@ add_subdirectory(acs)
# OS macros
if (UNIX)
target_compile_definitions(SRB2SDL2 PRIVATE -DUNIXCOMMON)
target_compile_definitions(BLANKART PRIVATE -DUNIXCOMMON)
endif()
if(CMAKE_COMPILER_IS_GNUCC)
@ -256,54 +284,68 @@ if(CMAKE_COMPILER_IS_GNUCC)
endif()
if("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
target_compile_definitions(SRB2SDL2 PRIVATE -DLINUX)
target_compile_definitions(BLANKART PRIVATE -DLINUX)
if(${SRB2_SYSTEM_BITS} EQUAL 64)
target_compile_definitions(SRB2SDL2 PRIVATE -DLINUX64)
target_compile_definitions(BLANKART PRIVATE -DLINUX64)
endif()
endif()
if("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin")
target_compile_definitions(SRB2SDL2 PRIVATE -DMACOSX)
target_compile_definitions(BLANKART PRIVATE -DMACOSX)
endif()
if("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD")
target_compile_definitions(BLANKART PRIVATE -DFREEBSD)
target_link_libraries(BLANKART PRIVATE execinfo)
endif()
if("${SRB2_CONFIG_USE_GME}")
target_link_libraries(SRB2SDL2 PRIVATE gme)
target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_GME)
target_link_libraries(BLANKART PRIVATE gme)
target_compile_definitions(BLANKART PRIVATE -DHAVE_GME)
if(NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}")
# this sucks but gme doesn't use modern cmake to delineate public headers
target_include_directories(SRB2SDL2 PRIVATE "${libgme_SOURCE_DIR}")
target_include_directories(BLANKART PRIVATE "${libgme_SOURCE_DIR}")
endif()
endif()
target_link_libraries(SRB2SDL2 PRIVATE openmpt)
target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_OPENMPT)
target_link_libraries(BLANKART PRIVATE openmpt)
target_compile_definitions(BLANKART PRIVATE -DHAVE_OPENMPT)
target_link_libraries(SRB2SDL2 PRIVATE ZLIB::ZLIB PNG::PNG CURL::libcurl)
target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_ZLIB -DHAVE_PNG -DHAVE_CURL -D_LARGEFILE64_SOURCE)
target_sources(SRB2SDL2 PRIVATE apng.c)
target_link_libraries(BLANKART PRIVATE ZLIB::ZLIB PNG::PNG CURL::libcurl)
target_compile_definitions(BLANKART PRIVATE -DHAVE_ZLIB -DHAVE_PNG -DHAVE_CURL -D_LARGEFILE64_SOURCE)
target_sources(BLANKART PRIVATE apng.c)
target_link_libraries(SRB2SDL2 PRIVATE tcbrindle::span)
target_link_libraries(SRB2SDL2 PRIVATE fmt::fmt-header-only)
target_link_libraries(SRB2SDL2 PRIVATE Tracy::TracyClient)
target_link_libraries(BLANKART PRIVATE tcbrindle::span)
target_link_libraries(BLANKART PRIVATE fmt::fmt-header-only)
target_link_libraries(BLANKART PRIVATE Tracy::TracyClient)
if(NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}")
target_link_libraries(SRB2SDL2 PRIVATE sndfile)
target_link_libraries(SRB2SDL2 PRIVATE Vorbis::vorbis Vorbis::vorbisenc)
target_link_libraries(SRB2SDL2 PRIVATE Opus::opus)
target_link_libraries(SRB2SDL2 PRIVATE Ogg::ogg)
target_link_libraries(BLANKART PRIVATE sndfile)
target_link_libraries(BLANKART PRIVATE Vorbis::vorbis Vorbis::vorbisenc)
target_link_libraries(BLANKART PRIVATE Opus::opus)
target_link_libraries(BLANKART PRIVATE Ogg::ogg)
endif()
target_link_libraries(SRB2SDL2 PRIVATE xxHash::xxhash)
if(SRB2_CONFIG_UPNP)
target_compile_definitions(BLANKART PRIVATE -DHAVE_MINIUPNPC)
target_link_libraries(BLANKART PRIVATE miniupnpc)
if (WIN32)
target_compile_definitions(BLANKART PRIVATE -DMINIUPNP_STATICLIB)
target_link_libraries(BLANKART PRIVATE iphlpapi)
endif()
endif()
target_compile_definitions(SRB2SDL2 PRIVATE -DUSE_STUN)
target_link_libraries(BLANKART PRIVATE xxHash::xxhash)
target_compile_definitions(BLANKART PRIVATE -DUSE_STUN)
if(SRB2_CONFIG_ENABLE_DISCORDRPC)
target_link_libraries(SRB2SDL2 PRIVATE DiscordRPC::DiscordRPC)
target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_DISCORDRPC)
target_sources(SRB2SDL2 PRIVATE discord.c)
target_link_libraries(BLANKART PRIVATE DiscordRPC::DiscordRPC)
target_compile_definitions(BLANKART PRIVATE -DHAVE_DISCORDRPC)
target_sources(BLANKART PRIVATE discord.c)
endif()
set(SRB2_HAVE_THREADS ON)
target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_THREADS)
target_compile_definitions(BLANKART PRIVATE -DHAVE_THREADS)
if(${SRB2_CONFIG_HAVE_ZLIB})
if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES})
@ -321,7 +363,7 @@ if(${SRB2_CONFIG_HAVE_ZLIB})
endif()
if(${ZLIB_FOUND})
set(SRB2_HAVE_ZLIB ON)
target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_ZLIB)
target_compile_definitions(BLANKART PRIVATE -DHAVE_ZLIB)
else()
message(WARNING "You have specified that ZLIB is available but it was not found. BlanKart may not compile correctly.")
endif()
@ -342,9 +384,9 @@ if(${SRB2_CONFIG_HAVE_PNG} AND ${SRB2_CONFIG_HAVE_ZLIB})
endif()
if(${PNG_FOUND})
set(SRB2_HAVE_PNG ON)
target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_PNG)
target_compile_definitions(SRB2SDL2 PRIVATE -D_LARGEFILE64_SOURCE)
target_sources(SRB2SDL2 PRIVATE apng.c)
target_compile_definitions(BLANKART PRIVATE -DHAVE_PNG)
target_compile_definitions(BLANKART PRIVATE -D_LARGEFILE64_SOURCE)
target_sources(BLANKART PRIVATE apng.c)
else()
message(WARNING "You have specified that PNG is available but it was not found. BlanKart may not compile correctly.")
endif()
@ -352,13 +394,13 @@ if(${SRB2_CONFIG_HAVE_PNG} AND ${SRB2_CONFIG_HAVE_ZLIB})
endif()
if("${SRB2_CONFIG_HWRENDER}")
target_compile_definitions(SRB2SDL2 PRIVATE -DHWRENDER)
target_compile_definitions(BLANKART PRIVATE -DHWRENDER)
add_subdirectory(hardware)
if("${SRB2_CONFIG_STATIC_OPENGL}")
find_package(OpenGL)
if(${OPENGL_FOUND})
target_compile_definitions(SRB2SDL2 PRIVATE -DSTATIC_OPENGL)
target_compile_definitions(BLANKART PRIVATE -DSTATIC_OPENGL)
else()
message(WARNING "You have specified static opengl but opengl was not found. Not setting HWRENDER.")
endif()
@ -367,11 +409,11 @@ endif()
# TODO: build this with the game
if(${CMAKE_SYSTEM} MATCHES Windows AND ${CMAKE_C_COMPILER_ID} MATCHES "GNU" AND ${SRB2_SYSTEM_BITS} EQUAL 32)
target_link_libraries(SRB2SDL2 PRIVATE
target_link_libraries(BLANKART PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/../thirdparty/drmingw/lib/win32/libexchndl.a"
"${CMAKE_CURRENT_SOURCE_DIR}/../thirdparty/drmingw/lib/win32/libmgwhelp.a"
)
target_include_directories(SRB2SDL2 PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../thirdparty/drmingw/include")
target_include_directories(BLANKART PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../thirdparty/drmingw/include")
endif()
# Targets
@ -400,20 +442,20 @@ endif()
# Compatibility flag with later versions of GCC
# We should really fix our code to not need this
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
target_compile_options(SRB2SDL2 PRIVATE -mno-ms-bitfields)
target_compile_options(BLANKART PRIVATE -mno-ms-bitfields)
endif()
# TODO: fix prng and P_CreateBlockmap overflow at some point
target_compile_options(SRB2SDL2 PRIVATE -fwrapv)
target_compile_options(BLANKART PRIVATE -fwrapv)
if (${CMAKE_BUILD_TYPE} MATCHES Debug)
target_compile_options(SRB2SDL2 PRIVATE -O0)
target_compile_options(BLANKART PRIVATE -O0)
else()
target_compile_options(SRB2SDL2 PRIVATE -O3)
target_compile_options(BLANKART PRIVATE -O3)
endif()
# Compiler warnings configuration
target_compile_options(SRB2SDL2 PRIVATE
target_compile_options(BLANKART PRIVATE
# Using generator expressions to handle per-language compile options
# C, GNU
@ -529,7 +571,7 @@ target_compile_options(SRB2SDL2 PRIVATE
>
)
if(SRB2_CONFIG_ERRORMODE)
target_compile_options(SRB2SDL2 PRIVATE
target_compile_options(BLANKART PRIVATE
$<$<OR:$<C_COMPILER_ID:GNU>,$<C_COMPILER_ID:AppleClang>,$<C_COMPILER_ID:Clang>>:
-Werror
>
@ -537,37 +579,37 @@ if(SRB2_CONFIG_ERRORMODE)
endif()
# Link warnings configuration
target_link_options(SRB2SDL2 PRIVATE
target_link_options(BLANKART PRIVATE
$<$<C_COMPILER_ID:GNU>:
# -Wl,--as-needed - Was controlled by NOLDWARNING
>
)
if(${SRB2_CONFIG_DEV_BUILD})
target_compile_definitions(SRB2SDL2 PRIVATE -DDEVELOP)
target_compile_definitions(BLANKART PRIVATE -DDEVELOP)
endif()
target_compile_definitions(SRB2SDL2 PRIVATE -DCMAKECONFIG)
target_compile_definitions(BLANKART PRIVATE -DCMAKECONFIG)
# Misc. build options from Makefiles
if(SRB2_CONFIG_DEBUGMODE)
target_compile_definitions(SRB2SDL2 PRIVATE -D_DEBUG -DZDEBUG -DPARANOIA -DRANGECHECK -DPACKETDROP)
target_compile_definitions(BLANKART PRIVATE -D_DEBUG -DZDEBUG -DPARANOIA -DRANGECHECK -DPACKETDROP)
endif()
if(SRB2_CONFIG_MOBJCONSISTANCY)
target_compile_definitions(SRB2SDL2 PRIVATE -DMOBJCONSISTANCY)
target_compile_definitions(BLANKART PRIVATE -DMOBJCONSISTANCY)
endif()
if(SRB2_CONFIG_PACKETDROP)
target_compile_definitions(SRB2SDL2 PRIVATE -DPACKETDROP)
target_compile_definitions(BLANKART PRIVATE -DPACKETDROP)
endif()
if(SRB2_CONFIG_ZDEBUG)
target_compile_definitions(SRB2SDL2 PRIVATE -DZDEBUG)
target_compile_definitions(BLANKART PRIVATE -DZDEBUG)
endif()
if(SRB2_CONFIG_PROFILEMODE AND "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
target_compile_options(SRB2SDL2 PRIVATE -pg)
target_link_options(SRB2SDL2 PRIVATE -pg)
target_compile_options(BLANKART PRIVATE -pg)
target_link_options(BLANKART PRIVATE -pg)
endif()
if(SRB2_CONFIG_LTO AND NOT SRB2_CONFIG_DEBUGMODE)
set_property(TARGET SRB2SDL2 PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
set_property(TARGET BLANKART PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()
# strip debug symbols into separate file when using gcc or clang.
@ -578,11 +620,11 @@ if((CMAKE_COMPILER_IS_GNUCC OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND NOT
set(OBJCOPY_ONLY_KEEP_DEBUG "--only-keep-debug")
endif()
message(STATUS "Will make separate debug symbols in *.debug")
add_custom_command(TARGET SRB2SDL2 POST_BUILD
COMMAND ${CMAKE_OBJCOPY} ${OBJCOPY_ONLY_KEEP_DEBUG} $<TARGET_FILE:SRB2SDL2> $<TARGET_FILE:SRB2SDL2>.debug
add_custom_command(TARGET BLANKART POST_BUILD
COMMAND ${CMAKE_OBJCOPY} ${OBJCOPY_ONLY_KEEP_DEBUG} $<TARGET_FILE:BLANKART> $<TARGET_FILE:BLANKART>.debug
# mold linker: .gnu_debuglink is present by default, so --add-gnu-debuglink would fail
COMMAND ${CMAKE_OBJCOPY} --strip-debug --remove-section=.gnu_debuglink $<TARGET_FILE:SRB2SDL2>
COMMAND ${CMAKE_OBJCOPY} --add-gnu-debuglink=$<TARGET_FILE:SRB2SDL2>.debug $<TARGET_FILE:SRB2SDL2>
COMMAND ${CMAKE_OBJCOPY} --strip-debug --remove-section=.gnu_debuglink $<TARGET_FILE:BLANKART>
COMMAND ${CMAKE_OBJCOPY} --add-gnu-debuglink=$<TARGET_FILE:BLANKART>.debug $<TARGET_FILE:BLANKART>
)
endif()
endif()
@ -608,12 +650,12 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL Windows AND NOT "${SRB2_CONFIG_INTERNAL_LIBRA
endif()
list(TRANSFORM ADDITIONAL_DLLS PREPEND "${MINGW_BIN_PATH}/")
endif()
add_custom_command(TARGET SRB2SDL2 POST_BUILD
add_custom_command(TARGET BLANKART POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_RUNTIME_DLLS:SRB2SDL2>
$<TARGET_RUNTIME_DLLS:BLANKART>
${ADDITIONAL_DLLS}
$<TARGET_FILE_DIR:SRB2SDL2>
$<TARGET_FILE_DIR:BLANKART>
COMMAND_EXPAND_LISTS
COMMENT "Copying runtime DLLs"
)

View file

@ -1,4 +1,4 @@
target_sources(SRB2SDL2 PRIVATE
target_sources(BLANKART PRIVATE
ACSVM/Action.cpp
ACSVM/Array.cpp
ACSVM/BinaryIO.cpp

View file

@ -1,5 +1,5 @@
add_subdirectory(ACSVM)
target_sources(SRB2SDL2 PRIVATE
target_sources(BLANKART PRIVATE
environment.cpp
environment.hpp
thread.cpp

View file

@ -1,3 +1,3 @@
target_sources(SRB2SDL2 PRIVATE
target_sources(BLANKART PRIVATE
internal/b_soc.c
)

View file

@ -1,4 +1,4 @@
target_sources(SRB2SDL2 PRIVATE
target_sources(BLANKART PRIVATE
lapi.c
lbaselib.c
ldo.c

View file

@ -32,6 +32,7 @@ extern "C" {
#define WRITEUINT16(p,b) do { UINT16 *p_tmp = ( UINT16 *)p; const UINT16 tv = ( UINT16)(b); memcpy(p, &tv, sizeof( UINT16)); p_tmp++; *(void**)(&(p)) = (void *)p_tmp; } while (0)
#define WRITEINT32(p,b) do { INT32 *p_tmp = ( INT32 *)p; const INT32 tv = ( INT32)(b); memcpy(p, &tv, sizeof( INT32)); p_tmp++; *(void**)(&(p)) = (void *)p_tmp; } while (0)
#define WRITEUINT32(p,b) do { UINT32 *p_tmp = ( UINT32 *)p; const UINT32 tv = ( UINT32)(b); memcpy(p, &tv, sizeof( UINT32)); p_tmp++; *(void**)(&(p)) = (void *)p_tmp; } while (0)
#define WRITEINT64(p,b) do { INT64 *p_tmp = ( INT64 *)p; const INT64 tv = ( INT64)(b); memcpy(p, &tv, sizeof( INT64)); p_tmp++; *(void**)(&(p)) = (void *)p_tmp; } while (0)
#define WRITEUINT64(p,b) do { UINT64 *p_tmp = ( UINT64 *)p; const UINT64 tv = ( UINT64)(b); memcpy(p, &tv, sizeof( UINT64)); p_tmp++; *(void**)(&(p)) = (void *)p_tmp; } while (0)
#define WRITECHAR(p,b) do { char *p_tmp = ( char *)p; const char tv = ( char)(b); memcpy(p, &tv, sizeof( char)); p_tmp++; *(void**)(&(p)) = (void *)p_tmp; } while (0)
#define WRITEFIXED(p,b) do { fixed_t *p_tmp = (fixed_t *)p; const fixed_t tv = (fixed_t)(b); memcpy(p, &tv, sizeof(fixed_t)); p_tmp++; *(void**)(&(p)) = (void *)p_tmp; } while (0)
@ -45,6 +46,7 @@ extern "C" {
#define READUINT16(p) ({ const UINT16 *p_tmp = (const UINT16 *)p; UINT16 b; memcpy(&b, p, sizeof( UINT16)); p_tmp++; *(const void**)(&(p)) = (const void *)p_tmp; b; })
#define READINT32(p) ({ const INT32 *p_tmp = (const INT32 *)p; INT32 b; memcpy(&b, p, sizeof( INT32)); p_tmp++; *(const void**)(&(p)) = (const void *)p_tmp; b; })
#define READUINT32(p) ({ const UINT32 *p_tmp = (const UINT32 *)p; UINT32 b; memcpy(&b, p, sizeof( UINT32)); p_tmp++; *(const void**)(&(p)) = (const void *)p_tmp; b; })
#define READINT64(p) ({ const INT64 *p_tmp = (const INT64 *)p; INT64 b; memcpy(&b, p, sizeof( INT64)); p_tmp++; *(const void**)(&(p)) = (const void *)p_tmp; b; })
#define READUINT64(p) ({ const UINT64 *p_tmp = (const UINT64 *)p; UINT64 b; memcpy(&b, p, sizeof( UINT64)); p_tmp++; *(const void**)(&(p)) = (const void *)p_tmp; b; })
#define READCHAR(p) ({ const char *p_tmp = (const char *)p; char b; memcpy(&b, p, sizeof( char)); p_tmp++; *(const void**)(&(p)) = (const void *)p_tmp; b; })
#define READFIXED(p) ({ const fixed_t *p_tmp = (const fixed_t *)p; fixed_t b; memcpy(&b, p, sizeof(fixed_t)); p_tmp++; *(const void**)(&(p)) = (const void *)p_tmp; b; })
@ -56,6 +58,7 @@ extern "C" {
#define READUINT16(p) ((const UINT16*) (*(const void**)(&(p)) = (const void*)&((const UINT16*) (p))[1]))[-1]
#define READINT32(p) ((const INT32*) (*(const void**)(&(p)) = (const void*)&((const INT32*) (p))[1]))[-1]
#define READUINT32(p) ((const UINT32*) (*(const void**)(&(p)) = (const void*)&((const UINT32*) (p))[1]))[-1]
#define READINT64(p) ((const INT64*) (*(const void**)(&(p)) = (const void*)&((const INT64*) (p))[1]))[-1]
#define READUINT64(p) ((const UINT64*) (*(const void**)(&(p)) = (const void*)&((const UINT64*) (p))[1]))[-1]
#define READCHAR(p) ((const char*) (*(const void**)(&(p)) = (const void*)&((const char*) (p))[1]))[-1]
#define READFIXED(p) ((const fixed_t*)(*(const void**)(&(p)) = (const void*)&((const fixed_t*)(p))[1]))[-1]

View file

@ -1454,7 +1454,7 @@ consvar_t *CV_FindVar(const char *name)
consvar_t *cvar;
for (cvar = consvar_vars; cvar; cvar = cvar->next)
if (fasticmp(name,cvar->name))
if (fasticmp(name, cvar->name))
return cvar;
return NULL;

View file

@ -518,18 +518,18 @@ static void CON_RecalcSize(void)
switch (cv_constextsize.value)
{
case V_NOSCALEPATCH:
con_scalefactor = 1;
break;
case V_SMALLSCALEPATCH:
con_scalefactor = vid.smalldupx;
break;
case V_MEDSCALEPATCH:
con_scalefactor = vid.meddupx;
break;
default: // Full scaling
con_scalefactor = vid.dupx;
break;
case V_NOSCALEPATCH:
con_scalefactor = 1;
break;
case V_SMALLSCALEPATCH:
con_scalefactor = vid.smalldup;
break;
case V_MEDSCALEPATCH:
con_scalefactor = vid.meddup;
break;
default: // Full scaling
con_scalefactor = vid.dup;
break;
}
con_recalc = false;
@ -652,7 +652,7 @@ void CON_MoveConsole(void)
}
// Not instant - Increment fracmovement fractionally
fracmovement += FixedMul(cons_speed.value*vid.fdupy, renderdeltatics);
fracmovement += FixedMul(cons_speed.value*vid.fdup, renderdeltatics);
if (con_curlines < con_destlines) // Move the console downwards
{
@ -727,6 +727,8 @@ void CON_ToggleOff(void)
I_UpdateMouseGrab();
I_SetTextInput(false);
Unlock_state();
}
@ -767,17 +769,24 @@ void CON_Ticker(void)
con_destlines = 0;
CON_ClearHUD();
I_UpdateMouseGrab();
I_SetTextInput(false);
}
else
{
CON_ChangeHeight();
I_SetTextInput(true);
}
}
// check if console ready for prompt
if (con_destlines >= minheight)
{
consoleready = true;
}
else
{
consoleready = false;
}
// make overlay messages disappear after a while
for (i = 0; i < con_hudlines; i++)
{
@ -1503,9 +1512,9 @@ static void CON_DrawBackpic(void)
con_backpic = W_CachePatchNum(piclump, PU_PATCH);
// Center the backpic, and draw a vertically cropped patch.
w = (BASEVIDWIDTH * vid.dupx);
w = (BASEVIDWIDTH * vid.dup);
x = (vid.width / 2) - (w / 2);
h = con_curlines/vid.dupy;
h = con_curlines/vid.dup;
// If the patch doesn't fill the entire screen,
// then fill the sides with a solid color.

View file

@ -1,4 +1,4 @@
target_sources(SRB2SDL2 PRIVATE
target_sources(BLANKART PRIVATE
memory.cpp
thread_pool.cpp
)

View file

@ -2106,8 +2106,6 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
renderdeltatics = FRACUNIT;
R_SetTimeFrac(FRACUNIT);
memset(deviceResponding, false, sizeof (deviceResponding));
if (cl_mode == CL_CONFIRMCONNECT)
{
D_ProcessEvents(); //needed for menu system to receive inputs
@ -2837,7 +2835,7 @@ void CL_Reset(void)
http_source[0] = '\0';
#endif
G_ResetAllDeviceRumbles();
G_ResetAllControllerRumbles();
// D_StartTitle should get done now, but the calling function will handle it
}

View file

@ -29,6 +29,8 @@ typedef enum
ev_console,
ev_mouse,
ev_joystick,
ev_accelerometer,
ev_gyroscope,
} evtype_t;
// Event structure.

View file

@ -93,8 +93,8 @@
#define ASSET_HASH_TEXTURES_KART 0xb4211b2f32b6a291
#define ASSET_HASH_CHARS_KART 0x1e68a3e01aa5c68b
#define ASSET_HASH_MAPS_KART 0x38558ed00da41ce9
#define ASSET_HASH_MAIN_PK3 0x45e00f9adfbf9f75
#define ASSET_HASH_MAPPATCH_PK3 0xbbc2c6a7a685da3a
#define ASSET_HASH_MAIN_PK3 0xd9e606e74d2d9012
#define ASSET_HASH_MAPPATCH_PK3 0x1745690024efbaf8
#define ASSET_HASH_BONUSCHARS_KART 0x60e6f13d822a7461
#ifdef USE_PATCH_FILE
#define ASSET_HASH_PATCH_PK3 0x0000000000000000
@ -181,6 +181,8 @@ INT32 eventhead, eventtail;
boolean dedicated = false;
boolean loaded_config = false;
//
// D_PostEvent
// Called by the I/O functions when input is detected
@ -219,7 +221,6 @@ void D_ProcessEvents(void)
for (size_t i = 0; i < 4; i++)
gamekeydown[0][KEY_MOUSEMOVE + i] = 0;
memset(deviceResponding, false, sizeof (deviceResponding));
for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1))
{
ev = &events[eventtail];
@ -319,8 +320,7 @@ boolean D_RenderLevel(void)
{
// V_DrawPatchFill, but for the fourth screen only
patch_t *pat = static_cast<patch_t*>(W_CachePatchName("SRB2BACK", PU_CACHE));
INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
INT32 x, y, pw = SHORT(pat->width) * dupz, ph = SHORT(pat->height) * dupz;
INT32 x, y, pw = SHORT(pat->width) * vid.dup, ph = SHORT(pat->height) * vid.dup;
for (x = vid.width>>1; x < vid.width; x += pw)
{
@ -595,14 +595,11 @@ static void D_Display(void)
// STUPID race condition...
{
wipegamestate = gamestate;
cansetrender = true;
// clean up border stuff
// see if the border needs to be initially drawn
if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction && curbghide && (!hidetitlemap)))
{
// Rendering a level; don't allow renderer changes!
cansetrender = false;
D_RenderLevel();
@ -1065,11 +1062,6 @@ void D_SRB2Loop(void)
}
renderisnewtic = true;
if (!dedicated)
{
G_DeviceLEDTick();
}
}
else
{
@ -1110,6 +1102,11 @@ void D_SRB2Loop(void)
if (takescreenshot)
M_DoScreenShot();
if (!dedicated)
{
G_ControllerLEDTick();
}
// consoleplayer -> displayplayers (hear sounds from viewpoint)
S_UpdateSounds(); // move positional sounds
if (renderisnewtic)
@ -1224,7 +1221,6 @@ void D_StartTitle(void)
// clear cmd building stuff
memset(gamekeydown, 0, sizeof(gamekeydown));
memset(deviceResponding, false, sizeof (deviceResponding));
F_StartTitleScreen();
@ -1232,13 +1228,13 @@ void D_StartTitle(void)
if (rendermode != render_none)
V_SetPaletteLump("PLAYPAL");
G_ResetAllDeviceRumbles();
G_ResetAllControllerRumbles();
// The title screen is obviously not a tutorial! (Unless I'm mistaken)
tutorialmode = false;
// map palettes affect this
G_ResetDeviceLED();
G_ResetControllerLED();
}
//
@ -1667,6 +1663,7 @@ void D_SRB2Main(void)
M_Init();
if (!dedicated)
{
CV_RegisterVar(&cv_highreshudscale);
CV_RegisterVar(&cv_ticrate);
CV_RegisterVar(&cv_accuratefps);
CV_RegisterVar(&cv_constextsize);
@ -1796,6 +1793,8 @@ void D_SRB2Main(void)
savedata.lives = 0; // flag this as not-used
loaded_config = true; // so pallettechange doesent get called 500 times at startup lol
CON_SetLoadingProgress(LOADED_CONFIG);
CONS_Printf("R_InitTextureData()...\n");
@ -2007,9 +2006,9 @@ void D_SRB2Main(void)
// user settings come before "+" parameters.
if (dedicated)
COM_ImmedExecute(va("exec \"%s" PATHSEP "kartserv.cfg\"\n", srb2home));
COM_ImmedExecute(va("exec \"%s" PATHSEP "blanserv.cfg\"\n", srb2home));
else
COM_ImmedExecute(va("exec \"%s" PATHSEP "kartexec.cfg\" -noerror\n", srb2home));
COM_ImmedExecute(va("exec \"%s" PATHSEP "blanexec.cfg\" -noerror\n", srb2home));
if (!autostart)
M_PushSpecialParameters(); // push all "+" parameters at the command buffer

View file

@ -55,6 +55,8 @@ typedef enum
extern boolean gameconfig_loaded;
extern tic_t rendergametic;
extern boolean loaded_config;
extern char srb2home[256]; //Alam: My Home
extern boolean usehome; //Alam: which path?
extern const char *pandf; //Alam: how to path?

View file

@ -18,6 +18,7 @@
#include "console.h"
#include "command.h"
#include "i_time.h"
#include "i_gamepad.h"
#include "i_system.h"
#include "g_game.h"
#include "hu_stuff.h"
@ -170,6 +171,7 @@ static void KartSlopeBoost_OnChange(void);
static void KartDrafting_OnChange(void);
static void KartAirDrop_OnChange(void);
static void KartAirThrust_OnChange(void);
static void KartRecoveryDash_OnChange(void);
static void KartWaterSkipLock_OnChange(void);
static void KartItemLitter_OnChange(void);
static void KartItemPush_OnChange(void);
@ -233,6 +235,11 @@ static void Command_Teamchange2_f(void);
static void Command_Teamchange3_f(void);
static void Command_Teamchange4_f(void);
static void Command_Restat(void);
static void Command_Restat2(void);
static void Command_Restat3(void);
static void Command_Restat4(void);
static void Command_ServerTeamChange_f(void);
static void Command_Clearscores_f(void);
@ -376,31 +383,22 @@ consvar_t cv_usemouse = CVAR_INIT ("use_mouse", "Off", CV_SAVE|CV_CALL,usemouse_
consvar_t cv_laglesscam = CVAR_INIT ("laglesscamera", "Off", CV_SAVE,CV_OnOff, NULL);
consvar_t cv_usejoystick[MAXSPLITSCREENPLAYERS] = {
CVAR_INIT ("use_joystick", "1", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick1),
CVAR_INIT ("use_joystick2", "2", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick2),
CVAR_INIT ("use_joystick3", "3", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick3),
CVAR_INIT ("use_joystick4", "4", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick4)
consvar_t cv_usecontroller[MAXSPLITSCREENPLAYERS] = {
CVAR_INIT ("use_joystick", "1", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitController1),
CVAR_INIT ("use_joystick2", "2", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitController2),
CVAR_INIT ("use_joystick3", "3", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitController3),
CVAR_INIT ("use_joystick4", "4", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitController4)
};
#if (defined (LJOYSTICK) || defined (HAVE_SDL))
consvar_t cv_joyscale[MAXSPLITSCREENPLAYERS] = {
CVAR_INIT ("padscale", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale),
CVAR_INIT ("padscale2", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale2),
CVAR_INIT ("padscale3", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale3),
CVAR_INIT ("padscale4", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale4)
consvar_t cv_controllerscale[MAXSPLITSCREENPLAYERS] = {
CVAR_INIT ("padscale", "1", CV_SAVE|CV_CALL, NULL, I_ControllerScale),
CVAR_INIT ("padscale2", "1", CV_SAVE|CV_CALL, NULL, I_ControllerScale2),
CVAR_INIT ("padscale3", "1", CV_SAVE|CV_CALL, NULL, I_ControllerScale3),
CVAR_INIT ("padscale4", "1", CV_SAVE|CV_CALL, NULL, I_ControllerScale4)
};
#ifdef LJOYSTICK
consvar_t cv_joyport[MAXSPLITSCREENPLAYERS] = { //Alam: for later
CVAR_INIT ("padport", "/dev/js0", CV_SAVE, joyport_cons_t, NULL),
CVAR_INIT ("padport2", "/dev/js0", CV_SAVE, joyport_cons_t, NULL),
CVAR_INIT ("padport3", "/dev/js0", CV_SAVE, joyport_cons_t, NULL),
CVAR_INIT ("padport4", "/dev/js0", CV_SAVE, joyport_cons_t, NULL)
};
#endif
#else
consvar_t cv_joyscale[MAXSPLITSCREENPLAYERS] = { //Alam: Dummy for save
consvar_t cv_controllerscale[MAXSPLITSCREENPLAYERS] = { //Alam: Dummy for save
CVAR_INIT ("padscale", "1", CV_SAVE|CV_HIDEN, NULL, NULL),
CVAR_INIT ("padscale2", "1", CV_SAVE|CV_HIDEN, NULL, NULL),
CVAR_INIT ("padscale3", "1", CV_SAVE|CV_HIDEN, NULL, NULL),
@ -431,6 +429,7 @@ static CV_PossibleValue_t kartspeedometer_cons_t[] = {{0, "Off"}, {1, "Kilometer
consvar_t cv_kartspeedometer = CVAR_INIT ("kartdisplayspeed", "Percentage", CV_SAVE, kartspeedometer_cons_t, NULL); // use tics in display
static CV_PossibleValue_t kartvoices_cons_t[] = {{0, "Never"}, {1, "Tasteful"}, {2, "Meme"}, {0, NULL}};
consvar_t cv_kartvoices = CVAR_INIT ("kartvoices", "Tasteful", CV_SAVE, kartvoices_cons_t, NULL);
consvar_t cv_karthorns = CVAR_INIT ("taunthorns", "Tasteful", CV_SAVE, kartvoices_cons_t, NULL);
static CV_PossibleValue_t kartbot_cons_t[] = {
{0, "Off"},
@ -493,17 +492,19 @@ consvar_t cv_kartstacking_panel_maxgrade = CVAR_INIT ("vanillaboost_panel_maxgra
//
// Invincibility
//
// Classic boosts
consvar_t cv_kartstacking_invincibility_classicspeedboost = CVAR_INIT ("vanillaboost_invincibility_classicspeedboost", "0.375", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_invincibility_classicaccelboost = CVAR_INIT ("vanillaboost_invincibility_classicaccelboost", "3.0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_invincibility_classichandleboost = CVAR_INIT ("vanillaboost_invincibility_classichandleboost", "0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
// Alternate boosts
consvar_t cv_kartstacking_invincibility_alternatespeedboost = CVAR_INIT ("vanillaboost_invincibility_alternatespeedboost", "0.67", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_invincibility_alternateaccelboost = CVAR_INIT ("vanillaboost_invincibility_alternateaccelboost", "3.0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_invincibility_alternatehandleboost = CVAR_INIT ("vanillaboost_invincibility_alternatehandleboost", "0.45", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_invincibility_speedboost = CVAR_INIT ("vanillaboost_invincibility_speedboost", "0.375", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_invincibility_accelboost = CVAR_INIT ("vanillaboost_invincibility_accelboost", "3.0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_invincibility_handleboost = CVAR_INIT ("vanillaboost_invincibility_handleboost", "0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_invincibility_stackable = CVAR_INIT ("vanillaboost_invincibility_stackable", "On", CV_NETVAR|CV_GUARD, CV_OnOff, NULL);
//
// S-Monitor
//
consvar_t cv_kartstacking_smonitor_speedboost = CVAR_INIT ("vanillaboost_smonitor_speedboost", "0.75", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_smonitor_accelboost = CVAR_INIT ("vanillaboost_smonitor_accelboost", "3.0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_smonitor_handleboost = CVAR_INIT ("vanillaboost_smonitor_handleboost", "0.48", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_smonitor_stackable = CVAR_INIT ("vanillaboost_smonitor_stackable", "On", CV_NETVAR|CV_GUARD, CV_OnOff, NULL);
consvar_t cv_kartstacking_grow_speedboost = CVAR_INIT ("vanillaboost_grow_speedboost", "0.2", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_grow_accelboost = CVAR_INIT ("vanillaboost_grow_accelboost", "0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_grow_handleboost = CVAR_INIT ("vanillaboost_grow_handleboost", "0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
@ -519,7 +520,7 @@ consvar_t cv_kartstacking_bubble_accelboost = CVAR_INIT ("vanillaboost_bubble_ac
consvar_t cv_kartstacking_bubble_handleboost = CVAR_INIT ("vanillaboost_bubble_handleboost", "0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_bubble_stackable = CVAR_INIT ("vanillaboost_bubble_stackable", "Off", CV_NETVAR|CV_GUARD, CV_OnOff, NULL);
consvar_t cv_kartstacking_flame_speedval = CVAR_INIT ("vanillaboost_flame_speedval", "0.25", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_flame_speedval = CVAR_INIT ("vanillaboost_flame_speedval", "0.14", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_flame_accelboost = CVAR_INIT ("vanillaboost_flame_accelboost", "6.0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_flame_handleboost = CVAR_INIT ("vanillaboost_flame_handleboost", "0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_flame_stackable = CVAR_INIT ("vanillaboost_flame_stackable", "On", CV_NETVAR|CV_GUARD, CV_OnOff, NULL);
@ -544,6 +545,24 @@ consvar_t cv_kartstacking_ring_accelboost = CVAR_INIT ("vanillaboost_ring_accelb
consvar_t cv_kartstacking_ring_handleboost = CVAR_INIT ("vanillaboost_ring_handleboost", "0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_ring_stackable = CVAR_INIT ("vanillaboost_ring_stackable", "On", CV_NETVAR|CV_CHEAT|CV_GUARD, CV_OnOff, NULL);
consvar_t cv_kartstacking_heavydrop_speedboost = CVAR_INIT ("vanillaboost_heavydrop_speedboost", "0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_heavydrop_accelboost = CVAR_INIT ("vanillaboost_heavydrop_accelboost", "8.0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_heavydrop_handleboost = CVAR_INIT ("vanillaboost_heavydrop_handleboost", "0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_heavydrop_stackable = CVAR_INIT ("vanillaboost_heavydrop_stackable", "On", CV_NETVAR|CV_CHEAT|CV_GUARD, CV_OnOff, NULL);
consvar_t cv_kartstacking_heavydrop_uniform = CVAR_INIT ("vanillaboost_heavydrop_uniform", "No", CV_NETVAR|CV_CHEAT|CV_GUARD, CV_YesNo, NULL);
consvar_t cv_kartstacking_ssmt_speedboost = CVAR_INIT ("vanillaboost_ssmt_speedboost", "0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_ssmt_accelboost = CVAR_INIT ("vanillaboost_ssmt_accelboost", "10.0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_ssmt_handleboost = CVAR_INIT ("vanillaboost_ssmt_handleboost", "0.01", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_recspin_speedboost_lo = CVAR_INIT ("vanillaboost_recspin_speedboost_lo", "0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_recspin_accelboost_lo = CVAR_INIT ("vanillaboost_recspin_accelboost_lo", "0.5", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_recspin_handleboost_lo = CVAR_INIT ("vanillaboost_recspin_handleboost_lo", "0.25", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_recspin_speedboost_hi = CVAR_INIT ("vanillaboost_recspin_speedboost_hi", "0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_recspin_accelboost_hi = CVAR_INIT ("vanillaboost_recspin_accelboost_hi", "8.0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_recspin_handleboost_hi = CVAR_INIT ("vanillaboost_recspin_handleboost_hi", "0.5", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_slope_decay = CVAR_INIT ("vanillaboost_slope_decay", "0.004", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_slope_brakemod = CVAR_INIT ("vanillaboost_slope_brakemod", "0.01", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_slope_speedboost_max = CVAR_INIT ("vanillaboost_slope_speedboost_max", "3.0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
@ -594,7 +613,12 @@ consvar_t cv_kartdrafting_closedraft = CVAR_INIT ("kartdrafting_closedraft", "Of
consvar_t cv_kartdrafting_closedeadzone = CVAR_INIT ("kartdrafting_closedeadzone", "640", CV_NETVAR|CV_CHEAT, CV_Unsigned, NULL);
consvar_t cv_kartdrafting_basedistance = CVAR_INIT ("kartdrafting_basedistance", "2560", CV_NETVAR|CV_CHEAT, CV_Unsigned, NULL);
consvar_t cv_kartairdrop = CVAR_INIT ("kartairdrop", "No", CV_NETVAR|CV_CALL|CV_NOINIT|CV_GUARD, CV_YesNo, KartAirDrop_OnChange);
static CV_PossibleValue_t airdrop_cons_t[] = {{AIRDROP_NONE, "Off"},
{AIRDROP_LIGHT, "Light"},
{AIRDROP_HEAVY, "Heavy"},
{AIRDROP_FUSION, "Fusion"},
{0, NULL}};
consvar_t cv_kartairdrop = CVAR_INIT ("kartairdrop", "Off", CV_NETVAR|CV_CALL|CV_NOINIT|CV_GUARD, airdrop_cons_t, KartAirDrop_OnChange);
consvar_t cv_kartairthrust = CVAR_INIT ("kartairthrust", "No", CV_NETVAR|CV_CALL|CV_NOINIT|CV_GUARD, CV_YesNo, KartAirThrust_OnChange);
consvar_t cv_kartairthrust_reductionrate = CVAR_INIT ("kartairthrust_reductionrate", "0.5", CV_NETVAR|CV_FLOAT|CV_CHEAT|CV_GUARD, CV_Unsigned, NULL);
@ -603,7 +627,7 @@ consvar_t cv_kartairthrust_power2 = CVAR_INIT ("kartairthrust_power2", "0.35", C
consvar_t cv_kartairthrust_power3 = CVAR_INIT ("kartairthrust_power3", "0.5", CV_NETVAR|CV_FLOAT|CV_CHEAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartairthrust_power4 = CVAR_INIT ("kartairthrust_power4", "0.75", CV_NETVAR|CV_FLOAT|CV_CHEAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartwaterskiplock = CVAR_INIT ("kartwaterskiplock", "No", CV_NETVAR|CV_CALL|CV_NOINIT|CV_GUARD, CV_YesNo, KartWaterSkipLock_OnChange);
consvar_t cv_kartwaterskiplock = CVAR_INIT ("kartwaterskiplock", "Yes", CV_NETVAR|CV_CALL|CV_NOINIT|CV_GUARD, CV_YesNo, KartWaterSkipLock_OnChange);
consvar_t cv_kartitemlitter = CVAR_INIT ("kartitemlitter", "On", CV_NETVAR|CV_CALL|CV_NOINIT, CV_OnOff, KartItemLitter_OnChange);
consvar_t cv_kartitempush = CVAR_INIT ("kartitempush", "Off", CV_NETVAR|CV_CALL|CV_NOINIT, CV_OnOff, KartItemPush_OnChange);
@ -612,6 +636,9 @@ consvar_t cv_kartforcelegacyodds = CVAR_INIT ("kartforcelegacyodds", "Off", CV_N
consvar_t cv_handleboostslip = CVAR_INIT ("karthandleboostsliptide", "Off", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_kartrecoverydash = CVAR_INIT ("kartrecoverydash", "No", CV_NETVAR|CV_CALL|CV_NOINIT|CV_GUARD, CV_YesNo, KartRecoveryDash_OnChange);
consvar_t cv_kartrecoverydash_spinspeed = CVAR_INIT ("kartrecoverydash_spinspeed", "24.0", CV_NETVAR|CV_FLOAT|CV_CHEAT|CV_GUARD, CV_Unsigned, NULL);
#define ANTIBUMP_MAX (UINT32_MAX / TICRATE)
static CV_PossibleValue_t antibump_cons_t[] = {{0, "MIN"}, {ANTIBUMP_MAX, "MAX"}, {0, NULL}};
consvar_t cv_kartantibump = CVAR_INIT ("kartantibump", "0", CV_NETVAR|CV_CALL|CV_NOINIT, antibump_cons_t, KartAntiBump_OnChange);
@ -637,14 +664,19 @@ consvar_t cv_kartaltshrinktime = CVAR_INIT ("kartaltshrinktime", "14", CV_NETVAR
static CV_PossibleValue_t kartinvintheme_cons_t[] = {{0, "Standard"}, {1, "Full"}, {0, NULL}};
consvar_t cv_kartinvintheme = CVAR_INIT ("kartinvintheme", "Standard", CV_SAVE, kartinvintheme_cons_t, NULL);
// How far the player must be from the cluster to begin frequently rolling Invincibility.
static CV_PossibleValue_t invindist_cons_t[] = {{1, "MIN"}, {32000, "MAX"}, {0, NULL}};
consvar_t cv_kartinvindist = CVAR_INIT ("kartinvindist", "8600", CV_NETVAR|CV_CHEAT|CV_GUARD, invindist_cons_t, NULL);
// Invincibility damage toggles
static CV_PossibleValue_t kartinvindmg_cons_t[] = {{0, "None"}, {DMG_WIPEOUT, "Wipe-out"}, {DMG_FLIPOVER, "Flip-over"}, {0, NULL}};
consvar_t cv_kartinvindistmul = CVAR_INIT ("kartinvindistmul", "0.54", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
// Experiment: Let's default to flip-over for now.
consvar_t cv_kartinvindamage = CVAR_INIT ("kartinvindamage", "Flip-over", CV_NETVAR|CV_CHEAT|CV_GUARD, kartinvindmg_cons_t, NULL);
consvar_t cv_kartinvin_maxtime = CVAR_INIT ("kartinvin_maxtime", "35.0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartinvin_midtime = CVAR_INIT ("kartinvin_midtime", "23.333", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
// How far the player must be from the cluster to roll an S-Monitor.
static CV_PossibleValue_t smonitordist_cons_t[] = {{1, "MIN"}, {32000, "MAX"}, {0, NULL}};
consvar_t cv_kartsmonitordist = CVAR_INIT ("smonitor_startdist", "12000", CV_NETVAR|CV_CHEAT|CV_GUARD, smonitordist_cons_t, NULL);
consvar_t cv_kartsmonitor_decaydist = CVAR_INIT ("smonitor_decaydist", "3600", CV_NETVAR|CV_CHEAT|CV_GUARD, smonitordist_cons_t, NULL);
static CV_PossibleValue_t smonitordecaytime_cons_t[] = {{1, "MIN"}, {6, "MAX"}, {0, NULL}};
consvar_t cv_kartsmonitor_decaytime = CVAR_INIT ("smonitor_decaytime", "2", CV_NETVAR|CV_CHEAT|CV_GUARD, smonitordecaytime_cons_t, NULL);
// opinionated stuff for testing balance tweaks on the shields
consvar_t cv_kartbubble_defense_canidle = CVAR_INIT ("kartbubble_defense_canidle", "On", CV_NETVAR, CV_OnOff, NULL);
@ -652,8 +684,7 @@ static CV_PossibleValue_t bubble_defense_damagerate_cons_t[] = {{0, "MIN"}, {FRA
consvar_t cv_kartbubble_defense_damagerate = CVAR_INIT ("kartbubble_defense_damagerate", "1.0", CV_NETVAR|CV_FLOAT, bubble_defense_damagerate_cons_t, NULL);
consvar_t cv_kartbubble_boost_allow = CVAR_INIT ("kartbubble_boost_allow", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_kartbubble_boost_offroadignore = CVAR_INIT ("kartbubble_boost_offroadignore", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_kartflame_fastfuel = CVAR_INIT ("kartflame_fastfuel", "Off", CV_NETVAR, CV_OnOff, NULL);
// we want this to be default now apparently
consvar_t cv_kartflame_fastfuel = CVAR_INIT ("kartflame_fastfuel", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_kartflame_offroadburn = CVAR_INIT ("kartflame_offroadburn", "On", CV_NETVAR, CV_OnOff, NULL);
// "Arrow Bullet": above a certain speed threshold, an aura in the shape of the Shrink arrow
@ -769,6 +800,15 @@ consvar_t cv_minihead = CVAR_INIT ("smallminimapplayers", "Off", CV_SAVE, CV_OnO
static CV_PossibleValue_t spinoutroll_cons_t[] = {{0, "Off"}, {1, "Minimap Only"}, {2, "Rankings Only"}, {3, "Minimap+Rankings"}, {0, NULL}};
consvar_t cv_spinoutroll = CVAR_INIT ("spinoutroll", "Minimap+Rankings", CV_SAVE, spinoutroll_cons_t, NULL);
// Item/Ringbox Roulette drawn on player, from RadioRacers
consvar_t cv_rouletteonplayer = CVAR_INIT ("rouletteonplayer", "Off", CV_SAVE, CV_OnOff, NULL);
static CV_PossibleValue_t rlplrtrans_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}};
// Controllable visibility for the player-tracking roulette icons.
// Default is 7 (70% visible; V_30TRANS)
consvar_t cv_rouletteplayertrans = CVAR_INIT ("rouletteonplayertrans", "7", CV_SAVE, rlplrtrans_cons_t, NULL);
consvar_t cv_showviewpointtext = CVAR_INIT ("showviewpointtext", "On", CV_SAVE, CV_OnOff, NULL);
// Intermission time Tails 04-19-2002
@ -1091,6 +1131,8 @@ void D_RegisterServerCommands(void)
CV_RegisterVar(&cv_showminimapangle);
CV_RegisterVar(&cv_minihead);
CV_RegisterVar(&cv_spinoutroll);
CV_RegisterVar(&cv_rouletteonplayer);
CV_RegisterVar(&cv_rouletteplayertrans);
CV_RegisterVar(&cv_showlapemblem);
CV_RegisterVar(&cv_lapemblemmode);
CV_RegisterVar(&cv_racesplits);
@ -1133,6 +1175,14 @@ void D_RegisterServerCommands(void)
COM_AddCommand("playsound", Command_PlaySound);
RegisterNetXCmd(XD_PLAYSOUND, Got_PlaySound);
// player restat
CV_RegisterVar(&cv_allowrestat);
CV_RegisterVar(&cv_notifyrestat);
COM_AddCommand("restat", Command_Restat);
COM_AddCommand("restat2", Command_Restat2);
COM_AddCommand("restat3", Command_Restat3);
COM_AddCommand("restat4", Command_Restat4);
}
// =========================================================================
@ -1250,6 +1300,7 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_follower[i]);
CV_RegisterVar(&cv_followercolor[i]);
CV_RegisterVar(&cv_jitterlegacy[i]);
CV_RegisterVar(&cv_driftmode[i]);
CV_RegisterVar(&cv_voice[i]);
}
@ -1277,7 +1328,10 @@ void D_RegisterClientCommands(void)
COM_AddCommand("displayplayer", Command_Displayplayer_f);
// FIXME: not to be here.. but needs be done for config loading
#ifdef BACKWARDSCOMPATCORRECTION
CV_RegisterVar(&cv_globalgamma);
#endif
CV_RegisterVar(&cv_globalbrightness);
CV_RegisterVar(&cv_globalsaturation);
CV_RegisterVar(&cv_rhue);
@ -1287,12 +1341,12 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_bhue);
CV_RegisterVar(&cv_mhue);
CV_RegisterVar(&cv_rgamma);
CV_RegisterVar(&cv_ygamma);
CV_RegisterVar(&cv_ggamma);
CV_RegisterVar(&cv_cgamma);
CV_RegisterVar(&cv_bgamma);
CV_RegisterVar(&cv_mgamma);
CV_RegisterVar(&cv_rbrightness);
CV_RegisterVar(&cv_ybrightness);
CV_RegisterVar(&cv_gbrightness);
CV_RegisterVar(&cv_cbrightness);
CV_RegisterVar(&cv_bbrightness);
CV_RegisterVar(&cv_mbrightness);
CV_RegisterVar(&cv_rsaturation);
CV_RegisterVar(&cv_ysaturation);
@ -1333,9 +1387,9 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_deadzonestyle[i]);
CV_RegisterVar(&cv_litesteer[i]);
CV_RegisterVar(&cv_turnsmooth[i]);
CV_RegisterVar(&cv_rumble[i]);
CV_RegisterVar(&cv_controllerrumble[i]);
CV_RegisterVar(&cv_rumblestrength[i]);
CV_RegisterVar(&cv_gamepadled[i]);
CV_RegisterVar(&cv_controllerled[i]);
}
// filesrch.c
@ -1356,11 +1410,8 @@ void D_RegisterClientCommands(void)
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
CV_RegisterVar(&cv_usejoystick[i]);
CV_RegisterVar(&cv_joyscale[i]);
#ifdef LJOYSTICK
CV_RegisterVar(&cv_joyport[i]);
#endif
CV_RegisterVar(&cv_usecontroller[i]);
CV_RegisterVar(&cv_controllerscale[i]);
}
// s_sound.c
@ -1442,6 +1493,109 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_serverinfoscreen);
}
static void RestatForPlayer(UINT32 ssplayer)
{
player_t* player = &players[g_localplayers[ssplayer]];
int speed;
int weight;
if (!cv_allowrestat.value)
{
CONS_Printf("This command has been disabled by the server host.\n");
return;
}
if (COM_Argc() > 2)
{
if (sscanf(COM_Argv(1), " %d", &speed) == 0 ||
sscanf(COM_Argv(2), " %d", &weight) == 0)
{
CONS_Printf("Expected two numbers (<speed> <weight>) in the range of 1-9.\n");
return;
}
// range checking
if (speed < 1 || speed > 9 ||
weight < 1 || weight > 9)
{
CONS_Printf("Expected two numbers (<speed> <weight>) in the range of 1-9.\n");
return;
}
// should be good now 🥲
player->kartspeedrestat = speed;
player->kartweightrestat = weight;
player->randomrestat = false;
CONS_Printf("You will be %d speed, %d weight for the next race.\n", speed, weight);
CONS_Printf("Use \"restat off\" to return to your skin's default stats.\n");
WeaponPref_Send(ssplayer);
return;
}
else if (COM_Argc() > 1)
{
if (fasticmp(COM_Argv(1), "random"))
{
player->randomrestat = !player->randomrestat;
if (player->randomrestat)
{
CONS_Printf("Random restat is now enabled.\n");
}
else
{
CONS_Printf("Random restat is now disabled.\n");
}
WeaponPref_Send(ssplayer);
return;
}
else if (fasticmp(COM_Argv(1), "off"))
{
player->kartspeedrestat = 0;
player->kartweightrestat = 0;
player->randomrestat = false;
WeaponPref_Send(ssplayer);
CONS_Printf("Now using skin default stats.\n");
return;
}
else
{
CONS_Printf(
"Usage: \"restat<playernum> <speed> <weight>\"\n"
"Alternatively: \"restat<playernum> random\" to toggle the use of random stats each round.\n"
"or \"restat<playernum> off\" to use your skin's default stats.\n");
}
}
else
{
CONS_Printf(
"Usage: \"restat<playernum> <speed> <weight>\"\n"
"Alternatively: \"restat<playernum> random\" to use random stats each round.\n"
"or \"restat<playernum> off\" to use your skin's default stats.\n");
}
}
static void Command_Restat(void)
{
RestatForPlayer(0);
}
static void Command_Restat2(void)
{
RestatForPlayer(1);
}
static void Command_Restat3(void)
{
RestatForPlayer(2);
}
static void Command_Restat4(void)
{
RestatForPlayer(3);
}
/**
* Searches the skins list for a skin of the "realname", if found, changes
* the CVAR value to be the "name" of the skin.
@ -2230,11 +2384,13 @@ enum {
WP_KICKSTARTACCEL = 1<<0,
WP_SHRINKME = 1<<1,
WP_FLIPCAM = 1<<2,
WP_LEGACYJITTER = 1<<3
WP_LEGACYJITTER = 1<<3,
WP_RANDOMRESTAT = 1<<4
};
void WeaponPref_Send(UINT8 ssplayer)
{
player_t* player = &players[g_localplayers[ssplayer]];
UINT8 prefs = 0;
if (cv_kickstartaccel[ssplayer].value)
@ -2248,10 +2404,16 @@ void WeaponPref_Send(UINT8 ssplayer)
if (!(cv_jitterlegacy[ssplayer].value))
prefs |= WP_LEGACYJITTER;
if (player->randomrestat)
prefs |= WP_RANDOMRESTAT;
UINT8 buf[2];
UINT8 buf[5];
buf[0] = prefs;
buf[1] = cv_mindelay.value;
buf[2] = player->kartspeedrestat;
buf[3] = player->kartweightrestat;
buf[4] = cv_driftmode[ssplayer].value;
SendNetXCmdForPlayer(ssplayer, XD_WEAPONPREF, buf, sizeof buf);
}
@ -2274,6 +2436,9 @@ void WeaponPref_Save(UINT8 **cp, INT32 playernum)
if (player->jitterlegacy)
prefs |= WP_LEGACYJITTER;
if (player->randomrestat)
prefs |= WP_RANDOMRESTAT;
WRITEUINT8(*cp, prefs);
}
@ -2285,6 +2450,7 @@ void WeaponPref_Parse(UINT8 **cp, INT32 playernum)
player->pflags &= ~(PF_KICKSTARTACCEL|PF_SHRINKME|PF_FLIPCAM);
player->jitterlegacy = false;
player->randomrestat = false;
if (prefs & WP_KICKSTARTACCEL)
player->pflags |= PF_KICKSTARTACCEL;
@ -2298,6 +2464,9 @@ void WeaponPref_Parse(UINT8 **cp, INT32 playernum)
if (prefs & WP_LEGACYJITTER)
player->jitterlegacy = true;
if (prefs & WP_RANDOMRESTAT)
player->randomrestat = true;
if (leveltime < 2)
{
// BAD HACK: No other place I tried to slot this in
@ -2309,14 +2478,38 @@ void WeaponPref_Parse(UINT8 **cp, INT32 playernum)
static void Got_WeaponPref(UINT8 **cp,INT32 playernum)
{
player_t *player = &players[playernum];
WeaponPref_Parse(cp, playernum);
UINT8 mindelay = READUINT8(*cp);
if (server)
{
for (UINT8 i = 0; i < G_LocalSplitscreenPartySize(playernum); ++i)
playerdelaytable[G_LocalSplitscreenPartyMember(playernum, i)] = mindelay;
playerdelaytable[G_LocalSplitscreenPartyMember(playernum, i)] = mindelay;
}
UINT8 kartspeedrestat = READUINT8(*cp);
UINT8 kartweightrestat = READUINT8(*cp);
if (kartspeedrestat < 0 || kartspeedrestat > 9 ||
kartweightrestat < 0 || kartweightrestat > 9)
{
CONS_Alert(CONS_WARNING, M_GetText("Illegal restat values received from %s\n"), player_names[playernum]);
if (server)
SendKick(playernum, KICK_MSG_CON_FAIL);
return;
}
player->kartspeedrestat = kartspeedrestat;
player->kartweightrestat = kartweightrestat;
UINT8 driftmode = READUINT8(*cp);
if (driftmode >= NUMDRIFTMODES)
{
CONS_Alert(CONS_WARNING, M_GetText("Illegal drift mode received from %s\n"), player_names[playernum]);
if (server)
SendKick(playernum, KICK_MSG_CON_FAIL);
return;
}
player->driftmode = driftmode;
// SEE ALSO g_demo.c
demo_extradata[playernum] |= DXD_WEAPONPREF;
@ -3696,6 +3889,18 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
mapnumber = READINT16(*cp);
if (grandprixinfo.gp)
{
if (gametype != GT_RACE)
{
grandprixinfo.eventmode = GPEVENT_CHALLENGE;
}
else
{
grandprixinfo.eventmode = GPEVENT_NONE;
}
}
if (netgame)
P_SetRandSeed(READUINT32(*cp));
@ -3874,7 +4079,7 @@ static void Got_Pause(UINT8 **cp, INT32 playernum)
}
I_UpdateMouseGrab();
G_ResetAllDeviceRumbles();
G_ResetAllControllerRumbles();
}
static void Command_ReplayMarker(void)
@ -8285,29 +8490,14 @@ static void KartAirDrop_OnChange(void)
return;
}
if (!K_AirDropActive() && cv_kartairdrop.value)
if (leveltime < starttime)
{
if (leveltime < starttime)
{
airdropactive = true;
CONS_Printf(M_GetText("Air Drop has been turned \"On\".\n"));
}
else
{
CONS_Printf(M_GetText("Air Drop will be turned \"On\" Next Round.\n"));
}
CONS_Printf(M_GetText("Air Drop has been set to \"%s\".\n"), cv_kartairdrop.string);
airdropactive = (UINT8)cv_kartairdrop.value;
}
else if (K_AirDropActive() && !cv_kartairdrop.value)
else
{
if (leveltime < starttime)
{
airdropactive = false;
CONS_Printf(M_GetText("Air Drop has been turned \"Off\".\n"));
}
else
{
CONS_Printf(M_GetText("Air Drop will be turned \"Off\" next round.\n"));
}
CONS_Printf(M_GetText("Air Drop will be set to \"%s\" next round.\n"), cv_kartairdrop.string);
}
}
@ -8344,6 +8534,39 @@ static void KartAirThrust_OnChange(void)
}
}
static void KartRecoveryDash_OnChange(void)
{
if (K_CanChangeRules(false) == false)
{
return;
}
if (!K_RecoveryDashActive() && cv_kartrecoverydash.value)
{
if (leveltime < starttime)
{
recoverydashactive = true;
CONS_Printf(M_GetText("Recovery Dash has been turned \"On\".\n"));
}
else
{
CONS_Printf(M_GetText("Recovery Dash will be turned \"On\" Next Round.\n"));
}
}
else if (K_RecoveryDashActive() && !cv_kartrecoverydash.value)
{
if (leveltime < starttime)
{
recoverydashactive = false;
CONS_Printf(M_GetText("Recovery Dash has been turned \"Off\".\n"));
}
else
{
CONS_Printf(M_GetText("Recovery Dash will be turned \"Off\" next round.\n"));
}
}
}
static void KartWaterSkipLock_OnChange(void)
{
if (K_CanChangeRules(false) == false)

View file

@ -37,11 +37,8 @@ extern consvar_t cv_splitplayers;
extern consvar_t cv_seenames;
extern consvar_t cv_usemouse;
extern consvar_t cv_laglesscam;
extern consvar_t cv_usejoystick[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_joyscale[MAXSPLITSCREENPLAYERS];
#ifdef LJOYSTICK
extern consvar_t cv_joyport[MAXSPLITSCREENPLAYERS];
#endif
extern consvar_t cv_usecontroller[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_controllerscale[MAXSPLITSCREENPLAYERS];
// normally in p_mobj but the .h is not read
extern consvar_t cv_itemrespawntime;
@ -88,6 +85,7 @@ extern consvar_t cv_kartvoterulechanges;
extern consvar_t cv_kartgametypepreference;
extern consvar_t cv_kartspeedometer;
extern consvar_t cv_kartvoices;
extern consvar_t cv_karthorns;
extern consvar_t cv_kartbot;
extern consvar_t cv_kartbot_cap;
extern consvar_t cv_kartbot_modifiermax;
@ -118,14 +116,16 @@ extern consvar_t cv_kartstacking_panel_separate;
extern consvar_t cv_kartstacking_panel_maxgrade;
extern consvar_t cv_kartstacking_invincibility_classicspeedboost;
extern consvar_t cv_kartstacking_invincibility_classicaccelboost;
extern consvar_t cv_kartstacking_invincibility_classichandleboost;
extern consvar_t cv_kartstacking_invincibility_alternatespeedboost;
extern consvar_t cv_kartstacking_invincibility_alternateaccelboost;
extern consvar_t cv_kartstacking_invincibility_alternatehandleboost;
extern consvar_t cv_kartstacking_invincibility_speedboost;
extern consvar_t cv_kartstacking_invincibility_accelboost;
extern consvar_t cv_kartstacking_invincibility_handleboost;
extern consvar_t cv_kartstacking_invincibility_stackable;
extern consvar_t cv_kartstacking_smonitor_speedboost;
extern consvar_t cv_kartstacking_smonitor_accelboost;
extern consvar_t cv_kartstacking_smonitor_handleboost;
extern consvar_t cv_kartstacking_smonitor_stackable;
extern consvar_t cv_kartstacking_flame_speedval;
extern consvar_t cv_kartstacking_flame_accelboost;
extern consvar_t cv_kartstacking_flame_handleboost;
@ -167,6 +167,24 @@ extern consvar_t cv_kartstacking_ring_accelboost;
extern consvar_t cv_kartstacking_ring_handleboost;
extern consvar_t cv_kartstacking_ring_stackable;
extern consvar_t cv_kartstacking_heavydrop_speedboost;
extern consvar_t cv_kartstacking_heavydrop_accelboost;
extern consvar_t cv_kartstacking_heavydrop_handleboost;
extern consvar_t cv_kartstacking_heavydrop_stackable;
extern consvar_t cv_kartstacking_heavydrop_uniform;
extern consvar_t cv_kartstacking_ssmt_speedboost;
extern consvar_t cv_kartstacking_ssmt_accelboost;
extern consvar_t cv_kartstacking_ssmt_handleboost;
extern consvar_t cv_kartstacking_recspin_speedboost_lo;
extern consvar_t cv_kartstacking_recspin_accelboost_lo;
extern consvar_t cv_kartstacking_recspin_handleboost_lo;
extern consvar_t cv_kartstacking_recspin_speedboost_hi;
extern consvar_t cv_kartstacking_recspin_accelboost_hi;
extern consvar_t cv_kartstacking_recspin_handleboost_hi;
extern consvar_t cv_kartstacking_slope_decay;
extern consvar_t cv_kartstacking_slope_brakemod;
extern consvar_t cv_kartstacking_slope_speedboost_max;
@ -194,10 +212,10 @@ extern consvar_t cv_kartexplosion_limitlifetime_cap;
extern consvar_t cv_kartslipdash;
extern consvar_t cv_kartslopeboost;
extern consvar_t cv_kartinvintheme;
extern consvar_t cv_kartinvindist;
extern consvar_t cv_kartinvindistmul;
extern consvar_t cv_kartinvin_maxtime;
extern consvar_t cv_kartinvin_midtime;
extern consvar_t cv_kartinvindamage;
extern consvar_t cv_kartsmonitordist;
extern consvar_t cv_kartsmonitor_decaydist;
extern consvar_t cv_kartsmonitor_decaytime;
// opinionated stuff for testing
extern consvar_t cv_kartbubble_defense_canidle;
@ -230,6 +248,9 @@ extern consvar_t cv_kartforcelegacyodds;
extern consvar_t cv_handleboostslip;
extern consvar_t cv_kartrecoverydash;
extern consvar_t cv_kartrecoverydash_spinspeed;
extern consvar_t cv_kartoddsdist;
extern consvar_t cv_kartlegacyoddsdist;
@ -275,6 +296,8 @@ extern consvar_t cv_showlapemblem;
extern consvar_t cv_lapemblemmode;
extern consvar_t cv_racesplits;
extern consvar_t cv_showviewpointtext;
extern consvar_t cv_rouletteonplayer;
extern consvar_t cv_rouletteplayertrans;
extern consvar_t cv_skipmapcheck;

View file

@ -71,8 +71,8 @@ typedef enum
// TODO: Is there a better way to track this?
PF_GAINAX = 1<<3,
PF_KICKSTARTACCEL = 1<<4, // Accessibility feature: Is accelerate in kickstart mode?
// 1<<5 free
// 1<<6 free
// free: 1<<5 and 1<<6
PF_WANTSTOJOIN = 1<<7, // Spectator that wants to join
@ -103,13 +103,24 @@ typedef enum
PF_SHRINKACTIVE = 1<<26, // "Shrink me" cheat is in effect. (Can't be disabled mid-race)
PF_JUSTFLIPPED = 1<<27, // Just got flipped over, handle the bump interaction.
PF_RECOVERYSPIN = 1<<28, // Player was charging SSMT last tick
// up to 1<<28 is free
PF_USEDOWN = 1<<29, // For lua compat, don't use!
PF_ATTACKDOWN = 1<<30, // For lua compat, don't use!
PF_SLIDING = 1<<31, // For lua compat, don't use!
} pflags_t;
typedef enum
{
PAF_AIRDROPINPUT = 1<<0, // Air drop input held
PAF_WANTSAIRDROP = 1<<1, // Wants Air drop (input pressed and buffered)
PAF_AIRDROP_LIGHT = 1<<2, // Is in Light Air Drop
PAF_AIRDROP_HEAVY = 1<<3, // Is in Heavy Air Drop
PAF_AIRDROP_MASK = (PAF_AIRDROP_LIGHT|PAF_AIRDROP_HEAVY), // Is in any Air Drop state
} p_airdropflags_t;
typedef enum
{
// Are animation frames playing?
@ -198,11 +209,17 @@ typedef enum
khud_boostcam, // Camera push forward on boost
khud_destboostcam, // Ditto
khud_timeovercam, // Camera timer for leaving behind or not
khud_heavydropcam, // Camera timer for heavy air drop
khud_postdropcam, // Camera timer for landing after heavy air drop (both timers superposition for feel)
khud_flamecamtime, // Timer for flame shield usage camera effect
// Sounds
khud_enginesnd, // Engine sound offset this player is using.
khud_voices, // Used to stop the player saying more voices than it should
khud_tauntvoices, // Used to specifically stop taunt voice spam
khud_confirmvictim, // Player ID that you dealt damage to
khud_confirmvictimdelay, // Delay before playing the sound
khud_taunthorns, // Used to specifically stop taunt horn spam
// Battle
khud_cardanimation, // Used to determine the position of some full-screen Battle Mode graphics
@ -433,6 +450,21 @@ struct saltyhop_t
fixed_t momz, zoffset; // erm... the mechanism....
};
// this WILL conflict with a future commit I just need this to proto
// yama: Nah, I'mma do my own thing
typedef enum
{
DRIFTMODE_CLASSIC = 0, // SRB2Kart drifting; no changes
DRIFTMODE_SNAPSHOT, // AKA "Runahead" - Use a prediction system to reduce the chances of a wrongdrift
DRIFTMODE_INSTANT, // Instantly decide your drift on the tic it happens
DRIFTMODE_DELAY, // Delay the time before a drift is decided
NUMDRIFTMODES
} driftmode_e;
// (12 frames / 60fps) * 35tps
// Delay-drift: Time the game is given to predict a "wanted" drift
#define DRIFT_DELAY_TIME (7)
// enum for saved lap times
typedef enum
{
@ -504,6 +536,10 @@ struct player_t
UINT8 kartspeed; // Kart speed stat between 1 and 9
UINT8 kartweight; // Kart weight stat between 1 and 9
UINT8 kartspeedrestat; // Player's wanted kart speed from restat
UINT8 kartweightrestat; // Player's wanted kart weight from restat
boolean randomrestat; // Randomly set the restat values of the player every game
INT32 followerskin; // Kart: This player's follower "skin"
boolean followerready; // Kart: Used to know when we can have a follower or not. (This is set on the first NameAndColor follower update)
UINT16 followercolor; // Kart: Used to store the follower colour the player wishes to use
@ -560,7 +596,9 @@ struct player_t
UINT8 justbumped; // Prevent players from endlessly bumping into each other
boolean noclip; // Fix Grow breaking the "noclip" cheat. Also applies noclip as a bonus.
driftmode_e driftmode;
SINT8 drift; // (-5 to 5) - Drifting Left or Right, plus a bigger counter = sharper turn
INT16 driftturnsnapshot;
SINT8 driftlock; // Prevents you from using drift angle for x tics. Used for zipper fix.
fixed_t driftcharge; // Charge your drift so you can release a burst of speed
UINT8 driftboost; // (0 to 125) - Boost you get from drifting
@ -569,6 +607,19 @@ struct player_t
tic_t driftelapsed; // CLIENT ONLY - Elapsed time spent during a drift.
SINT8 driftlevel; // CLIENT ONLY - handles controller rumble and air thrust power, cleared at the start of every tick.
INT32 drift_wannaturn; // Turn values the game uses to determine the direction you want to drift.
INT32 nulldrift; // When you drift without accelerating, this value ticks up/down depending on your drift's angle.
INT32 nulldrifttilt; // Sliptide-like kart tilting! (Can be toggled off)
tic_t nulldrifttime;
// (Delay-drift) - Delay in tics before the final drift angle is determined.
// Potentially influenced by player lag.
tic_t driftdelay;
tic_t recoverydashcharge; // Time spent charging SSMT
UINT16 recoverydash; // SSMT boost timer (weak boost that ignores offroad)
fixed_t spinoutrot; // When a player spins out, this value increments modulus 360.
SINT8 aizdriftstrat; // (-1 to 1) - Let go of your drift while boosting? Helper for the SICK STRATZ (sliptiding!) you have just unlocked
@ -590,6 +641,7 @@ struct player_t
fixed_t prevspeedboost; // Max speed boost value from the last frame
fixed_t accelboost; // Boost value smoothing for acceleration
fixed_t handleboost; // Boost value smoothing for handling
fixed_t forcedtopspeed; // Force this top speed while charging SSMT
angle_t boostangle; // angle set when not spun out OR boosted to determine what direction you should keep going at if you're spun out and boosted.
boostinfo_t boostinfo; // Stores values used for setting speed and accel boosts.
UINT8 numsneakers; // Number of stacked sneakers
@ -622,6 +674,7 @@ struct player_t
SINT8 throwdir; // Held dir of controls; 1 = forward, 0 = none, -1 = backward (was "player->heldDir")
UINT8 sadtimer; // How long you've been sad
UINT8 bricktimer; // How long you've been brick'ed up
// player's ring count
SINT8 rings;
@ -637,8 +690,11 @@ struct player_t
UINT8 ringvolume; // When consuming lots of rings, lower the sound a little.
UINT8 ringtransparency; // When consuming lots of rings, fade out the rings again.
UINT8 airdroptime; // Tracks how long airdrop has been active, used for delay before airdrop kicks in.
boolean ringdrop; // Set when having ringdrop applied.
INT32 airdroppredelay; // Handles the delay before airdrop can be activated once going airborne.
INT32 airdroptime; // Tracks how long the player has been in airdrop.
INT32 airdropbuffer; // Mercy time for when heavy air drop will instantly activate once the pre-delay is over.
INT32 airdropheavydash; // Heavy Air Drop acceleration assist time
p_airdropflags_t airdropflags; // Airdrop-exclusive bitflags.
mobj_t *shieldtracer; // Blankart: Shield mobj
@ -651,8 +707,8 @@ struct player_t
UINT16 flamedash; // Flame Shield dash power
INT32 flametimer; // Flame Shield dash meter left ("fuel")
UINT8 flamestore; // Flame Shield reserve boost ("temperature")
UINT8 flameburnstop; // Time Flame Shield can't increase temperature for
tic_t flameoverheat; // Time the Flame Shield spends overheating
tic_t flamecamtime; // Timer for flame shield usage camera effect
UINT16 hyudorotimer; // Duration of the Hyudoro offroad effect itself
SINT8 stealingtimer; // you are stealing
@ -679,10 +735,12 @@ struct player_t
UINT16 rocketsneakertimer; // Rocket Sneaker duration timer
UINT16 invincibilitytimer; // Invincibility timer
UINT16 maxinvincibilitytime; // (Alternate) Initial time for Invincibility, used for the item bar.
UINT16 invincibilitybottleneck; // (Alternate) Prevents breakaways by gradienting towards a heavier decrement.
INT16 invincibilitycancel; // (Alternate) Duration of Invincibility canceling.
UINT8 invincibilitywarning; // (Alternate) "Timer warning" boolean to signal Alt. Invin. is running out.
UINT16 smonitortimer; // S-Monitor timer
UINT16 maxsmonitortime; // Initial time for the S-Monitor, used for the item bar.
UINT16 smonitorexpiring; // Once you pass the cluster player, this starts the time limit for your S-Monitor invincibility.
INT16 smonitorcancel; // Duration of S-Monitor canceling.
UINT8 smonitorwarning; // "Timer warning" boolean to signal the S-Monitor is running out.
UINT8 eggmanexplode; // Fake item recieved, explode in a few seconds
SINT8 eggmanblame; // (-1 to 15) - Fake item recieved, who set this fake
@ -692,9 +750,6 @@ struct player_t
SINT8 lastjawztarget; // (-1 to 15) - Last person you target with jawz, for playing the target switch sfx
UINT8 jawztargetdelay; // (0 to 5) - Delay for Jawz target switching, to make it less twitchy
UINT8 confirmVictim; // Player ID that you dealt damage to
UINT8 confirmVictimDelay; // Delay before playing the sound
UINT8 dashRingPullTics; // Timer during which the player is pulled towards a dash ring
UINT8 dashRingPushTics; // Timer during which the player displays effects and has no gravity after being thrust by a dash ring
UINT8 dashRainbowPogo; // Determines when to disable pogospring extra gravity after using a rainbow dash ring

View file

@ -33,8 +33,9 @@ typedef enum
BT_FORWARD = 1<<5, // Aim Item Forward
BT_BACKWARD = 1<<6, // Aim Item Backward
BT_LOOKBACK = 1<<7, // Look Backward
BT_HORN = 1<<8, // Honk your (follower's) horn
// free: 1<<8 to 1<<12
// free: 1<<9 to 1<<12
// Lua garbage
BT_CUSTOM1 = 1<<13,

View file

@ -88,7 +88,7 @@ static int action_call(lua_State *L)
// Hardcoded A_Action name to call for super() or NULL if super() would be invalid.
// Set in lua_infolib.
const char *superactions[MAXRECURSION];
const char *superactions[MAXRECURSION] = {};
UINT8 superstack = 0;
static int lib_dummysuper(lua_State *L)
@ -178,6 +178,18 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
if (mathlib) return luaL_error(L, "playerflag '%s' could not be found.\n", word);
return 0;
}
else if (fastncmp("PAF_", word, 4)) {
p = word+4;
for (i = 0; AIRDROPFLAG_LIST[i]; i++)
{
if (fastcmp(p, AIRDROPFLAG_LIST[i])) {
CacheAndPushConstant(L, word, ((lua_Integer)1<<i));
return 1;
}
}
if (mathlib) return luaL_error(L, "airdropflag '%s' could not be found.\n", word);
return 0;
}
else if (fastncmp("IF_", word, 3)) {
p = word+3;
for (i = 0; ITEMFLAG_LIST[i]; i++)
@ -360,7 +372,7 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
else if (fastncmp("sfx_",word,4)) {
p = word+4;
for (i = 0; i < NUMSFX; i++)
if (S_sfx[i].name && fastcmp(p, S_sfx[i].name)) {
if (S_sfx[i].name && fasticmp(p, S_sfx[i].name)) {
CacheAndPushConstant(L, word, i);
return 1;
}

View file

@ -866,7 +866,7 @@ void readlevelheader(MYFILE *f, char * name)
if (mapheaderinfo[num]->lumpname == NULL)
{
mapheaderinfo[num]->lumpname = Z_StrDup(name);
mapheaderinfo[num]->lumpnamehash = quickncasehash(mapheaderinfo[num]->lumpname, MAXMAPLUMPNAME);
mapheaderinfo[num]->lumpnamehash = FNV1a_QuickCaseHash(mapheaderinfo[num]->lumpname, MAXMAPLUMPNAME);
}
do
@ -3762,7 +3762,9 @@ void readfollower(MYFILE *f)
followers[numfollowers].bobspeed = TICRATE*2;
followers[numfollowers].bobamp = 4*FRACUNIT;
followers[numfollowers].hitconfirmtime = TICRATE;
followers[numfollowers].horntime = TICRATE;
followers[numfollowers].defaultcolor = FOLLOWERCOLOR_MATCH;
followers[numfollowers].hornsound = sfx_horn00;
strcpy(followers[numfollowers].icon, "MISSING");
do
@ -3829,6 +3831,10 @@ void readfollower(MYFILE *f)
followers[numfollowers].defaultcolor = color == MAXSKINCOLORS ? SKINCOLOR_GREEN : color;
}
}
else if (fastcmp(word, "HORNSOUND"))
{
followers[numfollowers].hornsound = get_number(word2);
}
else if (fastcmp(word, "SCALE"))
{
followers[numfollowers].scale = (fixed_t)get_number(word2);
@ -3914,6 +3920,16 @@ void readfollower(MYFILE *f)
{
followers[numfollowers].hitconfirmtime = (tic_t)get_number(word2);
}
else if (fastcmp(word, "HORNSTATE"))
{
if (word2)
strupr(word2);
followers[numfollowers].hornstate = get_number(word2);
}
else if (fastcmp(word, "HORNTIME"))
{
followers[numfollowers].horntime = (tic_t)get_number(word2);
}
else
{
deh_warning("Follower %d: unknown word '%s'", numfollowers, word);
@ -3980,6 +3996,7 @@ if ((signed)followers[numfollowers].field < threshold) \
FALLBACK(bobamp, "BOBAMP", 0, 0);
FALLBACK(bobspeed, "BOBSPEED", 0, 0);
FALLBACK(hitconfirmtime, "HITCONFIRMTIME", 1, 1);
FALLBACK(horntime, "HORNTIME", 1, 1);
FALLBACK(scale, "SCALE", 1, 1); // No null/negative scale
FALLBACK(bubblescale, "BUBBLESCALE", 0, 0); // No negative scale
@ -4011,6 +4028,7 @@ if (!followers[numfollowers].field) \
NOSTATE(losestate, "LOSESTATE");
NOSTATE(winstate, "WINSTATE");
NOSTATE(hitconfirmstate, "HITCONFIRMSTATE");
NOSTATE(hornstate, "HORNSTATE");
#undef NOSTATE
CONS_Printf("Added follower '%s'\n", dname);

View file

@ -32,6 +32,7 @@
#include "k_kart.h" // awardscaledrings_t
#include "k_hud.h" // scoreboardmod_e
#include "k_waypoint.h" // waypoint values (for lua)
#include "h_timers.h" // timerflags_t
#include "deh_tables.h"
@ -425,6 +426,17 @@ struct int_const_s const PLAYERFLAG_ALIASES[] = {
{ NULL, 0 }
};
const char *const AIRDROPFLAG_LIST[] = {
"AIRDROPINPUT", // Wants air drop (active while holding down brake, used for bouncy air drop)
"WANTSAIRDROP", // Is in Air Drop (activation / deactivation criteria change if light or heavy)
"AIRDROP_LIGHT", // Is in Light Air Drop
"AIRDROP_HEAVY", // Is in Heavy Air Drop
"AIRDROP_MASK", // Is in any Air Drop state
NULL // stop loop here.
};
const char *const ITEMFLAG_LIST[] = {
"USERINGS",
"ITEMOUT",
@ -557,6 +569,7 @@ const char *const SD_LIST[] = {
"LAVA",
"DEATHPIT",
"INSTAKILL",
"FLIPOVER",
NULL
};
@ -862,7 +875,7 @@ struct menu_drawer_s const MENU_DRAWERS[] = {
};
struct odds_func_s const USEODDS_FUNCS[] = {
{ "ALTINVINODDS", &KO_AltInvinOdds },
{ "SMONITORODDS", &KO_SMonitorOdds },
{ "SPBRACEODDS", &KO_SPBRaceOdds },
{ NULL, NULL }
};
@ -1369,6 +1382,7 @@ struct int_const_s const INT_CONST[] = {
{"BT_FORWARD",BT_FORWARD},
{"BT_BACKWARD",BT_BACKWARD},
{"BT_LOOKBACK",BT_LOOKBACK},
{"BT_HORN",BT_HORN},
{"BT_CUSTOM1",BT_CUSTOM1}, // Lua customizable
{"BT_CUSTOM2",BT_CUSTOM2}, // Lua customizable
{"BT_CUSTOM3",BT_CUSTOM3}, // Lua customizable
@ -1544,6 +1558,7 @@ struct int_const_s const INT_CONST[] = {
{"GC_CUSTOM3",gc_custom3},
{"GC_RESPAWN",gc_respawn},
{"GC_DIRECTOR",gc_director},
{"GC_HORNCODE",gc_horncode},
{"NUM_GAMECONTROLS",num_gamecontrols},
// screen.h constants
@ -1584,6 +1599,7 @@ struct int_const_s const INT_CONST[] = {
{"KIF_DARKBG",KIF_DARKBG},
{"KIF_COLPATCH2PLAYER",KIF_COLPATCH2PLAYER},
{"KIF_HIDEFROMROULETTE",KIF_HIDEFROMROULETTE},
{"KIF_HYUCANTSTEAL",KIF_HYUCANTSTEAL},
// kartresultflags_e
{"KRF_INDIRECTITEM",KRF_INDIRECTITEM},
@ -1739,14 +1755,15 @@ struct int_const_s const INT_CONST[] = {
{"PICKUPITEM_ITEM", PICKUPITEM_ITEM},
{"PICKUPITEM_EGGMAN", PICKUPITEM_EGGMAN},
{"PICKUPITEM_FLOATING", PICKUPITEM_FLOATING},
{"PICKUPITEM_EGGMINE", PICKUPITEM_EGGMINE},
// kart_fullturn
{"KART_FULLTURN", KART_FULLTURN},
// invin constants
{"KART_NUMINVSPARKLESANIM", KART_NUMINVSPARKLESANIM},
{"BASEINVINTIME", BASEINVINTIME},
{"MININVINTIME", MININVINTIME},
{"INVINTIME", INVINTIME},
{"SMONITORTIME", SMONITORTIME},
// grow/shrink scale
{"GROW_SCALE", GROW_SCALE},
@ -1796,5 +1813,35 @@ struct int_const_s const INT_CONST[] = {
{"BLANKART", 1},
// recoverydash stuff
{"RECOVERYDASHADD", RECOVERYDASHADD},
{"RECOVERYDASHCHARGETIME", RECOVERYDASHCHARGETIME},
{"RECOVERYDASHWIPETIME", RECOVERYDASHWIPETIME},
// airdroptype_t
{"AIRDROP_NONE", AIRDROP_NONE},
{"AIRDROP_LIGHT", AIRDROP_LIGHT},
{"AIRDROP_HEAVY", AIRDROP_HEAVY},
{"AIRDROP_FUSION", AIRDROP_FUSION},
// item timer stuff
{"TIMER_COUNTER", TIMER_COUNTER},
{"TIMER_NONUMBER",TIMER_NONUMBER},
{"TIMER_PURPLE", TIMER_PURPLE},
{"TIMER_YELLOW", TIMER_YELLOW},
{"TIMER_GREEN", TIMER_GREEN},
{"TIMER_BLUE", TIMER_BLUE},
{"TIMER_RED", TIMER_RED},
{"TIMER_GRAY", TIMER_GRAY},
{"TIMER_ORANGE", TIMER_ORANGE},
{"TIMER_SKY", TIMER_SKY},
{"TIMER_LAVENDER", TIMER_LAVENDER},
{"TIMER_GOLD", TIMER_GOLD},
{"TIMER_AQUA", TIMER_AQUA},
{"TIMER_MAGENTA", TIMER_MAGENTA},
{"TIMER_PINK", TIMER_PINK},
{"TIMER_BROWN", TIMER_BROWN},
{"TIMER_TAN", TIMER_TAN},
{NULL,0}
};

View file

@ -93,6 +93,7 @@ extern const char *const MOBJEFLAG_LIST[];
extern const char *const MAPTHINGFLAG_LIST[4];
extern const char *const PLAYERFLAG_LIST[];
extern struct int_const_s const PLAYERFLAG_ALIASES[];
extern const char *const AIRDROPFLAG_LIST[];
extern const char *const ITEMFLAG_LIST[];
extern const char *const GAMETYPERULE_LIST[];
extern const char *const ML_LIST[]; // Linedef flags

View file

@ -34,7 +34,7 @@ FUNCPRINTF void deh_warning(const char *first, ...)
vsnprintf(buf, 1000, first, argptr); // sizeof only returned 4 here. it didn't like that pointer.
va_end(argptr);
if(dbg_line == -1) // Not in a SOC, line number unknown.
if (dbg_line == -1) // Not in a SOC, line number unknown.
CONS_Alert(CONS_WARNING, "%s\n", buf);
else
CONS_Alert(CONS_WARNING, "Line %u: %s\n", dbg_line, buf);
@ -726,7 +726,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
{
cupheader_t *cup = kartcupheaders;
cupheader_t *prev = NULL;
UINT32 hash = quickncasehash(word2, MAXCUPNAME);
UINT32 hash = FNV1a_QuickCaseHash(word2, MAXCUPNAME);
while (cup)
{

View file

@ -412,22 +412,6 @@ extern boolean capslock;
// i_system.c, replace getchar() once the keyboard has been appropriated
INT32 I_GetKey(void);
/* http://www.cse.yorku.ca/~oz/hash.html */
static inline
UINT32 quickncasehash (const char *p, size_t n)
{
size_t i = 0;
UINT32 x = 5381;
while (i < n && p[i])
{
x = (x * 33) ^ tolower(p[i]);
i++;
}
return x;
}
// Standard Hashing Functions (tm)
// see W_MakeFileHash for hashing files
#include "xxhash.h"

View file

@ -367,7 +367,7 @@ struct mapheader_t
{
// Core game information, not user-modifiable directly
char *lumpname; ///< Lump name can be really long
UINT32 lumpnamehash; ///< quickncasehash(->lumpname, MAXMAPLUMPNAME)
UINT32 lumpnamehash; ///< FNV1a_QuickCaseHash(->lumpname, MAXMAPLUMPNAME)
lumpnum_t lumpnum; ///< Lump number for the map, used by vres_GetMap
void *thumbnailPic; ///< Lump data for the level select thumbnail.

View file

@ -58,22 +58,22 @@ void I_Tactile2(FFType Type, const JoyFF_t *Effect)
(void)Effect;
}
void I_JoyScale(void){}
void I_ControllerScale(void){}
void I_JoyScale2(void){}
void I_ControllerScale2(void){}
void I_InitJoystick(void){}
void I_InitController(void){}
void I_InitJoystick2(void){}
void I_InitController2(void){}
INT32 I_NumJoys(void)
INT32 I_NumControllers(void)
{
return 0;
}
const char *I_GetJoyName(INT32 joyindex)
const char *I_GetControllerName(INT32 joyid)
{
(void)joyindex;
(void)joyid;
return NULL;
}

View file

@ -651,8 +651,8 @@ void F_SecretCreditsTicker(void)
dscreditsticks++;
INT32 w = (vid.width / vid.dupx);
INT32 h = (vid.height / vid.dupy);
INT32 w = vid.scaledwidth;
INT32 h = (vid.height / vid.dup);
const INT32 vidxdiff = (w - BASEVIDWIDTH) / 2;
const INT32 vidydiff = (h - BASEVIDHEIGHT) / 2;
@ -1132,7 +1132,7 @@ void F_SecretCreditsTicker(void)
case 1: y += 30<<FRACBITS; break;
default: y += 12<<FRACBITS; break;
}
if (FixedMul(y,vid.dupy) > vid.height)
if (FixedMul(y,vid.dup) > vid.height)
break;
}
}
@ -1159,7 +1159,7 @@ void F_SecretCreditsTicker(void)
// Repeats horizontally until it reaches across the screen.
static void F_DrawBannerPatch(fixed_t x, fixed_t y, fixed_t scale, INT32 scrn, patch_t *patch, const UINT8 *colormap)
{
fixed_t w = (vid.width / vid.dupx);
fixed_t w = vid.scaledwidth;
fixed_t vidxdiff = ((w - BASEVIDWIDTH) << FRACBITS) / 2;
fixed_t pw = (static_cast<fixed_t>(SHORT(patch->width)) * scale);
@ -1320,8 +1320,8 @@ static void F_FakeTitleScreen(tic_t count)
{
INT32 w, h;
w = (vid.width / vid.dupx);
h = (vid.height / vid.dupy);
w = vid.scaledwidth;
h = (vid.height / vid.dup);
const INT32 vidxdiff = (w - BASEVIDWIDTH) / 2;
const INT32 vidydiff = (h - BASEVIDHEIGHT) / 2;
@ -1369,8 +1369,8 @@ void F_SecretCreditsDrawer(void)
INT32 w, h;
UINT8 bgcolor = 31;
w = (vid.width / vid.dupx);
h = (vid.height / vid.dupy);
w = vid.scaledwidth;
h = (vid.height / vid.dup);
const INT32 vidxdiff = (w - BASEVIDWIDTH) / 2;
const INT32 vidydiff = (h - BASEVIDHEIGHT) / 2;
@ -1473,7 +1473,7 @@ void F_SecretCreditsDrawer(void)
y += 20<<FRACBITS;
break;
}
if (((y>>FRACBITS) * vid.dupy) > vid.height)
if (((y>>FRACBITS) * vid.dup) > vid.height)
break;
}
}
@ -1501,7 +1501,7 @@ void F_SecretCreditsDrawer(void)
y += 20<<FRACBITS;
break;
}
if (((y>>FRACBITS) * vid.dupy) > vid.height)
if (((y>>FRACBITS) * vid.dup) > vid.height)
break;
}
}

View file

@ -235,7 +235,7 @@ static void F_TitleBGScroll(INT32 scrollspeed)
pat = W_CachePatchName("TITLEBG1", PU_CACHE);
pat2 = W_CachePatchName("TITLEBG2", PU_CACHE);
w = (vid.width / vid.dupx)<<FRACBITS;
w = (vid.scaledwidth << 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_GetTimeFrac(RTF_MENU) * scrollspeed))/16;
@ -777,7 +777,7 @@ void F_CreditDrawer(void)
y += 12<<FRACBITS;
break;
}
if (((y>>FRACBITS) * vid.dupy) > vid.height)
if (((y>>FRACBITS) * vid.dup) > vid.height)
break;
}
}
@ -797,7 +797,7 @@ void F_CreditTicker(void)
case 1: y += 30<<FRACBITS; break;
default: y += 12<<FRACBITS; break;
}
if (FixedMul(y,vid.dupy) > vid.height)
if (FixedMul(y,vid.dup) > vid.height)
break;
}
@ -924,6 +924,11 @@ const char *blancredits[] = {
"\"Chearii\"",
"\"hayaunderscore\" aka \"DeltaKanyx\"",
"\"Guilmon35249vr\"",
"Vivian \"toaster\" Grannell", // Horncode
"AJ \"Tyron\" Martinez", // Horncode
"\"Superstarxalien\"", // Horncode
"\"Freaky Mutant Man\"", // Color profiles menu
"\"blondedradio\"", // Screen-tracking item roulette, lifted near-directly from RadioRacers
"",
"\1Item Design",
"\"NepDisk\"",
@ -937,6 +942,9 @@ const char *blancredits[] = {
"\"luna\"",
"\"White Mage (guy who picked up controller)\"",
"\"minenice\"",
"\"StarrydustNova\"",
"\"merritt\"",
"\"Sunflower\" aka \"AnimeSonic\"",
"",
"\1New Item Art",
"\"Spee\"",
@ -957,9 +965,13 @@ const char *blancredits[] = {
"\"Miguelius256\"",
"\"Toddoesstuff\"",
"\"RetroStation\"",
"\"StarrydustNova\"",
"\"joshyflip\"",
"",
"\1New Misc Art",
"\"scizor300\"",
"\"StarrydustNova\"", // Per some indev talks. Can't reveal the secrets yet!
"\"joshyflip\"", // Per some indev talks. Can't reveal the secrets yet!
"",
"\1Additional Assets",
"Sonic Team Jr.",
@ -1030,11 +1042,14 @@ const char *blancredits[] = {
"\"PX8916\"",
"\"Tom\"",
"\"Phoenix\"",
"\"StarrydustNova\"",
"\"Prada\"",
"",
"\1Special Thanks",
"\"merritt\"",
"\"luna\"",
"\"Sunflower\" aka \"AnimeSonic\"",
"\"StarrydustNova\"",
"Sunflower's Garden",
"The Moe Mansion and Birdhouse Team",
"SRB2Kart Saturn Contributors",
@ -1149,7 +1164,7 @@ void F_BlanCreditDrawer(void)
}
F_DrawDiagCubes();
if (((y>>FRACBITS) * vid.dupy) > vid.height)
if (((y>>FRACBITS) * vid.dup) > vid.height)
break;
}
}
@ -1169,7 +1184,7 @@ void F_BlanCreditTicker(void)
case 1: y += 20<<FRACBITS; break;
default: y += 12<<FRACBITS; break;
}
if (FixedMul(y,vid.dupy) > vid.height)
if (FixedMul(y,vid.dup) > vid.height)
break;
}
@ -1291,9 +1306,8 @@ void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, const char *patchname)
INT32 xscrolled, x, xneg = (scrollxspeed > 0) - (scrollxspeed < 0), tilex;
INT32 yscrolled, y, yneg = (scrollyspeed > 0) - (scrollyspeed < 0), tiley;
boolean xispos = (scrollxspeed >= 0), yispos = (scrollyspeed >= 0);
INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
INT16 patwidth, patheight;
INT32 pw, ph; // scaled by dupz
INT32 pw, ph; // scaled by vid.dup
patch_t *pat;
INT32 i, j;
fixed_t fracmenuanimtimer, xscrolltimer, yscrolltimer;
@ -1318,8 +1332,8 @@ void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, const char *patchname)
patwidth = pat->width;
patheight = pat->height;
pw = patwidth * dupz;
ph = patheight * dupz;
pw = patwidth * vid.dup;
ph = patheight * vid.dup;
tilex = max(FixedCeil(FixedDiv(vid.width, pw)) >> FRACBITS, 1)+2; // one tile on both sides of center
tiley = max(FixedCeil(FixedDiv(vid.height, ph)) >> FRACBITS, 1)+2;
@ -1329,8 +1343,8 @@ void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, const char *patchname)
yscrolltimer = ((fracmenuanimtimer*scrollyspeed)/16 + patheight*yneg*FRACUNIT) % (patheight * FRACUNIT);
// coordinate offsets
xscrolled = FixedInt(xscrolltimer * dupz);
yscrolled = FixedInt(yscrolltimer * dupz);
xscrolled = FixedInt(xscrolltimer * vid.dup);
yscrolled = FixedInt(yscrolltimer * vid.dup);
for (x = (xispos) ? -pw*(tilex-1)+pw : 0, i = 0;
i < tilex;
@ -1796,9 +1810,7 @@ void F_StartWaitingPlayers(void)
#ifdef NOWAY
randskin = M_RandomKey(numskins);
if (waitcolormap)
Z_Free(waitcolormap);
Z_Free(waitcolormap);
waitcolormap = R_GetTranslationColormap(randskin, skins[randskin].prefcolor, 0);
sprdef = &skins[randskin].sprites[P_GetSkinSprite2(&skins[randskin], SPR2_FSTN, NULL)];
@ -2100,7 +2112,7 @@ static fixed_t F_GetPromptHideHudBound(void)
F_GetPageTextGeometry(&pagelines, &rightside, &boxh, &texth, &texty, &namey, &chevrony, &textx, &textr);
// calc boxheight (see V_DrawPromptBack)
boxh *= vid.dupy;
boxh *= vid.dup;
boxh = (boxh * 4) + (boxh/2)*5; // 4 lines of space plus gaps between and some leeway
// return a coordinate to check

View file

@ -283,8 +283,7 @@ void closefilemenu(boolean validsize)
coredirmenu = NULL;
}
if (refreshdirname)
Z_Free(refreshdirname);
Z_Free(refreshdirname);
refreshdirname = NULL;
}
@ -312,8 +311,7 @@ void searchfilemenu(char *tempname)
if (!menusearch.length)
{
if (dirmenu)
Z_Free(dirmenu);
Z_Free(dirmenu);
dirmenu = coredirmenu;
sizedirmenu = sizecoredirmenu;
@ -355,8 +353,8 @@ void searchfilemenu(char *tempname)
I_Error("searchfilemenu(): could not create \"No results...\".");
sizedirmenu = 1;
dir_on[menudepthleft] = 0;
if (tempname)
Z_Free(tempname);
Z_Free(tempname);
return;
}
@ -480,8 +478,8 @@ boolean preparefilemenu(boolean samedepth, boolean replayhut)
{
closedir(dirhandle);
closefilemenu(false);
if (tempname)
Z_Free(tempname);
Z_Free(tempname);
return false;
}

View file

@ -33,7 +33,7 @@
#include "z_zone.h"
#include "i_video.h"
#include "byteptr.h"
#include "i_joy.h"
#include "i_gamepad.h"
#include "r_local.h"
#include "r_skins.h"
#include "y_inter.h"

View file

@ -19,6 +19,7 @@
#include "d_clisrv.h"
#include "f_finale.h"
#include "filesrch.h" // for refreshdirmenu
#include "g_input.h"
#include "m_fixed.h"
#include "p_setup.h"
#include "p_saveg.h"
@ -41,7 +42,7 @@
#include "z_zone.h"
#include "i_video.h"
#include "byteptr.h"
#include "i_joy.h"
#include "i_gamepad.h"
#include "r_local.h"
#include "r_skins.h"
#include "y_inter.h"
@ -84,8 +85,8 @@ UINT8 ultimatemode = false;
JoyType_t Joystick[MAXSPLITSCREENPLAYERS];
// SRB2kart
char gamedatafilename[64] = "kartdata.dat";
char timeattackfolder[64] = "kart";
char gamedatafilename[64] = "blandata.dat";
char timeattackfolder[64] = "blan";
char customversionstring[32] = "\0";
static void G_DoCompleted(void);
@ -464,6 +465,15 @@ consvar_t cv_jitterlegacy[MAXSPLITSCREENPLAYERS] = {
CVAR_INIT ("driftjitter4", "Ring Racers", CV_SAVE|CV_CALL|CV_NOINIT, driftjitter_cons_t, weaponPrefChange)
};
static CV_PossibleValue_t driftmode_cons_t[] = {{DRIFTMODE_CLASSIC, "Classic"}, {DRIFTMODE_SNAPSHOT, "Snapshot"}, {DRIFTMODE_INSTANT, "Instant"}, {0, NULL}};
consvar_t cv_driftmode[MAXSPLITSCREENPLAYERS] = {
CVAR_INIT ("driftmode", "Classic", CV_SAVE|CV_CALL|CV_NOINIT, driftmode_cons_t, weaponPrefChange),
CVAR_INIT ("driftmode2", "Classic", CV_SAVE|CV_CALL|CV_NOINIT, driftmode_cons_t, weaponPrefChange),
CVAR_INIT ("driftmode3", "Classic", CV_SAVE|CV_CALL|CV_NOINIT, driftmode_cons_t, weaponPrefChange),
CVAR_INIT ("driftmode4", "Classic", CV_SAVE|CV_CALL|CV_NOINIT, driftmode_cons_t, weaponPrefChange)
};
static CV_PossibleValue_t zerotoone_cons_t[] = {{0, "MIN"}, {FRACUNIT, "MAX"}, {0, NULL}};
consvar_t cv_deadzonex[MAXSPLITSCREENPLAYERS] = {
CVAR_INIT ("xdeadzone", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL),
@ -493,6 +503,10 @@ consvar_t cv_deadzonestyle[MAXSPLITSCREENPLAYERS] = {
CVAR_INIT ("deadzonestyle4", "Kart", CV_SAVE, deadzonestyle_cons_t, NULL)
};
// allows players to use restat (server toggle)
consvar_t cv_allowrestat = CVAR_INIT ("allowrestat", "Yes", CV_NETVAR, CV_YesNo, NULL);
consvar_t cv_notifyrestat = CVAR_INIT ("notifyrestat", "Yes", CV_NETVAR, CV_YesNo, NULL);
// now automatically allocated in D_RegisterClientCommands
// so that it doesn't have to be updated depending on the value of MAXPLAYERS
char player_names[MAXPLAYERS][MAXPLAYERNAME+1];
@ -929,7 +943,7 @@ static void G_SetSaveGameModified(void)
savemoddata = true;
strlcpy(gamedatafilename, "modkartdata.dat", sizeof (gamedatafilename));
strlcpy(gamedatafilename, "modblandata.dat", sizeof (gamedatafilename));
strlwr(gamedatafilename);
// Also save a time attack folder
@ -1015,7 +1029,7 @@ INT32 G_MapNumber(const char * name)
#endif
{
INT32 map;
UINT32 hash = quickncasehash(name, MAXMAPLUMPNAME);
UINT32 hash = FNV1a_QuickCaseHash(name, MAXMAPLUMPNAME);
for (map = 0; map < nummapheaders; ++map)
{
@ -1173,6 +1187,7 @@ boolean G_AxisInDeadzone(UINT8 p, event_t *ev)
// if defaults is true, also check default controls if the gamecontrol has no binds
boolean G_ControlBoundToKey(UINT8 p, INT32 gc, INT32 key, boolean defaults)
{
INT32 deviceID;
INT32 i;
INT32 (*map)[MAXINPUTMAPPING] = &gamecontrol[p][gc];
@ -1181,9 +1196,11 @@ boolean G_ControlBoundToKey(UINT8 p, INT32 gc, INT32 key, boolean defaults)
if (defaults)
{
deviceID = I_GetControllerSlotfromID(I_GetControllerIDForPlayer(p));
for (i = 0; i < MAXINPUTMAPPING; i++)
if (G_KeyIsAvailable((*map)[i], cv_usejoystick[p].value, false))
if (G_KeyIsAvailable((*map)[i], deviceID, false))
goto bound;
map = &gamecontroldefault[gc];
}
bound:
@ -1246,11 +1263,18 @@ INT32 G_PlayerInputAnalog(UINT8 p, INT32 gc, boolean digital, SINT8 type)
return 0;
}
fixed_t deadzonetype = G_GetDeadZoneType(p,type);
fixed_t deadzonetype = G_GetDeadZoneType(p, type);
deadzone = (JOYAXISRANGE * deadzonetype) / FRACUNIT;
deviceID = I_GetJoystickDeviceIndexForPlayer(p) + 1;
deviceID = I_GetControllerSlotfromID(I_GetControllerIDForPlayer(p));
if (deviceID >= MAXDEVICES)
return 0;
// not a controller?
// then its a keyboard or mouse
if (deviceID == INVALID_DEVICE)
deviceID = KEYBOARD_MOUSE_DEVICE;
retrygetcontrol:
for (i = 0; i < MAXINPUTMAPPING; i++)
@ -1527,14 +1551,17 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
forward += (value * MAXPLMOVE) / JOYAXISRANGE;
}
if (player->sneakertimer)
if (player->sneakertimer || player->recoverydash)
forward = MAXPLMOVE; // 50
value = G_PlayerInputAnalog(forplayer, gc_brake, false, DEADZONE_BUTTON);
if (value != 0)
{
cmd->buttons |= BT_BRAKE;
forward -= (value * 25) / JOYAXISRANGE;
if (!(player->pflags & PF_RECOVERYSPIN))
{
forward -= (value * 25) / JOYAXISRANGE;
}
}
// But forward/backward IS used for aiming.
@ -1563,6 +1590,12 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
cmd->buttons |= BT_LOOKBACK;
}
// horn with any button/key
if (G_PlayerInputDown(forplayer, gc_horncode, false, DEADZONE_BUTTON))
{
cmd->buttons |= BT_HORN;
}
// Lua scriptable buttons
if (G_PlayerInputDown(forplayer, gc_custom1, false, DEADZONE_BUTTON))
cmd->buttons |= BT_CUSTOM1;
@ -1790,14 +1823,13 @@ void G_DoLoadLevel(boolean resetplayer)
// clear cmd building stuff
memset(gamekeydown, 0, sizeof (gamekeydown));
memset(deviceResponding, false, sizeof (deviceResponding));
// clear hud messages remains (usually from game startup)
CON_ClearHUD();
server_lagless = cv_lagless.value;
G_ResetAllDeviceRumbles();
G_ResetAllControllerRumbles();
if (doAutomate == true)
{
@ -2148,6 +2180,12 @@ boolean G_Responder(event_t *ev)
case ev_joystick:
return true; // eat events
case ev_accelerometer:
return true; // eat events
case ev_gyroscope:
return true; // eat events
default:
break;
}
@ -2722,6 +2760,60 @@ static inline void G_PlayerFinishLevel(INT32 player)
}
}
typedef struct {
INT32 player;
boolean notifyrestat;
UINT8 kartspeed, kartweight, kartspeedrestat, kartweightrestat;
} restatmessage_t;
static void G_HandleRestatMessage(restatmessage_t *rm)
{
if (players[rm->player].jointime == 0)
return;
UINT16 chatcolor = skincolors[players[rm->player].skincolor].chatcolor;
char color_prefix[2] = {};
if (chatcolor > V_TANMAP)
{
sprintf(color_prefix, "%c", '\x80');
}
else
{
sprintf(color_prefix, "%c", '\x80' + (chatcolor >> V_CHARCOLORSHIFT));
}
if (rm->kartspeedrestat != 0 && rm->kartweightrestat != 0)
{
if (playeringame[rm->player] && rm->notifyrestat)
{
if ((splitscreen && rm->player == consoleplayer) || rm->player != consoleplayer)
{
HU_AddChatText(va("%s%s\x82 is now \x84%d speed\x82, \x87%d weight\x82.", color_prefix, player_names[rm->player], rm->kartspeed, rm->kartweight), true);
}
else
{
HU_AddChatText(va("%sYou\x82 are now \x84%d speed\x82, \x87%d weight\x82.", color_prefix, rm->kartspeed, rm->kartweight), true);
}
}
}
else
{
if (playeringame[rm->player] && rm->notifyrestat)
{
if ((splitscreen && rm->player == consoleplayer) || rm->player != consoleplayer)
{
HU_AddChatText(va("%s%s\x82 is now using their skin's default stats.", color_prefix, player_names[rm->player]), true);
}
else
{
HU_AddChatText(va("%sYou\x82 are now using your skin's default stats.", color_prefix), true);
}
}
}
}
//
// G_PlayerReborn
// Called after a player dies. Almost everything is cleared and initialized.
@ -2736,6 +2828,10 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
UINT8 kartspeed;
UINT8 kartweight;
UINT8 kartspeedrestat;
UINT8 kartweightrestat;
boolean randomrestat;
boolean notifyrestat;
boolean followerready;
INT32 followerskin;
@ -2833,6 +2929,10 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
kartspeed = players[player].kartspeed;
kartweight = players[player].kartweight;
kartspeedrestat = players[player].kartspeedrestat;
kartweightrestat = players[player].kartweightrestat;
randomrestat = players[player].randomrestat;
followerready = players[player].followerready;
followercolor = players[player].followercolor;
followerskin = players[player].followerskin;
@ -2858,7 +2958,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_KICKSTARTACCEL|PF_SHRINKME|PF_SHRINKACTIVE|PF_FLIPCAM));
// SRB2kart
if (betweenmaps || leveltime <= starttime || spectator == true)
if (betweenmaps || leveltime <= starttime || spectator == true || players[player].jointime == 0)
{
itemroulette = 0;
previtemroulette = 0;
@ -2884,7 +2984,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
exiting = 0;
khudfinish = 0;
khudcardanimation = 0;
starpostx =0;
starpostx = 0;
starposty = 0;
starpostz = 0;
starpostangle = 0;
@ -2898,6 +2998,42 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
{
laptime[i] = 0;
}
// might cause issues with weponpref sync?
if (!cv_allowrestat.value)
{
kartspeedrestat = 0;
kartweightrestat = 0;
randomrestat = false;
}
if (randomrestat)
{
kartspeedrestat = P_RandomRange(1, 9);
kartweightrestat = P_RandomRange(1, 9);
}
if (kartspeedrestat != 0 && kartweightrestat != 0)
{
kartspeed = kartspeedrestat;
kartweight = kartweightrestat;
notifyrestat = (
randomrestat ||
kartspeedrestat != players[player].kartspeed ||
kartweightrestat != players[player].kartweight
) && cv_notifyrestat.value;
}
else
{
kartspeed = skins[players[player].skin].kartspeed;
kartweight = skins[players[player].skin].kartweight;
notifyrestat = (
players[player].kartspeed != skins[players[player].skin].kartspeed ||
players[player].kartweight != skins[players[player].skin].kartweight
) && cv_notifyrestat.value;
}
}
else
{
@ -2990,6 +3126,10 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
else
{
follower = NULL;
// Nice and Tidy.
restatmessage_t rm = {player, notifyrestat, kartspeed, kartweight, kartspeedrestat, kartweightrestat};
G_HandleRestatMessage(&rm);
}
spectatorreentry = (betweenmaps ? 0 : players[player].spectatorreentry);
@ -3021,6 +3161,10 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
p->voice_id = voice;
p->kartspeed = kartspeed;
p->kartweight = kartweight;
p->kartspeedrestat = kartspeedrestat;
p->kartweightrestat = kartweightrestat;
p->randomrestat = randomrestat;
//
p->charflags = charflags;
memcpy(players[player].availabilities, availabilities, sizeof(availabilities));
@ -3655,7 +3799,7 @@ void G_FinishExitLevel(void)
{
if (gamestate == GS_LEVEL)
{
G_ResetAllDeviceRumbles();
G_ResetAllControllerRumbles();
if (g_exit.retry)
{
@ -4525,7 +4669,7 @@ static INT16 G_GetNextMap(boolean advancemap)
if (cupLevelNum < nummapheaders && mapheaderinfo[cupLevelNum]
&& mapheaderinfo[cupLevelNum]->typeoflevel & (TOL_BOSS|TOL_BATTLE))
{
grandprixinfo.eventmode = GPEVENT_BONUS;
grandprixinfo.eventmode = GPEVENT_CHALLENGE;
newmap = cupLevelNum;
}
}
@ -4864,7 +5008,8 @@ void G_NextLevel(void)
}
forceresetplayers = false;
deferencoremode = (cv_kartencore.value == 1);
if (cv_kartencore.value == 1)
deferencoremode = true;
gameaction = ga_worlddone;
}

View file

@ -80,6 +80,7 @@ extern consvar_t cv_invertmouse;
extern consvar_t cv_kickstartaccel[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_shrinkme[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_jitterlegacy[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_driftmode[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_deadzonex[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_deadzoney[MAXSPLITSCREENPLAYERS];
@ -96,6 +97,8 @@ extern consvar_t cv_resetspecialmusic;
extern consvar_t cv_resume;
extern consvar_t cv_allowrestat, cv_notifyrestat;
void weaponPrefChange(void);
void weaponPrefChange2(void);
void weaponPrefChange3(void);

View file

@ -14,13 +14,12 @@
#include "doomdef.h"
#include "doomstat.h"
#include "g_input.h"
#include "i_system.h"
#include "k_items.h"
#include "keys.h"
#include "hu_stuff.h" // need HUFONT start & end
#include "d_net.h"
#include "console.h"
#include "i_joy.h" // JOYAXISRANGE
#include "i_gamepad.h" // JOYAXISRANGE
#include "m_menu.h" // menustack
#include "i_system.h"
#include "g_game.h"
@ -55,19 +54,19 @@ consvar_t cv_turnsmooth[MAXSPLITSCREENPLAYERS] = {
CVAR_INIT ("turnsmoothing4", "Off", CV_SAVE, turnsmooth_cons_t, NULL)
};
static void G_ResetPlayerDeviceRumble(INT32 player);
static void G_ResetPlayerControllerRumble(INT32 player);
static void rumble_off_handle(void);
static void rumble_off_handle2(void);
static void rumble_off_handle3(void);
static void rumble_off_handle4(void);
static void G_ResetPlayerGamepadIndicatorColor(INT32 player);
static void G_ResetPlayerControllerIndicatorColor(INT32 player);
static void led_off_handle(void);
static void led_off_handle2(void);
static void led_off_handle3(void);
static void led_off_handle4(void);
consvar_t cv_rumble[MAXSPLITSCREENPLAYERS] = {
consvar_t cv_controllerrumble[MAXSPLITSCREENPLAYERS] = {
CVAR_INIT ("rumble", "On", CV_SAVE, CV_OnOff, rumble_off_handle),
CVAR_INIT ("rumble2", "On", CV_SAVE, CV_OnOff, rumble_off_handle2),
CVAR_INIT ("rumble3", "On", CV_SAVE, CV_OnOff, rumble_off_handle3),
@ -83,62 +82,62 @@ consvar_t cv_rumblestrength[MAXSPLITSCREENPLAYERS] = {
CVAR_INIT ("rumblestrength4", "1.0", CV_SAVE|CV_FLOAT, rumblestrength_cons_t, NULL)
};
static CV_PossibleValue_t gamepadled_cons_t[] = {{0, "Off"}, {1, "Skincolor"}, {2, "Mobjcolor"}, {0, NULL}};
consvar_t cv_gamepadled[MAXSPLITSCREENPLAYERS] = {
CVAR_INIT ("gamepadled", "Skincolor", CV_SAVE|CV_CALL|CV_NOINIT, gamepadled_cons_t, led_off_handle),
CVAR_INIT ("gamepadled2", "Skincolor", CV_SAVE|CV_CALL|CV_NOINIT, gamepadled_cons_t, led_off_handle2),
CVAR_INIT ("gamepadled3", "Skincolor", CV_SAVE|CV_CALL|CV_NOINIT, gamepadled_cons_t, led_off_handle3),
CVAR_INIT ("gamepadled4", "Skincolor", CV_SAVE|CV_CALL|CV_NOINIT, gamepadled_cons_t, led_off_handle4)
static CV_PossibleValue_t controllerled_cons_t[] = {{0, "Off"}, {1, "Skincolor"}, {2, "Mobjcolor"}, {0, NULL}};
consvar_t cv_controllerled[MAXSPLITSCREENPLAYERS] = {
CVAR_INIT ("gamepadled", "Skincolor", CV_SAVE|CV_CALL|CV_NOINIT, controllerled_cons_t, led_off_handle),
CVAR_INIT ("gamepadled2", "Skincolor", CV_SAVE|CV_CALL|CV_NOINIT, controllerled_cons_t, led_off_handle2),
CVAR_INIT ("gamepadled3", "Skincolor", CV_SAVE|CV_CALL|CV_NOINIT, controllerled_cons_t, led_off_handle3),
CVAR_INIT ("gamepadled4", "Skincolor", CV_SAVE|CV_CALL|CV_NOINIT, controllerled_cons_t, led_off_handle4)
};
static void rumble_off_handle(void)
{
if (cv_rumble[0].value == 0)
G_ResetPlayerDeviceRumble(0);
if (cv_controllerrumble[0].value == 0)
G_ResetPlayerControllerRumble(0);
}
static void rumble_off_handle2(void)
{
if (cv_rumble[1].value == 0)
G_ResetPlayerDeviceRumble(1);
if (cv_controllerrumble[1].value == 0)
G_ResetPlayerControllerRumble(1);
}
static void rumble_off_handle3(void)
{
if (cv_rumble[2].value == 0)
G_ResetPlayerDeviceRumble(2);
if (cv_controllerrumble[2].value == 0)
G_ResetPlayerControllerRumble(2);
}
static void rumble_off_handle4(void)
{
if (cv_rumble[3].value == 0)
G_ResetPlayerDeviceRumble(3);
if (cv_controllerrumble[3].value == 0)
G_ResetPlayerControllerRumble(3);
}
static void led_off_handle(void)
{
G_ResetPlayerGamepadIndicatorColor(0);
G_ResetPlayerControllerIndicatorColor(0);
}
static void led_off_handle2(void)
{
G_ResetPlayerGamepadIndicatorColor(1);
G_ResetPlayerControllerIndicatorColor(1);
}
static void led_off_handle3(void)
{
G_ResetPlayerGamepadIndicatorColor(2);
G_ResetPlayerControllerIndicatorColor(2);
}
static void led_off_handle4(void)
{
G_ResetPlayerGamepadIndicatorColor(3);
G_ResetPlayerControllerIndicatorColor(3);
}
// current state of the keys
// JOYAXISRANGE for fully pressed, 0 for not pressed
INT32 gamekeydown[MAXDEVICES][NUMINPUTS] = {};
boolean deviceResponding[MAXDEVICES] = {false};
inputpoll_t gamekeydown = {};
inputpoll_t gamekeydown_msec = {};
// several key codes (or virtual key) per game control
INT32 gamecontrol[MAXSPLITSCREENPLAYERS][num_gamecontrols][MAXINPUTMAPPING] = {};
@ -148,18 +147,19 @@ INT32 gamecontroldefault[num_gamecontrols][MAXINPUTMAPPING] = {
[gc_aimbackward] = {KEY_DOWNARROW, KEY_AXIS1+3 }, // Left Y+
[gc_turnleft ] = {KEY_LEFTARROW, KEY_AXIS1+0 }, // Left X-
[gc_turnright ] = {KEY_RIGHTARROW, KEY_AXIS1+1 }, // Left X+
[gc_accelerate ] = {'a', KEY_JOY1+0 }, // A
[gc_accelerate ] = {'a', KEY_JOY1+0 }, // East
[gc_drift ] = {'s', KEY_JOY1+10, KEY_AXIS1+9}, // RB, RT
[gc_brake ] = {'d', KEY_JOY1+1 }, // B
[gc_brake ] = {'d', KEY_JOY1+1 }, // South
[gc_fire ] = {KEY_SPACE, KEY_JOY1+9, KEY_AXIS1+8}, // LB, LT
[gc_lookback ] = {KEY_LSHIFT, KEY_JOY1+2 }, // X
[gc_lookback ] = {KEY_LSHIFT, KEY_JOY1+2 }, // North
[gc_horncode ] = {'r', KEY_JOY1+8 }, // R-Stick Click
[gc_pause ] = {KEY_PAUSE, KEY_JOY1+4 }, // Back
[gc_systemmenu ] = { KEY_JOY1+6 }, // Start
[gc_console ] = {KEY_CONSOLE },
[gc_screenshot ] = {KEY_F8 },
[gc_recordgif ] = {KEY_F9 },
[gc_viewpoint ] = {KEY_F12, KEY_JOY1+3 }, // Y
[gc_viewpoint ] = {KEY_F12, KEY_JOY1+3 }, // West
[gc_talkkey ] = {'t', KEY_HAT1+1 }, // D-Pad Down
//[gc_teamkey ] = {'y' },
[gc_scores ] = {KEY_TAB, KEY_HAT1+0 }, // D-Pad Up
@ -200,7 +200,7 @@ INT32 G_GetDevicePlayer(INT32 deviceID)
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
if (deviceID == I_GetJoystickDeviceIndexForPlayer(i) + 1)
if (deviceID == I_GetControllerIDForPlayer(i) + 1)
{
return i;
}
@ -213,8 +213,8 @@ INT32 G_GetDevicePlayer(INT32 deviceID)
INT32 G_AxisToKey(event_t *ev)
{
return KEY_AXIS1 + (ev->data1 >= JOYANALOGS
? ev->data1 + JOYANALOGS // triggers
: ev->data1*2 + (ev->data2 >= 0)); // analog sticks
? ev->data1 + JOYANALOGS // triggers
: ev->data1*2 + (ev->data2 >= 0)); // analog sticks
}
//
@ -228,32 +228,23 @@ void G_MapEventsToControls(event_t *ev)
{
INT32 i;
if (ev->device >= 0 && ev->device < MAXDEVICES)
{
switch (ev->type)
{
case ev_keydown:
//case ev_keyup:
//case ev_mouse:
//case ev_joystick:
deviceResponding[ev->device] = true;
break;
INT32 device = ev->device;
default:
break;
}
}
else
{
// not a keyboard?
// try to see if its a controller in use
if (device > KEYBOARD_MOUSE_DEVICE)
device = I_GetControllerSlotfromID(device-1);
// invalid device
if (device < KEYBOARD_MOUSE_DEVICE || device >= MAXDEVICES)
return;
}
switch (ev->type)
{
case ev_keydown:
if (ev->data1 < NUMINPUTS)
{
gamekeydown[ev->device][ev->data1] = JOYAXISRANGE;
gamekeydown[device][ev->data1] = JOYAXISRANGE;
}
#ifdef PARANOIA
else
@ -266,7 +257,7 @@ void G_MapEventsToControls(event_t *ev)
case ev_keyup:
if (ev->data1 < NUMINPUTS)
{
gamekeydown[ev->device][ev->data1] = 0;
gamekeydown[device][ev->data1] = 0;
}
#ifdef PARANOIA
else
@ -286,28 +277,28 @@ void G_MapEventsToControls(event_t *ev)
if (ev->data2 < 0)
{
// Left
gamekeydown[ev->device][KEY_MOUSEMOVE + 2] = abs(ev->data2);
gamekeydown[ev->device][KEY_MOUSEMOVE + 3] = 0;
gamekeydown[device][KEY_MOUSEMOVE + 2] = abs(ev->data2);
gamekeydown[device][KEY_MOUSEMOVE + 3] = 0;
}
else
{
// Right
gamekeydown[ev->device][KEY_MOUSEMOVE + 2] = 0;
gamekeydown[ev->device][KEY_MOUSEMOVE + 3] = abs(ev->data2);
gamekeydown[device][KEY_MOUSEMOVE + 2] = 0;
gamekeydown[device][KEY_MOUSEMOVE + 3] = abs(ev->data2);
}
// Y axis
if (ev->data3 < 0)
{
// Up
gamekeydown[ev->device][KEY_MOUSEMOVE] = abs(ev->data3);
gamekeydown[ev->device][KEY_MOUSEMOVE + 1] = 0;
gamekeydown[device][KEY_MOUSEMOVE] = abs(ev->data3);
gamekeydown[device][KEY_MOUSEMOVE + 1] = 0;
}
else
{
// Down
gamekeydown[ev->device][KEY_MOUSEMOVE] = 0;
gamekeydown[ev->device][KEY_MOUSEMOVE + 1] = abs(ev->data3);
gamekeydown[device][KEY_MOUSEMOVE] = 0;
gamekeydown[device][KEY_MOUSEMOVE + 1] = abs(ev->data3);
}
break;
@ -325,6 +316,7 @@ void G_MapEventsToControls(event_t *ev)
break;
}
// tf is this for?
if (G_GetDevicePlayer(ev->device) == 0)
{
if (CON_Ready() || chat_on)
@ -336,9 +328,9 @@ void G_MapEventsToControls(event_t *ev)
{
// analog stick axes have a negative and positive keydown
i -= ev->data2 >= 0;
gamekeydown[ev->device][i++] = max(0, -ev->data2);
gamekeydown[device][i++] = max(0, -ev->data2);
}
gamekeydown[ev->device][i] = max(0, ev->data2);
gamekeydown[device][i] = max(0, ev->data2);
break;
@ -457,12 +449,17 @@ static keyname_t keynames[] =
{KEY_JOY1+12, "D-PAD DOWN"},
{KEY_JOY1+13, "D-PAD LEFT"},
{KEY_JOY1+14, "D-PAD RIGHT"},
{KEY_JOY1+15, "MISC. BUTTON"},
{KEY_JOY1+16, "PADDLE1 BUTTON"},
{KEY_JOY1+17, "PADDLE2 BUTTON"},
{KEY_JOY1+18, "PADDLE3 BUTTON"},
{KEY_JOY1+19, "PADDLE4 BUTTON"},
{KEY_JOY1+15, "MISC. BUTTON 1"},
{KEY_JOY1+16, "PADDLE BUTTON 1"},
{KEY_JOY1+17, "PADDLE BUTTON 2"},
{KEY_JOY1+18, "PADDLE BUTTON 3"},
{KEY_JOY1+19, "PADDLE BUTTON 4"},
{KEY_JOY1+20, "TOUCHPAD"},
{KEY_JOY1+21, "MISC. BUTTON 2"},
{KEY_JOY1+22, "MISC. BUTTON 3"},
{KEY_JOY1+23, "MISC. BUTTON 4"},
{KEY_JOY1+24, "MISC. BUTTON 5"},
{KEY_JOY1+25, "MISC. BUTTON 6"},
{KEY_AXIS1+0, "L-STICK LEFT"},
{KEY_AXIS1+1, "L-STICK RIGHT"},
@ -474,6 +471,20 @@ static keyname_t keynames[] =
{KEY_AXIS1+7, "R-STICK DOWN"},
{KEY_AXIS1+8, "L TRIGGER"},
{KEY_AXIS1+9, "R TRIGGER"},
{KEY_ACCELEROMETER1+0, "TILT -X"},
{KEY_ACCELEROMETER1+1, "TILT +X"},
{KEY_ACCELEROMETER1+2, "TILT -Y"},
{KEY_ACCELEROMETER1+3, "TILT +Y"},
{KEY_ACCELEROMETER1+4, "TILT -Z"},
{KEY_ACCELEROMETER1+5, "TILT +Z"},
{KEY_GYROSCOPE1+0, "ROTATE -X"},
{KEY_GYROSCOPE1+1, "ROTATE +X"},
{KEY_GYROSCOPE1+2, "ROTATE -Y"},
{KEY_GYROSCOPE1+3, "ROTATE +Y"},
{KEY_GYROSCOPE1+4, "ROTATE -Z"},
{KEY_GYROSCOPE1+5, "ROTATE +Z"},
};
static const char *gamecontrolname[num_gamecontrols] =
@ -508,11 +519,12 @@ static const char *gamecontrolname[num_gamecontrols] =
"custom3",
"respawn",
"director",
"horncode",
};
#define NUMKEYNAMES (sizeof (keynames)/sizeof (keyname_t))
skincolornum_t G_GetSkinColorForGamepad(INT32 playernum)
skincolornum_t G_GetSkinColorForController(INT32 playernum)
{
I_Assert(playernum >= 0 && playernum < MAXSPLITSCREENPLAYERS);
@ -523,7 +535,7 @@ skincolornum_t G_GetSkinColorForGamepad(INT32 playernum)
if (player)
{
// make rgb rainbow vomit when invul or flash blue when grow
if ((cv_gamepadled[playernum].value == 2) && player->mo && player->mo->color)
if ((cv_controllerled[playernum].value == 2) && player->mo && player->mo->color)
return (skincolornum_t)player->mo->color;
// take actual player skincolour when ingame
@ -538,45 +550,46 @@ skincolornum_t G_GetSkinColorForGamepad(INT32 playernum)
// Sets the Indicator LED on supported gamepads to a desired skincolor
// pass SKINCOLOR_NONE/0 to set the players skin color
void G_SetPlayerGamepadIndicatorColor(INT32 playernum, UINT16 color)
void G_SetPlayerControllerIndicatorColor(INT32 playernum, UINT16 color)
{
skincolornum_t skincolor;
byteColor_t byte_color;
I_Assert(playernum >= 0 && playernum < MAXSPLITSCREENPLAYERS);
if (cv_gamepadled[playernum].value == 0)
if (cv_controllerled[playernum].value == 0)
{
return;
}
// so we can override this
skincolor = color ? color : G_GetSkinColorForGamepad(playernum);
skincolor = color ? color : G_GetSkinColorForController(playernum);
byte_color = V_GetColor(skincolors[skincolor].ramp[8]).s;
I_SetGamepadIndicatorColor(playernum, byte_color.red, byte_color.green, byte_color.blue);
I_SetControllerIndicatorColor(playernum, byte_color.red, byte_color.green, byte_color.blue);
}
static void G_ResetPlayerGamepadIndicatorColor(INT32 playernum)
static void G_ResetPlayerControllerIndicatorColor(INT32 playernum)
{
I_Assert(playernum >= 0 && playernum < MAXSPLITSCREENPLAYERS);
if (cv_gamepadled[playernum].value == 0)
if (cv_controllerled[playernum].value == 0)
{
I_SetGamepadIndicatorColor(playernum, 0, 0, 255);
I_SetControllerIndicatorColor(playernum, 0, 0, 255);
}
else
{
G_SetPlayerGamepadIndicatorColor(playernum, 0);
G_SetPlayerControllerIndicatorColor(playernum, 0);
}
}
static skincolornum_t curcolor[MAXSPLITSCREENPLAYERS] = {};
void G_DeviceLEDTick(void)
void G_ControllerLEDTick(void)
{
UINT8 i;
static skincolornum_t newcolor = SKINCOLOR_NONE;
const INT32 numcontrollers = I_NumControllers();
if (numcontrollers == 0)
{
@ -585,44 +598,48 @@ void G_DeviceLEDTick(void)
for (i = 0; i <= splitscreen; i++)
{
if (!cv_usejoystick[i].value || !cv_gamepadled[i].value)
if (!cv_usecontroller[i].value || !cv_controllerled[i].value)
continue;
newcolor = G_GetSkinColorForGamepad(i);
// Players controller does not have an addressable rbg light, bummer!
if (!I_ControllerSupportsIndicatorColor(i))
continue;
newcolor = G_GetSkinColorForController(i);
if (curcolor[i] == newcolor) // dont update if same colour
continue;
G_SetPlayerGamepadIndicatorColor(i, newcolor);
G_SetPlayerControllerIndicatorColor(i, newcolor);
curcolor[i] = newcolor;
}
}
void G_ResetDeviceLED(void)
void G_ResetControllerLED(void)
{
memset(curcolor, 0, sizeof(curcolor));
}
static void G_ResetPlayerDeviceRumble(INT32 playernum)
static void G_ResetPlayerControllerRumble(INT32 playernum)
{
I_Assert(playernum >= 0 && playernum < MAXSPLITSCREENPLAYERS);
I_GamepadRumble(playernum, 0, 0, 0);
I_ControllerRumble(playernum, 0, 0, 0);
}
void G_ResetAllDeviceRumbles(void)
void G_ResetAllControllerRumbles(void)
{
for (int i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
I_GamepadRumble(i, 0, 0, 0);
I_ControllerRumble(i, 0, 0, 0);
}
}
void G_PlayerDeviceRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, UINT32 duration)
void G_PlayerControllerRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, UINT32 duration)
{
I_Assert(playernum >= 0 && playernum < MAXSPLITSCREENPLAYERS);
if (cv_rumble[playernum].value == 0)
if (cv_controllerrumble[playernum].value == 0)
{
return;
}
@ -633,7 +650,7 @@ void G_PlayerDeviceRumble(INT32 playernum, UINT16 low_strength, UINT16 high_stre
low_strength = (UINT16)min(FixedMul(low_strength, cv_rumblestrength[playernum].value), UINT16_MAX);
high_strength = (UINT16)min(FixedMul(high_strength, cv_rumblestrength[playernum].value), UINT16_MAX);
I_GamepadRumble(playernum, low_strength, high_strength, duration);
I_ControllerRumble(playernum, low_strength, high_strength, duration);
}
// rumble strengths
@ -649,9 +666,10 @@ enum
// Controller rumble!
// this keeps track of a bunch of things
// and makes your controller rumble accordingly
void G_DeviceRumbleTick(void)
void G_ControllerRumbleTick(void)
{
UINT8 i;
const INT32 numcontrollers = I_NumControllers();
if (dedicated || numcontrollers == 0 || gamestate != GS_LEVEL)
{
@ -660,11 +678,15 @@ void G_DeviceRumbleTick(void)
for (i = 0; i <= splitscreen; i++)
{
if (!cv_usejoystick[i].value || !cv_rumble[i].value)
if (!cv_usecontroller[i].value || !cv_controllerrumble[i].value)
{
continue;
}
// Players controller does not support rumble, bummer!
if (!I_ControllerSupportsRumble(i))
continue;
if (camera[i].freecam)
{
continue;
@ -686,11 +708,16 @@ void G_DeviceRumbleTick(void)
player->playerstate == PST_DEAD ||
player->respawn > 1)
{
G_PlayerDeviceRumble(i, low, high, 0);
G_PlayerControllerRumble(i, low, high, 0);
continue;
}
if (player->spinouttimer)
if (player->mo->eflags & MFE_JUSTBOUNCEDWALL)
{
high = RUMBLE_STRONG;
low = RUMBLE_MODERATE;
}
else if (player->spinouttimer)
{
//low = high = FRACUNIT / 6;
low = high = FixedMul((RUMBLE_VERYSTRONG), (FixedDiv(player->spinouttimer, (3*TICRATE / 2)))); // try do some some kinda fadeout, 3*TICRATE / 2 is the "default" spinout time
@ -721,6 +748,10 @@ void G_DeviceRumbleTick(void)
{
high = RUMBLE_MODERATE;
}
else if (player->smonitortimer)
{
high = RUMBLE_MODERATE;
}
else
{
low = high = RUMBLE_MODERATE;
@ -791,7 +822,7 @@ void G_DeviceRumbleTick(void)
continue;
}
G_PlayerDeviceRumble(i, low, high, lenght);
G_PlayerControllerRumble(i, low, high, lenght);
}
}

View file

@ -29,11 +29,14 @@ extern "C" {
#define MOUSEBUTTONS 8
#define JOYBUTTONS 21 // 21 buttons, to match SDL_GameControllerButton
#define JOYANALOGS 4 // 4 analog stick axes (2 sticks * 2 axes)
#define JOYTRIGGERS 2 // 2 trigger axes, positive only
#define JOYAXISES (JOYANALOGS + JOYTRIGGERS)
#define JOYAXISKEYS ((2 * JOYANALOGS) + JOYTRIGGERS)
#define JOYBUTTONS 26 // 26 buttons, to match SDL_GameControllerButton
#define JOY_DPAD_UP 11
#define JOYANALOGS 4 // 4 analog stick axes (2 sticks * 2 axes)
#define JOYTRIGGERS 2 // 2 trigger axes, positive only
#define JOYIMUAXISES 6 // 3 accelerometer, 3 gyroscope axes (x, y, z)
#define JOYAXISES (JOYANALOGS + JOYTRIGGERS + JOYIMUAXISES)
#define JOYAXISKEYS ((2 * JOYANALOGS) + JOYTRIGGERS + (2 * JOYIMUAXISES))
#define MAXINPUTMAPPING 4
@ -43,8 +46,10 @@ extern "C" {
typedef enum
{
KEY_JOY1 = NUMKEYS,
KEY_HAT1 = KEY_JOY1 + 11, // macro for SDL_CONTROLLER_BUTTON_DPAD_UP
KEY_HAT1 = KEY_JOY1 + JOY_DPAD_UP,
KEY_AXIS1 = KEY_JOY1 + JOYBUTTONS,
KEY_ACCELEROMETER1 = KEY_AXIS1 + JOYANALOGS + JOYTRIGGERS,
KEY_GYROSCOPE1 = KEY_ACCELEROMETER1 + 6,
JOYINPUTEND = KEY_AXIS1 + JOYAXISKEYS,
KEY_MOUSE1 = JOYINPUTEND,
@ -88,6 +93,7 @@ typedef enum
gc_custom3, // Lua scriptable
gc_respawn,
gc_director,
gc_horncode,
num_gamecontrols
} gamecontrols_e;
@ -97,15 +103,18 @@ extern consvar_t cv_mousesens2, cv_mouseysens2;
extern consvar_t cv_controlperkey;
extern consvar_t cv_litesteer[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_turnsmooth[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_rumble[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_controllerrumble[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_rumblestrength[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_gamepadled[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_controllerled[MAXSPLITSCREENPLAYERS];
// current state of the keys: JOYAXISRANGE or 0 when boolean.
// Or anything inbetween for analog values
#define MAXDEVICES (MAXGAMEPADS + 1) // Gamepads + keyboard & mouse
extern INT32 gamekeydown[MAXDEVICES][NUMINPUTS];
extern boolean deviceResponding[MAXDEVICES];
// the above is horrid since device tracks the gamepad id for whatever godawful reason
// the gamepad instance id may be alot larger than (MAXGAMEPADS + 1)/"9"
typedef INT32 inputpoll_t[MAXDEVICES][NUMINPUTS];
extern inputpoll_t gamekeydown, gamekeydown_msec;
// several key codes (or virtual key) per game control
extern INT32 gamecontrol[MAXSPLITSCREENPLAYERS][num_gamecontrols][MAXINPUTMAPPING];
@ -130,13 +139,16 @@ extern const INT32 gcl_full[num_gcl_full];
// peace to my little coder fingers!
// check a gamecontrol being active or not
skincolornum_t G_GetSkinColorForGamepad(INT32 playernum);
void G_SetPlayerGamepadIndicatorColor(INT32 playernum, UINT16 color);
void G_DeviceLEDTick(void);
void G_ResetDeviceLED(void);
void G_ResetAllDeviceRumbles(void);
void G_PlayerDeviceRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, UINT32 duration);
void G_DeviceRumbleTick(void);
#define INVALID_DEVICE -1
#define KEYBOARD_MOUSE_DEVICE 0
skincolornum_t G_GetSkinColorForController(INT32 playernum);
void G_SetPlayerControllerIndicatorColor(INT32 playernum, UINT16 color);
void G_ControllerLEDTick(void);
void G_ResetControllerLED(void);
void G_ResetAllControllerRumbles(void);
void G_PlayerControllerRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, UINT32 duration);
void G_ControllerRumbleTick(void);
INT32 G_GetDevicePlayer(INT32 deviceID);

View file

@ -38,22 +38,20 @@
consvar_t cv_itemtimers = CVAR_INIT ("itemtimers", "On", CV_SAVE, CV_OnOff, NULL);
typedef struct itimer_s
typedef struct itimer_s
{
const char* name; // name of timer
INT32 timer; // current time
//std::vector<patch_t*> patches; // timer graphics (big/freeplay)
std::vector<patch_t*> patches_small; // timer graphics (small)
INT32 anim_frames; // tic duration for each graphic
//INT32 xoffs = 0, yoffs = 0; // offsets for freeplay mode
INT32 xoffs_small = 0, yoffs_small = 0; // offsets for normal mode
boolean counter; // not a timer, show a counter instead
boolean badtimer; // timer is colored red
INT32 *timer_p; // if defined, uses a pointer for the timer instead
std::vector<patch_t*> patches; // timer graphics (small)
INT32 anim_frames = 1; // tic duration for each graphic
UINT32 flags = 0; // settings for timer
lua_Integer timer_func_ref = LUA_NOREF; // if set, calls a function from registry to get timer value
boolean timer_func_error = false; // don't print error every frame
} itimer_t;
static bool sorttimers(itimer_t a, itimer_t b)
{
// Just sort by time please.
return a.timer < b.timer;
}
@ -141,30 +139,24 @@ static std::vector<itimer_t> addTimers;
static std::vector<itimer_t> addTimers_unsorted;
void K_AddItemTimerEx(
const char *name,
INT32 *timer,
/*char **patches,*/ char **patches_small,
/*INT32 patches_size,*/ INT32 patches_small_size,
const char *name,
lua_Integer timer_func_ref,
const char **patches,
INT32 patches_size,
INT32 anim_duration,
INT32 xoffs, INT32 yoffs,
INT32 xoffs_small, INT32 yoffs_small,
boolean counter, boolean unsorted)
UINT32 flags, boolean unsorted)
{
itimer_t t; // woo yeah baby
t.name = name;
t.timer_p = timer;
t.timer_func_ref = timer_func_ref;
INT32 i;
//for (i = 0; i < patches_size; i++)
//t.patches.push_back(qche(patches[i]));
for (i = 0; i < patches_small_size; i++)
t.patches_small.push_back(qche(patches_small[i]));
for (i = 0; i < patches_size; i++)
t.patches.push_back(qche(patches[i]));
t.anim_frames = anim_duration;
//t.xoffs = xoffs; t.yoffs = yoffs;
t.xoffs_small = xoffs_small; t.yoffs_small = yoffs_small;
t.counter = counter;
t.flags = flags;
// yeah
if (unsorted)
@ -196,7 +188,7 @@ void K_getTimersDrawinfo(drawinfo_t *out)
if (r_splitscreen > 0)
{
flags &= ~V_HUDTRANS;
flags |= V_30TRANS;
flags |= V_HUDTRANSHALF;
}
out->x = fx;
@ -204,6 +196,40 @@ void K_getTimersDrawinfo(drawinfo_t *out)
out->flags = flags;
}
static INT32 getLuaTimer(itimer_t *itimer)
{
lua_pushcfunction(gL, LUA_GetErrorMessage);
lua_Integer errorh = lua_gettop(gL);
lua_getfield(gL, LUA_REGISTRYINDEX, LREG_TIMERS);
lua_rawgeti(gL, -1, itimer->timer_func_ref);
I_Assert(lua_isfunction(gL, -1));
LUA_PushUserdata(gL, stplyr, META_PLAYER);
if (lua_pcall(gL, 1, 1, errorh) != 0)
{
if (!itimer->timer_func_error)
{
itimer->timer_func_error = true;
CONS_Alert(CONS_WARNING, "%s\n", lua_tostring(gL, -1));
}
lua_pop(gL, 3); // Pop error message, timers table and error handler
return 0;
}
// TODO - print error if returned value isn't integer?
if (lua_isnumber(gL, -1))
itimer->timer = lua_tointeger(gL, -1);
lua_pop(gL, 3); // Pop function result, timers table and error handler
return itimer->timer;
}
void K_DisplayItemTimers(void)
{
if (!cv_itemtimers.value) return;
@ -211,72 +237,71 @@ void K_DisplayItemTimers(void)
if (!LUA_HudEnabled(hud_itemtimers)) return;
if (stplyr->mo == NULL || P_MobjWasRemoved(stplyr->mo)) return;
// I love and hate you C++
std::vector<itimer_t> timers =
std::vector<itimer_t> timers =
{
{ // sneaker
"shoe",
stplyr->sneakertimer,
//{qche("K_ISSHOE")},
{qche("K_TISHOE")},
1, /*-15, -15,*/ -4, -2,
1,
},
{ // invinc
"invincible",
stplyr->invincibilitytimer,
//{qche("K_ISINV1"), qche("K_ISINV2"), qche("K_ISINV3"), qche("K_ISINV4"), qche("K_ISINV5"), qche("K_ISINV6")},
{qche("K_TIINV1"), qche("K_TIINV2"), qche("K_TIINV3"), qche("K_TIINV4"), qche("K_TIINV5"), qche("K_TIINV6")},
3, /*-15, -15,*/ -4, -2,
3,
},
{ // s-monitor
"s-monitor",
stplyr->smonitortimer,
{qche("K_TISMR1")/*, qche("K_TIINV2"), qche("K_TIINV3"), qche("K_TIINV4"), qche("K_TIINV5"), qche("K_TIINV6")*/},
3,
// Hide the timer until it's necessary
static_cast<uint32_t>(((stplyr->smonitortimer >= SMONITORTIME)) ? TIMER_NONUMBER : 0),
},
{ // grow
"grow",
std::max<INT16>(0, stplyr->growshrinktimer),
//{qche("K_ISGROW")},
{qche("K_TIGROW")},
1, /*-15, -15,*/ -4, -2,
1,
},
{ // rocket sneakers
"rocketsneakers",
stplyr->rocketsneakertimer,
//{qche("K_ISRSHE")},
{qche("K_TIRSHE")},
1, /*-15, -15,*/ -4, -2,
1,
},
{ // hyudoro
"hyudoro",
stplyr->hyudorotimer,
//{qche("K_ISHYUD")},
{qche("K_TIHYUD")},
1, /*-15, -15,*/ -4, -2,
1,
},
{ // drift boost
"driftsparkboost",
stplyr->driftboost,
//{qche("K_DRSP1"), qche("K_DRSP2")},
{qche("K_TISRK1"), qche("K_TISRK2")},
2, /*-15, -15,*/ -4, -2,
2,
},
{ // start boost
"startboost",
stplyr->startboost,
//{qche("K_ISSTB")},
{qche("K_TISTB")},
1, /*-15, -15,*/ -4, -2,
1,
},
{ // ring boost
"ringboost",
stplyr->ringboost,
//{qche("K_ISRING")},
{qche("K_TIRING")},
1, /*-15, -15,*/ -4, -2,
1,
},
{ // flameshield
"flameshield",
stplyr->flametimer,
//{qche("K_ISFLMS")},
{qche("K_TIFLMS")},
1, /*-15, -15,*/ -4, -2,
1,
},
};
};
// insert sortable timers
timers.insert(timers.end(), addTimers.begin(), addTimers.end());
@ -289,41 +314,27 @@ void K_DisplayItemTimers(void)
{ // spinout
"spinout",
std::max<UINT16>(stplyr->spinouttimer, stplyr->wipeoutslow),
//{qche("K_DIZZ1"), qche("K_DIZZ2"), qche("K_DIZZ3"), qche("K_DIZZ4")},
{qche("K_TISPN1"), qche("K_TISPN2"), qche("K_TISPN3"), qche("K_TISPN4")},
3, /*-15, -15,*/ -4, -2,
false,
true,
3,
TIMER_RED,
}
);
timers.push_back(
{ // shrink
"shrink",
std::max<INT16>(0, -stplyr->growshrinktimer),
//{qche("K_ISSHRK")},
{qche("K_TISHRK")},
1,
//-15,
//-15,
-4,
-2,
false,
true,
static_cast<uint32_t>((K_IsAltShrunk(stplyr) ? 0 : TIMER_RED)),
}
);
timers.push_back(
{ // spb
"spb",
(INT32)spbTimers[stplyr-players],
//{qche("K_ISSPB")},
{qche("K_TISPB")},
1,
//-15,
//-15,
-4,
-2,
false,
(stplyr->position == K_GetBestRank())
static_cast<uint32_t>((stplyr->position == K_GetBestRank()) ? TIMER_RED : 0),
}
);
// Same with boost stacks
@ -331,39 +342,20 @@ void K_DisplayItemTimers(void)
{ // boosts
"boosts",
K_StackingActive() ? stplyr->numboosts : 0,
//{qche("K_DRSP1"), qche("K_DRSP2")},
{qche("K_TISRK1"), qche("K_TISRK2")},
2, /*-15, -15,*/ -3, -2,
true,
2,
TIMER_GREEN|TIMER_COUNTER,
}
);
timers.push_back(
{ // item cooldown
"itemusecooldown",
(INT32)stplyr->itemusecooldown,
//{qche("K_ISFLMS")},
{qche("SERVLOCK")},
1, /*-15, -15,*/ -4, -2,
false, false
1,
}
);
/*timers.push_back(
{ // dead
"spr_realisticexplosion",
stplyr->deadtimer ? std::max<INT32>(0, TICRATE - stplyr->deadtimer) : 0,
//{qche("IT_DED1"), qche("IT_DED2"), qche("IT_DED3"), qche("IT_DED4"), qche("IT_DED5"), qche("IT_DED6"), qche("IT_DED7"), qche("IT_DED8")},
{qche("IT_DEAD1"), qche("IT_DEAD2"), qche("IT_DEAD3"), qche("IT_DEAD4"), qche("IT_DEAD5"), qche("IT_DEAD6"), qche("IT_DEAD7"), qche("IT_DEAD8")},
1,
//0,
//-4,
0,
0,
false,
true,
}
);*/
// insert unsortable timers
timers.insert(timers.end(), addTimers_unsorted.begin(), addTimers_unsorted.end());
@ -390,7 +382,7 @@ void K_DisplayItemTimers(void)
for (itimer_t& t : timers)
{
INT32 timer = t.timer;
if (t.timer_p) timer = *t.timer_p;
if (t.timer_func_ref != LUA_NOREF) timer = getLuaTimer(&t);
if (stplyr->deadtimer && !fastcmp(t.name, "spr_realisticexplosion")) continue;
if (timer > 0)
offs += stepx;
@ -403,7 +395,6 @@ void K_DisplayItemTimers(void)
if (t.timer <= 0) continue;
if (stplyr->deadtimer && !fastcmp(t.name, "spr_realisticexplosion")) continue;
INT32 timer = t.timer;
if (t.timer_p) timer = *t.timer_p;
INT32 seconds = timer / TICRATE, _centiseconds = G_TicsToCentiseconds(timer);
const char* str = va("%d.%02d", seconds, _centiseconds);
@ -411,7 +402,7 @@ void K_DisplayItemTimers(void)
str = va("%d.%01d", seconds, G_TicsToDeciseconds(timer));
if (seconds > 99) // exceeds 100 seconds?
str = va("%d", seconds);
INT32 animsize = t.patches_small.size();
INT32 animsize = t.patches.size();
INT32 patchnum = (leveltime % (t.anim_frames * animsize) / t.anim_frames);
UINT8 *cmap = NULL, *textcmap = NULL;
INT32 font = TINY_FONT;
@ -429,123 +420,55 @@ void K_DisplayItemTimers(void)
textcmap = cmap;
}
if (fastcmp(t.name, "boosts"))
{
flags |= V_GREENMAP;
}
if (t.counter) // don't show up as time
if (t.flags & TIMER_COUNTER) // don't show up as time
{
str = va("%d", timer);
font = HU_FONT;
}
INT32 width = V_StringScaledWidth(FRACUNIT, FRACUNIT, FRACUNIT, flags|V_MONOSPACE, font, str) >> FRACBITS;
// very bad!
if (t.badtimer)
{
flags |= V_REDMAP;
//textcmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_CRIMSON, GTC_CACHE);
}
#define COLORTIMER(color) \
if (t.flags & TIMER_##color) \
flags |= V_##color##MAP\
patch_t *item = t.patches_small[patchnum];
V_DrawFixedPatch((itemx - (item->width/2))<<FRACBITS, (itemy + t.yoffs_small)<<FRACBITS, FRACUNIT, flags, t.patches_small[patchnum], cmap);
V_DrawStringScaledEx(
(itemx - (width/2) - item->leftoffset) << FRACBITS,
(itemy + 12) << FRACBITS,
FRACUNIT,
FRACUNIT,
FRACUNIT,
FRACUNIT,
flags|V_MONOSPACE,
textcmap,
font,
str
);
// Color timers!
COLORTIMER(RED);
COLORTIMER(PURPLE);
COLORTIMER(YELLOW);
COLORTIMER(GREEN);
COLORTIMER(BLUE);
COLORTIMER(RED);
COLORTIMER(GRAY);
COLORTIMER(ORANGE);
COLORTIMER(SKY);
COLORTIMER(LAVENDER);
COLORTIMER(GOLD);
COLORTIMER(AQUA);
COLORTIMER(MAGENTA);
COLORTIMER(PINK);
COLORTIMER(BROWN);
COLORTIMER(TAN);
patch_t *item = t.patches[patchnum];
V_DrawFixedPatch((itemx - (item->width/2))<<FRACBITS, (itemy - 2)<<FRACBITS, FRACUNIT, flags, t.patches[patchnum], cmap);
if (!(t.flags & TIMER_NONUMBER))
{
V_DrawStringScaledEx(
(itemx - (width/2) - item->leftoffset) << FRACBITS,
(itemy + 12) << FRACBITS,
FRACUNIT,
FRACUNIT,
FRACUNIT,
FRACUNIT,
flags|V_MONOSPACE,
textcmap,
font,
str
);
}
itemx += stepx;
}
}
/*else // FREEPLAY - Move these to the left side, where the rankings usually are
{
if (r_splitscreen) // How?
return;
INT32 fx = 9, fy = 92, step = 20;
INT32 flags = V_SNAPTOLEFT|V_SLIDEIN;
// center it
INT32 offs = -step;
for (itimer_t& t : timers)
{
INT32 timer = t.timer;
if (t.timer_p) timer = *t.timer_p;
if (stplyr->deadtimer && !fastcmp(t.name, "spr_realisticexplosion")) continue;
if (timer > 0)
offs += step;
}
fy -= offs/2;
// draw relevant timers
for (itimer_t& t : timers)
{
if (t.timer <= 0) continue;
if (stplyr->deadtimer && !fastcmp(t.name, "spr_realisticexplosion")) continue;
INT32 timer = t.timer;
if (t.timer_p) timer = *t.timer_p;
INT32 seconds = timer / TICRATE, _centiseconds = G_TicsToCentiseconds(timer);
INT32 patchnum = (leveltime % (t.anim_frames * t.patches.size()) / t.anim_frames);
UINT8 *cmap = NULL, *textcmap = NULL;
const char* str = va("%d.%02d", seconds, _centiseconds);
if (seconds > 9) // exceeds 9 seconds?
str = va("%d.%01d", seconds, G_TicsToDeciseconds(timer));
if (seconds > 99) // exceeds 100 seconds?
str = va("%d", seconds);
boolean bost = false;
if (fastcmp(t.name, "boosts")) // don't show up as time
{
str = va("%d", timer);
bost = true;
}
INT32 width = V_StringScaledWidth(FRACUNIT, FRACUNIT, FRACUNIT, flags|V_MONOSPACE, OPPRNK_FONT, str) >> FRACBITS;
if (fastcmp(t.name, "driftsparkboost"))
{
if (timer > 85) // rainbow
cmap = R_GetTranslationColormap(TC_DEFAULT, (skincolornum_t)K_RainbowColor(leveltime), GTC_CACHE);
else if (timer > 50 && K_PurpleDriftActive()) // purple
cmap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_PURPLE, GTC_CACHE);
else if (timer > 25) // ketchup
cmap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_KETCHUP, GTC_CACHE);
else // blu
cmap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_SAPPHIRE, GTC_CACHE);
textcmap = cmap;
}
// very bad!
if (t.badtimer)
textcmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_CRIMSON, GTC_CACHE);
patch_t *item = t.patches[patchnum];
V_DrawFixedPatch((fx+t.xoffs)<<FRACBITS, (fy+t.yoffs)<<FRACBITS, FRACUNIT, flags, item, cmap);
V_DrawStringScaledEx(
(fx + (item->width/2) - (width/2) - item->leftoffset + t.xoffs) << FRACBITS,
(fy+5) << FRACBITS,
FRACUNIT,
FRACUNIT,
FRACUNIT,
FRACUNIT,
flags|V_MONOSPACE,
textcmap,
TINY_FONT,
str
);
fy += step;
}
}
*/
}

View file

@ -19,6 +19,29 @@ extern "C" {
#include "command.h"
#include "d_player.h"
#include "k_hud.h"
#include "lua_script.h"
#include "lua_libs.h"
typedef enum timerflags_e
{
TIMER_COUNTER = 1,
TIMER_NONUMBER = 1<<1,
TIMER_PURPLE = 1<<2,
TIMER_YELLOW = 1<<3,
TIMER_GREEN = 1<<4,
TIMER_BLUE = 1<<5,
TIMER_RED = 1<<6,
TIMER_GRAY = 1<<7,
TIMER_ORANGE = 1<<8,
TIMER_SKY = 1<<9,
TIMER_LAVENDER = 1<<10,
TIMER_GOLD = 1<<11,
TIMER_AQUA = 1<<12,
TIMER_MAGENTA = 1<<13,
TIMER_PINK = 1<<14,
TIMER_BROWN = 1<<15,
TIMER_TAN = 1<<16,
} timerflags_t;
extern consvar_t cv_itemtimers;
extern tic_t spbTimers[MAXPLAYERS];
@ -27,13 +50,11 @@ void K_UpdateSPBTimer(void);
// Adds an item timer.
void K_AddItemTimerEx(
const char *name,
INT32 *timer,
char **patches, char **patches_small,
INT32 patches_size, INT32 patches_small_size,
lua_Integer timer_func_ref,
const char **patches,
INT32 patches_size,
INT32 anim_duration,
INT32 xoffs, INT32 yoffs,
INT32 xoffs_small, INT32 yoffs_small,
boolean counter, boolean unsorted);
UINT32 flags, boolean unsorted);
void K_DisplayItemTimers(void);
void K_getTimersDrawinfo(drawinfo_t *out);

View file

@ -1,4 +1,4 @@
target_sources(SRB2SDL2 PRIVATE
target_sources(BLANKART PRIVATE
hw_bsp.c
hw_draw.c
hw_light.c

View file

@ -86,7 +86,7 @@ void HWR_SetCurrentTexture(GLMipmap_t *texture)
}
else
{
HWD.pfnSetTexture(texture);
GL_SetTexture(texture);
}
}
@ -141,8 +141,8 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
}
else
{
HWD.pfnSetShader((shader_target != SHADER_NONE) ? HWR_GetShaderFromTarget(shader_target) : shader_target);
HWD.pfnDrawPolygon(pSurf, pOutVerts, iNumPts, PolyFlags);
GL_SetShader((shader_target != SHADER_NONE) ? HWR_GetShaderFromTarget(shader_target) : shader_target);
GL_DrawPolygon(pSurf, pOutVerts, iNumPts, PolyFlags);
}
}
@ -320,7 +320,7 @@ void HWR_RenderBatches(void)
if (cv_glshaders.value && gl_shadersavailable)
{
HWD.pfnSetShader(currentShader);
GL_SetShader(currentShader);
}
if (currentPolyFlags & PF_NoTexture)
@ -329,9 +329,9 @@ void HWR_RenderBatches(void)
}
else
{
HWD.pfnSetTexture(currentTexture);
GL_SetTexture(currentTexture);
if (currentBrightmap)
HWD.pfnSetTexture(currentBrightmap);
GL_SetTexture(currentBrightmap);
}
while (1)// note: remember handling notexture polyflag as having texture number 0 (also in comparePolygons)
@ -449,7 +449,7 @@ void HWR_RenderBatches(void)
if (changeState || stopFlag)
{
// execute draw call
HWD.pfnDrawIndexedTriangles(&currentSurfaceInfo, finalVertexArray, finalIndexWritePos, currentPolyFlags, finalVertexIndexArray);
GL_DrawIndexedTriangles(&currentSurfaceInfo, finalVertexArray, finalIndexWritePos, currentPolyFlags, finalVertexIndexArray);
// update stats
ps_hw_numcalls++;
ps_hw_numverts += finalIndexWritePos;
@ -465,7 +465,7 @@ void HWR_RenderBatches(void)
// change state according to change bools and next vars, update current vars and reset bools
if (changeShader)
{
HWD.pfnSetShader(nextShader);
GL_SetShader(nextShader);
currentShader = nextShader;
changeShader = false;
@ -474,11 +474,11 @@ void HWR_RenderBatches(void)
if (changeTexture)
{
// texture should be already ready for use from calls to SetTexture during batch collection
HWD.pfnSetTexture(nextTexture);
GL_SetTexture(nextTexture);
currentTexture = nextTexture;
if (nextBrightmap)
HWD.pfnSetTexture(nextBrightmap);
GL_SetTexture(nextBrightmap);
currentBrightmap = nextBrightmap;
changeTexture = false;

View file

@ -14,7 +14,7 @@
#include "hw_defs.h"
#include "hw_data.h"
#include "hw_drv.h"
#include "hw_gpu.h"
#ifdef __cplusplus
extern "C" {

View file

@ -15,7 +15,7 @@
#ifdef HWRENDER
#include "hw_main.h"
#include "hw_glob.h"
#include "hw_drv.h"
#include "hw_gpu.h"
#include "hw_batching.h"
#include "../doomstat.h" //gamemode
@ -620,7 +620,6 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm
static size_t gl_numtextures = 0; // Texture count
static GLMapTexture_t *gl_textures; // For all textures
static GLMapTexture_t *gl_flats; // For all (texture) flats, as normal flats don't need to be cached
boolean gl_maptexturesloaded = false;
void HWR_FreeTextureData(patch_t *patch)
{
@ -632,7 +631,7 @@ void HWR_FreeTextureData(patch_t *patch)
grPatch = patch->hardware;
if (vid.glstate == VID_GL_LIBRARY_LOADED)
HWD.pfnDeleteTexture(grPatch->mipmap);
GL_DeleteTexture(grPatch->mipmap);
if (grPatch->mipmap->data)
Z_Free(grPatch->mipmap->data);
}
@ -700,7 +699,7 @@ void HWR_FreeTextureColormaps(patch_t *patch)
Z_Free(next->colormap);
next->data = NULL;
next->colormap = NULL;
HWD.pfnDeleteTexture(next);
GL_DeleteTexture(next);
// Free the old colormap mipmap from memory.
free(next);
@ -735,7 +734,7 @@ static void HWR_FreePatchCache(boolean freeall)
// free all textures after each level
void HWR_ClearAllTextures(void)
{
HWD.pfnClearMipMapCache(); // free references to the textures
GL_ClearMipMapCache(); // free references to the textures
HWR_FreePatchCache(true);
}
@ -748,12 +747,11 @@ void HWR_InitMapTextures(void)
{
gl_textures = NULL;
gl_flats = NULL;
gl_maptexturesloaded = false;
}
static void FreeMapTexture(GLMapTexture_t *tex)
{
HWD.pfnDeleteTexture(&tex->mipmap);
GL_DeleteTexture(&tex->mipmap);
if (tex->mipmap.data)
Z_Free(tex->mipmap.data);
tex->mipmap.data = NULL;
@ -778,7 +776,6 @@ void HWR_FreeMapTextures(void)
gl_textures = NULL;
gl_flats = NULL;
gl_numtextures = 0;
gl_maptexturesloaded = false;
}
static void HWR_PrecacheLevelFlats(void)
@ -1025,8 +1022,6 @@ void HWR_LoadMapTextures(size_t pnumtextures)
if (gl_textures == NULL || gl_flats == NULL)
I_Error("HWR_LoadMapTextures: ran out of memory for OpenGL textures");
gl_maptexturesloaded = true;
}
// --------------------------------------------------------------------------
@ -1048,7 +1043,7 @@ GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean noencoremap)
// If hardware does not have the texture, then call pfnSetTexture to upload it
if (!grtex->mipmap.downloaded)
HWD.pfnSetTexture(&grtex->mipmap);
GL_SetTexture(&grtex->mipmap);
HWR_SetCurrentTexture(&grtex->mipmap);
// The system-memory data can be purged now.
@ -1072,7 +1067,7 @@ GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean noencoremap)
// If hardware does not have the texture, then call pfnSetTexture to upload it
if (!grtexbright->mipmap.downloaded)
HWD.pfnSetTexture(&grtexbright->mipmap);
GL_SetTexture(&grtexbright->mipmap);
HWR_SetCurrentTexture(&grtexbright->mipmap);
// The system-memory data can be purged now.
@ -1170,7 +1165,7 @@ void HWR_GetRawFlat(lumpnum_t flatlumpnum, boolean noencoremap)
// If hardware does not have the texture, then call pfnSetTexture to upload it
if (!grmip->downloaded)
HWD.pfnSetTexture(grmip);
GL_SetTexture(grmip);
HWR_SetCurrentTexture(grmip);
// The system-memory data can be purged now.
@ -1226,7 +1221,7 @@ void HWR_GetLevelFlat(levelflat_t *levelflat, boolean noencoremap)
}
if (!grMipmap->downloaded)
HWD.pfnSetTexture(&grtex->mipmap);
GL_SetTexture(&grtex->mipmap);
HWR_SetCurrentTexture(&grtex->mipmap);
@ -1252,7 +1247,7 @@ void HWR_GetLevelFlat(levelflat_t *levelflat, boolean noencoremap)
grtex->mipmap.flags |= TF_BRIGHTMAP;
if (!grMipmap->downloaded)
HWD.pfnSetTexture(&grtex->mipmap);
GL_SetTexture(&grtex->mipmap);
HWR_SetCurrentTexture(&grtex->mipmap);
@ -1271,7 +1266,7 @@ static void HWR_LoadPatchMipmap(patch_t *patch, GLMipmap_t *grMipmap)
// If hardware does not have the texture, then call pfnSetTexture to upload it
if (!grMipmap->downloaded)
HWD.pfnSetTexture(grMipmap);
GL_SetTexture(grMipmap);
HWR_SetCurrentTexture(grMipmap);
// The system-memory data can be purged now.
@ -1289,9 +1284,9 @@ static void HWR_UpdatePatchMipmap(patch_t *patch, GLMipmap_t *grMipmap)
// If hardware does not have the texture, then call pfnSetTexture to upload it
// If it does have the texture, then call pfnUpdateTexture to update it
if (!grMipmap->downloaded)
HWD.pfnSetTexture(grMipmap);
GL_SetTexture(grMipmap);
else
HWD.pfnUpdateTexture(grMipmap);
GL_UpdateTexture(grMipmap);
HWR_SetCurrentTexture(grMipmap);
// The system-memory data can be purged now.
@ -1499,7 +1494,7 @@ patch_t *HWR_GetPic(lumpnum_t lumpnum)
grPatch->mipmap->flags = 0;
grPatch->max_s = grPatch->max_t = 1.0f;
}
HWD.pfnSetTexture(grPatch->mipmap);
GL_SetTexture(grPatch->mipmap);
//CONS_Debug(DBG_RENDER, "picloaded at %x as texture %d\n",grPatch->mipmap->data, grPatch->mipmap->downloaded);
return patch;
@ -1618,7 +1613,7 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum)
if (!grmip->downloaded && !grmip->data)
HWR_CacheFadeMask(grmip, fademasklumpnum);
HWD.pfnSetTexture(grmip);
GL_SetTexture(grmip);
// The system-memory data can be purged now.
Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED);
@ -1654,11 +1649,11 @@ void HWR_SetPalette(RGBA_t *palette)
crushed_palette[i].s.alpha = 255;
}
HWD.pfnSetScreenPalette(crushed_palette);
GL_SetScreenPalette(crushed_palette);
}
else
{
HWD.pfnSetScreenPalette(palette);
GL_SetScreenPalette(palette);
}
// this part is responsible for keeping track of the palette OUTSIDE of a level.
@ -1668,7 +1663,7 @@ void HWR_SetPalette(RGBA_t *palette)
else
{
// set the palette for the textures
HWD.pfnSetTexturePalette(palette);
GL_SetPalette(palette);
// reset mapPalette so next call to HWR_SetMapPalette will update everything correctly
memset(mapPalette, 0, sizeof(mapPalette));
// hardware driver will flush there own cache if cache is non paletized
@ -1700,7 +1695,7 @@ static void HWR_SetPaletteLookup(RGBA_t *palette)
}
}
#undef STEP_SIZE
HWD.pfnSetPaletteLookup(lut);
GL_SetPaletteLookup(lut);
Z_Free(lut);
}
@ -1769,7 +1764,7 @@ void HWR_SetMapPalette(void)
// in palette rendering mode, this means that all rgba textures now have wrong colors
// and the lookup table is outdated
HWR_SetPaletteLookup(mapPalette);
HWD.pfnSetTexturePalette(mapPalette);
GL_SetPalette(mapPalette);
if (patchformat == GL_TEXFMT_RGBA || textureformat == GL_TEXFMT_RGBA)
{
@ -1792,7 +1787,7 @@ UINT32 HWR_CreateLightTable(UINT8 *lighttable)
for (i = 0; i < 256 * 32; i++)
hw_lighttable[i] = palette[lighttable[i]];
id = HWD.pfnCreateLightTable(hw_lighttable);
id = GL_CreateLightTable(hw_lighttable);
Z_Free(hw_lighttable);
return id;
}
@ -1828,7 +1823,7 @@ UINT32 HWR_GetLightTableID(extracolormap_t *colormap)
void HWR_ClearLightTables(void)
{
if (vid.glstate == VID_GL_LIBRARY_LOADED)
HWD.pfnClearLightTables();
GL_ClearLightTables();
}
#endif //HWRENDER

View file

@ -322,7 +322,7 @@ angle_t gld_FrustumAngle(angle_t tiltangle)
double floatangle;
angle_t a1;
float tilt = (float)fabs(((double)(int)tiltangle) / ANG1);
float tilt = fabsf(((float)(int)tiltangle) / (float)ANG1);
if (tilt > 90.0f)
tilt = 90.0f;
@ -333,11 +333,11 @@ angle_t gld_FrustumAngle(angle_t tiltangle)
// ok, this is a gross hack that barely works...
// but at least it doesn't overestimate too much...
clipfov = atan(1 / projMatrix[0]) * 360 / M_PI; // use the actual view of the scene
floatangle = 2.0f + (45.0f + (tilt / 1.9f)) * clipfov / 90.0f;
clipfov = atan(1 / (GLdouble)projMatrix[0]) * 360.0 / M_PI;
floatangle = 2.0 + (45.0 + ((double)tilt / 1.9)) * clipfov / 90.0;
if (floatangle >= 180.0)
return 0xffffffff;
a1 = (angle_t)(ANG1 * (int)floatangle);
a1 = (angle_t)lrint(ANG1 * floatangle);
return a1;
}

View file

@ -19,7 +19,7 @@
#ifdef HWRENDER
#include "hw_main.h"
#include "hw_glob.h"
#include "hw_drv.h"
#include "hw_gpu.h"
#include "../r_draw.h" //viewborderlump
#include "../r_main.h"
@ -65,7 +65,7 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
// | /|
// |/ |
// 0--1
float dupx, dupy, fscalew, fscaleh, fwidth, fheight;
float dup, fscalew, fscaleh, fwidth, fheight;
const cliprect_t *clip = V_GetClipRect();
@ -80,25 +80,21 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
hwrPatch = ((GLPatch_t *)gpatch->hardware);
dupx = (float)vid.dupx;
dupy = (float)vid.dupy;
dup = (float)vid.dup;
switch (option & V_SCALEPATCHMASK)
{
case V_NOSCALEPATCH:
dupx = dupy = 1.0f;
break;
case V_SMALLSCALEPATCH:
dupx = (float)vid.smalldupx;
dupy = (float)vid.smalldupy;
break;
case V_MEDSCALEPATCH:
dupx = (float)vid.meddupx;
dupy = (float)vid.meddupy;
break;
case V_NOSCALEPATCH:
dup = 1.0f;
break;
case V_SMALLSCALEPATCH:
dup = (float)vid.smalldup;
break;
case V_MEDSCALEPATCH:
dup = (float)vid.meddup;
break;
}
dupx = dupy = (dupx < dupy ? dupx : dupy);
fscalew = fscaleh = FIXED_TO_FLOAT(pscale);
if (vscale != pscale)
fscaleh = FIXED_TO_FLOAT(vscale);
@ -126,15 +122,15 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
if (!(option & V_NOSCALESTART))
{
cx = cx * dupx;
cy = cy * dupy;
cx = cx * dup;
cy = cy * dup;
if (!(option & V_SCALEPATCHMASK))
{
INT32 intx, inty;
intx = (INT32)cx;
inty = (INT32)cy;
V_AdjustXYWithSnap(&intx, &inty, option, dupx, dupy);
V_AdjustXYWithSnap(&intx, &inty, option, dup);
cx = (float)intx;
cy = (float)inty;
}
@ -142,13 +138,13 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
if (pscale != FRACUNIT || (r_splitscreen && option & V_SPLITSCREEN))
{
fwidth = (float)(gpatch->width) * fscalew * dupx;
fheight = (float)(gpatch->height) * fscaleh * dupy;
fwidth = (float)(gpatch->width) * fscalew * dup;
fheight = (float)(gpatch->height) * fscaleh * dup;
}
else
{
fwidth = (float)(gpatch->width) * dupx;
fheight = (float)(gpatch->height) * dupy;
fwidth = (float)(gpatch->width) * dup;
fheight = (float)(gpatch->height) * dup;
}
s_min = t_min = 0.0f;
@ -259,10 +255,10 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
else
Surf.PolyColor.s.alpha = 0;
HWD.pfnDrawPolygon(&Surf, v, 4, flags|PF_Modulated);
GL_DrawPolygon(&Surf, v, 4, flags|PF_Modulated);
}
else
HWD.pfnDrawPolygon(NULL, v, 4, flags|PF_Translucent);
GL_DrawPolygon(NULL, v, 4, flags|PF_Translucent);
}
void HWR_DrawAffinePatch(patch_t *gpatch, fixed_t x, fixed_t y, const affine_t *transform, INT32 option, const UINT8 *colormap)
@ -276,15 +272,15 @@ void HWR_DrawAffinePatch(patch_t *gpatch, fixed_t x, fixed_t y, const affine_t *
HWR_GetMappedPatch(gpatch, colormap);
// positions of the x, y, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1
float fwidth = vid.width;// / vid.dupx;
float fheight = vid.height;// / vid.dupy;
float fwidth = vid.width;// / vid.dup;
float fheight = vid.height;// / vid.dup;
float cx = -1.0f + (x / (fwidth/2));
float cy = 1.0f - (y / (fheight/2));
float fa = FIXED_TO_FLOAT(transform->a) / vid.dupx;
float fd = FIXED_TO_FLOAT(transform->d) / vid.dupx;
float fc = FIXED_TO_FLOAT(transform->c) / vid.dupy;
float fb = FIXED_TO_FLOAT(transform->b) / vid.dupy;
float fa = FIXED_TO_FLOAT(transform->a) / vid.dup;
float fd = FIXED_TO_FLOAT(transform->d) / vid.dup;
float fc = FIXED_TO_FLOAT(transform->c) / vid.dup;
float fb = FIXED_TO_FLOAT(transform->b) / vid.dup;
float fx = FIXED_TO_FLOAT(transform->ox);
float fy = FIXED_TO_FLOAT(transform->oy);
@ -384,10 +380,10 @@ void HWR_DrawAffinePatch(patch_t *gpatch, fixed_t x, fixed_t y, const affine_t *
else
Surf.PolyColor.s.alpha = 0;
HWD.pfnDrawPolygon(&Surf, v, 4, flags|PF_Modulated);
GL_DrawPolygon(&Surf, v, 4, flags|PF_Modulated);
}
else
HWD.pfnDrawPolygon(NULL, v, 4, flags|PF_Translucent);
GL_DrawPolygon(NULL, v, 4, flags|PF_Translucent);
}
void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, INT32 option, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h)
@ -403,31 +399,27 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
// | /|
// |/ |
// 0--1
float dupx, dupy, fscale, fwidth, fheight;
float dup, fscale, fwidth, fheight;
// make patch ready in hardware cache
HWR_GetPatch(gpatch);
hwrPatch = ((GLPatch_t *)gpatch->hardware);
dupx = (float)vid.dupx;
dupy = (float)vid.dupy;
dup = (float)vid.dup;
switch (option & V_SCALEPATCHMASK)
{
case V_NOSCALEPATCH:
dupx = dupy = 1.0f;
break;
case V_SMALLSCALEPATCH:
dupx = (float)vid.smalldupx;
dupy = (float)vid.smalldupy;
break;
case V_MEDSCALEPATCH:
dupx = (float)vid.meddupx;
dupy = (float)vid.meddupy;
break;
case V_NOSCALEPATCH:
dup = 1.0f;
break;
case V_SMALLSCALEPATCH:
dup = (float)vid.smalldup;
break;
case V_MEDSCALEPATCH:
dup = (float)vid.meddup;
break;
}
dupx = dupy = (dupx < dupy ? dupx : dupy);
fscale = FIXED_TO_FLOAT(pscale);
// fuck it, no GL support for croppedpatch V_SPLITSCREEN right now. it's not like it's accessible to Lua or anything, and we only use it for menus...
@ -437,8 +429,8 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
if (!(option & V_NOSCALESTART))
{
cx = cx * dupx;
cy = cy * dupy;
cx = cx * dup;
cy = cy * dup;
if (!(option & V_SCALEPATCHMASK))
{
@ -446,19 +438,19 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
// no the patch is cropped do not do this ever
// centre screen
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dup) > 1.0E-36f)
{
if (option & V_SNAPTORIGHT)
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dup));
else if (!(option & V_SNAPTOLEFT))
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2;
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dup))/2;
}
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dup) > 1.0E-36f)
{
if (option & V_SNAPTOBOTTOM)
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dup));
else if (!(option & V_SNAPTOTOP))
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2;
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dup))/2;
}
}
}
@ -474,13 +466,13 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
if (pscale != FRACUNIT)
{
fwidth *= fscale * dupx;
fheight *= fscale * dupy;
fwidth *= fscale * dup;
fheight *= fscale * dup;
}
else
{
fwidth *= dupx;
fheight *= dupy;
fwidth *= dup;
fheight *= dup;
}
// positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1
@ -540,10 +532,10 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
else
Surf.PolyColor.s.alpha = 0;
HWD.pfnDrawPolygon(&Surf, v, 4, flags|PF_Modulated);
GL_DrawPolygon(&Surf, v, 4, flags|PF_Modulated);
}
else
HWD.pfnDrawPolygon(NULL, v, 4, flags|PF_Translucent);
GL_DrawPolygon(NULL, v, 4, flags|PF_Translucent);
}
void HWR_DrawPic(INT32 x, INT32 y, lumpnum_t lumpnum)
@ -560,9 +552,9 @@ void HWR_DrawPic(INT32 x, INT32 y, lumpnum_t lumpnum)
// 0--1
v[0].x = v[3].x = 2.0f * (float)x/vid.width - 1;
v[2].x = v[1].x = 2.0f * (float)(x + patch->width*FIXED_TO_FLOAT(vid.fdupx))/vid.width - 1;
v[2].x = v[1].x = 2.0f * (float)(x + patch->width*FIXED_TO_FLOAT(vid.fdup))/vid.width - 1;
v[0].y = v[1].y = 1.0f - 2.0f * (float)y/vid.height;
v[2].y = v[3].y = 1.0f - 2.0f * (float)(y + patch->height*FIXED_TO_FLOAT(vid.fdupy))/vid.height;
v[2].y = v[3].y = 1.0f - 2.0f * (float)(y + patch->height*FIXED_TO_FLOAT(vid.fdup))/vid.height;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
@ -578,7 +570,7 @@ void HWR_DrawPic(INT32 x, INT32 y, lumpnum_t lumpnum)
// But then, the question is: why not 0 instead of PF_Masked ?
// or maybe PF_Environment ??? (like what I said above)
// BP: PF_Environment don't change anything ! and 0 is undifined
HWD.pfnDrawPolygon(NULL, v, 4, PF_Translucent | PF_NoDepthTest);
GL_DrawPolygon(NULL, v, 4, PF_Translucent | PF_NoDepthTest);
}
// ==========================================================================
@ -630,7 +622,7 @@ void HWR_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum)
// BTW, I see we put 0 for PFs, and If I'm right, that
// means we take the previous PFs as default
// how can we be sure they are ok?
HWD.pfnDrawPolygon(NULL, v, 4, PF_NoDepthTest); //PF_Translucent);
GL_DrawPolygon(NULL, v, 4, PF_NoDepthTest); //PF_Translucent);
}
@ -665,10 +657,10 @@ void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength)
Surf.LightTableId = HWR_GetLightTableID(NULL);
Surf.LightInfo.light_level = strength;
HWD.pfnMakeScreenTexture(scr_tex);
HWD.pfnSetShader(HWR_GetShaderFromTarget(SHADER_UI_COLORMAP_FADE));
HWD.pfnDrawScreenTexture(scr_tex, &Surf, PF_ColorMapped|PF_NoDepthTest);
HWD.pfnUnSetShader();
GL_MakeScreenTexture(scr_tex);
GL_SetShader(HWR_GetShaderFromTarget(SHADER_UI_COLORMAP_FADE));
GL_DrawScreenTexture(scr_tex, &Surf, PF_ColorMapped|PF_NoDepthTest);
GL_UnSetShader();
return;
}
@ -681,7 +673,7 @@ void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength)
Surf.PolyColor.rgba = palette[color&0xFF].rgba;
Surf.PolyColor.s.alpha = softwaretranstogl[strength];
}
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
GL_DrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
}
// -----------------+
@ -705,12 +697,12 @@ void HWR_DrawFadeFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT16 ac
if (!(color & V_NOSCALESTART))
{
float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
float dup = (float)vid.dup;
fx *= dupx;
fy *= dupy;
fw *= dupx;
fh *= dupy;
fx *= dup;
fy *= dup;
fw *= dup;
fh *= dup;
// adjustxy
}
@ -763,7 +755,7 @@ void HWR_DrawFadeFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT16 ac
Surf.PolyColor.rgba = palette[actualcolor&0xFF].rgba;
Surf.PolyColor.s.alpha = softwaretranstogl[strength];
}
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
GL_DrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
}
// Draw the console background with translucency support
@ -790,7 +782,7 @@ void HWR_DrawConsoleBack(UINT32 color, INT32 height)
Surf.PolyColor.rgba = UINT2RGBA(color);
Surf.PolyColor.s.alpha = 0x80;
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
GL_DrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
}
void HWR_EncoreInvertScreen(void)
@ -811,7 +803,7 @@ void HWR_EncoreInvertScreen(void)
Surf.PolyColor.rgba = 0xFFFFFFFF;
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_NoDepthTest);
GL_DrawPolygon(&Surf, v, 4, PF_NoTexture|PF_NoDepthTest);
}
// Very similar to HWR_DrawConsoleBack, except we draw from the middle(-ish) of the screen to the bottom.
@ -841,7 +833,7 @@ void HWR_DrawTutorialBack(UINT32 color, INT32 boxheight)
Surf.PolyColor.rgba = UINT2RGBA(color);
Surf.PolyColor.s.alpha = (color == 0 ? 0xC0 : 0x80); // make black darker, like software
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
GL_DrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
}
// ==========================================================================
@ -866,7 +858,7 @@ void HWR_drawAMline(const fline_t *fl, INT32 color)
v2.x = ((float)fl->b.x-(vid.width/2.0f))*(2.0f/vid.width);
v2.y = ((float)fl->b.y-(vid.height/2.0f))*(2.0f/vid.height);
HWD.pfnDraw2DLine(&v1, &v2, color_rgba);
GL_Draw2DLine(&v1, &v2, color_rgba);
}
// -----------------+
@ -892,27 +884,27 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color)
if (!(color & V_NOSCALESTART))
{
float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
float dup = (float)vid.dup;
fx *= dupx;
fy *= dupy;
fw *= dupx;
fh *= dupy;
fx *= dup;
fy *= dup;
fw *= dup;
fh *= dup;
if (fabsf((float)vid.width - ((float)BASEVIDWIDTH * dupx)) > 1.0E-36f)
if (fabsf((float)vid.width - ((float)BASEVIDWIDTH * dup)) > 1.0E-36f)
{
if (color & V_SNAPTORIGHT)
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dup));
else if (!(color & V_SNAPTOLEFT))
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dup)) / 2;
}
if (fabsf((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) > 1.0E-36f)
if (fabsf((float)vid.height - ((float)BASEVIDHEIGHT * dup)) > 1.0E-36f)
{
// same thing here
if (color & V_SNAPTOBOTTOM)
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dup));
else if (!(color & V_SNAPTOTOP))
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2;
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dup)) / 2;
}
}
@ -959,7 +951,7 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color)
Surf.PolyColor = V_GetColor(color);
HWD.pfnDrawPolygon(&Surf, v, 4,
GL_DrawPolygon(&Surf, v, 4,
PF_Modulated|PF_NoTexture|PF_NoDepthTest);
}
@ -984,17 +976,17 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT32
if (!(color & V_NOSCALESTART))
{
float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
float dup = (float)vid.dup;
INT32 intx, inty;
fx *= dupx;
fy *= dupy;
fw *= dupx;
fh *= dupy;
fx *= dup;
fy *= dup;
fw *= dup;
fh *= dup;
intx = (INT32)fx;
inty = (INT32)fy;
V_AdjustXYWithSnap(&intx, &inty, color, dupx, dupy);
V_AdjustXYWithSnap(&intx, &inty, color, dup);
fx = (float)intx;
fy = (float)inty;
}
@ -1039,7 +1031,7 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT32
Surf.PolyColor.rgba = UINT2RGBA(actualcolor);
Surf.PolyColor.s.alpha = 0x80;
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
GL_DrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
}
// -----------------+
@ -1075,7 +1067,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
clearColour.green = (float)rgbaColour.s.green / 255;
clearColour.blue = (float)rgbaColour.s.blue / 255;
clearColour.alpha = 1;
HWD.pfnClearBuffer(true, false, &clearColour);
GL_ClearBuffer(true, false, &clearColour);
return;
}
}
@ -1110,7 +1102,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
else Surf.PolyColor.s.alpha = 0;
}
HWD.pfnDrawPolygon(&Surf, v, 4,
GL_DrawPolygon(&Surf, v, 4,
flags);
}
@ -1194,7 +1186,7 @@ UINT8 *HWR_GetScreenshot(INT32 scale)
return NULL;
// returns 24bit 888 RGB
HWD.pfnReadScreenTexture(tex, (void *)buf, scale);
GL_ReadScreenTexture(tex, (void *)buf, scale);
return buf;
}

View file

@ -1,146 +0,0 @@
// BLANKART
//-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2020 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file hw_drv.h
/// \brief imports/exports for the 3D hardware low-level interface API
#ifndef __HWR_DRV_H__
#define __HWR_DRV_H__
// this must be here 19991024 by Kin
#include "../screen.h"
#include "hw_data.h"
#include "hw_defs.h"
#include "hw_md2.h"
#include "hw_dll.h"
#ifdef __cplusplus
extern "C" {
#endif
// ==========================================================================
// STANDARD DLL EXPORTS
// ==========================================================================
EXPORT boolean HWRAPI(Init) (void);
#ifndef HAVE_SDL
EXPORT void HWRAPI(Shutdown) (void);
#endif
EXPORT void HWRAPI(SetTexturePalette) (RGBA_t *ppal);
EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl);
EXPORT void HWRAPI(Draw2DLine) (F2DCoord *v1, F2DCoord *v2, RGBA_t Color);
EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags);
EXPORT void HWRAPI(DrawIndexedTriangles) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, UINT32 *IndexArray);
EXPORT void HWRAPI(RenderSkyDome) (gl_sky_t *sky);
EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags);
EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat *ClearColor);
EXPORT void HWRAPI(SetTexture) (GLMipmap_t *TexInfo);
EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *TexInfo);
EXPORT void HWRAPI(DeleteTexture) (GLMipmap_t *TexInfo);
EXPORT void HWRAPI(ReadScreenTexture) (int tex, UINT8 *restrict dest, INT32 scale);
EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip);
EXPORT void HWRAPI(ClearMipMapCache) (void);
//Hurdler: added for backward compatibility
EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value);
//Hurdler: added for new development
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float hscale, float vscale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface);
EXPORT void HWRAPI(CreateModelVBOs) (model_t *model);
EXPORT void HWRAPI(SetTransform) (FTransform *stransform);
EXPORT INT32 HWRAPI(GetTextureUsed) (void);
EXPORT void HWRAPI(FlushScreenTextures) (void);
EXPORT void HWRAPI(DoScreenWipe) (int wipeStart, int wipeEnd);
EXPORT void HWRAPI(DrawScreenTexture) (int tex, FSurfaceInfo *surf, FBITFIELD polyflags);
EXPORT void HWRAPI(RenderVhsEffect) (INT16 upbary, INT16 downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize);
EXPORT void HWRAPI(MakeScreenTexture) (int tex);
EXPORT void HWRAPI(DrawScreenFinalTexture) (int tex, int width, int height);
#define SCREENVERTS 10
EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]);
EXPORT boolean HWRAPI(InitShaders) (void);
EXPORT void HWRAPI(LoadShader) (int slot, char *code, hwdshaderstage_t stage);
EXPORT boolean HWRAPI(CompileShader) (int slot);
EXPORT void HWRAPI(SetShader) (int slot);
EXPORT void HWRAPI(UnSetShader) (void);
EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value);
EXPORT void HWRAPI(SetPaletteLookup)(UINT8 *lut);
EXPORT UINT32 HWRAPI(CreateLightTable)(RGBA_t *hw_lighttable);
EXPORT void HWRAPI(ClearLightTables)(void);
EXPORT void HWRAPI(SetScreenPalette)(RGBA_t *palette);
// ==========================================================================
// HWR DRIVER OBJECT, FOR CLIENT PROGRAM
// ==========================================================================
#if !defined (_CREATE_DLL_)
struct hwdriver_s
{
Init pfnInit;
SetTexturePalette pfnSetTexturePalette;
FinishUpdate pfnFinishUpdate;
Draw2DLine pfnDraw2DLine;
DrawPolygon pfnDrawPolygon;
DrawIndexedTriangles pfnDrawIndexedTriangles;
RenderSkyDome pfnRenderSkyDome;
SetBlend pfnSetBlend;
ClearBuffer pfnClearBuffer;
SetTexture pfnSetTexture;
UpdateTexture pfnUpdateTexture;
DeleteTexture pfnDeleteTexture;
ReadScreenTexture pfnReadScreenTexture;
GClipRect pfnGClipRect;
ClearMipMapCache pfnClearMipMapCache;
SetSpecialState pfnSetSpecialState;
DrawModel pfnDrawModel;
CreateModelVBOs pfnCreateModelVBOs;
SetTransform pfnSetTransform;
GetTextureUsed pfnGetTextureUsed;
#ifndef HAVE_SDL
Shutdown pfnShutdown;
#endif
PostImgRedraw pfnPostImgRedraw;
FlushScreenTextures pfnFlushScreenTextures;
DoScreenWipe pfnDoScreenWipe;
RenderVhsEffect pfnRenderVhsEffect;
DrawScreenTexture pfnDrawScreenTexture;
MakeScreenTexture pfnMakeScreenTexture;
DrawScreenFinalTexture pfnDrawScreenFinalTexture;
InitShaders pfnInitShaders;
LoadShader pfnLoadShader;
CompileShader pfnCompileShader;
SetShader pfnSetShader;
UnSetShader pfnUnSetShader;
SetShaderInfo pfnSetShaderInfo;
SetPaletteLookup pfnSetPaletteLookup;
CreateLightTable pfnCreateLightTable;
ClearLightTables pfnClearLightTables;
SetScreenPalette pfnSetScreenPalette;
};
extern struct hwdriver_s hwdriver;
#define HWD hwdriver
#endif //not defined _CREATE_DLL_
#ifdef __cplusplus
} // extern "C"
#endif
#endif //__HWR_DRV_H__

78
src/hardware/hw_gpu.h Normal file
View file

@ -0,0 +1,78 @@
// BLANKART
//-----------------------------------------------------------------------------
// Copyright (C) 2020 by Jaime "Lactozilla" Passos.
// Copyright (C) 2020 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file hw_gpu.h
/// \brief GPU low-level interface API
#ifndef __HWR_GPU_H__
#define __HWR_GPU_H__
#include "../screen.h"
#include "hw_data.h"
#include "hw_defs.h"
#include "hw_md2.h"
#ifdef __cplusplus
extern "C" {
#endif
boolean GL_Init(void);
void GL_SetPalette(RGBA_t *palette);
void GL_FinishUpdate(INT32 waitvbl);
void GL_Draw2DLine(F2DCoord *v1, F2DCoord *v2, RGBA_t Color);
void GL_DrawPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags);
void GL_DrawIndexedTriangles(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, UINT32 *IndexArray);
void GL_RenderSkyDome(gl_sky_t *sky);
void GL_SetBlend(FBITFIELD PolyFlags);
void GL_ClearBuffer(FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat *ClearColor);
void GL_SetTexture(GLMipmap_t *pTexInfo);
void GL_UpdateTexture(GLMipmap_t *pTexInfo);
void GL_DeleteTexture(GLMipmap_t *pTexInfo);
void GL_ReadScreenTexture(int tex, UINT8 *restrict dest, INT32 scale);
void GL_GClipRect(INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip);
void GL_ClearMipMapCache(void);
void GL_SetSpecialState(hwdspecialstate_t IdState, INT32 Value);
// Hurdler: added for new development
void GL_DrawModel(model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float hscale, float vscale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface);
void GL_CreateModelVBOs(model_t *model);
void GL_SetTransform(FTransform *ptransform);
INT32 GL_GetTextureUsed(void);
void GL_FlushScreenTextures(void);
void GL_DoScreenWipe(int wipeStart, int wipeEnd);
void GL_DrawScreenTexture(int tex, FSurfaceInfo *surf, FBITFIELD polyflags);
void GL_MakeScreenTexture(int tex);
void GL_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize);
void GL_DrawScreenFinalTexture(int tex, int width, int height);
#define SCREENVERTS 10
void GL_PostImgRedraw(float points[SCREENVERTS][SCREENVERTS][2]);
boolean GL_InitShaders(void);
void GL_LoadShader(int slot, char *code, hwdshaderstage_t stage);
boolean GL_CompileShader(int slot);
void GL_SetShader(int slot);
void GL_UnSetShader(void);
void GL_SetShaderInfo(hwdshaderinfo_t info, INT32 value);
void GL_SetPaletteLookup(UINT8 *lut);
UINT32 GL_CreateLightTable(RGBA_t *hw_lighttable);
void GL_UpdateLightTable(UINT32 id, RGBA_t *hw_lighttable);
void GL_ClearLightTables(void);
void GL_SetScreenPalette(RGBA_t *palette);
#ifdef __cplusplus
} // extern "C"
#endif
#endif //__HWR_GPU_H__

View file

@ -15,7 +15,7 @@
#ifdef HWRENDER
#include "hw_light.h"
#include "hw_drv.h"
#include "hw_gpu.h"
#include "../i_video.h"
#include "../z_zone.h"
#include "../m_random.h"
@ -881,7 +881,7 @@ void HWR_WallLighting(FOutVector *wlVerts)
if (dynlights->mo[j]->state->nextstate == S_NULL)
Surf.PolyColor.s.alpha = (UINT8)(((float)dynlights->mo[j]->tics/(float)dynlights->mo[j]->state->tics)*Surf.PolyColor.s.alpha);
HWD.pfnDrawPolygon (&Surf, wlVerts, 4, LIGHTMAPFLAGS);
GL_DrawPolygon (&Surf, wlVerts, 4, LIGHTMAPFLAGS);
} // end for (j = 0; j < dynlights->nb; j++)
}
@ -950,7 +950,7 @@ void HWR_PlaneLighting(FOutVector *clVerts, int nrClipVerts)
if ((dynlights->mo[j]->state->nextstate == S_NULL))
Surf.PolyColor.s.alpha = (unsigned char)(((float)dynlights->mo[j]->tics/(float)dynlights->mo[j]->state->tics)*Surf.PolyColor.s.alpha);
HWD.pfnDrawPolygon (&Surf, clVerts, nrClipVerts, LIGHTMAPFLAGS);
GL_DrawPolygon (&Surf, clVerts, nrClipVerts, LIGHTMAPFLAGS);
} // end for (j = 0; j < dynlights->nb; j++)
}
@ -1047,7 +1047,7 @@ void HWR_DoCoronasLighting(FOutVector *outVerts, gl_vissprite_t *spr)
HWR_GetPic(coronalumpnum); /// \todo use different coronas
HWD.pfnDrawPolygon (&Surf, light, 4, PF_Modulated | PF_Additive | PF_Corona | PF_NoDepthTest);
GL_DrawPolygon (&Surf, light, 4, PF_Modulated | PF_Additive | PF_Corona | PF_NoDepthTest);
}
}
#endif
@ -1135,7 +1135,7 @@ void HWR_DrawCoronas(void)
light[3].y = cy+size*1.33f;
light[3].s = 0.0f; light[3].t = 1.0f;
HWD.pfnDrawPolygon (&Surf, light, 4, PF_Modulated | PF_Additive | PF_NoDepthTest | PF_Corona);
GL_DrawPolygon (&Surf, light, 4, PF_Modulated | PF_Additive | PF_NoDepthTest | PF_Corona);
}
}
#endif
@ -1244,7 +1244,7 @@ static void HWR_SetLight(void)
lightmappatch.mipmap->height = 128;
lightmappatch.mipmap->flags = 0; //TF_WRAPXY; // DEBUG: view the overdraw !
}
HWD.pfnSetTexture(lightmappatch.mipmap);
GL_SetTexture(lightmappatch.mipmap);
// The system-memory data can be purged now.
Z_ChangeTag(lightmappatch.mipmap->data, PU_HWRCACHE_UNLOCKED);

View file

@ -21,7 +21,7 @@
#include "hw_clip.h"
#include "hw_glob.h"
#include "hw_light.h"
#include "hw_drv.h"
#include "hw_gpu.h"
#include "hw_batching.h"
#include "../i_video.h" // for rendermode == render_glide
@ -59,7 +59,6 @@
// ==========================================================================
// the hardware driver object
// ==========================================================================
struct hwdriver_s hwdriver;
// ==========================================================================
// PROTOS
@ -308,8 +307,8 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col
// Clamp the light level, since it can sometimes go out of the 0-255 range from animations
light_level = min(max(light_level, cv_secbright.value), 255);
V_CubeApply(&tint_color.s.red, &tint_color.s.green, &tint_color.s.blue);
V_CubeApply(&fade_color.s.red, &fade_color.s.green, &fade_color.s.blue);
V_CubeApply(&tint_color);
V_CubeApply(&fade_color);
Surface->PolyColor.rgba = poly_color.rgba;
Surface->TintColor.rgba = tint_color.rgba;
Surface->FadeColor.rgba = fade_color.rgba;
@ -4562,7 +4561,7 @@ static void HWR_CreateDrawNodes(void)
ps_hw_nodedrawtime = I_GetPreciseTime();
// Okay! Let's draw it all! Woo!
HWD.pfnSetTransform(&atransform);
GL_SetTransform(&atransform);
for (i = 0; i < p; i++)
{
@ -4617,9 +4616,9 @@ static void HWR_DrawSprites(void)
boolean skipshadow = false; // skip shadow if it was drawn already for a linkdraw sprite encountered earlier in the list
#ifdef BAD_MODEL_OPTIONS
HWD.pfnSetSpecialState(HWD_SET_MODEL_LIGHTING, cv_glmodellighting.value);
GL_SetSpecialState(HWD_SET_MODEL_LIGHTING, cv_glmodellighting.value);
#else
HWD.pfnSetSpecialState(HWD_SET_MODEL_LIGHTING, 1);
GL_SetSpecialState(HWD_SET_MODEL_LIGHTING, 1);
#endif
for (i = 0; i < gl_visspritecount; i++)
@ -4682,7 +4681,7 @@ static void HWR_DrawSprites(void)
}
}
}
HWD.pfnSetSpecialState(HWD_SET_MODEL_LIGHTING, 0);
GL_SetSpecialState(HWD_SET_MODEL_LIGHTING, 0);
// At the end of sprite drawing, draw shapes of linkdraw sprites to z-buffer, so they
// don't get drawn over by transparent surfaces.
@ -4692,7 +4691,7 @@ static void HWR_DrawSprites(void)
// (Other states probably don't matter. Here I left them same as in LinkDrawHackFinish)
// Without this workaround the rest of the draw calls in this frame (including UI, screen texture)
// can get drawn using an incorrect glBlendFunc, resulting in a occasional black screen.
HWD.pfnSetBlend(PF_Translucent|PF_Occlude|PF_Masked);
GL_SetBlend(PF_Translucent|PF_Occlude|PF_Masked);
}
// --------------------------------------------------------------------------
@ -4830,12 +4829,15 @@ static void HWR_ProjectSprite(mobj_t *thing)
interpmobjstate_t interp = {0};
mobj_t *interptarg;
if (G_GamestateUsesLevel() == false)
return;
if (!thing)
return;
interptarg = thing;
if (R_IsOverlayingInvinciblePlayer(thing))
if (R_IsOverlayingSMonitorPlayer(thing))
{
// Kill overlay misalignment
interptarg = thing->target;
@ -5280,7 +5282,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
if (thing->colorized)
{
vis->colormap = R_GetTranslationColormap(
R_IsOverlayingInvinciblePlayer(thing) ? TC_BLINK : TC_RAINBOW,
R_IsOverlayingSMonitorPlayer(thing) ? TC_BLINK : TC_RAINBOW,
thing->color,
GTC_CACHE);
}
@ -5637,7 +5639,7 @@ static void HWR_DrawSkyBackground(player_t *player)
{
UINT8 viewnum = R_GetViewNumber();
camera_t *thiscam = &camera[viewnum];
HWD.pfnSetBlend(PF_Translucent|PF_NoDepthTest|PF_Modulated);
GL_SetBlend(PF_Translucent|PF_NoDepthTest|PF_Modulated);
if (cv_glskydome.value)
{
@ -5680,10 +5682,10 @@ static void HWR_DrawSkyBackground(player_t *player)
}
if (HWR_UseShader())
HWD.pfnSetShader(HWR_GetShaderFromTarget(SHADER_SKY));
GL_SetShader(HWR_GetShaderFromTarget(SHADER_SKY));
HWD.pfnSetTransform(&dometransform);
HWD.pfnRenderSkyDome(&gl_sky);
GL_SetTransform(&dometransform);
GL_RenderSkyDome(&gl_sky);
}
else
{
@ -5764,8 +5766,8 @@ static void HWR_DrawSkyBackground(player_t *player)
v[0].t = v[1].t -= ((float) angle / angleturn);
}
HWD.pfnUnSetShader();
HWD.pfnDrawPolygon(NULL, v, 4, 0);
GL_UnSetShader();
GL_DrawPolygon(NULL, v, 4, 0);
}
}
@ -5782,16 +5784,16 @@ static inline void HWR_ClearView(void)
/// \bug faB - enable depth mask, disable color mask
HWD.pfnGClipRect((INT32)gl_viewwindowx,
GL_GClipRect((INT32)gl_viewwindowx,
(INT32)gl_viewwindowy,
(INT32)(gl_viewwindowx + gl_viewwidth),
(INT32)(gl_viewwindowy + gl_viewheight),
ZCLIP_PLANE);
HWD.pfnClearBuffer(false, true, 0);
GL_ClearBuffer(false, true, 0);
//disable clip window - set to full size
// rem by Hurdler
// HWD.pfnGClipRect(0, 0, vid.width, vid.height);
// GL_GClipRect(0, 0, vid.width, vid.height);
}
@ -5826,7 +5828,7 @@ void HWR_SetViewSize(void)
gl_pspritexscale = gl_viewwidth / BASEVIDWIDTH;
gl_pspriteyscale = ((vid.height*gl_pspritexscale*BASEVIDWIDTH)/BASEVIDHEIGHT)/vid.width;
HWD.pfnFlushScreenTextures();
GL_FlushScreenTextures();
}
// -------------------+
@ -5882,7 +5884,7 @@ static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean
//
static void HWR_SetShaderState(void)
{
HWD.pfnSetSpecialState(HWD_SET_SHADERS, (INT32)HWR_UseShader());
GL_SetSpecialState(HWD_SET_SHADERS, (INT32)HWR_UseShader());
}
static void HWR_ClearClipper(void)
@ -5984,7 +5986,7 @@ void HWR_RenderSkyboxView(player_t *player)
//04/01/2000: Hurdler: added for T&L
// Actually it only works on Walls and Planes
HWD.pfnSetTransform(&atransform);
GL_SetTransform(&atransform);
HWR_ClearClipper();
@ -6028,15 +6030,15 @@ void HWR_RenderSkyboxView(player_t *player)
HWR_CreateDrawNodes();
}
HWD.pfnSetTransform(NULL);
HWD.pfnUnSetShader();
GL_SetTransform(NULL);
GL_UnSetShader();
// Check for new console commands.
NetUpdate();
// added by Hurdler for correct splitscreen
// moved here by hurdler so it works with the new near clipping plane
HWD.pfnGClipRect(0, 0, vid.width, vid.height, NZCLIP_PLANE);
GL_GClipRect(0, 0, vid.width, vid.height, NZCLIP_PLANE);
}
// ==========================================================================
@ -6072,10 +6074,10 @@ void HWR_RenderPlayerView(void)
ClearColor.alpha = 1.0f;
if (cv_glshaders.value)
HWD.pfnSetShaderInfo(HWD_SHADERINFO_LEVELTIME, (INT32)leveltime); // The water surface shader needs the leveltime.
GL_SetShaderInfo(HWD_SHADERINFO_LEVELTIME, (INT32)leveltime); // The water surface shader needs the leveltime.
if (viewssnum == 0) // Only do it if it's the first screen being rendered
HWD.pfnClearBuffer(true, false, &ClearColor); // Clear the Color Buffer, stops HOMs. Also seems to fix the skybox issue on Intel GPUs.
GL_ClearBuffer(true, false, &ClearColor); // Clear the Color Buffer, stops HOMs. Also seems to fix the skybox issue on Intel GPUs.
ps_hw_skyboxtime = I_GetPreciseTime();
if (skybox) // If there's a skybox and we should be drawing the sky, draw the skybox
@ -6110,8 +6112,7 @@ void HWR_RenderPlayerView(void)
{
// V_DrawPatchFill, but for the fourth screen only
patch_t *gpatch = (patch_t *)W_CachePatchName("SRB2BACK", PU_CACHE);
INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
INT32 x, y, pw = SHORT(gpatch->width) * dupz, ph = SHORT(gpatch->height) * dupz;
INT32 x, y, pw = SHORT(gpatch->width) * vid.dup, ph = SHORT(gpatch->height) * vid.dup;
for (x = vid.width>>1; x < vid.width; x += pw)
{
@ -6177,7 +6178,7 @@ void HWR_RenderPlayerView(void)
//04/01/2000: Hurdler: added for T&L
// Actually it only works on Walls and Planes
HWD.pfnSetTransform(&atransform);
GL_SetTransform(&atransform);
HWR_ClearClipper();
@ -6235,8 +6236,8 @@ void HWR_RenderPlayerView(void)
HWR_CreateDrawNodes();
}
HWD.pfnSetTransform(NULL);
HWD.pfnUnSetShader();
GL_SetTransform(NULL);
GL_UnSetShader();
HWR_DoPostProcessor(player);
@ -6245,7 +6246,7 @@ void HWR_RenderPlayerView(void)
// added by Hurdler for correct splitscreen
// moved here by hurdler so it works with the new near clipping plane
HWD.pfnGClipRect(0, 0, vid.width, vid.height, NZCLIP_PLANE);
GL_GClipRect(0, 0, vid.width, vid.height, NZCLIP_PLANE);
}
// Returns whether palette rendering is "actually enabled."
@ -6381,13 +6382,13 @@ consvar_t cv_glpalettedepth = CVAR_INIT ("gr_palettedepth", "16 bits", CV_SAVE|C
static void CV_glfiltermode_OnChange(void)
{
ONLY_IF_GL_LOADED
HWD.pfnSetSpecialState(HWD_SET_TEXTUREFILTERMODE, cv_glfiltermode.value);
GL_SetSpecialState(HWD_SET_TEXTUREFILTERMODE, cv_glfiltermode.value);
}
static void CV_glanisotropic_OnChange(void)
{
ONLY_IF_GL_LOADED
HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_glanisotropicmode.value);
GL_SetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_glanisotropicmode.value);
}
void CV_glmodellighting_OnChange(void);
@ -6512,12 +6513,11 @@ void HWR_Switch(void)
HWR_AddSessionCommands();
// Set special states from CVARs
HWD.pfnSetSpecialState(HWD_SET_TEXTUREFILTERMODE, cv_glfiltermode.value);
HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_glanisotropicmode.value);
GL_SetSpecialState(HWD_SET_TEXTUREFILTERMODE, cv_glfiltermode.value);
GL_SetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_glanisotropicmode.value);
// Load textures
if (!gl_maptexturesloaded)
HWR_LoadMapTextures(numtextures);
HWR_LoadMapTextures(numtextures);
// Create plane polygons
if (!gl_maploaded && levelloaded)
@ -6536,7 +6536,7 @@ void HWR_Shutdown(void)
HWR_FreeExtraSubsectors();
HWR_FreePolyPool();
HWR_FreeMapTextures();
HWD.pfnFlushScreenTextures();
GL_FlushScreenTextures();
}
void transform(float *cx, float *cy, float *cz)
@ -6622,12 +6622,12 @@ void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend,
INT32 HWR_GetTextureUsed(void)
{
return HWD.pfnGetTextureUsed();
return GL_GetTextureUsed();
}
void HWR_DoPostProcessor(player_t *player)
{
HWD.pfnUnSetShader();
GL_UnSetShader();
// Armageddon Blast Flash!
// Could this even be considered postprocessor?
@ -6651,14 +6651,14 @@ void HWR_DoPostProcessor(player_t *player)
Surf.PolyColor.s.alpha = 0xc0; // match software mode
V_CubeApply(&Surf.PolyColor.s.red, &Surf.PolyColor.s.green, &Surf.PolyColor.s.blue);
V_CubeApply(&Surf.PolyColor);
HWD.pfnDrawPolygon(&Surf, v, 4, PF_Modulated|PF_Additive|PF_NoTexture|PF_NoDepthTest);
GL_DrawPolygon(&Surf, v, 4, PF_Modulated|PF_Additive|PF_NoTexture|PF_NoDepthTest);
}
// Capture the screen for intermission and screen waving
if (gamestate != GS_INTERMISSION)
HWD.pfnMakeScreenTexture(HWD_SCREENTEXTURE_GENERIC1);
GL_MakeScreenTexture(HWD_SCREENTEXTURE_GENERIC1);
if (r_splitscreen) // Not supported in splitscreen - someone want to add support?
return;
@ -6702,11 +6702,11 @@ void HWR_DoPostProcessor(player_t *player)
v[x][y][1] = (y/((float)(SCREENVERTS-1.0f)/9.0f))-4.5f;
}
}
HWD.pfnPostImgRedraw(v);
GL_PostImgRedraw(v);
// Capture the screen again for screen waving on the intermission
if (gamestate != GS_INTERMISSION)
HWD.pfnMakeScreenTexture(HWD_SCREENTEXTURE_GENERIC1);
GL_MakeScreenTexture(HWD_SCREENTEXTURE_GENERIC1);
}
// Flipping of the screen isn't done here anymore
}
@ -6714,18 +6714,18 @@ void HWR_DoPostProcessor(player_t *player)
void HWR_StartScreenWipe(void)
{
//CONS_Debug(DBG_RENDER, "In HWR_StartScreenWipe()\n");
HWD.pfnMakeScreenTexture(HWD_SCREENTEXTURE_WIPE_START);
GL_MakeScreenTexture(HWD_SCREENTEXTURE_WIPE_START);
}
void HWR_EndScreenWipe(void)
{
//CONS_Debug(DBG_RENDER, "In HWR_EndScreenWipe()\n");
HWD.pfnMakeScreenTexture(HWD_SCREENTEXTURE_WIPE_END);
GL_MakeScreenTexture(HWD_SCREENTEXTURE_WIPE_END);
}
void HWR_DrawIntermissionBG(void)
{
HWD.pfnDrawScreenTexture(HWD_SCREENTEXTURE_GENERIC1, NULL, 0);
GL_DrawScreenTexture(HWD_SCREENTEXTURE_GENERIC1, NULL, 0);
}
//
@ -6770,7 +6770,7 @@ void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum)
return;
HWR_GetFadeMask(wipelumpnum);
HWD.pfnDoScreenWipe(HWD_SCREENTEXTURE_WIPE_START, HWD_SCREENTEXTURE_WIPE_END);
GL_DoScreenWipe(HWD_SCREENTEXTURE_WIPE_START, HWD_SCREENTEXTURE_WIPE_END);
}
void HWR_DoTintedWipe(UINT8 wipenum, UINT8 scrnnum)
@ -6779,21 +6779,21 @@ void HWR_DoTintedWipe(UINT8 wipenum, UINT8 scrnnum)
HWR_DoWipe(wipenum, scrnnum);
}
void HWR_RenderVhsEffect(INT16 upbary, INT16 downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize)
void HWR_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize)
{
HWD.pfnRenderVhsEffect(upbary, downbary, updistort, downdistort, barsize);
GL_RenderVhsEffect(upbary, downbary, updistort, downdistort, barsize);
}
void HWR_MakeScreenFinalTexture(void)
{
int tex = HWR_ShouldUsePaletteRendering() ? HWD_SCREENTEXTURE_GENERIC3 : HWD_SCREENTEXTURE_GENERIC2;
HWD.pfnMakeScreenTexture(tex);
GL_MakeScreenTexture(tex);
}
void HWR_DrawScreenFinalTexture(int width, int height)
{
int tex = HWR_ShouldUsePaletteRendering() ? HWD_SCREENTEXTURE_GENERIC3 : HWD_SCREENTEXTURE_GENERIC2;
HWD.pfnDrawScreenFinalTexture(tex, width, height);
GL_DrawScreenFinalTexture(tex, width, height);
}
#endif // HWRENDER

View file

@ -66,7 +66,7 @@ void HWR_MakeIntermissionBG(void);
void HWR_DrawIntermissionBG(void);
void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum);
void HWR_DoTintedWipe(UINT8 wipenum, UINT8 scrnnum);
void HWR_RenderVhsEffect(INT16 upbary, INT16 downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize);
void HWR_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize);
void HWR_MakeScreenFinalTexture(void);
void HWR_DrawScreenFinalTexture(int width, int height);
@ -147,7 +147,6 @@ extern precise_t ps_hw_batchdrawtime;
extern boolean gl_init;
extern boolean gl_maploaded;
extern boolean gl_maptexturesloaded;
extern boolean gl_sessioncommandsadded;
extern boolean gl_shadersavailable;

View file

@ -24,7 +24,7 @@
#include "../doomstat.h"
#ifdef HWRENDER
#include "hw_drv.h"
#include "hw_gpu.h"
#include "hw_light.h"
#include "hw_md2.h"
#include "../d_main.h"
@ -421,13 +421,13 @@ static void md2_loadTexture(md2_t *model)
size = w*h;
while (size--)
{
V_CubeApply(&image->s.red, &image->s.green, &image->s.blue);
V_CubeApply(image);
image++;
}
}
}
HWD.pfnSetTexture(grPatch->mipmap);
GL_SetTexture(grPatch->mipmap);
}
// -----------------+
@ -482,7 +482,7 @@ static void md2_loadBlendTexture(md2_t *model)
grPatch->mipmap->height = (UINT16)h;
}
HWD.pfnSetTexture(grPatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary
GL_SetTexture(grPatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary
Z_Free(filename);
}
@ -757,17 +757,16 @@ static void HWR_CreateBlendedTexture(patch_t *gpatch, patch_t *blendgpatch, GLMi
GLPatch_t *hwrBlendPatch = blendgpatch->hardware;
UINT16 w = gpatch->width, h = gpatch->height;
UINT32 size = w*h;
RGBA_t *image, *blendimage, *cur, blendcolor;
UINT8 translation[17]; // First the color index
UINT8 cutoff[17]; // Brightness cutoff before using the next color
RGBA_t *image, *blendimage, *cur;
RGBA_t blendcolor = {};
UINT8 translation[17] = {}; // First the color index
UINT8 cutoff[17] = {}; // Brightness cutoff before using the next color
UINT8 translen = 0;
UINT8 i;
UINT8 colorbrightnesses[17];
UINT8 color_match_lookup[256]; // optimization attempt
UINT8 colorbrightnesses[17] = {};
UINT8 color_match_lookup[256] = {}; // optimization attempt
blendcolor = V_GetColor(0); // initialize
memset(translation, 0, sizeof(translation));
memset(cutoff, 0, sizeof(cutoff));
if (grMipmap->width == 0)
{
@ -781,14 +780,10 @@ static void HWR_CreateBlendedTexture(patch_t *gpatch, patch_t *blendgpatch, GLMi
grMipmap->format = GL_TEXFMT_RGBA;
}
if (grMipmap->data)
{
Z_Free(grMipmap->data);
grMipmap->data = NULL;
}
Z_Free(grMipmap->data);
grMipmap->data = NULL;
cur = Z_Malloc(size*4, PU_HWRMODELTEXTURE, &grMipmap->data);
memset(cur, 0x00, size*4);
cur = Z_Calloc(size*4, PU_HWRMODELTEXTURE, &grMipmap->data);
image = hwrPatch->mipmap->data;
blendimage = hwrBlendPatch->mipmap->data;
@ -1153,7 +1148,7 @@ static void HWR_GetBlendedTexture(patch_t *patch, patch_t *blendpatch, INT32 ski
if (blendpatch == NULL || colormap == colormaps || colormap == NULL)
{
// Don't do any blending
HWD.pfnSetTexture(grPatch->mipmap);
GL_SetTexture(grPatch->mipmap);
return;
}
@ -1161,7 +1156,7 @@ static void HWR_GetBlendedTexture(patch_t *patch, patch_t *blendpatch, INT32 ski
&& (patch->width != blendpatch->width || patch->height != blendpatch->height))
{
// Blend image exists, but it's bad.
HWD.pfnSetTexture(grPatch->mipmap);
GL_SetTexture(grPatch->mipmap);
return;
}
@ -1178,10 +1173,10 @@ static void HWR_GetBlendedTexture(patch_t *patch, patch_t *blendpatch, INT32 ski
{
memcpy(grMipmap->colormap->data, colormap, 256 * sizeof(UINT8));
HWR_CreateBlendedTexture(patch, blendpatch, grMipmap, skinnum, color);
HWD.pfnUpdateTexture(grMipmap);
GL_UpdateTexture(grMipmap);
}
else
HWD.pfnSetTexture(grMipmap); // found the colormap, set it to the correct texture
GL_SetTexture(grMipmap); // found the colormap, set it to the correct texture
Z_ChangeTag(grMipmap->data, PU_HWRMODELTEXTURE_UNLOCKED);
return;
@ -1207,7 +1202,7 @@ static void HWR_GetBlendedTexture(patch_t *patch, patch_t *blendpatch, INT32 ski
HWR_CreateBlendedTexture(patch, blendpatch, newMipmap, skinnum, color);
HWD.pfnSetTexture(newMipmap);
GL_SetTexture(newMipmap);
Z_ChangeTag(newMipmap->data, PU_HWRMODELTEXTURE_UNLOCKED);
}
@ -1508,7 +1503,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
// note down the max_s and max_t that end up in the VBO
md2->model->vbo_max_s = md2->model->max_s;
md2->model->vbo_max_t = md2->model->max_t;
HWD.pfnCreateModelVBOs(md2->model);
GL_CreateModelVBOs(md2->model);
}
else
{
@ -1518,7 +1513,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
}
}
//HWD.pfnSetBlend(blend); // This seems to actually break translucency?
//GL_SetBlend(blend); // This seems to actually break translucency?
//Hurdler: arf, I don't like that implementation at all... too much crappy
if (gpatch && hwrPatch && hwrPatch->mipmap->format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture
@ -1726,7 +1721,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
p.mirror = atransform.mirror;
if (HWR_UseShader())
HWD.pfnSetShader(HWR_GetShaderFromTarget(SHADER_MODEL));
GL_SetShader(HWR_GetShaderFromTarget(SHADER_MODEL));
{
float this_scale = FIXED_TO_FLOAT(interp.scale);
fixed_t floorClip = spr->mobj->terrain ? spr->mobj->terrain->floorClip : 0;
@ -1835,7 +1830,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
p.y += yx + zy + ypiv;
}
HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, md2->scale * xs, md2->scale * ys, flip, hflip, &Surf);
GL_DrawModel(md2->model, frame, durs, tics, nextFrame, &p, md2->scale * xs, md2->scale * ys, flip, hflip, &Surf);
}
}

View file

@ -12,7 +12,7 @@
#ifdef HWRENDER
#include "hw_glob.h"
#include "hw_drv.h"
#include "hw_gpu.h"
#include "hw_shaders.h"
#include "../z_zone.h"
@ -88,7 +88,7 @@ boolean HWR_InitShaders(void)
{
int i;
if (!HWD.pfnInitShaders())
if (!GL_InitShaders())
return false;
for (i = 0; i < NUMSHADERTARGETS; i++)
@ -368,16 +368,16 @@ static void HWR_CompileShader(int index)
{
char *preprocessed = HWR_PreprocessShader(vertex_source);
if (!preprocessed) return;
HWD.pfnLoadShader(index, preprocessed, HWD_SHADERSTAGE_VERTEX);
GL_LoadShader(index, preprocessed, HWD_SHADERSTAGE_VERTEX);
}
if (fragment_source)
{
char *preprocessed = HWR_PreprocessShader(fragment_source);
if (!preprocessed) return;
HWD.pfnLoadShader(index, preprocessed, HWD_SHADERSTAGE_FRAGMENT);
GL_LoadShader(index, preprocessed, HWD_SHADERSTAGE_FRAGMENT);
}
gl_shaders[index].compiled = HWD.pfnCompileShader(index);
gl_shaders[index].compiled = GL_CompileShader(index);
}
// compile or recompile shaders

View file

@ -392,7 +392,7 @@ static void UnSetRes(void)
// Returns : pvidmodes - points to list of detected OpenGL video modes
// : numvidmodes - number of detected OpenGL video modes
// -----------------+
EXPORT void HWRAPI(GetModeList) (vmode_t** pvidmodes, INT32 *numvidmodes)
void GL_GetModeList(vmode_t** pvidmodes, INT32 *numvidmodes)
{
INT32 i;
@ -497,7 +497,7 @@ EXPORT void HWRAPI(GetModeList) (vmode_t** pvidmodes, INT32 *numvidmodes)
// -----------------+
// Shutdown : Shutdown OpenGL, restore the display mode
// -----------------+
EXPORT void HWRAPI(Shutdown) (void)
void GL_Shutdown(void)
{
#ifdef DEBUG_TO_FILE
long nb_centiemes;
@ -526,7 +526,7 @@ EXPORT void HWRAPI(Shutdown) (void)
// -----------------+
// FinishUpdate : Swap front and back buffers
// -----------------+
EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl)
void GL_FinishUpdate(INT32 waitvbl)
{
#ifdef USE_WGL_SWAP
static INT32 oldwaitvbl = 0;
@ -554,13 +554,13 @@ EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl)
// : in OpenGL, we store values for conversion of paletted graphics when
// : they are downloaded to the 3D card.
// -----------------+
EXPORT void HWRAPI(SetPalette) (RGBA_t *pal)
void GL_SetPalette(RGBA_t *palette)
{
size_t palsize = (sizeof(RGBA_t) * 256);
// on a palette change, you have to reload all of the textures
if (memcmp(&myPaletteData, pal, palsize))
if (memcmp(&myPaletteData, palette, palsize))
{
memcpy(&myPaletteData, pal, palsize);
memcpy(&myPaletteData, palette, palsize);
Flush();
}
}

View file

@ -26,6 +26,7 @@
#include "r_vbo.h"
#include "../hw_clip.h"
#include "../hw_shaders.h"
#include "../hw_gpu.h"
#if defined (HWRENDER) && !defined (NOROPENGL)
@ -734,7 +735,7 @@ void SetupGLFunc4(void)
#endif
}
EXPORT boolean HWRAPI(InitShaders) (void)
boolean GL_InitShaders(void)
{
#ifdef GL_SHADERS
@ -756,7 +757,7 @@ EXPORT boolean HWRAPI(InitShaders) (void)
#endif
}
EXPORT void HWRAPI(LoadShader) (int slot, char *code, hwdshaderstage_t stage)
void GL_LoadShader(int slot, char *code, hwdshaderstage_t stage)
{
#ifdef GL_SHADERS
gl_shader_t *shader;
@ -788,7 +789,7 @@ EXPORT void HWRAPI(LoadShader) (int slot, char *code, hwdshaderstage_t stage)
}
EXPORT boolean HWRAPI(CompileShader) (int slot)
boolean GL_CompileShader(int slot)
{
#ifdef GL_SHADERS
if (slot < 0 || slot >= HWR_MAXSHADERS)
@ -814,7 +815,7 @@ EXPORT boolean HWRAPI(CompileShader) (int slot)
// Those are given to the uniforms.
//
EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value)
void GL_SetShaderInfo(hwdshaderinfo_t info, INT32 value)
{
#ifdef GL_SHADERS
switch (info)
@ -846,12 +847,12 @@ EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value)
#endif
}
EXPORT void HWRAPI(SetShader) (int slot)
void GL_SetShader(int slot)
{
#ifdef GL_SHADERS
if (slot == SHADER_NONE)
{
UnSetShader();
GL_UnSetShader();
return;
}
@ -880,7 +881,7 @@ EXPORT void HWRAPI(SetShader) (int slot)
gl_shadersenabled = false;
}
EXPORT void HWRAPI(UnSetShader) (void)
void GL_UnSetShader(void)
{
#ifdef GL_SHADERS
if (gl_shadersenabled) // don't repeatedly call glUseProgram if not needed
@ -995,7 +996,7 @@ void SetModelView(GLint w, GLint h)
// The screen textures need to be flushed if the width or height change so that they be remade for the correct size
if (screen_width != w || screen_height != h)
FlushScreenTextures();
GL_FlushScreenTextures();
screen_width = w;
screen_height = h;
@ -1114,7 +1115,7 @@ void SetStates(void)
// this set CurrentPolyFlags to the actual configuration
CurrentPolyFlags = 0xffffffff;
SetBlend(0);
GL_SetBlend(0);
tex_downloaded = 0;
SetNoTexture(GL_TEXTURE0);
@ -1148,7 +1149,7 @@ void SetStates(void)
// -----------------+
// DeleteTexture : Deletes a texture from the GPU and frees its data
// -----------------+
EXPORT void HWRAPI(DeleteTexture) (GLMipmap_t *pTexInfo)
void GL_DeleteTexture(GLMipmap_t *pTexInfo)
{
FTextureInfo *head = TexCacheHead;
@ -1246,16 +1247,15 @@ INT32 isExtAvailable(const char *extension, const GLubyte *start)
// -----------------+
// Init : Initialise the OpenGL interface API
// -----------------+
EXPORT boolean HWRAPI(Init) (void)
boolean GL_Init(void)
{
return LoadGL();
}
// -----------------+
// ClearMipMapCache : Flush OpenGL textures from memory
// -----------------+
EXPORT void HWRAPI(ClearMipMapCache) (void)
void GL_ClearMipMapCache(void)
{
// GL_DBG_Printf ("HWR_Flush(exe)\n");
Flush();
@ -1264,7 +1264,7 @@ EXPORT void HWRAPI(ClearMipMapCache) (void)
// Writes screen texture tex into dst_data.
// Pixel format is 24-bit RGB. Row order is top to bottom.
// Dimensions are screen_width * screen_height.
EXPORT void HWRAPI(ReadScreenTexture) (int tex, UINT8 *restrict dest, INT32 scale)
void GL_ReadScreenTexture(int tex, UINT8 *restrict dest, INT32 scale)
{
const INT32 stride = (screen_width/scale)*3;
INT32 scanlines = screen_height;
@ -1275,14 +1275,14 @@ EXPORT void HWRAPI(ReadScreenTexture) (int tex, UINT8 *restrict dest, INT32 scal
// and draw generic2 back after reading the framebuffer.
// this hack is for some reason **much** faster than the simple solution of using glGetTexImage.
if (tex != HWD_SCREENTEXTURE_GENERIC2)
DrawScreenTexture(tex, NULL, 0);
GL_DrawScreenTexture(tex, NULL, 0);
image = malloc(screen_width*screen_height*3);
pglPixelStorei(GL_PACK_ALIGNMENT, 1);
pglReadPixels(0, 0, screen_width, screen_height, GL_RGB, GL_UNSIGNED_BYTE, image);
if (tex != HWD_SCREENTEXTURE_GENERIC2)
DrawScreenTexture(HWD_SCREENTEXTURE_GENERIC2, NULL, 0);
GL_DrawScreenTexture(HWD_SCREENTEXTURE_GENERIC2, NULL, 0);
// TODO the downscaling happens in the screen capture code now,
// yet we're still doing this on the CPU? sheesh...
@ -1303,10 +1303,24 @@ EXPORT void HWRAPI(ReadScreenTexture) (int tex, UINT8 *restrict dest, INT32 scal
}
// -----------------+
// SetPalette : Changes the current texture palette
// -----------------+
void GL_SetPalette(RGBA_t *palette)
{
size_t palsize = (sizeof(RGBA_t) * 256);
// on a palette change, you have to reload all of the textures
if (memcmp(&myPaletteData, palette, palsize))
{
memcpy(&myPaletteData, palette, palsize);
Flush();
}
}
// -----------------+
// GClipRect : Defines the 2D hardware clipping window
// -----------------+
EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip)
void GL_GClipRect(INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip)
{
// GL_DBG_Printf ("GClipRect(%d, %d, %d, %d)\n", minx, miny, maxx, maxy);
@ -1328,7 +1342,7 @@ EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, f
// -----------------+
// ClearBuffer : Clear the color/alpha/depth buffer(s)
// -----------------+
EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask,
void GL_ClearBuffer(FBOOLEAN ColorMask,
FBOOLEAN DepthMask,
FRGBAFloat * ClearColor)
{
@ -1352,7 +1366,7 @@ EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask,
ClearMask |= GL_DEPTH_BUFFER_BIT;
}
SetBlend(DepthMask ? PF_Occlude | CurrentPolyFlags : CurrentPolyFlags&~PF_Occlude);
GL_SetBlend(DepthMask ? PF_Occlude | CurrentPolyFlags : CurrentPolyFlags&~PF_Occlude);
pglClear(ClearMask);
pglEnableClientState(GL_VERTEX_ARRAY); // We always use this one
@ -1363,7 +1377,7 @@ EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask,
// -----------------+
// HWRAPI Draw2DLine: Render a 2D line
// -----------------+
EXPORT void HWRAPI(Draw2DLine) (F2DCoord * v1,
void GL_Draw2DLine(F2DCoord * v1,
F2DCoord * v2,
RGBA_t Color)
{
@ -1373,7 +1387,7 @@ EXPORT void HWRAPI(Draw2DLine) (F2DCoord * v1,
GLfloat angle;
// BP: we should reflect the new state in our variable
//SetBlend(PF_Modulated|PF_NoTexture);
//GL_SetBlend(PF_Modulated|PF_NoTexture);
pglDisable(GL_TEXTURE_2D);
@ -1492,7 +1506,7 @@ static void SetBlendMode(FBITFIELD flags)
}
}
EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags)
void GL_SetBlend(FBITFIELD PolyFlags)
{
FBITFIELD Xor;
Xor = CurrentPolyFlags^PolyFlags;
@ -1609,7 +1623,7 @@ static void AllocTextureBuffer(GLMipmap_t *pTexInfo)
// -----------------+
// UpdateTexture : Updates texture data.
// -----------------+
EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo)
void GL_UpdateTexture(GLMipmap_t *pTexInfo)
{
// Upload a texture
GLuint num = pTexInfo->downloaded;
@ -1778,7 +1792,7 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo)
// -----------------+
// SetTexture : The mipmap becomes the current texture source
// -----------------+
EXPORT void HWRAPI(SetTexture) (GLMipmap_t *pTexInfo)
void GL_SetTexture(GLMipmap_t *pTexInfo)
{
if (!pTexInfo)
{
@ -1805,7 +1819,7 @@ EXPORT void HWRAPI(SetTexture) (GLMipmap_t *pTexInfo)
{
FTextureInfo *newTex = calloc(1, sizeof (*newTex));
UpdateTexture(pTexInfo);
GL_UpdateTexture(pTexInfo);
newTex->texture = pTexInfo;
newTex->downloaded = (UINT32)pTexInfo->downloaded;
@ -2093,7 +2107,7 @@ static void PreparePolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FBITFIELD
if ((PolyFlags & PF_Corona) && (oglflags & GLF_NOZBUFREAD))
PolyFlags &= ~(PF_NoDepthTest|PF_Corona);
SetBlend(PolyFlags); //TODO: inline (#pragma..)
GL_SetBlend(PolyFlags); //TODO: inline (#pragma..)
if (pSurf)
{
@ -2202,7 +2216,7 @@ static void PreparePolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FBITFIELD
// -----------------+
// DrawPolygon : Render a polygon, set the texture, set render mode
// -----------------+
EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags)
void GL_DrawPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags)
{
PreparePolygon(pSurf, pOutVerts, PolyFlags);
@ -2220,7 +2234,7 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUI
Clamp2D(GL_TEXTURE_WRAP_T);
}
EXPORT void HWRAPI(DrawIndexedTriangles) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, UINT32 *IndexArray)
void GL_DrawIndexedTriangles(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, UINT32 *IndexArray)
{
PreparePolygon(pSurf, pOutVerts, PolyFlags);
@ -2236,7 +2250,7 @@ EXPORT void HWRAPI(DrawIndexedTriangles) (FSurfaceInfo *pSurf, FOutVector *pOutV
#define sky_vbo_u ((void*)offsetof(gl_skyvertex_t, u))
#define sky_vbo_r ((void*)offsetof(gl_skyvertex_t, r))
EXPORT void HWRAPI(RenderSkyDome) (gl_sky_t *sky)
void GL_RenderSkyDome(gl_sky_t *sky)
{
int i, j;
@ -2312,7 +2326,7 @@ EXPORT void HWRAPI(RenderSkyDome) (gl_sky_t *sky)
pglDisableClientState(GL_COLOR_ARRAY);
}
EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value)
void GL_SetSpecialState(hwdspecialstate_t IdState, INT32 Value)
{
switch (IdState)
{
@ -2542,7 +2556,7 @@ static void CreateModelVBOTiny(mesh_t *mesh, tinyframe_t *frame)
pglBindBuffer(GL_ARRAY_BUFFER, 0);
}
EXPORT void HWRAPI(CreateModelVBOs) (model_t *model)
void GL_CreateModelVBOs(model_t *model)
{
int i;
for (i = 0; i < model->numMeshes; i++)
@ -2677,7 +2691,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float
lt_downloaded = Surface->LightTableId;
}
SetBlend(flags);
GL_SetBlend(flags);
Shader_SetUniforms(Surface, &poly, &tint, &fade);
pglEnable(GL_CULL_FACE);
@ -2865,7 +2879,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float
// -----------------+
// HWRAPI DrawModel : Draw a model
// -----------------+
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float hscale, float vscale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface)
void GL_DrawModel(model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float hscale, float vscale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface)
{
DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, hscale, vscale, flipped, hflipped, Surface);
}
@ -2873,7 +2887,7 @@ EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, float duration,
// -----------------+
// SetTransform :
// -----------------+
EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
void GL_SetTransform(FTransform *stransform)
{
static boolean special_splitscreen;
boolean shearing = false;
@ -2936,7 +2950,7 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
}
EXPORT INT32 HWRAPI(GetTextureUsed) (void)
INT32 GL_GetTextureUsed(void)
{
FTextureInfo *tmp = TexCacheHead;
INT32 res = 0;
@ -2961,7 +2975,7 @@ EXPORT INT32 HWRAPI(GetTextureUsed) (void)
return res;
}
EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2])
void GL_PostImgRedraw(float points[SCREENVERTS][SCREENVERTS][2])
{
INT32 x, y;
float float_x, float_y, float_nextx, float_nexty;
@ -3047,7 +3061,7 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2])
// Sryder: This needs to be called whenever the screen changes resolution in order to reset the screen textures to use
// a new size
EXPORT void HWRAPI(FlushScreenTextures) (void)
void GL_FlushScreenTextures(void)
{
int i;
pglDeleteTextures(NUMSCREENTEXTURES, screenTextures);
@ -3055,7 +3069,7 @@ EXPORT void HWRAPI(FlushScreenTextures) (void)
screenTextures[i] = 0;
}
EXPORT void HWRAPI(DrawScreenTexture)(int tex, FSurfaceInfo *surf, FBITFIELD polyflags)
void GL_DrawScreenTexture(int tex, FSurfaceInfo *surf, FBITFIELD polyflags)
{
float xfix, yfix;
@ -3101,7 +3115,7 @@ EXPORT void HWRAPI(DrawScreenTexture)(int tex, FSurfaceInfo *surf, FBITFIELD pol
}
// Do screen fades!
EXPORT void HWRAPI(DoScreenWipe)(int wipeStart, int wipeEnd)
void GL_DoScreenWipe(int wipeStart, int wipeEnd)
{
float xfix, yfix;
@ -3139,7 +3153,7 @@ EXPORT void HWRAPI(DoScreenWipe)(int wipeStart, int wipeEnd)
pglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
SetBlend(PF_Modulated|PF_NoDepthTest);
GL_SetBlend(PF_Modulated|PF_NoDepthTest);
pglEnable(GL_TEXTURE_2D);
// Draw the original screen
@ -3149,7 +3163,7 @@ EXPORT void HWRAPI(DoScreenWipe)(int wipeStart, int wipeEnd)
pglVertexPointer(3, GL_FLOAT, 0, screenVerts);
pglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
SetBlend(PF_Modulated|PF_Translucent|PF_NoDepthTest);
GL_SetBlend(PF_Modulated|PF_Translucent|PF_NoDepthTest);
// Draw the end screen that fades in
pglActiveTexture(GL_TEXTURE0);
@ -3180,7 +3194,7 @@ EXPORT void HWRAPI(DoScreenWipe)(int wipeStart, int wipeEnd)
}
// Create a texture from the screen.
EXPORT void HWRAPI(MakeScreenTexture) (int tex)
void GL_MakeScreenTexture(int tex)
{
boolean firstTime = (screenTextures[tex] == 0);
@ -3203,7 +3217,7 @@ EXPORT void HWRAPI(MakeScreenTexture) (int tex)
tex_downloaded = screenTextures[tex];
}
EXPORT void HWRAPI(RenderVhsEffect) (INT16 upbary, INT16 downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize)
void GL_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize)
{
float xfix, yfix;
float fix[8];
@ -3219,22 +3233,30 @@ EXPORT void HWRAPI(RenderVhsEffect) (INT16 upbary, INT16 downbary, UINT8 updisto
1.0f, -1.0f, 1.0f
};
xfix = 1/((float)(texsize)/((float)((screen_width))));
yfix = 1/((float)(texsize)/((float)((screen_height))));
const GLfloat scrwf = (float)screen_width;
const GLfloat scrwh = (float)screen_height;
xfix = 1/((float)(texsize)/((float)((scrwf))));
yfix = 1/((float)(texsize)/((float)((scrwh))));
GL_SetBlend(PF_Modulated|PF_Translucent|PF_NoDepthTest);
// Slight fuzziness
MakeScreenTexture(HWD_SCREENTEXTURE_VHS);
SetBlend(PF_Modulated|PF_Translucent|PF_NoDepthTest);
GL_MakeScreenTexture(HWD_SCREENTEXTURE_VHS);
pglBindTexture(GL_TEXTURE_2D, screenTextures[HWD_SCREENTEXTURE_VHS]);
const float stride = 2.f/scrwh;
uint32_t r = rand();
for (i = 0; i < 1; i += stride)
const float ystep = 2.f/scrwh * (float)vid.udup/4.f;
for (i = 0; i < 1; i += ystep)
{
fix[2] = (float)(rand() % 128) / -22000.f * xfix;
// avoid calling rand thousands of times
r ^= r >> 13;
r ^= r >> 11;
r ^= r << 21;
fix[2] = (float)(r & 127) / -22000.f * xfix;
fix[0] = fix[2];
fix[6] = fix[0] + xfix;
fix[4] = fix[2] + xfix;
@ -3252,8 +3274,8 @@ EXPORT void HWRAPI(RenderVhsEffect) (INT16 upbary, INT16 downbary, UINT8 updisto
}
// Upward bar
//GL_MakeScreenTexture(HWD_SCREENTEXTURE_VHS);
//pglBindTexture(GL_TEXTURE_2D, screenTextures[HWD_SCREENTEXTURE_VHS]);
GL_MakeScreenTexture(HWD_SCREENTEXTURE_VHS);
pglBindTexture(GL_TEXTURE_2D, screenTextures[HWD_SCREENTEXTURE_VHS]);
color[0] = color[1] = color[2] = 190;
color[3] = 250;
@ -3276,13 +3298,14 @@ EXPORT void HWRAPI(RenderVhsEffect) (INT16 upbary, INT16 downbary, UINT8 updisto
fix[1] = fix[7] += (fix[3] - fix[7])*2;
screenVerts[1] = screenVerts[10] += (screenVerts[4] - screenVerts[1])*2;
pglTexCoordPointer(2, GL_FLOAT, 0, fix);
pglVertexPointer(3, GL_FLOAT, 0, screenVerts);
pglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
// Downward bar
//GL_MakeScreenTexture(HWD_SCREENTEXTURE_VHS);
//pglBindTexture(GL_TEXTURE_2D, screenTextures[HWD_SCREENTEXTURE_VHS]);
GL_MakeScreenTexture(HWD_SCREENTEXTURE_VHS);
pglBindTexture(GL_TEXTURE_2D, screenTextures[HWD_SCREENTEXTURE_VHS]);
fix[0] = 0.0f;
fix[6] = xfix;
@ -3301,12 +3324,13 @@ EXPORT void HWRAPI(RenderVhsEffect) (INT16 upbary, INT16 downbary, UINT8 updisto
fix[1] = fix[7] += (fix[3] - fix[7])*2;
screenVerts[1] = screenVerts[10] += (screenVerts[4] - screenVerts[1])*2;
pglTexCoordPointer(2, GL_FLOAT, 0, fix);
pglVertexPointer(3, GL_FLOAT, 0, screenVerts);
pglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
EXPORT void HWRAPI(DrawScreenFinalTexture)(int tex, int width, int height)
void GL_DrawScreenFinalTexture(int tex, int width, int height)
{
float xfix, yfix;
float origaspect, newaspect;
@ -3360,7 +3384,7 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int tex, int width, int height)
clearColour.red = clearColour.green = clearColour.blue = 0;
clearColour.alpha = 1;
ClearBuffer(true, false, &clearColour);
GL_ClearBuffer(true, false, &clearColour);
pglBindTexture(GL_TEXTURE_2D, screenTextures[tex]);
pglColor4ubv(white);
@ -3372,7 +3396,7 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int tex, int width, int height)
tex_downloaded = screenTextures[tex];
}
EXPORT void HWRAPI(SetPaletteLookup)(UINT8 *lut)
void GL_SetPaletteLookup(UINT8 *lut)
{
GLenum internalFormat;
if (gl_version[0] == '1' || gl_version[0] == '2')
@ -3398,7 +3422,7 @@ EXPORT void HWRAPI(SetPaletteLookup)(UINT8 *lut)
pglActiveTexture(GL_TEXTURE0);
}
EXPORT UINT32 HWRAPI(CreateLightTable)(RGBA_t *hw_lighttable)
UINT32 GL_CreateLightTable(RGBA_t *hw_lighttable)
{
LTListItem *item = malloc(sizeof(LTListItem));
if (!LightTablesTail)
@ -3424,7 +3448,7 @@ EXPORT UINT32 HWRAPI(CreateLightTable)(RGBA_t *hw_lighttable)
}
// Delete light table textures, ids given before become invalid and must not be used.
EXPORT void HWRAPI(ClearLightTables)(void)
void GL_ClearLightTables(void)
{
while (LightTablesHead)
{
@ -3441,7 +3465,7 @@ EXPORT void HWRAPI(ClearLightTables)(void)
}
// This palette is used for the palette rendering postprocessing step.
EXPORT void HWRAPI(SetScreenPalette)(RGBA_t *palette)
void GL_SetScreenPalette(RGBA_t *palette)
{
if (memcmp(screenPalette, palette, sizeof(screenPalette)))
{

View file

@ -23,7 +23,7 @@
#ifdef HAVE_SDL
#define _MATH_DEFINES_DEFINED
#include "SDL_opengl.h" //Alam_GBC: Simple, yes?
#include <SDL3/SDL_opengl.h> //Alam_GBC: Simple, yes?
#else
#include <GL/gl.h>
@ -36,7 +36,8 @@
#define _CREATE_DLL_ // necessary for Unix AND Windows
#include "../../doomdef.h"
#include "../hw_drv.h"
#include "../hw_gpu.h"
#include "../hw_dll.h"
#include "../../z_zone.h"
#ifdef __cplusplus

View file

@ -307,7 +307,7 @@ static ALvoid ALSetPan(ALuint sid, INT32 sep)
* Initialise driver and listener
*
*****************************************************************************/
EXPORT INT32 HWRAPI( Startup ) (I_Error_t FatalErrorFunction, snddev_t *snd_dev)
EXPORT INT32 GL_(I_Error_t FatalErrorFunction, snddev_t *snd_dev)
{
ALenum model = AL_INVERSE_DISTANCE_CLAMPED;
ALCboolean inited = ALC_FALSE;
@ -412,7 +412,7 @@ EXPORT INT32 HWRAPI( Startup ) (I_Error_t FatalErrorFunction, snddev_t *snd_dev)
* Shutdown 3D Sound
*
******************************************************************************/
EXPORT void HWRAPI( Shutdown ) ( void )
EXPORT void GL_( void )
{
ALsizei i;

View file

@ -436,6 +436,7 @@ static void HU_removeChatText_Log(void)
for(i=0;i<chat_nummsg_log-1;i++) {
strcpy(chat_log[i], chat_log[i+1]);
}
chat_nummsg_log--; // lost 1 msg.
}
@ -915,8 +916,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
if ((cv_chatnotifications.value) && (flags & HU_SHOUT))
S_StartSound(NULL, sfx_sysmsg);
if (tempchar)
Z_Free(tempchar);
Z_Free(tempchar);
}
#ifdef _DEBUG
// I just want to point out while I'm here that because the data is still
@ -1155,6 +1155,7 @@ void HU_clearChatChars(void)
chat_on = false;
I_UpdateMouseGrab();
I_SetTextInput(false);
}
//
@ -1200,6 +1201,7 @@ boolean HU_Responder(event_t *ev)
teamtalk = false;
chat_scrollmedown = true;
typelines = 1;
I_SetTextInput(true);
return true;
}
if (G_ControlBoundToKey(0, gc_teamkey, ev->data1, false)
@ -1212,6 +1214,7 @@ boolean HU_Responder(event_t *ev)
teamtalk = G_GametypeHasTeams(); // Don't teamtalk if we don't have teams.
chat_scrollmedown = true;
typelines = 1;
I_SetTextInput(true);
return true;
}
}
@ -1241,6 +1244,7 @@ boolean HU_Responder(event_t *ev)
chat_on = false;
chat_scrollmedown = true; // you hit enter, so you might wanna autoscroll to see what you just sent. :)
I_SetTextInput(false);
I_UpdateMouseGrab();
}
else if (c == KEY_ESCAPE
@ -1249,6 +1253,7 @@ boolean HU_Responder(event_t *ev)
&& c >= NUMKEYS)) // If it's not a keyboard key, then the chat button is used as a toggle.
{
chat_on = false;
I_SetTextInput(false);
I_UpdateMouseGrab();
}
else if ((c == KEY_UPARROW || c == KEY_MOUSEWHEELUP) && chat_scroll > 0 && !OLDCHAT) // CHAT SCROLLING YAYS!
@ -1332,6 +1337,7 @@ static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
x = 0;
}
}
return newstring;
}
@ -1370,7 +1376,7 @@ static void HU_drawMiniChat(void)
emote_t *emote = NULL;
int emotelen = 0;
while(msg[j]) // iterate through msg
while (msg[j]) // iterate through msg
{
if (msg[j] < HU_FONTSTART) // don't draw
{
@ -1402,20 +1408,21 @@ static void HU_drawMiniChat(void)
{
j++;
}
prev_linereturn = false;
dx += charwidth;
if (dx >= boxw)
{
dx = 0;
linescount += 1;
}
}
dy = 0;
dx = 0;
msglines += linescount+1;
if (msg)
Z_Free(msg);
Z_Free(msg);
}
y = chaty - charheight*(msglines+1);
@ -1449,7 +1456,7 @@ static void HU_drawMiniChat(void)
emote_t *emote = NULL;
int emotelen = 0;
while(msg[j]) // iterate through msg
while (msg[j]) // iterate through msg
{
if (msg[j] < HU_FONTSTART) // don't draw
{
@ -1494,17 +1501,17 @@ static void HU_drawMiniChat(void)
dx += charwidth;
prev_linereturn = false;
if (dx >= boxw)
{
dx = 0;
dy += charheight;
}
}
dy += charheight;
dx = 0;
if (msg)
Z_Free(msg);
Z_Free(msg);
}
// decrement addy and make that shit smooth:
@ -1558,7 +1565,7 @@ static void HU_drawChatLog(INT32 offset)
V_DrawFillConsoleMap(chatx, chat_topy, boxw, boxh*charheight +2, 159|V_SNAPTOBOTTOM|V_SNAPTOLEFT); // log box
for (i=0; i<chat_nummsg_log; i++) // iterate through our chatlog
for (i = 0; i < chat_nummsg_log; i++) // iterate through our chatlog
{
INT32 clrflag = 0;
INT32 j = 0;
@ -1567,7 +1574,7 @@ static void HU_drawChatLog(INT32 offset)
emote_t *emote = NULL;
int emotelen = 0;
while(msg[j]) // iterate through msg
while (msg[j]) // iterate through msg
{
if (msg[j] < HU_FONTSTART) // don't draw
{
@ -1612,11 +1619,10 @@ static void HU_drawChatLog(INT32 offset)
dy += charheight;
}
}
dy += charheight;
dx = 0;
if (msg)
Z_Free(msg);
Z_Free(msg);
}
@ -2442,7 +2448,7 @@ static inline void HU_DrawSpectatorTicker(void)
INT32 i;
INT32 length = 0, height = 174;
INT32 totallength = 0, templength = -8;
INT32 dupadjust = (vid.width/vid.dupx), duptweak = (dupadjust - BASEVIDWIDTH)/2;
INT32 dupadjust = vid.scaledwidth, duptweak = (dupadjust - BASEVIDWIDTH)/2;
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].spectator)

125
src/i_gamepad.h Normal file
View file

@ -0,0 +1,125 @@
// BLANKART
//-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2020 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file i_gamepad.h
/// \brief share gamepad information with game control code
#ifndef __I_GAMEPAD_H__
#define __I_GAMEPAD_H__
#include "g_input.h"
#ifdef __cplusplus
extern "C" {
#endif
/*!
\brief -JOYAXISRANGE to +JOYAXISRANGE for each axis
(1024-1) so we can do a right shift instead of division
(doesnt matter anyway, just give enough precision)
a gamepad will return -1, 0, or 1 in the event data
an analog type joystick will return a value
from -JOYAXISRANGE to +JOYAXISRANGE for each axis
*/
#define JOYAXISRANGE 1023
// detect a bug if we increase JOYBUTTONS above DIJOYSTATE's number of buttons
#if (JOYBUTTONS > 64)
"JOYBUTTONS is greater than INT64 bits can hold"
#endif
/** \brief The struct JoyType_s
share some joystick information (maybe 2 for splitscreen), to the game input code,
actually, we need to know if it is a gamepad or analog controls
*/
struct JoyType_t
{
/*! this joystick is a gamepad, read: digital axes
if FALSE, interpret the joystick event data as JOYAXISRANGE (see above) */
INT32 bGamepadStyle;
};
/** \brief Joystick info
for palyer[sic] 1-4's joystick/gamepad
*/
extern JoyType_t Joystick[MAXSPLITSCREENPLAYERS];
/** \brief to set up the first joystick scale
*/
void I_ControllerScale(void);
/** \brief to set up the second joystick scale
*/
void I_ControllerScale2(void);
/** \brief to set up the third joystick scale
*/
void I_ControllerScale3(void);
/** \brief to set up the fourth joystick scale
*/
void I_ControllerScale4(void);
// Called by D_SRB2Main.
/** \brief to startup a joystick
*/
void I_InitController(UINT8 index);
/** \brief to startup the first joystick
*/
void I_InitController1(void);
/** \brief to startup the second joystick
*/
void I_InitController2(void);
/** \brief to startup the third joystick
*/
void I_InitController3(void);
/** \brief to startup the fourth joystick
*/
void I_InitController4(void);
/** \brief return the number of joystick on the system
*/
INT32 I_NumControllers(void);
/** \brief The *I_GetControllerName function
\param joyid which joystick
\return joystick name
*/
const char *I_GetControllerName(INT32 joyid);
INT32 I_GetControllerSlotfromID(INT32 id);
boolean I_ControllerSupportsRumble(INT32 playernum);
boolean I_ControllerSupportsIndicatorMono(INT32 playernum);
boolean I_ControllerSupportsIndicatorColor(INT32 playernum);
boolean I_ControllerSupportsIndicatorPlayer(INT32 playernum);
boolean I_ControllerSupportsSensorAccelerometer(INT32 playernum);
boolean I_ControllerSupportsSensorGyro(INT32 playernum);
void I_ControllerRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, UINT32 duration);
void I_SetControllerIndicatorColor(INT32 playernum, UINT8 red, UINT8 green, UINT8 blue);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // __I_JOY_H__

View file

@ -1,65 +0,0 @@
// BLANKART
//-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2020 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file i_joy.h
/// \brief share joystick information with game control code
#ifndef __I_JOY_H__
#define __I_JOY_H__
#include "g_input.h"
#ifdef __cplusplus
extern "C" {
#endif
/*!
\brief -JOYAXISRANGE to +JOYAXISRANGE for each axis
(1024-1) so we can do a right shift instead of division
(doesnt matter anyway, just give enough precision)
a gamepad will return -1, 0, or 1 in the event data
an analog type joystick will return a value
from -JOYAXISRANGE to +JOYAXISRANGE for each axis
*/
#define JOYAXISRANGE 1023
// detect a bug if we increase JOYBUTTONS above DIJOYSTATE's number of buttons
#if (JOYBUTTONS > 64)
"JOYBUTTONS is greater than INT64 bits can hold"
#endif
/** \brief The struct JoyType_s
share some joystick information (maybe 2 for splitscreen), to the game input code,
actually, we need to know if it is a gamepad or analog controls
*/
struct JoyType_t
{
/*! if true, we MUST Poll() to get new joystick data,
that is: we NEED the DIRECTINPUTDEVICE2 ! (watchout NT compatibility) */
INT32 bJoyNeedPoll;
/*! this joystick is a gamepad, read: digital axes
if FALSE, interpret the joystick event data as JOYAXISRANGE (see above) */
INT32 bGamepadStyle;
};
/** \brief Joystick info
for palyer[sic] 1-4's joystick/gamepad
*/
extern JoyType_t Joystick[MAXSPLITSCREENPLAYERS];
#ifdef __cplusplus
} // extern "C"
#endif
#endif // __I_JOY_H__

View file

@ -118,132 +118,6 @@ ticcmd_t *I_BaseTiccmd4(void);
*/
void I_Quit(void) FUNCNORETURN;
typedef enum
{
EvilForce = -1,
//Constant
ConstantForce = 0,
//Ramp
RampForce,
//Periodics
SquareForce,
SineForce,
TriangleForce,
SawtoothUpForce,
SawtoothDownForce,
//MAX
NumberofForces,
} FFType;
struct JoyFF_t
{
INT32 ForceX; ///< The X of the Force's Vel
INT32 ForceY; ///< The Y of the Force's Vel
//All
UINT32 Duration; ///< The total duration of the effect, in microseconds
INT32 Gain; //< /The gain to be applied to the effect, in the range from 0 through 10,000.
//All, CONSTANTFORCE -10,000 to 10,000
INT32 Magnitude; ///< Magnitude of the effect, in the range from 0 through 10,000.
//RAMPFORCE
INT32 Start; ///< Magnitude at the start of the effect, in the range from -10,000 through 10,000.
INT32 End; ///< Magnitude at the end of the effect, in the range from -10,000 through 10,000.
//PERIODIC
INT32 Offset; ///< Offset of the effect.
UINT32 Phase; ///< Position in the cycle of the periodic effect at which playback begins, in the range from 0 through 35,999
UINT32 Period; ///< Period of the effect, in microseconds.
};
/** \brief Forcefeedback for the first joystick
\param Type what kind of Effect
\param Effect Effect Info
\return void
*/
void I_Tactile(FFType Type, const JoyFF_t *Effect);
/** \brief Forcefeedback for the second joystick
\param Type what kind of Effect
\param Effect Effect Info
\return void
*/
void I_Tactile2(FFType Type, const JoyFF_t *Effect);
/** \brief Forcefeedback for the third joystick
\param Type what kind of Effect
\param Effect Effect Info
\return void
*/
void I_Tactile3(FFType Type, const JoyFF_t *Effect);
/** \brief Forcefeedback for the fourth joystick
\param Type what kind of Effect
\param Effect Effect Info
\return void
*/
void I_Tactile4(FFType Type, const JoyFF_t *Effect);
/** \brief to set up the first joystick scale
*/
void I_JoyScale(void);
/** \brief to set up the second joystick scale
*/
void I_JoyScale2(void);
/** \brief to set up the third joystick scale
*/
void I_JoyScale3(void);
/** \brief to set up the fourth joystick scale
*/
void I_JoyScale4(void);
// Called by D_SRB2Main.
/** \brief to startup a joystick
*/
void I_InitJoystick(UINT8 index);
/** \brief to startup the first joystick
*/
void I_InitJoystick1(void);
/** \brief to startup the second joystick
*/
void I_InitJoystick2(void);
/** \brief to startup the third joystick
*/
void I_InitJoystick3(void);
/** \brief to startup the fourth joystick
*/
void I_InitJoystick4(void);
/** \brief return the number of joystick on the system
*/
INT32 I_NumJoys(void);
extern INT32 numcontrollers;
/** \brief The *I_GetJoyName function
\param joyindex which joystick
\return joystick name
*/
const char *I_GetJoyName(INT32 joyindex);
void I_GamepadRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, UINT32 duration);
void I_SetGamepadIndicatorColor(INT32 playernum, UINT8 red, UINT8 green, UINT8 blue);
#ifndef NOMUMBLE
#include "p_mobj.h" // mobj_t
#include "s_sound.h" // listener_t
@ -320,7 +194,7 @@ const char *I_LocateWad(void);
*/
void I_GetJoystickEvents(UINT8 index);
INT32 I_GetJoystickDeviceIndexForPlayer(UINT8 pnum);
INT32 I_GetControllerIDForPlayer(UINT8 pnum);
/** \brief Checks if the mouse needs to be grabbed
*/

View file

@ -118,14 +118,10 @@ typedef union
} mysockaddr_t;
#ifdef HAVE_MINIUPNPC
#ifdef STATIC_MINIUPNPC
#define STATICLIB
#endif
#include "miniupnpc/miniwget.h"
#include "miniupnpc/miniupnpc.h"
#include "miniupnpc/upnpcommands.h"
#undef STATICLIB
static UINT8 UPNP_support = TRUE;
static UINT8 UPNP_support = true;
#endif // HAVE_MINIUPNC
#include "i_system.h"
@ -137,6 +133,7 @@ typedef union
#include "m_argv.h"
#include "stun.h"
#include "z_zone.h"
#include "i_threads.h"
#include "doomstat.h"
@ -279,21 +276,48 @@ static const char* inet_ntopA(short af, const void *cp, char *buf, socklen_t len
#endif
#ifdef HAVE_MINIUPNPC // based on old XChat patch
static void I_ShutdownUPnP(void);
static void I_InitUPnP(void);
static I_mutex upnp_mutex;
static struct UPNPUrls urls;
static struct IGDdatas data;
static char lanaddr[64];
static void I_ShutdownUPnP(void)
struct upnpdata
{
FreeUPNPUrls(&urls);
int upnpc_started;
};
static struct upnpdata *upnpuser;
static void init_upnpc_once(struct upnpdata *upnpdata);
static void I_InitUPnP(void)
{
upnpuser = malloc(sizeof *upnpuser);
upnpuser->upnpc_started = 0;
I_spawn_thread("init_upnpc_once", (I_thread_fn)init_upnpc_once, upnpuser);
}
static inline void I_InitUPnP(void)
static void
init_upnpc_once(struct upnpdata *upnpuserdata)
{
if (upnpuserdata->upnpc_started != 0)
return;
I_lock_mutex(&upnp_mutex);
const char * const deviceTypes[] = {
"urn:schemas-upnp-org:device:InternetGatewayDevice:2",
"urn:schemas-upnp-org:device:InternetGatewayDevice:1",
0
};
struct UPNPDev * devlist = NULL;
int upnp_error = -2;
CONS_Printf(M_GetText("Looking for UPnP Internet Gateway Device\n"));
devlist = upnpDiscover(2000, NULL, NULL, 0, false, &upnp_error);
int scope_id = 0;
int status_code = 0;
memset(&urls, 0, sizeof(struct UPNPUrls));
memset(&data, 0, sizeof(struct IGDdatas));
I_OutputMsg(M_GetText("Looking for UPnP Internet Gateway Device\n"));
devlist = upnpDiscoverDevices(deviceTypes, 500, NULL, NULL, 0, false, 2, &upnp_error, 0);
if (devlist)
{
struct UPNPDev *dev = devlist;
@ -308,12 +332,16 @@ static inline void I_InitUPnP(void)
if (!dev)
dev = devlist; /* defaulting to first device */
CONS_Printf(M_GetText("Found UPnP device:\n desc: %s\n st: %s\n"),
I_OutputMsg(M_GetText("Found UPnP device:\n desc: %s\n st: %s\n"),
dev->descURL, dev->st);
#if (MINIUPNPC_API_VERSION >= 18)
UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr), NULL, 0);
#else
UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
CONS_Printf(M_GetText("Local LAN IP address: %s\n"), lanaddr);
descXML = miniwget(dev->descURL, &descXMLsize);
#endif
I_OutputMsg(M_GetText("Local LAN IP address: %s\n"), lanaddr);
descXML = miniwget(dev->descURL, &descXMLsize, scope_id, &status_code);
if (descXML)
{
parserootdesc(descXML, descXMLsize, &data);
@ -321,33 +349,47 @@ static inline void I_InitUPnP(void)
descXML = NULL;
memset(&urls, 0, sizeof(struct UPNPUrls));
memset(&data, 0, sizeof(struct IGDdatas));
GetUPNPUrls(&urls, &data, dev->descURL);
GetUPNPUrls(&urls, &data, dev->descURL, status_code);
I_AddExitFunc(I_ShutdownUPnP);
}
freeUPNPDevlist(devlist);
}
else if (upnp_error == UPNPDISCOVER_SOCKET_ERROR)
{
CONS_Printf(M_GetText("No UPnP devices discovered\n"));
I_OutputMsg(M_GetText("No UPnP devices discovered\n"));
}
I_unlock_mutex(upnp_mutex);
upnpuserdata->upnpc_started =1;
}
static inline void I_UPnP_add(const char * addr, const char *port, const char * servicetype)
{
if (addr == NULL)
addr = lanaddr;
if (!urls.controlURL || urls.controlURL[0] == '\0')
return;
I_lock_mutex(&upnp_mutex);
if (addr == NULL)
addr = lanaddr;
UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
port, port, addr, "SRB2", servicetype, NULL, NULL);
I_unlock_mutex(upnp_mutex);
}
static inline void I_UPnP_rem(const char *port, const char * servicetype)
{
if (!urls.controlURL || urls.controlURL[0] == '\0')
return;
I_lock_mutex(&upnp_mutex);
UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype,
port, servicetype, NULL);
I_unlock_mutex(upnp_mutex);
}
static void I_ShutdownUPnP(void)
{
I_UPnP_rem(serverport_name, "UDP");
I_lock_mutex(&upnp_mutex);
FreeUPNPUrls(&urls);
I_unlock_mutex(upnp_mutex);
}
#endif
@ -1298,10 +1340,10 @@ boolean I_InitTcpDriver(void)
{
I_AddExitFunc(I_ShutdownTcpDriver);
#ifdef HAVE_MINIUPNPC
if (M_CheckParm("-useUPnP"))
I_InitUPnP();
else
if (M_CheckParm("-noUPnP"))
UPNP_support = false;
else
I_InitUPnP();
#endif
}
return init_tcp_driver;
@ -1550,11 +1592,8 @@ static boolean SOCK_SetBanUsername(const char *username)
username = "Direct IP ban";
}
if (banned[numbans - 1].username)
{
Z_Free(banned[numbans - 1].username);
banned[numbans - 1].username = NULL;
}
Z_Free(banned[numbans - 1].username);
banned[numbans - 1].username = NULL;
banned[numbans - 1].username = Z_StrDup(username);
return true;
@ -1567,11 +1606,8 @@ static boolean SOCK_SetBanReason(const char *reason)
reason = "No reason given";
}
if (banned[numbans - 1].reason)
{
Z_Free(banned[numbans - 1].reason);
banned[numbans - 1].reason = NULL;
}
Z_Free(banned[numbans - 1].reason);
banned[numbans - 1].reason = NULL;
banned[numbans - 1].reason = Z_StrDup(reason);
return true;

View file

@ -20,6 +20,9 @@
extern "C" {
#endif
boolean I_UseNativeKeyboard(void);
void I_SetTextInput(boolean enable);
typedef enum
{
/// Software
@ -153,8 +156,6 @@ void I_EndRead(void);
UINT32 I_GetRefreshRate(void);
boolean I_UseNativeKeyboard(void);
extern consvar_t cv_keyboardlayout;
void I_SetBorderlessWindow(void);

View file

@ -19,3 +19,4 @@ _(SUPERRING)
_(LANDMINE)
_(BUBBLESHIELD)
_(FLAMESHIELD)
_(EGGBRICK)

View file

@ -29,6 +29,7 @@ _(OP_JOYSTICKSET)
_(OP_VIDEO)
_(OP_VIDEOMODE)
_(OP_VISUAL)
_(OP_VIDCOLORPROFILE)
_(OP_OPENGL)
_(OP_SOUND)

View file

@ -874,3 +874,6 @@ _(RAINBOWDASHRING)
// Sneaker Panels
_(SNEAKERPANEL)
_(SNEAKERPANELSPAWNER)
// Horncode
_(FOLLOWERHORN)

View file

@ -1017,3 +1017,14 @@ _(sysmsg)
// Dash Rings
_(dashr)
_(rainbr)
// Horncode
_(horn00)
// Fastfall bounce
_(vclgna)
// Items
// Egg mine
_(bckuse)
_(egrbhe)

View file

@ -653,5 +653,11 @@ _(SSWG)
// Arrow Bullet
_(AWBT)
// Recovery Spin Skid
_(RCSP)
// Horncode
_(FHRN)
// First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later
_(VIEW)

View file

@ -3621,3 +3621,10 @@ _(GHORIZ4)
// Arrow Bullet
_(ALTSHRINK_ARROWBULLET)
// Recovery Spin Skid
_(RECSPIN_SKID)
// Horncode
_(HORNCODE)
_(HORNCODE_ANGRY)
_(HORNCODE_HAPPY)

View file

@ -493,6 +493,12 @@ void K_BattleInit(boolean singleplayercontext)
{
if (!(K_CanChangeRules(true) && !cv_kartitembreaker.value))
itembreaker = true;
for (int i = 0; i < MAXPLAYERS; i++)
{
if (players[i].bot == true)
P_SetPlayerSpectator(i);
}
}
if (gametyperules & GTR_BUMPERS)

View file

@ -43,6 +43,7 @@
#include "i_net.h" // doomcom
#include "blan/b_soc.h"
#include "v_video.h" // for debugging
#include "k_battle.h" // item breaker
#include "k_waypoint.h"
#include "k_items.h"
@ -175,7 +176,7 @@ void K_SetBot(UINT8 newplayernum, UINT16 skinnum, UINT8 difficulty, botStyle_e s
// The bot may immediately become a spectator AT THE START of a GP.
// For each subsequent round of GP, K_UpdateGrandPrixBots will handle this.
players[newplayernum].spectator = grandprixinfo.gp && grandprixinfo.initalize;
players[newplayernum].spectator = grandprixinfo.gp && grandprixinfo.initalize && K_BotDefaultSpectator();
skincolornum_t color = static_cast<skincolornum_t>(skins[skinnum].prefcolor);
const char *realname = skins[skinnum].realname;
@ -266,6 +267,10 @@ void K_UpdateMatchRaceBots(void)
{
difficulty = 0;
}
else if (itembreaker && !cv_forcebots.value)
{
difficulty = 0;
}
else if (K_CanChangeRules(true) == false)
{
difficulty = 0;
@ -1342,7 +1347,7 @@ static INT32 K_HandleBotTrack(botdata_t *bd, const player_t *player, angle_t des
bd->brakedown = false;
// Additional grip for turns.
if ((player->speed > K_GetKartSpeed(player, false, false)/2) && !bd->griplockout)//35*FRACUNIT
if (player->mo && P_IsObjectOnGround(player->mo) && (player->speed > K_GetKartSpeed(player, false, false)/2) && !bd->griplockout)//35*FRACUNIT
{
const angle_t MAXERROR = ANGLE_45;
const angle_t MIDERROR = ANGLE_22h;

View file

@ -16,6 +16,7 @@
#include "doomdef.h"
#include "doomtype.h"
#include "r_textures.h"
#include "m_misc.h"
#include "w_wad.h"
#include "z_zone.h"
@ -62,7 +63,7 @@ static brightmapStorage_t *K_GetBrightmapStorageByIndex(size_t checkIndex)
--------------------------------------------------*/
static brightmapStorage_t *K_GetBrightmapStorageByTextureName(const char *checkName)
{
UINT32 checkHash = quickncasehash(checkName, 8);
UINT32 checkHash = FNV1a_QuickCaseHash(checkName, 8);
size_t i;
if (maxBrightmapStorage == 0)
@ -119,7 +120,7 @@ static boolean K_BRIGHTLumpParser(char *data, size_t size)
{
bms = K_NewBrightmap();
strncpy(bms->textureName, tkn, 8);
bms->textureHash = quickncasehash(tkn, 8);
bms->textureHash = FNV1a_QuickCaseHash(tkn, 8);
}
Z_Free(tkn);
@ -129,7 +130,7 @@ static boolean K_BRIGHTLumpParser(char *data, size_t size)
if (tkn && pos <= size)
{
strncpy(bms->brightmapName, tkn, 8);
bms->brightmapHash = quickncasehash(tkn, 8);
bms->brightmapHash = FNV1a_QuickCaseHash(tkn, 8);
}
else
{

View file

@ -99,6 +99,10 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
// Melt item
S_StartSound(t2, sfx_s3k43);
damageitem = true;
// and cut temperature and fuel by 10% of max
t2->player->flamestore -= min(FLAMESTOREMAX/10, t2->player->flamestore);
t2->player->flametimer -= min((itemtime*3)/10, t2->player->flametimer - 1);
t2->player->flameburnstop = TICRATE/4;
}
else
{
@ -188,6 +192,10 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2)
{
// Melt item
S_StartSound(t2, sfx_s3k43);
// and cut temperature and fuel by 10% of max
t2->player->flamestore -= min(FLAMESTOREMAX/10, t2->player->flamestore);
t2->player->flametimer -= min((itemtime*3)/10, t2->player->flametimer - 1);
t2->player->flameburnstop = TICRATE/4;
}
else
{
@ -261,6 +269,10 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2)
// Melt item
S_StartSound(t2, sfx_s3k43);
P_KillMobj(t1, t2, t2, DMG_NORMAL);
// and cut temperature and fuel by 10% of max
t2->player->flamestore -= min(FLAMESTOREMAX/10, t2->player->flamestore);
t2->player->flametimer -= min((itemtime*3)/10, t2->player->flametimer - 1);
t2->player->flameburnstop = TICRATE/4;
return true;
}
else
@ -306,9 +318,9 @@ void K_EggMineBounce(mobj_t *t1, mobj_t *t2)
fixed_t localspacey = t1->y - pointy;
angle_t impulseangle = R_PointToAngle2(0, 0, (localspacex + t2->momx)/2, (localspacey + t2->momy)/2);
P_InstaThrust(t1, impulseangle, impulse);
zimpulse = (P_MobjFlip(t1) * min((P_AproxDistance(t2->momx, t2->momy) + P_AproxDistance(t1->momx, t1->momy)), 28*mapobjectscale)) + t2->momz/2;
zimpulse = (P_MobjFlip(t1) * min((P_AproxDistance(t2->momx, t2->momy) + P_AproxDistance(t1->momx, t1->momy)), 32*mapobjectscale)) + t2->momz/2;
if (t2->type == MT_EGGMINE)
if (t2->type != MT_PLAYER)
{
fixed_t zdiff = (t1->z + (t1->height*P_MobjFlip(t1)/2)) - (t2->z + (t2->height*P_MobjFlip(t2))/2);
zimpulse /= 2;
@ -318,12 +330,11 @@ void K_EggMineBounce(mobj_t *t1, mobj_t *t2)
}
}
// doesn't this look familiar
t1->z += 1;
t1->momz = zimpulse;
t1->z += t1->momz;
if (t1->extravalue1 == 0)
{
K_SpawnEggMineBumpEffect(t1);
t1->extravalue1 = 6;
}
@ -331,6 +342,7 @@ void K_EggMineBounce(mobj_t *t1, mobj_t *t2)
boolean K_EggMineCollide(mobj_t *t1, mobj_t *t2)
{
boolean damageitem = false;
boolean sprung = false;
if (t1->health <= 0 || t2->health <= 0)
@ -342,29 +354,34 @@ boolean K_EggMineCollide(mobj_t *t1, mobj_t *t2)
{
return true;
}
if (t2->player && t2->player->hyudorotimer)
{
return true; // no interaction
}
if (t2->player && t2->player->flamestore && (K_GetShieldFromPlayer(t2->player) == KSHIELD_FLAME))
{
// Melt item
S_StartSound(t2, sfx_s3k43);
// and cut temperature and fuel by 10% of max
t2->player->flamestore -= min(FLAMESTOREMAX/10, t2->player->flamestore);
t2->player->flametimer -= min((itemtime*3)/10, t2->player->flametimer - 1);
t2->player->flameburnstop = TICRATE/4;
return true;
}
if (t2->type == MT_PLAYER && t1->health > 1)
else if (t2->type == MT_PLAYER && t1->health > 1)
{
if (t1->health > 2)
if (t1->health > 2 && (P_DamageMobj(t2, t1, t1->target, 1, DMG_FLIPOVER)))
{
K_DoEggMineStrip(t2, t1, t1->target);
S_StartSound(t2, sfx_bsnipe);
P_DamageMobj(t2, t1, t1->target, 1, DMG_FLIPOVER);
P_RemoveMobj(t1);
return true;
}
else if (P_IsObjectOnGround(t2))
{
S_StartSound(t2, sfx_cdfm37);
// should think of something else for this specific interaction if people want something to happen
// t2->momz = 3*t1->scale*P_MobjFlip(t2);
K_SpawnEggMineBumpEffect(t1);
t1->extravalue1 = 6;
return true;
@ -377,20 +394,37 @@ boolean K_EggMineCollide(mobj_t *t1, mobj_t *t2)
// Let thrown items hit springs!
sprung = P_DoSpring(t2, t1);
}
else if (K_IsMissileOrKartItem(t2))
else if (t2->type == MT_SSMINE_SHIELD || t2->type == MT_SSMINE || t2->type == MT_LANDMINE)
{
if (t1->health > 1)
{
t1->z += 1;
t1->momz += 12*mapobjectscale;
t1->momx /= 2;
t1->momy /= 2;
}
damageitem = true;
// Bomb death
P_KillMobj(t2, t1, t1->target, DMG_NORMAL);
}
else if (P_IsKartItem(t2->type))
{
// eggmines don't kill eachother
if (!(t2->type == MT_SPB || t2->type == MT_EGGMINE || t2->type == MT_EGGMINE_SHIELD))
{
P_KillMobj(t2, t1, t1->target, DMG_INSTAKILL);
K_ItemDamage(t2, t1, true);
if (!(t2->type == MT_SPB)) damageitem = true;
}
P_KillMobj(t1, t2, t2->target, DMG_INSTAKILL);
}
if (sprung)
{
return false;
}
if (damageitem && t1->health <= 1)
P_KillMobj(t1, t2, t2->target, DMG_INSTAKILL);
return true;
}
@ -398,6 +432,9 @@ boolean K_EggMineShieldCollide(mobj_t *t1, mobj_t *t2)
{
if (t1->health <= 0 || t2->health <= 0)
return true;
if (t2->type == MT_SPB)
return true;
if (K_IsMissileOrKartItem(t2))
{
@ -405,8 +442,8 @@ boolean K_EggMineShieldCollide(mobj_t *t1, mobj_t *t2)
if (!(t2->type == MT_SPB || t2->type == MT_EGGMINE || t2->type == MT_EGGMINE_SHIELD))
{
P_KillMobj(t2, t1, t1->target, DMG_INSTAKILL);
if (!(t2->type == MT_SPB)) P_KillMobj(t1, t2, t2->target, DMG_INSTAKILL);
}
P_KillMobj(t1, t2, t2->target, DMG_INSTAKILL);
return true;
}
@ -510,13 +547,19 @@ boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2)
{
// Melt item
S_StartSound(t2, sfx_s3k43);
// and cut temperature and fuel by 10% of max
t2->player->flamestore -= min(FLAMESTOREMAX/10, t2->player->flamestore);
t2->player->flametimer -= min((itemtime*3)/10, t2->player->flametimer - 1);
t2->player->flameburnstop = TICRATE/4;
}
else
{
// these can only come from eggmines now
K_DoEggMineStrip(t2, t1, t1->target);
// Player Damage
P_DamageMobj(t2, t1, t1->target, 1, DMG_FLIPOVER);
if (P_DamageMobj(t2, t1, t1->target, 1, DMG_FLIPOVER))
{
// these can only come from eggmines now
K_DoEggMineStrip(t2, t1, t1->target);
}
}
P_SpawnMobj(t1->x, t1->y, t1->z, MT_MINEEXPLOSIONSOUND);
@ -672,6 +715,10 @@ static void K_BubbleShieldCollideDrain(player_t *player, mobj_t *bubble, INT16 d
static boolean K_BubbleReflectingTrapItem(const mobj_t *t)
{
// slow orbis are traps
if ((t->type == MT_ORBINAUT) && (FixedHypot(t->momx, t->momy) < 24*mapobjectscale))
return true;
return t->type == MT_BANANA || (t->type == MT_ORBINAUT && t->flags2 & MF2_AMBUSH) || t->type == MT_JAWZ_DUD ||
t->type == MT_EGGMANITEM || t->type == MT_SSMINE || t->type == MT_SSMINE_SHIELD || t->type == MT_LANDMINE ||
t->type == MT_EGGMINE;
@ -679,7 +726,7 @@ static boolean K_BubbleReflectingTrapItem(const mobj_t *t)
static boolean K_StrongPlayerBump(const player_t *player)
{
return (((!K_IsKartItemAlternate(KITEM_INVINCIBILITY)) && (player->invincibilitytimer))
return ((player->invincibilitytimer)
|| (player->growshrinktimer > 0));
}
@ -711,7 +758,7 @@ boolean K_BubbleShieldReflect(mobj_t *t1, mobj_t *t2)
t2->angle = angle;
}
if (K_BubbleReflectingTrapItem(t2))
if (K_BubbleReflectingTrapItem(t2) && (t2->momz * P_MobjFlip(t2) <= 8*t2->scale))
{
// Stupid hack: Toss trap/dud items into the air
t2->momz += (24*t2->scale) * P_MobjFlip(t2);
@ -723,10 +770,7 @@ boolean K_BubbleShieldReflect(mobj_t *t1, mobj_t *t2)
if (t2->type == MT_JAWZ)
P_SetTarget(&t2->tracer, t2->target); // Back to the source!
P_SetTarget(&t2->target, owner); // Let the source reflect it back again!
if ((t2->type == MT_ORBINAUT && t2->flags2 & MF2_AMBUSH) || t2->type == MT_JAWZ_DUD)
t2->flags |= MF_NOCLIPTHING;
else
t2->threshold = 10;
t2->threshold = 10;
}
S_StartSound(t1, sfx_s3k44);
@ -750,8 +794,7 @@ static INT16 K_GetBubbleDamage(mobj_t* itm)
}
INT16 dmg = BUBBLEITMDAMAGE;
fixed_t momentum_epsilon =
FixedMul(FixedMul(itm->radius, itm->scale), K_GetKartGameSpeedScalar(gamespeed));
fixed_t momentum_epsilon = 32*mapobjectscale;
switch (itm->type)
{
@ -775,7 +818,7 @@ static INT16 K_GetBubbleDamage(mobj_t* itm)
/*FALLTHRU*/
case MT_ORBINAUT:
{
fixed_t momentum = K_Momentum3D(itm);
fixed_t momentum = K_Momentum2D(itm);
// Reward players on the offensive by letting fast Orbinauts shatter Bubble Shields.
// Same thing for Banana snipes.
@ -918,16 +961,17 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
if (P_MobjWasRemoved(t1) || P_MobjWasRemoved(t2) || !t1->player || !t2->player)
return false;
const boolean flameT1 = ((t1->player->flamestore > 0) && (t1->player->flametimer > 0));
const boolean flameT2 = ((t2->player->flamestore > 0) && (t2->player->flametimer > 0));
const boolean flameT1 = ((t1->player->flamestore >= FLAMESTOREMAX-1) && (t1->player->flametimer > 0));
const boolean flameT2 = ((t2->player->flamestore >= FLAMESTOREMAX-1) && (t2->player->flametimer > 0));
const boolean hyudoroT1 = (t1->player->hyudorotimer > 0);
const boolean hyudoroT2 = (t2->player->hyudorotimer > 0);
boolean t1Condition = false;
boolean t2Condition = false;
// Rim suggestion: Flipover damage is negligible at best, just cull it from Invincibility as a whole.
if (!K_IsKartItemAlternate(KITEM_INVINCIBILITY))
UINT8 invindamage = INVINDAMAGE;
if (invindamage)
{
t1Condition = (t1->player->invincibilitytimer > 0);
t2Condition = (t2->player->invincibilitytimer > 0);
@ -939,16 +983,16 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
K_DoInstashield(t2->player);
return false;
}
else if (!K_IsKartItemAlternate(KITEM_INVINCIBILITY))
else
{
if (t1Condition == true && t2Condition == false)
{
P_DamageMobj(t2, t1, t1, 1, DMG_WIPEOUT);
P_DamageMobj(t2, t1, t1, 1, invindamage);
return true;
}
else if (t1Condition == false && t2Condition == true)
{
P_DamageMobj(t1, t2, t2, 1, DMG_WIPEOUT);
P_DamageMobj(t1, t2, t2, 1, invindamage);
return true;
}
}

View file

@ -17,7 +17,7 @@
#include "r_things.h"
#include "v_video.h"
UINT16 altinvinccolors[16] = {
UINT16 smonitorcolors[16] = {
SKINCOLOR_BLOODCELL, // 0
SKINCOLOR_FUCHSIA, // 1
SKINCOLOR_MOON, // 2
@ -69,14 +69,14 @@ UINT16 K_RainbowColor(tic_t time)
}
/*--------------------------------------------------
UINT16 K_AltInvincibilityColor(tic_t time)
UINT16 K_SMonitorColor(tic_t time)
See header file for description.
--------------------------------------------------*/
UINT16 K_AltInvincibilityColor(tic_t time)
UINT16 K_SMonitorColor(tic_t time)
{
return (UINT16)(altinvinccolors[(time) & 15]);
return (UINT16)(smonitorcolors[(time) & 15]);
}
/*--------------------------------------------------

View file

@ -55,9 +55,9 @@ UINT8 K_ColorRelativeLuminance(UINT8 r, UINT8 g, UINT8 b);
UINT16 K_RainbowColor(tic_t time);
/*--------------------------------------------------
UINT16 K_AltInvincibilityColor(tic_t time)
UINT16 K_SMonitorColor(tic_t time)
Gives you a color from the "alt Invincibility" color table, for less
Gives you a color from the S-Monitor color table, for less
aggressive rainbow coloring.
Input Arguments:-
@ -67,7 +67,7 @@ UINT16 K_RainbowColor(tic_t time);
Skincolor value.
--------------------------------------------------*/
UINT16 K_AltInvincibilityColor(tic_t time);
UINT16 K_SMonitorColor(tic_t time);
/*--------------------------------------------------
void K_RainbowColormap(UINT8 *dest_colormap, skincolornum_t skincolor);

View file

@ -11,6 +11,8 @@
#include "r_skins.h"
#include "p_local.h"
#include "p_mobj.h"
#include "s_sound.h"
#include "m_cond.h"
INT32 numfollowers = 0;
follower_t followers[MAXSKINS];
@ -243,6 +245,32 @@ static void K_UpdateFollowerState(mobj_t *f, statenum_t state, followerstate_t t
}
}
/*--------------------------------------------------
static void K_UpdateFollowerMood(mobj_t *f, followermood_t mood, tic_t time)
Sets a follower object's mood and time before returning to a normal mood.
Input Arguments:-
f - The follower's mobj_t.
mood - The mood to set.
time - The mood's duration.
Return:-
None
--------------------------------------------------*/
static void K_UpdateFollowerMood(mobj_t *f, followermood_t mood, tic_t time)
{
if (f == NULL || P_MobjWasRemoved(f) == true)
{
// safety net
return;
}
f->extravalue3 = mood;
f->cvmem = (INT32)(time);
}
/*--------------------------------------------------
void K_HandleFollower(player_t *player)
@ -565,12 +593,27 @@ void K_HandleFollower(player_t *player)
// However with how the code is factored, this is just a special case of S_INVISBLE to avoid having to add other player variables.
// Mood system
// For now, all this does is change the VFX generated when you honk your horn.
if (player->follower->cvmem && (player->follower->extravalue3 != FOLLOWERMOOD_NORMAL))
{
// Tick down the mood timer
player->follower->cvmem--;
// Return to our normal mood
if (player->follower->cvmem == 0)
{
player->follower->extravalue3 = FOLLOWERMOOD_NORMAL;
}
}
// handle follower animations. Could probably be better...
// hurt or dead
if (P_PlayerInPain(player) == true || player->mo->state == &states[S_KART_SPINOUT] || player->mo->health <= 0)
{
// cancel hit confirm.
// cancel hit confirm / horn
player->follower->movecount = 0;
player->follower->reactiontime = 0;
// spin out
player->follower->angle = player->drawangle;
@ -582,6 +625,11 @@ void K_HandleFollower(player_t *player)
// if dead, follow the player's z momentum exactly so they both look like they die at the same speed.
player->follower->momz = player->mo->momz;
}
else
{
// Not dead; get mad on the player's behalf.
K_UpdateFollowerMood(player->follower, FOLLOWERMOOD_ANGRY, (3 * TICRATE / 2));
}
}
else if (player->exiting)
{
@ -600,8 +648,14 @@ void K_HandleFollower(player_t *player)
else if (player->follower->movecount)
{
K_UpdateFollowerState(player->follower, fl.hitconfirmstate, FOLLOWERSTATE_HITCONFIRM);
K_UpdateFollowerMood(player->follower, FOLLOWERMOOD_HAPPY, (3 * TICRATE / 2));
player->follower->movecount--;
}
else if (player->follower->reactiontime)
{
K_UpdateFollowerState(player->follower, fl.hornstate, FOLLOWERSTATE_HORN);
player->follower->reactiontime--;
}
else if (player->speed > 10*player->mo->scale) // animation for moving fast enough
{
K_UpdateFollowerState(player->follower, fl.followstate, FOLLOWERSTATE_FOLLOW);
@ -610,5 +664,135 @@ void K_HandleFollower(player_t *player)
{
K_UpdateFollowerState(player->follower, fl.idlestate, FOLLOWERSTATE_IDLE);
}
// Horncode
if (P_MobjWasRemoved(player->follower->hprev) == false)
{
mobj_t *honk = player->follower->hprev;
honk->flags2 &= ~MF2_AMBUSH;
honk->color = player->skincolor;
P_MoveOrigin(
honk,
player->follower->x,
player->follower->y,
player->follower->z + player->follower->height
);
K_FlipFromObject(honk, player->follower);
honk->angle = R_PointToAngle2(
player->mo->x,
player->mo->y,
player->follower->x,
player->follower->y
);
honk->destscale = (2*player->mo->scale)/3;
fixed_t offsetamount = 0;
if (honk->fuse > 1)
{
offsetamount = (honk->fuse-1)*honk->destscale/2;
if (leveltime & 1)
offsetamount = -offsetamount;
}
else if (S_SoundPlaying(honk, fl.hornsound))
{
honk->fuse++;
}
honk->sprxoff = P_ReturnThrustX(honk, honk->angle, offsetamount);
honk->spryoff = P_ReturnThrustY(honk, honk->angle, offsetamount);
honk->sprzoff = -honk->sprxoff;
}
}
}
/*--------------------------------------------------
void K_FollowerHornTaunt(player_t *taunter, player_t *victim)
See header file for description.
--------------------------------------------------*/
void K_FollowerHornTaunt(player_t *taunter, player_t *victim)
{
if (
(cv_karthorns.value == 0)
|| taunter == NULL
|| victim == NULL
|| taunter->followerskin < 0
|| taunter->followerskin >= numfollowers
|| (P_IsLocalPlayer(victim) == false && cv_karthorns.value != 2)
|| P_MobjWasRemoved(taunter->mo) == true
|| P_MobjWasRemoved(taunter->follower) == true
)
return;
const follower_t *fl = &followers[taunter->followerskin];
const boolean tasteful = (taunter->karthud[khud_taunthorns] == 0);
if (tasteful || cv_karthorns.value == 2)
{
mobj_t *honk = taunter->follower->hprev;
const fixed_t desiredscale = (2*taunter->mo->scale)/3;
if (P_MobjWasRemoved(honk) == true)
{
honk = P_SpawnMobj(
taunter->follower->x,
taunter->follower->y,
taunter->follower->z + taunter->follower->height,
MT_FOLLOWERHORN
);
if (P_MobjWasRemoved(honk) == true)
return; // Permit lua override of horn production
// Set the horn icon based on the follower's mood.
switch (taunter->follower->extravalue3)
{
case FOLLOWERMOOD_ANGRY:
P_SetMobjState(honk, S_HORNCODE_ANGRY);
break;
case FOLLOWERMOOD_HAPPY:
P_SetMobjState(honk, S_HORNCODE_HAPPY);
default:
break;
}
P_SetTarget(&taunter->follower->hprev, honk);
P_SetTarget(&honk->target, taunter->follower);
K_FlipFromObject(honk, taunter->follower);
honk->color = taunter->skincolor;
honk->angle = honk->old_angle = R_PointToAngle2(
taunter->mo->x,
taunter->mo->y,
taunter->follower->x,
taunter->follower->y
);
}
// Only do for the first activation this tic.
if (!(honk->flags2 & MF2_AMBUSH))
{
honk->destscale = desiredscale;
P_SetScale(honk, (11*desiredscale)/10);
honk->fuse = TICRATE/2;
honk->renderflags |= RF_DONTDRAW;
taunter->follower->reactiontime = fl->horntime; // reactiontime is used to play the horn animation for followers.
S_StartSound(taunter->follower, fl->hornsound);
honk->flags2 |= MF2_AMBUSH;
}
honk->renderflags &= ~K_GetPlayerDontDrawFlag(victim);
}
}

View file

@ -45,9 +45,18 @@ typedef enum
FOLLOWERSTATE_WIN,
FOLLOWERSTATE_LOSE,
FOLLOWERSTATE_HITCONFIRM, // Uses movecount as a timer for how long to play this state.
FOLLOWERSTATE_HORN, // Uses reactiontime as a timer for how long to play this state.
FOLLOWERSTATE__MAX
} followerstate_t;
typedef enum
{
FOLLOWERMOOD_NORMAL, // Default mood, produces a ++ symbol when you honk.
FOLLOWERMOOD_HAPPY, // Happy mood (recent hitconfirm, won race), produces a ♪ symbol when you honk.
FOLLOWERMOOD_ANGRY, // Angry/upset mood (taking damage, recently took damage), produces a 💢 symbol when you honk.
FOLLOWERMOOD__MAX
} followermood_t;
//
// We'll define these here because they're really just a mobj that'll follow some rules behind a player
//
@ -89,6 +98,10 @@ struct follower_t
statenum_t losestate; // state when the player has lost
statenum_t hitconfirmstate; // state for hit confirm
tic_t hitconfirmtime; // time to keep the above playing for
statenum_t hornstate; // state for pressing horn
tic_t horntime; // time to keep the above playing for
sfxenum_t hornsound; // Press (B) to announce you are pressing (B)
};
extern INT32 numfollowers;
@ -179,6 +192,21 @@ UINT16 K_GetEffectiveFollowerColor(UINT16 followercolor, follower_t *follower, U
void K_HandleFollower(player_t *player);
/*--------------------------------------------------
void K_FollowerHornTaunt(player_t *taunter, player_t *victim)
Plays horn and spawns object (MOSTLY non-netsynced)
Input Arguments:-
taunter - Source player with a follower
victim - Player that hears and sees the honk
Return:-
None
--------------------------------------------------*/
void K_FollowerHornTaunt(player_t *taunter, player_t *victim);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -335,7 +335,6 @@ void K_UpdateGrandPrixBots(void)
player_t *oldrival = NULL;
player_t *newrival = NULL;
UINT16 newrivalscore = 0;
boolean validbots = (K_UsingLegacyCheckpoints() == false);
UINT8 i;
for (i = 0; i < MAXGPPLAYERS; i++)
@ -344,13 +343,8 @@ void K_UpdateGrandPrixBots(void)
{
continue;
}
players[i].spectator = (grandprixinfo.eventmode != GPEVENT_NONE);
if (!validbots || itembreaker)
{
players[i].spectator = true;
}
players[i].spectator = K_BotDefaultSpectator();
}
// Find the rival.
@ -430,11 +424,10 @@ void K_UpdateGrandPrixBots(void)
newrival->botvars.rival = true;
}
if (!validbots)
if (K_UsingLegacyCheckpoints() && !K_BotDefaultSpectator())
{
CONS_Alert(CONS_ERROR, "This map does not use waypoints so bot functionality will not work.\nConsider adding new waypoints directly or via map patching for bot support.\n");
}
}
/*--------------------------------------------------
@ -783,3 +776,35 @@ boolean K_CanChangeRules(boolean allowdemos)
return true;
}
/*--------------------------------------------------
boolean K_BotDefaultSpectator(player_t *player);
See header file for description.
--------------------------------------------------*/
boolean K_BotDefaultSpectator(void)
{
if (cv_forcebots.value)
{
return false;
}
if (!(gametyperules & GTR_BOTS))
{
// This gametype does not support bots.
return true;
}
if (grandprixinfo.eventmode != GPEVENT_NONE)
{
// This is a special round of GP, so bots must spectate.
return true;
}
if (K_UsingLegacyCheckpoints())
{
return true;
}
return false;
}

Some files were not shown because too many files have changed in this diff Show more