2001-02-19 21:15:25 +00:00
|
|
|
/*
|
|
|
|
host.c
|
|
|
|
|
2001-05-09 17:12:49 +00:00
|
|
|
host init
|
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
|
|
|
|
|
2010-11-29 10:50:59 +00:00
|
|
|
#ifdef HAVE_UNISTD_H
|
2022-05-26 07:17:00 +00:00
|
|
|
# include <unistd.h>
|
2010-11-29 10:50:59 +00:00
|
|
|
#endif
|
|
|
|
|
2002-07-31 05:19:03 +00:00
|
|
|
#include "QF/cbuf.h"
|
2022-05-26 07:11:50 +00:00
|
|
|
#include "QF/dstring.h"
|
2001-03-27 20:33:07 +00:00
|
|
|
#include "QF/cmd.h"
|
2001-05-31 03:41:35 +00:00
|
|
|
#include "QF/cvar.h"
|
2022-05-26 07:17:00 +00:00
|
|
|
#include "QF/dstring.h"
|
2003-04-13 22:07:58 +00:00
|
|
|
#include "QF/gib.h"
|
2022-05-26 07:17:00 +00:00
|
|
|
#include "QF/idparse.h"
|
|
|
|
#include "QF/qargs.h"
|
2001-05-09 17:12:49 +00:00
|
|
|
|
2012-02-13 12:58:34 +00:00
|
|
|
#include "QF/plugin/console.h"
|
|
|
|
|
2002-04-11 18:42:55 +00:00
|
|
|
#include "buildnum.h"
|
2022-02-22 06:23:09 +00:00
|
|
|
|
2022-06-03 06:43:53 +00:00
|
|
|
#include "nq/include/client.h"
|
2020-06-21 14:15:17 +00:00
|
|
|
#include "nq/include/host.h"
|
|
|
|
#include "nq/include/server.h"
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-05-09 06:15:14 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
/*
|
2001-08-29 02:12:57 +00:00
|
|
|
A server can always be started, even if the system started out as a client
|
|
|
|
to a remote system.
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-08-29 02:12:57 +00:00
|
|
|
A client can NOT be started if the system started as a dedicated server.
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-08-29 02:12:57 +00:00
|
|
|
Memory is cleared/released when a server or client begins, not when they end.
|
2001-02-19 21:15:25 +00:00
|
|
|
*/
|
|
|
|
|
2003-12-19 03:41:58 +00:00
|
|
|
SERVER_PLUGIN_PROTOS
|
|
|
|
static plugin_list_t server_plugin_list[] = {
|
|
|
|
SERVER_PLUGIN_LIST
|
|
|
|
};
|
|
|
|
|
2001-08-29 02:12:57 +00:00
|
|
|
qboolean host_initialized; // true if into command execution
|
2001-02-19 21:15:25 +00:00
|
|
|
|
|
|
|
quakeparms_t host_parms;
|
|
|
|
|
2002-07-31 05:19:03 +00:00
|
|
|
cbuf_t *host_cbuf;
|
|
|
|
|
2001-05-19 20:57:29 +00:00
|
|
|
double host_frametime;
|
|
|
|
double host_time;
|
|
|
|
double realtime; // without any filtering or bounding
|
|
|
|
double oldrealtime; // last frame run
|
2001-08-29 02:12:57 +00:00
|
|
|
|
2003-07-25 22:21:47 +00:00
|
|
|
double con_frametime;
|
|
|
|
double con_realtime;
|
|
|
|
double oldcon_realtime;
|
|
|
|
|
2001-05-19 20:57:29 +00:00
|
|
|
int host_framecount;
|
2021-07-29 02:12:37 +00:00
|
|
|
size_t host_hunklevel;
|
2013-01-16 04:18:54 +00:00
|
|
|
int host_in_game;
|
2021-07-26 06:43:57 +00:00
|
|
|
size_t minimum_memory;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
client_t *host_client; // current client
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-05-19 20:57:29 +00:00
|
|
|
jmp_buf host_abortserver;
|
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
|
|
|
float host_mem_size;
|
|
|
|
static cvar_t host_mem_size_cvar = {
|
|
|
|
.name = "host_mem_size",
|
|
|
|
.description =
|
|
|
|
"Amount of memory (in MB) to allocate for the "
|
|
|
|
PACKAGE_NAME
|
|
|
|
" heap",
|
|
|
|
.default_value = "40",
|
|
|
|
.flags = CVAR_ROM,
|
|
|
|
.value = { .type = &cexpr_float, .value = &host_mem_size },
|
|
|
|
};
|
2001-09-06 23:58: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
|
|
|
float host_framerate;
|
|
|
|
static cvar_t host_framerate_cvar = {
|
|
|
|
.name = "host_framerate",
|
|
|
|
.description =
|
|
|
|
"set for slow motion",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_NONE,
|
|
|
|
.value = { .type = &cexpr_float, .value = &host_framerate },
|
|
|
|
};
|
|
|
|
int host_speeds;
|
|
|
|
static cvar_t host_speeds_cvar = {
|
|
|
|
.name = "host_speeds",
|
|
|
|
.description =
|
|
|
|
"set for running times",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_NONE,
|
|
|
|
.value = { .type = &cexpr_int, .value = &host_speeds },
|
|
|
|
};
|
|
|
|
int max_edicts;
|
|
|
|
static cvar_t max_edicts_cvar = {
|
|
|
|
.name = "max_edicts",
|
|
|
|
.description =
|
|
|
|
"maximum server edicts",
|
|
|
|
.default_value = "1024",
|
|
|
|
.flags = CVAR_NONE,
|
|
|
|
.value = { .type = &cexpr_int, .value = &max_edicts },
|
|
|
|
};
|
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
|
|
|
float sys_ticrate;
|
|
|
|
static cvar_t sys_ticrate_cvar = {
|
|
|
|
.name = "sys_ticrate",
|
|
|
|
.description =
|
|
|
|
"None",
|
|
|
|
.default_value = "0.05",
|
|
|
|
.flags = CVAR_NONE,
|
|
|
|
.value = { .type = &cexpr_float, .value = &sys_ticrate },
|
|
|
|
};
|
|
|
|
int serverprofile;
|
|
|
|
static cvar_t serverprofile_cvar = {
|
|
|
|
.name = "serverprofile",
|
|
|
|
.description =
|
|
|
|
"None",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_NONE,
|
|
|
|
.value = { .type = &cexpr_int, .value = &serverprofile },
|
|
|
|
};
|
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 cl_quakerc;
|
|
|
|
static cvar_t cl_quakerc_cvar = {
|
|
|
|
.name = "cl_quakerc",
|
|
|
|
.description =
|
|
|
|
"exec quake.rc on startup",
|
|
|
|
.default_value = "1",
|
|
|
|
.flags = CVAR_NONE,
|
|
|
|
.value = { .type = &cexpr_int, .value = &cl_quakerc },
|
|
|
|
};
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2022-04-24 11:04:06 +00:00
|
|
|
float fraglimit;
|
[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 fraglimit_cvar = {
|
|
|
|
.name = "fraglimit",
|
|
|
|
.description =
|
|
|
|
"None",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_SERVERINFO,
|
2022-04-24 11:04:06 +00:00
|
|
|
.value = { .type = &cexpr_float, .value = &fraglimit },
|
[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 timelimit;
|
|
|
|
static cvar_t timelimit_cvar = {
|
|
|
|
.name = "timelimit",
|
|
|
|
.description =
|
|
|
|
"None",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_SERVERINFO,
|
|
|
|
.value = { .type = &cexpr_int, .value = &timelimit },
|
|
|
|
};
|
|
|
|
int teamplay;
|
|
|
|
static cvar_t teamplay_cvar = {
|
|
|
|
.name = "teamplay",
|
|
|
|
.description =
|
|
|
|
"None",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_SERVERINFO,
|
|
|
|
.value = { .type = &cexpr_int, .value = &teamplay },
|
|
|
|
};
|
2022-04-24 11:04:06 +00:00
|
|
|
float noexit;
|
[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 noexit_cvar = {
|
|
|
|
.name = "noexit",
|
|
|
|
.description =
|
|
|
|
"None",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_SERVERINFO,
|
2022-04-24 11:04:06 +00:00
|
|
|
.value = { .type = &cexpr_float, .value = &noexit },
|
[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
|
|
|
float samelevel;
|
[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 samelevel_cvar = {
|
|
|
|
.name = "samelevel",
|
|
|
|
.description =
|
|
|
|
"None",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_NONE,
|
2022-04-24 11:04:06 +00:00
|
|
|
.value = { .type = &cexpr_float, .value = &samelevel },
|
[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
|
|
|
};
|
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 skill;
|
|
|
|
static cvar_t skill_cvar = {
|
|
|
|
.name = "skill",
|
|
|
|
.description =
|
|
|
|
"0 - 3",
|
|
|
|
.default_value = "1",
|
|
|
|
.flags = CVAR_NONE,
|
|
|
|
.value = { .type = &cexpr_int, .value = &skill },
|
|
|
|
};
|
|
|
|
int coop;
|
|
|
|
static cvar_t coop_cvar = {
|
|
|
|
.name = "coop",
|
|
|
|
.description =
|
|
|
|
"0 or 1",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_NONE,
|
|
|
|
.value = { .type = &cexpr_int, .value = &coop },
|
|
|
|
};
|
|
|
|
int deathmatch;
|
|
|
|
static cvar_t deathmatch_cvar = {
|
|
|
|
.name = "deathmatch",
|
|
|
|
.description =
|
|
|
|
"0, 1, or 2",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_NONE,
|
|
|
|
.value = { .type = &cexpr_int, .value = &deathmatch },
|
|
|
|
};
|
2010-11-29 10:50:59 +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 pausable;
|
|
|
|
static cvar_t pausable_cvar = {
|
|
|
|
.name = "pausable",
|
|
|
|
.description =
|
|
|
|
"None",
|
|
|
|
.default_value = "1",
|
|
|
|
.flags = CVAR_NONE,
|
|
|
|
.value = { .type = &cexpr_int, .value = &pausable },
|
|
|
|
};
|
2001-08-29 02:12:57 +00:00
|
|
|
|
2022-04-24 11:04:06 +00:00
|
|
|
float temp1;
|
[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 temp1_cvar = {
|
|
|
|
.name = "temp1",
|
|
|
|
.description =
|
|
|
|
"None",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_NONE,
|
2022-04-24 11:04:06 +00:00
|
|
|
.value = { .type = &cexpr_float, .value = &temp1 },
|
[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_usleep;
|
|
|
|
static cvar_t cl_usleep_cvar = {
|
|
|
|
.name = "cl_usleep",
|
|
|
|
.description =
|
|
|
|
"Turn this on to save cpu when fps limited. May affect frame rate "
|
|
|
|
"adversely depending on local machine/os conditions",
|
|
|
|
.default_value = "1",
|
|
|
|
.flags = CVAR_ARCHIVE,
|
|
|
|
.value = { .type = &cexpr_int, .value = &cl_usleep },
|
|
|
|
};
|
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
|
|
|
Host_EndGame (const char *message, ...)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2003-07-08 22:39:45 +00:00
|
|
|
static dstring_t *str;
|
2001-08-29 02:12:57 +00:00
|
|
|
va_list argptr;
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2003-07-08 22:39:45 +00:00
|
|
|
if (!str)
|
|
|
|
str = dstring_new ();
|
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
va_start (argptr, message);
|
2003-07-08 22:39:45 +00:00
|
|
|
dvsprintf (str, message, argptr);
|
2001-02-19 21:15:25 +00:00
|
|
|
va_end (argptr);
|
2021-03-29 10:58:00 +00:00
|
|
|
Sys_MaskPrintf (SYS_dev, "Host_EndGame: %s\n", str->str);
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
if (sv.active)
|
|
|
|
Host_ShutdownServer (false);
|
|
|
|
|
2022-04-06 10:32:55 +00:00
|
|
|
if (net_is_dedicated)
|
2003-07-08 22:39:45 +00:00
|
|
|
Sys_Error ("Host_EndGame: %s", str->str); // dedicated servers exit
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
if (cls.demonum != -1)
|
|
|
|
CL_NextDemo ();
|
|
|
|
else
|
|
|
|
CL_Disconnect ();
|
|
|
|
|
|
|
|
longjmp (host_abortserver, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2001-05-09 17:12:49 +00:00
|
|
|
Host_Error
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-05-09 17:12:49 +00:00
|
|
|
This shuts down both the client and server
|
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
|
|
|
Host_Error (const char *error, ...)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2003-07-08 22:39:45 +00:00
|
|
|
static dstring_t *str;
|
2001-02-26 06:48:02 +00:00
|
|
|
static qboolean inerror = false;
|
2001-08-29 02:12:57 +00:00
|
|
|
va_list argptr;
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
if (inerror)
|
|
|
|
Sys_Error ("Host_Error: recursively entered");
|
2003-07-08 22:39:45 +00:00
|
|
|
|
|
|
|
if (!str)
|
|
|
|
str = dstring_new ();
|
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
inerror = true;
|
|
|
|
|
2022-11-02 06:08:09 +00:00
|
|
|
cl.viewstate.loading = false;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
va_start (argptr, error);
|
2003-07-08 22:39:45 +00:00
|
|
|
dvsprintf (str, error, argptr);
|
2001-02-19 21:15:25 +00:00
|
|
|
va_end (argptr);
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
if (sv.active)
|
|
|
|
Host_ShutdownServer (false);
|
|
|
|
|
2022-04-06 10:32:55 +00:00
|
|
|
if (net_is_dedicated)
|
2003-07-08 22:39:45 +00:00
|
|
|
Sys_Error ("Host_Error: %s", str->str); // dedicated servers exit
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2007-11-06 10:17:14 +00:00
|
|
|
Sys_Printf ("Host_Error: %s\n", str->str);
|
2002-02-20 19:22:52 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
CL_Disconnect ();
|
|
|
|
cls.demonum = -1;
|
|
|
|
|
|
|
|
inerror = false;
|
|
|
|
|
|
|
|
longjmp (host_abortserver, 1);
|
|
|
|
}
|
|
|
|
|
2003-01-06 18:28:13 +00:00
|
|
|
static void
|
2001-02-26 06:48:02 +00:00
|
|
|
Host_FindMaxClients (void)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2001-02-26 06:48:02 +00:00
|
|
|
int i;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
|
|
|
svs.maxclients = 1;
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
i = COM_CheckParm ("-dedicated");
|
2001-02-26 06:48:02 +00:00
|
|
|
if (i) {
|
|
|
|
if (i != (com_argc - 1)) {
|
|
|
|
svs.maxclients = atoi (com_argv[i + 1]);
|
|
|
|
} else
|
2001-02-19 21:15:25 +00:00
|
|
|
svs.maxclients = 8;
|
2022-04-06 10:32:55 +00:00
|
|
|
}
|
|
|
|
cls.state = ca_disconnected;
|
|
|
|
net_is_dedicated = i;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
|
|
|
i = COM_CheckParm ("-listen");
|
2001-02-26 06:48:02 +00:00
|
|
|
if (i) {
|
2022-04-06 10:32:55 +00:00
|
|
|
if (net_is_dedicated)
|
2001-02-19 21:15:25 +00:00
|
|
|
Sys_Error ("Only one of -dedicated or -listen can be specified");
|
|
|
|
if (i != (com_argc - 1))
|
2001-02-26 06:48:02 +00:00
|
|
|
svs.maxclients = atoi (com_argv[i + 1]);
|
2001-02-19 21:15:25 +00:00
|
|
|
else
|
|
|
|
svs.maxclients = 8;
|
|
|
|
}
|
|
|
|
if (svs.maxclients < 1)
|
|
|
|
svs.maxclients = 8;
|
|
|
|
else if (svs.maxclients > MAX_SCOREBOARD)
|
|
|
|
svs.maxclients = MAX_SCOREBOARD;
|
|
|
|
|
|
|
|
svs.maxclientslimit = svs.maxclients;
|
|
|
|
if (svs.maxclientslimit < 4)
|
|
|
|
svs.maxclientslimit = 4;
|
2001-02-26 06:48:02 +00:00
|
|
|
svs.clients =
|
2021-07-28 06:01:45 +00:00
|
|
|
Hunk_AllocName (0, svs.maxclientslimit * sizeof (client_t), "clients");
|
2001-02-19 21:15:25 +00:00
|
|
|
|
|
|
|
if (svs.maxclients > 1)
|
[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
|
|
|
deathmatch = 1.0;
|
2001-02-19 21:15:25 +00:00
|
|
|
else
|
[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
|
|
|
deathmatch = 0.0;
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
2003-01-06 18:28:13 +00:00
|
|
|
static void
|
2001-02-26 06:48:02 +00:00
|
|
|
Host_InitLocal (void)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
|
|
|
Host_InitCommands ();
|
|
|
|
|
[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 (&host_framerate_cvar, 0, 0);
|
|
|
|
Cvar_Register (&host_speeds_cvar, 0, 0);
|
|
|
|
Cvar_Register (&max_edicts_cvar, 0, 0);
|
|
|
|
|
|
|
|
Cvar_Register (&sys_ticrate_cvar, 0, 0);
|
|
|
|
Cvar_Register (&serverprofile_cvar, 0, 0);
|
|
|
|
|
|
|
|
Cvar_Register (&cl_quakerc_cvar, 0, 0);
|
|
|
|
|
|
|
|
Cvar_Register (&fraglimit_cvar, Cvar_Info, &fraglimit);
|
|
|
|
Cvar_Register (&timelimit_cvar, Cvar_Info, &timelimit);
|
|
|
|
Cvar_Register (&teamplay_cvar, Cvar_Info, &teamplay);
|
|
|
|
Cvar_Register (&samelevel_cvar, 0, 0);
|
|
|
|
Cvar_Register (&noexit_cvar, Cvar_Info, &noexit);
|
|
|
|
Cvar_Register (&skill_cvar, 0, 0);
|
|
|
|
Cvar_Register (&deathmatch_cvar, 0, 0);
|
|
|
|
Cvar_Register (&coop_cvar, 0, 0);
|
|
|
|
Cvar_Register (&pausable_cvar, 0, 0);
|
|
|
|
Cvar_Register (&temp1_cvar, 0, 0);
|
|
|
|
Cvar_Register (&cl_usleep_cvar, 0, 0);
|
2001-02-19 21:15:25 +00:00
|
|
|
|
|
|
|
Host_FindMaxClients ();
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-05-19 20:57:29 +00:00
|
|
|
host_time = 1.0; // so a think at time 0 won't get called
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2001-05-09 17:12:49 +00:00
|
|
|
SV_ClientPrintf
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-05-09 17:12:49 +00:00
|
|
|
Sends text across to be displayed
|
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
|
|
|
SV_ClientPrintf (const char *fmt, ...)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2003-07-08 22:39:45 +00:00
|
|
|
static dstring_t *str;
|
2001-08-29 02:12:57 +00:00
|
|
|
va_list argptr;
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2003-07-08 22:39:45 +00:00
|
|
|
if (!str)
|
|
|
|
str = dstring_new ();
|
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
va_start (argptr, fmt);
|
2003-07-08 22:39:45 +00:00
|
|
|
dvsprintf (str, fmt, argptr);
|
2001-02-19 21:15:25 +00:00
|
|
|
va_end (argptr);
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
MSG_WriteByte (&host_client->message, svc_print);
|
2003-07-08 22:39:45 +00:00
|
|
|
MSG_WriteString (&host_client->message, str->str);
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2001-05-09 17:12:49 +00:00
|
|
|
SV_BroadcastPrintf
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-05-09 17:12:49 +00:00
|
|
|
Sends text to all active clients
|
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
|
|
|
SV_BroadcastPrintf (const char *fmt, ...)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2003-07-08 22:39:45 +00:00
|
|
|
static dstring_t *str;
|
2001-08-29 02:12:57 +00:00
|
|
|
va_list argptr;
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2003-07-08 22:39:45 +00:00
|
|
|
if (!str)
|
|
|
|
str = dstring_new ();
|
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
va_start (argptr, fmt);
|
2003-07-08 22:39:45 +00:00
|
|
|
dvsprintf (str, fmt, argptr);
|
2001-02-19 21:15:25 +00:00
|
|
|
va_end (argptr);
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2022-01-16 13:15:18 +00:00
|
|
|
for (unsigned i = 0; i < svs.maxclients; i++)
|
2001-02-26 06:48:02 +00:00
|
|
|
if (svs.clients[i].active && svs.clients[i].spawned) {
|
2001-02-19 21:15:25 +00:00
|
|
|
MSG_WriteByte (&svs.clients[i].message, svc_print);
|
2003-07-08 22:39:45 +00:00
|
|
|
MSG_WriteString (&svs.clients[i].message, str->str);
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2001-05-09 17:12:49 +00:00
|
|
|
Host_ClientCommands
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-05-09 17:12:49 +00:00
|
|
|
Send text over to the client to be executed
|
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
|
|
|
Host_ClientCommands (const char *fmt, ...)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2003-07-08 22:39:45 +00:00
|
|
|
static dstring_t *str;
|
2001-08-29 02:12:57 +00:00
|
|
|
va_list argptr;
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2003-07-08 22:39:45 +00:00
|
|
|
if (!str)
|
|
|
|
str = dstring_new ();
|
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
va_start (argptr, fmt);
|
2003-07-08 22:39:45 +00:00
|
|
|
dvsprintf (str, fmt, argptr);
|
2001-02-19 21:15:25 +00:00
|
|
|
va_end (argptr);
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
MSG_WriteByte (&host_client->message, svc_stufftext);
|
2003-07-08 22:39:45 +00:00
|
|
|
MSG_WriteString (&host_client->message, str->str);
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2001-05-09 17:12:49 +00:00
|
|
|
SV_DropClient
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-05-09 17:12:49 +00:00
|
|
|
Called when the player is getting totally kicked off the host
|
|
|
|
if (crash = true), don't bother sending signofs
|
2001-02-19 21:15:25 +00:00
|
|
|
*/
|
2001-02-26 06:48:02 +00:00
|
|
|
void
|
|
|
|
SV_DropClient (qboolean crash)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2001-02-26 06:48:02 +00:00
|
|
|
client_t *client;
|
2022-01-16 13:15:18 +00:00
|
|
|
unsigned i;
|
|
|
|
pr_uint_t saveSelf;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
if (!crash) {
|
2001-02-19 21:15:25 +00:00
|
|
|
// send any final messages (don't check for errors)
|
2001-02-26 06:48:02 +00:00
|
|
|
if (NET_CanSendMessage (host_client->netconnection)) {
|
2001-02-19 21:15:25 +00:00
|
|
|
MSG_WriteByte (&host_client->message, svc_disconnect);
|
2001-08-29 02:12:57 +00:00
|
|
|
NET_SendMessage (host_client->netconnection,
|
|
|
|
&host_client->message);
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
2001-02-26 06:48:02 +00:00
|
|
|
|
|
|
|
if (host_client->edict && host_client->spawned) {
|
|
|
|
// call the prog function for removing a client
|
|
|
|
// this will set the body to a dead frame, among other things
|
2001-03-03 08:31:58 +00:00
|
|
|
saveSelf = *sv_globals.self;
|
2022-01-22 07:00:04 +00:00
|
|
|
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, host_client->edict);
|
2002-05-31 21:05:58 +00:00
|
|
|
PR_ExecuteProgram (&sv_pr_state, sv_funcs.ClientDisconnect);
|
2001-03-03 08:31:58 +00:00
|
|
|
*sv_globals.self = saveSelf;
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
2007-11-06 10:17:14 +00:00
|
|
|
Sys_Printf ("Client %s removed\n", host_client->name);
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
2001-08-29 02:12:57 +00:00
|
|
|
// break the net connection
|
2021-03-29 10:58:00 +00:00
|
|
|
Sys_MaskPrintf (SYS_net, "dropping client\n");
|
2001-02-19 21:15:25 +00:00
|
|
|
NET_Close (host_client->netconnection);
|
|
|
|
host_client->netconnection = NULL;
|
|
|
|
|
2001-08-29 02:12:57 +00:00
|
|
|
// free the client (the body stays around)
|
2001-02-19 21:15:25 +00:00
|
|
|
host_client->active = false;
|
|
|
|
host_client->name[0] = 0;
|
|
|
|
host_client->old_frags = -999999;
|
|
|
|
net_activeconnections--;
|
|
|
|
|
2001-08-29 02:12:57 +00:00
|
|
|
// send notification to all clients
|
2022-01-16 13:15:18 +00:00
|
|
|
for (i = 0, client = svs.clients; i < svs.maxclients;
|
|
|
|
i++, client++) {
|
2001-02-19 21:15:25 +00:00
|
|
|
if (!client->active)
|
|
|
|
continue;
|
|
|
|
MSG_WriteByte (&client->message, svc_updatename);
|
|
|
|
MSG_WriteByte (&client->message, host_client - svs.clients);
|
|
|
|
MSG_WriteString (&client->message, "");
|
|
|
|
MSG_WriteByte (&client->message, svc_updatefrags);
|
|
|
|
MSG_WriteByte (&client->message, host_client - svs.clients);
|
|
|
|
MSG_WriteShort (&client->message, 0);
|
|
|
|
MSG_WriteByte (&client->message, svc_updatecolors);
|
|
|
|
MSG_WriteByte (&client->message, host_client - svs.clients);
|
|
|
|
MSG_WriteByte (&client->message, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2001-05-09 17:12:49 +00:00
|
|
|
Host_ShutdownServer
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2010-01-13 06:42:26 +00:00
|
|
|
This happens only at the end of a game, not between levels
|
2001-02-19 21:15:25 +00:00
|
|
|
*/
|
2001-02-26 06:48:02 +00:00
|
|
|
void
|
|
|
|
Host_ShutdownServer (qboolean crash)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2005-06-08 06:35:48 +00:00
|
|
|
byte message[4];
|
2001-02-26 06:48:02 +00:00
|
|
|
double start;
|
2022-01-16 13:15:18 +00:00
|
|
|
unsigned count, i;
|
2001-08-29 02:12:57 +00:00
|
|
|
sizebuf_t buf;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
|
|
|
if (!sv.active)
|
|
|
|
return;
|
|
|
|
|
|
|
|
sv.active = false;
|
|
|
|
|
2001-08-29 02:12:57 +00:00
|
|
|
// stop all client sounds immediately
|
2012-05-23 12:38:25 +00:00
|
|
|
if (cls.state >= ca_connected)
|
2001-02-19 21:15:25 +00:00
|
|
|
CL_Disconnect ();
|
|
|
|
|
2001-08-29 02:12:57 +00:00
|
|
|
// flush any pending messages - like the score!!!
|
2001-02-26 06:48:02 +00:00
|
|
|
start = Sys_DoubleTime ();
|
|
|
|
do {
|
2001-02-19 21:15:25 +00:00
|
|
|
count = 0;
|
2001-02-26 06:48:02 +00:00
|
|
|
for (i = 0, host_client = svs.clients; i < svs.maxclients;
|
|
|
|
i++, host_client++) {
|
|
|
|
if (host_client->active && host_client->message.cursize) {
|
|
|
|
if (NET_CanSendMessage (host_client->netconnection)) {
|
|
|
|
NET_SendMessage (host_client->netconnection,
|
|
|
|
&host_client->message);
|
2001-02-19 21:15:25 +00:00
|
|
|
SZ_Clear (&host_client->message);
|
2001-02-26 06:48:02 +00:00
|
|
|
} else {
|
|
|
|
NET_GetMessage (host_client->netconnection);
|
2001-02-19 21:15:25 +00:00
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2001-02-26 06:48:02 +00:00
|
|
|
if ((Sys_DoubleTime () - start) > 3.0)
|
2001-02-19 21:15:25 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
while (count);
|
|
|
|
|
2001-08-29 02:12:57 +00:00
|
|
|
// make sure all the clients know we're disconnecting
|
2001-02-19 21:15:25 +00:00
|
|
|
buf.data = message;
|
|
|
|
buf.maxsize = 4;
|
|
|
|
buf.cursize = 0;
|
2001-02-26 06:48:02 +00:00
|
|
|
MSG_WriteByte (&buf, svc_disconnect);
|
2010-11-21 05:27:43 +00:00
|
|
|
count = NET_SendToAll (&buf, 5.0);
|
2001-02-19 21:15:25 +00:00
|
|
|
if (count)
|
2007-11-06 10:17:14 +00:00
|
|
|
Sys_Printf
|
2001-02-26 06:48:02 +00:00
|
|
|
("Host_ShutdownServer: NET_SendToAll failed for %u clients\n",
|
|
|
|
count);
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
for (i = 0, host_client = svs.clients; i < svs.maxclients;
|
|
|
|
i++, host_client++)
|
2001-02-19 21:15:25 +00:00
|
|
|
if (host_client->active)
|
2001-02-26 06:48:02 +00:00
|
|
|
SV_DropClient (crash);
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-08-29 02:12:57 +00:00
|
|
|
// clear structures
|
2001-02-26 06:48:02 +00:00
|
|
|
memset (&sv, 0, sizeof (sv));
|
|
|
|
memset (svs.clients, 0, svs.maxclientslimit * sizeof (client_t));
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2001-05-09 17:12:49 +00:00
|
|
|
Host_ClearMemory
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-05-09 17:12:49 +00:00
|
|
|
This clears all the memory used by both the client and server, but does
|
|
|
|
not reinitialize anything.
|
2001-02-19 21:15:25 +00:00
|
|
|
*/
|
2001-02-26 06:48:02 +00:00
|
|
|
void
|
|
|
|
Host_ClearMemory (void)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2021-03-29 10:58:00 +00:00
|
|
|
Sys_MaskPrintf (SYS_dev, "Clearing memory\n");
|
2001-02-19 21:15:25 +00:00
|
|
|
Mod_ClearAll ();
|
|
|
|
if (host_hunklevel)
|
2021-07-28 06:01:45 +00:00
|
|
|
Hunk_FreeToLowMark (0, host_hunklevel);
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
2022-05-16 11:51:37 +00:00
|
|
|
static struct LISTENER_SET_TYPE(void) host_server_spawn = LISTENER_SET_STATIC_INIT(4);
|
|
|
|
|
|
|
|
void
|
|
|
|
Host_SpawnServer (void)
|
|
|
|
{
|
|
|
|
LISTENER_INVOKE (&host_server_spawn, NULL);
|
|
|
|
Host_ClearMemory ();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Host_OnServerSpawn (void (*onSpawn) (void))
|
|
|
|
{
|
|
|
|
LISTENER_ADD (&host_server_spawn,
|
|
|
|
(void(*)(void *, const void*)) onSpawn, 0);
|
|
|
|
}
|
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
/*
|
2001-05-09 17:12:49 +00:00
|
|
|
Host_FilterTime
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-05-09 17:12:49 +00:00
|
|
|
Returns false if the time is too short to run a frame
|
2001-02-19 21:15:25 +00:00
|
|
|
*/
|
2010-11-29 10:50:59 +00:00
|
|
|
static float
|
2001-02-26 06:48:02 +00:00
|
|
|
Host_FilterTime (float time)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2002-05-07 04:32:28 +00:00
|
|
|
float timedifference;
|
2001-09-06 04:35:02 +00:00
|
|
|
float timescale = 1.0;
|
|
|
|
|
2003-07-25 22:21:47 +00:00
|
|
|
con_realtime += time;
|
|
|
|
|
2001-09-06 04:35:02 +00:00
|
|
|
if (cls.demoplayback) {
|
[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
|
|
|
timescale = max (0, demo_speed);
|
2001-09-06 04:35:02 +00:00
|
|
|
time *= timescale;
|
|
|
|
}
|
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
realtime += time;
|
|
|
|
|
2002-05-07 04:32:28 +00:00
|
|
|
//FIXME not having the framerate cap is nice, but it breaks net play
|
|
|
|
timedifference = (timescale / 72.0) - (realtime - oldrealtime);
|
|
|
|
|
2021-02-03 09:24:15 +00:00
|
|
|
if (!cls.demoplayback && (timedifference > 0))
|
2010-11-29 10:50:59 +00:00
|
|
|
return timedifference; // framerate is too high
|
2002-05-07 04:32:28 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
host_frametime = realtime - oldrealtime;
|
|
|
|
oldrealtime = realtime;
|
|
|
|
|
2003-07-25 22:21:47 +00:00
|
|
|
con_frametime = con_realtime - oldcon_realtime;
|
|
|
|
oldcon_realtime = con_realtime;
|
|
|
|
|
[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_framerate > 0)
|
|
|
|
host_frametime = host_framerate;
|
2002-04-25 16:50:56 +00:00
|
|
|
else // don't allow really long or short frames
|
2021-02-03 09:24:15 +00:00
|
|
|
host_frametime = bound (0.000, host_frametime, 0.1);
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2010-11-29 10:50:59 +00:00
|
|
|
return 0;
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
2003-08-16 05:29:02 +00:00
|
|
|
/*
|
|
|
|
Host_Frame
|
|
|
|
|
|
|
|
Runs all active servers
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
_Host_Frame (float time)
|
|
|
|
{
|
2004-01-27 06:02:41 +00:00
|
|
|
static int first = 1;
|
2010-11-29 10:50:59 +00:00
|
|
|
float sleeptime;
|
2004-01-27 06:02:41 +00:00
|
|
|
|
2003-08-16 05:29:02 +00:00
|
|
|
if (setjmp (host_abortserver))
|
|
|
|
return; // something bad happened, or the
|
|
|
|
// server disconnected
|
|
|
|
|
|
|
|
rand (); // keep the random time dependent
|
|
|
|
|
2012-01-05 10:19:37 +00:00
|
|
|
if (cls.demo_capture)
|
|
|
|
time = 1.0 / 30; //FIXME fixed 30fps atm
|
|
|
|
|
2003-08-16 05:29:02 +00:00
|
|
|
// decide the simulation time
|
2010-11-29 10:50:59 +00:00
|
|
|
if ((sleeptime = Host_FilterTime (time)) != 0) {
|
|
|
|
// don't run too fast, or packet will flood outs
|
|
|
|
#ifdef HAVE_USLEEP
|
[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_usleep && sleeptime > 0.002) // minimum sleep time
|
2010-11-29 10:50:59 +00:00
|
|
|
usleep ((unsigned long) (sleeptime * 1000000 / 2));
|
|
|
|
#endif
|
2012-05-21 23:23:22 +00:00
|
|
|
return;
|
2010-11-29 10:50:59 +00:00
|
|
|
}
|
2022-04-08 09:27:53 +00:00
|
|
|
host_time += host_frametime; //FIXME is this needed? vcr stuff
|
2003-08-16 05:29:02 +00:00
|
|
|
|
2004-01-27 06:02:41 +00:00
|
|
|
if (first) {
|
|
|
|
first = 0;
|
|
|
|
|
|
|
|
if (isDedicated) {
|
|
|
|
if (!sv.active)
|
|
|
|
Cmd_ExecuteString ("map start", src_command);
|
|
|
|
if (!sv.active)
|
|
|
|
Sys_Error ("Could not initialize server");
|
|
|
|
} else {
|
|
|
|
Con_NewMap ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-08-16 05:29:02 +00:00
|
|
|
NET_Poll ();
|
|
|
|
|
2022-04-08 09:27:53 +00:00
|
|
|
if (!net_is_dedicated) {
|
|
|
|
// Whether or not the server is active, if this is not a dedicated
|
|
|
|
// server, then the client always needs to be able to process input
|
|
|
|
// and send commands to the server before the server runs a frame.
|
2022-05-26 08:10:23 +00:00
|
|
|
CL_PreFrame ();
|
2022-04-08 09:27:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (sv.active) {
|
2022-05-26 08:10:23 +00:00
|
|
|
SV_Frame ();
|
2003-08-16 05:29:02 +00:00
|
|
|
}
|
|
|
|
|
2022-04-08 09:27:53 +00:00
|
|
|
if (!net_is_dedicated) {
|
2022-05-26 07:17:00 +00:00
|
|
|
CL_Frame ();
|
2012-01-05 10:19:37 +00:00
|
|
|
}
|
2022-03-31 15:58:14 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
host_framecount++;
|
|
|
|
}
|
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
void
|
|
|
|
Host_Frame (float time)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2001-08-29 02:12:57 +00:00
|
|
|
double time1, time2;
|
2001-02-26 06:48:02 +00:00
|
|
|
static double timetotal;
|
2022-04-08 09:29:04 +00:00
|
|
|
int c;
|
|
|
|
double m;
|
2001-08-29 02:12:57 +00:00
|
|
|
static int timecount;
|
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
|
|
|
if (!serverprofile) {
|
2001-02-19 21:15:25 +00:00
|
|
|
_Host_Frame (time);
|
|
|
|
return;
|
|
|
|
}
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
time1 = Sys_DoubleTime ();
|
|
|
|
_Host_Frame (time);
|
2001-02-26 06:48:02 +00:00
|
|
|
time2 = Sys_DoubleTime ();
|
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
timetotal += time2 - time1;
|
|
|
|
timecount++;
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
if (timecount < 1000)
|
|
|
|
return;
|
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
m = timetotal * 1000 / timecount;
|
2001-02-19 21:15:25 +00:00
|
|
|
timecount = 0;
|
|
|
|
timetotal = 0;
|
|
|
|
c = 0;
|
2022-01-16 13:15:18 +00:00
|
|
|
for (unsigned i = 0; i < svs.maxclients; i++) {
|
2001-02-19 21:15:25 +00:00
|
|
|
if (svs.clients[i].active)
|
|
|
|
c++;
|
|
|
|
}
|
|
|
|
|
2022-04-08 09:29:04 +00:00
|
|
|
Sys_Printf ("serverprofile: %2i clients %5.3g msec\n", c, m);
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
#define VCR_SIGNATURE 0x56435231
|
|
|
|
// "VCR1"
|
|
|
|
|
2003-01-06 18:28:13 +00:00
|
|
|
static void
|
2001-02-26 06:48:02 +00:00
|
|
|
Host_InitVCR (quakeparms_t *parms)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2001-02-26 06:48:02 +00:00
|
|
|
char *p;
|
2001-08-29 02:12:57 +00:00
|
|
|
int i, len, n;
|
2001-02-26 06:48:02 +00:00
|
|
|
|
|
|
|
if (COM_CheckParm ("-playback")) {
|
2001-02-19 21:15:25 +00:00
|
|
|
if (com_argc != 2)
|
2002-05-14 06:12:29 +00:00
|
|
|
Sys_Error ("No other parameters allowed with -playback");
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2003-05-23 17:17:01 +00:00
|
|
|
vcrFile = QFS_Open ("quake.vcr", "rbz");
|
2001-03-30 23:24:57 +00:00
|
|
|
if (!vcrFile)
|
2002-05-14 06:12:29 +00:00
|
|
|
Sys_Error ("playback file not found");
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-03-30 23:24:57 +00:00
|
|
|
Qread (vcrFile, &i, sizeof (int));
|
2001-02-19 21:15:25 +00:00
|
|
|
|
|
|
|
if (i != VCR_SIGNATURE)
|
2002-05-14 06:12:29 +00:00
|
|
|
Sys_Error ("Invalid signature in vcr file");
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-03-30 23:24:57 +00:00
|
|
|
Qread (vcrFile, &com_argc, sizeof (int));
|
2001-02-26 06:48:02 +00:00
|
|
|
com_argv = malloc (com_argc * sizeof (char *));
|
2002-05-14 06:37:28 +00:00
|
|
|
SYS_CHECKMEM (com_argv);
|
2001-02-19 21:15:25 +00:00
|
|
|
|
|
|
|
com_argv[0] = parms->argv[0];
|
2001-02-26 06:48:02 +00:00
|
|
|
for (i = 0; i < com_argc; i++) {
|
2001-03-30 23:24:57 +00:00
|
|
|
Qread (vcrFile, &len, sizeof (int));
|
2001-02-26 06:48:02 +00:00
|
|
|
|
|
|
|
p = malloc (len);
|
2002-05-14 06:37:28 +00:00
|
|
|
SYS_CHECKMEM (p);
|
2001-03-30 23:24:57 +00:00
|
|
|
Qread (vcrFile, p, len);
|
2001-02-26 06:48:02 +00:00
|
|
|
com_argv[i + 1] = p;
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
2001-02-26 06:48:02 +00:00
|
|
|
com_argc++; /* add one for arg[0] */
|
2001-02-19 21:15:25 +00:00
|
|
|
parms->argc = com_argc;
|
|
|
|
parms->argv = com_argv;
|
|
|
|
}
|
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
if ((n = COM_CheckParm ("-record")) != 0) {
|
2003-05-23 17:17:01 +00:00
|
|
|
vcrFile = QFS_Open ("quake.vcr", "wb");
|
2001-02-19 21:15:25 +00:00
|
|
|
|
|
|
|
i = VCR_SIGNATURE;
|
2001-03-30 23:24:57 +00:00
|
|
|
Qwrite (vcrFile, &i, sizeof (int));
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
i = com_argc - 1;
|
2001-03-30 23:24:57 +00:00
|
|
|
Qwrite (vcrFile, &i, sizeof (int));
|
2001-02-26 06:48:02 +00:00
|
|
|
|
|
|
|
for (i = 1; i < com_argc; i++) {
|
|
|
|
if (i == n) {
|
2001-02-19 21:15:25 +00:00
|
|
|
len = 10;
|
2001-03-30 23:24:57 +00:00
|
|
|
Qwrite (vcrFile, &len, sizeof (int));
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-03-30 23:24:57 +00:00
|
|
|
Qwrite (vcrFile, "-playback", len);
|
2001-02-19 21:15:25 +00:00
|
|
|
continue;
|
|
|
|
}
|
2001-02-26 06:48:02 +00:00
|
|
|
len = strlen (com_argv[i]) + 1;
|
2001-03-30 23:24:57 +00:00
|
|
|
Qwrite (vcrFile, &len, sizeof (int));
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-03-30 23:24:57 +00:00
|
|
|
Qwrite (vcrFile, com_argv[i], len);
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
}
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
2021-12-13 00:13:39 +00:00
|
|
|
static memhunk_t *
|
2011-12-22 06:44:28 +00:00
|
|
|
Host_Init_Memory (void)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2002-02-19 20:47:45 +00:00
|
|
|
int mem_parm = COM_CheckParm ("-mem");
|
2021-07-26 06:43:57 +00:00
|
|
|
size_t mem_size;
|
2002-02-19 20:47:45 +00:00
|
|
|
void *mem_base;
|
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
if (standard_quake)
|
|
|
|
minimum_memory = MINIMUM_MEMORY;
|
|
|
|
else
|
|
|
|
minimum_memory = MINIMUM_MEMORY_LEVELPAK;
|
|
|
|
|
[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 (&host_mem_size_cvar, 0, 0);
|
2002-02-19 20:47:45 +00:00
|
|
|
if (mem_parm)
|
[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_Set ("host_mem_size", com_argv[mem_parm + 1]);
|
2002-02-19 20:47:45 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
if (COM_CheckParm ("-minmemory"))
|
[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
|
|
|
host_mem_size = minimum_memory / (1024 * 1024.0);
|
2002-02-19 20:47:45 +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
|
|
|
mem_size = ((size_t) host_mem_size * 1024 * 1024);
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2002-02-19 20:47:45 +00:00
|
|
|
if (mem_size < minimum_memory)
|
|
|
|
Sys_Error ("Only %4.1f megs of memory reported, can't execute game",
|
|
|
|
mem_size / (float) 0x100000);
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2021-02-03 04:19:19 +00:00
|
|
|
mem_base = Sys_Alloc (mem_size);
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2002-02-19 20:47:45 +00:00
|
|
|
if (!mem_base)
|
2021-07-26 06:43:57 +00:00
|
|
|
Sys_Error ("Can't allocate %zd", mem_size);
|
2002-02-19 20:47:45 +00:00
|
|
|
|
|
|
|
Sys_PageIn (mem_base, mem_size);
|
2021-12-13 00:13:39 +00:00
|
|
|
memhunk_t *hunk = Memory_Init (mem_base, mem_size);
|
2012-02-01 12:52:47 +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
|
|
|
Sys_Printf ("%4.1f megabyte heap\n", host_mem_size);
|
2021-12-13 00:13:39 +00:00
|
|
|
return hunk;
|
2002-02-19 20:47:45 +00:00
|
|
|
}
|
2021-11-18 06:27:44 +00:00
|
|
|
|
2013-01-16 04:18:54 +00:00
|
|
|
static void
|
2021-11-18 06:27:44 +00:00
|
|
|
Host_ExecConfig (cbuf_t *cbuf, int skip_quakerc)
|
2013-01-16 04:18:54 +00:00
|
|
|
{
|
2021-11-18 06:27:44 +00:00
|
|
|
// quakeforge.cfg overrides quake.rc as it contains quakeforge-specific
|
|
|
|
// commands. If it doesn't exist, then this is the first time quakeforge
|
|
|
|
// has been used in this installation, thus any existing legacy config
|
|
|
|
// should be used to set up defaults on the assumption that the user has
|
|
|
|
// things set up to work with another (hopefully compatible) client
|
|
|
|
if (CL_ReadConfiguration ("quakeforge.cfg")) {
|
[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
|
|
|
Cmd_Exec_File (cbuf, fs_usercfg, 0);
|
2021-11-18 06:27:44 +00:00
|
|
|
Cmd_StuffCmds (cbuf);
|
|
|
|
COM_Check_quakerc ("startdemos", cbuf);
|
|
|
|
} else {
|
|
|
|
if (!skip_quakerc) {
|
|
|
|
Cbuf_InsertText (cbuf, "exec quake.rc\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
|
|
|
Cmd_Exec_File (cbuf, fs_usercfg, 0);
|
2021-11-18 06:27:44 +00:00
|
|
|
// Reparse the command line for + commands.
|
|
|
|
// (sets still done, but it doesn't matter)
|
|
|
|
// (Note, no non-base commands exist yet)
|
|
|
|
if (skip_quakerc || !COM_Check_quakerc ("stuffcmds", 0)) {
|
|
|
|
Cmd_StuffCmds (cbuf);
|
|
|
|
}
|
|
|
|
}
|
2013-01-16 04:18:54 +00:00
|
|
|
}
|
2021-11-18 06:27:44 +00:00
|
|
|
|
2002-02-19 20:47:45 +00:00
|
|
|
void
|
|
|
|
Host_Init (void)
|
|
|
|
{
|
2022-05-12 11:15:19 +00:00
|
|
|
Sys_RegisterShutdown (Host_Shutdown, 0);
|
2007-11-06 10:17:14 +00:00
|
|
|
Sys_Printf ("Host_Init\n");
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2002-08-03 06:04:00 +00:00
|
|
|
host_cbuf = Cbuf_New (&id_interp);
|
2002-07-31 05:19:03 +00:00
|
|
|
cmd_source = src_command;
|
|
|
|
|
2002-08-20 23:04:57 +00:00
|
|
|
Sys_Init ();
|
2011-12-22 06:44:28 +00:00
|
|
|
GIB_Init (true);
|
2022-05-26 07:17:00 +00:00
|
|
|
|
2021-04-12 13:09:09 +00:00
|
|
|
COM_ParseConfig (host_cbuf);
|
2011-12-22 06:44:28 +00:00
|
|
|
|
2021-12-13 00:13:39 +00:00
|
|
|
memhunk_t *hunk = Host_Init_Memory ();
|
2002-01-17 04:29:41 +00:00
|
|
|
|
2002-01-17 04:11:36 +00:00
|
|
|
PI_Init ();
|
|
|
|
|
2021-12-13 00:13:39 +00:00
|
|
|
Game_Init (hunk);
|
2011-12-22 06:44:28 +00:00
|
|
|
|
2012-02-01 12:52:47 +00:00
|
|
|
if (!isDedicated)
|
|
|
|
CL_InitCvars ();
|
|
|
|
|
2003-12-19 03:41:58 +00:00
|
|
|
if (isDedicated) {
|
|
|
|
PI_RegisterPlugins (server_plugin_list);
|
2023-01-20 04:27:17 +00:00
|
|
|
Con_Load ("server");
|
|
|
|
Con_Init ();
|
2002-01-16 21:53:42 +00:00
|
|
|
}
|
2001-10-03 21:25:43 +00:00
|
|
|
|
2002-02-19 20:47:45 +00:00
|
|
|
Host_InitVCR (&host_parms);
|
2001-02-19 21:15:25 +00:00
|
|
|
Host_InitLocal ();
|
2002-01-17 04:11:36 +00:00
|
|
|
|
2022-04-06 10:32:55 +00:00
|
|
|
NET_Init (host_cbuf);
|
2002-01-17 19:10:07 +00:00
|
|
|
|
2002-01-17 04:11:36 +00:00
|
|
|
Mod_Init ();
|
2002-04-11 18:42:55 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
SV_Init ();
|
|
|
|
|
2022-04-06 10:32:55 +00:00
|
|
|
if (!net_is_dedicated)
|
2011-12-22 06:44:28 +00:00
|
|
|
CL_Init (host_cbuf);
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2012-02-26 09:45:50 +00:00
|
|
|
if (con_module) {
|
|
|
|
con_module->data->console->realtime = &con_realtime;
|
|
|
|
con_module->data->console->frametime = &con_frametime;
|
|
|
|
con_module->data->console->quit = Host_Quit_f;
|
2022-05-12 11:15:19 +00:00
|
|
|
//FIXME need to rethink cbuf connections (they can form a stack)
|
|
|
|
Cbuf_DeleteStack (con_module->data->console->cbuf);
|
2012-02-26 09:45:50 +00:00
|
|
|
con_module->data->console->cbuf = host_cbuf;
|
|
|
|
}
|
|
|
|
|
[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
|
|
|
Host_ExecConfig (host_cbuf, isDedicated || !cl_quakerc);
|
2001-05-17 07:53:22 +00:00
|
|
|
|
2021-07-28 06:01:45 +00:00
|
|
|
Hunk_AllocName (0, 0, "-HOST_HUNKLEVEL-");
|
|
|
|
host_hunklevel = Hunk_LowMark (0);
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2010-08-19 06:01:43 +00:00
|
|
|
Sys_Printf ("\nVersion %s (build %04d)\n\n", PACKAGE_VERSION,
|
2002-04-11 18:42:55 +00:00
|
|
|
build_number ());
|
|
|
|
|
2010-08-19 06:01:43 +00:00
|
|
|
Sys_Printf ("\x80\x81\x81\x82 %s initialized \x80\x81\x81\x82\n",
|
|
|
|
PACKAGE_NAME);
|
2004-01-07 06:29:34 +00:00
|
|
|
|
|
|
|
host_initialized = true;
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2001-05-09 17:12:49 +00:00
|
|
|
Host_Shutdown
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-05-09 17:12:49 +00:00
|
|
|
FIXME: this is a callback from Sys_Quit and Sys_Error. It would be
|
|
|
|
better to run quit through here before final handoff to the sys code.
|
2001-02-19 21:15:25 +00:00
|
|
|
*/
|
2001-02-26 06:48:02 +00:00
|
|
|
void
|
2020-03-21 13:24:11 +00:00
|
|
|
Host_Shutdown (void *data)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
|
|
|
static qboolean isdown = false;
|
2001-02-26 06:48:02 +00:00
|
|
|
|
|
|
|
if (isdown) {
|
2001-02-19 21:15:25 +00:00
|
|
|
printf ("recursive shutdown\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
isdown = true;
|
|
|
|
}
|