The joys of not having git.

This history of this branch is a close but not quite accurate representation 
of reality. Many commits were merged, and several scrambled, so tracking 
through it will often produce unusable code.

However, the end result of the branch is accurate.
This commit is contained in:
Bill Currie 2004-12-30 11:29:09 +00:00
commit 0029a26f40
187 changed files with 7128 additions and 4944 deletions

View file

@ -2,7 +2,7 @@ This is our new development tree (we're back to "quakeforge"), where we're again
While almost always in working order, it's under heavy development so be prepared to encounter some issues (Wear your hard hat!). Please check the docs.
UNIX users: because of the diversity of machines QuakeForge runs on, we do not provide UNIX binaries. You need to compile QuakeForge yourself however, QuakeForge is very easy to compile once you have the following packages installed:
UNIX users: because of the diversity of machines QuakeForge runs on, we do not provide UNIX binaries. You need to compile QuakeForge yourself, however QuakeForge is very easy to compile once you have the following packages installed:
* GNU autoconf 2.50 or later
* GNU automake 1.6 or later

View file

@ -1123,7 +1123,11 @@ dnl Checks for CD-ROM
dnl ==================================================================
CD_CFLAGS=""
CD_PLUGIN_TARGETS="cd_file.la"
if test "x$HAVE_VORBIS" = xyes; then
CD_PLUGIN_TARGETS="cd_file.la"
else
CD_PLUGIN_TARGETS=""
fi
unset CDTYPE
AC_MSG_CHECKING(for CD audio support)
@ -1998,7 +2002,10 @@ if test "x$static_plugins" = xyes; then
else
plugin_ldflags="$plugin_ldflags"' -version-info $(plugin_version) -rpath $(plugindir)'
fi
plugin_ldflags="$plugin_ldflags -module -avoid-version"
dnl Don't use -module here, it belongs in makefile.am due to automake
dnl needing it there to work correctly
plugin_ldflags="$plugin_ldflags -avoid-version"
SERVER_PLUGIN_STATIC_LIBS=""
CLIENT_PLUGIN_STATIC_LIBS=""
CD_PLUGIN_STATIC_LIBS=""

View file

@ -24,7 +24,20 @@ EXTRA_DIST= 3dfx.txt CodingStyle glqnotes.txt \
data/docs/install.quake data/docs/install.quake2 data/docs/readme \
data/docs/readme.glquake data/docs/readme.squake data/docs/readme.x11 \
\
ideas/quakedownload.txt ideas/rhamph.txt ideas/serverlist.txt
ideas/quakedownload.txt ideas/rhamph.txt ideas/serverlist.txt \
\
progs/vm-mem.fig
doc: quakeforge.dox
%.png: %.fig
@mkdir -p `dirname $@`
fig2dev -L png $< $@
%.eps: %.fig
@mkdir -p `dirname $@`
fig2dev -L ps $< $@
progs/vm-mem.png: progs/vm-mem.fig
progs/vm-mem.eps: progs/vm-mem.fig
doc: quakeforge.dox progs/vm-mem.png progs/vm-mem.eps
doxygen quakeforge.dox

29
doc/progs/vm-exec.c Normal file
View file

@ -0,0 +1,29 @@
#include "QF/progs.h"
int
call_progs_main (progs_t *pr, int argc, const char **argv)
{
int i;
dfunction_t *dfunc;
func_t progs_main = 0;
string_t *pr_argv;
if ((dfunc = PR_FindFunction (pr, "main"))) {
progs_main = dfunc - pr->pr_functions;
} else {
PR_Undefined (pr, "function", "main");
return -1;
}
PR_PushFrame (pr);
pr_argv = PR_Zone_Malloc (pr, (argc + 1) * 4);
for (i = 0; i < argc; i++)
pr_argv[i] = PR_SetTempString (pr, argv[1 + i]);
pr_argv[i] = 0;
P_INT (pr, 0) = argc;
P_POINTER (pr, 1) = PR_SetPointer (pr, pr_argv);
PR_ExecuteProgram (pr, progs_main);
PR_PopFrame (pr);
PR_Zone_Free (pr, pr_argv);
return R_INT (pr);
}

View file

@ -345,8 +345,12 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = @top_srcdir@/include @top_srcdir@/libs @top_srcdir@/nq
INPUT += @top_srcdir@/qw @top_srcdir@/tools
INPUT = @top_srcdir@/include
INPUT += @top_srcdir@/libs
INPUT += @top_srcdir@/nq
INPUT += @top_srcdir@/qtv
INPUT += @top_srcdir@/qw
INPUT += @top_srcdir@/tools
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
@ -367,9 +371,16 @@ RECURSIVE = YES
# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
EXCLUDE = qc-lex.c qc-parse.c qc-parse.h
EXCLUDE += fbset_modes_l.c fbset_modes_y.c fbset_modes_y.h
EXCLUDE = @top_srcdir@/tools/qfcc/source/qc-lex.c
EXCLUDE += @top_srcdir@/tools/qfcc/source/qc-parse.c
EXCLUDE += @top_srcdir@/tools/qfcc/source/qc-parse.h
EXCLUDE += @top_srcdir@/tools/qfcc/test
EXCLUDE += @top_srcdir@/tools/texpaint
EXCLUDE += @top_srcdir@/libs/video/targets/fbset_modes_l.c
EXCLUDE += @top_srcdir@/libs/video/targets/fbset_modes_y.c
EXCLUDE += @top_srcdir@/libs/video/targets/fbset_modes_y.h
EXCLUDE += @top_srcdir@/tools/Forge
EXCLUDE += @top_srcdir@/include/QF/GL
# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories
# that are symbolic links (a Unix filesystem feature) are excluded from the input.
@ -386,7 +397,8 @@ EXCLUDE_PATTERNS =
# directories that contain example code fragments that are included (see
# the \include command).
EXAMPLE_PATH =
EXAMPLE_PATH = @top_srcdir@/doc
EXAMPLE_PATH += @top_srcdir@/doc/progs
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
@ -406,7 +418,8 @@ EXAMPLE_RECURSIVE = NO
# directories that contain image that are included in the documentation (see
# the \image command).
IMAGE_PATH =
IMAGE_PATH = @top_builddir@/doc
IMAGE_PATH += @top_builddir@/doc/progs
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
@ -430,7 +443,7 @@ FILTER_SOURCE_FILES = NO
# If the SOURCE_BROWSER tag is set to YES then a list of source files will
# be generated. Documented entities will be cross-referenced with these sources.
SOURCE_BROWSER = YES
SOURCE_BROWSER = NO
# Setting the INLINE_SOURCES tag to YES will include the body
# of functions and classes directly in the documentation.

View file

@ -7,9 +7,9 @@ nobase_pkginclude_HEADERS = \
llist.h locs.h mathlib.h mdfour.h model.h modelgen.h msg.h object.h pak.h \
pakfile.h pcx.h png.h plugin.h pr_comp.h pr_debug.h pr_obj.h progs.h \
qargs.h qdefs.h qendian.h qfplist.h qtypes.h quakefs.h quakeio.h render.h \
riff.h ruamoko.h screen.h sizebuf.h skin.h sound.h spritegn.h sys.h \
teamplay.h tga.h uint32.h va.h ver_check.h vid.h view.h wad.h wadfile.h \
zone.h \
riff.h ruamoko.h screen.h script.h sizebuf.h skin.h sound.h spritegn.h \
sys.h teamplay.h tga.h uint32.h va.h ver_check.h vid.h view.h wad.h \
wadfile.h zone.h \
\
GL/ati.h GL/defines.h GL/extensions.h GL/funcs.h GL/qf_explosions.h \
GL/qf_funcs_list.h GL/qf_lightmap.h GL/qf_noisetextures.h \

View file

@ -32,6 +32,13 @@
#ifndef __QF_cbuf_h
#define __QF_cbuf_h
/** \addtogroup utils */
//@{
/** \defgroup cbuf Command buffer management.
*/
//@{
#include <stdarg.h>
#include "QF/qtypes.h"
@ -95,4 +102,7 @@ void Cbuf_Execute (cbuf_t *cbuf);
void Cbuf_Execute_Stack (cbuf_t *cbuf);
void Cbuf_Execute_Sets (cbuf_t *cbuf);
//@}
//@}
#endif//__QF_cbuf_h

View file

@ -29,10 +29,20 @@
#ifndef __checksum_h
#define __checksum_h
/** \addtogroup utils */
//@{
/** \addtogroup crc
*/
//@{
#include "QF/qtypes.h"
unsigned int Com_BlockChecksum (const void *buffer, int length);
void Com_BlockFullChecksum (const void *buffer, int len, unsigned char *outbuf);
byte COM_BlockSequenceCRCByte (const byte *base, int length, int sequence);
//@}
//@}
#endif // __checksum_h

View file

@ -29,6 +29,13 @@
#ifndef __QF_cmd_h
#define __QF_cmd_h
/** \addtogroup utils */
//@{
/** \defgroup cmd Command management.
*/
//@{
#include "QF/qtypes.h"
typedef void (*xcommand_t) (void);
@ -66,4 +73,7 @@ void Cmd_Exec_File (struct cbuf_s *cbuf, const char *path, int qfs);
extern struct cbuf_args_s *cmd_args;
extern struct cvar_s *cmd_warncmd;
//@}
//@}
#endif//__QF_cmd_h

View file

@ -29,6 +29,13 @@
#ifndef __crc_h
#define __crc_h
/** \addtogroup utils */
//@{
/** \defgroup crc Checksum generation.
*/
//@{
#include "QF/qtypes.h"
void CRC_Init(unsigned short *crcvalue);
@ -37,4 +44,7 @@ void CRC_ProcessBlock (byte *start, unsigned short *crcvalue, int count);
unsigned short CRC_Value(unsigned short crcvalue);
unsigned short CRC_Block (byte *start, int count);
//@}
//@}
#endif // __crc_h

View file

@ -29,6 +29,13 @@
#ifndef __cvar_h
#define __cvar_h
/** \addtogroup utils */
//@{
/** \defgroup cvar Configuration variables
*/
//@{
#include "QF/qtypes.h"
#include "QF/quakeio.h"
@ -126,4 +133,7 @@ void Cvar_Shutdown (void);
extern cvar_t *cvar_vars;
//@}
//@}
#endif // __cvar_h

View file

@ -29,6 +29,13 @@
#ifndef __dstring_h
#define __dstring_h
/** \addtogroup utils */
//@{
/** \defgroup dstring Dynamic Strings
*/
//@{
#include <stdarg.h>
#include <stdlib.h>
@ -150,4 +157,7 @@ int davsprintf (dstring_t *dstr, const char *fmt, va_list args);
int dasprintf (dstring_t *dstr, const char *fmt, ...) __attribute__((format(printf,2,3)));
//@}
//@}
//@}
#endif // __dstring_h

View file

@ -29,6 +29,13 @@
#ifndef __hash_h
#define __hash_h
/** \addtogroup utils */
//@{
/** \defgroup hash Hash tables
*/
//@{
typedef struct hashtab_s hashtab_t;
/** create a new hash table:
@ -105,7 +112,9 @@ void *Hash_FindElement (hashtab_t *tab, void *ele);
tab: the table to search
key: the key string identifying the elements being searched for
returns a null terminated list of element pointers if at least one found,
otherwise 0.
otherwise 0. returned list is guaranteed to be in reverse order of
insertion. ie, deleting items from the list in list order will delete the
correct items.
*/
void **Hash_FindList (hashtab_t *tab, const char *key);
void **Hash_FindElementList (hashtab_t *tab, void *ele);
@ -152,4 +161,7 @@ void **Hash_GetList (hashtab_t *tab);
*/
void Hash_Stats (hashtab_t *tab);
//@}
//@}
#endif // __hash_h

View file

@ -31,6 +31,13 @@
#ifndef __QF_idparse_h
#define __QF_idparse_h
/** \addtogroup utils */
//@{
/** \addtogroup cbuf
*/
//@{
extern const char *com_token;
struct cbuf_args_s;
@ -40,4 +47,7 @@ void COM_TokenizeString (const char *str, struct cbuf_args_s *args);
extern struct cbuf_interpreter_s id_interp;
//@}
//@}
#endif//__QF_idparse_h

View file

@ -29,6 +29,13 @@
#ifndef _INFO_H
#define _INFO_H
/** \addtogroup utils */
//@{
/** \defgroup info Info Keys
*/
//@{
#include <stdlib.h> // for size_t. sys/types.h SHOULD be used, but can't :(bc)
#include <QF/qtypes.h>
@ -60,4 +67,7 @@ void Info_Destroy (info_t *info);
char *Info_MakeString (info_t *info, int (*filter)(const char *));
void Info_AddKeys (info_t *info, info_t *keys);
//@}
//@}
#endif // _INFO_H

View file

@ -29,6 +29,13 @@
#ifndef __mathlib_h
#define __mathlib_h
/** \addtogroup utils */
//@{
/** \defgroup mathlib Vector and matrix functions
*/
//@{
#include <math.h>
#include "QF/qtypes.h"
@ -312,4 +319,7 @@ VectorNormalize (vec3_t v)
return length;
}
//@}
//@}
#endif // __mathlib_h

View file

@ -30,6 +30,13 @@
#ifndef __mdfour_h
#define __mdfour_h
/** \addtogroup utils */
//@{
/** \addtogroup crc
*/
//@{
#include "QF/uint32.h"
#define MDFOUR_DIGEST_BYTES 16
@ -44,4 +51,7 @@ void mdfour_update(struct mdfour *md, const unsigned char *in, int n); //old: MD
void mdfour_result(struct mdfour *md, unsigned char *out); // old: MD4Final
void mdfour(unsigned char *out, const unsigned char *in, int n);
//@}
//@}
#endif // __mdfour_h

View file

@ -406,6 +406,7 @@ typedef struct model_s
int numtextures;
texture_t **textures;
texture_t *skytexture;
byte *visdata;
byte *lightdata;

View file

@ -28,6 +28,13 @@
#ifndef _MSG_H
#define _MSG_H
/** \addtogroup utils */
//@{
/** \defgroup msg Message reading and writing
*/
//@{
#include "QF/sizebuf.h"
void MSG_WriteByte (sizebuf_t *sb, int c);
@ -66,4 +73,7 @@ void MSG_ReadCoordAngleV (qmsg_t *msg, vec3_t coord, vec3_t angles);
void MSG_ReadAngleV (qmsg_t *msg, vec3_t angles);
float MSG_ReadAngle16 (qmsg_t *msg);
//@}
//@}
#endif

View file

@ -32,6 +32,13 @@
#ifndef __qf_pak_h
#define __qf_pak_h
/** \addtogroup utils */
//@{
/** \addtogroup pak
*/
//@{
#define PAK_PATH_LENGTH 56
typedef struct {
@ -45,4 +52,7 @@ typedef struct {
int dirlen;
} dpackheader_t;
//@}
//@}
#endif//__qf_pak_h

View file

@ -31,6 +31,13 @@
#ifndef __QF_pakfile_h
#define __QF_pakfile_h
/** \addtogroup utils */
//@{
/** \defgroup pak pakfile proccessing
*/
//@{
#include "QF/hash.h"
#include "QF/pak.h"
#include "QF/quakeio.h"
@ -60,4 +67,7 @@ int pack_add (pack_t *pack, const char *filename);
int pack_extract (pack_t *pack, dpackfile_t *pf);
dpackfile_t *pack_find_file (pack_t *pack, const char *filename);
//@}
//@}
#endif//__QF_pakfile_h

View file

@ -29,6 +29,13 @@
#ifndef __QF_plugin_h_
#define __QF_plugin_h_
/** \addtogroup utils */
//@{
/** \defgroup plugin Plugins
*/
//@{
#define QFPLUGIN_VERSION "1.0"
#include <QF/qtypes.h>
@ -110,4 +117,7 @@ void PI_Shutdown (void);
// FIXME: we need a generic function to initialize unused fields
//@}
//@}
#endif // __QF_plugin_h_

View file

@ -370,7 +370,7 @@ typedef struct pr_va_list_s {
} pr_va_list_t;
#define PROG_ID_VERSION 6
#define PROG_VERSION 0x00fff004 // MMmmmRRR 0.fff.004 (hex)
#define PROG_VERSION 0x00fff005 // MMmmmRRR 0.fff.005 (hex)
typedef struct dprograms_s {
unsigned int version;

View file

@ -106,8 +106,8 @@ typedef struct pr_protocol_s {
pointer_t class_pointer; // pr_class_t
string_t protocol_name;
pointer_t protocol_list; // pr_protocol_list_t
pointer_t instance_methods; // pr_method_list_t
pointer_t class_methods; // pr_method_list_t
pointer_t instance_methods; // pr_method_description_list_t
pointer_t class_methods; // pr_method_description_list_t
} pr_protocol_t;
typedef struct pr_category_s {
@ -121,20 +121,29 @@ typedef struct pr_category_s {
typedef struct pr_protocol_list_s {
pointer_t next;
int count;
pointer_t list[1];
pointer_t list[1]; // pr_protocol_t
} pr_protocol_list_t;
typedef struct pr_method_list_s {
pointer_t method_next;
int method_count;
struct pr_method_s {
pr_sel_t method_name;
pointer_t method_name; // pr_sel_t
string_t method_types;
func_t method_imp; // typedef id (id, SEL, ...) IMP
} method_list[1];
} pr_method_list_t;
typedef struct pr_method_s pr_method_t;
typedef struct pr_method_description_list_s {
int count;
struct pr_method_description_s {
pointer_t name; // pr_sel_t
string_t types;
} list[1];
} pr_method_description_list_t;
typedef struct pr_method_description_s pr_method_description_t;
typedef struct pr_ivar_list_s {
int ivar_count;
struct pr_ivar_s {
@ -145,13 +154,24 @@ typedef struct pr_ivar_list_s {
} pr_ivar_list_t;
typedef struct pr_ivar_s pr_ivar_t;
typedef struct pr_static_instances_s {
// one per staticly instanced class per module (eg, 3 instances of Object
// will produce one of these structs with 3 pointers to those instances in
// instances[]
string_t class_name;
pointer_t instances[1]; // null terminated array of pr_id_t
} pr_static_instances_t;
typedef struct pr_symtab_s {
int sel_ref_cnt;
pointer_t refs; // pr_sel_t
int cls_def_cnt;
int cat_def_cnt;
pointer_t defs[1]; // variable array of class pointers then
// category pointers
pointer_t defs[1]; // variable array of cls_def_cnt class
// pointers then cat_def_cnt category
// pointers followed by a null terminated
// array of pr_static_instances (not yet
// implemented in qfcc)
} pr_symtab_t;
typedef struct pr_module_s {

File diff suppressed because it is too large Load diff

View file

@ -31,6 +31,13 @@
#ifndef __qargs_h
#define __qargs_h
/** \addtogroup utils */
//@{
/** \addtogroup misc
*/
//@{
#include "QF/qtypes.h"
extern int com_argc;
@ -44,4 +51,7 @@ void COM_Init (void);
void COM_Init_Cvars (void);
void COM_InitArgv (int argc, const char **argv);
//@}
//@}
#endif // __qargs_h

View file

@ -31,6 +31,13 @@
#ifndef __qendian_h
#define __qendian_h
/** \addtogroup utils */
//@{
/** \defgroup qendian Endian handling functions
*/
//@{
#include "QF/qtypes.h"
#ifndef NULL
@ -89,4 +96,7 @@ byte ReadByte (struct QFile_s *file);
unsigned short ReadShort (struct QFile_s *file);
unsigned long ReadLong (struct QFile_s *file);
//@}
//@}
#endif // __qendian_h

View file

@ -29,18 +29,20 @@
#ifndef __QF_qfplist_h_
#define __QF_qfplist_h_
#include "QF/qtypes.h"
/** \addtogroup utils */
//@{
// Ugly defines for fast checking and conversion from char to number
#define inrange(ch,min,max) ((ch) >= (min) && (ch) <= (max))
#define char2num(ch) \
inrange((ch), '0', '9') ? ((ch) - 0x30) \
: (inrange((ch), 'a', 'f') ? ((ch) - 0x57) : ((ch) - 0x37))
/** \defgroup qfplist Property lists
*/
//@{
#include "QF/qtypes.h"
/**
There are four types of data that can be stored in a property list:
QFDictionary A list of values, each associated with a key (a C string).
QFDictionary A list of values, each associated with a key (a C
string).
QFArray A list of indexed values
QFString A string.
QFBinary Random binary data. The parser doesn't load these yet.
@ -64,9 +66,9 @@ inrange((ch), '0', '9') ? ((ch) - 0x30) \
<!-- in the following paragram, the \< and \> are just < and >. the \ is
for doxygen -->
QFBinary data (though not loaded currently) is hex-encoded and contained
within angle brackets, \< \>. The length of the encoded data must be an even
number, so while \<FF00\> is valid, \<F00\> isn't.
QFBinary data is hex-encoded and contained within angle brackets, \< \>.
The length of the encoded data must be an even number, so while \<FF00\>
is valid, \<F00\> isn't.
Property lists may contain C-style or BCPL-style comments.
*/
@ -111,63 +113,79 @@ typedef struct plbinary_s plbinary_t;
struct hashtab_s;
/**
\fn plitem_t *PL_GetPropertyList (const char *string)
\brief Create an in-memory representation of the contents of a property list
/** Create an in-memory representation of the contents of a property list.
\param string the saved plist, as read from a file.
\return Returns an object equivalent to the passed-in string.
You are responsible for freeing the object returned.
\note You are responsible for freeing the object returned.
*/
plitem_t *PL_GetPropertyList (const char *);
plitem_t *PL_GetPropertyList (const char *string);
/**
\fn plitem_t *PL_ObjectForKey (plitem_t *dict, const char *key)
\brief Retrieve a value from a dictionary object.
/** Create a property list string from the in-memory representation.
\param pl the in-memory representation
\return the text representation of the property list
\note You are responsible for freeing the string returned.
*/
char *PL_WritePropertyList (plitem_t *pl);
/** Retrieve the type of an object.
\param item The object
\return the type of the object
*/
pltype_t PL_Type (plitem_t *item);
/** Retrieve a string from a string object.
\param string The string object
\return pointer to the actual string value or NULL if string isn't a
string.
\note You are NOT responsible for freeing the returned object. It will
be destroyed when its container is.
*/
const char *PL_String (plitem_t *string);
/** Retrieve a value from a dictionary object.
\param dict The dictionary to retrieve a value from
\param key The unique key associated with the value
\return You are NOT responsible for freeing the returned object. It will
\return the value associated with the key, or NULL if not found or dict
isn't a dictionary.
\note You are NOT responsible for freeing the returned object. It will
be destroyed when its container is.
*/
plitem_t *PL_ObjectForKey (plitem_t *, const char *);
plitem_t *PL_ObjectForKey (plitem_t *dict, const char *key);
/**
\fn plitem_t *PL_ObjectAtIndex (plitem_t *array, int index)
\brief Retrieve a value from an array object.
/** Retrieve a value from an array object.
\param array The array to get the value from
\param index The index within the array to retrieve
\return You are NOT responsible for freeing the returned object. It will
\return the value associated with the key, or NULL if not found or array
isn't an array.
\note You are NOT responsible for freeing the returned object. It will
be destroyed when its container is.
*/
plitem_t *PL_ObjectAtIndex (plitem_t *, int);
plitem_t *PL_ObjectAtIndex (plitem_t *array, int index);
/**
\fn plitem_t *PL_D_AllKeys (plitem_t *dict)
\brief Retrieve a list of all keys in a dictionary.
/** Retrieve a list of all keys in a dictionary.
\param dict The dictionary to list
\return Returns an Array containing Strings. You are responsible for
freeing this array.
\return an Array containing Strings or NULL if dict isn't a dictionary
\note You are responsible for freeing this array.
*/
plitem_t *PL_D_AllKeys (plitem_t *);
plitem_t *PL_D_AllKeys (plitem_t *dict);
/**
\brief Retrieve the number of keys in a dictionalry
/** Retrieve the number of keys in a dictionary.
\param dict The dictionary to get the number of keys of.
\return Returns the number of keys in the dictionary.
*/
int PL_D_NumKeys (plitem_t *);
int PL_D_NumKeys (plitem_t *dict);
/**
\fn qboolean PL_D_AddObject (plitem_t *dict, plitem_t *key, plitem_t *value)
/** Add a key/value pair to a dictionary.
\param dict The dictionary to add the key/value pair to
\param key The key of the key/value pair to be added to the dictionary
@ -175,54 +193,54 @@ int PL_D_NumKeys (plitem_t *);
\return true on success, false on failure
Note: the dictionary becomes the owner of both the key and
the value.
\note the dictionary becomes the owner of both the key and the value.
*/
qboolean PL_D_AddObject (plitem_t *, plitem_t *, plitem_t *);
qboolean PL_D_AddObject (plitem_t *dict, plitem_t *key, plitem_t *value);
/** Add an item to an array.
/**
\fn qboolean PL_A_AddObject (plitem_t *array, plitem_t *item)
\param array The array to add the item to
\param item The item to be added to the array
\return true on success, false on failure
Note: the array becomes the owner of the added item.
\note the array becomes the owner of the added item.
*/
qboolean PL_A_AddObject (plitem_t *, plitem_t *);
qboolean PL_A_AddObject (plitem_t *array, plitem_t *item);
/** Retrieve the number of items in an array.
/**
\param array The array to get the number of objects in
\return number of objects in the array
*/
int PL_A_NumObjects (plitem_t *array);
/**
\fn qboolean PL_A_InsertObjectAtIndex (plitem_t *array, plitem_t *item, int index)
/** Insert an item into an array before the specified location.
\param array The array to add the item to
\param item The item to be added to the array
\param index The location at which to insert the item into the array
\return true on success, false on failure
Note: the array becomes the owner of the added item.
\note the array becomes the owner of the added item.
*/
qboolean PL_A_InsertObjectAtIndex (plitem_t *, plitem_t *, int);
qboolean PL_A_InsertObjectAtIndex (plitem_t *array, plitem_t *item, int index);
plitem_t *PL_NewDictionary (void);
plitem_t *PL_NewArray (void);
plitem_t *PL_NewData (void *, int);
plitem_t *PL_NewString (const char *);
/**
\fn void PL_Free (plitem_t *object)
\brief Free a property list object
/** Free a property list object.
This function takes care of freeing any referenced property list data, so
only call it on top-level objects.
\param item the property list object to be freed
*/
void PL_Free (plitem_t *);
void PL_Free (plitem_t *item);
typedef struct pldata_s { // Unparsed property list string
const char *ptr;
@ -232,12 +250,7 @@ typedef struct pldata_s { // Unparsed property list string
const char *error;
} pldata_t;
/*
Internal prototypes
//@}
//@}
static plist_t *PL_ParsePropertyList (pldata_t *);
static qboolean PL_SkipSpace (pldata_t *);
static char *PL_ParseQuotedString (pldata_t *);
static char *PL_ParseUnquotedString (pldata_t *);
*/
#endif // __QF_qfplist_h_

View file

@ -31,6 +31,13 @@
#ifndef __quakefs_h
#define __quakefs_h
/** \addtogroup utils */
//@{
/** \defgroup quakefs Quake Filesystem
*/
//@{
#include "QF/qtypes.h"
#include "QF/quakeio.h"
@ -125,4 +132,7 @@ void QFS_FilelistFree (filelist_t *list);
// FIXME: This is here temporarily until fs_usercfg gets sorted out
char *expand_squiggle (const char *path);
//@}
//@}
#endif // __quakefs_h

View file

@ -30,6 +30,13 @@
#ifndef __quakeio_h
#define __quakeio_h
/** \addtogroup utils */
//@{
/** \defgroup quakeio File IO
*/
//@{
typedef struct QFile_s QFile;
int Qrename(const char *old, const char *new);
@ -53,4 +60,7 @@ int Qflush(QFile *file);
int Qeof(QFile *file);
const char *Qgetline(QFile *file);
//@}
//@}
#endif /*__quakeio_h*/

96
include/QF/script.h Normal file
View file

@ -0,0 +1,96 @@
/*
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 the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
See file, 'COPYING', for details.
*/
#ifndef __QF_script_h
#define __QF_script_h
/** \addtogroup utils */
//@{
/** \defgroup script Scripts
Line oriented script parsing. Multiple scripts being parsed at the same
time is supported.
*/
//@{
#include "QF/qtypes.h"
typedef struct script_s {
/// The current (or next when unget is true) token
struct dstring_s *token;
/// True if the last token has been pushed back.
qboolean unget;
/// current position within the script
const char *p;
/// name of the file being processed. used only for error reporting
const char *file;
/// line number of the file being processed. used only for error reporting
/// but updated internally.
int line;
/// if set, will be called instead of the internal error handler
void (*error)(struct script_s *script, const char *msg);
/// if set, multi line quoted tokens will be treated as errors
int no_quote_lines;
} script_t;
/** Return a new script_t object.
\return A new, blank, script object. Use Script_Start() to initialize.
*/
script_t *Script_New (void);
/** Delete a script_t object.
\param script The script_t object to be deleted
Does not free the memory passed to Script_Start().
*/
void Script_Delete (script_t *script);
/** Prepare a script_t object for parsing.
The caller is responsible for freeing the memory associated with file and
data when parsing is complete.
\param script The script_t object being parsed
\param file Name of the file being parsed. used only for error reporting
\param data The script to be parsed
*/
void Script_Start (script_t *script, const char *file, const char *data);
/** Check if a new token is available.
\param script The script_t object being parsed
\param crossline True to allow passing \n
\return True if a token is available, false if end of file
or end of line (if crossline is false) has been hit
*/
qboolean Script_TokenAvailable (script_t *script, qboolean crossline);
/** Get the next token. Generates an error and exits the program if no token
is available and crossline is false.
\param script The script_t object being parsed
\param crossline True to allow passing \n
\return True on success, false on failure (no token available)
*/
qboolean Script_GetToken (script_t *script, qboolean crossline);
/** Unget the current token. Only one level of unget is supported.
\param script The script_t object being parsed
*/
void Script_UngetToken (script_t *script);
//@}
//@}
#endif//__QF_script_h

View file

@ -28,6 +28,14 @@
#ifndef __sizebuf_h
#define __sizebuf_h
/** \addtogroup utils */
//@{
/** \defgroup sizebuf Fixed Size Buffers
Fixed size buffer management
*/
//@{
#include "QF/qtypes.h"
typedef struct sizebuf_s
@ -46,4 +54,7 @@ void *SZ_GetSpace (sizebuf_t *buf, int length);
void SZ_Write (sizebuf_t *buf, const void *data, int length);
void SZ_Print (sizebuf_t *buf, const char *data); // strcats onto the sizebuf
//@}
//@}
#endif // __sizebuf_h

View file

@ -29,6 +29,14 @@
#ifndef __sys_h
#define __sys_h
/** \addtogroup utils */
//@{
/** \defgroup sys Portability
Non-portable functions
*/
//@{
#include <stdio.h>
#include <stdarg.h>
@ -70,7 +78,7 @@ void Sys_RegisterShutdown (void (*func) (void));
double Sys_DoubleTime (void);
void Sys_TimeOfDay(date_t *date);
int Sys_CheckInput (int idle, int net_socket);
int Sys_CheckInput (int idle, unsigned int net_socket);
const char *Sys_ConsoleInput (void);
void Sys_Sleep (void);
@ -105,4 +113,7 @@ void Sys_DebugLog(const char *file, const char *fmt, ...) __attribute__((format(
Sys_Error ("%s: Failed to allocate memory.", __FUNCTION__); \
} while (0)
//@}
//@}
#endif // __sys_h

View file

@ -30,9 +30,20 @@
#ifndef __va_h
#define __va_h
/** \addtogroup utils */
//@{
/** \addtogroup misc
Formatted printing.
*/
//@{
// does a varargs printf into a temp buffer
char *va(const char *format, ...) __attribute__((format(printf,1,2)));
// does a varargs printf into a malloced buffer
char *nva(const char *format, ...) __attribute__((format(printf,1,2)));
//@}
//@}
#endif // __va_h

View file

@ -29,6 +29,13 @@
#ifndef __ver_check_h_
#define __ver_check_h_
/** \addtogroup utils */
//@{
/** \addtogroup misc
*/
//@{
/*
ver_compare
@ -38,4 +45,7 @@
*/
int ver_compare (const char *, const char *);
//@}
//@}
#endif // __ver_check_h_

View file

@ -30,6 +30,14 @@
#ifndef _WAD_H
#define _WAD_H
/** \addtogroup utils */
//@{
/** \addtogroup wad
Wad Files
*/
//@{
#include "QF/wadfile.h"
@ -42,4 +50,7 @@ void *W_GetLumpName (const char *name);
void SwapPic (qpic_t *pic);
//@}
//@}
#endif // _WAD_H

View file

@ -25,7 +25,14 @@
$Id$
*/
// wadfile.h
/** \addtogroup utils */
//@{
/** \defgroup wad Wad Files
Wadfile processing
*/
//@{
#ifndef __QF_wadfile_h
#define __QF_wadfile_h
@ -98,4 +105,7 @@ int wad_add_data (wad_t *wad, const char *lumpname, byte type,
const void *data, int bytes);
lumpinfo_t *wad_find_lump (wad_t *wad, const char *filename);
//@}
//@}
#endif//__QF_wadfile_h

View file

@ -28,71 +28,70 @@
#ifndef __zone_h
#define __zone_h
/*
memory allocation
/** \addtogroup utils */
//@{
/** \defgroup zone Memory Management
H_??? The hunk manages the entire memory block given to quake. It must be
contiguous. Memory can be allocated from either the low or high end in a
stack fashion. The only way memory is released is by resetting one of the
pointers.
Hunk allocations should be given a name, so the Hunk_Print () function
can display usage.
Hunk allocations are guaranteed to be 16 byte aligned.
The video buffers are allocated high to avoid leaving a hole underneath
server allocations when changing to a higher video mode.
H_??? The hunk manages the entire memory block given to quake. It must be
contiguous. Memory can be allocated from either the low or high end in a
stack fashion. The only way memory is released is by resetting one of the
pointers.
Z_??? Zone memory functions used for small, dynamic allocations like text
strings from command input. There is only about 48K for it, allocated at
the very bottom of the hunk.
Hunk allocations should be given a name, so the Hunk_Print () function
can display usage.
Cache_??? Cache memory is for objects that can be dynamically loaded and
can usefully stay persistant between levels. The size of the cache
fluctuates from level to level.
Hunk allocations are guaranteed to be 16 byte aligned.
The video buffers are allocated high to avoid leaving a hole underneath
server allocations when changing to a higher video mode.
To allocate a cachable object
Z_??? Zone memory functions used for small, dynamic allocations like text
strings from command input. There is only about 48K for it, allocated at
the very bottom of the hunk.
Cache_??? Cache memory is for objects that can be dynamically loaded and
can usefully stay persistant between levels. The size of the cache
fluctuates from level to level.
To allocate a cachable object
Temp_??? Temp memory is used for file loading and surface caching. The
size of the cache memory is adjusted so that there is a minimum of 512k
remaining for temp memory.
Temp_??? Temp memory is used for file loading and surface caching. The size
of the cache memory is adjusted so that there is a minimum of 512k remaining
for temp memory.
------ Top of Memory -------
high hunk allocations
------ Top of Memory -------
<--- high hunk reset point held by vid
high hunk allocations
video buffer
<--- high hunk reset point held by vid
z buffer
video buffer
surface cache
z buffer
<--- high hunk used
surface cache
cachable memory
<--- high hunk used
<--- low hunk used
cachable memory
client and server low hunk allocations
<--- low hunk used
client and server low hunk allocations
<-- low hunk reset point held by host
startup hunk allocations
Zone block
----- Bottom of Memory -----
<-- low hunk reset point held by host
startup hunk allocations
Zone block
----- Bottom of Memory -----
*/
//@{
typedef struct memzone_s memzone_t;
@ -103,6 +102,7 @@ void Z_Free (memzone_t *zone, void *ptr);
void *Z_Malloc (memzone_t *zone, int size); // returns 0 filled memory
void *Z_TagMalloc (memzone_t *zone, int size, int tag);
void *Z_Realloc (memzone_t *zone, void *ptr, int size);
void Z_Print (memzone_t *zone);
void Z_CheckHeap (memzone_t *zone);
void *Hunk_Alloc (int size); // returns 0 filled memory
@ -174,4 +174,7 @@ void *QA_realloc (void *ptr, size_t size);
void QA_free (void *ptr);
char *QA_strdup (const char *s);
//@}
//@}
#endif // __zone_h

View file

@ -33,10 +33,6 @@
#define __rua_internal_h
#include "QF/quakeio.h"
#define QFILE_MAX_HANDLES 20
typedef struct {
QFile *handles[QFILE_MAX_HANDLES];
} qfile_resources_t;
void RUA_Cbuf_Init (struct progs_s *pr, int secure);
@ -54,10 +50,11 @@ void RUA_Obj_Init (struct progs_s *pr, int secure);
void RUA_Plist_Init (struct progs_s *pr, int secure);
void RUA_Script_Init (progs_t *pr, int secure);
void RUA_String_Init (struct progs_s *pr, int secure);
void RUA_QFile_Init (struct progs_s *pr, int secure);
QFile **QFile_AllocHandle (struct progs_s *pr, qfile_resources_t *res);
int QFile_AllocHandle (struct progs_s *pr, QFile *file);
void RUA_QFS_Init (struct progs_s *pr, int secure);

View file

@ -55,8 +55,7 @@ typedef struct trace_s
#define MOVE_NOMONSTERS 1
#define MOVE_MISSILE 2
typedef struct areanode_s
{
typedef struct areanode_s {
int axis; // -1 = leaf node
float dist;
struct areanode_s *children[2];
@ -116,5 +115,7 @@ hull_t *SV_HullForEntity (struct edict_s *ent, const vec3_t mins,
qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f,
const vec3_t p1, const vec3_t p2,
trace_t *trace);
qboolean MOD_TraceLine (hull_t *hull, int num,
const vec3_t start, const vec3_t end, trace_t *trace);
#endif // __world_h

View file

@ -121,5 +121,5 @@ CDAudio_Init (void)
"play (track number) - Plays the specified track one time.\n"
"stop - Stops the currently playing track.");
Sys_Printf ("CD Audio Initialized\n");
return 0; // FIXME: Assumes success
return 0;
}

View file

@ -5,13 +5,13 @@ INCLUDES= -I$(top_srcdir)/include
SDL_LIBS= @SDL_LIBS@
XMMS_LIBS= @XMMS_LIBS@
plugin_version= 1:0:0
plugin_ldflags= @plugin_ldflags@
plugin_ldflags= @plugin_ldflags@ -module
plugin_libadd= @plugin_libadd@
EXEEXT=
plugin_PROGRAMS= @CD_PLUGIN_TARGETS@
noinst_PROGRAMS= @CD_PLUGIN_STATIC@
EXTRA_PROGRAMS= cd_file.la cd_linux.la cd_sdl.la cd_sgi.la cd_win.la cd_xmms.la
plugin_LTLIBRARIES= @CD_PLUGIN_TARGETS@
noinst_LTLIBRARIES= @CD_PLUGIN_STATIC@
EXTRA_LTLIBRARIES= cd_file.la cd_linux.la cd_sdl.la cd_sgi.la cd_win.la cd_xmms.la
cd_file_la_LDFLAGS= $(plugin_ldflags)
cd_file_la_SOURCES= cd_file.c
@ -20,19 +20,19 @@ cd_linux_la_LDFLAGS= $(plugin_ldflags)
cd_linux_la_SOURCES= cd_linux.c
cd_sdl_la_LDFLAGS= $(plugin_ldflags)
cd_sdl_la_LDADD= $(SDL_LIBS) $(plugin_libadd)
cd_sdl_la_LIBADD= $(SDL_LIBS) $(plugin_libadd)
cd_sdl_la_CFLAGS= $(SDL_CFLAGS)
cd_sdl_la_SOURCES= cd_sdl.c
cd_sgi_la_LDFLAGS= $(plugin_ldflags)
cd_sgi_la_LDADD= $(SGI_CD_LIBS)
cd_sgi_la_LIBADD= $(SGI_CD_LIBS)
cd_sgi_la_SOURCES= cd_sgi.c
cd_win_la_LDFLAGS= $(plugin_ldflags)
cd_win_la_LDADD= $(plugin_libadd)
cd_win_la_LIBADD= $(plugin_libadd)
cd_win_la_SOURCES= cd_win.c
cd_xmms_la_LDFLAGS= $(plugin_ldflags)
cd_xmms_la_LDADD= $(XMMS_LIBS)
cd_xmms_la_LIBADD= $(XMMS_LIBS)
cd_xmms_la_CFLAGS= $(XMMS_CFLAGS)
cd_xmms_la_SOURCES= cd_xmms.c

View file

@ -2,7 +2,6 @@
cd_sgi.c
audio cd playback support for sgi irix machines
FIXME: Update for plugin API
Copyright (C) 1996-1997 Id Software, Inc.

View file

@ -50,8 +50,6 @@ static general_data_t plugin_info_general_data;
static general_funcs_t plugin_info_general_funcs;
static cd_funcs_t plugin_info_cd_funcs;
extern HWND mainwindow; //FIXME
static qboolean cdValid = false;
static qboolean playing = false;
static qboolean wasPlaying = false;
@ -208,7 +206,7 @@ I_CDAudio_Play (int track, qboolean looping)
return;
}
if (track < 0 || track >= sizeof (remap)) {
if (track < 0 || track >= (int) sizeof (remap)) {
Sys_Printf ("CDAudio: invalid track number\n");
return;
}

View file

@ -3,21 +3,21 @@ AUTOMAKE_OPTIONS= foreign
AM_CFLAGS= @PREFER_PIC@ @VORBIS_CFLAGS@ @OGG_CFLAGS@
INCLUDES= -I$(top_srcdir)/include
plugin_version= 1:0:0
plugin_ldflags= @plugin_ldflags@
plugin_ldflags= @plugin_ldflags@ -module
plugin_libadd= @plugin_libadd@
EXEEXT=
plugin_PROGRAMS= @SND_REND_TARGETS@
EXTRA_PROGRAMS= snd_render_default.la
plugin_LTLIBRARIES= @SND_REND_TARGETS@
EXTRA_LTLIBRARIES= snd_render_default.la
noinst_PROGRAMS= @SND_REND_STATIC@
noinst_LTLIBRARIES= @SND_REND_STATIC@
snd_render_default_la_LDFLAGS= $(plugin_ldflags)
snd_render_default_la_SOURCES= snd_dma.c snd_mem.c snd_mix.c vorbis.c wav.c midi.c
if ASM_ARCH
snd_render_default_la_LDADD= $(VORBISFILE_LIBS) $(VORBIS_LIBS) $(OGG_LIBS) $(WM_LIBS)
snd_render_default_la_LIBADD= $(VORBISFILE_LIBS) $(VORBIS_LIBS) $(OGG_LIBS) $(WM_LIBS)
snd_render_default_la_DEPENDENCIES=
else
snd_render_default_la_LDADD= $(VORBISFILE_LIBS) $(VORBIS_LIBS) $(OGG_LIBS) $(WM_LIBS)
snd_render_default_la_LIBADD= $(VORBISFILE_LIBS) $(VORBIS_LIBS) $(OGG_LIBS) $(WM_LIBS)
snd_render_default_la_DEPENDENCIES=
endif

View file

@ -91,7 +91,6 @@ get_info (void * handle) {
static int
midi_stream_read (void *file, byte *buf, int count, wavinfo_t *info)
{
// FIXME: need to check what the return of this function /should/ be
return WildMidi_GetOutput (file, (char *)buf, (unsigned long int)count);
}
@ -103,7 +102,6 @@ midi_stream_seek (void *file, int pos, wavinfo_t *info)
pos += info->dataofs;
new_pos = pos;
// FIXME: need to check what the return of this function /should/ be
return WildMidi_SampledSeek(file, &new_pos);
}

View file

@ -1,285 +0,0 @@
/*
snd_mixa.S
x86 assembly-language sound code
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 "asm_i386.h"
// #include "quakeasm.h"
#ifdef USE_INTEL_ASM
#ifdef _WIN32
# undef PIC //no such thing in win32
#endif
.text
.extern C(snd_scaletable)
.extern C(paintbuffer)
.extern C(snd_linear_count)
.extern C(snd_p)
.extern C(snd_vol)
.extern C(snd_out)
//----------------------------------------------------------------------
// 8-bit sound-mixing code
//----------------------------------------------------------------------
#define ch 4+16
#define sc 8+16
#define count 12+16
.globl C(NOT_SND_PaintChannelFrom8)
#ifdef PIC
.type C(NOT_SND_PaintChannelFrom8),@function
#endif
C(NOT_SND_PaintChannelFrom8):
pushl %esi // preserve register variables
pushl %edi
pushl %ebx
pushl %ebp
// int data;
// short *lscale, *rscale;
// unsigned char *sfx;
// int i;
movl ch(%esp),%ebx
movl sc(%esp),%esi
// if (ch->leftvol > 255)
// ch->leftvol = 255;
// if (ch->rightvol > 255)
// ch->rightvol = 255;
movl ch_leftvol(%ebx),%eax
movl ch_rightvol(%ebx),%edx
cmpl $255,%eax
jna LLeftSet
movl $255,%eax
LLeftSet:
cmpl $255,%edx
jna LRightSet
movl $255,%edx
LRightSet:
// lscale = snd_scaletable[ch->leftvol >> 3];
// rscale = snd_scaletable[ch->rightvol >> 3];
// sfx = (signed char *)sc->data + ch->pos;
// ch->pos += count;
andl $0xF8,%eax
addl $(sfxc_data),%esi
andl $0xF8,%edx
movl ch_pos(%ebx),%edi
movl count(%esp),%ecx
addl %edi,%esi
shll $7,%eax
addl %ecx,%edi
addl %ecx,%esi
shll $7,%edx
movl %edi,ch_pos(%ebx)
#ifdef PIC
call .Lpic1
.Lpic1: popl %ebx
addl $C(_GLOBAL_OFFSET_TABLE_)+[.-.Lpic1],%ebx
movl C(snd_scaletable)@GOT(%ebx,%eax),%eax
movl C(snd_scaletable)@GOT(%ebx,%edx),%edx
movl C(paintbuffer)@GOT(%ebx),%ebx
#else
leal C(snd_scaletable)(%eax),%eax
leal C(snd_scaletable)(%edx),%edx
leal C(paintbuffer),%ebx
#endif
pushl %ebx // save paintbuffer offset
testl $1,%ecx
leal 0(%ebx,%ecx,psp_size),%ecx
movl $0,%ebx
movb -1(%esi),%bl
jz LMix8Loop
movl (%eax,%ebx,4),%edi
movl (%edx,%ebx,4),%ebp
addl psp_left-psp_size(%ecx),%edi
addl psp_right-psp_size(%ecx),%ebp
movl %edi,psp_left-psp_size(%ecx)
movl %ebp,psp_right-psp_size(%ecx)
movb -2(%esi),%bl
subl $psp_size,%ecx
decl %esi
cmpl (%esp),%ecx
jz LDone
// for (i=0 ; i<count ; i++)
// {
LMix8Loop:
// data = sfx[i];
// paintbuffer[i].left += lscale[data];
// paintbuffer[i].right += rscale[data];
movl (%eax,%ebx,4),%edi
movl (%edx,%ebx,4),%ebp
addl psp_left-psp_size(%ecx),%edi
addl psp_right-psp_size(%ecx),%ebp
movb -2(%esi),%bl
movl %edi,psp_left-psp_size(%ecx)
movl %ebp,psp_right-psp_size(%ecx)
movl (%eax,%ebx,4),%edi
movl (%edx,%ebx,4),%ebp
movb -3(%esi),%bl
addl psp_left-psp_size*2(%ecx),%edi
addl psp_right-psp_size*2(%ecx),%ebp
movl %edi,psp_left-psp_size*2(%ecx)
movl %ebp,psp_right-psp_size*2(%ecx)
// }
subl $2*psp_size,%ecx
subl $2,%esi
cmpl (%esp),%ecx
jnz LMix8Loop
LDone:
addl $4,%esp // remove paintbuffer offset
popl %ebp
popl %ebx
popl %edi
popl %esi
ret
#ifdef PIC
.Lfe1:
.size C(NOT_SND_PaintChannelFrom8),.Lfe1-C(NOT_SND_PaintChannelFrom8)
#endif
//----------------------------------------------------------------------
// Transfer of stereo buffer to 16-bit DMA buffer code
//----------------------------------------------------------------------
.globl C(SND_WriteLinearBlastStereo16)
#ifdef PIC
.type C(SND_WriteLinearBlastStereo16),@function
#endif
C(SND_WriteLinearBlastStereo16):
pushl %esi // preserve register variables
pushl %edi
pushl %ebx
#ifdef PIC
call .Lpic2
.Lpic2:
popl %ebx
addl $C(_GLOBAL_OFFSET_TABLE_)+[.-.Lpic2],%ebx
#endif
// int i;
// int val;
#ifdef PIC
movl C(snd_linear_count)@GOTOFF(%ebx),%ecx
movl C(snd_vol)@GOTOFF(%ebx),%esi
movl C(snd_out)@GOTOFF(%ebx),%edi
movl C(snd_p)@GOTOFF(%ebx),%ebx
#else
movl C(snd_linear_count),%ecx
movl C(snd_vol),%esi
movl C(snd_out),%edi
movl C(snd_p),%ebx
#endif
// for (i=0 ; i<snd_linear_count ; i+=2)
// {
LWLBLoopTop:
// val = (snd_p[i]*snd_vol)>>8;
// if (val > 0x7fff)
// snd_out[i] = 0x7fff;
// else if (val < (short)0x8000)
// snd_out[i] = (short)0x8000;
// else
// snd_out[i] = val;
movl -8(%ebx,%ecx,4),%eax
imull %esi,%eax
sarl $8,%eax
cmpl $0x7FFF,%eax
jg LClampHigh
cmpl $0xFFFF8000,%eax
jnl LClampDone
movl $0xFFFF8000,%eax
jmp LClampDone
LClampHigh:
movl $0x7FFF,%eax
LClampDone:
// val = (snd_p[i+1]*snd_vol)>>8;
// if (val > 0x7fff)
// snd_out[i+1] = 0x7fff;
// else if (val < (short)0x8000)
// snd_out[i+1] = (short)0x8000;
// else
// snd_out[i+1] = val;
movl -4(%ebx,%ecx,4),%edx
imull %esi,%edx
sarl $8,%edx
cmpl $0x7FFF,%edx
jg LClampHigh2
cmpl $0xFFFF8000,%edx
jnl LClampDone2
movl $0xFFFF8000,%edx
jmp LClampDone2
LClampHigh2:
movl $0x7FFF,%edx
LClampDone2:
shll $16,%edx
andl $0xFFFF,%eax
orl %eax,%edx
movl %edx,-4(%edi,%ecx,2)
// }
subl $2,%ecx
jnz LWLBLoopTop
// snd_p += snd_linear_count;
popl %ebx
popl %edi
popl %esi
ret
#ifdef PIC
.Lfe2:
.size C(SND_WriteLinearBlastStereo16),.Lfe2-C(SND_WriteLinearBlastStereo16)
#endif
#endif // USE_INTEL_ASM

View file

@ -4,39 +4,39 @@ AM_CFLAGS= @PREFER_PIC@
INCLUDES= -I$(top_srcdir)/include
SDL_LIBS = @SDL_LIBS@
plugin_version= 1:0:0
plugin_ldflags= @plugin_ldflags@
plugin_ldflags= @plugin_ldflags@ -module
plugin_libadd= @plugin_libadd@
EXEEXT=
plugin_PROGRAMS= @SND_PLUGIN_TARGETS@
noinst_PROGRAMS= @SND_PLUGIN_STATIC@
EXTRA_PROGRAMS= \
plugin_LTLIBRARIES= @SND_PLUGIN_TARGETS@
noinst_LTLIBRARIES= @SND_PLUGIN_STATIC@
EXTRA_LTLIBRARIES= \
snd_output_sdl.la snd_output_alsa.la snd_output_alsa0_9.la\
snd_output_oss.la snd_output_sgi.la snd_output_sun.la \
snd_output_win.la snd_output_dx.la snd_output_disk.la
snd_output_sdl_la_LDFLAGS= $(plugin_ldflags)
snd_output_sdl_la_LDADD= $(SDL_LIBS) $(plugin_libadd)
snd_output_sdl_la_LIBADD= $(SDL_LIBS) $(plugin_libadd)
snd_output_sdl_la_CFLAGS= $(SDL_CFLAGS)
snd_output_sdl_la_SOURCES= snd_sdl.c
snd_output_alsa_la_LDFLAGS= $(plugin_ldflags)
snd_output_alsa_la_LDADD=
snd_output_alsa_la_LIBADD=
snd_output_alsa_la_CFLAGS= $(ALSA_CFLAGS)
snd_output_alsa_la_SOURCES= snd_alsa.c
snd_output_alsa0_9_la_LDFLAGS= $(plugin_ldflags)
snd_output_alsa0_9_la_LDADD=
snd_output_alsa0_9_la_LIBADD=
snd_output_alsa0_9_la_CFLAGS= $(ALSA_CFLAGS)
snd_output_alsa0_9_la_SOURCES= snd_alsa_0_9.c
snd_output_oss_la_LDFLAGS= $(plugin_ldflags)
snd_output_oss_la_LDADD= $(OSS_LIBS)
snd_output_oss_la_LIBADD= $(OSS_LIBS)
snd_output_oss_la_CFLAGS= $(OSS_CFLAGS)
snd_output_oss_la_SOURCES= snd_oss.c
snd_output_sgi_la_LDFLAGS= $(plugin_ldflags)
snd_output_sgi_la_LDADD= $(SGISND_LIBS)
snd_output_sgi_la_LIBADD= $(SGISND_LIBS)
snd_output_sgi_la_CFLAGS= $(SGISND_CFLAGS)
snd_output_sgi_la_SOURCES= snd_sgi.c
@ -45,16 +45,16 @@ snd_output_sun_la_CFLAGS= $(SUNSND_CFLAGS)
snd_output_sun_la_SOURCES= snd_sun.c
snd_output_win_la_LDFLAGS= $(plugin_ldflags)
snd_output_win_la_LDADD= $(WINSND_LIBS) $(plugin_libadd)
snd_output_win_la_LIBADD= $(WINSND_LIBS) $(plugin_libadd)
snd_output_win_la_CFLAGS= $(WIN32SND_CFLAGS)
snd_output_win_la_SOURCES= snd_win.c
snd_output_dx_la_LDFLAGS= $(plugin_ldflags)
snd_output_dx_la_LDADD= $(WINSND_LIBS) $(plugin_libadd)
snd_output_dx_la_LIBADD= $(WINSND_LIBS) $(plugin_libadd)
snd_output_dx_la_CFLAGS= $(WIN32SND_CFLAGS)
snd_output_dx_la_SOURCES= snd_dx.c
snd_output_disk_la_LDFLAGS= $(plugin_ldflags)
snd_output_disk_la_LDADD= $(plugin_libadd)
snd_output_disk_la_LIBADD= $(plugin_libadd)
snd_output_disk_la_CFLAGS=
snd_output_disk_la_SOURCES= snd_disk.c

View file

@ -1,327 +0,0 @@
/*
snd_mme.c
(description)
Copyright (C) 1996-1997 Id Software, Inc.
Copyright (C) 1999-2000 Marcus Sundberg [mackan@stacken.kth.se]
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
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
#include <mme/mmsystem.h>
#ifdef HAVE_MME_MME_PUBLIC_H
# include <mme/mme_public.h>
#endif
#include "sound.h"
#include "QF/sys.h"
// 64K is > 1 second at 16-bit, 11025 Hz
#define WAV_BUFFERS 64
#define WAV_MASK 0x3F
#define WAV_BUFFER_SIZE 0x0400
static qboolean wav_init;
static qboolean snd_firsttime = true, snd_iswave;
static int sample16;
static int snd_sent, snd_completed;
static int snd_blocked = 0;
static HPSTR lpData;
static LPWAVEHDR lpWaveHdr;
static HWAVEOUT hWaveOut;
static DWORD gSndBufSize;
static volatile dma_t sn;
/* MME Callback function */
static void
mme_callback ( HANDLE h, UINT wMsg, DWORD instance, LPARAM p1, LPARAM p2 )
{
if (wMsg == WOM_DONE) {
snd_completed++;
}
}
static void
S_BlockSound ( void )
{
if (++snd_blocked == 1)
waveOutReset(hWaveOut);
}
static void
S_UnblockSound ( void )
{
if (!snd_blocked)
return;
snd_blocked--;
}
static void
FreeSound ( void )
{
// only release primary buffer if it's not also the mixing buffer we just released
if (hWaveOut) {
waveOutReset (hWaveOut);
waveOutClose (hWaveOut);
if (lpWaveHdr) {
mmeFreeMem(lpWaveHdr);
}
if (lpData) {
mmeFreeBuffer(lpData);
}
}
hWaveOut = 0;
lpWaveHdr = 0;
lpData = NULL;
lpWaveHdr = NULL;
wav_init = false;
}
/*
SNDDM_InitWav
Crappy windows multimedia base
*/
static qboolean
SNDDMA_InitWav ( void )
{
int hr, i;
LPPCMWAVEFORMAT format;
if ((format = (LPPCMWAVEFORMAT)
mmeAllocMem(sizeof(*format))) == NULL) {
Sys_Printf("Failed to allocate PCMWAVEFORMAT struct\n");
return false;
}
snd_sent = 0;
snd_completed = 0;
sn.channels = 2;
sn.samplebits = 16;
sn.speed = 11025;
memset(format, 0, sizeof(*format));
format->wf.wFormatTag = WAVE_FORMAT_PCM;
format->wf.nChannels = sn.channels;
format->wBitsPerSample = sn.samplebits;
format->wf.nSamplesPerSec = sn.speed;
format->wf.nBlockAlign = format->wf.nChannels
*format->wBitsPerSample / 8;
format->wf.nAvgBytesPerSec = format->wf.nSamplesPerSec
*format->wf.nBlockAlign;
/* Open a waveform device for output using our callback function. */
while ((hr = waveOutOpen((LPHWAVEOUT)&hWaveOut, WAVE_MAPPER,
(LPWAVEFORMAT)format,
(void (*)())mme_callback, 0,
CALLBACK_FUNCTION | WAVE_OPEN_SHAREABLE))
!= MMSYSERR_NOERROR)
{
if (hr != MMSYSERR_ALLOCATED) {
mmeFreeMem(format);
Sys_Printf ("waveOutOpen failed: %d\n", hr);
return false;
} else {
Sys_Printf ("waveOutOpen failed 2222\n");
}
}
mmeFreeMem(format);
/*
Allocate and lock memory for the waveform data. The memory
for waveform data must be globally allocated with
GMEM_MOVEABLE and GMEM_SHARE flags.
*/
gSndBufSize = WAV_BUFFERS*WAV_BUFFER_SIZE;
lpData = mmeAllocBuffer(gSndBufSize);
if (!lpData) {
Sys_Printf ("Sound: Out of memory.\n");
FreeSound ();
return false;
}
memset (lpData, 0, gSndBufSize);
/*
Allocate and lock memory for the header. This memory must
also be globally allocated with GMEM_MOVEABLE and
GMEM_SHARE flags.
*/
lpWaveHdr = mmeAllocMem(sizeof(WAVEHDR) * WAV_BUFFERS);
if (lpWaveHdr == NULL)
{
Sys_Printf ("Sound: Failed to Alloc header.\n");
FreeSound ();
return false;
}
memset (lpWaveHdr, 0, sizeof(WAVEHDR) * WAV_BUFFERS);
/* After allocation, set up and prepare headers. */
for (i=0 ; i<WAV_BUFFERS ; i++) {
lpWaveHdr[i].dwBufferLength = WAV_BUFFER_SIZE;
lpWaveHdr[i].lpData = lpData + i*WAV_BUFFER_SIZE;
}
sn.soundalive = true;
sn.splitbuffer = false;
sn.samples = gSndBufSize/(sn.samplebits/8);
sn.samplepos = 0;
sn.submission_chunk = 1;
sn.buffer = (unsigned char *) lpData;
sample16 = (sn.samplebits/8) - 1;
wav_init = true;
return true;
}
/*
SNDDMA_Init
Try to find a sound device to mix for.
Returns false if nothing is found.
*/
static volatile dma_t *
SNDDMA_Init ( void )
{
wav_init = 0;
if (snd_firsttime || snd_iswave) {
snd_iswave = SNDDMA_InitWav ();
if (snd_iswave) {
if (snd_firsttime)
Sys_Printf ("Wave sound initialized\n");
} else {
Sys_Printf ("Wave sound failed to init\n");
}
}
snd_firsttime = false;
if (!wav_init) {
if (snd_firsttime)
Sys_Printf ("No sound device initialized\n");
return 0;
}
return &sn;
}
/*
SNDDMA_GetDMAPos
return the current sample position (in mono samples read)
inside the recirculating dma buffer, so the mixing code will know
how many sample are required to fill it up.
*/
static int
SNDDMA_GetDMAPos ( void )
{
int s = 0;
if (wav_init) {
s = snd_sent * WAV_BUFFER_SIZE;
}
s >>= sample16;
s &= (sn.samples-1);
return s;
}
/*
SNDDMA_Submit
Send sound to device if buffer isn't really the dma buffer
*/
static void
SNDDMA_Submit ( void )
{
int wResult;
LPWAVEHDR h;
if (!wav_init) return;
if (mmeCheckForCallbacks()) mmeProcessCallbacks();
if (snd_completed == snd_sent) {
Sys_DPrintf ("Sound overrun\n");
}
// submit two new sound blocks
while (((snd_sent - snd_completed) >> sample16) < 4)
{
int i = (snd_sent&WAV_MASK);
h = lpWaveHdr + i;
h->dwBufferLength = WAV_BUFFER_SIZE;
h->lpData = lpData + i*WAV_BUFFER_SIZE;
snd_sent++;
/*
Now the data block can be sent to the output device. The
waveOutWrite function returns immediately and waveform
data is sent to the output device in the background.
*/
wResult = waveOutWrite(hWaveOut, h, sizeof(WAVEHDR));
if (wResult != MMSYSERR_NOERROR)
{
Sys_Printf ("Failed to write block to device\n");
FreeSound ();
return;
}
}
}
/*
SNDDMA_Shutdown
Reset the sound device for exiting
*/
static void
SNDDMA_Shutdown ( void )
{
FreeSound ();
}

View file

@ -3,14 +3,14 @@ AUTOMAKE_OPTIONS= foreign
AM_CFLAGS= @PREFER_PIC@
INCLUDES= -I$(top_srcdir)/include
plugin_version= 1:0:0
plugin_ldflags= @plugin_ldflags@
plugin_ldflags= @plugin_ldflags@ -module
plugin_libadd= @plugin_libadd@
EXEEXT=
lib_LTLIBRARIES= libQFconsole.la
plugin_PROGRAMS= @SERVER_PLUGIN_TARGETS@ @CLIENT_PLUGIN_TARGETS@
noinst_PROGRAMS= @SERVER_PLUGIN_STATIC@ @CLIENT_PLUGIN_STATIC@
EXTRA_PROGRAMS= console_server.la console_client.la
plugin_LTLIBRARIES= @SERVER_PLUGIN_TARGETS@ @CLIENT_PLUGIN_TARGETS@
noinst_LTLIBRARIES= @SERVER_PLUGIN_STATIC@ @CLIENT_PLUGIN_STATIC@
EXTRA_LTLIBRARIES= console_server.la console_client.la
common_sources= \
buffer.c complete.c console.c inputline.c list.c filelist.c view.c
@ -22,9 +22,9 @@ libQFconsole_la_LIBADD= $(plugin_libadd) $(top_builddir)/libs/util/libQFutil.la
libQFconsole_la_SOURCES= $(common_sources)
console_client_la_LDFLAGS= $(plugin_ldflags)
console_client_la_LDADD= $(plugin_libadd)
console_client_la_LIBADD= $(plugin_libadd)
console_client_la_SOURCES= $(client_sources)
console_server_la_LDFLAGS= $(plugin_ldflags)
console_server_la_LDADD= $(CURSES_LIBS) $(plugin_libadd)
console_server_la_LIBADD= $(CURSES_LIBS) $(plugin_libadd)
console_server_la_SOURCES= $(server_sources)

View file

@ -91,17 +91,21 @@ static int
menu_resolve_globals (progs_t *pr)
{
const char *sym;
ddef_t *def;
dfunction_t *f;
if (!(f = ED_FindFunction (pr, sym = "menu_init")))
if (!(f = PR_FindFunction (pr, sym = "menu_init")))
goto error;
menu_init = (func_t)(f - menu_pr_state.pr_functions);
if (!(f = ED_FindFunction (pr, sym = "menu_draw_hud")))
if (!(f = PR_FindFunction (pr, sym = "menu_draw_hud")))
goto error;
menu_draw_hud = (func_t)(f - pr->pr_functions);
if (!(def = PR_FindGlobal (pr, sym = "time")))
goto error;
menu_pr_state.globals.time = &G_FLOAT (pr, def->ofs);
return 1;
error:
Con_Printf ("%s: undefined function %s\n", pr->progs_name, sym);
Con_Printf ("%s: undefined symbol %s\n", pr->progs_name, sym);
return 0;
}
@ -444,6 +448,7 @@ Menu_Init (void)
menu_pr_state.allocate_progs_mem = menu_allocate_progs_mem;
menu_pr_state.free_progs_mem = menu_free_progs_mem;
menu_pr_state.load_file = menu_load_file;
menu_pr_state.resolve = menu_resolve_globals;
menu_hash = Hash_NewTable (61, menu_get_key, menu_free, 0);
@ -457,15 +462,12 @@ Menu_Init (void)
PR_Cmds_Init (&menu_pr_state);
R_Progs_Init (&menu_pr_state);
PR_AddLoadFunc (&menu_pr_state, menu_resolve_globals);
confirm_quit = Cvar_Get ("confirm_quit", "1", CVAR_ARCHIVE, NULL,
"confirm quit command");
Cmd_AddCommand ("togglemenu", togglemenu_f,
"Toggle the display of the menu");
Cmd_AddCommand ("quit", quit_f, "Exit the program");
}
void
@ -474,8 +476,6 @@ Menu_Load (void)
int size;
QFile *file;
menu_pr_state.time = con_data.realtime;
Hash_FlushTable (menu_hash);
menu = 0;
top_menu = 0;
@ -519,7 +519,7 @@ Menu_Draw (view_t *view)
if (menu->fadescreen)
Draw_FadeScreen ();
*menu_pr_state.globals.time = *menu_pr_state.time;
*menu_pr_state.globals.time = *con_data.realtime;
if (menu->draw) {
P_INT (&menu_pr_state, 0) = x;
@ -563,7 +563,7 @@ Menu_Draw (view_t *view)
void
Menu_Draw_Hud (view_t *view)
{
*menu_pr_state.globals.time = *menu_pr_state.time;
*menu_pr_state.globals.time = *con_data.realtime;
PR_ExecuteProgram (&menu_pr_state, menu_draw_hud);
}

View file

@ -92,7 +92,7 @@ bi_gib_builtin_f (void)
pr_list[i].integer_var = PR_SetTempString (builtin->pr, GIB_Argv(i));
P_INT (builtin->pr, 0) = GIB_Argc();
P_INT (builtin->pr, 1) = POINTER_TO_PROG (builtin->pr, pr_list);
P_INT (builtin->pr, 1) = PR_SetPointer (builtin->pr, pr_list);
PR_ExecuteProgram (builtin->pr, builtin->func);
PR_PopFrame (builtin->pr);
PR_Zone_Free (builtin->pr, pr_list);

View file

@ -60,10 +60,12 @@ get_inputline (progs_t *pr, int arg, const char *func)
{
pr_type_t *handle;
inputline_t *line;
int min = (pr_type_t *) pr->zone - pr->pr_globals;
int max = min + pr->zone_size / sizeof (pr_type_t);
if (arg <= ((pr_type_t *) pr->zone - pr->pr_globals)
|| (size_t) arg >= (pr->zone_size / sizeof (pr_type_t)))
PR_RunError (pr, "%s: Invalid inputline_t", func);
if (arg <= min || arg >= max)
PR_RunError (pr, "%s: Invalid inputline_t: $%x $%x $%x", func, arg,
min, max);
handle = pr->pr_globals + arg;

View file

@ -52,7 +52,6 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "compat.h"
//FIXME lines to #undef U really shouldn't be here
#include "QF/csqc.h"
#define U __attribute__ ((unused))
static U void (*const gib_progs_init)(progs_t *) = GIB_Progs_Init;
@ -266,7 +265,7 @@ PF_Find (progs_t *pr)
e = P_EDICTNUM (pr, 0);
f = P_INT (pr, 1);
field_def = ED_FieldAtOfs (pr, f);
field_def = PR_FieldAtOfs (pr, f);
if (!field_def)
PR_RunError (pr, "PF_Find: bad search field: %d", f);
type = field_def->type & ~DEF_SAVEGLOBAL;
@ -331,6 +330,7 @@ static void
PF_traceon (progs_t *pr)
{
pr->pr_trace = true;
pr->pr_trace_depth = pr->pr_depth;
}
/*
@ -583,9 +583,9 @@ PF_sprintf (progs_t *pr)
dstring_t *dstr;
int str;
str = PR_NewString (pr);
dstr = PR_GetDString (pr, str);
PR_Sprintf (pr, dstr, "bi_printf", fmt, count, args);
str = PR_NewMutableString (pr);
dstr = PR_GetMutableString (pr, str);
PR_Sprintf (pr, dstr, "PF_sprintf", fmt, count, args);
PR_MakeTempString (pr, str);
R_STRING (pr) = str;
}
@ -599,42 +599,66 @@ PR_gametype (progs_t *pr)
RETURN_STRING (pr, pr_gametype);
}
static void
PF_PR_SetField (progs_t *pr)
{
edict_t *ent = P_EDICT (pr, 0);
ddef_t *field = PR_FindField (pr, P_GSTRING (pr, 1));
const char *value = P_GSTRING (pr, 2);
R_INT (pr) = 0;
if (field)
R_INT (pr) = ED_ParseEpair (pr, ent->v, field, value);
}
static void
PF_PR_FindFunction (progs_t *pr)
{
dfunction_t *func = PR_FindFunction (pr, P_GSTRING (pr, 0));
R_FUNCTION (pr) = 0;
if (func)
R_FUNCTION (pr) = func - pr->pr_functions;
}
#define QF (PR_RANGE_QF << PR_RANGE_SHIFT) |
static builtin_t builtins[] = {
{"break", PF_break, 6},
{"random", PF_random, 7},
{"normalize", PF_normalize, 9},
{"vlen", PF_vlen, 12},
{"vectoyaw", PF_vectoyaw, 13},
{"find", PF_Find, 18},
{"dprint", PF_dprint, 25},
{"ftos", PF_ftos, 26},
{"vtos", PF_vtos, 27},
{"coredump", PF_coredump, 28},
{"traceon", PF_traceon, 29},
{"traceoff", PF_traceoff, 30},
{"eprint", PF_eprint, 31},
{"rint", PF_rint, 36},
{"floor", PF_floor, 37},
{"ceil", PF_ceil, 38},
{"fabs", PF_fabs, 43},
{"cvar", PF_cvar, 45},
{"nextent", PF_nextent, 47},
{"vectoangles", PF_vectoangles, 51},
{"cvar_set", PF_cvar_set, 72},
{"stof", PF_stof, 81},
{"break", PF_break, 6},
{"random", PF_random, 7},
{"normalize", PF_normalize, 9},
{"vlen", PF_vlen, 12},
{"vectoyaw", PF_vectoyaw, 13},
{"find", PF_Find, 18},
{"dprint", PF_dprint, 25},
{"ftos", PF_ftos, 26},
{"vtos", PF_vtos, 27},
{"coredump", PF_coredump, 28},
{"traceon", PF_traceon, 29},
{"traceoff", PF_traceoff, 30},
{"eprint", PF_eprint, 31},
{"rint", PF_rint, 36},
{"floor", PF_floor, 37},
{"ceil", PF_ceil, 38},
{"fabs", PF_fabs, 43},
{"cvar", PF_cvar, 45},
{"nextent", PF_nextent, 47},
{"vectoangles", PF_vectoangles, 51},
{"cvar_set", PF_cvar_set, 72},
{"stof", PF_stof, 81},
{"strlen", PF_strlen, QF 100},
{"charcount", PF_charcount, QF 101},
{"sprintf", PF_sprintf, QF 109},
{"ftoi", PF_ftoi, QF 110},
{"itof", PF_itof, QF 111},
{"itos", PF_itos, QF 112},
{"stoi", PF_stoi, QF 113},
{"stov", PF_stov, QF 114},
{"gametype", PR_gametype, QF 115},
{"strlen", PF_strlen, QF 100},
{"charcount", PF_charcount, QF 101},
{"sprintf", PF_sprintf, QF 109},
{"ftoi", PF_ftoi, QF 110},
{"itof", PF_itof, QF 111},
{"itos", PF_itos, QF 112},
{"stoi", PF_stoi, QF 113},
{"stov", PF_stov, QF 114},
{"gametype", PR_gametype, QF 115},
{"PR_SetField", PF_PR_SetField, -1},
{"PR_FindFunction", PF_PR_FindFunction, -1},
{0}
};

View file

@ -146,11 +146,8 @@ PR_Load_Source_File (progs_t *pr, const char *fname)
if (!f)
return 0;
for (dir = source_paths; *dir && !f->text; dir++) {
int len;
len = strlen (*dir) + strlen (fname) + 2;
path = Hunk_TempAlloc (len);
sprintf (path, "%s%s%s", *dir, **dir ? "/" : "", fname);
f->text = pr->load_file (pr, path);
f->text = pr->load_file (pr, va ("%s%s%s", *dir, **dir ? "/" : "",
fname));
}
if (!f->text) {
pr->file_error (pr, path);
@ -192,7 +189,6 @@ PR_LoadDebug (progs_t *pr)
char *sym_path;
const char *path_end, *sym_file;
unsigned int i;
int start = Hunk_LowMark ();
ddef_t *def;
pr_type_t *str = 0;
@ -219,13 +215,13 @@ PR_LoadDebug (progs_t *pr)
pr->debugfile = PR_GetString (pr, str->string_var);
sym_file = QFS_SkipPath (pr->debugfile);
path_end = QFS_SkipPath (pr->progs_name);
sym_path = Hunk_TempAlloc (strlen (sym_file) + (path_end - pr->progs_name)
+ 1);
sym_path = malloc (strlen (sym_file) + (path_end - pr->progs_name) + 1);
strncpy (sym_path, pr->progs_name, path_end - pr->progs_name);
strcpy (sym_path + (path_end - pr->progs_name), sym_file);
pr->debug = pr->load_file (pr, sym_path);
if (!pr->debug) {
Sys_Printf ("can't load %s for debug info\n", sym_path);
free (sym_path);
return 1;
}
pr->debug->version = LittleLong (pr->debug->version);
@ -235,8 +231,8 @@ PR_LoadDebug (progs_t *pr)
(pr->debug->version >> 24) & 0xff,
(pr->debug->version >> 12) & 0xfff,
pr->debug->version & 0xfff);
Hunk_FreeToLowMark (start);
pr->debug = 0;
free (sym_path);
return 1;
}
pr->debug->crc = LittleShort (pr->debug->crc);
@ -247,10 +243,11 @@ PR_LoadDebug (progs_t *pr)
pr->progs_name,
pr->debug->crc,
pr->crc);
Hunk_FreeToLowMark (start);
pr->debug = 0;
free (sym_path);
return 1;
}
free (sym_path);
pr->debug->you_tell_me_and_we_will_both_know = LittleShort
(pr->debug->you_tell_me_and_we_will_both_know);
pr->debug->auxfunctions = LittleLong (pr->debug->auxfunctions);
@ -355,7 +352,6 @@ PR_Get_Source_File (progs_t *pr, pr_lineno_t *lineno)
const char *
PR_Get_Source_Line (progs_t *pr, unsigned int addr)
{
char *str;
const char *fname;
unsigned int line;
file_t *file;
@ -374,16 +370,11 @@ PR_Get_Source_Line (progs_t *pr, unsigned int addr)
file = PR_Load_Source_File (pr, fname);
str = Hunk_TempAlloc (strlen (fname) + 12);
sprintf (str, "%s:%d", fname, line);
if (!file || line > file->num_lines)
return str;
return va ("%s:%d", fname, line);
str = Hunk_TempAlloc (strlen (str) + file->lines[line - 1].len + 2);
sprintf (str, "%s:%d:%.*s", fname, line,
(int)file->lines[line - 1].len, file->lines[line - 1].text);
return str;
return va ("%s:%d:%.*s", fname, line, (int)file->lines[line - 1].len,
file->lines[line - 1].text);
}
ddef_t *
@ -495,7 +486,7 @@ value_string (progs_t *pr, etype_t type, pr_type_t *val)
}
break;
case ev_field:
def = ED_FieldAtOfs (pr, val->integer_var);
def = PR_FieldAtOfs (pr, val->integer_var);
if (def)
dsprintf (line, ".%s", PR_GetString (pr, def->s_name));
else
@ -517,7 +508,7 @@ value_string (progs_t *pr, etype_t type, pr_type_t *val)
if (pr_debug->int_val && pr->debug)
def = PR_Get_Local_Def (pr, ofs);
if (!def)
def = ED_GlobalAtOfs (pr, ofs);
def = PR_GlobalAtOfs (pr, ofs);
if (def && def->s_name)
dsprintf (line, "&%s", PR_GetString (pr, def->s_name));
else
@ -554,7 +545,7 @@ def_string (progs_t *pr, int ofs, dstring_t *dstr)
if (pr_debug->int_val && pr->debug)
def = PR_Get_Local_Def (pr, ofs);
if (!def)
def = ED_GlobalAtOfs (pr, ofs);
def = PR_GlobalAtOfs (pr, ofs);
if (!def || !*(name = PR_GetString (pr, def->s_name)))
dsprintf (dstr, "[$%x]", ofs);
else
@ -845,6 +836,8 @@ ED_Print (progs_t *pr, edict_t *ed)
if (!v[0].float_var && !v[1].float_var && !v[2].float_var)
continue;
break;
case ev_void:
break;
default:
PR_Error (pr, "ED_Print: Unhandled type %d", type);
}

View file

@ -90,11 +90,13 @@ ED_Alloc (progs_t *pr)
int start = pr->reserved_edicts ? *pr->reserved_edicts : 0;
int max_edicts = pr->pr_edictareasize / pr->pr_edict_size;
for (i = start + 1; i < *(pr)->num_edicts; i++) {
for (i = start + 1; i < *pr->num_edicts; i++) {
e = EDICT_NUM (pr, i);
// the first couple seconds of server time can involve a lot of
// freeing and allocating, so relax the replacement policy
if (e->free && (e->freetime < 2 || *(pr)->time - e->freetime > 0.5)) {
if (e->free && (!pr->globals.time
|| e->freetime < 2
|| *pr->globals.time - e->freetime > 0.5)) {
ED_ClearEdict (pr, e, 0);
return e;
}
@ -135,7 +137,8 @@ ED_Free (progs_t *pr, edict_t *ed)
ED_ClearEdict (pr, ed, 0);
}
ed->free = true;
ed->freetime = *(pr)->time;
if (pr->globals.time)
ed->freetime = *pr->globals.time;
}
//===========================================================================
@ -160,7 +163,7 @@ ED_PrintEdicts (progs_t *pr, const char *fieldval)
int count;
ddef_t *def;
def = ED_FindField(pr, "classname");
def = PR_FindField(pr, "classname");
if (fieldval && fieldval[0] && def) {
count = 0;
@ -192,13 +195,13 @@ ED_Count (progs_t *pr)
ddef_t *model_def;
edict_t *ent;
solid_def = ED_FindField (pr, "solid");
model_def = ED_FindField (pr, "model");
solid_def = PR_FindField (pr, "solid");
model_def = PR_FindField (pr, "model");
active = models = solid = step = zombie = 0;
for (i = 0; i < *(pr)->num_edicts; i++) {
ent = EDICT_NUM (pr, i);
if (ent->free) {
if (*(pr)->time - ent->freetime <= 0.5)
if (pr->globals.time && *pr->globals.time - ent->freetime <= 0.5)
zombie++;
continue;
}
@ -217,7 +220,7 @@ ED_Count (progs_t *pr)
}
edict_t *
EDICT_NUM (progs_t *pr, int n)
ED_EdictNum (progs_t *pr, int n)
{
int offs = n * pr->pr_edict_size;
if (offs < 0 || n >= pr->pr_edictareasize)
@ -227,20 +230,7 @@ EDICT_NUM (progs_t *pr, int n)
}
int
NUM_FOR_BAD_EDICT (progs_t *pr, edict_t *e)
{
int b;
b = (byte *) e - (byte *) * (pr)->edicts;
if (pr->pr_edict_size)
b /= pr->pr_edict_size;
return b;
}
int
NUM_FOR_EDICT (progs_t *pr, edict_t *e)
ED_NumForEdict (progs_t *pr, edict_t *e)
{
int b;

View file

@ -112,12 +112,15 @@ PR_PopFrame (progs_t *pr)
pr->pr_xtstr = frame->tstr;
}
/*
PR_EnterFunction
Returns the new program statement counter
/** Setup the stackframe prior to calling a progs function. Saves all local
data the called function will trample on and copies the parameters used
by the function into the function's local data space.
\param pr pointer to progs_t VM struct
\param f pointer to the descriptor for the called function
\note Passing a descriptor for a builtin function will result in
undefined behavior.
*/
void
static void
PR_EnterFunction (progs_t *pr, dfunction_t *f)
{
int i, j, c, o;
@ -242,6 +245,24 @@ signal_hook (int sig, void *data)
return 0;
}
int
PR_CallFunction (progs_t *pr, func_t fnum)
{
dfunction_t *f;
if (!fnum)
PR_RunError (pr, "NULL function");
f = pr->pr_functions + fnum;
if (f->first_statement < 0) {
// negative statements are built in functions
((bfunction_t *) f)->func (pr);
return 0;
} else {
PR_EnterFunction (pr, f);
return 1;
}
}
/*
PR_ExecuteProgram
@ -252,31 +273,23 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
{
int exitdepth, profile, startprofile;
unsigned int pointer;
dfunction_t *f;
dstatement_t *st;
edict_t *ed;
pr_type_t *ptr;
if (!fnum || fnum >= pr->progs->numfunctions) {
if (*pr->globals.self)
ED_Print (pr, PROG_TO_EDICT (pr, *pr->globals.self));
PR_RunError (pr, "PR_ExecuteProgram: NULL function");
}
f = &pr->pr_functions[fnum];
//Sys_Printf("%s:\n", PR_GetString(pr,f->s_name));
pr->pr_trace = false;
// make a stack frame
exitdepth = pr->pr_depth;
PR_EnterFunction (pr, f);
st = pr->pr_statements + pr->pr_xstatement;
startprofile = profile = 0;
Sys_PushSignalHook (signal_hook, pr);
if (!PR_CallFunction (pr, fnum)) {
// called a builtin instead of progs code
Sys_PopSignalHook ();
return;
}
st = pr->pr_statements + pr->pr_xstatement;
while (1) {
pr_type_t *op_a, *op_b, *op_c;
@ -306,16 +319,11 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
QuatAdd (OPA.quat_var, OPB.quat_var, OPC.quat_var);
break;
case OP_ADD_S:
{
const char *a = PR_GetString (pr, OPA.string_var);
const char *b = PR_GetString (pr, OPB.string_var);
int lena = strlen (a);
int size = lena + strlen (b) + 1;
char *c = Hunk_TempAlloc (size);
strcpy (c, a);
strcpy (c + lena, b);
OPC.string_var = PR_SetTempString (pr, c);
}
OPC.string_var = PR_CatStrings (pr,
PR_GetString (pr,
OPA.string_var),
PR_GetString (pr,
OPB.string_var));
break;
case OP_SUB_F:
OPC.float_var = OPA.float_var - OPB.float_var;
@ -776,15 +784,7 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
pr->pr_xfunction->profile += profile - startprofile;
startprofile = profile;
pr->pr_argc = st->op - OP_CALL0;
if (!OPA.func_var)
PR_RunError (pr, "NULL function");
f = &pr->pr_functions[OPA.func_var];
// negative statements are built in functions
if (f->first_statement < 0) {
((bfunction_t *) f)->func (pr);
} else {
PR_EnterFunction (pr, f);
}
PR_CallFunction (pr, OPA.func_var);
st = pr->pr_statements + pr->pr_xstatement;
break;
case OP_DONE:
@ -800,6 +800,8 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
PR_LeaveFunction (pr);
st = pr->pr_statements + pr->pr_xstatement;
if (pr->pr_depth == exitdepth) {
if (pr->pr_trace && pr->pr_depth <= pr->pr_trace_depth)
pr->pr_trace = false;
Sys_PopSignalHook ();
return; // all done
}

View file

@ -45,12 +45,12 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "QF/cvar.h"
#include "QF/dstring.h"
#include "QF/hash.h"
#include "QF/idparse.h"
#include "QF/progs.h"
#include "QF/qdefs.h"
#include "QF/qfplist.h"
#include "QF/qendian.h"
#include "QF/quakefs.h"
#include "QF/script.h"
#include "QF/sys.h"
#include "QF/zone.h"
#include "QF/va.h"
@ -86,7 +86,7 @@ PR_UglyValueString (progs_t *pr, etype_t type, pr_type_t *val)
snprintf (line, sizeof (line), "%s", PR_GetString (pr, f->s_name));
break;
case ev_field:
def = ED_FieldAtOfs (pr, val->integer_var);
def = PR_FieldAtOfs (pr, val->integer_var);
snprintf (line, sizeof (line), "%s",
PR_GetString (pr, def->s_name));
break;
@ -194,7 +194,7 @@ ED_NewString (progs_t *pr, const char *string)
int i, l;
l = strlen (string) + 1;
new = Hunk_TempAlloc (l);
new = alloca (l);
new_p = new;
for (i = 0; i < l; i++) {
@ -218,7 +218,7 @@ ED_NewString (progs_t *pr, const char *string)
Can parse either fields or globals
returns false if error
*/
static qboolean
qboolean
ED_ParseEpair (progs_t *pr, pr_type_t *base, ddef_t *key, const char *s)
{
int i;
@ -258,7 +258,7 @@ ED_ParseEpair (progs_t *pr, pr_type_t *base, ddef_t *key, const char *s)
break;
case ev_field:
def = ED_FindField (pr, s);
def = PR_FindField (pr, s);
if (!def) {
Sys_Printf ("Can't find field %s\n", s);
return false;
@ -267,7 +267,7 @@ ED_ParseEpair (progs_t *pr, pr_type_t *base, ddef_t *key, const char *s)
break;
case ev_func:
func = ED_FindFunction (pr, s);
func = PR_FindFunction (pr, s);
if (!func) {
Sys_Printf ("Can't find function %s\n", s);
return false;
@ -288,8 +288,8 @@ ED_ParseEpair (progs_t *pr, pr_type_t *base, ddef_t *key, const char *s)
ent should be a properly initialized empty edict.
Used for initial level load and for savegames.
*/
const char *
ED_ParseEdict (progs_t *pr, const char *data, edict_t *ent)
void
ED_ParseEdict (progs_t *pr, script_t *script, edict_t *ent)
{
ddef_t *key;
qboolean anglehack;
@ -302,17 +302,17 @@ ED_ParseEdict (progs_t *pr, const char *data, edict_t *ent)
if (ent != *(pr)->edicts) // hack
memset (&ent->v, 0, pr->progs->entityfields * 4);
while (1) { // go through all the dictionary pairs
// parse key
data = COM_Parse (data);
if (com_token[0] == '}')
break;
if (!data)
// go through all the dictionary pairs
while (1) {
if (!Script_GetToken (script, 1))
PR_Error (pr, "ED_ParseEntity: EOF without closing brace");
// parse key
if (script->token->str[0] == '}')
break;
token = com_token;
token = script->token->str;
// anglehack is to allow QuakeEd to write single scalar angles
// and allow them to be turned into vectors. (FIXME...)
// and allow them to be turned into vectors.
if (!strcmp (token, "angle")) {
token = "angles";
anglehack = true;
@ -332,11 +332,12 @@ ED_ParseEdict (progs_t *pr, const char *data, edict_t *ent)
}
// parse value
data = COM_Parse (data);
if (!data)
//FIXME shouldn't cross line
if (!Script_GetToken (script, 1))
PR_Error (pr, "ED_ParseEntity: EOF without closing brace");
token = script->token->str;
if (com_token[0] == '}')
if (token[0] == '}')
PR_Error (pr, "ED_ParseEntity: closing brace without data");
init = true;
@ -346,10 +347,10 @@ ED_ParseEdict (progs_t *pr, const char *data, edict_t *ent)
if (keyname->str[0] == '_')
continue;
key = ED_FindField (pr, keyname->str);
key = PR_FindField (pr, keyname->str);
if (!key) {
if (!pr->parse_field
|| !pr->parse_field (pr, keyname->str, com_token)) {
|| !pr->parse_field (pr, keyname->str, token)) {
Sys_Printf ("'%s' is not a field\n", keyname->str);
continue;
}
@ -357,9 +358,9 @@ ED_ParseEdict (progs_t *pr, const char *data, edict_t *ent)
int ret;
if (anglehack) {
ret = ED_ParseEpair (pr, ent->v, key, va ("0 %s 0", com_token));
ret = ED_ParseEpair (pr, ent->v, key, va ("0 %s 0", token));
} else {
ret = ED_ParseEpair (pr, ent->v, key, com_token);
ret = ED_ParseEpair (pr, ent->v, key, token);
}
if (!ret)
PR_Error (pr, "ED_ParseEdict: parse error");
@ -370,31 +371,32 @@ ED_ParseEdict (progs_t *pr, const char *data, edict_t *ent)
ent->free = true;
dstring_delete (keyname);
return data;
}
void
ED_ParseGlobals (progs_t *pr, const char *data)
ED_ParseGlobals (progs_t *pr, script_t *script)
{
dstring_t *keyname = dstring_new ();
ddef_t *key;
dstring_t *keyname = dstring_new ();
ddef_t *key;
const char *token;
while (1) {
// parse key
data = COM_Parse (data);
if (com_token[0] == '}')
break;
if (!data)
if (!Script_GetToken (script, 1))
PR_Error (pr, "ED_ParseEntity: EOF without closing brace");
token = script->token->str;
if (token[0] == '}')
break;
dstring_copystr (keyname, com_token);
dstring_copystr (keyname, script->token->str);
// parse value
data = COM_Parse (data);
if (!data)
//FIXME shouldn't cross line
if (!Script_GetToken (script, 1))
PR_Error (pr, "ED_ParseEntity: EOF without closing brace");
token = script->token->str;
if (com_token[0] == '}')
if (token[0] == '}')
PR_Error (pr, "ED_ParseEntity: closing brace without data");
key = PR_FindGlobal (pr, keyname->str);
@ -403,7 +405,7 @@ ED_ParseGlobals (progs_t *pr, const char *data)
continue;
}
if (!ED_ParseEpair (pr, pr->pr_globals, key, com_token))
if (!ED_ParseEpair (pr, pr->pr_globals, key, token))
PR_Error (pr, "ED_ParseGlobals: parse error");
}
dstring_delete (keyname);
@ -423,7 +425,7 @@ ED_ParseGlobals (progs_t *pr, const char *data)
to call ED_CallSpawnFunctions () to let the objects initialize themselves.
*/
static void
ED_ParseOld (progs_t *pr, const char *data)
ED_ParseOld (progs_t *pr, script_t *script)
{
edict_t *ent = NULL;
int inhibit = 0;
@ -431,21 +433,17 @@ ED_ParseOld (progs_t *pr, const char *data)
pr_type_t *classname;
ddef_t *def;
*pr->globals.time = *(pr)->time;
while (1) { // parse ents
while (Script_GetToken (script, 1)) { // parse ents
// parse the opening brace
data = COM_Parse (data);
if (!data)
break;
if (com_token[0] != '{')
PR_Error (pr, "ED_LoadFromFile: found %s when expecting {", com_token);
if (script->token->str[0] != '{')
PR_Error (pr, "ED_LoadFromFile: found %s when expecting {",
script->token->str);
if (!ent)
ent = EDICT_NUM (pr, 0);
else
ent = ED_Alloc (pr);
data = ED_ParseEdict (pr, data, ent);
ED_ParseEdict (pr, script, ent);
// remove things from different skill levels or deathmatch
if (pr->prune_edict && pr->prune_edict (pr, ent)) {
@ -454,10 +452,8 @@ ED_ParseOld (progs_t *pr, const char *data)
continue;
}
//
// immediately call spawn function
//
def = ED_FindField (pr, "classname");
def = PR_FindField (pr, "classname");
if (!def) {
Sys_Printf ("No classname for:\n");
ED_Print (pr, ent);
@ -467,7 +463,7 @@ ED_ParseOld (progs_t *pr, const char *data)
classname = &ent->v[def->ofs];
// look for the spawn function
func = ED_FindFunction (pr, PR_GetString (pr, classname->string_var));
func = PR_FindFunction (pr, PR_GetString (pr, classname->string_var));
if (!func) {
Sys_Printf ("No spawn function for:\n");
ED_Print (pr, ent);
@ -487,12 +483,35 @@ ED_ParseOld (progs_t *pr, const char *data)
void
ED_LoadFromFile (progs_t *pr, const char *data)
{
if (*data == '(') {
// new style (plist) entity data
plitem_t *plist = PL_GetPropertyList (data);
plist = plist;
} else {
// oldstyle entity data
ED_ParseOld (pr, data);
script_t *script;
if (pr->edict_parse) {
PR_PushFrame (pr);
P_INT (pr, 0) = PR_SetTempString (pr, data);
PR_ExecuteProgram (pr, pr->edict_parse);
PR_PopFrame (pr);
return;
}
script = Script_New ();
Script_Start (script, "ent data", data);
if (Script_GetToken (script, 1)) {
if (*script->token->str == '(') {
// new style (plist) entity data
plitem_t *plist = PL_GetPropertyList (data);
plist = plist;
} else {
// oldstyle entity data
Script_UngetToken (script);
ED_ParseOld (pr, script);
}
}
Script_Delete (script);
}
void
ED_EntityParseFunction (progs_t *pr)
{
pr->edict_parse = P_FUNCTION (pr, 0);
}

View file

@ -55,11 +55,8 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "compat.h"
/*
ED_GlobalAtOfs
*/
ddef_t *
ED_GlobalAtOfs (progs_t * pr, int ofs)
ddef_t *
PR_GlobalAtOfs (progs_t * pr, int ofs)
{
ddef_t *def;
unsigned int i;
@ -72,11 +69,8 @@ ED_GlobalAtOfs (progs_t * pr, int ofs)
return NULL;
}
/*
ED_FieldAtOfs
*/
ddef_t *
ED_FieldAtOfs (progs_t * pr, int ofs)
ddef_t *
PR_FieldAtOfs (progs_t * pr, int ofs)
{
ddef_t *def;
unsigned int i;
@ -89,76 +83,30 @@ ED_FieldAtOfs (progs_t * pr, int ofs)
return NULL;
}
/*
ED_FindField
*/
ddef_t *
ED_FindField (progs_t * pr, const char *name)
ddef_t *
PR_FindField (progs_t * pr, const char *name)
{
return Hash_Find (pr->field_hash, name);
}
int
ED_GetFieldIndex (progs_t *pr, const char *name)
{
ddef_t *def;
def = ED_FindField (pr, name);
if (def)
return def->ofs;
return -1;
}
/*
PR_FindGlobal
*/
ddef_t *
ddef_t *
PR_FindGlobal (progs_t * pr, const char *name)
{
return Hash_Find (pr->global_hash, name);
}
pr_type_t *
PR_GetGlobalPointer (progs_t *pr, const char *name)
{
ddef_t *def;
def = PR_FindGlobal (pr, name);
if (def)
return &pr->pr_globals[def->ofs];
PR_Error (pr, "undefined global %s", name);
return 0;
}
func_t
PR_GetFunctionIndex (progs_t *pr, const char *name)
{
dfunction_t *func = ED_FindFunction (pr, name);
if (func)
return func - pr->pr_functions;
PR_Error (pr, "undefined function %s", name);
return -1;
}
int
PR_GetFieldOffset (progs_t *pr, const char *name)
{
ddef_t *def = ED_FindField (pr, name);
if (def)
return def->ofs;
PR_Error (pr, "undefined field %s", name);
return -1;
}
/*
ED_FindFunction
*/
dfunction_t *
ED_FindFunction (progs_t * pr, const char *name)
PR_FindFunction (progs_t * pr, const char *name)
{
return Hash_Find (pr->function_hash, name);
}
void
PR_Undefined (progs_t *pr, const char *type, const char *name)
{
PR_Error (pr, "undefined %s %s", type, name);
}
int
PR_ResolveGlobals (progs_t *pr)
{
@ -200,11 +148,14 @@ PR_ResolveGlobals (progs_t *pr)
pr->globals.self = &G_INT (pr, def->ofs);
}
if (pr->fields.nextthink == -1)
pr->fields.nextthink = ED_GetFieldIndex (pr, sym = "nextthink");
if ((def = PR_FindField (pr, "nextthink")))
pr->fields.nextthink = def->ofs;
if (pr->fields.frame == -1)
pr->fields.frame = ED_GetFieldIndex (pr, sym = "frame");
if ((def = PR_FindField (pr, "frame")))
pr->fields.frame = def->ofs;
if (pr->fields.think == -1)
pr->fields.think = ED_GetFieldIndex (pr, sym = "think");
if ((def = PR_FindField (pr, "think")))
pr->fields.think = def->ofs;
return 1;
error:
Sys_Printf ("%s: undefined symbol: %s\n", pr->progs_name, sym);
@ -215,7 +166,7 @@ int
PR_AccessField (progs_t *pr, const char *name, etype_t type,
const char *file, int line)
{
ddef_t *def = ED_FindField (pr, name);
ddef_t *def = PR_FindField (pr, name);
if (!def)
PR_Error (pr, "undefined field %s accessed at %s:%d", name, file, line);

View file

@ -46,11 +46,22 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "QF/hash.h"
#include "QF/progs.h"
typedef enum {
str_static,
str_dynamic,
str_mutable,
str_temp,
str_return,
} str_e;
struct strref_s {
strref_t *next;
char *string;
dstring_t *dstring;
int count;
strref_t **prev;
str_e type;
union {
char *string;
dstring_t *dstring;
} s;
};
// format adjustments
@ -107,12 +118,12 @@ new_string_ref (progs_t *pr)
pr->dyn_str_size++;
size = pr->dyn_str_size * sizeof (strref_t *);
pr->dynamic_strings = realloc (pr->dynamic_strings, size);
if (!pr->dynamic_strings)
pr->string_map = realloc (pr->string_map, size);
if (!pr->string_map)
PR_Error (pr, "out of memory");
if (!(pr->free_string_refs = calloc (1024, sizeof (strref_t))))
PR_Error (pr, "out of memory");
pr->dynamic_strings[pr->dyn_str_size - 1] = pr->free_string_refs;
pr->string_map[pr->dyn_str_size - 1] = pr->free_string_refs;
for (i = 0, sr = pr->free_string_refs; i < 1023; i++, sr++)
sr->next = sr + 1;
sr->next = 0;
@ -126,8 +137,8 @@ new_string_ref (progs_t *pr)
static void
free_string_ref (progs_t *pr, strref_t *sr)
{
sr->string = 0;
sr->dstring = 0;
if (sr->prev)
*sr->prev = sr->next;
sr->next = pr->free_string_refs;
pr->free_string_refs = sr;
}
@ -139,9 +150,9 @@ string_index (progs_t *pr, strref_t *sr)
unsigned int i;
if (o >= 0 && o < pr->num_strings)
return sr->string - pr->pr_strings;
return sr->s.string - pr->pr_strings;
for (i = 0; i < pr->dyn_str_size; i++) {
int d = sr - pr->dynamic_strings[i];
int d = sr - pr->string_map[i];
if (d >= 0 && d < 1024)
return ~(i * 1024 + d);
}
@ -153,7 +164,8 @@ strref_get_key (void *_sr, void *notused)
{
strref_t *sr = (strref_t*)_sr;
return sr->string;
// only static strings will ever be in the hash table
return sr->s.string;
}
static void
@ -196,7 +208,7 @@ PR_LoadStrings (progs_t *pr)
} else {
pr->strref_hash = Hash_NewTable (1021, strref_get_key, strref_free,
pr);
pr->dynamic_strings = 0;
pr->string_map = 0;
pr->free_string_refs = 0;
pr->dyn_str_size = 0;
}
@ -207,11 +219,16 @@ PR_LoadStrings (progs_t *pr)
count = 0;
str = pr->pr_strings;
while (str < end) {
pr->static_strings[count].string = str;
if (!Hash_Find (pr->strref_hash, str)) {
pr->static_strings[count].type = str_static;
pr->static_strings[count].s.string = str;
Hash_Add (pr->strref_hash, &pr->static_strings[count]);
count++;
}
str += strlen (str) + 1;
Hash_Add (pr->strref_hash, &pr->static_strings[count]);
count++;
}
pr->static_strings = realloc (pr->static_strings,
count * sizeof (strref_t));
pr->num_strings = count;
return 1;
}
@ -226,7 +243,7 @@ get_strref (progs_t *pr, int num)
if (row >= pr->dyn_str_size)
return 0;
return &pr->dynamic_strings[row][num];
return &pr->string_map[row][num];
} else {
return 0;
}
@ -239,9 +256,16 @@ get_string (progs_t *pr, int num)
strref_t *ref = get_strref (pr, num);
if (!ref)
return 0;
if (ref->dstring)
return ref->dstring->str;
return ref->string;
switch (ref->type) {
case str_static:
case str_temp:
case str_dynamic:
case str_return:
return ref->s.string;
case str_mutable:
return ref->s.dstring->str;
}
PR_Error (pr, "internal string error");
} else {
if (num >= pr->pr_stringsize)
return 0;
@ -267,22 +291,33 @@ PR_GetString (progs_t *pr, int num)
}
dstring_t *
PR_GetDString (progs_t *pr, int num)
PR_GetMutableString (progs_t *pr, int num)
{
strref_t *ref = get_strref (pr, num);
if (ref) {
if (ref->dstring)
return ref->dstring;
if (ref->type == str_mutable)
return ref->s.dstring;
PR_RunError (pr, "not a dstring: %d", num);
}
PR_RunError (pr, "Invalid string offset: %d", num);
}
static inline char *
pr_stralloc (progs_t *pr, int len)
{
return PR_Zone_Malloc (pr, len + 1);
}
static inline void
pr_strfree (progs_t *pr, char *s)
{
PR_Zone_Free (pr, s);
}
static inline char *
pr_strdup (progs_t *pr, const char *s)
{
size_t len = strlen (s) + 1;
char *new = PR_Zone_Malloc (pr, len);
char *new = pr_stralloc (pr, strlen (s));
strcpy (new, s);
return new;
}
@ -290,12 +325,16 @@ pr_strdup (progs_t *pr, const char *s)
int
PR_SetString (progs_t *pr, const char *s)
{
strref_t *sr = Hash_Find (pr->strref_hash, s);
strref_t *sr;
if (!s)
s = "";
sr = Hash_Find (pr->strref_hash, s);
if (!sr) {
sr = new_string_ref (pr);
sr->string = pr_strdup(pr, s);
sr->count = 0;
sr->type = str_static;
sr->s.string = pr_strdup(pr, s);
Hash_Add (pr->strref_hash, sr);
}
return string_index (pr, sr);
@ -325,19 +364,49 @@ PR_SetReturnString (progs_t *pr, const char *s)
}
if ((sr = pr->return_strings[pr->rs_slot])) {
if (sr->string)
PR_Zone_Free (pr, sr->string);
if (sr->type != str_return)
PR_Error (pr, "internal string error");
pr_strfree (pr, sr->s.string);
} else {
sr = new_string_ref (pr);
}
sr->string = pr_strdup(pr, s);
sr->count = 0;
sr->type = str_return;
sr->s.string = pr_strdup(pr, s);
pr->return_strings[pr->rs_slot++] = sr;
pr->rs_slot %= PR_RS_SLOTS;
return string_index (pr, sr);
}
static inline int
pr_settempstring (progs_t *pr, char *s)
{
strref_t *sr;
sr = new_string_ref (pr);
sr->type = str_temp;
sr->s.string = s;
sr->next = pr->pr_xtstr;
pr->pr_xtstr = sr;
return string_index (pr, sr);
}
int
PR_CatStrings (progs_t *pr, const char *a, const char *b)
{
int lena;
char *c;
lena = strlen (a);
c = pr_stralloc (pr, lena + strlen (b));
strcpy (c, a);
strcpy (c + lena, b);
return pr_settempstring (pr, c);
}
int
PR_SetTempString (progs_t *pr, const char *s)
{
@ -346,11 +415,28 @@ PR_SetTempString (progs_t *pr, const char *s)
if (!s)
return PR_SetString (pr, "");
if ((sr = Hash_Find (pr->strref_hash, s))) {
return string_index (pr, sr);
}
return pr_settempstring (pr, pr_strdup (pr, s));
}
int
PR_SetDynamicString (progs_t *pr, const char *s)
{
strref_t *sr;
if (!s)
return PR_SetString (pr, "");
if ((sr = Hash_Find (pr->strref_hash, s))) {
return string_index (pr, sr);
}
sr = new_string_ref (pr);
sr->string = pr_strdup(pr, s);
sr->count = 0;
sr->next = pr->pr_xtstr;
pr->pr_xtstr = sr;
sr->type = str_dynamic;
sr->s.string = pr_strdup (pr, s);
return string_index (pr, sr);
}
@ -361,23 +447,26 @@ PR_MakeTempString (progs_t *pr, int str)
if (!sr)
PR_RunError (pr, "invalid string %d", str);
if (sr->dstring) {
if (sr->dstring->str)
sr->string = sr->dstring->str;
PR_Zone_Free (pr, sr->dstring);
if (sr->type != str_mutable)
PR_RunError (pr, "not a dstring: %d", str);
if (sr->s.dstring->str) {
sr->s.string = dstring_freeze (sr->s.dstring);
} else {
dstring_delete (sr->s.dstring);
}
if (!sr->string)
sr->string = pr_strdup (pr, "");
sr->count = 0;
if (!sr->s.string)
sr->s.string = pr_strdup (pr, "");
sr->type = str_temp;
sr->next = pr->pr_xtstr;
pr->pr_xtstr = sr;
}
int
PR_NewString (progs_t *pr)
PR_NewMutableString (progs_t *pr)
{
strref_t *sr = new_string_ref (pr);
sr->dstring = _dstring_newstr (pr->ds_mem);
sr->type = str_mutable;
sr->s.dstring = _dstring_newstr (pr->ds_mem);
return string_index (pr, sr);
}
@ -387,14 +476,25 @@ PR_FreeString (progs_t *pr, int str)
strref_t *sr = get_strref (pr, str);
if (sr) {
if (sr->dstring)
dstring_delete (sr->dstring);
else
PR_Zone_Free (pr, sr->string);
switch (sr->type) {
case str_static:
case str_temp:
return;
case str_mutable:
dstring_delete (sr->s.dstring);
break;
case str_dynamic:
pr_strfree (pr, sr->s.string);
break;
case str_return:
default:
PR_Error (pr, "internal string error");
}
free_string_ref (pr, sr);
return;
}
PR_RunError (pr, "attempt to free invalid string %d", str);
if (!get_string (pr, str))
PR_RunError (pr, "attempt to free invalid string %d", str);
}
void
@ -404,7 +504,9 @@ PR_FreeTempStrings (progs_t *pr)
for (sr = pr->pr_xtstr; sr; sr = t) {
t = sr->next;
PR_Zone_Free (pr, sr->string);
if (sr->type != str_temp)
PR_Error (pr, "internal string error");
pr_strfree (pr, sr->s.string);
free_string_ref (pr, sr);
}
pr->pr_xtstr = 0;
@ -462,14 +564,18 @@ I_DoPrint (dstring_t *result, fmt_item_t *formatting)
PRINT (string);
break;
case 'i':
dstring_appendstr (tmp, "ld");
dstring_appendstr (tmp, "d");
PRINT (integer);
break;
case 'x':
dstring_appendstr (tmp, "x");
PRINT (integer);
break;
case 'u':
if (current->flags & FMT_HEX)
dstring_appendstr (tmp, "lx");
dstring_appendstr (tmp, "x");
else
dstring_appendstr (tmp, "lu");
dstring_appendstr (tmp, "u");
PRINT (uinteger);
break;
case 'f':

View file

@ -67,6 +67,13 @@ user_write_data (png_structp png_ptr, png_bytep data, png_size_t length)
Qwrite ((QFile *) png_get_io_ptr (png_ptr), data, length);
}
/* Qflush wrapper for libpng */
static void
user_flush_data (png_structp png_ptr)
{
Qflush ((QFile *) png_get_io_ptr (png_ptr));
}
/* Basicly taken from the libpng example rpng-x */
static int
readpng_init (QFile *infile, png_structp *png_ptr, png_infop *info_ptr)
@ -223,8 +230,7 @@ WritePNG (const char *fileName, byte *data, int width, int height)
return; /* Can't open file */
}
/* FIXME: NULL should be a QF equiv to fflush? */
png_set_write_fn (png_ptr, outfile, user_write_data, NULL);
png_set_write_fn (png_ptr, outfile, user_write_data, user_flush_data);
/* Write the header */
if (setjmp(png_jmpbuf(png_ptr))) {

View file

@ -8,7 +8,7 @@ lib_LTLIBRARIES= libQFmodels.la @VID_MODEL_TARGETS@
EXTRA_LTLIBRARIES= \
libQFmodels_gl.la libQFmodels_sw.la
models_sources = clip_hull.c model.c
models_sources = clip_hull.c model.c trace.c
libQFmodels_la_LDFLAGS= -version-info 1:0:0 -no-undefined
libQFmodels_la_LIBADD= brush/libbrush.la $(top_builddir)/libs/util/libQFutil.la

View file

@ -177,7 +177,7 @@ Mod_LoadTextures (lump_t *l)
memcpy (tx + 1, mt + 1, pixels);
if (!strncmp (mt->name, "sky", 3))
R_InitSky (tx);
loadmodel->skytexture = tx;
else {
Mod_ProcessTexture (mt, tx);
}

189
libs/models/trace.c Normal file
View file

@ -0,0 +1,189 @@
/*
trace.c
BSP line tracing
Copyright (C) 2004 Bill Currie
Author: Bill Currie <bill@taniwha.org>
Date: 2004/9/25
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include "QF/model.h"
#include "compat.h"
#include "world.h"
/* LINE TESTING IN HULLS */
// 1/32 epsilon to keep floating point happy
#define DIST_EPSILON (0.03125)
typedef struct {
vec3_t backpt;
int side;
int num;
mplane_t *plane;
} tracestack_t;
static inline void
calc_impact (trace_t *trace, const vec3_t start, const vec3_t end,
mplane_t *plane)
{
vec_t t1, t2, frac;
int i, side;
if (plane->type < 3) {
t1 = start[plane->type] - plane->dist;
t2 = end[plane->type] - plane->dist;
} else {
t1 = DotProduct (plane->normal, start) - plane->dist;
t2 = DotProduct (plane->normal, end) - plane->dist;
}
side = t1 < 0;
if (side) {
frac = (t1 + DIST_EPSILON) / (t1 - t2);
// invert plane paramterers
trace->plane.normal[0] = -plane->normal[0];
trace->plane.normal[1] = -plane->normal[1];
trace->plane.normal[2] = -plane->normal[2];
trace->plane.dist = -plane->dist;
} else {
frac = (t1 - DIST_EPSILON) / (t1 - t2);
VectorCopy (plane->normal, trace->plane.normal);
trace->plane.dist = plane->dist;
}
frac = bound (0, frac, 1);
trace->fraction = frac;
for (i = 0; i < 3; i++)
trace->endpos[i] = start[i] + frac * (end[i] - start[i]);
}
qboolean
MOD_TraceLine (hull_t *hull, int num, const vec3_t start, const vec3_t end,
trace_t *trace)
{
vec_t front, back;
vec3_t frontpt, backpt;
int side, empty, solid;
tracestack_t *tstack;
tracestack_t tracestack[256];
dclipnode_t *node;
mplane_t *plane, *split_plane;
VectorCopy (start, frontpt);
VectorCopy (end, backpt);
tstack = tracestack;
empty = 0;
solid = 0;
split_plane = 0;
while (1) {
while (num < 0) {
if (!solid && num != CONTENTS_SOLID) {
empty = 1;
if (num == CONTENTS_EMPTY)
trace->inopen = true;
else
trace->inwater = true;
} else if (!empty && num == CONTENTS_SOLID) {
solid = 1;
} else if (empty || solid) {
// DONE!
trace->allsolid = solid & (num == CONTENTS_SOLID);
trace->startsolid = solid;
calc_impact (trace, start, end, split_plane);
return false;
}
// pop up the stack for a back side
if (tstack-- == tracestack) {
trace->allsolid = solid & (num == CONTENTS_SOLID);
trace->startsolid = solid;
return true;
}
// set the hit point for this plane
VectorCopy (backpt, frontpt);
// go down the back side
VectorCopy (tstack->backpt, backpt);
side = tstack->side;
split_plane = tstack->plane;
num = hull->clipnodes[tstack->num].children[side ^ 1];
}
node = hull->clipnodes + num;
plane = hull->planes + node->planenum;
if (plane->type < 3) {
front = frontpt[plane->type] - plane->dist;
back = backpt[plane->type] - plane->dist;
} else {
front = DotProduct (plane->normal, frontpt) - plane->dist;
back = DotProduct (plane->normal, backpt) - plane->dist;
}
if (front >= 0 && back >= 0) {
num = node->children[0];
continue;
}
if (front < 0 && back < 0) {
num = node->children[1];
continue;
}
side = front < 0;
front = front / (front - back);
tstack->num = num;
tstack->side = side;
tstack->plane = plane;
VectorCopy (backpt, tstack->backpt);
tstack++;
backpt[0] = frontpt[0] + front * (backpt[0] - frontpt[0]);
backpt[1] = frontpt[1] + front * (backpt[1] - frontpt[1]);
backpt[2] = frontpt[2] + front * (backpt[2] - frontpt[2]);
num = node->children[side];
}
}

View file

@ -9,5 +9,5 @@ libQFruamoko_la_LDFLAGS= -version-info 1:0:0 -no-undefined
libQFruamoko_la_LIBADD= $(top_builddir)/libs/gamecode/engine/libQFgamecode.la $(top_builddir)/libs/util/libQFutil.la
libQFruamoko_la_SOURCES= \
rua_cbuf.c rua_cmd.c rua_cvar.c rua_file.c rua_hash.c rua_init.c \
rua_obj.c rua_plist.c rua_qfile.c rua_qfs.c rua_string.c \
rua_math.c
rua_math.c rua_obj.c rua_plist.c rua_qfile.c rua_qfs.c rua_script.c \
rua_string.c

View file

@ -47,20 +47,13 @@ typedef struct {
static cbuf_t *
get_cbuf (progs_t *pr, int arg, const char *func)
{
pr_type_t *handle;
cbuf_t *cbuf;
cbuf_t *cbuf = 0;
if (arg == 0) {
cbuf_resources_t *res = PR_Resources_Find (pr, "Cbuf");
cbuf = res->cbuf;
} else {
if (arg <= ((pr_type_t *) pr->zone - pr->pr_globals)
|| (size_t) arg >= (pr->zone_size / sizeof (pr_type_t)))
PR_RunError (pr, "%s: Invalid cbuf_t", func);
handle = pr->pr_globals + arg;
cbuf = *(cbuf_t **)handle;
PR_RunError (pr, "%s: Invalid cbuf_t", func);
}
if (!cbuf)
PR_RunError (pr, "Invalid cbuf_t");

View file

@ -78,7 +78,7 @@ bi_cmd_free (void *_c, void *unused)
}
static void
bi_cmd_f (void *pr)
bi_cmd_f (void)
{
bi_cmd_t *cmd = Hash_Find (bi_cmds, Cmd_Argv (0));
@ -95,7 +95,7 @@ bi_Cmd_AddCommand (progs_t *pr)
char *name = strdup (P_GSTRING (pr, 0));
func_t func = P_FUNCTION (pr, 1);
if (!cmd || !name || !Cmd_AddCommand (name, (void(*)(void))bi_cmd_f, "CSQC command")) {
if (!cmd || !name || !Cmd_AddCommand (name, bi_cmd_f, "CSQC command")) {
if (name)
free (name);
if (cmd)
@ -159,7 +159,7 @@ static builtin_t builtins[] = {
void
RUA_Cmd_Init (progs_t *pr, int secure)
{
cmd_resources_t *res = malloc (sizeof (cmd_resources_t));
cmd_resources_t *res = calloc (1, sizeof (cmd_resources_t));
res->cmds = 0;
PR_Resources_Register (pr, "Cmd", res, bi_cmd_clear);

View file

@ -118,8 +118,7 @@ file_writeable (char *path)
static void
bi_File_Open (progs_t *pr)
{
qfile_resources_t *res = PR_Resources_Find (pr, "QFile");
QFile **file = QFile_AllocHandle (pr, res);
QFile *file;
const char *pth = P_GSTRING (pr, 0);
const char *mode = P_GSTRING (pr, 1);
char *path;
@ -163,12 +162,13 @@ bi_File_Open (progs_t *pr)
if (do_write && !file_writeable (path))
goto error;
*file = QFS_Open (va ("%s/%s", qfs_gamedir->dir.def, path), mode);
if (!*file)
file = QFS_Open (va ("%s/%s", qfs_gamedir->dir.def, path), mode);
if (!file)
goto error;
R_INT (pr) = (file - res->handles) + 1;
free (path);
return;
if ((R_INT (pr) = QFile_AllocHandle (pr, file)))
return;
Qclose (file);
error:
free (path);
R_INT (pr) = 0;

View file

@ -60,9 +60,40 @@ typedef struct bi_hashtab_s {
} bi_hashtab_t;
typedef struct {
PR_RESMAP (bi_hashtab_t) table_map;
bi_hashtab_t *tabs;
} hash_resources_t;
static bi_hashtab_t *
table_new (hash_resources_t *res)
{
PR_RESNEW (bi_hashtab_t, res->table_map);
}
static void
table_free (hash_resources_t *res, bi_hashtab_t *table)
{
PR_RESFREE (bi_hashtab_t, res->table_map, table);
}
static void
table_reset (hash_resources_t *res)
{
PR_RESRESET (bi_hashtab_t, res->table_map);
}
static inline bi_hashtab_t *
table_get (hash_resources_t *res, int index)
{
PR_RESGET(res->table_map, index);
}
static inline int
table_index (hash_resources_t *res, bi_hashtab_t *table)
{
PR_RESINDEX(res->table_map, table);
}
static const char *
bi_get_key (void *key, void *_ht)
{
@ -112,7 +143,7 @@ bi_Hash_NewTable (progs_t *pr)
void (*f)(void*,void*);
bi_hashtab_t *ht;
ht = PR_Zone_Malloc (pr, sizeof (bi_hashtab_t));
ht = table_new (res);
ht->pr = pr;
ht->gk = P_FUNCTION (pr, 1);
ht->f = P_FUNCTION (pr, 2);
@ -120,19 +151,31 @@ bi_Hash_NewTable (progs_t *pr)
ht->next = res->tabs;
ht->prev = &res->tabs;
if (ht->next)
ht->next->prev = &ht->next;
if (res->tabs)
res->tabs->prev = &ht->next;
res->tabs = ht;
gk = ht->gk ? bi_get_key : 0;
f = ht->f ? bi_free : 0;
ht->tab = Hash_NewTable (tsize, gk, f, ht);
RETURN_POINTER (pr, ht);
R_INT (pr) = table_index (res, ht);
}
static bi_hashtab_t *
get_table (progs_t *pr, const char *name, int index)
{
hash_resources_t *res = PR_Resources_Find (pr, "Hash");
bi_hashtab_t *ht = table_get (res, index);
if (!ht)
PR_RunError (pr, "invalid hash table index passed to %s", name + 3);
return ht;
}
static void
bi_Hash_SetHashCompare (progs_t *pr)
{
bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0);
bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0));
unsigned long (*gh)(void*,void*);
int (*cmp)(void*,void*,void*);
@ -146,17 +189,18 @@ bi_Hash_SetHashCompare (progs_t *pr)
static void
bi_Hash_DelTable (progs_t *pr)
{
bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0);
hash_resources_t *res = PR_Resources_Find (pr, "Hash");
bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0));
Hash_DelTable (ht->tab);
*ht->prev = ht->next;
PR_Zone_Free (pr, ht);
table_free (res, ht);
}
static void
bi_Hash_FlushTable (progs_t *pr)
{
bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0);
bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0));
Hash_FlushTable (ht->tab);
}
@ -164,7 +208,7 @@ bi_Hash_FlushTable (progs_t *pr)
static void
bi_Hash_Add (progs_t *pr)
{
bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0);
bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0));
R_INT (pr) = Hash_Add (ht->tab, (void *) (long) P_INT (pr, 1));
}
@ -172,7 +216,7 @@ bi_Hash_Add (progs_t *pr)
static void
bi_Hash_AddElement (progs_t *pr)
{
bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0);
bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0));
R_INT (pr) = Hash_AddElement (ht->tab, (void *) (long) P_INT (pr, 1));
}
@ -180,7 +224,7 @@ bi_Hash_AddElement (progs_t *pr)
static void
bi_Hash_Find (progs_t *pr)
{
bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0);
bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0));
R_INT (pr) = (long) Hash_Find (ht->tab, P_GSTRING (pr, 1));
}
@ -188,7 +232,7 @@ bi_Hash_Find (progs_t *pr)
static void
bi_Hash_FindElement (progs_t *pr)
{
bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0);
bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0));
R_INT (pr) = (long) Hash_FindElement (ht->tab,
(void *) (long) P_INT (pr, 1));
@ -197,7 +241,7 @@ bi_Hash_FindElement (progs_t *pr)
static void
bi_Hash_FindList (progs_t *pr)
{
bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0);
bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0));
void **list, **l;
pr_type_t *pr_list;
int count;
@ -206,6 +250,7 @@ bi_Hash_FindList (progs_t *pr)
for (count = 1, l = list; *l; l++)
count++;
pr_list = PR_Zone_Malloc (pr, count * sizeof (pr_type_t));
// the hash tables stores progs pointers...
for (count = 0, l = list; *l; l++)
pr_list[count++].integer_var = (long) *l;
free (list);
@ -215,7 +260,7 @@ bi_Hash_FindList (progs_t *pr)
static void
bi_Hash_FindElementList (progs_t *pr)
{
bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0);
bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0));
void **list, **l;
pr_type_t *pr_list;
int count;
@ -224,6 +269,7 @@ bi_Hash_FindElementList (progs_t *pr)
for (count = 1, l = list; *l; l++)
count++;
pr_list = PR_Zone_Malloc (pr, count * sizeof (pr_type_t));
// the hash tables stores progs pointers...
for (count = 0, l = list; *l; l++)
pr_list[count++].integer_var = (long) *l;
free (list);
@ -233,7 +279,7 @@ bi_Hash_FindElementList (progs_t *pr)
static void
bi_Hash_Del (progs_t *pr)
{
bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0);
bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0));
R_INT (pr) = (long) Hash_Del (ht->tab, P_GSTRING (pr, 1));
}
@ -241,7 +287,7 @@ bi_Hash_Del (progs_t *pr)
static void
bi_Hash_DelElement (progs_t *pr)
{
bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0);
bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0));
R_INT (pr) = (long) Hash_DelElement (ht->tab,
(void *) (long) P_INT (pr, 1));
@ -250,7 +296,7 @@ bi_Hash_DelElement (progs_t *pr)
static void
bi_Hash_Free (progs_t *pr)
{
bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0);
bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0));
Hash_Free (ht->tab, (void *) (long) P_INT (pr, 1));
}
@ -270,7 +316,7 @@ bi_Hash_Buffer (progs_t *pr)
static void
bi_Hash_GetList (progs_t *pr)
{
bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0);
bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0));
void **list, **l;
pr_type_t *pr_list;
int count;
@ -279,6 +325,7 @@ bi_Hash_GetList (progs_t *pr)
for (count = 1, l = list; *l; l++)
count++;
pr_list = PR_Zone_Malloc (pr, count * sizeof (pr_type_t));
// the hash tables stores progs pointers...
for (count = 0, l = list; *l; l++)
pr_list[count++].integer_var = (long) *l;
free (list);
@ -288,7 +335,7 @@ bi_Hash_GetList (progs_t *pr)
static void
bi_Hash_Stats (progs_t *pr)
{
bi_hashtab_t *ht = &P_STRUCT (pr, bi_hashtab_t, 0);
bi_hashtab_t *ht = get_table (pr, __FUNCTION__, P_INT (pr, 0));
Hash_Stats (ht->tab);
}
@ -302,6 +349,7 @@ bi_hash_clear (progs_t *pr, void *data)
for (ht = res->tabs; ht; ht = ht->next)
Hash_DelTable (ht->tab);
res->tabs = 0;
table_reset (res);
}
static builtin_t builtins[] = {
@ -328,7 +376,7 @@ static builtin_t builtins[] = {
void
RUA_Hash_Init (progs_t *pr, int secure)
{
hash_resources_t *res = malloc (sizeof (hash_resources_t));
hash_resources_t *res = calloc (1, sizeof (hash_resources_t));
res->tabs = 0;
PR_Resources_Register (pr, "Hash", res, bi_hash_clear);

View file

@ -48,6 +48,7 @@ static void (*init_funcs[])(progs_t *, int) = {
RUA_Plist_Init,
RUA_QFile_Init,
RUA_QFS_Init,
RUA_Script_Init,
RUA_String_Init,
};

File diff suppressed because it is too large Load diff

View file

@ -55,6 +55,7 @@ typedef struct {
static inline void
return_plitem (progs_t *pr, plitem_t *plitem)
{
memset (&R_INT (pr), 0, 8);
memcpy (&R_INT (pr), &plitem, sizeof (plitem));
}
@ -92,6 +93,27 @@ bi_PL_GetPropertyList (progs_t *pr)
return_plitem (pr, record_plitem (pr, plitem));
}
static void
bi_PL_WritePropertyList (progs_t *pr)
{
char *pl = PL_WritePropertyList (p_plitem (pr, 0));
R_STRING (pr) = PR_SetDynamicString (pr, pl);
free (pl);
}
static void
bi_PL_Type (progs_t *pr)
{
R_INT (pr) = PL_Type (p_plitem (pr, 0));
}
static void
bi_PL_String (progs_t *pr)
{
const char *str = PL_String (p_plitem (pr, 0));
RETURN_STRING (pr, str);
}
static void
bi_PL_ObjectForKey (progs_t *pr)
{
@ -104,6 +126,18 @@ bi_PL_ObjectAtIndex (progs_t *pr)
return_plitem (pr, PL_ObjectAtIndex (p_plitem (pr, 0), P_INT (pr, 1)));
}
static void
bi_PL_D_AllKeys (progs_t *pr)
{
return_plitem (pr, PL_D_AllKeys (p_plitem (pr, 0)));
}
static void
bi_PL_D_NumKeys (progs_t *pr)
{
R_INT (pr) = PL_D_NumKeys (p_plitem (pr, 0));
}
static void
bi_PL_D_AddObject (progs_t *pr)
{
@ -119,6 +153,12 @@ bi_PL_A_AddObject (progs_t *pr)
remove_plitem (pr, p_plitem (pr, 1)));
}
static void
bi_PL_A_NumObjects (progs_t *pr)
{
R_INT (pr) = PL_A_NumObjects (p_plitem (pr, 0));
}
static void
bi_PL_A_InsertObjectAtIndex (progs_t *pr)
{
@ -128,9 +168,9 @@ bi_PL_A_InsertObjectAtIndex (progs_t *pr)
}
static void
bi_PL_NewDictionary (progs_t *pr)
bi_PL_Free (progs_t *pr)
{
return_plitem (pr, record_plitem (pr, PL_NewDictionary ()));
PL_Free (remove_plitem (pr, p_plitem (pr, 0)));
}
static void
@ -138,18 +178,26 @@ bi_PL_NewArray (progs_t *pr)
{
return_plitem (pr, record_plitem (pr, PL_NewArray ()));
}
/*
static void
bi_PL_NewData (progs_t *pr)
{
return_plitem (pr, record_plitem (pr, PL_NewData (P_GPOINTER (pr, 0),
P_INT (pr, 1))));
}
*/
static void
bi_PL_NewString (progs_t *pr)
{
return_plitem (pr, record_plitem (pr, PL_NewString (P_GSTRING (pr, 0))));
}
static void
bi_PL_NewDictionary (progs_t *pr)
{
return_plitem (pr, record_plitem (pr, PL_NewDictionary ()));
}
static void
bi_plist_clear (progs_t *pr, void *data)
{
@ -172,22 +220,29 @@ plist_compare (void *k1, void *k2, void *unused)
static builtin_t builtins[] = {
{"PL_GetPropertyList", bi_PL_GetPropertyList, -1},
{"PL_WritePropertyList", bi_PL_WritePropertyList, -1},
{"PL_Type", bi_PL_Type, -1},
{"PL_String", bi_PL_String, -1},
{"PL_ObjectForKey", bi_PL_ObjectForKey, -1},
{"PL_ObjectAtIndex", bi_PL_ObjectAtIndex, -1},
{"PL_D_AllKeys", bi_PL_D_AllKeys, -1},
{"PL_D_NumKeys", bi_PL_D_NumKeys, -1},
{"PL_D_AddObject", bi_PL_D_AddObject, -1},
{"PL_A_AddObject", bi_PL_A_AddObject, -1},
{"PL_A_NumObjects", bi_PL_A_NumObjects, -1},
{"PL_A_InsertObjectAtIndex", bi_PL_A_InsertObjectAtIndex, -1},
{"PL_NewDictionary", bi_PL_NewDictionary, -1},
{"PL_NewArray", bi_PL_NewArray, -1},
// {"PL_NewData", bi_PL_NewData, -1},
{"PL_NewData", bi_PL_NewData, -1},
{"PL_NewString", bi_PL_NewString, -1},
{"PL_Free", bi_PL_Free, -1},
{0}
};
void
RUA_Plist_Init (progs_t *pr, int secure)
{
plist_resources_t *res = malloc (sizeof (plist_resources_t));
plist_resources_t *res = calloc (1, sizeof (plist_resources_t));
res->items = Hash_NewTable (1021, 0, 0, 0);
Hash_SetHashCompare (res->items, plist_get_hash, plist_compare);

View file

@ -46,32 +46,82 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "rua_internal.h"
typedef struct qfile_s {
struct qfile_s *next;
struct qfile_s **prev;
QFile *file;
} qfile_t;
typedef struct {
PR_RESMAP (qfile_t) handle_map;
qfile_t *handles;
} qfile_resources_t;
static qfile_t *
handle_new (qfile_resources_t *res)
{
PR_RESNEW (qfile_t, res->handle_map);
}
static void
handle_free (qfile_resources_t *res, qfile_t *handle)
{
PR_RESFREE (qfile_t, res->handle_map, handle);
}
static void
handle_reset (qfile_resources_t *res)
{
PR_RESRESET (qfile_t, res->handle_map);
}
static inline qfile_t *
handle_get (qfile_resources_t *res, int index)
{
PR_RESGET(res->handle_map, index);
}
static inline int
handle_index (qfile_resources_t *res, qfile_t *handle)
{
PR_RESINDEX(res->handle_map, handle);
}
static void
bi_qfile_clear (progs_t *pr, void *data)
{
qfile_resources_t *res = (qfile_resources_t *) data;
int i;
for (i = 0; i < QFILE_MAX_HANDLES; i++)
if (res->handles[i]) {
Qclose (res->handles[i]);
res->handles[i] = 0;
}
qfile_t *handle;
for (handle = res->handles; handle; handle = handle->next)
Qclose (handle->file);
res->handles = 0;
handle_reset (res);
}
QFile **
QFile_AllocHandle (struct progs_s *pr, qfile_resources_t *res)
static int
alloc_handle (qfile_resources_t *res, QFile *file)
{
int h;
qfile_t *handle = handle_new (res);
for (h = 0; h < QFILE_MAX_HANDLES && res->handles[h]; h++)
;
if (h == QFILE_MAX_HANDLES)
goto error;
res->handles[h] = (QFile *) 1;
return res->handles + h;
error:
return 0;
if (!handle)
return 0;
handle->next = res->handles;
handle->prev = &res->handles;
if (res->handles)
res->handles->prev = &handle->next;
res->handles = handle;
handle->file = file;
return handle_index (res, handle);
}
int
QFile_AllocHandle (progs_t *pr, QFile *file)
{
qfile_resources_t *res = PR_Resources_Find (pr, "QFile");
return alloc_handle (res, file);
}
static void
@ -103,44 +153,48 @@ bi_Qopen (progs_t *pr)
qfile_resources_t *res = PR_Resources_Find (pr, "QFile");
const char *path = P_GSTRING (pr, 0);
const char *mode = P_GSTRING (pr, 1);
QFile **h = QFile_AllocHandle (pr, res);
QFile *file;
if (!h) {
R_INT (pr) = 0;
R_INT (pr) = 0;
if (!(file = Qopen (path, mode)))
return;
}
*h = Qopen (path, mode);
R_INT (pr) = (h - res->handles) + 1;
if (!(R_INT (pr) = alloc_handle (res, file)))
Qclose (file);
}
static QFile **
get_qfile (progs_t *pr, int handle, const char *func)
static qfile_t *
get_handle (progs_t *pr, const char *name, int handle)
{
qfile_resources_t *res = PR_Resources_Find (pr, "QFile");
qfile_t *h = handle_get (res, handle);
if (handle < 1 || handle > QFILE_MAX_HANDLES || !res->handles[handle - 1])
PR_RunError (pr, "%s: Invalid QFile", func);
return res->handles + handle - 1;
if (!h)
PR_RunError (pr, "invalid file handle passed to %s", name + 3);
return h;
}
static void
bi_Qclose (progs_t *pr)
{
qfile_resources_t *res = PR_Resources_Find (pr, "QFile");
int handle = P_INT (pr, 0);
QFile **h = get_qfile (pr, handle, "Qclose");
qfile_t *h = handle_get (res, handle);
Qclose (*h);
*h = 0;
if (!h)
PR_RunError (pr, "invalid file handle pass to Qclose");
Qclose (h->file);
*h->prev = h->next;
handle_free (res, h);
}
static void
bi_Qgetline (progs_t *pr)
{
int handle = P_INT (pr, 0);
QFile **h = get_qfile (pr, handle, "Qgetline");
qfile_t *h = get_handle (pr, __FUNCTION__, handle);
const char *s;
s = Qgetline (*h);
s = Qgetline (h->file);
if (s)
RETURN_STRING (pr, s);
else
@ -161,112 +215,112 @@ static void
bi_Qread (progs_t *pr)
{
int handle = P_INT (pr, 0);
QFile **h = get_qfile (pr, handle, "Qread");
qfile_t *h = get_handle (pr, __FUNCTION__, handle);
pr_type_t *buf = P_GPOINTER (pr, 1);
int count = P_INT (pr, 2);
check_buffer (pr, buf, count, "Qread");
R_INT (pr) = Qread (*h, buf, count);
R_INT (pr) = Qread (h->file, buf, count);
}
static void
bi_Qwrite (progs_t *pr)
{
int handle = P_INT (pr, 0);
QFile **h = get_qfile (pr, handle, "Qwrite");
qfile_t *h = get_handle (pr, __FUNCTION__, handle);
pr_type_t *buf = P_GPOINTER (pr, 1);
int count = P_INT (pr, 2);
check_buffer (pr, buf, count, "Qwrite");
R_INT (pr) = Qwrite (*h, buf, count);
R_INT (pr) = Qwrite (h->file, buf, count);
}
static void
bi_Qputs (progs_t *pr)
{
int handle = P_INT (pr, 0);
QFile **h = get_qfile (pr, handle, "Qputs");
qfile_t *h = get_handle (pr, __FUNCTION__, handle);
const char *str = P_GSTRING (pr, 1);
R_INT (pr) = Qputs (*h, str);
R_INT (pr) = Qputs (h->file, str);
}
#if 0
static void
bi_Qgets (progs_t *pr)
{
int handle = P_INT (pr, 0);
QFile **h = get_qfile (pr, handle, "Qgets");
qfile_t *h = get_handle (pr, __FUNCTION__, handle);
pr_type_t *buf = P_GPOINTER (pr, 1);
int count = P_INT (pr, 2);
check_buffer (pr, buf, count, "Qgets");
R_INT (pr) = POINTER_TO_PROG (pr, Qgets (*h, (char *) buf, count));
RETURN_POINTER (pr, Qgets (h->file, (char *) buf, count));
}
#endif
static void
bi_Qgetc (progs_t *pr)
{
int handle = P_INT (pr, 0);
QFile **h = get_qfile (pr, handle, "Qgetc");
qfile_t *h = get_handle (pr, __FUNCTION__, handle);
R_INT (pr) = Qgetc (*h);
R_INT (pr) = Qgetc (h->file);
}
static void
bi_Qputc (progs_t *pr)
{
int handle = P_INT (pr, 0);
QFile **h = get_qfile (pr, handle, "Qputc");
qfile_t *h = get_handle (pr, __FUNCTION__, handle);
int c = P_INT (pr, 1);
R_INT (pr) = Qputc (*h, c);
R_INT (pr) = Qputc (h->file, c);
}
static void
bi_Qseek (progs_t *pr)
{
int handle = P_INT (pr, 0);
QFile **h = get_qfile (pr, handle, "Qseek");
qfile_t *h = get_handle (pr, __FUNCTION__, handle);
int offset = P_INT (pr, 1);
int whence = P_INT (pr, 2);
R_INT (pr) = Qseek (*h, offset, whence);
R_INT (pr) = Qseek (h->file, offset, whence);
}
static void
bi_Qtell (progs_t *pr)
{
int handle = P_INT (pr, 0);
QFile **h = get_qfile (pr, handle, "Qtell");
qfile_t *h = get_handle (pr, __FUNCTION__, handle);
R_INT (pr) = Qtell (*h);
R_INT (pr) = Qtell (h->file);
}
static void
bi_Qflush (progs_t *pr)
{
int handle = P_INT (pr, 0);
QFile **h = get_qfile (pr, handle, "Qflush");
qfile_t *h = get_handle (pr, __FUNCTION__, handle);
R_INT (pr) = Qflush (*h);
R_INT (pr) = Qflush (h->file);
}
static void
bi_Qeof (progs_t *pr)
{
int handle = P_INT (pr, 0);
QFile **h = get_qfile (pr, handle, "Qeof");
qfile_t *h = get_handle (pr, __FUNCTION__, handle);
R_INT (pr) = Qeof (*h);
R_INT (pr) = Qeof (h->file);
}
static void
bi_Qfilesize (progs_t *pr)
{
int handle = P_INT (pr, 0);
QFile **h = get_qfile (pr, handle, "Qfilesize");
qfile_t *h = get_handle (pr, __FUNCTION__, handle);
R_INT (pr) = Qfilesize (*h);
R_INT (pr) = Qfilesize (h->file);
}
static builtin_t secure_builtins[] = {

View file

@ -99,16 +99,16 @@ bi_QFS_LoadFile (progs_t *pr)
static void
bi_QFS_OpenFile (progs_t *pr)
{
qfile_resources_t *res = PR_Resources_Find (pr, "QFile");
QFile **file = QFile_AllocHandle (pr, res);
QFile *file;
const char *filename = P_GSTRING (pr, 0);
QFS_FOpenFile (filename, file);
if (!*file) {
RETURN_POINTER (pr, 0);
QFS_FOpenFile (filename, &file);
if (!file) {
R_INT (pr) = 0;
return;
}
R_INT (pr) = (file - res->handles) + 1;
if (!(R_INT (pr) = QFile_AllocHandle (pr, file)))
Qclose (file);
}
static void
@ -136,9 +136,9 @@ bi_QFS_Filelist (progs_t *pr)
list = PR_Zone_Malloc (pr, sizeof (list) + filelist->count * 4);
list->count = filelist->count;
strings = (string_t *) list + 1;
list->list = POINTER_TO_PROG (pr, strings);
list->list = PR_SetPointer (pr, strings);
for (i = 0; i < filelist->count; i++)
strings[i] = PR_SetString (pr, filelist->list[i]);
strings[i] = PR_SetTempString (pr, filelist->list[i]);
RETURN_POINTER (pr, list);
}

222
libs/ruamoko/rua_script.c Normal file
View file

@ -0,0 +1,222 @@
/*
rua_script.c
Script api for ruamoko
Copyright (C) 2004 Bill Currie
Author: Bill Currie
Date: 2002/11/11
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
#include <stdlib.h>
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include "QF/progs.h"
#include "QF/script.h"
#include "rua_internal.h"
typedef struct {
script_t script;
string_t dstr;
progs_t *pr;
string_t err_msg;
} rua_script_t;
typedef struct {
PR_RESMAP(rua_script_t) scripts;
} script_resources_t;
static rua_script_t *
script_new (script_resources_t *res)
{
PR_RESNEW (rua_script_t, res->scripts);
}
static void
script_free (script_resources_t *res, rua_script_t *script)
{
PR_RESFREE (rua_script_t, res->scripts, script);
}
static void
script_reset (script_resources_t *res)
{
PR_RESRESET (rua_script_t, res->scripts);
}
static inline rua_script_t *
script_get (script_resources_t *res, int index)
{
PR_RESGET(res->scripts, index);
}
static inline int
script_index (script_resources_t *res, rua_script_t *script)
{
PR_RESINDEX(res->scripts, script);
}
static void
bi_script_clear (progs_t *pr, void *data)
{
script_resources_t *res = (script_resources_t *) data;
script_reset (res);
}
static void
bi_script_error (script_t *_script, const char *msg)
{
rua_script_t *script = (rua_script_t *)_script;
script->err_msg = PR_SetString (script->pr, msg);
}
static void
bi_Script_New (progs_t *pr)
{
script_resources_t *res = PR_Resources_Find (pr, "Script");
rua_script_t *script = script_new (res);
if (!script)
PR_RunError (pr, "out of memory");
script->dstr = PR_NewMutableString (pr);
script->script.token = PR_GetMutableString (pr, script->dstr);
script->script.error = bi_script_error;
script->pr = pr;
R_INT (pr) = script_index (res, script);
}
static void
bi_Script_Delete (progs_t *pr)
{
script_resources_t *res = PR_Resources_Find (pr, "Script");
rua_script_t *script = script_get (res, P_INT (pr, 0));
if (!script)
PR_RunError (pr, "invalid script handle");
PR_FreeString (pr, script->dstr);
script_free (res, script);
}
static void
bi_Script_Start (progs_t *pr)
{
script_resources_t *res = PR_Resources_Find (pr, "Script");
rua_script_t *script = script_get (res, P_INT (pr, 0));
if (!script)
PR_RunError (pr, "invalid script handle");
Script_Start (&script->script, P_GSTRING (pr, 1), P_GSTRING (pr, 2));
R_STRING (pr) = script->dstr;
}
static void
bi_Script_TokenAvailable (progs_t *pr)
{
script_resources_t *res = PR_Resources_Find (pr, "Script");
rua_script_t *script = script_get (res, P_INT (pr, 0));
if (!script)
PR_RunError (pr, "invalid script handle");
R_INT (pr) = Script_TokenAvailable (&script->script, P_INT (pr, 1));
}
static void
bi_Script_GetToken (progs_t *pr)
{
script_resources_t *res = PR_Resources_Find (pr, "Script");
rua_script_t *script = script_get (res, P_INT (pr, 0));
if (!script)
PR_RunError (pr, "invalid script handle");
R_INT (pr) = Script_GetToken (&script->script, P_INT (pr, 1));
}
static void
bi_Script_UngetToken (progs_t *pr)
{
script_resources_t *res = PR_Resources_Find (pr, "Script");
rua_script_t *script = script_get (res, P_INT (pr, 0));
if (!script)
PR_RunError (pr, "invalid script handle");
Script_UngetToken (&script->script);
}
static void
bi_Script_Error (progs_t *pr)
{
script_resources_t *res = PR_Resources_Find (pr, "Script");
rua_script_t *script = script_get (res, P_INT (pr, 0));
if (!script)
PR_RunError (pr, "invalid script handle");
R_STRING (pr) = script->err_msg;
script->err_msg = 0;
}
static void
bi_Script_NoQuoteLines (progs_t *pr)
{
script_resources_t *res = PR_Resources_Find (pr, "Script");
rua_script_t *script = script_get (res, P_INT (pr, 0));
if (!script)
PR_RunError (pr, "invalid script handle");
R_INT (pr) = script->script.no_quote_lines;
script->script.no_quote_lines = P_INT (pr, 1);
}
static builtin_t builtins[] = {
{"Script_New", bi_Script_New, -1},
{"Script_Delete", bi_Script_Delete, -1},
{"Script_Start", bi_Script_Start, -1},
{"Script_TokenAvailable", bi_Script_TokenAvailable, -1},
{"Script_GetToken", bi_Script_GetToken, -1},
{"Script_UngetToken", bi_Script_UngetToken, -1},
{"Script_Error", bi_Script_Error, -1},
{"Script_NoQuoteLines", bi_Script_NoQuoteLines, -1},
{0}
};
void
RUA_Script_Init (progs_t *pr, int secure)
{
script_resources_t *res = calloc (1, sizeof (script_resources_t));
PR_Resources_Register (pr, "Script", res, bi_script_clear);
PR_RegisterBuiltins (pr, builtins);
}

View file

@ -50,7 +50,7 @@ static __attribute__ ((unused)) const char rcsid[] =
static void
bi_str_new (progs_t *pr)
{
R_STRING (pr) = PR_NewString (pr);
R_STRING (pr) = PR_NewMutableString (pr);
}
static void
@ -78,11 +78,53 @@ bi_str_clear (progs_t *pr)
R_STRING (pr) = P_STRING (pr, 0);
}
static void
bi_str_mid (progs_t *pr)
{
const char *str = P_GSTRING (pr, 0);
int pos = P_INT (pr, 1);
int end = P_INT (pr, 2);
int size = strlen (str);
char *temp;
if (pr->pr_argc == 2)
end = size;
R_STRING (pr) = 0;
if (pos < 0)
pos += size;
if (end < 0)
end += size;
if (end > size)
end = size;
if (pos < 0 || pos >= size || end <= pos)
return;
temp = alloca (end - pos + 1);
strncpy (temp, str + pos, end - pos);
temp[end - pos] = 0;
RETURN_STRING (pr, temp);
}
static void
bi_str_str (progs_t *pr)
{
const char *haystack = P_GSTRING (pr, 0);
const char *needle = P_GSTRING (pr, 1);
char *res = strstr (haystack, needle);
R_STRING (pr) = 0;
if (res)
R_STRING (pr) = res - pr->pr_strings;
}
static builtin_t builtins[] = {
{"str_new", bi_str_new, -1},
{"str_free", bi_str_free, -1},
{"str_copy", bi_str_copy, -1},
{"str_clear", bi_str_clear, -1},
{"str_mid|*i", bi_str_mid, -1},
{"str_mid|*ii", bi_str_mid, -1},
{"str_str", bi_str_str, -1},
{0}
};

View file

@ -38,7 +38,7 @@ libQFutil_la_SOURCES= \
bspfile.c buildnum.c cbuf.c checksum.c cmd.c crc.c cvar.c dstring.c \
fendian.c hash.c idparse.c info.c link.c llist.c \
mathlib.c mdfour.c msg.c pakfile.c plugin.c qargs.c qendian.c \
qfplist.c quakefs.c quakeio.c riff.c sizebuf.c string.c sys.c \
qfplist.c quakefs.c quakeio.c riff.c script.c sizebuf.c string.c sys.c \
va.c ver_check.c wad.c wadfile.c zone.c $(fnmatch) $(getopt)
EXTRA_DIST= $(fnmatch_src) $(getopt_src)

View file

@ -35,15 +35,41 @@ static __attribute__ ((unused)) const char rcsid[] =
#include <stdlib.h>
#include <string.h>
#include "QF/dstring.h"
#include "QF/hash.h"
#include "QF/qfplist.h"
#include "QF/qtypes.h"
#include "QF/sys.h"
// Ugly defines for fast checking and conversion from char to number
#define inrange(ch,min,max) ((ch) >= (min) && (ch) <= (max))
#define char2num(ch) \
inrange((ch), '0', '9') ? ((ch) - 0x30) \
: (inrange((ch), 'a', 'f') ? ((ch) - 0x57) : ((ch) - 0x37))
static byte quotable_bitmap[32];
static inline int
is_quotable (byte x)
{
return quotable_bitmap[x / 8] & (1 << (x % 8));
}
static void
init_quotables (void)
{
const char *unquotables = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz!#$%&*+-./:?@|~_^";
const byte *c;
memset (quotable_bitmap, ~0, sizeof (quotable_bitmap));
for (c = unquotables; *c; c++)
quotable_bitmap[*c / 8] &= ~(1 << (*c % 8));
}
static plitem_t *PL_ParsePropertyListItem (pldata_t *);
static qboolean PL_SkipSpace (pldata_t *);
static char *PL_ParseQuotedString (pldata_t *);
static char *PL_ParseUnquotedString (pldata_t *);
static char *PL_ParseData (pldata_t *, int *);
static const char *
dict_get_key (void *i, void *unused)
@ -143,6 +169,14 @@ PL_Free (plitem_t *item)
free (item);
}
const char *
PL_String (plitem_t *string)
{
if (string->type != QFString)
return NULL;
return string->data;
}
plitem_t *
PL_ObjectForKey (plitem_t *dict, const char *key)
{
@ -159,22 +193,23 @@ PL_ObjectForKey (plitem_t *dict, const char *key)
plitem_t *
PL_D_AllKeys (plitem_t *dict)
{
void **list;
void **list, **l;
dictkey_t *current;
plitem_t *array;
if (dict->type != QFDictionary)
return NULL;
if (!(list = Hash_GetList ((hashtab_t *) dict->data)))
if (!(l = list = Hash_GetList ((hashtab_t *) dict->data)))
return NULL;
if (!(array = PL_NewArray ()))
return NULL;
while ((current = (dictkey_t *) *list++)) {
while ((current = (dictkey_t *) *l++)) {
PL_A_AddObject (array, PL_NewString (current->key));
}
free (list);
return array;
}
@ -333,6 +368,53 @@ PL_SkipSpace (pldata_t *pl)
return false;
}
static inline byte
to_hex (byte a)
{
if (a >= '0' && a <= '9')
return a - '0';
if (a >= 'A' && a <= 'F')
return a - 'A' + 10;
return a - 'a' + 10;
}
static inline byte
make_byte (byte h, byte l)
{
return (to_hex (h) << 4) | to_hex (l);
}
static char *
PL_ParseData (pldata_t *pl, int *len)
{
unsigned int start = ++pl->pos;
int nibbles = 0, i;
char *str;
while (pl->pos < pl->end) {
if (isxdigit (pl->ptr[pl->pos])) {
nibbles++;
continue;
}
if (pl->ptr[pl->pos] == '>') {
if (nibbles & 1) {
pl->error = "invalid data, missing nibble";
return NULL;
}
*len = nibbles / 2;
str = malloc (*len);
for (i = 0; i < *len; i++)
str[i] = make_byte (pl->ptr[start + i * 2],
pl->ptr[start + i * 2 + 1]);
return str;
}
pl->error = "invalid character in data";
return NULL;
}
pl->error = "Reached end of string while parsing data";
return NULL;
}
static char *
PL_ParseQuotedString (pldata_t *pl)
{
@ -478,7 +560,7 @@ PL_ParseUnquotedString (pldata_t *pl)
char *str;
while (pl->pos < pl->end) {
if (!isalnum ((byte) pl->ptr[pl->pos]) && pl->ptr[pl->pos] != '_')
if (is_quotable (pl->ptr[pl->pos]))
break;
pl->pos++;
}
@ -622,9 +704,16 @@ PL_ParsePropertyListItem (pldata_t *pl)
return item;
}
case '<':
pl->error = "Unexpected character in string (binary data unsupported)";
return NULL;
case '<': {
int len;
char *str = PL_ParseData (pl, &len);
if (!str) {
return NULL;
} else {
return PL_NewData (str, len);
}
}
case '"': {
char *str = PL_ParseQuotedString (pl);
@ -654,6 +743,9 @@ PL_GetPropertyList (const char *string)
pldata_t *pl = calloc (1, sizeof (pldata_t));
plitem_t *newpl = NULL;
if (!quotable_bitmap[0])
init_quotables ();
pl->ptr = string;
pl->pos = 0;
pl->end = strlen (string);
@ -670,3 +762,143 @@ PL_GetPropertyList (const char *string)
return NULL;
}
}
static void
write_tabs (dstring_t *dstr, int num)
{
int len = strlen (dstr->str);
dstr->size = len + num + 1;
dstring_adjust (dstr);
memset (dstr->str + len, '\t', num);
dstr->str[len + num] = 0;
}
static void
write_string (dstring_t *dstr, const char *str)
{
const char *s;
char c;
for (s = str; *s && !is_quotable (*s); s++)
;
if (!*s) {
dstring_appendstr (dstr, str);
return;
}
dstring_appendstr (dstr, "\"");
while (*str) {
for (s = str; (*s && isascii ((byte) *s) && isprint ((byte) *s)
&& *s != '\\' && *s != '\"'); s++)
;
dstring_appendsubstr (dstr, str, s - str);
if (*s) {
switch (*s) {
case '\"':
case '\\':
c = *s;
break;
case '\n':
c = 'n';
break;
case '\a':
c = 'a';
break;
case '\b':
c = 'b';
break;
case '\f':
c = 'f';
break;
case '\r':
c = 'r';
break;
case '\t':
c = 't';
break;
case '\v':
c = 'v';
break;
default:
c = 0;
dasprintf (dstr, "\\%03o", (byte) *s);
break;
}
if (c)
dasprintf (dstr, "\\%c", c);
s++;
}
str = s;
}
dstring_appendstr (dstr, "\"");
}
static void
write_item (dstring_t *dstr, plitem_t *item, int level)
{
void **list, **l;
dictkey_t *current;
plarray_t *array;
plbinary_t *binary;
int i;
switch (item->type) {
case QFDictionary:
dstring_appendstr (dstr, "{\n");
l = list = Hash_GetList ((hashtab_t *) item->data);
while ((current = (dictkey_t *) *l++)) {
write_tabs (dstr, level + 1);
write_string (dstr, current->key);
dstring_appendstr (dstr, " = ");
write_item (dstr, current->value, level + 1);
dstring_appendstr (dstr, ";\n");
}
free (list);
write_tabs (dstr, level);
dstring_appendstr (dstr, "}");
break;
case QFArray:
dstring_appendstr (dstr, "(\n");
array = (plarray_t *) item->data;
for (i = 0; i < array->numvals; i++) {
write_tabs (dstr, level + 1);
write_item (dstr, array->values[i], level + 1);
if (i < array->numvals - 1)
dstring_appendstr (dstr, ",\n");
}
dstring_appendstr (dstr, "\n");
write_tabs (dstr, level);
dstring_appendstr (dstr, ")");
break;
case QFBinary:
dstring_appendstr (dstr, "<");
binary = (plbinary_t *) item->data;
for (i = 0; i < (int) binary->size; i++)
dasprintf (dstr, "%02X", ((char *) binary->data)[i]);
dstring_appendstr (dstr, ">");
break;
case QFString:
write_string (dstr, item->data);
break;
default:
break;
}
}
char *
PL_WritePropertyList (plitem_t *pl)
{
dstring_t *dstr = dstring_newstr ();
if (!quotable_bitmap[0])
init_quotables ();
write_item (dstr, pl, 0);
dstring_appendstr (dstr, "\n");
return dstring_freeze (dstr);
}
pltype_t
PL_Type (plitem_t *item)
{
return item->type;
}

View file

@ -1066,7 +1066,7 @@ QFS_LoadGameDirectory (const char *dir)
pak = QFS_LoadPackFile (pakfiles[i]);
if (!pak) {
Sys_Error (va ("Bad pakfile %s!!", pakfiles[i]));
Sys_Error ("Bad pakfile %s!!", pakfiles[i]);
} else {
search = calloc (1, sizeof (searchpath_t));
search->pack = pak;

173
libs/util/script.c Normal file
View file

@ -0,0 +1,173 @@
/*
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 the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
See file, 'COPYING', for details.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include "QF/dstring.h"
#include "QF/script.h"
static void __attribute__ ((format (printf, 2, 3), noreturn))
script_error (script_t *script, const char *fmt, ...)
{
va_list args;
va_start (args, fmt);
fprintf (stderr, "%s:%d: ", script->file, script->line);
vfprintf (stderr, fmt, args);
fprintf (stderr, "\n");
va_end (args);
exit (1);
}
script_t *
Script_New (void)
{
script_t *script = calloc (1, sizeof (script_t));
script->token = dstring_newstr ();
return script;
}
void
Script_Delete (script_t *script)
{
dstring_delete (script->token);
free (script);
}
void
Script_Start (script_t *script, const char *file, const char *data)
{
script->line = 1;
script->file = file;
script->p = data;
script->unget = false;
}
qboolean
Script_TokenAvailable (script_t *script, qboolean crossline)
{
if (script->unget)
return true;
skipspace:
while (isspace ((unsigned char) *script->p)) {
if (*script->p == '\n') {
if (!crossline)
return false;
script->line++;
}
script->p++;
}
if (!*script->p)
return false;
if (*script->p == 26 || *script->p == 4) {
// end of file characters
script->p++;
goto skipspace;
}
if (script->p[0] == '/' && script->p[1] == '/') {
// comment field
while (*script->p && *script->p != '\n')
script->p++;
if (!*script->p)
return false;
if (!crossline)
return false;
goto skipspace;
}
return true;
}
qboolean
Script_GetToken (script_t *script, qboolean crossline)
{
const char *token_p;
if (script->unget) { // is a token allready waiting?
script->unget = false;
return true;
}
if (!Script_TokenAvailable (script, crossline)) {
if (!crossline) {
if (script->error)
script->error (script, "line is incomplete");
else
script_error (script, "line is incomplete");
}
return false;
}
// copy token
if (*script->p == '"') {
int start_line = script->line;
script->p++;
token_p = script->p;
while (*script->p != '"') {
if (!*script->p) {
script->line = start_line;
if (script->error)
script->error (script, "EOF inside quoted token");
else
script_error (script, "EOF inside quoted token");
return false;
}
if (*script->p == '\n') {
if (script->no_quote_lines) {
if (script->error)
script->error (script, "EOL inside quoted token");
else
script_error (script, "EOL inside quoted token");
}
script->line++;
}
script->p++;
}
dstring_copysubstr (script->token, token_p, script->p - token_p);
script->p++;
} else {
token_p = script->p;
while (*script->p && !isspace ((unsigned char) *script->p))
script->p++;
dstring_copysubstr (script->token, token_p, script->p - token_p);
}
return true;
}
void
Script_UngetToken (script_t *script)
{
script->unget = true;
}

View file

@ -504,7 +504,7 @@ Sys_DebugLog (const char *file, const char *fmt, ...)
}
int
Sys_CheckInput (int idle, int net_socket)
Sys_CheckInput (int idle, unsigned int net_socket)
{
fd_set fdset;
int res;

View file

@ -266,6 +266,7 @@ wad_add (wad_t *wad, const char *filename, const char *lumpname, byte type)
static char buf[4];
Qwrite (wad->handle, buf, 4 - (pf->size & 3));
}
pf->disksize = pf->size;
Hash_AddElement (wad->lump_hash, pf);
return 0;
}
@ -312,6 +313,7 @@ wad_add_data (wad_t *wad, const char *lumpname, byte type, const void *data,
static char buf[4];
Qwrite (wad->handle, buf, 4 - (pf->size & 3));
}
pf->disksize = pf->size;
Hash_AddElement (wad->lump_hash, pf);
return 0;
}

View file

@ -92,9 +92,9 @@ typedef struct memblock_s
struct memzone_s
{
int size; // total bytes malloced, including header
int used; // ammount used, including header
memblock_t blocklist; // start / end cap for linked list
memblock_t *rover;
int pad; // pad to 64 bit boundary
};
@ -105,12 +105,15 @@ Z_ClearZone (memzone_t *zone, int size)
// set the entire zone to one free block
zone->blocklist.next = zone->blocklist.prev = block =
(memblock_t *) ((byte *) zone + sizeof (memzone_t));
block = (memblock_t *) (zone + 1);
zone->blocklist.next = block;
zone->blocklist.prev = block;
zone->blocklist.tag = 1; // in use block
zone->blocklist.id = 0;
zone->blocklist.size = 0;
zone->rover = block;
zone->size = size;
zone->used = sizeof (memzone_t);
block->prev = block->next = &zone->blocklist;
block->tag = 0; // free block
@ -133,6 +136,7 @@ Z_Free (memzone_t *zone, void *ptr)
Sys_Error ("Z_Free: freed a freed pointer");
block->tag = 0; // mark as free
zone->used -= block->size;
other = block->prev;
if (!other->tag) {
@ -219,10 +223,12 @@ Z_TagMalloc (memzone_t *zone, int size, int tag)
base->id = ZONEID;
zone->used += base->size;
// marker for memory trash testing
*(int *) ((byte *) base + base->size - 4) = ZONEID;
return (void *) ((byte *) base + sizeof (memblock_t));
return (void *) (base + 1);
}
void *
@ -254,18 +260,19 @@ Z_Realloc (memzone_t *zone, void *ptr, int size)
return ptr;
}
/*
static void
void
Z_Print (memzone_t *zone)
{
memblock_t *block;
Sys_Printf ("zone size: %i location: %p\n",zone->size,zone);
Sys_Printf ("zone size: %i location: %p used: %i\n",
zone->size, zone, zone->used);
for (block = zone->blocklist.next ; ; block = block->next)
{
Sys_Printf ("block:%p size:%7i tag:%3i\n",
block, block->size, block->tag);
Sys_Printf ("block:%p size:%7i tag:%3i ofs:%d\n",
block, block->size, block->tag, (byte *) block - (byte *) zone);
if (block->next == &zone->blocklist)
break; // all blocks have been hit
@ -275,9 +282,13 @@ Z_Print (memzone_t *zone)
Sys_Printf ("ERROR: next block doesn't have proper back link\n");
if (!block->tag && !block->next->tag)
Sys_Printf ("ERROR: two consecutive free blocks\n");
if (block->tag
&& (*(int *) ((byte *) block + block->size - 4) != ZONEID))
Sys_Printf ("ERROR: memory trashed in block\n");
fflush (stdout);
}
}
*/
void
Z_CheckHeap (memzone_t *zone)
{

View file

@ -193,8 +193,10 @@ R_NewMap (model_t *worldmodel, struct model_s **models, int num_models)
tex = r_worldentity.model->textures[i];
if (!tex)
continue;
if (!strncmp (tex->name, "sky", 3))
if (!strncmp (tex->name, "sky", 3)) {
skytexturenum = i;
R_InitSky (tex);
}
if (!strncmp (tex->name, "window02_1", 10))
mirrortexturenum = i;
tex->texturechain = NULL;

View file

@ -31,6 +31,8 @@
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
#include <stdlib.h>
#include "QF/console.h"
#include "QF/render.h"
#include "QF/sys.h"
@ -38,18 +40,47 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "r_local.h"
mnode_t *r_pefragtopnode;
efrag_t *r_free_efrags;
// FIXME: put this on hunk?
efrag_t r_efrags[MAX_EFRAGS];
vec3_t r_emins, r_emaxs;
typedef struct s_efrag_list {
struct s_efrag_list *next;
efrag_t efrags[MAX_EFRAGS];
} t_efrag_list;
static efrag_t *r_free_efrags;
static t_efrag_list *efrag_list;
/* ENTITY FRAGMENT FUNCTIONS */
efrag_t **lastlink;
static efrag_t **lastlink;
static entity_t *r_addent;
vec3_t r_emins, r_emaxs;
entity_t *r_addent;
static inline void
init_efrag_list (t_efrag_list *efl)
{
int i;
for (i = 0; i < MAX_EFRAGS - 1; i++)
efl->efrags[i].entnext = &efl->efrags[i + 1];
efl->efrags[i].entnext = NULL;
}
void
R_ClearEfrags (void)
{
t_efrag_list *efl;
if (!efrag_list)
efrag_list = calloc (1, sizeof (t_efrag_list));
r_free_efrags = efrag_list->efrags;;
for (efl = efrag_list; efl; efl = efl->next) {
init_efrag_list (efl);
if (efl->next)
efl->efrags[MAX_EFRAGS - 1].entnext = &efl->next->efrags[0];
}
}
/*
R_RemoveEfrags
@ -112,8 +143,11 @@ R_SplitEntityOnNode (mnode_t *node)
// grab an efrag off the free list
ef = r_free_efrags;
if (__builtin_expect (!ef, 0)) {
Con_Printf ("Too many efrags!\n");
return; // no free fragments...
t_efrag_list *efl = calloc (1, sizeof (t_efrag_list));
SYS_CHECKMEM (efl);
efl->next = efrag_list;
efrag_list = efl;
ef = r_free_efrags = &efl->efrags[0];
}
r_free_efrags = r_free_efrags->entnext;
@ -259,15 +293,3 @@ R_StoreEfrags (efrag_t **ppefrag)
}
}
}
void
R_ClearEfrags (void)
{
// allocate the efrags and chain together into a free list
int i;
r_free_efrags = r_efrags;
for (i = 0; i < MAX_EFRAGS - 1; i++)
r_free_efrags[i].entnext = &r_free_efrags[i + 1];
r_free_efrags[i].entnext = NULL;
}

View file

@ -198,6 +198,9 @@ R_NewMap (model_t *worldmodel, struct model_s **models, int num_models)
for (i = 0; i < r_worldentity.model->numleafs; i++)
r_worldentity.model->leafs[i].efrags = NULL;
if (worldmodel->skytexture)
R_InitSky (worldmodel->skytexture);
r_viewleaf = NULL;
R_ClearParticles ();

View file

@ -226,6 +226,9 @@ R_NewMap (model_t *worldmodel, struct model_s **models, int num_models)
for (i = 0; i < r_worldentity.model->numleafs; i++)
r_worldentity.model->leafs[i].efrags = NULL;
if (worldmodel->skytexture)
R_InitSky (worldmodel->skytexture);
r_viewleaf = NULL;
R_ClearParticles ();

View file

@ -166,7 +166,7 @@ _JOY_Read (void)
void
JOY_Read (void)
{
int i;
DWORD i;
DWORD buttonstate, povstate;
if (!joy_found) {

View file

@ -119,7 +119,7 @@ QFGL_LoadLibrary (void)
if (!(handle = LoadLibrary (gl_driver->string)))
Sys_Error ("Couldn't load OpenGL library %s!", gl_driver->string);
(FARPROC) glGetProcAddress = GetProcAddress (handle, "wglGetProcAddress");
glGetProcAddress = (void *(WINAPI *)(const char*)) GetProcAddress (handle, "wglGetProcAddress");
return handle;
}
@ -452,7 +452,7 @@ void
VID_Init (unsigned char *palette)
{
BOOL stat;
int bpp, vid_mode;
WORD bpp, vid_mode;
HDC hdc;
HGLRC baseRC;
DWORD lasterror;

View file

@ -74,13 +74,13 @@ Chase_Reset (void)
// start position 12 units behind head
}
static void
static inline void
TraceLine (vec3_t start, vec3_t end, vec3_t impact)
{
trace_t trace;
memset (&trace, 0, sizeof (trace));
SV_RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, start, end, &trace);
MOD_TraceLine (cl.worldmodel->hulls, 0, start, end, &trace);
VectorCopy (trace.endpos, impact);
}

View file

@ -39,16 +39,18 @@ static __attribute__ ((unused)) const char rcsid[] =
#endif
#include "QF/cbuf.h"
#include "QF/idparse.h"
#include "QF/cmd.h"
#include "QF/cvar.h"
#include "QF/va.h"
#include "QF/screen.h"
#include "QF/msg.h"
#include "QF/model.h"
#include "QF/console.h"
#include "QF/cvar.h"
#include "QF/dstring.h"
#include "QF/idparse.h"
#include "QF/keys.h"
#include "QF/model.h"
#include "QF/msg.h"
#include "QF/screen.h"
#include "QF/script.h"
#include "QF/sys.h"
#include "QF/va.h"
#include "client.h"
#include "compat.h"
@ -410,22 +412,26 @@ Host_Connect_f (void)
Writes a SAVEGAME_COMMENT_LENGTH character comment describing the current
*/
static void
Host_SavegameComment (char *text)
Host_SavegameComment (QFile *file)
{
int i;
char kills[20];
unsigned i;
dstring_t *comment = dstring_newstr ();
for (i = 0; i < SAVEGAME_COMMENT_LENGTH; i++)
text[i] = ' ';
memcpy (text, cl.levelname, strlen (cl.levelname));
snprintf (kills, sizeof (kills), "kills:%3i/%3i", cl.stats[STAT_MONSTERS],
cl.stats[STAT_TOTALMONSTERS]);
memcpy (text + 22, kills, strlen (kills));
dsprintf (comment, "%-21s kills:%3i/%3i", cl.levelname,
cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]);
if ((i = comment->size - 1) < SAVEGAME_COMMENT_LENGTH) {
comment->size = SAVEGAME_COMMENT_LENGTH + 1;
dstring_adjust (comment);
while (i < comment->size - 1)
comment->str[i++] = ' ';
}
comment->str[SAVEGAME_COMMENT_LENGTH] = '\n';
comment->str[SAVEGAME_COMMENT_LENGTH + 1] = '\0';
// convert space to _ to make stdio happy
for (i = 0; i < SAVEGAME_COMMENT_LENGTH; i++)
if (text[i] == ' ')
text[i] = '_';
text[SAVEGAME_COMMENT_LENGTH] = '\0';
if (comment->str[i] == ' ')
comment->str[i] = '_';
Qwrite (file, comment->str, SAVEGAME_COMMENT_LENGTH + 1);
}
static void
@ -434,7 +440,6 @@ Host_Savegame_f (void)
char name[256];
QFile *f;
int i;
char comment[SAVEGAME_COMMENT_LENGTH + 1];
if (cmd_source != src_command)
return;
@ -484,8 +489,7 @@ Host_Savegame_f (void)
}
Qprintf (f, "%i\n", SAVEGAME_VERSION);
Host_SavegameComment (comment);
Qprintf (f, "%s\n", comment);
Host_SavegameComment (f);
for (i = 0; i < NUM_SPAWN_PARMS; i++)
Qprintf (f, "%f\n", svs.clients->spawn_parms[i]);
Qprintf (f, "%d\n", current_skill);
@ -513,77 +517,88 @@ Host_Savegame_f (void)
static void
Host_Loadgame_f (void)
{
char name[MAX_OSPATH];
dstring_t *name = 0;
QFile *f;
char mapname[MAX_QPATH];
char *mapname = 0;
script_t *script = 0;
char *str = 0;
float time, tfloat;
char str[32768];
const char *start;
unsigned int i;
int r;
edict_t *ent;
int entnum;
int version;
float spawn_parms[NUM_SPAWN_PARMS];
char buf[100];
if (cmd_source != src_command)
return;
goto end;
if (Cmd_Argc () != 2) {
Con_Printf ("load <savename> : load a game\n");
return;
goto end;
}
cls.demonum = -1; // stop demo loop in case this fails
snprintf (name, sizeof (name), "%s/%s",
qfs_gamedir->dir.def, Cmd_Argv (1));
QFS_DefaultExtension (name, ".sav");
name = dstring_newstr ();
dsprintf (name, "%s/%s", qfs_gamedir->dir.def, Cmd_Argv (1));
name->size += 4;
dstring_adjust (name);
QFS_DefaultExtension (name->str, ".sav");
// we can't call SCR_BeginLoadingPlaque, because too much stack space has
// been used. The menu calls it before stuffing loadgame command
// SCR_BeginLoadingPlaque ();
Con_Printf ("Loading game from %s...\n", name);
f = QFS_Open (name, "rz");
Con_Printf ("Loading game from %s...\n", name->str);
f = QFS_Open (name->str, "rz");
if (!f) {
Con_Printf ("ERROR: couldn't open.\n");
return;
goto end;
}
str = malloc (Qfilesize (f) + 1);
i = Qread (f, str, Qfilesize (f));
str[i] = 0;
Qclose (f);
Qgets (f, buf, sizeof (buf));
sscanf (buf, "%i\n", &version);
script = Script_New ();
Script_Start (script, name->str, str);
Script_GetToken (script, 1);
sscanf (script->token->str, "%i", &version);
if (version != SAVEGAME_VERSION) {
Qclose (f);
Con_Printf ("Savegame is version %i, not %i\n", version,
SAVEGAME_VERSION);
return;
goto end;
}
Qgets (f, buf, sizeof (buf));
sscanf (buf, "%s\n", str);
// savegame comment (ignored)
Script_GetToken (script, 1);
for (i = 0; i < NUM_SPAWN_PARMS; i++) {
Qgets (f, buf, sizeof (buf));
sscanf (buf, "%f\n", &spawn_parms[i]);
Script_GetToken (script, 1);
sscanf (script->token->str, "%f", &spawn_parms[i]);
}
// this silliness is so we can load 1.06 save files, which have float skill
// values
Qgets (f, buf, sizeof (buf));
sscanf (buf, "%f\n", &tfloat);
Script_GetToken (script, 1);
sscanf (script->token->str, "%f", &tfloat);
current_skill = (int) (tfloat + 0.1);
Cvar_SetValue (skill, (float) current_skill);
Qgets (f, buf, sizeof (buf));
sscanf (buf, "%s\n", mapname);
Qgets (f, buf, sizeof (buf));
sscanf (buf, "%f\n", &time);
Script_GetToken (script, 1);
mapname = strdup (script->token->str);
Script_GetToken (script, 1);
sscanf (script->token->str, "%f", &time);
CL_Disconnect_f ();
SV_SpawnServer (mapname);
if (!sv.active) {
Con_Printf ("Couldn't load map\n");
return;
Con_Printf ("Couldn't load map %s\n", mapname);
goto end;
}
sv.paused = true; // pause until all clients connect
sv.loadgame = true;
@ -591,44 +606,27 @@ Host_Loadgame_f (void)
// load the light styles
for (i = 0; i < MAX_LIGHTSTYLES; i++) {
char *s;
Qgets (f, buf, sizeof (buf));
sscanf (buf, "%s\n", str);
s = Hunk_Alloc (strlen (str) + 1);
strcpy (s, str);
Script_GetToken (script, 1);
s = Hunk_Alloc (strlen (script->token->str) + 1);
strcpy (s, script->token->str);
sv.lightstyles[i] = s;
}
// load the edicts out of the savegame file
entnum = -1; // -1 is the globals
while (!Qeof (f)) {
for (i = 0; i < sizeof (str) - 1; i++) {
r = Qgetc (f);
if (r == EOF || !r)
break;
str[i] = r;
if (r == '}') {
i++;
break;
}
}
if (i == sizeof (str) - 1)
Sys_Error ("Loadgame buffer overflow");
str[i] = 0;
start = str;
start = COM_Parse (str);
if (!com_token[0])
break; // end of file
if (strcmp (com_token, "{"))
while (Script_GetToken (script, 1)) {
if (strcmp (script->token->str, "{"))
Sys_Error ("First token isn't a brace");
if (entnum == -1) { // parse the global vars
ED_ParseGlobals (&sv_pr_state, start);
ED_ParseGlobals (&sv_pr_state, script);
} else { // parse an edict
ent = EDICT_NUM (&sv_pr_state, entnum);
memset (&ent->v, 0, sv_pr_state.progs->entityfields * 4);
ent->free = false;
ED_ParseEdict (&sv_pr_state, start, ent);
ED_ParseEdict (&sv_pr_state, script, ent);
// link it into the bsp tree
if (!ent->free)
@ -641,8 +639,6 @@ Host_Loadgame_f (void)
sv.num_edicts = entnum;
sv.time = time;
Qclose (f);
for (i = 0; i < NUM_SPAWN_PARMS; i++)
svs.clients->spawn_parms[i] = spawn_parms[i];
@ -650,6 +646,15 @@ Host_Loadgame_f (void)
CL_EstablishConnection ("local");
Host_Reconnect_f ();
}
end:
if (mapname)
free (mapname);
if (script)
Script_Delete (script);
if (str)
free (str);
if (name)
dstring_delete (name);
}
//============================================================================

View file

@ -35,6 +35,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "QF/cmd.h"
#include "QF/cvar.h"
#include "QF/msg.h"
#include "QF/mathlib.h"
#include "QF/sys.h"
#include "QF/va.h"
@ -121,7 +122,8 @@ void
SV_StartSound (edict_t *entity, int channel, const char *sample, int volume,
float attenuation)
{
int ent, field_mask, sound_num, i;
int ent, field_mask, sound_num;
vec3_t v;
if (volume < 0 || volume > 255)
Sys_Error ("SV_StartSound: volume = %i", volume);
@ -165,10 +167,9 @@ SV_StartSound (edict_t *entity, int channel, const char *sample, int volume,
MSG_WriteByte (&sv.datagram, attenuation * 64);
MSG_WriteShort (&sv.datagram, channel);
MSG_WriteByte (&sv.datagram, sound_num);
for (i=0; i < 3; i++) // FIXME: replace with MSG_WriteCoordV?
MSG_WriteCoord (&sv.datagram, SVvector (entity, origin)[i] + 0.5 *
(SVvector (entity, mins)[i] +
SVvector (entity, maxs)[i]));
VectorBlend (SVvector (entity, mins), SVvector (entity, maxs), 0.5, v);
VectorAdd (v, SVvector (entity, origin), v);
MSG_WriteCoordV (&sv.datagram, v);
}
// CLIENT SPAWNING ============================================================
@ -509,6 +510,7 @@ void
SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
{
int bits, items, i;
vec3_t v;
edict_t *other;
// send a damage message
@ -517,10 +519,9 @@ SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
MSG_WriteByte (msg, svc_damage);
MSG_WriteByte (msg, SVfloat (ent, dmg_save));
MSG_WriteByte (msg, SVfloat (ent, dmg_take));
for (i=0; i < 3; i++) // FIXME: replace with MSG_WriteCoordV
MSG_WriteCoord (msg, SVvector (other, origin)[i] + 0.5 *
(SVvector (other, mins)[i] +
SVvector (other, maxs)[i]));
VectorBlend (SVvector (other, mins), SVvector (other, maxs), 0.5, v);
VectorAdd (v, SVvector (other, origin), v);
MSG_WriteCoordV (msg, v);
SVfloat (ent, dmg_take) = 0;
SVfloat (ent, dmg_save) = 0;
}
@ -1010,6 +1011,7 @@ SV_SpawnServer (const char *server)
// serverflags are for cross level information (sigils)
*sv_globals.serverflags = svs.serverflags;
*sv_globals.time = sv.time;
if ((buf = QFS_LoadFile (va ("maps/%s.ent", server), 0))) {
ED_LoadFromFile (&sv_pr_state, buf);
free (buf);

View file

@ -37,7 +37,6 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "host.h"
#include "server.h"
#include "sv_progs.h"
#include "world.h"
#define sv_frametime host_frametime
@ -93,9 +92,6 @@ SV_CheckAllEnts (void)
void
SV_CheckVelocity (edict_t *ent)
{
#if 0
float wishspeed;
#endif
int i;
// bound velocity
@ -112,29 +108,20 @@ SV_CheckVelocity (edict_t *ent)
classname)));
SVvector (ent, origin)[i] = 0;
}
#if 1
if (SVvector (ent, velocity)[i] > sv_maxvelocity->value)
SVvector (ent, velocity)[i] = sv_maxvelocity->value;
else if (SVvector (ent, velocity)[i] < -sv_maxvelocity->value)
SVvector (ent, velocity)[i] = -sv_maxvelocity->value;
#endif
}
#if 0
wishspeed = VectorLength (SVvector (ent, velocity));
if (wishspeed > sv_maxvelocity->value) {
VectorScale (SVvector (ent, velocity), sv_maxvelocity->value /
wishspeed, SVvector (ent, velocity));
}
#endif
}
/*
SV_RunThink
SV_RunThink
Runs thinking code if time. There is some play in the exact time the think
function will be called, because it is called before any movement is done
in a frame. Not used for pushmove objects, because they must be exact.
Returns false if the entity removed itself.
Runs thinking code if time. There is some play in the exact time the think
function will be called, because it is called before any movement is done
in a frame. Not used for pushmove objects, because they must be exact.
Returns false if the entity removed itself.
*/
qboolean
SV_RunThink (edict_t *ent)
@ -188,10 +175,10 @@ SV_Impact (edict_t *e1, edict_t *e2)
}
/*
ClipVelocity
ClipVelocity
Slide off of the impacting object
returns the blocked flags (1 = floor, 2 = step / wall)
Slide off of the impacting object
returns the blocked flags (1 = floor, 2 = step / wall)
*/
static int
ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce)
@ -743,6 +730,7 @@ SV_RunEntity (edict_t *ent)
default:
Sys_Error ("SV_Physics: bad movetype %i",
(int) SVfloat (ent, movetype));
break;
}
}

View file

@ -1440,6 +1440,9 @@ static builtin_t builtins[] = {
{"freeboxhull", PF_freeboxhull, QF 96},
{"rotate_bbox", PF_rotate_bbox, QF 97},
{"checkextension", PF_checkextension, QF 99},
{"EntityParseFunction", ED_EntityParseFunction, -1},
{0}
};

View file

@ -139,7 +139,7 @@ ED_Count_f (void)
ED_Count (&sv_pr_state);
}
void
static void
PR_Profile_f (void)
{
if (!sv_pr_state.progs) {
@ -359,66 +359,102 @@ set_address (sv_def_t *def, void *address)
}
}
static int
resolve_globals (progs_t *pr, sv_def_t *def, int mode)
{
ddef_t *ddef;
int ret = 1;
if (mode == 2) {
for (; def->name; def++)
set_address (def, &G_FLOAT (pr, def->offset));
return 1;
}
for (; def->name; def++) {
ddef = PR_FindGlobal (pr, def->name);
if (ddef) {
set_address (def, &G_FLOAT(pr, ddef->ofs));
} else if (mode) {
PR_Undefined (pr, "global", def->name);
ret = 0;
}
}
return ret;
}
static int
resolve_functions (progs_t *pr, sv_def_t *def, int mode)
{
dfunction_t *dfunc;
int ret = 1;
if (mode == 2) {
for (; def->name; def++)
*(func_t *) def->field = G_FUNCTION (pr, def->offset);
return 1;
}
for (; def->name; def++) {
dfunc = PR_FindFunction (pr, def->name);
if (dfunc) {
*(func_t *) def->field = dfunc - pr->pr_functions;
} else if (mode) {
PR_Undefined (pr, "function", def->name);
ret = 0;
}
}
return ret;
}
static int
resolve_fields (progs_t *pr, sv_def_t *def, int mode)
{
ddef_t *ddef;
int ret = 1;
if (mode == 2) {
for (; def->name; def++)
*(int *) def->field = def->offset;
return 1;
}
for (; def->name; def++) {
*(int *)def->field = -1;
ddef = PR_FindField (pr, def->name);
if (ddef) {
*(int *)def->field = ddef->ofs;
} else if (mode) {
PR_Undefined (pr, "field", def->name);
ret = 0;
}
}
return ret;
}
static int
resolve (progs_t *pr)
{
sv_def_t *def;
ddef_t *ddef;
dfunction_t *f;
void *global;
func_t func;
int ret = 1;
if (pr->progs->crc == nq_crc) {
global = &G_FLOAT(pr, nq_self[0].offset);
set_address (&nq_self[0], global);
for (def = nq_defs; def->name; def++) {
global = &G_FLOAT(pr, def->offset);
set_address (def, global);
}
for (def = nq_funcs; def->name; def++) {
func = G_FUNCTION (pr, def->offset);
*(func_t *)def->field = func;
}
for (def = nq_fields; def->name; def++) {
*(int *)def->field = def->offset;
}
resolve_globals (pr, nq_self, 2);
resolve_globals (pr, nq_defs, 2);
resolve_functions (pr, nq_funcs, 2);
resolve_fields (pr, nq_fields, 2);
} else {
for (def = nq_self; def->name; def++) {
ddef = PR_FindGlobal (&sv_pr_state, def->name);
if (ddef) {
global = &G_FLOAT(pr, ddef->ofs);
set_address (def, global);
}
}
for (def = nq_defs; def->name; def++) {
global = PR_GetGlobalPointer (pr, def->name);
set_address (def, global);
}
for (def = nq_funcs; def->name; def++) {
*(func_t *)def->field = PR_GetFunctionIndex (pr, def->name);
}
for (def = nq_fields; def->name; def++) {
*(int *)def->field = PR_GetFieldOffset (pr, def->name);
}
}
for (def = nq_opt_defs; def->name; def++) {
ddef = PR_FindGlobal (&sv_pr_state, def->name);
if (ddef) {
global = &G_FLOAT(pr, ddef->ofs);
set_address (def, global);
}
}
for (def = nq_opt_funcs; def->name; def++) {
if ((f = ED_FindFunction (pr, def->name)) != NULL)
*(func_t *)def->field = (func_t) (f - pr->pr_functions);
}
for (def = nq_opt_fields; def->name; def++) {
*(int *)def->field = ED_GetFieldIndex (pr, def->name);
if (!resolve_globals (pr, nq_self, 0))
ret = 0;
if (!resolve_globals (pr, nq_defs, 1))
ret = 0;
if (!resolve_functions (pr, nq_funcs, 1))
ret = 0;
if (!resolve_fields (pr, nq_fields, 1))
ret = 0;
}
resolve_globals (pr, nq_opt_defs, 0);
resolve_functions (pr, nq_opt_funcs, 0);
resolve_fields (pr, nq_opt_fields, 0);
// progs engine needs these globals anyway
sv_pr_state.globals.self = sv_globals.self;
sv_pr_state.globals.time = sv_globals.time;
return 1;
return ret;
}
void
@ -457,7 +493,6 @@ SV_Progs_Init (void)
{
sv_pr_state.edicts = &sv.edicts;
sv_pr_state.num_edicts = &sv.num_edicts;
sv_pr_state.time = &sv.time;
sv_pr_state.reserved_edicts = &svs.maxclients;
sv_pr_state.unlink = SV_UnlinkEdict;
sv_pr_state.parse_field = parse_field;

View file

@ -647,8 +647,8 @@ SV_ClipToLinks (areanode_t *node, moveclip_t * clip)
if (SVfloat (touch, solid) == SOLID_TRIGGER)
Sys_Error ("Trigger in clipping list");
if (clip->type == MOVE_NOMONSTERS && SVfloat (touch, solid)
!= SOLID_BSP)
if (clip->type == MOVE_NOMONSTERS
&& SVfloat (touch, solid) != SOLID_BSP)
continue;
if (clip->boxmins[0] > SVvector (touch, absmax)[0]

View file

@ -1,469 +0,0 @@
/*
net_svc.h
(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$
*/
#ifndef NET_SVC_H
#define NET_SVC_H
#include "QF/mathlib.h"
#include "QF/msg.h"
#include "bothdefs.h"
#include "pmove.h"
typedef enum
{
NET_OK,
NET_SHORT,
NET_ERROR
} net_status_t;
typedef struct net_svc_nop_s
{
} net_svc_nop_t;
typedef struct net_svc_disconnect_s
{
} net_svc_disconnect_t;
typedef struct net_svc_print_s
{
byte level;
const char *message;
} net_svc_print_t;
typedef struct net_svc_centerprint_s
{
const char *message;
} net_svc_centerprint_t;
typedef struct net_svc_stufftext_s
{
const char *commands;
} net_svc_stufftext_t;
typedef struct net_svc_damage_s
{
byte armor;
byte blood;
vec3_t from;
} net_svc_damage_t;
typedef struct net_svc_serverdata_s
{
int protocolversion;
int servercount; // FIXME: rename this
const char *gamedir;
byte playernum;
qboolean spectator;
const char *levelname;
movevars_t movevars;
} net_svc_serverdata_t;
typedef struct net_svc_setangle_s
{
vec3_t angles;
} net_svc_setangle_t;
typedef struct net_svc_lightstyle_s
{
byte stylenum;
const char *map;
} net_svc_lightstyle_t;
typedef struct net_svc_sound_s
{
short channel;
float volume;
float attenuation;
byte sound_num;
vec3_t position;
int entity;
} net_svc_sound_t;
typedef struct net_svc_stopsound_s
{
int entity;
int channel;
} net_svc_stopsound_t;
typedef struct net_svc_updatefrags_s
{
byte player;
short frags;
} net_svc_updatefrags_t;
typedef struct net_svc_updateping_s
{
byte player;
short ping;
} net_svc_updateping_t;
typedef struct net_svc_updatepl_s
{
byte player;
byte packetloss;
} net_svc_updatepl_t;
typedef struct net_svc_updateentertime_s
{
byte player;
float secondsago;
} net_svc_updateentertime_t;
typedef struct net_svc_spawnbaseline_s
{
short num;
byte modelindex;
byte frame;
byte colormap;
byte skinnum;
vec3_t origin;
vec3_t angles;
} net_svc_spawnbaseline_t;
typedef struct net_svc_spawnstatic_s
{
byte modelindex;
byte frame;
byte colormap;
byte skinnum;
vec3_t origin;
vec3_t angles;
} net_svc_spawnstatic_t;
typedef struct net_svc_tempentity_s
{
byte type;
vec3_t position;
byte gunshotcount; // gunshot sparks
byte colorstart; // palette start (I think?)
byte colorlength; // palette length
vec3_t beamend; // beam endpos
short beamentity; // beam entity
} net_svc_tempentity_t;
typedef struct net_svc_killedmonster_s
{
} net_svc_killedmonster_t;
typedef struct net_svc_foundsecret_s
{
} net_svc_foundsecret_t;
typedef struct net_svc_spawnstaticsound_s
{
vec3_t position;
byte sound_num;
byte volume;
byte attenuation; // FIXME: should be a float (convert usages)
} net_svc_spawnstaticsound_t;
typedef struct net_svc_updatestat_s
{
byte stat;
byte value;
} net_svc_updatestat_t;
typedef struct net_svc_updatestatlong_s
{
byte stat;
int value;
} net_svc_updatestatlong_t;
typedef struct net_svc_cdtrack_s
{
byte cdtrack;
} net_svc_cdtrack_t;
typedef struct net_svc_intermission_s
{
vec3_t origin;
vec3_t angles;
} net_svc_intermission_t;
typedef struct net_svc_finale_s
{
const char *message;
} net_svc_finale_t;
typedef struct net_svc_sellscreen_s
{
} net_svc_sellscreen_t;
typedef struct net_svc_smallkick_s
{
} net_svc_smallkick_t;
typedef struct net_svc_bigkick_s
{
} net_svc_bigkick_t;
typedef struct net_svc_muzzleflash_s
{
short player;
} net_svc_muzzleflash_t;
typedef struct net_svc_updateuserinfo_s
{
byte slot;
int userid;
const char *userinfo;
} net_svc_updateuserinfo_t;
typedef struct net_svc_setinfo_s
{
byte slot;
const char *key;
const char *value;
} net_svc_setinfo_t;
typedef struct net_svc_serverinfo_s
{
const char *key;
const char *value;
} net_svc_serverinfo_t;
typedef struct net_svc_download_s
{
short size;
byte percent;
const char *name; // only one of name or data will be set
const byte *data;
} net_svc_download_t;
typedef struct net_svc_playerinfo_s
{
byte playernum;
int flags;
vec3_t origin;
byte frame;
byte msec;
usercmd_t usercmd;
vec3_t velocity;
byte modelindex;
byte skinnum;
byte effects;
byte weaponframe;
} net_svc_playerinfo_t;
typedef struct net_svc_nails_s
{
byte numnails;
struct {
vec3_t origin;
vec3_t angles;
} nails[MAX_PROJECTILES];
} net_svc_nails_t;
typedef struct net_svc_chokecount_s
{
byte count;
} net_svc_chokecount_t;
typedef struct net_svc_modellist_s
{
byte startmodel;
const char *models[MAX_MODELS + 1]; // space left for terminating
// empty string
byte nextmodel;
} net_svc_modellist_t;
typedef struct net_svc_soundlist_s
{
byte startsound;
const char *sounds[MAX_SOUNDS + 1]; // space left for terminating
// empty string
byte nextsound;
} net_svc_soundlist_t;
typedef struct net_svc_packetentities_s
{
int numwords, numdeltas;
unsigned int words[MAX_PACKET_ENTITIES * 2 + 1];
entity_state_t deltas[MAX_PACKET_ENTITIES];
} net_svc_packetentities_t;
typedef struct net_svc_deltapacketentities_s
{
int numwords, numdeltas;
byte from;
unsigned int words[MAX_PACKET_ENTITIES * 2 + 1];
entity_state_t deltas[MAX_PACKET_ENTITIES];
} net_svc_deltapacketentities_t;
typedef struct net_svc_maxspeed_s
{
float maxspeed;
} net_svc_maxspeed_t;
typedef struct net_svc_entgravity_s
{
float gravity;
} net_svc_entgravity_t;
typedef struct net_svc_setpause_s
{
byte paused;
} net_svc_setpause_t;
const char *NET_SVC_GetString (int type);
net_status_t NET_SVC_NOP_Emit (net_svc_nop_t *block, sizebuf_t *buf);
net_status_t NET_SVC_NOP_Parse (net_svc_nop_t *block, qmsg_t *msg);
net_status_t NET_SVC_Disconnect_Emit (net_svc_disconnect_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_Disconnect_Parse (net_svc_disconnect_t *block, qmsg_t *msg);
net_status_t NET_SVC_Print_Emit (net_svc_print_t *block, sizebuf_t *buf);
net_status_t NET_SVC_Print_Parse (net_svc_print_t *block, qmsg_t *msg);
net_status_t NET_SVC_Centerprint_Emit (net_svc_centerprint_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_Centerprint_Parse (net_svc_centerprint_t *block,
qmsg_t *msg);
net_status_t NET_SVC_Stufftext_Emit (net_svc_stufftext_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_Stufftext_Parse (net_svc_stufftext_t *block, qmsg_t *msg);
net_status_t NET_SVC_Damage_Emit (net_svc_damage_t *block, sizebuf_t *buf);
net_status_t NET_SVC_Damage_Parse (net_svc_damage_t *block, qmsg_t *msg);
net_status_t NET_SVC_ServerData_Emit (net_svc_serverdata_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_ServerData_Parse (net_svc_serverdata_t *block, qmsg_t *msg);
net_status_t NET_SVC_SetAngle_Emit (net_svc_setangle_t *block, sizebuf_t *buf);
net_status_t NET_SVC_SetAngle_Parse (net_svc_setangle_t *block, qmsg_t *msg);
net_status_t NET_SVC_LightStyle_Emit (net_svc_lightstyle_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_LightStyle_Parse (net_svc_lightstyle_t *block, qmsg_t *msg);
net_status_t NET_SVC_Sound_Emit (net_svc_sound_t *block, sizebuf_t *buf);
net_status_t NET_SVC_Sound_Parse (net_svc_sound_t *block, qmsg_t *msg);
net_status_t NET_SVC_StopSound_Emit (net_svc_stopsound_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_StopSound_Parse (net_svc_stopsound_t *block, qmsg_t *msg);
net_status_t NET_SVC_UpdateFrags_Emit (net_svc_updatefrags_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_UpdateFrags_Parse (net_svc_updatefrags_t *block,
qmsg_t *msg);
net_status_t NET_SVC_UpdatePing_Emit (net_svc_updateping_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_UpdatePing_Parse (net_svc_updateping_t *block, qmsg_t *msg);
net_status_t NET_SVC_UpdatePL_Emit (net_svc_updatepl_t *block, sizebuf_t *buf);
net_status_t NET_SVC_UpdatePL_Parse (net_svc_updatepl_t *block, qmsg_t *msg);
net_status_t NET_SVC_UpdateEnterTime_Emit (net_svc_updateentertime_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_UpdateEnterTime_Parse (net_svc_updateentertime_t *block,
qmsg_t *msg);
net_status_t NET_SVC_SpawnBaseline_Emit (net_svc_spawnbaseline_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_SpawnBaseline_Parse (net_svc_spawnbaseline_t *block,
qmsg_t *msg);
net_status_t NET_SVC_SpawnStatic_Emit (net_svc_spawnstatic_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_SpawnStatic_Parse (net_svc_spawnstatic_t *block,
qmsg_t *msg);
net_status_t NET_SVC_TempEntity_Emit (net_svc_tempentity_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_TempEntity_Parse (net_svc_tempentity_t *block, qmsg_t *msg);
net_status_t NET_SVC_KilledMonster_Emit (net_svc_killedmonster_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_KilledMonster_Parse (net_svc_killedmonster_t *block,
qmsg_t *msg);
net_status_t NET_SVC_FoundSecret_Emit (net_svc_foundsecret_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_FoundSecret_Parse (net_svc_foundsecret_t *block,
qmsg_t *msg);
net_status_t NET_SVC_SpawnStaticSound_Emit (net_svc_spawnstaticsound_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_SpawnStaticSound_Parse (net_svc_spawnstaticsound_t *block,
qmsg_t *msg);
net_status_t NET_SVC_UpdateStat_Emit (net_svc_updatestat_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_UpdateStat_Parse (net_svc_updatestat_t *block, qmsg_t *msg);
net_status_t NET_SVC_UpdateStatLong_Emit (net_svc_updatestatlong_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_UpdateStatLong_Parse (net_svc_updatestatlong_t *block,
qmsg_t *msg);
net_status_t NET_SVC_CDTrack_Emit (net_svc_cdtrack_t *block, sizebuf_t *buf);
net_status_t NET_SVC_CDTrack_Parse (net_svc_cdtrack_t *block, qmsg_t *msg);
net_status_t NET_SVC_Intermission_Emit (net_svc_intermission_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_Intermission_Parse (net_svc_intermission_t *block,
qmsg_t *msg);
net_status_t NET_SVC_Finale_Emit (net_svc_finale_t *block, sizebuf_t *buf);
net_status_t NET_SVC_Finale_Parse (net_svc_finale_t *block, qmsg_t *msg);
net_status_t NET_SVC_SellScreen_Emit (net_svc_sellscreen_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_SellScreen_Parse (net_svc_sellscreen_t *block, qmsg_t *msg);
net_status_t NET_SVC_SmallKick_Emit (net_svc_smallkick_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_SmallKick_Parse (net_svc_smallkick_t *block, qmsg_t *msg);
net_status_t NET_SVC_BigKick_Emit (net_svc_bigkick_t *block, sizebuf_t *buf);
net_status_t NET_SVC_BigKick_Parse (net_svc_bigkick_t *block, qmsg_t *msg);
net_status_t NET_SVC_MuzzleFlash_Emit (net_svc_muzzleflash_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_MuzzleFlash_Parse (net_svc_muzzleflash_t *block,
qmsg_t *msg);
net_status_t NET_SVC_UpdateUserInfo_Emit (net_svc_updateuserinfo_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_UpdateUserInfo_Parse (net_svc_updateuserinfo_t *block,
qmsg_t *msg);
net_status_t NET_SVC_SetInfo_Emit (net_svc_setinfo_t *block, sizebuf_t *buf);
net_status_t NET_SVC_SetInfo_Parse (net_svc_setinfo_t *block, qmsg_t *msg);
net_status_t NET_SVC_ServerInfo_Emit (net_svc_serverinfo_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_ServerInfo_Parse (net_svc_serverinfo_t *block, qmsg_t *msg);
net_status_t NET_SVC_Download_Emit (net_svc_download_t *block, sizebuf_t *buf);
net_status_t NET_SVC_Download_Parse (net_svc_download_t *block, qmsg_t *msg);
net_status_t NET_SVC_Playerinfo_Emit (net_svc_playerinfo_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_Playerinfo_Parse (net_svc_playerinfo_t *block, qmsg_t *msg);
net_status_t NET_SVC_Nails_Emit (net_svc_nails_t *block, sizebuf_t *buf);
net_status_t NET_SVC_Nails_Parse (net_svc_nails_t *block, qmsg_t *msg);
net_status_t NET_SVC_ChokeCount_Emit (net_svc_chokecount_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_ChokeCount_Parse (net_svc_chokecount_t *block, qmsg_t *msg);
net_status_t NET_SVC_Modellist_Emit (net_svc_modellist_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_Modellist_Parse (net_svc_modellist_t *block, qmsg_t *msg);
net_status_t NET_SVC_Soundlist_Emit (net_svc_soundlist_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_Soundlist_Parse (net_svc_soundlist_t *block, qmsg_t *msg);
net_status_t NET_SVC_PacketEntities_Emit (net_svc_packetentities_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_PacketEntities_Parse (net_svc_packetentities_t *block,
qmsg_t *msg);
net_status_t NET_SVC_DeltaPacketEntities_Emit (net_svc_deltapacketentities_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_DeltaPacketEntities_Parse (net_svc_deltapacketentities_t *block,
qmsg_t *msg);
net_status_t NET_SVC_MaxSpeed_Emit (net_svc_maxspeed_t *block, sizebuf_t *buf);
net_status_t NET_SVC_MaxSpeed_Parse (net_svc_maxspeed_t *block, qmsg_t *msg);
net_status_t NET_SVC_EntGravity_Emit (net_svc_entgravity_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_EntGravity_Parse (net_svc_entgravity_t *block, qmsg_t *msg);
net_status_t NET_SVC_SetPause_Emit (net_svc_setpause_t *block, sizebuf_t *buf);
net_status_t NET_SVC_SetPause_Parse (net_svc_setpause_t *block, qmsg_t *msg);
#endif // NET_SVC_H

View file

@ -33,29 +33,12 @@
#include "QF/mathlib.h"
#include "QF/model.h"
#include "world.h"
#define STOP_EPSILON 0.1
typedef struct
{
vec3_t normal;
float dist;
} pmplane_t;
typedef struct
{
qboolean allsolid; // if true, plane is not valid
qboolean startsolid; // if true, the initial point was in a solid area
qboolean inopen, inwater;
float fraction; // time completed, 1.0 = didn't hit anything
vec3_t endpos; // final position
pmplane_t plane; // surface normal at impact
int ent; // entity the surface is on
} pmtrace_t;
#define MAX_PHYSENTS (MAX_CLIENTS + MAX_PACKET_ENTITIES)
typedef struct
{
typedef struct {
vec3_t origin;
model_t *model; // only for bsp models
vec3_t mins, maxs; // only for non-bsp models
@ -64,31 +47,30 @@ typedef struct
} physent_t;
typedef struct
{
int sequence; // just for debugging prints
typedef struct {
int sequence; // just for debugging prints
// player state
vec3_t origin;
vec3_t angles;
vec3_t velocity;
int oldbuttons;
int oldonground;
float waterjumptime;
qboolean dead;
qboolean flying;
int spectator;
vec3_t origin;
vec3_t angles;
vec3_t velocity;
int oldbuttons;
int oldonground;
float waterjumptime;
qboolean dead;
qboolean flying;
int spectator;
// world state
int numphysent;
physent_t physents[MAX_PHYSENTS]; // 0 should be the world
int numphysent;
physent_t physents[MAX_PHYSENTS]; // 0 should be the world
// input
usercmd_t cmd;
usercmd_t cmd;
// results
int numtouch;
int touchindex[MAX_PHYSENTS];
int numtouch;
physent_t *touchindex[MAX_PHYSENTS];
} playermove_t;
typedef struct {
@ -126,9 +108,6 @@ int PM_HullPointContents (hull_t *hull, int num, const vec3_t p);
int PM_PointContents (const vec3_t point);
qboolean PM_TestPlayerPosition (const vec3_t point);
pmtrace_t PM_PlayerMove (const vec3_t start, const vec3_t stop);
qboolean PM_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f,
const vec3_t p1, const vec3_t p2,
pmtrace_t *trace);
trace_t PM_PlayerMove (const vec3_t start, const vec3_t stop);
#endif // _PMOVE_H

View file

@ -29,11 +29,6 @@
#ifndef __sv_pr_cmds_h
#define __sv_pr_cmds_h
#ifndef PROGS_T
typedef struct progs_s progs_t;
# define PROGS_T
#endif
void PF_error (progs_t *pr);
void PF_objerror (progs_t *pr);
void PF_makevectors (progs_t *pr);

View file

@ -202,7 +202,7 @@ Cam_Lock (int playernum)
Sbar_Changed ();
}
static pmtrace_t
static trace_t
Cam_DoTrace (vec3_t vec1, vec3_t vec2)
{
#if 0
@ -223,7 +223,7 @@ Cam_TryFlyby (player_state_t * self, player_state_t * player, vec3_t vec,
qboolean checkvis)
{
float len;
pmtrace_t trace;
trace_t trace;
vec3_t v;
vectoangles (vec, v);
@ -256,7 +256,7 @@ static qboolean
Cam_IsVisible (player_state_t * player, vec3_t vec)
{
float d;
pmtrace_t trace;
trace_t trace;
vec3_t v;
trace = Cam_DoTrace (player->origin, vec);
@ -682,10 +682,10 @@ CL_Cam_Init_Cvars (void)
static void
TraceLine (vec3_t start, vec3_t end, vec3_t impact)
{
pmtrace_t trace;
trace_t trace;
memset (&trace, 0, sizeof (trace));
PM_RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, start, end, &trace);
MOD_TraceLine (cl.worldmodel->hulls, 0, start, end, &trace);
VectorCopy (trace.endpos, impact);
}

Some files were not shown because too many files have changed in this diff Show more