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. 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 autoconf 2.50 or later
* GNU automake 1.6 or later * GNU automake 1.6 or later

View file

@ -1123,7 +1123,11 @@ dnl Checks for CD-ROM
dnl ================================================================== dnl ==================================================================
CD_CFLAGS="" 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 unset CDTYPE
AC_MSG_CHECKING(for CD audio support) AC_MSG_CHECKING(for CD audio support)
@ -1998,7 +2002,10 @@ if test "x$static_plugins" = xyes; then
else else
plugin_ldflags="$plugin_ldflags"' -version-info $(plugin_version) -rpath $(plugindir)' plugin_ldflags="$plugin_ldflags"' -version-info $(plugin_version) -rpath $(plugindir)'
fi 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="" SERVER_PLUGIN_STATIC_LIBS=""
CLIENT_PLUGIN_STATIC_LIBS="" CLIENT_PLUGIN_STATIC_LIBS=""
CD_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/install.quake data/docs/install.quake2 data/docs/readme \
data/docs/readme.glquake data/docs/readme.squake data/docs/readme.x11 \ 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 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 # directories like "/usr/src/myproject". Separate the files or directories
# with spaces. # with spaces.
INPUT = @top_srcdir@/include @top_srcdir@/libs @top_srcdir@/nq INPUT = @top_srcdir@/include
INPUT += @top_srcdir@/qw @top_srcdir@/tools 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 # 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 # 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 # 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. # subdirectory from a directory tree whose root is specified with the INPUT tag.
EXCLUDE = qc-lex.c qc-parse.c qc-parse.h EXCLUDE = @top_srcdir@/tools/qfcc/source/qc-lex.c
EXCLUDE += fbset_modes_l.c fbset_modes_y.c fbset_modes_y.h 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@/tools/Forge
EXCLUDE += @top_srcdir@/include/QF/GL
# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories # 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. # 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 # directories that contain example code fragments that are included (see
# the \include command). # 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 # 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 # 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 # directories that contain image that are included in the documentation (see
# the \image command). # 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 # 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 # 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 # 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. # 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 # Setting the INLINE_SOURCES tag to YES will include the body
# of functions and classes directly in the documentation. # 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 \ 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 \ 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 \ 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 \ riff.h ruamoko.h screen.h script.h sizebuf.h skin.h sound.h spritegn.h \
teamplay.h tga.h uint32.h va.h ver_check.h vid.h view.h wad.h wadfile.h \ sys.h teamplay.h tga.h uint32.h va.h ver_check.h vid.h view.h wad.h \
zone.h \ wadfile.h zone.h \
\ \
GL/ati.h GL/defines.h GL/extensions.h GL/funcs.h GL/qf_explosions.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 \ GL/qf_funcs_list.h GL/qf_lightmap.h GL/qf_noisetextures.h \

View file

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

View file

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

View file

@ -29,6 +29,13 @@
#ifndef __QF_cmd_h #ifndef __QF_cmd_h
#define __QF_cmd_h #define __QF_cmd_h
/** \addtogroup utils */
//@{
/** \defgroup cmd Command management.
*/
//@{
#include "QF/qtypes.h" #include "QF/qtypes.h"
typedef void (*xcommand_t) (void); 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 cbuf_args_s *cmd_args;
extern struct cvar_s *cmd_warncmd; extern struct cvar_s *cmd_warncmd;
//@}
//@}
#endif//__QF_cmd_h #endif//__QF_cmd_h

View file

@ -29,6 +29,13 @@
#ifndef __crc_h #ifndef __crc_h
#define __crc_h #define __crc_h
/** \addtogroup utils */
//@{
/** \defgroup crc Checksum generation.
*/
//@{
#include "QF/qtypes.h" #include "QF/qtypes.h"
void CRC_Init(unsigned short *crcvalue); 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_Value(unsigned short crcvalue);
unsigned short CRC_Block (byte *start, int count); unsigned short CRC_Block (byte *start, int count);
//@}
//@}
#endif // __crc_h #endif // __crc_h

View file

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

View file

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

View file

@ -29,6 +29,13 @@
#ifndef __hash_h #ifndef __hash_h
#define __hash_h #define __hash_h
/** \addtogroup utils */
//@{
/** \defgroup hash Hash tables
*/
//@{
typedef struct hashtab_s hashtab_t; typedef struct hashtab_s hashtab_t;
/** create a new hash table: /** create a new hash table:
@ -105,7 +112,9 @@ void *Hash_FindElement (hashtab_t *tab, void *ele);
tab: the table to search tab: the table to search
key: the key string identifying the elements being searched for key: the key string identifying the elements being searched for
returns a null terminated list of element pointers if at least one found, 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_FindList (hashtab_t *tab, const char *key);
void **Hash_FindElementList (hashtab_t *tab, void *ele); void **Hash_FindElementList (hashtab_t *tab, void *ele);
@ -152,4 +161,7 @@ void **Hash_GetList (hashtab_t *tab);
*/ */
void Hash_Stats (hashtab_t *tab); void Hash_Stats (hashtab_t *tab);
//@}
//@}
#endif // __hash_h #endif // __hash_h

View file

@ -31,6 +31,13 @@
#ifndef __QF_idparse_h #ifndef __QF_idparse_h
#define __QF_idparse_h #define __QF_idparse_h
/** \addtogroup utils */
//@{
/** \addtogroup cbuf
*/
//@{
extern const char *com_token; extern const char *com_token;
struct cbuf_args_s; 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; extern struct cbuf_interpreter_s id_interp;
//@}
//@}
#endif//__QF_idparse_h #endif//__QF_idparse_h

View file

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

View file

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

View file

@ -30,6 +30,13 @@
#ifndef __mdfour_h #ifndef __mdfour_h
#define __mdfour_h #define __mdfour_h
/** \addtogroup utils */
//@{
/** \addtogroup crc
*/
//@{
#include "QF/uint32.h" #include "QF/uint32.h"
#define MDFOUR_DIGEST_BYTES 16 #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_result(struct mdfour *md, unsigned char *out); // old: MD4Final
void mdfour(unsigned char *out, const unsigned char *in, int n); void mdfour(unsigned char *out, const unsigned char *in, int n);
//@}
//@}
#endif // __mdfour_h #endif // __mdfour_h

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -370,7 +370,7 @@ typedef struct pr_va_list_s {
} pr_va_list_t; } pr_va_list_t;
#define PROG_ID_VERSION 6 #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 { typedef struct dprograms_s {
unsigned int version; unsigned int version;

View file

@ -106,8 +106,8 @@ typedef struct pr_protocol_s {
pointer_t class_pointer; // pr_class_t pointer_t class_pointer; // pr_class_t
string_t protocol_name; string_t protocol_name;
pointer_t protocol_list; // pr_protocol_list_t pointer_t protocol_list; // pr_protocol_list_t
pointer_t instance_methods; // pr_method_list_t pointer_t instance_methods; // pr_method_description_list_t
pointer_t class_methods; // pr_method_list_t pointer_t class_methods; // pr_method_description_list_t
} pr_protocol_t; } pr_protocol_t;
typedef struct pr_category_s { typedef struct pr_category_s {
@ -121,20 +121,29 @@ typedef struct pr_category_s {
typedef struct pr_protocol_list_s { typedef struct pr_protocol_list_s {
pointer_t next; pointer_t next;
int count; int count;
pointer_t list[1]; pointer_t list[1]; // pr_protocol_t
} pr_protocol_list_t; } pr_protocol_list_t;
typedef struct pr_method_list_s { typedef struct pr_method_list_s {
pointer_t method_next; pointer_t method_next;
int method_count; int method_count;
struct pr_method_s { struct pr_method_s {
pr_sel_t method_name; pointer_t method_name; // pr_sel_t
string_t method_types; string_t method_types;
func_t method_imp; // typedef id (id, SEL, ...) IMP func_t method_imp; // typedef id (id, SEL, ...) IMP
} method_list[1]; } method_list[1];
} pr_method_list_t; } pr_method_list_t;
typedef struct pr_method_s pr_method_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 { typedef struct pr_ivar_list_s {
int ivar_count; int ivar_count;
struct pr_ivar_s { struct pr_ivar_s {
@ -145,13 +154,24 @@ typedef struct pr_ivar_list_s {
} pr_ivar_list_t; } pr_ivar_list_t;
typedef struct pr_ivar_s pr_ivar_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 { typedef struct pr_symtab_s {
int sel_ref_cnt; int sel_ref_cnt;
pointer_t refs; // pr_sel_t pointer_t refs; // pr_sel_t
int cls_def_cnt; int cls_def_cnt;
int cat_def_cnt; int cat_def_cnt;
pointer_t defs[1]; // variable array of class pointers then pointer_t defs[1]; // variable array of cls_def_cnt class
// category pointers // 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; } pr_symtab_t;
typedef struct pr_module_s { typedef struct pr_module_s {

File diff suppressed because it is too large Load diff

View file

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

View file

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

View file

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

View file

@ -31,6 +31,13 @@
#ifndef __quakefs_h #ifndef __quakefs_h
#define __quakefs_h #define __quakefs_h
/** \addtogroup utils */
//@{
/** \defgroup quakefs Quake Filesystem
*/
//@{
#include "QF/qtypes.h" #include "QF/qtypes.h"
#include "QF/quakeio.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 // FIXME: This is here temporarily until fs_usercfg gets sorted out
char *expand_squiggle (const char *path); char *expand_squiggle (const char *path);
//@}
//@}
#endif // __quakefs_h #endif // __quakefs_h

View file

@ -30,6 +30,13 @@
#ifndef __quakeio_h #ifndef __quakeio_h
#define __quakeio_h #define __quakeio_h
/** \addtogroup utils */
//@{
/** \defgroup quakeio File IO
*/
//@{
typedef struct QFile_s QFile; typedef struct QFile_s QFile;
int Qrename(const char *old, const char *new); int Qrename(const char *old, const char *new);
@ -53,4 +60,7 @@ int Qflush(QFile *file);
int Qeof(QFile *file); int Qeof(QFile *file);
const char *Qgetline(QFile *file); const char *Qgetline(QFile *file);
//@}
//@}
#endif /*__quakeio_h*/ #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 #ifndef __sizebuf_h
#define __sizebuf_h #define __sizebuf_h
/** \addtogroup utils */
//@{
/** \defgroup sizebuf Fixed Size Buffers
Fixed size buffer management
*/
//@{
#include "QF/qtypes.h" #include "QF/qtypes.h"
typedef struct sizebuf_s 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_Write (sizebuf_t *buf, const void *data, int length);
void SZ_Print (sizebuf_t *buf, const char *data); // strcats onto the sizebuf void SZ_Print (sizebuf_t *buf, const char *data); // strcats onto the sizebuf
//@}
//@}
#endif // __sizebuf_h #endif // __sizebuf_h

View file

@ -29,6 +29,14 @@
#ifndef __sys_h #ifndef __sys_h
#define __sys_h #define __sys_h
/** \addtogroup utils */
//@{
/** \defgroup sys Portability
Non-portable functions
*/
//@{
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
@ -70,7 +78,7 @@ void Sys_RegisterShutdown (void (*func) (void));
double Sys_DoubleTime (void); double Sys_DoubleTime (void);
void Sys_TimeOfDay(date_t *date); 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); const char *Sys_ConsoleInput (void);
void Sys_Sleep (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__); \ Sys_Error ("%s: Failed to allocate memory.", __FUNCTION__); \
} while (0) } while (0)
//@}
//@}
#endif // __sys_h #endif // __sys_h

View file

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

View file

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

View file

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

View file

@ -25,7 +25,14 @@
$Id$ $Id$
*/ */
// wadfile.h
/** \addtogroup utils */
//@{
/** \defgroup wad Wad Files
Wadfile processing
*/
//@{
#ifndef __QF_wadfile_h #ifndef __QF_wadfile_h
#define __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); const void *data, int bytes);
lumpinfo_t *wad_find_lump (wad_t *wad, const char *filename); lumpinfo_t *wad_find_lump (wad_t *wad, const char *filename);
//@}
//@}
#endif//__QF_wadfile_h #endif//__QF_wadfile_h

View file

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

View file

@ -33,10 +33,6 @@
#define __rua_internal_h #define __rua_internal_h
#include "QF/quakeio.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); 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_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_String_Init (struct progs_s *pr, int secure);
void RUA_QFile_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); 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_NOMONSTERS 1
#define MOVE_MISSILE 2 #define MOVE_MISSILE 2
typedef struct areanode_s typedef struct areanode_s {
{
int axis; // -1 = leaf node int axis; // -1 = leaf node
float dist; float dist;
struct areanode_s *children[2]; 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, qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f,
const vec3_t p1, const vec3_t p2, const vec3_t p1, const vec3_t p2,
trace_t *trace); 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 #endif // __world_h

View file

@ -121,5 +121,5 @@ CDAudio_Init (void)
"play (track number) - Plays the specified track one time.\n" "play (track number) - Plays the specified track one time.\n"
"stop - Stops the currently playing track."); "stop - Stops the currently playing track.");
Sys_Printf ("CD Audio Initialized\n"); 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@ SDL_LIBS= @SDL_LIBS@
XMMS_LIBS= @XMMS_LIBS@ XMMS_LIBS= @XMMS_LIBS@
plugin_version= 1:0:0 plugin_version= 1:0:0
plugin_ldflags= @plugin_ldflags@ plugin_ldflags= @plugin_ldflags@ -module
plugin_libadd= @plugin_libadd@ plugin_libadd= @plugin_libadd@
EXEEXT= EXEEXT=
plugin_PROGRAMS= @CD_PLUGIN_TARGETS@ plugin_LTLIBRARIES= @CD_PLUGIN_TARGETS@
noinst_PROGRAMS= @CD_PLUGIN_STATIC@ noinst_LTLIBRARIES= @CD_PLUGIN_STATIC@
EXTRA_PROGRAMS= cd_file.la cd_linux.la cd_sdl.la cd_sgi.la cd_win.la cd_xmms.la 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_LDFLAGS= $(plugin_ldflags)
cd_file_la_SOURCES= cd_file.c 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_linux_la_SOURCES= cd_linux.c
cd_sdl_la_LDFLAGS= $(plugin_ldflags) 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_CFLAGS= $(SDL_CFLAGS)
cd_sdl_la_SOURCES= cd_sdl.c cd_sdl_la_SOURCES= cd_sdl.c
cd_sgi_la_LDFLAGS= $(plugin_ldflags) 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_sgi_la_SOURCES= cd_sgi.c
cd_win_la_LDFLAGS= $(plugin_ldflags) 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_win_la_SOURCES= cd_win.c
cd_xmms_la_LDFLAGS= $(plugin_ldflags) 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_CFLAGS= $(XMMS_CFLAGS)
cd_xmms_la_SOURCES= cd_xmms.c cd_xmms_la_SOURCES= cd_xmms.c

View file

@ -2,7 +2,6 @@
cd_sgi.c cd_sgi.c
audio cd playback support for sgi irix machines audio cd playback support for sgi irix machines
FIXME: Update for plugin API
Copyright (C) 1996-1997 Id Software, Inc. 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 general_funcs_t plugin_info_general_funcs;
static cd_funcs_t plugin_info_cd_funcs; static cd_funcs_t plugin_info_cd_funcs;
extern HWND mainwindow; //FIXME
static qboolean cdValid = false; static qboolean cdValid = false;
static qboolean playing = false; static qboolean playing = false;
static qboolean wasPlaying = false; static qboolean wasPlaying = false;
@ -208,7 +206,7 @@ I_CDAudio_Play (int track, qboolean looping)
return; return;
} }
if (track < 0 || track >= sizeof (remap)) { if (track < 0 || track >= (int) sizeof (remap)) {
Sys_Printf ("CDAudio: invalid track number\n"); Sys_Printf ("CDAudio: invalid track number\n");
return; return;
} }

View file

@ -3,21 +3,21 @@ AUTOMAKE_OPTIONS= foreign
AM_CFLAGS= @PREFER_PIC@ @VORBIS_CFLAGS@ @OGG_CFLAGS@ AM_CFLAGS= @PREFER_PIC@ @VORBIS_CFLAGS@ @OGG_CFLAGS@
INCLUDES= -I$(top_srcdir)/include INCLUDES= -I$(top_srcdir)/include
plugin_version= 1:0:0 plugin_version= 1:0:0
plugin_ldflags= @plugin_ldflags@ plugin_ldflags= @plugin_ldflags@ -module
plugin_libadd= @plugin_libadd@ plugin_libadd= @plugin_libadd@
EXEEXT= EXEEXT=
plugin_PROGRAMS= @SND_REND_TARGETS@ plugin_LTLIBRARIES= @SND_REND_TARGETS@
EXTRA_PROGRAMS= snd_render_default.la 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_LDFLAGS= $(plugin_ldflags)
snd_render_default_la_SOURCES= snd_dma.c snd_mem.c snd_mix.c vorbis.c wav.c midi.c snd_render_default_la_SOURCES= snd_dma.c snd_mem.c snd_mix.c vorbis.c wav.c midi.c
if ASM_ARCH 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= snd_render_default_la_DEPENDENCIES=
else 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= snd_render_default_la_DEPENDENCIES=
endif endif

View file

@ -91,7 +91,6 @@ get_info (void * handle) {
static int static int
midi_stream_read (void *file, byte *buf, int count, wavinfo_t *info) 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); 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; pos += info->dataofs;
new_pos = pos; new_pos = pos;
// FIXME: need to check what the return of this function /should/ be
return WildMidi_SampledSeek(file, &new_pos); 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 INCLUDES= -I$(top_srcdir)/include
SDL_LIBS = @SDL_LIBS@ SDL_LIBS = @SDL_LIBS@
plugin_version= 1:0:0 plugin_version= 1:0:0
plugin_ldflags= @plugin_ldflags@ plugin_ldflags= @plugin_ldflags@ -module
plugin_libadd= @plugin_libadd@ plugin_libadd= @plugin_libadd@
EXEEXT= EXEEXT=
plugin_PROGRAMS= @SND_PLUGIN_TARGETS@ plugin_LTLIBRARIES= @SND_PLUGIN_TARGETS@
noinst_PROGRAMS= @SND_PLUGIN_STATIC@ noinst_LTLIBRARIES= @SND_PLUGIN_STATIC@
EXTRA_PROGRAMS= \ EXTRA_LTLIBRARIES= \
snd_output_sdl.la snd_output_alsa.la snd_output_alsa0_9.la\ 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_oss.la snd_output_sgi.la snd_output_sun.la \
snd_output_win.la snd_output_dx.la snd_output_disk.la snd_output_win.la snd_output_dx.la snd_output_disk.la
snd_output_sdl_la_LDFLAGS= $(plugin_ldflags) 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_CFLAGS= $(SDL_CFLAGS)
snd_output_sdl_la_SOURCES= snd_sdl.c snd_output_sdl_la_SOURCES= snd_sdl.c
snd_output_alsa_la_LDFLAGS= $(plugin_ldflags) 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_CFLAGS= $(ALSA_CFLAGS)
snd_output_alsa_la_SOURCES= snd_alsa.c snd_output_alsa_la_SOURCES= snd_alsa.c
snd_output_alsa0_9_la_LDFLAGS= $(plugin_ldflags) 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_CFLAGS= $(ALSA_CFLAGS)
snd_output_alsa0_9_la_SOURCES= snd_alsa_0_9.c snd_output_alsa0_9_la_SOURCES= snd_alsa_0_9.c
snd_output_oss_la_LDFLAGS= $(plugin_ldflags) 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_CFLAGS= $(OSS_CFLAGS)
snd_output_oss_la_SOURCES= snd_oss.c snd_output_oss_la_SOURCES= snd_oss.c
snd_output_sgi_la_LDFLAGS= $(plugin_ldflags) 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_CFLAGS= $(SGISND_CFLAGS)
snd_output_sgi_la_SOURCES= snd_sgi.c 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_sun_la_SOURCES= snd_sun.c
snd_output_win_la_LDFLAGS= $(plugin_ldflags) 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_CFLAGS= $(WIN32SND_CFLAGS)
snd_output_win_la_SOURCES= snd_win.c snd_output_win_la_SOURCES= snd_win.c
snd_output_dx_la_LDFLAGS= $(plugin_ldflags) 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_CFLAGS= $(WIN32SND_CFLAGS)
snd_output_dx_la_SOURCES= snd_dx.c snd_output_dx_la_SOURCES= snd_dx.c
snd_output_disk_la_LDFLAGS= $(plugin_ldflags) 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_CFLAGS=
snd_output_disk_la_SOURCES= snd_disk.c 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@ AM_CFLAGS= @PREFER_PIC@
INCLUDES= -I$(top_srcdir)/include INCLUDES= -I$(top_srcdir)/include
plugin_version= 1:0:0 plugin_version= 1:0:0
plugin_ldflags= @plugin_ldflags@ plugin_ldflags= @plugin_ldflags@ -module
plugin_libadd= @plugin_libadd@ plugin_libadd= @plugin_libadd@
EXEEXT= EXEEXT=
lib_LTLIBRARIES= libQFconsole.la lib_LTLIBRARIES= libQFconsole.la
plugin_PROGRAMS= @SERVER_PLUGIN_TARGETS@ @CLIENT_PLUGIN_TARGETS@ plugin_LTLIBRARIES= @SERVER_PLUGIN_TARGETS@ @CLIENT_PLUGIN_TARGETS@
noinst_PROGRAMS= @SERVER_PLUGIN_STATIC@ @CLIENT_PLUGIN_STATIC@ noinst_LTLIBRARIES= @SERVER_PLUGIN_STATIC@ @CLIENT_PLUGIN_STATIC@
EXTRA_PROGRAMS= console_server.la console_client.la EXTRA_LTLIBRARIES= console_server.la console_client.la
common_sources= \ common_sources= \
buffer.c complete.c console.c inputline.c list.c filelist.c view.c 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) libQFconsole_la_SOURCES= $(common_sources)
console_client_la_LDFLAGS= $(plugin_ldflags) 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_client_la_SOURCES= $(client_sources)
console_server_la_LDFLAGS= $(plugin_ldflags) 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) console_server_la_SOURCES= $(server_sources)

View file

@ -91,17 +91,21 @@ static int
menu_resolve_globals (progs_t *pr) menu_resolve_globals (progs_t *pr)
{ {
const char *sym; const char *sym;
ddef_t *def;
dfunction_t *f; dfunction_t *f;
if (!(f = ED_FindFunction (pr, sym = "menu_init"))) if (!(f = PR_FindFunction (pr, sym = "menu_init")))
goto error; goto error;
menu_init = (func_t)(f - menu_pr_state.pr_functions); 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; goto error;
menu_draw_hud = (func_t)(f - pr->pr_functions); 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; return 1;
error: 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; return 0;
} }
@ -444,6 +448,7 @@ Menu_Init (void)
menu_pr_state.allocate_progs_mem = menu_allocate_progs_mem; menu_pr_state.allocate_progs_mem = menu_allocate_progs_mem;
menu_pr_state.free_progs_mem = menu_free_progs_mem; menu_pr_state.free_progs_mem = menu_free_progs_mem;
menu_pr_state.load_file = menu_load_file; 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); menu_hash = Hash_NewTable (61, menu_get_key, menu_free, 0);
@ -457,15 +462,12 @@ Menu_Init (void)
PR_Cmds_Init (&menu_pr_state); PR_Cmds_Init (&menu_pr_state);
R_Progs_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 = Cvar_Get ("confirm_quit", "1", CVAR_ARCHIVE, NULL,
"confirm quit command"); "confirm quit command");
Cmd_AddCommand ("togglemenu", togglemenu_f, Cmd_AddCommand ("togglemenu", togglemenu_f,
"Toggle the display of the menu"); "Toggle the display of the menu");
Cmd_AddCommand ("quit", quit_f, "Exit the program"); Cmd_AddCommand ("quit", quit_f, "Exit the program");
} }
void void
@ -474,8 +476,6 @@ Menu_Load (void)
int size; int size;
QFile *file; QFile *file;
menu_pr_state.time = con_data.realtime;
Hash_FlushTable (menu_hash); Hash_FlushTable (menu_hash);
menu = 0; menu = 0;
top_menu = 0; top_menu = 0;
@ -519,7 +519,7 @@ Menu_Draw (view_t *view)
if (menu->fadescreen) if (menu->fadescreen)
Draw_FadeScreen (); Draw_FadeScreen ();
*menu_pr_state.globals.time = *menu_pr_state.time; *menu_pr_state.globals.time = *con_data.realtime;
if (menu->draw) { if (menu->draw) {
P_INT (&menu_pr_state, 0) = x; P_INT (&menu_pr_state, 0) = x;
@ -563,7 +563,7 @@ Menu_Draw (view_t *view)
void void
Menu_Draw_Hud (view_t *view) 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); 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)); pr_list[i].integer_var = PR_SetTempString (builtin->pr, GIB_Argv(i));
P_INT (builtin->pr, 0) = GIB_Argc(); 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_ExecuteProgram (builtin->pr, builtin->func);
PR_PopFrame (builtin->pr); PR_PopFrame (builtin->pr);
PR_Zone_Free (builtin->pr, pr_list); 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; pr_type_t *handle;
inputline_t *line; 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) if (arg <= min || arg >= max)
|| (size_t) arg >= (pr->zone_size / sizeof (pr_type_t))) PR_RunError (pr, "%s: Invalid inputline_t: $%x $%x $%x", func, arg,
PR_RunError (pr, "%s: Invalid inputline_t", func); min, max);
handle = pr->pr_globals + arg; handle = pr->pr_globals + arg;

View file

@ -52,7 +52,6 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "compat.h" #include "compat.h"
//FIXME lines to #undef U really shouldn't be here
#include "QF/csqc.h" #include "QF/csqc.h"
#define U __attribute__ ((unused)) #define U __attribute__ ((unused))
static U void (*const gib_progs_init)(progs_t *) = GIB_Progs_Init; 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); e = P_EDICTNUM (pr, 0);
f = P_INT (pr, 1); f = P_INT (pr, 1);
field_def = ED_FieldAtOfs (pr, f); field_def = PR_FieldAtOfs (pr, f);
if (!field_def) if (!field_def)
PR_RunError (pr, "PF_Find: bad search field: %d", f); PR_RunError (pr, "PF_Find: bad search field: %d", f);
type = field_def->type & ~DEF_SAVEGLOBAL; type = field_def->type & ~DEF_SAVEGLOBAL;
@ -331,6 +330,7 @@ static void
PF_traceon (progs_t *pr) PF_traceon (progs_t *pr)
{ {
pr->pr_trace = true; pr->pr_trace = true;
pr->pr_trace_depth = pr->pr_depth;
} }
/* /*
@ -583,9 +583,9 @@ PF_sprintf (progs_t *pr)
dstring_t *dstr; dstring_t *dstr;
int str; int str;
str = PR_NewString (pr); str = PR_NewMutableString (pr);
dstr = PR_GetDString (pr, str); dstr = PR_GetMutableString (pr, str);
PR_Sprintf (pr, dstr, "bi_printf", fmt, count, args); PR_Sprintf (pr, dstr, "PF_sprintf", fmt, count, args);
PR_MakeTempString (pr, str); PR_MakeTempString (pr, str);
R_STRING (pr) = str; R_STRING (pr) = str;
} }
@ -599,6 +599,27 @@ PR_gametype (progs_t *pr)
RETURN_STRING (pr, pr_gametype); 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) | #define QF (PR_RANGE_QF << PR_RANGE_SHIFT) |
static builtin_t builtins[] = { static builtin_t builtins[] = {
@ -635,6 +656,9 @@ static builtin_t builtins[] = {
{"stoi", PF_stoi, QF 113}, {"stoi", PF_stoi, QF 113},
{"stov", PF_stov, QF 114}, {"stov", PF_stov, QF 114},
{"gametype", PR_gametype, QF 115}, {"gametype", PR_gametype, QF 115},
{"PR_SetField", PF_PR_SetField, -1},
{"PR_FindFunction", PF_PR_FindFunction, -1},
{0} {0}
}; };

View file

@ -146,11 +146,8 @@ PR_Load_Source_File (progs_t *pr, const char *fname)
if (!f) if (!f)
return 0; return 0;
for (dir = source_paths; *dir && !f->text; dir++) { for (dir = source_paths; *dir && !f->text; dir++) {
int len; f->text = pr->load_file (pr, va ("%s%s%s", *dir, **dir ? "/" : "",
len = strlen (*dir) + strlen (fname) + 2; fname));
path = Hunk_TempAlloc (len);
sprintf (path, "%s%s%s", *dir, **dir ? "/" : "", fname);
f->text = pr->load_file (pr, path);
} }
if (!f->text) { if (!f->text) {
pr->file_error (pr, path); pr->file_error (pr, path);
@ -192,7 +189,6 @@ PR_LoadDebug (progs_t *pr)
char *sym_path; char *sym_path;
const char *path_end, *sym_file; const char *path_end, *sym_file;
unsigned int i; unsigned int i;
int start = Hunk_LowMark ();
ddef_t *def; ddef_t *def;
pr_type_t *str = 0; pr_type_t *str = 0;
@ -219,13 +215,13 @@ PR_LoadDebug (progs_t *pr)
pr->debugfile = PR_GetString (pr, str->string_var); pr->debugfile = PR_GetString (pr, str->string_var);
sym_file = QFS_SkipPath (pr->debugfile); sym_file = QFS_SkipPath (pr->debugfile);
path_end = QFS_SkipPath (pr->progs_name); path_end = QFS_SkipPath (pr->progs_name);
sym_path = Hunk_TempAlloc (strlen (sym_file) + (path_end - pr->progs_name) sym_path = malloc (strlen (sym_file) + (path_end - pr->progs_name) + 1);
+ 1);
strncpy (sym_path, pr->progs_name, path_end - pr->progs_name); strncpy (sym_path, pr->progs_name, path_end - pr->progs_name);
strcpy (sym_path + (path_end - pr->progs_name), sym_file); strcpy (sym_path + (path_end - pr->progs_name), sym_file);
pr->debug = pr->load_file (pr, sym_path); pr->debug = pr->load_file (pr, sym_path);
if (!pr->debug) { if (!pr->debug) {
Sys_Printf ("can't load %s for debug info\n", sym_path); Sys_Printf ("can't load %s for debug info\n", sym_path);
free (sym_path);
return 1; return 1;
} }
pr->debug->version = LittleLong (pr->debug->version); pr->debug->version = LittleLong (pr->debug->version);
@ -235,8 +231,8 @@ PR_LoadDebug (progs_t *pr)
(pr->debug->version >> 24) & 0xff, (pr->debug->version >> 24) & 0xff,
(pr->debug->version >> 12) & 0xfff, (pr->debug->version >> 12) & 0xfff,
pr->debug->version & 0xfff); pr->debug->version & 0xfff);
Hunk_FreeToLowMark (start);
pr->debug = 0; pr->debug = 0;
free (sym_path);
return 1; return 1;
} }
pr->debug->crc = LittleShort (pr->debug->crc); pr->debug->crc = LittleShort (pr->debug->crc);
@ -247,10 +243,11 @@ PR_LoadDebug (progs_t *pr)
pr->progs_name, pr->progs_name,
pr->debug->crc, pr->debug->crc,
pr->crc); pr->crc);
Hunk_FreeToLowMark (start);
pr->debug = 0; pr->debug = 0;
free (sym_path);
return 1; 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 = LittleShort
(pr->debug->you_tell_me_and_we_will_both_know); (pr->debug->you_tell_me_and_we_will_both_know);
pr->debug->auxfunctions = LittleLong (pr->debug->auxfunctions); pr->debug->auxfunctions = LittleLong (pr->debug->auxfunctions);
@ -355,7 +352,6 @@ PR_Get_Source_File (progs_t *pr, pr_lineno_t *lineno)
const char * const char *
PR_Get_Source_Line (progs_t *pr, unsigned int addr) PR_Get_Source_Line (progs_t *pr, unsigned int addr)
{ {
char *str;
const char *fname; const char *fname;
unsigned int line; unsigned int line;
file_t *file; file_t *file;
@ -374,16 +370,11 @@ PR_Get_Source_Line (progs_t *pr, unsigned int addr)
file = PR_Load_Source_File (pr, fname); 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) 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); return va ("%s:%d:%.*s", fname, line, (int)file->lines[line - 1].len,
sprintf (str, "%s:%d:%.*s", fname, line, file->lines[line - 1].text);
(int)file->lines[line - 1].len, file->lines[line - 1].text);
return str;
} }
ddef_t * ddef_t *
@ -495,7 +486,7 @@ value_string (progs_t *pr, etype_t type, pr_type_t *val)
} }
break; break;
case ev_field: case ev_field:
def = ED_FieldAtOfs (pr, val->integer_var); def = PR_FieldAtOfs (pr, val->integer_var);
if (def) if (def)
dsprintf (line, ".%s", PR_GetString (pr, def->s_name)); dsprintf (line, ".%s", PR_GetString (pr, def->s_name));
else else
@ -517,7 +508,7 @@ value_string (progs_t *pr, etype_t type, pr_type_t *val)
if (pr_debug->int_val && pr->debug) if (pr_debug->int_val && pr->debug)
def = PR_Get_Local_Def (pr, ofs); def = PR_Get_Local_Def (pr, ofs);
if (!def) if (!def)
def = ED_GlobalAtOfs (pr, ofs); def = PR_GlobalAtOfs (pr, ofs);
if (def && def->s_name) if (def && def->s_name)
dsprintf (line, "&%s", PR_GetString (pr, def->s_name)); dsprintf (line, "&%s", PR_GetString (pr, def->s_name));
else else
@ -554,7 +545,7 @@ def_string (progs_t *pr, int ofs, dstring_t *dstr)
if (pr_debug->int_val && pr->debug) if (pr_debug->int_val && pr->debug)
def = PR_Get_Local_Def (pr, ofs); def = PR_Get_Local_Def (pr, ofs);
if (!def) if (!def)
def = ED_GlobalAtOfs (pr, ofs); def = PR_GlobalAtOfs (pr, ofs);
if (!def || !*(name = PR_GetString (pr, def->s_name))) if (!def || !*(name = PR_GetString (pr, def->s_name)))
dsprintf (dstr, "[$%x]", ofs); dsprintf (dstr, "[$%x]", ofs);
else 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) if (!v[0].float_var && !v[1].float_var && !v[2].float_var)
continue; continue;
break; break;
case ev_void:
break;
default: default:
PR_Error (pr, "ED_Print: Unhandled type %d", type); 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 start = pr->reserved_edicts ? *pr->reserved_edicts : 0;
int max_edicts = pr->pr_edictareasize / pr->pr_edict_size; 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); e = EDICT_NUM (pr, i);
// the first couple seconds of server time can involve a lot of // the first couple seconds of server time can involve a lot of
// freeing and allocating, so relax the replacement policy // 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); ED_ClearEdict (pr, e, 0);
return e; return e;
} }
@ -135,7 +137,8 @@ ED_Free (progs_t *pr, edict_t *ed)
ED_ClearEdict (pr, ed, 0); ED_ClearEdict (pr, ed, 0);
} }
ed->free = true; 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; int count;
ddef_t *def; ddef_t *def;
def = ED_FindField(pr, "classname"); def = PR_FindField(pr, "classname");
if (fieldval && fieldval[0] && def) { if (fieldval && fieldval[0] && def) {
count = 0; count = 0;
@ -192,13 +195,13 @@ ED_Count (progs_t *pr)
ddef_t *model_def; ddef_t *model_def;
edict_t *ent; edict_t *ent;
solid_def = ED_FindField (pr, "solid"); solid_def = PR_FindField (pr, "solid");
model_def = ED_FindField (pr, "model"); model_def = PR_FindField (pr, "model");
active = models = solid = step = zombie = 0; active = models = solid = step = zombie = 0;
for (i = 0; i < *(pr)->num_edicts; i++) { for (i = 0; i < *(pr)->num_edicts; i++) {
ent = EDICT_NUM (pr, i); ent = EDICT_NUM (pr, i);
if (ent->free) { if (ent->free) {
if (*(pr)->time - ent->freetime <= 0.5) if (pr->globals.time && *pr->globals.time - ent->freetime <= 0.5)
zombie++; zombie++;
continue; continue;
} }
@ -217,7 +220,7 @@ ED_Count (progs_t *pr)
} }
edict_t * edict_t *
EDICT_NUM (progs_t *pr, int n) ED_EdictNum (progs_t *pr, int n)
{ {
int offs = n * pr->pr_edict_size; int offs = n * pr->pr_edict_size;
if (offs < 0 || n >= pr->pr_edictareasize) if (offs < 0 || n >= pr->pr_edictareasize)
@ -227,20 +230,7 @@ EDICT_NUM (progs_t *pr, int n)
} }
int int
NUM_FOR_BAD_EDICT (progs_t *pr, edict_t *e) ED_NumForEdict (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)
{ {
int b; int b;

View file

@ -112,12 +112,15 @@ PR_PopFrame (progs_t *pr)
pr->pr_xtstr = frame->tstr; pr->pr_xtstr = frame->tstr;
} }
/* /** Setup the stackframe prior to calling a progs function. Saves all local
PR_EnterFunction data the called function will trample on and copies the parameters used
by the function into the function's local data space.
Returns the new program statement counter \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) PR_EnterFunction (progs_t *pr, dfunction_t *f)
{ {
int i, j, c, o; int i, j, c, o;
@ -242,6 +245,24 @@ signal_hook (int sig, void *data)
return 0; 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 PR_ExecuteProgram
@ -252,31 +273,23 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
{ {
int exitdepth, profile, startprofile; int exitdepth, profile, startprofile;
unsigned int pointer; unsigned int pointer;
dfunction_t *f;
dstatement_t *st; dstatement_t *st;
edict_t *ed; edict_t *ed;
pr_type_t *ptr; 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 // make a stack frame
exitdepth = pr->pr_depth; exitdepth = pr->pr_depth;
PR_EnterFunction (pr, f);
st = pr->pr_statements + pr->pr_xstatement;
startprofile = profile = 0; startprofile = profile = 0;
Sys_PushSignalHook (signal_hook, pr); 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) { while (1) {
pr_type_t *op_a, *op_b, *op_c; 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); QuatAdd (OPA.quat_var, OPB.quat_var, OPC.quat_var);
break; break;
case OP_ADD_S: case OP_ADD_S:
{ OPC.string_var = PR_CatStrings (pr,
const char *a = PR_GetString (pr, OPA.string_var); PR_GetString (pr,
const char *b = PR_GetString (pr, OPB.string_var); OPA.string_var),
int lena = strlen (a); PR_GetString (pr,
int size = lena + strlen (b) + 1; OPB.string_var));
char *c = Hunk_TempAlloc (size);
strcpy (c, a);
strcpy (c + lena, b);
OPC.string_var = PR_SetTempString (pr, c);
}
break; break;
case OP_SUB_F: case OP_SUB_F:
OPC.float_var = OPA.float_var - OPB.float_var; 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; pr->pr_xfunction->profile += profile - startprofile;
startprofile = profile; startprofile = profile;
pr->pr_argc = st->op - OP_CALL0; pr->pr_argc = st->op - OP_CALL0;
if (!OPA.func_var) PR_CallFunction (pr, 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);
}
st = pr->pr_statements + pr->pr_xstatement; st = pr->pr_statements + pr->pr_xstatement;
break; break;
case OP_DONE: case OP_DONE:
@ -800,6 +800,8 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
PR_LeaveFunction (pr); PR_LeaveFunction (pr);
st = pr->pr_statements + pr->pr_xstatement; st = pr->pr_statements + pr->pr_xstatement;
if (pr->pr_depth == exitdepth) { if (pr->pr_depth == exitdepth) {
if (pr->pr_trace && pr->pr_depth <= pr->pr_trace_depth)
pr->pr_trace = false;
Sys_PopSignalHook (); Sys_PopSignalHook ();
return; // all done return; // all done
} }

View file

@ -45,12 +45,12 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "QF/cvar.h" #include "QF/cvar.h"
#include "QF/dstring.h" #include "QF/dstring.h"
#include "QF/hash.h" #include "QF/hash.h"
#include "QF/idparse.h"
#include "QF/progs.h" #include "QF/progs.h"
#include "QF/qdefs.h" #include "QF/qdefs.h"
#include "QF/qfplist.h" #include "QF/qfplist.h"
#include "QF/qendian.h" #include "QF/qendian.h"
#include "QF/quakefs.h" #include "QF/quakefs.h"
#include "QF/script.h"
#include "QF/sys.h" #include "QF/sys.h"
#include "QF/zone.h" #include "QF/zone.h"
#include "QF/va.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)); snprintf (line, sizeof (line), "%s", PR_GetString (pr, f->s_name));
break; break;
case ev_field: case ev_field:
def = ED_FieldAtOfs (pr, val->integer_var); def = PR_FieldAtOfs (pr, val->integer_var);
snprintf (line, sizeof (line), "%s", snprintf (line, sizeof (line), "%s",
PR_GetString (pr, def->s_name)); PR_GetString (pr, def->s_name));
break; break;
@ -194,7 +194,7 @@ ED_NewString (progs_t *pr, const char *string)
int i, l; int i, l;
l = strlen (string) + 1; l = strlen (string) + 1;
new = Hunk_TempAlloc (l); new = alloca (l);
new_p = new; new_p = new;
for (i = 0; i < l; i++) { for (i = 0; i < l; i++) {
@ -218,7 +218,7 @@ ED_NewString (progs_t *pr, const char *string)
Can parse either fields or globals Can parse either fields or globals
returns false if error returns false if error
*/ */
static qboolean qboolean
ED_ParseEpair (progs_t *pr, pr_type_t *base, ddef_t *key, const char *s) ED_ParseEpair (progs_t *pr, pr_type_t *base, ddef_t *key, const char *s)
{ {
int i; int i;
@ -258,7 +258,7 @@ ED_ParseEpair (progs_t *pr, pr_type_t *base, ddef_t *key, const char *s)
break; break;
case ev_field: case ev_field:
def = ED_FindField (pr, s); def = PR_FindField (pr, s);
if (!def) { if (!def) {
Sys_Printf ("Can't find field %s\n", s); Sys_Printf ("Can't find field %s\n", s);
return false; return false;
@ -267,7 +267,7 @@ ED_ParseEpair (progs_t *pr, pr_type_t *base, ddef_t *key, const char *s)
break; break;
case ev_func: case ev_func:
func = ED_FindFunction (pr, s); func = PR_FindFunction (pr, s);
if (!func) { if (!func) {
Sys_Printf ("Can't find function %s\n", s); Sys_Printf ("Can't find function %s\n", s);
return false; 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. ent should be a properly initialized empty edict.
Used for initial level load and for savegames. Used for initial level load and for savegames.
*/ */
const char * void
ED_ParseEdict (progs_t *pr, const char *data, edict_t *ent) ED_ParseEdict (progs_t *pr, script_t *script, edict_t *ent)
{ {
ddef_t *key; ddef_t *key;
qboolean anglehack; qboolean anglehack;
@ -302,17 +302,17 @@ ED_ParseEdict (progs_t *pr, const char *data, edict_t *ent)
if (ent != *(pr)->edicts) // hack if (ent != *(pr)->edicts) // hack
memset (&ent->v, 0, pr->progs->entityfields * 4); memset (&ent->v, 0, pr->progs->entityfields * 4);
while (1) { // go through all the dictionary pairs // go through all the dictionary pairs
// parse key while (1) {
data = COM_Parse (data); if (!Script_GetToken (script, 1))
if (com_token[0] == '}')
break;
if (!data)
PR_Error (pr, "ED_ParseEntity: EOF without closing brace"); 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 // 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")) { if (!strcmp (token, "angle")) {
token = "angles"; token = "angles";
anglehack = true; anglehack = true;
@ -332,11 +332,12 @@ ED_ParseEdict (progs_t *pr, const char *data, edict_t *ent)
} }
// parse value // parse value
data = COM_Parse (data); //FIXME shouldn't cross line
if (!data) if (!Script_GetToken (script, 1))
PR_Error (pr, "ED_ParseEntity: EOF without closing brace"); 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"); PR_Error (pr, "ED_ParseEntity: closing brace without data");
init = true; init = true;
@ -346,10 +347,10 @@ ED_ParseEdict (progs_t *pr, const char *data, edict_t *ent)
if (keyname->str[0] == '_') if (keyname->str[0] == '_')
continue; continue;
key = ED_FindField (pr, keyname->str); key = PR_FindField (pr, keyname->str);
if (!key) { if (!key) {
if (!pr->parse_field 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); Sys_Printf ("'%s' is not a field\n", keyname->str);
continue; continue;
} }
@ -357,9 +358,9 @@ ED_ParseEdict (progs_t *pr, const char *data, edict_t *ent)
int ret; int ret;
if (anglehack) { 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 { } else {
ret = ED_ParseEpair (pr, ent->v, key, com_token); ret = ED_ParseEpair (pr, ent->v, key, token);
} }
if (!ret) if (!ret)
PR_Error (pr, "ED_ParseEdict: parse error"); 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; ent->free = true;
dstring_delete (keyname); dstring_delete (keyname);
return data;
} }
void void
ED_ParseGlobals (progs_t *pr, const char *data) ED_ParseGlobals (progs_t *pr, script_t *script)
{ {
dstring_t *keyname = dstring_new (); dstring_t *keyname = dstring_new ();
ddef_t *key; ddef_t *key;
const char *token;
while (1) { while (1) {
// parse key // parse key
data = COM_Parse (data); if (!Script_GetToken (script, 1))
if (com_token[0] == '}')
break;
if (!data)
PR_Error (pr, "ED_ParseEntity: EOF without closing brace"); 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 // parse value
data = COM_Parse (data); //FIXME shouldn't cross line
if (!data) if (!Script_GetToken (script, 1))
PR_Error (pr, "ED_ParseEntity: EOF without closing brace"); 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"); PR_Error (pr, "ED_ParseEntity: closing brace without data");
key = PR_FindGlobal (pr, keyname->str); key = PR_FindGlobal (pr, keyname->str);
@ -403,7 +405,7 @@ ED_ParseGlobals (progs_t *pr, const char *data)
continue; 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"); PR_Error (pr, "ED_ParseGlobals: parse error");
} }
dstring_delete (keyname); 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. to call ED_CallSpawnFunctions () to let the objects initialize themselves.
*/ */
static void static void
ED_ParseOld (progs_t *pr, const char *data) ED_ParseOld (progs_t *pr, script_t *script)
{ {
edict_t *ent = NULL; edict_t *ent = NULL;
int inhibit = 0; int inhibit = 0;
@ -431,21 +433,17 @@ ED_ParseOld (progs_t *pr, const char *data)
pr_type_t *classname; pr_type_t *classname;
ddef_t *def; ddef_t *def;
*pr->globals.time = *(pr)->time; while (Script_GetToken (script, 1)) { // parse ents
while (1) { // parse ents
// parse the opening brace // parse the opening brace
data = COM_Parse (data); if (script->token->str[0] != '{')
if (!data) PR_Error (pr, "ED_LoadFromFile: found %s when expecting {",
break; script->token->str);
if (com_token[0] != '{')
PR_Error (pr, "ED_LoadFromFile: found %s when expecting {", com_token);
if (!ent) if (!ent)
ent = EDICT_NUM (pr, 0); ent = EDICT_NUM (pr, 0);
else else
ent = ED_Alloc (pr); ent = ED_Alloc (pr);
data = ED_ParseEdict (pr, data, ent); ED_ParseEdict (pr, script, ent);
// remove things from different skill levels or deathmatch // remove things from different skill levels or deathmatch
if (pr->prune_edict && pr->prune_edict (pr, ent)) { if (pr->prune_edict && pr->prune_edict (pr, ent)) {
@ -454,10 +452,8 @@ ED_ParseOld (progs_t *pr, const char *data)
continue; continue;
} }
//
// immediately call spawn function // immediately call spawn function
// def = PR_FindField (pr, "classname");
def = ED_FindField (pr, "classname");
if (!def) { if (!def) {
Sys_Printf ("No classname for:\n"); Sys_Printf ("No classname for:\n");
ED_Print (pr, ent); ED_Print (pr, ent);
@ -467,7 +463,7 @@ ED_ParseOld (progs_t *pr, const char *data)
classname = &ent->v[def->ofs]; classname = &ent->v[def->ofs];
// look for the spawn function // 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) { if (!func) {
Sys_Printf ("No spawn function for:\n"); Sys_Printf ("No spawn function for:\n");
ED_Print (pr, ent); ED_Print (pr, ent);
@ -487,12 +483,35 @@ ED_ParseOld (progs_t *pr, const char *data)
void void
ED_LoadFromFile (progs_t *pr, const char *data) ED_LoadFromFile (progs_t *pr, const char *data)
{ {
if (*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 // new style (plist) entity data
plitem_t *plist = PL_GetPropertyList (data); plitem_t *plist = PL_GetPropertyList (data);
plist = plist; plist = plist;
} else { } else {
// oldstyle entity data // oldstyle entity data
ED_ParseOld (pr, 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" #include "compat.h"
/*
ED_GlobalAtOfs
*/
ddef_t * ddef_t *
ED_GlobalAtOfs (progs_t * pr, int ofs) PR_GlobalAtOfs (progs_t * pr, int ofs)
{ {
ddef_t *def; ddef_t *def;
unsigned int i; unsigned int i;
@ -72,11 +69,8 @@ ED_GlobalAtOfs (progs_t * pr, int ofs)
return NULL; return NULL;
} }
/*
ED_FieldAtOfs
*/
ddef_t * ddef_t *
ED_FieldAtOfs (progs_t * pr, int ofs) PR_FieldAtOfs (progs_t * pr, int ofs)
{ {
ddef_t *def; ddef_t *def;
unsigned int i; unsigned int i;
@ -89,76 +83,30 @@ ED_FieldAtOfs (progs_t * pr, int ofs)
return NULL; return NULL;
} }
/*
ED_FindField
*/
ddef_t * ddef_t *
ED_FindField (progs_t * pr, const char *name) PR_FindField (progs_t * pr, const char *name)
{ {
return Hash_Find (pr->field_hash, 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) PR_FindGlobal (progs_t * pr, const char *name)
{ {
return Hash_Find (pr->global_hash, 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 * 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); 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 int
PR_ResolveGlobals (progs_t *pr) PR_ResolveGlobals (progs_t *pr)
{ {
@ -200,11 +148,14 @@ PR_ResolveGlobals (progs_t *pr)
pr->globals.self = &G_INT (pr, def->ofs); pr->globals.self = &G_INT (pr, def->ofs);
} }
if (pr->fields.nextthink == -1) 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) 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) 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; return 1;
error: error:
Sys_Printf ("%s: undefined symbol: %s\n", pr->progs_name, sym); 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, PR_AccessField (progs_t *pr, const char *name, etype_t type,
const char *file, int line) const char *file, int line)
{ {
ddef_t *def = ED_FindField (pr, name); ddef_t *def = PR_FindField (pr, name);
if (!def) if (!def)
PR_Error (pr, "undefined field %s accessed at %s:%d", name, file, line); 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/hash.h"
#include "QF/progs.h" #include "QF/progs.h"
typedef enum {
str_static,
str_dynamic,
str_mutable,
str_temp,
str_return,
} str_e;
struct strref_s { struct strref_s {
strref_t *next; strref_t *next;
strref_t **prev;
str_e type;
union {
char *string; char *string;
dstring_t *dstring; dstring_t *dstring;
int count; } s;
}; };
// format adjustments // format adjustments
@ -107,12 +118,12 @@ new_string_ref (progs_t *pr)
pr->dyn_str_size++; pr->dyn_str_size++;
size = pr->dyn_str_size * sizeof (strref_t *); size = pr->dyn_str_size * sizeof (strref_t *);
pr->dynamic_strings = realloc (pr->dynamic_strings, size); pr->string_map = realloc (pr->string_map, size);
if (!pr->dynamic_strings) if (!pr->string_map)
PR_Error (pr, "out of memory"); PR_Error (pr, "out of memory");
if (!(pr->free_string_refs = calloc (1024, sizeof (strref_t)))) if (!(pr->free_string_refs = calloc (1024, sizeof (strref_t))))
PR_Error (pr, "out of memory"); 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++) for (i = 0, sr = pr->free_string_refs; i < 1023; i++, sr++)
sr->next = sr + 1; sr->next = sr + 1;
sr->next = 0; sr->next = 0;
@ -126,8 +137,8 @@ new_string_ref (progs_t *pr)
static void static void
free_string_ref (progs_t *pr, strref_t *sr) free_string_ref (progs_t *pr, strref_t *sr)
{ {
sr->string = 0; if (sr->prev)
sr->dstring = 0; *sr->prev = sr->next;
sr->next = pr->free_string_refs; sr->next = pr->free_string_refs;
pr->free_string_refs = sr; pr->free_string_refs = sr;
} }
@ -139,9 +150,9 @@ string_index (progs_t *pr, strref_t *sr)
unsigned int i; unsigned int i;
if (o >= 0 && o < pr->num_strings) 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++) { 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) if (d >= 0 && d < 1024)
return ~(i * 1024 + d); return ~(i * 1024 + d);
} }
@ -153,7 +164,8 @@ strref_get_key (void *_sr, void *notused)
{ {
strref_t *sr = (strref_t*)_sr; 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 static void
@ -196,7 +208,7 @@ PR_LoadStrings (progs_t *pr)
} else { } else {
pr->strref_hash = Hash_NewTable (1021, strref_get_key, strref_free, pr->strref_hash = Hash_NewTable (1021, strref_get_key, strref_free,
pr); pr);
pr->dynamic_strings = 0; pr->string_map = 0;
pr->free_string_refs = 0; pr->free_string_refs = 0;
pr->dyn_str_size = 0; pr->dyn_str_size = 0;
} }
@ -207,11 +219,16 @@ PR_LoadStrings (progs_t *pr)
count = 0; count = 0;
str = pr->pr_strings; str = pr->pr_strings;
while (str < end) { while (str < end) {
pr->static_strings[count].string = str; if (!Hash_Find (pr->strref_hash, str)) {
str += strlen (str) + 1; pr->static_strings[count].type = str_static;
pr->static_strings[count].s.string = str;
Hash_Add (pr->strref_hash, &pr->static_strings[count]); Hash_Add (pr->strref_hash, &pr->static_strings[count]);
count++; count++;
} }
str += strlen (str) + 1;
}
pr->static_strings = realloc (pr->static_strings,
count * sizeof (strref_t));
pr->num_strings = count; pr->num_strings = count;
return 1; return 1;
} }
@ -226,7 +243,7 @@ get_strref (progs_t *pr, int num)
if (row >= pr->dyn_str_size) if (row >= pr->dyn_str_size)
return 0; return 0;
return &pr->dynamic_strings[row][num]; return &pr->string_map[row][num];
} else { } else {
return 0; return 0;
} }
@ -239,9 +256,16 @@ get_string (progs_t *pr, int num)
strref_t *ref = get_strref (pr, num); strref_t *ref = get_strref (pr, num);
if (!ref) if (!ref)
return 0; return 0;
if (ref->dstring) switch (ref->type) {
return ref->dstring->str; case str_static:
return ref->string; 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 { } else {
if (num >= pr->pr_stringsize) if (num >= pr->pr_stringsize)
return 0; return 0;
@ -267,22 +291,33 @@ PR_GetString (progs_t *pr, int num)
} }
dstring_t * dstring_t *
PR_GetDString (progs_t *pr, int num) PR_GetMutableString (progs_t *pr, int num)
{ {
strref_t *ref = get_strref (pr, num); strref_t *ref = get_strref (pr, num);
if (ref) { if (ref) {
if (ref->dstring) if (ref->type == str_mutable)
return ref->dstring; return ref->s.dstring;
PR_RunError (pr, "not a dstring: %d", num); PR_RunError (pr, "not a dstring: %d", num);
} }
PR_RunError (pr, "Invalid string offset: %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 * static inline char *
pr_strdup (progs_t *pr, const char *s) pr_strdup (progs_t *pr, const char *s)
{ {
size_t len = strlen (s) + 1; char *new = pr_stralloc (pr, strlen (s));
char *new = PR_Zone_Malloc (pr, len);
strcpy (new, s); strcpy (new, s);
return new; return new;
} }
@ -290,12 +325,16 @@ pr_strdup (progs_t *pr, const char *s)
int int
PR_SetString (progs_t *pr, const char *s) 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) { if (!sr) {
sr = new_string_ref (pr); sr = new_string_ref (pr);
sr->string = pr_strdup(pr, s); sr->type = str_static;
sr->count = 0; sr->s.string = pr_strdup(pr, s);
Hash_Add (pr->strref_hash, sr); Hash_Add (pr->strref_hash, sr);
} }
return string_index (pr, 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 = pr->return_strings[pr->rs_slot])) {
if (sr->string) if (sr->type != str_return)
PR_Zone_Free (pr, sr->string); PR_Error (pr, "internal string error");
pr_strfree (pr, sr->s.string);
} else { } else {
sr = new_string_ref (pr); sr = new_string_ref (pr);
} }
sr->string = pr_strdup(pr, s); sr->type = str_return;
sr->count = 0; sr->s.string = pr_strdup(pr, s);
pr->return_strings[pr->rs_slot++] = sr; pr->return_strings[pr->rs_slot++] = sr;
pr->rs_slot %= PR_RS_SLOTS; pr->rs_slot %= PR_RS_SLOTS;
return string_index (pr, sr); 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 int
PR_SetTempString (progs_t *pr, const char *s) PR_SetTempString (progs_t *pr, const char *s)
{ {
@ -346,11 +415,28 @@ PR_SetTempString (progs_t *pr, const char *s)
if (!s) if (!s)
return PR_SetString (pr, ""); 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 = new_string_ref (pr);
sr->string = pr_strdup(pr, s); sr->type = str_dynamic;
sr->count = 0; sr->s.string = pr_strdup (pr, s);
sr->next = pr->pr_xtstr;
pr->pr_xtstr = sr;
return string_index (pr, sr); return string_index (pr, sr);
} }
@ -361,23 +447,26 @@ PR_MakeTempString (progs_t *pr, int str)
if (!sr) if (!sr)
PR_RunError (pr, "invalid string %d", str); PR_RunError (pr, "invalid string %d", str);
if (sr->dstring) { if (sr->type != str_mutable)
if (sr->dstring->str) PR_RunError (pr, "not a dstring: %d", str);
sr->string = sr->dstring->str; if (sr->s.dstring->str) {
PR_Zone_Free (pr, sr->dstring); sr->s.string = dstring_freeze (sr->s.dstring);
} else {
dstring_delete (sr->s.dstring);
} }
if (!sr->string) if (!sr->s.string)
sr->string = pr_strdup (pr, ""); sr->s.string = pr_strdup (pr, "");
sr->count = 0; sr->type = str_temp;
sr->next = pr->pr_xtstr; sr->next = pr->pr_xtstr;
pr->pr_xtstr = sr; pr->pr_xtstr = sr;
} }
int int
PR_NewString (progs_t *pr) PR_NewMutableString (progs_t *pr)
{ {
strref_t *sr = new_string_ref (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); return string_index (pr, sr);
} }
@ -387,13 +476,24 @@ PR_FreeString (progs_t *pr, int str)
strref_t *sr = get_strref (pr, str); strref_t *sr = get_strref (pr, str);
if (sr) { if (sr) {
if (sr->dstring) switch (sr->type) {
dstring_delete (sr->dstring); case str_static:
else case str_temp:
PR_Zone_Free (pr, sr->string); 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); free_string_ref (pr, sr);
return; return;
} }
if (!get_string (pr, str))
PR_RunError (pr, "attempt to free invalid string %d", str); PR_RunError (pr, "attempt to free invalid string %d", str);
} }
@ -404,7 +504,9 @@ PR_FreeTempStrings (progs_t *pr)
for (sr = pr->pr_xtstr; sr; sr = t) { for (sr = pr->pr_xtstr; sr; sr = t) {
t = sr->next; 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); free_string_ref (pr, sr);
} }
pr->pr_xtstr = 0; pr->pr_xtstr = 0;
@ -462,14 +564,18 @@ I_DoPrint (dstring_t *result, fmt_item_t *formatting)
PRINT (string); PRINT (string);
break; break;
case 'i': case 'i':
dstring_appendstr (tmp, "ld"); dstring_appendstr (tmp, "d");
PRINT (integer);
break;
case 'x':
dstring_appendstr (tmp, "x");
PRINT (integer); PRINT (integer);
break; break;
case 'u': case 'u':
if (current->flags & FMT_HEX) if (current->flags & FMT_HEX)
dstring_appendstr (tmp, "lx"); dstring_appendstr (tmp, "x");
else else
dstring_appendstr (tmp, "lu"); dstring_appendstr (tmp, "u");
PRINT (uinteger); PRINT (uinteger);
break; break;
case 'f': 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); 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 */ /* Basicly taken from the libpng example rpng-x */
static int static int
readpng_init (QFile *infile, png_structp *png_ptr, png_infop *info_ptr) 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 */ return; /* Can't open file */
} }
/* FIXME: NULL should be a QF equiv to fflush? */ png_set_write_fn (png_ptr, outfile, user_write_data, user_flush_data);
png_set_write_fn (png_ptr, outfile, user_write_data, NULL);
/* Write the header */ /* Write the header */
if (setjmp(png_jmpbuf(png_ptr))) { if (setjmp(png_jmpbuf(png_ptr))) {

View file

@ -8,7 +8,7 @@ lib_LTLIBRARIES= libQFmodels.la @VID_MODEL_TARGETS@
EXTRA_LTLIBRARIES= \ EXTRA_LTLIBRARIES= \
libQFmodels_gl.la libQFmodels_sw.la 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_LDFLAGS= -version-info 1:0:0 -no-undefined
libQFmodels_la_LIBADD= brush/libbrush.la $(top_builddir)/libs/util/libQFutil.la 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); memcpy (tx + 1, mt + 1, pixels);
if (!strncmp (mt->name, "sky", 3)) if (!strncmp (mt->name, "sky", 3))
R_InitSky (tx); loadmodel->skytexture = tx;
else { else {
Mod_ProcessTexture (mt, tx); 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_LIBADD= $(top_builddir)/libs/gamecode/engine/libQFgamecode.la $(top_builddir)/libs/util/libQFutil.la
libQFruamoko_la_SOURCES= \ libQFruamoko_la_SOURCES= \
rua_cbuf.c rua_cmd.c rua_cvar.c rua_file.c rua_hash.c rua_init.c \ 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_obj.c rua_plist.c rua_qfile.c rua_qfs.c rua_script.c \
rua_math.c rua_string.c

View file

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

View file

@ -78,7 +78,7 @@ bi_cmd_free (void *_c, void *unused)
} }
static void static void
bi_cmd_f (void *pr) bi_cmd_f (void)
{ {
bi_cmd_t *cmd = Hash_Find (bi_cmds, Cmd_Argv (0)); 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)); char *name = strdup (P_GSTRING (pr, 0));
func_t func = P_FUNCTION (pr, 1); 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) if (name)
free (name); free (name);
if (cmd) if (cmd)
@ -159,7 +159,7 @@ static builtin_t builtins[] = {
void void
RUA_Cmd_Init (progs_t *pr, int secure) 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; res->cmds = 0;
PR_Resources_Register (pr, "Cmd", res, bi_cmd_clear); PR_Resources_Register (pr, "Cmd", res, bi_cmd_clear);

View file

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

View file

@ -60,9 +60,40 @@ typedef struct bi_hashtab_s {
} bi_hashtab_t; } bi_hashtab_t;
typedef struct { typedef struct {
PR_RESMAP (bi_hashtab_t) table_map;
bi_hashtab_t *tabs; bi_hashtab_t *tabs;
} hash_resources_t; } 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 * static const char *
bi_get_key (void *key, void *_ht) bi_get_key (void *key, void *_ht)
{ {
@ -112,7 +143,7 @@ bi_Hash_NewTable (progs_t *pr)
void (*f)(void*,void*); void (*f)(void*,void*);
bi_hashtab_t *ht; bi_hashtab_t *ht;
ht = PR_Zone_Malloc (pr, sizeof (bi_hashtab_t)); ht = table_new (res);
ht->pr = pr; ht->pr = pr;
ht->gk = P_FUNCTION (pr, 1); ht->gk = P_FUNCTION (pr, 1);
ht->f = P_FUNCTION (pr, 2); ht->f = P_FUNCTION (pr, 2);
@ -120,19 +151,31 @@ bi_Hash_NewTable (progs_t *pr)
ht->next = res->tabs; ht->next = res->tabs;
ht->prev = &res->tabs; ht->prev = &res->tabs;
if (ht->next) if (res->tabs)
ht->next->prev = &ht->next; res->tabs->prev = &ht->next;
res->tabs = ht;
gk = ht->gk ? bi_get_key : 0; gk = ht->gk ? bi_get_key : 0;
f = ht->f ? bi_free : 0; f = ht->f ? bi_free : 0;
ht->tab = Hash_NewTable (tsize, gk, f, ht); 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 static void
bi_Hash_SetHashCompare (progs_t *pr) 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*); unsigned long (*gh)(void*,void*);
int (*cmp)(void*,void*,void*); int (*cmp)(void*,void*,void*);
@ -146,17 +189,18 @@ bi_Hash_SetHashCompare (progs_t *pr)
static void static void
bi_Hash_DelTable (progs_t *pr) 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); Hash_DelTable (ht->tab);
*ht->prev = ht->next; *ht->prev = ht->next;
PR_Zone_Free (pr, ht); table_free (res, ht);
} }
static void static void
bi_Hash_FlushTable (progs_t *pr) 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); Hash_FlushTable (ht->tab);
} }
@ -164,7 +208,7 @@ bi_Hash_FlushTable (progs_t *pr)
static void static void
bi_Hash_Add (progs_t *pr) 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)); 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 static void
bi_Hash_AddElement (progs_t *pr) 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)); 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 static void
bi_Hash_Find (progs_t *pr) 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)); R_INT (pr) = (long) Hash_Find (ht->tab, P_GSTRING (pr, 1));
} }
@ -188,7 +232,7 @@ bi_Hash_Find (progs_t *pr)
static void static void
bi_Hash_FindElement (progs_t *pr) 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, R_INT (pr) = (long) Hash_FindElement (ht->tab,
(void *) (long) P_INT (pr, 1)); (void *) (long) P_INT (pr, 1));
@ -197,7 +241,7 @@ bi_Hash_FindElement (progs_t *pr)
static void static void
bi_Hash_FindList (progs_t *pr) 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; void **list, **l;
pr_type_t *pr_list; pr_type_t *pr_list;
int count; int count;
@ -206,6 +250,7 @@ bi_Hash_FindList (progs_t *pr)
for (count = 1, l = list; *l; l++) for (count = 1, l = list; *l; l++)
count++; count++;
pr_list = PR_Zone_Malloc (pr, count * sizeof (pr_type_t)); pr_list = PR_Zone_Malloc (pr, count * sizeof (pr_type_t));
// the hash tables stores progs pointers...
for (count = 0, l = list; *l; l++) for (count = 0, l = list; *l; l++)
pr_list[count++].integer_var = (long) *l; pr_list[count++].integer_var = (long) *l;
free (list); free (list);
@ -215,7 +260,7 @@ bi_Hash_FindList (progs_t *pr)
static void static void
bi_Hash_FindElementList (progs_t *pr) 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; void **list, **l;
pr_type_t *pr_list; pr_type_t *pr_list;
int count; int count;
@ -224,6 +269,7 @@ bi_Hash_FindElementList (progs_t *pr)
for (count = 1, l = list; *l; l++) for (count = 1, l = list; *l; l++)
count++; count++;
pr_list = PR_Zone_Malloc (pr, count * sizeof (pr_type_t)); pr_list = PR_Zone_Malloc (pr, count * sizeof (pr_type_t));
// the hash tables stores progs pointers...
for (count = 0, l = list; *l; l++) for (count = 0, l = list; *l; l++)
pr_list[count++].integer_var = (long) *l; pr_list[count++].integer_var = (long) *l;
free (list); free (list);
@ -233,7 +279,7 @@ bi_Hash_FindElementList (progs_t *pr)
static void static void
bi_Hash_Del (progs_t *pr) 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)); R_INT (pr) = (long) Hash_Del (ht->tab, P_GSTRING (pr, 1));
} }
@ -241,7 +287,7 @@ bi_Hash_Del (progs_t *pr)
static void static void
bi_Hash_DelElement (progs_t *pr) 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, R_INT (pr) = (long) Hash_DelElement (ht->tab,
(void *) (long) P_INT (pr, 1)); (void *) (long) P_INT (pr, 1));
@ -250,7 +296,7 @@ bi_Hash_DelElement (progs_t *pr)
static void static void
bi_Hash_Free (progs_t *pr) 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)); Hash_Free (ht->tab, (void *) (long) P_INT (pr, 1));
} }
@ -270,7 +316,7 @@ bi_Hash_Buffer (progs_t *pr)
static void static void
bi_Hash_GetList (progs_t *pr) 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; void **list, **l;
pr_type_t *pr_list; pr_type_t *pr_list;
int count; int count;
@ -279,6 +325,7 @@ bi_Hash_GetList (progs_t *pr)
for (count = 1, l = list; *l; l++) for (count = 1, l = list; *l; l++)
count++; count++;
pr_list = PR_Zone_Malloc (pr, count * sizeof (pr_type_t)); pr_list = PR_Zone_Malloc (pr, count * sizeof (pr_type_t));
// the hash tables stores progs pointers...
for (count = 0, l = list; *l; l++) for (count = 0, l = list; *l; l++)
pr_list[count++].integer_var = (long) *l; pr_list[count++].integer_var = (long) *l;
free (list); free (list);
@ -288,7 +335,7 @@ bi_Hash_GetList (progs_t *pr)
static void static void
bi_Hash_Stats (progs_t *pr) 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); Hash_Stats (ht->tab);
} }
@ -302,6 +349,7 @@ bi_hash_clear (progs_t *pr, void *data)
for (ht = res->tabs; ht; ht = ht->next) for (ht = res->tabs; ht; ht = ht->next)
Hash_DelTable (ht->tab); Hash_DelTable (ht->tab);
res->tabs = 0; res->tabs = 0;
table_reset (res);
} }
static builtin_t builtins[] = { static builtin_t builtins[] = {
@ -328,7 +376,7 @@ static builtin_t builtins[] = {
void void
RUA_Hash_Init (progs_t *pr, int secure) 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; res->tabs = 0;
PR_Resources_Register (pr, "Hash", res, bi_hash_clear); 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_Plist_Init,
RUA_QFile_Init, RUA_QFile_Init,
RUA_QFS_Init, RUA_QFS_Init,
RUA_Script_Init,
RUA_String_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 static inline void
return_plitem (progs_t *pr, plitem_t *plitem) return_plitem (progs_t *pr, plitem_t *plitem)
{ {
memset (&R_INT (pr), 0, 8);
memcpy (&R_INT (pr), &plitem, sizeof (plitem)); memcpy (&R_INT (pr), &plitem, sizeof (plitem));
} }
@ -92,6 +93,27 @@ bi_PL_GetPropertyList (progs_t *pr)
return_plitem (pr, record_plitem (pr, plitem)); 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 static void
bi_PL_ObjectForKey (progs_t *pr) 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))); 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 static void
bi_PL_D_AddObject (progs_t *pr) 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))); 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 static void
bi_PL_A_InsertObjectAtIndex (progs_t *pr) bi_PL_A_InsertObjectAtIndex (progs_t *pr)
{ {
@ -128,9 +168,9 @@ bi_PL_A_InsertObjectAtIndex (progs_t *pr)
} }
static void 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 static void
@ -138,18 +178,26 @@ bi_PL_NewArray (progs_t *pr)
{ {
return_plitem (pr, record_plitem (pr, PL_NewArray ())); return_plitem (pr, record_plitem (pr, PL_NewArray ()));
} }
/*
static void static void
bi_PL_NewData (progs_t *pr) bi_PL_NewData (progs_t *pr)
{ {
return_plitem (pr, record_plitem (pr, PL_NewData (P_GPOINTER (pr, 0),
P_INT (pr, 1))));
} }
*/
static void static void
bi_PL_NewString (progs_t *pr) bi_PL_NewString (progs_t *pr)
{ {
return_plitem (pr, record_plitem (pr, PL_NewString (P_GSTRING (pr, 0)))); 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 static void
bi_plist_clear (progs_t *pr, void *data) bi_plist_clear (progs_t *pr, void *data)
{ {
@ -172,22 +220,29 @@ plist_compare (void *k1, void *k2, void *unused)
static builtin_t builtins[] = { static builtin_t builtins[] = {
{"PL_GetPropertyList", bi_PL_GetPropertyList, -1}, {"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_ObjectForKey", bi_PL_ObjectForKey, -1},
{"PL_ObjectAtIndex", bi_PL_ObjectAtIndex, -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_D_AddObject", bi_PL_D_AddObject, -1},
{"PL_A_AddObject", bi_PL_A_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_A_InsertObjectAtIndex", bi_PL_A_InsertObjectAtIndex, -1},
{"PL_NewDictionary", bi_PL_NewDictionary, -1}, {"PL_NewDictionary", bi_PL_NewDictionary, -1},
{"PL_NewArray", bi_PL_NewArray, -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_NewString", bi_PL_NewString, -1},
{"PL_Free", bi_PL_Free, -1},
{0} {0}
}; };
void void
RUA_Plist_Init (progs_t *pr, int secure) 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); res->items = Hash_NewTable (1021, 0, 0, 0);
Hash_SetHashCompare (res->items, plist_get_hash, plist_compare); 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" #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 static void
bi_qfile_clear (progs_t *pr, void *data) bi_qfile_clear (progs_t *pr, void *data)
{ {
qfile_resources_t *res = (qfile_resources_t *) data; qfile_resources_t *res = (qfile_resources_t *) data;
int i; qfile_t *handle;
for (i = 0; i < QFILE_MAX_HANDLES; i++) for (handle = res->handles; handle; handle = handle->next)
if (res->handles[i]) { Qclose (handle->file);
Qclose (res->handles[i]); res->handles = 0;
res->handles[i] = 0; handle_reset (res);
}
} }
QFile ** static int
QFile_AllocHandle (struct progs_s *pr, qfile_resources_t *res) 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 (!handle)
;
if (h == QFILE_MAX_HANDLES)
goto error;
res->handles[h] = (QFile *) 1;
return res->handles + h;
error:
return 0; 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 static void
@ -103,44 +153,48 @@ bi_Qopen (progs_t *pr)
qfile_resources_t *res = PR_Resources_Find (pr, "QFile"); qfile_resources_t *res = PR_Resources_Find (pr, "QFile");
const char *path = P_GSTRING (pr, 0); const char *path = P_GSTRING (pr, 0);
const char *mode = P_GSTRING (pr, 1); 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; return;
} if (!(R_INT (pr) = alloc_handle (res, file)))
*h = Qopen (path, mode); Qclose (file);
R_INT (pr) = (h - res->handles) + 1;
} }
static QFile ** static qfile_t *
get_qfile (progs_t *pr, int handle, const char *func) get_handle (progs_t *pr, const char *name, int handle)
{ {
qfile_resources_t *res = PR_Resources_Find (pr, "QFile"); 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]) if (!h)
PR_RunError (pr, "%s: Invalid QFile", func); PR_RunError (pr, "invalid file handle passed to %s", name + 3);
return res->handles + handle - 1; return h;
} }
static void static void
bi_Qclose (progs_t *pr) bi_Qclose (progs_t *pr)
{ {
qfile_resources_t *res = PR_Resources_Find (pr, "QFile");
int handle = P_INT (pr, 0); int handle = P_INT (pr, 0);
QFile **h = get_qfile (pr, handle, "Qclose"); qfile_t *h = handle_get (res, handle);
Qclose (*h); if (!h)
*h = 0; PR_RunError (pr, "invalid file handle pass to Qclose");
Qclose (h->file);
*h->prev = h->next;
handle_free (res, h);
} }
static void static void
bi_Qgetline (progs_t *pr) bi_Qgetline (progs_t *pr)
{ {
int handle = P_INT (pr, 0); int handle = P_INT (pr, 0);
QFile **h = get_qfile (pr, handle, "Qgetline"); qfile_t *h = get_handle (pr, __FUNCTION__, handle);
const char *s; const char *s;
s = Qgetline (*h); s = Qgetline (h->file);
if (s) if (s)
RETURN_STRING (pr, s); RETURN_STRING (pr, s);
else else
@ -161,112 +215,112 @@ static void
bi_Qread (progs_t *pr) bi_Qread (progs_t *pr)
{ {
int handle = P_INT (pr, 0); 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); pr_type_t *buf = P_GPOINTER (pr, 1);
int count = P_INT (pr, 2); int count = P_INT (pr, 2);
check_buffer (pr, buf, count, "Qread"); check_buffer (pr, buf, count, "Qread");
R_INT (pr) = Qread (*h, buf, count); R_INT (pr) = Qread (h->file, buf, count);
} }
static void static void
bi_Qwrite (progs_t *pr) bi_Qwrite (progs_t *pr)
{ {
int handle = P_INT (pr, 0); 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); pr_type_t *buf = P_GPOINTER (pr, 1);
int count = P_INT (pr, 2); int count = P_INT (pr, 2);
check_buffer (pr, buf, count, "Qwrite"); check_buffer (pr, buf, count, "Qwrite");
R_INT (pr) = Qwrite (*h, buf, count); R_INT (pr) = Qwrite (h->file, buf, count);
} }
static void static void
bi_Qputs (progs_t *pr) bi_Qputs (progs_t *pr)
{ {
int handle = P_INT (pr, 0); 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); const char *str = P_GSTRING (pr, 1);
R_INT (pr) = Qputs (*h, str); R_INT (pr) = Qputs (h->file, str);
} }
#if 0 #if 0
static void static void
bi_Qgets (progs_t *pr) bi_Qgets (progs_t *pr)
{ {
int handle = P_INT (pr, 0); 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); pr_type_t *buf = P_GPOINTER (pr, 1);
int count = P_INT (pr, 2); int count = P_INT (pr, 2);
check_buffer (pr, buf, count, "Qgets"); 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 #endif
static void static void
bi_Qgetc (progs_t *pr) bi_Qgetc (progs_t *pr)
{ {
int handle = P_INT (pr, 0); 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 static void
bi_Qputc (progs_t *pr) bi_Qputc (progs_t *pr)
{ {
int handle = P_INT (pr, 0); 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); int c = P_INT (pr, 1);
R_INT (pr) = Qputc (*h, c); R_INT (pr) = Qputc (h->file, c);
} }
static void static void
bi_Qseek (progs_t *pr) bi_Qseek (progs_t *pr)
{ {
int handle = P_INT (pr, 0); 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 offset = P_INT (pr, 1);
int whence = P_INT (pr, 2); int whence = P_INT (pr, 2);
R_INT (pr) = Qseek (*h, offset, whence); R_INT (pr) = Qseek (h->file, offset, whence);
} }
static void static void
bi_Qtell (progs_t *pr) bi_Qtell (progs_t *pr)
{ {
int handle = P_INT (pr, 0); 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 static void
bi_Qflush (progs_t *pr) bi_Qflush (progs_t *pr)
{ {
int handle = P_INT (pr, 0); 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 static void
bi_Qeof (progs_t *pr) bi_Qeof (progs_t *pr)
{ {
int handle = P_INT (pr, 0); 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 static void
bi_Qfilesize (progs_t *pr) bi_Qfilesize (progs_t *pr)
{ {
int handle = P_INT (pr, 0); 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[] = { static builtin_t secure_builtins[] = {

View file

@ -99,16 +99,16 @@ bi_QFS_LoadFile (progs_t *pr)
static void static void
bi_QFS_OpenFile (progs_t *pr) bi_QFS_OpenFile (progs_t *pr)
{ {
qfile_resources_t *res = PR_Resources_Find (pr, "QFile"); QFile *file;
QFile **file = QFile_AllocHandle (pr, res);
const char *filename = P_GSTRING (pr, 0); const char *filename = P_GSTRING (pr, 0);
QFS_FOpenFile (filename, file); QFS_FOpenFile (filename, &file);
if (!*file) { if (!file) {
RETURN_POINTER (pr, 0); R_INT (pr) = 0;
return; return;
} }
R_INT (pr) = (file - res->handles) + 1; if (!(R_INT (pr) = QFile_AllocHandle (pr, file)))
Qclose (file);
} }
static void static void
@ -136,9 +136,9 @@ bi_QFS_Filelist (progs_t *pr)
list = PR_Zone_Malloc (pr, sizeof (list) + filelist->count * 4); list = PR_Zone_Malloc (pr, sizeof (list) + filelist->count * 4);
list->count = filelist->count; list->count = filelist->count;
strings = (string_t *) list + 1; 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++) 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); 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 static void
bi_str_new (progs_t *pr) bi_str_new (progs_t *pr)
{ {
R_STRING (pr) = PR_NewString (pr); R_STRING (pr) = PR_NewMutableString (pr);
} }
static void static void
@ -78,11 +78,53 @@ bi_str_clear (progs_t *pr)
R_STRING (pr) = P_STRING (pr, 0); 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[] = { static builtin_t builtins[] = {
{"str_new", bi_str_new, -1}, {"str_new", bi_str_new, -1},
{"str_free", bi_str_free, -1}, {"str_free", bi_str_free, -1},
{"str_copy", bi_str_copy, -1}, {"str_copy", bi_str_copy, -1},
{"str_clear", bi_str_clear, -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} {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 \ 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 \ 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 \ 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) va.c ver_check.c wad.c wadfile.c zone.c $(fnmatch) $(getopt)
EXTRA_DIST= $(fnmatch_src) $(getopt_src) EXTRA_DIST= $(fnmatch_src) $(getopt_src)

View file

@ -35,15 +35,41 @@ static __attribute__ ((unused)) const char rcsid[] =
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "QF/dstring.h"
#include "QF/hash.h" #include "QF/hash.h"
#include "QF/qfplist.h" #include "QF/qfplist.h"
#include "QF/qtypes.h" #include "QF/qtypes.h"
#include "QF/sys.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 plitem_t *PL_ParsePropertyListItem (pldata_t *);
static qboolean PL_SkipSpace (pldata_t *); static qboolean PL_SkipSpace (pldata_t *);
static char *PL_ParseQuotedString (pldata_t *); static char *PL_ParseQuotedString (pldata_t *);
static char *PL_ParseUnquotedString (pldata_t *); static char *PL_ParseUnquotedString (pldata_t *);
static char *PL_ParseData (pldata_t *, int *);
static const char * static const char *
dict_get_key (void *i, void *unused) dict_get_key (void *i, void *unused)
@ -143,6 +169,14 @@ PL_Free (plitem_t *item)
free (item); free (item);
} }
const char *
PL_String (plitem_t *string)
{
if (string->type != QFString)
return NULL;
return string->data;
}
plitem_t * plitem_t *
PL_ObjectForKey (plitem_t *dict, const char *key) PL_ObjectForKey (plitem_t *dict, const char *key)
{ {
@ -159,22 +193,23 @@ PL_ObjectForKey (plitem_t *dict, const char *key)
plitem_t * plitem_t *
PL_D_AllKeys (plitem_t *dict) PL_D_AllKeys (plitem_t *dict)
{ {
void **list; void **list, **l;
dictkey_t *current; dictkey_t *current;
plitem_t *array; plitem_t *array;
if (dict->type != QFDictionary) if (dict->type != QFDictionary)
return NULL; return NULL;
if (!(list = Hash_GetList ((hashtab_t *) dict->data))) if (!(l = list = Hash_GetList ((hashtab_t *) dict->data)))
return NULL; return NULL;
if (!(array = PL_NewArray ())) if (!(array = PL_NewArray ()))
return NULL; return NULL;
while ((current = (dictkey_t *) *list++)) { while ((current = (dictkey_t *) *l++)) {
PL_A_AddObject (array, PL_NewString (current->key)); PL_A_AddObject (array, PL_NewString (current->key));
} }
free (list);
return array; return array;
} }
@ -333,6 +368,53 @@ PL_SkipSpace (pldata_t *pl)
return false; 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 * static char *
PL_ParseQuotedString (pldata_t *pl) PL_ParseQuotedString (pldata_t *pl)
{ {
@ -478,7 +560,7 @@ PL_ParseUnquotedString (pldata_t *pl)
char *str; char *str;
while (pl->pos < pl->end) { while (pl->pos < pl->end) {
if (!isalnum ((byte) pl->ptr[pl->pos]) && pl->ptr[pl->pos] != '_') if (is_quotable (pl->ptr[pl->pos]))
break; break;
pl->pos++; pl->pos++;
} }
@ -622,9 +704,16 @@ PL_ParsePropertyListItem (pldata_t *pl)
return item; return item;
} }
case '<': case '<': {
pl->error = "Unexpected character in string (binary data unsupported)"; int len;
char *str = PL_ParseData (pl, &len);
if (!str) {
return NULL; return NULL;
} else {
return PL_NewData (str, len);
}
}
case '"': { case '"': {
char *str = PL_ParseQuotedString (pl); char *str = PL_ParseQuotedString (pl);
@ -654,6 +743,9 @@ PL_GetPropertyList (const char *string)
pldata_t *pl = calloc (1, sizeof (pldata_t)); pldata_t *pl = calloc (1, sizeof (pldata_t));
plitem_t *newpl = NULL; plitem_t *newpl = NULL;
if (!quotable_bitmap[0])
init_quotables ();
pl->ptr = string; pl->ptr = string;
pl->pos = 0; pl->pos = 0;
pl->end = strlen (string); pl->end = strlen (string);
@ -670,3 +762,143 @@ PL_GetPropertyList (const char *string)
return NULL; 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]); pak = QFS_LoadPackFile (pakfiles[i]);
if (!pak) { if (!pak) {
Sys_Error (va ("Bad pakfile %s!!", pakfiles[i])); Sys_Error ("Bad pakfile %s!!", pakfiles[i]);
} else { } else {
search = calloc (1, sizeof (searchpath_t)); search = calloc (1, sizeof (searchpath_t));
search->pack = pak; 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 int
Sys_CheckInput (int idle, int net_socket) Sys_CheckInput (int idle, unsigned int net_socket)
{ {
fd_set fdset; fd_set fdset;
int res; 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]; static char buf[4];
Qwrite (wad->handle, buf, 4 - (pf->size & 3)); Qwrite (wad->handle, buf, 4 - (pf->size & 3));
} }
pf->disksize = pf->size;
Hash_AddElement (wad->lump_hash, pf); Hash_AddElement (wad->lump_hash, pf);
return 0; return 0;
} }
@ -312,6 +313,7 @@ wad_add_data (wad_t *wad, const char *lumpname, byte type, const void *data,
static char buf[4]; static char buf[4];
Qwrite (wad->handle, buf, 4 - (pf->size & 3)); Qwrite (wad->handle, buf, 4 - (pf->size & 3));
} }
pf->disksize = pf->size;
Hash_AddElement (wad->lump_hash, pf); Hash_AddElement (wad->lump_hash, pf);
return 0; return 0;
} }

View file

@ -92,9 +92,9 @@ typedef struct memblock_s
struct memzone_s struct memzone_s
{ {
int size; // total bytes malloced, including header int size; // total bytes malloced, including header
int used; // ammount used, including header
memblock_t blocklist; // start / end cap for linked list memblock_t blocklist; // start / end cap for linked list
memblock_t *rover; 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 // set the entire zone to one free block
zone->blocklist.next = zone->blocklist.prev = block = block = (memblock_t *) (zone + 1);
(memblock_t *) ((byte *) zone + sizeof (memzone_t)); zone->blocklist.next = block;
zone->blocklist.prev = block;
zone->blocklist.tag = 1; // in use block zone->blocklist.tag = 1; // in use block
zone->blocklist.id = 0; zone->blocklist.id = 0;
zone->blocklist.size = 0; zone->blocklist.size = 0;
zone->rover = block; zone->rover = block;
zone->size = size;
zone->used = sizeof (memzone_t);
block->prev = block->next = &zone->blocklist; block->prev = block->next = &zone->blocklist;
block->tag = 0; // free block block->tag = 0; // free block
@ -133,6 +136,7 @@ Z_Free (memzone_t *zone, void *ptr)
Sys_Error ("Z_Free: freed a freed pointer"); Sys_Error ("Z_Free: freed a freed pointer");
block->tag = 0; // mark as free block->tag = 0; // mark as free
zone->used -= block->size;
other = block->prev; other = block->prev;
if (!other->tag) { if (!other->tag) {
@ -219,10 +223,12 @@ Z_TagMalloc (memzone_t *zone, int size, int tag)
base->id = ZONEID; base->id = ZONEID;
zone->used += base->size;
// marker for memory trash testing // marker for memory trash testing
*(int *) ((byte *) base + base->size - 4) = ZONEID; *(int *) ((byte *) base + base->size - 4) = ZONEID;
return (void *) ((byte *) base + sizeof (memblock_t)); return (void *) (base + 1);
} }
void * void *
@ -254,18 +260,19 @@ Z_Realloc (memzone_t *zone, void *ptr, int size)
return ptr; return ptr;
} }
/*
static void void
Z_Print (memzone_t *zone) Z_Print (memzone_t *zone)
{ {
memblock_t *block; 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) for (block = zone->blocklist.next ; ; block = block->next)
{ {
Sys_Printf ("block:%p size:%7i tag:%3i\n", Sys_Printf ("block:%p size:%7i tag:%3i ofs:%d\n",
block, block->size, block->tag); block, block->size, block->tag, (byte *) block - (byte *) zone);
if (block->next == &zone->blocklist) if (block->next == &zone->blocklist)
break; // all blocks have been hit 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"); Sys_Printf ("ERROR: next block doesn't have proper back link\n");
if (!block->tag && !block->next->tag) if (!block->tag && !block->next->tag)
Sys_Printf ("ERROR: two consecutive free blocks\n"); 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 void
Z_CheckHeap (memzone_t *zone) 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]; tex = r_worldentity.model->textures[i];
if (!tex) if (!tex)
continue; continue;
if (!strncmp (tex->name, "sky", 3)) if (!strncmp (tex->name, "sky", 3)) {
skytexturenum = i; skytexturenum = i;
R_InitSky (tex);
}
if (!strncmp (tex->name, "window02_1", 10)) if (!strncmp (tex->name, "window02_1", 10))
mirrortexturenum = i; mirrortexturenum = i;
tex->texturechain = NULL; tex->texturechain = NULL;

View file

@ -31,6 +31,8 @@
static __attribute__ ((unused)) const char rcsid[] = static __attribute__ ((unused)) const char rcsid[] =
"$Id$"; "$Id$";
#include <stdlib.h>
#include "QF/console.h" #include "QF/console.h"
#include "QF/render.h" #include "QF/render.h"
#include "QF/sys.h" #include "QF/sys.h"
@ -38,18 +40,47 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "r_local.h" #include "r_local.h"
mnode_t *r_pefragtopnode; mnode_t *r_pefragtopnode;
efrag_t *r_free_efrags; vec3_t r_emins, r_emaxs;
// FIXME: put this on hunk?
efrag_t r_efrags[MAX_EFRAGS]; 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 */ /* 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 R_RemoveEfrags
@ -112,8 +143,11 @@ R_SplitEntityOnNode (mnode_t *node)
// grab an efrag off the free list // grab an efrag off the free list
ef = r_free_efrags; ef = r_free_efrags;
if (__builtin_expect (!ef, 0)) { if (__builtin_expect (!ef, 0)) {
Con_Printf ("Too many efrags!\n"); t_efrag_list *efl = calloc (1, sizeof (t_efrag_list));
return; // no free fragments... SYS_CHECKMEM (efl);
efl->next = efrag_list;
efrag_list = efl;
ef = r_free_efrags = &efl->efrags[0];
} }
r_free_efrags = r_free_efrags->entnext; 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++) for (i = 0; i < r_worldentity.model->numleafs; i++)
r_worldentity.model->leafs[i].efrags = NULL; r_worldentity.model->leafs[i].efrags = NULL;
if (worldmodel->skytexture)
R_InitSky (worldmodel->skytexture);
r_viewleaf = NULL; r_viewleaf = NULL;
R_ClearParticles (); 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++) for (i = 0; i < r_worldentity.model->numleafs; i++)
r_worldentity.model->leafs[i].efrags = NULL; r_worldentity.model->leafs[i].efrags = NULL;
if (worldmodel->skytexture)
R_InitSky (worldmodel->skytexture);
r_viewleaf = NULL; r_viewleaf = NULL;
R_ClearParticles (); R_ClearParticles ();

View file

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

View file

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

View file

@ -74,13 +74,13 @@ Chase_Reset (void)
// start position 12 units behind head // start position 12 units behind head
} }
static void static inline void
TraceLine (vec3_t start, vec3_t end, vec3_t impact) TraceLine (vec3_t start, vec3_t end, vec3_t impact)
{ {
trace_t trace; trace_t trace;
memset (&trace, 0, sizeof (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); VectorCopy (trace.endpos, impact);
} }

View file

@ -39,16 +39,18 @@ static __attribute__ ((unused)) const char rcsid[] =
#endif #endif
#include "QF/cbuf.h" #include "QF/cbuf.h"
#include "QF/idparse.h"
#include "QF/cmd.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/console.h"
#include "QF/cvar.h"
#include "QF/dstring.h"
#include "QF/idparse.h"
#include "QF/keys.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/sys.h"
#include "QF/va.h"
#include "client.h" #include "client.h"
#include "compat.h" #include "compat.h"
@ -410,22 +412,26 @@ Host_Connect_f (void)
Writes a SAVEGAME_COMMENT_LENGTH character comment describing the current Writes a SAVEGAME_COMMENT_LENGTH character comment describing the current
*/ */
static void static void
Host_SavegameComment (char *text) Host_SavegameComment (QFile *file)
{ {
int i; unsigned i;
char kills[20]; dstring_t *comment = dstring_newstr ();
for (i = 0; i < SAVEGAME_COMMENT_LENGTH; i++) dsprintf (comment, "%-21s kills:%3i/%3i", cl.levelname,
text[i] = ' '; cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]);
memcpy (text, cl.levelname, strlen (cl.levelname)); if ((i = comment->size - 1) < SAVEGAME_COMMENT_LENGTH) {
snprintf (kills, sizeof (kills), "kills:%3i/%3i", cl.stats[STAT_MONSTERS], comment->size = SAVEGAME_COMMENT_LENGTH + 1;
cl.stats[STAT_TOTALMONSTERS]); dstring_adjust (comment);
memcpy (text + 22, kills, strlen (kills)); 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 // convert space to _ to make stdio happy
for (i = 0; i < SAVEGAME_COMMENT_LENGTH; i++) for (i = 0; i < SAVEGAME_COMMENT_LENGTH; i++)
if (text[i] == ' ') if (comment->str[i] == ' ')
text[i] = '_'; comment->str[i] = '_';
text[SAVEGAME_COMMENT_LENGTH] = '\0'; Qwrite (file, comment->str, SAVEGAME_COMMENT_LENGTH + 1);
} }
static void static void
@ -434,7 +440,6 @@ Host_Savegame_f (void)
char name[256]; char name[256];
QFile *f; QFile *f;
int i; int i;
char comment[SAVEGAME_COMMENT_LENGTH + 1];
if (cmd_source != src_command) if (cmd_source != src_command)
return; return;
@ -484,8 +489,7 @@ Host_Savegame_f (void)
} }
Qprintf (f, "%i\n", SAVEGAME_VERSION); Qprintf (f, "%i\n", SAVEGAME_VERSION);
Host_SavegameComment (comment); Host_SavegameComment (f);
Qprintf (f, "%s\n", comment);
for (i = 0; i < NUM_SPAWN_PARMS; i++) for (i = 0; i < NUM_SPAWN_PARMS; i++)
Qprintf (f, "%f\n", svs.clients->spawn_parms[i]); Qprintf (f, "%f\n", svs.clients->spawn_parms[i]);
Qprintf (f, "%d\n", current_skill); Qprintf (f, "%d\n", current_skill);
@ -513,77 +517,88 @@ Host_Savegame_f (void)
static void static void
Host_Loadgame_f (void) Host_Loadgame_f (void)
{ {
char name[MAX_OSPATH]; dstring_t *name = 0;
QFile *f; QFile *f;
char mapname[MAX_QPATH]; char *mapname = 0;
script_t *script = 0;
char *str = 0;
float time, tfloat; float time, tfloat;
char str[32768];
const char *start;
unsigned int i; unsigned int i;
int r;
edict_t *ent; edict_t *ent;
int entnum; int entnum;
int version; int version;
float spawn_parms[NUM_SPAWN_PARMS]; float spawn_parms[NUM_SPAWN_PARMS];
char buf[100];
if (cmd_source != src_command) if (cmd_source != src_command)
return; goto end;
if (Cmd_Argc () != 2) { if (Cmd_Argc () != 2) {
Con_Printf ("load <savename> : load a game\n"); Con_Printf ("load <savename> : load a game\n");
return; goto end;
} }
cls.demonum = -1; // stop demo loop in case this fails cls.demonum = -1; // stop demo loop in case this fails
snprintf (name, sizeof (name), "%s/%s", name = dstring_newstr ();
qfs_gamedir->dir.def, Cmd_Argv (1)); dsprintf (name, "%s/%s", qfs_gamedir->dir.def, Cmd_Argv (1));
QFS_DefaultExtension (name, ".sav"); name->size += 4;
dstring_adjust (name);
QFS_DefaultExtension (name->str, ".sav");
// we can't call SCR_BeginLoadingPlaque, because too much stack space has // we can't call SCR_BeginLoadingPlaque, because too much stack space has
// been used. The menu calls it before stuffing loadgame command // been used. The menu calls it before stuffing loadgame command
// SCR_BeginLoadingPlaque (); // SCR_BeginLoadingPlaque ();
Con_Printf ("Loading game from %s...\n", name); Con_Printf ("Loading game from %s...\n", name->str);
f = QFS_Open (name, "rz"); f = QFS_Open (name->str, "rz");
if (!f) { if (!f) {
Con_Printf ("ERROR: couldn't open.\n"); Con_Printf ("ERROR: couldn't open.\n");
return; goto end;
} }
str = malloc (Qfilesize (f) + 1);
Qgets (f, buf, sizeof (buf)); i = Qread (f, str, Qfilesize (f));
sscanf (buf, "%i\n", &version); str[i] = 0;
if (version != SAVEGAME_VERSION) {
Qclose (f); Qclose (f);
script = Script_New ();
Script_Start (script, name->str, str);
Script_GetToken (script, 1);
sscanf (script->token->str, "%i", &version);
if (version != SAVEGAME_VERSION) {
Con_Printf ("Savegame is version %i, not %i\n", version, Con_Printf ("Savegame is version %i, not %i\n", version,
SAVEGAME_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++) { for (i = 0; i < NUM_SPAWN_PARMS; i++) {
Qgets (f, buf, sizeof (buf)); Script_GetToken (script, 1);
sscanf (buf, "%f\n", &spawn_parms[i]); sscanf (script->token->str, "%f", &spawn_parms[i]);
} }
// this silliness is so we can load 1.06 save files, which have float skill // this silliness is so we can load 1.06 save files, which have float skill
// values // values
Qgets (f, buf, sizeof (buf)); Script_GetToken (script, 1);
sscanf (buf, "%f\n", &tfloat); sscanf (script->token->str, "%f", &tfloat);
current_skill = (int) (tfloat + 0.1); current_skill = (int) (tfloat + 0.1);
Cvar_SetValue (skill, (float) current_skill); Cvar_SetValue (skill, (float) current_skill);
Qgets (f, buf, sizeof (buf)); Script_GetToken (script, 1);
sscanf (buf, "%s\n", mapname); mapname = strdup (script->token->str);
Qgets (f, buf, sizeof (buf));
sscanf (buf, "%f\n", &time); Script_GetToken (script, 1);
sscanf (script->token->str, "%f", &time);
CL_Disconnect_f (); CL_Disconnect_f ();
SV_SpawnServer (mapname); SV_SpawnServer (mapname);
if (!sv.active) { if (!sv.active) {
Con_Printf ("Couldn't load map\n"); Con_Printf ("Couldn't load map %s\n", mapname);
return; goto end;
} }
sv.paused = true; // pause until all clients connect sv.paused = true; // pause until all clients connect
sv.loadgame = true; sv.loadgame = true;
@ -591,44 +606,27 @@ Host_Loadgame_f (void)
// load the light styles // load the light styles
for (i = 0; i < MAX_LIGHTSTYLES; i++) { for (i = 0; i < MAX_LIGHTSTYLES; i++) {
char *s; char *s;
Qgets (f, buf, sizeof (buf));
sscanf (buf, "%s\n", str); Script_GetToken (script, 1);
s = Hunk_Alloc (strlen (str) + 1); s = Hunk_Alloc (strlen (script->token->str) + 1);
strcpy (s, str); strcpy (s, script->token->str);
sv.lightstyles[i] = s; sv.lightstyles[i] = s;
} }
// load the edicts out of the savegame file // load the edicts out of the savegame file
entnum = -1; // -1 is the globals entnum = -1; // -1 is the globals
while (!Qeof (f)) { while (Script_GetToken (script, 1)) {
for (i = 0; i < sizeof (str) - 1; i++) { if (strcmp (script->token->str, "{"))
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, "{"))
Sys_Error ("First token isn't a brace"); Sys_Error ("First token isn't a brace");
if (entnum == -1) { // parse the global vars if (entnum == -1) { // parse the global vars
ED_ParseGlobals (&sv_pr_state, start); ED_ParseGlobals (&sv_pr_state, script);
} else { // parse an edict } else { // parse an edict
ent = EDICT_NUM (&sv_pr_state, entnum); ent = EDICT_NUM (&sv_pr_state, entnum);
memset (&ent->v, 0, sv_pr_state.progs->entityfields * 4); memset (&ent->v, 0, sv_pr_state.progs->entityfields * 4);
ent->free = false; ent->free = false;
ED_ParseEdict (&sv_pr_state, start, ent); ED_ParseEdict (&sv_pr_state, script, ent);
// link it into the bsp tree // link it into the bsp tree
if (!ent->free) if (!ent->free)
@ -641,8 +639,6 @@ Host_Loadgame_f (void)
sv.num_edicts = entnum; sv.num_edicts = entnum;
sv.time = time; sv.time = time;
Qclose (f);
for (i = 0; i < NUM_SPAWN_PARMS; i++) for (i = 0; i < NUM_SPAWN_PARMS; i++)
svs.clients->spawn_parms[i] = spawn_parms[i]; svs.clients->spawn_parms[i] = spawn_parms[i];
@ -650,6 +646,15 @@ Host_Loadgame_f (void)
CL_EstablishConnection ("local"); CL_EstablishConnection ("local");
Host_Reconnect_f (); 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/cmd.h"
#include "QF/cvar.h" #include "QF/cvar.h"
#include "QF/msg.h" #include "QF/msg.h"
#include "QF/mathlib.h"
#include "QF/sys.h" #include "QF/sys.h"
#include "QF/va.h" #include "QF/va.h"
@ -121,7 +122,8 @@ void
SV_StartSound (edict_t *entity, int channel, const char *sample, int volume, SV_StartSound (edict_t *entity, int channel, const char *sample, int volume,
float attenuation) float attenuation)
{ {
int ent, field_mask, sound_num, i; int ent, field_mask, sound_num;
vec3_t v;
if (volume < 0 || volume > 255) if (volume < 0 || volume > 255)
Sys_Error ("SV_StartSound: volume = %i", volume); 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_WriteByte (&sv.datagram, attenuation * 64);
MSG_WriteShort (&sv.datagram, channel); MSG_WriteShort (&sv.datagram, channel);
MSG_WriteByte (&sv.datagram, sound_num); MSG_WriteByte (&sv.datagram, sound_num);
for (i=0; i < 3; i++) // FIXME: replace with MSG_WriteCoordV? VectorBlend (SVvector (entity, mins), SVvector (entity, maxs), 0.5, v);
MSG_WriteCoord (&sv.datagram, SVvector (entity, origin)[i] + 0.5 * VectorAdd (v, SVvector (entity, origin), v);
(SVvector (entity, mins)[i] + MSG_WriteCoordV (&sv.datagram, v);
SVvector (entity, maxs)[i]));
} }
// CLIENT SPAWNING ============================================================ // CLIENT SPAWNING ============================================================
@ -509,6 +510,7 @@ void
SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg) SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
{ {
int bits, items, i; int bits, items, i;
vec3_t v;
edict_t *other; edict_t *other;
// send a damage message // send a damage message
@ -517,10 +519,9 @@ SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
MSG_WriteByte (msg, svc_damage); MSG_WriteByte (msg, svc_damage);
MSG_WriteByte (msg, SVfloat (ent, dmg_save)); MSG_WriteByte (msg, SVfloat (ent, dmg_save));
MSG_WriteByte (msg, SVfloat (ent, dmg_take)); MSG_WriteByte (msg, SVfloat (ent, dmg_take));
for (i=0; i < 3; i++) // FIXME: replace with MSG_WriteCoordV VectorBlend (SVvector (other, mins), SVvector (other, maxs), 0.5, v);
MSG_WriteCoord (msg, SVvector (other, origin)[i] + 0.5 * VectorAdd (v, SVvector (other, origin), v);
(SVvector (other, mins)[i] + MSG_WriteCoordV (msg, v);
SVvector (other, maxs)[i]));
SVfloat (ent, dmg_take) = 0; SVfloat (ent, dmg_take) = 0;
SVfloat (ent, dmg_save) = 0; SVfloat (ent, dmg_save) = 0;
} }
@ -1010,6 +1011,7 @@ SV_SpawnServer (const char *server)
// serverflags are for cross level information (sigils) // serverflags are for cross level information (sigils)
*sv_globals.serverflags = svs.serverflags; *sv_globals.serverflags = svs.serverflags;
*sv_globals.time = sv.time;
if ((buf = QFS_LoadFile (va ("maps/%s.ent", server), 0))) { if ((buf = QFS_LoadFile (va ("maps/%s.ent", server), 0))) {
ED_LoadFromFile (&sv_pr_state, buf); ED_LoadFromFile (&sv_pr_state, buf);
free (buf); free (buf);

View file

@ -37,7 +37,6 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "host.h" #include "host.h"
#include "server.h" #include "server.h"
#include "sv_progs.h"
#include "world.h" #include "world.h"
#define sv_frametime host_frametime #define sv_frametime host_frametime
@ -93,9 +92,6 @@ SV_CheckAllEnts (void)
void void
SV_CheckVelocity (edict_t *ent) SV_CheckVelocity (edict_t *ent)
{ {
#if 0
float wishspeed;
#endif
int i; int i;
// bound velocity // bound velocity
@ -112,20 +108,11 @@ SV_CheckVelocity (edict_t *ent)
classname))); classname)));
SVvector (ent, origin)[i] = 0; SVvector (ent, origin)[i] = 0;
} }
#if 1
if (SVvector (ent, velocity)[i] > sv_maxvelocity->value) if (SVvector (ent, velocity)[i] > sv_maxvelocity->value)
SVvector (ent, velocity)[i] = sv_maxvelocity->value; SVvector (ent, velocity)[i] = sv_maxvelocity->value;
else if (SVvector (ent, velocity)[i] < -sv_maxvelocity->value) else if (SVvector (ent, velocity)[i] < -sv_maxvelocity->value)
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
} }
/* /*
@ -743,6 +730,7 @@ SV_RunEntity (edict_t *ent)
default: default:
Sys_Error ("SV_Physics: bad movetype %i", Sys_Error ("SV_Physics: bad movetype %i",
(int) SVfloat (ent, movetype)); (int) SVfloat (ent, movetype));
break;
} }
} }

View file

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

View file

@ -139,7 +139,7 @@ ED_Count_f (void)
ED_Count (&sv_pr_state); ED_Count (&sv_pr_state);
} }
void static void
PR_Profile_f (void) PR_Profile_f (void)
{ {
if (!sv_pr_state.progs) { 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 static int
resolve (progs_t *pr) resolve (progs_t *pr)
{ {
sv_def_t *def; int ret = 1;
ddef_t *ddef;
dfunction_t *f;
void *global;
func_t func;
if (pr->progs->crc == nq_crc) { if (pr->progs->crc == nq_crc) {
global = &G_FLOAT(pr, nq_self[0].offset); resolve_globals (pr, nq_self, 2);
set_address (&nq_self[0], global); resolve_globals (pr, nq_defs, 2);
for (def = nq_defs; def->name; def++) { resolve_functions (pr, nq_funcs, 2);
global = &G_FLOAT(pr, def->offset); resolve_fields (pr, nq_fields, 2);
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;
}
} else { } else {
for (def = nq_self; def->name; def++) { if (!resolve_globals (pr, nq_self, 0))
ddef = PR_FindGlobal (&sv_pr_state, def->name); ret = 0;
if (ddef) { if (!resolve_globals (pr, nq_defs, 1))
global = &G_FLOAT(pr, ddef->ofs); ret = 0;
set_address (def, global); if (!resolve_functions (pr, nq_funcs, 1))
} ret = 0;
} if (!resolve_fields (pr, nq_fields, 1))
for (def = nq_defs; def->name; def++) { ret = 0;
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);
} }
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 // progs engine needs these globals anyway
sv_pr_state.globals.self = sv_globals.self; sv_pr_state.globals.self = sv_globals.self;
sv_pr_state.globals.time = sv_globals.time; sv_pr_state.globals.time = sv_globals.time;
return 1; return ret;
} }
void void
@ -457,7 +493,6 @@ SV_Progs_Init (void)
{ {
sv_pr_state.edicts = &sv.edicts; sv_pr_state.edicts = &sv.edicts;
sv_pr_state.num_edicts = &sv.num_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.reserved_edicts = &svs.maxclients;
sv_pr_state.unlink = SV_UnlinkEdict; sv_pr_state.unlink = SV_UnlinkEdict;
sv_pr_state.parse_field = parse_field; 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) if (SVfloat (touch, solid) == SOLID_TRIGGER)
Sys_Error ("Trigger in clipping list"); Sys_Error ("Trigger in clipping list");
if (clip->type == MOVE_NOMONSTERS && SVfloat (touch, solid) if (clip->type == MOVE_NOMONSTERS
!= SOLID_BSP) && SVfloat (touch, solid) != SOLID_BSP)
continue; continue;
if (clip->boxmins[0] > SVvector (touch, absmax)[0] 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/mathlib.h"
#include "QF/model.h" #include "QF/model.h"
#include "world.h"
#define STOP_EPSILON 0.1 #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) #define MAX_PHYSENTS (MAX_CLIENTS + MAX_PACKET_ENTITIES)
typedef struct typedef struct {
{
vec3_t origin; vec3_t origin;
model_t *model; // only for bsp models model_t *model; // only for bsp models
vec3_t mins, maxs; // only for non-bsp models vec3_t mins, maxs; // only for non-bsp models
@ -64,8 +47,7 @@ typedef struct
} physent_t; } physent_t;
typedef struct typedef struct {
{
int sequence; // just for debugging prints int sequence; // just for debugging prints
// player state // player state
@ -88,7 +70,7 @@ typedef struct
// results // results
int numtouch; int numtouch;
int touchindex[MAX_PHYSENTS]; physent_t *touchindex[MAX_PHYSENTS];
} playermove_t; } playermove_t;
typedef struct { 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); int PM_PointContents (const vec3_t point);
qboolean PM_TestPlayerPosition (const vec3_t point); qboolean PM_TestPlayerPosition (const vec3_t point);
pmtrace_t PM_PlayerMove (const vec3_t start, const vec3_t stop); trace_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);
#endif // _PMOVE_H #endif // _PMOVE_H

View file

@ -29,11 +29,6 @@
#ifndef __sv_pr_cmds_h #ifndef __sv_pr_cmds_h
#define __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_error (progs_t *pr);
void PF_objerror (progs_t *pr); void PF_objerror (progs_t *pr);
void PF_makevectors (progs_t *pr); void PF_makevectors (progs_t *pr);

View file

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

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