Quake II has two palettes. One static palette used for the world and one
dynamic palette used by cinematics. Switching from the cinematic back to
the world palette is handled by putting up the loading plaque. Since a
cinematic always ends with loading somehting else this generally works.
Unfortunatly setting `developer 1` skips the loading plaque. The palette
never gets reset and the world looks like a bad LSD trip. ;) A correct
fix is complicated, because the loading plaque logic is messed up and
working by luck. Reworking the logic has a high propability breaking
corner cased exploited by mods.
Therefor take the easy route and uncoditionally switch to the world
palette when bringing up the loading plaque with `developer 1`.
Closes#925.
commit 93e9633382 "Port step smoothing code from r1q2." ported
r1q2 stair step smoothing for ranges that are equivalent to 8, 12 and 16
units/step.
Later in commit 7f996cc "Don't smooth half height steps" we removed
step sizes 8 and 12, because it appeared to make an elevator in hangar2
(over the water, after jump'n'run sequency) stutter.
However, in reality what made them stutter was the broken comparison
for velocity with an illegal cast, that we later fixed in
e30f82494 "Don't cast the array itself but it's content."
So now restore the smoothing for step sizes 8 and 12, which hopefully
fixes bug #923, and definitely does *not* break the elevater in hangar2.
Fixes crash when entering "multiplayer" -> "player setup" menu with a skin name len > 16
Fixes "playermodels" cmd, which showed "(null)" as a final skin for every model
Enabled by default, can be disabled via s_reverb 0. Also by default
picks preset automatically out of 7 presets based on surrounding
size, this function can be disabled via s_reverb_preset_autopick 0.
Presets can be set manually via s_reverb_preset (0-113).
Cherrypick of ac7be51e94
When a spin control is at min or max value, pressing the arrow key to
switch to the next nonexiting value executes the callback function. That
is confusing.
Example: 'freelook' is set to 'no'. The user presses left arrow,
switching to the nonexiting value before no. The code handles the
case and resets the current value drom -1 to 0. Nevertheless the
callback is executed and switches 'freelook' from no to yes...
Fix that by not executing the callback when we're at min or max value.
Closes#884.
Changed 6 cvars for stick layout to 1; includes menu option
Axial deadzone replaced with radial one, 6 cvars to 2
Expo different for each thumbstick (1 cvar to 2); sliders included
Expo applied to full joystick vector magnitude, instead of per axis
Deleted "joystick_up" ("updown" function) and its sensitivity
Converted model info from AOS to SOA
All strings allocated dynamically at run-time
New command "playermodels" prints valid models to console
Fixes any bugs that may have existed in the directory search
The issue still exists of undefined behavior if a directory name for a
model exceeds the predefined limits.
Old sliders required some of their associated cvars to be "extern" so
their current value could be read. That's no longer needed, so they are
"static" now.
"menuslider_s" types, used to create sliders in menus, now are directly
associated to a cvar. That makes possible for them to get their
currently selected value from the cvar, and express their min and max
values in terms of the real values of the cvar.
The rhythm at how they change can be overridden with s->slidestep.
The new sliders also present visually their current value to the user,
making them more useful than before.
"init_delay" was renamed to "updates_countdown", since it's now a "general
purpose" countdown, having also to count the inputs left for gyro calibration,
besides controller initialization.
Reason for the countdown is now explicit, not having to depend if
"gyro_calibration" was true or not to select what was the purpose of the
countdown.
Explanation comment added for gyro initialization on Linux & Mac.
REMINDER: see if SDL2 will keep the difference of gyro readings between Windows
and Linux/Mac for the Switch controllers.
For example, on Windows with AMDs drivers, GLES3 isn't supported,
so CreateSDLWindow() will fail. We should just try the regular GL3
renderer then instead of exiting with Com_Error()
Also make (Windows') Sys_Error() print to stdout (in addition to stderr),
so errors end up in stdout.txt as well (like all other messages).
SDL2 provides different gyro readings between Windows and Linux/Mac for
the Switch Pro Controller. To keep the natural sensitivity scale intact
(in-game turn = controller turn), the normalization factor is handled
differently by platform, at least for now.
Also, now giving info when there's no gyro sensor available/detected.
And green light for the DualShock 4, because why not :)
Cvar to choose between "yaw" (0) or "roll" (1) axis of the controller
to turn (change your yaw) in-game.
Cvars to change pitch and yaw gyro sensitivities.
Updated cvar documentation with new section "Game Controller".
SDL 2.0.16 and a controller with a gyroscope required to make it work.
Manual calibration of the gyro sensor is needed to avoid "drifting"; a menu
option to do it is included.
New cvar 'gyro_mode' for mode of operation, and to assign action to the new
"+gyroaction" button: disable or enable the gyro.
Several effects use dlights which are rendered for only one frame.
Muzzle flashes are an example. While this worked on 1997th computers,
todays hardware renders way too many frames for these dlights to be
visible at all. Work around that by enforcing a minimal display time
of 32 milliseconds for each dlight.
Fixes part of #815.
When a key/button name is too long, and its bound to an inventory element, its
display in the inventory screen misaligns the item it is bound to, even pushing
it out of the inventory frame.
This commit limits its display to the maximum of 6 characters the inventory
screen allows.
Adds menu bitmap struct, drawing of a menu bitmap and highlighting if bitmap menu item is in focus.
Allows items that are gray (inactive) to be skipped when adjusting the menu cursor.
Removed switch case from Menu_SelectItem, all items either do or do not call their callback functions.
When setting rfps based on GLimp_GetRefreshRate() and vid_maxfps,
take into account that GLimp_GetRefreshRate() might return a value
that's slightly too low (like 58 or 59 when it's 59.95 and should be 60)
The 20% tolerance that, in case of vsync enabled, used to be handled
with `packetdelta < 0.8 * 1000000/pfps` (and the same for rfps) is now
instead added to rfps (and thus implicitly pfps, if it's >= refreshrate)
May be unreliable on some devices, e.g. Nintendo Switch Pro Controller.
Works great on others, e.g. DualShock 4.
Delay added to gamepad initialization on hotplug, gives time to the OS to
recognize the device.
Allows to bind buttons that only will work with "+joyaltselector" active.
The definition of another "scope" of keys was needed, to identify ALT bindings.
Handles game controller button bindings exclusively.
Classic "customize controls" option now handles only keyboard / mouse bindings.
This separation is achieved with the new order of QKEYS in keyboard.h, and
binding functions in menus (especially "MenuKey" functions) now take into
account the "scope" where they operate: keyboard/mouse only, controller only,
or both.
Streamlined menu inputs by making most "*_MenuKey(key)" functions to use
Key_GetMenuKey(). "Backspace" is not a special case anymore, so any menus
that have a "delete" option can already handle any input expected, like the
backspace or delete keys, or the "Y" button of the controller, to run it.
Also, fixed a bug where changing the key for "team chat" also changes the one
for "chat" in the "multiplayer" -> "customize controls" menu.
This removes the usage of SDL_Joystick for joystick buttons and hat, and
relies exclusively on SDL_GameController for input. This allows to identify
buttons in a consistent manner across multiple types of controllers, which
in turn allows to assign specific tasks to them without worrying of breaking
usability, like having "A" to accept and "B" to cancel in menus.
Init and Shutdown logic of game controller have been separated from main SDL
Init and Shutdown functions.
Old style button names "JOYx" have been removed.
If your gamepad has paddles or other extra buttons, you'll need at least
SDL version 2.0.14 to use them.
because on some systems (like RPi4 with my experimental GLES3 branch)
the overhead of a FBO is really noticeable, so no reason to pay for it
when it's not needed
Can be disabled with gl3_usefbo 0.
Mostly this adds an underwater warping effect, like the soft-renderer,
and also like the vulkan renderer (the shader is based on the vk one).
When this is enabled, the v_blend effect (for fullscreen overlay with
one color, like when hit or to make the screen white-ish when under
water) is now applied in the shader used for rendering the FBO instead
of rendering a fullscreen quad in blendmode.
This fixes the framecounter in the soft renderer when `viewsize` is set
to something smaller than 100. This requires the renerer to rerender
bigger parts of the borders which has a measurable speed impact. About
5 frames less with the framecounter enabled on my system. No impact with
`viewsize 100`.
The GL renderers require that the borders are redrawn after every
glClear() call, the damage tracking doesn't take that into account.
Since the speedup by the damage tracking is neglibiable in the GL
renderers, don't use it. Just redraw everything when we're running
with everthing which isn't the soft renderer.
I think this looks ugly, I always called it nightmare and it was one of
the first changes I've made to Quake II. But for the sake of peace and
quiet change it to be standard conformant. Closes#809.
both if GL pointparameters are used or not
(though depending on driver and hardware the pointparameters-based
particles *might* be always square or always round, regardless of
gl1_particle_square - that's driver-bugs which we can't fix, disable
pointparameters with `gl1_pointparameters 0` to work around it, or
just use the GL3 renderer)
r_lerp_list is to allow exceptions to r_2D_unfiltered (like for having
pixely UI in general, but filtered console background).
r_videos_unfiltered controls whether videos should be filtered or not
I also made r_nolerp_list CVAR_ARCHIVE, like users probably expect it.
because on MSVC it uses alloca() (or _malloca()) which mustn't be called
in loops, as the memory is only freed when returning from the function,
not when leaving the scope (or before the next loop iteration).
Instead do one "dry-run" iteration to figure out how big the array must
be at most, and then allocate it once before the loop with that size.
The easiest way to build this is to check out the dhewm3-libs project
(https://github.com/dhewm/dhewm3-libs/) to provide the dependencies
(SDL2, OpenAL, cURL) and set YQUAKE2LIBS accordingly, by passing
-DYQUAKE2LIBS=c:/path/to/dhewm3-libs/i686-w64-mingw32 to cmake.
I wouldn't really recommend building with MSVC - I just somehow made it
work and ignored all the warnings and I have no idea how portable the
resulting binaries are etc. For binaries you actually want to use, please
continue using MinGW-w64. Especially my workaround for VLAs (C99 variable
length arrays) is kinda fishy, particularly if those arrays are allocated
in a loop (that's inly done in ref_gl1.dll's code).
The only reason I did this is that I had to debug on Windows and, at least
for my specific bug, gdb didn't really work with binaries produced by
MingGW-w64 and MSVC's debugger works well with binaries produced by MSVC.
Currently requires VS 2019 16.8 or newer with C11 (/std:c11) because I
couldn't get YQ2_ALIGNAS_TYPE() to work with MSVC without _Alignas().
If we can get this to work, VS2015 or newer might suffice (but not older
versions, because their so called C standardlib didn't provide exotic
functions like snprintf()).
# Conflicts:
# CMakeLists.txt
Restored original gamemode prioritization to dm > coop > sp, fixed a bug where server start menu did not clear singleplayer cvar, and rewrote how server init manages gamemode cvars
The code is building fine but at startup the rendere library cannot by
loaded: "LoadLibrary returned 126" Disable thread local as a band-aid
fix, it might be worth to have a deeper look and figure out what exactly
goes wrong.
Closes#762.
This is a corner case, next to unlikely that anyone would have ever hit
it. That's why my tests with asan didn't find the leak. The if case are
paletted textures which must be enabled by setting `gl1_palettedtexture`
to 1 and requires an GPU with support for `GL_EXT_paletted_texture`.
Nvidia dropped support for that in 2005. Additionally a sky texture
must be uploaded.
This brings several small bugfixes and more robust handling of files
without comment / tag header. It's not mentioned in the changelog,
but at least for dhewm3 updating to this latest version fixed some
problems with missdecoded files on MacOS when running on the M1 aarch64
CPUs.
This was an issue an Windows with it's small stack. It didn't trigger on
Linux. While at it make the code a little bit more robust by allocating
exactly the amount of data we need and not some arbitrary guess.
Setting r_2D_unfiltered to 1 (0 is default), 2D elements (GUI, menu,
console) are rendered without texture filtering in GL1 and GL3, while
everything else is still rendered with whatever is set in gl_texturemode
This setting (and now also gl_nolerp_list) is applied immediately,
so no vid_restart is needed.
refs #752
Injecting the demo loop right after the `game` cvar was changed cannot
work: The demo loop is implemented through aliases, aliases are expended
as soon as they're added to the command buffer. However, the game isn't
changed as soon as the cvar is set, but the next time when the control
flow enters the file system. Therefor the aliases get expanded to the
wrong game and the demo loops breaks.
This closes#719.
While having a Vulkan renderer in Yamagi Quake II sounded like a good
idea, especially for cheap hardware with broken OpenGL drivers, the last
weeks showed that the code is not ready for primetime. Some examples
for critical problems:
* Render glitches when using non-standard assets. Everything with more
polygons and texture resultion than baseq2 seems to be broken.
* The startup and shutdown code is a mess. While I fixes the most
critical bug, there're a lot of cases left. Startup and shutdown
mostly works by luck.
* At least one memory leak in the model code.
And neither @DanielGibson nor myself have deeper knowledge about Vulkan.
We don't have the time and the motivation to learn it. While some
community members did excellent work on ref_vk (especially @0lvin and
@rg3), the community maintenance promised in the initial pull request
never really materialized. Therefor we risk ending up with a renderer
that we can't and won't maintain by ourself.
Vulkan is not gone. The code will be recommitted in a separate
repository at: https://github.com/yquake2/ref_vk
We're willing to give community members commit access to that
repository. Send a substantial pull request and ask for it.
This is next to no functional change, the only difference to before is,
that the Vulkan renderer is treated as an unknown renderer. gl3 is the
first regular fallback.
Unitl now the video menu showed all known renderer libs (gl1, gl3, vk
and soft), regardless if the lib was available or not. Rework the
renderer selection logic to skip over non existent renderer libs:
Generate an array combining the menu string and cvar string of all
available renderer libs, use this array instead of the hardcoded array.
While at it simplify the code a little bit.
So far I haven't seen a restart loop, but at least in theory they'e
possible. Because its hard to break out of such loop, especially on
Windows were interaction with the taskmanager is required, play save
and restart max. 3 times in a row.
The timeout specifies how long Vulkan waits for the next frame becoming
available. On the one hand we need to take the vsync or the possibility
that we get scheduled away for longer times into account. On the other
hand we don't want to wait for too long, the game may run into the
timeout after its windows was minimized, etc. 500 milliseconds sounds
like a good compromise.
Some GPU drivers set a maximal extent size of 0x0 when the window gets
minimized. One example is Intel on Windows. A swapchain with extent
size of 0x0 is invalid, so we cannot reinitialize the renderer... Work
around that by postponing the restart as long as the maxmimal extent
size stays 0x0.
This could should be done in the client (don't call into th renderer
when the window is minimized), but it would need a lot of changes
to the client <-> renderer interactions. So take the easy route.
The client might call into the renderer after it was shut down by
`VID_ShutdownRenderer()` or initialized `VID_LoadRenderer()`. This
is arguably a client bug, but hard to fix on client side and not
a problem for all other renderers. Work around it by marking the
current frame as 'not started' at Vulkan shutdown and init.
This is more in line with the rest of the code. Reinitializing the
internal state when building a new context is saver than relying on
Vulkan telling us that something is wrong an reacting to that.
Just calling `QVk_Shutdown()` is wrong. It doesn't wait for Vulkan to
finish, which can cause crashes. And it leaks some ressources which
makes the GPU driver unhappy.
The ref_vk renderer was written for vkQ2 which has differend renderer
<-> client semantics. In YQ2 we can end up initializing or shutting the
renderer down several times. Not by the client, but by the client not
knowing of the renderer has already initialized / shutdown it's internal
state. This is fatal, leading to ressource leaks, crashes and other fun.
Introduce a new global variable `vk_initialize` and use it to track if
we're initialized or not.
Since `vid_fullscreen` isn't special anymore, it's completely handled by
`Vid_Restart_f()`, which in turn simplifies the spaghetti code in the vk
renderer. If I understand that glibberish correctly the only we need to
handle is the partial restart in `QVk_Restart()`.
This function will be used to replace the vid_fullscreen->modified
mechanism used the communicate renderer configuration restarts to the
client with a proper proper API. The implementation is backward
compatible, existing renderers are still working.
VK_WARNING: Validation Performance Warning: [ UNASSIGNED-BestPractices-vkCreateRenderPass-image-requires-memory ] Object 0: handle = 0x58e7d23ea0, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x4003982 | Attachment 2 in the VkRenderPass is a multisampled image with 4 samples, but it uses loadOp/storeOp which requires accessing data from memory. Multisampled images should always be loadOp = CLEAR or DONT_CARE, storeOp = DONT_CARE. This allows the implementation to use lazily allocated memory effectively. (performance)
This brings yquake2 closer to vkQuake2 regarding renderer restarts when
the swapchain is out of date, among other situations that trigger a
Vulkan renderer restart.
Basically, the current behavior has the problem that when the renderer
is restarted at the beginning of the frame, the models are lost and we
end up with "ERROR: Mod_PointInLeaf: bad model" when attempting to
render anything after that restart.
To solve this, we move the restart logic to EndFrame and add a twist to
it: we use a vid_refresh variable to signal the server that the client
needs re-registration before starting the next frame cleanly, which will
trigger the registration logic to prepare the models again.
When creating the Vulkan texture samplers, make them have the real
anisotropic filtering value selected by the user. This has two side
effects:
* We no longer need two sets of texture samplers in Vulkan (one with and
another one without anisotropic filtering).
* The anisotropic filter value in Vulkan is no longer an on/off switch
and we use the value as chosen by the user.
Making the anisotropic filter value only be applied after hitting Apply
in the video menu will make it more natural for the Vulkan renderer to
restart itself when a new anisotropic value is selected, paving the way
to use the actual anisotropic filtering value in Vulkan.
This was the default until 2.0.12 and is what the expects. It changed
with 2.0.14, casing problems with window ordering under windows and
some X11 window managers like kwin.
Do it unconditionally. So we're shure that we're ending with a minimized
windows, no matter what SDL does.
Fixes part of #647.
One of the most common bug reports is, that the fullscreen mode doesn't
behave like users expect. This is caused by `vid_fullscreen 1` setting
desktop fullscreen mode (a fullscreen windows) and not the native
fullscreen mode. This commits switches the semantics:
* 1: Native fullscreen, like Vanilla Quake II.
* 2: Desktop fullscreen.
With this alt-tab reverts to native fullscreen. While at it improve the
documentation, suggest setting `r_mode -2` when using `vid_fullscreen
2`. Change the menu strings to make things clearer, set `r_mode -2` when
selecting 'fullscreen window' in the menu.
I pondered several other options:
* Introducing a second cvar for the desktop fullscreen, like we did in
dhewm3. This has the problem, that in Quake II vi_fullscreen is
special and used to communicate changed to the renderer configuration
between the client and renderer. A second fullscreen cvar would
complicate this already shaky mechanism even more.
* Setting `r_mode -2` when `vid_fullscreen 2`. This might not be what
the user wants and causes problems when we're unable to get the
desktop resolution.
Switching this back to Vanilla Q2 behavior fixes at least one lightning
problem in the space map in baseq2. It'll break the lighting in some
addon maps, but is more correct from a global standpoint. You can't
have everything...
Closes#677.
If an error is detected in vkAcquireNextImageKHR or vkQueuePresentKHR,
avoid restarting the whole video system and the game window. Instead,
shut down the Vulkan subsystem as gracefully as possible and restart it
without touching the window.
This fixes the problem with infinite video restarts under the Gnome
desktop environment.
1: The Vanilla Quake II behaviour, footsteps are generated when the
player is faster than 255.
0: Footstep sounds are never generated.
2: Footstep sounds are always generated.
Defaults to `1`, cheat protected to `1`.
Closes#666.
When windowed or in "switch resolution" mode, the viewport must be kept
in the top-left corner or it will appear cut while in fullscreen.
Also, make offset and width calculations safe from the point of view of
the swapchain extent, in case there's a mismatch.
Since we are now loading the world color buffer content before drawing
on them again, we need to make sure the attachment layout transition
from shader-read-optimal to color-attachment-optimal happens before
color attachment read operations.
The contents of the previous drawn frame, used to mask geometry glitches
due to geometry sometimes not being watertight, was not being correctly
loaded for MSAA cases.
When MSAA is not used, the single-sample attachment needs to be loaded
and stored. With MSAA enabled, it's the multisample attachment the one
needing to be loaded and stored.
The pipeline used to draw a texture quad was only created compatible
with the RP_UI render pass, which has a single-sample color attachment.
This made the pipeline work when MSAA was disabled, but it did not work
properly with it enabled.
To fix the issue, create a set of pipelines, instead of a single one,
with compatibility with the different types of render passes, as the
pipeline is used for both the scaled down view borders as well as UI
elements in the third render pass.