Pull in changes from master

This commit is contained in:
Jeff Teunissen 2010-08-23 00:03:46 -04:00
commit 4452c31859
25 changed files with 342 additions and 1054 deletions

View file

@ -13,9 +13,8 @@ EXTRA_DIST= ChangeLog configure.ac \
tools/gas2masm/gas2masm.dsp tools/gas2masm/gas2masm.dsw \
tools/gas2masm/gas2masm.mak tools/gas2masm/gas2masm.mdp
changelog::
( cd $(top_srcdir); \
tools/cvs2cl/cvs2cl.pl --stdout -b --utc -S --no-wrap) > ChangeLog
ChangeLog:
git log > ChangeLog
NOCONV_DIST= $(distdir)/include/win32/resources/icon1.ico

View file

@ -19,7 +19,7 @@ if test "$1" = "clean"; then
rm -f aclocal.m4 build-stamp changelog-stamp config.cache config.log \
config.status configure configure-stamp install-sh libtool missing \
mkinstalldirs quakeforge-config quakeforge.lsm
rm -f compile config.guess config.sub depcomp ltmain.sh
rm -f compile config.guess config.sub depcomp ltmain.sh ylwrap
rm -rf autom4te.cache
cd -

View file

@ -6,6 +6,23 @@ else
cvs_def_disabled="!= xno"
fi
if test "x$GCC" = xyes; then
set $CC
shift
args="$*"
AC_MSG_CHECKING(for gcc version)
CCVER="gcc `$CC --version | grep '[[0-9]]\.[[0-9]]' | sed -e 's/.*(GCC)//' -e 's/[[^0-9]]*\([[0-9.]]*\).*/\1/'`"
set $CCVER
save_IFS="$IFS"
IFS="."
set $2
CC_MAJ=$1
CC_MIN=$2
CC_SUB=$3
IFS="$save_IFS"
AC_MSG_RESULT($CCVER)
fi
AC_ARG_ENABLE(debug,
[ --disable-debug compile without debugging],
debug=$enable_debug
@ -29,20 +46,6 @@ if test "x$optimize" = xyes; then
AC_MSG_RESULT(yes)
BUILD_TYPE="$BUILD_TYPE Optimize"
if test "x$GCC" = xyes; then
set $CC
shift
args="$*"
AC_MSG_CHECKING(for gcc version)
CCVER="gcc `$CC --version | grep '[[0-9]]\.[[0-9]]' | sed -e 's/.*(GCC)//' -e 's/[[^0-9]]*\([[0-9.]]*\).*/\1/'`"
set $CCVER
save_IFS="$IFS"
IFS="."
set $2
CC_MAJ=$1
CC_MIN=$2
CC_SUB=$3
IFS="$save_IFS"
AC_MSG_RESULT($CCVER)
saved_cflags="$CFLAGS"
CFLAGS=""
QF_CC_OPTION(-frename-registers)

View file

@ -4,7 +4,14 @@ AC_PREREQ(2.67)
dnl This is the only place where the package name and version appear
AC_INIT([QuakeForge], [git-master])
AM_INIT_AUTOMAKE([foreign])
dnl LT_INIT messes with CFLAGS (evil bastard)
if test "x${CFLAGS-unset}" = xunset; then
CFLAGS=""
fi
saved_CFLAGS="$CFLAGS"
LT_INIT([win32-dll])
CFLAGS="$saved_CFLAGS"
AC_REVISION([$Revision$]) dnl
@ -17,9 +24,6 @@ m4_include(config.d/versions.m4)
AC_LANG_C
if test "x${CFLAGS-unset}" = xunset; then
CFLAGS=""
fi
if test "$x{AR-unset}" = xunset; then
AR="ar"
fi
@ -115,17 +119,6 @@ if test "x$enable_typecheck_progs" = xyes; then
AC_DEFINE(TYPECHECK_PROGS, 1, [Define this if you want progs typechecking])
fi
AC_ARG_ENABLE(boxclip,
[ --enable-boxclip enable box clipping],
boxclip=$enable_boxclip,
boxclip=no
)
if test "x$boxclip" != xno; then
AC_DEFINE(ENABLE_BOXCLIP, 1, [Define if you want boxclipping])
else
AC_DEFINE(ENABLE_BOXCLIP, 0, [Define if you want boxclipping])
fi
TOPSRC=`readlink -f ${srcdir}`
AC_SUBST(TOPSRC)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 13 KiB

60
doc/ideas/quack.fig Normal file
View file

@ -0,0 +1,60 @@
#FIG 3.2
Landscape
Center
Inches
Letter
100.00
Single
-2
1200 2
1 3 0 1 0 0 100 0 20 0.000 1 0.0000 1200 1200 1200 1200 1200 1200 2400 1200
1 3 0 1 0 7 100 0 20 0.000 1 0.0000 1200 1200 928 928 1200 1200 2128 1200
3 1 0 1 0 0 100 0 20 0.000 0 0 0 12
3000 1200 3000 2100 3300 2400 3900 2400 4200 2100 4200 1200
4050 1050 3900 1200 3900 2100 3300 2100 3300 1200 3150 1050
1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
1.000 1.000 1.000 1.000
3 1 0 1 0 0 100 0 20 0.000 0 0 0 12
4800 2250 4800 1350 5100 1050 5700 1050 6000 1350 6000 2250
5850 2400 5700 2250 5700 1350 5100 1350 5100 2250 4950 2400
1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
1.000 1.000 1.000 1.000
3 1 0 1 0 0 100 0 20 0.000 0 0 0 12
7800 2400 6900 2400 6600 2100 6600 1350 6900 1050 7800 1050
7950 1200 7800 1350 6900 1350 6900 2100 7800 2100 7950 2250
1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
1.000 1.000 1.000 1.000
3 1 0 1 0 0 100 0 20 0.000 0 0 0 6
4950 1800 5100 1650 5700 1650 5850 1800 5700 1950 5100 1950
1.000 1.000 1.000 1.000 1.000 1.000
3 1 0 1 0 0 100 0 20 0.000 0 0 0 10
1200 1200 1500 1200 2100 2100 2400 2100 2550 2250 2400 2400
2100 2400 1500 1500 1200 1500 1050 1350
1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
1.000 1.000
3 1 0 1 0 0 100 0 20 0.000 0 0 0 6
8700 2250 8550 2400 8400 2250 8400 150 8550 0 8700 150
1.000 1.000 1.000 1.000 1.000 1.000
3 1 0 1 0 0 100 0 20 0.000 0 0 0 12
9750 2400 8850 2400 8550 2100 8550 1350 8850 1050 9750 1050
9900 1200 9750 1350 8850 1350 8850 2100 9750 2100 9900 2250
1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
1.000 1.000 1.000 1.000
3 0 0 1 0 7 100 0 -1 0.000 0 0 0 14
375 4725 1200 4125 450 3525 825 2775 2550 2700 3000 3525
4200 4050 4275 4200 2700 3750 4200 4575 4050 4650 2550 4050
2025 4275 3000 4875
0.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
1.000 1.000 1.000 1.000 1.000 0.000
3 3 0 1 0 7 100 0 -1 0.000 0 0 0 4
4500 3900 5625 3900 5625 4875 4575 4875
-1.000 -1.000 -1.000 -1.000
3 2 0 1 0 7 100 0 -1 0.000 0 0 0 3
6150 4950 6150 3900 6900 3900
0.000 -1.000 0.000
3 2 0 1 0 7 100 0 -1 0.000 0 0 0 6
8100 4650 7350 4950 7350 3900 8100 3975 8175 5550 7425 5625
0.000 -1.000 -1.000 -1.000 -1.000 0.000
3 2 0 1 0 7 100 0 -1 0.000 0 0 0 5
9000 4350 9750 4350 9300 3675 8925 4350 9375 5025
0.000 -1.000 -1.000 -1.000 0.000

View file

@ -8,10 +8,10 @@ Quake and QuakeWorld game engine. Our purpose? To improve the state of the
game by improving the engine and making it accessable to the largest number
of players we can.
\li \ref faq
\li \ref key_binding
\li \ref cshift_cvars
\li \ref qw_cap_spec
\li \ref qw_download_spec
\li \ref server_timestampes
\li \subpage faq
\li \subpage key_binding
\li \subpage cshift_cvars
\li \subpage qw_cap_spec
\li \subpage qw_download_spec
\li \subpage server_timestampes
*/

View file

@ -3,13 +3,15 @@
\page surround_sound_spec Description of Surround-Sound Channels
Swiped from the vorbis docs
\li one channel - the stream is monophonic
\li two channels - the stream is stereo. channel order: left, right
\li three channels - the stream is a 1d-surround encoding. channel order: left, center, right
\li four channels - the stream is quadraphonic surround. channel order: front left, front right, rear left, rear right
\li five channels - the stream is five-channel surround. channel order: front left, center, front right, rear left, rear right
\li six channels - the stream is 5.1 surround. channel order: front left, center, front right, rear left, rear right, LFE
\li seven channels - the stream is 6.1 surround. channel order: front left, center, front right, side left, side right, rear center, LFE
\li eight channels - the stream is 7.1 surround. channel order: front left, center, front right, side left, side right, rear left, rear right, LFE
\li greater than eight channels - channel use and order is undefined
<dl>
<dt>one channel</dt> <dd>the stream is monophonic</dd>
<dt>two channels</dt> <dd>the stream is stereo. channel order: left, right</dd>
<dt>three channels</dt> <dd>the stream is a 1d-surround encoding. channel order: left, center, right</dd>
<dt>four channels</dt> <dd>the stream is quadraphonic surround. channel order: front left, front right, rear left, rear right</dd>
<dt>five channels</dt> <dd>the stream is five-channel surround. channel order: front left, center, front right, rear left, rear right</dd>
<dt>six channels</dt> <dd>the stream is 5.1 surround. channel order: front left, center, front right, rear left, rear right, LFE</dd>
<dt>seven channels</dt> <dd>the stream is 6.1 surround. channel order: front left, center, front right, side left, side right, rear center, LFE</dd>
<dt>eight channels</dt> <dd>the stream is 7.1 surround. channel order: front left, center, front right, side left, side right, rear left, rear right, LFE</dd>
<dt>greater than eight channels</dt> <dd>channel use and order is undefined </dd>
</dl>
*/

View file

@ -8,74 +8,76 @@ the date and time.
The following special codes are interpreted inside sv_timefmt strings.
\%a The abbreviated weekday name according to the current
locale.
<dl>
<dt>\%a</dt> <dd>The abbreviated weekday name according to the current
locale.</dd>
\%A The full weekday name according to the current
locale.
<dt>\%A</dt> <dd>The full weekday name according to the current
locale.</dd>
\%b The abbreviated month name according to the current
locale.
<dt>\%b</dt> <dd>The abbreviated month name according to the current
locale.</dd>
\%B The full month name according to the current
locale.
<dt>\%B</dt> <dd>The full month name according to the current
locale.</dd>
\%c The preferred date and time representation for the
current locale.
<dt>\%c</dt> <dd>The preferred date and time representation for the
current locale.</dd>
\%d The day of the month as a decimal number (range 01
to 31).
<dt>\%d</dt> <dd>The day of the month as a decimal number (range 01
to 31).</dd>
\%h Equivalent to %b. (SU)
<dt>\%h</dt> <dd>Equivalent to %b. (SU)</dd>
\%H The hour as a decimal number using a 24-hour clock
(range 00 to 23).
<dt>\%H</dt> <dd>The hour as a decimal number using a 24-hour clock
(range 00 to 23).</dd>
\%I The hour as a decimal number using a 12-hour clock
(range 01 to 12).
<dt>\%I</dt> <dd>The hour as a decimal number using a 12-hour clock
(range 01 to 12).</dd>
\%j The day of the year as a decimal number (range 001
to 366).
<dt>\%j</dt> <dd>The day of the year as a decimal number (range 001
to 366).</dd>
\%k The hour (24-hour clock) as a decimal number (range
0 to 23); single digits are preceded by a blank.
(See also %H.) (TZ)
<dt>\%k</dt> <dd>The hour (24-hour clock) as a decimal number (range
0 to 23); single digits are preceded by a blank.
(See also %H.) (TZ)</dd>
\%m The month as a decimal number (range 01 to 12).
<dt>\%m</dt> <dd>The month as a decimal number (range 01 to 12).</dd>
\%M The minute as a decimal number (range 00 to 59).
<dt>\%M</dt> <dd>The minute as a decimal number (range 00 to 59).</dd>
\%p Either `AM' or `PM' according to the given time
value, or the corresponding strings for the current
locale. Noon is treated as `pm' and midnight as
`am'.
<dt>\%p</dt> <dd>Either `AM' or `PM' according to the given time
value, or the corresponding strings for the current
locale. Noon is treated as `pm' and midnight as
`am'.</dd>
\%S The second as a decimal number (range 00 to 61).
<dt>\%S</dt> <dd>The second as a decimal number (range 00 to 61).</dd>
\%U The week number of the current year as a decimal
number, range 00 to 53, starting with the first
Sunday as the first day of week 01. See also %V and
%W.
<dt>\%U</dt> <dd>The week number of the current year as a decimal
number, range 00 to 53, starting with the first
Sunday as the first day of week 01. See also %V and
%W.</dd>
\%w The day of the week as a decimal, range 0 to 6,
Sunday being 0. See also %u.
<dt>\%w</dt> <dd>The day of the week as a decimal, range 0 to 6,
Sunday being 0. See also %u.</dd>
\%W The week number of the current year as a decimal
number, range 00 to 53, starting with the first
Monday as the first day of week 01.
<dt>\%W</dt> <dd>The week number of the current year as a decimal
number, range 00 to 53, starting with the first
Monday as the first day of week 01.</dd>
\%x The preferred date representation for the current
locale without the time.
<dt>\%x</dt> <dd>The preferred date representation for the current
locale without the time.</dd>
\%X The preferred time representation for the current
locale without the date.
<dt>\%X</dt> <dd>The preferred time representation for the current
locale without the date.</dd>
\%y The year as a decimal number without a century
(range 00 to 99).
<dt>\%y</dt> <dd>The year as a decimal number without a century
(range 00 to 99).</dd>
\%Y The year as a decimal number including the century.
<dt>\%Y</dt> <dd>The year as a decimal number including the century.</dd>
\%Z The time zone name or abbreviation.
\%\% A literal `\%' character.
<dt>\%Z</dt> <dd>The time zone name or abbreviation.</dd>
<dt>\%\%</dt> <dd>A literal `\%' character.</dd>
</dl>
*/

View file

@ -39,80 +39,50 @@
/**
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).
QFArray A list of indexed values
QFString A string.
QFBinary Random binary data. The parser doesn't load these yet.
<dl>
<dt>QFDictionary</dt> <dd>A list of values, each associated with a
key (a C string).</dd>
<dt>QFArray</dt> <dd>A list of indexed values</dd>
<dt>QFString</dt> <dd>A string.</dd>
<dt>QFBinary</dt> <dd>Random binary data.</dd>
</dl>
In textual form, a dictionary looks like:
\code
{
key = value;
}
\endcode
An array looks like:
\code
(
value1,
value2
)
\endcode
An unquoted string may contain only alphanumeric characters and/or the
underscore character, '_'. Quoted strings may contain whitespace, C escape
sequences, and so on. The quote character is '"'. Optionally, Python style
long strings ("""...""") may be used, allowing for unquoted '"' quotes in
the string.
underscore character, <code>_</code>. Quoted strings may contain
whitespace, C escape sequences, and so on. The quote character is
<code>\"</code>. Optionally, Python style long strings
(<code>\"\"\"...\"\"\"</code>) may be used, allowing for unquoted
<code>"</code> quotes in the string.
<!-- in the following paragraph, the \< and \> are just < and >. the \ is
for doxygen -->
QFBinary data is hex-encoded and contained within angle brackets, \< \>.
The length of the encoded data must be an even number, so while \<FF00\>
is valid, \<F00\> isn't.
QFBinary data is hex-encoded and contained within angle brackets, \c \<
\c \>. The length of the encoded data must be an even number, so while
\c \<FF00\> is valid, \c \<F00\> isn't.
Property lists may contain C-style or BCPL-style comments.
*/
typedef enum {QFDictionary, QFArray, QFBinary, QFString} pltype_t; // possible types
typedef enum {QFDictionary, QFArray, QFBinary, QFString} pltype_t;
/*
Generic property list item
/** Generic property list item.
All inspection and manipulation is to be done via the accessor functions.
*/
struct plitem_s {
pltype_t type; // Type
void *data;
};
typedef struct plitem_s plitem_t;
/*
Dictionaries
*/
struct dictkey_s {
char *key;
plitem_t *value;
};
typedef struct dictkey_s dictkey_t;
/*
Arrays
*/
struct plarray_s {
int numvals; // Number of items in array
int maxvals;
struct plitem_s **values; // Array data
};
typedef struct plarray_s plarray_t;
/*
Typeless, unformatted binary data (not supported yet)
*/
struct plbinary_s {
size_t size;
void *data;
};
typedef struct plbinary_s plbinary_t;
struct hashtab_s;
/** Create an in-memory representation of the contents of a property list.
\param string the saved plist, as read from a file.
@ -249,10 +219,33 @@ qboolean PL_A_InsertObjectAtIndex (plitem_t *array, plitem_t *item, int index);
*/
plitem_t *PL_RemoveObjectAtIndex (plitem_t *array, int index);
/** Create a new dictionary object.
The dictionary will be empty.
\return the new dictionary object
*/
plitem_t *PL_NewDictionary (void);
/** Create a new array object.
The array will be empty.
\return the new array object
*/
plitem_t *PL_NewArray (void);
plitem_t *PL_NewData (void *, int);
plitem_t *PL_NewString (const char *);
/** Create a new data object from the given data.
Takes ownership of the given data.
\param data pointer to data buffer
\param size number of bytes in the buffer
\return the new dictionary object
\note The data will be freed via free() when the item is freed.
*/
plitem_t *PL_NewData (void *data, size_t size);
/** Create a new string object.
Makes a copy of the given string.
\param str C string to copy
\return the new dictionary object
*/
plitem_t *PL_NewString (const char *str);
/** Free a property list object.
@ -263,14 +256,6 @@ plitem_t *PL_NewString (const char *);
*/
void PL_Free (plitem_t *item);
typedef struct pldata_s { // Unparsed property list string
const char *ptr;
unsigned int end;
unsigned int pos;
unsigned int line;
const char *error;
} pldata_t;
//@}
#endif // __QF_qfplist_h_

View file

@ -6,7 +6,7 @@ INCLUDES= -I$(top_srcdir)/include
SDL_LIBS= @SDL_LIBS@
XMMS_LIBS= @XMMS_LIBS@
plugin_version= 1:0:0
plugin_ldflags= @plugin_ldflags@ -module
plugin_ldflags= @plugin_ldflags@ -module -rpath $(plugindir)
plugin_libadd= @plugin_libadd@
EXEEXT=

View file

@ -174,7 +174,7 @@ Load_Tracklist (void)
Qread (oggfile, buffile, size);
tracklist = PL_GetPropertyList (buffile);
if (!tracklist || tracklist->type != QFDictionary) {
if (!tracklist || PL_Type (tracklist) != QFDictionary) {
Sys_Printf ("Malformed or empty tracklist file. check mus_ogglist\n");
return -1;
}
@ -198,16 +198,16 @@ I_OGGMus_SetPlayList (int track)
Sys_Printf ("No Track entry for track #%d.\n", track);
return;
}
if (play_list->type == QFString)
if (PL_Type (play_list) == QFString)
return;
if (play_list->type != QFArray) {
if (PL_Type (play_list) != QFArray) {
Sys_Printf ("Track entry for track #%d not string or array.\n", track);
play_list = 0;
return;
}
for (i = 0; i < PL_A_NumObjects (play_list); i++) {
plitem_t *item = PL_ObjectAtIndex (play_list, i);
if (!item || item->type != QFString) {
if (!item || PL_Type (item) != QFString) {
Sys_Printf ("Bad subtract %d in track %d.\n", i, track);
play_list = 0;
return;
@ -224,7 +224,7 @@ I_OGGMus_PlayNext (int looping)
if (!play_list)
return;
if (play_list->type == QFString) {
if (PL_Type (play_list) == QFString) {
track = PL_String (play_list);
play_pos = 0;
} else {
@ -331,7 +331,7 @@ I_OGGMus_Info (void)
continue;
}
Sys_Printf (" %s - %s\n", trackstring, (char *) currenttrack->data);
Sys_Printf (" %s - %s\n", trackstring, PL_String (currenttrack));
count++;
}
}

View file

@ -3,7 +3,7 @@ AUTOMAKE_OPTIONS= foreign
CFLAGS+= @PREFER_PIC@ @VORBIS_CFLAGS@ @OGG_CFLAGS@
INCLUDES= -I$(top_srcdir)/include
plugin_version= 1:0:0
plugin_ldflags= @plugin_ldflags@ -module
plugin_ldflags= @plugin_ldflags@ -module -rpath $(plugindir)
plugin_libadd= @plugin_libadd@
EXEEXT=

View file

@ -4,7 +4,7 @@ CFLAGS+= @PREFER_PIC@
INCLUDES= -I$(top_srcdir)/include
SDL_LIBS = @SDL_LIBS@
plugin_version= 1:0:0
plugin_ldflags= @plugin_ldflags@ -module
plugin_ldflags= @plugin_ldflags@ -module -rpath $(plugindir)
plugin_libadd= @plugin_libadd@
EXEEXT=
@ -50,7 +50,7 @@ snd_output_win_la_CFLAGS= $(WIN32SND_CFLAGS)
snd_output_win_la_SOURCES= snd_win.c
snd_output_dx_la_LDFLAGS= $(plugin_ldflags)
snd_output_dx_la_LIBADD= $(WINSND_LIBS) $(plugin_libadd)
snd_output_dx_la_LIBADD= $(WINSND_LIBS) $(plugin_libadd)
snd_output_dx_la_CFLAGS= $(WIN32SND_CFLAGS)
snd_output_dx_la_SOURCES= snd_dx.c

View file

@ -3,7 +3,7 @@ AUTOMAKE_OPTIONS= foreign
CFLAGS+= @PREFER_PIC@
INCLUDES= -I$(top_srcdir)/include
plugin_version= 1:0:0
plugin_ldflags= @plugin_ldflags@ -module
plugin_ldflags= @plugin_ldflags@ -module -rpath $(plugindir)
plugin_libadd= @plugin_libadd@
EXEEXT=

View file

@ -4,12 +4,6 @@ SUBDIRS= alias brush sprite
CFLAGS+= @PREFER_PIC@
INCLUDES= -I$(top_srcdir)/include
noinst_PROGRAMS= testclip
testclip_SOURCES=testclip.c
testclip_LDADD= libQFmodels.la $(top_builddir)/libs/util/libQFutil.la
testclip_DEPENDENCIES=
lib_LTLIBRARIES= libQFmodels.la @VID_MODEL_TARGETS@
EXTRA_LTLIBRARIES= \
libQFmodels_gl.la libQFmodels_sw.la

View file

@ -1,428 +0,0 @@
#include "QF/va.h"
#include "getopt.h"
#include "world.h"
#undef DIST_EPSILON
#define DIST_EPSILON 0
#define TEST_BOXCLIP
#include "trace.c"
dclipnode_t clipnodes0[] = {
{ 0, { 1, -1}},
{ 1, {-1, -2}},
};
mplane_t planes0[] = {
{{1, 0, 0}, 0, 0, 0}, // 0
{{0.8, 0, 0.6}, 0, 4, 0}, // 1
};
hull_t hull0 = {
clipnodes0,
planes0,
0,
1,
{0, 0, 0},
{0, 0, 0},
};
dclipnode_t clipnodes1[] = {
{ 0, { 1, -2}},
{ 1, {-2, 2}},
{ 2, {-2, 3}},
{ 3, { 4, -2}},
{ 4, { 5, 6}},
{ 5, {-2, -1}},
{ 6, { 7, 8}},
{ 7, {-1, -2}},
{ 8, { 9, 13}},
{ 9, {10, -1}},
{ 10, {-1, 11}},
{ 11, {12, -2}},
{ 12, {-2, -1}},
{ 13, {-1, -2}},
};
mplane_t planes1[] = {
{{0, 1, 0}, -96, 1, 0}, // 0 wall at right
{{0, 1, 0}, 96, 1, 0}, // 1 wall at left (with ditch)
{{1, 0, 0}, 128, 0, 0}, // 2 wall at front (with shelves)
{{1, 0, 0}, -32, 0, 0}, // 3 wall at back
{{0, 0, 1}, 32, 2, 0}, // 4 top of shelves
{{0, 0, 1}, 104, 2, 0}, // 5 ceiling
{{0, 1, 0}, 32, 1, 0}, // 6 edge of ditch
{{0, 0, 1}, -24, 2, 0}, // 7 floor of ditch
{{0, 0, 1}, 24, 2, 0}, // 8 bottom of selves
{{1, 0, 0}, 64, 0, 0}, // 9 end of shelves
{{0, 1, 0}, -16, 1, 0}, // 10 ditch side of 2nd shelf
{{0, 1, 0}, -64, 1, 0}, // 11 ditch side of 1st shelf
{{0, 1, 0}, -48, 1, 0}, // 12 1st shelf side of 2nd shelf
{{0, 0, 1}, 8, 2, 0}, // 13 main floor
};
hull_t hull1 = {
clipnodes1,
planes1,
0,
13,
{0, 0, 0},
{0, 0, 0},
};
dclipnode_t clipnodes2[] = {
{0, {1, 12}}, // 0
{1, {-1, 2}}, // 1
{2, {3, 6}}, // 2
{3, {-1, 4}}, // 3
{4, {5, -1}}, // 4
{5, {-1, -2}}, // 5
{6, {7, 9}}, // 6
{7, {-1, 8}}, // 7
{4, {-2, -1}}, // 8
{8, {10, -1}}, // 9
{5, {-1, 11}}, // 10
{4, {-2, -1}}, // 11
{9, {13, 25}}, // 12
{2, {-1, 14}}, // 13
{6, {15, 19}}, // 14
{10, {-1, 16}}, // 15
{11, {17, 18}}, // 16
{7, {-1, -2}}, // 17
{4, {-2, -1}}, // 18
{11, {20, 23}}, // 19
{12, {-1, 21}}, // 20
{8, {22, -1}}, // 21
{5, {-1, -2}}, // 22
{8, {24, -1}}, // 23
{4, {-2, -1}}, // 24
{3, {-1, 26}}, // 25
{8, {27, -1}}, // 26
{11, {28, -1}}, // 27
{12, {-1, 29}}, // 28
{13, {-2, -1}}, // 29
};
mplane_t planes2[] = {
{{1, 0, 0}, 912, 0, 0, {0, 0}}, // 0 0
{{1, 0, 0}, 1168, 0, 0, {0, 0}}, // 1 1
{{0, 1, 0}, 2112, 1, 0, {0, 0}}, // 2 2 13
{{0, 1, 0}, 2128, 1, 0, {0, 0}}, // 3 3 25
{{0.229038, 0, 0.973417}, 18.3218, 5, 0, {0, 0}}, // 4 4 8 11 18 24
{{0.229038, -0, 0.973417}, 57.2585, 5, 0, {0, 0}}, // 5 5 10 22
{{0, 1, 0}, 1984, 1, 0, {0, 0}}, // 6 6 14
{{0.229039, -0, 0.973417}, 33.8978, 5, 0, {0, 0}}, // 7 7 17
{{0, 1, 0}, 1968, 1, 0, {0, 0}}, // 8 9 21 23 26
{{1, 0, 0}, 736, 0, 0, {0, 0}}, // 9 12
{{0, 0, 1}, -176, 2, 0, {0, 0}}, // 10 15
{{0, 0, 1}, -192, 2, 0, {0, 0}}, // 11 16 19 27
{{0, 0, 1}, -152, 2, 0, {0, 0}}, // 12 20 28
{{1, 0, 0}, 720, 0, 0, {0, 0}}, // 13 29
};
hull_t hull2 = {
clipnodes2,
planes2,
0,
6,
{0, 0, 0},
{0, 0, 0},
};
dclipnode_t clipnodes3[] = {
{0, {1, 12}}, // 0
{1, {2, 7}}, // 1
{2, {-2, 3}}, // 2
{3, {4, -2}}, // 3
{4, {-2, 5}}, // 4
{5, {-2, 6}}, // 5
{6, {-1, -2}}, // 6
{7, {-2, 8}}, // 7
{8, {9, -2}}, // 8
{9, {10, 11}}, // 9
{10, {-2, -1}}, // 10
{6, {-1, -2}}, // 11
{3, {13, -2}}, // 12
{11, {14, -2}}, // 13
{4, {-2, 15}}, // 14
{2, {-2, 16}}, // 15
{9, {-1, -2}}, // 16
};
mplane_t planes3[] = {
{{0, 1, 0}, -224, 1, 0, {0, 0}}, // 0
{{0, 1, 0}, -192, 1, 0, {0, 0}}, // 1
{{0, 0, 1}, 192, 2, 0, {0, 0}}, // 2
{{1, 0, 0}, 384, 0, 0, {0, 0}}, // 3
{{1, 0, 0}, 576, 0, 0, {0, 0}}, // 4
{{0, 1, 0}, -16, 1, 0, {0, 0}}, // 5
{{-0, 0.242536, 0.970142}, -3.88057, 5, 0, {0, 0}}, // 6
{{1, 0, 0}, 552, 0, 0, {0, 0}}, // 7
{{1, 0, 0}, 408, 0, 0, {0, 0}}, // 8
{{0, 0, 1}, 48, 2, 0, {0, 0}}, // 9
{{0, 0, 1}, 160, 2, 0, {0, 0}}, // 10
{{0, 1, 0}, -416, 1, 0, {0, 0}}, // 11
};
hull_t hull3 = {
clipnodes3,
planes3,
0,
16,
{0, 0, 0},
{0, 0, 0},
};
dclipnode_t clipnodes4[] = {
{0, {1, 25}}, // 0
{1, {-1, 2}}, // 1
{2, {3, 11}}, // 2
{3, {4, -1}}, // 3
{4, {5, 8}}, // 4
{5, {-1, 6}}, // 5
{6, {-1, 7}}, // 6
{7, {-1, -2}}, // 7
{5, {-1, 9}}, // 8
{8, {10, -1}}, // 9
{7, {-1, -2}}, // 10
{9, {12, 17}}, // 11
{4, {13, 15}}, // 12
{6, {-1, 14}}, // 13
{7, {-1, -2}}, // 14
{7, {-1, 16}}, // 15
{8, {-2, -1}}, // 16
{10, {-1, 18}}, // 17
{4, {19, 22}}, // 18
{11, {20, -1}}, // 19
{6, {-1, 21}}, // 20
{7, {-1, -2}}, // 21
{11, {23, -1}}, // 22
{7, {-1, 24}}, // 23
{8, {-2, -1}}, // 24
{11, {26, -1}}, // 25
{5, {-1, 27}}, // 26
{12, {28, -1}}, // 27
{13, {-1, 29}}, // 28
{14, {-2, -1}}, // 29
};
mplane_t planes4[] = {
{{0, 1, 0}, 832, 1, 0, {0, 0}}, // 0
{{0, 1, 0}, 1216, 1, 0, {0, 0}}, // 1
{{1, 0, 0}, 608, 0, 0, {0, 0}}, // 2
{{1, 0, 0}, 624, 0, 0, {0, 0}}, // 3
{{0, 0, 1}, -40, 2, 0, {0, 0}}, // 4
{{1, 0, 0}, 672, 0, 0, {0, 0}}, // 5
{{0, 0, 1}, -24, 2, 0, {0, 0}}, // 6
{{0, -0.242536, 0.970142}, -256.118, 5, 0, {0, 0}}, // 7
{{-0, -0.242536, 0.970142}, -271.64, 5, 0, {0, 0}}, // 8
{{1, 0, 0}, 480, 0, 0, {0, 0}}, // 9
{{1, 0, 0}, 464, 0, 0, {0, 0}}, // 10
{{1, 0, 0}, 416, 0, 0, {0, 0}}, // 11
{{0, 1, 0}, 768, 1, 0, {0, 0}}, // 12
{{0, 0, 1}, -64, 2, 0, {0, 0}}, // 13
{{0, 0, 1}, -80, 2, 0, {0, 0}}, // 14
};
hull_t hull4 = {
clipnodes4,
planes4,
0,
6,
{0, 0, 0},
{0, 0, 0},
};
typedef struct {
const char *desc;
hull_t *hull;
vec3_t start;
vec3_t end;
struct {
float frac;
qboolean allsolid;
qboolean startsolid;
qboolean inopen;
qboolean inwater;
} expect;
} test_t;
test_t tests[] = {
{0, &hull0, {-20, 0, 28}, {20, 0, 28}, {1, 0, 0, 1, 0}},
{0, &hull0, {-20, 0, 27}, {20, 0, 27}, {0.1, 0, 0, 1, 0}},
{0, &hull0, {-20, 0, -76}, {20, 0, -76}, {0.1, 0, 0, 1, 0}},
{0, &hull0, {-20, 0, -77}, {20, 0, -77}, {0.1, 0, 0, 1, 0}},
{"drop on trench edge",
&hull1, {0, 47, 40}, {0, 47, 32}, {0.5, 0, 0, 1, 0}},
{"drop past trench edge",
&hull1, {0, 48, 40}, {0, 48, 32}, {1, 0, 0, 1, 0}},
{"run into trench edge",
&hull1, {0, 52, 35}, {0, 44, 35}, {0.5, 0, 0, 1, 0}},
{"run over trench edge",
&hull1, {0, 52, 36}, {0, 44, 36}, {1, 0, 0, 1, 0}},
{"run into end of 2nd shelf",
&hull1, {47, -32, 36}, {49, -32, 36}, {0.5, 0, 0, 1, 0}},
{"run inside end of 2nd shelf",
&hull1, {48, -32, 36}, {50, -32, 36}, {1, 1, 1, 0, 0}},
{"run into end of 2nd shelf p2",
&hull1, {44, -32, 59}, {52, -32, 59}, {0.5, 0, 0, 1, 0}},
{"run over end of 2nd shelf",
&hull1, {44, -32, 60}, {52, -32, 60}, {1, 0, 0, 1, 0}},
{"drop past end of 2nd shelf",
&hull1, {47, -32, 76}, {47, -32, 44}, {1, 0, 1, 1, 0}},
{"drop onto end of 2nd shelf",
&hull1, {48, -32, 76}, {48, -32, 44}, {0.5, 0, 1, 1, 0}},
{"drop onto top of ramp: hull2",
&hull2, {896, 2048, -144}, {896, 2048, -152}, {0.5, 0, 0, 1, 0}},
{"drop onto edge of 2nd shelf p1",
&hull1, {96, -47, 61}, {96, -47, 59}, {0.5, 0, 0, 1, 0}},
{"drop onto edge of 2nd shelf p2",
&hull1, {96, -47.9612, 61}, {96, -47.1025, 59}, {0.5, 0, 0, 1, 0}},
{"drop onto edge of 2nd shelf p3",
&hull1, {94.8916, -34.8506, 61}, {94.8146, -28.5696, 59},
{0.5, 0, 0, 1, 0}},
{"run over top of ramp: hull3",
&hull3, {480, -216, 76}, {480, -200, 76}, {1, 0, 0, 1, 0}},
{"drop onto top of ramp, A: hull3",
&hull3, {480, -207.977, 77}, {468, -207.977, 75}, {0.5, 0, 0, 1, 0}},
{"drop onto top of ramp, B: hull3",
&hull3, {480, -208.873, 77}, {468, -208.873, 75}, {0.5, 0, 0, 1, 0}},
{"diagonal drop onto top of ramp: hull3",
&hull3, {480, -208.873, 77}, {468, -207.977, 75}, {0.5, 0, 0, 1, 0}},
{"drop onto thin bridge",
&hull4, {544, 1080, 5}, {544, 1080, 3}, {0.5, 0, 0, 1, 0}},
{"long drop onto thin bridge",
&hull4, {544, 1080, 78}, {544, 1080, -70}, {0.5, 0, 0, 1, 0}},
};
const int num_tests = sizeof (tests) / sizeof (tests[0]);
int verbose = 0;
static trace_t
do_trace (hull_t *hull, vec3_t start, vec3_t end)
{
trace_t trace;
trace.allsolid = true;
trace.startsolid = false;
trace.inopen = false;
trace.inwater = false;
trace.fraction = 1;
trace.extents[0] = 16;
trace.extents[1] = 16;
trace.extents[2] = 28;
trace.isbox = true;
VectorCopy (end, trace.endpos);
MOD_TraceLine (hull, 0, start, end, &trace);
return trace;
}
static int
run_test (test_t *test)
{
const char *desc;
vec3_t end;
int res = 0;
VectorSubtract (test->end, test->start, end);
VectorMultAdd (test->start, test->expect.frac, end, end);
if (verbose)
printf ("expect: (%g %g %g) -> (%g %g %g) => (%g %g %g)"
" %3g %d %d %d %d\n",
test->start[0], test->start[1], test->start[2],
test->end[0], test->end[1], test->end[2],
end[0], end[1], end[2],
test->expect.frac,
test->expect.allsolid, test->expect.startsolid,
test->expect.inopen, test->expect.inwater);
trace_t trace = do_trace (test->hull, test->start, test->end);
if (verbose)
printf (" got: (%g %g %g) -> (%g %g %g) => (%g %g %g)"
" %3g %d %d %d %d\n",
test->start[0], test->start[1], test->start[2],
test->end[0], test->end[1], test->end[2],
trace.endpos[0], trace.endpos[1], trace.endpos[2],
trace.fraction,
trace.allsolid, trace.startsolid,
trace.inopen, trace.inwater);
if (VectorCompare (end, trace.endpos)
&& test->expect.frac == trace.fraction
&& test->expect.allsolid == trace.allsolid
&& test->expect.startsolid == trace.startsolid
&& test->expect.inopen == trace.inopen
&& test->expect.inwater == trace.inwater)
res = 1;
if (test->desc)
desc = va ("(%d) %s", (int)(long)(test - tests), test->desc);
else
desc = va ("test #%d", (int)(long)(test - tests));
printf ("%s: %s\n", res ? "PASS" : "FAIL", desc);
return res;
}
int
main (int argc, char **argv)
{
vec3_t start, end;
int c, i;
int pass = 1;
int test = -1;
while ((c = getopt (argc, argv, "vt:")) != EOF) {
switch (c) {
case 'v':
verbose = 1;
break;
case 't':
test = atoi (optarg);
break;
default:
fprintf (stderr,
"-v (verbose) and/or -t TEST (test number)\n");
return 1;
}
}
if (test == -1) {
for (i = 0; i < num_tests; i++) {
if (verbose && i)
puts ("");
pass &= run_test (&tests[i]);
}
} else if (test >= 0 && test < num_tests) {
pass &= run_test (&tests[test]);
} else {
fprintf (stderr, "Bad test number (0 - %d)\n", num_tests);
return 1;
}
for (i = 0; i < 0; i++) {
start[0] = 480;
start[1] = -240 + i;
start[2] = 77;
VectorCopy (start, end);
end[2] -= 16;
do_trace (&hull3, start, end);
}
// start[0] = 480;
// start[1] = -207.253967;
// start[2] = 76.03125;
// VectorCopy (start, end);
// end[1] += 16;
// do_trace (&hull3, start, end);
return !pass;
}

View file

@ -83,356 +83,7 @@ calc_impact (trace_t *trace, const vec3_t start, const vec3_t end,
VectorSubtract (end, start, dist);
VectorMultAdd (start, frac, dist, trace->endpos);
}
#if ENABLE_BOXCLIP || defined(TEST_BOXCLIP)
#define ALLSOLID 1
#define STARTSOLID 2
#define INOPEN 4
#define INWATER 8
#define SOLID (ALLSOLID | STARTSOLID)
typedef struct {
mplane_t *plane;
vec3_t point; // arbitrary point on plane
int side;
} tp_t;
typedef struct {
vec3_t p;
vec3_t v;
} line_t;
typedef struct {
const vec_t *start;
const vec_t *end;
const vec_t *extents;
qboolean isbox;
hull_t hull;
tp_t split;
tp_t impact;
float fraction;
int flags;
} tl_t;
static inline void
set_split (tl_t *tl, tp_t *n, tp_t *o)
{
if (o)
*o = tl->split;
if (n) {
tl->split = *n;
} else {
tl->split.plane = 0;
VectorZero (tl->split.point);
tl->split.side = 0;
}
}
static inline void
set_impact (tl_t *tl, mplane_t *plane, int side)
{
tl->impact.plane = plane;
tl->impact.side = side;
}
#define print_tp(tp) \
Sys_Printf ("%s [(%g %g %g) %g %d]\n", #tp, \
(tp).plane->normal[0], (tp).plane->normal[1], \
(tp).plane->normal[2], (tp).plane->dist, (tp).side)
static inline vec_t
sgn (vec_t v)
{
return v < 0 ? -1 : (v > 0 ? 1 : 0);
}
static inline float
calc_offset (tl_t *tl, mplane_t *plane)
{
if (tl->isbox) {
if (plane->type < 3)
return tl->extents[plane->type];
else
return (fabs (tl->extents[0] * plane->normal[0])
+ fabs (tl->extents[1] * plane->normal[1])
+ fabs (tl->extents[2] * plane->normal[2]));
}
return 0;
}
static void
impact (tl_t *tl, tp_t *split)
{
float t1, t2, offset, frac;
int side = 0;
t1 = PlaneDiff (tl->start, split->plane);
t2 = PlaneDiff (tl->end, split->plane);
offset = calc_offset (tl, split->plane);
if (t1 < t2) {
side = -1;
frac = (t1 + offset) / (t1 - t2);
} else if (t1 > t2) {
side = 0;
frac = (t1 - offset) / (t1 - t2);
} else {
frac = 0;
Sys_DPrintf ("help! help! the world is falling apart!\n");
}
if (frac >= 0) {
tl->fraction = frac;
set_impact (tl, split->plane, side);
// print_tp (tl->impact);
}
}
static void
select_vertex (tl_t *tl, tp_t *split, vec3_t vert)
{
int axis;
for (axis = 0; axis < 3; axis++) {
vec_t s = sgn (tl->split.plane->normal[axis]);
if (!tl->split.side)
s = -s;
if (!s) {
s = sgn (split->plane->normal[axis]);
if (split->side)
s = -s;
if (!s)
s = 1;
}
vert[axis] = tl->extents[axis] * s;
}
}
static int
intersection_point (const mplane_t *plane, const vec3_t _p1, const vec3_t _p2,
const vec3_t offs, vec3_t point)
{
vec_t t1, t2;
vec3_t p1, p2;
VectorAdd (_p1, offs, p1);
VectorAdd (_p2, offs, p2);
t1 = PlaneDiff (p1, plane);
t2 = PlaneDiff (p2, plane);
if (!(t1 - t2))
return 0;
VectorSubtract (p2, p1, point);
VectorMultAdd (p1, t1 / (t1 - t2), point, point);
return 1;
}
static int
intersection_line (tl_t *tl, tp_t *split, const vec3_t p1, const vec3_t p2,
line_t *line)
{
const vec_t *pn1 = tl->split.plane->normal;
const vec_t *pp1 = tl->split.point;
const vec_t *pn2 = split->plane->normal;
const vec_t *pp2 = split->point;
vec3_t pvec;
vec_t t;
// find the line of intersection of the two planes, both direction
// and a point on the line.
CrossProduct (pn1, pn2, line->v);
if (VectorIsZero (line->v))
//planes are parallel, no intersection
return 0;
CrossProduct (pn1, line->v, pvec);
VectorSubtract (pp2, pp1, line->p);
t = DotProduct (line->p, pn2) / DotProduct (pvec, pn2);
VectorMultAdd (pp1, t, line->p, line->p);
return 1;
}
static int
traceline (int num, float p1f, float p2f, const vec3_t p1, const vec3_t p2,
tl_t *tl)
{
dclipnode_t *node;
mplane_t *plane;
float t1, t2, frac, frac2, midf, offset;
int side, cross;
vec3_t mid;
int c1, c2;
tp_t split, save;
line_t line;
vec3_t dist, vert, vert2, point;
int check_intersection;
do {
// Skip past non-intersecting nodes
// Sys_Printf ("%d\n", num);
while (num >= 0) {
node = tl->hull.clipnodes + num;
plane = tl->hull.planes + node->planenum;
t1 = PlaneDiff (p1, plane);
t2 = PlaneDiff (p2, plane);
offset = calc_offset (tl, plane);
if (t1 >= offset && t2 >= offset) {
num = node->children[side = 0];
} else if (t1 < -offset && t2 < -offset) {
num = node->children[side = 1];
} else {
break;
}
// Sys_Printf ("%d\n", num);
}
if (num < 0) {
return num;
}
split.plane = plane;
split.side = t1 < t2;
VectorSubtract (p2, p1, dist);
VectorMultAdd (p1, t1 / (t1 - t2), dist, split.point);
if (tl->split.plane) {
select_vertex (tl, &split, vert);
if ((t1 >= -offset && t1 < offset)
&& (t2 < -offset || t2 >= offset)) {
// p1 straddles the plane, p2 is clear of the plane
intersection_point (tl->split.plane, p1, p2, vert, point);
if ((PlaneDiff (point, plane) < 0) != (t1 < t2)) {
// the trace misses the intersection of the two planes, so
// both ends of the trace are really on the same side of
// the plane
num = node->children[!(t1 < t2)];
continue;
}
}
}
break;
} while (1);
check_intersection = 0;
if (tl->split.plane) {
VectorNegate (vert, vert2);
intersection_point (tl->split.plane, p1, p2, vert2, point);
if ((PlaneDiff (point, plane) < 0) != (t1 < t2)) {
// the two edges of the hypercube of motion are on opposite sides
// of the line of intersection of the two planes, so the box hits
// the intersection somewhere
check_intersection = 1;
}
}
cross = !(t1 >= -offset && t1 < offset && t2 >= -offset && t2 < offset);
if (t1 < t2) {
side = 1;
frac = (t1 - offset) / (t1 - t2);
frac2 = (t1 + offset) / (t1 - t2);
} else {
side = 0;
frac = (t1 + offset) / (t1 - t2);
frac2 = (t1 - offset) / (t1 - t2);
}
if (check_intersection) {
intersection_line (tl, &split, p1, p2, &line);
}
set_split (tl, &split, &save);
if (cross) {
frac = bound (0, frac, 1);
midf = p1f + (p2f - p1f) * frac;
VectorMultAdd (p1, frac, dist, mid);
c1 = c2 = traceline (node->children[side], p1f, midf, p1, mid, tl);
frac2 = bound (0, frac2, 1);
midf = p1f + (p2f - p1f) * frac2;
if (!tl->impact.plane || midf < tl->fraction) {
VectorMultAdd (p1, frac2, dist, mid);
c2 = traceline (node->children[side ^ 1], midf, p2f, mid, p2, tl);
}
} else {
c1 = c2 = traceline (node->children[side], p1f, p2f, p1, mid, tl);
if (c1 != CONTENTS_SOLID)
c2 = traceline (node->children[side ^ 1], p1f, p2f, mid, p2, tl);
if (c1 == CONTENTS_SOLID || c2 == CONTENTS_SOLID)
c1 = c2 = CONTENTS_SOLID;
else
c1 = c2 = min (c1, c2);
}
set_split (tl, &save, 0);
if (cross) {
if (c1 != CONTENTS_SOLID && c2 == CONTENTS_SOLID)
impact (tl, &split);
if (c1 == CONTENTS_SOLID && !(tl->flags & SOLID))
tl->flags |= STARTSOLID;
if (c1 == CONTENTS_EMPTY || c2 == CONTENTS_EMPTY) {
tl->flags &= ~ALLSOLID;
tl->flags |= INOPEN;
}
if (c1 < CONTENTS_SOLID || c2 < CONTENTS_SOLID) {
tl->flags &= ~ALLSOLID;
tl->flags |= INWATER;
}
return c1;
//return frac2 ? c1 : c2;
} else {
if (c1 == CONTENTS_SOLID || c2 == CONTENTS_SOLID) {
if (!p1f) {
tl->flags &= SOLID;
tl->flags |= STARTSOLID;
}
return CONTENTS_SOLID;
}
if (c1 == CONTENTS_EMPTY && c2 == CONTENTS_EMPTY) {
tl->flags &= ~ALLSOLID;
tl->flags |= INOPEN;
} else {
tl->flags &= ~ALLSOLID;
tl->flags |= INWATER;
}
return min (c1, c2); //FIXME correct?
}
}
VISIBLE void
MOD_TraceLine (hull_t *hull, int num,
const vec3_t start_point, const vec3_t end_point,
trace_t *trace)
{
tl_t tl;
int c;
tl.start = start_point;
tl.end = end_point;
tl.extents = trace->extents;
tl.isbox = trace->isbox;
tl.hull = *hull;
set_split (&tl, 0, 0);
set_impact (&tl, 0, 0);
tl.fraction = 1;
tl.flags = ALLSOLID;
c = traceline (num, 0, 1, start_point, end_point, &tl);
if (c == CONTENTS_EMPTY) {
tl.flags &= ~ALLSOLID;
tl.flags |= INOPEN;
}
if (c < CONTENTS_SOLID) {
tl.flags &= ~ALLSOLID;
tl.flags |= INOPEN;
}
if (tl.fraction < 1) {
calc_impact (trace, start_point, end_point, tl.impact.plane);
}
trace->allsolid = (tl.flags & ALLSOLID) != 0;
trace->startsolid = (tl.flags & STARTSOLID) != 0;
trace->inopen = (tl.flags & INOPEN) != 0;
trace->inwater = (tl.flags & INWATER) != 0;
}
#else
typedef struct {
vec3_t end;
int side;
@ -572,4 +223,3 @@ MOD_TraceLine (hull_t *hull, int num,
num = node->children[side];
}
}
#endif

View file

@ -45,6 +45,51 @@ static __attribute__ ((used)) const char rcsid[] =
#include "QF/qtypes.h"
#include "QF/sys.h"
/*
Generic property list item.
*/
struct plitem_s {
pltype_t type;
void *data;
};
/*
Dictionaries
*/
struct dictkey_s {
char *key;
plitem_t *value;
};
typedef struct dictkey_s dictkey_t;
/*
Arrays
*/
struct plarray_s {
int numvals; ///< Number of items in array
int maxvals; ///< Number of items that can be stored
///< before a realloc is necesary.
struct plitem_s **values; ///< Array data
};
typedef struct plarray_s plarray_t;
/*
Typeless, unformatted binary data
*/
struct plbinary_s {
size_t size;
void *data;
};
typedef struct plbinary_s plbinary_t;
typedef struct pldata_s { // Unparsed property list string
const char *ptr;
unsigned int end;
unsigned int pos;
unsigned int line;
const char *error;
} pldata_t;
// Ugly defines for fast checking and conversion from char to number
#define inrange(ch,min,max) ((ch) >= (min) && (ch) <= (max))
#define char2num(ch) \
@ -119,7 +164,7 @@ PL_NewArray (void)
}
VISIBLE plitem_t *
PL_NewData (void *data, int size)
PL_NewData (void *data, size_t size)
{
plitem_t *item = PL_NewItem (QFBinary);
plbinary_t *bin = malloc (sizeof (plbinary_t));

View file

@ -308,9 +308,10 @@ qfs_get_gd_params (plitem_t *gdpl, gamedir_t *gamedir, dstring_t *path,
hashtab_t *vars)
{
plitem_t *p;
const char *ps;
if ((p = PL_ObjectForKey (gdpl, "Path")) && *(char *) p->data) {
char *str = qfs_var_subst (p->data, vars);
if ((p = PL_ObjectForKey (gdpl, "Path")) && *(ps = PL_String (p))) {
char *str = qfs_var_subst (ps, vars);
char *e = strchr (str, '"');
if (!e)
@ -322,61 +323,77 @@ qfs_get_gd_params (plitem_t *gdpl, gamedir_t *gamedir, dstring_t *path,
free (str);
}
if (!gamedir->gamecode && (p = PL_ObjectForKey (gdpl, "GameCode")))
gamedir->gamecode = qfs_var_subst (p->data, vars);
gamedir->gamecode = qfs_var_subst (PL_String (p), vars);
if (!gamedir->dir.skins && (p = PL_ObjectForKey (gdpl, "SkinPath")))
gamedir->dir.skins = qfs_var_subst (p->data, vars);
gamedir->dir.skins = qfs_var_subst (PL_String (p), vars);
if (!gamedir->dir.progs && (p = PL_ObjectForKey (gdpl, "ProgPath")))
gamedir->dir.progs = qfs_var_subst (p->data, vars);
gamedir->dir.progs = qfs_var_subst (PL_String (p), vars);
if (!gamedir->dir.sound && (p = PL_ObjectForKey (gdpl, "SoundPath")))
gamedir->dir.sound = qfs_var_subst (p->data, vars);
gamedir->dir.sound = qfs_var_subst (PL_String (p), vars);
if (!gamedir->dir.maps && (p = PL_ObjectForKey (gdpl, "MapPath")))
gamedir->dir.maps = qfs_var_subst (p->data, vars);
gamedir->dir.maps = qfs_var_subst (PL_String (p), vars);
}
static void
qfs_inherit (plitem_t *plist, plitem_t *gdpl, gamedir_t *gamedir,
dstring_t *path, hashtab_t *dirs, hashtab_t *vars)
{
plitem_t *base;
plitem_t *base_item;
if (!(base = PL_ObjectForKey (gdpl, "Inherit")))
if (!(base_item = PL_ObjectForKey (gdpl, "Inherit")))
return;
if (base->type == QFString) {
if (Hash_Find (dirs, base->data))
return;
gdpl = PL_ObjectForKey (plist, base->data);
if (!gdpl) {
Sys_Printf ("base `%s' not found\n", (char *)base->data);
return;
}
qfs_set_var (vars, "gamedir", base->data);
Hash_Add (dirs, strdup (base->data));
qfs_get_gd_params (gdpl, gamedir, path, vars);
qfs_inherit (plist, gdpl, gamedir, path, dirs, vars);
} else if (base->type == QFArray) {
int i;
plarray_t *a = base->data;
for (i = 0; i < a->numvals; i++) {
base = a->values[i];
if (Hash_Find (dirs, base->data))
continue;
gdpl = PL_ObjectForKey (plist, base->data);
if (!gdpl) {
Sys_Printf ("base `%s' not found\n", (char *)base->data);
continue;
switch (PL_Type (base_item)) {
case QFString:
{
const char *base = PL_String (base_item);
if (Hash_Find (dirs, base))
return;
gdpl = PL_ObjectForKey (plist, base);
if (!gdpl) {
Sys_Printf ("base `%s' not found\n", base);
return;
}
qfs_set_var (vars, "gamedir", base);
Hash_Add (dirs, strdup (base));
qfs_get_gd_params (gdpl, gamedir, path, vars);
qfs_inherit (plist, gdpl, gamedir, path, dirs, vars);
}
qfs_set_var (vars, "gamedir", base->data);
Hash_Add (dirs, strdup (base->data));
qfs_get_gd_params (gdpl, gamedir, path, vars);
qfs_inherit (plist, gdpl, gamedir, path, dirs, vars);
}
break;
case QFArray:
{
int i, num_dirs;
plitem_t *basedir_item;
const char *basedir;
num_dirs = PL_A_NumObjects (base_item);
for (i = 0; i < num_dirs; i++) {
basedir_item = PL_ObjectAtIndex (base_item, i);
if (!basedir_item)
continue;
basedir = PL_String (basedir_item);
if (!basedir || Hash_Find (dirs, basedir))
continue;
gdpl = PL_ObjectForKey (plist, basedir);
if (!gdpl) {
Sys_Printf ("base `%s' not found\n", basedir);
continue;
}
qfs_set_var (vars, "gamedir", basedir);
Hash_Add (dirs, strdup (basedir));
qfs_get_gd_params (gdpl, gamedir, path, vars);
qfs_inherit (plist, gdpl, gamedir, path, dirs, vars);
}
}
break;
default:
break;
}
}
static int
qfs_compare (const void *a, const void *b)
{
return strcmp ((*(dictkey_t **)a)->key, (*(dictkey_t **)b)->key);
return strcmp (*(const char **) a, *(const char **) b);
}
static const char *
@ -397,19 +414,24 @@ qfs_find_gamedir (const char *name, hashtab_t *dirs)
plitem_t *gdpl = PL_ObjectForKey (qfs_gd_plist, name);
if (!gdpl) {
dictkey_t **list = (dictkey_t **) Hash_GetList (qfs_gd_plist->data);
dictkey_t **l;
for (l = list; *l; l++)
;
qsort (list, l - list, sizeof (char *), qfs_compare);
while (l-- != list) {
if (!fnmatch ((*l)->key, name, 0)) {
gdpl = (*l)->value;
Hash_Add (dirs, strdup ((*l)->key));
plitem_t *keys = PL_D_AllKeys (qfs_gd_plist);
int num_keys = PL_A_NumObjects (keys);
const char **list = malloc (num_keys * sizeof (char *));
int i;
for (i = 0; i < num_keys; i++)
list[i] = PL_String (PL_ObjectAtIndex (keys, i));
qsort (list, num_keys, sizeof (const char *), qfs_compare);
while (i--) {
if (!fnmatch (list[i], name, 0)) {
gdpl = PL_ObjectForKey (qfs_gd_plist, list[i]);
Hash_Add (dirs, strdup (list[i]));
break;
}
}
free (list);
PL_Free (keys);
}
return gdpl;
}
@ -566,7 +588,7 @@ qfs_load_config (void)
PL_Free (qfs_gd_plist);
qfs_gd_plist = PL_GetPropertyList (buf);
free (buf);
if (qfs_gd_plist && qfs_gd_plist->type == QFDictionary)
if (qfs_gd_plist && PL_Type (qfs_gd_plist) == QFDictionary)
return; // done
Sys_Printf ("not a dictionary\n");
no_config:

View file

@ -56,10 +56,6 @@ SV_CheckStuck (edict_t *ent)
int i, j, z;
vec3_t org;
#if ENABLE_BOXCLIP
return;
#endif
if (!SV_TestEntityPosition (ent)) {
VectorCopy (SVvector (ent, origin), SVvector (ent, oldorigin));
return;

View file

@ -237,23 +237,14 @@ SV_FlyMove (edict_t *ent, float time, trace_t *steptrace)
time_left = time;
for (bumpcount = 0; bumpcount < numbumps; bumpcount++) {
#if ENABLE_BOXCLIP
extern int dp;
#endif
if (VectorIsZero (SVvector (ent, velocity)))
break;
VectorMultAdd (SVvector (ent, origin), time_left,
SVvector (ent, velocity), end);
#if ENABLE_BOXCLIP
dp = 1;
#endif
trace = SV_Move (SVvector (ent, origin), SVvector (ent, mins),
SVvector (ent, maxs), end, false, ent);
#if ENABLE_BOXCLIP
dp = 0;
#endif
if (trace.allsolid) { // entity is trapped in another solid
VectorZero (SVvector (ent, velocity));

View file

@ -500,10 +500,6 @@ SV_TestEntityPosition (edict_t *ent)
return NULL;
}
#if ENABLE_BOXCLIP
int dp;
#endif
/*
SV_ClipMoveToEntity
@ -523,7 +519,7 @@ SV_ClipMoveToEntity (edict_t *touched, edict_t *mover, const vec3_t start,
trace.fraction = 1;
trace.allsolid = true;
trace.isbox = ENABLE_BOXCLIP ? true : false;//XXX box clipping test
trace.isbox = 0;
VectorCopy (end, trace.endpos);
// get the clipping hull
@ -540,18 +536,6 @@ SV_ClipMoveToEntity (edict_t *touched, edict_t *mover, const vec3_t start,
if (trace.fraction != 1)
VectorAdd (trace.endpos, offset, trace.endpos);
#if ENABLE_BOXCLIP
if (dp)
printf ("(%g %g %g) -> (%g %g %g) => (%g %g %g)"
" %3g %d %d %d %d\n",
start_l[0], start_l[1], start_l[2],
end_l[0], end_l[1], end_l[2],
trace.endpos[0], trace.endpos[1], trace.endpos[2],
trace.fraction,
trace.allsolid, trace.startsolid,
trace.inopen, trace.inwater);
#endif
// did we clip the move?
if (trace.fraction < 1 || trace.startsolid)
trace.ent = touched;

View file

@ -31,8 +31,6 @@ SUBDIRS= include source doc
# uncomment the following if qfcc requires the math library
#qfcc_LDADD=-lm
EXTRA_DIST=qfcc.lsm.in
dist-zip: distdir
-chmod -R a+r $(distdir)
ZIP="-r9q" zip $(distdir).zip $(NOCONV_DIST)

View file

@ -156,14 +156,6 @@ parse_noise (const char *arg)
}
}
static inline const char *
plstring (plitem_t *pl)
{
if (pl->type == QFString)
return pl->data;
return 0;
}
static plitem_t *
get_item (const char *key, plitem_t *d1, plitem_t *d2)
{
@ -189,12 +181,12 @@ set_properties (entity_t *ent, plitem_t *dict)
}
if ((p = get_item ("light", dict, prop))
|| (p = get_item ("_light", dict, prop))) {
if ((str = plstring (p))) {
if ((str = PL_String (p))) {
ent->light = parse_light (str, ent->color);
}
}
if ((p = get_item ("style", dict, prop))) {
if ((str = plstring (p))) {
if ((str = PL_String (p))) {
ent->style = atoi (str);
if ((unsigned) ent->style > 254)
fprintf (stderr, "Bad light style %i (must be 0-254)",
@ -202,29 +194,29 @@ set_properties (entity_t *ent, plitem_t *dict)
}
}
if ((p = get_item ("angle", dict, prop))) {
if ((str = plstring (p))) {
if ((str = PL_String (p))) {
ent->angle = parse_float (str);
}
}
if ((p = get_item ("wait", dict, prop))) {
if ((str = plstring (p))) {
if ((str = PL_String (p))) {
ent->falloff = parse_float (str);
ent->falloff *= ent->falloff; // presquared
}
}
if ((p = get_item ("_lightradius", dict, prop))) {
if ((str = plstring (p))) {
if ((str = PL_String (p))) {
ent->lightradius = parse_float (str);
}
}
if ((p = get_item ("color", dict, prop))
|| (p = get_item ("_color", dict, prop))) {
if ((str = plstring (p))) {
if ((str = PL_String (p))) {
parse_color (str, ent->color2);
}
}
if ((p = get_item ("_attenuation", dict, prop))) {
if ((str = plstring (p))) {
if ((str = PL_String (p))) {
ent->attenuation = parse_attenuation (str);
if (ent->attenuation == -1) {
ent->attenuation = options.attenuation;
@ -234,27 +226,27 @@ set_properties (entity_t *ent, plitem_t *dict)
}
}
if ((p = get_item ("_radius", dict, prop))) {
if ((str = plstring (p))) {
if ((str = PL_String (p))) {
ent->radius = parse_float (str);
}
}
if ((p = get_item ("_noise", dict, prop))) {
if ((str = plstring (p))) {
if ((str = PL_String (p))) {
ent->noise = parse_float (str);
}
}
if ((p = get_item ("_noisetype", dict, prop))) {
if ((str = plstring (p))) {
if ((str = PL_String (p))) {
ent->noisetype = parse_noise (str);
}
}
if ((p = get_item ("_persistence", dict, prop))) {
if ((str = plstring (p))) {
if ((str = PL_String (p))) {
ent->persistence = parse_float (str);
}
}
if ((p = get_item ("_resolution", dict, prop))) {
if ((str = plstring (p))) {
if ((str = PL_String (p))) {
ent->resolution = parse_float (str);
}
}