Angle kicks are used for weapon recoil, damage kicks and the like.
Setting the `cl_anglekicks` to `0` ignored them, they're read from
the network but not displayed. The cvar is cheat protected, it's
reset to `1` on server connect.
Rquested by Martin via mail.
This prevenits the worlds from advancing during client connect. The
player won't get attacked by monsters or hurt by the environment. Note
that in baseq2 there're still 4 world frames processed by the game and
100 world frames if the player enters a level that he or she already
visited. Both aren't a big problem, 4 world frames are hardly enough
for monsters starting to attack and in most levels the starting area
can't be reached by monsters and is free from environmental effects.
Pause mode is only entered for local servers and only in single player
mode. This should prevent problems with coop and deathmatch games.
The behaviour can be controlled by `cl_loadpaused`:
* `0`: Do not enter pause mode, Vanilla Quake I behaviour.
* `1`: Enter pause mode at load and leave it at first regular server
frame.
* `2`: Enter pause mode at load, never leave it. The player must leave
it by hand.
This was requested in issue #417.
My solution to this problem is somewhat hacky. A newly added function
OGG_SaveState() can be called to save the state and OGG_RecoverState()
at a later time to restore it. There's only one state and it works
only iff OGG is state playing.
This closes#347.
...and fix the bugs, that were worked around with that crap, instead.
This removes some corner cases like cancelation of all HTTP downloads
and fallback to UDP if too many 404 errors were generated. If this is
still a problem in reality - for example HTTP servers blocking the
client after too many 404 or even crashing HTTP server - fix the server
and don't force the clients to work around that.
These are:
- CL_ResetPrecacheCheck(): Resets the precacher, forces it to reevaluate
which assets are available and what needs to be downloaded.
- FS_FileInGamedir(): Checks if a file (and only a real file, not
somthing in a pak) is available in fs_gamedir.
- FS_AddPAKFromGamedir(): Adds a pak in fs_gamedir to the search path.
This is a very first cut:
* It compiles
* It doesn't crash
What's missing:
* cmake integration
* CURL should be loaded dynamically
* Integration between download code and filesystem
* Likely UTF-8 stuff
* cl_http.c needs cleanup
* Windows support
The input system backend was once used in the client and the renderers,
but for some years now it has been an integral part of the client only.
Move it there.
On Unix platforms unicode is implemented through UTF-8 which is
transparent for applications. But on Windows a UTF-16 dialect is
used which needs alteration at application side. This wrapper is
another step to unicode support on Windows, now we can replace
fopen() by a function that converts our internal UTF-8 pathes to
Windows UTF-16 dialect.
This is a noop for Unix platforms. The Windows build is broken,
the compiler errors out in shared.h. This will be fixed in a
later commit.
Caveats:
* fopen() calls in 3rd party code (std_* and unzip) are not replaced.
This may become a problem. We need to check that.
* In the Unix specific code fopen() isn't replaced since it's not
necessayry.
If too many of these sounds are started in one frame (for example if the
player shoots with the super shotgun into the power screen of a Brain)
things get too loud and OpenAL is forced to scale the volume of several
other sounds and the background music down. That leads to a noticable
and annoying drop in the overall volume.
Work around that by limiting the number of sounds started. 16 was
choosen by empirical testing.
Miscframes are coupled to renderframes and are just checking for
renderer changes (very cheap) and advancing CD audio if implemented.
There's no reason not to that at every frame.
This allows us to implement the global timing without an artificial
brake slowing the game unnecessary down. This is only partial working,
more changes and fixes are coming.
The old framecounter had two problems:
* It measured only the time of the current render frame, not the total
time spend between the last and the current render frame. Therefor the
calculated value was too high.
* It was based upon milliseconds and rather inaccurate.
This new frame counter solves both problems. The total time spend
between two render frames is measured and the measurement done in
microseconds.
There're three modes:
* cl_drawfps 1 displayes the average frame rate calculated over the last
60 frames.
* cl_drawfps 2 displays a nice string with minimal framerate, maximum
framerate and average framerate. All three values are calculated over
the last 60 frames.
* cl_drawfps 3 is the same as number 2 but with a second line showing the
raw values.
TODO:
* Discuss if cl_drawfps should be renamed to cl_showfps. All other
status displays are named cl_show*.
While at it remove several unsused drawing functions.
This is the same as the well known Sys_Milliseconds() but like the name
suggests with microsecond precision. To be used in the upcoming new
framecounter.
Until now autoexec.cfg was a special case. It was read several
times, whenever the 'game' cvar was altered or when the client was
restarted. But only if it was in the right directory in the right
position of the internal search path... Remove this altogether and
replace it by an ordinary 'exec autoexec.cfg' at startup.
This may break some mods that depend on an autoexec.cfg if the user has
his own version in ~/.yq2/. Such mods should use default.cfg instead.
This closes issue #163.
With vsync enabled the render times of consecutive frames can diverge.
The first frame arrives right at the next display frame and is rendered
without waiting time. The next frame has to wait 20ms. The leads to some
problems with the move prediction if the client is asynchronous. Fix
this by capping the desired frame rate at the display refresh rate. Also
make sure that the network framerate is never higher then the renderer
framerate.
With the commit the timing is always correct:
* With no limit as much frames as possible are rendered. In this case
rfps > nfps and everything's good.
* With vsync enabled rfps > nfps or rfps == nfps is given. Also rfps
will never exceed the display refresh rate.
* On slow hardware either rfps > nfps or an implicit rfpc == nfps is
given.
Yesterday I chose setting cl_async to 0 since I saw some movement
changed with the async client enabled. Especially when clipping against
bevels the game started to stutter and there were small rendering
problems. After some debugging I realized that it is caused by slight
inaccuracies in the move prediction. When cl_maxfps is too low, the
movement error between two render frames becomes to big, leading to
misspositions. There're two ways to solve this problem:
* Processing more client frames. Most async clients I've looked on
process 60 or even 90 render frames. I chose to stay at 60 since
I was unable to see differences with higher rates.
* Changed to pmove.c and the pmove_t struct. Some multiplayer focused
clients go that way. But there's a very high of breaking singleplayer
movement and pmove_t is part of the server <-> game API. Additionally
the network code must / should be altered. So this is unsuitable for
YQ2.
Please note that there's still a change in movement. Before 4ae8706 and
when cl_async is set to 0 movement is dependend on the render framerate.
At low framerate bevel clipping isn't working too good, at high
framerates prediction causes physics changes like the famous 125hz bug.
With cl_async set to 1 the network framerate is stable, leading to a
more consistant behahiour.
Most (all?) clients implement the synchronous and the asynchronous
client by seperate code pathes. Instead of doing that we force the
asynchronous path to process one network frame for each render frame.
This is more than enough for everyone and prevents wasting CPU time.
Without this change as many client frames as possible are rendered,
Quake II uses a complete core.
This is largely based upon the cl_async 1 mode from KMQuake2, which in
turn is based upon r1q2. The origins of this code may be even older...
Different to KMQuake2 the asynchonous mode is not optional, the client
is always asynchonous. Since we're mainly integrating this rather
fundamental change to simplify the complex internal timing between
client, server and refresh, there's no point in keeping it optional.
The old cl_maxfps cvar controls the network frames. 30 frames should be
enough, even Q3A hasn't more. The new gl_maxfps cvar controls the render
frames. It's set to 95 fps by default to avoid possible remnant of the
famous 125hz bug.
it's saved in $HOME/.yq2/$mod/history.txt
While I was at it, I made the max number of lines in the history
configurable at compiletime by introducing a NUM_KEY_LINES #define
In the old times the refresher was a stand alone DLL. For performance
reasons and to avoid laggy input parts of the input system were
implemented in this DLL. Now that the renfresher is part of the main
binary and initialized at client startup we can remove most of the
abstractions between input system, refresher and client. Also the
input system can be treated as a normal subsystem.
Changes:
- Untangle the VID_* stuff and the IN_* stuff. The functions
called by function pointers in in_state are now called directly
and 'struct in_state' was removed.
- Remove input.h and rename the appropriate backend functions.
There's no longer a need for an abstraction layer between the
input backend and the input frontend.
- Move input initialization and shutdown into CL_Init(), like it's
already done for all other subsystems.
- Remove Key_ClearStates(). I'm pretty sure that's a left over from
the old Win 9x backends and unnecessary.
- General cleanup.
This change is needed to break a otherwise fatal cycle:
- The renderer calls VID_MenuInit()
- VID_MenuInit() calls SCR_GetMenuScale()
- SCR_GetMenuScale() relies on gl_menuscale which is still
uninitialized at this time.
Input devices should send key events and nothing more. The ability to
add commands into the input buffer was used by the joystick code
(removed long time ago) and as a dirty hack to work around limitations
of DirectInput.
Revert "change several strcat calls to Q_strlcat calls"
This reverts commit ab879f1bc7.
Revert "change (v)sprintf calls to (v)snprintf calls"
This reverts commit b46e210d76.