Itsa me, quake3io!

This commit is contained in:
Zachary Slater 2005-08-26 04:48:05 +00:00
parent dbe4ddb103
commit 5b755058f5
1409 changed files with 798983 additions and 798983 deletions

0
COPYING.txt Normal file → Executable file
View file

0
README.txt Normal file → Executable file
View file

862
code/Construct Normal file → Executable file
View file

@ -1,431 +1,431 @@
# -*- mode: perl -*-
# cons script for cgame game q3_ui ui .so and .qvm builds
#
# Oct. 2001 TTimo <ttimo@idsoftware.com>
#
# the top directory is
# <config>-<cpu>-<OS>-<libc version>
# where:
# <config> is "debug" or "release"
# <cpu> is "x86" or "ppc"
# <OS> is "Linux" "BSD" "IRIX" etc.
# <libc version> is major.minor of libc config
# source the compiler version utility
BEGIN {
push @INC, './unix';
}
use Cons_gcc;
# defaults
$config = 'debug';
$do_smp = 1;
$do_masterserver = 0;
$do_authserver = 0;
$do_authport = 0;
$do_setup = 0;
$do_bspc = 0;
$do_sdk = 0;
$do_pk3 = 0;
# those are exported
$DO_WIN32 = 0;
$NO_VM = 0;
$NO_SO = 0;
$CC='gcc';
$CXX='g++';
# detect an sdk build (don't attempt client build and other things)
if ( -r 'unix/Conscript-client' )
{
$no_core = 0;
}
else
{
$no_core = 1;
}
# detection of CPU type
$cpu = `uname -m`;
chop ($cpu);
if ($cpu +~ /i?86/)
{
$cpu = 'x86';
}
# OS
$OS = `uname`;
chop ($OS);
# hacky win32 detection and win32 specifics code
if ($OS =~ CYGWIN)
{
$DO_WIN32 = 1;
}
else
{
# libc .. do the little magic!
$libc_cmd = '/lib/libc.so.6 |grep "GNU C "|grep version|awk -F "version " \'{ print $2 }\'|cut -b -3';
$libc = `$libc_cmd`;
chop ($libc);
}
if ($DO_WIN32 eq 1)
{
print("Win32 build\n");
$config = $ARGV[0];
# TODO: option to override $Q3BASE from command line
$Q3BASE = $ENV{Q3BASE}; # FIXME: this doesn't play nice with cygwin path syntax
print("\$Q3BASE: $Q3BASE\n");
if($config eq 'debug')
{
$DIR = 'Debug';
system("cp -v $DIR/quake3.exe \$Q3BASE");
system("cp -v $DIR/cgamex86.dll $DIR/qagamex86.dll $DIR/uix86.dll \$Q3BASE/baseq3");
}
elsif ($config eq 'debug-TA')
{
$DIR = 'Debug_TA';
system("cp -v $DIR/quake3.exe \$Q3BASE");
system("cp -v $DIR/cgamex86.dll $DIR/qagamex86.dll $DIR/uix86.dll \$Q3BASE/missionpack");
}
elsif($config eq 'release-TA')
{
$DIR = 'Release_TA';
# spank!
system("./spank.sh");
system("cp -v $DIR/quake3.exe \$Q3BASE");
}
else
{
printf("ERROR: no config option (debug debug-TA release-TA)");
exit;
}
# copy selected stuff to shared media
$DESTDIR='/cygdrive/e/incoming/Id/q3-1.32';
system("cp -v $DIR/quake3.exe $DESTDIR");
system("cp -v /cygdrive/e/Q3SetupMedia/quake3/CHANGES-1.32.txt $DESTDIR");
exit;
}
if(@ARGV gt 0)
{
foreach $cmdopt (@ARGV)
{
if(lc($cmdopt) eq 'release')
{
$config = 'release';
next;
}
elsif(lc($cmdopt) eq 'debug')
{
$config = 'debug';
next;
}
elsif(lc($cmdopt) eq 'novm')
{
$NO_VM = 1;
next;
}
elsif(lc($cmdopt) eq 'noso')
{
$NO_SO = 1;
next;
}
elsif(lc($cmdopt) eq 'nosmp')
{
$do_smp = 0;
next;
}
elsif(lc($cmdopt) =~ 'master_server=.*')
{
$do_masterserver = 1;
$master_server = lc($cmdopt);
$master_server =~ s/master_server=(.*)/\1/;
next;
}
elsif(lc($cmdopt) =~ 'auth_server=.*')
{
$do_authserver = 1;
$auth_server = lc($cmdopt);
$auth_server =~ s/auth_server=(.*)/\1/;
next;
}
elsif(lc($cmdopt) =~ 'auth_port=.*')
{
$do_authport = 1;
$auth_port = lc($cmdopt);
$auth_port =~ s/auth_port=(.*)/\1/;
next;
}
elsif(lc($cmdopt) =~ 'setup')
{
$do_setup = 1;
next;
}
elsif(lc($cmdopt) =~ 'bspc')
{
$do_bspc = 1;
next;
}
elsif(lc($cmdopt) =~ 'sdk')
{
$do_sdk = 1;
next;
}
elsif(lc($cmdopt) =~ 'pk3')
{
$do_pk3 = 1;
next;
}
elsif(lc($cmdopt) =~ 'gcc=.*')
{
$CC=lc($cmdopt);
$CC =~ s/gcc=(.*)/\1/;
next;
}
elsif(lc($cmdopt) =~ 'g\+\+=.*')
{
$CXX=lc($cmdopt);
$CXX=~s/g\+\+=(.*)/\1/;
next;
}
else
{
# output an error & exit
print("Error\n $0: Unknown command line option: [ $cmdopt ]\n");
system("cons -h");
exit;
}
}
}
if (($do_setup eq 1) && ($config ne 'release'))
{
print("Error\n $0: 'setup' requires 'release'\n");
exit;
}
# sdk
if ($do_sdk eq 1)
{
# extract the Q3 version from q_shared.h
$line = `cat game/q_shared.h | grep Q3_VERSION`;
chomp $line;
$line =~ s/.*Q3\ (.*)\"/$1/;
$Q3_VER = $line;
$SDK_NAME = "linuxq3a-sdk-$Q3_VER.x86.run";
Default "unix/$SDK_NAME";
Export qw( SDK_NAME Q3_VER );
Build 'unix/Conscript-sdk';
return;
}
# build the config directory
$CONFIG_DIR = $config . '-' . $cpu . '-' . $OS . '-' . $libc;
$COMMON_CFLAGS = '-pipe -fsigned-char ';
if ($config eq 'debug')
{
# use -Werror for better QA
$BASE_CFLAGS = $COMMON_CFLAGS . '-g -Wall -Werror -O ';
$BSPC_BASE_CFLAGS = $COMMON_CFLAGS . '-g -O -DLINUX -DBSPC -Dstricmp=strcasecmp ';
}
else
{
$BASE_CFLAGS = $COMMON_CFLAGS . '-DNDEBUG -O6 -mcpu=pentiumpro -march=pentium -fomit-frame-pointer -ffast-math -malign-loops=2 -malign-jumps=2 -malign-functions=2 -fno-strict-aliasing -fstrength-reduce ';
$BSPC_BASE_CFLAGS = $BASE_CFLAGS . '-DLINUX -DBSPC -Dstricmp=strcasecmp ';
}
if ($do_masterserver eq 1)
{
$BASE_CFLAGS .= "-DMASTER_SERVER_NAME=\\\"$master_server\\\" ";
}
if ($do_authserver eq 1)
{
$BASE_CFLAGS .= "-DAUTHORIZE_SERVER_NAME=\\\"$auth_server\\\" ";
}
if ($do_authport eq 1)
{
$BASE_CFLAGS .= "-DPORT_AUTHORIZE=$auth_port ";
}
my @gcc_version = Cons_gcc::get_gcc_version($CC);
print("GCC version: $gcc_version[1] - $gcc_version[2]\n");
# with 2.95 you can link with gcc, this avoids nasty useless libstdc++ dependency
if ($gcc_version[0] eq '2')
{
$LINK = $CC;
} else {
$LINK = $CXX;
}
my @ccache = Cons_gcc::get_ccache();
if ($ccache[0] eq '1')
{
$CC = $ccache[1] . " " . $CC;
$CXX = $ccache[1] . " " . $CXX;
}
print 'cpu : ' . $cpu . "\nOS : " . $OS . "\n";
print "libc: " . $libc . "\n";
print "configured for " . $config . " build\n";
print 'CFLAGS: ' . $BASE_CFLAGS . "\n";
# install config
$INSTALL_BASEDIR='#install';
Default $INSTALL_BASEDIR;
sub build_tools {
system("mkdir qvmtools 2>/dev/null");
if (@_[0] eq 'q3lcc')
{
system("cd ../lcc ; make all ; cp /tmp/lcc ../code/qvmtools/q3lcc ; cp /tmp/rcc ../code/qvmtools/q3rcc ; cp /tmp/cpp ../code/qvmtools/q3cpp");
}
elsif (@_[0] eq 'q3asm')
{
system("cd ../q3asm ; make ; cp q3asm ../code/qvmtools");
}
else
{
printf("build_tools: @_[0] unrecognized command\n");
die;
}
return 1;
}
# build tools
$env_tools = new cons();
Command $env_tools 'qvmtools/q3lcc', '[perl] &build_tools(\'q3lcc\')';
Command $env_tools 'qvmtools/q3asm', '[perl] &build_tools(\'q3asm\')';
if ($do_bspc eq 1)
{
# build bspc
$BUILD_DIR = $CONFIG_DIR . '/bspc';
Link $BUILD_DIR => '.';
$INSTALL_DIR = $INSTALL_BASEDIR . '/utils';
Export qw( BSPC_BASE_CFLAGS BUILD_DIR INSTALL_DIR CC CXX LINK );
Build $BUILD_DIR . '/bspc/Conscript';
}
# build vanilla Q3
$TARGET_DIR='Q3';
$INSTALL_DIR = $INSTALL_BASEDIR . '/baseq3';
$BUILD_DIR = $CONFIG_DIR . '/' . $TARGET_DIR . '/cgame';
Link $BUILD_DIR => '.';
Export qw( BASE_CFLAGS TARGET_DIR INSTALL_DIR NO_VM NO_SO CC CXX LINK );
Build $BUILD_DIR . '/cgame/Conscript';
$BUILD_DIR = $CONFIG_DIR . '/' . $TARGET_DIR . '/game';
Link $BUILD_DIR => '.';
Export qw( BASE_CFLAGS TARGET_DIR INSTALL_DIR NO_VM NO_SO CC CXX LINK );
Build $BUILD_DIR . '/game/Conscript';
$BUILD_DIR = $CONFIG_DIR . '/' . $TARGET_DIR . '/q3_ui';
Link $BUILD_DIR => '.';
Export qw( BASE_CFLAGS TARGET_DIR INSTALL_DIR NO_VM NO_SO CC CXX LINK );
Build $BUILD_DIR . '/q3_ui/Conscript';
# build TA
$TARGET_DIR='TA';
$INSTALL_DIR = $INSTALL_BASEDIR . '/missionpack';
$BUILD_DIR = $CONFIG_DIR . "/" . $TARGET_DIR . '/cgame';
Link $BUILD_DIR => '.';
Export qw( BASE_CFLAGS TARGET_DIR INSTALL_DIR NO_VM NO_SO CC CXX LINK );
Build $BUILD_DIR . '/cgame/Conscript';
$BUILD_DIR = $CONFIG_DIR . "/" . $TARGET_DIR . '/game';
Link $BUILD_DIR => '.';
Export qw( BASE_CFLAGS TARGET_DIR INSTALL_DIR NO_VM NO_SO CC CXX LINK );
Build $BUILD_DIR . '/game/Conscript';
$BUILD_DIR = $CONFIG_DIR . '/' . $TARGET_DIR . '/ui';
Link $BUILD_DIR => '.';
Export qw( BASE_CFLAGS TARGET_DIR INSTALL_DIR NO_VM NO_SO CC CXX LINK );
Build $BUILD_DIR . '/ui/Conscript';
# core
if ($no_core eq 1)
{
return;
}
$INSTALL_DIR = $INSTALL_BASEDIR;
$BUILD_DIR = $CONFIG_DIR . '/core/dedicated';
Link $BUILD_DIR => '.';
$hack = $BASE_CFLAGS; # hit me!
$BASE_CFLAGS .= '-DDEDICATED ';
Export qw( BASE_CFLAGS BUILD_DIR INSTALL_DIR CC CXX LINK );
Build $BUILD_DIR . '/unix/Conscript-dedicated';
$BASE_CFLAGS = $hack;
$TARGETNAME = 'linuxquake3';
$BUILD_DIR = $CONFIG_DIR . '/core/client';
$BASE_LDFLAGS = '';
Link $BUILD_DIR => '.';
Export qw( BASE_CFLAGS BASE_LDFLAGS BUILD_DIR INSTALL_DIR TARGETNAME CC CXX LINK );
Build $BUILD_DIR . '/unix/Conscript-client';
if ($do_smp eq 1)
{
$TARGETNAME = 'linuxquake3-smp';
$BUILD_DIR = $CONFIG_DIR . '/core/client-smp';
$BASE_CFLAGS .= '-DSMP ';
$BASE_LDFLAGS = '-lpthread ';
Link $BUILD_DIR => '.';
Export qw( BASE_CFLAGS BASE_LDFLAGS BUILD_DIR INSTALL_DIR TARGETNAME CC CXX LINK );
Build $BUILD_DIR . '/unix/Conscript-client';
}
if ($NO_VM eq 0 && $do_pk3 eq 1)
{
# build the PK3s
$INSTALL_DIR = $INSTALL_BASEDIR;
$BUILD_DIR = $CONFIG_DIR . '/pk3-builder';
Link $BUILD_DIR => 'unix';
Export qw( INSTALL_DIR BUILD_DIR CONFIG_DIR CC CXX LINK );
Build $BUILD_DIR . '/Conscript-pk3';
}
if ($do_setup eq 1)
{
Link $CONFIG_DIR => '.';
Export qw( INSTALL_BASEDIR );
Build $CONFIG_DIR . '/unix/Conscript-setup';
}
Help
"
Usage: cons [-h] [ -- [release|debug] [novm] [noso] [nosmp] [master_server=<adr>] [auth_server=<adr>] [auth_port=<port>] [pk3] [bspc] [setup] [sdk]]
Default build type is Debug, specifying '-- release' on the
command line builds a Release version (NOTE that this option
only affects the native libraries).
novm: will not build the VMs
noso: will not build the so
below are for core builds only:
nosmp : do not build the SMP-enabled version of the renderer
pk3 : generate the pk3s on the fly (defined in unix/Conscript-pk3)
bspc : build bspc
setup : build setup
sdk : build the mod sdk
"
;
# -*- mode: perl -*-
# cons script for cgame game q3_ui ui .so and .qvm builds
#
# Oct. 2001 TTimo <ttimo@idsoftware.com>
#
# the top directory is
# <config>-<cpu>-<OS>-<libc version>
# where:
# <config> is "debug" or "release"
# <cpu> is "x86" or "ppc"
# <OS> is "Linux" "BSD" "IRIX" etc.
# <libc version> is major.minor of libc config
# source the compiler version utility
BEGIN {
push @INC, './unix';
}
use Cons_gcc;
# defaults
$config = 'debug';
$do_smp = 1;
$do_masterserver = 0;
$do_authserver = 0;
$do_authport = 0;
$do_setup = 0;
$do_bspc = 0;
$do_sdk = 0;
$do_pk3 = 0;
# those are exported
$DO_WIN32 = 0;
$NO_VM = 0;
$NO_SO = 0;
$CC='gcc';
$CXX='g++';
# detect an sdk build (don't attempt client build and other things)
if ( -r 'unix/Conscript-client' )
{
$no_core = 0;
}
else
{
$no_core = 1;
}
# detection of CPU type
$cpu = `uname -m`;
chop ($cpu);
if ($cpu +~ /i?86/)
{
$cpu = 'x86';
}
# OS
$OS = `uname`;
chop ($OS);
# hacky win32 detection and win32 specifics code
if ($OS =~ CYGWIN)
{
$DO_WIN32 = 1;
}
else
{
# libc .. do the little magic!
$libc_cmd = '/lib/libc.so.6 |grep "GNU C "|grep version|awk -F "version " \'{ print $2 }\'|cut -b -3';
$libc = `$libc_cmd`;
chop ($libc);
}
if ($DO_WIN32 eq 1)
{
print("Win32 build\n");
$config = $ARGV[0];
# TODO: option to override $Q3BASE from command line
$Q3BASE = $ENV{Q3BASE}; # FIXME: this doesn't play nice with cygwin path syntax
print("\$Q3BASE: $Q3BASE\n");
if($config eq 'debug')
{
$DIR = 'Debug';
system("cp -v $DIR/quake3.exe \$Q3BASE");
system("cp -v $DIR/cgamex86.dll $DIR/qagamex86.dll $DIR/uix86.dll \$Q3BASE/baseq3");
}
elsif ($config eq 'debug-TA')
{
$DIR = 'Debug_TA';
system("cp -v $DIR/quake3.exe \$Q3BASE");
system("cp -v $DIR/cgamex86.dll $DIR/qagamex86.dll $DIR/uix86.dll \$Q3BASE/missionpack");
}
elsif($config eq 'release-TA')
{
$DIR = 'Release_TA';
# spank!
system("./spank.sh");
system("cp -v $DIR/quake3.exe \$Q3BASE");
}
else
{
printf("ERROR: no config option (debug debug-TA release-TA)");
exit;
}
# copy selected stuff to shared media
$DESTDIR='/cygdrive/e/incoming/Id/q3-1.32';
system("cp -v $DIR/quake3.exe $DESTDIR");
system("cp -v /cygdrive/e/Q3SetupMedia/quake3/CHANGES-1.32.txt $DESTDIR");
exit;
}
if(@ARGV gt 0)
{
foreach $cmdopt (@ARGV)
{
if(lc($cmdopt) eq 'release')
{
$config = 'release';
next;
}
elsif(lc($cmdopt) eq 'debug')
{
$config = 'debug';
next;
}
elsif(lc($cmdopt) eq 'novm')
{
$NO_VM = 1;
next;
}
elsif(lc($cmdopt) eq 'noso')
{
$NO_SO = 1;
next;
}
elsif(lc($cmdopt) eq 'nosmp')
{
$do_smp = 0;
next;
}
elsif(lc($cmdopt) =~ 'master_server=.*')
{
$do_masterserver = 1;
$master_server = lc($cmdopt);
$master_server =~ s/master_server=(.*)/\1/;
next;
}
elsif(lc($cmdopt) =~ 'auth_server=.*')
{
$do_authserver = 1;
$auth_server = lc($cmdopt);
$auth_server =~ s/auth_server=(.*)/\1/;
next;
}
elsif(lc($cmdopt) =~ 'auth_port=.*')
{
$do_authport = 1;
$auth_port = lc($cmdopt);
$auth_port =~ s/auth_port=(.*)/\1/;
next;
}
elsif(lc($cmdopt) =~ 'setup')
{
$do_setup = 1;
next;
}
elsif(lc($cmdopt) =~ 'bspc')
{
$do_bspc = 1;
next;
}
elsif(lc($cmdopt) =~ 'sdk')
{
$do_sdk = 1;
next;
}
elsif(lc($cmdopt) =~ 'pk3')
{
$do_pk3 = 1;
next;
}
elsif(lc($cmdopt) =~ 'gcc=.*')
{
$CC=lc($cmdopt);
$CC =~ s/gcc=(.*)/\1/;
next;
}
elsif(lc($cmdopt) =~ 'g\+\+=.*')
{
$CXX=lc($cmdopt);
$CXX=~s/g\+\+=(.*)/\1/;
next;
}
else
{
# output an error & exit
print("Error\n $0: Unknown command line option: [ $cmdopt ]\n");
system("cons -h");
exit;
}
}
}
if (($do_setup eq 1) && ($config ne 'release'))
{
print("Error\n $0: 'setup' requires 'release'\n");
exit;
}
# sdk
if ($do_sdk eq 1)
{
# extract the Q3 version from q_shared.h
$line = `cat game/q_shared.h | grep Q3_VERSION`;
chomp $line;
$line =~ s/.*Q3\ (.*)\"/$1/;
$Q3_VER = $line;
$SDK_NAME = "linuxq3a-sdk-$Q3_VER.x86.run";
Default "unix/$SDK_NAME";
Export qw( SDK_NAME Q3_VER );
Build 'unix/Conscript-sdk';
return;
}
# build the config directory
$CONFIG_DIR = $config . '-' . $cpu . '-' . $OS . '-' . $libc;
$COMMON_CFLAGS = '-pipe -fsigned-char ';
if ($config eq 'debug')
{
# use -Werror for better QA
$BASE_CFLAGS = $COMMON_CFLAGS . '-g -Wall -Werror -O ';
$BSPC_BASE_CFLAGS = $COMMON_CFLAGS . '-g -O -DLINUX -DBSPC -Dstricmp=strcasecmp ';
}
else
{
$BASE_CFLAGS = $COMMON_CFLAGS . '-DNDEBUG -O6 -mcpu=pentiumpro -march=pentium -fomit-frame-pointer -ffast-math -malign-loops=2 -malign-jumps=2 -malign-functions=2 -fno-strict-aliasing -fstrength-reduce ';
$BSPC_BASE_CFLAGS = $BASE_CFLAGS . '-DLINUX -DBSPC -Dstricmp=strcasecmp ';
}
if ($do_masterserver eq 1)
{
$BASE_CFLAGS .= "-DMASTER_SERVER_NAME=\\\"$master_server\\\" ";
}
if ($do_authserver eq 1)
{
$BASE_CFLAGS .= "-DAUTHORIZE_SERVER_NAME=\\\"$auth_server\\\" ";
}
if ($do_authport eq 1)
{
$BASE_CFLAGS .= "-DPORT_AUTHORIZE=$auth_port ";
}
my @gcc_version = Cons_gcc::get_gcc_version($CC);
print("GCC version: $gcc_version[1] - $gcc_version[2]\n");
# with 2.95 you can link with gcc, this avoids nasty useless libstdc++ dependency
if ($gcc_version[0] eq '2')
{
$LINK = $CC;
} else {
$LINK = $CXX;
}
my @ccache = Cons_gcc::get_ccache();
if ($ccache[0] eq '1')
{
$CC = $ccache[1] . " " . $CC;
$CXX = $ccache[1] . " " . $CXX;
}
print 'cpu : ' . $cpu . "\nOS : " . $OS . "\n";
print "libc: " . $libc . "\n";
print "configured for " . $config . " build\n";
print 'CFLAGS: ' . $BASE_CFLAGS . "\n";
# install config
$INSTALL_BASEDIR='#install';
Default $INSTALL_BASEDIR;
sub build_tools {
system("mkdir qvmtools 2>/dev/null");
if (@_[0] eq 'q3lcc')
{
system("cd ../lcc ; make all ; cp /tmp/lcc ../code/qvmtools/q3lcc ; cp /tmp/rcc ../code/qvmtools/q3rcc ; cp /tmp/cpp ../code/qvmtools/q3cpp");
}
elsif (@_[0] eq 'q3asm')
{
system("cd ../q3asm ; make ; cp q3asm ../code/qvmtools");
}
else
{
printf("build_tools: @_[0] unrecognized command\n");
die;
}
return 1;
}
# build tools
$env_tools = new cons();
Command $env_tools 'qvmtools/q3lcc', '[perl] &build_tools(\'q3lcc\')';
Command $env_tools 'qvmtools/q3asm', '[perl] &build_tools(\'q3asm\')';
if ($do_bspc eq 1)
{
# build bspc
$BUILD_DIR = $CONFIG_DIR . '/bspc';
Link $BUILD_DIR => '.';
$INSTALL_DIR = $INSTALL_BASEDIR . '/utils';
Export qw( BSPC_BASE_CFLAGS BUILD_DIR INSTALL_DIR CC CXX LINK );
Build $BUILD_DIR . '/bspc/Conscript';
}
# build vanilla Q3
$TARGET_DIR='Q3';
$INSTALL_DIR = $INSTALL_BASEDIR . '/baseq3';
$BUILD_DIR = $CONFIG_DIR . '/' . $TARGET_DIR . '/cgame';
Link $BUILD_DIR => '.';
Export qw( BASE_CFLAGS TARGET_DIR INSTALL_DIR NO_VM NO_SO CC CXX LINK );
Build $BUILD_DIR . '/cgame/Conscript';
$BUILD_DIR = $CONFIG_DIR . '/' . $TARGET_DIR . '/game';
Link $BUILD_DIR => '.';
Export qw( BASE_CFLAGS TARGET_DIR INSTALL_DIR NO_VM NO_SO CC CXX LINK );
Build $BUILD_DIR . '/game/Conscript';
$BUILD_DIR = $CONFIG_DIR . '/' . $TARGET_DIR . '/q3_ui';
Link $BUILD_DIR => '.';
Export qw( BASE_CFLAGS TARGET_DIR INSTALL_DIR NO_VM NO_SO CC CXX LINK );
Build $BUILD_DIR . '/q3_ui/Conscript';
# build TA
$TARGET_DIR='TA';
$INSTALL_DIR = $INSTALL_BASEDIR . '/missionpack';
$BUILD_DIR = $CONFIG_DIR . "/" . $TARGET_DIR . '/cgame';
Link $BUILD_DIR => '.';
Export qw( BASE_CFLAGS TARGET_DIR INSTALL_DIR NO_VM NO_SO CC CXX LINK );
Build $BUILD_DIR . '/cgame/Conscript';
$BUILD_DIR = $CONFIG_DIR . "/" . $TARGET_DIR . '/game';
Link $BUILD_DIR => '.';
Export qw( BASE_CFLAGS TARGET_DIR INSTALL_DIR NO_VM NO_SO CC CXX LINK );
Build $BUILD_DIR . '/game/Conscript';
$BUILD_DIR = $CONFIG_DIR . '/' . $TARGET_DIR . '/ui';
Link $BUILD_DIR => '.';
Export qw( BASE_CFLAGS TARGET_DIR INSTALL_DIR NO_VM NO_SO CC CXX LINK );
Build $BUILD_DIR . '/ui/Conscript';
# core
if ($no_core eq 1)
{
return;
}
$INSTALL_DIR = $INSTALL_BASEDIR;
$BUILD_DIR = $CONFIG_DIR . '/core/dedicated';
Link $BUILD_DIR => '.';
$hack = $BASE_CFLAGS; # hit me!
$BASE_CFLAGS .= '-DDEDICATED ';
Export qw( BASE_CFLAGS BUILD_DIR INSTALL_DIR CC CXX LINK );
Build $BUILD_DIR . '/unix/Conscript-dedicated';
$BASE_CFLAGS = $hack;
$TARGETNAME = 'linuxquake3';
$BUILD_DIR = $CONFIG_DIR . '/core/client';
$BASE_LDFLAGS = '';
Link $BUILD_DIR => '.';
Export qw( BASE_CFLAGS BASE_LDFLAGS BUILD_DIR INSTALL_DIR TARGETNAME CC CXX LINK );
Build $BUILD_DIR . '/unix/Conscript-client';
if ($do_smp eq 1)
{
$TARGETNAME = 'linuxquake3-smp';
$BUILD_DIR = $CONFIG_DIR . '/core/client-smp';
$BASE_CFLAGS .= '-DSMP ';
$BASE_LDFLAGS = '-lpthread ';
Link $BUILD_DIR => '.';
Export qw( BASE_CFLAGS BASE_LDFLAGS BUILD_DIR INSTALL_DIR TARGETNAME CC CXX LINK );
Build $BUILD_DIR . '/unix/Conscript-client';
}
if ($NO_VM eq 0 && $do_pk3 eq 1)
{
# build the PK3s
$INSTALL_DIR = $INSTALL_BASEDIR;
$BUILD_DIR = $CONFIG_DIR . '/pk3-builder';
Link $BUILD_DIR => 'unix';
Export qw( INSTALL_DIR BUILD_DIR CONFIG_DIR CC CXX LINK );
Build $BUILD_DIR . '/Conscript-pk3';
}
if ($do_setup eq 1)
{
Link $CONFIG_DIR => '.';
Export qw( INSTALL_BASEDIR );
Build $CONFIG_DIR . '/unix/Conscript-setup';
}
Help
"
Usage: cons [-h] [ -- [release|debug] [novm] [noso] [nosmp] [master_server=<adr>] [auth_server=<adr>] [auth_port=<port>] [pk3] [bspc] [setup] [sdk]]
Default build type is Debug, specifying '-- release' on the
command line builds a Release version (NOTE that this option
only affects the native libraries).
novm: will not build the VMs
noso: will not build the so
below are for core builds only:
nosmp : do not build the SMP-enabled version of the renderer
pk3 : generate the pk3s on the fly (defined in unix/Conscript-pk3)
bspc : build bspc
setup : build setup
sdk : build the mod sdk
"
;

6
code/Makefile Normal file → Executable file
View file

@ -1,3 +1,3 @@
# nasty ugly to get build system working from Anjuta
all:
if [ `hostname` == sparkle ] ; then ./unix/pcons-2.3.1 -j4 -- novm noso ; else ./unix/cons ; fi
# nasty ugly to get build system working from Anjuta
all:
if [ `hostname` == sparkle ] ; then ./unix/pcons-2.3.1 -j4 -- novm noso ; else ./unix/cons ; fi

534
code/botlib/aasfile.h Normal file → Executable file
View file

@ -1,267 +1,267 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
//NOTE: int = default signed
// default long
#define AASID (('S'<<24)+('A'<<16)+('A'<<8)+'E')
#define AASVERSION_OLD 4
#define AASVERSION 5
//presence types
#define PRESENCE_NONE 1
#define PRESENCE_NORMAL 2
#define PRESENCE_CROUCH 4
//travel types
#define MAX_TRAVELTYPES 32
#define TRAVEL_INVALID 1 //temporary not possible
#define TRAVEL_WALK 2 //walking
#define TRAVEL_CROUCH 3 //crouching
#define TRAVEL_BARRIERJUMP 4 //jumping onto a barrier
#define TRAVEL_JUMP 5 //jumping
#define TRAVEL_LADDER 6 //climbing a ladder
#define TRAVEL_WALKOFFLEDGE 7 //walking of a ledge
#define TRAVEL_SWIM 8 //swimming
#define TRAVEL_WATERJUMP 9 //jump out of the water
#define TRAVEL_TELEPORT 10 //teleportation
#define TRAVEL_ELEVATOR 11 //travel by elevator
#define TRAVEL_ROCKETJUMP 12 //rocket jumping required for travel
#define TRAVEL_BFGJUMP 13 //bfg jumping required for travel
#define TRAVEL_GRAPPLEHOOK 14 //grappling hook required for travel
#define TRAVEL_DOUBLEJUMP 15 //double jump
#define TRAVEL_RAMPJUMP 16 //ramp jump
#define TRAVEL_STRAFEJUMP 17 //strafe jump
#define TRAVEL_JUMPPAD 18 //jump pad
#define TRAVEL_FUNCBOB 19 //func bob
//additional travel flags
#define TRAVELTYPE_MASK 0xFFFFFF
#define TRAVELFLAG_NOTTEAM1 (1 << 24)
#define TRAVELFLAG_NOTTEAM2 (2 << 24)
//face flags
#define FACE_SOLID 1 //just solid at the other side
#define FACE_LADDER 2 //ladder
#define FACE_GROUND 4 //standing on ground when in this face
#define FACE_GAP 8 //gap in the ground
#define FACE_LIQUID 16 //face seperating two areas with liquid
#define FACE_LIQUIDSURFACE 32 //face seperating liquid and air
#define FACE_BRIDGE 64 //can walk over this face if bridge is closed
//area contents
#define AREACONTENTS_WATER 1
#define AREACONTENTS_LAVA 2
#define AREACONTENTS_SLIME 4
#define AREACONTENTS_CLUSTERPORTAL 8
#define AREACONTENTS_TELEPORTAL 16
#define AREACONTENTS_ROUTEPORTAL 32
#define AREACONTENTS_TELEPORTER 64
#define AREACONTENTS_JUMPPAD 128
#define AREACONTENTS_DONOTENTER 256
#define AREACONTENTS_VIEWPORTAL 512
#define AREACONTENTS_MOVER 1024
#define AREACONTENTS_NOTTEAM1 2048
#define AREACONTENTS_NOTTEAM2 4096
//number of model of the mover inside this area
#define AREACONTENTS_MODELNUMSHIFT 24
#define AREACONTENTS_MAXMODELNUM 0xFF
#define AREACONTENTS_MODELNUM (AREACONTENTS_MAXMODELNUM << AREACONTENTS_MODELNUMSHIFT)
//area flags
#define AREA_GROUNDED 1 //bot can stand on the ground
#define AREA_LADDER 2 //area contains one or more ladder faces
#define AREA_LIQUID 4 //area contains a liquid
#define AREA_DISABLED 8 //area is disabled for routing when set
#define AREA_BRIDGE 16 //area ontop of a bridge
//aas file header lumps
#define AAS_LUMPS 14
#define AASLUMP_BBOXES 0
#define AASLUMP_VERTEXES 1
#define AASLUMP_PLANES 2
#define AASLUMP_EDGES 3
#define AASLUMP_EDGEINDEX 4
#define AASLUMP_FACES 5
#define AASLUMP_FACEINDEX 6
#define AASLUMP_AREAS 7
#define AASLUMP_AREASETTINGS 8
#define AASLUMP_REACHABILITY 9
#define AASLUMP_NODES 10
#define AASLUMP_PORTALS 11
#define AASLUMP_PORTALINDEX 12
#define AASLUMP_CLUSTERS 13
//========== bounding box =========
//bounding box
typedef struct aas_bbox_s
{
int presencetype;
int flags;
vec3_t mins, maxs;
} aas_bbox_t;
//============ settings ===========
//reachability to another area
typedef struct aas_reachability_s
{
int areanum; //number of the reachable area
int facenum; //number of the face towards the other area
int edgenum; //number of the edge towards the other area
vec3_t start; //start point of inter area movement
vec3_t end; //end point of inter area movement
int traveltype; //type of travel required to get to the area
unsigned short int traveltime;//travel time of the inter area movement
} aas_reachability_t;
//area settings
typedef struct aas_areasettings_s
{
//could also add all kind of statistic fields
int contents; //contents of the area
int areaflags; //several area flags
int presencetype; //how a bot can be present in this area
int cluster; //cluster the area belongs to, if negative it's a portal
int clusterareanum; //number of the area in the cluster
int numreachableareas; //number of reachable areas from this one
int firstreachablearea; //first reachable area in the reachable area index
} aas_areasettings_t;
//cluster portal
typedef struct aas_portal_s
{
int areanum; //area that is the actual portal
int frontcluster; //cluster at front of portal
int backcluster; //cluster at back of portal
int clusterareanum[2]; //number of the area in the front and back cluster
} aas_portal_t;
//cluster portal index
typedef int aas_portalindex_t;
//cluster
typedef struct aas_cluster_s
{
int numareas; //number of areas in the cluster
int numreachabilityareas; //number of areas with reachabilities
int numportals; //number of cluster portals
int firstportal; //first cluster portal in the index
} aas_cluster_t;
//============ 3d definition ============
typedef vec3_t aas_vertex_t;
//just a plane in the third dimension
typedef struct aas_plane_s
{
vec3_t normal; //normal vector of the plane
float dist; //distance of the plane (normal vector * distance = point in plane)
int type;
} aas_plane_t;
//edge
typedef struct aas_edge_s
{
int v[2]; //numbers of the vertexes of this edge
} aas_edge_t;
//edge index, negative if vertexes are reversed
typedef int aas_edgeindex_t;
//a face bounds an area, often it will also seperate two areas
typedef struct aas_face_s
{
int planenum; //number of the plane this face is in
int faceflags; //face flags (no use to create face settings for just this field)
int numedges; //number of edges in the boundary of the face
int firstedge; //first edge in the edge index
int frontarea; //area at the front of this face
int backarea; //area at the back of this face
} aas_face_t;
//face index, stores a negative index if backside of face
typedef int aas_faceindex_t;
//area with a boundary of faces
typedef struct aas_area_s
{
int areanum; //number of this area
//3d definition
int numfaces; //number of faces used for the boundary of the area
int firstface; //first face in the face index used for the boundary of the area
vec3_t mins; //mins of the area
vec3_t maxs; //maxs of the area
vec3_t center; //'center' of the area
} aas_area_t;
//nodes of the bsp tree
typedef struct aas_node_s
{
int planenum;
int children[2]; //child nodes of this node, or areas as leaves when negative
//when a child is zero it's a solid leaf
} aas_node_t;
//=========== aas file ===============
//header lump
typedef struct
{
int fileofs;
int filelen;
} aas_lump_t;
//aas file header
typedef struct aas_header_s
{
int ident;
int version;
int bspchecksum;
//data entries
aas_lump_t lumps[AAS_LUMPS];
} aas_header_t;
//====== additional information ======
/*
- when a node child is a solid leaf the node child number is zero
- two adjacent areas (sharing a plane at opposite sides) share a face
this face is a portal between the areas
- when an area uses a face from the faceindex with a positive index
then the face plane normal points into the area
- the face edges are stored counter clockwise using the edgeindex
- two adjacent convex areas (sharing a face) only share One face
this is a simple result of the areas being convex
- the areas can't have a mixture of ground and gap faces
other mixtures of faces in one area are allowed
- areas with the AREACONTENTS_CLUSTERPORTAL in the settings have
the cluster number set to the negative portal number
- edge zero is a dummy
- face zero is a dummy
- area zero is a dummy
- node zero is a dummy
*/
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
//NOTE: int = default signed
// default long
#define AASID (('S'<<24)+('A'<<16)+('A'<<8)+'E')
#define AASVERSION_OLD 4
#define AASVERSION 5
//presence types
#define PRESENCE_NONE 1
#define PRESENCE_NORMAL 2
#define PRESENCE_CROUCH 4
//travel types
#define MAX_TRAVELTYPES 32
#define TRAVEL_INVALID 1 //temporary not possible
#define TRAVEL_WALK 2 //walking
#define TRAVEL_CROUCH 3 //crouching
#define TRAVEL_BARRIERJUMP 4 //jumping onto a barrier
#define TRAVEL_JUMP 5 //jumping
#define TRAVEL_LADDER 6 //climbing a ladder
#define TRAVEL_WALKOFFLEDGE 7 //walking of a ledge
#define TRAVEL_SWIM 8 //swimming
#define TRAVEL_WATERJUMP 9 //jump out of the water
#define TRAVEL_TELEPORT 10 //teleportation
#define TRAVEL_ELEVATOR 11 //travel by elevator
#define TRAVEL_ROCKETJUMP 12 //rocket jumping required for travel
#define TRAVEL_BFGJUMP 13 //bfg jumping required for travel
#define TRAVEL_GRAPPLEHOOK 14 //grappling hook required for travel
#define TRAVEL_DOUBLEJUMP 15 //double jump
#define TRAVEL_RAMPJUMP 16 //ramp jump
#define TRAVEL_STRAFEJUMP 17 //strafe jump
#define TRAVEL_JUMPPAD 18 //jump pad
#define TRAVEL_FUNCBOB 19 //func bob
//additional travel flags
#define TRAVELTYPE_MASK 0xFFFFFF
#define TRAVELFLAG_NOTTEAM1 (1 << 24)
#define TRAVELFLAG_NOTTEAM2 (2 << 24)
//face flags
#define FACE_SOLID 1 //just solid at the other side
#define FACE_LADDER 2 //ladder
#define FACE_GROUND 4 //standing on ground when in this face
#define FACE_GAP 8 //gap in the ground
#define FACE_LIQUID 16 //face seperating two areas with liquid
#define FACE_LIQUIDSURFACE 32 //face seperating liquid and air
#define FACE_BRIDGE 64 //can walk over this face if bridge is closed
//area contents
#define AREACONTENTS_WATER 1
#define AREACONTENTS_LAVA 2
#define AREACONTENTS_SLIME 4
#define AREACONTENTS_CLUSTERPORTAL 8
#define AREACONTENTS_TELEPORTAL 16
#define AREACONTENTS_ROUTEPORTAL 32
#define AREACONTENTS_TELEPORTER 64
#define AREACONTENTS_JUMPPAD 128
#define AREACONTENTS_DONOTENTER 256
#define AREACONTENTS_VIEWPORTAL 512
#define AREACONTENTS_MOVER 1024
#define AREACONTENTS_NOTTEAM1 2048
#define AREACONTENTS_NOTTEAM2 4096
//number of model of the mover inside this area
#define AREACONTENTS_MODELNUMSHIFT 24
#define AREACONTENTS_MAXMODELNUM 0xFF
#define AREACONTENTS_MODELNUM (AREACONTENTS_MAXMODELNUM << AREACONTENTS_MODELNUMSHIFT)
//area flags
#define AREA_GROUNDED 1 //bot can stand on the ground
#define AREA_LADDER 2 //area contains one or more ladder faces
#define AREA_LIQUID 4 //area contains a liquid
#define AREA_DISABLED 8 //area is disabled for routing when set
#define AREA_BRIDGE 16 //area ontop of a bridge
//aas file header lumps
#define AAS_LUMPS 14
#define AASLUMP_BBOXES 0
#define AASLUMP_VERTEXES 1
#define AASLUMP_PLANES 2
#define AASLUMP_EDGES 3
#define AASLUMP_EDGEINDEX 4
#define AASLUMP_FACES 5
#define AASLUMP_FACEINDEX 6
#define AASLUMP_AREAS 7
#define AASLUMP_AREASETTINGS 8
#define AASLUMP_REACHABILITY 9
#define AASLUMP_NODES 10
#define AASLUMP_PORTALS 11
#define AASLUMP_PORTALINDEX 12
#define AASLUMP_CLUSTERS 13
//========== bounding box =========
//bounding box
typedef struct aas_bbox_s
{
int presencetype;
int flags;
vec3_t mins, maxs;
} aas_bbox_t;
//============ settings ===========
//reachability to another area
typedef struct aas_reachability_s
{
int areanum; //number of the reachable area
int facenum; //number of the face towards the other area
int edgenum; //number of the edge towards the other area
vec3_t start; //start point of inter area movement
vec3_t end; //end point of inter area movement
int traveltype; //type of travel required to get to the area
unsigned short int traveltime;//travel time of the inter area movement
} aas_reachability_t;
//area settings
typedef struct aas_areasettings_s
{
//could also add all kind of statistic fields
int contents; //contents of the area
int areaflags; //several area flags
int presencetype; //how a bot can be present in this area
int cluster; //cluster the area belongs to, if negative it's a portal
int clusterareanum; //number of the area in the cluster
int numreachableareas; //number of reachable areas from this one
int firstreachablearea; //first reachable area in the reachable area index
} aas_areasettings_t;
//cluster portal
typedef struct aas_portal_s
{
int areanum; //area that is the actual portal
int frontcluster; //cluster at front of portal
int backcluster; //cluster at back of portal
int clusterareanum[2]; //number of the area in the front and back cluster
} aas_portal_t;
//cluster portal index
typedef int aas_portalindex_t;
//cluster
typedef struct aas_cluster_s
{
int numareas; //number of areas in the cluster
int numreachabilityareas; //number of areas with reachabilities
int numportals; //number of cluster portals
int firstportal; //first cluster portal in the index
} aas_cluster_t;
//============ 3d definition ============
typedef vec3_t aas_vertex_t;
//just a plane in the third dimension
typedef struct aas_plane_s
{
vec3_t normal; //normal vector of the plane
float dist; //distance of the plane (normal vector * distance = point in plane)
int type;
} aas_plane_t;
//edge
typedef struct aas_edge_s
{
int v[2]; //numbers of the vertexes of this edge
} aas_edge_t;
//edge index, negative if vertexes are reversed
typedef int aas_edgeindex_t;
//a face bounds an area, often it will also seperate two areas
typedef struct aas_face_s
{
int planenum; //number of the plane this face is in
int faceflags; //face flags (no use to create face settings for just this field)
int numedges; //number of edges in the boundary of the face
int firstedge; //first edge in the edge index
int frontarea; //area at the front of this face
int backarea; //area at the back of this face
} aas_face_t;
//face index, stores a negative index if backside of face
typedef int aas_faceindex_t;
//area with a boundary of faces
typedef struct aas_area_s
{
int areanum; //number of this area
//3d definition
int numfaces; //number of faces used for the boundary of the area
int firstface; //first face in the face index used for the boundary of the area
vec3_t mins; //mins of the area
vec3_t maxs; //maxs of the area
vec3_t center; //'center' of the area
} aas_area_t;
//nodes of the bsp tree
typedef struct aas_node_s
{
int planenum;
int children[2]; //child nodes of this node, or areas as leaves when negative
//when a child is zero it's a solid leaf
} aas_node_t;
//=========== aas file ===============
//header lump
typedef struct
{
int fileofs;
int filelen;
} aas_lump_t;
//aas file header
typedef struct aas_header_s
{
int ident;
int version;
int bspchecksum;
//data entries
aas_lump_t lumps[AAS_LUMPS];
} aas_header_t;
//====== additional information ======
/*
- when a node child is a solid leaf the node child number is zero
- two adjacent areas (sharing a plane at opposite sides) share a face
this face is a portal between the areas
- when an area uses a face from the faceindex with a positive index
then the face plane normal points into the area
- the face edges are stored counter clockwise using the edgeindex
- two adjacent convex areas (sharing a face) only share One face
this is a simple result of the areas being convex
- the areas can't have a mixture of ground and gap faces
other mixtures of faces in one area are allowed
- areas with the AREACONTENTS_CLUSTERPORTAL in the settings have
the cluster number set to the negative portal number
- edge zero is a dummy
- face zero is a dummy
- area zero is a dummy
- node zero is a dummy
*/

178
code/botlib/be_aas_bsp.h Normal file → Executable file
View file

@ -1,89 +1,89 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_bsp.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_bsp.h $
*
*****************************************************************************/
#ifdef AASINTERN
//loads the given BSP file
int AAS_LoadBSPFile(void);
//dump the loaded BSP data
void AAS_DumpBSPData(void);
//unlink the given entity from the bsp tree leaves
void AAS_UnlinkFromBSPLeaves(bsp_link_t *leaves);
//link the given entity to the bsp tree leaves of the given model
bsp_link_t *AAS_BSPLinkEntity(vec3_t absmins,
vec3_t absmaxs,
int entnum,
int modelnum);
//calculates collision with given entity
qboolean AAS_EntityCollision(int entnum,
vec3_t start,
vec3_t boxmins,
vec3_t boxmaxs,
vec3_t end,
int contentmask,
bsp_trace_t *trace);
//for debugging
void AAS_PrintFreeBSPLinks(char *str);
//
#endif //AASINTERN
#define MAX_EPAIRKEY 128
//trace through the world
bsp_trace_t AAS_Trace( vec3_t start,
vec3_t mins,
vec3_t maxs,
vec3_t end,
int passent,
int contentmask);
//returns the contents at the given point
int AAS_PointContents(vec3_t point);
//returns true when p2 is in the PVS of p1
qboolean AAS_inPVS(vec3_t p1, vec3_t p2);
//returns true when p2 is in the PHS of p1
qboolean AAS_inPHS(vec3_t p1, vec3_t p2);
//returns true if the given areas are connected
qboolean AAS_AreasConnected(int area1, int area2);
//creates a list with entities totally or partly within the given box
int AAS_BoxEntities(vec3_t absmins, vec3_t absmaxs, int *list, int maxcount);
//gets the mins, maxs and origin of a BSP model
void AAS_BSPModelMinsMaxsOrigin(int modelnum, vec3_t angles, vec3_t mins, vec3_t maxs, vec3_t origin);
//handle to the next bsp entity
int AAS_NextBSPEntity(int ent);
//return the value of the BSP epair key
int AAS_ValueForBSPEpairKey(int ent, char *key, char *value, int size);
//get a vector for the BSP epair key
int AAS_VectorForBSPEpairKey(int ent, char *key, vec3_t v);
//get a float for the BSP epair key
int AAS_FloatForBSPEpairKey(int ent, char *key, float *value);
//get an integer for the BSP epair key
int AAS_IntForBSPEpairKey(int ent, char *key, int *value);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_bsp.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_bsp.h $
*
*****************************************************************************/
#ifdef AASINTERN
//loads the given BSP file
int AAS_LoadBSPFile(void);
//dump the loaded BSP data
void AAS_DumpBSPData(void);
//unlink the given entity from the bsp tree leaves
void AAS_UnlinkFromBSPLeaves(bsp_link_t *leaves);
//link the given entity to the bsp tree leaves of the given model
bsp_link_t *AAS_BSPLinkEntity(vec3_t absmins,
vec3_t absmaxs,
int entnum,
int modelnum);
//calculates collision with given entity
qboolean AAS_EntityCollision(int entnum,
vec3_t start,
vec3_t boxmins,
vec3_t boxmaxs,
vec3_t end,
int contentmask,
bsp_trace_t *trace);
//for debugging
void AAS_PrintFreeBSPLinks(char *str);
//
#endif //AASINTERN
#define MAX_EPAIRKEY 128
//trace through the world
bsp_trace_t AAS_Trace( vec3_t start,
vec3_t mins,
vec3_t maxs,
vec3_t end,
int passent,
int contentmask);
//returns the contents at the given point
int AAS_PointContents(vec3_t point);
//returns true when p2 is in the PVS of p1
qboolean AAS_inPVS(vec3_t p1, vec3_t p2);
//returns true when p2 is in the PHS of p1
qboolean AAS_inPHS(vec3_t p1, vec3_t p2);
//returns true if the given areas are connected
qboolean AAS_AreasConnected(int area1, int area2);
//creates a list with entities totally or partly within the given box
int AAS_BoxEntities(vec3_t absmins, vec3_t absmaxs, int *list, int maxcount);
//gets the mins, maxs and origin of a BSP model
void AAS_BSPModelMinsMaxsOrigin(int modelnum, vec3_t angles, vec3_t mins, vec3_t maxs, vec3_t origin);
//handle to the next bsp entity
int AAS_NextBSPEntity(int ent);
//return the value of the BSP epair key
int AAS_ValueForBSPEpairKey(int ent, char *key, char *value, int size);
//get a vector for the BSP epair key
int AAS_VectorForBSPEpairKey(int ent, char *key, vec3_t v);
//get a float for the BSP epair key
int AAS_FloatForBSPEpairKey(int ent, char *key, float *value);
//get an integer for the BSP epair key
int AAS_IntForBSPEpairKey(int ent, char *key, int *value);

974
code/botlib/be_aas_bspq3.c Normal file → Executable file
View file

@ -1,487 +1,487 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_bspq3.c
*
* desc: BSP, Environment Sampling
*
* $Archive: /MissionPack/code/botlib/be_aas_bspq3.c $
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_memory.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_aas_def.h"
extern botlib_import_t botimport;
//#define TRACE_DEBUG
#define ON_EPSILON 0.005
//#define DEG2RAD( a ) (( a * M_PI ) / 180.0F)
#define MAX_BSPENTITIES 2048
typedef struct rgb_s
{
int red;
int green;
int blue;
} rgb_t;
//bsp entity epair
typedef struct bsp_epair_s
{
char *key;
char *value;
struct bsp_epair_s *next;
} bsp_epair_t;
//bsp data entity
typedef struct bsp_entity_s
{
bsp_epair_t *epairs;
} bsp_entity_t;
//id Sofware BSP data
typedef struct bsp_s
{
//true when bsp file is loaded
int loaded;
//entity data
int entdatasize;
char *dentdata;
//bsp entities
int numentities;
bsp_entity_t entities[MAX_BSPENTITIES];
} bsp_t;
//global bsp
bsp_t bspworld;
#ifdef BSP_DEBUG
typedef struct cname_s
{
int value;
char *name;
} cname_t;
cname_t contentnames[] =
{
{CONTENTS_SOLID,"CONTENTS_SOLID"},
{CONTENTS_WINDOW,"CONTENTS_WINDOW"},
{CONTENTS_AUX,"CONTENTS_AUX"},
{CONTENTS_LAVA,"CONTENTS_LAVA"},
{CONTENTS_SLIME,"CONTENTS_SLIME"},
{CONTENTS_WATER,"CONTENTS_WATER"},
{CONTENTS_MIST,"CONTENTS_MIST"},
{LAST_VISIBLE_CONTENTS,"LAST_VISIBLE_CONTENTS"},
{CONTENTS_AREAPORTAL,"CONTENTS_AREAPORTAL"},
{CONTENTS_PLAYERCLIP,"CONTENTS_PLAYERCLIP"},
{CONTENTS_MONSTERCLIP,"CONTENTS_MONSTERCLIP"},
{CONTENTS_CURRENT_0,"CONTENTS_CURRENT_0"},
{CONTENTS_CURRENT_90,"CONTENTS_CURRENT_90"},
{CONTENTS_CURRENT_180,"CONTENTS_CURRENT_180"},
{CONTENTS_CURRENT_270,"CONTENTS_CURRENT_270"},
{CONTENTS_CURRENT_UP,"CONTENTS_CURRENT_UP"},
{CONTENTS_CURRENT_DOWN,"CONTENTS_CURRENT_DOWN"},
{CONTENTS_ORIGIN,"CONTENTS_ORIGIN"},
{CONTENTS_MONSTER,"CONTENTS_MONSTER"},
{CONTENTS_DEADMONSTER,"CONTENTS_DEADMONSTER"},
{CONTENTS_DETAIL,"CONTENTS_DETAIL"},
{CONTENTS_TRANSLUCENT,"CONTENTS_TRANSLUCENT"},
{CONTENTS_LADDER,"CONTENTS_LADDER"},
{0, 0}
};
void PrintContents(int contents)
{
int i;
for (i = 0; contentnames[i].value; i++)
{
if (contents & contentnames[i].value)
{
botimport.Print(PRT_MESSAGE, "%s\n", contentnames[i].name);
} //end if
} //end for
} //end of the function PrintContents
#endif // BSP_DEBUG
//===========================================================================
// traces axial boxes of any size through the world
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
bsp_trace_t AAS_Trace(vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int passent, int contentmask)
{
bsp_trace_t bsptrace;
botimport.Trace(&bsptrace, start, mins, maxs, end, passent, contentmask);
return bsptrace;
} //end of the function AAS_Trace
//===========================================================================
// returns the contents at the given point
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_PointContents(vec3_t point)
{
return botimport.PointContents(point);
} //end of the function AAS_PointContents
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean AAS_EntityCollision(int entnum,
vec3_t start, vec3_t boxmins, vec3_t boxmaxs, vec3_t end,
int contentmask, bsp_trace_t *trace)
{
bsp_trace_t enttrace;
botimport.EntityTrace(&enttrace, start, boxmins, boxmaxs, end, entnum, contentmask);
if (enttrace.fraction < trace->fraction)
{
Com_Memcpy(trace, &enttrace, sizeof(bsp_trace_t));
return qtrue;
} //end if
return qfalse;
} //end of the function AAS_EntityCollision
//===========================================================================
// returns true if in Potentially Hearable Set
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean AAS_inPVS(vec3_t p1, vec3_t p2)
{
return botimport.inPVS(p1, p2);
} //end of the function AAS_InPVS
//===========================================================================
// returns true if in Potentially Visible Set
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean AAS_inPHS(vec3_t p1, vec3_t p2)
{
return qtrue;
} //end of the function AAS_inPHS
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_BSPModelMinsMaxsOrigin(int modelnum, vec3_t angles, vec3_t mins, vec3_t maxs, vec3_t origin)
{
botimport.BSPModelMinsMaxsOrigin(modelnum, angles, mins, maxs, origin);
} //end of the function AAS_BSPModelMinsMaxs
//===========================================================================
// unlinks the entity from all leaves
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_UnlinkFromBSPLeaves(bsp_link_t *leaves)
{
} //end of the function AAS_UnlinkFromBSPLeaves
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
bsp_link_t *AAS_BSPLinkEntity(vec3_t absmins, vec3_t absmaxs, int entnum, int modelnum)
{
return NULL;
} //end of the function AAS_BSPLinkEntity
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_BoxEntities(vec3_t absmins, vec3_t absmaxs, int *list, int maxcount)
{
return 0;
} //end of the function AAS_BoxEntities
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_NextBSPEntity(int ent)
{
ent++;
if (ent >= 1 && ent < bspworld.numentities) return ent;
return 0;
} //end of the function AAS_NextBSPEntity
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_BSPEntityInRange(int ent)
{
if (ent <= 0 || ent >= bspworld.numentities)
{
botimport.Print(PRT_MESSAGE, "bsp entity out of range\n");
return qfalse;
} //end if
return qtrue;
} //end of the function AAS_BSPEntityInRange
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_ValueForBSPEpairKey(int ent, char *key, char *value, int size)
{
bsp_epair_t *epair;
value[0] = '\0';
if (!AAS_BSPEntityInRange(ent)) return qfalse;
for (epair = bspworld.entities[ent].epairs; epair; epair = epair->next)
{
if (!strcmp(epair->key, key))
{
strncpy(value, epair->value, size-1);
value[size-1] = '\0';
return qtrue;
} //end if
} //end for
return qfalse;
} //end of the function AAS_FindBSPEpair
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_VectorForBSPEpairKey(int ent, char *key, vec3_t v)
{
char buf[MAX_EPAIRKEY];
double v1, v2, v3;
VectorClear(v);
if (!AAS_ValueForBSPEpairKey(ent, key, buf, MAX_EPAIRKEY)) return qfalse;
//scanf into doubles, then assign, so it is vec_t size independent
v1 = v2 = v3 = 0;
sscanf(buf, "%lf %lf %lf", &v1, &v2, &v3);
v[0] = v1;
v[1] = v2;
v[2] = v3;
return qtrue;
} //end of the function AAS_VectorForBSPEpairKey
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_FloatForBSPEpairKey(int ent, char *key, float *value)
{
char buf[MAX_EPAIRKEY];
*value = 0;
if (!AAS_ValueForBSPEpairKey(ent, key, buf, MAX_EPAIRKEY)) return qfalse;
*value = atof(buf);
return qtrue;
} //end of the function AAS_FloatForBSPEpairKey
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_IntForBSPEpairKey(int ent, char *key, int *value)
{
char buf[MAX_EPAIRKEY];
*value = 0;
if (!AAS_ValueForBSPEpairKey(ent, key, buf, MAX_EPAIRKEY)) return qfalse;
*value = atoi(buf);
return qtrue;
} //end of the function AAS_IntForBSPEpairKey
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_FreeBSPEntities(void)
{
int i;
bsp_entity_t *ent;
bsp_epair_t *epair, *nextepair;
for (i = 1; i < bspworld.numentities; i++)
{
ent = &bspworld.entities[i];
for (epair = ent->epairs; epair; epair = nextepair)
{
nextepair = epair->next;
//
if (epair->key) FreeMemory(epair->key);
if (epair->value) FreeMemory(epair->value);
FreeMemory(epair);
} //end for
} //end for
bspworld.numentities = 0;
} //end of the function AAS_FreeBSPEntities
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ParseBSPEntities(void)
{
script_t *script;
token_t token;
bsp_entity_t *ent;
bsp_epair_t *epair;
script = LoadScriptMemory(bspworld.dentdata, bspworld.entdatasize, "entdata");
SetScriptFlags(script, SCFL_NOSTRINGWHITESPACES|SCFL_NOSTRINGESCAPECHARS);//SCFL_PRIMITIVE);
bspworld.numentities = 1;
while(PS_ReadToken(script, &token))
{
if (strcmp(token.string, "{"))
{
ScriptError(script, "invalid %s\n", token.string);
AAS_FreeBSPEntities();
FreeScript(script);
return;
} //end if
if (bspworld.numentities >= MAX_BSPENTITIES)
{
botimport.Print(PRT_MESSAGE, "too many entities in BSP file\n");
break;
} //end if
ent = &bspworld.entities[bspworld.numentities];
bspworld.numentities++;
ent->epairs = NULL;
while(PS_ReadToken(script, &token))
{
if (!strcmp(token.string, "}")) break;
epair = (bsp_epair_t *) GetClearedHunkMemory(sizeof(bsp_epair_t));
epair->next = ent->epairs;
ent->epairs = epair;
if (token.type != TT_STRING)
{
ScriptError(script, "invalid %s\n", token.string);
AAS_FreeBSPEntities();
FreeScript(script);
return;
} //end if
StripDoubleQuotes(token.string);
epair->key = (char *) GetHunkMemory(strlen(token.string) + 1);
strcpy(epair->key, token.string);
if (!PS_ExpectTokenType(script, TT_STRING, 0, &token))
{
AAS_FreeBSPEntities();
FreeScript(script);
return;
} //end if
StripDoubleQuotes(token.string);
epair->value = (char *) GetHunkMemory(strlen(token.string) + 1);
strcpy(epair->value, token.string);
} //end while
if (strcmp(token.string, "}"))
{
ScriptError(script, "missing }\n");
AAS_FreeBSPEntities();
FreeScript(script);
return;
} //end if
} //end while
FreeScript(script);
} //end of the function AAS_ParseBSPEntities
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_BSPTraceLight(vec3_t start, vec3_t end, vec3_t endpos, int *red, int *green, int *blue)
{
return 0;
} //end of the function AAS_BSPTraceLight
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_DumpBSPData(void)
{
AAS_FreeBSPEntities();
if (bspworld.dentdata) FreeMemory(bspworld.dentdata);
bspworld.dentdata = NULL;
bspworld.entdatasize = 0;
//
bspworld.loaded = qfalse;
Com_Memset( &bspworld, 0, sizeof(bspworld) );
} //end of the function AAS_DumpBSPData
//===========================================================================
// load an bsp file
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_LoadBSPFile(void)
{
AAS_DumpBSPData();
bspworld.entdatasize = strlen(botimport.BSPEntityData()) + 1;
bspworld.dentdata = (char *) GetClearedHunkMemory(bspworld.entdatasize);
Com_Memcpy(bspworld.dentdata, botimport.BSPEntityData(), bspworld.entdatasize);
AAS_ParseBSPEntities();
bspworld.loaded = qtrue;
return BLERR_NOERROR;
} //end of the function AAS_LoadBSPFile
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_bspq3.c
*
* desc: BSP, Environment Sampling
*
* $Archive: /MissionPack/code/botlib/be_aas_bspq3.c $
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_memory.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_aas_def.h"
extern botlib_import_t botimport;
//#define TRACE_DEBUG
#define ON_EPSILON 0.005
//#define DEG2RAD( a ) (( a * M_PI ) / 180.0F)
#define MAX_BSPENTITIES 2048
typedef struct rgb_s
{
int red;
int green;
int blue;
} rgb_t;
//bsp entity epair
typedef struct bsp_epair_s
{
char *key;
char *value;
struct bsp_epair_s *next;
} bsp_epair_t;
//bsp data entity
typedef struct bsp_entity_s
{
bsp_epair_t *epairs;
} bsp_entity_t;
//id Sofware BSP data
typedef struct bsp_s
{
//true when bsp file is loaded
int loaded;
//entity data
int entdatasize;
char *dentdata;
//bsp entities
int numentities;
bsp_entity_t entities[MAX_BSPENTITIES];
} bsp_t;
//global bsp
bsp_t bspworld;
#ifdef BSP_DEBUG
typedef struct cname_s
{
int value;
char *name;
} cname_t;
cname_t contentnames[] =
{
{CONTENTS_SOLID,"CONTENTS_SOLID"},
{CONTENTS_WINDOW,"CONTENTS_WINDOW"},
{CONTENTS_AUX,"CONTENTS_AUX"},
{CONTENTS_LAVA,"CONTENTS_LAVA"},
{CONTENTS_SLIME,"CONTENTS_SLIME"},
{CONTENTS_WATER,"CONTENTS_WATER"},
{CONTENTS_MIST,"CONTENTS_MIST"},
{LAST_VISIBLE_CONTENTS,"LAST_VISIBLE_CONTENTS"},
{CONTENTS_AREAPORTAL,"CONTENTS_AREAPORTAL"},
{CONTENTS_PLAYERCLIP,"CONTENTS_PLAYERCLIP"},
{CONTENTS_MONSTERCLIP,"CONTENTS_MONSTERCLIP"},
{CONTENTS_CURRENT_0,"CONTENTS_CURRENT_0"},
{CONTENTS_CURRENT_90,"CONTENTS_CURRENT_90"},
{CONTENTS_CURRENT_180,"CONTENTS_CURRENT_180"},
{CONTENTS_CURRENT_270,"CONTENTS_CURRENT_270"},
{CONTENTS_CURRENT_UP,"CONTENTS_CURRENT_UP"},
{CONTENTS_CURRENT_DOWN,"CONTENTS_CURRENT_DOWN"},
{CONTENTS_ORIGIN,"CONTENTS_ORIGIN"},
{CONTENTS_MONSTER,"CONTENTS_MONSTER"},
{CONTENTS_DEADMONSTER,"CONTENTS_DEADMONSTER"},
{CONTENTS_DETAIL,"CONTENTS_DETAIL"},
{CONTENTS_TRANSLUCENT,"CONTENTS_TRANSLUCENT"},
{CONTENTS_LADDER,"CONTENTS_LADDER"},
{0, 0}
};
void PrintContents(int contents)
{
int i;
for (i = 0; contentnames[i].value; i++)
{
if (contents & contentnames[i].value)
{
botimport.Print(PRT_MESSAGE, "%s\n", contentnames[i].name);
} //end if
} //end for
} //end of the function PrintContents
#endif // BSP_DEBUG
//===========================================================================
// traces axial boxes of any size through the world
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
bsp_trace_t AAS_Trace(vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int passent, int contentmask)
{
bsp_trace_t bsptrace;
botimport.Trace(&bsptrace, start, mins, maxs, end, passent, contentmask);
return bsptrace;
} //end of the function AAS_Trace
//===========================================================================
// returns the contents at the given point
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_PointContents(vec3_t point)
{
return botimport.PointContents(point);
} //end of the function AAS_PointContents
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean AAS_EntityCollision(int entnum,
vec3_t start, vec3_t boxmins, vec3_t boxmaxs, vec3_t end,
int contentmask, bsp_trace_t *trace)
{
bsp_trace_t enttrace;
botimport.EntityTrace(&enttrace, start, boxmins, boxmaxs, end, entnum, contentmask);
if (enttrace.fraction < trace->fraction)
{
Com_Memcpy(trace, &enttrace, sizeof(bsp_trace_t));
return qtrue;
} //end if
return qfalse;
} //end of the function AAS_EntityCollision
//===========================================================================
// returns true if in Potentially Hearable Set
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean AAS_inPVS(vec3_t p1, vec3_t p2)
{
return botimport.inPVS(p1, p2);
} //end of the function AAS_InPVS
//===========================================================================
// returns true if in Potentially Visible Set
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean AAS_inPHS(vec3_t p1, vec3_t p2)
{
return qtrue;
} //end of the function AAS_inPHS
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_BSPModelMinsMaxsOrigin(int modelnum, vec3_t angles, vec3_t mins, vec3_t maxs, vec3_t origin)
{
botimport.BSPModelMinsMaxsOrigin(modelnum, angles, mins, maxs, origin);
} //end of the function AAS_BSPModelMinsMaxs
//===========================================================================
// unlinks the entity from all leaves
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_UnlinkFromBSPLeaves(bsp_link_t *leaves)
{
} //end of the function AAS_UnlinkFromBSPLeaves
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
bsp_link_t *AAS_BSPLinkEntity(vec3_t absmins, vec3_t absmaxs, int entnum, int modelnum)
{
return NULL;
} //end of the function AAS_BSPLinkEntity
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_BoxEntities(vec3_t absmins, vec3_t absmaxs, int *list, int maxcount)
{
return 0;
} //end of the function AAS_BoxEntities
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_NextBSPEntity(int ent)
{
ent++;
if (ent >= 1 && ent < bspworld.numentities) return ent;
return 0;
} //end of the function AAS_NextBSPEntity
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_BSPEntityInRange(int ent)
{
if (ent <= 0 || ent >= bspworld.numentities)
{
botimport.Print(PRT_MESSAGE, "bsp entity out of range\n");
return qfalse;
} //end if
return qtrue;
} //end of the function AAS_BSPEntityInRange
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_ValueForBSPEpairKey(int ent, char *key, char *value, int size)
{
bsp_epair_t *epair;
value[0] = '\0';
if (!AAS_BSPEntityInRange(ent)) return qfalse;
for (epair = bspworld.entities[ent].epairs; epair; epair = epair->next)
{
if (!strcmp(epair->key, key))
{
strncpy(value, epair->value, size-1);
value[size-1] = '\0';
return qtrue;
} //end if
} //end for
return qfalse;
} //end of the function AAS_FindBSPEpair
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_VectorForBSPEpairKey(int ent, char *key, vec3_t v)
{
char buf[MAX_EPAIRKEY];
double v1, v2, v3;
VectorClear(v);
if (!AAS_ValueForBSPEpairKey(ent, key, buf, MAX_EPAIRKEY)) return qfalse;
//scanf into doubles, then assign, so it is vec_t size independent
v1 = v2 = v3 = 0;
sscanf(buf, "%lf %lf %lf", &v1, &v2, &v3);
v[0] = v1;
v[1] = v2;
v[2] = v3;
return qtrue;
} //end of the function AAS_VectorForBSPEpairKey
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_FloatForBSPEpairKey(int ent, char *key, float *value)
{
char buf[MAX_EPAIRKEY];
*value = 0;
if (!AAS_ValueForBSPEpairKey(ent, key, buf, MAX_EPAIRKEY)) return qfalse;
*value = atof(buf);
return qtrue;
} //end of the function AAS_FloatForBSPEpairKey
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_IntForBSPEpairKey(int ent, char *key, int *value)
{
char buf[MAX_EPAIRKEY];
*value = 0;
if (!AAS_ValueForBSPEpairKey(ent, key, buf, MAX_EPAIRKEY)) return qfalse;
*value = atoi(buf);
return qtrue;
} //end of the function AAS_IntForBSPEpairKey
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_FreeBSPEntities(void)
{
int i;
bsp_entity_t *ent;
bsp_epair_t *epair, *nextepair;
for (i = 1; i < bspworld.numentities; i++)
{
ent = &bspworld.entities[i];
for (epair = ent->epairs; epair; epair = nextepair)
{
nextepair = epair->next;
//
if (epair->key) FreeMemory(epair->key);
if (epair->value) FreeMemory(epair->value);
FreeMemory(epair);
} //end for
} //end for
bspworld.numentities = 0;
} //end of the function AAS_FreeBSPEntities
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ParseBSPEntities(void)
{
script_t *script;
token_t token;
bsp_entity_t *ent;
bsp_epair_t *epair;
script = LoadScriptMemory(bspworld.dentdata, bspworld.entdatasize, "entdata");
SetScriptFlags(script, SCFL_NOSTRINGWHITESPACES|SCFL_NOSTRINGESCAPECHARS);//SCFL_PRIMITIVE);
bspworld.numentities = 1;
while(PS_ReadToken(script, &token))
{
if (strcmp(token.string, "{"))
{
ScriptError(script, "invalid %s\n", token.string);
AAS_FreeBSPEntities();
FreeScript(script);
return;
} //end if
if (bspworld.numentities >= MAX_BSPENTITIES)
{
botimport.Print(PRT_MESSAGE, "too many entities in BSP file\n");
break;
} //end if
ent = &bspworld.entities[bspworld.numentities];
bspworld.numentities++;
ent->epairs = NULL;
while(PS_ReadToken(script, &token))
{
if (!strcmp(token.string, "}")) break;
epair = (bsp_epair_t *) GetClearedHunkMemory(sizeof(bsp_epair_t));
epair->next = ent->epairs;
ent->epairs = epair;
if (token.type != TT_STRING)
{
ScriptError(script, "invalid %s\n", token.string);
AAS_FreeBSPEntities();
FreeScript(script);
return;
} //end if
StripDoubleQuotes(token.string);
epair->key = (char *) GetHunkMemory(strlen(token.string) + 1);
strcpy(epair->key, token.string);
if (!PS_ExpectTokenType(script, TT_STRING, 0, &token))
{
AAS_FreeBSPEntities();
FreeScript(script);
return;
} //end if
StripDoubleQuotes(token.string);
epair->value = (char *) GetHunkMemory(strlen(token.string) + 1);
strcpy(epair->value, token.string);
} //end while
if (strcmp(token.string, "}"))
{
ScriptError(script, "missing }\n");
AAS_FreeBSPEntities();
FreeScript(script);
return;
} //end if
} //end while
FreeScript(script);
} //end of the function AAS_ParseBSPEntities
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_BSPTraceLight(vec3_t start, vec3_t end, vec3_t endpos, int *red, int *green, int *blue)
{
return 0;
} //end of the function AAS_BSPTraceLight
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_DumpBSPData(void)
{
AAS_FreeBSPEntities();
if (bspworld.dentdata) FreeMemory(bspworld.dentdata);
bspworld.dentdata = NULL;
bspworld.entdatasize = 0;
//
bspworld.loaded = qfalse;
Com_Memset( &bspworld, 0, sizeof(bspworld) );
} //end of the function AAS_DumpBSPData
//===========================================================================
// load an bsp file
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_LoadBSPFile(void)
{
AAS_DumpBSPData();
bspworld.entdatasize = strlen(botimport.BSPEntityData()) + 1;
bspworld.dentdata = (char *) GetClearedHunkMemory(bspworld.entdatasize);
Com_Memcpy(bspworld.dentdata, botimport.BSPEntityData(), bspworld.entdatasize);
AAS_ParseBSPEntities();
bspworld.loaded = qtrue;
return BLERR_NOERROR;
} //end of the function AAS_LoadBSPFile

3090
code/botlib/be_aas_cluster.c Normal file → Executable file

File diff suppressed because it is too large Load diff

76
code/botlib/be_aas_cluster.h Normal file → Executable file
View file

@ -1,38 +1,38 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_cluster.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_cluster.h $
*
*****************************************************************************/
#ifdef AASINTERN
//initialize the AAS clustering
void AAS_InitClustering(void);
//
void AAS_SetViewPortalsAsClusterPortals(void);
#endif //AASINTERN
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_cluster.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_cluster.h $
*
*****************************************************************************/
#ifdef AASINTERN
//initialize the AAS clustering
void AAS_InitClustering(void);
//
void AAS_SetViewPortalsAsClusterPortals(void);
#endif //AASINTERN

1554
code/botlib/be_aas_debug.c Normal file → Executable file

File diff suppressed because it is too large Load diff

124
code/botlib/be_aas_debug.h Normal file → Executable file
View file

@ -1,62 +1,62 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_debug.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_debug.h $
*
*****************************************************************************/
//clear the shown debug lines
void AAS_ClearShownDebugLines(void);
//
void AAS_ClearShownPolygons(void);
//show a debug line
void AAS_DebugLine(vec3_t start, vec3_t end, int color);
//show a permenent line
void AAS_PermanentLine(vec3_t start, vec3_t end, int color);
//show a permanent cross
void AAS_DrawPermanentCross(vec3_t origin, float size, int color);
//draw a cross in the plane
void AAS_DrawPlaneCross(vec3_t point, vec3_t normal, float dist, int type, int color);
//show a bounding box
void AAS_ShowBoundingBox(vec3_t origin, vec3_t mins, vec3_t maxs);
//show a face
void AAS_ShowFace(int facenum);
//show an area
void AAS_ShowArea(int areanum, int groundfacesonly);
//
void AAS_ShowAreaPolygons(int areanum, int color, int groundfacesonly);
//draw a cros
void AAS_DrawCross(vec3_t origin, float size, int color);
//print the travel type
void AAS_PrintTravelType(int traveltype);
//draw an arrow
void AAS_DrawArrow(vec3_t start, vec3_t end, int linecolor, int arrowcolor);
//visualize the given reachability
void AAS_ShowReachability(struct aas_reachability_s *reach);
//show the reachable areas from the given area
void AAS_ShowReachableAreas(int areanum);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_debug.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_debug.h $
*
*****************************************************************************/
//clear the shown debug lines
void AAS_ClearShownDebugLines(void);
//
void AAS_ClearShownPolygons(void);
//show a debug line
void AAS_DebugLine(vec3_t start, vec3_t end, int color);
//show a permenent line
void AAS_PermanentLine(vec3_t start, vec3_t end, int color);
//show a permanent cross
void AAS_DrawPermanentCross(vec3_t origin, float size, int color);
//draw a cross in the plane
void AAS_DrawPlaneCross(vec3_t point, vec3_t normal, float dist, int type, int color);
//show a bounding box
void AAS_ShowBoundingBox(vec3_t origin, vec3_t mins, vec3_t maxs);
//show a face
void AAS_ShowFace(int facenum);
//show an area
void AAS_ShowArea(int areanum, int groundfacesonly);
//
void AAS_ShowAreaPolygons(int areanum, int color, int groundfacesonly);
//draw a cros
void AAS_DrawCross(vec3_t origin, float size, int color);
//print the travel type
void AAS_PrintTravelType(int traveltype);
//draw an arrow
void AAS_DrawArrow(vec3_t start, vec3_t end, int linecolor, int arrowcolor);
//visualize the given reachability
void AAS_ShowReachability(struct aas_reachability_s *reach);
//show the reachable areas from the given area
void AAS_ShowReachableAreas(int areanum);

612
code/botlib/be_aas_def.h Normal file → Executable file
View file

@ -1,306 +1,306 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_def.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_def.h $
*
*****************************************************************************/
//debugging on
#define AAS_DEBUG
#define MAX_CLIENTS 64
#define MAX_MODELS 256 // these are sent over the net as 8 bits
#define MAX_SOUNDS 256 // so they cannot be blindly increased
#define MAX_CONFIGSTRINGS 1024
#define CS_SCORES 32
#define CS_MODELS (CS_SCORES+MAX_CLIENTS)
#define CS_SOUNDS (CS_MODELS+MAX_MODELS)
#define DF_AASENTNUMBER(x) (x - aasworld.entities)
#define DF_NUMBERAASENT(x) (&aasworld.entities[x])
#define DF_AASENTCLIENT(x) (x - aasworld.entities - 1)
#define DF_CLIENTAASENT(x) (&aasworld.entities[x + 1])
#ifndef MAX_PATH
#define MAX_PATH MAX_QPATH
#endif
//string index (for model, sound and image index)
typedef struct aas_stringindex_s
{
int numindexes;
char **index;
} aas_stringindex_t;
//structure to link entities to areas and areas to entities
typedef struct aas_link_s
{
int entnum;
int areanum;
struct aas_link_s *next_ent, *prev_ent;
struct aas_link_s *next_area, *prev_area;
} aas_link_t;
//structure to link entities to leaves and leaves to entities
typedef struct bsp_link_s
{
int entnum;
int leafnum;
struct bsp_link_s *next_ent, *prev_ent;
struct bsp_link_s *next_leaf, *prev_leaf;
} bsp_link_t;
typedef struct bsp_entdata_s
{
vec3_t origin;
vec3_t angles;
vec3_t absmins;
vec3_t absmaxs;
int solid;
int modelnum;
} bsp_entdata_t;
//entity
typedef struct aas_entity_s
{
//entity info
aas_entityinfo_t i;
//links into the AAS areas
aas_link_t *areas;
//links into the BSP leaves
bsp_link_t *leaves;
} aas_entity_t;
typedef struct aas_settings_s
{
vec3_t phys_gravitydirection;
float phys_friction;
float phys_stopspeed;
float phys_gravity;
float phys_waterfriction;
float phys_watergravity;
float phys_maxvelocity;
float phys_maxwalkvelocity;
float phys_maxcrouchvelocity;
float phys_maxswimvelocity;
float phys_walkaccelerate;
float phys_airaccelerate;
float phys_swimaccelerate;
float phys_maxstep;
float phys_maxsteepness;
float phys_maxwaterjump;
float phys_maxbarrier;
float phys_jumpvel;
float phys_falldelta5;
float phys_falldelta10;
float rs_waterjump;
float rs_teleport;
float rs_barrierjump;
float rs_startcrouch;
float rs_startgrapple;
float rs_startwalkoffledge;
float rs_startjump;
float rs_rocketjump;
float rs_bfgjump;
float rs_jumppad;
float rs_aircontrolledjumppad;
float rs_funcbob;
float rs_startelevator;
float rs_falldamage5;
float rs_falldamage10;
float rs_maxfallheight;
float rs_maxjumpfallheight;
} aas_settings_t;
#define CACHETYPE_PORTAL 0
#define CACHETYPE_AREA 1
//routing cache
typedef struct aas_routingcache_s
{
byte type; //portal or area cache
float time; //last time accessed or updated
int size; //size of the routing cache
int cluster; //cluster the cache is for
int areanum; //area the cache is created for
vec3_t origin; //origin within the area
float starttraveltime; //travel time to start with
int travelflags; //combinations of the travel flags
struct aas_routingcache_s *prev, *next;
struct aas_routingcache_s *time_prev, *time_next;
unsigned char *reachabilities; //reachabilities used for routing
unsigned short int traveltimes[1]; //travel time for every area (variable sized)
} aas_routingcache_t;
//fields for the routing algorithm
typedef struct aas_routingupdate_s
{
int cluster;
int areanum; //area number of the update
vec3_t start; //start point the area was entered
unsigned short int tmptraveltime; //temporary travel time
unsigned short int *areatraveltimes; //travel times within the area
qboolean inlist; //true if the update is in the list
struct aas_routingupdate_s *next;
struct aas_routingupdate_s *prev;
} aas_routingupdate_t;
//reversed reachability link
typedef struct aas_reversedlink_s
{
int linknum; //the aas_areareachability_t
int areanum; //reachable from this area
struct aas_reversedlink_s *next; //next link
} aas_reversedlink_t;
//reversed area reachability
typedef struct aas_reversedreachability_s
{
int numlinks;
aas_reversedlink_t *first;
} aas_reversedreachability_t;
//areas a reachability goes through
typedef struct aas_reachabilityareas_s
{
int firstarea, numareas;
} aas_reachabilityareas_t;
typedef struct aas_s
{
int loaded; //true when an AAS file is loaded
int initialized; //true when AAS has been initialized
int savefile; //set true when file should be saved
int bspchecksum;
//current time
float time;
int numframes;
//name of the aas file
char filename[MAX_PATH];
char mapname[MAX_PATH];
//bounding boxes
int numbboxes;
aas_bbox_t *bboxes;
//vertexes
int numvertexes;
aas_vertex_t *vertexes;
//planes
int numplanes;
aas_plane_t *planes;
//edges
int numedges;
aas_edge_t *edges;
//edge index
int edgeindexsize;
aas_edgeindex_t *edgeindex;
//faces
int numfaces;
aas_face_t *faces;
//face index
int faceindexsize;
aas_faceindex_t *faceindex;
//convex areas
int numareas;
aas_area_t *areas;
//convex area settings
int numareasettings;
aas_areasettings_t *areasettings;
//reachablity list
int reachabilitysize;
aas_reachability_t *reachability;
//nodes of the bsp tree
int numnodes;
aas_node_t *nodes;
//cluster portals
int numportals;
aas_portal_t *portals;
//cluster portal index
int portalindexsize;
aas_portalindex_t *portalindex;
//clusters
int numclusters;
aas_cluster_t *clusters;
//
int numreachabilityareas;
float reachabilitytime;
//enities linked in the areas
aas_link_t *linkheap; //heap with link structures
int linkheapsize; //size of the link heap
aas_link_t *freelinks; //first free link
aas_link_t **arealinkedentities; //entities linked into areas
//entities
int maxentities;
int maxclients;
aas_entity_t *entities;
//string indexes
char *configstrings[MAX_CONFIGSTRINGS];
int indexessetup;
//index to retrieve travel flag for a travel type
int travelflagfortype[MAX_TRAVELTYPES];
//travel flags for each area based on contents
int *areacontentstravelflags;
//routing update
aas_routingupdate_t *areaupdate;
aas_routingupdate_t *portalupdate;
//number of routing updates during a frame (reset every frame)
int frameroutingupdates;
//reversed reachability links
aas_reversedreachability_t *reversedreachability;
//travel times within the areas
unsigned short ***areatraveltimes;
//array of size numclusters with cluster cache
aas_routingcache_t ***clusterareacache;
aas_routingcache_t **portalcache;
//cache list sorted on time
aas_routingcache_t *oldestcache; // start of cache list sorted on time
aas_routingcache_t *newestcache; // end of cache list sorted on time
//maximum travel time through portal areas
int *portalmaxtraveltimes;
//areas the reachabilities go through
int *reachabilityareaindex;
aas_reachabilityareas_t *reachabilityareas;
} aas_t;
#define AASINTERN
#ifndef BSPCINCLUDE
#include "be_aas_main.h"
#include "be_aas_entity.h"
#include "be_aas_sample.h"
#include "be_aas_cluster.h"
#include "be_aas_reach.h"
#include "be_aas_route.h"
#include "be_aas_routealt.h"
#include "be_aas_debug.h"
#include "be_aas_file.h"
#include "be_aas_optimize.h"
#include "be_aas_bsp.h"
#include "be_aas_move.h"
#endif //BSPCINCLUDE
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_def.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_def.h $
*
*****************************************************************************/
//debugging on
#define AAS_DEBUG
#define MAX_CLIENTS 64
#define MAX_MODELS 256 // these are sent over the net as 8 bits
#define MAX_SOUNDS 256 // so they cannot be blindly increased
#define MAX_CONFIGSTRINGS 1024
#define CS_SCORES 32
#define CS_MODELS (CS_SCORES+MAX_CLIENTS)
#define CS_SOUNDS (CS_MODELS+MAX_MODELS)
#define DF_AASENTNUMBER(x) (x - aasworld.entities)
#define DF_NUMBERAASENT(x) (&aasworld.entities[x])
#define DF_AASENTCLIENT(x) (x - aasworld.entities - 1)
#define DF_CLIENTAASENT(x) (&aasworld.entities[x + 1])
#ifndef MAX_PATH
#define MAX_PATH MAX_QPATH
#endif
//string index (for model, sound and image index)
typedef struct aas_stringindex_s
{
int numindexes;
char **index;
} aas_stringindex_t;
//structure to link entities to areas and areas to entities
typedef struct aas_link_s
{
int entnum;
int areanum;
struct aas_link_s *next_ent, *prev_ent;
struct aas_link_s *next_area, *prev_area;
} aas_link_t;
//structure to link entities to leaves and leaves to entities
typedef struct bsp_link_s
{
int entnum;
int leafnum;
struct bsp_link_s *next_ent, *prev_ent;
struct bsp_link_s *next_leaf, *prev_leaf;
} bsp_link_t;
typedef struct bsp_entdata_s
{
vec3_t origin;
vec3_t angles;
vec3_t absmins;
vec3_t absmaxs;
int solid;
int modelnum;
} bsp_entdata_t;
//entity
typedef struct aas_entity_s
{
//entity info
aas_entityinfo_t i;
//links into the AAS areas
aas_link_t *areas;
//links into the BSP leaves
bsp_link_t *leaves;
} aas_entity_t;
typedef struct aas_settings_s
{
vec3_t phys_gravitydirection;
float phys_friction;
float phys_stopspeed;
float phys_gravity;
float phys_waterfriction;
float phys_watergravity;
float phys_maxvelocity;
float phys_maxwalkvelocity;
float phys_maxcrouchvelocity;
float phys_maxswimvelocity;
float phys_walkaccelerate;
float phys_airaccelerate;
float phys_swimaccelerate;
float phys_maxstep;
float phys_maxsteepness;
float phys_maxwaterjump;
float phys_maxbarrier;
float phys_jumpvel;
float phys_falldelta5;
float phys_falldelta10;
float rs_waterjump;
float rs_teleport;
float rs_barrierjump;
float rs_startcrouch;
float rs_startgrapple;
float rs_startwalkoffledge;
float rs_startjump;
float rs_rocketjump;
float rs_bfgjump;
float rs_jumppad;
float rs_aircontrolledjumppad;
float rs_funcbob;
float rs_startelevator;
float rs_falldamage5;
float rs_falldamage10;
float rs_maxfallheight;
float rs_maxjumpfallheight;
} aas_settings_t;
#define CACHETYPE_PORTAL 0
#define CACHETYPE_AREA 1
//routing cache
typedef struct aas_routingcache_s
{
byte type; //portal or area cache
float time; //last time accessed or updated
int size; //size of the routing cache
int cluster; //cluster the cache is for
int areanum; //area the cache is created for
vec3_t origin; //origin within the area
float starttraveltime; //travel time to start with
int travelflags; //combinations of the travel flags
struct aas_routingcache_s *prev, *next;
struct aas_routingcache_s *time_prev, *time_next;
unsigned char *reachabilities; //reachabilities used for routing
unsigned short int traveltimes[1]; //travel time for every area (variable sized)
} aas_routingcache_t;
//fields for the routing algorithm
typedef struct aas_routingupdate_s
{
int cluster;
int areanum; //area number of the update
vec3_t start; //start point the area was entered
unsigned short int tmptraveltime; //temporary travel time
unsigned short int *areatraveltimes; //travel times within the area
qboolean inlist; //true if the update is in the list
struct aas_routingupdate_s *next;
struct aas_routingupdate_s *prev;
} aas_routingupdate_t;
//reversed reachability link
typedef struct aas_reversedlink_s
{
int linknum; //the aas_areareachability_t
int areanum; //reachable from this area
struct aas_reversedlink_s *next; //next link
} aas_reversedlink_t;
//reversed area reachability
typedef struct aas_reversedreachability_s
{
int numlinks;
aas_reversedlink_t *first;
} aas_reversedreachability_t;
//areas a reachability goes through
typedef struct aas_reachabilityareas_s
{
int firstarea, numareas;
} aas_reachabilityareas_t;
typedef struct aas_s
{
int loaded; //true when an AAS file is loaded
int initialized; //true when AAS has been initialized
int savefile; //set true when file should be saved
int bspchecksum;
//current time
float time;
int numframes;
//name of the aas file
char filename[MAX_PATH];
char mapname[MAX_PATH];
//bounding boxes
int numbboxes;
aas_bbox_t *bboxes;
//vertexes
int numvertexes;
aas_vertex_t *vertexes;
//planes
int numplanes;
aas_plane_t *planes;
//edges
int numedges;
aas_edge_t *edges;
//edge index
int edgeindexsize;
aas_edgeindex_t *edgeindex;
//faces
int numfaces;
aas_face_t *faces;
//face index
int faceindexsize;
aas_faceindex_t *faceindex;
//convex areas
int numareas;
aas_area_t *areas;
//convex area settings
int numareasettings;
aas_areasettings_t *areasettings;
//reachablity list
int reachabilitysize;
aas_reachability_t *reachability;
//nodes of the bsp tree
int numnodes;
aas_node_t *nodes;
//cluster portals
int numportals;
aas_portal_t *portals;
//cluster portal index
int portalindexsize;
aas_portalindex_t *portalindex;
//clusters
int numclusters;
aas_cluster_t *clusters;
//
int numreachabilityareas;
float reachabilitytime;
//enities linked in the areas
aas_link_t *linkheap; //heap with link structures
int linkheapsize; //size of the link heap
aas_link_t *freelinks; //first free link
aas_link_t **arealinkedentities; //entities linked into areas
//entities
int maxentities;
int maxclients;
aas_entity_t *entities;
//string indexes
char *configstrings[MAX_CONFIGSTRINGS];
int indexessetup;
//index to retrieve travel flag for a travel type
int travelflagfortype[MAX_TRAVELTYPES];
//travel flags for each area based on contents
int *areacontentstravelflags;
//routing update
aas_routingupdate_t *areaupdate;
aas_routingupdate_t *portalupdate;
//number of routing updates during a frame (reset every frame)
int frameroutingupdates;
//reversed reachability links
aas_reversedreachability_t *reversedreachability;
//travel times within the areas
unsigned short ***areatraveltimes;
//array of size numclusters with cluster cache
aas_routingcache_t ***clusterareacache;
aas_routingcache_t **portalcache;
//cache list sorted on time
aas_routingcache_t *oldestcache; // start of cache list sorted on time
aas_routingcache_t *newestcache; // end of cache list sorted on time
//maximum travel time through portal areas
int *portalmaxtraveltimes;
//areas the reachabilities go through
int *reachabilityareaindex;
aas_reachabilityareas_t *reachabilityareas;
} aas_t;
#define AASINTERN
#ifndef BSPCINCLUDE
#include "be_aas_main.h"
#include "be_aas_entity.h"
#include "be_aas_sample.h"
#include "be_aas_cluster.h"
#include "be_aas_reach.h"
#include "be_aas_route.h"
#include "be_aas_routealt.h"
#include "be_aas_debug.h"
#include "be_aas_file.h"
#include "be_aas_optimize.h"
#include "be_aas_bsp.h"
#include "be_aas_move.h"
#endif //BSPCINCLUDE

874
code/botlib/be_aas_entity.c Normal file → Executable file
View file

@ -1,437 +1,437 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_entity.c
*
* desc: AAS entities
*
* $Archive: /MissionPack/code/botlib/be_aas_entity.c $
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_memory.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "l_utils.h"
#include "l_log.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_interface.h"
#include "be_aas_def.h"
#define MASK_SOLID CONTENTS_PLAYERCLIP
//FIXME: these might change
enum {
ET_GENERAL,
ET_PLAYER,
ET_ITEM,
ET_MISSILE,
ET_MOVER
};
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_UpdateEntity(int entnum, bot_entitystate_t *state)
{
int relink;
aas_entity_t *ent;
vec3_t absmins, absmaxs;
if (!aasworld.loaded)
{
botimport.Print(PRT_MESSAGE, "AAS_UpdateEntity: not loaded\n");
return BLERR_NOAASFILE;
} //end if
ent = &aasworld.entities[entnum];
if (!state) {
//unlink the entity
AAS_UnlinkFromAreas(ent->areas);
//unlink the entity from the BSP leaves
AAS_UnlinkFromBSPLeaves(ent->leaves);
//
ent->areas = NULL;
//
ent->leaves = NULL;
return BLERR_NOERROR;
}
ent->i.update_time = AAS_Time() - ent->i.ltime;
ent->i.type = state->type;
ent->i.flags = state->flags;
ent->i.ltime = AAS_Time();
VectorCopy(ent->i.origin, ent->i.lastvisorigin);
VectorCopy(state->old_origin, ent->i.old_origin);
ent->i.solid = state->solid;
ent->i.groundent = state->groundent;
ent->i.modelindex = state->modelindex;
ent->i.modelindex2 = state->modelindex2;
ent->i.frame = state->frame;
ent->i.event = state->event;
ent->i.eventParm = state->eventParm;
ent->i.powerups = state->powerups;
ent->i.weapon = state->weapon;
ent->i.legsAnim = state->legsAnim;
ent->i.torsoAnim = state->torsoAnim;
//number of the entity
ent->i.number = entnum;
//updated so set valid flag
ent->i.valid = qtrue;
//link everything the first frame
if (aasworld.numframes == 1) relink = qtrue;
else relink = qfalse;
//
if (ent->i.solid == SOLID_BSP)
{
//if the angles of the model changed
if (!VectorCompare(state->angles, ent->i.angles))
{
VectorCopy(state->angles, ent->i.angles);
relink = qtrue;
} //end if
//get the mins and maxs of the model
//FIXME: rotate mins and maxs
AAS_BSPModelMinsMaxsOrigin(ent->i.modelindex, ent->i.angles, ent->i.mins, ent->i.maxs, NULL);
} //end if
else if (ent->i.solid == SOLID_BBOX)
{
//if the bounding box size changed
if (!VectorCompare(state->mins, ent->i.mins) ||
!VectorCompare(state->maxs, ent->i.maxs))
{
VectorCopy(state->mins, ent->i.mins);
VectorCopy(state->maxs, ent->i.maxs);
relink = qtrue;
} //end if
VectorCopy(state->angles, ent->i.angles);
} //end if
//if the origin changed
if (!VectorCompare(state->origin, ent->i.origin))
{
VectorCopy(state->origin, ent->i.origin);
relink = qtrue;
} //end if
//if the entity should be relinked
if (relink)
{
//don't link the world model
if (entnum != ENTITYNUM_WORLD)
{
//absolute mins and maxs
VectorAdd(ent->i.mins, ent->i.origin, absmins);
VectorAdd(ent->i.maxs, ent->i.origin, absmaxs);
//unlink the entity
AAS_UnlinkFromAreas(ent->areas);
//relink the entity to the AAS areas (use the larges bbox)
ent->areas = AAS_LinkEntityClientBBox(absmins, absmaxs, entnum, PRESENCE_NORMAL);
//unlink the entity from the BSP leaves
AAS_UnlinkFromBSPLeaves(ent->leaves);
//link the entity to the world BSP tree
ent->leaves = AAS_BSPLinkEntity(absmins, absmaxs, entnum, 0);
} //end if
} //end if
return BLERR_NOERROR;
} //end of the function AAS_UpdateEntity
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_EntityInfo(int entnum, aas_entityinfo_t *info)
{
if (!aasworld.initialized)
{
botimport.Print(PRT_FATAL, "AAS_EntityInfo: aasworld not initialized\n");
Com_Memset(info, 0, sizeof(aas_entityinfo_t));
return;
} //end if
if (entnum < 0 || entnum >= aasworld.maxentities)
{
botimport.Print(PRT_FATAL, "AAS_EntityInfo: entnum %d out of range\n", entnum);
Com_Memset(info, 0, sizeof(aas_entityinfo_t));
return;
} //end if
Com_Memcpy(info, &aasworld.entities[entnum].i, sizeof(aas_entityinfo_t));
} //end of the function AAS_EntityInfo
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_EntityOrigin(int entnum, vec3_t origin)
{
if (entnum < 0 || entnum >= aasworld.maxentities)
{
botimport.Print(PRT_FATAL, "AAS_EntityOrigin: entnum %d out of range\n", entnum);
VectorClear(origin);
return;
} //end if
VectorCopy(aasworld.entities[entnum].i.origin, origin);
} //end of the function AAS_EntityOrigin
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_EntityModelindex(int entnum)
{
if (entnum < 0 || entnum >= aasworld.maxentities)
{
botimport.Print(PRT_FATAL, "AAS_EntityModelindex: entnum %d out of range\n", entnum);
return 0;
} //end if
return aasworld.entities[entnum].i.modelindex;
} //end of the function AAS_EntityModelindex
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_EntityType(int entnum)
{
if (!aasworld.initialized) return 0;
if (entnum < 0 || entnum >= aasworld.maxentities)
{
botimport.Print(PRT_FATAL, "AAS_EntityType: entnum %d out of range\n", entnum);
return 0;
} //end if
return aasworld.entities[entnum].i.type;
} //end of the AAS_EntityType
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_EntityModelNum(int entnum)
{
if (!aasworld.initialized) return 0;
if (entnum < 0 || entnum >= aasworld.maxentities)
{
botimport.Print(PRT_FATAL, "AAS_EntityModelNum: entnum %d out of range\n", entnum);
return 0;
} //end if
return aasworld.entities[entnum].i.modelindex;
} //end of the function AAS_EntityModelNum
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_OriginOfMoverWithModelNum(int modelnum, vec3_t origin)
{
int i;
aas_entity_t *ent;
for (i = 0; i < aasworld.maxentities; i++)
{
ent = &aasworld.entities[i];
if (ent->i.type == ET_MOVER)
{
if (ent->i.modelindex == modelnum)
{
VectorCopy(ent->i.origin, origin);
return qtrue;
} //end if
} //end if
} //end for
return qfalse;
} //end of the function AAS_OriginOfMoverWithModelNum
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_EntitySize(int entnum, vec3_t mins, vec3_t maxs)
{
aas_entity_t *ent;
if (!aasworld.initialized) return;
if (entnum < 0 || entnum >= aasworld.maxentities)
{
botimport.Print(PRT_FATAL, "AAS_EntitySize: entnum %d out of range\n", entnum);
return;
} //end if
ent = &aasworld.entities[entnum];
VectorCopy(ent->i.mins, mins);
VectorCopy(ent->i.maxs, maxs);
} //end of the function AAS_EntitySize
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_EntityBSPData(int entnum, bsp_entdata_t *entdata)
{
aas_entity_t *ent;
ent = &aasworld.entities[entnum];
VectorCopy(ent->i.origin, entdata->origin);
VectorCopy(ent->i.angles, entdata->angles);
VectorAdd(ent->i.origin, ent->i.mins, entdata->absmins);
VectorAdd(ent->i.origin, ent->i.maxs, entdata->absmaxs);
entdata->solid = ent->i.solid;
entdata->modelnum = ent->i.modelindex - 1;
} //end of the function AAS_EntityBSPData
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ResetEntityLinks(void)
{
int i;
for (i = 0; i < aasworld.maxentities; i++)
{
aasworld.entities[i].areas = NULL;
aasworld.entities[i].leaves = NULL;
} //end for
} //end of the function AAS_ResetEntityLinks
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_InvalidateEntities(void)
{
int i;
for (i = 0; i < aasworld.maxentities; i++)
{
aasworld.entities[i].i.valid = qfalse;
aasworld.entities[i].i.number = i;
} //end for
} //end of the function AAS_InvalidateEntities
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_UnlinkInvalidEntities(void)
{
int i;
aas_entity_t *ent;
for (i = 0; i < aasworld.maxentities; i++)
{
ent = &aasworld.entities[i];
if (!ent->i.valid)
{
AAS_UnlinkFromAreas( ent->areas );
ent->areas = NULL;
AAS_UnlinkFromBSPLeaves( ent->leaves );
ent->leaves = NULL;
} //end for
} //end for
} //end of the function AAS_UnlinkInvalidEntities
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_NearestEntity(vec3_t origin, int modelindex)
{
int i, bestentnum;
float dist, bestdist;
aas_entity_t *ent;
vec3_t dir;
bestentnum = 0;
bestdist = 99999;
for (i = 0; i < aasworld.maxentities; i++)
{
ent = &aasworld.entities[i];
if (ent->i.modelindex != modelindex) continue;
VectorSubtract(ent->i.origin, origin, dir);
if (abs(dir[0]) < 40)
{
if (abs(dir[1]) < 40)
{
dist = VectorLength(dir);
if (dist < bestdist)
{
bestdist = dist;
bestentnum = i;
} //end if
} //end if
} //end if
} //end for
return bestentnum;
} //end of the function AAS_NearestEntity
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_BestReachableEntityArea(int entnum)
{
aas_entity_t *ent;
ent = &aasworld.entities[entnum];
return AAS_BestReachableLinkArea(ent->areas);
} //end of the function AAS_BestReachableEntityArea
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_NextEntity(int entnum)
{
if (!aasworld.loaded) return 0;
if (entnum < 0) entnum = -1;
while(++entnum < aasworld.maxentities)
{
if (aasworld.entities[entnum].i.valid) return entnum;
} //end while
return 0;
} //end of the function AAS_NextEntity
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_entity.c
*
* desc: AAS entities
*
* $Archive: /MissionPack/code/botlib/be_aas_entity.c $
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_memory.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "l_utils.h"
#include "l_log.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_interface.h"
#include "be_aas_def.h"
#define MASK_SOLID CONTENTS_PLAYERCLIP
//FIXME: these might change
enum {
ET_GENERAL,
ET_PLAYER,
ET_ITEM,
ET_MISSILE,
ET_MOVER
};
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_UpdateEntity(int entnum, bot_entitystate_t *state)
{
int relink;
aas_entity_t *ent;
vec3_t absmins, absmaxs;
if (!aasworld.loaded)
{
botimport.Print(PRT_MESSAGE, "AAS_UpdateEntity: not loaded\n");
return BLERR_NOAASFILE;
} //end if
ent = &aasworld.entities[entnum];
if (!state) {
//unlink the entity
AAS_UnlinkFromAreas(ent->areas);
//unlink the entity from the BSP leaves
AAS_UnlinkFromBSPLeaves(ent->leaves);
//
ent->areas = NULL;
//
ent->leaves = NULL;
return BLERR_NOERROR;
}
ent->i.update_time = AAS_Time() - ent->i.ltime;
ent->i.type = state->type;
ent->i.flags = state->flags;
ent->i.ltime = AAS_Time();
VectorCopy(ent->i.origin, ent->i.lastvisorigin);
VectorCopy(state->old_origin, ent->i.old_origin);
ent->i.solid = state->solid;
ent->i.groundent = state->groundent;
ent->i.modelindex = state->modelindex;
ent->i.modelindex2 = state->modelindex2;
ent->i.frame = state->frame;
ent->i.event = state->event;
ent->i.eventParm = state->eventParm;
ent->i.powerups = state->powerups;
ent->i.weapon = state->weapon;
ent->i.legsAnim = state->legsAnim;
ent->i.torsoAnim = state->torsoAnim;
//number of the entity
ent->i.number = entnum;
//updated so set valid flag
ent->i.valid = qtrue;
//link everything the first frame
if (aasworld.numframes == 1) relink = qtrue;
else relink = qfalse;
//
if (ent->i.solid == SOLID_BSP)
{
//if the angles of the model changed
if (!VectorCompare(state->angles, ent->i.angles))
{
VectorCopy(state->angles, ent->i.angles);
relink = qtrue;
} //end if
//get the mins and maxs of the model
//FIXME: rotate mins and maxs
AAS_BSPModelMinsMaxsOrigin(ent->i.modelindex, ent->i.angles, ent->i.mins, ent->i.maxs, NULL);
} //end if
else if (ent->i.solid == SOLID_BBOX)
{
//if the bounding box size changed
if (!VectorCompare(state->mins, ent->i.mins) ||
!VectorCompare(state->maxs, ent->i.maxs))
{
VectorCopy(state->mins, ent->i.mins);
VectorCopy(state->maxs, ent->i.maxs);
relink = qtrue;
} //end if
VectorCopy(state->angles, ent->i.angles);
} //end if
//if the origin changed
if (!VectorCompare(state->origin, ent->i.origin))
{
VectorCopy(state->origin, ent->i.origin);
relink = qtrue;
} //end if
//if the entity should be relinked
if (relink)
{
//don't link the world model
if (entnum != ENTITYNUM_WORLD)
{
//absolute mins and maxs
VectorAdd(ent->i.mins, ent->i.origin, absmins);
VectorAdd(ent->i.maxs, ent->i.origin, absmaxs);
//unlink the entity
AAS_UnlinkFromAreas(ent->areas);
//relink the entity to the AAS areas (use the larges bbox)
ent->areas = AAS_LinkEntityClientBBox(absmins, absmaxs, entnum, PRESENCE_NORMAL);
//unlink the entity from the BSP leaves
AAS_UnlinkFromBSPLeaves(ent->leaves);
//link the entity to the world BSP tree
ent->leaves = AAS_BSPLinkEntity(absmins, absmaxs, entnum, 0);
} //end if
} //end if
return BLERR_NOERROR;
} //end of the function AAS_UpdateEntity
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_EntityInfo(int entnum, aas_entityinfo_t *info)
{
if (!aasworld.initialized)
{
botimport.Print(PRT_FATAL, "AAS_EntityInfo: aasworld not initialized\n");
Com_Memset(info, 0, sizeof(aas_entityinfo_t));
return;
} //end if
if (entnum < 0 || entnum >= aasworld.maxentities)
{
botimport.Print(PRT_FATAL, "AAS_EntityInfo: entnum %d out of range\n", entnum);
Com_Memset(info, 0, sizeof(aas_entityinfo_t));
return;
} //end if
Com_Memcpy(info, &aasworld.entities[entnum].i, sizeof(aas_entityinfo_t));
} //end of the function AAS_EntityInfo
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_EntityOrigin(int entnum, vec3_t origin)
{
if (entnum < 0 || entnum >= aasworld.maxentities)
{
botimport.Print(PRT_FATAL, "AAS_EntityOrigin: entnum %d out of range\n", entnum);
VectorClear(origin);
return;
} //end if
VectorCopy(aasworld.entities[entnum].i.origin, origin);
} //end of the function AAS_EntityOrigin
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_EntityModelindex(int entnum)
{
if (entnum < 0 || entnum >= aasworld.maxentities)
{
botimport.Print(PRT_FATAL, "AAS_EntityModelindex: entnum %d out of range\n", entnum);
return 0;
} //end if
return aasworld.entities[entnum].i.modelindex;
} //end of the function AAS_EntityModelindex
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_EntityType(int entnum)
{
if (!aasworld.initialized) return 0;
if (entnum < 0 || entnum >= aasworld.maxentities)
{
botimport.Print(PRT_FATAL, "AAS_EntityType: entnum %d out of range\n", entnum);
return 0;
} //end if
return aasworld.entities[entnum].i.type;
} //end of the AAS_EntityType
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_EntityModelNum(int entnum)
{
if (!aasworld.initialized) return 0;
if (entnum < 0 || entnum >= aasworld.maxentities)
{
botimport.Print(PRT_FATAL, "AAS_EntityModelNum: entnum %d out of range\n", entnum);
return 0;
} //end if
return aasworld.entities[entnum].i.modelindex;
} //end of the function AAS_EntityModelNum
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_OriginOfMoverWithModelNum(int modelnum, vec3_t origin)
{
int i;
aas_entity_t *ent;
for (i = 0; i < aasworld.maxentities; i++)
{
ent = &aasworld.entities[i];
if (ent->i.type == ET_MOVER)
{
if (ent->i.modelindex == modelnum)
{
VectorCopy(ent->i.origin, origin);
return qtrue;
} //end if
} //end if
} //end for
return qfalse;
} //end of the function AAS_OriginOfMoverWithModelNum
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_EntitySize(int entnum, vec3_t mins, vec3_t maxs)
{
aas_entity_t *ent;
if (!aasworld.initialized) return;
if (entnum < 0 || entnum >= aasworld.maxentities)
{
botimport.Print(PRT_FATAL, "AAS_EntitySize: entnum %d out of range\n", entnum);
return;
} //end if
ent = &aasworld.entities[entnum];
VectorCopy(ent->i.mins, mins);
VectorCopy(ent->i.maxs, maxs);
} //end of the function AAS_EntitySize
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_EntityBSPData(int entnum, bsp_entdata_t *entdata)
{
aas_entity_t *ent;
ent = &aasworld.entities[entnum];
VectorCopy(ent->i.origin, entdata->origin);
VectorCopy(ent->i.angles, entdata->angles);
VectorAdd(ent->i.origin, ent->i.mins, entdata->absmins);
VectorAdd(ent->i.origin, ent->i.maxs, entdata->absmaxs);
entdata->solid = ent->i.solid;
entdata->modelnum = ent->i.modelindex - 1;
} //end of the function AAS_EntityBSPData
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ResetEntityLinks(void)
{
int i;
for (i = 0; i < aasworld.maxentities; i++)
{
aasworld.entities[i].areas = NULL;
aasworld.entities[i].leaves = NULL;
} //end for
} //end of the function AAS_ResetEntityLinks
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_InvalidateEntities(void)
{
int i;
for (i = 0; i < aasworld.maxentities; i++)
{
aasworld.entities[i].i.valid = qfalse;
aasworld.entities[i].i.number = i;
} //end for
} //end of the function AAS_InvalidateEntities
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_UnlinkInvalidEntities(void)
{
int i;
aas_entity_t *ent;
for (i = 0; i < aasworld.maxentities; i++)
{
ent = &aasworld.entities[i];
if (!ent->i.valid)
{
AAS_UnlinkFromAreas( ent->areas );
ent->areas = NULL;
AAS_UnlinkFromBSPLeaves( ent->leaves );
ent->leaves = NULL;
} //end for
} //end for
} //end of the function AAS_UnlinkInvalidEntities
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_NearestEntity(vec3_t origin, int modelindex)
{
int i, bestentnum;
float dist, bestdist;
aas_entity_t *ent;
vec3_t dir;
bestentnum = 0;
bestdist = 99999;
for (i = 0; i < aasworld.maxentities; i++)
{
ent = &aasworld.entities[i];
if (ent->i.modelindex != modelindex) continue;
VectorSubtract(ent->i.origin, origin, dir);
if (abs(dir[0]) < 40)
{
if (abs(dir[1]) < 40)
{
dist = VectorLength(dir);
if (dist < bestdist)
{
bestdist = dist;
bestentnum = i;
} //end if
} //end if
} //end if
} //end for
return bestentnum;
} //end of the function AAS_NearestEntity
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_BestReachableEntityArea(int entnum)
{
aas_entity_t *ent;
ent = &aasworld.entities[entnum];
return AAS_BestReachableLinkArea(ent->areas);
} //end of the function AAS_BestReachableEntityArea
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_NextEntity(int entnum)
{
if (!aasworld.loaded) return 0;
if (entnum < 0) entnum = -1;
while(++entnum < aasworld.maxentities)
{
if (aasworld.entities[entnum].i.valid) return entnum;
} //end while
return 0;
} //end of the function AAS_NextEntity

126
code/botlib/be_aas_entity.h Normal file → Executable file
View file

@ -1,63 +1,63 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_entity.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_entity.h $
*
*****************************************************************************/
#ifdef AASINTERN
//invalidates all entity infos
void AAS_InvalidateEntities(void);
//unlink not updated entities
void AAS_UnlinkInvalidEntities(void);
//resets the entity AAS and BSP links (sets areas and leaves pointers to NULL)
void AAS_ResetEntityLinks(void);
//updates an entity
int AAS_UpdateEntity(int ent, bot_entitystate_t *state);
//gives the entity data used for collision detection
void AAS_EntityBSPData(int entnum, bsp_entdata_t *entdata);
#endif //AASINTERN
//returns the size of the entity bounding box in mins and maxs
void AAS_EntitySize(int entnum, vec3_t mins, vec3_t maxs);
//returns the BSP model number of the entity
int AAS_EntityModelNum(int entnum);
//returns the origin of an entity with the given model number
int AAS_OriginOfMoverWithModelNum(int modelnum, vec3_t origin);
//returns the best reachable area the entity is situated in
int AAS_BestReachableEntityArea(int entnum);
//returns the info of the given entity
void AAS_EntityInfo(int entnum, aas_entityinfo_t *info);
//returns the next entity
int AAS_NextEntity(int entnum);
//returns the origin of the entity
void AAS_EntityOrigin(int entnum, vec3_t origin);
//returns the entity type
int AAS_EntityType(int entnum);
//returns the model index of the entity
int AAS_EntityModelindex(int entnum);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_entity.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_entity.h $
*
*****************************************************************************/
#ifdef AASINTERN
//invalidates all entity infos
void AAS_InvalidateEntities(void);
//unlink not updated entities
void AAS_UnlinkInvalidEntities(void);
//resets the entity AAS and BSP links (sets areas and leaves pointers to NULL)
void AAS_ResetEntityLinks(void);
//updates an entity
int AAS_UpdateEntity(int ent, bot_entitystate_t *state);
//gives the entity data used for collision detection
void AAS_EntityBSPData(int entnum, bsp_entdata_t *entdata);
#endif //AASINTERN
//returns the size of the entity bounding box in mins and maxs
void AAS_EntitySize(int entnum, vec3_t mins, vec3_t maxs);
//returns the BSP model number of the entity
int AAS_EntityModelNum(int entnum);
//returns the origin of an entity with the given model number
int AAS_OriginOfMoverWithModelNum(int modelnum, vec3_t origin);
//returns the best reachable area the entity is situated in
int AAS_BestReachableEntityArea(int entnum);
//returns the info of the given entity
void AAS_EntityInfo(int entnum, aas_entityinfo_t *info);
//returns the next entity
int AAS_NextEntity(int entnum);
//returns the origin of the entity
void AAS_EntityOrigin(int entnum, vec3_t origin);
//returns the entity type
int AAS_EntityType(int entnum);
//returns the model index of the entity
int AAS_EntityModelindex(int entnum);

1164
code/botlib/be_aas_file.c Normal file → Executable file

File diff suppressed because it is too large Load diff

84
code/botlib/be_aas_file.h Normal file → Executable file
View file

@ -1,42 +1,42 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_file.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_file.h $
*
*****************************************************************************/
#ifdef AASINTERN
//loads the AAS file with the given name
int AAS_LoadAASFile(char *filename);
//writes an AAS file with the given name
qboolean AAS_WriteAASFile(char *filename);
//dumps the loaded AAS data
void AAS_DumpAASData(void);
//print AAS file information
void AAS_FileInfo(void);
#endif //AASINTERN
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_file.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_file.h $
*
*****************************************************************************/
#ifdef AASINTERN
//loads the AAS file with the given name
int AAS_LoadAASFile(char *filename);
//writes an AAS file with the given name
qboolean AAS_WriteAASFile(char *filename);
//dumps the loaded AAS data
void AAS_DumpAASData(void);
//print AAS file information
void AAS_FileInfo(void);
#endif //AASINTERN

94
code/botlib/be_aas_funcs.h Normal file → Executable file
View file

@ -1,47 +1,47 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_funcs.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_funcs.h $
*
*****************************************************************************/
#ifndef BSPCINCLUDE
#include "be_aas_main.h"
#include "be_aas_entity.h"
#include "be_aas_sample.h"
#include "be_aas_cluster.h"
#include "be_aas_reach.h"
#include "be_aas_route.h"
#include "be_aas_routealt.h"
#include "be_aas_debug.h"
#include "be_aas_file.h"
#include "be_aas_optimize.h"
#include "be_aas_bsp.h"
#include "be_aas_move.h"
#endif //BSPCINCLUDE
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_funcs.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_funcs.h $
*
*****************************************************************************/
#ifndef BSPCINCLUDE
#include "be_aas_main.h"
#include "be_aas_entity.h"
#include "be_aas_sample.h"
#include "be_aas_cluster.h"
#include "be_aas_reach.h"
#include "be_aas_route.h"
#include "be_aas_routealt.h"
#include "be_aas_debug.h"
#include "be_aas_file.h"
#include "be_aas_optimize.h"
#include "be_aas_bsp.h"
#include "be_aas_move.h"
#endif //BSPCINCLUDE

858
code/botlib/be_aas_main.c Normal file → Executable file
View file

@ -1,429 +1,429 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_main.c
*
* desc: AAS
*
* $Archive: /MissionPack/code/botlib/be_aas_main.c $
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_memory.h"
#include "l_libvar.h"
#include "l_utils.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "l_log.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_interface.h"
#include "be_aas_def.h"
aas_t aasworld;
libvar_t *saveroutingcache;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void QDECL AAS_Error(char *fmt, ...)
{
char str[1024];
va_list arglist;
va_start(arglist, fmt);
vsprintf(str, fmt, arglist);
va_end(arglist);
botimport.Print(PRT_FATAL, str);
} //end of the function AAS_Error
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
char *AAS_StringFromIndex(char *indexname, char *stringindex[], int numindexes, int index)
{
if (!aasworld.indexessetup)
{
botimport.Print(PRT_ERROR, "%s: index %d not setup\n", indexname, index);
return "";
} //end if
if (index < 0 || index >= numindexes)
{
botimport.Print(PRT_ERROR, "%s: index %d out of range\n", indexname, index);
return "";
} //end if
if (!stringindex[index])
{
if (index)
{
botimport.Print(PRT_ERROR, "%s: reference to unused index %d\n", indexname, index);
} //end if
return "";
} //end if
return stringindex[index];
} //end of the function AAS_StringFromIndex
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_IndexFromString(char *indexname, char *stringindex[], int numindexes, char *string)
{
int i;
if (!aasworld.indexessetup)
{
botimport.Print(PRT_ERROR, "%s: index not setup \"%s\"\n", indexname, string);
return 0;
} //end if
for (i = 0; i < numindexes; i++)
{
if (!stringindex[i]) continue;
if (!Q_stricmp(stringindex[i], string)) return i;
} //end for
return 0;
} //end of the function AAS_IndexFromString
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
char *AAS_ModelFromIndex(int index)
{
return AAS_StringFromIndex("ModelFromIndex", &aasworld.configstrings[CS_MODELS], MAX_MODELS, index);
} //end of the function AAS_ModelFromIndex
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_IndexFromModel(char *modelname)
{
return AAS_IndexFromString("IndexFromModel", &aasworld.configstrings[CS_MODELS], MAX_MODELS, modelname);
} //end of the function AAS_IndexFromModel
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_UpdateStringIndexes(int numconfigstrings, char *configstrings[])
{
int i;
//set string pointers and copy the strings
for (i = 0; i < numconfigstrings; i++)
{
if (configstrings[i])
{
//if (aasworld.configstrings[i]) FreeMemory(aasworld.configstrings[i]);
aasworld.configstrings[i] = (char *) GetMemory(strlen(configstrings[i]) + 1);
strcpy(aasworld.configstrings[i], configstrings[i]);
} //end if
} //end for
aasworld.indexessetup = qtrue;
} //end of the function AAS_UpdateStringIndexes
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_Loaded(void)
{
return aasworld.loaded;
} //end of the function AAS_Loaded
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_Initialized(void)
{
return aasworld.initialized;
} //end of the function AAS_Initialized
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_SetInitialized(void)
{
aasworld.initialized = qtrue;
botimport.Print(PRT_MESSAGE, "AAS initialized.\n");
#ifdef DEBUG
//create all the routing cache
//AAS_CreateAllRoutingCache();
//
//AAS_RoutingInfo();
#endif
} //end of the function AAS_SetInitialized
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ContinueInit(float time)
{
//if no AAS file loaded
if (!aasworld.loaded) return;
//if AAS is already initialized
if (aasworld.initialized) return;
//calculate reachability, if not finished return
if (AAS_ContinueInitReachability(time)) return;
//initialize clustering for the new map
AAS_InitClustering();
//if reachability has been calculated and an AAS file should be written
//or there is a forced data optimization
if (aasworld.savefile || ((int)LibVarGetValue("forcewrite")))
{
//optimize the AAS data
if ((int)LibVarValue("aasoptimize", "0")) AAS_Optimize();
//save the AAS file
if (AAS_WriteAASFile(aasworld.filename))
{
botimport.Print(PRT_MESSAGE, "%s written succesfully\n", aasworld.filename);
} //end if
else
{
botimport.Print(PRT_ERROR, "couldn't write %s\n", aasworld.filename);
} //end else
} //end if
//initialize the routing
AAS_InitRouting();
//at this point AAS is initialized
AAS_SetInitialized();
} //end of the function AAS_ContinueInit
//===========================================================================
// called at the start of every frame
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_StartFrame(float time)
{
aasworld.time = time;
//unlink all entities that were not updated last frame
AAS_UnlinkInvalidEntities();
//invalidate the entities
AAS_InvalidateEntities();
//initialize AAS
AAS_ContinueInit(time);
//
aasworld.frameroutingupdates = 0;
//
if (bot_developer)
{
if (LibVarGetValue("showcacheupdates"))
{
AAS_RoutingInfo();
LibVarSet("showcacheupdates", "0");
} //end if
if (LibVarGetValue("showmemoryusage"))
{
PrintUsedMemorySize();
LibVarSet("showmemoryusage", "0");
} //end if
if (LibVarGetValue("memorydump"))
{
PrintMemoryLabels();
LibVarSet("memorydump", "0");
} //end if
} //end if
//
if (saveroutingcache->value)
{
AAS_WriteRouteCache();
LibVarSet("saveroutingcache", "0");
} //end if
//
aasworld.numframes++;
return BLERR_NOERROR;
} //end of the function AAS_StartFrame
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
float AAS_Time(void)
{
return aasworld.time;
} //end of the function AAS_Time
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ProjectPointOntoVector( vec3_t point, vec3_t vStart, vec3_t vEnd, vec3_t vProj )
{
vec3_t pVec, vec;
VectorSubtract( point, vStart, pVec );
VectorSubtract( vEnd, vStart, vec );
VectorNormalize( vec );
// project onto the directional vector for this segment
VectorMA( vStart, DotProduct( pVec, vec ), vec, vProj );
} //end of the function AAS_ProjectPointOntoVector
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_LoadFiles(const char *mapname)
{
int errnum;
char aasfile[MAX_PATH];
// char bspfile[MAX_PATH];
strcpy(aasworld.mapname, mapname);
//NOTE: first reset the entity links into the AAS areas and BSP leaves
// the AAS link heap and BSP link heap are reset after respectively the
// AAS file and BSP file are loaded
AAS_ResetEntityLinks();
// load bsp info
AAS_LoadBSPFile();
//load the aas file
Com_sprintf(aasfile, MAX_PATH, "maps/%s.aas", mapname);
errnum = AAS_LoadAASFile(aasfile);
if (errnum != BLERR_NOERROR)
return errnum;
botimport.Print(PRT_MESSAGE, "loaded %s\n", aasfile);
strncpy(aasworld.filename, aasfile, MAX_PATH);
return BLERR_NOERROR;
} //end of the function AAS_LoadFiles
//===========================================================================
// called everytime a map changes
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_LoadMap(const char *mapname)
{
int errnum;
//if no mapname is provided then the string indexes are updated
if (!mapname)
{
return 0;
} //end if
//
aasworld.initialized = qfalse;
//NOTE: free the routing caches before loading a new map because
// to free the caches the old number of areas, number of clusters
// and number of areas in a clusters must be available
AAS_FreeRoutingCaches();
//load the map
errnum = AAS_LoadFiles(mapname);
if (errnum != BLERR_NOERROR)
{
aasworld.loaded = qfalse;
return errnum;
} //end if
//
AAS_InitSettings();
//initialize the AAS link heap for the new map
AAS_InitAASLinkHeap();
//initialize the AAS linked entities for the new map
AAS_InitAASLinkedEntities();
//initialize reachability for the new map
AAS_InitReachability();
//initialize the alternative routing
AAS_InitAlternativeRouting();
//everything went ok
return 0;
} //end of the function AAS_LoadMap
//===========================================================================
// called when the library is first loaded
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_Setup(void)
{
aasworld.maxclients = (int) LibVarValue("maxclients", "128");
aasworld.maxentities = (int) LibVarValue("maxentities", "1024");
// as soon as it's set to 1 the routing cache will be saved
saveroutingcache = LibVar("saveroutingcache", "0");
//allocate memory for the entities
if (aasworld.entities) FreeMemory(aasworld.entities);
aasworld.entities = (aas_entity_t *) GetClearedHunkMemory(aasworld.maxentities * sizeof(aas_entity_t));
//invalidate all the entities
AAS_InvalidateEntities();
//force some recalculations
//LibVarSet("forceclustering", "1"); //force clustering calculation
//LibVarSet("forcereachability", "1"); //force reachability calculation
aasworld.numframes = 0;
return BLERR_NOERROR;
} //end of the function AAS_Setup
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_Shutdown(void)
{
AAS_ShutdownAlternativeRouting();
//
AAS_DumpBSPData();
//free routing caches
AAS_FreeRoutingCaches();
//free aas link heap
AAS_FreeAASLinkHeap();
//free aas linked entities
AAS_FreeAASLinkedEntities();
//free the aas data
AAS_DumpAASData();
//free the entities
if (aasworld.entities) FreeMemory(aasworld.entities);
//clear the aasworld structure
Com_Memset(&aasworld, 0, sizeof(aas_t));
//aas has not been initialized
aasworld.initialized = qfalse;
//NOTE: as soon as a new .bsp file is loaded the .bsp file memory is
// freed an reallocated, so there's no need to free that memory here
//print shutdown
botimport.Print(PRT_MESSAGE, "AAS shutdown.\n");
} //end of the function AAS_Shutdown
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_main.c
*
* desc: AAS
*
* $Archive: /MissionPack/code/botlib/be_aas_main.c $
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_memory.h"
#include "l_libvar.h"
#include "l_utils.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "l_log.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_interface.h"
#include "be_aas_def.h"
aas_t aasworld;
libvar_t *saveroutingcache;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void QDECL AAS_Error(char *fmt, ...)
{
char str[1024];
va_list arglist;
va_start(arglist, fmt);
vsprintf(str, fmt, arglist);
va_end(arglist);
botimport.Print(PRT_FATAL, str);
} //end of the function AAS_Error
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
char *AAS_StringFromIndex(char *indexname, char *stringindex[], int numindexes, int index)
{
if (!aasworld.indexessetup)
{
botimport.Print(PRT_ERROR, "%s: index %d not setup\n", indexname, index);
return "";
} //end if
if (index < 0 || index >= numindexes)
{
botimport.Print(PRT_ERROR, "%s: index %d out of range\n", indexname, index);
return "";
} //end if
if (!stringindex[index])
{
if (index)
{
botimport.Print(PRT_ERROR, "%s: reference to unused index %d\n", indexname, index);
} //end if
return "";
} //end if
return stringindex[index];
} //end of the function AAS_StringFromIndex
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_IndexFromString(char *indexname, char *stringindex[], int numindexes, char *string)
{
int i;
if (!aasworld.indexessetup)
{
botimport.Print(PRT_ERROR, "%s: index not setup \"%s\"\n", indexname, string);
return 0;
} //end if
for (i = 0; i < numindexes; i++)
{
if (!stringindex[i]) continue;
if (!Q_stricmp(stringindex[i], string)) return i;
} //end for
return 0;
} //end of the function AAS_IndexFromString
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
char *AAS_ModelFromIndex(int index)
{
return AAS_StringFromIndex("ModelFromIndex", &aasworld.configstrings[CS_MODELS], MAX_MODELS, index);
} //end of the function AAS_ModelFromIndex
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_IndexFromModel(char *modelname)
{
return AAS_IndexFromString("IndexFromModel", &aasworld.configstrings[CS_MODELS], MAX_MODELS, modelname);
} //end of the function AAS_IndexFromModel
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_UpdateStringIndexes(int numconfigstrings, char *configstrings[])
{
int i;
//set string pointers and copy the strings
for (i = 0; i < numconfigstrings; i++)
{
if (configstrings[i])
{
//if (aasworld.configstrings[i]) FreeMemory(aasworld.configstrings[i]);
aasworld.configstrings[i] = (char *) GetMemory(strlen(configstrings[i]) + 1);
strcpy(aasworld.configstrings[i], configstrings[i]);
} //end if
} //end for
aasworld.indexessetup = qtrue;
} //end of the function AAS_UpdateStringIndexes
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_Loaded(void)
{
return aasworld.loaded;
} //end of the function AAS_Loaded
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_Initialized(void)
{
return aasworld.initialized;
} //end of the function AAS_Initialized
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_SetInitialized(void)
{
aasworld.initialized = qtrue;
botimport.Print(PRT_MESSAGE, "AAS initialized.\n");
#ifdef DEBUG
//create all the routing cache
//AAS_CreateAllRoutingCache();
//
//AAS_RoutingInfo();
#endif
} //end of the function AAS_SetInitialized
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ContinueInit(float time)
{
//if no AAS file loaded
if (!aasworld.loaded) return;
//if AAS is already initialized
if (aasworld.initialized) return;
//calculate reachability, if not finished return
if (AAS_ContinueInitReachability(time)) return;
//initialize clustering for the new map
AAS_InitClustering();
//if reachability has been calculated and an AAS file should be written
//or there is a forced data optimization
if (aasworld.savefile || ((int)LibVarGetValue("forcewrite")))
{
//optimize the AAS data
if ((int)LibVarValue("aasoptimize", "0")) AAS_Optimize();
//save the AAS file
if (AAS_WriteAASFile(aasworld.filename))
{
botimport.Print(PRT_MESSAGE, "%s written succesfully\n", aasworld.filename);
} //end if
else
{
botimport.Print(PRT_ERROR, "couldn't write %s\n", aasworld.filename);
} //end else
} //end if
//initialize the routing
AAS_InitRouting();
//at this point AAS is initialized
AAS_SetInitialized();
} //end of the function AAS_ContinueInit
//===========================================================================
// called at the start of every frame
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_StartFrame(float time)
{
aasworld.time = time;
//unlink all entities that were not updated last frame
AAS_UnlinkInvalidEntities();
//invalidate the entities
AAS_InvalidateEntities();
//initialize AAS
AAS_ContinueInit(time);
//
aasworld.frameroutingupdates = 0;
//
if (bot_developer)
{
if (LibVarGetValue("showcacheupdates"))
{
AAS_RoutingInfo();
LibVarSet("showcacheupdates", "0");
} //end if
if (LibVarGetValue("showmemoryusage"))
{
PrintUsedMemorySize();
LibVarSet("showmemoryusage", "0");
} //end if
if (LibVarGetValue("memorydump"))
{
PrintMemoryLabels();
LibVarSet("memorydump", "0");
} //end if
} //end if
//
if (saveroutingcache->value)
{
AAS_WriteRouteCache();
LibVarSet("saveroutingcache", "0");
} //end if
//
aasworld.numframes++;
return BLERR_NOERROR;
} //end of the function AAS_StartFrame
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
float AAS_Time(void)
{
return aasworld.time;
} //end of the function AAS_Time
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ProjectPointOntoVector( vec3_t point, vec3_t vStart, vec3_t vEnd, vec3_t vProj )
{
vec3_t pVec, vec;
VectorSubtract( point, vStart, pVec );
VectorSubtract( vEnd, vStart, vec );
VectorNormalize( vec );
// project onto the directional vector for this segment
VectorMA( vStart, DotProduct( pVec, vec ), vec, vProj );
} //end of the function AAS_ProjectPointOntoVector
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_LoadFiles(const char *mapname)
{
int errnum;
char aasfile[MAX_PATH];
// char bspfile[MAX_PATH];
strcpy(aasworld.mapname, mapname);
//NOTE: first reset the entity links into the AAS areas and BSP leaves
// the AAS link heap and BSP link heap are reset after respectively the
// AAS file and BSP file are loaded
AAS_ResetEntityLinks();
// load bsp info
AAS_LoadBSPFile();
//load the aas file
Com_sprintf(aasfile, MAX_PATH, "maps/%s.aas", mapname);
errnum = AAS_LoadAASFile(aasfile);
if (errnum != BLERR_NOERROR)
return errnum;
botimport.Print(PRT_MESSAGE, "loaded %s\n", aasfile);
strncpy(aasworld.filename, aasfile, MAX_PATH);
return BLERR_NOERROR;
} //end of the function AAS_LoadFiles
//===========================================================================
// called everytime a map changes
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_LoadMap(const char *mapname)
{
int errnum;
//if no mapname is provided then the string indexes are updated
if (!mapname)
{
return 0;
} //end if
//
aasworld.initialized = qfalse;
//NOTE: free the routing caches before loading a new map because
// to free the caches the old number of areas, number of clusters
// and number of areas in a clusters must be available
AAS_FreeRoutingCaches();
//load the map
errnum = AAS_LoadFiles(mapname);
if (errnum != BLERR_NOERROR)
{
aasworld.loaded = qfalse;
return errnum;
} //end if
//
AAS_InitSettings();
//initialize the AAS link heap for the new map
AAS_InitAASLinkHeap();
//initialize the AAS linked entities for the new map
AAS_InitAASLinkedEntities();
//initialize reachability for the new map
AAS_InitReachability();
//initialize the alternative routing
AAS_InitAlternativeRouting();
//everything went ok
return 0;
} //end of the function AAS_LoadMap
//===========================================================================
// called when the library is first loaded
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_Setup(void)
{
aasworld.maxclients = (int) LibVarValue("maxclients", "128");
aasworld.maxentities = (int) LibVarValue("maxentities", "1024");
// as soon as it's set to 1 the routing cache will be saved
saveroutingcache = LibVar("saveroutingcache", "0");
//allocate memory for the entities
if (aasworld.entities) FreeMemory(aasworld.entities);
aasworld.entities = (aas_entity_t *) GetClearedHunkMemory(aasworld.maxentities * sizeof(aas_entity_t));
//invalidate all the entities
AAS_InvalidateEntities();
//force some recalculations
//LibVarSet("forceclustering", "1"); //force clustering calculation
//LibVarSet("forcereachability", "1"); //force reachability calculation
aasworld.numframes = 0;
return BLERR_NOERROR;
} //end of the function AAS_Setup
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_Shutdown(void)
{
AAS_ShutdownAlternativeRouting();
//
AAS_DumpBSPData();
//free routing caches
AAS_FreeRoutingCaches();
//free aas link heap
AAS_FreeAASLinkHeap();
//free aas linked entities
AAS_FreeAASLinkedEntities();
//free the aas data
AAS_DumpAASData();
//free the entities
if (aasworld.entities) FreeMemory(aasworld.entities);
//clear the aasworld structure
Com_Memset(&aasworld, 0, sizeof(aas_t));
//aas has not been initialized
aasworld.initialized = qfalse;
//NOTE: as soon as a new .bsp file is loaded the .bsp file memory is
// freed an reallocated, so there's no need to free that memory here
//print shutdown
botimport.Print(PRT_MESSAGE, "AAS shutdown.\n");
} //end of the function AAS_Shutdown

122
code/botlib/be_aas_main.h Normal file → Executable file
View file

@ -1,61 +1,61 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_main.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_main.h $
*
*****************************************************************************/
#ifdef AASINTERN
extern aas_t aasworld;
//AAS error message
void QDECL AAS_Error(char *fmt, ...);
//set AAS initialized
void AAS_SetInitialized(void);
//setup AAS with the given number of entities and clients
int AAS_Setup(void);
//shutdown AAS
void AAS_Shutdown(void);
//start a new map
int AAS_LoadMap(const char *mapname);
//start a new time frame
int AAS_StartFrame(float time);
#endif //AASINTERN
//returns true if AAS is initialized
int AAS_Initialized(void);
//returns true if the AAS file is loaded
int AAS_Loaded(void);
//returns the model name from the given index
char *AAS_ModelFromIndex(int index);
//returns the index from the given model name
int AAS_IndexFromModel(char *modelname);
//returns the current time
float AAS_Time(void);
//
void AAS_ProjectPointOntoVector( vec3_t point, vec3_t vStart, vec3_t vEnd, vec3_t vProj );
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_main.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_main.h $
*
*****************************************************************************/
#ifdef AASINTERN
extern aas_t aasworld;
//AAS error message
void QDECL AAS_Error(char *fmt, ...);
//set AAS initialized
void AAS_SetInitialized(void);
//setup AAS with the given number of entities and clients
int AAS_Setup(void);
//shutdown AAS
void AAS_Shutdown(void);
//start a new map
int AAS_LoadMap(const char *mapname);
//start a new time frame
int AAS_StartFrame(float time);
#endif //AASINTERN
//returns true if AAS is initialized
int AAS_Initialized(void);
//returns true if the AAS file is loaded
int AAS_Loaded(void);
//returns the model name from the given index
char *AAS_ModelFromIndex(int index);
//returns the index from the given model name
int AAS_IndexFromModel(char *modelname);
//returns the current time
float AAS_Time(void);
//
void AAS_ProjectPointOntoVector( vec3_t point, vec3_t vStart, vec3_t vEnd, vec3_t vProj );

2202
code/botlib/be_aas_move.c Normal file → Executable file

File diff suppressed because it is too large Load diff

142
code/botlib/be_aas_move.h Normal file → Executable file
View file

@ -1,71 +1,71 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_move.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_move.h $
*
*****************************************************************************/
#ifdef AASINTERN
extern aas_settings_t aassettings;
#endif //AASINTERN
//movement prediction
int AAS_PredictClientMovement(struct aas_clientmove_s *move,
int entnum, vec3_t origin,
int presencetype, int onground,
vec3_t velocity, vec3_t cmdmove,
int cmdframes,
int maxframes, float frametime,
int stopevent, int stopareanum, int visualize);
//predict movement until bounding box is hit
int AAS_ClientMovementHitBBox(struct aas_clientmove_s *move,
int entnum, vec3_t origin,
int presencetype, int onground,
vec3_t velocity, vec3_t cmdmove,
int cmdframes,
int maxframes, float frametime,
vec3_t mins, vec3_t maxs, int visualize);
//returns true if on the ground at the given origin
int AAS_OnGround(vec3_t origin, int presencetype, int passent);
//returns true if swimming at the given origin
int AAS_Swimming(vec3_t origin);
//returns the jump reachability run start point
void AAS_JumpReachRunStart(struct aas_reachability_s *reach, vec3_t runstart);
//returns true if against a ladder at the given origin
int AAS_AgainstLadder(vec3_t origin);
//rocket jump Z velocity when rocket-jumping at origin
float AAS_RocketJumpZVelocity(vec3_t origin);
//bfg jump Z velocity when bfg-jumping at origin
float AAS_BFGJumpZVelocity(vec3_t origin);
//calculates the horizontal velocity needed for a jump and returns true this velocity could be calculated
int AAS_HorizontalVelocityForJump(float zvel, vec3_t start, vec3_t end, float *velocity);
//
void AAS_SetMovedir(vec3_t angles, vec3_t movedir);
//
int AAS_DropToFloor(vec3_t origin, vec3_t mins, vec3_t maxs);
//
void AAS_InitSettings(void);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_move.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_move.h $
*
*****************************************************************************/
#ifdef AASINTERN
extern aas_settings_t aassettings;
#endif //AASINTERN
//movement prediction
int AAS_PredictClientMovement(struct aas_clientmove_s *move,
int entnum, vec3_t origin,
int presencetype, int onground,
vec3_t velocity, vec3_t cmdmove,
int cmdframes,
int maxframes, float frametime,
int stopevent, int stopareanum, int visualize);
//predict movement until bounding box is hit
int AAS_ClientMovementHitBBox(struct aas_clientmove_s *move,
int entnum, vec3_t origin,
int presencetype, int onground,
vec3_t velocity, vec3_t cmdmove,
int cmdframes,
int maxframes, float frametime,
vec3_t mins, vec3_t maxs, int visualize);
//returns true if on the ground at the given origin
int AAS_OnGround(vec3_t origin, int presencetype, int passent);
//returns true if swimming at the given origin
int AAS_Swimming(vec3_t origin);
//returns the jump reachability run start point
void AAS_JumpReachRunStart(struct aas_reachability_s *reach, vec3_t runstart);
//returns true if against a ladder at the given origin
int AAS_AgainstLadder(vec3_t origin);
//rocket jump Z velocity when rocket-jumping at origin
float AAS_RocketJumpZVelocity(vec3_t origin);
//bfg jump Z velocity when bfg-jumping at origin
float AAS_BFGJumpZVelocity(vec3_t origin);
//calculates the horizontal velocity needed for a jump and returns true this velocity could be calculated
int AAS_HorizontalVelocityForJump(float zvel, vec3_t start, vec3_t end, float *velocity);
//
void AAS_SetMovedir(vec3_t angles, vec3_t movedir);
//
int AAS_DropToFloor(vec3_t origin, vec3_t mins, vec3_t maxs);
//
void AAS_InitSettings(void);

624
code/botlib/be_aas_optimize.c Normal file → Executable file
View file

@ -1,312 +1,312 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_optimize.c
*
* desc: decreases the .aas file size after the reachabilities have
* been calculated, just dumps all the faces, edges and vertexes
*
* $Archive: /MissionPack/code/botlib/be_aas_optimize.c $
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_libvar.h"
#include "l_memory.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_interface.h"
#include "be_aas_def.h"
typedef struct optimized_s
{
//vertexes
int numvertexes;
aas_vertex_t *vertexes;
//edges
int numedges;
aas_edge_t *edges;
//edge index
int edgeindexsize;
aas_edgeindex_t *edgeindex;
//faces
int numfaces;
aas_face_t *faces;
//face index
int faceindexsize;
aas_faceindex_t *faceindex;
//convex areas
int numareas;
aas_area_t *areas;
//
int *vertexoptimizeindex;
int *edgeoptimizeindex;
int *faceoptimizeindex;
} optimized_t;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_KeepEdge(aas_edge_t *edge)
{
return 1;
} //end of the function AAS_KeepFace
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_OptimizeEdge(optimized_t *optimized, int edgenum)
{
int i, optedgenum;
aas_edge_t *edge, *optedge;
edge = &aasworld.edges[abs(edgenum)];
if (!AAS_KeepEdge(edge)) return 0;
optedgenum = optimized->edgeoptimizeindex[abs(edgenum)];
if (optedgenum)
{
//keep the edge reversed sign
if (edgenum > 0) return optedgenum;
else return -optedgenum;
} //end if
optedge = &optimized->edges[optimized->numedges];
for (i = 0; i < 2; i++)
{
if (optimized->vertexoptimizeindex[edge->v[i]])
{
optedge->v[i] = optimized->vertexoptimizeindex[edge->v[i]];
} //end if
else
{
VectorCopy(aasworld.vertexes[edge->v[i]], optimized->vertexes[optimized->numvertexes]);
optedge->v[i] = optimized->numvertexes;
optimized->vertexoptimizeindex[edge->v[i]] = optimized->numvertexes;
optimized->numvertexes++;
} //end else
} //end for
optimized->edgeoptimizeindex[abs(edgenum)] = optimized->numedges;
optedgenum = optimized->numedges;
optimized->numedges++;
//keep the edge reversed sign
if (edgenum > 0) return optedgenum;
else return -optedgenum;
} //end of the function AAS_OptimizeEdge
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_KeepFace(aas_face_t *face)
{
if (!(face->faceflags & FACE_LADDER)) return 0;
else return 1;
} //end of the function AAS_KeepFace
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_OptimizeFace(optimized_t *optimized, int facenum)
{
int i, edgenum, optedgenum, optfacenum;
aas_face_t *face, *optface;
face = &aasworld.faces[abs(facenum)];
if (!AAS_KeepFace(face)) return 0;
optfacenum = optimized->faceoptimizeindex[abs(facenum)];
if (optfacenum)
{
//keep the face side sign
if (facenum > 0) return optfacenum;
else return -optfacenum;
} //end if
optface = &optimized->faces[optimized->numfaces];
Com_Memcpy(optface, face, sizeof(aas_face_t));
optface->numedges = 0;
optface->firstedge = optimized->edgeindexsize;
for (i = 0; i < face->numedges; i++)
{
edgenum = aasworld.edgeindex[face->firstedge + i];
optedgenum = AAS_OptimizeEdge(optimized, edgenum);
if (optedgenum)
{
optimized->edgeindex[optface->firstedge + optface->numedges] = optedgenum;
optface->numedges++;
optimized->edgeindexsize++;
} //end if
} //end for
optimized->faceoptimizeindex[abs(facenum)] = optimized->numfaces;
optfacenum = optimized->numfaces;
optimized->numfaces++;
//keep the face side sign
if (facenum > 0) return optfacenum;
else return -optfacenum;
} //end of the function AAS_OptimizeFace
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_OptimizeArea(optimized_t *optimized, int areanum)
{
int i, facenum, optfacenum;
aas_area_t *area, *optarea;
area = &aasworld.areas[areanum];
optarea = &optimized->areas[areanum];
Com_Memcpy(optarea, area, sizeof(aas_area_t));
optarea->numfaces = 0;
optarea->firstface = optimized->faceindexsize;
for (i = 0; i < area->numfaces; i++)
{
facenum = aasworld.faceindex[area->firstface + i];
optfacenum = AAS_OptimizeFace(optimized, facenum);
if (optfacenum)
{
optimized->faceindex[optarea->firstface + optarea->numfaces] = optfacenum;
optarea->numfaces++;
optimized->faceindexsize++;
} //end if
} //end for
} //end of the function AAS_OptimizeArea
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_OptimizeAlloc(optimized_t *optimized)
{
optimized->vertexes = (aas_vertex_t *) GetClearedMemory(aasworld.numvertexes * sizeof(aas_vertex_t));
optimized->numvertexes = 0;
optimized->edges = (aas_edge_t *) GetClearedMemory(aasworld.numedges * sizeof(aas_edge_t));
optimized->numedges = 1; //edge zero is a dummy
optimized->edgeindex = (aas_edgeindex_t *) GetClearedMemory(aasworld.edgeindexsize * sizeof(aas_edgeindex_t));
optimized->edgeindexsize = 0;
optimized->faces = (aas_face_t *) GetClearedMemory(aasworld.numfaces * sizeof(aas_face_t));
optimized->numfaces = 1; //face zero is a dummy
optimized->faceindex = (aas_faceindex_t *) GetClearedMemory(aasworld.faceindexsize * sizeof(aas_faceindex_t));
optimized->faceindexsize = 0;
optimized->areas = (aas_area_t *) GetClearedMemory(aasworld.numareas * sizeof(aas_area_t));
optimized->numareas = aasworld.numareas;
//
optimized->vertexoptimizeindex = (int *) GetClearedMemory(aasworld.numvertexes * sizeof(int));
optimized->edgeoptimizeindex = (int *) GetClearedMemory(aasworld.numedges * sizeof(int));
optimized->faceoptimizeindex = (int *) GetClearedMemory(aasworld.numfaces * sizeof(int));
} //end of the function AAS_OptimizeAlloc
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_OptimizeStore(optimized_t *optimized)
{
//store the optimized vertexes
if (aasworld.vertexes) FreeMemory(aasworld.vertexes);
aasworld.vertexes = optimized->vertexes;
aasworld.numvertexes = optimized->numvertexes;
//store the optimized edges
if (aasworld.edges) FreeMemory(aasworld.edges);
aasworld.edges = optimized->edges;
aasworld.numedges = optimized->numedges;
//store the optimized edge index
if (aasworld.edgeindex) FreeMemory(aasworld.edgeindex);
aasworld.edgeindex = optimized->edgeindex;
aasworld.edgeindexsize = optimized->edgeindexsize;
//store the optimized faces
if (aasworld.faces) FreeMemory(aasworld.faces);
aasworld.faces = optimized->faces;
aasworld.numfaces = optimized->numfaces;
//store the optimized face index
if (aasworld.faceindex) FreeMemory(aasworld.faceindex);
aasworld.faceindex = optimized->faceindex;
aasworld.faceindexsize = optimized->faceindexsize;
//store the optimized areas
if (aasworld.areas) FreeMemory(aasworld.areas);
aasworld.areas = optimized->areas;
aasworld.numareas = optimized->numareas;
//free optimize indexes
FreeMemory(optimized->vertexoptimizeindex);
FreeMemory(optimized->edgeoptimizeindex);
FreeMemory(optimized->faceoptimizeindex);
} //end of the function AAS_OptimizeStore
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_Optimize(void)
{
int i, sign;
optimized_t optimized;
AAS_OptimizeAlloc(&optimized);
for (i = 1; i < aasworld.numareas; i++)
{
AAS_OptimizeArea(&optimized, i);
} //end for
//reset the reachability face pointers
for (i = 0; i < aasworld.reachabilitysize; i++)
{
//NOTE: for TRAVEL_ELEVATOR the facenum is the model number of
// the elevator
if ((aasworld.reachability[i].traveltype & TRAVELTYPE_MASK) == TRAVEL_ELEVATOR) continue;
//NOTE: for TRAVEL_JUMPPAD the facenum is the Z velocity and the edgenum is the hor velocity
if ((aasworld.reachability[i].traveltype & TRAVELTYPE_MASK) == TRAVEL_JUMPPAD) continue;
//NOTE: for TRAVEL_FUNCBOB the facenum and edgenum contain other coded information
if ((aasworld.reachability[i].traveltype & TRAVELTYPE_MASK) == TRAVEL_FUNCBOB) continue;
//
sign = aasworld.reachability[i].facenum;
aasworld.reachability[i].facenum = optimized.faceoptimizeindex[abs(aasworld.reachability[i].facenum)];
if (sign < 0) aasworld.reachability[i].facenum = -aasworld.reachability[i].facenum;
sign = aasworld.reachability[i].edgenum;
aasworld.reachability[i].edgenum = optimized.edgeoptimizeindex[abs(aasworld.reachability[i].edgenum)];
if (sign < 0) aasworld.reachability[i].edgenum = -aasworld.reachability[i].edgenum;
} //end for
//store the optimized AAS data into aasworld
AAS_OptimizeStore(&optimized);
//print some nice stuff :)
botimport.Print(PRT_MESSAGE, "AAS data optimized.\n");
} //end of the function AAS_Optimize
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_optimize.c
*
* desc: decreases the .aas file size after the reachabilities have
* been calculated, just dumps all the faces, edges and vertexes
*
* $Archive: /MissionPack/code/botlib/be_aas_optimize.c $
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_libvar.h"
#include "l_memory.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_interface.h"
#include "be_aas_def.h"
typedef struct optimized_s
{
//vertexes
int numvertexes;
aas_vertex_t *vertexes;
//edges
int numedges;
aas_edge_t *edges;
//edge index
int edgeindexsize;
aas_edgeindex_t *edgeindex;
//faces
int numfaces;
aas_face_t *faces;
//face index
int faceindexsize;
aas_faceindex_t *faceindex;
//convex areas
int numareas;
aas_area_t *areas;
//
int *vertexoptimizeindex;
int *edgeoptimizeindex;
int *faceoptimizeindex;
} optimized_t;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_KeepEdge(aas_edge_t *edge)
{
return 1;
} //end of the function AAS_KeepFace
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_OptimizeEdge(optimized_t *optimized, int edgenum)
{
int i, optedgenum;
aas_edge_t *edge, *optedge;
edge = &aasworld.edges[abs(edgenum)];
if (!AAS_KeepEdge(edge)) return 0;
optedgenum = optimized->edgeoptimizeindex[abs(edgenum)];
if (optedgenum)
{
//keep the edge reversed sign
if (edgenum > 0) return optedgenum;
else return -optedgenum;
} //end if
optedge = &optimized->edges[optimized->numedges];
for (i = 0; i < 2; i++)
{
if (optimized->vertexoptimizeindex[edge->v[i]])
{
optedge->v[i] = optimized->vertexoptimizeindex[edge->v[i]];
} //end if
else
{
VectorCopy(aasworld.vertexes[edge->v[i]], optimized->vertexes[optimized->numvertexes]);
optedge->v[i] = optimized->numvertexes;
optimized->vertexoptimizeindex[edge->v[i]] = optimized->numvertexes;
optimized->numvertexes++;
} //end else
} //end for
optimized->edgeoptimizeindex[abs(edgenum)] = optimized->numedges;
optedgenum = optimized->numedges;
optimized->numedges++;
//keep the edge reversed sign
if (edgenum > 0) return optedgenum;
else return -optedgenum;
} //end of the function AAS_OptimizeEdge
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_KeepFace(aas_face_t *face)
{
if (!(face->faceflags & FACE_LADDER)) return 0;
else return 1;
} //end of the function AAS_KeepFace
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_OptimizeFace(optimized_t *optimized, int facenum)
{
int i, edgenum, optedgenum, optfacenum;
aas_face_t *face, *optface;
face = &aasworld.faces[abs(facenum)];
if (!AAS_KeepFace(face)) return 0;
optfacenum = optimized->faceoptimizeindex[abs(facenum)];
if (optfacenum)
{
//keep the face side sign
if (facenum > 0) return optfacenum;
else return -optfacenum;
} //end if
optface = &optimized->faces[optimized->numfaces];
Com_Memcpy(optface, face, sizeof(aas_face_t));
optface->numedges = 0;
optface->firstedge = optimized->edgeindexsize;
for (i = 0; i < face->numedges; i++)
{
edgenum = aasworld.edgeindex[face->firstedge + i];
optedgenum = AAS_OptimizeEdge(optimized, edgenum);
if (optedgenum)
{
optimized->edgeindex[optface->firstedge + optface->numedges] = optedgenum;
optface->numedges++;
optimized->edgeindexsize++;
} //end if
} //end for
optimized->faceoptimizeindex[abs(facenum)] = optimized->numfaces;
optfacenum = optimized->numfaces;
optimized->numfaces++;
//keep the face side sign
if (facenum > 0) return optfacenum;
else return -optfacenum;
} //end of the function AAS_OptimizeFace
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_OptimizeArea(optimized_t *optimized, int areanum)
{
int i, facenum, optfacenum;
aas_area_t *area, *optarea;
area = &aasworld.areas[areanum];
optarea = &optimized->areas[areanum];
Com_Memcpy(optarea, area, sizeof(aas_area_t));
optarea->numfaces = 0;
optarea->firstface = optimized->faceindexsize;
for (i = 0; i < area->numfaces; i++)
{
facenum = aasworld.faceindex[area->firstface + i];
optfacenum = AAS_OptimizeFace(optimized, facenum);
if (optfacenum)
{
optimized->faceindex[optarea->firstface + optarea->numfaces] = optfacenum;
optarea->numfaces++;
optimized->faceindexsize++;
} //end if
} //end for
} //end of the function AAS_OptimizeArea
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_OptimizeAlloc(optimized_t *optimized)
{
optimized->vertexes = (aas_vertex_t *) GetClearedMemory(aasworld.numvertexes * sizeof(aas_vertex_t));
optimized->numvertexes = 0;
optimized->edges = (aas_edge_t *) GetClearedMemory(aasworld.numedges * sizeof(aas_edge_t));
optimized->numedges = 1; //edge zero is a dummy
optimized->edgeindex = (aas_edgeindex_t *) GetClearedMemory(aasworld.edgeindexsize * sizeof(aas_edgeindex_t));
optimized->edgeindexsize = 0;
optimized->faces = (aas_face_t *) GetClearedMemory(aasworld.numfaces * sizeof(aas_face_t));
optimized->numfaces = 1; //face zero is a dummy
optimized->faceindex = (aas_faceindex_t *) GetClearedMemory(aasworld.faceindexsize * sizeof(aas_faceindex_t));
optimized->faceindexsize = 0;
optimized->areas = (aas_area_t *) GetClearedMemory(aasworld.numareas * sizeof(aas_area_t));
optimized->numareas = aasworld.numareas;
//
optimized->vertexoptimizeindex = (int *) GetClearedMemory(aasworld.numvertexes * sizeof(int));
optimized->edgeoptimizeindex = (int *) GetClearedMemory(aasworld.numedges * sizeof(int));
optimized->faceoptimizeindex = (int *) GetClearedMemory(aasworld.numfaces * sizeof(int));
} //end of the function AAS_OptimizeAlloc
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_OptimizeStore(optimized_t *optimized)
{
//store the optimized vertexes
if (aasworld.vertexes) FreeMemory(aasworld.vertexes);
aasworld.vertexes = optimized->vertexes;
aasworld.numvertexes = optimized->numvertexes;
//store the optimized edges
if (aasworld.edges) FreeMemory(aasworld.edges);
aasworld.edges = optimized->edges;
aasworld.numedges = optimized->numedges;
//store the optimized edge index
if (aasworld.edgeindex) FreeMemory(aasworld.edgeindex);
aasworld.edgeindex = optimized->edgeindex;
aasworld.edgeindexsize = optimized->edgeindexsize;
//store the optimized faces
if (aasworld.faces) FreeMemory(aasworld.faces);
aasworld.faces = optimized->faces;
aasworld.numfaces = optimized->numfaces;
//store the optimized face index
if (aasworld.faceindex) FreeMemory(aasworld.faceindex);
aasworld.faceindex = optimized->faceindex;
aasworld.faceindexsize = optimized->faceindexsize;
//store the optimized areas
if (aasworld.areas) FreeMemory(aasworld.areas);
aasworld.areas = optimized->areas;
aasworld.numareas = optimized->numareas;
//free optimize indexes
FreeMemory(optimized->vertexoptimizeindex);
FreeMemory(optimized->edgeoptimizeindex);
FreeMemory(optimized->faceoptimizeindex);
} //end of the function AAS_OptimizeStore
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_Optimize(void)
{
int i, sign;
optimized_t optimized;
AAS_OptimizeAlloc(&optimized);
for (i = 1; i < aasworld.numareas; i++)
{
AAS_OptimizeArea(&optimized, i);
} //end for
//reset the reachability face pointers
for (i = 0; i < aasworld.reachabilitysize; i++)
{
//NOTE: for TRAVEL_ELEVATOR the facenum is the model number of
// the elevator
if ((aasworld.reachability[i].traveltype & TRAVELTYPE_MASK) == TRAVEL_ELEVATOR) continue;
//NOTE: for TRAVEL_JUMPPAD the facenum is the Z velocity and the edgenum is the hor velocity
if ((aasworld.reachability[i].traveltype & TRAVELTYPE_MASK) == TRAVEL_JUMPPAD) continue;
//NOTE: for TRAVEL_FUNCBOB the facenum and edgenum contain other coded information
if ((aasworld.reachability[i].traveltype & TRAVELTYPE_MASK) == TRAVEL_FUNCBOB) continue;
//
sign = aasworld.reachability[i].facenum;
aasworld.reachability[i].facenum = optimized.faceoptimizeindex[abs(aasworld.reachability[i].facenum)];
if (sign < 0) aasworld.reachability[i].facenum = -aasworld.reachability[i].facenum;
sign = aasworld.reachability[i].edgenum;
aasworld.reachability[i].edgenum = optimized.edgeoptimizeindex[abs(aasworld.reachability[i].edgenum)];
if (sign < 0) aasworld.reachability[i].edgenum = -aasworld.reachability[i].edgenum;
} //end for
//store the optimized AAS data into aasworld
AAS_OptimizeStore(&optimized);
//print some nice stuff :)
botimport.Print(PRT_MESSAGE, "AAS data optimized.\n");
} //end of the function AAS_Optimize

66
code/botlib/be_aas_optimize.h Normal file → Executable file
View file

@ -1,33 +1,33 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_optimize.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_optimize.h $
*
*****************************************************************************/
void AAS_Optimize(void);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_optimize.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_optimize.h $
*
*****************************************************************************/
void AAS_Optimize(void);

9094
code/botlib/be_aas_reach.c Normal file → Executable file

File diff suppressed because it is too large Load diff

136
code/botlib/be_aas_reach.h Normal file → Executable file
View file

@ -1,68 +1,68 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_reach.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_reach.h $
*
*****************************************************************************/
#ifdef AASINTERN
//initialize calculating the reachabilities
void AAS_InitReachability(void);
//continue calculating the reachabilities
int AAS_ContinueInitReachability(float time);
//
int AAS_BestReachableLinkArea(aas_link_t *areas);
#endif //AASINTERN
//returns true if the are has reachabilities to other areas
int AAS_AreaReachability(int areanum);
//returns the best reachable area and goal origin for a bounding box at the given origin
int AAS_BestReachableArea(vec3_t origin, vec3_t mins, vec3_t maxs, vec3_t goalorigin);
//returns the best jumppad area from which the bbox at origin is reachable
int AAS_BestReachableFromJumpPadArea(vec3_t origin, vec3_t mins, vec3_t maxs);
//returns the next reachability using the given model
int AAS_NextModelReachability(int num, int modelnum);
//returns the total area of the ground faces of the given area
float AAS_AreaGroundFaceArea(int areanum);
//returns true if the area is crouch only
int AAS_AreaCrouch(int areanum);
//returns true if a player can swim in this area
int AAS_AreaSwim(int areanum);
//returns true if the area is filled with a liquid
int AAS_AreaLiquid(int areanum);
//returns true if the area contains lava
int AAS_AreaLava(int areanum);
//returns true if the area contains slime
int AAS_AreaSlime(int areanum);
//returns true if the area has one or more ground faces
int AAS_AreaGrounded(int areanum);
//returns true if the area has one or more ladder faces
int AAS_AreaLadder(int areanum);
//returns true if the area is a jump pad
int AAS_AreaJumpPad(int areanum);
//returns true if the area is donotenter
int AAS_AreaDoNotEnter(int areanum);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_reach.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_reach.h $
*
*****************************************************************************/
#ifdef AASINTERN
//initialize calculating the reachabilities
void AAS_InitReachability(void);
//continue calculating the reachabilities
int AAS_ContinueInitReachability(float time);
//
int AAS_BestReachableLinkArea(aas_link_t *areas);
#endif //AASINTERN
//returns true if the are has reachabilities to other areas
int AAS_AreaReachability(int areanum);
//returns the best reachable area and goal origin for a bounding box at the given origin
int AAS_BestReachableArea(vec3_t origin, vec3_t mins, vec3_t maxs, vec3_t goalorigin);
//returns the best jumppad area from which the bbox at origin is reachable
int AAS_BestReachableFromJumpPadArea(vec3_t origin, vec3_t mins, vec3_t maxs);
//returns the next reachability using the given model
int AAS_NextModelReachability(int num, int modelnum);
//returns the total area of the ground faces of the given area
float AAS_AreaGroundFaceArea(int areanum);
//returns true if the area is crouch only
int AAS_AreaCrouch(int areanum);
//returns true if a player can swim in this area
int AAS_AreaSwim(int areanum);
//returns true if the area is filled with a liquid
int AAS_AreaLiquid(int areanum);
//returns true if the area contains lava
int AAS_AreaLava(int areanum);
//returns true if the area contains slime
int AAS_AreaSlime(int areanum);
//returns true if the area has one or more ground faces
int AAS_AreaGrounded(int areanum);
//returns true if the area has one or more ladder faces
int AAS_AreaLadder(int areanum);
//returns true if the area is a jump pad
int AAS_AreaJumpPad(int areanum);
//returns true if the area is donotenter
int AAS_AreaDoNotEnter(int areanum);

4418
code/botlib/be_aas_route.c Normal file → Executable file

File diff suppressed because it is too large Load diff

134
code/botlib/be_aas_route.h Normal file → Executable file
View file

@ -1,67 +1,67 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_route.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_route.h $
*
*****************************************************************************/
#ifdef AASINTERN
//initialize the AAS routing
void AAS_InitRouting(void);
//free the AAS routing caches
void AAS_FreeRoutingCaches(void);
//returns the travel time from start to end in the given area
unsigned short int AAS_AreaTravelTime(int areanum, vec3_t start, vec3_t end);
//
void AAS_CreateAllRoutingCache(void);
void AAS_WriteRouteCache(void);
//
void AAS_RoutingInfo(void);
#endif //AASINTERN
//returns the travel flag for the given travel type
int AAS_TravelFlagForType(int traveltype);
//return the travel flag(s) for traveling through this area
int AAS_AreaContentsTravelFlags(int areanum);
//returns the index of the next reachability for the given area
int AAS_NextAreaReachability(int areanum, int reachnum);
//returns the reachability with the given index
void AAS_ReachabilityFromNum(int num, struct aas_reachability_s *reach);
//returns a random goal area and goal origin
int AAS_RandomGoalArea(int areanum, int travelflags, int *goalareanum, vec3_t goalorigin);
//enable or disable an area for routing
int AAS_EnableRoutingArea(int areanum, int enable);
//returns the travel time within the given area from start to end
unsigned short int AAS_AreaTravelTime(int areanum, vec3_t start, vec3_t end);
//returns the travel time from the area to the goal area using the given travel flags
int AAS_AreaTravelTimeToGoalArea(int areanum, vec3_t origin, int goalareanum, int travelflags);
//predict a route up to a stop event
int AAS_PredictRoute(struct aas_predictroute_s *route, int areanum, vec3_t origin,
int goalareanum, int travelflags, int maxareas, int maxtime,
int stopevent, int stopcontents, int stoptfl, int stopareanum);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_route.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_route.h $
*
*****************************************************************************/
#ifdef AASINTERN
//initialize the AAS routing
void AAS_InitRouting(void);
//free the AAS routing caches
void AAS_FreeRoutingCaches(void);
//returns the travel time from start to end in the given area
unsigned short int AAS_AreaTravelTime(int areanum, vec3_t start, vec3_t end);
//
void AAS_CreateAllRoutingCache(void);
void AAS_WriteRouteCache(void);
//
void AAS_RoutingInfo(void);
#endif //AASINTERN
//returns the travel flag for the given travel type
int AAS_TravelFlagForType(int traveltype);
//return the travel flag(s) for traveling through this area
int AAS_AreaContentsTravelFlags(int areanum);
//returns the index of the next reachability for the given area
int AAS_NextAreaReachability(int areanum, int reachnum);
//returns the reachability with the given index
void AAS_ReachabilityFromNum(int num, struct aas_reachability_s *reach);
//returns a random goal area and goal origin
int AAS_RandomGoalArea(int areanum, int travelflags, int *goalareanum, vec3_t goalorigin);
//enable or disable an area for routing
int AAS_EnableRoutingArea(int areanum, int enable);
//returns the travel time within the given area from start to end
unsigned short int AAS_AreaTravelTime(int areanum, vec3_t start, vec3_t end);
//returns the travel time from the area to the goal area using the given travel flags
int AAS_AreaTravelTimeToGoalArea(int areanum, vec3_t origin, int goalareanum, int travelflags);
//predict a route up to a stop event
int AAS_PredictRoute(struct aas_predictroute_s *route, int areanum, vec3_t origin,
int goalareanum, int travelflags, int maxareas, int maxtime,
int stopevent, int stopcontents, int stoptfl, int stopareanum);

480
code/botlib/be_aas_routealt.c Normal file → Executable file
View file

@ -1,240 +1,240 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_routealt.c
*
* desc: AAS
*
* $Archive: /MissionPack/code/botlib/be_aas_routealt.c $
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_utils.h"
#include "l_memory.h"
#include "l_log.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_interface.h"
#include "be_aas_def.h"
#define ENABLE_ALTROUTING
//#define ALTROUTE_DEBUG
typedef struct midrangearea_s
{
int valid;
unsigned short starttime;
unsigned short goaltime;
} midrangearea_t;
midrangearea_t *midrangeareas;
int *clusterareas;
int numclusterareas;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_AltRoutingFloodCluster_r(int areanum)
{
int i, otherareanum;
aas_area_t *area;
aas_face_t *face;
//add the current area to the areas of the current cluster
clusterareas[numclusterareas] = areanum;
numclusterareas++;
//remove the area from the mid range areas
midrangeareas[areanum].valid = qfalse;
//flood to other areas through the faces of this area
area = &aasworld.areas[areanum];
for (i = 0; i < area->numfaces; i++)
{
face = &aasworld.faces[abs(aasworld.faceindex[area->firstface + i])];
//get the area at the other side of the face
if (face->frontarea == areanum) otherareanum = face->backarea;
else otherareanum = face->frontarea;
//if there is an area at the other side of this face
if (!otherareanum) continue;
//if the other area is not a midrange area
if (!midrangeareas[otherareanum].valid) continue;
//
AAS_AltRoutingFloodCluster_r(otherareanum);
} //end for
} //end of the function AAS_AltRoutingFloodCluster_r
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_AlternativeRouteGoals(vec3_t start, int startareanum, vec3_t goal, int goalareanum, int travelflags,
aas_altroutegoal_t *altroutegoals, int maxaltroutegoals,
int type)
{
#ifndef ENABLE_ALTROUTING
return 0;
#else
int i, j, bestareanum;
int numaltroutegoals, nummidrangeareas;
int starttime, goaltime, goaltraveltime;
float dist, bestdist;
vec3_t mid, dir;
#ifdef ALTROUTE_DEBUG
int startmillisecs;
startmillisecs = Sys_MilliSeconds();
#endif
if (!startareanum || !goalareanum)
return 0;
//travel time towards the goal area
goaltraveltime = AAS_AreaTravelTimeToGoalArea(startareanum, start, goalareanum, travelflags);
//clear the midrange areas
Com_Memset(midrangeareas, 0, aasworld.numareas * sizeof(midrangearea_t));
numaltroutegoals = 0;
//
nummidrangeareas = 0;
//
for (i = 1; i < aasworld.numareas; i++)
{
//
if (!(type & ALTROUTEGOAL_ALL))
{
if (!(type & ALTROUTEGOAL_CLUSTERPORTALS && (aasworld.areasettings[i].contents & AREACONTENTS_CLUSTERPORTAL)))
{
if (!(type & ALTROUTEGOAL_VIEWPORTALS && (aasworld.areasettings[i].contents & AREACONTENTS_VIEWPORTAL)))
{
continue;
} //end if
} //end if
} //end if
//if the area has no reachabilities
if (!AAS_AreaReachability(i)) continue;
//tavel time from the area to the start area
starttime = AAS_AreaTravelTimeToGoalArea(startareanum, start, i, travelflags);
if (!starttime) continue;
//if the travel time from the start to the area is greater than the shortest goal travel time
if (starttime > (float) 1.1 * goaltraveltime) continue;
//travel time from the area to the goal area
goaltime = AAS_AreaTravelTimeToGoalArea(i, NULL, goalareanum, travelflags);
if (!goaltime) continue;
//if the travel time from the area to the goal is greater than the shortest goal travel time
if (goaltime > (float) 0.8 * goaltraveltime) continue;
//this is a mid range area
midrangeareas[i].valid = qtrue;
midrangeareas[i].starttime = starttime;
midrangeareas[i].goaltime = goaltime;
Log_Write("%d midrange area %d", nummidrangeareas, i);
nummidrangeareas++;
} //end for
//
for (i = 1; i < aasworld.numareas; i++)
{
if (!midrangeareas[i].valid) continue;
//get the areas in one cluster
numclusterareas = 0;
AAS_AltRoutingFloodCluster_r(i);
//now we've got a cluster with areas through which an alternative route could go
//get the 'center' of the cluster
VectorClear(mid);
for (j = 0; j < numclusterareas; j++)
{
VectorAdd(mid, aasworld.areas[clusterareas[j]].center, mid);
} //end for
VectorScale(mid, 1.0 / numclusterareas, mid);
//get the area closest to the center of the cluster
bestdist = 999999;
bestareanum = 0;
for (j = 0; j < numclusterareas; j++)
{
VectorSubtract(mid, aasworld.areas[clusterareas[j]].center, dir);
dist = VectorLength(dir);
if (dist < bestdist)
{
bestdist = dist;
bestareanum = clusterareas[j];
} //end if
} //end for
//now we've got an area for an alternative route
//FIXME: add alternative goal origin
VectorCopy(aasworld.areas[bestareanum].center, altroutegoals[numaltroutegoals].origin);
altroutegoals[numaltroutegoals].areanum = bestareanum;
altroutegoals[numaltroutegoals].starttraveltime = midrangeareas[bestareanum].starttime;
altroutegoals[numaltroutegoals].goaltraveltime = midrangeareas[bestareanum].goaltime;
altroutegoals[numaltroutegoals].extratraveltime =
(midrangeareas[bestareanum].starttime + midrangeareas[bestareanum].goaltime) -
goaltraveltime;
numaltroutegoals++;
//
#ifdef ALTROUTE_DEBUG
AAS_ShowAreaPolygons(bestareanum, 1, qtrue);
#endif
//don't return more than the maximum alternative route goals
if (numaltroutegoals >= maxaltroutegoals) break;
} //end for
#ifdef ALTROUTE_DEBUG
botimport.Print(PRT_MESSAGE, "alternative route goals in %d msec\n", Sys_MilliSeconds() - startmillisecs);
#endif
return numaltroutegoals;
#endif
} //end of the function AAS_AlternativeRouteGoals
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_InitAlternativeRouting(void)
{
#ifdef ENABLE_ALTROUTING
if (midrangeareas) FreeMemory(midrangeareas);
midrangeareas = (midrangearea_t *) GetMemory(aasworld.numareas * sizeof(midrangearea_t));
if (clusterareas) FreeMemory(clusterareas);
clusterareas = (int *) GetMemory(aasworld.numareas * sizeof(int));
#endif
} //end of the function AAS_InitAlternativeRouting
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ShutdownAlternativeRouting(void)
{
#ifdef ENABLE_ALTROUTING
if (midrangeareas) FreeMemory(midrangeareas);
midrangeareas = NULL;
if (clusterareas) FreeMemory(clusterareas);
clusterareas = NULL;
numclusterareas = 0;
#endif
} //end of the function AAS_ShutdownAlternativeRouting
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_routealt.c
*
* desc: AAS
*
* $Archive: /MissionPack/code/botlib/be_aas_routealt.c $
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_utils.h"
#include "l_memory.h"
#include "l_log.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_interface.h"
#include "be_aas_def.h"
#define ENABLE_ALTROUTING
//#define ALTROUTE_DEBUG
typedef struct midrangearea_s
{
int valid;
unsigned short starttime;
unsigned short goaltime;
} midrangearea_t;
midrangearea_t *midrangeareas;
int *clusterareas;
int numclusterareas;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_AltRoutingFloodCluster_r(int areanum)
{
int i, otherareanum;
aas_area_t *area;
aas_face_t *face;
//add the current area to the areas of the current cluster
clusterareas[numclusterareas] = areanum;
numclusterareas++;
//remove the area from the mid range areas
midrangeareas[areanum].valid = qfalse;
//flood to other areas through the faces of this area
area = &aasworld.areas[areanum];
for (i = 0; i < area->numfaces; i++)
{
face = &aasworld.faces[abs(aasworld.faceindex[area->firstface + i])];
//get the area at the other side of the face
if (face->frontarea == areanum) otherareanum = face->backarea;
else otherareanum = face->frontarea;
//if there is an area at the other side of this face
if (!otherareanum) continue;
//if the other area is not a midrange area
if (!midrangeareas[otherareanum].valid) continue;
//
AAS_AltRoutingFloodCluster_r(otherareanum);
} //end for
} //end of the function AAS_AltRoutingFloodCluster_r
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_AlternativeRouteGoals(vec3_t start, int startareanum, vec3_t goal, int goalareanum, int travelflags,
aas_altroutegoal_t *altroutegoals, int maxaltroutegoals,
int type)
{
#ifndef ENABLE_ALTROUTING
return 0;
#else
int i, j, bestareanum;
int numaltroutegoals, nummidrangeareas;
int starttime, goaltime, goaltraveltime;
float dist, bestdist;
vec3_t mid, dir;
#ifdef ALTROUTE_DEBUG
int startmillisecs;
startmillisecs = Sys_MilliSeconds();
#endif
if (!startareanum || !goalareanum)
return 0;
//travel time towards the goal area
goaltraveltime = AAS_AreaTravelTimeToGoalArea(startareanum, start, goalareanum, travelflags);
//clear the midrange areas
Com_Memset(midrangeareas, 0, aasworld.numareas * sizeof(midrangearea_t));
numaltroutegoals = 0;
//
nummidrangeareas = 0;
//
for (i = 1; i < aasworld.numareas; i++)
{
//
if (!(type & ALTROUTEGOAL_ALL))
{
if (!(type & ALTROUTEGOAL_CLUSTERPORTALS && (aasworld.areasettings[i].contents & AREACONTENTS_CLUSTERPORTAL)))
{
if (!(type & ALTROUTEGOAL_VIEWPORTALS && (aasworld.areasettings[i].contents & AREACONTENTS_VIEWPORTAL)))
{
continue;
} //end if
} //end if
} //end if
//if the area has no reachabilities
if (!AAS_AreaReachability(i)) continue;
//tavel time from the area to the start area
starttime = AAS_AreaTravelTimeToGoalArea(startareanum, start, i, travelflags);
if (!starttime) continue;
//if the travel time from the start to the area is greater than the shortest goal travel time
if (starttime > (float) 1.1 * goaltraveltime) continue;
//travel time from the area to the goal area
goaltime = AAS_AreaTravelTimeToGoalArea(i, NULL, goalareanum, travelflags);
if (!goaltime) continue;
//if the travel time from the area to the goal is greater than the shortest goal travel time
if (goaltime > (float) 0.8 * goaltraveltime) continue;
//this is a mid range area
midrangeareas[i].valid = qtrue;
midrangeareas[i].starttime = starttime;
midrangeareas[i].goaltime = goaltime;
Log_Write("%d midrange area %d", nummidrangeareas, i);
nummidrangeareas++;
} //end for
//
for (i = 1; i < aasworld.numareas; i++)
{
if (!midrangeareas[i].valid) continue;
//get the areas in one cluster
numclusterareas = 0;
AAS_AltRoutingFloodCluster_r(i);
//now we've got a cluster with areas through which an alternative route could go
//get the 'center' of the cluster
VectorClear(mid);
for (j = 0; j < numclusterareas; j++)
{
VectorAdd(mid, aasworld.areas[clusterareas[j]].center, mid);
} //end for
VectorScale(mid, 1.0 / numclusterareas, mid);
//get the area closest to the center of the cluster
bestdist = 999999;
bestareanum = 0;
for (j = 0; j < numclusterareas; j++)
{
VectorSubtract(mid, aasworld.areas[clusterareas[j]].center, dir);
dist = VectorLength(dir);
if (dist < bestdist)
{
bestdist = dist;
bestareanum = clusterareas[j];
} //end if
} //end for
//now we've got an area for an alternative route
//FIXME: add alternative goal origin
VectorCopy(aasworld.areas[bestareanum].center, altroutegoals[numaltroutegoals].origin);
altroutegoals[numaltroutegoals].areanum = bestareanum;
altroutegoals[numaltroutegoals].starttraveltime = midrangeareas[bestareanum].starttime;
altroutegoals[numaltroutegoals].goaltraveltime = midrangeareas[bestareanum].goaltime;
altroutegoals[numaltroutegoals].extratraveltime =
(midrangeareas[bestareanum].starttime + midrangeareas[bestareanum].goaltime) -
goaltraveltime;
numaltroutegoals++;
//
#ifdef ALTROUTE_DEBUG
AAS_ShowAreaPolygons(bestareanum, 1, qtrue);
#endif
//don't return more than the maximum alternative route goals
if (numaltroutegoals >= maxaltroutegoals) break;
} //end for
#ifdef ALTROUTE_DEBUG
botimport.Print(PRT_MESSAGE, "alternative route goals in %d msec\n", Sys_MilliSeconds() - startmillisecs);
#endif
return numaltroutegoals;
#endif
} //end of the function AAS_AlternativeRouteGoals
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_InitAlternativeRouting(void)
{
#ifdef ENABLE_ALTROUTING
if (midrangeareas) FreeMemory(midrangeareas);
midrangeareas = (midrangearea_t *) GetMemory(aasworld.numareas * sizeof(midrangearea_t));
if (clusterareas) FreeMemory(clusterareas);
clusterareas = (int *) GetMemory(aasworld.numareas * sizeof(int));
#endif
} //end of the function AAS_InitAlternativeRouting
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ShutdownAlternativeRouting(void)
{
#ifdef ENABLE_ALTROUTING
if (midrangeareas) FreeMemory(midrangeareas);
midrangeareas = NULL;
if (clusterareas) FreeMemory(clusterareas);
clusterareas = NULL;
numclusterareas = 0;
#endif
} //end of the function AAS_ShutdownAlternativeRouting

80
code/botlib/be_aas_routealt.h Normal file → Executable file
View file

@ -1,40 +1,40 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_routealt.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_routealt.h $
*
*****************************************************************************/
#ifdef AASINTERN
void AAS_InitAlternativeRouting(void);
void AAS_ShutdownAlternativeRouting(void);
#endif //AASINTERN
int AAS_AlternativeRouteGoals(vec3_t start, int startareanum, vec3_t goal, int goalareanum, int travelflags,
aas_altroutegoal_t *altroutegoals, int maxaltroutegoals,
int type);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_routealt.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_routealt.h $
*
*****************************************************************************/
#ifdef AASINTERN
void AAS_InitAlternativeRouting(void);
void AAS_ShutdownAlternativeRouting(void);
#endif //AASINTERN
int AAS_AlternativeRouteGoals(vec3_t start, int startareanum, vec3_t goal, int goalareanum, int travelflags,
aas_altroutegoal_t *altroutegoals, int maxaltroutegoals,
int type);

2788
code/botlib/be_aas_sample.c Normal file → Executable file

File diff suppressed because it is too large Load diff

138
code/botlib/be_aas_sample.h Normal file → Executable file
View file

@ -1,69 +1,69 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_sample.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_sample.h $
*
*****************************************************************************/
#ifdef AASINTERN
void AAS_InitAASLinkHeap(void);
void AAS_InitAASLinkedEntities(void);
void AAS_FreeAASLinkHeap(void);
void AAS_FreeAASLinkedEntities(void);
aas_face_t *AAS_AreaGroundFace(int areanum, vec3_t point);
aas_face_t *AAS_TraceEndFace(aas_trace_t *trace);
aas_plane_t *AAS_PlaneFromNum(int planenum);
aas_link_t *AAS_AASLinkEntity(vec3_t absmins, vec3_t absmaxs, int entnum);
aas_link_t *AAS_LinkEntityClientBBox(vec3_t absmins, vec3_t absmaxs, int entnum, int presencetype);
qboolean AAS_PointInsideFace(int facenum, vec3_t point, float epsilon);
qboolean AAS_InsideFace(aas_face_t *face, vec3_t pnormal, vec3_t point, float epsilon);
void AAS_UnlinkFromAreas(aas_link_t *areas);
#endif //AASINTERN
//returns the mins and maxs of the bounding box for the given presence type
void AAS_PresenceTypeBoundingBox(int presencetype, vec3_t mins, vec3_t maxs);
//returns the cluster the area is in (negative portal number if the area is a portal)
int AAS_AreaCluster(int areanum);
//returns the presence type(s) of the area
int AAS_AreaPresenceType(int areanum);
//returns the presence type(s) at the given point
int AAS_PointPresenceType(vec3_t point);
//returns the result of the trace of a client bbox
aas_trace_t AAS_TraceClientBBox(vec3_t start, vec3_t end, int presencetype, int passent);
//stores the areas the trace went through and returns the number of passed areas
int AAS_TraceAreas(vec3_t start, vec3_t end, int *areas, vec3_t *points, int maxareas);
//returns the areas the bounding box is in
int AAS_BBoxAreas(vec3_t absmins, vec3_t absmaxs, int *areas, int maxareas);
//return area information
int AAS_AreaInfo( int areanum, aas_areainfo_t *info );
//returns the area the point is in
int AAS_PointAreaNum(vec3_t point);
//
int AAS_PointReachabilityAreaIndex( vec3_t point );
//returns the plane the given face is in
void AAS_FacePlane(int facenum, vec3_t normal, float *dist);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_aas_sample.h
*
* desc: AAS
*
* $Archive: /source/code/botlib/be_aas_sample.h $
*
*****************************************************************************/
#ifdef AASINTERN
void AAS_InitAASLinkHeap(void);
void AAS_InitAASLinkedEntities(void);
void AAS_FreeAASLinkHeap(void);
void AAS_FreeAASLinkedEntities(void);
aas_face_t *AAS_AreaGroundFace(int areanum, vec3_t point);
aas_face_t *AAS_TraceEndFace(aas_trace_t *trace);
aas_plane_t *AAS_PlaneFromNum(int planenum);
aas_link_t *AAS_AASLinkEntity(vec3_t absmins, vec3_t absmaxs, int entnum);
aas_link_t *AAS_LinkEntityClientBBox(vec3_t absmins, vec3_t absmaxs, int entnum, int presencetype);
qboolean AAS_PointInsideFace(int facenum, vec3_t point, float epsilon);
qboolean AAS_InsideFace(aas_face_t *face, vec3_t pnormal, vec3_t point, float epsilon);
void AAS_UnlinkFromAreas(aas_link_t *areas);
#endif //AASINTERN
//returns the mins and maxs of the bounding box for the given presence type
void AAS_PresenceTypeBoundingBox(int presencetype, vec3_t mins, vec3_t maxs);
//returns the cluster the area is in (negative portal number if the area is a portal)
int AAS_AreaCluster(int areanum);
//returns the presence type(s) of the area
int AAS_AreaPresenceType(int areanum);
//returns the presence type(s) at the given point
int AAS_PointPresenceType(vec3_t point);
//returns the result of the trace of a client bbox
aas_trace_t AAS_TraceClientBBox(vec3_t start, vec3_t end, int presencetype, int passent);
//stores the areas the trace went through and returns the number of passed areas
int AAS_TraceAreas(vec3_t start, vec3_t end, int *areas, vec3_t *points, int maxareas);
//returns the areas the bounding box is in
int AAS_BBoxAreas(vec3_t absmins, vec3_t absmaxs, int *areas, int maxareas);
//return area information
int AAS_AreaInfo( int areanum, aas_areainfo_t *info );
//returns the area the point is in
int AAS_PointAreaNum(vec3_t point);
//
int AAS_PointReachabilityAreaIndex( vec3_t point );
//returns the plane the given face is in
void AAS_FacePlane(int facenum, vec3_t normal, float *dist);

1580
code/botlib/be_ai_char.c Normal file → Executable file

File diff suppressed because it is too large Load diff

6034
code/botlib/be_ai_chat.c Normal file → Executable file

File diff suppressed because it is too large Load diff

268
code/botlib/be_ai_gen.c Normal file → Executable file
View file

@ -1,134 +1,134 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_ai_gen.c
*
* desc: genetic selection
*
* $Archive: /MissionPack/code/botlib/be_ai_gen.c $
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_memory.h"
#include "l_log.h"
#include "l_utils.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_interface.h"
#include "../game/be_ai_gen.h"
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int GeneticSelection(int numranks, float *rankings)
{
float sum, select;
int i, index;
sum = 0;
for (i = 0; i < numranks; i++)
{
if (rankings[i] < 0) continue;
sum += rankings[i];
} //end for
if (sum > 0)
{
//select a bot where the ones with the higest rankings have
//the highest chance of being selected
select = random() * sum;
for (i = 0; i < numranks; i++)
{
if (rankings[i] < 0) continue;
sum -= rankings[i];
if (sum <= 0) return i;
} //end for
} //end if
//select a bot randomly
index = random() * numranks;
for (i = 0; i < numranks; i++)
{
if (rankings[index] >= 0) return index;
index = (index + 1) % numranks;
} //end for
return 0;
} //end of the function GeneticSelection
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int GeneticParentsAndChildSelection(int numranks, float *ranks, int *parent1, int *parent2, int *child)
{
float rankings[256], max;
int i;
if (numranks > 256)
{
botimport.Print(PRT_WARNING, "GeneticParentsAndChildSelection: too many bots\n");
*parent1 = *parent2 = *child = 0;
return qfalse;
} //end if
for (max = 0, i = 0; i < numranks; i++)
{
if (ranks[i] < 0) continue;
max++;
} //end for
if (max < 3)
{
botimport.Print(PRT_WARNING, "GeneticParentsAndChildSelection: too few valid bots\n");
*parent1 = *parent2 = *child = 0;
return qfalse;
} //end if
Com_Memcpy(rankings, ranks, sizeof(float) * numranks);
//select first parent
*parent1 = GeneticSelection(numranks, rankings);
rankings[*parent1] = -1;
//select second parent
*parent2 = GeneticSelection(numranks, rankings);
rankings[*parent2] = -1;
//reverse the rankings
max = 0;
for (i = 0; i < numranks; i++)
{
if (rankings[i] < 0) continue;
if (rankings[i] > max) max = rankings[i];
} //end for
for (i = 0; i < numranks; i++)
{
if (rankings[i] < 0) continue;
rankings[i] = max - rankings[i];
} //end for
//select child
*child = GeneticSelection(numranks, rankings);
return qtrue;
} //end of the function GeneticParentsAndChildSelection
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_ai_gen.c
*
* desc: genetic selection
*
* $Archive: /MissionPack/code/botlib/be_ai_gen.c $
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_memory.h"
#include "l_log.h"
#include "l_utils.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_interface.h"
#include "../game/be_ai_gen.h"
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int GeneticSelection(int numranks, float *rankings)
{
float sum, select;
int i, index;
sum = 0;
for (i = 0; i < numranks; i++)
{
if (rankings[i] < 0) continue;
sum += rankings[i];
} //end for
if (sum > 0)
{
//select a bot where the ones with the higest rankings have
//the highest chance of being selected
select = random() * sum;
for (i = 0; i < numranks; i++)
{
if (rankings[i] < 0) continue;
sum -= rankings[i];
if (sum <= 0) return i;
} //end for
} //end if
//select a bot randomly
index = random() * numranks;
for (i = 0; i < numranks; i++)
{
if (rankings[index] >= 0) return index;
index = (index + 1) % numranks;
} //end for
return 0;
} //end of the function GeneticSelection
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int GeneticParentsAndChildSelection(int numranks, float *ranks, int *parent1, int *parent2, int *child)
{
float rankings[256], max;
int i;
if (numranks > 256)
{
botimport.Print(PRT_WARNING, "GeneticParentsAndChildSelection: too many bots\n");
*parent1 = *parent2 = *child = 0;
return qfalse;
} //end if
for (max = 0, i = 0; i < numranks; i++)
{
if (ranks[i] < 0) continue;
max++;
} //end for
if (max < 3)
{
botimport.Print(PRT_WARNING, "GeneticParentsAndChildSelection: too few valid bots\n");
*parent1 = *parent2 = *child = 0;
return qfalse;
} //end if
Com_Memcpy(rankings, ranks, sizeof(float) * numranks);
//select first parent
*parent1 = GeneticSelection(numranks, rankings);
rankings[*parent1] = -1;
//select second parent
*parent2 = GeneticSelection(numranks, rankings);
rankings[*parent2] = -1;
//reverse the rankings
max = 0;
for (i = 0; i < numranks; i++)
{
if (rankings[i] < 0) continue;
if (rankings[i] > max) max = rankings[i];
} //end for
for (i = 0; i < numranks; i++)
{
if (rankings[i] < 0) continue;
rankings[i] = max - rankings[i];
} //end for
//select child
*child = GeneticSelection(numranks, rankings);
return qtrue;
} //end of the function GeneticParentsAndChildSelection

3642
code/botlib/be_ai_goal.c Normal file → Executable file

File diff suppressed because it is too large Load diff

7220
code/botlib/be_ai_move.c Normal file → Executable file

File diff suppressed because it is too large Load diff

1086
code/botlib/be_ai_weap.c Normal file → Executable file

File diff suppressed because it is too large Load diff

1824
code/botlib/be_ai_weight.c Normal file → Executable file

File diff suppressed because it is too large Load diff

166
code/botlib/be_ai_weight.h Normal file → Executable file
View file

@ -1,83 +1,83 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_ai_weight.h
*
* desc: fuzzy weights
*
* $Archive: /source/code/botlib/be_ai_weight.h $
*
*****************************************************************************/
#define WT_BALANCE 1
#define MAX_WEIGHTS 128
//fuzzy seperator
typedef struct fuzzyseperator_s
{
int index;
int value;
int type;
float weight;
float minweight;
float maxweight;
struct fuzzyseperator_s *child;
struct fuzzyseperator_s *next;
} fuzzyseperator_t;
//fuzzy weight
typedef struct weight_s
{
char *name;
struct fuzzyseperator_s *firstseperator;
} weight_t;
//weight configuration
typedef struct weightconfig_s
{
int numweights;
weight_t weights[MAX_WEIGHTS];
char filename[MAX_QPATH];
} weightconfig_t;
//reads a weight configuration
weightconfig_t *ReadWeightConfig(char *filename);
//free a weight configuration
void FreeWeightConfig(weightconfig_t *config);
//writes a weight configuration, returns true if successfull
qboolean WriteWeightConfig(char *filename, weightconfig_t *config);
//find the fuzzy weight with the given name
int FindFuzzyWeight(weightconfig_t *wc, char *name);
//returns the fuzzy weight for the given inventory and weight
float FuzzyWeight(int *inventory, weightconfig_t *wc, int weightnum);
float FuzzyWeightUndecided(int *inventory, weightconfig_t *wc, int weightnum);
//scales the weight with the given name
void ScaleWeight(weightconfig_t *config, char *name, float scale);
//scale the balance range
void ScaleBalanceRange(weightconfig_t *config, float scale);
//evolves the weight configuration
void EvolveWeightConfig(weightconfig_t *config);
//interbreed the weight configurations and stores the interbreeded one in configout
void InterbreedWeightConfigs(weightconfig_t *config1, weightconfig_t *config2, weightconfig_t *configout);
//frees cached weight configurations
void BotShutdownWeights(void);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_ai_weight.h
*
* desc: fuzzy weights
*
* $Archive: /source/code/botlib/be_ai_weight.h $
*
*****************************************************************************/
#define WT_BALANCE 1
#define MAX_WEIGHTS 128
//fuzzy seperator
typedef struct fuzzyseperator_s
{
int index;
int value;
int type;
float weight;
float minweight;
float maxweight;
struct fuzzyseperator_s *child;
struct fuzzyseperator_s *next;
} fuzzyseperator_t;
//fuzzy weight
typedef struct weight_s
{
char *name;
struct fuzzyseperator_s *firstseperator;
} weight_t;
//weight configuration
typedef struct weightconfig_s
{
int numweights;
weight_t weights[MAX_WEIGHTS];
char filename[MAX_QPATH];
} weightconfig_t;
//reads a weight configuration
weightconfig_t *ReadWeightConfig(char *filename);
//free a weight configuration
void FreeWeightConfig(weightconfig_t *config);
//writes a weight configuration, returns true if successfull
qboolean WriteWeightConfig(char *filename, weightconfig_t *config);
//find the fuzzy weight with the given name
int FindFuzzyWeight(weightconfig_t *wc, char *name);
//returns the fuzzy weight for the given inventory and weight
float FuzzyWeight(int *inventory, weightconfig_t *wc, int weightnum);
float FuzzyWeightUndecided(int *inventory, weightconfig_t *wc, int weightnum);
//scales the weight with the given name
void ScaleWeight(weightconfig_t *config, char *name, float scale);
//scale the balance range
void ScaleBalanceRange(weightconfig_t *config, float scale);
//evolves the weight configuration
void EvolveWeightConfig(weightconfig_t *config);
//interbreed the weight configurations and stores the interbreeded one in configout
void InterbreedWeightConfigs(weightconfig_t *config1, weightconfig_t *config2, weightconfig_t *configout);
//frees cached weight configurations
void BotShutdownWeights(void);

1016
code/botlib/be_ea.c Normal file → Executable file

File diff suppressed because it is too large Load diff

1762
code/botlib/be_interface.c Normal file → Executable file

File diff suppressed because it is too large Load diff

114
code/botlib/be_interface.h Normal file → Executable file
View file

@ -1,57 +1,57 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_interface.h
*
* desc: botlib interface
*
* $Archive: /source/code/botlib/be_interface.h $
*
*****************************************************************************/
//#define DEBUG //debug code
#define RANDOMIZE //randomize bot behaviour
//FIXME: get rid of this global structure
typedef struct botlib_globals_s
{
int botlibsetup; //true when the bot library has been setup
int maxentities; //maximum number of entities
int maxclients; //maximum number of clients
float time; //the global time
#ifdef DEBUG
qboolean debug; //true if debug is on
int goalareanum;
vec3_t goalorigin;
int runai;
#endif
} botlib_globals_t;
extern botlib_globals_t botlibglobals;
extern botlib_import_t botimport;
extern int bot_developer; //true if developer is on
//
int Sys_MilliSeconds(void);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: be_interface.h
*
* desc: botlib interface
*
* $Archive: /source/code/botlib/be_interface.h $
*
*****************************************************************************/
//#define DEBUG //debug code
#define RANDOMIZE //randomize bot behaviour
//FIXME: get rid of this global structure
typedef struct botlib_globals_s
{
int botlibsetup; //true when the bot library has been setup
int maxentities; //maximum number of entities
int maxclients; //maximum number of clients
float time; //the global time
#ifdef DEBUG
qboolean debug; //true if debug is on
int goalareanum;
vec3_t goalorigin;
int runai;
#endif
} botlib_globals_t;
extern botlib_globals_t botlibglobals;
extern botlib_import_t botimport;
extern int bot_developer; //true if developer is on
//
int Sys_MilliSeconds(void);

3118
code/botlib/botlib.vcproj Normal file → Executable file

File diff suppressed because it is too large Load diff

302
code/botlib/l_crc.c Normal file → Executable file
View file

@ -1,151 +1,151 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: l_crc.c
*
* desc: CRC calculation
*
* $Archive: /MissionPack/CODE/botlib/l_crc.c $
*
*****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "../game/q_shared.h"
#include "../game/botlib.h"
#include "be_interface.h" //for botimport.Print
// FIXME: byte swap?
// this is a 16 bit, non-reflected CRC using the polynomial 0x1021
// and the initial and final xor values shown below... in other words, the
// CCITT standard CRC used by XMODEM
#define CRC_INIT_VALUE 0xffff
#define CRC_XOR_VALUE 0x0000
unsigned short crctable[257] =
{
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void CRC_Init(unsigned short *crcvalue)
{
*crcvalue = CRC_INIT_VALUE;
} //end of the function CRC_Init
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void CRC_ProcessByte(unsigned short *crcvalue, byte data)
{
*crcvalue = (*crcvalue << 8) ^ crctable[(*crcvalue >> 8) ^ data];
} //end of the function CRC_ProcessByte
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
unsigned short CRC_Value(unsigned short crcvalue)
{
return crcvalue ^ CRC_XOR_VALUE;
} //end of the function CRC_Value
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
unsigned short CRC_ProcessString(unsigned char *data, int length)
{
unsigned short crcvalue;
int i, ind;
CRC_Init(&crcvalue);
for (i = 0; i < length; i++)
{
ind = (crcvalue >> 8) ^ data[i];
if (ind < 0 || ind > 256) ind = 0;
crcvalue = (crcvalue << 8) ^ crctable[ind];
} //end for
return CRC_Value(crcvalue);
} //end of the function CRC_ProcessString
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void CRC_ContinueProcessString(unsigned short *crc, char *data, int length)
{
int i;
for (i = 0; i < length; i++)
{
*crc = (*crc << 8) ^ crctable[(*crc >> 8) ^ data[i]];
} //end for
} //end of the function CRC_ProcessString
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: l_crc.c
*
* desc: CRC calculation
*
* $Archive: /MissionPack/CODE/botlib/l_crc.c $
*
*****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "../game/q_shared.h"
#include "../game/botlib.h"
#include "be_interface.h" //for botimport.Print
// FIXME: byte swap?
// this is a 16 bit, non-reflected CRC using the polynomial 0x1021
// and the initial and final xor values shown below... in other words, the
// CCITT standard CRC used by XMODEM
#define CRC_INIT_VALUE 0xffff
#define CRC_XOR_VALUE 0x0000
unsigned short crctable[257] =
{
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void CRC_Init(unsigned short *crcvalue)
{
*crcvalue = CRC_INIT_VALUE;
} //end of the function CRC_Init
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void CRC_ProcessByte(unsigned short *crcvalue, byte data)
{
*crcvalue = (*crcvalue << 8) ^ crctable[(*crcvalue >> 8) ^ data];
} //end of the function CRC_ProcessByte
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
unsigned short CRC_Value(unsigned short crcvalue)
{
return crcvalue ^ CRC_XOR_VALUE;
} //end of the function CRC_Value
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
unsigned short CRC_ProcessString(unsigned char *data, int length)
{
unsigned short crcvalue;
int i, ind;
CRC_Init(&crcvalue);
for (i = 0; i < length; i++)
{
ind = (crcvalue >> 8) ^ data[i];
if (ind < 0 || ind > 256) ind = 0;
crcvalue = (crcvalue << 8) ^ crctable[ind];
} //end for
return CRC_Value(crcvalue);
} //end of the function CRC_ProcessString
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void CRC_ContinueProcessString(unsigned short *crc, char *data, int length)
{
int i;
for (i = 0; i < length; i++)
{
*crc = (*crc << 8) ^ crctable[(*crc >> 8) ^ data[i]];
} //end for
} //end of the function CRC_ProcessString

58
code/botlib/l_crc.h Normal file → Executable file
View file

@ -1,29 +1,29 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
typedef unsigned short crc_t;
void CRC_Init(unsigned short *crcvalue);
void CRC_ProcessByte(unsigned short *crcvalue, byte data);
unsigned short CRC_Value(unsigned short crcvalue);
unsigned short CRC_ProcessString(unsigned char *data, int length);
void CRC_ContinueProcessString(unsigned short *crc, char *data, int length);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
typedef unsigned short crc_t;
void CRC_Init(unsigned short *crcvalue);
void CRC_ProcessByte(unsigned short *crcvalue, byte data);
unsigned short CRC_Value(unsigned short crcvalue);
unsigned short CRC_ProcessString(unsigned char *data, int length);
void CRC_ContinueProcessString(unsigned short *crc, char *data, int length);

588
code/botlib/l_libvar.c Normal file → Executable file
View file

@ -1,294 +1,294 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: l_libvar.c
*
* desc: bot library variables
*
* $Archive: /MissionPack/code/botlib/l_libvar.c $
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_memory.h"
#include "l_libvar.h"
//list with library variables
libvar_t *libvarlist;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
float LibVarStringValue(char *string)
{
int dotfound = 0;
float value = 0;
while(*string)
{
if (*string < '0' || *string > '9')
{
if (dotfound || *string != '.')
{
return 0;
} //end if
else
{
dotfound = 10;
string++;
} //end if
} //end if
if (dotfound)
{
value = value + (float) (*string - '0') / (float) dotfound;
dotfound *= 10;
} //end if
else
{
value = value * 10.0 + (float) (*string - '0');
} //end else
string++;
} //end while
return value;
} //end of the function LibVarStringValue
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
libvar_t *LibVarAlloc(char *var_name)
{
libvar_t *v;
v = (libvar_t *) GetMemory(sizeof(libvar_t) + strlen(var_name) + 1);
Com_Memset(v, 0, sizeof(libvar_t));
v->name = (char *) v + sizeof(libvar_t);
strcpy(v->name, var_name);
//add the variable in the list
v->next = libvarlist;
libvarlist = v;
return v;
} //end of the function LibVarAlloc
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void LibVarDeAlloc(libvar_t *v)
{
if (v->string) FreeMemory(v->string);
FreeMemory(v);
} //end of the function LibVarDeAlloc
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void LibVarDeAllocAll(void)
{
libvar_t *v;
for (v = libvarlist; v; v = libvarlist)
{
libvarlist = libvarlist->next;
LibVarDeAlloc(v);
} //end for
libvarlist = NULL;
} //end of the function LibVarDeAllocAll
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
libvar_t *LibVarGet(char *var_name)
{
libvar_t *v;
for (v = libvarlist; v; v = v->next)
{
if (!Q_stricmp(v->name, var_name))
{
return v;
} //end if
} //end for
return NULL;
} //end of the function LibVarGet
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
char *LibVarGetString(char *var_name)
{
libvar_t *v;
v = LibVarGet(var_name);
if (v)
{
return v->string;
} //end if
else
{
return "";
} //end else
} //end of the function LibVarGetString
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
float LibVarGetValue(char *var_name)
{
libvar_t *v;
v = LibVarGet(var_name);
if (v)
{
return v->value;
} //end if
else
{
return 0;
} //end else
} //end of the function LibVarGetValue
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
libvar_t *LibVar(char *var_name, char *value)
{
libvar_t *v;
v = LibVarGet(var_name);
if (v) return v;
//create new variable
v = LibVarAlloc(var_name);
//variable string
v->string = (char *) GetMemory(strlen(value) + 1);
strcpy(v->string, value);
//the value
v->value = LibVarStringValue(v->string);
//variable is modified
v->modified = qtrue;
//
return v;
} //end of the function LibVar
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
char *LibVarString(char *var_name, char *value)
{
libvar_t *v;
v = LibVar(var_name, value);
return v->string;
} //end of the function LibVarString
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
float LibVarValue(char *var_name, char *value)
{
libvar_t *v;
v = LibVar(var_name, value);
return v->value;
} //end of the function LibVarValue
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void LibVarSet(char *var_name, char *value)
{
libvar_t *v;
v = LibVarGet(var_name);
if (v)
{
FreeMemory(v->string);
} //end if
else
{
v = LibVarAlloc(var_name);
} //end else
//variable string
v->string = (char *) GetMemory(strlen(value) + 1);
strcpy(v->string, value);
//the value
v->value = LibVarStringValue(v->string);
//variable is modified
v->modified = qtrue;
} //end of the function LibVarSet
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean LibVarChanged(char *var_name)
{
libvar_t *v;
v = LibVarGet(var_name);
if (v)
{
return v->modified;
} //end if
else
{
return qfalse;
} //end else
} //end of the function LibVarChanged
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void LibVarSetNotModified(char *var_name)
{
libvar_t *v;
v = LibVarGet(var_name);
if (v)
{
v->modified = qfalse;
} //end if
} //end of the function LibVarSetNotModified
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: l_libvar.c
*
* desc: bot library variables
*
* $Archive: /MissionPack/code/botlib/l_libvar.c $
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_memory.h"
#include "l_libvar.h"
//list with library variables
libvar_t *libvarlist;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
float LibVarStringValue(char *string)
{
int dotfound = 0;
float value = 0;
while(*string)
{
if (*string < '0' || *string > '9')
{
if (dotfound || *string != '.')
{
return 0;
} //end if
else
{
dotfound = 10;
string++;
} //end if
} //end if
if (dotfound)
{
value = value + (float) (*string - '0') / (float) dotfound;
dotfound *= 10;
} //end if
else
{
value = value * 10.0 + (float) (*string - '0');
} //end else
string++;
} //end while
return value;
} //end of the function LibVarStringValue
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
libvar_t *LibVarAlloc(char *var_name)
{
libvar_t *v;
v = (libvar_t *) GetMemory(sizeof(libvar_t) + strlen(var_name) + 1);
Com_Memset(v, 0, sizeof(libvar_t));
v->name = (char *) v + sizeof(libvar_t);
strcpy(v->name, var_name);
//add the variable in the list
v->next = libvarlist;
libvarlist = v;
return v;
} //end of the function LibVarAlloc
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void LibVarDeAlloc(libvar_t *v)
{
if (v->string) FreeMemory(v->string);
FreeMemory(v);
} //end of the function LibVarDeAlloc
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void LibVarDeAllocAll(void)
{
libvar_t *v;
for (v = libvarlist; v; v = libvarlist)
{
libvarlist = libvarlist->next;
LibVarDeAlloc(v);
} //end for
libvarlist = NULL;
} //end of the function LibVarDeAllocAll
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
libvar_t *LibVarGet(char *var_name)
{
libvar_t *v;
for (v = libvarlist; v; v = v->next)
{
if (!Q_stricmp(v->name, var_name))
{
return v;
} //end if
} //end for
return NULL;
} //end of the function LibVarGet
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
char *LibVarGetString(char *var_name)
{
libvar_t *v;
v = LibVarGet(var_name);
if (v)
{
return v->string;
} //end if
else
{
return "";
} //end else
} //end of the function LibVarGetString
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
float LibVarGetValue(char *var_name)
{
libvar_t *v;
v = LibVarGet(var_name);
if (v)
{
return v->value;
} //end if
else
{
return 0;
} //end else
} //end of the function LibVarGetValue
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
libvar_t *LibVar(char *var_name, char *value)
{
libvar_t *v;
v = LibVarGet(var_name);
if (v) return v;
//create new variable
v = LibVarAlloc(var_name);
//variable string
v->string = (char *) GetMemory(strlen(value) + 1);
strcpy(v->string, value);
//the value
v->value = LibVarStringValue(v->string);
//variable is modified
v->modified = qtrue;
//
return v;
} //end of the function LibVar
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
char *LibVarString(char *var_name, char *value)
{
libvar_t *v;
v = LibVar(var_name, value);
return v->string;
} //end of the function LibVarString
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
float LibVarValue(char *var_name, char *value)
{
libvar_t *v;
v = LibVar(var_name, value);
return v->value;
} //end of the function LibVarValue
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void LibVarSet(char *var_name, char *value)
{
libvar_t *v;
v = LibVarGet(var_name);
if (v)
{
FreeMemory(v->string);
} //end if
else
{
v = LibVarAlloc(var_name);
} //end else
//variable string
v->string = (char *) GetMemory(strlen(value) + 1);
strcpy(v->string, value);
//the value
v->value = LibVarStringValue(v->string);
//variable is modified
v->modified = qtrue;
} //end of the function LibVarSet
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean LibVarChanged(char *var_name)
{
libvar_t *v;
v = LibVarGet(var_name);
if (v)
{
return v->modified;
} //end if
else
{
return qfalse;
} //end else
} //end of the function LibVarChanged
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void LibVarSetNotModified(char *var_name)
{
libvar_t *v;
v = LibVarGet(var_name);
if (v)
{
v->modified = qfalse;
} //end if
} //end of the function LibVarSetNotModified

126
code/botlib/l_libvar.h Normal file → Executable file
View file

@ -1,63 +1,63 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: l_libvar.h
*
* desc: botlib vars
*
* $Archive: /source/code/botlib/l_libvar.h $
*
*****************************************************************************/
//library variable
typedef struct libvar_s
{
char *name;
char *string;
int flags;
qboolean modified; // set each time the cvar is changed
float value;
struct libvar_s *next;
} libvar_t;
//removes all library variables
void LibVarDeAllocAll(void);
//gets the library variable with the given name
libvar_t *LibVarGet(char *var_name);
//gets the string of the library variable with the given name
char *LibVarGetString(char *var_name);
//gets the value of the library variable with the given name
float LibVarGetValue(char *var_name);
//creates the library variable if not existing already and returns it
libvar_t *LibVar(char *var_name, char *value);
//creates the library variable if not existing already and returns the value
float LibVarValue(char *var_name, char *value);
//creates the library variable if not existing already and returns the value string
char *LibVarString(char *var_name, char *value);
//sets the library variable
void LibVarSet(char *var_name, char *value);
//returns true if the library variable has been modified
qboolean LibVarChanged(char *var_name);
//sets the library variable to unmodified
void LibVarSetNotModified(char *var_name);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: l_libvar.h
*
* desc: botlib vars
*
* $Archive: /source/code/botlib/l_libvar.h $
*
*****************************************************************************/
//library variable
typedef struct libvar_s
{
char *name;
char *string;
int flags;
qboolean modified; // set each time the cvar is changed
float value;
struct libvar_s *next;
} libvar_t;
//removes all library variables
void LibVarDeAllocAll(void);
//gets the library variable with the given name
libvar_t *LibVarGet(char *var_name);
//gets the string of the library variable with the given name
char *LibVarGetString(char *var_name);
//gets the value of the library variable with the given name
float LibVarGetValue(char *var_name);
//creates the library variable if not existing already and returns it
libvar_t *LibVar(char *var_name, char *value);
//creates the library variable if not existing already and returns the value
float LibVarValue(char *var_name, char *value);
//creates the library variable if not existing already and returns the value string
char *LibVarString(char *var_name, char *value);
//sets the library variable
void LibVarSet(char *var_name, char *value);
//returns true if the library variable has been modified
qboolean LibVarChanged(char *var_name);
//sets the library variable to unmodified
void LibVarSetNotModified(char *var_name);

338
code/botlib/l_log.c Normal file → Executable file
View file

@ -1,169 +1,169 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: l_log.c
*
* desc: log file
*
* $Archive: /MissionPack/CODE/botlib/l_log.c $
*
*****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "../game/q_shared.h"
#include "../game/botlib.h"
#include "be_interface.h" //for botimport.Print
#include "l_libvar.h"
#define MAX_LOGFILENAMESIZE 1024
typedef struct logfile_s
{
char filename[MAX_LOGFILENAMESIZE];
FILE *fp;
int numwrites;
} logfile_t;
static logfile_t logfile;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_Open(char *filename)
{
if (!LibVarValue("log", "0")) return;
if (!filename || !strlen(filename))
{
botimport.Print(PRT_MESSAGE, "openlog <filename>\n");
return;
} //end if
if (logfile.fp)
{
botimport.Print(PRT_ERROR, "log file %s is already opened\n", logfile.filename);
return;
} //end if
logfile.fp = fopen(filename, "wb");
if (!logfile.fp)
{
botimport.Print(PRT_ERROR, "can't open the log file %s\n", filename);
return;
} //end if
strncpy(logfile.filename, filename, MAX_LOGFILENAMESIZE);
botimport.Print(PRT_MESSAGE, "Opened log %s\n", logfile.filename);
} //end of the function Log_Create
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_Close(void)
{
if (!logfile.fp) return;
if (fclose(logfile.fp))
{
botimport.Print(PRT_ERROR, "can't close log file %s\n", logfile.filename);
return;
} //end if
logfile.fp = NULL;
botimport.Print(PRT_MESSAGE, "Closed log %s\n", logfile.filename);
} //end of the function Log_Close
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_Shutdown(void)
{
if (logfile.fp) Log_Close();
} //end of the function Log_Shutdown
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void QDECL Log_Write(char *fmt, ...)
{
va_list ap;
if (!logfile.fp) return;
va_start(ap, fmt);
vfprintf(logfile.fp, fmt, ap);
va_end(ap);
//fprintf(logfile.fp, "\r\n");
fflush(logfile.fp);
} //end of the function Log_Write
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void QDECL Log_WriteTimeStamped(char *fmt, ...)
{
va_list ap;
if (!logfile.fp) return;
fprintf(logfile.fp, "%d %02d:%02d:%02d:%02d ",
logfile.numwrites,
(int) (botlibglobals.time / 60 / 60),
(int) (botlibglobals.time / 60),
(int) (botlibglobals.time),
(int) ((int) (botlibglobals.time * 100)) -
((int) botlibglobals.time) * 100);
va_start(ap, fmt);
vfprintf(logfile.fp, fmt, ap);
va_end(ap);
fprintf(logfile.fp, "\r\n");
logfile.numwrites++;
fflush(logfile.fp);
} //end of the function Log_Write
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
FILE *Log_FilePointer(void)
{
return logfile.fp;
} //end of the function Log_FilePointer
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_Flush(void)
{
if (logfile.fp) fflush(logfile.fp);
} //end of the function Log_Flush
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: l_log.c
*
* desc: log file
*
* $Archive: /MissionPack/CODE/botlib/l_log.c $
*
*****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "../game/q_shared.h"
#include "../game/botlib.h"
#include "be_interface.h" //for botimport.Print
#include "l_libvar.h"
#define MAX_LOGFILENAMESIZE 1024
typedef struct logfile_s
{
char filename[MAX_LOGFILENAMESIZE];
FILE *fp;
int numwrites;
} logfile_t;
static logfile_t logfile;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_Open(char *filename)
{
if (!LibVarValue("log", "0")) return;
if (!filename || !strlen(filename))
{
botimport.Print(PRT_MESSAGE, "openlog <filename>\n");
return;
} //end if
if (logfile.fp)
{
botimport.Print(PRT_ERROR, "log file %s is already opened\n", logfile.filename);
return;
} //end if
logfile.fp = fopen(filename, "wb");
if (!logfile.fp)
{
botimport.Print(PRT_ERROR, "can't open the log file %s\n", filename);
return;
} //end if
strncpy(logfile.filename, filename, MAX_LOGFILENAMESIZE);
botimport.Print(PRT_MESSAGE, "Opened log %s\n", logfile.filename);
} //end of the function Log_Create
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_Close(void)
{
if (!logfile.fp) return;
if (fclose(logfile.fp))
{
botimport.Print(PRT_ERROR, "can't close log file %s\n", logfile.filename);
return;
} //end if
logfile.fp = NULL;
botimport.Print(PRT_MESSAGE, "Closed log %s\n", logfile.filename);
} //end of the function Log_Close
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_Shutdown(void)
{
if (logfile.fp) Log_Close();
} //end of the function Log_Shutdown
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void QDECL Log_Write(char *fmt, ...)
{
va_list ap;
if (!logfile.fp) return;
va_start(ap, fmt);
vfprintf(logfile.fp, fmt, ap);
va_end(ap);
//fprintf(logfile.fp, "\r\n");
fflush(logfile.fp);
} //end of the function Log_Write
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void QDECL Log_WriteTimeStamped(char *fmt, ...)
{
va_list ap;
if (!logfile.fp) return;
fprintf(logfile.fp, "%d %02d:%02d:%02d:%02d ",
logfile.numwrites,
(int) (botlibglobals.time / 60 / 60),
(int) (botlibglobals.time / 60),
(int) (botlibglobals.time),
(int) ((int) (botlibglobals.time * 100)) -
((int) botlibglobals.time) * 100);
va_start(ap, fmt);
vfprintf(logfile.fp, fmt, ap);
va_end(ap);
fprintf(logfile.fp, "\r\n");
logfile.numwrites++;
fflush(logfile.fp);
} //end of the function Log_Write
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
FILE *Log_FilePointer(void)
{
return logfile.fp;
} //end of the function Log_FilePointer
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_Flush(void)
{
if (logfile.fp) fflush(logfile.fp);
} //end of the function Log_Flush

92
code/botlib/l_log.h Normal file → Executable file
View file

@ -1,46 +1,46 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: l_log.h
*
* desc: log file
*
* $Archive: /source/code/botlib/l_log.h $
*
*****************************************************************************/
//open a log file
void Log_Open(char *filename);
//close the current log file
void Log_Close(void);
//close log file if present
void Log_Shutdown(void);
//write to the current opened log file
void QDECL Log_Write(char *fmt, ...);
//write to the current opened log file with a time stamp
void QDECL Log_WriteTimeStamped(char *fmt, ...);
//returns a pointer to the log file
FILE *Log_FilePointer(void);
//flush log file
void Log_Flush(void);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: l_log.h
*
* desc: log file
*
* $Archive: /source/code/botlib/l_log.h $
*
*****************************************************************************/
//open a log file
void Log_Open(char *filename);
//close the current log file
void Log_Close(void);
//close log file if present
void Log_Shutdown(void);
//write to the current opened log file
void QDECL Log_Write(char *fmt, ...);
//write to the current opened log file with a time stamp
void QDECL Log_WriteTimeStamped(char *fmt, ...);
//returns a pointer to the log file
FILE *Log_FilePointer(void);
//flush log file
void Log_Flush(void);

926
code/botlib/l_memory.c Normal file → Executable file
View file

@ -1,463 +1,463 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: l_memory.c
*
* desc: memory allocation
*
* $Archive: /MissionPack/code/botlib/l_memory.c $
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "../game/botlib.h"
#include "l_log.h"
#include "be_interface.h"
//#define MEMDEBUG
//#define MEMORYMANEGER
#define MEM_ID 0x12345678l
#define HUNK_ID 0x87654321l
int allocatedmemory;
int totalmemorysize;
int numblocks;
#ifdef MEMORYMANEGER
typedef struct memoryblock_s
{
unsigned long int id;
void *ptr;
int size;
#ifdef MEMDEBUG
char *label;
char *file;
int line;
#endif //MEMDEBUG
struct memoryblock_s *prev, *next;
} memoryblock_t;
memoryblock_t *memory;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void LinkMemoryBlock(memoryblock_t *block)
{
block->prev = NULL;
block->next = memory;
if (memory) memory->prev = block;
memory = block;
} //end of the function LinkMemoryBlock
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void UnlinkMemoryBlock(memoryblock_t *block)
{
if (block->prev) block->prev->next = block->next;
else memory = block->next;
if (block->next) block->next->prev = block->prev;
} //end of the function UnlinkMemoryBlock
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetMemoryDebug(unsigned long size, char *label, char *file, int line)
#else
void *GetMemory(unsigned long size)
#endif //MEMDEBUG
{
void *ptr;
memoryblock_t *block;
assert(botimport.GetMemory); // bk001129 - was NULL'ed
ptr = botimport.GetMemory(size + sizeof(memoryblock_t));
block = (memoryblock_t *) ptr;
block->id = MEM_ID;
block->ptr = (char *) ptr + sizeof(memoryblock_t);
block->size = size + sizeof(memoryblock_t);
#ifdef MEMDEBUG
block->label = label;
block->file = file;
block->line = line;
#endif //MEMDEBUG
LinkMemoryBlock(block);
allocatedmemory += block->size;
totalmemorysize += block->size + sizeof(memoryblock_t);
numblocks++;
return block->ptr;
} //end of the function GetMemoryDebug
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetClearedMemoryDebug(unsigned long size, char *label, char *file, int line)
#else
void *GetClearedMemory(unsigned long size)
#endif //MEMDEBUG
{
void *ptr;
#ifdef MEMDEBUG
ptr = GetMemoryDebug(size, label, file, line);
#else
ptr = GetMemory(size);
#endif //MEMDEBUG
Com_Memset(ptr, 0, size);
return ptr;
} //end of the function GetClearedMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetHunkMemoryDebug(unsigned long size, char *label, char *file, int line)
#else
void *GetHunkMemory(unsigned long size)
#endif //MEMDEBUG
{
void *ptr;
memoryblock_t *block;
ptr = botimport.HunkAlloc(size + sizeof(memoryblock_t));
block = (memoryblock_t *) ptr;
block->id = HUNK_ID;
block->ptr = (char *) ptr + sizeof(memoryblock_t);
block->size = size + sizeof(memoryblock_t);
#ifdef MEMDEBUG
block->label = label;
block->file = file;
block->line = line;
#endif //MEMDEBUG
LinkMemoryBlock(block);
allocatedmemory += block->size;
totalmemorysize += block->size + sizeof(memoryblock_t);
numblocks++;
return block->ptr;
} //end of the function GetHunkMemoryDebug
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetClearedHunkMemoryDebug(unsigned long size, char *label, char *file, int line)
#else
void *GetClearedHunkMemory(unsigned long size)
#endif //MEMDEBUG
{
void *ptr;
#ifdef MEMDEBUG
ptr = GetHunkMemoryDebug(size, label, file, line);
#else
ptr = GetHunkMemory(size);
#endif //MEMDEBUG
Com_Memset(ptr, 0, size);
return ptr;
} //end of the function GetClearedHunkMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
memoryblock_t *BlockFromPointer(void *ptr, char *str)
{
memoryblock_t *block;
if (!ptr)
{
#ifdef MEMDEBUG
//char *crash = (char *) NULL;
//crash[0] = 1;
botimport.Print(PRT_FATAL, "%s: NULL pointer\n", str);
#endif // MEMDEBUG
return NULL;
} //end if
block = (memoryblock_t *) ((char *) ptr - sizeof(memoryblock_t));
if (block->id != MEM_ID && block->id != HUNK_ID)
{
botimport.Print(PRT_FATAL, "%s: invalid memory block\n", str);
return NULL;
} //end if
if (block->ptr != ptr)
{
botimport.Print(PRT_FATAL, "%s: memory block pointer invalid\n", str);
return NULL;
} //end if
return block;
} //end of the function BlockFromPointer
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void FreeMemory(void *ptr)
{
memoryblock_t *block;
block = BlockFromPointer(ptr, "FreeMemory");
if (!block) return;
UnlinkMemoryBlock(block);
allocatedmemory -= block->size;
totalmemorysize -= block->size + sizeof(memoryblock_t);
numblocks--;
//
if (block->id == MEM_ID)
{
botimport.FreeMemory(block);
} //end if
} //end of the function FreeMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AvailableMemory(void)
{
return botimport.AvailableMemory();
} //end of the function AvailableMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int MemoryByteSize(void *ptr)
{
memoryblock_t *block;
block = BlockFromPointer(ptr, "MemoryByteSize");
if (!block) return 0;
return block->size;
} //end of the function MemoryByteSize
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void PrintUsedMemorySize(void)
{
botimport.Print(PRT_MESSAGE, "total allocated memory: %d KB\n", allocatedmemory >> 10);
botimport.Print(PRT_MESSAGE, "total botlib memory: %d KB\n", totalmemorysize >> 10);
botimport.Print(PRT_MESSAGE, "total memory blocks: %d\n", numblocks);
} //end of the function PrintUsedMemorySize
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void PrintMemoryLabels(void)
{
memoryblock_t *block;
int i;
PrintUsedMemorySize();
i = 0;
Log_Write("============= Botlib memory log ==============\r\n");
Log_Write("\r\n");
for (block = memory; block; block = block->next)
{
#ifdef MEMDEBUG
if (block->id == HUNK_ID)
{
Log_Write("%6d, hunk %p, %8d: %24s line %6d: %s\r\n", i, block->ptr, block->size, block->file, block->line, block->label);
} //end if
else
{
Log_Write("%6d, %p, %8d: %24s line %6d: %s\r\n", i, block->ptr, block->size, block->file, block->line, block->label);
} //end else
#endif //MEMDEBUG
i++;
} //end for
} //end of the function PrintMemoryLabels
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void DumpMemory(void)
{
memoryblock_t *block;
for (block = memory; block; block = memory)
{
FreeMemory(block->ptr);
} //end for
totalmemorysize = 0;
allocatedmemory = 0;
} //end of the function DumpMemory
#else
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetMemoryDebug(unsigned long size, char *label, char *file, int line)
#else
void *GetMemory(unsigned long size)
#endif //MEMDEBUG
{
void *ptr;
unsigned long int *memid;
ptr = botimport.GetMemory(size + sizeof(unsigned long int));
if (!ptr) return NULL;
memid = (unsigned long int *) ptr;
*memid = MEM_ID;
return (unsigned long int *) ((char *) ptr + sizeof(unsigned long int));
} //end of the function GetMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetClearedMemoryDebug(unsigned long size, char *label, char *file, int line)
#else
void *GetClearedMemory(unsigned long size)
#endif //MEMDEBUG
{
void *ptr;
#ifdef MEMDEBUG
ptr = GetMemoryDebug(size, label, file, line);
#else
ptr = GetMemory(size);
#endif //MEMDEBUG
Com_Memset(ptr, 0, size);
return ptr;
} //end of the function GetClearedMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetHunkMemoryDebug(unsigned long size, char *label, char *file, int line)
#else
void *GetHunkMemory(unsigned long size)
#endif //MEMDEBUG
{
void *ptr;
unsigned long int *memid;
ptr = botimport.HunkAlloc(size + sizeof(unsigned long int));
if (!ptr) return NULL;
memid = (unsigned long int *) ptr;
*memid = HUNK_ID;
return (unsigned long int *) ((char *) ptr + sizeof(unsigned long int));
} //end of the function GetHunkMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetClearedHunkMemoryDebug(unsigned long size, char *label, char *file, int line)
#else
void *GetClearedHunkMemory(unsigned long size)
#endif //MEMDEBUG
{
void *ptr;
#ifdef MEMDEBUG
ptr = GetHunkMemoryDebug(size, label, file, line);
#else
ptr = GetHunkMemory(size);
#endif //MEMDEBUG
Com_Memset(ptr, 0, size);
return ptr;
} //end of the function GetClearedHunkMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void FreeMemory(void *ptr)
{
unsigned long int *memid;
memid = (unsigned long int *) ((char *) ptr - sizeof(unsigned long int));
if (*memid == MEM_ID)
{
botimport.FreeMemory(memid);
} //end if
} //end of the function FreeMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AvailableMemory(void)
{
return botimport.AvailableMemory();
} //end of the function AvailableMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void PrintUsedMemorySize(void)
{
} //end of the function PrintUsedMemorySize
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void PrintMemoryLabels(void)
{
} //end of the function PrintMemoryLabels
#endif
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: l_memory.c
*
* desc: memory allocation
*
* $Archive: /MissionPack/code/botlib/l_memory.c $
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "../game/botlib.h"
#include "l_log.h"
#include "be_interface.h"
//#define MEMDEBUG
//#define MEMORYMANEGER
#define MEM_ID 0x12345678l
#define HUNK_ID 0x87654321l
int allocatedmemory;
int totalmemorysize;
int numblocks;
#ifdef MEMORYMANEGER
typedef struct memoryblock_s
{
unsigned long int id;
void *ptr;
int size;
#ifdef MEMDEBUG
char *label;
char *file;
int line;
#endif //MEMDEBUG
struct memoryblock_s *prev, *next;
} memoryblock_t;
memoryblock_t *memory;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void LinkMemoryBlock(memoryblock_t *block)
{
block->prev = NULL;
block->next = memory;
if (memory) memory->prev = block;
memory = block;
} //end of the function LinkMemoryBlock
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void UnlinkMemoryBlock(memoryblock_t *block)
{
if (block->prev) block->prev->next = block->next;
else memory = block->next;
if (block->next) block->next->prev = block->prev;
} //end of the function UnlinkMemoryBlock
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetMemoryDebug(unsigned long size, char *label, char *file, int line)
#else
void *GetMemory(unsigned long size)
#endif //MEMDEBUG
{
void *ptr;
memoryblock_t *block;
assert(botimport.GetMemory); // bk001129 - was NULL'ed
ptr = botimport.GetMemory(size + sizeof(memoryblock_t));
block = (memoryblock_t *) ptr;
block->id = MEM_ID;
block->ptr = (char *) ptr + sizeof(memoryblock_t);
block->size = size + sizeof(memoryblock_t);
#ifdef MEMDEBUG
block->label = label;
block->file = file;
block->line = line;
#endif //MEMDEBUG
LinkMemoryBlock(block);
allocatedmemory += block->size;
totalmemorysize += block->size + sizeof(memoryblock_t);
numblocks++;
return block->ptr;
} //end of the function GetMemoryDebug
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetClearedMemoryDebug(unsigned long size, char *label, char *file, int line)
#else
void *GetClearedMemory(unsigned long size)
#endif //MEMDEBUG
{
void *ptr;
#ifdef MEMDEBUG
ptr = GetMemoryDebug(size, label, file, line);
#else
ptr = GetMemory(size);
#endif //MEMDEBUG
Com_Memset(ptr, 0, size);
return ptr;
} //end of the function GetClearedMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetHunkMemoryDebug(unsigned long size, char *label, char *file, int line)
#else
void *GetHunkMemory(unsigned long size)
#endif //MEMDEBUG
{
void *ptr;
memoryblock_t *block;
ptr = botimport.HunkAlloc(size + sizeof(memoryblock_t));
block = (memoryblock_t *) ptr;
block->id = HUNK_ID;
block->ptr = (char *) ptr + sizeof(memoryblock_t);
block->size = size + sizeof(memoryblock_t);
#ifdef MEMDEBUG
block->label = label;
block->file = file;
block->line = line;
#endif //MEMDEBUG
LinkMemoryBlock(block);
allocatedmemory += block->size;
totalmemorysize += block->size + sizeof(memoryblock_t);
numblocks++;
return block->ptr;
} //end of the function GetHunkMemoryDebug
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetClearedHunkMemoryDebug(unsigned long size, char *label, char *file, int line)
#else
void *GetClearedHunkMemory(unsigned long size)
#endif //MEMDEBUG
{
void *ptr;
#ifdef MEMDEBUG
ptr = GetHunkMemoryDebug(size, label, file, line);
#else
ptr = GetHunkMemory(size);
#endif //MEMDEBUG
Com_Memset(ptr, 0, size);
return ptr;
} //end of the function GetClearedHunkMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
memoryblock_t *BlockFromPointer(void *ptr, char *str)
{
memoryblock_t *block;
if (!ptr)
{
#ifdef MEMDEBUG
//char *crash = (char *) NULL;
//crash[0] = 1;
botimport.Print(PRT_FATAL, "%s: NULL pointer\n", str);
#endif // MEMDEBUG
return NULL;
} //end if
block = (memoryblock_t *) ((char *) ptr - sizeof(memoryblock_t));
if (block->id != MEM_ID && block->id != HUNK_ID)
{
botimport.Print(PRT_FATAL, "%s: invalid memory block\n", str);
return NULL;
} //end if
if (block->ptr != ptr)
{
botimport.Print(PRT_FATAL, "%s: memory block pointer invalid\n", str);
return NULL;
} //end if
return block;
} //end of the function BlockFromPointer
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void FreeMemory(void *ptr)
{
memoryblock_t *block;
block = BlockFromPointer(ptr, "FreeMemory");
if (!block) return;
UnlinkMemoryBlock(block);
allocatedmemory -= block->size;
totalmemorysize -= block->size + sizeof(memoryblock_t);
numblocks--;
//
if (block->id == MEM_ID)
{
botimport.FreeMemory(block);
} //end if
} //end of the function FreeMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AvailableMemory(void)
{
return botimport.AvailableMemory();
} //end of the function AvailableMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int MemoryByteSize(void *ptr)
{
memoryblock_t *block;
block = BlockFromPointer(ptr, "MemoryByteSize");
if (!block) return 0;
return block->size;
} //end of the function MemoryByteSize
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void PrintUsedMemorySize(void)
{
botimport.Print(PRT_MESSAGE, "total allocated memory: %d KB\n", allocatedmemory >> 10);
botimport.Print(PRT_MESSAGE, "total botlib memory: %d KB\n", totalmemorysize >> 10);
botimport.Print(PRT_MESSAGE, "total memory blocks: %d\n", numblocks);
} //end of the function PrintUsedMemorySize
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void PrintMemoryLabels(void)
{
memoryblock_t *block;
int i;
PrintUsedMemorySize();
i = 0;
Log_Write("============= Botlib memory log ==============\r\n");
Log_Write("\r\n");
for (block = memory; block; block = block->next)
{
#ifdef MEMDEBUG
if (block->id == HUNK_ID)
{
Log_Write("%6d, hunk %p, %8d: %24s line %6d: %s\r\n", i, block->ptr, block->size, block->file, block->line, block->label);
} //end if
else
{
Log_Write("%6d, %p, %8d: %24s line %6d: %s\r\n", i, block->ptr, block->size, block->file, block->line, block->label);
} //end else
#endif //MEMDEBUG
i++;
} //end for
} //end of the function PrintMemoryLabels
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void DumpMemory(void)
{
memoryblock_t *block;
for (block = memory; block; block = memory)
{
FreeMemory(block->ptr);
} //end for
totalmemorysize = 0;
allocatedmemory = 0;
} //end of the function DumpMemory
#else
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetMemoryDebug(unsigned long size, char *label, char *file, int line)
#else
void *GetMemory(unsigned long size)
#endif //MEMDEBUG
{
void *ptr;
unsigned long int *memid;
ptr = botimport.GetMemory(size + sizeof(unsigned long int));
if (!ptr) return NULL;
memid = (unsigned long int *) ptr;
*memid = MEM_ID;
return (unsigned long int *) ((char *) ptr + sizeof(unsigned long int));
} //end of the function GetMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetClearedMemoryDebug(unsigned long size, char *label, char *file, int line)
#else
void *GetClearedMemory(unsigned long size)
#endif //MEMDEBUG
{
void *ptr;
#ifdef MEMDEBUG
ptr = GetMemoryDebug(size, label, file, line);
#else
ptr = GetMemory(size);
#endif //MEMDEBUG
Com_Memset(ptr, 0, size);
return ptr;
} //end of the function GetClearedMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetHunkMemoryDebug(unsigned long size, char *label, char *file, int line)
#else
void *GetHunkMemory(unsigned long size)
#endif //MEMDEBUG
{
void *ptr;
unsigned long int *memid;
ptr = botimport.HunkAlloc(size + sizeof(unsigned long int));
if (!ptr) return NULL;
memid = (unsigned long int *) ptr;
*memid = HUNK_ID;
return (unsigned long int *) ((char *) ptr + sizeof(unsigned long int));
} //end of the function GetHunkMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetClearedHunkMemoryDebug(unsigned long size, char *label, char *file, int line)
#else
void *GetClearedHunkMemory(unsigned long size)
#endif //MEMDEBUG
{
void *ptr;
#ifdef MEMDEBUG
ptr = GetHunkMemoryDebug(size, label, file, line);
#else
ptr = GetHunkMemory(size);
#endif //MEMDEBUG
Com_Memset(ptr, 0, size);
return ptr;
} //end of the function GetClearedHunkMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void FreeMemory(void *ptr)
{
unsigned long int *memid;
memid = (unsigned long int *) ((char *) ptr - sizeof(unsigned long int));
if (*memid == MEM_ID)
{
botimport.FreeMemory(memid);
} //end if
} //end of the function FreeMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AvailableMemory(void)
{
return botimport.AvailableMemory();
} //end of the function AvailableMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void PrintUsedMemorySize(void)
{
} //end of the function PrintUsedMemorySize
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void PrintMemoryLabels(void)
{
} //end of the function PrintMemoryLabels
#endif

152
code/botlib/l_memory.h Normal file → Executable file
View file

@ -1,76 +1,76 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: l_memory.h
*
* desc: memory management
*
* $Archive: /source/code/botlib/l_memory.h $
*
*****************************************************************************/
//#define MEMDEBUG
#ifdef MEMDEBUG
#define GetMemory(size) GetMemoryDebug(size, #size, __FILE__, __LINE__);
#define GetClearedMemory(size) GetClearedMemoryDebug(size, #size, __FILE__, __LINE__);
//allocate a memory block of the given size
void *GetMemoryDebug(unsigned long size, char *label, char *file, int line);
//allocate a memory block of the given size and clear it
void *GetClearedMemoryDebug(unsigned long size, char *label, char *file, int line);
//
#define GetHunkMemory(size) GetHunkMemoryDebug(size, #size, __FILE__, __LINE__);
#define GetClearedHunkMemory(size) GetClearedHunkMemoryDebug(size, #size, __FILE__, __LINE__);
//allocate a memory block of the given size
void *GetHunkMemoryDebug(unsigned long size, char *label, char *file, int line);
//allocate a memory block of the given size and clear it
void *GetClearedHunkMemoryDebug(unsigned long size, char *label, char *file, int line);
#else
//allocate a memory block of the given size
void *GetMemory(unsigned long size);
//allocate a memory block of the given size and clear it
void *GetClearedMemory(unsigned long size);
//
#ifdef BSPC
#define GetHunkMemory GetMemory
#define GetClearedHunkMemory GetClearedMemory
#else
//allocate a memory block of the given size
void *GetHunkMemory(unsigned long size);
//allocate a memory block of the given size and clear it
void *GetClearedHunkMemory(unsigned long size);
#endif
#endif
//free the given memory block
void FreeMemory(void *ptr);
//returns the amount available memory
int AvailableMemory(void);
//prints the total used memory size
void PrintUsedMemorySize(void);
//print all memory blocks with label
void PrintMemoryLabels(void);
//returns the size of the memory block in bytes
int MemoryByteSize(void *ptr);
//free all allocated memory
void DumpMemory(void);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: l_memory.h
*
* desc: memory management
*
* $Archive: /source/code/botlib/l_memory.h $
*
*****************************************************************************/
//#define MEMDEBUG
#ifdef MEMDEBUG
#define GetMemory(size) GetMemoryDebug(size, #size, __FILE__, __LINE__);
#define GetClearedMemory(size) GetClearedMemoryDebug(size, #size, __FILE__, __LINE__);
//allocate a memory block of the given size
void *GetMemoryDebug(unsigned long size, char *label, char *file, int line);
//allocate a memory block of the given size and clear it
void *GetClearedMemoryDebug(unsigned long size, char *label, char *file, int line);
//
#define GetHunkMemory(size) GetHunkMemoryDebug(size, #size, __FILE__, __LINE__);
#define GetClearedHunkMemory(size) GetClearedHunkMemoryDebug(size, #size, __FILE__, __LINE__);
//allocate a memory block of the given size
void *GetHunkMemoryDebug(unsigned long size, char *label, char *file, int line);
//allocate a memory block of the given size and clear it
void *GetClearedHunkMemoryDebug(unsigned long size, char *label, char *file, int line);
#else
//allocate a memory block of the given size
void *GetMemory(unsigned long size);
//allocate a memory block of the given size and clear it
void *GetClearedMemory(unsigned long size);
//
#ifdef BSPC
#define GetHunkMemory GetMemory
#define GetClearedHunkMemory GetClearedMemory
#else
//allocate a memory block of the given size
void *GetHunkMemory(unsigned long size);
//allocate a memory block of the given size and clear it
void *GetClearedHunkMemory(unsigned long size);
#endif
#endif
//free the given memory block
void FreeMemory(void *ptr);
//returns the amount available memory
int AvailableMemory(void);
//prints the total used memory size
void PrintUsedMemorySize(void);
//print all memory blocks with label
void PrintMemoryLabels(void);
//returns the size of the memory block in bytes
int MemoryByteSize(void *ptr);
//free all allocated memory
void DumpMemory(void);

6456
code/botlib/l_precomp.c Normal file → Executable file

File diff suppressed because it is too large Load diff

360
code/botlib/l_precomp.h Normal file → Executable file
View file

@ -1,180 +1,180 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: l_precomp.h
*
* desc: pre compiler
*
* $Archive: /source/code/botlib/l_precomp.h $
*
*****************************************************************************/
#ifndef MAX_PATH
#define MAX_PATH MAX_QPATH
#endif
#ifndef PATH_SEPERATORSTR
#if defined(WIN32)|defined(_WIN32)|defined(__NT__)|defined(__WINDOWS__)|defined(__WINDOWS_386__)
#define PATHSEPERATOR_STR "\\"
#else
#define PATHSEPERATOR_STR "/"
#endif
#endif
#ifndef PATH_SEPERATORCHAR
#if defined(WIN32)|defined(_WIN32)|defined(__NT__)|defined(__WINDOWS__)|defined(__WINDOWS_386__)
#define PATHSEPERATOR_CHAR '\\'
#else
#define PATHSEPERATOR_CHAR '/'
#endif
#endif
#if defined(BSPC) && !defined(QDECL)
#define QDECL
#endif
#define DEFINE_FIXED 0x0001
#define BUILTIN_LINE 1
#define BUILTIN_FILE 2
#define BUILTIN_DATE 3
#define BUILTIN_TIME 4
#define BUILTIN_STDC 5
#define INDENT_IF 0x0001
#define INDENT_ELSE 0x0002
#define INDENT_ELIF 0x0004
#define INDENT_IFDEF 0x0008
#define INDENT_IFNDEF 0x0010
//macro definitions
typedef struct define_s
{
char *name; //define name
int flags; //define flags
int builtin; // > 0 if builtin define
int numparms; //number of define parameters
token_t *parms; //define parameters
token_t *tokens; //macro tokens (possibly containing parm tokens)
struct define_s *next; //next defined macro in a list
struct define_s *hashnext; //next define in the hash chain
} define_t;
//indents
//used for conditional compilation directives:
//#if, #else, #elif, #ifdef, #ifndef
typedef struct indent_s
{
int type; //indent type
int skip; //true if skipping current indent
script_t *script; //script the indent was in
struct indent_s *next; //next indent on the indent stack
} indent_t;
//source file
typedef struct source_s
{
char filename[1024]; //file name of the script
char includepath[1024]; //path to include files
punctuation_t *punctuations; //punctuations to use
script_t *scriptstack; //stack with scripts of the source
token_t *tokens; //tokens to read first
define_t *defines; //list with macro definitions
define_t **definehash; //hash chain with defines
indent_t *indentstack; //stack with indents
int skip; // > 0 if skipping conditional code
token_t token; //last read token
} source_t;
//read a token from the source
int PC_ReadToken(source_t *source, token_t *token);
//expect a certain token
int PC_ExpectTokenString(source_t *source, char *string);
//expect a certain token type
int PC_ExpectTokenType(source_t *source, int type, int subtype, token_t *token);
//expect a token
int PC_ExpectAnyToken(source_t *source, token_t *token);
//returns true when the token is available
int PC_CheckTokenString(source_t *source, char *string);
//returns true an reads the token when a token with the given type is available
int PC_CheckTokenType(source_t *source, int type, int subtype, token_t *token);
//skip tokens until the given token string is read
int PC_SkipUntilString(source_t *source, char *string);
//unread the last token read from the script
void PC_UnreadLastToken(source_t *source);
//unread the given token
void PC_UnreadToken(source_t *source, token_t *token);
//read a token only if on the same line, lines are concatenated with a slash
int PC_ReadLine(source_t *source, token_t *token);
//returns true if there was a white space in front of the token
int PC_WhiteSpaceBeforeToken(token_t *token);
//add a define to the source
int PC_AddDefine(source_t *source, char *string);
//add a globals define that will be added to all opened sources
int PC_AddGlobalDefine(char *string);
//remove the given global define
int PC_RemoveGlobalDefine(char *name);
//remove all globals defines
void PC_RemoveAllGlobalDefines(void);
//add builtin defines
void PC_AddBuiltinDefines(source_t *source);
//set the source include path
void PC_SetIncludePath(source_t *source, char *path);
//set the punction set
void PC_SetPunctuations(source_t *source, punctuation_t *p);
//set the base folder to load files from
void PC_SetBaseFolder(char *path);
//load a source file
source_t *LoadSourceFile(const char *filename);
//load a source from memory
source_t *LoadSourceMemory(char *ptr, int length, char *name);
//free the given source
void FreeSource(source_t *source);
//print a source error
void QDECL SourceError(source_t *source, char *str, ...);
//print a source warning
void QDECL SourceWarning(source_t *source, char *str, ...);
#ifdef BSPC
// some of BSPC source does include game/q_shared.h and some does not
// we define pc_token_s pc_token_t if needed (yes, it's ugly)
#ifndef __Q_SHARED_H
#define MAX_TOKENLENGTH 1024
typedef struct pc_token_s
{
int type;
int subtype;
int intvalue;
float floatvalue;
char string[MAX_TOKENLENGTH];
} pc_token_t;
#endif //!_Q_SHARED_H
#endif //BSPC
//
int PC_LoadSourceHandle(const char *filename);
int PC_FreeSourceHandle(int handle);
int PC_ReadTokenHandle(int handle, pc_token_t *pc_token);
int PC_SourceFileAndLine(int handle, char *filename, int *line);
void PC_CheckOpenSourceHandles(void);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: l_precomp.h
*
* desc: pre compiler
*
* $Archive: /source/code/botlib/l_precomp.h $
*
*****************************************************************************/
#ifndef MAX_PATH
#define MAX_PATH MAX_QPATH
#endif
#ifndef PATH_SEPERATORSTR
#if defined(WIN32)|defined(_WIN32)|defined(__NT__)|defined(__WINDOWS__)|defined(__WINDOWS_386__)
#define PATHSEPERATOR_STR "\\"
#else
#define PATHSEPERATOR_STR "/"
#endif
#endif
#ifndef PATH_SEPERATORCHAR
#if defined(WIN32)|defined(_WIN32)|defined(__NT__)|defined(__WINDOWS__)|defined(__WINDOWS_386__)
#define PATHSEPERATOR_CHAR '\\'
#else
#define PATHSEPERATOR_CHAR '/'
#endif
#endif
#if defined(BSPC) && !defined(QDECL)
#define QDECL
#endif
#define DEFINE_FIXED 0x0001
#define BUILTIN_LINE 1
#define BUILTIN_FILE 2
#define BUILTIN_DATE 3
#define BUILTIN_TIME 4
#define BUILTIN_STDC 5
#define INDENT_IF 0x0001
#define INDENT_ELSE 0x0002
#define INDENT_ELIF 0x0004
#define INDENT_IFDEF 0x0008
#define INDENT_IFNDEF 0x0010
//macro definitions
typedef struct define_s
{
char *name; //define name
int flags; //define flags
int builtin; // > 0 if builtin define
int numparms; //number of define parameters
token_t *parms; //define parameters
token_t *tokens; //macro tokens (possibly containing parm tokens)
struct define_s *next; //next defined macro in a list
struct define_s *hashnext; //next define in the hash chain
} define_t;
//indents
//used for conditional compilation directives:
//#if, #else, #elif, #ifdef, #ifndef
typedef struct indent_s
{
int type; //indent type
int skip; //true if skipping current indent
script_t *script; //script the indent was in
struct indent_s *next; //next indent on the indent stack
} indent_t;
//source file
typedef struct source_s
{
char filename[1024]; //file name of the script
char includepath[1024]; //path to include files
punctuation_t *punctuations; //punctuations to use
script_t *scriptstack; //stack with scripts of the source
token_t *tokens; //tokens to read first
define_t *defines; //list with macro definitions
define_t **definehash; //hash chain with defines
indent_t *indentstack; //stack with indents
int skip; // > 0 if skipping conditional code
token_t token; //last read token
} source_t;
//read a token from the source
int PC_ReadToken(source_t *source, token_t *token);
//expect a certain token
int PC_ExpectTokenString(source_t *source, char *string);
//expect a certain token type
int PC_ExpectTokenType(source_t *source, int type, int subtype, token_t *token);
//expect a token
int PC_ExpectAnyToken(source_t *source, token_t *token);
//returns true when the token is available
int PC_CheckTokenString(source_t *source, char *string);
//returns true an reads the token when a token with the given type is available
int PC_CheckTokenType(source_t *source, int type, int subtype, token_t *token);
//skip tokens until the given token string is read
int PC_SkipUntilString(source_t *source, char *string);
//unread the last token read from the script
void PC_UnreadLastToken(source_t *source);
//unread the given token
void PC_UnreadToken(source_t *source, token_t *token);
//read a token only if on the same line, lines are concatenated with a slash
int PC_ReadLine(source_t *source, token_t *token);
//returns true if there was a white space in front of the token
int PC_WhiteSpaceBeforeToken(token_t *token);
//add a define to the source
int PC_AddDefine(source_t *source, char *string);
//add a globals define that will be added to all opened sources
int PC_AddGlobalDefine(char *string);
//remove the given global define
int PC_RemoveGlobalDefine(char *name);
//remove all globals defines
void PC_RemoveAllGlobalDefines(void);
//add builtin defines
void PC_AddBuiltinDefines(source_t *source);
//set the source include path
void PC_SetIncludePath(source_t *source, char *path);
//set the punction set
void PC_SetPunctuations(source_t *source, punctuation_t *p);
//set the base folder to load files from
void PC_SetBaseFolder(char *path);
//load a source file
source_t *LoadSourceFile(const char *filename);
//load a source from memory
source_t *LoadSourceMemory(char *ptr, int length, char *name);
//free the given source
void FreeSource(source_t *source);
//print a source error
void QDECL SourceError(source_t *source, char *str, ...);
//print a source warning
void QDECL SourceWarning(source_t *source, char *str, ...);
#ifdef BSPC
// some of BSPC source does include game/q_shared.h and some does not
// we define pc_token_s pc_token_t if needed (yes, it's ugly)
#ifndef __Q_SHARED_H
#define MAX_TOKENLENGTH 1024
typedef struct pc_token_s
{
int type;
int subtype;
int intvalue;
float floatvalue;
char string[MAX_TOKENLENGTH];
} pc_token_t;
#endif //!_Q_SHARED_H
#endif //BSPC
//
int PC_LoadSourceHandle(const char *filename);
int PC_FreeSourceHandle(int handle);
int PC_ReadTokenHandle(int handle, pc_token_t *pc_token);
int PC_SourceFileAndLine(int handle, char *filename, int *line);
void PC_CheckOpenSourceHandles(void);

2866
code/botlib/l_script.c Normal file → Executable file

File diff suppressed because it is too large Load diff

494
code/botlib/l_script.h Normal file → Executable file
View file

@ -1,247 +1,247 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: l_script.h
*
* desc: lexicographical parser
*
* $Archive: /source/code/botlib/l_script.h $
*
*****************************************************************************/
//undef if binary numbers of the form 0b... or 0B... are not allowed
#define BINARYNUMBERS
//undef if not using the token.intvalue and token.floatvalue
#define NUMBERVALUE
//use dollar sign also as punctuation
#define DOLLAR
//maximum token length
#define MAX_TOKEN 1024
#if defined(BSPC) && !defined(QDECL)
#define QDECL
#endif
//script flags
#define SCFL_NOERRORS 0x0001
#define SCFL_NOWARNINGS 0x0002
#define SCFL_NOSTRINGWHITESPACES 0x0004
#define SCFL_NOSTRINGESCAPECHARS 0x0008
#define SCFL_PRIMITIVE 0x0010
#define SCFL_NOBINARYNUMBERS 0x0020
#define SCFL_NONUMBERVALUES 0x0040
//token types
#define TT_STRING 1 // string
#define TT_LITERAL 2 // literal
#define TT_NUMBER 3 // number
#define TT_NAME 4 // name
#define TT_PUNCTUATION 5 // punctuation
//string sub type
//---------------
// the length of the string
//literal sub type
//----------------
// the ASCII code of the literal
//number sub type
//---------------
#define TT_DECIMAL 0x0008 // decimal number
#define TT_HEX 0x0100 // hexadecimal number
#define TT_OCTAL 0x0200 // octal number
#ifdef BINARYNUMBERS
#define TT_BINARY 0x0400 // binary number
#endif //BINARYNUMBERS
#define TT_FLOAT 0x0800 // floating point number
#define TT_INTEGER 0x1000 // integer number
#define TT_LONG 0x2000 // long number
#define TT_UNSIGNED 0x4000 // unsigned number
//punctuation sub type
//--------------------
#define P_RSHIFT_ASSIGN 1
#define P_LSHIFT_ASSIGN 2
#define P_PARMS 3
#define P_PRECOMPMERGE 4
#define P_LOGIC_AND 5
#define P_LOGIC_OR 6
#define P_LOGIC_GEQ 7
#define P_LOGIC_LEQ 8
#define P_LOGIC_EQ 9
#define P_LOGIC_UNEQ 10
#define P_MUL_ASSIGN 11
#define P_DIV_ASSIGN 12
#define P_MOD_ASSIGN 13
#define P_ADD_ASSIGN 14
#define P_SUB_ASSIGN 15
#define P_INC 16
#define P_DEC 17
#define P_BIN_AND_ASSIGN 18
#define P_BIN_OR_ASSIGN 19
#define P_BIN_XOR_ASSIGN 20
#define P_RSHIFT 21
#define P_LSHIFT 22
#define P_POINTERREF 23
#define P_CPP1 24
#define P_CPP2 25
#define P_MUL 26
#define P_DIV 27
#define P_MOD 28
#define P_ADD 29
#define P_SUB 30
#define P_ASSIGN 31
#define P_BIN_AND 32
#define P_BIN_OR 33
#define P_BIN_XOR 34
#define P_BIN_NOT 35
#define P_LOGIC_NOT 36
#define P_LOGIC_GREATER 37
#define P_LOGIC_LESS 38
#define P_REF 39
#define P_COMMA 40
#define P_SEMICOLON 41
#define P_COLON 42
#define P_QUESTIONMARK 43
#define P_PARENTHESESOPEN 44
#define P_PARENTHESESCLOSE 45
#define P_BRACEOPEN 46
#define P_BRACECLOSE 47
#define P_SQBRACKETOPEN 48
#define P_SQBRACKETCLOSE 49
#define P_BACKSLASH 50
#define P_PRECOMP 51
#define P_DOLLAR 52
//name sub type
//-------------
// the length of the name
//punctuation
typedef struct punctuation_s
{
char *p; //punctuation character(s)
int n; //punctuation indication
struct punctuation_s *next; //next punctuation
} punctuation_t;
//token
typedef struct token_s
{
char string[MAX_TOKEN]; //available token
int type; //last read token type
int subtype; //last read token sub type
#ifdef NUMBERVALUE
unsigned long int intvalue; //integer value
long double floatvalue; //floating point value
#endif //NUMBERVALUE
char *whitespace_p; //start of white space before token
char *endwhitespace_p; //start of white space before token
int line; //line the token was on
int linescrossed; //lines crossed in white space
struct token_s *next; //next token in chain
} token_t;
//script file
typedef struct script_s
{
char filename[1024]; //file name of the script
char *buffer; //buffer containing the script
char *script_p; //current pointer in the script
char *end_p; //pointer to the end of the script
char *lastscript_p; //script pointer before reading token
char *whitespace_p; //begin of the white space
char *endwhitespace_p; //end of the white space
int length; //length of the script in bytes
int line; //current line in script
int lastline; //line before reading token
int tokenavailable; //set by UnreadLastToken
int flags; //several script flags
punctuation_t *punctuations; //the punctuations used in the script
punctuation_t **punctuationtable;
token_t token; //available token
struct script_s *next; //next script in a chain
} script_t;
//read a token from the script
int PS_ReadToken(script_t *script, token_t *token);
//expect a certain token
int PS_ExpectTokenString(script_t *script, char *string);
//expect a certain token type
int PS_ExpectTokenType(script_t *script, int type, int subtype, token_t *token);
//expect a token
int PS_ExpectAnyToken(script_t *script, token_t *token);
//returns true when the token is available
int PS_CheckTokenString(script_t *script, char *string);
//returns true an reads the token when a token with the given type is available
int PS_CheckTokenType(script_t *script, int type, int subtype, token_t *token);
//skip tokens until the given token string is read
int PS_SkipUntilString(script_t *script, char *string);
//unread the last token read from the script
void PS_UnreadLastToken(script_t *script);
//unread the given token
void PS_UnreadToken(script_t *script, token_t *token);
//returns the next character of the read white space, returns NULL if none
char PS_NextWhiteSpaceChar(script_t *script);
//remove any leading and trailing double quotes from the token
void StripDoubleQuotes(char *string);
//remove any leading and trailing single quotes from the token
void StripSingleQuotes(char *string);
//read a possible signed integer
signed long int ReadSignedInt(script_t *script);
//read a possible signed floating point number
long double ReadSignedFloat(script_t *script);
//set an array with punctuations, NULL restores default C/C++ set
void SetScriptPunctuations(script_t *script, punctuation_t *p);
//set script flags
void SetScriptFlags(script_t *script, int flags);
//get script flags
int GetScriptFlags(script_t *script);
//reset a script
void ResetScript(script_t *script);
//returns true if at the end of the script
int EndOfScript(script_t *script);
//returns a pointer to the punctuation with the given number
char *PunctuationFromNum(script_t *script, int num);
//load a script from the given file at the given offset with the given length
script_t *LoadScriptFile(const char *filename);
//load a script from the given memory with the given length
script_t *LoadScriptMemory(char *ptr, int length, char *name);
//free a script
void FreeScript(script_t *script);
//set the base folder to load files from
void PS_SetBaseFolder(char *path);
//print a script error with filename and line number
void QDECL ScriptError(script_t *script, char *str, ...);
//print a script warning with filename and line number
void QDECL ScriptWarning(script_t *script, char *str, ...);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: l_script.h
*
* desc: lexicographical parser
*
* $Archive: /source/code/botlib/l_script.h $
*
*****************************************************************************/
//undef if binary numbers of the form 0b... or 0B... are not allowed
#define BINARYNUMBERS
//undef if not using the token.intvalue and token.floatvalue
#define NUMBERVALUE
//use dollar sign also as punctuation
#define DOLLAR
//maximum token length
#define MAX_TOKEN 1024
#if defined(BSPC) && !defined(QDECL)
#define QDECL
#endif
//script flags
#define SCFL_NOERRORS 0x0001
#define SCFL_NOWARNINGS 0x0002
#define SCFL_NOSTRINGWHITESPACES 0x0004
#define SCFL_NOSTRINGESCAPECHARS 0x0008
#define SCFL_PRIMITIVE 0x0010
#define SCFL_NOBINARYNUMBERS 0x0020
#define SCFL_NONUMBERVALUES 0x0040
//token types
#define TT_STRING 1 // string
#define TT_LITERAL 2 // literal
#define TT_NUMBER 3 // number
#define TT_NAME 4 // name
#define TT_PUNCTUATION 5 // punctuation
//string sub type
//---------------
// the length of the string
//literal sub type
//----------------
// the ASCII code of the literal
//number sub type
//---------------
#define TT_DECIMAL 0x0008 // decimal number
#define TT_HEX 0x0100 // hexadecimal number
#define TT_OCTAL 0x0200 // octal number
#ifdef BINARYNUMBERS
#define TT_BINARY 0x0400 // binary number
#endif //BINARYNUMBERS
#define TT_FLOAT 0x0800 // floating point number
#define TT_INTEGER 0x1000 // integer number
#define TT_LONG 0x2000 // long number
#define TT_UNSIGNED 0x4000 // unsigned number
//punctuation sub type
//--------------------
#define P_RSHIFT_ASSIGN 1
#define P_LSHIFT_ASSIGN 2
#define P_PARMS 3
#define P_PRECOMPMERGE 4
#define P_LOGIC_AND 5
#define P_LOGIC_OR 6
#define P_LOGIC_GEQ 7
#define P_LOGIC_LEQ 8
#define P_LOGIC_EQ 9
#define P_LOGIC_UNEQ 10
#define P_MUL_ASSIGN 11
#define P_DIV_ASSIGN 12
#define P_MOD_ASSIGN 13
#define P_ADD_ASSIGN 14
#define P_SUB_ASSIGN 15
#define P_INC 16
#define P_DEC 17
#define P_BIN_AND_ASSIGN 18
#define P_BIN_OR_ASSIGN 19
#define P_BIN_XOR_ASSIGN 20
#define P_RSHIFT 21
#define P_LSHIFT 22
#define P_POINTERREF 23
#define P_CPP1 24
#define P_CPP2 25
#define P_MUL 26
#define P_DIV 27
#define P_MOD 28
#define P_ADD 29
#define P_SUB 30
#define P_ASSIGN 31
#define P_BIN_AND 32
#define P_BIN_OR 33
#define P_BIN_XOR 34
#define P_BIN_NOT 35
#define P_LOGIC_NOT 36
#define P_LOGIC_GREATER 37
#define P_LOGIC_LESS 38
#define P_REF 39
#define P_COMMA 40
#define P_SEMICOLON 41
#define P_COLON 42
#define P_QUESTIONMARK 43
#define P_PARENTHESESOPEN 44
#define P_PARENTHESESCLOSE 45
#define P_BRACEOPEN 46
#define P_BRACECLOSE 47
#define P_SQBRACKETOPEN 48
#define P_SQBRACKETCLOSE 49
#define P_BACKSLASH 50
#define P_PRECOMP 51
#define P_DOLLAR 52
//name sub type
//-------------
// the length of the name
//punctuation
typedef struct punctuation_s
{
char *p; //punctuation character(s)
int n; //punctuation indication
struct punctuation_s *next; //next punctuation
} punctuation_t;
//token
typedef struct token_s
{
char string[MAX_TOKEN]; //available token
int type; //last read token type
int subtype; //last read token sub type
#ifdef NUMBERVALUE
unsigned long int intvalue; //integer value
long double floatvalue; //floating point value
#endif //NUMBERVALUE
char *whitespace_p; //start of white space before token
char *endwhitespace_p; //start of white space before token
int line; //line the token was on
int linescrossed; //lines crossed in white space
struct token_s *next; //next token in chain
} token_t;
//script file
typedef struct script_s
{
char filename[1024]; //file name of the script
char *buffer; //buffer containing the script
char *script_p; //current pointer in the script
char *end_p; //pointer to the end of the script
char *lastscript_p; //script pointer before reading token
char *whitespace_p; //begin of the white space
char *endwhitespace_p; //end of the white space
int length; //length of the script in bytes
int line; //current line in script
int lastline; //line before reading token
int tokenavailable; //set by UnreadLastToken
int flags; //several script flags
punctuation_t *punctuations; //the punctuations used in the script
punctuation_t **punctuationtable;
token_t token; //available token
struct script_s *next; //next script in a chain
} script_t;
//read a token from the script
int PS_ReadToken(script_t *script, token_t *token);
//expect a certain token
int PS_ExpectTokenString(script_t *script, char *string);
//expect a certain token type
int PS_ExpectTokenType(script_t *script, int type, int subtype, token_t *token);
//expect a token
int PS_ExpectAnyToken(script_t *script, token_t *token);
//returns true when the token is available
int PS_CheckTokenString(script_t *script, char *string);
//returns true an reads the token when a token with the given type is available
int PS_CheckTokenType(script_t *script, int type, int subtype, token_t *token);
//skip tokens until the given token string is read
int PS_SkipUntilString(script_t *script, char *string);
//unread the last token read from the script
void PS_UnreadLastToken(script_t *script);
//unread the given token
void PS_UnreadToken(script_t *script, token_t *token);
//returns the next character of the read white space, returns NULL if none
char PS_NextWhiteSpaceChar(script_t *script);
//remove any leading and trailing double quotes from the token
void StripDoubleQuotes(char *string);
//remove any leading and trailing single quotes from the token
void StripSingleQuotes(char *string);
//read a possible signed integer
signed long int ReadSignedInt(script_t *script);
//read a possible signed floating point number
long double ReadSignedFloat(script_t *script);
//set an array with punctuations, NULL restores default C/C++ set
void SetScriptPunctuations(script_t *script, punctuation_t *p);
//set script flags
void SetScriptFlags(script_t *script, int flags);
//get script flags
int GetScriptFlags(script_t *script);
//reset a script
void ResetScript(script_t *script);
//returns true if at the end of the script
int EndOfScript(script_t *script);
//returns a pointer to the punctuation with the given number
char *PunctuationFromNum(script_t *script, int num);
//load a script from the given file at the given offset with the given length
script_t *LoadScriptFile(const char *filename);
//load a script from the given memory with the given length
script_t *LoadScriptMemory(char *ptr, int length, char *name);
//free a script
void FreeScript(script_t *script);
//set the base folder to load files from
void PS_SetBaseFolder(char *path);
//print a script error with filename and line number
void QDECL ScriptError(script_t *script, char *str, ...);
//print a script warning with filename and line number
void QDECL ScriptWarning(script_t *script, char *str, ...);

924
code/botlib/l_struct.c Normal file → Executable file
View file

@ -1,462 +1,462 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: l_struct.c
*
* desc: structure reading / writing
*
* $Archive: /MissionPack/CODE/botlib/l_struct.c $
*
*****************************************************************************/
#ifdef BOTLIB
#include "../game/q_shared.h"
#include "../game/botlib.h" //for the include of be_interface.h
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "l_utils.h"
#include "be_interface.h"
#endif //BOTLIB
#ifdef BSPC
//include files for usage in the BSP Converter
#include "../bspc/qbsp.h"
#include "../bspc/l_log.h"
#include "../bspc/l_mem.h"
#include "l_precomp.h"
#include "l_struct.h"
#define qtrue true
#define qfalse false
#endif //BSPC
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
fielddef_t *FindField(fielddef_t *defs, char *name)
{
int i;
for (i = 0; defs[i].name; i++)
{
if (!strcmp(defs[i].name, name)) return &defs[i];
} //end for
return NULL;
} //end of the function FindField
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean ReadNumber(source_t *source, fielddef_t *fd, void *p)
{
token_t token;
int negative = qfalse;
long int intval, intmin = 0, intmax = 0;
double floatval;
if (!PC_ExpectAnyToken(source, &token)) return 0;
//check for minus sign
if (token.type == TT_PUNCTUATION)
{
if (fd->type & FT_UNSIGNED)
{
SourceError(source, "expected unsigned value, found %s", token.string);
return 0;
} //end if
//if not a minus sign
if (strcmp(token.string, "-"))
{
SourceError(source, "unexpected punctuation %s", token.string);
return 0;
} //end if
negative = qtrue;
//read the number
if (!PC_ExpectAnyToken(source, &token)) return 0;
} //end if
//check if it is a number
if (token.type != TT_NUMBER)
{
SourceError(source, "expected number, found %s", token.string);
return 0;
} //end if
//check for a float value
if (token.subtype & TT_FLOAT)
{
if ((fd->type & FT_TYPE) != FT_FLOAT)
{
SourceError(source, "unexpected float");
return 0;
} //end if
floatval = token.floatvalue;
if (negative) floatval = -floatval;
if (fd->type & FT_BOUNDED)
{
if (floatval < fd->floatmin || floatval > fd->floatmax)
{
SourceError(source, "float out of range [%f, %f]", fd->floatmin, fd->floatmax);
return 0;
} //end if
} //end if
*(float *) p = (float) floatval;
return 1;
} //end if
//
intval = token.intvalue;
if (negative) intval = -intval;
//check bounds
if ((fd->type & FT_TYPE) == FT_CHAR)
{
if (fd->type & FT_UNSIGNED) {intmin = 0; intmax = 255;}
else {intmin = -128; intmax = 127;}
} //end if
if ((fd->type & FT_TYPE) == FT_INT)
{
if (fd->type & FT_UNSIGNED) {intmin = 0; intmax = 65535;}
else {intmin = -32768; intmax = 32767;}
} //end else if
if ((fd->type & FT_TYPE) == FT_CHAR || (fd->type & FT_TYPE) == FT_INT)
{
if (fd->type & FT_BOUNDED)
{
intmin = Maximum(intmin, fd->floatmin);
intmax = Minimum(intmax, fd->floatmax);
} //end if
if (intval < intmin || intval > intmax)
{
SourceError(source, "value %d out of range [%d, %d]", intval, intmin, intmax);
return 0;
} //end if
} //end if
else if ((fd->type & FT_TYPE) == FT_FLOAT)
{
if (fd->type & FT_BOUNDED)
{
if (intval < fd->floatmin || intval > fd->floatmax)
{
SourceError(source, "value %d out of range [%f, %f]", intval, fd->floatmin, fd->floatmax);
return 0;
} //end if
} //end if
} //end else if
//store the value
if ((fd->type & FT_TYPE) == FT_CHAR)
{
if (fd->type & FT_UNSIGNED) *(unsigned char *) p = (unsigned char) intval;
else *(char *) p = (char) intval;
} //end if
else if ((fd->type & FT_TYPE) == FT_INT)
{
if (fd->type & FT_UNSIGNED) *(unsigned int *) p = (unsigned int) intval;
else *(int *) p = (int) intval;
} //end else
else if ((fd->type & FT_TYPE) == FT_FLOAT)
{
*(float *) p = (float) intval;
} //end else
return 1;
} //end of the function ReadNumber
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean ReadChar(source_t *source, fielddef_t *fd, void *p)
{
token_t token;
if (!PC_ExpectAnyToken(source, &token)) return 0;
//take literals into account
if (token.type == TT_LITERAL)
{
StripSingleQuotes(token.string);
*(char *) p = token.string[0];
} //end if
else
{
PC_UnreadLastToken(source);
if (!ReadNumber(source, fd, p)) return 0;
} //end if
return 1;
} //end of the function ReadChar
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int ReadString(source_t *source, fielddef_t *fd, void *p)
{
token_t token;
if (!PC_ExpectTokenType(source, TT_STRING, 0, &token)) return 0;
//remove the double quotes
StripDoubleQuotes(token.string);
//copy the string
strncpy((char *) p, token.string, MAX_STRINGFIELD);
//make sure the string is closed with a zero
((char *)p)[MAX_STRINGFIELD-1] = '\0';
//
return 1;
} //end of the function ReadString
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int ReadStructure(source_t *source, structdef_t *def, char *structure)
{
token_t token;
fielddef_t *fd;
void *p;
int num;
if (!PC_ExpectTokenString(source, "{")) return 0;
while(1)
{
if (!PC_ExpectAnyToken(source, &token)) return qfalse;
//if end of structure
if (!strcmp(token.string, "}")) break;
//find the field with the name
fd = FindField(def->fields, token.string);
if (!fd)
{
SourceError(source, "unknown structure field %s", token.string);
return qfalse;
} //end if
if (fd->type & FT_ARRAY)
{
num = fd->maxarray;
if (!PC_ExpectTokenString(source, "{")) return qfalse;
} //end if
else
{
num = 1;
} //end else
p = (void *)(structure + fd->offset);
while (num-- > 0)
{
if (fd->type & FT_ARRAY)
{
if (PC_CheckTokenString(source, "}")) break;
} //end if
switch(fd->type & FT_TYPE)
{
case FT_CHAR:
{
if (!ReadChar(source, fd, p)) return qfalse;
p = (char *) p + sizeof(char);
break;
} //end case
case FT_INT:
{
if (!ReadNumber(source, fd, p)) return qfalse;
p = (char *) p + sizeof(int);
break;
} //end case
case FT_FLOAT:
{
if (!ReadNumber(source, fd, p)) return qfalse;
p = (char *) p + sizeof(float);
break;
} //end case
case FT_STRING:
{
if (!ReadString(source, fd, p)) return qfalse;
p = (char *) p + MAX_STRINGFIELD;
break;
} //end case
case FT_STRUCT:
{
if (!fd->substruct)
{
SourceError(source, "BUG: no sub structure defined");
return qfalse;
} //end if
ReadStructure(source, fd->substruct, (char *) p);
p = (char *) p + fd->substruct->size;
break;
} //end case
} //end switch
if (fd->type & FT_ARRAY)
{
if (!PC_ExpectAnyToken(source, &token)) return qfalse;
if (!strcmp(token.string, "}")) break;
if (strcmp(token.string, ","))
{
SourceError(source, "expected a comma, found %s", token.string);
return qfalse;
} //end if
} //end if
} //end while
} //end while
return qtrue;
} //end of the function ReadStructure
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int WriteIndent(FILE *fp, int indent)
{
while(indent-- > 0)
{
if (fprintf(fp, "\t") < 0) return qfalse;
} //end while
return qtrue;
} //end of the function WriteIndent
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int WriteFloat(FILE *fp, float value)
{
char buf[128];
int l;
sprintf(buf, "%f", value);
l = strlen(buf);
//strip any trailing zeros
while(l-- > 1)
{
if (buf[l] != '0' && buf[l] != '.') break;
if (buf[l] == '.')
{
buf[l] = 0;
break;
} //end if
buf[l] = 0;
} //end while
//write the float to file
if (fprintf(fp, "%s", buf) < 0) return 0;
return 1;
} //end of the function WriteFloat
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int WriteStructWithIndent(FILE *fp, structdef_t *def, char *structure, int indent)
{
int i, num;
void *p;
fielddef_t *fd;
if (!WriteIndent(fp, indent)) return qfalse;
if (fprintf(fp, "{\r\n") < 0) return qfalse;
indent++;
for (i = 0; def->fields[i].name; i++)
{
fd = &def->fields[i];
if (!WriteIndent(fp, indent)) return qfalse;
if (fprintf(fp, "%s\t", fd->name) < 0) return qfalse;
p = (void *)(structure + fd->offset);
if (fd->type & FT_ARRAY)
{
num = fd->maxarray;
if (fprintf(fp, "{") < 0) return qfalse;
} //end if
else
{
num = 1;
} //end else
while(num-- > 0)
{
switch(fd->type & FT_TYPE)
{
case FT_CHAR:
{
if (fprintf(fp, "%d", *(char *) p) < 0) return qfalse;
p = (char *) p + sizeof(char);
break;
} //end case
case FT_INT:
{
if (fprintf(fp, "%d", *(int *) p) < 0) return qfalse;
p = (char *) p + sizeof(int);
break;
} //end case
case FT_FLOAT:
{
if (!WriteFloat(fp, *(float *)p)) return qfalse;
p = (char *) p + sizeof(float);
break;
} //end case
case FT_STRING:
{
if (fprintf(fp, "\"%s\"", (char *) p) < 0) return qfalse;
p = (char *) p + MAX_STRINGFIELD;
break;
} //end case
case FT_STRUCT:
{
if (!WriteStructWithIndent(fp, fd->substruct, structure, indent)) return qfalse;
p = (char *) p + fd->substruct->size;
break;
} //end case
} //end switch
if (fd->type & FT_ARRAY)
{
if (num > 0)
{
if (fprintf(fp, ",") < 0) return qfalse;
} //end if
else
{
if (fprintf(fp, "}") < 0) return qfalse;
} //end else
} //end if
} //end while
if (fprintf(fp, "\r\n") < 0) return qfalse;
} //end for
indent--;
if (!WriteIndent(fp, indent)) return qfalse;
if (fprintf(fp, "}\r\n") < 0) return qfalse;
return qtrue;
} //end of the function WriteStructWithIndent
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int WriteStructure(FILE *fp, structdef_t *def, char *structure)
{
return WriteStructWithIndent(fp, def, structure, 0);
} //end of the function WriteStructure
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: l_struct.c
*
* desc: structure reading / writing
*
* $Archive: /MissionPack/CODE/botlib/l_struct.c $
*
*****************************************************************************/
#ifdef BOTLIB
#include "../game/q_shared.h"
#include "../game/botlib.h" //for the include of be_interface.h
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "l_utils.h"
#include "be_interface.h"
#endif //BOTLIB
#ifdef BSPC
//include files for usage in the BSP Converter
#include "../bspc/qbsp.h"
#include "../bspc/l_log.h"
#include "../bspc/l_mem.h"
#include "l_precomp.h"
#include "l_struct.h"
#define qtrue true
#define qfalse false
#endif //BSPC
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
fielddef_t *FindField(fielddef_t *defs, char *name)
{
int i;
for (i = 0; defs[i].name; i++)
{
if (!strcmp(defs[i].name, name)) return &defs[i];
} //end for
return NULL;
} //end of the function FindField
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean ReadNumber(source_t *source, fielddef_t *fd, void *p)
{
token_t token;
int negative = qfalse;
long int intval, intmin = 0, intmax = 0;
double floatval;
if (!PC_ExpectAnyToken(source, &token)) return 0;
//check for minus sign
if (token.type == TT_PUNCTUATION)
{
if (fd->type & FT_UNSIGNED)
{
SourceError(source, "expected unsigned value, found %s", token.string);
return 0;
} //end if
//if not a minus sign
if (strcmp(token.string, "-"))
{
SourceError(source, "unexpected punctuation %s", token.string);
return 0;
} //end if
negative = qtrue;
//read the number
if (!PC_ExpectAnyToken(source, &token)) return 0;
} //end if
//check if it is a number
if (token.type != TT_NUMBER)
{
SourceError(source, "expected number, found %s", token.string);
return 0;
} //end if
//check for a float value
if (token.subtype & TT_FLOAT)
{
if ((fd->type & FT_TYPE) != FT_FLOAT)
{
SourceError(source, "unexpected float");
return 0;
} //end if
floatval = token.floatvalue;
if (negative) floatval = -floatval;
if (fd->type & FT_BOUNDED)
{
if (floatval < fd->floatmin || floatval > fd->floatmax)
{
SourceError(source, "float out of range [%f, %f]", fd->floatmin, fd->floatmax);
return 0;
} //end if
} //end if
*(float *) p = (float) floatval;
return 1;
} //end if
//
intval = token.intvalue;
if (negative) intval = -intval;
//check bounds
if ((fd->type & FT_TYPE) == FT_CHAR)
{
if (fd->type & FT_UNSIGNED) {intmin = 0; intmax = 255;}
else {intmin = -128; intmax = 127;}
} //end if
if ((fd->type & FT_TYPE) == FT_INT)
{
if (fd->type & FT_UNSIGNED) {intmin = 0; intmax = 65535;}
else {intmin = -32768; intmax = 32767;}
} //end else if
if ((fd->type & FT_TYPE) == FT_CHAR || (fd->type & FT_TYPE) == FT_INT)
{
if (fd->type & FT_BOUNDED)
{
intmin = Maximum(intmin, fd->floatmin);
intmax = Minimum(intmax, fd->floatmax);
} //end if
if (intval < intmin || intval > intmax)
{
SourceError(source, "value %d out of range [%d, %d]", intval, intmin, intmax);
return 0;
} //end if
} //end if
else if ((fd->type & FT_TYPE) == FT_FLOAT)
{
if (fd->type & FT_BOUNDED)
{
if (intval < fd->floatmin || intval > fd->floatmax)
{
SourceError(source, "value %d out of range [%f, %f]", intval, fd->floatmin, fd->floatmax);
return 0;
} //end if
} //end if
} //end else if
//store the value
if ((fd->type & FT_TYPE) == FT_CHAR)
{
if (fd->type & FT_UNSIGNED) *(unsigned char *) p = (unsigned char) intval;
else *(char *) p = (char) intval;
} //end if
else if ((fd->type & FT_TYPE) == FT_INT)
{
if (fd->type & FT_UNSIGNED) *(unsigned int *) p = (unsigned int) intval;
else *(int *) p = (int) intval;
} //end else
else if ((fd->type & FT_TYPE) == FT_FLOAT)
{
*(float *) p = (float) intval;
} //end else
return 1;
} //end of the function ReadNumber
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean ReadChar(source_t *source, fielddef_t *fd, void *p)
{
token_t token;
if (!PC_ExpectAnyToken(source, &token)) return 0;
//take literals into account
if (token.type == TT_LITERAL)
{
StripSingleQuotes(token.string);
*(char *) p = token.string[0];
} //end if
else
{
PC_UnreadLastToken(source);
if (!ReadNumber(source, fd, p)) return 0;
} //end if
return 1;
} //end of the function ReadChar
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int ReadString(source_t *source, fielddef_t *fd, void *p)
{
token_t token;
if (!PC_ExpectTokenType(source, TT_STRING, 0, &token)) return 0;
//remove the double quotes
StripDoubleQuotes(token.string);
//copy the string
strncpy((char *) p, token.string, MAX_STRINGFIELD);
//make sure the string is closed with a zero
((char *)p)[MAX_STRINGFIELD-1] = '\0';
//
return 1;
} //end of the function ReadString
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int ReadStructure(source_t *source, structdef_t *def, char *structure)
{
token_t token;
fielddef_t *fd;
void *p;
int num;
if (!PC_ExpectTokenString(source, "{")) return 0;
while(1)
{
if (!PC_ExpectAnyToken(source, &token)) return qfalse;
//if end of structure
if (!strcmp(token.string, "}")) break;
//find the field with the name
fd = FindField(def->fields, token.string);
if (!fd)
{
SourceError(source, "unknown structure field %s", token.string);
return qfalse;
} //end if
if (fd->type & FT_ARRAY)
{
num = fd->maxarray;
if (!PC_ExpectTokenString(source, "{")) return qfalse;
} //end if
else
{
num = 1;
} //end else
p = (void *)(structure + fd->offset);
while (num-- > 0)
{
if (fd->type & FT_ARRAY)
{
if (PC_CheckTokenString(source, "}")) break;
} //end if
switch(fd->type & FT_TYPE)
{
case FT_CHAR:
{
if (!ReadChar(source, fd, p)) return qfalse;
p = (char *) p + sizeof(char);
break;
} //end case
case FT_INT:
{
if (!ReadNumber(source, fd, p)) return qfalse;
p = (char *) p + sizeof(int);
break;
} //end case
case FT_FLOAT:
{
if (!ReadNumber(source, fd, p)) return qfalse;
p = (char *) p + sizeof(float);
break;
} //end case
case FT_STRING:
{
if (!ReadString(source, fd, p)) return qfalse;
p = (char *) p + MAX_STRINGFIELD;
break;
} //end case
case FT_STRUCT:
{
if (!fd->substruct)
{
SourceError(source, "BUG: no sub structure defined");
return qfalse;
} //end if
ReadStructure(source, fd->substruct, (char *) p);
p = (char *) p + fd->substruct->size;
break;
} //end case
} //end switch
if (fd->type & FT_ARRAY)
{
if (!PC_ExpectAnyToken(source, &token)) return qfalse;
if (!strcmp(token.string, "}")) break;
if (strcmp(token.string, ","))
{
SourceError(source, "expected a comma, found %s", token.string);
return qfalse;
} //end if
} //end if
} //end while
} //end while
return qtrue;
} //end of the function ReadStructure
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int WriteIndent(FILE *fp, int indent)
{
while(indent-- > 0)
{
if (fprintf(fp, "\t") < 0) return qfalse;
} //end while
return qtrue;
} //end of the function WriteIndent
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int WriteFloat(FILE *fp, float value)
{
char buf[128];
int l;
sprintf(buf, "%f", value);
l = strlen(buf);
//strip any trailing zeros
while(l-- > 1)
{
if (buf[l] != '0' && buf[l] != '.') break;
if (buf[l] == '.')
{
buf[l] = 0;
break;
} //end if
buf[l] = 0;
} //end while
//write the float to file
if (fprintf(fp, "%s", buf) < 0) return 0;
return 1;
} //end of the function WriteFloat
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int WriteStructWithIndent(FILE *fp, structdef_t *def, char *structure, int indent)
{
int i, num;
void *p;
fielddef_t *fd;
if (!WriteIndent(fp, indent)) return qfalse;
if (fprintf(fp, "{\r\n") < 0) return qfalse;
indent++;
for (i = 0; def->fields[i].name; i++)
{
fd = &def->fields[i];
if (!WriteIndent(fp, indent)) return qfalse;
if (fprintf(fp, "%s\t", fd->name) < 0) return qfalse;
p = (void *)(structure + fd->offset);
if (fd->type & FT_ARRAY)
{
num = fd->maxarray;
if (fprintf(fp, "{") < 0) return qfalse;
} //end if
else
{
num = 1;
} //end else
while(num-- > 0)
{
switch(fd->type & FT_TYPE)
{
case FT_CHAR:
{
if (fprintf(fp, "%d", *(char *) p) < 0) return qfalse;
p = (char *) p + sizeof(char);
break;
} //end case
case FT_INT:
{
if (fprintf(fp, "%d", *(int *) p) < 0) return qfalse;
p = (char *) p + sizeof(int);
break;
} //end case
case FT_FLOAT:
{
if (!WriteFloat(fp, *(float *)p)) return qfalse;
p = (char *) p + sizeof(float);
break;
} //end case
case FT_STRING:
{
if (fprintf(fp, "\"%s\"", (char *) p) < 0) return qfalse;
p = (char *) p + MAX_STRINGFIELD;
break;
} //end case
case FT_STRUCT:
{
if (!WriteStructWithIndent(fp, fd->substruct, structure, indent)) return qfalse;
p = (char *) p + fd->substruct->size;
break;
} //end case
} //end switch
if (fd->type & FT_ARRAY)
{
if (num > 0)
{
if (fprintf(fp, ",") < 0) return qfalse;
} //end if
else
{
if (fprintf(fp, "}") < 0) return qfalse;
} //end else
} //end if
} //end while
if (fprintf(fp, "\r\n") < 0) return qfalse;
} //end for
indent--;
if (!WriteIndent(fp, indent)) return qfalse;
if (fprintf(fp, "}\r\n") < 0) return qfalse;
return qtrue;
} //end of the function WriteStructWithIndent
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int WriteStructure(FILE *fp, structdef_t *def, char *structure)
{
return WriteStructWithIndent(fp, def, structure, 0);
} //end of the function WriteStructure

150
code/botlib/l_struct.h Normal file → Executable file
View file

@ -1,75 +1,75 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: l_struct.h
*
* desc: structure reading/writing
*
* $Archive: /source/code/botlib/l_struct.h $
*
*****************************************************************************/
#define MAX_STRINGFIELD 80
//field types
#define FT_CHAR 1 // char
#define FT_INT 2 // int
#define FT_FLOAT 3 // float
#define FT_STRING 4 // char [MAX_STRINGFIELD]
#define FT_STRUCT 6 // struct (sub structure)
//type only mask
#define FT_TYPE 0x00FF // only type, clear subtype
//sub types
#define FT_ARRAY 0x0100 // array of type
#define FT_BOUNDED 0x0200 // bounded value
#define FT_UNSIGNED 0x0400
//structure field definition
typedef struct fielddef_s
{
char *name; //name of the field
int offset; //offset in the structure
int type; //type of the field
//type specific fields
int maxarray; //maximum array size
float floatmin, floatmax; //float min and max
struct structdef_s *substruct; //sub structure
} fielddef_t;
//structure definition
typedef struct structdef_s
{
int size;
fielddef_t *fields;
} structdef_t;
//read a structure from a script
int ReadStructure(source_t *source, structdef_t *def, char *structure);
//write a structure to a file
int WriteStructure(FILE *fp, structdef_t *def, char *structure);
//writes indents
int WriteIndent(FILE *fp, int indent);
//writes a float without traling zeros
int WriteFloat(FILE *fp, float value);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: l_struct.h
*
* desc: structure reading/writing
*
* $Archive: /source/code/botlib/l_struct.h $
*
*****************************************************************************/
#define MAX_STRINGFIELD 80
//field types
#define FT_CHAR 1 // char
#define FT_INT 2 // int
#define FT_FLOAT 3 // float
#define FT_STRING 4 // char [MAX_STRINGFIELD]
#define FT_STRUCT 6 // struct (sub structure)
//type only mask
#define FT_TYPE 0x00FF // only type, clear subtype
//sub types
#define FT_ARRAY 0x0100 // array of type
#define FT_BOUNDED 0x0200 // bounded value
#define FT_UNSIGNED 0x0400
//structure field definition
typedef struct fielddef_s
{
char *name; //name of the field
int offset; //offset in the structure
int type; //type of the field
//type specific fields
int maxarray; //maximum array size
float floatmin, floatmax; //float min and max
struct structdef_s *substruct; //sub structure
} fielddef_t;
//structure definition
typedef struct structdef_s
{
int size;
fielddef_t *fields;
} structdef_t;
//read a structure from a script
int ReadStructure(source_t *source, structdef_t *def, char *structure);
//write a structure to a file
int WriteStructure(FILE *fp, structdef_t *def, char *structure);
//writes indents
int WriteIndent(FILE *fp, int indent);
//writes a float without traling zeros
int WriteFloat(FILE *fp, float value);

70
code/botlib/l_utils.h Normal file → Executable file
View file

@ -1,35 +1,35 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: l_util.h
*
* desc: utils
*
* $Archive: /source/code/botlib/l_util.h $
*
*****************************************************************************/
#define Vector2Angles(v,a) vectoangles(v,a)
#define MAX_PATH MAX_QPATH
#define Maximum(x,y) (x > y ? x : y)
#define Minimum(x,y) (x < y ? x : y)
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/*****************************************************************************
* name: l_util.h
*
* desc: utils
*
* $Archive: /source/code/botlib/l_util.h $
*
*****************************************************************************/
#define Vector2Angles(v,a) vectoangles(v,a)
#define MAX_PATH MAX_QPATH
#define Maximum(x,y) (x > y ? x : y)
#define Minimum(x,y) (x < y ? x : y)

110
code/botlib/lcc.mak Normal file → Executable file
View file

@ -1,55 +1,55 @@
#
# Makefile for Gladiator Bot library: gladiator.dll
# Intended for LCC-Win32
#
CC=lcc
CFLAGS=-DC_ONLY -o
OBJS= be_aas_bspq2.obj \
be_aas_bsphl.obj \
be_aas_cluster.obj \
be_aas_debug.obj \
be_aas_entity.obj \
be_aas_file.obj \
be_aas_light.obj \
be_aas_main.obj \
be_aas_move.obj \
be_aas_optimize.obj \
be_aas_reach.obj \
be_aas_route.obj \
be_aas_routealt.obj \
be_aas_sample.obj \
be_aas_sound.obj \
be_ai2_dm.obj \
be_ai2_dmnet.obj \
be_ai2_main.obj \
be_ai_char.obj \
be_ai_chat.obj \
be_ai_goal.obj \
be_ai_load.obj \
be_ai_move.obj \
be_ai_weap.obj \
be_ai_weight.obj \
be_ea.obj \
be_interface.obj \
l_crc.obj \
l_libvar.obj \
l_log.obj \
l_memory.obj \
l_precomp.obj \
l_script.obj \
l_struct.obj \
l_utils.obj \
q_shared.obj
all: gladiator.dll
gladiator.dll: $(OBJS)
lcclnk -dll -entry GetBotAPI *.obj botlib.def -o gladiator.dll
clean:
del *.obj gladiator.dll
%.obj: %.c
$(CC) $(CFLAGS) $<
#
# Makefile for Gladiator Bot library: gladiator.dll
# Intended for LCC-Win32
#
CC=lcc
CFLAGS=-DC_ONLY -o
OBJS= be_aas_bspq2.obj \
be_aas_bsphl.obj \
be_aas_cluster.obj \
be_aas_debug.obj \
be_aas_entity.obj \
be_aas_file.obj \
be_aas_light.obj \
be_aas_main.obj \
be_aas_move.obj \
be_aas_optimize.obj \
be_aas_reach.obj \
be_aas_route.obj \
be_aas_routealt.obj \
be_aas_sample.obj \
be_aas_sound.obj \
be_ai2_dm.obj \
be_ai2_dmnet.obj \
be_ai2_main.obj \
be_ai_char.obj \
be_ai_chat.obj \
be_ai_goal.obj \
be_ai_load.obj \
be_ai_move.obj \
be_ai_weap.obj \
be_ai_weight.obj \
be_ea.obj \
be_interface.obj \
l_crc.obj \
l_libvar.obj \
l_log.obj \
l_memory.obj \
l_precomp.obj \
l_script.obj \
l_struct.obj \
l_utils.obj \
q_shared.obj
all: gladiator.dll
gladiator.dll: $(OBJS)
lcclnk -dll -entry GetBotAPI *.obj botlib.def -o gladiator.dll
clean:
del *.obj gladiator.dll
%.obj: %.c
$(CC) $(CFLAGS) $<

184
code/botlib/linux-i386.mak Normal file → Executable file
View file

@ -1,92 +1,92 @@
#
# Makefile for Gladiator Bot library: gladiator.so
# Intended for gcc/Linux
#
ARCH=i386
CC=gcc
BASE_CFLAGS=-Dstricmp=strcasecmp
#use these cflags to optimize it
CFLAGS=$(BASE_CFLAGS) -m486 -O6 -ffast-math -funroll-loops \
-fomit-frame-pointer -fexpensive-optimizations -malign-loops=2 \
-malign-jumps=2 -malign-functions=2
#use these when debugging
#CFLAGS=$(BASE_CFLAGS) -g
LDFLAGS=-ldl -lm
SHLIBEXT=so
SHLIBCFLAGS=-fPIC
SHLIBLDFLAGS=-shared
DO_CC=$(CC) $(CFLAGS) $(SHLIBCFLAGS) -o $@ -c $<
#############################################################################
# SETUP AND BUILD
# GLADIATOR BOT
#############################################################################
.c.o:
$(DO_CC)
GAME_OBJS = \
be_aas_bsphl.o\
be_aas_bspq2.o\
be_aas_cluster.o\
be_aas_debug.o\
be_aas_entity.o\
be_aas_file.o\
be_aas_light.o\
be_aas_main.o\
be_aas_move.o\
be_aas_optimize.o\
be_aas_reach.o\
be_aas_route.o\
be_aas_routealt.o\
be_aas_sample.o\
be_aas_sound.o\
be_ai2_dmq2.o\
be_ai2_dmhl.o\
be_ai2_dmnet.o\
be_ai2_main.o\
be_ai_char.o\
be_ai_chat.o\
be_ai_goal.o\
be_ai_load.o\
be_ai_move.o\
be_ai_weap.o\
be_ai_weight.o\
be_ea.o\
be_interface.o\
l_crc.o\
l_libvar.o\
l_log.o\
l_memory.o\
l_precomp.o\
l_script.o\
l_struct.o\
l_utils.o\
q_shared.o
glad$(ARCH).$(SHLIBEXT) : $(GAME_OBJS)
$(CC) $(CFLAGS) $(SHLIBLDFLAGS) -o $@ $(GAME_OBJS)
#############################################################################
# MISC
#############################################################################
clean:
-rm -f $(GAME_OBJS)
depend:
gcc -MM $(GAME_OBJS:.o=.c)
install:
cp gladiator.so ..
#
# From "make depend"
#
#
# Makefile for Gladiator Bot library: gladiator.so
# Intended for gcc/Linux
#
ARCH=i386
CC=gcc
BASE_CFLAGS=-Dstricmp=strcasecmp
#use these cflags to optimize it
CFLAGS=$(BASE_CFLAGS) -m486 -O6 -ffast-math -funroll-loops \
-fomit-frame-pointer -fexpensive-optimizations -malign-loops=2 \
-malign-jumps=2 -malign-functions=2
#use these when debugging
#CFLAGS=$(BASE_CFLAGS) -g
LDFLAGS=-ldl -lm
SHLIBEXT=so
SHLIBCFLAGS=-fPIC
SHLIBLDFLAGS=-shared
DO_CC=$(CC) $(CFLAGS) $(SHLIBCFLAGS) -o $@ -c $<
#############################################################################
# SETUP AND BUILD
# GLADIATOR BOT
#############################################################################
.c.o:
$(DO_CC)
GAME_OBJS = \
be_aas_bsphl.o\
be_aas_bspq2.o\
be_aas_cluster.o\
be_aas_debug.o\
be_aas_entity.o\
be_aas_file.o\
be_aas_light.o\
be_aas_main.o\
be_aas_move.o\
be_aas_optimize.o\
be_aas_reach.o\
be_aas_route.o\
be_aas_routealt.o\
be_aas_sample.o\
be_aas_sound.o\
be_ai2_dmq2.o\
be_ai2_dmhl.o\
be_ai2_dmnet.o\
be_ai2_main.o\
be_ai_char.o\
be_ai_chat.o\
be_ai_goal.o\
be_ai_load.o\
be_ai_move.o\
be_ai_weap.o\
be_ai_weight.o\
be_ea.o\
be_interface.o\
l_crc.o\
l_libvar.o\
l_log.o\
l_memory.o\
l_precomp.o\
l_script.o\
l_struct.o\
l_utils.o\
q_shared.o
glad$(ARCH).$(SHLIBEXT) : $(GAME_OBJS)
$(CC) $(CFLAGS) $(SHLIBLDFLAGS) -o $@ $(GAME_OBJS)
#############################################################################
# MISC
#############################################################################
clean:
-rm -f $(GAME_OBJS)
depend:
gcc -MM $(GAME_OBJS:.o=.c)
install:
cp gladiator.so ..
#
# From "make depend"
#

150
code/bspc/Conscript Normal file → Executable file
View file

@ -1,75 +1,75 @@
# bspc compile
Import qw( BSPC_BASE_CFLAGS BUILD_DIR INSTALL_DIR CC CXX LINK );
@BSPC_FILES = qw(
aas_areamerging.c
aas_cfg.c
aas_create.c
aas_edgemelting.c
aas_facemerging.c
aas_file.c
aas_gsubdiv.c
aas_map.c
aas_prunenodes.c
aas_store.c
be_aas_bspc.c
../botlib/be_aas_bspq3.c
../botlib/be_aas_cluster.c
../botlib/be_aas_move.c
../botlib/be_aas_optimize.c
../botlib/be_aas_reach.c
../botlib/be_aas_sample.c
brushbsp.c
bspc.c
../qcommon/cm_load.c
../qcommon/cm_patch.c
../qcommon/cm_test.c
../qcommon/cm_trace.c
csg.c
glfile.c
l_bsp_ent.c
l_bsp_hl.c
l_bsp_q1.c
l_bsp_q2.c
l_bsp_q3.c
l_bsp_sin.c
l_cmd.c
../botlib/l_libvar.c
l_log.c
l_math.c
l_mem.c
l_poly.c
../botlib/l_precomp.c
l_qfiles.c
../botlib/l_script.c
../botlib/l_struct.c
l_threads.c
l_utils.c
leakfile.c
map.c
map_hl.c
map_q1.c
map_q2.c
map_q3.c
map_sin.c
../qcommon/md4.c
nodraw.c
portals.c
textures.c
tree.c
../qcommon/unzip.c
);
$BSPC_REF = \@BSPC_FILES;
$env = new cons(
CC => $CC,
CXX => $CXX,
LINK => $LINK,
CFLAGS => $BSPC_BASE_CFLAGS,
LIBS => '-ldl -lm -lpthread'
);
Program $env 'bspc', @$BSPC_REF;
# this should install to Q3 or something?
Install $env $INSTALL_DIR, 'bspc';
# bspc compile
Import qw( BSPC_BASE_CFLAGS BUILD_DIR INSTALL_DIR CC CXX LINK );
@BSPC_FILES = qw(
aas_areamerging.c
aas_cfg.c
aas_create.c
aas_edgemelting.c
aas_facemerging.c
aas_file.c
aas_gsubdiv.c
aas_map.c
aas_prunenodes.c
aas_store.c
be_aas_bspc.c
../botlib/be_aas_bspq3.c
../botlib/be_aas_cluster.c
../botlib/be_aas_move.c
../botlib/be_aas_optimize.c
../botlib/be_aas_reach.c
../botlib/be_aas_sample.c
brushbsp.c
bspc.c
../qcommon/cm_load.c
../qcommon/cm_patch.c
../qcommon/cm_test.c
../qcommon/cm_trace.c
csg.c
glfile.c
l_bsp_ent.c
l_bsp_hl.c
l_bsp_q1.c
l_bsp_q2.c
l_bsp_q3.c
l_bsp_sin.c
l_cmd.c
../botlib/l_libvar.c
l_log.c
l_math.c
l_mem.c
l_poly.c
../botlib/l_precomp.c
l_qfiles.c
../botlib/l_script.c
../botlib/l_struct.c
l_threads.c
l_utils.c
leakfile.c
map.c
map_hl.c
map_q1.c
map_q2.c
map_q3.c
map_sin.c
../qcommon/md4.c
nodraw.c
portals.c
textures.c
tree.c
../qcommon/unzip.c
);
$BSPC_REF = \@BSPC_FILES;
$env = new cons(
CC => $CC,
CXX => $CXX,
LINK => $LINK,
CFLAGS => $BSPC_BASE_CFLAGS,
LIBS => '-ldl -lm -lpthread'
);
Program $env 'bspc', @$BSPC_REF;
# this should install to Q3 or something?
Install $env $INSTALL_DIR, 'bspc';

228
code/bspc/Makefile Normal file → Executable file
View file

@ -1,114 +1,114 @@
#
# Makefile for the BSPC tool for the Gladiator Bot
# Intended for gcc/Linux
#
# TTimo 5/15/2001
# some cleanup .. only used on i386 for GtkRadiant setups AFAIK .. removing the i386 tag
# TODO: the intermediate object files should go into their own directory
# specially for ../botlib and ../qcommon, the compilation flags on those might not be what you expect
#ARCH=i386
CC=gcc
BASE_CFLAGS=-Dstricmp=strcasecmp
#use these cflags to optimize it
CFLAGS=$(BASE_CFLAGS) -m486 -O6 -ffast-math -funroll-loops \
-fomit-frame-pointer -fexpensive-optimizations -malign-loops=2 \
-malign-jumps=2 -malign-functions=2 -DLINUX -DBSPC
#use these when debugging
#CFLAGS=$(BASE_CFLAGS) -g
LDFLAGS=-ldl -lm -lpthread
DO_CC=$(CC) $(CFLAGS) -o $@ -c $<
#############################################################################
# SETUP AND BUILD BSPC
#############################################################################
.c.o:
$(DO_CC)
GAME_OBJS = \
_files.o\
aas_areamerging.o\
aas_cfg.o\
aas_create.o\
aas_edgemelting.o\
aas_facemerging.o\
aas_file.o\
aas_gsubdiv.o\
aas_map.o\
aas_prunenodes.o\
aas_store.o\
be_aas_bspc.o\
../botlib/be_aas_bspq3.o\
../botlib/be_aas_cluster.o\
../botlib/be_aas_move.o\
../botlib/be_aas_optimize.o\
../botlib/be_aas_reach.o\
../botlib/be_aas_sample.o\
brushbsp.o\
bspc.o\
../qcommon/cm_load.o\
../qcommon/cm_patch.o\
../qcommon/cm_test.o\
../qcommon/cm_trace.o\
csg.o\
glfile.o\
l_bsp_ent.o\
l_bsp_hl.o\
l_bsp_q1.o\
l_bsp_q2.o\
l_bsp_q3.o\
l_bsp_sin.o\
l_cmd.o\
../botlib/l_libvar.o\
l_log.o\
l_math.o\
l_mem.o\
l_poly.o\
../botlib/l_precomp.o\
l_qfiles.o\
../botlib/l_script.o\
../botlib/l_struct.o\
l_threads.o\
l_utils.o\
leakfile.o\
map.o\
map_hl.o\
map_q1.o\
map_q2.o\
map_q3.o\
map_sin.o\
../qcommon/md4.o\
nodraw.o\
portals.o\
textures.o\
tree.o\
../qcommon/unzip.o
#tetrahedron.o
bspc : $(GAME_OBJS)
$(CC) $(CFLAGS) -o $@ $(GAME_OBJS) $(LDFLAGS)
strip $@
#############################################################################
# MISC
#############################################################################
clean:
-rm -f $(GAME_OBJS)
depend:
gcc -MM $(GAME_OBJS:.o=.c)
#install:
# cp bspci386 ..
#
# From "make depend"
#
#
# Makefile for the BSPC tool for the Gladiator Bot
# Intended for gcc/Linux
#
# TTimo 5/15/2001
# some cleanup .. only used on i386 for GtkRadiant setups AFAIK .. removing the i386 tag
# TODO: the intermediate object files should go into their own directory
# specially for ../botlib and ../qcommon, the compilation flags on those might not be what you expect
#ARCH=i386
CC=gcc
BASE_CFLAGS=-Dstricmp=strcasecmp
#use these cflags to optimize it
CFLAGS=$(BASE_CFLAGS) -m486 -O6 -ffast-math -funroll-loops \
-fomit-frame-pointer -fexpensive-optimizations -malign-loops=2 \
-malign-jumps=2 -malign-functions=2 -DLINUX -DBSPC
#use these when debugging
#CFLAGS=$(BASE_CFLAGS) -g
LDFLAGS=-ldl -lm -lpthread
DO_CC=$(CC) $(CFLAGS) -o $@ -c $<
#############################################################################
# SETUP AND BUILD BSPC
#############################################################################
.c.o:
$(DO_CC)
GAME_OBJS = \
_files.o\
aas_areamerging.o\
aas_cfg.o\
aas_create.o\
aas_edgemelting.o\
aas_facemerging.o\
aas_file.o\
aas_gsubdiv.o\
aas_map.o\
aas_prunenodes.o\
aas_store.o\
be_aas_bspc.o\
../botlib/be_aas_bspq3.o\
../botlib/be_aas_cluster.o\
../botlib/be_aas_move.o\
../botlib/be_aas_optimize.o\
../botlib/be_aas_reach.o\
../botlib/be_aas_sample.o\
brushbsp.o\
bspc.o\
../qcommon/cm_load.o\
../qcommon/cm_patch.o\
../qcommon/cm_test.o\
../qcommon/cm_trace.o\
csg.o\
glfile.o\
l_bsp_ent.o\
l_bsp_hl.o\
l_bsp_q1.o\
l_bsp_q2.o\
l_bsp_q3.o\
l_bsp_sin.o\
l_cmd.o\
../botlib/l_libvar.o\
l_log.o\
l_math.o\
l_mem.o\
l_poly.o\
../botlib/l_precomp.o\
l_qfiles.o\
../botlib/l_script.o\
../botlib/l_struct.o\
l_threads.o\
l_utils.o\
leakfile.o\
map.o\
map_hl.o\
map_q1.o\
map_q2.o\
map_q3.o\
map_sin.o\
../qcommon/md4.o\
nodraw.o\
portals.o\
textures.o\
tree.o\
../qcommon/unzip.o
#tetrahedron.o
bspc : $(GAME_OBJS)
$(CC) $(CFLAGS) -o $@ $(GAME_OBJS) $(LDFLAGS)
strip $@
#############################################################################
# MISC
#############################################################################
clean:
-rm -f $(GAME_OBJS)
depend:
gcc -MM $(GAME_OBJS:.o=.c)
#install:
# cp bspci386 ..
#
# From "make depend"
#

0
code/bspc/_files.c Normal file → Executable file
View file

780
code/bspc/aas_areamerging.c Normal file → Executable file
View file

@ -1,390 +1,390 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "qbsp.h"
#include "../botlib/aasfile.h"
#include "aas_create.h"
#include "aas_store.h"
#define CONVEX_EPSILON 0.3
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
tmp_node_t *AAS_RefreshMergedTree_r(tmp_node_t *tmpnode)
{
tmp_area_t *tmparea;
//if this is a solid leaf
if (!tmpnode) return NULL;
//if this is an area leaf
if (tmpnode->tmparea)
{
tmparea = tmpnode->tmparea;
while(tmparea->mergedarea) tmparea = tmparea->mergedarea;
tmpnode->tmparea = tmparea;
return tmpnode;
} //end if
//do the children recursively
tmpnode->children[0] = AAS_RefreshMergedTree_r(tmpnode->children[0]);
tmpnode->children[1] = AAS_RefreshMergedTree_r(tmpnode->children[1]);
return tmpnode;
} //end of the function AAS_RefreshMergedTree_r
//===========================================================================
// returns true if the two given faces would create a non-convex area at
// the given sides, otherwise false is returned
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int NonConvex(tmp_face_t *face1, tmp_face_t *face2, int side1, int side2)
{
int i;
winding_t *w1, *w2;
plane_t *plane1, *plane2;
w1 = face1->winding;
w2 = face2->winding;
plane1 = &mapplanes[face1->planenum ^ side1];
plane2 = &mapplanes[face2->planenum ^ side2];
//check if one of the points of face1 is at the back of the plane of face2
for (i = 0; i < w1->numpoints; i++)
{
if (DotProduct(plane2->normal, w1->p[i]) - plane2->dist < -CONVEX_EPSILON) return true;
} //end for
//check if one of the points of face2 is at the back of the plane of face1
for (i = 0; i < w2->numpoints; i++)
{
if (DotProduct(plane1->normal, w2->p[i]) - plane1->dist < -CONVEX_EPSILON) return true;
} //end for
return false;
} //end of the function NonConvex
//===========================================================================
// try to merge the areas at both sides of the given face
//
// Parameter: seperatingface : face that seperates two areas
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_TryMergeFaceAreas(tmp_face_t *seperatingface)
{
int side1, side2, area1faceflags, area2faceflags;
tmp_area_t *tmparea1, *tmparea2, *newarea;
tmp_face_t *face1, *face2, *nextface1, *nextface2;
tmparea1 = seperatingface->frontarea;
tmparea2 = seperatingface->backarea;
//areas must have the same presence type
if (tmparea1->presencetype != tmparea2->presencetype) return false;
//areas must have the same area contents
if (tmparea1->contents != tmparea2->contents) return false;
//areas must have the same bsp model inside (or both none)
if (tmparea1->modelnum != tmparea2->modelnum) return false;
area1faceflags = 0;
area2faceflags = 0;
for (face1 = tmparea1->tmpfaces; face1; face1 = face1->next[side1])
{
side1 = (face1->frontarea != tmparea1);
//debug: check if the area belongs to the area
if (face1->frontarea != tmparea1 &&
face1->backarea != tmparea1) Error("face does not belong to area1");
//just continue if the face is seperating the two areas
//NOTE: a result of this is that ground and gap areas can
// be merged if the seperating face is the gap
if ((face1->frontarea == tmparea1 &&
face1->backarea == tmparea2) ||
(face1->frontarea == tmparea2 &&
face1->backarea == tmparea1)) continue;
//get area1 face flags
area1faceflags |= face1->faceflags;
if (AAS_GapFace(face1, side1)) area1faceflags |= FACE_GAP;
//
for (face2 = tmparea2->tmpfaces; face2; face2 = face2->next[side2])
{
side2 = (face2->frontarea != tmparea2);
//debug: check if the area belongs to the area
if (face2->frontarea != tmparea2 &&
face2->backarea != tmparea2) Error("face does not belong to area2");
//just continue if the face is seperating the two areas
//NOTE: a result of this is that ground and gap areas can
// be merged if the seperating face is the gap
if ((face2->frontarea == tmparea1 &&
face2->backarea == tmparea2) ||
(face2->frontarea == tmparea2 &&
face2->backarea == tmparea1)) continue;
//get area2 face flags
area2faceflags |= face2->faceflags;
if (AAS_GapFace(face2, side2)) area2faceflags |= FACE_GAP;
//if the two faces would create a non-convex area
if (NonConvex(face1, face2, side1, side2)) return false;
} //end for
} //end for
//if one area has gap faces (that aren't seperating the two areas)
//and the other has ground faces (that aren't seperating the two areas),
//the areas can't be merged
if (((area1faceflags & FACE_GROUND) && (area2faceflags & FACE_GAP)) ||
((area2faceflags & FACE_GROUND) && (area1faceflags & FACE_GAP)))
{
// Log_Print(" can't merge: ground/gap\n");
return false;
} //end if
// Log_Print("merged area %d & %d to %d with %d faces\n", tmparea1->areanum, tmparea2->areanum, newarea->areanum, numfaces);
// return false;
//
//AAS_CheckArea(tmparea1);
//AAS_CheckArea(tmparea2);
//create the new area
newarea = AAS_AllocTmpArea();
newarea->presencetype = tmparea1->presencetype;
newarea->contents = tmparea1->contents;
newarea->modelnum = tmparea1->modelnum;
newarea->tmpfaces = NULL;
//add all the faces (except the seperating ones) from the first area
//to the new area
for (face1 = tmparea1->tmpfaces; face1; face1 = nextface1)
{
side1 = (face1->frontarea != tmparea1);
nextface1 = face1->next[side1];
//don't add seperating faces
if ((face1->frontarea == tmparea1 &&
face1->backarea == tmparea2) ||
(face1->frontarea == tmparea2 &&
face1->backarea == tmparea1))
{
continue;
} //end if
//
AAS_RemoveFaceFromArea(face1, tmparea1);
AAS_AddFaceSideToArea(face1, side1, newarea);
} //end for
//add all the faces (except the seperating ones) from the second area
//to the new area
for (face2 = tmparea2->tmpfaces; face2; face2 = nextface2)
{
side2 = (face2->frontarea != tmparea2);
nextface2 = face2->next[side2];
//don't add seperating faces
if ((face2->frontarea == tmparea1 &&
face2->backarea == tmparea2) ||
(face2->frontarea == tmparea2 &&
face2->backarea == tmparea1))
{
continue;
} //end if
//
AAS_RemoveFaceFromArea(face2, tmparea2);
AAS_AddFaceSideToArea(face2, side2, newarea);
} //end for
//free all shared faces
for (face1 = tmparea1->tmpfaces; face1; face1 = nextface1)
{
side1 = (face1->frontarea != tmparea1);
nextface1 = face1->next[side1];
//
AAS_RemoveFaceFromArea(face1, face1->frontarea);
AAS_RemoveFaceFromArea(face1, face1->backarea);
AAS_FreeTmpFace(face1);
} //end for
//
tmparea1->mergedarea = newarea;
tmparea1->invalid = true;
tmparea2->mergedarea = newarea;
tmparea2->invalid = true;
//
AAS_CheckArea(newarea);
AAS_FlipAreaFaces(newarea);
// Log_Print("merged area %d & %d to %d with %d faces\n", tmparea1->areanum, tmparea2->areanum, newarea->areanum);
return true;
} //end of the function AAS_TryMergeFaceAreas
//===========================================================================
// try to merge areas
// merged areas are added to the end of the convex area list so merging
// will be tried for those areas as well
//
// Parameter: -
// Returns: -
// Changes Globals: tmpaasworld
//===========================================================================
/*
void AAS_MergeAreas(void)
{
int side, nummerges;
tmp_area_t *tmparea, *othertmparea;
tmp_face_t *face;
nummerges = 0;
Log_Write("AAS_MergeAreas\r\n");
qprintf("%6d areas merged", 1);
//first merge grounded areas only
//NOTE: this is useless because the area settings aren't available yet
for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
{
// Log_Print("checking area %d\n", i);
//if the area is invalid
if (tmparea->invalid)
{
// Log_Print(" area invalid\n");
continue;
} //end if
//
// if (!(tmparea->settings->areaflags & AREA_GROUNDED)) continue;
//
for (face = tmparea->tmpfaces; face; face = face->next[side])
{
side = (face->frontarea != tmparea);
//if the face has both a front and back area
if (face->frontarea && face->backarea)
{
//
if (face->frontarea == tmparea) othertmparea = face->backarea;
else othertmparea = face->frontarea;
// if (!(othertmparea->settings->areaflags & AREA_GROUNDED)) continue;
// Log_Print(" checking area %d with %d\n", face->frontarea, face->backarea);
if (AAS_TryMergeFaceAreas(face))
{
qprintf("\r%6d", ++nummerges);
break;
} //end if
} //end if
} //end for
} //end for
//merge all areas
for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
{
// Log_Print("checking area %d\n", i);
//if the area is invalid
if (tmparea->invalid)
{
// Log_Print(" area invalid\n");
continue;
} //end if
//
for (face = tmparea->tmpfaces; face; face = face->next[side])
{
side = (face->frontarea != tmparea);
//if the face has both a front and back area
if (face->frontarea && face->backarea)
{
// Log_Print(" checking area %d with %d\n", face->frontarea, face->backarea);
if (AAS_TryMergeFaceAreas(face))
{
qprintf("\r%6d", ++nummerges);
break;
} //end if
} //end if
} //end for
} //end for
Log_Print("\r%6d areas merged\n", nummerges);
//refresh the merged tree
AAS_RefreshMergedTree_r(tmpaasworld.nodes);
} //end of the function AAS_MergeAreas*/
int AAS_GroundArea(tmp_area_t *tmparea)
{
tmp_face_t *face;
int side;
for (face = tmparea->tmpfaces; face; face = face->next[side])
{
side = (face->frontarea != tmparea);
if (face->faceflags & FACE_GROUND) return true;
} //end for
return false;
} //end of the function AAS_GroundArea
void AAS_MergeAreas(void)
{
int side, nummerges, merges, groundfirst;
tmp_area_t *tmparea, *othertmparea;
tmp_face_t *face;
nummerges = 0;
Log_Write("AAS_MergeAreas\r\n");
qprintf("%6d areas merged", 1);
//
groundfirst = true;
//for (i = 0; i < 4 || merges; i++)
while(1)
{
//if (i < 2) groundfirst = true;
//else groundfirst = false;
//
merges = 0;
//first merge grounded areas only
for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
{
//if the area is invalid
if (tmparea->invalid)
{
continue;
} //end if
//
if (groundfirst)
{
if (!AAS_GroundArea(tmparea)) continue;
} //end if
//
for (face = tmparea->tmpfaces; face; face = face->next[side])
{
side = (face->frontarea != tmparea);
//if the face has both a front and back area
if (face->frontarea && face->backarea)
{
//
if (face->frontarea == tmparea) othertmparea = face->backarea;
else othertmparea = face->frontarea;
//
if (groundfirst)
{
if (!AAS_GroundArea(othertmparea)) continue;
} //end if
if (AAS_TryMergeFaceAreas(face))
{
qprintf("\r%6d", ++nummerges);
merges++;
break;
} //end if
} //end if
} //end for
} //end for
if (!merges)
{
if (groundfirst) groundfirst = false;
else break;
} //end if
} //end for
qprintf("\n");
Log_Write("%6d areas merged\r\n", nummerges);
//refresh the merged tree
AAS_RefreshMergedTree_r(tmpaasworld.nodes);
} //end of the function AAS_MergeAreas
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "qbsp.h"
#include "../botlib/aasfile.h"
#include "aas_create.h"
#include "aas_store.h"
#define CONVEX_EPSILON 0.3
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
tmp_node_t *AAS_RefreshMergedTree_r(tmp_node_t *tmpnode)
{
tmp_area_t *tmparea;
//if this is a solid leaf
if (!tmpnode) return NULL;
//if this is an area leaf
if (tmpnode->tmparea)
{
tmparea = tmpnode->tmparea;
while(tmparea->mergedarea) tmparea = tmparea->mergedarea;
tmpnode->tmparea = tmparea;
return tmpnode;
} //end if
//do the children recursively
tmpnode->children[0] = AAS_RefreshMergedTree_r(tmpnode->children[0]);
tmpnode->children[1] = AAS_RefreshMergedTree_r(tmpnode->children[1]);
return tmpnode;
} //end of the function AAS_RefreshMergedTree_r
//===========================================================================
// returns true if the two given faces would create a non-convex area at
// the given sides, otherwise false is returned
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int NonConvex(tmp_face_t *face1, tmp_face_t *face2, int side1, int side2)
{
int i;
winding_t *w1, *w2;
plane_t *plane1, *plane2;
w1 = face1->winding;
w2 = face2->winding;
plane1 = &mapplanes[face1->planenum ^ side1];
plane2 = &mapplanes[face2->planenum ^ side2];
//check if one of the points of face1 is at the back of the plane of face2
for (i = 0; i < w1->numpoints; i++)
{
if (DotProduct(plane2->normal, w1->p[i]) - plane2->dist < -CONVEX_EPSILON) return true;
} //end for
//check if one of the points of face2 is at the back of the plane of face1
for (i = 0; i < w2->numpoints; i++)
{
if (DotProduct(plane1->normal, w2->p[i]) - plane1->dist < -CONVEX_EPSILON) return true;
} //end for
return false;
} //end of the function NonConvex
//===========================================================================
// try to merge the areas at both sides of the given face
//
// Parameter: seperatingface : face that seperates two areas
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_TryMergeFaceAreas(tmp_face_t *seperatingface)
{
int side1, side2, area1faceflags, area2faceflags;
tmp_area_t *tmparea1, *tmparea2, *newarea;
tmp_face_t *face1, *face2, *nextface1, *nextface2;
tmparea1 = seperatingface->frontarea;
tmparea2 = seperatingface->backarea;
//areas must have the same presence type
if (tmparea1->presencetype != tmparea2->presencetype) return false;
//areas must have the same area contents
if (tmparea1->contents != tmparea2->contents) return false;
//areas must have the same bsp model inside (or both none)
if (tmparea1->modelnum != tmparea2->modelnum) return false;
area1faceflags = 0;
area2faceflags = 0;
for (face1 = tmparea1->tmpfaces; face1; face1 = face1->next[side1])
{
side1 = (face1->frontarea != tmparea1);
//debug: check if the area belongs to the area
if (face1->frontarea != tmparea1 &&
face1->backarea != tmparea1) Error("face does not belong to area1");
//just continue if the face is seperating the two areas
//NOTE: a result of this is that ground and gap areas can
// be merged if the seperating face is the gap
if ((face1->frontarea == tmparea1 &&
face1->backarea == tmparea2) ||
(face1->frontarea == tmparea2 &&
face1->backarea == tmparea1)) continue;
//get area1 face flags
area1faceflags |= face1->faceflags;
if (AAS_GapFace(face1, side1)) area1faceflags |= FACE_GAP;
//
for (face2 = tmparea2->tmpfaces; face2; face2 = face2->next[side2])
{
side2 = (face2->frontarea != tmparea2);
//debug: check if the area belongs to the area
if (face2->frontarea != tmparea2 &&
face2->backarea != tmparea2) Error("face does not belong to area2");
//just continue if the face is seperating the two areas
//NOTE: a result of this is that ground and gap areas can
// be merged if the seperating face is the gap
if ((face2->frontarea == tmparea1 &&
face2->backarea == tmparea2) ||
(face2->frontarea == tmparea2 &&
face2->backarea == tmparea1)) continue;
//get area2 face flags
area2faceflags |= face2->faceflags;
if (AAS_GapFace(face2, side2)) area2faceflags |= FACE_GAP;
//if the two faces would create a non-convex area
if (NonConvex(face1, face2, side1, side2)) return false;
} //end for
} //end for
//if one area has gap faces (that aren't seperating the two areas)
//and the other has ground faces (that aren't seperating the two areas),
//the areas can't be merged
if (((area1faceflags & FACE_GROUND) && (area2faceflags & FACE_GAP)) ||
((area2faceflags & FACE_GROUND) && (area1faceflags & FACE_GAP)))
{
// Log_Print(" can't merge: ground/gap\n");
return false;
} //end if
// Log_Print("merged area %d & %d to %d with %d faces\n", tmparea1->areanum, tmparea2->areanum, newarea->areanum, numfaces);
// return false;
//
//AAS_CheckArea(tmparea1);
//AAS_CheckArea(tmparea2);
//create the new area
newarea = AAS_AllocTmpArea();
newarea->presencetype = tmparea1->presencetype;
newarea->contents = tmparea1->contents;
newarea->modelnum = tmparea1->modelnum;
newarea->tmpfaces = NULL;
//add all the faces (except the seperating ones) from the first area
//to the new area
for (face1 = tmparea1->tmpfaces; face1; face1 = nextface1)
{
side1 = (face1->frontarea != tmparea1);
nextface1 = face1->next[side1];
//don't add seperating faces
if ((face1->frontarea == tmparea1 &&
face1->backarea == tmparea2) ||
(face1->frontarea == tmparea2 &&
face1->backarea == tmparea1))
{
continue;
} //end if
//
AAS_RemoveFaceFromArea(face1, tmparea1);
AAS_AddFaceSideToArea(face1, side1, newarea);
} //end for
//add all the faces (except the seperating ones) from the second area
//to the new area
for (face2 = tmparea2->tmpfaces; face2; face2 = nextface2)
{
side2 = (face2->frontarea != tmparea2);
nextface2 = face2->next[side2];
//don't add seperating faces
if ((face2->frontarea == tmparea1 &&
face2->backarea == tmparea2) ||
(face2->frontarea == tmparea2 &&
face2->backarea == tmparea1))
{
continue;
} //end if
//
AAS_RemoveFaceFromArea(face2, tmparea2);
AAS_AddFaceSideToArea(face2, side2, newarea);
} //end for
//free all shared faces
for (face1 = tmparea1->tmpfaces; face1; face1 = nextface1)
{
side1 = (face1->frontarea != tmparea1);
nextface1 = face1->next[side1];
//
AAS_RemoveFaceFromArea(face1, face1->frontarea);
AAS_RemoveFaceFromArea(face1, face1->backarea);
AAS_FreeTmpFace(face1);
} //end for
//
tmparea1->mergedarea = newarea;
tmparea1->invalid = true;
tmparea2->mergedarea = newarea;
tmparea2->invalid = true;
//
AAS_CheckArea(newarea);
AAS_FlipAreaFaces(newarea);
// Log_Print("merged area %d & %d to %d with %d faces\n", tmparea1->areanum, tmparea2->areanum, newarea->areanum);
return true;
} //end of the function AAS_TryMergeFaceAreas
//===========================================================================
// try to merge areas
// merged areas are added to the end of the convex area list so merging
// will be tried for those areas as well
//
// Parameter: -
// Returns: -
// Changes Globals: tmpaasworld
//===========================================================================
/*
void AAS_MergeAreas(void)
{
int side, nummerges;
tmp_area_t *tmparea, *othertmparea;
tmp_face_t *face;
nummerges = 0;
Log_Write("AAS_MergeAreas\r\n");
qprintf("%6d areas merged", 1);
//first merge grounded areas only
//NOTE: this is useless because the area settings aren't available yet
for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
{
// Log_Print("checking area %d\n", i);
//if the area is invalid
if (tmparea->invalid)
{
// Log_Print(" area invalid\n");
continue;
} //end if
//
// if (!(tmparea->settings->areaflags & AREA_GROUNDED)) continue;
//
for (face = tmparea->tmpfaces; face; face = face->next[side])
{
side = (face->frontarea != tmparea);
//if the face has both a front and back area
if (face->frontarea && face->backarea)
{
//
if (face->frontarea == tmparea) othertmparea = face->backarea;
else othertmparea = face->frontarea;
// if (!(othertmparea->settings->areaflags & AREA_GROUNDED)) continue;
// Log_Print(" checking area %d with %d\n", face->frontarea, face->backarea);
if (AAS_TryMergeFaceAreas(face))
{
qprintf("\r%6d", ++nummerges);
break;
} //end if
} //end if
} //end for
} //end for
//merge all areas
for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
{
// Log_Print("checking area %d\n", i);
//if the area is invalid
if (tmparea->invalid)
{
// Log_Print(" area invalid\n");
continue;
} //end if
//
for (face = tmparea->tmpfaces; face; face = face->next[side])
{
side = (face->frontarea != tmparea);
//if the face has both a front and back area
if (face->frontarea && face->backarea)
{
// Log_Print(" checking area %d with %d\n", face->frontarea, face->backarea);
if (AAS_TryMergeFaceAreas(face))
{
qprintf("\r%6d", ++nummerges);
break;
} //end if
} //end if
} //end for
} //end for
Log_Print("\r%6d areas merged\n", nummerges);
//refresh the merged tree
AAS_RefreshMergedTree_r(tmpaasworld.nodes);
} //end of the function AAS_MergeAreas*/
int AAS_GroundArea(tmp_area_t *tmparea)
{
tmp_face_t *face;
int side;
for (face = tmparea->tmpfaces; face; face = face->next[side])
{
side = (face->frontarea != tmparea);
if (face->faceflags & FACE_GROUND) return true;
} //end for
return false;
} //end of the function AAS_GroundArea
void AAS_MergeAreas(void)
{
int side, nummerges, merges, groundfirst;
tmp_area_t *tmparea, *othertmparea;
tmp_face_t *face;
nummerges = 0;
Log_Write("AAS_MergeAreas\r\n");
qprintf("%6d areas merged", 1);
//
groundfirst = true;
//for (i = 0; i < 4 || merges; i++)
while(1)
{
//if (i < 2) groundfirst = true;
//else groundfirst = false;
//
merges = 0;
//first merge grounded areas only
for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
{
//if the area is invalid
if (tmparea->invalid)
{
continue;
} //end if
//
if (groundfirst)
{
if (!AAS_GroundArea(tmparea)) continue;
} //end if
//
for (face = tmparea->tmpfaces; face; face = face->next[side])
{
side = (face->frontarea != tmparea);
//if the face has both a front and back area
if (face->frontarea && face->backarea)
{
//
if (face->frontarea == tmparea) othertmparea = face->backarea;
else othertmparea = face->frontarea;
//
if (groundfirst)
{
if (!AAS_GroundArea(othertmparea)) continue;
} //end if
if (AAS_TryMergeFaceAreas(face))
{
qprintf("\r%6d", ++nummerges);
merges++;
break;
} //end if
} //end if
} //end for
} //end for
if (!merges)
{
if (groundfirst) groundfirst = false;
else break;
} //end if
} //end for
qprintf("\n");
Log_Write("%6d areas merged\r\n", nummerges);
//refresh the merged tree
AAS_RefreshMergedTree_r(tmpaasworld.nodes);
} //end of the function AAS_MergeAreas

48
code/bspc/aas_areamerging.h Normal file → Executable file
View file

@ -1,24 +1,24 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
void AAS_MergeAreas(void);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
void AAS_MergeAreas(void);

504
code/bspc/aas_cfg.c Normal file → Executable file
View file

@ -1,252 +1,252 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "qbsp.h"
#include "float.h"
#include "../botlib/aasfile.h"
#include "aas_store.h"
#include "aas_cfg.h"
#include "../botlib/l_precomp.h"
#include "../botlib/l_struct.h"
#include "../botlib/l_libvar.h"
//structure field offsets
#define BBOX_OFS(x) (int)&(((aas_bbox_t *)0)->x)
#define CFG_OFS(x) (int)&(((cfg_t *)0)->x)
//bounding box definition
fielddef_t bbox_fields[] =
{
{"presencetype", BBOX_OFS(presencetype), FT_INT},
{"flags", BBOX_OFS(flags), FT_INT},
{"mins", BBOX_OFS(mins), FT_FLOAT|FT_ARRAY, 3},
{"maxs", BBOX_OFS(maxs), FT_FLOAT|FT_ARRAY, 3},
{NULL, 0, 0, 0}
};
fielddef_t cfg_fields[] =
{
{"phys_gravitydirection", CFG_OFS(phys_gravitydirection), FT_FLOAT|FT_ARRAY, 3},
{"phys_friction", CFG_OFS(phys_friction), FT_FLOAT},
{"phys_stopspeed", CFG_OFS(phys_stopspeed), FT_FLOAT},
{"phys_gravity", CFG_OFS(phys_gravity), FT_FLOAT},
{"phys_waterfriction", CFG_OFS(phys_waterfriction), FT_FLOAT},
{"phys_watergravity", CFG_OFS(phys_watergravity), FT_FLOAT},
{"phys_maxvelocity", CFG_OFS(phys_maxvelocity), FT_FLOAT},
{"phys_maxwalkvelocity", CFG_OFS(phys_maxwalkvelocity), FT_FLOAT},
{"phys_maxcrouchvelocity", CFG_OFS(phys_maxcrouchvelocity), FT_FLOAT},
{"phys_maxswimvelocity", CFG_OFS(phys_maxswimvelocity), FT_FLOAT},
{"phys_walkaccelerate", CFG_OFS(phys_walkaccelerate), FT_FLOAT},
{"phys_airaccelerate", CFG_OFS(phys_airaccelerate), FT_FLOAT},
{"phys_swimaccelerate", CFG_OFS(phys_swimaccelerate), FT_FLOAT},
{"phys_maxstep", CFG_OFS(phys_maxstep), FT_FLOAT},
{"phys_maxsteepness", CFG_OFS(phys_maxsteepness), FT_FLOAT},
{"phys_maxwaterjump", CFG_OFS(phys_maxwaterjump), FT_FLOAT},
{"phys_maxbarrier", CFG_OFS(phys_maxbarrier), FT_FLOAT},
{"phys_jumpvel", CFG_OFS(phys_jumpvel), FT_FLOAT},
{"phys_falldelta5", CFG_OFS(phys_falldelta5), FT_FLOAT},
{"phys_falldelta10", CFG_OFS(phys_falldelta10), FT_FLOAT},
{"rs_waterjump", CFG_OFS(rs_waterjump), FT_FLOAT},
{"rs_teleport", CFG_OFS(rs_teleport), FT_FLOAT},
{"rs_barrierjump", CFG_OFS(rs_barrierjump), FT_FLOAT},
{"rs_startcrouch", CFG_OFS(rs_startcrouch), FT_FLOAT},
{"rs_startgrapple", CFG_OFS(rs_startgrapple), FT_FLOAT},
{"rs_startwalkoffledge", CFG_OFS(rs_startwalkoffledge), FT_FLOAT},
{"rs_startjump", CFG_OFS(rs_startjump), FT_FLOAT},
{"rs_rocketjump", CFG_OFS(rs_rocketjump), FT_FLOAT},
{"rs_bfgjump", CFG_OFS(rs_bfgjump), FT_FLOAT},
{"rs_jumppad", CFG_OFS(rs_jumppad), FT_FLOAT},
{"rs_aircontrolledjumppad", CFG_OFS(rs_aircontrolledjumppad), FT_FLOAT},
{"rs_funcbob", CFG_OFS(rs_funcbob), FT_FLOAT},
{"rs_startelevator", CFG_OFS(rs_startelevator), FT_FLOAT},
{"rs_falldamage5", CFG_OFS(rs_falldamage5), FT_FLOAT},
{"rs_falldamage10", CFG_OFS(rs_falldamage10), FT_FLOAT},
{"rs_maxjumpfallheight", CFG_OFS(rs_maxjumpfallheight), FT_FLOAT},
{NULL, 0, 0, 0}
};
structdef_t bbox_struct =
{
sizeof(aas_bbox_t), bbox_fields
};
structdef_t cfg_struct =
{
sizeof(cfg_t), cfg_fields
};
//global cfg
cfg_t cfg;
//===========================================================================
// the default Q3A configuration
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void DefaultCfg(void)
{
int i;
// default all float values to infinite
for (i = 0; cfg_fields[i].name; i++)
{
if ((cfg_fields[i].type & FT_TYPE) == FT_FLOAT)
*(float *)( ((char*)&cfg) + cfg_fields[i].offset ) = FLT_MAX;
} //end for
//
cfg.numbboxes = 2;
//bbox 0
cfg.bboxes[0].presencetype = PRESENCE_NORMAL;
cfg.bboxes[0].flags = 0;
cfg.bboxes[0].mins[0] = -15;
cfg.bboxes[0].mins[1] = -15;
cfg.bboxes[0].mins[2] = -24;
cfg.bboxes[0].maxs[0] = 15;
cfg.bboxes[0].maxs[1] = 15;
cfg.bboxes[0].maxs[2] = 32;
//bbox 1
cfg.bboxes[1].presencetype = PRESENCE_CROUCH;
cfg.bboxes[1].flags = 1;
cfg.bboxes[1].mins[0] = -15;
cfg.bboxes[1].mins[1] = -15;
cfg.bboxes[1].mins[2] = -24;
cfg.bboxes[1].maxs[0] = 15;
cfg.bboxes[1].maxs[1] = 15;
cfg.bboxes[1].maxs[2] = 16;
//
cfg.allpresencetypes = PRESENCE_NORMAL|PRESENCE_CROUCH;
cfg.phys_gravitydirection[0] = 0;
cfg.phys_gravitydirection[1] = 0;
cfg.phys_gravitydirection[2] = -1;
cfg.phys_maxsteepness = 0.7;
} //end of the function DefaultCfg
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
char * QDECL va( char *format, ... )
{
va_list argptr;
static char string[2][32000]; // in case va is called by nested functions
static int index = 0;
char *buf;
buf = string[index & 1];
index++;
va_start (argptr, format);
vsprintf (buf, format,argptr);
va_end (argptr);
return buf;
} //end of the function va
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void SetCfgLibVars(void)
{
int i;
float value;
for (i = 0; cfg_fields[i].name; i++)
{
if ((cfg_fields[i].type & FT_TYPE) == FT_FLOAT)
{
value = *(float *)(((char*)&cfg) + cfg_fields[i].offset);
if (value != FLT_MAX)
{
LibVarSet(cfg_fields[i].name, va("%f", value));
} //end if
} //end if
} //end for
} //end of the function SetCfgLibVars
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int LoadCfgFile(char *filename)
{
source_t *source;
token_t token;
int settingsdefined;
source = LoadSourceFile(filename);
if (!source)
{
Log_Print("couldn't open cfg file %s\n", filename);
return false;
} //end if
settingsdefined = false;
memset(&cfg, 0, sizeof(cfg_t));
while(PC_ReadToken(source, &token))
{
if (!stricmp(token.string, "bbox"))
{
if (cfg.numbboxes >= AAS_MAX_BBOXES)
{
SourceError(source, "too many bounding box volumes defined");
} //end if
if (!ReadStructure(source, &bbox_struct, (char *) &cfg.bboxes[cfg.numbboxes]))
{
FreeSource(source);
return false;
} //end if
cfg.allpresencetypes |= cfg.bboxes[cfg.numbboxes].presencetype;
cfg.numbboxes++;
} //end if
else if (!stricmp(token.string, "settings"))
{
if (settingsdefined)
{
SourceWarning(source, "settings already defined\n");
} //end if
settingsdefined = true;
if (!ReadStructure(source, &cfg_struct, (char *) &cfg))
{
FreeSource(source);
return false;
} //end if
} //end else if
} //end while
if (VectorLength(cfg.phys_gravitydirection) < 0.9 || VectorLength(cfg.phys_gravitydirection) > 1.1)
{
SourceError(source, "invalid gravity direction specified");
} //end if
if (cfg.numbboxes <= 0)
{
SourceError(source, "no bounding volumes specified");
} //end if
FreeSource(source);
SetCfgLibVars();
Log_Print("using cfg file %s\n", filename);
return true;
} //end of the function LoadCfgFile
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "qbsp.h"
#include "float.h"
#include "../botlib/aasfile.h"
#include "aas_store.h"
#include "aas_cfg.h"
#include "../botlib/l_precomp.h"
#include "../botlib/l_struct.h"
#include "../botlib/l_libvar.h"
//structure field offsets
#define BBOX_OFS(x) (int)&(((aas_bbox_t *)0)->x)
#define CFG_OFS(x) (int)&(((cfg_t *)0)->x)
//bounding box definition
fielddef_t bbox_fields[] =
{
{"presencetype", BBOX_OFS(presencetype), FT_INT},
{"flags", BBOX_OFS(flags), FT_INT},
{"mins", BBOX_OFS(mins), FT_FLOAT|FT_ARRAY, 3},
{"maxs", BBOX_OFS(maxs), FT_FLOAT|FT_ARRAY, 3},
{NULL, 0, 0, 0}
};
fielddef_t cfg_fields[] =
{
{"phys_gravitydirection", CFG_OFS(phys_gravitydirection), FT_FLOAT|FT_ARRAY, 3},
{"phys_friction", CFG_OFS(phys_friction), FT_FLOAT},
{"phys_stopspeed", CFG_OFS(phys_stopspeed), FT_FLOAT},
{"phys_gravity", CFG_OFS(phys_gravity), FT_FLOAT},
{"phys_waterfriction", CFG_OFS(phys_waterfriction), FT_FLOAT},
{"phys_watergravity", CFG_OFS(phys_watergravity), FT_FLOAT},
{"phys_maxvelocity", CFG_OFS(phys_maxvelocity), FT_FLOAT},
{"phys_maxwalkvelocity", CFG_OFS(phys_maxwalkvelocity), FT_FLOAT},
{"phys_maxcrouchvelocity", CFG_OFS(phys_maxcrouchvelocity), FT_FLOAT},
{"phys_maxswimvelocity", CFG_OFS(phys_maxswimvelocity), FT_FLOAT},
{"phys_walkaccelerate", CFG_OFS(phys_walkaccelerate), FT_FLOAT},
{"phys_airaccelerate", CFG_OFS(phys_airaccelerate), FT_FLOAT},
{"phys_swimaccelerate", CFG_OFS(phys_swimaccelerate), FT_FLOAT},
{"phys_maxstep", CFG_OFS(phys_maxstep), FT_FLOAT},
{"phys_maxsteepness", CFG_OFS(phys_maxsteepness), FT_FLOAT},
{"phys_maxwaterjump", CFG_OFS(phys_maxwaterjump), FT_FLOAT},
{"phys_maxbarrier", CFG_OFS(phys_maxbarrier), FT_FLOAT},
{"phys_jumpvel", CFG_OFS(phys_jumpvel), FT_FLOAT},
{"phys_falldelta5", CFG_OFS(phys_falldelta5), FT_FLOAT},
{"phys_falldelta10", CFG_OFS(phys_falldelta10), FT_FLOAT},
{"rs_waterjump", CFG_OFS(rs_waterjump), FT_FLOAT},
{"rs_teleport", CFG_OFS(rs_teleport), FT_FLOAT},
{"rs_barrierjump", CFG_OFS(rs_barrierjump), FT_FLOAT},
{"rs_startcrouch", CFG_OFS(rs_startcrouch), FT_FLOAT},
{"rs_startgrapple", CFG_OFS(rs_startgrapple), FT_FLOAT},
{"rs_startwalkoffledge", CFG_OFS(rs_startwalkoffledge), FT_FLOAT},
{"rs_startjump", CFG_OFS(rs_startjump), FT_FLOAT},
{"rs_rocketjump", CFG_OFS(rs_rocketjump), FT_FLOAT},
{"rs_bfgjump", CFG_OFS(rs_bfgjump), FT_FLOAT},
{"rs_jumppad", CFG_OFS(rs_jumppad), FT_FLOAT},
{"rs_aircontrolledjumppad", CFG_OFS(rs_aircontrolledjumppad), FT_FLOAT},
{"rs_funcbob", CFG_OFS(rs_funcbob), FT_FLOAT},
{"rs_startelevator", CFG_OFS(rs_startelevator), FT_FLOAT},
{"rs_falldamage5", CFG_OFS(rs_falldamage5), FT_FLOAT},
{"rs_falldamage10", CFG_OFS(rs_falldamage10), FT_FLOAT},
{"rs_maxjumpfallheight", CFG_OFS(rs_maxjumpfallheight), FT_FLOAT},
{NULL, 0, 0, 0}
};
structdef_t bbox_struct =
{
sizeof(aas_bbox_t), bbox_fields
};
structdef_t cfg_struct =
{
sizeof(cfg_t), cfg_fields
};
//global cfg
cfg_t cfg;
//===========================================================================
// the default Q3A configuration
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void DefaultCfg(void)
{
int i;
// default all float values to infinite
for (i = 0; cfg_fields[i].name; i++)
{
if ((cfg_fields[i].type & FT_TYPE) == FT_FLOAT)
*(float *)( ((char*)&cfg) + cfg_fields[i].offset ) = FLT_MAX;
} //end for
//
cfg.numbboxes = 2;
//bbox 0
cfg.bboxes[0].presencetype = PRESENCE_NORMAL;
cfg.bboxes[0].flags = 0;
cfg.bboxes[0].mins[0] = -15;
cfg.bboxes[0].mins[1] = -15;
cfg.bboxes[0].mins[2] = -24;
cfg.bboxes[0].maxs[0] = 15;
cfg.bboxes[0].maxs[1] = 15;
cfg.bboxes[0].maxs[2] = 32;
//bbox 1
cfg.bboxes[1].presencetype = PRESENCE_CROUCH;
cfg.bboxes[1].flags = 1;
cfg.bboxes[1].mins[0] = -15;
cfg.bboxes[1].mins[1] = -15;
cfg.bboxes[1].mins[2] = -24;
cfg.bboxes[1].maxs[0] = 15;
cfg.bboxes[1].maxs[1] = 15;
cfg.bboxes[1].maxs[2] = 16;
//
cfg.allpresencetypes = PRESENCE_NORMAL|PRESENCE_CROUCH;
cfg.phys_gravitydirection[0] = 0;
cfg.phys_gravitydirection[1] = 0;
cfg.phys_gravitydirection[2] = -1;
cfg.phys_maxsteepness = 0.7;
} //end of the function DefaultCfg
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
char * QDECL va( char *format, ... )
{
va_list argptr;
static char string[2][32000]; // in case va is called by nested functions
static int index = 0;
char *buf;
buf = string[index & 1];
index++;
va_start (argptr, format);
vsprintf (buf, format,argptr);
va_end (argptr);
return buf;
} //end of the function va
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void SetCfgLibVars(void)
{
int i;
float value;
for (i = 0; cfg_fields[i].name; i++)
{
if ((cfg_fields[i].type & FT_TYPE) == FT_FLOAT)
{
value = *(float *)(((char*)&cfg) + cfg_fields[i].offset);
if (value != FLT_MAX)
{
LibVarSet(cfg_fields[i].name, va("%f", value));
} //end if
} //end if
} //end for
} //end of the function SetCfgLibVars
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int LoadCfgFile(char *filename)
{
source_t *source;
token_t token;
int settingsdefined;
source = LoadSourceFile(filename);
if (!source)
{
Log_Print("couldn't open cfg file %s\n", filename);
return false;
} //end if
settingsdefined = false;
memset(&cfg, 0, sizeof(cfg_t));
while(PC_ReadToken(source, &token))
{
if (!stricmp(token.string, "bbox"))
{
if (cfg.numbboxes >= AAS_MAX_BBOXES)
{
SourceError(source, "too many bounding box volumes defined");
} //end if
if (!ReadStructure(source, &bbox_struct, (char *) &cfg.bboxes[cfg.numbboxes]))
{
FreeSource(source);
return false;
} //end if
cfg.allpresencetypes |= cfg.bboxes[cfg.numbboxes].presencetype;
cfg.numbboxes++;
} //end if
else if (!stricmp(token.string, "settings"))
{
if (settingsdefined)
{
SourceWarning(source, "settings already defined\n");
} //end if
settingsdefined = true;
if (!ReadStructure(source, &cfg_struct, (char *) &cfg))
{
FreeSource(source);
return false;
} //end if
} //end else if
} //end while
if (VectorLength(cfg.phys_gravitydirection) < 0.9 || VectorLength(cfg.phys_gravitydirection) > 1.1)
{
SourceError(source, "invalid gravity direction specified");
} //end if
if (cfg.numbboxes <= 0)
{
SourceError(source, "no bounding volumes specified");
} //end if
FreeSource(source);
SetCfgLibVars();
Log_Print("using cfg file %s\n", filename);
return true;
} //end of the function LoadCfgFile

146
code/bspc/aas_cfg.h Normal file → Executable file
View file

@ -1,73 +1,73 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#define BBOXFL_GROUNDED 1 //bounding box only valid when on ground
#define BBOXFL_NOTGROUNDED 2 //bounding box only valid when NOT on ground
typedef struct cfg_s
{
int numbboxes; //number of bounding boxes
aas_bbox_t bboxes[AAS_MAX_BBOXES]; //all the bounding boxes
int allpresencetypes; //or of all presence types
// aas settings
vec3_t phys_gravitydirection;
float phys_friction;
float phys_stopspeed;
float phys_gravity;
float phys_waterfriction;
float phys_watergravity;
float phys_maxvelocity;
float phys_maxwalkvelocity;
float phys_maxcrouchvelocity;
float phys_maxswimvelocity;
float phys_walkaccelerate;
float phys_airaccelerate;
float phys_swimaccelerate;
float phys_maxstep;
float phys_maxsteepness;
float phys_maxwaterjump;
float phys_maxbarrier;
float phys_jumpvel;
float phys_falldelta5;
float phys_falldelta10;
float rs_waterjump;
float rs_teleport;
float rs_barrierjump;
float rs_startcrouch;
float rs_startgrapple;
float rs_startwalkoffledge;
float rs_startjump;
float rs_rocketjump;
float rs_bfgjump;
float rs_jumppad;
float rs_aircontrolledjumppad;
float rs_funcbob;
float rs_startelevator;
float rs_falldamage5;
float rs_falldamage10;
float rs_maxjumpfallheight;
} cfg_t;
extern cfg_t cfg;
void DefaultCfg(void);
int LoadCfgFile(char *filename);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#define BBOXFL_GROUNDED 1 //bounding box only valid when on ground
#define BBOXFL_NOTGROUNDED 2 //bounding box only valid when NOT on ground
typedef struct cfg_s
{
int numbboxes; //number of bounding boxes
aas_bbox_t bboxes[AAS_MAX_BBOXES]; //all the bounding boxes
int allpresencetypes; //or of all presence types
// aas settings
vec3_t phys_gravitydirection;
float phys_friction;
float phys_stopspeed;
float phys_gravity;
float phys_waterfriction;
float phys_watergravity;
float phys_maxvelocity;
float phys_maxwalkvelocity;
float phys_maxcrouchvelocity;
float phys_maxswimvelocity;
float phys_walkaccelerate;
float phys_airaccelerate;
float phys_swimaccelerate;
float phys_maxstep;
float phys_maxsteepness;
float phys_maxwaterjump;
float phys_maxbarrier;
float phys_jumpvel;
float phys_falldelta5;
float phys_falldelta10;
float rs_waterjump;
float rs_teleport;
float rs_barrierjump;
float rs_startcrouch;
float rs_startgrapple;
float rs_startwalkoffledge;
float rs_startjump;
float rs_rocketjump;
float rs_bfgjump;
float rs_jumppad;
float rs_aircontrolledjumppad;
float rs_funcbob;
float rs_startelevator;
float rs_falldamage5;
float rs_falldamage10;
float rs_maxjumpfallheight;
} cfg_t;
extern cfg_t cfg;
void DefaultCfg(void);
int LoadCfgFile(char *filename);

2284
code/bspc/aas_create.c Normal file → Executable file

File diff suppressed because it is too large Load diff

272
code/bspc/aas_create.h Normal file → Executable file
View file

@ -1,136 +1,136 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#define AREA_PORTAL 1
//temporary AAS face
typedef struct tmp_face_s
{
int num; //face number
int planenum; //number of the plane the face is in
winding_t *winding; //winding of the face
struct tmp_area_s *frontarea; //area at the front of the face
struct tmp_area_s *backarea; //area at the back of the face
int faceflags; //flags of this face
int aasfacenum; //the number of the aas face used for this face
//double link list pointers for front and back area
struct tmp_face_s *prev[2], *next[2];
//links in the list with faces
struct tmp_face_s *l_prev, *l_next;
} tmp_face_t;
//temporary AAS area settings
typedef struct tmp_areasettings_s
{
//could also add all kind of statistic fields
int contents; //contents of the area
int modelnum; //bsp model inside this area
int areaflags; //area flags
int presencetype; //how a bot can be present in this area
int numreachableareas; //number of reachable areas from this one
int firstreachablearea; //first reachable area in the reachable area index
} tmp_areasettings_t;
//temporary AAS area
typedef struct tmp_area_s
{
int areanum; //number of the area
struct tmp_face_s *tmpfaces; //the faces of the area
int presencetype; //presence type of the area
int contents; //area contents
int modelnum; //bsp model inside this area
int invalid; //true if the area is invalid
tmp_areasettings_t *settings; //area settings
struct tmp_area_s *mergedarea; //points to the new area after merging
//when mergedarea != 0 the area has only the
//seperating face of the merged areas
int aasareanum; //number of the aas area created for this tmp area
//links in the list with areas
struct tmp_area_s *l_prev, *l_next;
} tmp_area_t;
//temporary AAS node
typedef struct tmp_node_s
{
int planenum; //node plane number
struct tmp_area_s *tmparea; //points to an area if this node is an area
struct tmp_node_s *children[2]; //child nodes of this node
} tmp_node_t;
#define NODEBUF_SIZE 128
//node buffer
typedef struct tmp_nodebuf_s
{
int numnodes;
struct tmp_nodebuf_s *next;
tmp_node_t nodes[NODEBUF_SIZE];
} tmp_nodebuf_t;
//the whole temorary AAS
typedef struct tmp_aas_s
{
//faces
int numfaces;
int facenum;
tmp_face_t *faces;
//areas
int numareas;
int areanum;
tmp_area_t *areas;
//area settings
int numareasettings;
tmp_areasettings_t *areasettings;
//nodes
int numnodes;
tmp_node_t *nodes;
//node buffer
tmp_nodebuf_t *nodebuffer;
} tmp_aas_t;
extern tmp_aas_t tmpaasworld;
//creates a .AAS file with the given name from an already loaded map
void AAS_Create(char *aasfile);
//adds a face side to an area
void AAS_AddFaceSideToArea(tmp_face_t *tmpface, int side, tmp_area_t *tmparea);
//remvoes a face from an area
void AAS_RemoveFaceFromArea(tmp_face_t *tmpface, tmp_area_t *tmparea);
//allocate a tmp face
tmp_face_t *AAS_AllocTmpFace(void);
//free the tmp face
void AAS_FreeTmpFace(tmp_face_t *tmpface);
//allocate a tmp area
tmp_area_t *AAS_AllocTmpArea(void);
//free a tmp area
void AAS_FreeTmpArea(tmp_area_t *tmparea);
//allocate a tmp node
tmp_node_t *AAS_AllocTmpNode(void);
//free a tmp node
void AAS_FreeTmpNode(tmp_node_t *node);
//checks if an area is ok
void AAS_CheckArea(tmp_area_t *tmparea);
//flips the area faces where needed
void AAS_FlipAreaFaces(tmp_area_t *tmparea);
//returns true if the face is a gap seen from the given side
int AAS_GapFace(tmp_face_t *tmpface, int side);
//returns true if the face is a ground face
int AAS_GroundFace(tmp_face_t *tmpface);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#define AREA_PORTAL 1
//temporary AAS face
typedef struct tmp_face_s
{
int num; //face number
int planenum; //number of the plane the face is in
winding_t *winding; //winding of the face
struct tmp_area_s *frontarea; //area at the front of the face
struct tmp_area_s *backarea; //area at the back of the face
int faceflags; //flags of this face
int aasfacenum; //the number of the aas face used for this face
//double link list pointers for front and back area
struct tmp_face_s *prev[2], *next[2];
//links in the list with faces
struct tmp_face_s *l_prev, *l_next;
} tmp_face_t;
//temporary AAS area settings
typedef struct tmp_areasettings_s
{
//could also add all kind of statistic fields
int contents; //contents of the area
int modelnum; //bsp model inside this area
int areaflags; //area flags
int presencetype; //how a bot can be present in this area
int numreachableareas; //number of reachable areas from this one
int firstreachablearea; //first reachable area in the reachable area index
} tmp_areasettings_t;
//temporary AAS area
typedef struct tmp_area_s
{
int areanum; //number of the area
struct tmp_face_s *tmpfaces; //the faces of the area
int presencetype; //presence type of the area
int contents; //area contents
int modelnum; //bsp model inside this area
int invalid; //true if the area is invalid
tmp_areasettings_t *settings; //area settings
struct tmp_area_s *mergedarea; //points to the new area after merging
//when mergedarea != 0 the area has only the
//seperating face of the merged areas
int aasareanum; //number of the aas area created for this tmp area
//links in the list with areas
struct tmp_area_s *l_prev, *l_next;
} tmp_area_t;
//temporary AAS node
typedef struct tmp_node_s
{
int planenum; //node plane number
struct tmp_area_s *tmparea; //points to an area if this node is an area
struct tmp_node_s *children[2]; //child nodes of this node
} tmp_node_t;
#define NODEBUF_SIZE 128
//node buffer
typedef struct tmp_nodebuf_s
{
int numnodes;
struct tmp_nodebuf_s *next;
tmp_node_t nodes[NODEBUF_SIZE];
} tmp_nodebuf_t;
//the whole temorary AAS
typedef struct tmp_aas_s
{
//faces
int numfaces;
int facenum;
tmp_face_t *faces;
//areas
int numareas;
int areanum;
tmp_area_t *areas;
//area settings
int numareasettings;
tmp_areasettings_t *areasettings;
//nodes
int numnodes;
tmp_node_t *nodes;
//node buffer
tmp_nodebuf_t *nodebuffer;
} tmp_aas_t;
extern tmp_aas_t tmpaasworld;
//creates a .AAS file with the given name from an already loaded map
void AAS_Create(char *aasfile);
//adds a face side to an area
void AAS_AddFaceSideToArea(tmp_face_t *tmpface, int side, tmp_area_t *tmparea);
//remvoes a face from an area
void AAS_RemoveFaceFromArea(tmp_face_t *tmpface, tmp_area_t *tmparea);
//allocate a tmp face
tmp_face_t *AAS_AllocTmpFace(void);
//free the tmp face
void AAS_FreeTmpFace(tmp_face_t *tmpface);
//allocate a tmp area
tmp_area_t *AAS_AllocTmpArea(void);
//free a tmp area
void AAS_FreeTmpArea(tmp_area_t *tmparea);
//allocate a tmp node
tmp_node_t *AAS_AllocTmpNode(void);
//free a tmp node
void AAS_FreeTmpNode(tmp_node_t *node);
//checks if an area is ok
void AAS_CheckArea(tmp_area_t *tmparea);
//flips the area faces where needed
void AAS_FlipAreaFaces(tmp_area_t *tmparea);
//returns true if the face is a gap seen from the given side
int AAS_GapFace(tmp_face_t *tmpface, int side);
//returns true if the face is a ground face
int AAS_GroundFace(tmp_face_t *tmpface);

216
code/bspc/aas_edgemelting.c Normal file → Executable file
View file

@ -1,108 +1,108 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "qbsp.h"
#include "../botlib/aasfile.h"
#include "aas_create.h"
//===========================================================================
// try to melt the windings of the two faces
// FIXME: this is buggy
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_MeltFaceWinding(tmp_face_t *face1, tmp_face_t *face2)
{
int i, n;
int splits = 0;
winding_t *w2, *neww;
plane_t *plane1;
#ifdef DEBUG
if (!face1->winding) Error("face1 %d without winding", face1->num);
if (!face2->winding) Error("face2 %d without winding", face2->num);
#endif //DEBUG
w2 = face2->winding;
plane1 = &mapplanes[face1->planenum];
for (i = 0; i < w2->numpoints; i++)
{
if (PointOnWinding(face1->winding, plane1->normal, plane1->dist, w2->p[i], &n))
{
neww = AddWindingPoint(face1->winding, w2->p[i], n);
FreeWinding(face1->winding);
face1->winding = neww;
splits++;
} //end if
} //end for
return splits;
} //end of the function AAS_MeltFaceWinding
//===========================================================================
// melt the windings of the area faces
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_MeltFaceWindingsOfArea(tmp_area_t *tmparea)
{
int side1, side2, num_windingsplits = 0;
tmp_face_t *face1, *face2;
for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
{
side1 = face1->frontarea != tmparea;
for (face2 = tmparea->tmpfaces; face2; face2 = face2->next[side2])
{
side2 = face2->frontarea != tmparea;
if (face1 == face2) continue;
num_windingsplits += AAS_MeltFaceWinding(face1, face2);
} //end for
} //end for
return num_windingsplits;
} //end of the function AAS_MeltFaceWindingsOfArea
//===========================================================================
// melt the windings of the faces of all areas
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_MeltAreaFaceWindings(void)
{
tmp_area_t *tmparea;
int num_windingsplits = 0;
Log_Write("AAS_MeltAreaFaceWindings\r\n");
qprintf("%6d edges melted", num_windingsplits);
//NOTE: first convex area (zero) is a dummy
for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
{
num_windingsplits += AAS_MeltFaceWindingsOfArea(tmparea);
qprintf("\r%6d", num_windingsplits);
} //end for
qprintf("\n");
Log_Write("%6d edges melted\r\n", num_windingsplits);
} //end of the function AAS_MeltAreaFaceWindings
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "qbsp.h"
#include "../botlib/aasfile.h"
#include "aas_create.h"
//===========================================================================
// try to melt the windings of the two faces
// FIXME: this is buggy
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_MeltFaceWinding(tmp_face_t *face1, tmp_face_t *face2)
{
int i, n;
int splits = 0;
winding_t *w2, *neww;
plane_t *plane1;
#ifdef DEBUG
if (!face1->winding) Error("face1 %d without winding", face1->num);
if (!face2->winding) Error("face2 %d without winding", face2->num);
#endif //DEBUG
w2 = face2->winding;
plane1 = &mapplanes[face1->planenum];
for (i = 0; i < w2->numpoints; i++)
{
if (PointOnWinding(face1->winding, plane1->normal, plane1->dist, w2->p[i], &n))
{
neww = AddWindingPoint(face1->winding, w2->p[i], n);
FreeWinding(face1->winding);
face1->winding = neww;
splits++;
} //end if
} //end for
return splits;
} //end of the function AAS_MeltFaceWinding
//===========================================================================
// melt the windings of the area faces
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_MeltFaceWindingsOfArea(tmp_area_t *tmparea)
{
int side1, side2, num_windingsplits = 0;
tmp_face_t *face1, *face2;
for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
{
side1 = face1->frontarea != tmparea;
for (face2 = tmparea->tmpfaces; face2; face2 = face2->next[side2])
{
side2 = face2->frontarea != tmparea;
if (face1 == face2) continue;
num_windingsplits += AAS_MeltFaceWinding(face1, face2);
} //end for
} //end for
return num_windingsplits;
} //end of the function AAS_MeltFaceWindingsOfArea
//===========================================================================
// melt the windings of the faces of all areas
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_MeltAreaFaceWindings(void)
{
tmp_area_t *tmparea;
int num_windingsplits = 0;
Log_Write("AAS_MeltAreaFaceWindings\r\n");
qprintf("%6d edges melted", num_windingsplits);
//NOTE: first convex area (zero) is a dummy
for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
{
num_windingsplits += AAS_MeltFaceWindingsOfArea(tmparea);
qprintf("\r%6d", num_windingsplits);
} //end for
qprintf("\n");
Log_Write("%6d edges melted\r\n", num_windingsplits);
} //end of the function AAS_MeltAreaFaceWindings

48
code/bspc/aas_edgemelting.h Normal file → Executable file
View file

@ -1,24 +1,24 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
void AAS_MeltAreaFaceWindings(void);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
void AAS_MeltAreaFaceWindings(void);

564
code/bspc/aas_facemerging.c Normal file → Executable file
View file

@ -1,282 +1,282 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "qbsp.h"
#include "../botlib/aasfile.h"
#include "aas_create.h"
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_TryMergeFaces(tmp_face_t *face1, tmp_face_t *face2)
{
winding_t *neww;
#ifdef DEBUG
if (!face1->winding) Error("face1 %d without winding", face1->num);
if (!face2->winding) Error("face2 %d without winding", face2->num);
#endif //DEBUG
//
if (face1->faceflags != face2->faceflags) return false;
//NOTE: if the front or back area is zero this doesn't mean there's
//a real area. It means there's solid at that side of the face
//if both faces have the same front area
if (face1->frontarea == face2->frontarea)
{
//if both faces have the same back area
if (face1->backarea == face2->backarea)
{
//if the faces are in the same plane
if (face1->planenum == face2->planenum)
{
//if they have both a front and a back area (no solid on either side)
if (face1->frontarea && face1->backarea)
{
neww = MergeWindings(face1->winding, face2->winding,
mapplanes[face1->planenum].normal);
} //end if
else
{
//this function is to be found in l_poly.c
neww = TryMergeWinding(face1->winding, face2->winding,
mapplanes[face1->planenum].normal);
} //end else
if (neww)
{
FreeWinding(face1->winding);
face1->winding = neww;
if (face2->frontarea) AAS_RemoveFaceFromArea(face2, face2->frontarea);
if (face2->backarea) AAS_RemoveFaceFromArea(face2, face2->backarea);
AAS_FreeTmpFace(face2);
return true;
} //end if
} //end if
else if ((face1->planenum & ~1) == (face2->planenum & ~1))
{
Log_Write("face %d and %d, same front and back area but flipped planes\r\n",
face1->num, face2->num);
} //end if
} //end if
} //end if
return false;
} //end of the function AAS_TryMergeFaces
/*
int AAS_TryMergeFaces(tmp_face_t *face1, tmp_face_t *face2)
{
winding_t *neww;
#ifdef DEBUG
if (!face1->winding) Error("face1 %d without winding", face1->num);
if (!face2->winding) Error("face2 %d without winding", face2->num);
#endif //DEBUG
//if the faces are in the same plane
if ((face1->planenum & ~1) != (face2->planenum & ~1)) return false;
// if (face1->planenum != face2->planenum) return false;
//NOTE: if the front or back area is zero this doesn't mean there's
//a real area. It means there's solid at that side of the face
//if both faces have the same front area
if (face1->frontarea != face2->frontarea ||
face1->backarea != face2->backarea)
{
if (!face1->frontarea || !face1->backarea ||
!face2->frontarea || !face2->backarea) return false;
else if (face1->frontarea != face2->backarea ||
face1->backarea != face2->frontarea) return false;
// return false;
} //end if
//this function is to be found in l_poly.c
neww = TryMergeWinding(face1->winding, face2->winding,
mapplanes[face1->planenum].normal);
if (!neww) return false;
//
FreeWinding(face1->winding);
face1->winding = neww;
//remove face2
if (face2->frontarea)
AAS_RemoveFaceFromArea(face2, &tmpaasworld.areas[face2->frontarea]);
if (face2->backarea)
AAS_RemoveFaceFromArea(face2, &tmpaasworld.areas[face2->backarea]);
return true;
} //end of the function AAS_TryMergeFaces*/
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_MergeAreaFaces(void)
{
int num_facemerges = 0;
int side1, side2, restart;
tmp_area_t *tmparea, *lasttmparea;
tmp_face_t *face1, *face2;
Log_Write("AAS_MergeAreaFaces\r\n");
qprintf("%6d face merges", num_facemerges);
//NOTE: first convex area is a dummy
lasttmparea = tmpaasworld.areas;
for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
{
restart = false;
//
if (tmparea->invalid) continue;
//
for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
{
side1 = face1->frontarea != tmparea;
for (face2 = face1->next[side1]; face2; face2 = face2->next[side2])
{
side2 = face2->frontarea != tmparea;
//if succesfully merged
if (AAS_TryMergeFaces(face1, face2))
{
//start over again after merging two faces
restart = true;
num_facemerges++;
qprintf("\r%6d", num_facemerges);
AAS_CheckArea(tmparea);
break;
} //end if
} //end for
if (restart)
{
tmparea = lasttmparea;
break;
} //end if
} //end for
lasttmparea = tmparea;
} //end for
qprintf("\n");
Log_Write("%6d face merges\r\n", num_facemerges);
} //end of the function AAS_MergeAreaFaces
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_MergePlaneFaces(tmp_area_t *tmparea, int planenum)
{
tmp_face_t *face1, *face2, *nextface2;
winding_t *neww;
int side1, side2;
for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
{
side1 = face1->frontarea != tmparea;
if (face1->planenum != planenum) continue;
//
for (face2 = face1->next[side1]; face2; face2 = nextface2)
{
side2 = face2->frontarea != tmparea;
nextface2 = face2->next[side2];
//
if ((face2->planenum & ~1) != (planenum & ~1)) continue;
//
neww = MergeWindings(face1->winding, face2->winding,
mapplanes[face1->planenum].normal);
FreeWinding(face1->winding);
face1->winding = neww;
if (face2->frontarea) AAS_RemoveFaceFromArea(face2, face2->frontarea);
if (face2->backarea) AAS_RemoveFaceFromArea(face2, face2->backarea);
AAS_FreeTmpFace(face2);
//
nextface2 = face1->next[side1];
} //end for
} //end for
} //end of the function AAS_MergePlaneFaces
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_CanMergePlaneFaces(tmp_area_t *tmparea, int planenum)
{
tmp_area_t *frontarea, *backarea;
tmp_face_t *face1;
int side1, merge, faceflags;
frontarea = backarea = NULL;
merge = false;
for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
{
side1 = face1->frontarea != tmparea;
if ((face1->planenum & ~1) != (planenum & ~1)) continue;
if (!frontarea && !backarea)
{
frontarea = face1->frontarea;
backarea = face1->backarea;
faceflags = face1->faceflags;
} //end if
else
{
if (frontarea != face1->frontarea) return false;
if (backarea != face1->backarea) return false;
if (faceflags != face1->faceflags) return false;
merge = true;
} //end else
} //end for
return merge;
} //end of the function AAS_CanMergePlaneFaces
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_MergeAreaPlaneFaces(void)
{
int num_facemerges = 0;
int side1;
tmp_area_t *tmparea, *nexttmparea;
tmp_face_t *face1;
Log_Write("AAS_MergePlaneFaces\r\n");
qprintf("%6d plane face merges", num_facemerges);
//NOTE: first convex area is a dummy
for (tmparea = tmpaasworld.areas; tmparea; tmparea = nexttmparea)
{
nexttmparea = tmparea->l_next;
//
if (tmparea->invalid) continue;
//
for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
{
side1 = face1->frontarea != tmparea;
//
if (AAS_CanMergePlaneFaces(tmparea, face1->planenum))
{
AAS_MergePlaneFaces(tmparea, face1->planenum);
nexttmparea = tmparea;
num_facemerges++;
qprintf("\r%6d", num_facemerges);
break;
} //end if
} //end for
} //end for
qprintf("\n");
Log_Write("%6d plane face merges\r\n", num_facemerges);
} //end of the function AAS_MergeAreaPlaneFaces
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "qbsp.h"
#include "../botlib/aasfile.h"
#include "aas_create.h"
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_TryMergeFaces(tmp_face_t *face1, tmp_face_t *face2)
{
winding_t *neww;
#ifdef DEBUG
if (!face1->winding) Error("face1 %d without winding", face1->num);
if (!face2->winding) Error("face2 %d without winding", face2->num);
#endif //DEBUG
//
if (face1->faceflags != face2->faceflags) return false;
//NOTE: if the front or back area is zero this doesn't mean there's
//a real area. It means there's solid at that side of the face
//if both faces have the same front area
if (face1->frontarea == face2->frontarea)
{
//if both faces have the same back area
if (face1->backarea == face2->backarea)
{
//if the faces are in the same plane
if (face1->planenum == face2->planenum)
{
//if they have both a front and a back area (no solid on either side)
if (face1->frontarea && face1->backarea)
{
neww = MergeWindings(face1->winding, face2->winding,
mapplanes[face1->planenum].normal);
} //end if
else
{
//this function is to be found in l_poly.c
neww = TryMergeWinding(face1->winding, face2->winding,
mapplanes[face1->planenum].normal);
} //end else
if (neww)
{
FreeWinding(face1->winding);
face1->winding = neww;
if (face2->frontarea) AAS_RemoveFaceFromArea(face2, face2->frontarea);
if (face2->backarea) AAS_RemoveFaceFromArea(face2, face2->backarea);
AAS_FreeTmpFace(face2);
return true;
} //end if
} //end if
else if ((face1->planenum & ~1) == (face2->planenum & ~1))
{
Log_Write("face %d and %d, same front and back area but flipped planes\r\n",
face1->num, face2->num);
} //end if
} //end if
} //end if
return false;
} //end of the function AAS_TryMergeFaces
/*
int AAS_TryMergeFaces(tmp_face_t *face1, tmp_face_t *face2)
{
winding_t *neww;
#ifdef DEBUG
if (!face1->winding) Error("face1 %d without winding", face1->num);
if (!face2->winding) Error("face2 %d without winding", face2->num);
#endif //DEBUG
//if the faces are in the same plane
if ((face1->planenum & ~1) != (face2->planenum & ~1)) return false;
// if (face1->planenum != face2->planenum) return false;
//NOTE: if the front or back area is zero this doesn't mean there's
//a real area. It means there's solid at that side of the face
//if both faces have the same front area
if (face1->frontarea != face2->frontarea ||
face1->backarea != face2->backarea)
{
if (!face1->frontarea || !face1->backarea ||
!face2->frontarea || !face2->backarea) return false;
else if (face1->frontarea != face2->backarea ||
face1->backarea != face2->frontarea) return false;
// return false;
} //end if
//this function is to be found in l_poly.c
neww = TryMergeWinding(face1->winding, face2->winding,
mapplanes[face1->planenum].normal);
if (!neww) return false;
//
FreeWinding(face1->winding);
face1->winding = neww;
//remove face2
if (face2->frontarea)
AAS_RemoveFaceFromArea(face2, &tmpaasworld.areas[face2->frontarea]);
if (face2->backarea)
AAS_RemoveFaceFromArea(face2, &tmpaasworld.areas[face2->backarea]);
return true;
} //end of the function AAS_TryMergeFaces*/
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_MergeAreaFaces(void)
{
int num_facemerges = 0;
int side1, side2, restart;
tmp_area_t *tmparea, *lasttmparea;
tmp_face_t *face1, *face2;
Log_Write("AAS_MergeAreaFaces\r\n");
qprintf("%6d face merges", num_facemerges);
//NOTE: first convex area is a dummy
lasttmparea = tmpaasworld.areas;
for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
{
restart = false;
//
if (tmparea->invalid) continue;
//
for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
{
side1 = face1->frontarea != tmparea;
for (face2 = face1->next[side1]; face2; face2 = face2->next[side2])
{
side2 = face2->frontarea != tmparea;
//if succesfully merged
if (AAS_TryMergeFaces(face1, face2))
{
//start over again after merging two faces
restart = true;
num_facemerges++;
qprintf("\r%6d", num_facemerges);
AAS_CheckArea(tmparea);
break;
} //end if
} //end for
if (restart)
{
tmparea = lasttmparea;
break;
} //end if
} //end for
lasttmparea = tmparea;
} //end for
qprintf("\n");
Log_Write("%6d face merges\r\n", num_facemerges);
} //end of the function AAS_MergeAreaFaces
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_MergePlaneFaces(tmp_area_t *tmparea, int planenum)
{
tmp_face_t *face1, *face2, *nextface2;
winding_t *neww;
int side1, side2;
for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
{
side1 = face1->frontarea != tmparea;
if (face1->planenum != planenum) continue;
//
for (face2 = face1->next[side1]; face2; face2 = nextface2)
{
side2 = face2->frontarea != tmparea;
nextface2 = face2->next[side2];
//
if ((face2->planenum & ~1) != (planenum & ~1)) continue;
//
neww = MergeWindings(face1->winding, face2->winding,
mapplanes[face1->planenum].normal);
FreeWinding(face1->winding);
face1->winding = neww;
if (face2->frontarea) AAS_RemoveFaceFromArea(face2, face2->frontarea);
if (face2->backarea) AAS_RemoveFaceFromArea(face2, face2->backarea);
AAS_FreeTmpFace(face2);
//
nextface2 = face1->next[side1];
} //end for
} //end for
} //end of the function AAS_MergePlaneFaces
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_CanMergePlaneFaces(tmp_area_t *tmparea, int planenum)
{
tmp_area_t *frontarea, *backarea;
tmp_face_t *face1;
int side1, merge, faceflags;
frontarea = backarea = NULL;
merge = false;
for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
{
side1 = face1->frontarea != tmparea;
if ((face1->planenum & ~1) != (planenum & ~1)) continue;
if (!frontarea && !backarea)
{
frontarea = face1->frontarea;
backarea = face1->backarea;
faceflags = face1->faceflags;
} //end if
else
{
if (frontarea != face1->frontarea) return false;
if (backarea != face1->backarea) return false;
if (faceflags != face1->faceflags) return false;
merge = true;
} //end else
} //end for
return merge;
} //end of the function AAS_CanMergePlaneFaces
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_MergeAreaPlaneFaces(void)
{
int num_facemerges = 0;
int side1;
tmp_area_t *tmparea, *nexttmparea;
tmp_face_t *face1;
Log_Write("AAS_MergePlaneFaces\r\n");
qprintf("%6d plane face merges", num_facemerges);
//NOTE: first convex area is a dummy
for (tmparea = tmpaasworld.areas; tmparea; tmparea = nexttmparea)
{
nexttmparea = tmparea->l_next;
//
if (tmparea->invalid) continue;
//
for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
{
side1 = face1->frontarea != tmparea;
//
if (AAS_CanMergePlaneFaces(tmparea, face1->planenum))
{
AAS_MergePlaneFaces(tmparea, face1->planenum);
nexttmparea = tmparea;
num_facemerges++;
qprintf("\r%6d", num_facemerges);
break;
} //end if
} //end for
} //end for
qprintf("\n");
Log_Write("%6d plane face merges\r\n", num_facemerges);
} //end of the function AAS_MergeAreaPlaneFaces

48
code/bspc/aas_facemerging.h Normal file → Executable file
View file

@ -1,24 +1,24 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
void AAS_MergeAreaFaces(void);
void AAS_MergeAreaPlaneFaces(void);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
void AAS_MergeAreaFaces(void);
void AAS_MergeAreaPlaneFaces(void);

1098
code/bspc/aas_file.c Normal file → Executable file

File diff suppressed because it is too large Load diff

50
code/bspc/aas_file.h Normal file → Executable file
View file

@ -1,25 +1,25 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
qboolean AAS_WriteAASFile(char *filename);
qboolean AAS_LoadAASFile(char *filename, int fpoffset, int fplength);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
qboolean AAS_WriteAASFile(char *filename);
qboolean AAS_LoadAASFile(char *filename, int fpoffset, int fplength);

1312
code/bspc/aas_gsubdiv.c Normal file → Executable file

File diff suppressed because it is too large Load diff

50
code/bspc/aas_gsubdiv.h Normal file → Executable file
View file

@ -1,25 +1,25 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
//works with the global tmpaasworld
void AAS_GravitationalSubdivision(void);
void AAS_LadderSubdivision(void);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
//works with the global tmpaasworld
void AAS_GravitationalSubdivision(void);
void AAS_LadderSubdivision(void);

1698
code/bspc/aas_map.c Normal file → Executable file

File diff suppressed because it is too large Load diff

46
code/bspc/aas_map.h Normal file → Executable file
View file

@ -1,23 +1,23 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
void AAS_CreateMapBrushes(mapbrush_t *brush, entity_t *mapent, int addbevels);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
void AAS_CreateMapBrushes(mapbrush_t *brush, entity_t *mapent, int addbevels);

178
code/bspc/aas_prunenodes.c Normal file → Executable file
View file

@ -1,89 +1,89 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "qbsp.h"
#include "../botlib/aasfile.h"
#include "aas_create.h"
int c_numprunes;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
tmp_node_t *AAS_PruneNodes_r(tmp_node_t *tmpnode)
{
tmp_area_t *tmparea1, *tmparea2;
//if it is a solid leaf
if (!tmpnode) return NULL;
//
if (tmpnode->tmparea) return tmpnode;
//process the children first
tmpnode->children[0] = AAS_PruneNodes_r(tmpnode->children[0]);
tmpnode->children[1] = AAS_PruneNodes_r(tmpnode->children[1]);
//if both children are areas
if (tmpnode->children[0] && tmpnode->children[1] &&
tmpnode->children[0]->tmparea && tmpnode->children[1]->tmparea)
{
tmparea1 = tmpnode->children[0]->tmparea;
while(tmparea1->mergedarea) tmparea1 = tmparea1->mergedarea;
tmparea2 = tmpnode->children[1]->tmparea;
while(tmparea2->mergedarea) tmparea2 = tmparea2->mergedarea;
if (tmparea1 == tmparea2)
{
c_numprunes++;
tmpnode->tmparea = tmparea1;
tmpnode->planenum = 0;
AAS_FreeTmpNode(tmpnode->children[0]);
AAS_FreeTmpNode(tmpnode->children[1]);
tmpnode->children[0] = NULL;
tmpnode->children[1] = NULL;
return tmpnode;
} //end if
} //end if
//if both solid leafs
if (!tmpnode->children[0] && !tmpnode->children[1])
{
c_numprunes++;
AAS_FreeTmpNode(tmpnode);
return NULL;
} //end if
//
return tmpnode;
} //end of the function AAS_PruneNodes_r
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_PruneNodes(void)
{
Log_Write("AAS_PruneNodes\r\n");
AAS_PruneNodes_r(tmpaasworld.nodes);
Log_Print("%6d nodes pruned\r\n", c_numprunes);
} //end of the function AAS_PruneNodes
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "qbsp.h"
#include "../botlib/aasfile.h"
#include "aas_create.h"
int c_numprunes;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
tmp_node_t *AAS_PruneNodes_r(tmp_node_t *tmpnode)
{
tmp_area_t *tmparea1, *tmparea2;
//if it is a solid leaf
if (!tmpnode) return NULL;
//
if (tmpnode->tmparea) return tmpnode;
//process the children first
tmpnode->children[0] = AAS_PruneNodes_r(tmpnode->children[0]);
tmpnode->children[1] = AAS_PruneNodes_r(tmpnode->children[1]);
//if both children are areas
if (tmpnode->children[0] && tmpnode->children[1] &&
tmpnode->children[0]->tmparea && tmpnode->children[1]->tmparea)
{
tmparea1 = tmpnode->children[0]->tmparea;
while(tmparea1->mergedarea) tmparea1 = tmparea1->mergedarea;
tmparea2 = tmpnode->children[1]->tmparea;
while(tmparea2->mergedarea) tmparea2 = tmparea2->mergedarea;
if (tmparea1 == tmparea2)
{
c_numprunes++;
tmpnode->tmparea = tmparea1;
tmpnode->planenum = 0;
AAS_FreeTmpNode(tmpnode->children[0]);
AAS_FreeTmpNode(tmpnode->children[1]);
tmpnode->children[0] = NULL;
tmpnode->children[1] = NULL;
return tmpnode;
} //end if
} //end if
//if both solid leafs
if (!tmpnode->children[0] && !tmpnode->children[1])
{
c_numprunes++;
AAS_FreeTmpNode(tmpnode);
return NULL;
} //end if
//
return tmpnode;
} //end of the function AAS_PruneNodes_r
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_PruneNodes(void)
{
Log_Write("AAS_PruneNodes\r\n");
AAS_PruneNodes_r(tmpaasworld.nodes);
Log_Print("%6d nodes pruned\r\n", c_numprunes);
} //end of the function AAS_PruneNodes

48
code/bspc/aas_prunenodes.h Normal file → Executable file
View file

@ -1,24 +1,24 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
void AAS_PruneNodes(void);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
void AAS_PruneNodes(void);

2164
code/bspc/aas_store.c Normal file → Executable file

File diff suppressed because it is too large Load diff

214
code/bspc/aas_store.h Normal file → Executable file
View file

@ -1,107 +1,107 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#define AAS_MAX_BBOXES 5
#define AAS_MAX_VERTEXES 512000
#define AAS_MAX_PLANES 65536
#define AAS_MAX_EDGES 512000
#define AAS_MAX_EDGEINDEXSIZE 512000
#define AAS_MAX_FACES 512000
#define AAS_MAX_FACEINDEXSIZE 512000
#define AAS_MAX_AREAS 65536
#define AAS_MAX_AREASETTINGS 65536
#define AAS_MAX_REACHABILITYSIZE 65536
#define AAS_MAX_NODES 256000
#define AAS_MAX_PORTALS 65536
#define AAS_MAX_PORTALINDEXSIZE 65536
#define AAS_MAX_CLUSTERS 65536
#define BSPCINCLUDE
#include "../game/be_aas.h"
#include "../botlib/be_aas_def.h"
/*
typedef struct bspc_aas_s
{
int loaded;
int initialized; //true when AAS has been initialized
int savefile; //set true when file should be saved
//bounding boxes
int numbboxes;
aas_bbox_t *bboxes;
//vertexes
int numvertexes;
aas_vertex_t *vertexes;
//planes
int numplanes;
aas_plane_t *planes;
//edges
int numedges;
aas_edge_t *edges;
//edge index
int edgeindexsize;
aas_edgeindex_t *edgeindex;
//faces
int numfaces;
aas_face_t *faces;
//face index
int faceindexsize;
aas_faceindex_t *faceindex;
//convex areas
int numareas;
aas_area_t *areas;
//convex area settings
int numareasettings;
aas_areasettings_t *areasettings;
//reachablity list
int reachabilitysize;
aas_reachability_t *reachability;
//nodes of the bsp tree
int numnodes;
aas_node_t *nodes;
//cluster portals
int numportals;
aas_portal_t *portals;
//cluster portal index
int portalindexsize;
aas_portalindex_t *portalindex;
//clusters
int numclusters;
aas_cluster_t *clusters;
//
int numreachabilityareas;
float reachabilitytime;
} bspc_aas_t;
extern bspc_aas_t aasworld;
//*/
extern aas_t aasworld;
//stores the AAS file from the temporary AAS
void AAS_StoreFile(char *filename);
//returns a number of the given plane
qboolean AAS_FindPlane(vec3_t normal, float dist, int *planenum);
//allocates the maximum AAS memory for storage
void AAS_AllocMaxAAS(void);
//frees the maximum AAS memory for storage
void AAS_FreeMaxAAS(void);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#define AAS_MAX_BBOXES 5
#define AAS_MAX_VERTEXES 512000
#define AAS_MAX_PLANES 65536
#define AAS_MAX_EDGES 512000
#define AAS_MAX_EDGEINDEXSIZE 512000
#define AAS_MAX_FACES 512000
#define AAS_MAX_FACEINDEXSIZE 512000
#define AAS_MAX_AREAS 65536
#define AAS_MAX_AREASETTINGS 65536
#define AAS_MAX_REACHABILITYSIZE 65536
#define AAS_MAX_NODES 256000
#define AAS_MAX_PORTALS 65536
#define AAS_MAX_PORTALINDEXSIZE 65536
#define AAS_MAX_CLUSTERS 65536
#define BSPCINCLUDE
#include "../game/be_aas.h"
#include "../botlib/be_aas_def.h"
/*
typedef struct bspc_aas_s
{
int loaded;
int initialized; //true when AAS has been initialized
int savefile; //set true when file should be saved
//bounding boxes
int numbboxes;
aas_bbox_t *bboxes;
//vertexes
int numvertexes;
aas_vertex_t *vertexes;
//planes
int numplanes;
aas_plane_t *planes;
//edges
int numedges;
aas_edge_t *edges;
//edge index
int edgeindexsize;
aas_edgeindex_t *edgeindex;
//faces
int numfaces;
aas_face_t *faces;
//face index
int faceindexsize;
aas_faceindex_t *faceindex;
//convex areas
int numareas;
aas_area_t *areas;
//convex area settings
int numareasettings;
aas_areasettings_t *areasettings;
//reachablity list
int reachabilitysize;
aas_reachability_t *reachability;
//nodes of the bsp tree
int numnodes;
aas_node_t *nodes;
//cluster portals
int numportals;
aas_portal_t *portals;
//cluster portal index
int portalindexsize;
aas_portalindex_t *portalindex;
//clusters
int numclusters;
aas_cluster_t *clusters;
//
int numreachabilityareas;
float reachabilitytime;
} bspc_aas_t;
extern bspc_aas_t aasworld;
//*/
extern aas_t aasworld;
//stores the AAS file from the temporary AAS
void AAS_StoreFile(char *filename);
//returns a number of the given plane
qboolean AAS_FindPlane(vec3_t normal, float dist, int *planenum);
//allocates the maximum AAS memory for storage
void AAS_AllocMaxAAS(void);
//frees the maximum AAS memory for storage
void AAS_FreeMaxAAS(void);

504
code/bspc/aasfile.h Normal file → Executable file
View file

@ -1,252 +1,252 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
//NOTE: int = default signed
// default long
#define AASID (('S'<<24)+('A'<<16)+('A'<<8)+'E')
#define AASVERSION_OLD 4
#define AASVERSION 5
//presence types
#define PRESENCE_NONE 1
#define PRESENCE_NORMAL 2
#define PRESENCE_CROUCH 4
//travel types
#define MAX_TRAVELTYPES 32
#define TRAVEL_INVALID 1 //temporary not possible
#define TRAVEL_WALK 2 //walking
#define TRAVEL_CROUCH 3 //crouching
#define TRAVEL_BARRIERJUMP 4 //jumping onto a barrier
#define TRAVEL_JUMP 5 //jumping
#define TRAVEL_LADDER 6 //climbing a ladder
#define TRAVEL_WALKOFFLEDGE 7 //walking of a ledge
#define TRAVEL_SWIM 8 //swimming
#define TRAVEL_WATERJUMP 9 //jump out of the water
#define TRAVEL_TELEPORT 10 //teleportation
#define TRAVEL_ELEVATOR 11 //travel by elevator
#define TRAVEL_ROCKETJUMP 12 //rocket jumping required for travel
#define TRAVEL_BFGJUMP 13 //bfg jumping required for travel
#define TRAVEL_GRAPPLEHOOK 14 //grappling hook required for travel
#define TRAVEL_DOUBLEJUMP 15 //double jump
#define TRAVEL_RAMPJUMP 16 //ramp jump
#define TRAVEL_STRAFEJUMP 17 //strafe jump
#define TRAVEL_JUMPPAD 18 //jump pad
#define TRAVEL_FUNCBOB 19 //func bob
//face flags
#define FACE_SOLID 1 //just solid at the other side
#define FACE_LADDER 2 //ladder
#define FACE_GROUND 4 //standing on ground when in this face
#define FACE_GAP 8 //gap in the ground
#define FACE_LIQUID 16
#define FACE_LIQUIDSURFACE 32
//area contents
#define AREACONTENTS_WATER 1
#define AREACONTENTS_LAVA 2
#define AREACONTENTS_SLIME 4
#define AREACONTENTS_CLUSTERPORTAL 8
#define AREACONTENTS_TELEPORTAL 16
#define AREACONTENTS_ROUTEPORTAL 32
#define AREACONTENTS_TELEPORTER 64
#define AREACONTENTS_JUMPPAD 128
#define AREACONTENTS_DONOTENTER 256
#define AREACONTENTS_VIEWPORTAL 512
//area flags
#define AREA_GROUNDED 1 //bot can stand on the ground
#define AREA_LADDER 2 //area contains one or more ladder faces
#define AREA_LIQUID 4 //area contains a liquid
//aas file header lumps
#define AAS_LUMPS 14
#define AASLUMP_BBOXES 0
#define AASLUMP_VERTEXES 1
#define AASLUMP_PLANES 2
#define AASLUMP_EDGES 3
#define AASLUMP_EDGEINDEX 4
#define AASLUMP_FACES 5
#define AASLUMP_FACEINDEX 6
#define AASLUMP_AREAS 7
#define AASLUMP_AREASETTINGS 8
#define AASLUMP_REACHABILITY 9
#define AASLUMP_NODES 10
#define AASLUMP_PORTALS 11
#define AASLUMP_PORTALINDEX 12
#define AASLUMP_CLUSTERS 13
//========== bounding box =========
//bounding box
typedef struct aas_bbox_s
{
int presencetype;
int flags;
vec3_t mins, maxs;
} aas_bbox_t;
//============ settings ===========
//reachability to another area
typedef struct aas_reachability_s
{
int areanum; //number of the reachable area
int facenum; //number of the face towards the other area
int edgenum; //number of the edge towards the other area
vec3_t start; //start point of inter area movement
vec3_t end; //end point of inter area movement
int traveltype; //type of travel required to get to the area
unsigned short int traveltime;//travel time of the inter area movement
} aas_reachability_t;
//area settings
typedef struct aas_areasettings_s
{
//could also add all kind of statistic fields
int contents; //contents of the convex area
int areaflags; //several area flags
int presencetype; //how a bot can be present in this convex area
int cluster; //cluster the area belongs to, if negative it's a portal
int clusterareanum; //number of the area in the cluster
int numreachableareas; //number of reachable areas from this one
int firstreachablearea; //first reachable area in the reachable area index
} aas_areasettings_t;
//cluster portal
typedef struct aas_portal_s
{
int areanum; //area that is the actual portal
int frontcluster; //cluster at front of portal
int backcluster; //cluster at back of portal
int clusterareanum[2]; //number of the area in the front and back cluster
} aas_portal_t;
//cluster portal index
typedef int aas_portalindex_t;
//cluster
typedef struct aas_cluster_s
{
int numareas; //number of areas in the cluster
int numreachabilityareas; //number of areas with reachabilities
int numportals; //number of cluster portals
int firstportal; //first cluster portal in the index
} aas_cluster_t;
//============ 3d definition ============
typedef vec3_t aas_vertex_t;
//just a plane in the third dimension
typedef struct aas_plane_s
{
vec3_t normal; //normal vector of the plane
float dist; //distance of the plane (normal vector * distance = point in plane)
int type;
} aas_plane_t;
//edge
typedef struct aas_edge_s
{
int v[2]; //numbers of the vertexes of this edge
} aas_edge_t;
//edge index, negative if vertexes are reversed
typedef int aas_edgeindex_t;
//a face bounds a convex area, often it will also seperate two convex areas
typedef struct aas_face_s
{
int planenum; //number of the plane this face is in
int faceflags; //face flags (no use to create face settings for just this field)
int numedges; //number of edges in the boundary of the face
int firstedge; //first edge in the edge index
int frontarea; //convex area at the front of this face
int backarea; //convex area at the back of this face
} aas_face_t;
//face index, stores a negative index if backside of face
typedef int aas_faceindex_t;
//convex area with a boundary of faces
typedef struct aas_area_s
{
int areanum; //number of this area
//3d definition
int numfaces; //number of faces used for the boundary of the convex area
int firstface; //first face in the face index used for the boundary of the convex area
vec3_t mins; //mins of the convex area
vec3_t maxs; //maxs of the convex area
vec3_t center; //'center' of the convex area
} aas_area_t;
//nodes of the bsp tree
typedef struct aas_node_s
{
int planenum;
int children[2]; //child nodes of this node, or convex areas as leaves when negative
//when a child is zero it's a solid leaf
} aas_node_t;
//=========== aas file ===============
//header lump
typedef struct
{
int fileofs;
int filelen;
} aas_lump_t;
//aas file header
typedef struct aas_header_s
{
int ident;
int version;
int bspchecksum;
//data entries
aas_lump_t lumps[AAS_LUMPS];
} aas_header_t;
//====== additional information ======
/*
- when a node child is a solid leaf the node child number is zero
- two adjacent areas (sharing a plane at opposite sides) share a face
this face is a portal between the areas
- when an area uses a face from the faceindex with a positive index
then the face plane normal points into the area
- the face edges are stored counter clockwise using the edgeindex
- two adjacent convex areas (sharing a face) only share One face
this is a simple result of the areas being convex
- the convex areas can't have a mixture of ground and gap faces
other mixtures of faces in one area are allowed
- areas with the AREACONTENTS_CLUSTERPORTAL in the settings have
cluster number zero
- edge zero is a dummy
- face zero is a dummy
- area zero is a dummy
- node zero is a dummy
*/
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
//NOTE: int = default signed
// default long
#define AASID (('S'<<24)+('A'<<16)+('A'<<8)+'E')
#define AASVERSION_OLD 4
#define AASVERSION 5
//presence types
#define PRESENCE_NONE 1
#define PRESENCE_NORMAL 2
#define PRESENCE_CROUCH 4
//travel types
#define MAX_TRAVELTYPES 32
#define TRAVEL_INVALID 1 //temporary not possible
#define TRAVEL_WALK 2 //walking
#define TRAVEL_CROUCH 3 //crouching
#define TRAVEL_BARRIERJUMP 4 //jumping onto a barrier
#define TRAVEL_JUMP 5 //jumping
#define TRAVEL_LADDER 6 //climbing a ladder
#define TRAVEL_WALKOFFLEDGE 7 //walking of a ledge
#define TRAVEL_SWIM 8 //swimming
#define TRAVEL_WATERJUMP 9 //jump out of the water
#define TRAVEL_TELEPORT 10 //teleportation
#define TRAVEL_ELEVATOR 11 //travel by elevator
#define TRAVEL_ROCKETJUMP 12 //rocket jumping required for travel
#define TRAVEL_BFGJUMP 13 //bfg jumping required for travel
#define TRAVEL_GRAPPLEHOOK 14 //grappling hook required for travel
#define TRAVEL_DOUBLEJUMP 15 //double jump
#define TRAVEL_RAMPJUMP 16 //ramp jump
#define TRAVEL_STRAFEJUMP 17 //strafe jump
#define TRAVEL_JUMPPAD 18 //jump pad
#define TRAVEL_FUNCBOB 19 //func bob
//face flags
#define FACE_SOLID 1 //just solid at the other side
#define FACE_LADDER 2 //ladder
#define FACE_GROUND 4 //standing on ground when in this face
#define FACE_GAP 8 //gap in the ground
#define FACE_LIQUID 16
#define FACE_LIQUIDSURFACE 32
//area contents
#define AREACONTENTS_WATER 1
#define AREACONTENTS_LAVA 2
#define AREACONTENTS_SLIME 4
#define AREACONTENTS_CLUSTERPORTAL 8
#define AREACONTENTS_TELEPORTAL 16
#define AREACONTENTS_ROUTEPORTAL 32
#define AREACONTENTS_TELEPORTER 64
#define AREACONTENTS_JUMPPAD 128
#define AREACONTENTS_DONOTENTER 256
#define AREACONTENTS_VIEWPORTAL 512
//area flags
#define AREA_GROUNDED 1 //bot can stand on the ground
#define AREA_LADDER 2 //area contains one or more ladder faces
#define AREA_LIQUID 4 //area contains a liquid
//aas file header lumps
#define AAS_LUMPS 14
#define AASLUMP_BBOXES 0
#define AASLUMP_VERTEXES 1
#define AASLUMP_PLANES 2
#define AASLUMP_EDGES 3
#define AASLUMP_EDGEINDEX 4
#define AASLUMP_FACES 5
#define AASLUMP_FACEINDEX 6
#define AASLUMP_AREAS 7
#define AASLUMP_AREASETTINGS 8
#define AASLUMP_REACHABILITY 9
#define AASLUMP_NODES 10
#define AASLUMP_PORTALS 11
#define AASLUMP_PORTALINDEX 12
#define AASLUMP_CLUSTERS 13
//========== bounding box =========
//bounding box
typedef struct aas_bbox_s
{
int presencetype;
int flags;
vec3_t mins, maxs;
} aas_bbox_t;
//============ settings ===========
//reachability to another area
typedef struct aas_reachability_s
{
int areanum; //number of the reachable area
int facenum; //number of the face towards the other area
int edgenum; //number of the edge towards the other area
vec3_t start; //start point of inter area movement
vec3_t end; //end point of inter area movement
int traveltype; //type of travel required to get to the area
unsigned short int traveltime;//travel time of the inter area movement
} aas_reachability_t;
//area settings
typedef struct aas_areasettings_s
{
//could also add all kind of statistic fields
int contents; //contents of the convex area
int areaflags; //several area flags
int presencetype; //how a bot can be present in this convex area
int cluster; //cluster the area belongs to, if negative it's a portal
int clusterareanum; //number of the area in the cluster
int numreachableareas; //number of reachable areas from this one
int firstreachablearea; //first reachable area in the reachable area index
} aas_areasettings_t;
//cluster portal
typedef struct aas_portal_s
{
int areanum; //area that is the actual portal
int frontcluster; //cluster at front of portal
int backcluster; //cluster at back of portal
int clusterareanum[2]; //number of the area in the front and back cluster
} aas_portal_t;
//cluster portal index
typedef int aas_portalindex_t;
//cluster
typedef struct aas_cluster_s
{
int numareas; //number of areas in the cluster
int numreachabilityareas; //number of areas with reachabilities
int numportals; //number of cluster portals
int firstportal; //first cluster portal in the index
} aas_cluster_t;
//============ 3d definition ============
typedef vec3_t aas_vertex_t;
//just a plane in the third dimension
typedef struct aas_plane_s
{
vec3_t normal; //normal vector of the plane
float dist; //distance of the plane (normal vector * distance = point in plane)
int type;
} aas_plane_t;
//edge
typedef struct aas_edge_s
{
int v[2]; //numbers of the vertexes of this edge
} aas_edge_t;
//edge index, negative if vertexes are reversed
typedef int aas_edgeindex_t;
//a face bounds a convex area, often it will also seperate two convex areas
typedef struct aas_face_s
{
int planenum; //number of the plane this face is in
int faceflags; //face flags (no use to create face settings for just this field)
int numedges; //number of edges in the boundary of the face
int firstedge; //first edge in the edge index
int frontarea; //convex area at the front of this face
int backarea; //convex area at the back of this face
} aas_face_t;
//face index, stores a negative index if backside of face
typedef int aas_faceindex_t;
//convex area with a boundary of faces
typedef struct aas_area_s
{
int areanum; //number of this area
//3d definition
int numfaces; //number of faces used for the boundary of the convex area
int firstface; //first face in the face index used for the boundary of the convex area
vec3_t mins; //mins of the convex area
vec3_t maxs; //maxs of the convex area
vec3_t center; //'center' of the convex area
} aas_area_t;
//nodes of the bsp tree
typedef struct aas_node_s
{
int planenum;
int children[2]; //child nodes of this node, or convex areas as leaves when negative
//when a child is zero it's a solid leaf
} aas_node_t;
//=========== aas file ===============
//header lump
typedef struct
{
int fileofs;
int filelen;
} aas_lump_t;
//aas file header
typedef struct aas_header_s
{
int ident;
int version;
int bspchecksum;
//data entries
aas_lump_t lumps[AAS_LUMPS];
} aas_header_t;
//====== additional information ======
/*
- when a node child is a solid leaf the node child number is zero
- two adjacent areas (sharing a plane at opposite sides) share a face
this face is a portal between the areas
- when an area uses a face from the faceindex with a positive index
then the face plane normal points into the area
- the face edges are stored counter clockwise using the edgeindex
- two adjacent convex areas (sharing a face) only share One face
this is a simple result of the areas being convex
- the convex areas can't have a mixture of ground and gap faces
other mixtures of faces in one area are allowed
- areas with the AREACONTENTS_CLUSTERPORTAL in the settings have
cluster number zero
- edge zero is a dummy
- face zero is a dummy
- area zero is a dummy
- node zero is a dummy
*/

584
code/bspc/be_aas_bspc.c Normal file → Executable file
View file

@ -1,292 +1,292 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "../game/q_shared.h"
#include "../bspc/l_log.h"
#include "../bspc/l_qfiles.h"
#include "../botlib/l_memory.h"
#include "../botlib/l_script.h"
#include "../botlib/l_precomp.h"
#include "../botlib/l_struct.h"
#include "../botlib/aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "../botlib/be_aas_def.h"
#include "../qcommon/cm_public.h"
//#define BSPC
extern botlib_import_t botimport;
extern qboolean capsule_collision;
botlib_import_t botimport;
clipHandle_t worldmodel;
void Error (char *error, ...);
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_Error(char *fmt, ...)
{
va_list argptr;
char text[1024];
va_start(argptr, fmt);
vsprintf(text, fmt, argptr);
va_end(argptr);
Error(text);
} //end of the function AAS_Error
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int Sys_MilliSeconds(void)
{
return clock() * 1000 / CLOCKS_PER_SEC;
} //end of the function Sys_MilliSeconds
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_DebugLine(vec3_t start, vec3_t end, int color)
{
} //end of the function AAS_DebugLine
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ClearShownDebugLines(void)
{
} //end of the function AAS_ClearShownDebugLines
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
char *BotImport_BSPEntityData(void)
{
return CM_EntityString();
} //end of the function AAS_GetEntityData
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void BotImport_Trace(bsp_trace_t *bsptrace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int passent, int contentmask)
{
trace_t result;
CM_BoxTrace(&result, start, end, mins, maxs, worldmodel, contentmask, capsule_collision);
bsptrace->allsolid = result.allsolid;
bsptrace->contents = result.contents;
VectorCopy(result.endpos, bsptrace->endpos);
bsptrace->ent = result.entityNum;
bsptrace->fraction = result.fraction;
bsptrace->exp_dist = 0;
bsptrace->plane.dist = result.plane.dist;
VectorCopy(result.plane.normal, bsptrace->plane.normal);
bsptrace->plane.signbits = result.plane.signbits;
bsptrace->plane.type = result.plane.type;
bsptrace->sidenum = 0;
bsptrace->startsolid = result.startsolid;
bsptrace->surface.flags = result.surfaceFlags;
} //end of the function BotImport_Trace
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int BotImport_PointContents(vec3_t p)
{
return CM_PointContents(p, worldmodel);
} //end of the function BotImport_PointContents
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void *BotImport_GetMemory(int size)
{
return GetMemory(size);
} //end of the function BotImport_GetMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void BotImport_Print(int type, char *fmt, ...)
{
va_list argptr;
char buf[1024];
va_start(argptr, fmt);
vsprintf(buf, fmt, argptr);
printf(buf);
if (buf[0] != '\r') Log_Write(buf);
va_end(argptr);
} //end of the function BotImport_Print
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void BotImport_BSPModelMinsMaxsOrigin(int modelnum, vec3_t angles, vec3_t outmins, vec3_t outmaxs, vec3_t origin)
{
clipHandle_t h;
vec3_t mins, maxs;
float max;
int i;
h = CM_InlineModel(modelnum);
CM_ModelBounds(h, mins, maxs);
//if the model is rotated
if ((angles[0] || angles[1] || angles[2]))
{ // expand for rotation
max = RadiusFromBounds(mins, maxs);
for (i = 0; i < 3; i++)
{
mins[i] = (mins[i] + maxs[i]) * 0.5 - max;
maxs[i] = (mins[i] + maxs[i]) * 0.5 + max;
} //end for
} //end if
if (outmins) VectorCopy(mins, outmins);
if (outmaxs) VectorCopy(maxs, outmaxs);
if (origin) VectorClear(origin);
} //end of the function BotImport_BSPModelMinsMaxsOrigin
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Com_DPrintf(char *fmt, ...)
{
va_list argptr;
char buf[1024];
va_start(argptr, fmt);
vsprintf(buf, fmt, argptr);
printf(buf);
if (buf[0] != '\r') Log_Write(buf);
va_end(argptr);
} //end of the function Com_DPrintf
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int COM_Compress( char *data_p ) {
return strlen(data_p);
}
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Com_Memset (void* dest, const int val, const size_t count) {
memset(dest, val, count);
}
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Com_Memcpy (void* dest, const void* src, const size_t count) {
memcpy(dest, src, count);
}
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_InitBotImport(void)
{
botimport.BSPEntityData = BotImport_BSPEntityData;
botimport.GetMemory = BotImport_GetMemory;
botimport.FreeMemory = FreeMemory;
botimport.Trace = BotImport_Trace;
botimport.PointContents = BotImport_PointContents;
botimport.Print = BotImport_Print;
botimport.BSPModelMinsMaxsOrigin = BotImport_BSPModelMinsMaxsOrigin;
} //end of the function AAS_InitBotImport
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_CalcReachAndClusters(struct quakefile_s *qf)
{
float time;
Log_Print("loading collision map...\n");
//
if (!qf->pakfile[0]) strcpy(qf->pakfile, qf->filename);
//load the map
CM_LoadMap((char *) qf, qfalse, &aasworld.bspchecksum);
//get a handle to the world model
worldmodel = CM_InlineModel(0); // 0 = world, 1 + are bmodels
//initialize bot import structure
AAS_InitBotImport();
//load the BSP entity string
AAS_LoadBSPFile();
//init physics settings
AAS_InitSettings();
//initialize AAS link heap
AAS_InitAASLinkHeap();
//initialize the AAS linked entities for the new map
AAS_InitAASLinkedEntities();
//reset all reachabilities and clusters
aasworld.reachabilitysize = 0;
aasworld.numclusters = 0;
//set all view portals as cluster portals in case we re-calculate the reachabilities and clusters (with -reach)
AAS_SetViewPortalsAsClusterPortals();
//calculate reachabilities
AAS_InitReachability();
time = 0;
while(AAS_ContinueInitReachability(time)) time++;
//calculate clusters
AAS_InitClustering();
} //end of the function AAS_CalcReachAndClusters
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "../game/q_shared.h"
#include "../bspc/l_log.h"
#include "../bspc/l_qfiles.h"
#include "../botlib/l_memory.h"
#include "../botlib/l_script.h"
#include "../botlib/l_precomp.h"
#include "../botlib/l_struct.h"
#include "../botlib/aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "../botlib/be_aas_def.h"
#include "../qcommon/cm_public.h"
//#define BSPC
extern botlib_import_t botimport;
extern qboolean capsule_collision;
botlib_import_t botimport;
clipHandle_t worldmodel;
void Error (char *error, ...);
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_Error(char *fmt, ...)
{
va_list argptr;
char text[1024];
va_start(argptr, fmt);
vsprintf(text, fmt, argptr);
va_end(argptr);
Error(text);
} //end of the function AAS_Error
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int Sys_MilliSeconds(void)
{
return clock() * 1000 / CLOCKS_PER_SEC;
} //end of the function Sys_MilliSeconds
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_DebugLine(vec3_t start, vec3_t end, int color)
{
} //end of the function AAS_DebugLine
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ClearShownDebugLines(void)
{
} //end of the function AAS_ClearShownDebugLines
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
char *BotImport_BSPEntityData(void)
{
return CM_EntityString();
} //end of the function AAS_GetEntityData
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void BotImport_Trace(bsp_trace_t *bsptrace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int passent, int contentmask)
{
trace_t result;
CM_BoxTrace(&result, start, end, mins, maxs, worldmodel, contentmask, capsule_collision);
bsptrace->allsolid = result.allsolid;
bsptrace->contents = result.contents;
VectorCopy(result.endpos, bsptrace->endpos);
bsptrace->ent = result.entityNum;
bsptrace->fraction = result.fraction;
bsptrace->exp_dist = 0;
bsptrace->plane.dist = result.plane.dist;
VectorCopy(result.plane.normal, bsptrace->plane.normal);
bsptrace->plane.signbits = result.plane.signbits;
bsptrace->plane.type = result.plane.type;
bsptrace->sidenum = 0;
bsptrace->startsolid = result.startsolid;
bsptrace->surface.flags = result.surfaceFlags;
} //end of the function BotImport_Trace
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int BotImport_PointContents(vec3_t p)
{
return CM_PointContents(p, worldmodel);
} //end of the function BotImport_PointContents
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void *BotImport_GetMemory(int size)
{
return GetMemory(size);
} //end of the function BotImport_GetMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void BotImport_Print(int type, char *fmt, ...)
{
va_list argptr;
char buf[1024];
va_start(argptr, fmt);
vsprintf(buf, fmt, argptr);
printf(buf);
if (buf[0] != '\r') Log_Write(buf);
va_end(argptr);
} //end of the function BotImport_Print
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void BotImport_BSPModelMinsMaxsOrigin(int modelnum, vec3_t angles, vec3_t outmins, vec3_t outmaxs, vec3_t origin)
{
clipHandle_t h;
vec3_t mins, maxs;
float max;
int i;
h = CM_InlineModel(modelnum);
CM_ModelBounds(h, mins, maxs);
//if the model is rotated
if ((angles[0] || angles[1] || angles[2]))
{ // expand for rotation
max = RadiusFromBounds(mins, maxs);
for (i = 0; i < 3; i++)
{
mins[i] = (mins[i] + maxs[i]) * 0.5 - max;
maxs[i] = (mins[i] + maxs[i]) * 0.5 + max;
} //end for
} //end if
if (outmins) VectorCopy(mins, outmins);
if (outmaxs) VectorCopy(maxs, outmaxs);
if (origin) VectorClear(origin);
} //end of the function BotImport_BSPModelMinsMaxsOrigin
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Com_DPrintf(char *fmt, ...)
{
va_list argptr;
char buf[1024];
va_start(argptr, fmt);
vsprintf(buf, fmt, argptr);
printf(buf);
if (buf[0] != '\r') Log_Write(buf);
va_end(argptr);
} //end of the function Com_DPrintf
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int COM_Compress( char *data_p ) {
return strlen(data_p);
}
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Com_Memset (void* dest, const int val, const size_t count) {
memset(dest, val, count);
}
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Com_Memcpy (void* dest, const void* src, const size_t count) {
memcpy(dest, src, count);
}
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_InitBotImport(void)
{
botimport.BSPEntityData = BotImport_BSPEntityData;
botimport.GetMemory = BotImport_GetMemory;
botimport.FreeMemory = FreeMemory;
botimport.Trace = BotImport_Trace;
botimport.PointContents = BotImport_PointContents;
botimport.Print = BotImport_Print;
botimport.BSPModelMinsMaxsOrigin = BotImport_BSPModelMinsMaxsOrigin;
} //end of the function AAS_InitBotImport
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_CalcReachAndClusters(struct quakefile_s *qf)
{
float time;
Log_Print("loading collision map...\n");
//
if (!qf->pakfile[0]) strcpy(qf->pakfile, qf->filename);
//load the map
CM_LoadMap((char *) qf, qfalse, &aasworld.bspchecksum);
//get a handle to the world model
worldmodel = CM_InlineModel(0); // 0 = world, 1 + are bmodels
//initialize bot import structure
AAS_InitBotImport();
//load the BSP entity string
AAS_LoadBSPFile();
//init physics settings
AAS_InitSettings();
//initialize AAS link heap
AAS_InitAASLinkHeap();
//initialize the AAS linked entities for the new map
AAS_InitAASLinkedEntities();
//reset all reachabilities and clusters
aasworld.reachabilitysize = 0;
aasworld.numclusters = 0;
//set all view portals as cluster portals in case we re-calculate the reachabilities and clusters (with -reach)
AAS_SetViewPortalsAsClusterPortals();
//calculate reachabilities
AAS_InitReachability();
time = 0;
while(AAS_ContinueInitReachability(time)) time++;
//calculate clusters
AAS_InitClustering();
} //end of the function AAS_CalcReachAndClusters

46
code/bspc/be_aas_bspc.h Normal file → Executable file
View file

@ -1,23 +1,23 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
void AAS_CalcReachAndClusters(struct quakefile_s *qf);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
void AAS_CalcReachAndClusters(struct quakefile_s *qf);

3742
code/bspc/brushbsp.c Normal file → Executable file

File diff suppressed because it is too large Load diff

1982
code/bspc/bspc.c Normal file → Executable file

File diff suppressed because it is too large Load diff

56
code/bspc/bspc.sln Normal file → Executable file
View file

@ -1,28 +1,28 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bspc", "bspc.vcproj", "{4E4EBC16-F345-4667-84E1-86633BAFDAE6}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SourceCodeControl) = preSolution
SccNumberOfProjects = 1
SccProjectUniqueName0 = bspc.vcproj
SccProjectName0 = \u0022$/source/code/bspc\u0022,\u0020IGAAAAAA
SccLocalPath0 = .
SccProvider0 = MSSCCI:Perforce\u0020SCM
EndGlobalSection
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{4E4EBC16-F345-4667-84E1-86633BAFDAE6}.Debug.ActiveCfg = Debug|Win32
{4E4EBC16-F345-4667-84E1-86633BAFDAE6}.Debug.Build.0 = Debug|Win32
{4E4EBC16-F345-4667-84E1-86633BAFDAE6}.Release.ActiveCfg = Release|Win32
{4E4EBC16-F345-4667-84E1-86633BAFDAE6}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bspc", "bspc.vcproj", "{4E4EBC16-F345-4667-84E1-86633BAFDAE6}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SourceCodeControl) = preSolution
SccNumberOfProjects = 1
SccProjectUniqueName0 = bspc.vcproj
SccProjectName0 = \u0022$/source/code/bspc\u0022,\u0020IGAAAAAA
SccLocalPath0 = .
SccProvider0 = MSSCCI:Perforce\u0020SCM
EndGlobalSection
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{4E4EBC16-F345-4667-84E1-86633BAFDAE6}.Debug.ActiveCfg = Debug|Win32
{4E4EBC16-F345-4667-84E1-86633BAFDAE6}.Debug.Build.0 = Debug|Win32
{4E4EBC16-F345-4667-84E1-86633BAFDAE6}.Release.ActiveCfg = Release|Win32
{4E4EBC16-F345-4667-84E1-86633BAFDAE6}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

2762
code/bspc/bspc.vcproj Normal file → Executable file

File diff suppressed because it is too large Load diff

168
code/bspc/cfgq3.c Normal file → Executable file
View file

@ -1,84 +1,84 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
//===========================================================================
// BSPC configuration file
// Quake3
//===========================================================================
#define PRESENCE_NONE 1
#define PRESENCE_NORMAL 2
#define PRESENCE_CROUCH 4
bbox //30x30x56
{
presencetype PRESENCE_NORMAL
flags 0x0000
mins {-15, -15, -24}
maxs {15, 15, 32}
} //end bbox
bbox //30x30x40
{
presencetype PRESENCE_CROUCH
flags 0x0001
mins {-15, -15, -24}
maxs {15, 15, 16}
} //end bbox
settings
{
phys_gravitydirection {0, 0, -1}
phys_friction 6
phys_stopspeed 100
phys_gravity 800
phys_waterfriction 1
phys_watergravity 400
phys_maxvelocity 320
phys_maxwalkvelocity 320
phys_maxcrouchvelocity 100
phys_maxswimvelocity 150
phys_maxacceleration 2200
phys_airaccelerate 0
phys_maxstep 18
phys_maxsteepness 0.7
phys_maxwaterjump 19
phys_maxbarrier 33
phys_jumpvel 270
phys_falldelta5 40
phys_falldelta10 60
rs_waterjump 400
rs_teleport 50
rs_barrierjump 100
rs_startcrouch 300
rs_startgrapple 500
rs_startwalkoffledge 70
rs_startjump 300
rs_rocketjump 500
rs_bfgjump 500
rs_jumppad 250
rs_aircontrolledjumppad 300
rs_funcbob 300
rs_startelevator 50
rs_falldamage5 300
rs_falldamage10 500
rs_maxjumpfallheight 450
} //end settings
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
//===========================================================================
// BSPC configuration file
// Quake3
//===========================================================================
#define PRESENCE_NONE 1
#define PRESENCE_NORMAL 2
#define PRESENCE_CROUCH 4
bbox //30x30x56
{
presencetype PRESENCE_NORMAL
flags 0x0000
mins {-15, -15, -24}
maxs {15, 15, 32}
} //end bbox
bbox //30x30x40
{
presencetype PRESENCE_CROUCH
flags 0x0001
mins {-15, -15, -24}
maxs {15, 15, 16}
} //end bbox
settings
{
phys_gravitydirection {0, 0, -1}
phys_friction 6
phys_stopspeed 100
phys_gravity 800
phys_waterfriction 1
phys_watergravity 400
phys_maxvelocity 320
phys_maxwalkvelocity 320
phys_maxcrouchvelocity 100
phys_maxswimvelocity 150
phys_maxacceleration 2200
phys_airaccelerate 0
phys_maxstep 18
phys_maxsteepness 0.7
phys_maxwaterjump 19
phys_maxbarrier 33
phys_jumpvel 270
phys_falldelta5 40
phys_falldelta10 60
rs_waterjump 400
rs_teleport 50
rs_barrierjump 100
rs_startcrouch 300
rs_startgrapple 500
rs_startwalkoffledge 70
rs_startjump 300
rs_rocketjump 500
rs_bfgjump 500
rs_jumppad 250
rs_aircontrolledjumppad 300
rs_funcbob 300
rs_startelevator 50
rs_falldamage5 300
rs_falldamage10 500
rs_maxjumpfallheight 450
} //end settings

2010
code/bspc/csg.c Normal file → Executable file

File diff suppressed because it is too large Load diff

1956
code/bspc/faces.c Normal file → Executable file

File diff suppressed because it is too large Load diff

464
code/bspc/gldraw.c Normal file → Executable file
View file

@ -1,232 +1,232 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>
#include "qbsp.h"
// can't use the glvertex3fv functions, because the vec3_t fields
// could be either floats or doubles, depending on DOUBLEVEC_T
qboolean drawflag;
vec3_t draw_mins, draw_maxs;
#define WIN_SIZE 512
void InitWindow (void)
{
auxInitDisplayMode (AUX_SINGLE | AUX_RGB);
auxInitPosition (0, 0, WIN_SIZE, WIN_SIZE);
auxInitWindow ("qcsg");
}
void Draw_ClearWindow (void)
{
static int init;
int w, h, g;
vec_t mx, my;
if (!drawflag)
return;
if (!init)
{
init = true;
InitWindow ();
}
glClearColor (1,0.8,0.8,0);
glClear (GL_COLOR_BUFFER_BIT);
w = (draw_maxs[0] - draw_mins[0]);
h = (draw_maxs[1] - draw_mins[1]);
mx = draw_mins[0] + w/2;
my = draw_mins[1] + h/2;
g = w > h ? w : h;
glLoadIdentity ();
gluPerspective (90, 1, 2, 16384);
gluLookAt (mx, my, draw_maxs[2] + g/2, mx , my, draw_maxs[2], 0, 1, 0);
glColor3f (0,0,0);
// glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
glDisable (GL_DEPTH_TEST);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#if 0
glColor4f (1,0,0,0.5);
glBegin (GL_POLYGON);
glVertex3f (0, 500, 0);
glVertex3f (0, 900, 0);
glVertex3f (0, 900, 100);
glVertex3f (0, 500, 100);
glEnd ();
#endif
glFlush ();
}
void Draw_SetRed (void)
{
if (!drawflag)
return;
glColor3f (1,0,0);
}
void Draw_SetGrey (void)
{
if (!drawflag)
return;
glColor3f (0.5,0.5,0.5);
}
void Draw_SetBlack (void)
{
if (!drawflag)
return;
glColor3f (0,0,0);
}
void DrawWinding (winding_t *w)
{
int i;
if (!drawflag)
return;
glColor4f (0,0,0,0.5);
glBegin (GL_LINE_LOOP);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
glEnd ();
glColor4f (0,1,0,0.3);
glBegin (GL_POLYGON);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
glEnd ();
glFlush ();
}
void DrawAuxWinding (winding_t *w)
{
int i;
if (!drawflag)
return;
glColor4f (0,0,0,0.5);
glBegin (GL_LINE_LOOP);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
glEnd ();
glColor4f (1,0,0,0.3);
glBegin (GL_POLYGON);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
glEnd ();
glFlush ();
}
//============================================================
#define GLSERV_PORT 25001
qboolean wins_init;
int draw_socket;
void GLS_BeginScene (void)
{
WSADATA winsockdata;
WORD wVersionRequested;
struct sockaddr_in address;
int r;
if (!wins_init)
{
wins_init = true;
wVersionRequested = MAKEWORD(1, 1);
r = WSAStartup (MAKEWORD(1, 1), &winsockdata);
if (r)
Error ("Winsock initialization failed.");
}
// connect a socket to the server
draw_socket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (draw_socket == -1)
Error ("draw_socket failed");
address.sin_family = AF_INET;
address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
address.sin_port = GLSERV_PORT;
r = connect (draw_socket, (struct sockaddr *)&address, sizeof(address));
if (r == -1)
{
closesocket (draw_socket);
draw_socket = 0;
}
}
void GLS_Winding (winding_t *w, int code)
{
byte buf[1024];
int i, j;
if (!draw_socket)
return;
((int *)buf)[0] = w->numpoints;
((int *)buf)[1] = code;
for (i=0 ; i<w->numpoints ; i++)
for (j=0 ; j<3 ; j++)
((float *)buf)[2+i*3+j] = w->p[i][j];
send (draw_socket, buf, w->numpoints*12+8, 0);
}
void GLS_EndScene (void)
{
closesocket (draw_socket);
draw_socket = 0;
}
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>
#include "qbsp.h"
// can't use the glvertex3fv functions, because the vec3_t fields
// could be either floats or doubles, depending on DOUBLEVEC_T
qboolean drawflag;
vec3_t draw_mins, draw_maxs;
#define WIN_SIZE 512
void InitWindow (void)
{
auxInitDisplayMode (AUX_SINGLE | AUX_RGB);
auxInitPosition (0, 0, WIN_SIZE, WIN_SIZE);
auxInitWindow ("qcsg");
}
void Draw_ClearWindow (void)
{
static int init;
int w, h, g;
vec_t mx, my;
if (!drawflag)
return;
if (!init)
{
init = true;
InitWindow ();
}
glClearColor (1,0.8,0.8,0);
glClear (GL_COLOR_BUFFER_BIT);
w = (draw_maxs[0] - draw_mins[0]);
h = (draw_maxs[1] - draw_mins[1]);
mx = draw_mins[0] + w/2;
my = draw_mins[1] + h/2;
g = w > h ? w : h;
glLoadIdentity ();
gluPerspective (90, 1, 2, 16384);
gluLookAt (mx, my, draw_maxs[2] + g/2, mx , my, draw_maxs[2], 0, 1, 0);
glColor3f (0,0,0);
// glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
glDisable (GL_DEPTH_TEST);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#if 0
glColor4f (1,0,0,0.5);
glBegin (GL_POLYGON);
glVertex3f (0, 500, 0);
glVertex3f (0, 900, 0);
glVertex3f (0, 900, 100);
glVertex3f (0, 500, 100);
glEnd ();
#endif
glFlush ();
}
void Draw_SetRed (void)
{
if (!drawflag)
return;
glColor3f (1,0,0);
}
void Draw_SetGrey (void)
{
if (!drawflag)
return;
glColor3f (0.5,0.5,0.5);
}
void Draw_SetBlack (void)
{
if (!drawflag)
return;
glColor3f (0,0,0);
}
void DrawWinding (winding_t *w)
{
int i;
if (!drawflag)
return;
glColor4f (0,0,0,0.5);
glBegin (GL_LINE_LOOP);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
glEnd ();
glColor4f (0,1,0,0.3);
glBegin (GL_POLYGON);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
glEnd ();
glFlush ();
}
void DrawAuxWinding (winding_t *w)
{
int i;
if (!drawflag)
return;
glColor4f (0,0,0,0.5);
glBegin (GL_LINE_LOOP);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
glEnd ();
glColor4f (1,0,0,0.3);
glBegin (GL_POLYGON);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
glEnd ();
glFlush ();
}
//============================================================
#define GLSERV_PORT 25001
qboolean wins_init;
int draw_socket;
void GLS_BeginScene (void)
{
WSADATA winsockdata;
WORD wVersionRequested;
struct sockaddr_in address;
int r;
if (!wins_init)
{
wins_init = true;
wVersionRequested = MAKEWORD(1, 1);
r = WSAStartup (MAKEWORD(1, 1), &winsockdata);
if (r)
Error ("Winsock initialization failed.");
}
// connect a socket to the server
draw_socket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (draw_socket == -1)
Error ("draw_socket failed");
address.sin_family = AF_INET;
address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
address.sin_port = GLSERV_PORT;
r = connect (draw_socket, (struct sockaddr *)&address, sizeof(address));
if (r == -1)
{
closesocket (draw_socket);
draw_socket = 0;
}
}
void GLS_Winding (winding_t *w, int code)
{
byte buf[1024];
int i, j;
if (!draw_socket)
return;
((int *)buf)[0] = w->numpoints;
((int *)buf)[1] = code;
for (i=0 ; i<w->numpoints ; i++)
for (j=0 ; j<3 ; j++)
((float *)buf)[2+i*3+j] = w->p[i][j];
send (draw_socket, buf, w->numpoints*12+8, 0);
}
void GLS_EndScene (void)
{
closesocket (draw_socket);
draw_socket = 0;
}

298
code/bspc/glfile.c Normal file → Executable file
View file

@ -1,149 +1,149 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "qbsp.h"
int c_glfaces;
int PortalVisibleSides (portal_t *p)
{
int fcon, bcon;
if (!p->onnode)
return 0; // outside
fcon = p->nodes[0]->contents;
bcon = p->nodes[1]->contents;
// same contents never create a face
if (fcon == bcon)
return 0;
// FIXME: is this correct now?
if (!fcon)
return 1;
if (!bcon)
return 2;
return 0;
}
void OutputWinding (winding_t *w, FILE *glview)
{
static int level = 128;
vec_t light;
int i;
fprintf (glview, "%i\n", w->numpoints);
level+=28;
light = (level&255)/255.0;
for (i=0 ; i<w->numpoints ; i++)
{
fprintf (glview, "%6.3f %6.3f %6.3f %6.3f %6.3f %6.3f\n",
w->p[i][0],
w->p[i][1],
w->p[i][2],
light,
light,
light);
}
fprintf (glview, "\n");
}
/*
=============
OutputPortal
=============
*/
void OutputPortal (portal_t *p, FILE *glview)
{
winding_t *w;
int sides;
sides = PortalVisibleSides (p);
if (!sides)
return;
c_glfaces++;
w = p->winding;
if (sides == 2) // back side
w = ReverseWinding (w);
OutputWinding (w, glview);
if (sides == 2)
FreeWinding(w);
}
/*
=============
WriteGLView_r
=============
*/
void WriteGLView_r (node_t *node, FILE *glview)
{
portal_t *p, *nextp;
if (node->planenum != PLANENUM_LEAF)
{
WriteGLView_r (node->children[0], glview);
WriteGLView_r (node->children[1], glview);
return;
}
// write all the portals
for (p=node->portals ; p ; p=nextp)
{
if (p->nodes[0] == node)
{
OutputPortal (p, glview);
nextp = p->next[0];
}
else
nextp = p->next[1];
}
}
/*
=============
WriteGLView
=============
*/
void WriteGLView (tree_t *tree, char *source)
{
char name[1024];
FILE *glview;
c_glfaces = 0;
sprintf (name, "%s%s.gl",outbase, source);
printf ("Writing %s\n", name);
glview = fopen (name, "w");
if (!glview)
Error ("Couldn't open %s", name);
WriteGLView_r (tree->headnode, glview);
fclose (glview);
printf ("%5i c_glfaces\n", c_glfaces);
}
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "qbsp.h"
int c_glfaces;
int PortalVisibleSides (portal_t *p)
{
int fcon, bcon;
if (!p->onnode)
return 0; // outside
fcon = p->nodes[0]->contents;
bcon = p->nodes[1]->contents;
// same contents never create a face
if (fcon == bcon)
return 0;
// FIXME: is this correct now?
if (!fcon)
return 1;
if (!bcon)
return 2;
return 0;
}
void OutputWinding (winding_t *w, FILE *glview)
{
static int level = 128;
vec_t light;
int i;
fprintf (glview, "%i\n", w->numpoints);
level+=28;
light = (level&255)/255.0;
for (i=0 ; i<w->numpoints ; i++)
{
fprintf (glview, "%6.3f %6.3f %6.3f %6.3f %6.3f %6.3f\n",
w->p[i][0],
w->p[i][1],
w->p[i][2],
light,
light,
light);
}
fprintf (glview, "\n");
}
/*
=============
OutputPortal
=============
*/
void OutputPortal (portal_t *p, FILE *glview)
{
winding_t *w;
int sides;
sides = PortalVisibleSides (p);
if (!sides)
return;
c_glfaces++;
w = p->winding;
if (sides == 2) // back side
w = ReverseWinding (w);
OutputWinding (w, glview);
if (sides == 2)
FreeWinding(w);
}
/*
=============
WriteGLView_r
=============
*/
void WriteGLView_r (node_t *node, FILE *glview)
{
portal_t *p, *nextp;
if (node->planenum != PLANENUM_LEAF)
{
WriteGLView_r (node->children[0], glview);
WriteGLView_r (node->children[1], glview);
return;
}
// write all the portals
for (p=node->portals ; p ; p=nextp)
{
if (p->nodes[0] == node)
{
OutputPortal (p, glview);
nextp = p->next[0];
}
else
nextp = p->next[1];
}
}
/*
=============
WriteGLView
=============
*/
void WriteGLView (tree_t *tree, char *source)
{
char name[1024];
FILE *glview;
c_glfaces = 0;
sprintf (name, "%s%s.gl",outbase, source);
printf ("Writing %s\n", name);
glview = fopen (name, "w");
if (!glview)
Error ("Couldn't open %s", name);
WriteGLView_r (tree->headnode, glview);
fclose (glview);
printf ("%5i c_glfaces\n", c_glfaces);
}

360
code/bspc/l_bsp_ent.c Normal file → Executable file
View file

@ -1,180 +1,180 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "l_cmd.h"
#include "l_math.h"
#include "l_mem.h"
#include "l_log.h"
#include "../botlib/l_script.h"
#include "l_bsp_ent.h"
#define MAX_KEY 32
#define MAX_VALUE 1024
int num_entities;
entity_t entities[MAX_MAP_ENTITIES];
void StripTrailing(char *e)
{
char *s;
s = e + strlen(e)-1;
while (s >= e && *s <= 32)
{
*s = 0;
s--;
}
}
/*
=================
ParseEpair
=================
*/
epair_t *ParseEpair(script_t *script)
{
epair_t *e;
token_t token;
e = GetMemory(sizeof(epair_t));
memset (e, 0, sizeof(epair_t));
PS_ExpectAnyToken(script, &token);
StripDoubleQuotes(token.string);
if (strlen(token.string) >= MAX_KEY-1)
Error ("ParseEpair: token %s too long", token.string);
e->key = copystring(token.string);
PS_ExpectAnyToken(script, &token);
StripDoubleQuotes(token.string);
if (strlen(token.string) >= MAX_VALUE-1)
Error ("ParseEpair: token %s too long", token.string);
e->value = copystring(token.string);
// strip trailing spaces
StripTrailing(e->key);
StripTrailing(e->value);
return e;
} //end of the function ParseEpair
/*
================
ParseEntity
================
*/
qboolean ParseEntity(script_t *script)
{
epair_t *e;
entity_t *mapent;
token_t token;
if (!PS_ReadToken(script, &token))
return false;
if (strcmp(token.string, "{"))
Error ("ParseEntity: { not found");
if (num_entities == MAX_MAP_ENTITIES)
Error ("num_entities == MAX_MAP_ENTITIES");
mapent = &entities[num_entities];
num_entities++;
do
{
if (!PS_ReadToken(script, &token))
Error ("ParseEntity: EOF without closing brace");
if (!strcmp(token.string, "}") )
break;
PS_UnreadLastToken(script);
e = ParseEpair(script);
e->next = mapent->epairs;
mapent->epairs = e;
} while (1);
return true;
} //end of the function ParseEntity
void PrintEntity (entity_t *ent)
{
epair_t *ep;
printf ("------- entity %p -------\n", ent);
for (ep=ent->epairs ; ep ; ep=ep->next)
{
printf ("%s = %s\n", ep->key, ep->value);
}
}
void SetKeyValue (entity_t *ent, char *key, char *value)
{
epair_t *ep;
for (ep=ent->epairs ; ep ; ep=ep->next)
if (!strcmp (ep->key, key) )
{
FreeMemory(ep->value);
ep->value = copystring(value);
return;
}
ep = GetMemory(sizeof(*ep));
ep->next = ent->epairs;
ent->epairs = ep;
ep->key = copystring(key);
ep->value = copystring(value);
}
char *ValueForKey (entity_t *ent, char *key)
{
epair_t *ep;
for (ep=ent->epairs ; ep ; ep=ep->next)
if (!strcmp (ep->key, key) )
return ep->value;
return "";
}
vec_t FloatForKey (entity_t *ent, char *key)
{
char *k;
k = ValueForKey (ent, key);
return atof(k);
}
void GetVectorForKey (entity_t *ent, char *key, vec3_t vec)
{
char *k;
double v1, v2, v3;
k = ValueForKey (ent, key);
// scanf into doubles, then assign, so it is vec_t size independent
v1 = v2 = v3 = 0;
sscanf (k, "%lf %lf %lf", &v1, &v2, &v3);
vec[0] = v1;
vec[1] = v2;
vec[2] = v3;
}
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "l_cmd.h"
#include "l_math.h"
#include "l_mem.h"
#include "l_log.h"
#include "../botlib/l_script.h"
#include "l_bsp_ent.h"
#define MAX_KEY 32
#define MAX_VALUE 1024
int num_entities;
entity_t entities[MAX_MAP_ENTITIES];
void StripTrailing(char *e)
{
char *s;
s = e + strlen(e)-1;
while (s >= e && *s <= 32)
{
*s = 0;
s--;
}
}
/*
=================
ParseEpair
=================
*/
epair_t *ParseEpair(script_t *script)
{
epair_t *e;
token_t token;
e = GetMemory(sizeof(epair_t));
memset (e, 0, sizeof(epair_t));
PS_ExpectAnyToken(script, &token);
StripDoubleQuotes(token.string);
if (strlen(token.string) >= MAX_KEY-1)
Error ("ParseEpair: token %s too long", token.string);
e->key = copystring(token.string);
PS_ExpectAnyToken(script, &token);
StripDoubleQuotes(token.string);
if (strlen(token.string) >= MAX_VALUE-1)
Error ("ParseEpair: token %s too long", token.string);
e->value = copystring(token.string);
// strip trailing spaces
StripTrailing(e->key);
StripTrailing(e->value);
return e;
} //end of the function ParseEpair
/*
================
ParseEntity
================
*/
qboolean ParseEntity(script_t *script)
{
epair_t *e;
entity_t *mapent;
token_t token;
if (!PS_ReadToken(script, &token))
return false;
if (strcmp(token.string, "{"))
Error ("ParseEntity: { not found");
if (num_entities == MAX_MAP_ENTITIES)
Error ("num_entities == MAX_MAP_ENTITIES");
mapent = &entities[num_entities];
num_entities++;
do
{
if (!PS_ReadToken(script, &token))
Error ("ParseEntity: EOF without closing brace");
if (!strcmp(token.string, "}") )
break;
PS_UnreadLastToken(script);
e = ParseEpair(script);
e->next = mapent->epairs;
mapent->epairs = e;
} while (1);
return true;
} //end of the function ParseEntity
void PrintEntity (entity_t *ent)
{
epair_t *ep;
printf ("------- entity %p -------\n", ent);
for (ep=ent->epairs ; ep ; ep=ep->next)
{
printf ("%s = %s\n", ep->key, ep->value);
}
}
void SetKeyValue (entity_t *ent, char *key, char *value)
{
epair_t *ep;
for (ep=ent->epairs ; ep ; ep=ep->next)
if (!strcmp (ep->key, key) )
{
FreeMemory(ep->value);
ep->value = copystring(value);
return;
}
ep = GetMemory(sizeof(*ep));
ep->next = ent->epairs;
ent->epairs = ep;
ep->key = copystring(key);
ep->value = copystring(value);
}
char *ValueForKey (entity_t *ent, char *key)
{
epair_t *ep;
for (ep=ent->epairs ; ep ; ep=ep->next)
if (!strcmp (ep->key, key) )
return ep->value;
return "";
}
vec_t FloatForKey (entity_t *ent, char *key)
{
char *k;
k = ValueForKey (ent, key);
return atof(k);
}
void GetVectorForKey (entity_t *ent, char *key, vec3_t vec)
{
char *k;
double v1, v2, v3;
k = ValueForKey (ent, key);
// scanf into doubles, then assign, so it is vec_t size independent
v1 = v2 = v3 = 0;
sscanf (k, "%lf %lf %lf", &v1, &v2, &v3);
vec[0] = v1;
vec[1] = v2;
vec[2] = v3;
}

116
code/bspc/l_bsp_ent.h Normal file → Executable file
View file

@ -1,58 +1,58 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef MAX_MAP_ENTITIES
#define MAX_MAP_ENTITIES 2048
#endif
typedef struct epair_s
{
struct epair_s *next;
char *key;
char *value;
} epair_t;
typedef struct
{
vec3_t origin;
int firstbrush;
int numbrushes;
epair_t *epairs;
// only valid for func_areaportals
int areaportalnum;
int portalareas[2];
int modelnum; //for bsp 2 map conversion
qboolean wasdetail; //for SIN
} entity_t;
extern int num_entities;
extern entity_t entities[MAX_MAP_ENTITIES];
void StripTrailing(char *e);
void SetKeyValue(entity_t *ent, char *key, char *value);
char *ValueForKey(entity_t *ent, char *key); // will return "" if not present
vec_t FloatForKey(entity_t *ent, char *key);
void GetVectorForKey(entity_t *ent, char *key, vec3_t vec);
qboolean ParseEntity(script_t *script);
epair_t *ParseEpair(script_t *script);
void PrintEntity(entity_t *ent);
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef MAX_MAP_ENTITIES
#define MAX_MAP_ENTITIES 2048
#endif
typedef struct epair_s
{
struct epair_s *next;
char *key;
char *value;
} epair_t;
typedef struct
{
vec3_t origin;
int firstbrush;
int numbrushes;
epair_t *epairs;
// only valid for func_areaportals
int areaportalnum;
int portalareas[2];
int modelnum; //for bsp 2 map conversion
qboolean wasdetail; //for SIN
} entity_t;
extern int num_entities;
extern entity_t entities[MAX_MAP_ENTITIES];
void StripTrailing(char *e);
void SetKeyValue(entity_t *ent, char *key, char *value);
char *ValueForKey(entity_t *ent, char *key); // will return "" if not present
vec_t FloatForKey(entity_t *ent, char *key);
void GetVectorForKey(entity_t *ent, char *key, vec3_t vec);
qboolean ParseEntity(script_t *script);
epair_t *ParseEpair(script_t *script);
void PrintEntity(entity_t *ent);

1776
code/bspc/l_bsp_hl.c Normal file → Executable file

File diff suppressed because it is too large Load diff

628
code/bspc/l_bsp_hl.h Normal file → Executable file
View file

@ -1,314 +1,314 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// upper design bounds
#define HL_MAX_MAP_HULLS 4
#define HL_MAX_MAP_MODELS 400
#define HL_MAX_MAP_BRUSHES 4096
#define HL_MAX_MAP_ENTITIES 1024
#define HL_MAX_MAP_ENTSTRING (128*1024)
#define HL_MAX_MAP_PLANES 32767
#define HL_MAX_MAP_NODES 32767 // because negative shorts are contents
#define HL_MAX_MAP_CLIPNODES 32767 //
#define HL_MAX_MAP_LEAFS 8192
#define HL_MAX_MAP_VERTS 65535
#define HL_MAX_MAP_FACES 65535
#define HL_MAX_MAP_MARKSURFACES 65535
#define HL_MAX_MAP_TEXINFO 8192
#define HL_MAX_MAP_EDGES 256000
#define HL_MAX_MAP_SURFEDGES 512000
#define HL_MAX_MAP_TEXTURES 512
#define HL_MAX_MAP_MIPTEX 0x200000
#define HL_MAX_MAP_LIGHTING 0x200000
#define HL_MAX_MAP_VISIBILITY 0x200000
#define HL_MAX_MAP_PORTALS 65536
// key / value pair sizes
#define MAX_KEY 32
#define MAX_VALUE 1024
//=============================================================================
#define HL_BSPVERSION 30
#define HL_TOOLVERSION 2
typedef struct
{
int fileofs, filelen;
} hl_lump_t;
#define HL_LUMP_ENTITIES 0
#define HL_LUMP_PLANES 1
#define HL_LUMP_TEXTURES 2
#define HL_LUMP_VERTEXES 3
#define HL_LUMP_VISIBILITY 4
#define HL_LUMP_NODES 5
#define HL_LUMP_TEXINFO 6
#define HL_LUMP_FACES 7
#define HL_LUMP_LIGHTING 8
#define HL_LUMP_CLIPNODES 9
#define HL_LUMP_LEAFS 10
#define HL_LUMP_MARKSURFACES 11
#define HL_LUMP_EDGES 12
#define HL_LUMP_SURFEDGES 13
#define HL_LUMP_MODELS 14
#define HL_HEADER_LUMPS 15
typedef struct
{
float mins[3], maxs[3];
float origin[3];
int headnode[HL_MAX_MAP_HULLS];
int visleafs; // not including the solid leaf 0
int firstface, numfaces;
} hl_dmodel_t;
typedef struct
{
int version;
hl_lump_t lumps[HL_HEADER_LUMPS];
} hl_dheader_t;
typedef struct
{
int nummiptex;
int dataofs[4]; // [nummiptex]
} hl_dmiptexlump_t;
#define MIPLEVELS 4
typedef struct hl_miptex_s
{
char name[16];
unsigned width, height;
unsigned offsets[MIPLEVELS]; // four mip maps stored
} hl_miptex_t;
typedef struct
{
float point[3];
} hl_dvertex_t;
// 0-2 are axial planes
#define PLANE_X 0
#define PLANE_Y 1
#define PLANE_Z 2
// 3-5 are non-axial planes snapped to the nearest
#define PLANE_ANYX 3
#define PLANE_ANYY 4
#define PLANE_ANYZ 5
typedef struct
{
float normal[3];
float dist;
int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate
} hl_dplane_t;
#define HL_CONTENTS_EMPTY -1
#define HL_CONTENTS_SOLID -2
#define HL_CONTENTS_WATER -3
#define HL_CONTENTS_SLIME -4
#define HL_CONTENTS_LAVA -5
#define HL_CONTENTS_SKY -6
#define HL_CONTENTS_ORIGIN -7 // removed at csg time
#define HL_CONTENTS_CLIP -8 // changed to contents_solid
#define HL_CONTENTS_CURRENT_0 -9
#define HL_CONTENTS_CURRENT_90 -10
#define HL_CONTENTS_CURRENT_180 -11
#define HL_CONTENTS_CURRENT_270 -12
#define HL_CONTENTS_CURRENT_UP -13
#define HL_CONTENTS_CURRENT_DOWN -14
#define HL_CONTENTS_TRANSLUCENT -15
// !!! if this is changed, it must be changed in asm_i386.h too !!!
typedef struct
{
int planenum;
short children[2]; // negative numbers are -(leafs+1), not nodes
short mins[3]; // for sphere culling
short maxs[3];
unsigned short firstface;
unsigned short numfaces; // counting both sides
} hl_dnode_t;
typedef struct
{
int planenum;
short children[2]; // negative numbers are contents
} hl_dclipnode_t;
typedef struct hl_texinfo_s
{
float vecs[2][4]; // [s/t][xyz offset]
int miptex;
int flags;
} hl_texinfo_t;
#define TEX_SPECIAL 1 // sky or slime, no lightmap or 256 subdivision
// note that edge 0 is never used, because negative edge nums are used for
// counterclockwise use of the edge in a face
typedef struct
{
unsigned short v[2]; // vertex numbers
} hl_dedge_t;
#define MAXLIGHTMAPS 4
typedef struct
{
short planenum;
short side;
int firstedge; // we must support > 64k edges
short numedges;
short texinfo;
// lighting info
byte styles[MAXLIGHTMAPS];
int lightofs; // start of [numstyles*surfsize] samples
} hl_dface_t;
#define AMBIENT_WATER 0
#define AMBIENT_SKY 1
#define AMBIENT_SLIME 2
#define AMBIENT_LAVA 3
#define NUM_AMBIENTS 4 // automatic ambient sounds
// leaf 0 is the generic HL_CONTENTS_SOLID leaf, used for all solid areas
// all other leafs need visibility info
typedef struct
{
int contents;
int visofs; // -1 = no visibility info
short mins[3]; // for frustum culling
short maxs[3];
unsigned short firstmarksurface;
unsigned short nummarksurfaces;
byte ambient_level[NUM_AMBIENTS];
} hl_dleaf_t;
//============================================================================
#ifndef QUAKE_GAME
#define ANGLE_UP -1
#define ANGLE_DOWN -2
// the utilities get to be lazy and just use large static arrays
extern int hl_nummodels;
extern hl_dmodel_t *hl_dmodels;//[MAX_MAP_MODELS];
extern int hl_dmodels_checksum;
extern int hl_visdatasize;
extern byte *hl_dvisdata;//[MAX_MAP_VISIBILITY];
extern int hl_dvisdata_checksum;
extern int hl_lightdatasize;
extern byte *hl_dlightdata;//[MAX_MAP_LIGHTING];
extern int hl_dlightdata_checksum;
extern int hl_texdatasize;
extern byte *hl_dtexdata;//[MAX_MAP_MIPTEX]; // (dmiptexlump_t)
extern int hl_dtexdata_checksum;
extern int hl_entdatasize;
extern char *hl_dentdata;//[MAX_MAP_ENTSTRING];
extern int hl_dentdata_checksum;
extern int hl_numleafs;
extern hl_dleaf_t *hl_dleafs;//[MAX_MAP_LEAFS];
extern int hl_dleafs_checksum;
extern int hl_numplanes;
extern hl_dplane_t *hl_dplanes;//[MAX_MAP_PLANES];
extern int hl_dplanes_checksum;
extern int hl_numvertexes;
extern hl_dvertex_t *hl_dvertexes;//[MAX_MAP_VERTS];
extern int hl_dvertexes_checksum;
extern int hl_numnodes;
extern hl_dnode_t *hl_dnodes;//[MAX_MAP_NODES];
extern int hl_dnodes_checksum;
extern int hl_numtexinfo;
extern hl_texinfo_t *hl_texinfo;//[MAX_MAP_TEXINFO];
extern int hl_texinfo_checksum;
extern int hl_numfaces;
extern hl_dface_t *hl_dfaces;//[MAX_MAP_FACES];
extern int hl_dfaces_checksum;
extern int hl_numclipnodes;
extern hl_dclipnode_t *hl_dclipnodes;//[MAX_MAP_CLIPNODES];
extern int hl_dclipnodes_checksum;
extern int hl_numedges;
extern hl_dedge_t *hl_dedges;//[MAX_MAP_EDGES];
extern int hl_dedges_checksum;
extern int hl_nummarksurfaces;
extern unsigned short *hl_dmarksurfaces;//[MAX_MAP_MARKSURFACES];
extern int hl_dmarksurfaces_checksum;
extern int hl_numsurfedges;
extern int *hl_dsurfedges;//[MAX_MAP_SURFEDGES];
extern int hl_dsurfedges_checksum;
int FastChecksum(void *buffer, int bytes);
void HL_AllocMaxBSP(void);
void HL_FreeMaxBSP(void);
void HL_DecompressVis(byte *in, byte *decompressed);
int HL_CompressVis(byte *vis, byte *dest);
void HL_LoadBSPFile(char *filename, int offset, int length);
void HL_WriteBSPFile(char *filename);
void HL_PrintBSPFileSizes(void);
void HL_PrintBSPFileSizes(void);
void HL_ParseEntities(void);
void HL_UnparseEntities(void);
#endif
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code 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.
Quake III Arena source code 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// upper design bounds
#define HL_MAX_MAP_HULLS 4
#define HL_MAX_MAP_MODELS 400
#define HL_MAX_MAP_BRUSHES 4096
#define HL_MAX_MAP_ENTITIES 1024
#define HL_MAX_MAP_ENTSTRING (128*1024)
#define HL_MAX_MAP_PLANES 32767
#define HL_MAX_MAP_NODES 32767 // because negative shorts are contents
#define HL_MAX_MAP_CLIPNODES 32767 //
#define HL_MAX_MAP_LEAFS 8192
#define HL_MAX_MAP_VERTS 65535
#define HL_MAX_MAP_FACES 65535
#define HL_MAX_MAP_MARKSURFACES 65535
#define HL_MAX_MAP_TEXINFO 8192
#define HL_MAX_MAP_EDGES 256000
#define HL_MAX_MAP_SURFEDGES 512000
#define HL_MAX_MAP_TEXTURES 512
#define HL_MAX_MAP_MIPTEX 0x200000
#define HL_MAX_MAP_LIGHTING 0x200000
#define HL_MAX_MAP_VISIBILITY 0x200000
#define HL_MAX_MAP_PORTALS 65536
// key / value pair sizes
#define MAX_KEY 32
#define MAX_VALUE 1024
//=============================================================================
#define HL_BSPVERSION 30
#define HL_TOOLVERSION 2
typedef struct
{
int fileofs, filelen;
} hl_lump_t;
#define HL_LUMP_ENTITIES 0
#define HL_LUMP_PLANES 1
#define HL_LUMP_TEXTURES 2
#define HL_LUMP_VERTEXES 3
#define HL_LUMP_VISIBILITY 4
#define HL_LUMP_NODES 5
#define HL_LUMP_TEXINFO 6
#define HL_LUMP_FACES 7
#define HL_LUMP_LIGHTING 8
#define HL_LUMP_CLIPNODES 9
#define HL_LUMP_LEAFS 10
#define HL_LUMP_MARKSURFACES 11
#define HL_LUMP_EDGES 12
#define HL_LUMP_SURFEDGES 13
#define HL_LUMP_MODELS 14
#define HL_HEADER_LUMPS 15
typedef struct
{
float mins[3], maxs[3];
float origin[3];
int headnode[HL_MAX_MAP_HULLS];
int visleafs; // not including the solid leaf 0
int firstface, numfaces;
} hl_dmodel_t;
typedef struct
{
int version;
hl_lump_t lumps[HL_HEADER_LUMPS];
} hl_dheader_t;
typedef struct
{
int nummiptex;
int dataofs[4]; // [nummiptex]
} hl_dmiptexlump_t;
#define MIPLEVELS 4
typedef struct hl_miptex_s
{
char name[16];
unsigned width, height;
unsigned offsets[MIPLEVELS]; // four mip maps stored
} hl_miptex_t;
typedef struct
{
float point[3];
} hl_dvertex_t;
// 0-2 are axial planes
#define PLANE_X 0
#define PLANE_Y 1
#define PLANE_Z 2
// 3-5 are non-axial planes snapped to the nearest
#define PLANE_ANYX 3
#define PLANE_ANYY 4
#define PLANE_ANYZ 5
typedef struct
{
float normal[3];
float dist;
int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate
} hl_dplane_t;
#define HL_CONTENTS_EMPTY -1
#define HL_CONTENTS_SOLID -2
#define HL_CONTENTS_WATER -3
#define HL_CONTENTS_SLIME -4
#define HL_CONTENTS_LAVA -5
#define HL_CONTENTS_SKY -6
#define HL_CONTENTS_ORIGIN -7 // removed at csg time
#define HL_CONTENTS_CLIP -8 // changed to contents_solid
#define HL_CONTENTS_CURRENT_0 -9
#define HL_CONTENTS_CURRENT_90 -10
#define HL_CONTENTS_CURRENT_180 -11
#define HL_CONTENTS_CURRENT_270 -12
#define HL_CONTENTS_CURRENT_UP -13
#define HL_CONTENTS_CURRENT_DOWN -14
#define HL_CONTENTS_TRANSLUCENT -15
// !!! if this is changed, it must be changed in asm_i386.h too !!!
typedef struct
{
int planenum;
short children[2]; // negative numbers are -(leafs+1), not nodes
short mins[3]; // for sphere culling
short maxs[3];
unsigned short firstface;
unsigned short numfaces; // counting both sides
} hl_dnode_t;
typedef struct
{
int planenum;
short children[2]; // negative numbers are contents
} hl_dclipnode_t;
typedef struct hl_texinfo_s
{
float vecs[2][4]; // [s/t][xyz offset]
int miptex;
int flags;
} hl_texinfo_t;
#define TEX_SPECIAL 1 // sky or slime, no lightmap or 256 subdivision
// note that edge 0 is never used, because negative edge nums are used for
// counterclockwise use of the edge in a face
typedef struct
{
unsigned short v[2]; // vertex numbers
} hl_dedge_t;
#define MAXLIGHTMAPS 4
typedef struct
{
short planenum;
short side;
int firstedge; // we must support > 64k edges
short numedges;
short texinfo;
// lighting info
byte styles[MAXLIGHTMAPS];
int lightofs; // start of [numstyles*surfsize] samples
} hl_dface_t;
#define AMBIENT_WATER 0
#define AMBIENT_SKY 1
#define AMBIENT_SLIME 2
#define AMBIENT_LAVA 3
#define NUM_AMBIENTS 4 // automatic ambient sounds
// leaf 0 is the generic HL_CONTENTS_SOLID leaf, used for all solid areas
// all other leafs need visibility info
typedef struct
{
int contents;
int visofs; // -1 = no visibility info
short mins[3]; // for frustum culling
short maxs[3];
unsigned short firstmarksurface;
unsigned short nummarksurfaces;
byte ambient_level[NUM_AMBIENTS];
} hl_dleaf_t;
//============================================================================
#ifndef QUAKE_GAME
#define ANGLE_UP -1
#define ANGLE_DOWN -2
// the utilities get to be lazy and just use large static arrays
extern int hl_nummodels;
extern hl_dmodel_t *hl_dmodels;//[MAX_MAP_MODELS];
extern int hl_dmodels_checksum;
extern int hl_visdatasize;
extern byte *hl_dvisdata;//[MAX_MAP_VISIBILITY];
extern int hl_dvisdata_checksum;
extern int hl_lightdatasize;
extern byte *hl_dlightdata;//[MAX_MAP_LIGHTING];
extern int hl_dlightdata_checksum;
extern int hl_texdatasize;
extern byte *hl_dtexdata;//[MAX_MAP_MIPTEX]; // (dmiptexlump_t)
extern int hl_dtexdata_checksum;
extern int hl_entdatasize;
extern char *hl_dentdata;//[MAX_MAP_ENTSTRING];
extern int hl_dentdata_checksum;
extern int hl_numleafs;
extern hl_dleaf_t *hl_dleafs;//[MAX_MAP_LEAFS];
extern int hl_dleafs_checksum;
extern int hl_numplanes;
extern hl_dplane_t *hl_dplanes;//[MAX_MAP_PLANES];
extern int hl_dplanes_checksum;
extern int hl_numvertexes;
extern hl_dvertex_t *hl_dvertexes;//[MAX_MAP_VERTS];
extern int hl_dvertexes_checksum;
extern int hl_numnodes;
extern hl_dnode_t *hl_dnodes;//[MAX_MAP_NODES];
extern int hl_dnodes_checksum;
extern int hl_numtexinfo;
extern hl_texinfo_t *hl_texinfo;//[MAX_MAP_TEXINFO];
extern int hl_texinfo_checksum;
extern int hl_numfaces;
extern hl_dface_t *hl_dfaces;//[MAX_MAP_FACES];
extern int hl_dfaces_checksum;
extern int hl_numclipnodes;
extern hl_dclipnode_t *hl_dclipnodes;//[MAX_MAP_CLIPNODES];
extern int hl_dclipnodes_checksum;
extern int hl_numedges;
extern hl_dedge_t *hl_dedges;//[MAX_MAP_EDGES];
extern int hl_dedges_checksum;
extern int hl_nummarksurfaces;
extern unsigned short *hl_dmarksurfaces;//[MAX_MAP_MARKSURFACES];
extern int hl_dmarksurfaces_checksum;
extern int hl_numsurfedges;
extern int *hl_dsurfedges;//[MAX_MAP_SURFEDGES];
extern int hl_dsurfedges_checksum;
int FastChecksum(void *buffer, int bytes);
void HL_AllocMaxBSP(void);
void HL_FreeMaxBSP(void);
void HL_DecompressVis(byte *in, byte *decompressed);
int HL_CompressVis(byte *vis, byte *dest);
void HL_LoadBSPFile(char *filename, int offset, int length);
void HL_WriteBSPFile(char *filename);
void HL_PrintBSPFileSizes(void);
void HL_PrintBSPFileSizes(void);
void HL_ParseEntities(void);
void HL_UnparseEntities(void);
#endif

1240
code/bspc/l_bsp_q1.c Normal file → Executable file

File diff suppressed because it is too large Load diff

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