The software renderer uses Bresenham's line slice algorithm as presented
by Michael Abrash in his Graphics Programming Black Book Special Edition
with the serial numbers filed off (as such, more just so *I* can read
the code easily), along with the Chen-Sutherland line clipping
algorithm. The other renderers were more or less trivial in comparison.
The scrap allocator works better if taller rects are allocated first (so
long as they're not too tall, more tuning needed) and qplaque is taller
than mainmenu (but draw order is reversed).
The software renderer uses Bresenham's line slice algorithm as presented
by Michael Abrash in his Graphics Programming Black Book Special Edition
with the serial numbers filed off (as such, more just so *I* can read
the code easily), along with the Chen-Sutherland line clipping
algorithm. The other renderers were more or less trivial in comparison.
This is meant for a "permanent" tear-down before freeing the memory
holding the VM state or at program shutdown. As a consequence, builtin
sub-systems registering resources are now required to pass a "destroy"
function pointer that will be called just before the memory holding
those resources is freed by the VM resource manager (ie, the manager
owns the resource memory block, but each subsystem is responsible for
cleaning up any resources held within that block).
This even enhances thread-safety in rua_obj (there are some problems
with cmd, cvar, and gib).
The palette is a modified version of the default VGA colormap as
explained by Noah Johnson (https://github.com/canidlogic/vgapal) and the
generation code is heavily influenced by his code. However, I've
reversed the HSV groups so I could have the pure bright colors in the
fullbright range and added a few colors in the 248-255 range (mostly
greens and ambers meant to be close to the old phosphor monitors).
The colormap is generated by laying the colors from the palette across
the middle of the map (rows 31 and 32) then linearly interpolating from
0 to the color, and the color to 2x the color (clamped) and then
converting back to a palette. Mr Fixit actually looks ok still in the
software renderer (unaffected in the others) though quakeguy is a hoot
in all the renderers :).
This replaces *_NewMap with *_NewScene and adds SCR_NewScene to handle
loading a new map (for quake) in the renderer, and will eventually be
how any new scene is loaded.
The goal is to have somewhere to put entities so they can be rendered. I
suspect I could have used a bsp tree to partition space for frustum
culling, but it's probably not worth it at this stage (but shouldn't
require any changes to the engine: just the model).
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
This is the bulk of the work for recording the resource pointer with
with builtin data. I don't know how much of a difference it makes for
most things, but it's probably pretty big for qwaq-curses due to the
very high number of calls to the curses builtins.
Closes#26
Now that the data is fetched from the correct location, the locals view
is useful again :). However, there seems to be a problem with array
views: not sure they're showing the correct data as I was getting
unexpected values in the display but normal vars seem to be ok.
While the .tmp defs weren't too much clutter in v6p progs, the .arg defs
in Ruamoko progs make for a lot of noise. Showing only user defs (those
without a leading .) makes for a much more usable locals display.
It now takes the function name to print in error message (passed on to
PR_Sprintf) and the argument number of the format string. The variable
arguments (in ...) are assumed to be immediately after the format
argument.
This is actually an old bug in qwaq that was masked by v6p progs
parameter passing: it was just luck that event got put in the correct
parameter and not trampled until the responder saw it. Ruamoko progs,
however, simply lost the event entirely because it never got explicitly
passed by the listener implementation.
This was easy to achieve in v6p progs because all return values passed
through .return and thus could not be lost. However, Ruamoko progs use a
return pointer which can wind up pointed into the void (the return
buffer) and thus cause the return value to be lost. Using @return on
obj_msg_sendv bounces the return pointer through to the called function.
In addition, nil is returned when the forwarding target is nil.
or 512kW (kilowatts? :P). Barely enough for vkgen to run (it runs out if
auto release is run during scan_types, probably due to fragmentation). I
imagine I need to look into better memory management schemes, especially
since I want to make zone allocations 64-byte aligned (instead of the
current 8). And it doesn't help that 16 words per allocation are
dedicated to the zone management.
Anyway, with this, vgken runs and produces sufficiently correct results
for the rest of QF to build, so long as qfcc is not optimizing.
It doesn't do much good for dynamic progs memory because zone currently
aligns to 8 bytes (oops, forgot to fix that), but at least the stack and
globals are properly aligned.
The ABI for the Ruamoko ISA set currently puts va_list into the
parameter stream whenever a varargs function is called. Unfortunately,
IMP is declared with ... and thus cannot be used directly unless all
methods become varargs, but I think that would cause even more
headaches.
This cleans up dprograms_t, making it easier to read and see what chunks
are in it (I was surprised to see only 6, the explicit pairs made it
seem to have more).
This is part of the work for #26 (Record resource pointer with builtin
function data). Currently, the data pointer gets as far as the
per-instance VM function table (I don't feel like tackling the job of
converting all the builtin functions tonight). All the builtin modules
that register a resources data block pass that block on to
PR_RegisterBuiltins.
This will make it possible for the engine to set up their parameter
pointers when running Ruamoko progs. At this stage, it doesn't matter
*too* much, except for varargs functions, because no builtin yet takes
anything larger than a float quaternion, but it will be critical when
double or long vec3 and vec4 values are passed.
Update qdb_get_string's mangling for qfcc's new unsigned int support and
fix an incorrect cast of the param pointer passed by prd_runerror that
caused a segfault when trying to use the string. Attempting to use
qwaq-app (ie, the qc debugger) on Ruamoko ISA progs mostly works, but
the defs are decidedly unhappy (due to the base registers).
Terminal apps effectively always have focus (unless I find a way to know
when an xterm loses/gains focus). Fixes input-app not updating on evdev
events.
And other related fields so integer is now int (and uinteger is uint). I
really don't know why I went with integer in the first place, but this
will make using macros easier for dealing with types.
They are both gone, and pr_pointer_t is now pr_ptr_t (pointer may be a
little clearer than ptr, but ptr is consistent with things like intptr,
and keeps the type name short).
Forgetting to invoke [super dealloc] in a derived class's -dealloc
method has caused me to waste far too much time chasing down the
resulting memory leaks and crashes. This is actually the main focus of
issue #24, but I want to take care of multiple paths before I consider
the issue to be done.
However, as a bonus, four cases were found :)
I have no idea why the code is disabled (especially considering the
comment), so leaving it that way for now, but this makes the code
compile when enabled.
It's very much a hack, but it will do for now until I can rewrite the
whole thing: it's not at all thread safe, but it is over eight years
old and has survived a lot of bit-rot.
The old math functions from quake and quakeworld don't belong with the
newer ones as their presence in the same object file causes invalid
builtin warnings when pr_cmds isn't present.
With some hacks that are not included (plan on handling events and
contexts properly), button inputs, including using listeners, are
working nicely: my little game is working again. While the trampoline
code was a bit repetitive (and I do want to clean that up), connecting
button listeners directly to Ruamoko instance methods proved to be quite
nice.
And create rua_game to coordinate other game builtins.
Menus are broken for key handling, but have been since the input rewrite
anyway. rua_input adds the ability to create buttons and axes (but not
destroy them). More work needs to be done to flesh things out, though.
Until now, the new qwaq startup was used only in command-line tools and
console applications where things like Ruamoko security and having a
hunk were not an issue. Now the start up code (qwaq-*.c) can specify
that Ruamoko is to be secured and provide a hunk on a per-thread basis,
and the thread data is passed into the progs code via a progs resource.
It now uses the advanced command line parsing used by qwaq-curses and
qwaq-cmd, but currently disables multi-threading (I don't want to deal
with threading in the engine just yet). The int file is -graphics
because qwaq-x11 is really just the X11 target, qwaq-win is built for
windows, but they use the same basic startup (I hope).
This is needed for cleaning up excess memsets when loading files because
Hunk_RawAllocName has nonnull on its hunk pointer (as the rest of the
hunk functions really should, but not just yet).
This is actually a better solution to the renderer directly accessing
client code than provided by 7e078c7f9c.
Essentially, V_RenderView should not have been calling R_RenderView, and
CL_UpdateScreen should have been calling V_RenderView directly. The
issue was that the renderers expected the world entity model to be valid
at all times. Now, R_RenderView checks the world entity model's validity
and immediately bails if it is not, and R_ClearState (which is called
whenever the client disconnects and thus no longer has a world to
render) clears the world entity model. Thus R_RenderView can (and is)
now called unconditionally from within the renderer, simplifying
renderer-specific variants.
This should be a much friendlier way of "grabbing" input, though I
suspect that using raw keyboard events will result in a keyboard grab,
which is part of the reason for wanting a friendly grab.
There does seem to be a problem with the mouse sneaking out of the
top-right and bottom-left corners. I currently suspect a bug in the X
server, but further investigation is needed.
This is the first step in the long-sought goal of allowing the window
size to change, but is required for passing on getting window position
and size information (though size is in viddef, it makes sense to pass
both together).
Right now, only raw pointer motion and button events are handled, and
the mouse escapes the window, and there are some issues with focus in
focus-follows-mouse environments. However, this should be a much nicer
setup than DGA.
This has smashed the keydest handling for many things, and bindings, but
seems to be a good start with the new input system: the console in
qw-client-x11 is usable (keyboard-only).
The button and axis values have been removed from the knum_t enum as
mouse events are separate from key events, and other button and axis
inputs will be handled separately.
keys.c has been disabled in the build as it is obsolute (thus much of
the breakage).
Input Mapping Tables are still at the core as they are a good concept,
however they include both axis and button mappings, and the size is not
hard-coded, but dependent on the known devices. Not much actually works
yet (nq segfaults when a key is pressed).
For drivers that support it. Polling is still supported and forces the
select timeout to 0 if any driver requires polling. For now, the default
timeout when all drivers use select is 10ms.
I had forgotten that _size was the number of rows in the map, not the
number of objects (1024 objects per row). This fixes the missed device
removal messages. And probably a slew of other bugs I'd yet to encounter
:P