mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
libutil.a is now used by both qw and nq
This commit is contained in:
parent
9aa50a847c
commit
7516666084
22 changed files with 165 additions and 5329 deletions
|
@ -1 +1,4 @@
|
|||
SUBDIRS= util
|
||||
|
||||
clean-local:
|
||||
rm -f *.a
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
noinst_LIBRARIES = libutil.a
|
||||
|
||||
libutil_a_SOURCES = cmd.c cvar.c hash.c mdfour.c sizebuf.c va.c zone.c
|
||||
|
||||
all-local: ../libutil.a
|
||||
|
||||
../libutil.a: libutil.a
|
||||
cp $(noinst_LIBRARIES) ..
|
||||
|
|
|
@ -182,6 +182,8 @@ void Cvar_Info (cvar_t *var);
|
|||
void
|
||||
Cvar_Set (cvar_t *var, char *value)
|
||||
{
|
||||
int changed;
|
||||
|
||||
if (!var)
|
||||
return;
|
||||
|
||||
|
@ -190,6 +192,7 @@ Cvar_Set (cvar_t *var, char *value)
|
|||
return;
|
||||
}
|
||||
|
||||
changed = strequal (var->string, value);
|
||||
free (var->string); // free the old value string
|
||||
|
||||
var->string = strdup (value);
|
||||
|
@ -197,7 +200,8 @@ Cvar_Set (cvar_t *var, char *value)
|
|||
var->int_val = atoi (var->string);
|
||||
sscanf (var->string, "%f %f %f", &var->vec[0], &var->vec[1], &var->vec[2]);
|
||||
|
||||
Cvar_Info (var);
|
||||
if (changed)
|
||||
Cvar_Info (var);
|
||||
}
|
||||
|
||||
|
||||
|
@ -209,9 +213,12 @@ Cvar_Set (cvar_t *var, char *value)
|
|||
void
|
||||
Cvar_SetROM (cvar_t *var, char *value)
|
||||
{
|
||||
int changed;
|
||||
|
||||
if (!var)
|
||||
return;
|
||||
|
||||
changed = strequal (var->string, value);
|
||||
free (var->string); // free the old value string
|
||||
|
||||
var->string = strdup (value);
|
||||
|
@ -219,7 +226,8 @@ Cvar_SetROM (cvar_t *var, char *value)
|
|||
var->int_val = atoi (var->string);
|
||||
sscanf (var->string, "%f %f %f", &var->vec[0], &var->vec[1], &var->vec[2]);
|
||||
|
||||
Cvar_Info (var);
|
||||
if (changed)
|
||||
Cvar_Info (var);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -39,6 +39,17 @@
|
|||
#include "console.h"
|
||||
#include "sizebuf.h"
|
||||
#include "sys.h"
|
||||
#include "zone.h"
|
||||
|
||||
void
|
||||
SZ_Alloc (sizebuf_t *buf, int startsize)
|
||||
{
|
||||
if (startsize < 256)
|
||||
startsize = 256;
|
||||
buf->data = Hunk_AllocName (startsize, "sizebuf");
|
||||
buf->maxsize = startsize;
|
||||
buf->cursize = 0;
|
||||
}
|
||||
|
||||
void
|
||||
SZ_Clear (sizebuf_t *buf)
|
||||
|
|
|
@ -49,11 +49,11 @@ sound_ASM= snd_mixa.S
|
|||
common_ASM= sys_ia32.S worlda.S $(math_ASM)
|
||||
#endif
|
||||
|
||||
common_SOURCES= crc.c cvar.c cmd.c mathlib.c wad.c world.c \
|
||||
common_SOURCES= crc.c mathlib.c wad.c world.c \
|
||||
model.c model_alias.c model_brush.c model_sprite.c \
|
||||
msg.c sizebuf.c qendian.c qargs.c quakefs.c \
|
||||
va.c quakeio.c link.c com.c \
|
||||
zone.c $(common_ASM)
|
||||
msg.c qendian.c qargs.c quakefs.c \
|
||||
quakeio.c link.c com.c \
|
||||
$(common_ASM)
|
||||
|
||||
#
|
||||
# ... System type
|
||||
|
@ -122,22 +122,23 @@ EXTRA_libqfjs_a_SOURCES= joy_linux.c joy_null.c
|
|||
#
|
||||
# ... Networking
|
||||
#
|
||||
libqfnet_a_SOURCES= mdfour.c net_bsd.c checksum.c net_dgrm.c net_loop.c \
|
||||
libqfnet_a_SOURCES= net_bsd.c checksum.c net_dgrm.c net_loop.c \
|
||||
net_main.c net_udp.c net_vcr.c
|
||||
|
||||
EXTRA_libqfcd_a_SOURCES=net_dos.c net_bw.c net_ipx.c net_mp.c net_ser.c \
|
||||
net_win.c net_wins.c net_wipx.c
|
||||
|
||||
client_LIBS= -L. -lqfsys -lqfsnd -lqfcd -lqfjs -lqfnet $(SOUND_LIBS) $(NET_LIBS) $(Z_LIBS)
|
||||
client_LIBS= -L. -L../../libs -lqfsys -lqfsnd -lqfcd -lqfjs -lqfnet -lutil $(SOUND_LIBS) $(NET_LIBS) $(Z_LIBS)
|
||||
client_LIB_DEPS= libqfsys.a libqfsnd.a libqfcd.a libqfjs.a libqfnet.a ../../libs/libutil.a
|
||||
|
||||
client_SOURCES= cl_cam.c cl_demo.c cl_input.c cl_main.c cl_parse.c \
|
||||
client_SOURCES= cl_cam.c cl_cmd.c cl_demo.c cl_input.c cl_main.c cl_parse.c \
|
||||
cl_tent.c console.c keys.c menu.c sbar.c r_part.c r_view.c \
|
||||
nonintel.c gib.c gib_instructions.c gib_vars.c \
|
||||
gib_interpret.c gib_modules.c gib_parse.c gib_stack.c vid.c
|
||||
|
||||
server_SOURCES= host.c host_cmd.c \
|
||||
pr_cmds.c pr_edict.c pr_exec.c \
|
||||
sv_main.c sv_move.c sv_phys.c sv_user.c
|
||||
sv_cvar.c sv_main.c sv_move.c sv_phys.c sv_user.c
|
||||
|
||||
combined_SOURCES= $(common_SOURCES) $(client_SOURCES) $(server_SOURCES)
|
||||
|
||||
|
@ -161,7 +162,7 @@ mgl_SOURCES= vid_mgl.c in_win.c
|
|||
|
||||
nq_mgl_SOURCES= $(combined_SOURCES) $(soft_SOURCES) $(mgl_SOURCES)
|
||||
nq_mgl_LDADD= $(client_LIBS) $(MGL_LIBS)
|
||||
nq_mgl_DEPENDENCIES=libqfsys.a libqfsnd.a libqfcd.a libqfjs.a libqfnet.a
|
||||
nq_mgl_DEPENDENCIES=$(client_LIB_DEPS)
|
||||
|
||||
#
|
||||
# ... Sam Lantinga's Simple DirectMedia Layer, version 1.0 and higher
|
||||
|
@ -170,7 +171,7 @@ sdl_SOURCES= vid_sdl.c in_sdl.c
|
|||
|
||||
nq_sdl_SOURCES= $(combined_SOURCES) $(soft_SOURCES) $(sdl_SOURCES)
|
||||
nq_sdl_LDADD= $(client_LIBS) $(SDL_LIBS)
|
||||
nq_sdl_DEPENDENCIES=libqfsys.a libqfsnd.a libqfcd.a libqfjs.a libqfnet.a
|
||||
nq_sdl_DEPENDENCIES=$(client_LIB_DEPS)
|
||||
|
||||
#
|
||||
# ... Linux SVGAlib
|
||||
|
@ -179,7 +180,7 @@ svga_SOURCES= d_copy.S vid_svgalib.c in_svgalib.c
|
|||
|
||||
nq_svga_SOURCES= $(combined_SOURCES) $(soft_SOURCES) $(svga_SOURCES)
|
||||
nq_svga_LDADD= $(client_LIBS) $(SVGA_LIBS)
|
||||
nq_svga_DEPENDENCIES=libqfsys.a libqfsnd.a libqfcd.a libqfjs.a libqfnet.a
|
||||
nq_svga_DEPENDENCIES=$(client_LIB_DEPS)
|
||||
|
||||
#
|
||||
# ... X11
|
||||
|
@ -188,7 +189,7 @@ x11_SOURCES= in_x11.c context_x11.c dga_check.c
|
|||
|
||||
nq_x11_SOURCES= $(combined_SOURCES) $(soft_SOURCES) $(x11_SOURCES) vid_x11.c
|
||||
nq_x11_LDADD= $(client_LIBS) $(X_PRE_LIBS) $(VIDMODE_LIBS) $(DGA_LIBS) $(X_LIBS) -lX11 $(X_EXTRA_LIBS) $(X_SHM_LIB)
|
||||
nq_x11_DEPENDENCIES=libqfsys.a libqfsnd.a libqfcd.a libqfjs.a libqfnet.a
|
||||
nq_x11_DEPENDENCIES=$(client_LIB_DEPS)
|
||||
|
||||
|
||||
#
|
||||
|
@ -208,7 +209,7 @@ tdfx_SOURCES= vid_3dfxsvga.c vid_common_gl.c in_svgalib.c
|
|||
|
||||
nq_3dfx_SOURCES= $(combined_SOURCES) $(ogl_SOURCES) $(tdfx_SOURCES)
|
||||
nq_3dfx_LDADD= $(client_LIBS) $(TDFXGL_LIBS) $(SVGA_LIBS) $(DL_LIBS)
|
||||
nq_3dfx_DEPENDENCIES=libqfsys.a libqfsnd.a libqfcd.a libqfjs.a libqfnet.a
|
||||
nq_3dfx_DEPENDENCIES=$(client_LIB_DEPS)
|
||||
|
||||
#
|
||||
# ... OpenGL in X Window
|
||||
|
@ -217,7 +218,7 @@ glx_SOURCES= vid_glx.c vid_common_gl.c $(x11_SOURCES)
|
|||
|
||||
nq_glx_SOURCES= $(combined_SOURCES) $(ogl_SOURCES) $(glx_SOURCES)
|
||||
nq_glx_LDADD= $(client_LIBS) $(GLX_LIBS) $(X_PRE_LIBS) $(VIDMODE_LIBS) $(DGA_LIBS) $(X_LIBS) -lX11 $(X_EXTRA_LIBS) $(DL_LIBS)
|
||||
nq_glx_DEPENDENCIES=libqfsys.a libqfsnd.a libqfcd.a libqfjs.a libqfnet.a
|
||||
nq_glx_DEPENDENCIES=$(client_LIB_DEPS)
|
||||
|
||||
#
|
||||
# ... Sam Lantinga's Simple DirectMedia Layer, version 1.1 and higher, in GL mode
|
||||
|
@ -226,7 +227,7 @@ sgl_SOURCES= vid_sgl.c vid_common_gl.c in_sdl.c
|
|||
|
||||
nq_sgl_SOURCES= $(combined_SOURCES) $(ogl_SOURCES) $(sgl_SOURCES)
|
||||
nq_sgl_LDADD= $(client_LIBS) $(X_LIBS) $(SDL_LIBS) $(GLX_LIBS) $(DL_LIBS)
|
||||
nq_sgl_DEPENDENCIES=libqfsys.a libqfsnd.a libqfcd.a libqfjs.a libqfnet.a
|
||||
nq_sgl_DEPENDENCIES=$(client_LIB_DEPS)
|
||||
|
||||
#
|
||||
# SGI/Microsoft WGL (Windows OpenGL)
|
||||
|
@ -235,7 +236,7 @@ wgl_SOURCES= vid_wgl.c
|
|||
|
||||
nq_wgl_SOURCES= $(combined_SOURCES) $(ogl_SOURCES) $(wgl_SOURCES)
|
||||
nq_wgl_LDADD= $(client_LIBS)
|
||||
nq_wgl_DEPENDENCIES=libqfsys.a libqfsnd.a libqfcd.a libqfjs.a libqfnet.a
|
||||
nq_wgl_DEPENDENCIES=$(client_LIB_DEPS)
|
||||
|
||||
#
|
||||
# dedicated server
|
||||
|
|
84
nq/source/cl_cmd.c
Normal file
84
nq/source/cl_cmd.c
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
cl_cmd.c
|
||||
|
||||
script command processing module
|
||||
|
||||
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
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "client.h"
|
||||
#include "cmd.h"
|
||||
#include "console.h"
|
||||
#include "msg.h"
|
||||
#include "sizebuf.h"
|
||||
|
||||
/*
|
||||
Cmd_ForwardToServer
|
||||
|
||||
Sends the entire command line over to the server
|
||||
*/
|
||||
void Cmd_ForwardToServer (void)
|
||||
{
|
||||
if (cls.state != ca_connected)
|
||||
{
|
||||
Con_Printf ("Can't \"%s\", not connected\n", Cmd_Argv(0));
|
||||
return;
|
||||
}
|
||||
|
||||
if (cls.demoplayback)
|
||||
return; // not really connected
|
||||
|
||||
MSG_WriteByte (&cls.message, clc_stringcmd);
|
||||
if (strcasecmp(Cmd_Argv(0), "cmd") != 0)
|
||||
{
|
||||
SZ_Print (&cls.message, Cmd_Argv(0));
|
||||
SZ_Print (&cls.message, " ");
|
||||
}
|
||||
if (Cmd_Argc() > 1)
|
||||
SZ_Print (&cls.message, Cmd_Args());
|
||||
else
|
||||
SZ_Print (&cls.message, "\n");
|
||||
}
|
||||
|
||||
/*
|
||||
cl_Cmd_Init
|
||||
*/
|
||||
void
|
||||
cl_Cmd_Init (void)
|
||||
{
|
||||
//
|
||||
// register our commands
|
||||
//
|
||||
Cmd_AddCommand ("cmd", Cmd_ForwardToServer, "No Description");
|
||||
}
|
1027
nq/source/cmd.c
1027
nq/source/cmd.c
File diff suppressed because it is too large
Load diff
502
nq/source/cvar.c
502
nq/source/cvar.c
|
@ -1,502 +0,0 @@
|
|||
/*
|
||||
cvar.c
|
||||
|
||||
dynamic variable tracking
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
Copyright (C) 1999,2000 Nelson Rush.
|
||||
Copyright (C) 1999,2000 contributors of the QuakeForge project
|
||||
Please see the file "AUTHORS" for a list of contributors
|
||||
|
||||
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
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "cvar.h"
|
||||
#include "console.h"
|
||||
#include "server.h"
|
||||
#include "cmd.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
cvar_t *cvar_vars;
|
||||
char *cvar_null_string = "";
|
||||
extern cvar_t *developer;
|
||||
cvar_alias_t *calias_vars;
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_FindVar
|
||||
============
|
||||
*/
|
||||
cvar_t *Cvar_FindVar (char *var_name)
|
||||
{
|
||||
cvar_t *var;
|
||||
|
||||
for (var=cvar_vars ; var ; var=var->next)
|
||||
if (!strcmp (var_name, var->name))
|
||||
return var;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cvar_t *Cvar_FindAlias (char *alias_name)
|
||||
{
|
||||
cvar_alias_t *alias;
|
||||
|
||||
for (alias = calias_vars ; alias ; alias=alias->next)
|
||||
if (!strcmp (alias_name, alias->name))
|
||||
return alias->cvar;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Cvar_Alias_Get (char *name, cvar_t *cvar)
|
||||
{
|
||||
cvar_alias_t *alias;
|
||||
cvar_t *var;
|
||||
|
||||
if (Cmd_Exists (name))
|
||||
{
|
||||
Con_Printf ("CAlias_Get: %s is a command\n", name);
|
||||
return;
|
||||
}
|
||||
if (Cvar_FindVar(name))
|
||||
{
|
||||
Con_Printf ("CAlias_Get: tried to alias used cvar name %s\n",name);
|
||||
return;
|
||||
}
|
||||
var = Cvar_FindAlias(name);
|
||||
if (!var)
|
||||
{
|
||||
alias = (cvar_alias_t *) calloc(1, sizeof(cvar_alias_t));
|
||||
alias->next = calias_vars;
|
||||
calias_vars = alias;
|
||||
alias->name = strdup(name);
|
||||
alias->cvar = cvar;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_VariableValue
|
||||
============
|
||||
*/
|
||||
float Cvar_VariableValue (char *var_name)
|
||||
{
|
||||
cvar_t *var;
|
||||
|
||||
var = Cvar_FindVar (var_name);
|
||||
if (!var)
|
||||
var = Cvar_FindAlias(var_name);
|
||||
if (!var)
|
||||
return 0;
|
||||
return atof (var->string);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_VariableString
|
||||
============
|
||||
*/
|
||||
char *Cvar_VariableString (char *var_name)
|
||||
{
|
||||
cvar_t *var;
|
||||
|
||||
var = Cvar_FindVar (var_name);
|
||||
if (!var)
|
||||
var = Cvar_FindAlias(var_name);
|
||||
if (!var)
|
||||
return cvar_null_string;
|
||||
return var->string;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_CompleteVariable
|
||||
============
|
||||
*/
|
||||
char *Cvar_CompleteVariable (char *partial)
|
||||
{
|
||||
cvar_t *cvar;
|
||||
cvar_alias_t *alias;
|
||||
int len;
|
||||
|
||||
len = strlen(partial);
|
||||
|
||||
if (!len)
|
||||
return NULL;
|
||||
|
||||
// check exact match
|
||||
for (cvar=cvar_vars ; cvar ; cvar=cvar->next)
|
||||
if (!strcasecmp (partial,cvar->name))
|
||||
return cvar->name;
|
||||
|
||||
// check aliases too :)
|
||||
for (alias=calias_vars ; alias ; alias=alias->next)
|
||||
if (!strcasecmp (partial, alias->name))
|
||||
return alias->name;
|
||||
|
||||
// check partial match
|
||||
for (cvar=cvar_vars ; cvar ; cvar=cvar->next)
|
||||
if (!strncasecmp (partial,cvar->name, len))
|
||||
return cvar->name;
|
||||
|
||||
// check aliases too :)
|
||||
for (alias=calias_vars ; alias ; alias=alias->next)
|
||||
if (!strncasecmp (partial, alias->name, len))
|
||||
return alias->name;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_Set
|
||||
============
|
||||
*/
|
||||
void Cvar_Set (cvar_t *var, char *value)
|
||||
{
|
||||
int changed;
|
||||
|
||||
if (!var)
|
||||
return;
|
||||
if(var->flags&CVAR_ROM)
|
||||
return;
|
||||
|
||||
changed = strcmp(var->string, value);
|
||||
free (var->string); // free the old value string
|
||||
|
||||
var->string = malloc (strlen(value)+1);
|
||||
strcpy (var->string, value);
|
||||
var->value = atof (var->string);
|
||||
var->int_val = atoi (var->string);
|
||||
|
||||
if ((var->flags & CVAR_SERVERINFO) && changed) {
|
||||
if (sv.active)
|
||||
SV_BroadcastPrintf ("\"%s\" changed to \"%s\"\n", var->name, var->string);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Cvar_SetROM
|
||||
|
||||
doesn't check for CVAR_ROM flag
|
||||
*/
|
||||
void Cvar_SetROM (cvar_t *var, char *value)
|
||||
{
|
||||
int changed;
|
||||
|
||||
if (!var)
|
||||
return;
|
||||
|
||||
changed = strcmp(var->string, value);
|
||||
free (var->string); // free the old value string
|
||||
|
||||
var->string = malloc (strlen(value)+1);
|
||||
strcpy (var->string, value);
|
||||
var->value = atof (var->string);
|
||||
var->int_val = atoi (var->string);
|
||||
|
||||
if ((var->flags & CVAR_SERVERINFO) && changed) {
|
||||
if (sv.active)
|
||||
SV_BroadcastPrintf ("\"%s\" changed to \"%s\"\n", var->name, var->string);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_SetValue
|
||||
============
|
||||
*/
|
||||
// 1999-09-07 weird cvar zeros fix by Maddes
|
||||
void Cvar_SetValue (cvar_t *var_name, float value)
|
||||
{
|
||||
char val[32];
|
||||
int i;
|
||||
|
||||
snprintf (val, sizeof(val), "%f", value);
|
||||
for (i=strlen(val)-1 ; i>0 && val[i]=='0' && val[i-1]!='.' ; i--)
|
||||
{
|
||||
val[i] = 0;
|
||||
}
|
||||
Cvar_Set (var_name, val);
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_Command
|
||||
|
||||
Handles variable inspection and changing from the console
|
||||
============
|
||||
*/
|
||||
qboolean Cvar_Command (void)
|
||||
{
|
||||
cvar_t *v;
|
||||
|
||||
// check variables
|
||||
v = Cvar_FindVar (Cmd_Argv(0));
|
||||
if (!v)
|
||||
v = Cvar_FindAlias (Cmd_Argv(0));
|
||||
if (!v)
|
||||
return false;
|
||||
|
||||
// perform a variable print or set
|
||||
if (Cmd_Argc() == 1)
|
||||
{
|
||||
Con_Printf ("\"%s\" is \"%s\"\n", v->name, v->string);
|
||||
return true;
|
||||
}
|
||||
|
||||
Cvar_Set (v, Cmd_Argv(1));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_WriteVariables
|
||||
|
||||
Writes lines containing "set variable value" for all variables
|
||||
with the archive flag set to true.
|
||||
============
|
||||
*/
|
||||
void Cvar_WriteVariables (QFile *f)
|
||||
{
|
||||
cvar_t *var;
|
||||
|
||||
for (var = cvar_vars ; var ; var = var->next)
|
||||
if (var->flags&CVAR_ARCHIVE)
|
||||
Qprintf (f, "%s \"%s\"\n", var->name, var->string);
|
||||
}
|
||||
|
||||
void Cvar_Set_f(void)
|
||||
{
|
||||
cvar_t *var;
|
||||
char *value;
|
||||
char *var_name;
|
||||
|
||||
if (Cmd_Argc() != 3)
|
||||
{
|
||||
Con_Printf ("usage: set <cvar> <value>\n");
|
||||
return;
|
||||
}
|
||||
var_name = Cmd_Argv (1);
|
||||
value = Cmd_Argv (2);
|
||||
var = Cvar_FindVar (var_name);
|
||||
if (!var)
|
||||
var = Cvar_FindAlias (var_name);
|
||||
if (var)
|
||||
{
|
||||
Cvar_Set (var, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
var = Cvar_Get (var_name, value, CVAR_USER_CREATED,
|
||||
"User created cvar");
|
||||
}
|
||||
}
|
||||
|
||||
void Cvar_Setrom_f(void)
|
||||
{
|
||||
cvar_t *var;
|
||||
char *value;
|
||||
char *var_name;
|
||||
|
||||
if (Cmd_Argc() != 2)
|
||||
{
|
||||
Con_Printf ("usage: setrom <cvar>\n");
|
||||
return;
|
||||
}
|
||||
var_name = Cmd_Argv (1);
|
||||
value = Cmd_Argv (2);
|
||||
var = Cvar_FindVar (var_name);
|
||||
if (!var)
|
||||
var = Cvar_FindAlias (var_name);
|
||||
if (var)
|
||||
{
|
||||
var->flags |= CVAR_ROM;
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf ("cvar %s not found\n", var_name);
|
||||
}
|
||||
}
|
||||
|
||||
void Cvar_Toggle_f (void)
|
||||
{
|
||||
cvar_t *var;
|
||||
|
||||
if (Cmd_Argc() != 2)
|
||||
{
|
||||
Con_Printf ("toggle <cvar> : toggle a cvar on/off\n");
|
||||
return;
|
||||
}
|
||||
|
||||
var = Cvar_FindVar (Cmd_Argv(1));
|
||||
if (!var)
|
||||
var = Cvar_FindAlias(Cmd_Argv(1));
|
||||
if (!var)
|
||||
{
|
||||
Con_Printf ("Unknown variable \"%s\"\n", Cmd_Argv(1));
|
||||
return;
|
||||
}
|
||||
|
||||
Cvar_Set (var, var->value ? "0" : "1"); //XXX should be int or float?
|
||||
}
|
||||
|
||||
void Cvar_Help_f (void)
|
||||
{
|
||||
char *var_name;
|
||||
cvar_t *var;
|
||||
|
||||
if (Cmd_Argc() != 2)
|
||||
{
|
||||
Con_Printf ("usage: help <cvar>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
var_name = Cmd_Argv (1);
|
||||
var = Cvar_FindVar (var_name);
|
||||
if (!var)
|
||||
var = Cvar_FindAlias (var_name);
|
||||
if (var)
|
||||
{
|
||||
Con_Printf ("%s\n",var->description);
|
||||
return;
|
||||
}
|
||||
Con_Printf ("variable not found\n");
|
||||
}
|
||||
|
||||
void Cvar_CvarList_f (void)
|
||||
{
|
||||
cvar_t *var;
|
||||
int i;
|
||||
|
||||
for (var=cvar_vars, i=0 ; var ; var=var->next, i++)
|
||||
{
|
||||
Con_Printf("%s\n",var->name);
|
||||
}
|
||||
Con_Printf ("------------\n%d variables\n", i);
|
||||
}
|
||||
|
||||
void Cvar_Init()
|
||||
{
|
||||
developer = Cvar_Get ("developer","0",0,"None");
|
||||
|
||||
Cmd_AddCommand ("set", Cvar_Set_f, "No Description");
|
||||
Cmd_AddCommand ("setrom", Cvar_Setrom_f, "No Description");
|
||||
Cmd_AddCommand ("toggle", Cvar_Toggle_f, "No Description");
|
||||
Cmd_AddCommand ("help",Cvar_Help_f, "No Description");
|
||||
Cmd_AddCommand ("cvarlist",Cvar_CvarList_f, "No Description");
|
||||
}
|
||||
|
||||
void Cvar_Shutdown (void)
|
||||
{
|
||||
cvar_t *var,*next;
|
||||
cvar_alias_t *alias,*nextalias;
|
||||
|
||||
// Free cvars
|
||||
var = cvar_vars;
|
||||
while(var)
|
||||
{
|
||||
next = var->next;
|
||||
free(var->description);
|
||||
free(var->string);
|
||||
free(var->name);
|
||||
free(var);
|
||||
var = next;
|
||||
}
|
||||
// Free aliases
|
||||
alias = calias_vars;
|
||||
while(alias)
|
||||
{
|
||||
nextalias = alias->next;
|
||||
free(alias->name);
|
||||
free(alias);
|
||||
alias = nextalias;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cvar_t *Cvar_Get(char *name, char *string, int cvarflags, char *description)
|
||||
{
|
||||
|
||||
cvar_t *v;
|
||||
|
||||
if (Cmd_Exists (name))
|
||||
{
|
||||
Con_Printf ("Cvar_Get: %s is a command\n",name);
|
||||
return NULL;
|
||||
}
|
||||
v = Cvar_FindVar(name);
|
||||
if (!v)
|
||||
{
|
||||
v = (cvar_t *) calloc(1, sizeof(cvar_t));
|
||||
// Cvar doesn't exist, so we create it
|
||||
v->next = cvar_vars;
|
||||
cvar_vars = v;
|
||||
v->name = strdup(name);
|
||||
v->string = malloc (strlen(string)+1);
|
||||
strcpy (v->string, string);
|
||||
v->flags = cvarflags;
|
||||
v->description = strdup(description);
|
||||
v->value = atof (v->string);
|
||||
v->int_val = atoi (v->string);
|
||||
return v;
|
||||
}
|
||||
// Cvar does exist, so we update the flags and return.
|
||||
v->flags ^= CVAR_USER_CREATED;
|
||||
v->flags |= cvarflags;
|
||||
if (!strcmp (v->description,"User created cvar"))
|
||||
{
|
||||
// Set with the real description
|
||||
free(v->description);
|
||||
v->description = strdup (description);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
/*
|
||||
Cvar_SetFlags
|
||||
|
||||
sets a Cvar's flags simply and easily
|
||||
*/
|
||||
void
|
||||
Cvar_SetFlags (cvar_t *var, int cvarflags)
|
||||
{
|
||||
if (var == NULL)
|
||||
return;
|
||||
|
||||
var->flags = cvarflags;
|
||||
}
|
||||
|
|
@ -883,6 +883,8 @@ void Host_Init (quakeparms_t *parms)
|
|||
com_argc = parms->argc;
|
||||
com_argv = parms->argv;
|
||||
|
||||
Cvar_Init_Hash ();
|
||||
Cmd_Init_Hash ();
|
||||
Memory_Init (parms->membase, parms->memsize);
|
||||
Cvar_Init ();
|
||||
CL_InitCvars ();
|
||||
|
|
|
@ -1,258 +0,0 @@
|
|||
/*
|
||||
mdfour.c
|
||||
|
||||
An implementation of MD4 designed for use in the samba SMB
|
||||
authentication protocol
|
||||
|
||||
Copyright (C) 1997-1998 Andrew Tridgell
|
||||
|
||||
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
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "mdfour.h"
|
||||
#include "uint32.h"
|
||||
|
||||
/* NOTE: This code makes no attempt to be fast!
|
||||
|
||||
It assumes that a int is at least 32 bits long
|
||||
*/
|
||||
|
||||
static struct mdfour *m;
|
||||
|
||||
#define F(X,Y,Z) (((X)&(Y)) | ((~(X))&(Z)))
|
||||
#define G(X,Y,Z) (((X)&(Y)) | ((X)&(Z)) | ((Y)&(Z)))
|
||||
#define H(X,Y,Z) ((X)^(Y)^(Z))
|
||||
|
||||
#ifdef LARGE_INT32
|
||||
# define lshift(x,s) ((((x)<<(s))&0xFFFFFFFF) | (((x)>>(32-(s)))&0xFFFFFFFF))
|
||||
#else
|
||||
# define lshift(x,s) (((x)<<(s)) | ((x)>>(32-(s))))
|
||||
#endif
|
||||
|
||||
#define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s)
|
||||
#define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + 0x5A827999,s)
|
||||
#define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + 0x6ED9EBA1,s)
|
||||
|
||||
/* this applies md4 to 64 byte chunks */
|
||||
static void
|
||||
mdfour64 (uint32 * M)
|
||||
{
|
||||
int j;
|
||||
uint32 AA, BB, CC, DD;
|
||||
uint32 X[16];
|
||||
uint32 A, B, C, D;
|
||||
|
||||
for (j = 0; j < 16; j++)
|
||||
X[j] = M[j];
|
||||
|
||||
A = m->A;
|
||||
B = m->B;
|
||||
C = m->C;
|
||||
D = m->D;
|
||||
AA = A;
|
||||
BB = B;
|
||||
CC = C;
|
||||
DD = D;
|
||||
|
||||
ROUND1 (A, B, C, D, 0, 3);
|
||||
ROUND1 (D, A, B, C, 1, 7);
|
||||
ROUND1 (C, D, A, B, 2, 11);
|
||||
ROUND1 (B, C, D, A, 3, 19);
|
||||
ROUND1 (A, B, C, D, 4, 3);
|
||||
ROUND1 (D, A, B, C, 5, 7);
|
||||
ROUND1 (C, D, A, B, 6, 11);
|
||||
ROUND1 (B, C, D, A, 7, 19);
|
||||
ROUND1 (A, B, C, D, 8, 3);
|
||||
ROUND1 (D, A, B, C, 9, 7);
|
||||
ROUND1 (C, D, A, B, 10, 11);
|
||||
ROUND1 (B, C, D, A, 11, 19);
|
||||
ROUND1 (A, B, C, D, 12, 3);
|
||||
ROUND1 (D, A, B, C, 13, 7);
|
||||
ROUND1 (C, D, A, B, 14, 11);
|
||||
ROUND1 (B, C, D, A, 15, 19);
|
||||
|
||||
ROUND2 (A, B, C, D, 0, 3);
|
||||
ROUND2 (D, A, B, C, 4, 5);
|
||||
ROUND2 (C, D, A, B, 8, 9);
|
||||
ROUND2 (B, C, D, A, 12, 13);
|
||||
ROUND2 (A, B, C, D, 1, 3);
|
||||
ROUND2 (D, A, B, C, 5, 5);
|
||||
ROUND2 (C, D, A, B, 9, 9);
|
||||
ROUND2 (B, C, D, A, 13, 13);
|
||||
ROUND2 (A, B, C, D, 2, 3);
|
||||
ROUND2 (D, A, B, C, 6, 5);
|
||||
ROUND2 (C, D, A, B, 10, 9);
|
||||
ROUND2 (B, C, D, A, 14, 13);
|
||||
ROUND2 (A, B, C, D, 3, 3);
|
||||
ROUND2 (D, A, B, C, 7, 5);
|
||||
ROUND2 (C, D, A, B, 11, 9);
|
||||
ROUND2 (B, C, D, A, 15, 13);
|
||||
|
||||
ROUND3 (A, B, C, D, 0, 3);
|
||||
ROUND3 (D, A, B, C, 8, 9);
|
||||
ROUND3 (C, D, A, B, 4, 11);
|
||||
ROUND3 (B, C, D, A, 12, 15);
|
||||
ROUND3 (A, B, C, D, 2, 3);
|
||||
ROUND3 (D, A, B, C, 10, 9);
|
||||
ROUND3 (C, D, A, B, 6, 11);
|
||||
ROUND3 (B, C, D, A, 14, 15);
|
||||
ROUND3 (A, B, C, D, 1, 3);
|
||||
ROUND3 (D, A, B, C, 9, 9);
|
||||
ROUND3 (C, D, A, B, 5, 11);
|
||||
ROUND3 (B, C, D, A, 13, 15);
|
||||
ROUND3 (A, B, C, D, 3, 3);
|
||||
ROUND3 (D, A, B, C, 11, 9);
|
||||
ROUND3 (C, D, A, B, 7, 11);
|
||||
ROUND3 (B, C, D, A, 15, 15);
|
||||
|
||||
A += AA;
|
||||
B += BB;
|
||||
C += CC;
|
||||
D += DD;
|
||||
|
||||
#ifdef LARGE_INT32
|
||||
A &= 0xFFFFFFFF;
|
||||
B &= 0xFFFFFFFF;
|
||||
C &= 0xFFFFFFFF;
|
||||
D &= 0xFFFFFFFF;
|
||||
#endif
|
||||
|
||||
for (j = 0; j < 16; j++)
|
||||
X[j] = 0;
|
||||
|
||||
m->A = A;
|
||||
m->B = B;
|
||||
m->C = C;
|
||||
m->D = D;
|
||||
}
|
||||
|
||||
static void
|
||||
copy64 (uint32 * M, unsigned char *in)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
M[i] = (in[i * 4 + 3] << 24) | (in[i * 4 + 2] << 16) |
|
||||
(in[i * 4 + 1] << 8) | (in[i * 4 + 0] << 0);
|
||||
}
|
||||
|
||||
static void
|
||||
copy4 (unsigned char *out, uint32 x)
|
||||
{
|
||||
out[0] = x & 0xFF;
|
||||
out[1] = (x >> 8) & 0xFF;
|
||||
out[2] = (x >> 16) & 0xFF;
|
||||
out[3] = (x >> 24) & 0xFF;
|
||||
}
|
||||
|
||||
void
|
||||
mdfour_begin (struct mdfour *md)
|
||||
{
|
||||
md->A = 0x67452301;
|
||||
md->B = 0xefcdab89;
|
||||
md->C = 0x98badcfe;
|
||||
md->D = 0x10325476;
|
||||
md->totalN = 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mdfour_tail (unsigned char *in, int n)
|
||||
{
|
||||
unsigned char buf[128];
|
||||
uint32 M[16];
|
||||
uint32 b;
|
||||
|
||||
m->totalN += n;
|
||||
|
||||
b = m->totalN * 8;
|
||||
|
||||
memset (buf, 0, 128);
|
||||
if (n)
|
||||
memcpy (buf, in, n);
|
||||
buf[n] = 0x80;
|
||||
|
||||
if (n <= 55) {
|
||||
copy4 (buf + 56, b);
|
||||
copy64 (M, buf);
|
||||
mdfour64 (M);
|
||||
} else {
|
||||
copy4 (buf + 120, b);
|
||||
copy64 (M, buf);
|
||||
mdfour64 (M);
|
||||
copy64 (M, buf + 64);
|
||||
mdfour64 (M);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mdfour_update (struct mdfour *md, unsigned char *in, int n)
|
||||
{
|
||||
uint32 M[16];
|
||||
|
||||
if (n == 0)
|
||||
mdfour_tail (in, n);
|
||||
|
||||
m = md;
|
||||
|
||||
while (n >= 64) {
|
||||
copy64 (M, in);
|
||||
mdfour64 (M);
|
||||
in += 64;
|
||||
n -= 64;
|
||||
m->totalN += 64;
|
||||
}
|
||||
|
||||
mdfour_tail (in, n);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mdfour_result (struct mdfour *md, unsigned char *out)
|
||||
{
|
||||
m = md;
|
||||
|
||||
copy4 (out, m->A);
|
||||
copy4 (out + 4, m->B);
|
||||
copy4 (out + 8, m->C);
|
||||
copy4 (out + 12, m->D);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mdfour (unsigned char *out, unsigned char *in, int n)
|
||||
{
|
||||
struct mdfour md;
|
||||
|
||||
mdfour_begin (&md);
|
||||
mdfour_update (&md, in, n);
|
||||
mdfour_result (&md, out);
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
/*
|
||||
sizebuf.c
|
||||
|
||||
(description)
|
||||
|
||||
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
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "sizebuf.h"
|
||||
#include "sys.h"
|
||||
#include "zone.h"
|
||||
|
||||
void SZ_Alloc (sizebuf_t *buf, int startsize)
|
||||
{
|
||||
if (startsize < 256)
|
||||
startsize = 256;
|
||||
buf->data = Hunk_AllocName (startsize, "sizebuf");
|
||||
buf->maxsize = startsize;
|
||||
buf->cursize = 0;
|
||||
}
|
||||
|
||||
void SZ_Clear (sizebuf_t *buf)
|
||||
{
|
||||
buf->cursize = 0;
|
||||
buf->overflowed = false;
|
||||
}
|
||||
|
||||
void *SZ_GetSpace (sizebuf_t *buf, int length)
|
||||
{
|
||||
void *data;
|
||||
|
||||
if (buf->cursize + length > buf->maxsize)
|
||||
{
|
||||
if (!buf->allowoverflow)
|
||||
Sys_Error ("SZ_GetSpace: overflow without allowoverflow set (%d)", buf->maxsize);
|
||||
|
||||
if (length > buf->maxsize)
|
||||
Sys_Error ("SZ_GetSpace: %i is > full buffer size", length);
|
||||
|
||||
Sys_Printf ("SZ_GetSpace: overflow\n"); // because Con_Printf may be redirected
|
||||
SZ_Clear (buf);
|
||||
buf->overflowed = true;
|
||||
}
|
||||
|
||||
data = buf->data + buf->cursize;
|
||||
buf->cursize += length;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void SZ_Write (sizebuf_t *buf, void *data, int length)
|
||||
{
|
||||
memcpy (SZ_GetSpace(buf,length),data,length);
|
||||
}
|
||||
|
||||
void SZ_Print (sizebuf_t *buf, char *data)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = strlen(data)+1;
|
||||
|
||||
if (!buf->cursize || buf->data[buf->cursize-1])
|
||||
memcpy ((byte *)SZ_GetSpace(buf, len),data,len); // no trailing 0
|
||||
else
|
||||
memcpy ((byte *)SZ_GetSpace(buf, len-1)-1,data,len); // write over trailing 0
|
||||
}
|
|
@ -1,9 +1,13 @@
|
|||
/*
|
||||
va.c
|
||||
|
||||
varargs printf function
|
||||
/*
|
||||
cvar.c
|
||||
|
||||
dynamic variable tracking
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
Copyright (C) 1999,2000 Nelson Rush.
|
||||
Copyright (C) 1999,2000 contributors of the QuakeForge project
|
||||
Please see the file "AUTHORS" for a list of contributors
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
|
@ -29,27 +33,16 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "qtypes.h"
|
||||
#include "cvar.h"
|
||||
#include "server.h"
|
||||
|
||||
/*
|
||||
va
|
||||
|
||||
does a varargs printf into a temp buffer, so I don't need to have
|
||||
varargs versions of all text functions.
|
||||
FIXME: make this buffer size safe someday
|
||||
*/
|
||||
char *
|
||||
va(char *format, ...)
|
||||
void
|
||||
Cvar_Info (cvar_t *var)
|
||||
{
|
||||
va_list argptr;
|
||||
static char string[1024];
|
||||
|
||||
va_start (argptr, format);
|
||||
vsnprintf (string, sizeof(string), format, argptr);
|
||||
va_end (argptr);
|
||||
|
||||
return string;
|
||||
if (var->flags & CVAR_SERVERINFO) {
|
||||
if (sv.active)
|
||||
SV_BroadcastPrintf ("\"%s\" changed to \"%s\"\n",
|
||||
var->name, var->string);
|
||||
}
|
||||
}
|
680
nq/source/zone.c
680
nq/source/zone.c
|
@ -1,680 +0,0 @@
|
|||
/*
|
||||
zone.c
|
||||
|
||||
(description)
|
||||
|
||||
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
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "cmd.h"
|
||||
#include "console.h"
|
||||
#include "qargs.h"
|
||||
#include "sys.h"
|
||||
#include "zone.h"
|
||||
|
||||
#define DYNAMIC_SIZE 0x20000
|
||||
#define ZONEID 0x1d4a11
|
||||
#define HUNK_SENTINAL 0x1df001ed
|
||||
|
||||
#define MINFRAGMENT 64
|
||||
|
||||
void Cache_FreeLow (int new_low_hunk);
|
||||
void Cache_FreeHigh (int new_high_hunk);
|
||||
|
||||
|
||||
/*
|
||||
The zone calls are pretty much only used for small strings and structures,
|
||||
all big things are allocated on the hunk.
|
||||
*/
|
||||
|
||||
//============================================================================
|
||||
|
||||
typedef struct {
|
||||
int sentinal;
|
||||
int size; // including sizeof(hunk_t), -1 = not
|
||||
// allocated
|
||||
char name[8];
|
||||
} hunk_t;
|
||||
|
||||
byte *hunk_base;
|
||||
int hunk_size;
|
||||
|
||||
int hunk_low_used;
|
||||
int hunk_high_used;
|
||||
|
||||
qboolean hunk_tempactive;
|
||||
int hunk_tempmark;
|
||||
|
||||
void R_FreeTextures (void);
|
||||
|
||||
/*
|
||||
Hunk_Check
|
||||
|
||||
Run consistancy and sentinal trahing checks
|
||||
*/
|
||||
void
|
||||
Hunk_Check (void)
|
||||
{
|
||||
hunk_t *h;
|
||||
|
||||
for (h = (hunk_t *) hunk_base; (byte *) h != hunk_base + hunk_low_used;) {
|
||||
if (h->sentinal != HUNK_SENTINAL)
|
||||
Sys_Error ("Hunk_Check: trashed sentinal");
|
||||
if (h->size < 16 || h->size + (byte *) h - hunk_base > hunk_size)
|
||||
Sys_Error ("Hunk_Check: bad size");
|
||||
h = (hunk_t *) ((byte *) h + h->size);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Hunk_Print
|
||||
|
||||
If "all" is specified, every single allocation is printed.
|
||||
Otherwise, allocations with the same name will be totaled up before
|
||||
printing.
|
||||
*/
|
||||
void
|
||||
Hunk_Print (qboolean all)
|
||||
{
|
||||
hunk_t *h, *next, *endlow, *starthigh, *endhigh;
|
||||
int count, sum;
|
||||
int totalblocks;
|
||||
char name[9];
|
||||
|
||||
name[8] = 0;
|
||||
count = 0;
|
||||
sum = 0;
|
||||
totalblocks = 0;
|
||||
|
||||
h = (hunk_t *) hunk_base;
|
||||
endlow = (hunk_t *) (hunk_base + hunk_low_used);
|
||||
starthigh = (hunk_t *) (hunk_base + hunk_size - hunk_high_used);
|
||||
endhigh = (hunk_t *) (hunk_base + hunk_size);
|
||||
|
||||
Con_Printf (" :%8i total hunk size\n", hunk_size);
|
||||
Con_Printf ("-------------------------\n");
|
||||
|
||||
while (1) {
|
||||
//
|
||||
// skip to the high hunk if done with low hunk
|
||||
//
|
||||
if (h == endlow) {
|
||||
Con_Printf ("-------------------------\n");
|
||||
Con_Printf (" :%8i REMAINING\n",
|
||||
hunk_size - hunk_low_used - hunk_high_used);
|
||||
Con_Printf ("-------------------------\n");
|
||||
h = starthigh;
|
||||
}
|
||||
//
|
||||
// if totally done, break
|
||||
//
|
||||
if (h == endhigh)
|
||||
break;
|
||||
|
||||
//
|
||||
// run consistancy checks
|
||||
//
|
||||
if (h->sentinal != HUNK_SENTINAL)
|
||||
Sys_Error ("Hunk_Check: trahsed sentinal");
|
||||
if (h->size < 16 || h->size + (byte *) h - hunk_base > hunk_size)
|
||||
Sys_Error ("Hunk_Check: bad size");
|
||||
|
||||
next = (hunk_t *) ((byte *) h + h->size);
|
||||
count++;
|
||||
totalblocks++;
|
||||
sum += h->size;
|
||||
|
||||
//
|
||||
// print the single block
|
||||
//
|
||||
memcpy (name, h->name, 8);
|
||||
if (all)
|
||||
Con_Printf ("%8p :%8i %8s\n", h, h->size, name);
|
||||
|
||||
//
|
||||
// print the total
|
||||
//
|
||||
if (next == endlow || next == endhigh ||
|
||||
strncmp (h->name, next->name, 8)) {
|
||||
if (!all)
|
||||
Con_Printf (" :%8i %8s (TOTAL)\n", sum, name);
|
||||
count = 0;
|
||||
sum = 0;
|
||||
}
|
||||
|
||||
h = next;
|
||||
}
|
||||
|
||||
Con_Printf ("-------------------------\n");
|
||||
Con_Printf ("%8i total blocks\n", totalblocks);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Hunk_AllocName
|
||||
*/
|
||||
void *
|
||||
Hunk_AllocName (int size, char *name)
|
||||
{
|
||||
hunk_t *h;
|
||||
|
||||
#ifdef PARANOID
|
||||
Hunk_Check ();
|
||||
#endif
|
||||
|
||||
if (size < 0)
|
||||
Sys_Error ("Hunk_Alloc: bad size: %i", size);
|
||||
|
||||
size = sizeof (hunk_t) + ((size + 15) & ~15);
|
||||
|
||||
if (hunk_size - hunk_low_used - hunk_high_used < size)
|
||||
// Sys_Error ("Hunk_Alloc: failed on %i bytes",size);
|
||||
#ifdef _WIN32
|
||||
Sys_Error
|
||||
("Not enough RAM allocated. Try starting using \"-heapsize 16000\" on the %s command line.",
|
||||
PROGRAM);
|
||||
#else
|
||||
Sys_Error
|
||||
("Not enough RAM allocated. Try starting using \"-mem 16\" on the %s command line.",
|
||||
PROGRAM);
|
||||
#endif
|
||||
|
||||
h = (hunk_t *) (hunk_base + hunk_low_used);
|
||||
hunk_low_used += size;
|
||||
|
||||
Cache_FreeLow (hunk_low_used);
|
||||
|
||||
memset (h, 0, size);
|
||||
|
||||
h->size = size;
|
||||
h->sentinal = HUNK_SENTINAL;
|
||||
strncpy (h->name, name, 8);
|
||||
|
||||
return (void *) (h + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
Hunk_Alloc
|
||||
*/
|
||||
void *
|
||||
Hunk_Alloc (int size)
|
||||
{
|
||||
return Hunk_AllocName (size, "unknown");
|
||||
}
|
||||
|
||||
int
|
||||
Hunk_LowMark (void)
|
||||
{
|
||||
return hunk_low_used;
|
||||
}
|
||||
|
||||
void
|
||||
Hunk_FreeToLowMark (int mark)
|
||||
{
|
||||
if (mark < 0 || mark > hunk_low_used)
|
||||
Sys_Error ("Hunk_FreeToLowMark: bad mark %i", mark);
|
||||
memset (hunk_base + mark, 0, hunk_low_used - mark);
|
||||
hunk_low_used = mark;
|
||||
}
|
||||
|
||||
int
|
||||
Hunk_HighMark (void)
|
||||
{
|
||||
if (hunk_tempactive) {
|
||||
hunk_tempactive = false;
|
||||
Hunk_FreeToHighMark (hunk_tempmark);
|
||||
}
|
||||
|
||||
return hunk_high_used;
|
||||
}
|
||||
|
||||
void
|
||||
Hunk_FreeToHighMark (int mark)
|
||||
{
|
||||
if (hunk_tempactive) {
|
||||
hunk_tempactive = false;
|
||||
Hunk_FreeToHighMark (hunk_tempmark);
|
||||
}
|
||||
if (mark < 0 || mark > hunk_high_used)
|
||||
Sys_Error ("Hunk_FreeToHighMark: bad mark %i", mark);
|
||||
memset (hunk_base + hunk_size - hunk_high_used, 0, hunk_high_used - mark);
|
||||
hunk_high_used = mark;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Hunk_HighAllocName
|
||||
*/
|
||||
void *
|
||||
Hunk_HighAllocName (int size, char *name)
|
||||
{
|
||||
hunk_t *h;
|
||||
|
||||
if (size < 0)
|
||||
Sys_Error ("Hunk_HighAllocName: bad size: %i", size);
|
||||
|
||||
if (hunk_tempactive) {
|
||||
Hunk_FreeToHighMark (hunk_tempmark);
|
||||
hunk_tempactive = false;
|
||||
}
|
||||
#ifdef PARANOID
|
||||
Hunk_Check ();
|
||||
#endif
|
||||
|
||||
size = sizeof (hunk_t) + ((size + 15) & ~15);
|
||||
|
||||
if (hunk_size - hunk_low_used - hunk_high_used < size) {
|
||||
Con_Printf ("Hunk_HighAlloc: failed on %i bytes\n", size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hunk_high_used += size;
|
||||
Cache_FreeHigh (hunk_high_used);
|
||||
|
||||
h = (hunk_t *) (hunk_base + hunk_size - hunk_high_used);
|
||||
|
||||
memset (h, 0, size);
|
||||
h->size = size;
|
||||
h->sentinal = HUNK_SENTINAL;
|
||||
strncpy (h->name, name, 8);
|
||||
|
||||
return (void *) (h + 1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Hunk_TempAlloc
|
||||
|
||||
Return space from the top of the hunk
|
||||
*/
|
||||
void *
|
||||
Hunk_TempAlloc (int size)
|
||||
{
|
||||
void *buf;
|
||||
|
||||
size = (size + 15) & ~15;
|
||||
|
||||
if (hunk_tempactive) {
|
||||
Hunk_FreeToHighMark (hunk_tempmark);
|
||||
hunk_tempactive = false;
|
||||
}
|
||||
|
||||
hunk_tempmark = Hunk_HighMark ();
|
||||
|
||||
buf = Hunk_HighAllocName (size, "temp");
|
||||
|
||||
hunk_tempactive = true;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
CACHE MEMORY
|
||||
*/
|
||||
|
||||
typedef struct cache_system_s {
|
||||
int size; // including this header
|
||||
cache_user_t *user;
|
||||
char name[16];
|
||||
struct cache_system_s *prev, *next;
|
||||
struct cache_system_s *lru_prev, *lru_next; // for LRU flushing
|
||||
} cache_system_t;
|
||||
|
||||
cache_system_t *Cache_TryAlloc (int size, qboolean nobottom);
|
||||
|
||||
cache_system_t cache_head;
|
||||
|
||||
/*
|
||||
Cache_Move
|
||||
*/
|
||||
void
|
||||
Cache_Move (cache_system_t * c)
|
||||
{
|
||||
cache_system_t *new;
|
||||
|
||||
// we are clearing up space at the bottom, so only allocate it late
|
||||
new = Cache_TryAlloc (c->size, true);
|
||||
if (new) {
|
||||
// Con_Printf ("cache_move ok\n");
|
||||
|
||||
memcpy (new + 1, c + 1, c->size - sizeof (cache_system_t));
|
||||
new->user = c->user;
|
||||
memcpy (new->name, c->name, sizeof (new->name));
|
||||
Cache_Free (c->user);
|
||||
new->user->data = (void *) (new + 1);
|
||||
} else {
|
||||
// Con_Printf ("cache_move failed\n");
|
||||
|
||||
Cache_Free (c->user); // tough luck...
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Cache_FreeLow
|
||||
|
||||
Throw things out until the hunk can be expanded to the given point
|
||||
*/
|
||||
void
|
||||
Cache_FreeLow (int new_low_hunk)
|
||||
{
|
||||
cache_system_t *c;
|
||||
|
||||
while (1) {
|
||||
c = cache_head.next;
|
||||
if (c == &cache_head)
|
||||
return; // nothing in cache at all
|
||||
if ((byte *) c >= hunk_base + new_low_hunk)
|
||||
return; // there is space to grow the hunk
|
||||
Cache_Move (c); // reclaim the space
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Cache_FreeHigh
|
||||
|
||||
Throw things out until the hunk can be expanded to the given point
|
||||
*/
|
||||
void
|
||||
Cache_FreeHigh (int new_high_hunk)
|
||||
{
|
||||
cache_system_t *c, *prev;
|
||||
|
||||
prev = NULL;
|
||||
while (1) {
|
||||
c = cache_head.prev;
|
||||
if (c == &cache_head)
|
||||
return; // nothing in cache at all
|
||||
if ((byte *) c + c->size <= hunk_base + hunk_size - new_high_hunk)
|
||||
return; // there is space to grow the hunk
|
||||
if (c == prev)
|
||||
Cache_Free (c->user); // didn't move out of the way
|
||||
else {
|
||||
Cache_Move (c); // try to move it
|
||||
prev = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Cache_UnlinkLRU (cache_system_t * cs)
|
||||
{
|
||||
if (!cs->lru_next || !cs->lru_prev)
|
||||
Sys_Error ("Cache_UnlinkLRU: NULL link");
|
||||
|
||||
cs->lru_next->lru_prev = cs->lru_prev;
|
||||
cs->lru_prev->lru_next = cs->lru_next;
|
||||
|
||||
cs->lru_prev = cs->lru_next = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
Cache_MakeLRU (cache_system_t * cs)
|
||||
{
|
||||
if (cs->lru_next || cs->lru_prev)
|
||||
Sys_Error ("Cache_MakeLRU: active link");
|
||||
|
||||
cache_head.lru_next->lru_prev = cs;
|
||||
cs->lru_next = cache_head.lru_next;
|
||||
cs->lru_prev = &cache_head;
|
||||
cache_head.lru_next = cs;
|
||||
}
|
||||
|
||||
/*
|
||||
Cache_TryAlloc
|
||||
|
||||
Looks for a free block of memory between the high and low hunk marks
|
||||
Size should already include the header and padding
|
||||
*/
|
||||
cache_system_t *
|
||||
Cache_TryAlloc (int size, qboolean nobottom)
|
||||
{
|
||||
cache_system_t *cs, *new;
|
||||
|
||||
// is the cache completely empty?
|
||||
|
||||
if (!nobottom && cache_head.prev == &cache_head) {
|
||||
if (hunk_size - hunk_high_used - hunk_low_used < size)
|
||||
Sys_Error ("Cache_TryAlloc: %i is greater then free hunk", size);
|
||||
|
||||
new = (cache_system_t *) (hunk_base + hunk_low_used);
|
||||
memset (new, 0, sizeof (*new));
|
||||
new->size = size;
|
||||
|
||||
cache_head.prev = cache_head.next = new;
|
||||
new->prev = new->next = &cache_head;
|
||||
|
||||
Cache_MakeLRU (new);
|
||||
return new;
|
||||
}
|
||||
// search from the bottom up for space
|
||||
|
||||
new = (cache_system_t *) (hunk_base + hunk_low_used);
|
||||
cs = cache_head.next;
|
||||
|
||||
do {
|
||||
if (!nobottom || cs != cache_head.next) {
|
||||
if ((byte *) cs - (byte *) new >= size) { // found space
|
||||
memset (new, 0, sizeof (*new));
|
||||
new->size = size;
|
||||
|
||||
new->next = cs;
|
||||
new->prev = cs->prev;
|
||||
cs->prev->next = new;
|
||||
cs->prev = new;
|
||||
|
||||
Cache_MakeLRU (new);
|
||||
|
||||
return new;
|
||||
}
|
||||
}
|
||||
// continue looking
|
||||
new = (cache_system_t *) ((byte *) cs + cs->size);
|
||||
cs = cs->next;
|
||||
|
||||
} while (cs != &cache_head);
|
||||
|
||||
// try to allocate one at the very end
|
||||
if (hunk_base + hunk_size - hunk_high_used - (byte *) new >= size) {
|
||||
memset (new, 0, sizeof (*new));
|
||||
new->size = size;
|
||||
|
||||
new->next = &cache_head;
|
||||
new->prev = cache_head.prev;
|
||||
cache_head.prev->next = new;
|
||||
cache_head.prev = new;
|
||||
|
||||
Cache_MakeLRU (new);
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
return NULL; // couldn't allocate
|
||||
}
|
||||
|
||||
/*
|
||||
Cache_Flush
|
||||
|
||||
Throw everything out, so new data will be demand cached
|
||||
*/
|
||||
void
|
||||
Cache_Flush (void)
|
||||
{
|
||||
while (cache_head.next != &cache_head)
|
||||
Cache_Free (cache_head.next->user); // reclaim the space
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Cache_Print
|
||||
*/
|
||||
void
|
||||
Cache_Print (void)
|
||||
{
|
||||
cache_system_t *cd;
|
||||
|
||||
for (cd = cache_head.next; cd != &cache_head; cd = cd->next) {
|
||||
Con_Printf ("%8i : %s\n", cd->size, cd->name);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Cache_Report
|
||||
*/
|
||||
void
|
||||
Cache_Report (void)
|
||||
{
|
||||
Con_DPrintf ("%4.1f megabyte data cache\n",
|
||||
(hunk_size - hunk_high_used -
|
||||
hunk_low_used) / (float) (1024 * 1024));
|
||||
}
|
||||
|
||||
/*
|
||||
Cache_Compact
|
||||
*/
|
||||
void
|
||||
Cache_Compact (void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
Cache_Init
|
||||
*/
|
||||
void
|
||||
Cache_Init (void)
|
||||
{
|
||||
cache_head.next = cache_head.prev = &cache_head;
|
||||
cache_head.lru_next = cache_head.lru_prev = &cache_head;
|
||||
|
||||
Cmd_AddCommand ("flush", Cache_Flush, "Clears the current game cache");
|
||||
}
|
||||
|
||||
/*
|
||||
Cache_Free
|
||||
|
||||
Frees the memory and removes it from the LRU list
|
||||
*/
|
||||
void
|
||||
Cache_Free (cache_user_t *c)
|
||||
{
|
||||
cache_system_t *cs;
|
||||
|
||||
if (!c->data)
|
||||
Sys_Error ("Cache_Free: not allocated");
|
||||
|
||||
cs = ((cache_system_t *) c->data) - 1;
|
||||
|
||||
cs->prev->next = cs->next;
|
||||
cs->next->prev = cs->prev;
|
||||
cs->next = cs->prev = NULL;
|
||||
|
||||
c->data = NULL;
|
||||
|
||||
Cache_UnlinkLRU (cs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Cache_Check
|
||||
*/
|
||||
void *
|
||||
Cache_Check (cache_user_t *c)
|
||||
{
|
||||
cache_system_t *cs;
|
||||
|
||||
if (!c->data)
|
||||
return NULL;
|
||||
|
||||
cs = ((cache_system_t *) c->data) - 1;
|
||||
|
||||
// move to head of LRU
|
||||
Cache_UnlinkLRU (cs);
|
||||
Cache_MakeLRU (cs);
|
||||
|
||||
return c->data;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Cache_Alloc
|
||||
*/
|
||||
void *
|
||||
Cache_Alloc (cache_user_t *c, int size, char *name)
|
||||
{
|
||||
cache_system_t *cs;
|
||||
|
||||
if (c->data)
|
||||
Sys_Error ("Cache_Alloc: already allocated");
|
||||
|
||||
if (size <= 0)
|
||||
Sys_Error ("Cache_Alloc: size %i", size);
|
||||
|
||||
size = (size + sizeof (cache_system_t) + 15) & ~15;
|
||||
|
||||
// find memory for it
|
||||
while (1) {
|
||||
cs = Cache_TryAlloc (size, false);
|
||||
if (cs) {
|
||||
strncpy (cs->name, name, sizeof (cs->name) - 1);
|
||||
c->data = (void *) (cs + 1);
|
||||
cs->user = c;
|
||||
break;
|
||||
}
|
||||
// free the least recently used cahedat
|
||||
if (cache_head.lru_prev == &cache_head)
|
||||
Sys_Error ("Cache_Alloc: out of memory");
|
||||
// not enough memory at all
|
||||
Cache_Free (cache_head.lru_prev->user);
|
||||
}
|
||||
|
||||
return Cache_Check (c);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
|
||||
/*
|
||||
Memory_Init
|
||||
*/
|
||||
void
|
||||
Memory_Init (void *buf, int size)
|
||||
{
|
||||
hunk_base = buf;
|
||||
hunk_size = size;
|
||||
hunk_low_used = 0;
|
||||
hunk_high_used = 0;
|
||||
|
||||
Cache_Init ();
|
||||
}
|
|
@ -49,10 +49,10 @@ endif
|
|||
if ASM_ARCH
|
||||
math_ASM = math.S sys_x86.S
|
||||
endif
|
||||
common_SOURCES= buildnum.c checksum.c cmd.c com.c crc.c cvar.c hash.c \
|
||||
info.c link.c mathlib.c mdfour.c model.c model_brush.c \
|
||||
common_SOURCES= buildnum.c checksum.c com.c crc.c \
|
||||
info.c link.c mathlib.c model.c model_brush.c \
|
||||
msg.c pmove.c pmovetst.c qargs.c qendian.c quakefs.c quakeio.c \
|
||||
sizebuf.c va.c zone.c $(math_ASM) $(packetlogger)
|
||||
$(math_ASM) $(packetlogger)
|
||||
|
||||
#
|
||||
# ... Network type
|
||||
|
@ -86,8 +86,8 @@ server_SOURCES= pr_edict.c pr_exec.c pr_offs.c sv_ccmds.c sv_cvar.c \
|
|||
sv_user.c ver_check.c world.c $(world_ASM)
|
||||
|
||||
qw_server_SOURCES= $(common_SOURCES) $(server_SOURCES)
|
||||
qw_server_LDADD= -L. -lqfnet -lqfsys_sv $(NET_LIBS) $(Z_LIBS) $(DL_LIBS)
|
||||
qw_server_DEPENDENCIES= libqfnet.a libqfsys_sv.a
|
||||
qw_server_LDADD= -L. -L../../libs -lqfnet -lqfsys_sv -lutil $(NET_LIBS) $(Z_LIBS) $(DL_LIBS)
|
||||
qw_server_DEPENDENCIES= libqfnet.a libqfsys_sv.a ../../libs/libutil.a
|
||||
|
||||
#
|
||||
# Client builds
|
||||
|
@ -170,7 +170,8 @@ endif
|
|||
libqfjs_a_CFLAGS= $(JOY_CFLAGS)
|
||||
EXTRA_libqfjs_a_SOURCES= joy_linux.c joy_win.c joy_null.c
|
||||
|
||||
CLIENT_LIBS= -L. -lqfnet -lqfsys_cl -lqfsnd -lqfcd -lqfjs $(SOUND_LIBS) $(NET_LIBS) $(CD_LIBS) $(JOY_LIBS) $(Z_LIBS)
|
||||
CLIENT_LIBS= -L. -L../../libs -lqfnet -lqfsys_cl -lqfsnd -lqfcd -lqfjs -lutil $(SOUND_LIBS) $(NET_LIBS) $(CD_LIBS) $(JOY_LIBS) $(Z_LIBS)
|
||||
CLIENT_LIB_DEPS= libqfnet.a libqfsys_cl.a libqfsnd.a libqfcd.a libqfjs.a ../../libs/libutil.a
|
||||
|
||||
if ASM_ARCH
|
||||
client_ASM= snd_mixa.S cl_math.S
|
||||
|
@ -215,7 +216,7 @@ fbset_modes_l.o: fbset_modes_l.c
|
|||
|
||||
qw_client_fbdev_SOURCES= $(common_SOURCES) $(client_SOURCES) $(soft_SOURCES) $(fbdev_SOURCES)
|
||||
qw_client_fbdev_LDADD= $(CLIENT_LIBS)
|
||||
qw_client_fbdev_DEPENDENCIES=libqfnet.a libqfsys_cl.a libqfsnd.a libqfcd.a libqfjs.a
|
||||
qw_client_fbdev_DEPENDENCIES= $(CLIENT_LIB_DEPS)
|
||||
|
||||
#
|
||||
# ... SciTech MGL
|
||||
|
@ -224,7 +225,7 @@ mgl_SOURCES= vid_mgl.c in_win.c
|
|||
|
||||
qw_client_mgl_SOURCES= $(common_SOURCES) $(client_SOURCES) $(soft_SOURCES) $(mgl_SOURCES)
|
||||
qw_client_mgl_LDADD= $(MGL_LIBS) $(CLIENT_LIBS)
|
||||
qw_client_mgl_DEPENDENCIES=libqfnet.a libqfsys_cl.a libqfsnd.a libqfcd.a libqfjs.a
|
||||
qw_client_mgl_DEPENDENCIES= $(CLIENT_LIB_DEPS)
|
||||
|
||||
#
|
||||
# ... Sam Lantinga's Simple DirectMedia Layer, version 1.0 and higher
|
||||
|
@ -233,7 +234,7 @@ sdl_SOURCES= vid_sdl.c in_sdl.c
|
|||
|
||||
qw_client_sdl_SOURCES= $(common_SOURCES) $(client_SOURCES) $(soft_SOURCES) $(sdl_SOURCES)
|
||||
qw_client_sdl_LDADD= $(SDL_LIBS) $(CLIENT_LIBS)
|
||||
qw_client_sdl_DEPENDENCIES=libqfnet.a libqfsys_cl.a libqfsnd.a libqfcd.a libqfjs.a
|
||||
qw_client_sdl_DEPENDENCIES= $(CLIENT_LIB_DEPS)
|
||||
|
||||
#
|
||||
# ... Linux SVGAlib
|
||||
|
@ -242,7 +243,7 @@ svga_SOURCES= d_copy.S vid_svgalib.c in_svgalib.c
|
|||
|
||||
qw_client_svga_SOURCES= $(common_SOURCES) $(client_SOURCES) $(soft_SOURCES) $(svga_SOURCES)
|
||||
qw_client_svga_LDADD= $(SVGA_LIBS) $(CLIENT_LIBS)
|
||||
qw_client_svga_DEPENDENCIES=libqfnet.a libqfsys_cl.a libqfsnd.a libqfcd.a libqfjs.a
|
||||
qw_client_svga_DEPENDENCIES= $(CLIENT_LIB_DEPS)
|
||||
|
||||
#
|
||||
# ... X11
|
||||
|
@ -251,7 +252,7 @@ x11_SOURCES= vid_x11.c in_x11.c context_x11.c dga_check.c
|
|||
|
||||
qw_client_x11_SOURCES= $(common_SOURCES) $(client_SOURCES) $(soft_SOURCES) $(x11_SOURCES)
|
||||
qw_client_x11_LDADD= $(X_PRE_LIBS) $(VIDMODE_LIBS) $(DGA_LIBS) $(X_LIBS) -lX11 $(X_EXTRA_LIBS) $(X_SHM_LIB) $(CLIENT_LIBS)
|
||||
qw_client_x11_DEPENDENCIES=libqfnet.a libqfsys_cl.a libqfsnd.a libqfcd.a libqfjs.a
|
||||
qw_client_x11_DEPENDENCIES= $(CLIENT_LIB_DEPS)
|
||||
|
||||
|
||||
#
|
||||
|
@ -273,7 +274,7 @@ tdfx_SOURCES= vid_3dfxsvga.c vid_common_gl.c in_svgalib.c
|
|||
|
||||
qw_client_3dfx_SOURCES= $(common_SOURCES) $(client_SOURCES) $(ogl_SOURCES) $(tdfx_SOURCES)
|
||||
qw_client_3dfx_LDADD= $(TDFXGL_LIBS) $(SVGA_LIBS) $(CLIENT_LIBS) $(DL_LIBS)
|
||||
qw_client_3dfx_DEPENDENCIES=libqfnet.a libqfsys_cl.a libqfsnd.a libqfcd.a libqfjs.a
|
||||
qw_client_3dfx_DEPENDENCIES= $(CLIENT_LIB_DEPS)
|
||||
|
||||
#
|
||||
# ... OpenGL in X Window
|
||||
|
@ -282,7 +283,7 @@ glx_SOURCES= vid_glx.c vid_common_gl.c in_x11.c context_x11.c dga_check.c
|
|||
|
||||
qw_client_glx_SOURCES= $(common_SOURCES) $(client_SOURCES) $(ogl_SOURCES) $(glx_SOURCES)
|
||||
qw_client_glx_LDADD= $(GLX_LIBS) $(X_PRE_LIBS) $(VIDMODE_LIBS) $(DGA_LIBS) $(X_LIBS) -lX11 $(X_EXTRA_LIBS) $(CLIENT_LIBS) $(DL_LIBS)
|
||||
qw_client_glx_DEPENDENCIES=libqfnet.a libqfsys_cl.a libqfsnd.a libqfcd.a libqfjs.a
|
||||
qw_client_glx_DEPENDENCIES= $(CLIENT_LIB_DEPS)
|
||||
|
||||
#
|
||||
# ... Sam Lantinga's Simple DirectMedia Layer, version 1.1 and higher, in GL mode
|
||||
|
@ -291,7 +292,7 @@ sgl_SOURCES= vid_sgl.c vid_common_gl.c in_sdl.c
|
|||
|
||||
qw_client_sgl_SOURCES= $(common_SOURCES) $(client_SOURCES) $(ogl_SOURCES) $(sgl_SOURCES)
|
||||
qw_client_sgl_LDADD= $(SDL_LIBS) $(X_LIBS) $(GLX_LIBS) $(CLIENT_LIBS) $(DL_LIBS)
|
||||
qw_client_sgl_DEPENDENCIES=libqfnet.a libqfsys_cl.a libqfsnd.a libqfcd.a libqfjs.a
|
||||
qw_client_sgl_DEPENDENCIES= $(CLIENT_LIB_DEPS)
|
||||
|
||||
#
|
||||
# SGI/Microsoft WGL (Windows OpenGL)
|
||||
|
@ -300,7 +301,7 @@ wgl_SOURCES= vid_wgl.c
|
|||
|
||||
qw_client_wgl_SOURCES= $(common_SOURCES) $(client_SOURCES) $(ogl_SOURCES) $(wgl_SOURCES)
|
||||
qw_client_wgl_LDADD= $(CLIENT_LIBS)
|
||||
qw_client_wgl_DEPENDENCIES=libqfnet.a libqfsys_cl.a libqfsnd.a libqfcd.a libqfjs.a
|
||||
qw_client_wgl_DEPENDENCIES= $(CLIENT_LIB_DEPS)
|
||||
|
||||
#
|
||||
# Stuff that doesn't get linked into an executable NEEDS to be mentioned here,
|
||||
|
|
|
@ -110,7 +110,7 @@ Cmd_ForwardToServer_f (void)
|
|||
}
|
||||
|
||||
/*
|
||||
Cmd_Init
|
||||
cl_Cmd_Init
|
||||
*/
|
||||
void
|
||||
cl_Cmd_Init (void)
|
||||
|
|
944
qw/source/cmd.c
944
qw/source/cmd.c
|
@ -1,944 +0,0 @@
|
|||
/*
|
||||
cmd.c
|
||||
|
||||
script command processing module
|
||||
|
||||
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
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "cvar.h"
|
||||
#include "cmd.h"
|
||||
#include "console.h"
|
||||
#include "hash.h"
|
||||
#include "host.h"
|
||||
#include "qargs.h"
|
||||
#include "qendian.h"
|
||||
#include "quakefs.h"
|
||||
#include "sizebuf.h"
|
||||
#include "sys.h"
|
||||
#include "zone.h"
|
||||
|
||||
void Cmd_ForwardToServer (void);
|
||||
|
||||
#define MAX_ALIAS_NAME 32
|
||||
|
||||
typedef struct cmdalias_s {
|
||||
struct cmdalias_s *next;
|
||||
char name[MAX_ALIAS_NAME];
|
||||
char *value;
|
||||
} cmdalias_t;
|
||||
|
||||
cmdalias_t *cmd_alias;
|
||||
cmd_source_t cmd_source;
|
||||
qboolean cmd_wait;
|
||||
|
||||
cvar_t *cl_warncmd;
|
||||
|
||||
hashtab_t *cmd_alias_hash;
|
||||
hashtab_t *cmd_hash;
|
||||
|
||||
//=============================================================================
|
||||
|
||||
/*
|
||||
Cmd_Wait_f
|
||||
|
||||
Causes execution of the remainder of the command buffer to be delayed until
|
||||
next frame. This allows commands like:
|
||||
bind g "impulse 5 ; +attack ; wait ; -attack ; impulse 2"
|
||||
*/
|
||||
void
|
||||
Cmd_Wait_f (void)
|
||||
{
|
||||
cmd_wait = true;
|
||||
}
|
||||
|
||||
/*
|
||||
COMMAND BUFFER
|
||||
*/
|
||||
|
||||
sizebuf_t cmd_text;
|
||||
byte cmd_text_buf[8192];
|
||||
|
||||
/*
|
||||
Cbuf_Init
|
||||
*/
|
||||
void
|
||||
Cbuf_Init (void)
|
||||
{
|
||||
cmd_text.data = cmd_text_buf;
|
||||
cmd_text.maxsize = sizeof (cmd_text_buf);
|
||||
}
|
||||
|
||||
/*
|
||||
Cbuf_AddText
|
||||
|
||||
Adds command text at the end of the buffer
|
||||
*/
|
||||
void
|
||||
Cbuf_AddText (char *text)
|
||||
{
|
||||
int l;
|
||||
|
||||
l = strlen (text);
|
||||
|
||||
if (cmd_text.cursize + l >= cmd_text.maxsize) {
|
||||
Con_Printf ("Cbuf_AddText: overflow\n");
|
||||
return;
|
||||
}
|
||||
SZ_Write (&cmd_text, text, strlen (text));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Cbuf_InsertText
|
||||
|
||||
Adds command text immediately after the current command
|
||||
Adds a \n to the text
|
||||
TODO: Can we just read the buffer in the reverse order?
|
||||
*/
|
||||
void
|
||||
Cbuf_InsertText (char *text)
|
||||
{
|
||||
int textlen;
|
||||
|
||||
textlen = strlen (text);
|
||||
if (cmd_text.cursize + 1 + textlen >= cmd_text.maxsize) {
|
||||
Con_Printf ("Cbuf_InsertText: overflow\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cmd_text.cursize) {
|
||||
memcpy (cmd_text.data, text, textlen);
|
||||
cmd_text.cursize = textlen;
|
||||
return;
|
||||
}
|
||||
// Move up to make room for inserted text
|
||||
memmove (cmd_text.data + textlen + 1, cmd_text.data, cmd_text.cursize);
|
||||
cmd_text.cursize += textlen + 1;
|
||||
|
||||
// Insert new text
|
||||
memcpy (cmd_text.data, text, textlen);
|
||||
cmd_text.data[textlen] = '\n';
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
extract_line (char *line)
|
||||
{
|
||||
int i;
|
||||
char *text;
|
||||
int quotes;
|
||||
|
||||
// find a \n or ; line break
|
||||
text = (char *) cmd_text.data;
|
||||
quotes = 0;
|
||||
for (i = 0; i < cmd_text.cursize; i++) {
|
||||
if (text[i] == '"')
|
||||
quotes++;
|
||||
if (!(quotes & 1) && text[i] == ';')
|
||||
break; // don't break if inside a quoted
|
||||
// string
|
||||
if (text[i] == '\n' || text[i] == '\r')
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy (line, text, i);
|
||||
line[i] = '\0';
|
||||
// delete the text from the command buffer and move remaining commands
|
||||
// down
|
||||
// this is necessary because commands (exec, alias) can insert data at
|
||||
// the
|
||||
// beginning of the text buffer
|
||||
|
||||
if (i == cmd_text.cursize)
|
||||
cmd_text.cursize = 0;
|
||||
else {
|
||||
i++;
|
||||
cmd_text.cursize -= i;
|
||||
memcpy (text, text + i, cmd_text.cursize);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Cbuf_Execute
|
||||
|
||||
*/
|
||||
void
|
||||
Cbuf_Execute (void)
|
||||
{
|
||||
char line[1024] = { 0 };
|
||||
|
||||
while (cmd_text.cursize) {
|
||||
extract_line (line);
|
||||
// execute the command line
|
||||
// Con_DPrintf("+%s\n",line),
|
||||
Cmd_ExecuteString (line, src_command);
|
||||
|
||||
if (cmd_wait) { // skip out while text still remains
|
||||
// in buffer, leaving it
|
||||
// for next frame
|
||||
cmd_wait = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Cbuf_Execute
|
||||
|
||||
*/
|
||||
void
|
||||
Cbuf_Execute_Sets (void)
|
||||
{
|
||||
char line[1024] = { 0 };
|
||||
|
||||
while (cmd_text.cursize) {
|
||||
extract_line (line);
|
||||
// execute the command line
|
||||
if (strnequal (line, "set", 3) && isspace ((int) line[3])) {
|
||||
// Con_DPrintf ("+%s\n",line);
|
||||
Cmd_ExecuteString (line, src_command);
|
||||
}
|
||||
if (strnequal (line, "setrom", 6) && isspace ((int) line[6])) {
|
||||
// Con_DPrintf ("+%s\n",line);
|
||||
Cmd_ExecuteString (line, src_command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
SCRIPT COMMANDS
|
||||
*/
|
||||
|
||||
/*
|
||||
Cmd_StuffCmds_f
|
||||
|
||||
Adds command line parameters as script statements
|
||||
Commands lead with a +, and continue until a - or another +
|
||||
quake +prog jctest.qp +cmd amlev1
|
||||
quake -nosound +cmd amlev1
|
||||
*/
|
||||
void
|
||||
Cmd_StuffCmds_f (void)
|
||||
{
|
||||
int i, j;
|
||||
int s;
|
||||
char *build, c;
|
||||
|
||||
s = strlen (com_cmdline);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
// pull out the commands
|
||||
build = malloc (s + 1);
|
||||
build[0] = 0;
|
||||
|
||||
for (i = 0; i < s - 1; i++) {
|
||||
if (com_cmdline[i] == '+') {
|
||||
i++;
|
||||
|
||||
for (j = i; !((com_cmdline[j] == '+')
|
||||
|| (com_cmdline[j] == '-'
|
||||
&& (j==0 || com_cmdline[j - 1] == ' '))
|
||||
|| (com_cmdline[j] == 0)); j++);
|
||||
|
||||
c = com_cmdline[j];
|
||||
com_cmdline[j] = 0;
|
||||
|
||||
strncat (build, com_cmdline + i, s - strlen (build));
|
||||
strncat (build, "\n", s - strlen (build));
|
||||
com_cmdline[j] = c;
|
||||
i = j - 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Con_Printf("[\n%s]\n",build);
|
||||
|
||||
if (build[0])
|
||||
Cbuf_InsertText (build);
|
||||
|
||||
free (build);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Cmd_Exec_File
|
||||
|
||||
*/
|
||||
void
|
||||
Cmd_Exec_File (char *path)
|
||||
{
|
||||
char *f;
|
||||
int len;
|
||||
QFile *file;
|
||||
|
||||
if (!path || !*path)
|
||||
return;
|
||||
if ((file = Qopen (path, "r")) != NULL) {
|
||||
len = COM_filelength (file);
|
||||
f = (char *) Hunk_TempAlloc (len + 1);
|
||||
if (f) {
|
||||
f[len] = 0;
|
||||
Qread (file, f, len);
|
||||
Qclose (file);
|
||||
Cbuf_InsertText (f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Cmd_Exec_f
|
||||
*/
|
||||
void
|
||||
Cmd_Exec_f (void)
|
||||
{
|
||||
char *f;
|
||||
int mark;
|
||||
|
||||
if (Cmd_Argc () != 2) {
|
||||
Con_Printf ("exec <filename> : execute a script file\n");
|
||||
return;
|
||||
}
|
||||
// FIXME: is this safe freeing the hunk here?
|
||||
mark = Hunk_LowMark ();
|
||||
f = (char *) COM_LoadHunkFile (Cmd_Argv (1));
|
||||
if (!f) {
|
||||
Con_Printf ("couldn't exec %s\n", Cmd_Argv (1));
|
||||
return;
|
||||
}
|
||||
if (!Cvar_Command () && ((cl_warncmd && cl_warncmd->int_val)
|
||||
|| (developer && developer->int_val)))
|
||||
Con_Printf ("execing %s\n", Cmd_Argv (1));
|
||||
|
||||
Cbuf_InsertText (f);
|
||||
Hunk_FreeToLowMark (mark);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Cmd_Echo_f
|
||||
|
||||
Just prints the rest of the line to the console
|
||||
*/
|
||||
void
|
||||
Cmd_Echo_f (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 1; i < Cmd_Argc (); i++)
|
||||
Con_Printf ("%s ", Cmd_Argv (i));
|
||||
Con_Printf ("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
Cmd_Alias_f
|
||||
|
||||
Creates a new command that executes a command string (possibly ; seperated)
|
||||
*/
|
||||
|
||||
char *
|
||||
CopyString (char *in)
|
||||
{
|
||||
char *out;
|
||||
|
||||
out = malloc (strlen (in) + 1);
|
||||
strcpy (out, in);
|
||||
return out;
|
||||
}
|
||||
|
||||
void
|
||||
Cmd_Alias_f (void)
|
||||
{
|
||||
cmdalias_t *a;
|
||||
char cmd[1024];
|
||||
int i, c;
|
||||
char *s;
|
||||
|
||||
if (Cmd_Argc () == 1) {
|
||||
Con_Printf ("Current alias commands:\n");
|
||||
for (a = cmd_alias; a; a = a->next)
|
||||
Con_Printf ("%s : %s\n", a->name, a->value);
|
||||
return;
|
||||
}
|
||||
|
||||
s = Cmd_Argv (1);
|
||||
if (strlen (s) >= MAX_ALIAS_NAME) {
|
||||
Con_Printf ("Alias name is too long\n");
|
||||
return;
|
||||
}
|
||||
// if the alias already exists, reuse it
|
||||
a = (cmdalias_t*)Hash_Find (cmd_alias_hash, s);
|
||||
if (a) {
|
||||
free (a->value);
|
||||
}
|
||||
|
||||
if (!a) {
|
||||
a = calloc (1, sizeof (cmdalias_t));
|
||||
a->next = cmd_alias;
|
||||
cmd_alias = a;
|
||||
strcpy (a->name, s);
|
||||
Hash_Add (cmd_alias_hash, a);
|
||||
}
|
||||
|
||||
// copy the rest of the command line
|
||||
cmd[0] = 0; // start out with a null string
|
||||
c = Cmd_Argc ();
|
||||
for (i = 2; i < c; i++) {
|
||||
strncat (cmd, Cmd_Argv (i), sizeof (cmd) - strlen (cmd));
|
||||
if (i != c)
|
||||
strncat (cmd, " ", sizeof (cmd) - strlen (cmd));
|
||||
}
|
||||
strncat (cmd, "\n", sizeof (cmd) - strlen (cmd));
|
||||
|
||||
a->value = CopyString (cmd);
|
||||
}
|
||||
|
||||
void
|
||||
Cmd_UnAlias_f (void)
|
||||
{
|
||||
cmdalias_t *a, *prev;
|
||||
char *s;
|
||||
|
||||
if (Cmd_Argc () != 2) {
|
||||
Con_Printf ("unalias <alias>: erase an existing alias\n");
|
||||
return;
|
||||
}
|
||||
|
||||
s = Cmd_Argv (1);
|
||||
if (strlen (s) >= MAX_ALIAS_NAME) {
|
||||
Con_Printf ("Alias name is too long\n");
|
||||
return;
|
||||
}
|
||||
|
||||
prev = cmd_alias;
|
||||
for (a = cmd_alias; a; a = a->next) {
|
||||
if (!strcmp (s, a->name)) {
|
||||
Hash_Del (cmd_alias_hash, s);
|
||||
free (a->value);
|
||||
prev->next = a->next;
|
||||
if (a == cmd_alias)
|
||||
cmd_alias = a->next;
|
||||
free (a);
|
||||
return;
|
||||
}
|
||||
prev = a;
|
||||
}
|
||||
Con_Printf ("Unknown alias \"%s\"\n", s);
|
||||
}
|
||||
|
||||
/*
|
||||
COMMAND EXECUTION
|
||||
*/
|
||||
|
||||
typedef struct cmd_function_s {
|
||||
struct cmd_function_s *next;
|
||||
char *name;
|
||||
xcommand_t function;
|
||||
char *description;
|
||||
} cmd_function_t;
|
||||
|
||||
|
||||
#define MAX_ARGS 80
|
||||
|
||||
static int cmd_argc;
|
||||
static char *cmd_argv[MAX_ARGS];
|
||||
static char *cmd_null_string = "";
|
||||
static char *cmd_args = NULL;
|
||||
|
||||
|
||||
|
||||
static cmd_function_t *cmd_functions; // possible commands to execute
|
||||
|
||||
/*
|
||||
Cmd_Argc
|
||||
*/
|
||||
int
|
||||
Cmd_Argc (void)
|
||||
{
|
||||
return cmd_argc;
|
||||
}
|
||||
|
||||
/*
|
||||
Cmd_Argv
|
||||
*/
|
||||
char *
|
||||
Cmd_Argv (int arg)
|
||||
{
|
||||
if (arg >= cmd_argc)
|
||||
return cmd_null_string;
|
||||
return cmd_argv[arg];
|
||||
}
|
||||
|
||||
/*
|
||||
Cmd_Args
|
||||
|
||||
Returns a single string containing argv(1) to argv(argc()-1)
|
||||
*/
|
||||
char *
|
||||
Cmd_Args (void)
|
||||
{
|
||||
if (!cmd_args)
|
||||
return "";
|
||||
return cmd_args;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Cmd_TokenizeString
|
||||
|
||||
Parses the given string into command line tokens.
|
||||
*/
|
||||
void
|
||||
Cmd_TokenizeString (char *text)
|
||||
{
|
||||
static char argv_buf[1024];
|
||||
int argv_idx;
|
||||
|
||||
argv_idx = 0;
|
||||
|
||||
cmd_argc = 0;
|
||||
cmd_args = NULL;
|
||||
|
||||
while (1) {
|
||||
// skip whitespace up to a /n
|
||||
while (*text && *(unsigned char *) text <= ' ' && *text != '\n') {
|
||||
text++;
|
||||
}
|
||||
|
||||
if (*text == '\n') { // a newline seperates commands in
|
||||
// the buffer
|
||||
text++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!*text)
|
||||
return;
|
||||
|
||||
if (cmd_argc == 1)
|
||||
cmd_args = text;
|
||||
|
||||
text = COM_Parse (text);
|
||||
if (!text)
|
||||
return;
|
||||
|
||||
if (cmd_argc < MAX_ARGS) {
|
||||
if (argv_idx + strlen (com_token) + 1 > 1024) {
|
||||
Con_Printf ("Cmd_TokenizeString: overflow\n");
|
||||
return;
|
||||
}
|
||||
cmd_argv[cmd_argc] = argv_buf + argv_idx;
|
||||
strcpy (cmd_argv[cmd_argc], com_token);
|
||||
argv_idx += strlen (com_token) + 1;
|
||||
|
||||
cmd_argc++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Cmd_AddCommand
|
||||
*/
|
||||
void
|
||||
Cmd_AddCommand (char *cmd_name, xcommand_t function, char *description)
|
||||
{
|
||||
cmd_function_t *cmd;
|
||||
cmd_function_t **c;
|
||||
|
||||
if (host_initialized) // because hunk allocation would get
|
||||
// stomped
|
||||
Sys_Error ("Cmd_AddCommand after host_initialized");
|
||||
|
||||
// fail if the command is a variable name
|
||||
if (Cvar_FindVar (cmd_name)) {
|
||||
Con_Printf ("Cmd_AddCommand: %s already defined as a var\n", cmd_name);
|
||||
return;
|
||||
}
|
||||
// fail if the command already exists
|
||||
cmd = (cmd_function_t*)Hash_Find (cmd_hash, cmd_name);
|
||||
if (cmd) {
|
||||
Con_Printf ("Cmd_AddCommand: %s already defined\n", cmd_name);
|
||||
return;
|
||||
}
|
||||
|
||||
cmd = Hunk_Alloc (sizeof (cmd_function_t));
|
||||
cmd->name = cmd_name;
|
||||
cmd->function = function;
|
||||
cmd->description = description;
|
||||
Hash_Add (cmd_hash, cmd);
|
||||
for (c = &cmd_functions; *c; c = &(*c)->next)
|
||||
if (strcmp ((*c)->name, cmd->name) >=0)
|
||||
break;
|
||||
cmd->next = *c;
|
||||
*c = cmd;
|
||||
}
|
||||
|
||||
/*
|
||||
Cmd_Exists
|
||||
*/
|
||||
qboolean
|
||||
Cmd_Exists (char *cmd_name)
|
||||
{
|
||||
cmd_function_t *cmd;
|
||||
|
||||
cmd = (cmd_function_t*)Hash_Find (cmd_hash, cmd_name);
|
||||
if (cmd) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Cmd_CompleteCommand
|
||||
*/
|
||||
char *
|
||||
Cmd_CompleteCommand (char *partial)
|
||||
{
|
||||
cmd_function_t *cmd;
|
||||
int len;
|
||||
cmdalias_t *a;
|
||||
|
||||
len = strlen (partial);
|
||||
|
||||
if (!len)
|
||||
return NULL;
|
||||
|
||||
// check for exact match
|
||||
for (cmd = cmd_functions; cmd; cmd = cmd->next)
|
||||
if (!strcasecmp (partial, cmd->name))
|
||||
return cmd->name;
|
||||
for (a = cmd_alias; a; a = a->next)
|
||||
if (!strcasecmp (partial, a->name))
|
||||
return a->name;
|
||||
|
||||
// check for partial match
|
||||
for (cmd = cmd_functions; cmd; cmd = cmd->next)
|
||||
if (!strncasecmp (partial, cmd->name, len))
|
||||
return cmd->name;
|
||||
for (a = cmd_alias; a; a = a->next)
|
||||
if (!strncasecmp (partial, a->name, len))
|
||||
return a->name;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
Cmd_ExpandVariables
|
||||
|
||||
Expand $fov-like expressions
|
||||
FIXME: better handling of buffer overflows?
|
||||
*/
|
||||
// dest must point to a 1024-byte buffer
|
||||
void
|
||||
Cmd_ExpandVariables (char *data, char *dest)
|
||||
{
|
||||
unsigned int c;
|
||||
char buf[1024];
|
||||
int i, len;
|
||||
cvar_t *var, *bestvar;
|
||||
int quotes = 0;
|
||||
|
||||
len = 0;
|
||||
|
||||
// parse a regular word
|
||||
while ((c = *data) != 0) {
|
||||
if (c == '"')
|
||||
quotes++;
|
||||
if (c == '$' && !(quotes & 1)) {
|
||||
data++;
|
||||
|
||||
// Copy the text after '$' to a temp buffer
|
||||
i = 0;
|
||||
buf[0] = 0;
|
||||
bestvar = NULL;
|
||||
while ((c = *data) > 32) {
|
||||
if (c == '$')
|
||||
break;
|
||||
data++;
|
||||
buf[i++] = c;
|
||||
buf[i] = 0;
|
||||
if ((var = Cvar_FindVar (buf)) != 0)
|
||||
bestvar = var;
|
||||
if (i >= sizeof (buf) - 1)
|
||||
break;
|
||||
}
|
||||
|
||||
if (bestvar) {
|
||||
// check buffer size
|
||||
if (len + strlen (bestvar->string) >= 1024 - 1)
|
||||
break;
|
||||
|
||||
strcpy (&dest[len], bestvar->string);
|
||||
len += strlen (bestvar->string);
|
||||
i = strlen (bestvar->name);
|
||||
while (buf[i])
|
||||
dest[len++] = buf[i++];
|
||||
} else {
|
||||
// no matching cvar name was found
|
||||
dest[len++] = '$';
|
||||
if (len + strlen (buf) >= 1024 - 1)
|
||||
break;
|
||||
strcpy (&dest[len], buf);
|
||||
len += strlen (buf);
|
||||
}
|
||||
} else {
|
||||
dest[len] = c;
|
||||
data++;
|
||||
len++;
|
||||
if (len >= 1024 - 1)
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
dest[len] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Cmd_ExecuteString
|
||||
|
||||
A complete command line has been parsed, so try to execute it
|
||||
FIXME: lookupnoadd the token to speed search?
|
||||
*/
|
||||
void
|
||||
Cmd_ExecuteString (char *text, cmd_source_t src)
|
||||
{
|
||||
cmd_function_t *cmd;
|
||||
cmdalias_t *a;
|
||||
char buf[1024];
|
||||
|
||||
cmd_source = src;
|
||||
|
||||
#if 0
|
||||
Cmd_TokenizeString (text);
|
||||
#else
|
||||
Cmd_ExpandVariables (text, buf);
|
||||
Cmd_TokenizeString (buf);
|
||||
#endif
|
||||
|
||||
// execute the command line
|
||||
if (!Cmd_Argc ())
|
||||
return; // no tokens
|
||||
|
||||
// check functions
|
||||
cmd = (cmd_function_t*)Hash_Find (cmd_hash, cmd_argv[0]);
|
||||
if (cmd) {
|
||||
if (!cmd->function)
|
||||
Cmd_ForwardToServer ();
|
||||
else
|
||||
cmd->function ();
|
||||
return;
|
||||
}
|
||||
|
||||
// Tonik: check cvars
|
||||
if (Cvar_Command ())
|
||||
return;
|
||||
|
||||
// check alias
|
||||
a = (cmdalias_t*)Hash_Find (cmd_alias_hash, cmd_argv[0]);
|
||||
if (a) {
|
||||
Cbuf_InsertText (a->value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cl_warncmd->int_val || developer->int_val)
|
||||
Con_Printf ("Unknown command \"%s\"\n", Cmd_Argv (0));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Cmd_CheckParm
|
||||
|
||||
Returns the position (1 to argc-1) in the command's argument list
|
||||
where the given parameter apears, or 0 if not present
|
||||
*/
|
||||
int
|
||||
Cmd_CheckParm (char *parm)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!parm)
|
||||
Sys_Error ("Cmd_CheckParm: NULL");
|
||||
|
||||
for (i = 1; i < Cmd_Argc (); i++)
|
||||
if (!strcasecmp (parm, Cmd_Argv (i)))
|
||||
return i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Cmd_CmdList_f (void)
|
||||
{
|
||||
cmd_function_t *cmd;
|
||||
int i;
|
||||
int show_description = 0;
|
||||
|
||||
if (Cmd_Argc() > 1)
|
||||
show_description = 1;
|
||||
for (cmd = cmd_functions, i = 0; cmd; cmd = cmd->next, i++) {
|
||||
if (show_description) {
|
||||
Con_Printf ("%-20s :\n%s\n", cmd->name, cmd->description);
|
||||
} else {
|
||||
Con_Printf ("%s\n", cmd->name);
|
||||
}
|
||||
}
|
||||
|
||||
Con_Printf ("------------\n%d commands\n", i);
|
||||
}
|
||||
|
||||
static void
|
||||
cmd_alias_free (void *_a)
|
||||
{
|
||||
cmdalias_t *a = (cmdalias_t*)_a;
|
||||
free (a->value);
|
||||
free (a);
|
||||
}
|
||||
|
||||
static char *
|
||||
cmd_alias_get_key (void *_a)
|
||||
{
|
||||
cmdalias_t *a = (cmdalias_t*)_a;
|
||||
return a->name;
|
||||
}
|
||||
|
||||
static char *
|
||||
cmd_get_key (void *c)
|
||||
{
|
||||
cmd_function_t *cmd = (cmd_function_t*)c;
|
||||
return cmd->name;
|
||||
}
|
||||
|
||||
/*
|
||||
Cmd_Init_Hash
|
||||
|
||||
initialise the command and alias hash tables
|
||||
*/
|
||||
|
||||
void
|
||||
Cmd_Init_Hash (void)
|
||||
{
|
||||
cmd_hash = Hash_NewTable (1021, cmd_get_key, 0);
|
||||
cmd_alias_hash = Hash_NewTable (1021, cmd_alias_get_key, cmd_alias_free);
|
||||
}
|
||||
|
||||
/*
|
||||
Cmd_Init
|
||||
*/
|
||||
void
|
||||
Cmd_Init (void)
|
||||
{
|
||||
//
|
||||
// register our commands
|
||||
//
|
||||
Cmd_AddCommand ("stuffcmds", Cmd_StuffCmds_f, "Execute the commands given at startup again");
|
||||
Cmd_AddCommand ("exec", Cmd_Exec_f, "Execute a script file");
|
||||
Cmd_AddCommand ("echo", Cmd_Echo_f, "Print text to console");
|
||||
Cmd_AddCommand ("alias", Cmd_Alias_f, "Used to create a reference to a command or list of commands.\n"
|
||||
"When used without parameters, displays all current aliases.\n"
|
||||
"Note: Enclose multiple commands within quotes and seperate each command with a semi-colon.");
|
||||
Cmd_AddCommand ("unalias", Cmd_UnAlias_f, "Remove the selected alias");
|
||||
Cmd_AddCommand ("wait", Cmd_Wait_f, "Wait a game tic");
|
||||
Cmd_AddCommand ("cmdlist", Cmd_CmdList_f, "List all commands");
|
||||
}
|
||||
|
||||
|
||||
char com_token[MAX_COM_TOKEN];
|
||||
|
||||
/*
|
||||
COM_Parse
|
||||
|
||||
Parse a token out of a string
|
||||
*/
|
||||
char *
|
||||
COM_Parse (char *data)
|
||||
{
|
||||
unsigned int c;
|
||||
int len;
|
||||
|
||||
len = 0;
|
||||
com_token[0] = 0;
|
||||
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
||||
// skip whitespace
|
||||
skipwhite:
|
||||
while ((c = *data) <= ' ') {
|
||||
if (c == 0)
|
||||
return NULL; // end of file;
|
||||
data++;
|
||||
}
|
||||
|
||||
// skip // comments
|
||||
if (c == '/' && data[1] == '/') {
|
||||
while (*data && *data != '\n')
|
||||
data++;
|
||||
goto skipwhite;
|
||||
}
|
||||
|
||||
// handle quoted strings specially
|
||||
if (c == '\"') {
|
||||
data++;
|
||||
while (1) {
|
||||
c = *data++;
|
||||
if (c == '\"' || !c) {
|
||||
com_token[len] = 0;
|
||||
return data;
|
||||
}
|
||||
com_token[len] = c;
|
||||
len++;
|
||||
}
|
||||
}
|
||||
// parse a regular word
|
||||
do {
|
||||
com_token[len] = c;
|
||||
data++;
|
||||
len++;
|
||||
if (len >= MAX_COM_TOKEN - 1)
|
||||
break;
|
||||
|
||||
c = *data;
|
||||
} while (c > 32);
|
||||
|
||||
com_token[len] = 0;
|
||||
return data;
|
||||
}
|
547
qw/source/cvar.c
547
qw/source/cvar.c
|
@ -1,547 +0,0 @@
|
|||
/*
|
||||
cvar.c
|
||||
|
||||
dynamic variable tracking
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
Copyright (C) 1999,2000 Nelson Rush.
|
||||
Copyright (C) 1999,2000 contributors of the QuakeForge project
|
||||
Please see the file "AUTHORS" for a list of contributors
|
||||
|
||||
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
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "commdef.h"
|
||||
#include "cvar.h"
|
||||
#include "console.h"
|
||||
#include "hash.h"
|
||||
#include "qargs.h"
|
||||
#include "cmd.h"
|
||||
#include "commdef.h"
|
||||
|
||||
cvar_t *cvar_vars;
|
||||
char *cvar_null_string = "";
|
||||
extern cvar_t *developer;
|
||||
cvar_alias_t *calias_vars;
|
||||
hashtab_t *cvar_hash;
|
||||
hashtab_t *calias_hash;
|
||||
|
||||
/*
|
||||
Cvar_FindVar
|
||||
*/
|
||||
cvar_t *
|
||||
Cvar_FindVar (char *var_name)
|
||||
{
|
||||
return (cvar_t*) Hash_Find (cvar_hash, var_name);
|
||||
}
|
||||
|
||||
cvar_t *
|
||||
Cvar_FindAlias (char *alias_name)
|
||||
{
|
||||
cvar_alias_t *alias;
|
||||
|
||||
alias = (cvar_alias_t*) Hash_Find (calias_hash, alias_name);
|
||||
if (alias)
|
||||
return alias->cvar;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Cvar_Alias_Get (char *name, cvar_t *cvar)
|
||||
{
|
||||
cvar_alias_t *alias;
|
||||
cvar_t *var;
|
||||
|
||||
if (Cmd_Exists (name)) {
|
||||
Con_Printf ("CAlias_Get: %s is a command\n", name);
|
||||
return;
|
||||
}
|
||||
if (Cvar_FindVar (name)) {
|
||||
Con_Printf ("CAlias_Get: tried to alias used cvar name %s\n", name);
|
||||
return;
|
||||
}
|
||||
var = Cvar_FindAlias (name);
|
||||
if (!var) {
|
||||
alias = (cvar_alias_t *) calloc (1, sizeof (cvar_alias_t));
|
||||
|
||||
alias->next = calias_vars;
|
||||
calias_vars = alias;
|
||||
alias->name = strdup (name);
|
||||
alias->cvar = cvar;
|
||||
Hash_Add (calias_hash, alias);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Cvar_VariableValue
|
||||
*/
|
||||
float
|
||||
Cvar_VariableValue (char *var_name)
|
||||
{
|
||||
cvar_t *var;
|
||||
|
||||
var = Cvar_FindVar (var_name);
|
||||
if (!var)
|
||||
var = Cvar_FindAlias (var_name);
|
||||
if (!var)
|
||||
return 0;
|
||||
return atof (var->string);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Cvar_VariableString
|
||||
*/
|
||||
char *
|
||||
Cvar_VariableString (char *var_name)
|
||||
{
|
||||
cvar_t *var;
|
||||
|
||||
var = Cvar_FindVar (var_name);
|
||||
if (!var)
|
||||
var = Cvar_FindAlias (var_name);
|
||||
if (!var)
|
||||
return cvar_null_string;
|
||||
return var->string;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Cvar_CompleteVariable
|
||||
*/
|
||||
char *
|
||||
Cvar_CompleteVariable (char *partial)
|
||||
{
|
||||
cvar_t *cvar;
|
||||
cvar_alias_t *alias;
|
||||
int len;
|
||||
|
||||
len = strlen (partial);
|
||||
|
||||
if (!len)
|
||||
return NULL;
|
||||
|
||||
// check exact match
|
||||
for (cvar = cvar_vars; cvar; cvar = cvar->next)
|
||||
if (!strcasecmp (partial, cvar->name))
|
||||
return cvar->name;
|
||||
|
||||
// check aliases too :)
|
||||
for (alias = calias_vars; alias; alias = alias->next)
|
||||
if (!strcasecmp (partial, alias->name))
|
||||
return alias->name;
|
||||
|
||||
// check partial match
|
||||
for (cvar = cvar_vars; cvar; cvar = cvar->next)
|
||||
if (!strncasecmp (partial, cvar->name, len))
|
||||
return cvar->name;
|
||||
|
||||
// check aliases too :)
|
||||
for (alias = calias_vars; alias; alias = alias->next)
|
||||
if (!strncasecmp (partial, alias->name, len))
|
||||
return alias->name;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void Cvar_Info (cvar_t *var);
|
||||
|
||||
/*
|
||||
Cvar_Set
|
||||
*/
|
||||
void
|
||||
Cvar_Set (cvar_t *var, char *value)
|
||||
{
|
||||
if (!var)
|
||||
return;
|
||||
|
||||
if (var->flags & CVAR_ROM) {
|
||||
Con_DPrintf ("Cvar \"%s\" is read-only, cannot modify\n", var->name);
|
||||
return;
|
||||
}
|
||||
|
||||
free (var->string); // free the old value string
|
||||
|
||||
var->string = strdup (value);
|
||||
var->value = atof (var->string);
|
||||
var->int_val = atoi (var->string);
|
||||
sscanf (var->string, "%f %f %f", &var->vec[0], &var->vec[1], &var->vec[2]);
|
||||
|
||||
Cvar_Info (var);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Cvar_SetROM
|
||||
|
||||
doesn't check for CVAR_ROM flag
|
||||
*/
|
||||
void
|
||||
Cvar_SetROM (cvar_t *var, char *value)
|
||||
{
|
||||
if (!var)
|
||||
return;
|
||||
|
||||
free (var->string); // free the old value string
|
||||
|
||||
var->string = strdup (value);
|
||||
var->value = atof (var->string);
|
||||
var->int_val = atoi (var->string);
|
||||
sscanf (var->string, "%f %f %f", &var->vec[0], &var->vec[1], &var->vec[2]);
|
||||
|
||||
Cvar_Info (var);
|
||||
}
|
||||
|
||||
/*
|
||||
Cvar_SetValue
|
||||
*/
|
||||
// 1999-09-07 weird cvar zeros fix by Maddes
|
||||
void
|
||||
Cvar_SetValue (cvar_t *var, float value)
|
||||
{
|
||||
char val[32];
|
||||
int i;
|
||||
|
||||
snprintf (val, sizeof (val), "%f", value);
|
||||
for (i = strlen (val) - 1; i > 0 && val[i] == '0' && val[i - 1] != '.'; i--) {
|
||||
val[i] = 0;
|
||||
}
|
||||
Cvar_Set (var, val);
|
||||
}
|
||||
|
||||
/*
|
||||
Cvar_Command
|
||||
|
||||
Handles variable inspection and changing from the console
|
||||
*/
|
||||
qboolean
|
||||
Cvar_Command (void)
|
||||
{
|
||||
cvar_t *v;
|
||||
|
||||
// check variables
|
||||
v = Cvar_FindVar (Cmd_Argv (0));
|
||||
if (!v)
|
||||
v = Cvar_FindAlias (Cmd_Argv (0));
|
||||
if (!v)
|
||||
return false;
|
||||
|
||||
// perform a variable print or set
|
||||
if (Cmd_Argc () == 1) {
|
||||
Con_Printf ("\"%s\" is \"%s\"\n", v->name, v->string);
|
||||
return true;
|
||||
}
|
||||
|
||||
Cvar_Set (v, Cmd_Argv (1));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Cvar_WriteVariables
|
||||
|
||||
Writes lines containing "set variable value" for all variables
|
||||
with the archive flag set to true.
|
||||
*/
|
||||
void
|
||||
Cvar_WriteVariables (QFile *f)
|
||||
{
|
||||
cvar_t *var;
|
||||
|
||||
for (var = cvar_vars; var; var = var->next)
|
||||
if (var->flags & CVAR_ARCHIVE)
|
||||
Qprintf (f, "%s \"%s\"\n", var->name, var->string);
|
||||
}
|
||||
|
||||
void
|
||||
Cvar_Set_f (void)
|
||||
{
|
||||
cvar_t *var;
|
||||
char *value;
|
||||
char *var_name;
|
||||
|
||||
if (Cmd_Argc () != 3) {
|
||||
Con_Printf ("usage: set <cvar> <value>\n");
|
||||
return;
|
||||
}
|
||||
var_name = Cmd_Argv (1);
|
||||
value = Cmd_Argv (2);
|
||||
var = Cvar_FindVar (var_name);
|
||||
|
||||
if (!var)
|
||||
var = Cvar_FindAlias (var_name);
|
||||
|
||||
if (var) {
|
||||
if (var->flags & CVAR_ROM) {
|
||||
Con_DPrintf ("Cvar \"%s\" is read-only, cannot modify\n", var_name);
|
||||
} else {
|
||||
Cvar_Set (var, value);
|
||||
}
|
||||
} else {
|
||||
var = Cvar_Get (var_name, value, CVAR_USER_CREATED,
|
||||
"User-created cvar");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Cvar_Setrom_f (void)
|
||||
{
|
||||
cvar_t *var;
|
||||
char *value;
|
||||
char *var_name;
|
||||
|
||||
if (Cmd_Argc () != 3) {
|
||||
Con_Printf ("usage: setrom <cvar> <value>\n");
|
||||
return;
|
||||
}
|
||||
var_name = Cmd_Argv (1);
|
||||
value = Cmd_Argv (2);
|
||||
var = Cvar_FindVar (var_name);
|
||||
|
||||
if (!var)
|
||||
var = Cvar_FindAlias (var_name);
|
||||
|
||||
if (var) {
|
||||
if (var->flags & CVAR_ROM) {
|
||||
Con_DPrintf ("Cvar \"%s\" is read-only, cannot modify\n", var_name);
|
||||
} else {
|
||||
Cvar_Set (var, value);
|
||||
Cvar_SetFlags (var, var->flags | CVAR_ROM);
|
||||
}
|
||||
} else {
|
||||
var = Cvar_Get (var_name, value, CVAR_USER_CREATED | CVAR_ROM,
|
||||
"User-created READ-ONLY Cvar");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Cvar_Toggle_f (void)
|
||||
{
|
||||
cvar_t *var;
|
||||
|
||||
if (Cmd_Argc () != 2) {
|
||||
Con_Printf ("toggle <cvar> : toggle a cvar on/off\n");
|
||||
return;
|
||||
}
|
||||
|
||||
var = Cvar_FindVar (Cmd_Argv (1));
|
||||
if (!var)
|
||||
var = Cvar_FindAlias (Cmd_Argv (1));
|
||||
if (!var) {
|
||||
Con_Printf ("Unknown variable \"%s\"\n", Cmd_Argv (1));
|
||||
return;
|
||||
}
|
||||
|
||||
Cvar_Set (var, var->int_val ? "0" : "1");
|
||||
}
|
||||
|
||||
void
|
||||
Cvar_Help_f (void)
|
||||
{
|
||||
char *var_name;
|
||||
cvar_t *var;
|
||||
|
||||
if (Cmd_Argc () != 2) {
|
||||
Con_Printf ("usage: help <cvar>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
var_name = Cmd_Argv (1);
|
||||
var = Cvar_FindVar (var_name);
|
||||
if (!var)
|
||||
var = Cvar_FindAlias (var_name);
|
||||
if (var) {
|
||||
Con_Printf ("%s\n", var->description);
|
||||
return;
|
||||
}
|
||||
Con_Printf ("variable not found\n");
|
||||
}
|
||||
|
||||
void
|
||||
Cvar_CvarList_f (void)
|
||||
{
|
||||
cvar_t *var;
|
||||
int i;
|
||||
int showhelp = 0;
|
||||
|
||||
if (Cmd_Argc () > 1)
|
||||
showhelp = 1;
|
||||
for (var = cvar_vars, i = 0; var; var = var->next, i++) {
|
||||
Con_Printf ("%c%c%c%c ",
|
||||
var->flags & CVAR_ROM ? 'r' : ' ',
|
||||
var->flags & CVAR_ARCHIVE ? '*' : ' ',
|
||||
var->flags & CVAR_USERINFO ? 'u' : ' ',
|
||||
var->flags & CVAR_SERVERINFO ? 's' : ' ');
|
||||
if (showhelp)
|
||||
Con_Printf ("%-20s : %s\n", var->name, var->description);
|
||||
else
|
||||
Con_Printf ("%s\n", var->name);
|
||||
}
|
||||
|
||||
Con_Printf ("------------\n%d variables\n", i);
|
||||
}
|
||||
|
||||
static void
|
||||
cvar_free (void *c)
|
||||
{
|
||||
cvar_t *cvar = (cvar_t*)c;
|
||||
free (cvar->name);
|
||||
free (cvar->string);
|
||||
free (cvar);
|
||||
}
|
||||
|
||||
static char *
|
||||
cvar_get_key (void *c)
|
||||
{
|
||||
cvar_t *cvar = (cvar_t*)c;
|
||||
return cvar->name;
|
||||
}
|
||||
|
||||
static void
|
||||
calias_free (void *c)
|
||||
{
|
||||
cvar_alias_t *calias = (cvar_alias_t*)c;
|
||||
free (calias->name);
|
||||
free (calias);
|
||||
}
|
||||
|
||||
static char *
|
||||
calias_get_key (void *c)
|
||||
{
|
||||
cvar_alias_t *calias = (cvar_alias_t*)c;
|
||||
return calias->name;
|
||||
}
|
||||
|
||||
void
|
||||
Cvar_Init_Hash (void)
|
||||
{
|
||||
cvar_hash = Hash_NewTable (1021, cvar_get_key, cvar_free);
|
||||
calias_hash = Hash_NewTable (1021, calias_get_key, calias_free);
|
||||
}
|
||||
|
||||
void
|
||||
Cvar_Init (void)
|
||||
{
|
||||
developer = Cvar_Get ("developer", "0", 0, "set to enable extra debugging information");
|
||||
|
||||
Cmd_AddCommand ("set", Cvar_Set_f, "Set the selected variable, useful on the command line (+set variablename setting)");
|
||||
Cmd_AddCommand ("setrom", Cvar_Setrom_f, "Set the selected variable and make it read only, useful on the command line.\n"
|
||||
"(+setrom variablename setting)");
|
||||
Cmd_AddCommand ("toggle", Cvar_Toggle_f, "Toggle a cvar on or off");
|
||||
Cmd_AddCommand ("help", Cvar_Help_f, "Display quake help");
|
||||
Cmd_AddCommand ("cvarlist", Cvar_CvarList_f, "List all cvars");
|
||||
}
|
||||
|
||||
void
|
||||
Cvar_Shutdown (void)
|
||||
{
|
||||
cvar_t *var, *next;
|
||||
cvar_alias_t *alias, *nextalias;
|
||||
|
||||
// Free cvars
|
||||
var = cvar_vars;
|
||||
while (var) {
|
||||
next = var->next;
|
||||
free (var->string);
|
||||
free (var->name);
|
||||
free (var);
|
||||
var = next;
|
||||
}
|
||||
// Free aliases
|
||||
alias = calias_vars;
|
||||
while (alias) {
|
||||
nextalias = alias->next;
|
||||
free (alias->name);
|
||||
free (alias);
|
||||
alias = nextalias;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cvar_t *
|
||||
Cvar_Get (char *name, char *string, int cvarflags, char *description)
|
||||
{
|
||||
|
||||
cvar_t *var;
|
||||
|
||||
if (Cmd_Exists (name)) {
|
||||
Con_Printf ("Cvar_Get: %s is a command\n", name);
|
||||
return NULL;
|
||||
}
|
||||
var = Cvar_FindVar (name);
|
||||
if (!var) {
|
||||
cvar_t **v;
|
||||
var = (cvar_t *) calloc (1, sizeof (cvar_t));
|
||||
|
||||
// Cvar doesn't exist, so we create it
|
||||
var->name = strdup (name);
|
||||
var->string = strdup (string);
|
||||
var->flags = cvarflags;
|
||||
var->description = description;
|
||||
var->value = atof (var->string);
|
||||
var->int_val = atoi (var->string);
|
||||
sscanf (var->string, "%f %f %f",
|
||||
&var->vec[0], &var->vec[1], &var->vec[2]);
|
||||
Hash_Add (cvar_hash, var);
|
||||
|
||||
for (v = &cvar_vars; *v; v = &(*v)->next)
|
||||
if (strcmp ((*v)->name, var->name) >= 0)
|
||||
break;
|
||||
var->next = *v;
|
||||
*v = var;
|
||||
} else {
|
||||
// Cvar does exist, so we update the flags and return.
|
||||
var->flags &= ~CVAR_USER_CREATED;
|
||||
var->flags |= cvarflags;
|
||||
var->description = description;
|
||||
}
|
||||
Cvar_Info (var);
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
/*
|
||||
Cvar_SetFlags
|
||||
|
||||
sets a Cvar's flags simply and easily
|
||||
*/
|
||||
void
|
||||
Cvar_SetFlags (cvar_t *var, int cvarflags)
|
||||
{
|
||||
if (var == NULL)
|
||||
return;
|
||||
|
||||
var->flags = cvarflags;
|
||||
}
|
135
qw/source/hash.c
135
qw/source/hash.c
|
@ -1,135 +0,0 @@
|
|||
/*
|
||||
hash.h
|
||||
|
||||
hash tables
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
Copyright (C) 2000 Marcus Sundberg <mackan@stacken.kth.se>
|
||||
|
||||
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
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "compat.h"
|
||||
#include "hash.h"
|
||||
|
||||
static unsigned long
|
||||
hash (const char *str)
|
||||
{
|
||||
unsigned long h = 0;
|
||||
while (*str) {
|
||||
h = (h << 4) + (unsigned char)*str++;
|
||||
if (h&0xf0000000)
|
||||
h = (h ^ (h >> 24)) & 0xfffffff;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
hashtab_t *
|
||||
Hash_NewTable (int tsize, char *(*gk)(void*), void (*f)(void*))
|
||||
{
|
||||
hashtab_t *tab = calloc (1, (size_t)&((hashtab_t*)0)->tab[tsize]);
|
||||
if (!tab)
|
||||
return 0;
|
||||
tab->tab_size = tsize;
|
||||
tab->get_key = gk;
|
||||
tab->free_ele = f;
|
||||
return tab;
|
||||
}
|
||||
|
||||
void
|
||||
Hash_DelTable (hashtab_t *tab)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < tab->tab_size; i++) {
|
||||
while (tab->tab[i]) {
|
||||
hashlink_t *t = tab->tab[i]->next;
|
||||
if (tab->free_ele)
|
||||
tab->free_ele (&tab->tab[i]->data);
|
||||
free (tab->tab[i]);
|
||||
tab->tab[i] = t;
|
||||
}
|
||||
}
|
||||
free (tab);
|
||||
}
|
||||
|
||||
int
|
||||
Hash_Add (hashtab_t *tab, void *ele)
|
||||
{
|
||||
unsigned long h = hash (tab->get_key(ele));
|
||||
size_t ind = h % tab->tab_size;
|
||||
hashlink_t *lnk = malloc (sizeof (hashlink_t));
|
||||
|
||||
if (!lnk)
|
||||
return -1;
|
||||
if (tab->tab[ind])
|
||||
tab->tab[ind]->prev = &lnk->next;
|
||||
lnk->next = tab->tab[ind];
|
||||
lnk->prev = &tab->tab[ind];
|
||||
lnk->data = ele;
|
||||
tab->tab[ind] = lnk;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *
|
||||
Hash_Find (hashtab_t *tab, const char *key)
|
||||
{
|
||||
unsigned long h = hash (key);
|
||||
size_t ind = h % tab->tab_size;
|
||||
hashlink_t *lnk = tab->tab[ind];
|
||||
|
||||
while (lnk) {
|
||||
if (strequal (key, tab->get_key (lnk->data)))
|
||||
return lnk->data;
|
||||
lnk = lnk->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Hash_Del (hashtab_t *tab, const char *key)
|
||||
{
|
||||
unsigned long h = hash (key);
|
||||
size_t ind = h % tab->tab_size;
|
||||
hashlink_t *lnk = tab->tab[ind];
|
||||
|
||||
while (lnk) {
|
||||
if (strequal (key, tab->get_key (lnk->data))) {
|
||||
if (lnk->next)
|
||||
lnk->next->prev = lnk->prev;
|
||||
*lnk->prev = lnk->next;
|
||||
free (lnk);
|
||||
return 0;
|
||||
}
|
||||
lnk = lnk->next;
|
||||
}
|
||||
return -1;
|
||||
}
|
|
@ -1,258 +0,0 @@
|
|||
/*
|
||||
mdfour.c
|
||||
|
||||
An implementation of MD4 designed for use in the samba SMB
|
||||
authentication protocol
|
||||
|
||||
Copyright (C) 1997-1998 Andrew Tridgell
|
||||
|
||||
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
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "mdfour.h"
|
||||
#include "uint32.h"
|
||||
|
||||
/* NOTE: This code makes no attempt to be fast!
|
||||
|
||||
It assumes that a int is at least 32 bits long
|
||||
*/
|
||||
|
||||
static struct mdfour *m;
|
||||
|
||||
#define F(X,Y,Z) (((X)&(Y)) | ((~(X))&(Z)))
|
||||
#define G(X,Y,Z) (((X)&(Y)) | ((X)&(Z)) | ((Y)&(Z)))
|
||||
#define H(X,Y,Z) ((X)^(Y)^(Z))
|
||||
|
||||
#ifdef LARGE_INT32
|
||||
# define lshift(x,s) ((((x)<<(s))&0xFFFFFFFF) | (((x)>>(32-(s)))&0xFFFFFFFF))
|
||||
#else
|
||||
# define lshift(x,s) (((x)<<(s)) | ((x)>>(32-(s))))
|
||||
#endif
|
||||
|
||||
#define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s)
|
||||
#define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + 0x5A827999,s)
|
||||
#define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + 0x6ED9EBA1,s)
|
||||
|
||||
/* this applies md4 to 64 byte chunks */
|
||||
static void
|
||||
mdfour64 (uint32 * M)
|
||||
{
|
||||
int j;
|
||||
uint32 AA, BB, CC, DD;
|
||||
uint32 X[16];
|
||||
uint32 A, B, C, D;
|
||||
|
||||
for (j = 0; j < 16; j++)
|
||||
X[j] = M[j];
|
||||
|
||||
A = m->A;
|
||||
B = m->B;
|
||||
C = m->C;
|
||||
D = m->D;
|
||||
AA = A;
|
||||
BB = B;
|
||||
CC = C;
|
||||
DD = D;
|
||||
|
||||
ROUND1 (A, B, C, D, 0, 3);
|
||||
ROUND1 (D, A, B, C, 1, 7);
|
||||
ROUND1 (C, D, A, B, 2, 11);
|
||||
ROUND1 (B, C, D, A, 3, 19);
|
||||
ROUND1 (A, B, C, D, 4, 3);
|
||||
ROUND1 (D, A, B, C, 5, 7);
|
||||
ROUND1 (C, D, A, B, 6, 11);
|
||||
ROUND1 (B, C, D, A, 7, 19);
|
||||
ROUND1 (A, B, C, D, 8, 3);
|
||||
ROUND1 (D, A, B, C, 9, 7);
|
||||
ROUND1 (C, D, A, B, 10, 11);
|
||||
ROUND1 (B, C, D, A, 11, 19);
|
||||
ROUND1 (A, B, C, D, 12, 3);
|
||||
ROUND1 (D, A, B, C, 13, 7);
|
||||
ROUND1 (C, D, A, B, 14, 11);
|
||||
ROUND1 (B, C, D, A, 15, 19);
|
||||
|
||||
ROUND2 (A, B, C, D, 0, 3);
|
||||
ROUND2 (D, A, B, C, 4, 5);
|
||||
ROUND2 (C, D, A, B, 8, 9);
|
||||
ROUND2 (B, C, D, A, 12, 13);
|
||||
ROUND2 (A, B, C, D, 1, 3);
|
||||
ROUND2 (D, A, B, C, 5, 5);
|
||||
ROUND2 (C, D, A, B, 9, 9);
|
||||
ROUND2 (B, C, D, A, 13, 13);
|
||||
ROUND2 (A, B, C, D, 2, 3);
|
||||
ROUND2 (D, A, B, C, 6, 5);
|
||||
ROUND2 (C, D, A, B, 10, 9);
|
||||
ROUND2 (B, C, D, A, 14, 13);
|
||||
ROUND2 (A, B, C, D, 3, 3);
|
||||
ROUND2 (D, A, B, C, 7, 5);
|
||||
ROUND2 (C, D, A, B, 11, 9);
|
||||
ROUND2 (B, C, D, A, 15, 13);
|
||||
|
||||
ROUND3 (A, B, C, D, 0, 3);
|
||||
ROUND3 (D, A, B, C, 8, 9);
|
||||
ROUND3 (C, D, A, B, 4, 11);
|
||||
ROUND3 (B, C, D, A, 12, 15);
|
||||
ROUND3 (A, B, C, D, 2, 3);
|
||||
ROUND3 (D, A, B, C, 10, 9);
|
||||
ROUND3 (C, D, A, B, 6, 11);
|
||||
ROUND3 (B, C, D, A, 14, 15);
|
||||
ROUND3 (A, B, C, D, 1, 3);
|
||||
ROUND3 (D, A, B, C, 9, 9);
|
||||
ROUND3 (C, D, A, B, 5, 11);
|
||||
ROUND3 (B, C, D, A, 13, 15);
|
||||
ROUND3 (A, B, C, D, 3, 3);
|
||||
ROUND3 (D, A, B, C, 11, 9);
|
||||
ROUND3 (C, D, A, B, 7, 11);
|
||||
ROUND3 (B, C, D, A, 15, 15);
|
||||
|
||||
A += AA;
|
||||
B += BB;
|
||||
C += CC;
|
||||
D += DD;
|
||||
|
||||
#ifdef LARGE_INT32
|
||||
A &= 0xFFFFFFFF;
|
||||
B &= 0xFFFFFFFF;
|
||||
C &= 0xFFFFFFFF;
|
||||
D &= 0xFFFFFFFF;
|
||||
#endif
|
||||
|
||||
for (j = 0; j < 16; j++)
|
||||
X[j] = 0;
|
||||
|
||||
m->A = A;
|
||||
m->B = B;
|
||||
m->C = C;
|
||||
m->D = D;
|
||||
}
|
||||
|
||||
static void
|
||||
copy64 (uint32 * M, unsigned char *in)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
M[i] = (in[i * 4 + 3] << 24) | (in[i * 4 + 2] << 16) |
|
||||
(in[i * 4 + 1] << 8) | (in[i * 4 + 0] << 0);
|
||||
}
|
||||
|
||||
static void
|
||||
copy4 (unsigned char *out, uint32 x)
|
||||
{
|
||||
out[0] = x & 0xFF;
|
||||
out[1] = (x >> 8) & 0xFF;
|
||||
out[2] = (x >> 16) & 0xFF;
|
||||
out[3] = (x >> 24) & 0xFF;
|
||||
}
|
||||
|
||||
void
|
||||
mdfour_begin (struct mdfour *md)
|
||||
{
|
||||
md->A = 0x67452301;
|
||||
md->B = 0xefcdab89;
|
||||
md->C = 0x98badcfe;
|
||||
md->D = 0x10325476;
|
||||
md->totalN = 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mdfour_tail (unsigned char *in, int n)
|
||||
{
|
||||
unsigned char buf[128];
|
||||
uint32 M[16];
|
||||
uint32 b;
|
||||
|
||||
m->totalN += n;
|
||||
|
||||
b = m->totalN * 8;
|
||||
|
||||
memset (buf, 0, 128);
|
||||
if (n)
|
||||
memcpy (buf, in, n);
|
||||
buf[n] = 0x80;
|
||||
|
||||
if (n <= 55) {
|
||||
copy4 (buf + 56, b);
|
||||
copy64 (M, buf);
|
||||
mdfour64 (M);
|
||||
} else {
|
||||
copy4 (buf + 120, b);
|
||||
copy64 (M, buf);
|
||||
mdfour64 (M);
|
||||
copy64 (M, buf + 64);
|
||||
mdfour64 (M);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mdfour_update (struct mdfour *md, unsigned char *in, int n)
|
||||
{
|
||||
uint32 M[16];
|
||||
|
||||
if (n == 0)
|
||||
mdfour_tail (in, n);
|
||||
|
||||
m = md;
|
||||
|
||||
while (n >= 64) {
|
||||
copy64 (M, in);
|
||||
mdfour64 (M);
|
||||
in += 64;
|
||||
n -= 64;
|
||||
m->totalN += 64;
|
||||
}
|
||||
|
||||
mdfour_tail (in, n);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mdfour_result (struct mdfour *md, unsigned char *out)
|
||||
{
|
||||
m = md;
|
||||
|
||||
copy4 (out, m->A);
|
||||
copy4 (out + 4, m->B);
|
||||
copy4 (out + 8, m->C);
|
||||
copy4 (out + 12, m->D);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mdfour (unsigned char *out, unsigned char *in, int n)
|
||||
{
|
||||
struct mdfour md;
|
||||
|
||||
mdfour_begin (&md);
|
||||
mdfour_update (&md, in, n);
|
||||
mdfour_result (&md, out);
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
/*
|
||||
sizebuf.c
|
||||
|
||||
(description)
|
||||
|
||||
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
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "console.h"
|
||||
#include "sizebuf.h"
|
||||
#include "sys.h"
|
||||
|
||||
void
|
||||
SZ_Clear (sizebuf_t *buf)
|
||||
{
|
||||
buf->cursize = 0;
|
||||
buf->overflowed = false;
|
||||
}
|
||||
|
||||
void *
|
||||
SZ_GetSpace (sizebuf_t *buf, int length)
|
||||
{
|
||||
void *data;
|
||||
|
||||
if (buf->cursize + length > buf->maxsize) {
|
||||
if (!buf->allowoverflow)
|
||||
Sys_Error ("SZ_GetSpace: overflow without allowoverflow set (%d)",
|
||||
buf->maxsize);
|
||||
|
||||
if (length > buf->maxsize)
|
||||
Sys_Error ("SZ_GetSpace: %i is > full buffer size", length);
|
||||
|
||||
Con_Printf ("SZ_GetSpace: overflow\n");
|
||||
SZ_Clear (buf);
|
||||
buf->overflowed = true;
|
||||
}
|
||||
|
||||
data = buf->data + buf->cursize;
|
||||
buf->cursize += length;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void
|
||||
SZ_Write (sizebuf_t *buf, void *data, int length)
|
||||
{
|
||||
memcpy (SZ_GetSpace (buf, length), data, length);
|
||||
}
|
||||
|
||||
void
|
||||
SZ_Print (sizebuf_t *buf, char *data)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = strlen (data) + 1;
|
||||
|
||||
if (!buf->cursize || buf->data[buf->cursize - 1])
|
||||
memcpy ((byte *) SZ_GetSpace (buf, len), data, len); // no
|
||||
// trailing 0
|
||||
else
|
||||
memcpy ((byte *) SZ_GetSpace (buf, len - 1) - 1, data, len); // write
|
||||
// over
|
||||
// trailing
|
||||
// 0
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
/*
|
||||
va.c
|
||||
|
||||
varargs printf function
|
||||
|
||||
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
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "qtypes.h"
|
||||
|
||||
/*
|
||||
va
|
||||
|
||||
does a varargs printf into a temp buffer, so I don't need to have
|
||||
varargs versions of all text functions.
|
||||
FIXME: make this buffer size safe someday
|
||||
*/
|
||||
char *
|
||||
va (char *format, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
static char string[1024];
|
||||
|
||||
va_start (argptr, format);
|
||||
vsnprintf (string, sizeof (string), format, argptr);
|
||||
va_end (argptr);
|
||||
|
||||
return string;
|
||||
}
|
680
qw/source/zone.c
680
qw/source/zone.c
|
@ -1,680 +0,0 @@
|
|||
/*
|
||||
zone.c
|
||||
|
||||
(description)
|
||||
|
||||
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
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "cmd.h"
|
||||
#include "console.h"
|
||||
#include "qargs.h"
|
||||
#include "sys.h"
|
||||
#include "zone.h"
|
||||
|
||||
#define DYNAMIC_SIZE 0x20000
|
||||
#define ZONEID 0x1d4a11
|
||||
#define HUNK_SENTINAL 0x1df001ed
|
||||
|
||||
#define MINFRAGMENT 64
|
||||
|
||||
void Cache_FreeLow (int new_low_hunk);
|
||||
void Cache_FreeHigh (int new_high_hunk);
|
||||
|
||||
|
||||
/*
|
||||
The zone calls are pretty much only used for small strings and structures,
|
||||
all big things are allocated on the hunk.
|
||||
*/
|
||||
|
||||
//============================================================================
|
||||
|
||||
typedef struct {
|
||||
int sentinal;
|
||||
int size; // including sizeof(hunk_t), -1 = not
|
||||
// allocated
|
||||
char name[8];
|
||||
} hunk_t;
|
||||
|
||||
byte *hunk_base;
|
||||
int hunk_size;
|
||||
|
||||
int hunk_low_used;
|
||||
int hunk_high_used;
|
||||
|
||||
qboolean hunk_tempactive;
|
||||
int hunk_tempmark;
|
||||
|
||||
void R_FreeTextures (void);
|
||||
|
||||
/*
|
||||
Hunk_Check
|
||||
|
||||
Run consistancy and sentinal trahing checks
|
||||
*/
|
||||
void
|
||||
Hunk_Check (void)
|
||||
{
|
||||
hunk_t *h;
|
||||
|
||||
for (h = (hunk_t *) hunk_base; (byte *) h != hunk_base + hunk_low_used;) {
|
||||
if (h->sentinal != HUNK_SENTINAL)
|
||||
Sys_Error ("Hunk_Check: trashed sentinal");
|
||||
if (h->size < 16 || h->size + (byte *) h - hunk_base > hunk_size)
|
||||
Sys_Error ("Hunk_Check: bad size");
|
||||
h = (hunk_t *) ((byte *) h + h->size);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Hunk_Print
|
||||
|
||||
If "all" is specified, every single allocation is printed.
|
||||
Otherwise, allocations with the same name will be totaled up before
|
||||
printing.
|
||||
*/
|
||||
void
|
||||
Hunk_Print (qboolean all)
|
||||
{
|
||||
hunk_t *h, *next, *endlow, *starthigh, *endhigh;
|
||||
int count, sum;
|
||||
int totalblocks;
|
||||
char name[9];
|
||||
|
||||
name[8] = 0;
|
||||
count = 0;
|
||||
sum = 0;
|
||||
totalblocks = 0;
|
||||
|
||||
h = (hunk_t *) hunk_base;
|
||||
endlow = (hunk_t *) (hunk_base + hunk_low_used);
|
||||
starthigh = (hunk_t *) (hunk_base + hunk_size - hunk_high_used);
|
||||
endhigh = (hunk_t *) (hunk_base + hunk_size);
|
||||
|
||||
Con_Printf (" :%8i total hunk size\n", hunk_size);
|
||||
Con_Printf ("-------------------------\n");
|
||||
|
||||
while (1) {
|
||||
//
|
||||
// skip to the high hunk if done with low hunk
|
||||
//
|
||||
if (h == endlow) {
|
||||
Con_Printf ("-------------------------\n");
|
||||
Con_Printf (" :%8i REMAINING\n",
|
||||
hunk_size - hunk_low_used - hunk_high_used);
|
||||
Con_Printf ("-------------------------\n");
|
||||
h = starthigh;
|
||||
}
|
||||
//
|
||||
// if totally done, break
|
||||
//
|
||||
if (h == endhigh)
|
||||
break;
|
||||
|
||||
//
|
||||
// run consistancy checks
|
||||
//
|
||||
if (h->sentinal != HUNK_SENTINAL)
|
||||
Sys_Error ("Hunk_Check: trahsed sentinal");
|
||||
if (h->size < 16 || h->size + (byte *) h - hunk_base > hunk_size)
|
||||
Sys_Error ("Hunk_Check: bad size");
|
||||
|
||||
next = (hunk_t *) ((byte *) h + h->size);
|
||||
count++;
|
||||
totalblocks++;
|
||||
sum += h->size;
|
||||
|
||||
//
|
||||
// print the single block
|
||||
//
|
||||
memcpy (name, h->name, 8);
|
||||
if (all)
|
||||
Con_Printf ("%8p :%8i %8s\n", h, h->size, name);
|
||||
|
||||
//
|
||||
// print the total
|
||||
//
|
||||
if (next == endlow || next == endhigh ||
|
||||
strncmp (h->name, next->name, 8)) {
|
||||
if (!all)
|
||||
Con_Printf (" :%8i %8s (TOTAL)\n", sum, name);
|
||||
count = 0;
|
||||
sum = 0;
|
||||
}
|
||||
|
||||
h = next;
|
||||
}
|
||||
|
||||
Con_Printf ("-------------------------\n");
|
||||
Con_Printf ("%8i total blocks\n", totalblocks);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Hunk_AllocName
|
||||
*/
|
||||
void *
|
||||
Hunk_AllocName (int size, char *name)
|
||||
{
|
||||
hunk_t *h;
|
||||
|
||||
#ifdef PARANOID
|
||||
Hunk_Check ();
|
||||
#endif
|
||||
|
||||
if (size < 0)
|
||||
Sys_Error ("Hunk_Alloc: bad size: %i", size);
|
||||
|
||||
size = sizeof (hunk_t) + ((size + 15) & ~15);
|
||||
|
||||
if (hunk_size - hunk_low_used - hunk_high_used < size)
|
||||
// Sys_Error ("Hunk_Alloc: failed on %i bytes",size);
|
||||
#ifdef _WIN32
|
||||
Sys_Error
|
||||
("Not enough RAM allocated. Try starting using \"-heapsize 16000\" on the %s command line.",
|
||||
PROGRAM);
|
||||
#else
|
||||
Sys_Error
|
||||
("Not enough RAM allocated. Try starting using \"-mem 16\" on the %s command line.",
|
||||
PROGRAM);
|
||||
#endif
|
||||
|
||||
h = (hunk_t *) (hunk_base + hunk_low_used);
|
||||
hunk_low_used += size;
|
||||
|
||||
Cache_FreeLow (hunk_low_used);
|
||||
|
||||
memset (h, 0, size);
|
||||
|
||||
h->size = size;
|
||||
h->sentinal = HUNK_SENTINAL;
|
||||
strncpy (h->name, name, 8);
|
||||
|
||||
return (void *) (h + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
Hunk_Alloc
|
||||
*/
|
||||
void *
|
||||
Hunk_Alloc (int size)
|
||||
{
|
||||
return Hunk_AllocName (size, "unknown");
|
||||
}
|
||||
|
||||
int
|
||||
Hunk_LowMark (void)
|
||||
{
|
||||
return hunk_low_used;
|
||||
}
|
||||
|
||||
void
|
||||
Hunk_FreeToLowMark (int mark)
|
||||
{
|
||||
if (mark < 0 || mark > hunk_low_used)
|
||||
Sys_Error ("Hunk_FreeToLowMark: bad mark %i", mark);
|
||||
memset (hunk_base + mark, 0, hunk_low_used - mark);
|
||||
hunk_low_used = mark;
|
||||
}
|
||||
|
||||
int
|
||||
Hunk_HighMark (void)
|
||||
{
|
||||
if (hunk_tempactive) {
|
||||
hunk_tempactive = false;
|
||||
Hunk_FreeToHighMark (hunk_tempmark);
|
||||
}
|
||||
|
||||
return hunk_high_used;
|
||||
}
|
||||
|
||||
void
|
||||
Hunk_FreeToHighMark (int mark)
|
||||
{
|
||||
if (hunk_tempactive) {
|
||||
hunk_tempactive = false;
|
||||
Hunk_FreeToHighMark (hunk_tempmark);
|
||||
}
|
||||
if (mark < 0 || mark > hunk_high_used)
|
||||
Sys_Error ("Hunk_FreeToHighMark: bad mark %i", mark);
|
||||
memset (hunk_base + hunk_size - hunk_high_used, 0, hunk_high_used - mark);
|
||||
hunk_high_used = mark;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Hunk_HighAllocName
|
||||
*/
|
||||
void *
|
||||
Hunk_HighAllocName (int size, char *name)
|
||||
{
|
||||
hunk_t *h;
|
||||
|
||||
if (size < 0)
|
||||
Sys_Error ("Hunk_HighAllocName: bad size: %i", size);
|
||||
|
||||
if (hunk_tempactive) {
|
||||
Hunk_FreeToHighMark (hunk_tempmark);
|
||||
hunk_tempactive = false;
|
||||
}
|
||||
#ifdef PARANOID
|
||||
Hunk_Check ();
|
||||
#endif
|
||||
|
||||
size = sizeof (hunk_t) + ((size + 15) & ~15);
|
||||
|
||||
if (hunk_size - hunk_low_used - hunk_high_used < size) {
|
||||
Con_Printf ("Hunk_HighAlloc: failed on %i bytes\n", size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hunk_high_used += size;
|
||||
Cache_FreeHigh (hunk_high_used);
|
||||
|
||||
h = (hunk_t *) (hunk_base + hunk_size - hunk_high_used);
|
||||
|
||||
memset (h, 0, size);
|
||||
h->size = size;
|
||||
h->sentinal = HUNK_SENTINAL;
|
||||
strncpy (h->name, name, 8);
|
||||
|
||||
return (void *) (h + 1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Hunk_TempAlloc
|
||||
|
||||
Return space from the top of the hunk
|
||||
*/
|
||||
void *
|
||||
Hunk_TempAlloc (int size)
|
||||
{
|
||||
void *buf;
|
||||
|
||||
size = (size + 15) & ~15;
|
||||
|
||||
if (hunk_tempactive) {
|
||||
Hunk_FreeToHighMark (hunk_tempmark);
|
||||
hunk_tempactive = false;
|
||||
}
|
||||
|
||||
hunk_tempmark = Hunk_HighMark ();
|
||||
|
||||
buf = Hunk_HighAllocName (size, "temp");
|
||||
|
||||
hunk_tempactive = true;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
CACHE MEMORY
|
||||
*/
|
||||
|
||||
typedef struct cache_system_s {
|
||||
int size; // including this header
|
||||
cache_user_t *user;
|
||||
char name[16];
|
||||
struct cache_system_s *prev, *next;
|
||||
struct cache_system_s *lru_prev, *lru_next; // for LRU flushing
|
||||
} cache_system_t;
|
||||
|
||||
cache_system_t *Cache_TryAlloc (int size, qboolean nobottom);
|
||||
|
||||
cache_system_t cache_head;
|
||||
|
||||
/*
|
||||
Cache_Move
|
||||
*/
|
||||
void
|
||||
Cache_Move (cache_system_t * c)
|
||||
{
|
||||
cache_system_t *new;
|
||||
|
||||
// we are clearing up space at the bottom, so only allocate it late
|
||||
new = Cache_TryAlloc (c->size, true);
|
||||
if (new) {
|
||||
// Con_Printf ("cache_move ok\n");
|
||||
|
||||
memcpy (new + 1, c + 1, c->size - sizeof (cache_system_t));
|
||||
new->user = c->user;
|
||||
memcpy (new->name, c->name, sizeof (new->name));
|
||||
Cache_Free (c->user);
|
||||
new->user->data = (void *) (new + 1);
|
||||
} else {
|
||||
// Con_Printf ("cache_move failed\n");
|
||||
|
||||
Cache_Free (c->user); // tough luck...
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Cache_FreeLow
|
||||
|
||||
Throw things out until the hunk can be expanded to the given point
|
||||
*/
|
||||
void
|
||||
Cache_FreeLow (int new_low_hunk)
|
||||
{
|
||||
cache_system_t *c;
|
||||
|
||||
while (1) {
|
||||
c = cache_head.next;
|
||||
if (c == &cache_head)
|
||||
return; // nothing in cache at all
|
||||
if ((byte *) c >= hunk_base + new_low_hunk)
|
||||
return; // there is space to grow the hunk
|
||||
Cache_Move (c); // reclaim the space
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Cache_FreeHigh
|
||||
|
||||
Throw things out until the hunk can be expanded to the given point
|
||||
*/
|
||||
void
|
||||
Cache_FreeHigh (int new_high_hunk)
|
||||
{
|
||||
cache_system_t *c, *prev;
|
||||
|
||||
prev = NULL;
|
||||
while (1) {
|
||||
c = cache_head.prev;
|
||||
if (c == &cache_head)
|
||||
return; // nothing in cache at all
|
||||
if ((byte *) c + c->size <= hunk_base + hunk_size - new_high_hunk)
|
||||
return; // there is space to grow the hunk
|
||||
if (c == prev)
|
||||
Cache_Free (c->user); // didn't move out of the way
|
||||
else {
|
||||
Cache_Move (c); // try to move it
|
||||
prev = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Cache_UnlinkLRU (cache_system_t * cs)
|
||||
{
|
||||
if (!cs->lru_next || !cs->lru_prev)
|
||||
Sys_Error ("Cache_UnlinkLRU: NULL link");
|
||||
|
||||
cs->lru_next->lru_prev = cs->lru_prev;
|
||||
cs->lru_prev->lru_next = cs->lru_next;
|
||||
|
||||
cs->lru_prev = cs->lru_next = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
Cache_MakeLRU (cache_system_t * cs)
|
||||
{
|
||||
if (cs->lru_next || cs->lru_prev)
|
||||
Sys_Error ("Cache_MakeLRU: active link");
|
||||
|
||||
cache_head.lru_next->lru_prev = cs;
|
||||
cs->lru_next = cache_head.lru_next;
|
||||
cs->lru_prev = &cache_head;
|
||||
cache_head.lru_next = cs;
|
||||
}
|
||||
|
||||
/*
|
||||
Cache_TryAlloc
|
||||
|
||||
Looks for a free block of memory between the high and low hunk marks
|
||||
Size should already include the header and padding
|
||||
*/
|
||||
cache_system_t *
|
||||
Cache_TryAlloc (int size, qboolean nobottom)
|
||||
{
|
||||
cache_system_t *cs, *new;
|
||||
|
||||
// is the cache completely empty?
|
||||
|
||||
if (!nobottom && cache_head.prev == &cache_head) {
|
||||
if (hunk_size - hunk_high_used - hunk_low_used < size)
|
||||
Sys_Error ("Cache_TryAlloc: %i is greater then free hunk", size);
|
||||
|
||||
new = (cache_system_t *) (hunk_base + hunk_low_used);
|
||||
memset (new, 0, sizeof (*new));
|
||||
new->size = size;
|
||||
|
||||
cache_head.prev = cache_head.next = new;
|
||||
new->prev = new->next = &cache_head;
|
||||
|
||||
Cache_MakeLRU (new);
|
||||
return new;
|
||||
}
|
||||
// search from the bottom up for space
|
||||
|
||||
new = (cache_system_t *) (hunk_base + hunk_low_used);
|
||||
cs = cache_head.next;
|
||||
|
||||
do {
|
||||
if (!nobottom || cs != cache_head.next) {
|
||||
if ((byte *) cs - (byte *) new >= size) { // found space
|
||||
memset (new, 0, sizeof (*new));
|
||||
new->size = size;
|
||||
|
||||
new->next = cs;
|
||||
new->prev = cs->prev;
|
||||
cs->prev->next = new;
|
||||
cs->prev = new;
|
||||
|
||||
Cache_MakeLRU (new);
|
||||
|
||||
return new;
|
||||
}
|
||||
}
|
||||
// continue looking
|
||||
new = (cache_system_t *) ((byte *) cs + cs->size);
|
||||
cs = cs->next;
|
||||
|
||||
} while (cs != &cache_head);
|
||||
|
||||
// try to allocate one at the very end
|
||||
if (hunk_base + hunk_size - hunk_high_used - (byte *) new >= size) {
|
||||
memset (new, 0, sizeof (*new));
|
||||
new->size = size;
|
||||
|
||||
new->next = &cache_head;
|
||||
new->prev = cache_head.prev;
|
||||
cache_head.prev->next = new;
|
||||
cache_head.prev = new;
|
||||
|
||||
Cache_MakeLRU (new);
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
return NULL; // couldn't allocate
|
||||
}
|
||||
|
||||
/*
|
||||
Cache_Flush
|
||||
|
||||
Throw everything out, so new data will be demand cached
|
||||
*/
|
||||
void
|
||||
Cache_Flush (void)
|
||||
{
|
||||
while (cache_head.next != &cache_head)
|
||||
Cache_Free (cache_head.next->user); // reclaim the space
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Cache_Print
|
||||
*/
|
||||
void
|
||||
Cache_Print (void)
|
||||
{
|
||||
cache_system_t *cd;
|
||||
|
||||
for (cd = cache_head.next; cd != &cache_head; cd = cd->next) {
|
||||
Con_Printf ("%8i : %s\n", cd->size, cd->name);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Cache_Report
|
||||
*/
|
||||
void
|
||||
Cache_Report (void)
|
||||
{
|
||||
Con_DPrintf ("%4.1f megabyte data cache\n",
|
||||
(hunk_size - hunk_high_used -
|
||||
hunk_low_used) / (float) (1024 * 1024));
|
||||
}
|
||||
|
||||
/*
|
||||
Cache_Compact
|
||||
*/
|
||||
void
|
||||
Cache_Compact (void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
Cache_Init
|
||||
*/
|
||||
void
|
||||
Cache_Init (void)
|
||||
{
|
||||
cache_head.next = cache_head.prev = &cache_head;
|
||||
cache_head.lru_next = cache_head.lru_prev = &cache_head;
|
||||
|
||||
Cmd_AddCommand ("flush", Cache_Flush, "Clears the current game cache");
|
||||
}
|
||||
|
||||
/*
|
||||
Cache_Free
|
||||
|
||||
Frees the memory and removes it from the LRU list
|
||||
*/
|
||||
void
|
||||
Cache_Free (cache_user_t *c)
|
||||
{
|
||||
cache_system_t *cs;
|
||||
|
||||
if (!c->data)
|
||||
Sys_Error ("Cache_Free: not allocated");
|
||||
|
||||
cs = ((cache_system_t *) c->data) - 1;
|
||||
|
||||
cs->prev->next = cs->next;
|
||||
cs->next->prev = cs->prev;
|
||||
cs->next = cs->prev = NULL;
|
||||
|
||||
c->data = NULL;
|
||||
|
||||
Cache_UnlinkLRU (cs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Cache_Check
|
||||
*/
|
||||
void *
|
||||
Cache_Check (cache_user_t *c)
|
||||
{
|
||||
cache_system_t *cs;
|
||||
|
||||
if (!c->data)
|
||||
return NULL;
|
||||
|
||||
cs = ((cache_system_t *) c->data) - 1;
|
||||
|
||||
// move to head of LRU
|
||||
Cache_UnlinkLRU (cs);
|
||||
Cache_MakeLRU (cs);
|
||||
|
||||
return c->data;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Cache_Alloc
|
||||
*/
|
||||
void *
|
||||
Cache_Alloc (cache_user_t *c, int size, char *name)
|
||||
{
|
||||
cache_system_t *cs;
|
||||
|
||||
if (c->data)
|
||||
Sys_Error ("Cache_Alloc: already allocated");
|
||||
|
||||
if (size <= 0)
|
||||
Sys_Error ("Cache_Alloc: size %i", size);
|
||||
|
||||
size = (size + sizeof (cache_system_t) + 15) & ~15;
|
||||
|
||||
// find memory for it
|
||||
while (1) {
|
||||
cs = Cache_TryAlloc (size, false);
|
||||
if (cs) {
|
||||
strncpy (cs->name, name, sizeof (cs->name) - 1);
|
||||
c->data = (void *) (cs + 1);
|
||||
cs->user = c;
|
||||
break;
|
||||
}
|
||||
// free the least recently used cahedat
|
||||
if (cache_head.lru_prev == &cache_head)
|
||||
Sys_Error ("Cache_Alloc: out of memory");
|
||||
// not enough memory at all
|
||||
Cache_Free (cache_head.lru_prev->user);
|
||||
}
|
||||
|
||||
return Cache_Check (c);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
|
||||
/*
|
||||
Memory_Init
|
||||
*/
|
||||
void
|
||||
Memory_Init (void *buf, int size)
|
||||
{
|
||||
hunk_base = buf;
|
||||
hunk_size = size;
|
||||
hunk_low_used = 0;
|
||||
hunk_high_used = 0;
|
||||
|
||||
Cache_Init ();
|
||||
}
|
Loading…
Reference in a new issue