I guess I wasn't sure how to find all the allocated entities from within
the registry, but it turned out to be trivial. This takes care of leaked
static entities (and, in a later commit, leaked light entities, which is
how I found the problem).
This is done only in nq because I am not sure of the consequences to the
rest of quake and I do most of my testing in nq when not using qwaq.
Needed for thousands separators in formatted printing.
It does almost nothing (just puts a non-function button on the screen),
but it will help develop the IMUI code and, of course, come to help with
debugging in general.
It's usually desirable to hide the cursor when playing quake, but when
using the console, or in various other states, being able to see the
cursor can be quite important.
I never liked it, but with C2x coming out, it's best to handle bools
properly. I haven't gone through all the uses of int as bool (I'll leave
that for fixing when I encounter them), but this gets QF working with
both c2x (really, gnu2x because of raw strings).
This will make it easy for client code to set up data needed by the
console before the console initializes. It already separates console
cvar setup and initialization, which has generally been a good thing.
viewstate's time is from cl.time which is not what's used to set
last_servermessage (that uses realtime). After careful investigation, I
found that cl.time is not at all suitable and that the original id code
used realtime (I think it was just me being lazy when I merged the
code). Fixes the stuck net icon.
It's currently used only by the vulkan renderer, as it's the only
renderer that can make good use of it for alias models, but now vulkan
show shirt/pants colors (finally).
Well, sort of: it's still really in the renderer, but now calling
R_AddEfrags automatically updates the visibility structure as necessary,
and deleting an entity cleans up the efrags automatically. I wanted this
over twenty years ago.
I think this makes the purpose of the functions more clear and makes the
protocol logic less dependent on the meaning of some of the updates.
Most of the update functions are not fully implemented yet.
I had forgotten that the cl structs in nq and qw were different layouts,
which resulted in qw's sbar/hud being quite broken. Rather than messing
with the structs, I decided it would be far better in the long run to
clean up sbar's access to the cl struct and the few other nq/qw specific
globals it used. There are still plenty of bugs to fix, but now almost
everything is in the one place.
The first scoreboard entry not showing was due to it being deleted
immediately because unused fragsort array entries had a valid player
index (0 in this case) and thus the unused view removal code was
removing views it should not.
Nicely, all the data is already sort-of available (ping and pl will be
interesting, and I need to double-check uid), but once I get some issues
with the first entry not working, I'll be able to "merge" sbar and
concentrate on rogue and hipnotic.
Because demoplayback seen by the shared client code is in viewstate and
that's in cl, it gets set to 0 when connecting, thus the network icon
while playing demos.
With the hierarchy code fixed for intra-hierarchy parenting, there's no
longer any need to first pull the sub-hierarchy out of the main
hierarchy before changing the parent, resulting in less memory churn.
Setting the parent to another object in the same hierarchy still causes
a segfault (worked around for now), but the mangled views were caused by
View_UpdateHierarchy not being called prior to the first call to
set_hud_sbar (why, though? I suspect something to do with oldlen). And
ECS_SortComponentPool finally gets used to ensure the sbar panels are
behind the info pics.
Frags, minifrags and miniteam now work (mostly, the auto-switching
between them is not working yet). Switching between hud and sbar is
mostly working, except for some problems with the hierarchies corrupting
themselves: setting the parent of an object to another object in the
same hierarchy is just completely broken, and working with complex
hierarchies seems to mess up something (things getting out of phase). I
guess my unit tests were too simple.
For nq, all that remains is the various overlays (death-match,
intermission and finale) and rogue and hipnotic specific updates.
Fortunately, other than the death-match overlay, qw is just a subset of
nq for the hud (and even then, I imagine the info in qw would be nice in
nq).
While the word-level text objects aren't used (because standard center
print messages are already flowed as such), using a passage object makes
dealing with the lines and incremental printing quite easy and
efficient (everything is counted just the once or twice, not every frame).
Most of the update functions are scheduled by Sbar_Changed() using
tables to determine what update functions need to be called for which
view entities. As hud_updateonce is called, and an entity can have only
one of any component, this becomes a set of updates to call when during
hud/sbar rendering.
This includes moving the related cvars from botn nq and qw into the
client hud code. In addition, the hud code supports update and
update-once function components. The update component is for updates
that occur every frame, but update-once components (not used yet) are
for one-shot updates (eg, when a value updates very infrequently).
Now only the time portion updates every frame, and then only when the
scores are shown (no real change for that one). Not really a significant
optimization, as the information was updated only while the scores were
shown, but it's still nice.
Much of the nq/qw HUD system is quite broken, but the basic status bar
seems to be working nicely. As is the console (both client and server).
Possibly the biggest benefit is separating the rendering of HUD elements
from the updating of them, and much less traversing of invisible views
whose only purpose is to control the positioning of the visible views.
The view flow tests are currently disabled until I adapt the flow code
to ECS.
There seems to be a problem with view resizing in that some gravities
don't follow resizing correctly.
While the libraries are probably getting a little out of hand, the
separation into its own directory is probably a good thing as an ECS
should not be tied to scenes. This should make the ECS more generally
useful.
This is the fix for the grenade explosion bug. It was rather difficult
to track down because *two* explosions are rendered for the one grenade
(but that's actually another bug due to the nq/qw merge). It's also
correct as changing the model can change the BSP leafs the entity
touches.
While chasing down the grenade explosion bug, I noticed that entities
were being created and destroyed (or really, not destroyed) just to
check of the entity was valid. In the old system, this wasn't
*horrible*, but with the ECS, it does mean entities and components are
getting churned up, which wouldn't be good for the entity generation
counter (only 12 bits).
This puts the hierarchy (transform) reference, animation, visibility,
renderer, active, and old_origin data in separate components. There are
a few bugs (crashes on grenade explosions in gl/glsl/vulkan, immediately
in sw, reasons known, missing brush models in vulkan).
While quake doesn't really need an ECS, the direction I want to take QF
does, and it does seem to have improved memory bandwidth a little
(uncertain). However, there's a lot more work to go (especially fixing
the above bugs), but this seems to be a good start.
This breaks console scaling for now (con_width and con_height are gone),
but is a major step towards window resize support as console stuff
should never have been in viddef_t in the first place.
The client screen init code now sets up a screen view (actually the
renderer's scr_view) that is passed to the client console so it can know
the size of the screen. The same view is used by the status bar code.
Also, the ram/cache/paused icon drawing is moved into the client screen
update code. A bit of duplication, but I do plan on merging that
eventually.
The scaling up of the volumes when setting a channel's volume bothered
me. The biggest issue being it hasn't been necessary for over a decade
since the conversion to a float-mixer. Now the volume and attenuation
scaling from protocol bytes is entirely in the client's hands.
This does mean that the gl and sw renderers can no longer call
S_ExtraUpdate, but really, they shouldn't be anyway. And I seem to
remember it not really helping (been way too long since quake ran that
slowly for me).