This is one these constructs which makes you wonder how it could ever
work. When querying a cvar by calling Cvar_Get(), the default value
(given in `var_value`) is copied into `cvar_t->default_string`. If a
NULL pointer is given in `var_value`, the NULL pointer is passed to
CopyString() and dereferenced. The game crashes. There's already a NULL
pointer check in the 'cvar wasn't found' branch, but none in the 'cvar
was found' branch... Moving the check to the beginning of the function
isn't an option, because at least lithium2 doesn't implement a NULL
pointer check either. We would just move the crash from the server into
the game.dll. Therefore copy an empty string into
cvar_t->default_string` when a NULL pointer was passed in `cvar_value`
and the cvar was found. Pass the empty string trough `CopyString()` to
get an Z_MAlloc() allocation for it, otherwise we would call `Z_Free()`
on an unallocated object further down below.
Reported by Chris Stewart.
ogg_enabled doesn't prevent music from playing, it just toggles if the
ogg backend should be enabled or not. If the user does something like
`ogg_enable=0; snd_restart` everything is okay. If they just set
`ogg_enable=0` strange things happen because the backend stays
initialized and will play tracks as requested. Work around the by
shutting the backend down if `ogg_enable == 0 && ogg_started == true`.
Closes#583.
This allows really bug configuration files up to 32k. It would be better
to switch the global buffer to something allocated at runtime, but thats
non-trivial... This change should be save, since the buffers are global
(allocated in the BSS) and not included in savegames nor send over the
network.
Closes#582.
It's an often reported, that the q2ded dedicated server consumes huges
amounts of CPU time. That's because users don't know that `busywait`
must be set to `0`. Since there's no point in using busywaits in the
dedicated server (the network jitter is always bigger than the
jitter caused by nanosleep() and equivalents), just force q2ded to
use nanosleep().
Some projectiles like grenades or rockets are classified as enemies.
Their explosion spawn a sound entity, monsters should move to that. But
the projectile is destroyed when exploding, it's entity struct is set to
NULL. Therefor the self->enemy pointer is also NULL. The self->enemy
check was removed in bc5f5698. Work around this by pretending that the
enemy is already there.
This was reported by @Soldy, closesyquake2/xatrix#56.
This is a special case, the bug was already present in Vanilla Q2: If a
server is offering assets for download but is missing some files the
USP download code runs in an endless loop. CL_ParseDownload() detects
that something is wrong and calls CL_RequestNextDownload() which tries
to download the same file again... Work around this by skippig over that
file.
This closes#552.
The new ordering was introduced in 16ee007, fixing some problems with
the wrong sound getting played when an entity triggers several sound at
the same timestamp. This broke the behavior of the mods, in #558 dday
was mentioned, muzzle flashe sound prevent the firing sound from getting
played.
Since we don't control the source of all mods, add a simple band aid
fix: Use the new ordering for baseq2, xatrix and rouge. Use the old
ordering for everything else.
An alternative approach is being discussed in #564.
I don't remember why we restricted it to client startup. The original
code executed it everytime when `game` changed... Revert to that
behavior. Look here if some problems come up. ;)
Closes#544.
Adaptive vsync is a often requested feauture and easy to implement. Set
`r_vsync` to `2` to enable. This is untested because my system doesn't
support it.
There already was one (that I only recently fixed) for semicolon, but
the same problem can happen with quotes or $ (which is used in macros)
(single-quote ' is probably not affected, added it just to be sure)
regardless of keyboard layout, with a special exemption for layouts
where that key generates a quote character (like the Brazilian one)
because you may wanna type a quote into the console.
(It's SDL_SCANCODE_GRAVE, that key between Esc, 1 and Tab)
The old hack of matching for ^, ~ and ` in Char_Event() didn't work very
well for layouts we didn't anticipate, which is especially relevant with
the recent Scancode fallback, which for example allows binding the ^ key
on Belgian keyboards (which is on SDL_SCANCODE_LEFTBRACKET, far away
from the "console key"), but in that case would *also* open the console.
This is mostly straight-forward, except for a small hack to prevent the
key from generating text input (on German layouts you otherwise get
"^" in the console when closing+opening it), which requires the
"console key" to be pressed without any modifiers like Shift or AltGr.
Yes, it's ugly, but it works and all the uglyness is contained in
IN_Update() and on the other hand Char_Event() becomes less ugly :)
If we can't map a SDL_KEYDOWN/KEYUP events SDL_Keycode to a known
Quake2 K_* keycode, we try to map the SDL_Scancode to one of the new
K_SC_* YQ2 scancodes instead.
The scancode name corresponds to the key at that position on US-QWERTY
keyboards *not* the one in the local layout, for example the German 'Ö'
key is K_SC_SEMICOLON.
This way (hopefully!) all keys on common keyboards can be bound,
regardless of their layout. The key name won't be immediately obvious
to the user, but it's only a fallback and better than nothing.
fixes#543