2001-02-19 21:15:25 +00:00
|
|
|
/*
|
|
|
|
cl_main.c
|
|
|
|
|
2001-05-09 05:41:34 +00:00
|
|
|
entity parsing and management
|
2001-02-19 21:15:25 +00:00
|
|
|
|
|
|
|
Copyright (C) 1996-1997 Id Software, Inc.
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
as published by the Free Software Foundation; either version 2
|
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to:
|
|
|
|
|
|
|
|
Free Software Foundation, Inc.
|
|
|
|
59 Temple Place - Suite 330
|
|
|
|
Boston, MA 02111-1307, USA
|
|
|
|
|
|
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
2002-07-31 05:19:03 +00:00
|
|
|
#include "QF/cbuf.h"
|
2011-12-22 06:44:28 +00:00
|
|
|
#include "QF/cdaudio.h"
|
2001-05-09 05:41:34 +00:00
|
|
|
#include "QF/cmd.h"
|
|
|
|
#include "QF/console.h"
|
2001-03-27 20:33:07 +00:00
|
|
|
#include "QF/cvar.h"
|
2011-12-22 06:44:28 +00:00
|
|
|
#include "QF/draw.h"
|
2022-05-26 08:10:23 +00:00
|
|
|
#include "QF/gib.h"
|
2001-05-09 05:41:34 +00:00
|
|
|
#include "QF/input.h"
|
2022-05-26 07:17:00 +00:00
|
|
|
#include "QF/image.h"
|
2013-01-25 19:27:38 +00:00
|
|
|
#include "QF/joystick.h"
|
2001-05-15 05:27:14 +00:00
|
|
|
#include "QF/keys.h"
|
2001-05-09 05:41:34 +00:00
|
|
|
#include "QF/msg.h"
|
2022-05-26 07:17:00 +00:00
|
|
|
#include "QF/png.h"
|
2021-03-21 07:13:03 +00:00
|
|
|
#include "QF/plist.h"
|
2001-05-21 22:25:35 +00:00
|
|
|
#include "QF/render.h"
|
2001-05-09 05:41:34 +00:00
|
|
|
#include "QF/screen.h"
|
2001-05-21 22:25:35 +00:00
|
|
|
#include "QF/skin.h"
|
2022-06-03 06:43:53 +00:00
|
|
|
#include "QF/sound.h"
|
2007-11-06 10:17:14 +00:00
|
|
|
#include "QF/sys.h"
|
2001-05-09 05:41:34 +00:00
|
|
|
#include "QF/va.h"
|
|
|
|
|
2012-02-13 12:58:34 +00:00
|
|
|
#include "QF/plugin/console.h"
|
2012-02-14 08:28:09 +00:00
|
|
|
#include "QF/plugin/vid_render.h"
|
2021-07-24 05:19:52 +00:00
|
|
|
#include "QF/scene/entity.h"
|
2022-03-04 16:48:10 +00:00
|
|
|
#include "QF/scene/scene.h"
|
2012-02-13 12:58:34 +00:00
|
|
|
|
2001-06-29 02:43:04 +00:00
|
|
|
#include "compat.h"
|
2011-12-22 06:44:28 +00:00
|
|
|
#include "sbar.h"
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2022-03-04 16:48:10 +00:00
|
|
|
#include "client/chase.h"
|
2021-12-19 04:08:39 +00:00
|
|
|
#include "client/particles.h"
|
2021-03-10 09:00:16 +00:00
|
|
|
#include "client/temp_entities.h"
|
2022-03-04 16:48:10 +00:00
|
|
|
#include "client/world.h"
|
2021-03-10 09:00:16 +00:00
|
|
|
|
2020-06-21 14:15:17 +00:00
|
|
|
#include "nq/include/cl_skin.h"
|
|
|
|
#include "nq/include/client.h"
|
|
|
|
#include "nq/include/host.h"
|
|
|
|
#include "nq/include/server.h"
|
|
|
|
|
2012-02-26 09:45:50 +00:00
|
|
|
CLIENT_PLUGIN_PROTOS
|
|
|
|
static plugin_list_t client_plugin_list[] = {
|
|
|
|
CLIENT_PLUGIN_LIST
|
|
|
|
};
|
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
// these two are not intended to be set directly
|
[cvar] Make cvars properly typed
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.
2022-04-23 03:22:45 +00:00
|
|
|
char *cl_name;
|
|
|
|
static cvar_t cl_name_cvar = {
|
|
|
|
.name = "_cl_name",
|
|
|
|
.description =
|
|
|
|
"Player name",
|
|
|
|
.default_value = "player",
|
|
|
|
.flags = CVAR_ARCHIVE,
|
|
|
|
.value = { .type = 0, .value = &cl_name },
|
|
|
|
};
|
|
|
|
int cl_color;
|
|
|
|
static cvar_t cl_color_cvar = {
|
|
|
|
.name = "_cl_color",
|
|
|
|
.description =
|
|
|
|
"Player color",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_ARCHIVE,
|
|
|
|
.value = { .type = &cexpr_int, .value = &cl_color },
|
|
|
|
};
|
2001-02-26 06:48:02 +00:00
|
|
|
|
[cvar] Make cvars properly typed
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.
2022-04-23 03:22:45 +00:00
|
|
|
int cl_writecfg;
|
|
|
|
static cvar_t cl_writecfg_cvar = {
|
|
|
|
.name = "cl_writecfg",
|
|
|
|
.description =
|
|
|
|
"write config files?",
|
|
|
|
.default_value = "1",
|
|
|
|
.flags = CVAR_NONE,
|
|
|
|
.value = { .type = &cexpr_int, .value = &cl_writecfg },
|
|
|
|
};
|
2001-05-14 19:46:16 +00:00
|
|
|
|
[cvar] Make cvars properly typed
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.
2022-04-23 03:22:45 +00:00
|
|
|
int cl_shownet;
|
|
|
|
static cvar_t cl_shownet_cvar = {
|
|
|
|
.name = "cl_shownet",
|
|
|
|
.description =
|
|
|
|
"show network packets. 0=off, 1=basic, 2=verbose",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_NONE,
|
|
|
|
.value = { .type = &cexpr_int, .value = &cl_shownet },
|
|
|
|
};
|
|
|
|
int cl_nolerp;
|
|
|
|
static cvar_t cl_nolerp_cvar = {
|
|
|
|
.name = "cl_nolerp",
|
|
|
|
.description =
|
|
|
|
"linear motion interpolation",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_NONE,
|
|
|
|
.value = { .type = &cexpr_int, .value = &cl_nolerp },
|
|
|
|
};
|
2001-02-19 21:15:25 +00:00
|
|
|
|
[cvar] Make cvars properly typed
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.
2022-04-23 03:22:45 +00:00
|
|
|
int hud_fps;
|
|
|
|
static cvar_t hud_fps_cvar = {
|
|
|
|
.name = "hud_fps",
|
|
|
|
.description =
|
|
|
|
"display realtime frames per second",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_ARCHIVE,
|
|
|
|
.value = { .type = &cexpr_int, .value = &hud_fps },
|
|
|
|
};
|
|
|
|
int hud_time;
|
|
|
|
static cvar_t hud_time_cvar = {
|
|
|
|
.name = "hud_time",
|
|
|
|
.description =
|
|
|
|
"display the current time",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_ARCHIVE,
|
|
|
|
.value = { .type = &cexpr_int, .value = &hud_time },
|
|
|
|
};
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2022-04-24 11:04:06 +00:00
|
|
|
static int r_ambient;
|
[cvar] Make cvars properly typed
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.
2022-04-23 03:22:45 +00:00
|
|
|
static cvar_t r_ambient_cvar = {
|
|
|
|
.name = "r_ambient",
|
|
|
|
.description =
|
|
|
|
"Determines the ambient lighting for a level",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_NONE,
|
2022-04-24 11:04:06 +00:00
|
|
|
.value = { .type = &cexpr_int, .value = &r_ambient },
|
[cvar] Make cvars properly typed
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.
2022-04-23 03:22:45 +00:00
|
|
|
};
|
2022-04-24 11:04:06 +00:00
|
|
|
static int r_drawflat;
|
[cvar] Make cvars properly typed
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.
2022-04-23 03:22:45 +00:00
|
|
|
static cvar_t r_drawflat_cvar = {
|
|
|
|
.name = "r_drawflat",
|
|
|
|
.description =
|
|
|
|
"Toggles the drawing of textures",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_NONE,
|
2022-04-24 11:04:06 +00:00
|
|
|
.value = { .type = &cexpr_int, .value = &r_drawflat },
|
[cvar] Make cvars properly typed
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.
2022-04-23 03:22:45 +00:00
|
|
|
};
|
2022-03-09 13:51:21 +00:00
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
int fps_count;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
client_static_t cls;
|
|
|
|
client_state_t cl;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2011-12-22 06:44:28 +00:00
|
|
|
/*
|
|
|
|
CL_WriteConfiguration
|
|
|
|
|
|
|
|
Writes key bindings and archived cvars to config.cfg
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
CL_WriteConfiguration (void)
|
|
|
|
{
|
|
|
|
// dedicated servers initialize the host but don't parse and set the
|
|
|
|
// config.cfg cvars
|
[cvar] Make cvars properly typed
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.
2022-04-23 03:22:45 +00:00
|
|
|
if (host_initialized && !isDedicated && cl_writecfg) {
|
2022-05-12 08:54:23 +00:00
|
|
|
plitem_t *config = PL_NewDictionary (0);
|
2021-11-18 06:27:44 +00:00
|
|
|
Cvar_SaveConfig (config);
|
|
|
|
IN_SaveConfig (config);
|
|
|
|
|
2021-04-12 13:09:09 +00:00
|
|
|
const char *path = va (0, "%s/quakeforge.cfg", qfs_gamedir->dir.def);
|
|
|
|
QFile *f = QFS_WOpen (path, 0);
|
|
|
|
|
2011-12-22 06:44:28 +00:00
|
|
|
if (!f) {
|
2021-04-12 13:09:09 +00:00
|
|
|
Sys_Printf ("Couldn't write quakeforge.cfg.\n");
|
2021-11-18 06:27:44 +00:00
|
|
|
} else {
|
|
|
|
char *cfg = PL_WritePropertyList (config);
|
|
|
|
Qputs (f, cfg);
|
|
|
|
free (cfg);
|
|
|
|
Qclose (f);
|
2011-12-22 06:44:28 +00:00
|
|
|
}
|
2021-11-18 06:27:44 +00:00
|
|
|
PL_Free (config);
|
|
|
|
}
|
|
|
|
}
|
2011-12-22 06:44:28 +00:00
|
|
|
|
2021-11-18 06:27:44 +00:00
|
|
|
int
|
|
|
|
CL_ReadConfiguration (const char *cfg_name)
|
|
|
|
{
|
|
|
|
QFile *cfg_file = QFS_FOpenFile (cfg_name);
|
|
|
|
if (!cfg_file) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
size_t len = Qfilesize (cfg_file);
|
|
|
|
char *cfg = malloc (len + 1);
|
|
|
|
Qread (cfg_file, cfg, len);
|
|
|
|
cfg[len] = 0;
|
|
|
|
Qclose (cfg_file);
|
|
|
|
|
2022-05-12 08:54:23 +00:00
|
|
|
plitem_t *config = PL_GetPropertyList (cfg, 0);
|
2022-05-12 11:15:19 +00:00
|
|
|
free (cfg);
|
|
|
|
|
2021-11-18 06:27:44 +00:00
|
|
|
if (!config) {
|
|
|
|
return 0;
|
2011-12-22 06:44:28 +00:00
|
|
|
}
|
2021-11-18 06:27:44 +00:00
|
|
|
|
|
|
|
Cvar_LoadConfig (config);
|
|
|
|
IN_LoadConfig (config);
|
|
|
|
|
|
|
|
PL_Free (config);
|
|
|
|
return 1;
|
2011-12-22 06:44:28 +00:00
|
|
|
}
|
|
|
|
|
2019-07-12 14:15:26 +00:00
|
|
|
static void
|
2020-06-25 05:03:52 +00:00
|
|
|
CL_Shutdown (void *data)
|
2011-12-22 06:44:28 +00:00
|
|
|
{
|
|
|
|
CL_WriteConfiguration ();
|
|
|
|
}
|
|
|
|
|
2019-07-08 03:46:22 +00:00
|
|
|
void
|
|
|
|
CL_ClearMemory (void)
|
|
|
|
{
|
|
|
|
VID_ClearMemory ();
|
2022-03-18 15:56:30 +00:00
|
|
|
SCR_SetFullscreen (0);
|
2022-04-08 09:27:53 +00:00
|
|
|
|
|
|
|
cls.signon = 0;
|
2022-05-12 13:49:48 +00:00
|
|
|
SZ_Clear (&cls.message);
|
|
|
|
|
|
|
|
if (cl.viewstate.weapon_entity) {
|
|
|
|
Scene_DestroyEntity (cl_world.scene, cl.viewstate.weapon_entity);
|
|
|
|
}
|
|
|
|
if (cl.players) {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < cl.maxclients; i++)
|
|
|
|
Info_Destroy (cl.players[i].userinfo);
|
|
|
|
}
|
|
|
|
// wipe the entire cl structure
|
2022-04-08 09:27:53 +00:00
|
|
|
__auto_type cam = cl.viewstate.camera_transform;
|
|
|
|
memset (&cl, 0, sizeof (cl));
|
|
|
|
cl.viewstate.camera_transform = cam;
|
2022-05-12 13:49:48 +00:00
|
|
|
|
|
|
|
CL_ClearTEnts ();
|
|
|
|
|
|
|
|
SCR_NewScene (0);
|
|
|
|
|
|
|
|
CL_ClearEnts ();
|
2011-12-22 06:44:28 +00:00
|
|
|
}
|
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
void
|
2001-02-26 06:48:02 +00:00
|
|
|
CL_InitCvars (void)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2011-12-22 06:44:28 +00:00
|
|
|
VID_Init_Cvars ();
|
2012-02-01 12:52:47 +00:00
|
|
|
IN_Init_Cvars ();
|
2011-12-22 06:44:28 +00:00
|
|
|
Mod_Init_Cvars ();
|
2012-02-01 12:52:47 +00:00
|
|
|
S_Init_Cvars ();
|
2011-12-22 06:44:28 +00:00
|
|
|
|
|
|
|
CL_Demo_Init ();
|
2022-02-22 06:23:09 +00:00
|
|
|
CL_Init_Input_Cvars ();
|
2012-02-01 12:52:47 +00:00
|
|
|
Chase_Init_Cvars ();
|
|
|
|
V_Init_Cvars ();
|
2011-12-22 06:44:28 +00:00
|
|
|
|
[cvar] Make cvars properly typed
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.
2022-04-23 03:22:45 +00:00
|
|
|
Cvar_Register (&cl_name_cvar, 0, 0);
|
|
|
|
Cvar_Register (&cl_color_cvar, 0, 0);
|
|
|
|
Cvar_Register (&cl_writecfg_cvar, 0, 0);
|
|
|
|
Cvar_Register (&cl_shownet_cvar, 0, 0);
|
|
|
|
Cvar_Register (&cl_nolerp_cvar, 0, 0);
|
|
|
|
Cvar_Register (&hud_fps_cvar, 0, 0);
|
|
|
|
Cvar_MakeAlias ("show_fps", &hud_fps_cvar);
|
|
|
|
Cvar_Register (&hud_time_cvar, 0, 0);
|
2022-03-09 13:51:21 +00:00
|
|
|
|
|
|
|
//FIXME not hooked up (don't do anything), but should not work in
|
|
|
|
//multi-player
|
[cvar] Make cvars properly typed
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.
2022-04-23 03:22:45 +00:00
|
|
|
Cvar_Register (&r_ambient_cvar, 0, 0);
|
|
|
|
Cvar_Register (&r_drawflat_cvar, 0, 0);
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
void
|
|
|
|
CL_ClearState (void)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2022-05-12 13:49:48 +00:00
|
|
|
CL_ClearMemory ();
|
2001-02-19 21:15:25 +00:00
|
|
|
if (!sv.active)
|
|
|
|
Host_ClearMemory ();
|
|
|
|
|
2022-03-01 05:44:53 +00:00
|
|
|
cl.viewstate.player_origin = (vec4f_t) {0, 0, 0, 1};
|
2022-02-25 06:48:57 +00:00
|
|
|
cl.viewstate.chase = 1;
|
|
|
|
cl.viewstate.chasestate = &cl.chasestate;
|
2022-03-01 02:43:23 +00:00
|
|
|
cl.chasestate.viewstate = &cl.viewstate;
|
2012-06-03 00:30:31 +00:00
|
|
|
cl.watervis = 1;
|
2022-03-18 15:56:30 +00:00
|
|
|
SCR_SetFullscreen (0);
|
2012-02-14 08:28:09 +00:00
|
|
|
r_data->lightstyle = cl.lightstyle;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2022-03-04 16:48:10 +00:00
|
|
|
cl.viewstate.weapon_entity = Scene_CreateEntity (cl_world.scene);
|
|
|
|
CL_Init_Entity (cl.viewstate.weapon_entity);
|
|
|
|
r_data->view_model = cl.viewstate.weapon_entity;
|
2022-05-13 12:24:45 +00:00
|
|
|
|
|
|
|
CL_TEnts_Precache ();
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
2001-05-13 23:15:34 +00:00
|
|
|
/*
|
|
|
|
CL_StopCshifts
|
|
|
|
|
|
|
|
Cleans the Cshifts, so your screen doesn't stay red after a timedemo :)
|
|
|
|
*/
|
2003-01-06 18:28:13 +00:00
|
|
|
static void
|
2001-05-13 23:15:34 +00:00
|
|
|
CL_StopCshifts (void)
|
|
|
|
{
|
|
|
|
int i;
|
2001-08-29 02:12:57 +00:00
|
|
|
|
2001-05-13 23:15:34 +00:00
|
|
|
for (i = 0; i < NUM_CSHIFTS; i++)
|
2022-02-25 06:48:57 +00:00
|
|
|
cl.viewstate.cshifts[i].percent = 0;
|
2001-05-13 23:15:34 +00:00
|
|
|
for (i = 0; i < MAX_CL_STATS; i++)
|
|
|
|
cl.stats[i] = 0;
|
|
|
|
}
|
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
/*
|
2001-05-11 01:01:27 +00:00
|
|
|
CL_Disconnect
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-05-11 01:01:27 +00:00
|
|
|
Sends a disconnect message to the server
|
|
|
|
This is also called on Host_Error, so it shouldn't cause any errors
|
2001-02-19 21:15:25 +00:00
|
|
|
*/
|
2001-02-26 06:48:02 +00:00
|
|
|
void
|
|
|
|
CL_Disconnect (void)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2001-05-13 23:15:34 +00:00
|
|
|
// stop sounds (especially looping!)
|
2007-03-17 03:10:45 +00:00
|
|
|
S_StopAllSounds ();
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-05-13 23:15:34 +00:00
|
|
|
// Clean the Cshifts
|
|
|
|
CL_StopCshifts ();
|
|
|
|
|
|
|
|
// if running a local server, shut it down
|
2001-02-19 21:15:25 +00:00
|
|
|
if (cls.demoplayback)
|
|
|
|
CL_StopPlayback ();
|
2012-05-23 12:38:25 +00:00
|
|
|
else if (cls.state >= ca_connected) {
|
2001-02-19 21:15:25 +00:00
|
|
|
if (cls.demorecording)
|
2011-06-03 13:47:32 +00:00
|
|
|
CL_StopRecording ();
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2021-03-29 10:58:00 +00:00
|
|
|
Sys_MaskPrintf (SYS_dev, "Sending clc_disconnect\n");
|
2001-02-19 21:15:25 +00:00
|
|
|
SZ_Clear (&cls.message);
|
|
|
|
MSG_WriteByte (&cls.message, clc_disconnect);
|
|
|
|
NET_SendUnreliableMessage (cls.netcon, &cls.message);
|
|
|
|
SZ_Clear (&cls.message);
|
|
|
|
NET_Close (cls.netcon);
|
|
|
|
|
2001-08-20 17:48:16 +00:00
|
|
|
CL_SetState (ca_disconnected);
|
2001-02-19 21:15:25 +00:00
|
|
|
if (sv.active)
|
2001-02-26 06:48:02 +00:00
|
|
|
Host_ShutdownServer (false);
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
2022-05-05 05:41:46 +00:00
|
|
|
cl_world.scene->worldmodel = NULL;
|
2012-07-21 08:53:49 +00:00
|
|
|
cl.intermission = 0;
|
2022-02-25 06:48:57 +00:00
|
|
|
cl.viewstate.intermission = 0;
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
void
|
|
|
|
CL_Disconnect_f (void)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
|
|
|
CL_Disconnect ();
|
|
|
|
if (sv.active)
|
|
|
|
Host_ShutdownServer (false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2001-05-11 01:01:27 +00:00
|
|
|
CL_EstablishConnection
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-05-11 01:01:27 +00:00
|
|
|
Host should be either "local" or a net address to be passed on
|
2001-02-19 21:15:25 +00:00
|
|
|
*/
|
2001-02-26 06:48:02 +00:00
|
|
|
void
|
2001-07-15 07:04:17 +00:00
|
|
|
CL_EstablishConnection (const char *host)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2022-04-06 10:32:55 +00:00
|
|
|
if (net_is_dedicated)
|
2001-02-19 21:15:25 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (cls.demoplayback)
|
|
|
|
return;
|
|
|
|
|
|
|
|
CL_Disconnect ();
|
|
|
|
|
|
|
|
cls.netcon = NET_Connect (host);
|
|
|
|
if (!cls.netcon)
|
|
|
|
Host_Error ("CL_Connect: connect failed\n");
|
2021-03-29 10:58:00 +00:00
|
|
|
Sys_MaskPrintf (SYS_dev, "CL_EstablishConnection: connected to %s\n",
|
2010-11-23 05:09:30 +00:00
|
|
|
host);
|
2001-02-26 06:48:02 +00:00
|
|
|
|
|
|
|
cls.demonum = -1; // not in the demo loop now
|
2001-08-20 17:48:16 +00:00
|
|
|
CL_SetState (ca_connected);
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2001-05-11 01:01:27 +00:00
|
|
|
CL_SignonReply
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-05-11 01:01:27 +00:00
|
|
|
An svc_signonnum has been received, perform a client side setup
|
2001-02-19 21:15:25 +00:00
|
|
|
*/
|
2001-02-26 06:48:02 +00:00
|
|
|
void
|
|
|
|
CL_SignonReply (void)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2021-03-29 10:58:00 +00:00
|
|
|
Sys_MaskPrintf (SYS_dev, "CL_SignonReply: %i\n", cls.signon);
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
switch (cls.signon) {
|
2012-05-23 12:38:25 +00:00
|
|
|
case so_none:
|
|
|
|
break;
|
|
|
|
case so_prespawn:
|
2001-02-19 21:15:25 +00:00
|
|
|
MSG_WriteByte (&cls.message, clc_stringcmd);
|
|
|
|
MSG_WriteString (&cls.message, "prespawn");
|
|
|
|
break;
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2012-05-23 12:38:25 +00:00
|
|
|
case so_spawn:
|
2001-02-19 21:15:25 +00:00
|
|
|
MSG_WriteByte (&cls.message, clc_stringcmd);
|
2021-01-31 07:01:20 +00:00
|
|
|
MSG_WriteString (&cls.message, va (0, "name \"%s\"\n",
|
[cvar] Make cvars properly typed
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.
2022-04-23 03:22:45 +00:00
|
|
|
cl_name));
|
2001-02-19 21:15:25 +00:00
|
|
|
MSG_WriteByte (&cls.message, clc_stringcmd);
|
2001-02-26 06:48:02 +00:00
|
|
|
MSG_WriteString (&cls.message,
|
[cvar] Make cvars properly typed
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.
2022-04-23 03:22:45 +00:00
|
|
|
va (0, "color %i %i\n", (cl_color) >> 4,
|
|
|
|
(cl_color) & 15));
|
2001-02-19 21:15:25 +00:00
|
|
|
MSG_WriteByte (&cls.message, clc_stringcmd);
|
2012-05-24 11:17:41 +00:00
|
|
|
MSG_WriteString (&cls.message, "spawn");
|
2001-02-19 21:15:25 +00:00
|
|
|
break;
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2012-05-23 12:38:25 +00:00
|
|
|
case so_begin:
|
2001-02-19 21:15:25 +00:00
|
|
|
MSG_WriteByte (&cls.message, clc_stringcmd);
|
|
|
|
MSG_WriteString (&cls.message, "begin");
|
2001-02-26 06:48:02 +00:00
|
|
|
Cache_Report (); // print remaining memory
|
2001-02-19 21:15:25 +00:00
|
|
|
break;
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2012-05-23 12:38:25 +00:00
|
|
|
case so_active:
|
2011-12-09 09:41:52 +00:00
|
|
|
cl.loading = false;
|
2012-05-23 12:38:25 +00:00
|
|
|
CL_SetState (ca_active);
|
2001-02-19 21:15:25 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2001-05-11 01:01:27 +00:00
|
|
|
CL_NextDemo
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-05-11 01:01:27 +00:00
|
|
|
Called to play the next demo in the demo loop
|
2001-02-19 21:15:25 +00:00
|
|
|
*/
|
2001-02-26 06:48:02 +00:00
|
|
|
void
|
|
|
|
CL_NextDemo (void)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
|
|
|
if (cls.demonum == -1)
|
2001-02-26 06:48:02 +00:00
|
|
|
return; // don't play demos
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2011-12-09 09:41:52 +00:00
|
|
|
cl.loading = true;
|
|
|
|
CL_UpdateScreen(cl.time);
|
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
if (!cls.demos[cls.demonum][0] || cls.demonum == MAX_DEMOS) {
|
2001-02-19 21:15:25 +00:00
|
|
|
cls.demonum = 0;
|
2001-02-26 06:48:02 +00:00
|
|
|
if (!cls.demos[cls.demonum][0]) {
|
2007-11-06 10:17:14 +00:00
|
|
|
Sys_Printf ("No demos listed with startdemos\n");
|
2001-02-19 21:15:25 +00:00
|
|
|
cls.demonum = -1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-31 07:01:20 +00:00
|
|
|
Cbuf_InsertText (host_cbuf, va (0, "playdemo %s\n",
|
|
|
|
cls.demos[cls.demonum]));
|
2001-02-19 21:15:25 +00:00
|
|
|
cls.demonum++;
|
|
|
|
}
|
|
|
|
|
2021-12-20 15:36:42 +00:00
|
|
|
static void
|
|
|
|
pointfile_f (void)
|
|
|
|
{
|
2022-05-05 05:41:46 +00:00
|
|
|
CL_LoadPointFile (cl_world.scene->worldmodel);
|
2021-12-20 15:36:42 +00:00
|
|
|
}
|
|
|
|
|
2003-01-06 18:28:13 +00:00
|
|
|
static void
|
2001-02-26 06:48:02 +00:00
|
|
|
CL_PrintEntities_f (void)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2001-02-26 06:48:02 +00:00
|
|
|
int i;
|
|
|
|
|
2022-03-04 16:48:10 +00:00
|
|
|
for (i = 0; i < cl.num_entities; i++) {
|
|
|
|
entity_t *ent = cl_entities[i];
|
2007-11-06 10:17:14 +00:00
|
|
|
Sys_Printf ("%3i:", i);
|
2022-03-04 16:48:10 +00:00
|
|
|
if (!ent || !ent->renderer.model) {
|
2007-11-06 10:17:14 +00:00
|
|
|
Sys_Printf ("EMPTY\n");
|
2001-02-19 21:15:25 +00:00
|
|
|
continue;
|
|
|
|
}
|
2021-03-19 11:18:45 +00:00
|
|
|
vec4f_t org = Transform_GetWorldPosition (ent->transform);
|
|
|
|
vec4f_t rot = Transform_GetWorldRotation (ent->transform);
|
|
|
|
Sys_Printf ("%s:%2i "VEC4F_FMT" "VEC4F_FMT"\n",
|
2021-03-09 14:52:40 +00:00
|
|
|
ent->renderer.model->path, ent->animation.frame,
|
2021-03-19 11:18:45 +00:00
|
|
|
VEC4_EXP (org), VEC4_EXP (rot));
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2001-05-14 19:46:16 +00:00
|
|
|
CL_ReadFromServer
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-05-14 19:46:16 +00:00
|
|
|
Read all incoming data from the server
|
2001-02-19 21:15:25 +00:00
|
|
|
*/
|
2001-02-26 06:48:02 +00:00
|
|
|
int
|
|
|
|
CL_ReadFromServer (void)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2001-02-26 06:48:02 +00:00
|
|
|
int ret;
|
2021-03-10 09:00:16 +00:00
|
|
|
TEntContext_t tentCtx = {
|
2022-03-04 16:48:10 +00:00
|
|
|
cl.viewstate.player_origin,
|
|
|
|
cl.viewentity
|
2021-03-10 09:00:16 +00:00
|
|
|
};
|
2001-02-19 21:15:25 +00:00
|
|
|
|
|
|
|
cl.oldtime = cl.time;
|
|
|
|
cl.time += host_frametime;
|
2021-03-19 11:18:45 +00:00
|
|
|
cl.viewstate.frametime = host_frametime;
|
2022-02-25 06:48:57 +00:00
|
|
|
cl.viewstate.time = cl.time;
|
2001-02-26 06:48:02 +00:00
|
|
|
|
|
|
|
do {
|
2001-02-19 21:15:25 +00:00
|
|
|
ret = CL_GetMessage ();
|
|
|
|
if (ret == -1)
|
|
|
|
Host_Error ("CL_ReadFromServer: lost server connection");
|
|
|
|
if (!ret)
|
|
|
|
break;
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
CL_ParseServerMessage ();
|
2012-05-23 12:38:25 +00:00
|
|
|
} while (ret && cls.state >= ca_connected);
|
2001-02-26 06:48:02 +00:00
|
|
|
|
[cvar] Make cvars properly typed
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.
2022-04-23 03:22:45 +00:00
|
|
|
if (cl_shownet)
|
2007-11-06 10:17:14 +00:00
|
|
|
Sys_Printf ("\n");
|
2001-02-19 21:15:25 +00:00
|
|
|
|
|
|
|
CL_RelinkEntities ();
|
2021-03-10 09:00:16 +00:00
|
|
|
CL_UpdateTEnts (cl.time, &tentCtx);
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-05-14 19:46:16 +00:00
|
|
|
// bring the links up to date
|
2001-02-19 21:15:25 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
void
|
|
|
|
CL_SendCmd (void)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2001-02-26 06:48:02 +00:00
|
|
|
usercmd_t cmd;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2012-05-23 12:38:25 +00:00
|
|
|
if (cls.state < ca_connected)
|
2001-02-19 21:15:25 +00:00
|
|
|
return;
|
|
|
|
|
2012-05-23 12:38:25 +00:00
|
|
|
if (cls.state == ca_active) {
|
2001-02-19 21:15:25 +00:00
|
|
|
CL_BaseMove (&cmd);
|
2001-02-26 06:48:02 +00:00
|
|
|
|
|
|
|
// send the unreliable message
|
2001-02-19 21:15:25 +00:00
|
|
|
CL_SendMove (&cmd);
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
if (cls.demoplayback) {
|
2001-02-19 21:15:25 +00:00
|
|
|
SZ_Clear (&cls.message);
|
|
|
|
return;
|
|
|
|
}
|
2001-05-14 19:46:16 +00:00
|
|
|
// send the reliable message
|
2001-02-19 21:15:25 +00:00
|
|
|
if (!cls.message.cursize)
|
2001-02-26 06:48:02 +00:00
|
|
|
return; // no message at all
|
|
|
|
|
|
|
|
if (!NET_CanSendMessage (cls.netcon)) {
|
2021-03-29 10:58:00 +00:00
|
|
|
Sys_MaskPrintf (SYS_dev, "CL_WriteToServer: can't send\n");
|
2001-02-19 21:15:25 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NET_SendMessage (cls.netcon, &cls.message) == -1)
|
|
|
|
Host_Error ("CL_WriteToServer: lost server connection");
|
|
|
|
|
|
|
|
SZ_Clear (&cls.message);
|
|
|
|
}
|
|
|
|
|
2001-08-20 17:48:16 +00:00
|
|
|
void
|
|
|
|
CL_SetState (cactive_t state)
|
|
|
|
{
|
2002-08-27 08:33:21 +00:00
|
|
|
cactive_t old_state = cls.state;
|
2001-08-20 17:48:16 +00:00
|
|
|
cls.state = state;
|
2022-02-25 06:48:57 +00:00
|
|
|
cl.viewstate.active = cls.state == ca_active;
|
|
|
|
cl.viewstate.drift_enabled = !cls.demoplayback;
|
2021-03-29 10:58:00 +00:00
|
|
|
Sys_MaskPrintf (SYS_net, "CL_SetState: %d -> %d\n", old_state, state);
|
2002-08-27 08:33:21 +00:00
|
|
|
if (old_state != state) {
|
2022-05-11 05:14:43 +00:00
|
|
|
if (old_state == ca_active && state != ca_disconnected) {
|
2002-08-27 08:33:21 +00:00
|
|
|
// leaving active state
|
2010-08-24 00:53:54 +00:00
|
|
|
S_AmbientOff ();
|
2022-05-11 05:14:43 +00:00
|
|
|
SCR_NewScene (0);
|
2012-05-23 12:38:25 +00:00
|
|
|
}
|
|
|
|
switch (state) {
|
|
|
|
case ca_disconnected:
|
2021-12-02 09:30:57 +00:00
|
|
|
CL_ClearState ();
|
2012-05-23 12:38:25 +00:00
|
|
|
cls.signon = so_none;
|
2012-07-06 01:44:29 +00:00
|
|
|
cl.loading = false;
|
2012-05-23 12:38:25 +00:00
|
|
|
VID_SetCaption ("Disconnected");
|
|
|
|
break;
|
|
|
|
case ca_connected:
|
|
|
|
cls.signon = so_none; // need all the signon messages
|
|
|
|
// before playing
|
2012-07-06 01:44:29 +00:00
|
|
|
cl.loading = true;
|
2012-05-23 12:38:25 +00:00
|
|
|
IN_ClearStates ();
|
|
|
|
VID_SetCaption ("Connected");
|
|
|
|
break;
|
|
|
|
case ca_active:
|
|
|
|
// entering active state
|
2012-07-06 01:44:29 +00:00
|
|
|
cl.loading = false;
|
2012-05-23 12:38:25 +00:00
|
|
|
IN_ClearStates ();
|
|
|
|
VID_SetCaption ("");
|
|
|
|
S_AmbientOn ();
|
|
|
|
break;
|
|
|
|
}
|
2012-06-24 02:22:37 +00:00
|
|
|
CL_UpdateScreen (cl.time);
|
2001-08-20 17:48:16 +00:00
|
|
|
}
|
2021-11-18 06:27:44 +00:00
|
|
|
host_in_game = 0;
|
|
|
|
Con_SetState (state == ca_active ? con_inactive : con_fullscreen);
|
|
|
|
if (state != old_state && state == ca_active) {
|
2022-02-22 06:23:09 +00:00
|
|
|
CL_Input_Activate (host_in_game = !cls.demoplayback);
|
2021-11-18 06:27:44 +00:00
|
|
|
}
|
2001-08-20 17:48:16 +00:00
|
|
|
}
|
|
|
|
|
2022-05-26 07:17:00 +00:00
|
|
|
static void
|
|
|
|
write_capture (tex_t *tex, void *data)
|
|
|
|
{
|
|
|
|
QFile *file = QFS_Open (va (0, "%s/qfmv%06d.png",
|
|
|
|
qfs_gamedir->dir.shots,
|
|
|
|
cls.demo_capture++), "wb");
|
|
|
|
if (file) {
|
|
|
|
WritePNG (file, tex);
|
|
|
|
Qclose (file);
|
|
|
|
}
|
|
|
|
free (tex);
|
|
|
|
}
|
|
|
|
|
2022-05-26 08:10:23 +00:00
|
|
|
void
|
|
|
|
CL_PreFrame (void)
|
|
|
|
{
|
|
|
|
IN_ProcessEvents ();
|
|
|
|
|
|
|
|
GIB_Thread_Execute ();
|
|
|
|
cmd_source = src_command;
|
|
|
|
Cbuf_Execute_Stack (host_cbuf);
|
|
|
|
|
|
|
|
CL_SendCmd ();
|
|
|
|
}
|
|
|
|
|
2022-05-26 07:17:00 +00:00
|
|
|
void
|
|
|
|
CL_Frame (void)
|
|
|
|
{
|
|
|
|
static double time1 = 0, time2 = 0, time3 = 0;
|
|
|
|
int pass1, pass2, pass3;
|
|
|
|
|
|
|
|
// fetch results from server
|
|
|
|
if (cls.state >= ca_connected)
|
|
|
|
CL_ReadFromServer ();
|
|
|
|
|
|
|
|
// update video
|
|
|
|
if (host_speeds)
|
|
|
|
time1 = Sys_DoubleTime ();
|
|
|
|
|
|
|
|
r_data->inhibit_viewmodel = (chase_active
|
|
|
|
|| (cl.stats[STAT_ITEMS] & IT_INVISIBILITY)
|
|
|
|
|| cl.stats[STAT_HEALTH] <= 0);
|
|
|
|
r_data->frametime = host_frametime;
|
|
|
|
|
|
|
|
CL_UpdateScreen (cl.time);
|
|
|
|
|
|
|
|
if (host_speeds)
|
|
|
|
time2 = Sys_DoubleTime ();
|
|
|
|
|
|
|
|
// update audio
|
|
|
|
if (cls.state == ca_active) {
|
|
|
|
mleaf_t *l;
|
|
|
|
byte *asl = 0;
|
|
|
|
vec4f_t origin;
|
|
|
|
|
|
|
|
origin = Transform_GetWorldPosition (cl.viewstate.camera_transform);
|
|
|
|
l = Mod_PointInLeaf (origin, cl_world.scene->worldmodel);
|
|
|
|
if (l)
|
|
|
|
asl = l->ambient_sound_level;
|
|
|
|
S_Update (cl.viewstate.camera_transform, asl);
|
|
|
|
R_DecayLights (host_frametime);
|
|
|
|
} else
|
|
|
|
S_Update (0, 0);
|
|
|
|
|
|
|
|
CDAudio_Update ();
|
|
|
|
|
|
|
|
if (host_speeds) {
|
|
|
|
pass1 = (time1 - time3) * 1000;
|
|
|
|
time3 = Sys_DoubleTime ();
|
|
|
|
pass2 = (time2 - time1) * 1000;
|
|
|
|
pass3 = (time3 - time2) * 1000;
|
|
|
|
Sys_Printf ("%3i tot %3i server %3i gfx %3i snd\n",
|
|
|
|
pass1 + pass2 + pass3, pass1, pass2, pass3);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cls.demo_capture) {
|
|
|
|
r_funcs->capture_screen (write_capture, 0);
|
|
|
|
}
|
|
|
|
fps_count++;
|
|
|
|
}
|
|
|
|
|
2003-01-06 18:28:13 +00:00
|
|
|
static void
|
2001-07-06 17:42:04 +00:00
|
|
|
Force_CenterView_f (void)
|
|
|
|
{
|
2022-03-01 02:43:23 +00:00
|
|
|
cl.viewstate.player_angles[PITCH] = 0;
|
2001-07-06 17:42:04 +00:00
|
|
|
}
|
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
void
|
2011-12-22 06:44:28 +00:00
|
|
|
CL_Init (cbuf_t *cbuf)
|
2001-02-26 06:48:02 +00:00
|
|
|
{
|
2012-02-01 10:52:13 +00:00
|
|
|
byte *basepal, *colormap;
|
2011-12-22 06:44:28 +00:00
|
|
|
|
2014-01-23 02:57:57 +00:00
|
|
|
basepal = (byte *) QFS_LoadHunkFile (QFS_FOpenFile ("gfx/palette.lmp"));
|
2011-12-22 06:44:28 +00:00
|
|
|
if (!basepal)
|
|
|
|
Sys_Error ("Couldn't load gfx/palette.lmp");
|
2014-01-23 02:57:57 +00:00
|
|
|
colormap = (byte *) QFS_LoadHunkFile (QFS_FOpenFile ("gfx/colormap.lmp"));
|
2012-02-01 10:52:13 +00:00
|
|
|
if (!colormap)
|
2011-12-22 06:44:28 +00:00
|
|
|
Sys_Error ("Couldn't load gfx/colormap.lmp");
|
|
|
|
|
2022-05-16 11:51:37 +00:00
|
|
|
Host_OnServerSpawn (CL_ClearMemory);
|
|
|
|
|
2012-02-01 12:52:47 +00:00
|
|
|
W_LoadWadFile ("gfx.wad");
|
2012-02-01 10:52:13 +00:00
|
|
|
VID_Init (basepal, colormap);
|
2021-11-18 06:33:49 +00:00
|
|
|
IN_Init ();
|
2022-05-26 07:17:00 +00:00
|
|
|
GIB_Key_Init ();
|
2011-12-22 06:44:28 +00:00
|
|
|
R_Init ();
|
2012-02-26 09:45:50 +00:00
|
|
|
r_data->lightstyle = cl.lightstyle;
|
2012-06-24 12:13:51 +00:00
|
|
|
S_Init (&cl.viewentity, &host_frametime);
|
2012-02-26 09:45:50 +00:00
|
|
|
|
|
|
|
PI_RegisterPlugins (client_plugin_list);
|
|
|
|
Con_Init ("client");
|
|
|
|
|
2011-12-22 06:44:28 +00:00
|
|
|
CDAudio_Init ();
|
2012-01-24 02:49:42 +00:00
|
|
|
|
2012-02-01 12:52:47 +00:00
|
|
|
Sbar_Init ();
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2022-02-22 06:23:09 +00:00
|
|
|
CL_Init_Input (cbuf);
|
2021-12-19 04:08:39 +00:00
|
|
|
CL_Particles_Init ();
|
2001-05-15 21:34:54 +00:00
|
|
|
CL_TEnts_Init ();
|
2022-03-04 16:48:10 +00:00
|
|
|
CL_World_Init ();
|
2002-12-11 22:09:23 +00:00
|
|
|
CL_ClearState ();
|
2012-02-01 12:52:47 +00:00
|
|
|
|
2022-02-28 03:12:51 +00:00
|
|
|
V_Init (&cl.viewstate);
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2021-12-20 15:36:42 +00:00
|
|
|
Cmd_AddCommand ("pointfile", pointfile_f,
|
|
|
|
"Load a pointfile to determine map leaks.");
|
2001-02-21 19:35:06 +00:00
|
|
|
Cmd_AddCommand ("entities", CL_PrintEntities_f, "No Description");
|
|
|
|
Cmd_AddCommand ("disconnect", CL_Disconnect_f, "No Description");
|
2001-11-06 07:14:29 +00:00
|
|
|
Cmd_AddCommand ("maplist", Con_Maplist_f, "List available maps");
|
2001-11-07 06:56:05 +00:00
|
|
|
Cmd_AddCommand ("skyboxlist", Con_Skyboxlist_f, "List skyboxes available");
|
2001-11-06 07:14:29 +00:00
|
|
|
Cmd_AddCommand ("demolist", Con_Demolist_DEM_f, "List available demos");
|
2001-08-29 02:12:57 +00:00
|
|
|
Cmd_AddCommand ("force_centerview", Force_CenterView_f, "force the view "
|
|
|
|
"to be level");
|
2012-02-01 12:52:47 +00:00
|
|
|
|
2022-05-12 11:15:19 +00:00
|
|
|
Sys_RegisterShutdown (CL_Shutdown, 0);
|
|
|
|
|
2012-02-01 12:52:47 +00:00
|
|
|
SZ_Alloc (&cls.message, 1024);
|
|
|
|
CL_SetState (ca_disconnected);
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|