I added Sys_RegisterShutdown years ago and never really did anything
with it: now any system that needs to be shutdown can ensure it gets
shutdown on program exit, and in the correct order (ie, reverse to init
order).
This makes sure that some unchecked event doesn't cause a lockup.
However, blocking input is really not the way to go: need to implement a
state machine and use non-blocking event reads.
Or really, allow it if the user specifically requests it: the default is
blocked. Modern systems (particularly displays) do not really like
changing resolution, so doing so by default seems rather wrong.
This makes sure that some unchecked event doesn't cause a lockup.
However, blocking input is really not the way to go: need to implement a
state machine and use non-blocking event reads.
Or really, allow it if the user specifically requests it: the default is
blocked. Modern systems (particularly displays) do not really like
changing resolution, so doing so by default seems rather wrong.
It's just a wrapper around hashtab, but it makes checking if a string is
in a set easy. Way overkill when only a few extensions are enabled, but
more might come later.
This paves the way for clean initialization of the Vulkan renderer, and
very much cleans up the older renderer initialization code as gl and sw
are no longer intertwined.
This fixes the segfault and pushes things very much in the desired
direction of proper system independence for rendering and presentation
separation (though things were headed in the right direction before).
Things are still a mess, but a proper cleanup will be a lot of work and
will, really, involve properly splitting quake-specific code* out from
the rest of the renderer.
* data loading and format specific stuff
A single graphics-capable queue should be enough for now. However, I'm
not sure I'm happy with a lot of the code: it's a bit difficult to write
flexibly configured code for Vulkan (or seems to be at this stage),
especially in C.
After messing with SIMD stuff for a little, I think I now understand why
the industry went with xyzw instead of the mathematical wxyz. Anyway, this
will make for less pain in the future (assuming I got everything).
I'm not certain despair actually meant for the break to be there. It
certainly would have sped up the game a bit but at the expense of proper
blood trails in the software renderers.
These are the ones where I could easily make scan-build happy. They do seem
to be potential holes where invalid data in one place could result in use
of uninitialized values.
While scan-build wasn't what I was looking for, it has proven useful
anyway: many of the sizeof errors were just noise, but a few were actual
bugs (allocating too much or too little memory).
Also fix a bug where despite supporting 32 buttons, only 18 were actually
supported, and a similar issue for the number of axes.
My saitek x52 has 34 buttons and 10 axes. Whee.
It seems mesa still has the bug where non-array attributes don't work
when set as attribute 0, and that the allocation order changed sometime
since I last tested with mesa. This fixes the black world and flickering
alias models on my eeepc.
So far, alias model rendering is the only victim, but things are working,
even if only color map lookup and fog blending are broken out at this
stage.
I expect the effect naming scheme will go through some changes until I'm
happy with it.
Again, based on The OpenGL Shader Wrangler. The wrangling part is not used
yet, but the shader compiler has been modified to take the built up shader.
Just to keep things compiling, a wrapper has been temporarily created.
Once and for all: remove the default and move the Sys_Error outside the
switch (changing appropriate breaks to returns). Now gcc will let me know
when I forget to update the switch statements.
I'd missed a set of bit->lightnum conversions that resulting in lightnum
becoming much greater than 128 and thus trashing memory when the surface
was marked.
Johnny's number->J_AXISn mapping is preserved, but I had intended for any
key to be supported (J_AXISn was just to ensure free keys were available).
This gives both methods (and some range checking on the axis button
number).
First, this completely smashes joystick input: it will not work (though it
doesn't crash). This is because there is, as of yet, no means to configure
the system.
Each joystick axis has:
- per-axis amplification (both pre and post).
- per-axis offset (offset applied after pre-amp but before post amp)
- selectable destination:
- linear delta: position and angles (as before)
- axis button: if the value crosses the threshold, the given key is
pressed or released as appropriate.
The axis amplification still uses joy_amp and joy_pre_amp (and
in_amp/in_pre_amp), but now also has the per-axis settings.
The per-axis offset is most useful for axis buttons. For example, the xbox
360 controller triggers are analong but go "all the way to negative on 0
state". Offsetting the input keeps axis button thresholds simple.
Amplification and offset is applied before anything is done with the axis
value. The formula is:
joy_amp * in_amp * axis-amp *
(offset + value * joy_pre_amp * in_pre_amp * axis-pre_amp)
Axis button thresholds are very simple: if the sign of the value is the
same as the sign of the threshold and abs(value) >= abs(threshold), the
button is pressed. While multiple thresholds and keys can be placed on an
axis, only one can be pressed at a time. The threshold furthest from 0
wins.
The seed is currently 0xdeadbeef, but I intend on fixing that soon. Now the
particle velocities and origins use fully independent bits (though a big
chunk is wasted right now).
This is a quick fix until I get a random number generator into QF.
Mingw's RAND_MAX is only 0x7fff and so the (((rnd >> 10) & 63) - 31.5) / 63.0
used for the z component of origin and velocity would never go positive.
For now, change the 10 to 9 (reusing another bit from Y). I plan on
implementing a full 32-bit PRNG in QF so we always have a reliable
generator.
Now the user can create and destroy IMTs at will, though currently
destroying IMTs is currently all or nothing (imt_drop_all).
An IMT is created via imt_create which takes the keydest name (key_game
etc), the name of the IMT (must be unique for all IMTs) and optionally the
name of the IMT to which the key binding search will fall back if there is
no binding in the current IMT, but must be already defined and on the same
keydest. This means that IMTs now have user determined fallback paths. The
requirements for the fallback IMT prevent loops and other weird behaviour.
Actual key binding via in_bind is unaffected. This is why the IMT name must
be unique across all IMTs.
The "imt" command works with the key_game keydest, but imt_keydest is
provided for specifying the active IMT for a specific keydest.
At startup, default IMTs are setup to emulate the previous static IMTs so
old configs will continue to work (mostly). New config files will be
written with commands to drop all of the current IMTs and build new ones,
with the bindings and active IMT set as well.
This fixes the status bar refresh issues in sw. The problem was that with
two viddef's hanging around, things got a little confused and recalc_refdef
wasn't getting into the renderer.
in_clear <imt>... where each argument to in_clear is an imt identifier. If
any identifiers are incorrect, the incorrect ones will be displayed and no
tables will be cleared. All or nothing.
It seems that SDL_SetColors causes a page flip, so VID_SetPalette only
queue a palette change (by checking for the need to change and storing the
requested palete) and VID_Update now checks for a queued palette change and
updates SDL's palette if required. This fixes the flickering console in sw
-sdl introduced by the cshift/centerprint change.
It was properly cleared after drawing water chains and sky chains, but I
had missed normal surfaces. It took the use of the same texture for both
normal surfaces and water surfaces to trigger the bug. Thanks go to Simon
'Sock' O'Callaghan and his In The Shadows mod.
vidmode is starting to show its age. Modern X doesn't need a config file,
and when one is not available, the list of available resolutions is quite
strange. Time to look into randr support.
The depth limits in the gl and glsl renderers and in the trace code really
bothered me, but then the fix hit me: at load-time, recurse the trees
normally and record the depth in the appropriate place. The node stacks can
then be allocated as necessary (I chose to add a paranoia buffer of 2, but
I expect the maximum depth will rarely be used).
The attached patch (against quakeforge git) changes the [con]width,
[con]height, and most importantly the rowbytes members of viddef_t
from unsigned to signed int, like in q2. This allows for a properly
negative vid.rowbytes which may be needed in, e.g. a DIB sections
windows driver if needed. Along with it, I changed a few places
where unsigned int is used along with comparisons against the relevant
vid.* members.
One thing I am not 100% sure is the signedness requirements of
d_zrowbytes and d_zwidth: q2 has them as unsigned but I am not sure
whether that is because they are needed as unsigned or it was just an
oversight of the id developers. They do look like they should be OK
as signed int to me, though: comments?
==
Note from Bill Currie: I had to do some extra changes as many
signed/unsigned comparisons were somehow missed.
It turns out the expected orientation of the sky cube is exactly that of
Blender's default cube looked at from the front view (num-1) and the front
face being the nearest face. This put's Marcher's sun nicely in the view
when exiting the cave.
Rearrange the sky_suffix and sky_coords arrays and remove the sky_target
array such that the faces can be loaded using
GL_TEXTURE_CUBE_MAP_POSITIVE_X + i (apparently certain drivers break if
the faces aren't loaded in the correct order).
Also, the nomalization of the direction vector in the fragment isn't
necessary.
All of the nastiness is hidden in bspfile.c (including the old bsp29
specific data types). However, the conversions between bsp29 and bsp2 are
implemented but not yet hooked up properly. This commit just gets the data
structures in place and the obvious changes necessary to the rest of the
engine to get it to compile, plus a few obvious "make it work" changes.