alien-arena-7.66+dfsg/0000700000175000017500000000000012315467667013636 5ustar zero79zero79alien-arena-7.66+dfsg/aclocal.m40000600000175000017500000012730012207204612015456 0ustar zero79zero79# generated automatically by aclocal 1.14 -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # Copyright (C) 2002-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.14' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.14], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.14])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_COND_IF -*- Autoconf -*- # Copyright (C) 2008-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_COND_IF # _AM_COND_ELSE # _AM_COND_ENDIF # -------------- # These macros are only used for tracing. m4_define([_AM_COND_IF]) m4_define([_AM_COND_ELSE]) m4_define([_AM_COND_ENDIF]) # AM_COND_IF(COND, [IF-TRUE], [IF-FALSE]) # --------------------------------------- # If the shell condition COND is true, execute IF-TRUE, otherwise execute # IF-FALSE. Allow automake to learn about conditional instantiating macros # (the AC_CONFIG_FOOS). AC_DEFUN([AM_COND_IF], [m4_ifndef([_AM_COND_VALUE_$1], [m4_fatal([$0: no such condition "$1"])])dnl _AM_COND_IF([$1])dnl if test -z "$$1_TRUE"; then : m4_n([$2])[]dnl m4_ifval([$3], [_AM_COND_ELSE([$1])dnl else $3 ])dnl _AM_COND_ENDIF([$1])dnl fi[]dnl ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering # Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAINTAINER_MODE([DEFAULT-MODE]) # ---------------------------------- # Control maintainer-specific portions of Makefiles. # Default is to disable them, unless 'enable' is passed literally. # For symmetry, 'disable' may be passed as well. Anyway, the user # can override the default with the --enable/--disable switch. AC_DEFUN([AM_MAINTAINER_MODE], [m4_case(m4_default([$1], [disable]), [enable], [m4_define([am_maintainer_other], [disable])], [disable], [m4_define([am_maintainer_other], [enable])], [m4_define([am_maintainer_other], [enable]) m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) dnl maintainer-mode's default is 'disable' unless 'enable' is passed AC_ARG_ENABLE([maintainer-mode], [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], am_maintainer_other[ make rules and dependencies not useful (and sometimes confusing) to the casual installer])], [USE_MAINTAINER_MODE=$enableval], [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) AC_MSG_RESULT([$USE_MAINTAINER_MODE]) AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) MAINT=$MAINTAINER_MODE_TRUE AC_SUBST([MAINT])dnl ] ) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/ax_append_flag.m4]) m4_include([m4/ax_expand_prefix.m4]) m4_include([m4/ax_pthread.m4]) m4_include([m4/pkg.m4]) alien-arena-7.66+dfsg/configure0000700000175000017500000106401512207204613015530 0ustar zero79zero79#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for alienarena 7.66. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and $0: alienrace@comcast.net about your system, including any $0: error possibly output before this message. Then install $0: a modern shell, or manually run the script under such a $0: shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='alienarena' PACKAGE_TARNAME='alienarena' PACKAGE_VERSION='7.66' PACKAGE_STRING='alienarena 7.66' PACKAGE_BUGREPORT='alienrace@comcast.net' PACKAGE_URL='' ac_unique_file="source/ref_gl/r_image.h" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_header_list= ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS ALLOCA LIBOBJS EGREP GREP USE_SYSTEM_LIBODE_FALSE USE_SYSTEM_LIBODE_TRUE WIN32_LIBS DEPS_LIBS DEPS_CFLAGS ODE_LIBS ODE_CFLAGS XXF86DGA_LIBS XXF86DGA_CFLAGS XXF86VM_LIBS XXF86VM_CFLAGS X11_LIBS X11_CFLAGS ZLIB_LIBS ZLIB_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC ax_pthread_config ALIENARENA_HOMEDIR icondir INSTALL_DOCS_FALSE INSTALL_DOCS_TRUE ALTERNATE_INSTALL_FALSE ALTERNATE_INSTALL_TRUE BUILD_CLIENT_FALSE BUILD_CLIENT_TRUE GL_LIBDIR XMKMF BUILD_UNIX_FALSE BUILD_UNIX_TRUE BUILD_WIN32_FALSE BUILD_WIN32_TRUE PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG RANLIB LN_S CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE ac_ct_CC CFLAGS CC am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CXX CPPFLAGS LDFLAGS CXXFLAGS CXX host_os host_vendor host_cpu host build_os build_vendor build_cpu build MAINT MAINTAINER_MODE_FALSE MAINTAINER_MODE_TRUE AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_maintainer_mode enable_dependency_tracking with_x enable_client enable_alternate_install enable_ansi_color with_system_libode enable_documents with_icondir with_zlib with_xf86vm with_xf86dga enable_build_status ' ac_precious_vars='build_alias host_alias target_alias CXX CXXFLAGS LDFLAGS LIBS CPPFLAGS CCC CC CFLAGS CPP PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR XMKMF GL_LIBDIR ALIENARENA_HOMEDIR ZLIB_CFLAGS ZLIB_LIBS X11_CFLAGS X11_LIBS XXF86VM_CFLAGS XXF86VM_LIBS XXF86DGA_CFLAGS XXF86DGA_LIBS ODE_CFLAGS ODE_LIBS DEPS_CFLAGS DEPS_LIBS' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures alienarena 7.66 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/alienarena] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names X features: --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of alienarena 7.66:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --disable-client build dedicated server only, not the client (default:no) --enable-alternate-install traditional single directory, in-place installation (default:no) --enable-ansi-color ANSI terminal color (default: no) --disable-documents Disable document installation (default: no) --disable-build-status hide the status message at the end of the configuration script (default:no) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-x use the X Window System --with(out)-system-libode use system-supplied libode (default:without) --with-icondir=DIR icon install directory (default:DATADIR/icons) --with(out)-zlib include Zlib compression support (default: check) --with(out)-xf86vm include XF86 VidMode support (default: check) --with(out)-xf86dga include XF86 DGA support (default: without) Some influential environment variables: CXX C++ compiler command CXXFLAGS C++ compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CC C compiler command CFLAGS C compiler flags CPP C preprocessor PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path XMKMF Path to xmkmf, Makefile generator for X Window System GL_LIBDIR directory containing libGL.dylib ALIENARENA_HOMEDIR User data and cfg subdirectory in $HOME ZLIB_CFLAGS C compiler flags for ZLIB, overriding pkg-config ZLIB_LIBS linker flags for ZLIB, overriding pkg-config X11_CFLAGS C compiler flags for X11, overriding pkg-config X11_LIBS linker flags for X11, overriding pkg-config XXF86VM_CFLAGS C compiler flags for XXF86VM, overriding pkg-config XXF86VM_LIBS linker flags for XXF86VM, overriding pkg-config XXF86DGA_CFLAGS C compiler flags for XXF86DGA, overriding pkg-config XXF86DGA_LIBS linker flags for XXF86DGA, overriding pkg-config ODE_CFLAGS C compiler flags for ODE, overriding pkg-config ODE_LIBS linker flags for ODE, overriding pkg-config DEPS_CFLAGS C compiler flags for DEPS, overriding pkg-config DEPS_LIBS linker flags for DEPS, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF alienarena configure 7.66 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## ------------------------------------ ## ## Report this to alienrace@comcast.net ## ## ------------------------------------ ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_c_find_intX_t LINENO BITS VAR # ----------------------------------- # Finds a signed integer type with width BITS, setting cache variable VAR # accordingly. ac_fn_c_find_intX_t () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5 $as_echo_n "checking for int$2_t... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" # Order is important - never check a type that is potentially smaller # than half of the expected target width. for ac_type in int$2_t 'int' 'long int' \ 'long long int' 'short int' 'signed char'; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default enum { N = $2 / 2 - 1 }; int main () { static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default enum { N = $2 / 2 - 1 }; int main () { static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1) < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else case $ac_type in #( int$2_t) : eval "$3=yes" ;; #( *) : eval "$3=\$ac_type" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if eval test \"x\$"$3"\" = x"no"; then : else break fi done fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_find_intX_t # ac_fn_c_find_uintX_t LINENO BITS VAR # ------------------------------------ # Finds an unsigned integer type with width BITS, setting cache variable VAR # accordingly. ac_fn_c_find_uintX_t () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5 $as_echo_n "checking for uint$2_t... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" # Order is important - never check a type that is potentially smaller # than half of the expected target width. for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \ 'unsigned long long int' 'unsigned short int' 'unsigned char'; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : case $ac_type in #( uint$2_t) : eval "$3=yes" ;; #( *) : eval "$3=\$ac_type" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if eval test \"x\$"$3"\" = x"no"; then : else break fi done fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_find_uintX_t # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by alienarena $as_me 7.66, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi as_fn_append ac_header_list " stdlib.h" as_fn_append ac_header_list " unistd.h" as_fn_append ac_header_list " sys/param.h" # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= for ac_dir in config "$srcdir"/config; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in config \"$srcdir\"/config" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. ac_config_headers="$ac_config_headers config/config.h" # The prefix default can be set in configure.ac (otherwise it is /usr/local) test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. Allows to override the makevar 'prefix' later test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' am__api_version='1.14' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='alienarena' VERSION='7.66' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=0;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 $as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } # Check whether --enable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then : enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval else USE_MAINTAINER_MODE=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 $as_echo "$USE_MAINTAINER_MODE" >&6; } if test $USE_MAINTAINER_MODE = yes; then MAINTAINER_MODE_TRUE= MAINTAINER_MODE_FALSE='#' else MAINTAINER_MODE_TRUE='#' MAINTAINER_MODE_FALSE= fi MAINT=$MAINTAINER_MODE_TRUE # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac # # Checks for programs. # ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 $as_echo_n "checking whether the C++ compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C++ compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 $as_echo_n "checking for C++ compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CXX" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CXX_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 $as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 $as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } PKG_CONFIG="" fi fi # # check host environment # cond_build_win32=no cond_build_unix=no unix_host=generic case ${host} in #( *-*-mingw* ) : cond_build_win32=yes ;; #( *-*-darwin*) : cond_build_unix=yes unix_host=darwin ;; #( *-*-linux* ) : cond_build_unix=yes unix_host=linux ;; #( *) : cond_build_unix=yes ;; esac if test "x${cond_build_win32}" = xyes ; then BUILD_WIN32_TRUE= BUILD_WIN32_FALSE='#' else BUILD_WIN32_TRUE='#' BUILD_WIN32_FALSE= fi if test "x${cond_build_unix}" = xyes ; then BUILD_UNIX_TRUE= BUILD_UNIX_FALSE='#' else BUILD_UNIX_TRUE='#' BUILD_UNIX_FALSE= fi # # Environment variable for specifying libGL.dylib path for Darwin when it # is not in the dlopen() search path. see dlopen (3) for Mac OS X. # Either export or in command line: GL_LIBDIR=/usr/Xll/lib, for example. # If this GL_LIBDIR is not given, use the shell variable x_libraries from # the AC_PATH_X macro (which may be empty) # gl_dlopen_path=default if test x"${unix_host}" = xdarwin ; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5 $as_echo_n "checking for X... " >&6; } # Check whether --with-x was given. if test "${with_x+set}" = set; then : withval=$with_x; fi # $have_x is `yes', `no', `disabled', or empty when we do not yet know. if test "x$with_x" = xno; then # The user explicitly disabled X. have_x=disabled else case $x_includes,$x_libraries in #( *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #( *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then : $as_echo_n "(cached) " >&6 else # One or both of the vars are not set, and there is no cached value. ac_x_includes=no ac_x_libraries=no rm -f -r conftest.dir if mkdir conftest.dir; then cd conftest.dir cat >Imakefile <<'_ACEOF' incroot: @echo incroot='${INCROOT}' usrlibdir: @echo usrlibdir='${USRLIBDIR}' libdir: @echo libdir='${LIBDIR}' _ACEOF if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. for ac_var in incroot usrlibdir libdir; do eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`" done # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. for ac_extension in a so sl dylib la dll; do if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" && test -f "$ac_im_libdir/libX11.$ac_extension"; then ac_im_usrlibdir=$ac_im_libdir; break fi done # Screen out bogus values from the imake configuration. They are # bogus both because they are the default anyway, and because # using them would break gcc on systems where it needs fixed includes. case $ac_im_incroot in /usr/include) ac_x_includes= ;; *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; esac case $ac_im_usrlibdir in /usr/lib | /usr/lib64 | /lib | /lib64) ;; *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; esac fi cd .. rm -f -r conftest.dir fi # Standard set of common directories for X headers. # Check X11 before X11Rn because it is often a symlink to the current release. ac_x_header_dirs=' /usr/X11/include /usr/X11R7/include /usr/X11R6/include /usr/X11R5/include /usr/X11R4/include /usr/include/X11 /usr/include/X11R7 /usr/include/X11R6 /usr/include/X11R5 /usr/include/X11R4 /usr/local/X11/include /usr/local/X11R7/include /usr/local/X11R6/include /usr/local/X11R5/include /usr/local/X11R4/include /usr/local/include/X11 /usr/local/include/X11R7 /usr/local/include/X11R6 /usr/local/include/X11R5 /usr/local/include/X11R4 /usr/X386/include /usr/x386/include /usr/XFree86/include/X11 /usr/include /usr/local/include /usr/unsupported/include /usr/athena/include /usr/local/x11r5/include /usr/lpp/Xamples/include /usr/openwin/include /usr/openwin/share/include' if test "$ac_x_includes" = no; then # Guess where to find include files, by looking for Xlib.h. # First, try using that file with no special directory specified. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # We can compile using X headers with no special include directory. ac_x_includes= else for ac_dir in $ac_x_header_dirs; do if test -r "$ac_dir/X11/Xlib.h"; then ac_x_includes=$ac_dir break fi done fi rm -f conftest.err conftest.i conftest.$ac_ext fi # $ac_x_includes = no if test "$ac_x_libraries" = no; then # Check for the libraries. # See if we find them without any special options. # Don't add to $LIBS permanently. ac_save_LIBS=$LIBS LIBS="-lX11 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { XrmInitialize () ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : LIBS=$ac_save_LIBS # We can link X programs with no special library path. ac_x_libraries= else LIBS=$ac_save_LIBS for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` do # Don't even attempt the hair of trying to link an X program! for ac_extension in a so sl dylib la dll; do if test -r "$ac_dir/libX11.$ac_extension"; then ac_x_libraries=$ac_dir break 2 fi done done fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi # $ac_x_libraries = no case $ac_x_includes,$ac_x_libraries in #( no,* | *,no | *\'*) # Didn't find X, or a directory has "'" in its name. ac_cv_have_x="have_x=no";; #( *) # Record where we found X for the cache. ac_cv_have_x="have_x=yes\ ac_x_includes='$ac_x_includes'\ ac_x_libraries='$ac_x_libraries'" esac fi ;; #( *) have_x=yes;; esac eval "$ac_cv_have_x" fi # $with_x != no if test "$have_x" != yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5 $as_echo "$have_x" >&6; } no_x=yes else # If each of the values was on the command line, it overrides each guess. test "x$x_includes" = xNONE && x_includes=$ac_x_includes test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries # Update the cache value to reflect the command line values. ac_cv_have_x="have_x=yes\ ac_x_includes='$x_includes'\ ac_x_libraries='$x_libraries'" { $as_echo "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5 $as_echo "libraries $x_libraries, headers $x_includes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GL_LIBDIR (location of libGL.dylib)" >&5 $as_echo_n "checking for GL_LIBDIR (location of libGL.dylib)... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${GL_LIBDIR}" >&5 $as_echo "${GL_LIBDIR}" >&6; } if test x"${GL_LIBDIR}" = x ; then : gl_dlopen_path=${x_libraries} else gl_dlopen_path=${GL_LIBDIR} fi fi # # Unix/Linux/Darwin dedicated server only build option # { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build the client" >&5 $as_echo_n "checking whether to build the client... " >&6; } if test -z "$BUILD_UNIX_TRUE"; then : # Check whether --enable-client was given. if test "${enable_client+set}" = set; then : enableval=$enable_client; build_client=${enableval} else build_client=yes fi else build_client=yes fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${build_client}" >&5 $as_echo "${build_client}" >&6; } if test "x${build_client}" = xyes ; then BUILD_CLIENT_TRUE= BUILD_CLIENT_FALSE='#' else BUILD_CLIENT_TRUE='#' BUILD_CLIENT_FALSE= fi # # Alternate Install. Install in the traditional single directory way. # Might be required for map making tools to work. Also, good when updating # from SVN regularly. Affects how Makefile sets DATADIR and does make-install. # for now, win32/mingw is always alternate install # if test -z "$BUILD_WIN32_TRUE"; then : alternate_install=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for traditional single directory, in place installation" >&5 $as_echo_n "checking for traditional single directory, in place installation... " >&6; } # Check whether --enable-alternate_install was given. if test "${enable_alternate_install+set}" = set; then : enableval=$enable_alternate_install; alternate_install=${enableval} else alternate_install=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${alternate_install}" >&5 $as_echo "${alternate_install}" >&6; } fi if test "x${alternate_install}" = xyes ; then ALTERNATE_INSTALL_TRUE= ALTERNATE_INSTALL_FALSE='#' else ALTERNATE_INSTALL_TRUE='#' ALTERNATE_INSTALL_FALSE= fi if test -z "$BUILD_UNIX_TRUE"; then : $as_echo "#define UNIX_VARIANT 1" >>confdefs.h case ${unix_host} in #( darwin ) : $as_echo "#define DARWIN_SPECIAL_CASE 1" >>confdefs.h $as_echo "#define _DARWIN_UNLIMITED_SELECT 1" >>confdefs.h ;; #( linux ) : $as_echo "#define LINUX_SPECIAL_CASE 1" >>confdefs.h ;; #( *) : generic $as_echo "#define GENERIC_UNIX 1" >>confdefs.h ;; esac # Check whether --enable-ansi-color was given. if test "${enable_ansi_color+set}" = set; then : enableval=$enable_ansi_color; ansi_color=${enableval} else ansi_color=no fi if test "x$ansi_color" = "xyes" ; then : $as_echo "#define ANSI_COLOR 1" >>confdefs.h fi fi if test -z "$BUILD_WIN32_TRUE"; then : $as_echo "#define WIN32_VARIANT 1" >>confdefs.h fi cat >>confdefs.h <<_ACEOF #define CPUSTRING "${host_cpu}" _ACEOF cat >>confdefs.h <<_ACEOF #define BUILDSTRING "${host_os}" _ACEOF # # ODE (Open Dynamic Engine) Library # # if no option or "--without-system-libode" is specified, use the recommended # integrated ODE. # if "--with-system-libode" is specified, check. look under BUILD_CLIENT # for details. # # Check whether --with-system-libode was given. if test "${with_system_libode+set}" = set; then : withval=$with_system_libode; system_ode=${withval} else system_ode=no fi # # Option for disabling installation of documents to allow for custom # documentation installation. Normally only useful for distro packagers. # Do not put in status message, because documents probably are being # installed in a custom way. # # Check whether --enable-documents was given. if test "${enable_documents+set}" = set; then : enableval=$enable_documents; no_docs=${documents} else no_docs=no fi if test "x${no_docs}" = "xno" ; then INSTALL_DOCS_TRUE= INSTALL_DOCS_FALSE='#' else INSTALL_DOCS_TRUE='#' INSTALL_DOCS_FALSE= fi # # Option for specifying where icon is installed. # # Check whether --with-icondir was given. if test "${with_icondir+set}" = set; then : withval=$with_icondir; with_icondir=${withval} else with_icondir=${datadir}/icons fi icondir=${with_icondir} # # User writable data and configuration subdirectory in $HOME # normally this is a hidden subdirectory # default is .codered. but distros modify this # can be overridden by environment variable, COR_GAME # # (These also are #defined in qcommon.h, but changing them is not a good idea # BASE_GAMEDATA "data1", GAME_GAMEDATA "arena", BOT_GAMEDATA "botinfo") # # AC_ARG_VAR creates ALIENARENA_HOMEDIR entry for ./configure --help # AC_DEFINE_UNQUOTED adds the setting to config.h, # overriding the define in qcommon.h # and # using the default, if not specified in the commandline # (Note: could also be specified in enviroment. That is not recommended # but is the reason for the package specific variable name.) # alienarena_homedir=".codered" if test "x${ALIENARENA_HOMEDIR}" = "x" ; then : ALIENARENA_HOMEDIR=${alienarena_homedir} else alienarena_homedir=${ALIENARENA_HOMEDIR} fi cat >>confdefs.h <<_ACEOF #define USER_GAMEDATA "${alienarena_homedir}" _ACEOF # # Checks for libraries. # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing acos" >&5 $as_echo_n "checking for library containing acos... " >&6; } if ${ac_cv_search_acos+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char acos (); int main () { return acos (); ; return 0; } _ACEOF for ac_lib in '' m; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_acos=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_acos+:} false; then : break fi done if ${ac_cv_search_acos+:} false; then : else ac_cv_search_acos=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_acos" >&5 $as_echo "$ac_cv_search_acos" >&6; } ac_res=$ac_cv_search_acos if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 $as_echo_n "checking for library containing dlopen... " >&6; } if ${ac_cv_search_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF for ac_lib in '' dl; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_dlopen=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_dlopen+:} false; then : break fi done if ${ac_cv_search_dlopen+:} false; then : else ac_cv_search_dlopen=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5 $as_echo "$ac_cv_search_dlopen" >&6; } ac_res=$ac_cv_search_dlopen if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5 $as_echo_n "checking for library containing clock_gettime... " >&6; } if ${ac_cv_search_clock_gettime+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char clock_gettime (); int main () { return clock_gettime (); ; return 0; } _ACEOF for ac_lib in '' rt; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_clock_gettime=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_clock_gettime+:} false; then : break fi done if ${ac_cv_search_clock_gettime+:} false; then : else ac_cv_search_clock_gettime=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5 $as_echo "$ac_cv_search_clock_gettime" >&6; } ac_res=$ac_cv_search_clock_gettime if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi if test -z "$BUILD_CLIENT_TRUE"; then : ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on True64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5 $as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_join (); int main () { return pthread_join (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ax_pthread_ok=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 $as_echo "$ax_pthread_ok" >&6; } if test x"$ax_pthread_ok" = xno; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) # -pthreads: Solaris/gcc # -mthreads: Mingw32/gcc, Lynx/gcc # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads too; # also defines -D_REENTRANT) # ... -mt is also the pthreads flag for HP/aCC # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case ${host_os} in solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (We need to link with -pthreads/-mt/ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather # a function called by this macro, so we could check for that, but # who knows whether they'll stub that too in a future libc.) So, # we'll just look for -pthreads and -lpthread first: ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" ;; darwin*) ax_pthread_flags="-pthread $ax_pthread_flags" ;; esac if test x"$ax_pthread_ok" = xno; then for flag in $ax_pthread_flags; do case $flag in none) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5 $as_echo_n "checking whether pthreads work without any flags... " >&6; } ;; -*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5 $as_echo_n "checking whether pthreads work with $flag... " >&6; } PTHREAD_CFLAGS="$flag" ;; pthread-config) # Extract the first word of "pthread-config", so it can be a program name with args. set dummy pthread-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ax_pthread_config+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ax_pthread_config"; then ac_cv_prog_ax_pthread_config="$ax_pthread_config" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ax_pthread_config="yes" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_ax_pthread_config" && ac_cv_prog_ax_pthread_config="no" fi fi ax_pthread_config=$ac_cv_prog_ax_pthread_config if test -n "$ax_pthread_config"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_config" >&5 $as_echo "$ax_pthread_config" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x"$ax_pthread_config" = xno; then continue; fi PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5 $as_echo_n "checking for the pthreads library -l$flag... " >&6; } PTHREAD_LIBS="-l$flag" ;; esac save_LIBS="$LIBS" save_CFLAGS="$CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include static void routine(void *a) { a = 0; } static void *start_routine(void *a) { return a; } int main () { pthread_t th; pthread_attr_t attr; pthread_create(&th, 0, start_routine, 0); pthread_join(th, 0); pthread_attr_init(&attr); pthread_cleanup_push(routine, 0); pthread_cleanup_pop(0) /* ; */ ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ax_pthread_ok=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 $as_echo "$ax_pthread_ok" >&6; } if test "x$ax_pthread_ok" = xyes; then break; fi PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$ax_pthread_ok" = xyes; then save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5 $as_echo_n "checking for joinable pthread attribute... " >&6; } attr_name=unknown for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int attr = $attr; return attr /* ; */ ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : attr_name=$attr; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done { $as_echo "$as_me:${as_lineno-$LINENO}: result: $attr_name" >&5 $as_echo "$attr_name" >&6; } if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then cat >>confdefs.h <<_ACEOF #define PTHREAD_CREATE_JOINABLE $attr_name _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5 $as_echo_n "checking if more special flags are required for pthreads... " >&6; } flag=no case ${host_os} in aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; osf* | hpux*) flag="-D_REENTRANT";; solaris*) if test "$GCC" = "yes"; then flag="-D_REENTRANT" else flag="-mt -D_REENTRANT" fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${flag}" >&5 $as_echo "${flag}" >&6; } if test "x$flag" != xno; then PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_PRIO_INHERIT" >&5 $as_echo_n "checking for PTHREAD_PRIO_INHERIT... " >&6; } if ${ax_cv_PTHREAD_PRIO_INHERIT+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int i = PTHREAD_PRIO_INHERIT; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ax_cv_PTHREAD_PRIO_INHERIT=yes else ax_cv_PTHREAD_PRIO_INHERIT=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_PRIO_INHERIT" >&5 $as_echo "$ax_cv_PTHREAD_PRIO_INHERIT" >&6; } if test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"; then : $as_echo "#define HAVE_PTHREAD_PRIO_INHERIT 1" >>confdefs.h fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" # More AIX lossage: must compile with xlc_r or cc_r if test x"$GCC" != xyes; then for ac_prog in xlc_r cc_r do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_PTHREAD_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PTHREAD_CC"; then ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_PTHREAD_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi PTHREAD_CC=$ac_cv_prog_PTHREAD_CC if test -n "$PTHREAD_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5 $as_echo "$PTHREAD_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$PTHREAD_CC" && break done test -n "$PTHREAD_CC" || PTHREAD_CC="${CC}" else PTHREAD_CC=$CC fi else PTHREAD_CC="$CC" fi # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test x"$ax_pthread_ok" = xyes; then $as_echo "#define HAVE_PTHREAD 1" >>confdefs.h : else ax_pthread_ok=no as_fn_error $? "\"Required pthreads support not found.\"" "$LINENO" 5 fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # # This might be a workaround for DSO missing pthread library error # if test "x$PTHREAD_LIBS" = "x" ; then : PTHREAD_LIBS="-pthread" fi # Check whether --with-zlib was given. if test "${with_zlib+set}" = set; then : withval=$with_zlib; else with_zlib=check fi have_zlib=no if test "x$with_zlib" != "xno" ; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ZLIB" >&5 $as_echo_n "checking for ZLIB... " >&6; } if test -n "$ZLIB_CFLAGS"; then pkg_cv_ZLIB_CFLAGS="$ZLIB_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib\""; } >&5 ($PKG_CONFIG --exists --print-errors "zlib") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_ZLIB_CFLAGS=`$PKG_CONFIG --cflags "zlib" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$ZLIB_LIBS"; then pkg_cv_ZLIB_LIBS="$ZLIB_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib\""; } >&5 ($PKG_CONFIG --exists --print-errors "zlib") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_ZLIB_LIBS=`$PKG_CONFIG --libs "zlib" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then ZLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "zlib" 2>&1` else ZLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "zlib" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$ZLIB_PKG_ERRORS" >&5 have_zlib=no if test "x$with_zlib" = "xyes" ; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "--with-zlib specified, but the library or headers could not be found See \`config.log' for more details" "$LINENO" 5; } fi elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } have_zlib=no if test "x$with_zlib" = "xyes" ; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "--with-zlib specified, but the library or headers could not be found See \`config.log' for more details" "$LINENO" 5; } fi else ZLIB_CFLAGS=$pkg_cv_ZLIB_CFLAGS ZLIB_LIBS=$pkg_cv_ZLIB_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_zlib=yes $as_echo "#define HAVE_ZLIB 1" >>confdefs.h fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing jpeg_read_header" >&5 $as_echo_n "checking for library containing jpeg_read_header... " >&6; } if ${ac_cv_search_jpeg_read_header+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char jpeg_read_header (); int main () { return jpeg_read_header (); ; return 0; } _ACEOF for ac_lib in '' jpeg; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_jpeg_read_header=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_jpeg_read_header+:} false; then : break fi done if ${ac_cv_search_jpeg_read_header+:} false; then : else ac_cv_search_jpeg_read_header=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_jpeg_read_header" >&5 $as_echo "$ac_cv_search_jpeg_read_header" >&6; } ac_res=$ac_cv_search_jpeg_read_header if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" else as_fn_error $? "\"Required jpeg library not found.\"" "$LINENO" 5 fi if test -z "$BUILD_UNIX_TRUE"; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for X11" >&5 $as_echo_n "checking for X11... " >&6; } if test -n "$X11_CFLAGS"; then pkg_cv_X11_CFLAGS="$X11_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"x11\""; } >&5 ($PKG_CONFIG --exists --print-errors "x11") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_X11_CFLAGS=`$PKG_CONFIG --cflags "x11" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$X11_LIBS"; then pkg_cv_X11_LIBS="$X11_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"x11\""; } >&5 ($PKG_CONFIG --exists --print-errors "x11") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_X11_LIBS=`$PKG_CONFIG --libs "x11" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then X11_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "x11" 2>&1` else X11_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "x11" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$X11_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (x11) were not met: $X11_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables X11_CFLAGS and X11_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables X11_CFLAGS and X11_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else X11_CFLAGS=$pkg_cv_X11_CFLAGS X11_LIBS=$pkg_cv_X11_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi # Check whether --with-xf86vm was given. if test "${with_xf86vm+set}" = set; then : withval=$with_xf86vm; else with_xf86vm=check fi have_Xxf86vm=no if test "x$with_xf86vm" != "xno" ; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XXF86VM" >&5 $as_echo_n "checking for XXF86VM... " >&6; } if test -n "$XXF86VM_CFLAGS"; then pkg_cv_XXF86VM_CFLAGS="$XXF86VM_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"xxf86vm\""; } >&5 ($PKG_CONFIG --exists --print-errors "xxf86vm") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_XXF86VM_CFLAGS=`$PKG_CONFIG --cflags "xxf86vm" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$XXF86VM_LIBS"; then pkg_cv_XXF86VM_LIBS="$XXF86VM_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"xxf86vm\""; } >&5 ($PKG_CONFIG --exists --print-errors "xxf86vm") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_XXF86VM_LIBS=`$PKG_CONFIG --libs "xxf86vm" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then XXF86VM_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "xxf86vm" 2>&1` else XXF86VM_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "xxf86vm" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$XXF86VM_PKG_ERRORS" >&5 have_Xxf86vm=no if test "x$with_xf86vm" = "xyes" ; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "--with-xf86vm specified, but the library or headers could not be found See \`config.log' for more details" "$LINENO" 5; } fi elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } have_Xxf86vm=no if test "x$with_xf86vm" = "xyes" ; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "--with-xf86vm specified, but the library or headers could not be found See \`config.log' for more details" "$LINENO" 5; } fi else XXF86VM_CFLAGS=$pkg_cv_XXF86VM_CFLAGS XXF86VM_LIBS=$pkg_cv_XXF86VM_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_Xxf86vm=yes $as_echo "#define HAVE_XXF86VM 1" >>confdefs.h fi fi # Check whether --with-xf86dga was given. if test "${with_xf86dga+set}" = set; then : withval=$with_xf86dga; else with_xf86dga=no fi have_Xxf86dga=no if test "x$with_xf86dga" != "xno" ; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XXF86DGA" >&5 $as_echo_n "checking for XXF86DGA... " >&6; } if test -n "$XXF86DGA_CFLAGS"; then pkg_cv_XXF86DGA_CFLAGS="$XXF86DGA_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"xxf86dga\""; } >&5 ($PKG_CONFIG --exists --print-errors "xxf86dga") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_XXF86DGA_CFLAGS=`$PKG_CONFIG --cflags "xxf86dga" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$XXF86DGA_LIBS"; then pkg_cv_XXF86DGA_LIBS="$XXF86DGA_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"xxf86dga\""; } >&5 ($PKG_CONFIG --exists --print-errors "xxf86dga") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_XXF86DGA_LIBS=`$PKG_CONFIG --libs "xxf86dga" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then XXF86DGA_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "xxf86dga" 2>&1` else XXF86DGA_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "xxf86dga" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$XXF86DGA_PKG_ERRORS" >&5 have_Xxf86dga=no if test "x$with_xf86dga" = "xyes" ; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "--with-xf86dga specified, but the library or headers could not be found See \`config.log' for more details" "$LINENO" 5; } fi elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } have_Xxf86dga=no if test "x$with_xf86dga" = "xyes" ; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "--with-xf86dga specified, but the library or headers could not be found See \`config.log' for more details" "$LINENO" 5; } fi else XXF86DGA_CFLAGS=$pkg_cv_XXF86DGA_CFLAGS XXF86DGA_LIBS=$pkg_cv_XXF86DGA_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_Xxf86dga=yes $as_echo "#define HAVE_XXF86DGA 1" >>confdefs.h for ac_header in X11/extensions/Xxf86dga.h do : ac_fn_c_check_header_compile "$LINENO" "X11/extensions/Xxf86dga.h" "ac_cv_header_X11_extensions_Xxf86dga_h" " #include #include " if test "x$ac_cv_header_X11_extensions_Xxf86dga_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_X11_EXTENSIONS_XXF86DGA_H 1 _ACEOF fi done fi fi fi # # if option to use system libode, rather than integrated ODE, is selected # use pkg-config to get cflags and libs. do not default to # integrated ODE on failure, as that is probably not what is wanted. # # for recommended integrated ODE build, setup client dependencies, # and configuration. Double precision math is "hardwired" here and # is not considered to be a user-specifiable option. # if test "x$system_ode" = "xyes" ; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ODE" >&5 $as_echo_n "checking for ODE... " >&6; } if test -n "$ODE_CFLAGS"; then pkg_cv_ODE_CFLAGS="$ODE_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ode\""; } >&5 ($PKG_CONFIG --exists --print-errors "ode") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_ODE_CFLAGS=`$PKG_CONFIG --cflags "ode" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$ODE_LIBS"; then pkg_cv_ODE_LIBS="$ODE_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ode\""; } >&5 ($PKG_CONFIG --exists --print-errors "ode") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_ODE_LIBS=`$PKG_CONFIG --libs "ode" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then ODE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ode" 2>&1` else ODE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ode" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$ODE_PKG_ERRORS" >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "--with-system-libode specified, but the library or headers could not be found See \`config.log' for more details" "$LINENO" 5; } elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "--with-system-libode specified, but the library or headers could not be found See \`config.log' for more details" "$LINENO" 5; } else ODE_CFLAGS=$pkg_cv_ODE_CFLAGS ODE_LIBS=$pkg_cv_ODE_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi else ODE_CFLAGS=-DdDOUBLE $as_echo "#define dEpsilon DBL_EPSILON" >>confdefs.h fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DEPS" >&5 $as_echo_n "checking for DEPS... " >&6; } if test -n "$DEPS_CFLAGS"; then pkg_cv_DEPS_CFLAGS="$DEPS_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcurl ogg vorbis vorbisfile freetype2\""; } >&5 ($PKG_CONFIG --exists --print-errors "libcurl ogg vorbis vorbisfile freetype2") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_DEPS_CFLAGS=`$PKG_CONFIG --cflags "libcurl ogg vorbis vorbisfile freetype2" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$DEPS_LIBS"; then pkg_cv_DEPS_LIBS="$DEPS_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcurl ogg vorbis vorbisfile freetype2\""; } >&5 ($PKG_CONFIG --exists --print-errors "libcurl ogg vorbis vorbisfile freetype2") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_DEPS_LIBS=`$PKG_CONFIG --libs "libcurl ogg vorbis vorbisfile freetype2" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then DEPS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libcurl ogg vorbis vorbisfile freetype2" 2>&1` else DEPS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libcurl ogg vorbis vorbisfile freetype2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$DEPS_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (libcurl ogg vorbis vorbisfile freetype2) were not met: $DEPS_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables DEPS_CFLAGS and DEPS_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables DEPS_CFLAGS and DEPS_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else DEPS_CFLAGS=$pkg_cv_DEPS_CFLAGS DEPS_LIBS=$pkg_cv_DEPS_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi win32_syslibs="" if test -z "$BUILD_WIN32_TRUE"; then : win32_syslibs="-lmingw32 -lwinmm -lwsock32 -lws2_32 -lgdi32 -luser32" fi WIN32_LIBS=$win32_syslibs fi if test "x$system_ode" = "xyes" ; then USE_SYSTEM_LIBODE_TRUE= USE_SYSTEM_LIBODE_FALSE='#' else USE_SYSTEM_LIBODE_TRUE='#' USE_SYSTEM_LIBODE_FALSE= fi # # Checks for header files # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in inttypes.h stdint.h stddef.h stdlib.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in float.h limits.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in arpa/inet.h netinet/in.h sys/ioctl.h sys/socket.h netdb.h termios.h sys/select.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dlfcn.h fcntl.h malloc.h string.h sys/param.h sys/stat.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in time.h sys/time.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in windows.h winsock.h winsock2.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done if test -z "$BUILD_CLIENT_TRUE"; then : jpeglib_h_found=no for ac_header in jpeglib.h jpeg/jpeglib.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF jpeglib_h_found=yes fi done if test "x${jpeglib_h_found}" = xno ; then : as_fn_error $? "\"Required JPEG header file not found.\"" "$LINENO" 5 fi openal_h_found=no for ac_header in AL/al.h al.h OpenAL/al.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF openal_h_found=yes fi done if test "x${openal_h_found}" = xno ; then : as_fn_error $? "\"Required OpenAL header file not found.\"" "$LINENO" 5 fi openalc_h_found=no for ac_header in AL/alc.h alc.h OpenAL/alc.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF openalc_h_found=yes fi done if test "x${openalc_h_found}" = xno ; then : as_fn_error $? "\"Required OpenAL header file not found.\"" "$LINENO" 5 fi for ac_header in GL/gl.h do : ac_fn_c_check_header_mongrel "$LINENO" "GL/gl.h" "ac_cv_header_GL_gl_h" "$ac_includes_default" if test "x$ac_cv_header_GL_gl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GL_GL_H 1 _ACEOF else as_fn_error $? "\"Required OpenGL header files not found.\"" "$LINENO" 5 fi done if test -z "$BUILD_UNIX_TRUE"; then : for ac_header in GL/glx.h do : ac_fn_c_check_header_mongrel "$LINENO" "GL/glx.h" "ac_cv_header_GL_glx_h" "$ac_includes_default" if test "x$ac_cv_header_GL_glx_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GL_GLX_H 1 _ACEOF else as_fn_error $? "\"Required OpenGL header files not found.\"" "$LINENO" 5 fi done fi fi # # Checks for typedefs, structures, and compiler characteristics. # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 $as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } if ${ac_cv_header_stdbool_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifndef bool "error: bool is not defined" #endif #ifndef false "error: false is not defined" #endif #if false "error: false is not 0" #endif #ifndef true "error: true is not defined" #endif #if true != 1 "error: true is not 1" #endif #ifndef __bool_true_false_are_defined "error: __bool_true_false_are_defined is not defined" #endif struct s { _Bool s: 1; _Bool t; } s; char a[true == 1 ? 1 : -1]; char b[false == 0 ? 1 : -1]; char c[__bool_true_false_are_defined == 1 ? 1 : -1]; char d[(bool) 0.5 == true ? 1 : -1]; /* See body of main program for 'e'. */ char f[(_Bool) 0.0 == false ? 1 : -1]; char g[true]; char h[sizeof (_Bool)]; char i[sizeof s.t]; enum { j = false, k = true, l = false * true, m = true * 256 }; /* The following fails for HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ _Bool n[m]; char o[sizeof n == m * sizeof n[0] ? 1 : -1]; char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; /* Catch a bug in an HP-UX C compiler. See http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html */ _Bool q = true; _Bool *pq = &q; int main () { bool e = &s; *pq |= q; *pq |= ! q; /* Refer to every declared value, to avoid compiler optimizations. */ return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + !m + !n + !o + !p + !q + !pq); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdbool_h=yes else ac_cv_header_stdbool_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5 $as_echo "$ac_cv_header_stdbool_h" >&6; } ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" if test "x$ac_cv_type__Bool" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE__BOOL 1 _ACEOF fi if test $ac_cv_header_stdbool_h = yes; then $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if ${ac_cv_c_inline+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_inline=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 $as_echo "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5 $as_echo_n "checking for uid_t in sys/types.h... " >&6; } if ${ac_cv_type_uid_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "uid_t" >/dev/null 2>&1; then : ac_cv_type_uid_t=yes else ac_cv_type_uid_t=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5 $as_echo "$ac_cv_type_uid_t" >&6; } if test $ac_cv_type_uid_t = no; then $as_echo "#define uid_t int" >>confdefs.h $as_echo "#define gid_t int" >>confdefs.h fi ac_fn_c_find_intX_t "$LINENO" "32" "ac_cv_c_int32_t" case $ac_cv_c_int32_t in #( no|yes) ;; #( *) cat >>confdefs.h <<_ACEOF #define int32_t $ac_cv_c_int32_t _ACEOF ;; esac ac_fn_c_find_intX_t "$LINENO" "64" "ac_cv_c_int64_t" case $ac_cv_c_int64_t in #( no|yes) ;; #( *) cat >>confdefs.h <<_ACEOF #define int64_t $ac_cv_c_int64_t _ACEOF ;; esac ac_fn_c_find_uintX_t "$LINENO" "64" "ac_cv_c_uint64_t" case $ac_cv_c_uint64_t in #( no|yes) ;; #( *) $as_echo "#define _UINT64_T 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define uint64_t $ac_cv_c_uint64_t _ACEOF ;; esac ac_fn_c_check_type "$LINENO" "ptrdiff_t" "ac_cv_type_ptrdiff_t" "$ac_includes_default" if test "x$ac_cv_type_ptrdiff_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PTRDIFF_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default" if test "x$ac_cv_type_uintptr_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UINTPTR_T 1 _ACEOF fi # # Checks for library functions. # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for error_at_line" >&5 $as_echo_n "checking for error_at_line... " >&6; } if ${ac_cv_lib_error_at_line+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { error_at_line (0, 0, "", 0, "an error occurred"); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_error_at_line=yes else ac_cv_lib_error_at_line=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_error_at_line" >&5 $as_echo "$ac_cv_lib_error_at_line" >&6; } if test $ac_cv_lib_error_at_line = no; then case " $LIBOBJS " in *" error.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS error.$ac_objext" ;; esac fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 $as_echo_n "checking for working alloca.h... " >&6; } if ${ac_cv_working_alloca_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char *p = (char *) alloca (2 * sizeof (int)); if (p) return 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_working_alloca_h=yes else ac_cv_working_alloca_h=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 $as_echo "$ac_cv_working_alloca_h" >&6; } if test $ac_cv_working_alloca_h = yes; then $as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 $as_echo_n "checking for alloca... " >&6; } if ${ac_cv_func_alloca_works+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __GNUC__ # define alloca __builtin_alloca #else # ifdef _MSC_VER # include # define alloca _alloca # else # ifdef HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ void *alloca (size_t); # endif # endif # endif # endif #endif int main () { char *p = (char *) alloca (1); if (p) return 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_func_alloca_works=yes else ac_cv_func_alloca_works=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 $as_echo "$ac_cv_func_alloca_works" >&6; } if test $ac_cv_func_alloca_works = yes; then $as_echo "#define HAVE_ALLOCA 1" >>confdefs.h else # The SVR3 libPW and SVR4 libucb both contain incompatible functions # that cause trouble. Some versions do not even contain alloca or # contain a buggy version. If you still want to use their alloca, # use ar to extract alloca.o from them instead of compiling alloca.c. ALLOCA=\${LIBOBJDIR}alloca.$ac_objext $as_echo "#define C_ALLOCA 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5 $as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } if ${ac_cv_os_cray+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined CRAY && ! defined CRAY2 webecray #else wenotbecray #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "webecray" >/dev/null 2>&1; then : ac_cv_os_cray=yes else ac_cv_os_cray=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5 $as_echo "$ac_cv_os_cray" >&6; } if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define CRAY_STACKSEG_END $ac_func _ACEOF break fi done fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 $as_echo_n "checking stack direction for C alloca... " >&6; } if ${ac_cv_c_stack_direction+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_c_stack_direction=0 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int find_stack_direction (int *addr, int depth) { int dir, dummy = 0; if (! addr) addr = &dummy; *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; dir = depth ? find_stack_direction (addr, depth - 1) : 0; return dir + dummy; } int main (int argc, char **argv) { return find_stack_direction (0, argc + !argv + 20) < 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_stack_direction=1 else ac_cv_c_stack_direction=-1 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 $as_echo "$ac_cv_c_stack_direction" >&6; } cat >>confdefs.h <<_ACEOF #define STACK_DIRECTION $ac_cv_c_stack_direction _ACEOF fi for ac_header in stdlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" if test "x$ac_cv_header_stdlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDLIB_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5 $as_echo_n "checking for GNU libc compatible malloc... " >&6; } if ${ac_cv_func_malloc_0_nonnull+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_malloc_0_nonnull=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined STDC_HEADERS || defined HAVE_STDLIB_H # include #else char *malloc (); #endif int main () { return ! malloc (0); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_malloc_0_nonnull=yes else ac_cv_func_malloc_0_nonnull=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_malloc_0_nonnull" >&5 $as_echo "$ac_cv_func_malloc_0_nonnull" >&6; } if test $ac_cv_func_malloc_0_nonnull = yes; then : $as_echo "#define HAVE_MALLOC 1" >>confdefs.h else $as_echo "#define HAVE_MALLOC 0" >>confdefs.h case " $LIBOBJS " in *" malloc.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS malloc.$ac_objext" ;; esac $as_echo "#define malloc rpl_malloc" >>confdefs.h fi for ac_header in $ac_header_list do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in getpagesize do : ac_fn_c_check_func "$LINENO" "getpagesize" "ac_cv_func_getpagesize" if test "x$ac_cv_func_getpagesize" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETPAGESIZE 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working mmap" >&5 $as_echo_n "checking for working mmap... " >&6; } if ${ac_cv_func_mmap_fixed_mapped+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_mmap_fixed_mapped=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default /* malloc might have been renamed as rpl_malloc. */ #undef malloc /* Thanks to Mike Haertel and Jim Avera for this test. Here is a matrix of mmap possibilities: mmap private not fixed mmap private fixed at somewhere currently unmapped mmap private fixed at somewhere already mapped mmap shared not fixed mmap shared fixed at somewhere currently unmapped mmap shared fixed at somewhere already mapped For private mappings, we should verify that changes cannot be read() back from the file, nor mmap's back from the file at a different address. (There have been systems where private was not correctly implemented like the infamous i386 svr4.0, and systems where the VM page cache was not coherent with the file system buffer cache like early versions of FreeBSD and possibly contemporary NetBSD.) For shared mappings, we should conversely verify that changes get propagated back to all the places they're supposed to be. Grep wants private fixed already mapped. The main things grep needs to know about mmap are: * does it exist and is it safe to write into the mmap'd area * how to use it (BSD variants) */ #include #include #if !defined STDC_HEADERS && !defined HAVE_STDLIB_H char *malloc (); #endif /* This mess was copied from the GNU getpagesize.h. */ #ifndef HAVE_GETPAGESIZE # ifdef _SC_PAGESIZE # define getpagesize() sysconf(_SC_PAGESIZE) # else /* no _SC_PAGESIZE */ # ifdef HAVE_SYS_PARAM_H # include # ifdef EXEC_PAGESIZE # define getpagesize() EXEC_PAGESIZE # else /* no EXEC_PAGESIZE */ # ifdef NBPG # define getpagesize() NBPG * CLSIZE # ifndef CLSIZE # define CLSIZE 1 # endif /* no CLSIZE */ # else /* no NBPG */ # ifdef NBPC # define getpagesize() NBPC # else /* no NBPC */ # ifdef PAGESIZE # define getpagesize() PAGESIZE # endif /* PAGESIZE */ # endif /* no NBPC */ # endif /* no NBPG */ # endif /* no EXEC_PAGESIZE */ # else /* no HAVE_SYS_PARAM_H */ # define getpagesize() 8192 /* punt totally */ # endif /* no HAVE_SYS_PARAM_H */ # endif /* no _SC_PAGESIZE */ #endif /* no HAVE_GETPAGESIZE */ int main () { char *data, *data2, *data3; const char *cdata2; int i, pagesize; int fd, fd2; pagesize = getpagesize (); /* First, make a file with some known garbage in it. */ data = (char *) malloc (pagesize); if (!data) return 1; for (i = 0; i < pagesize; ++i) *(data + i) = rand (); umask (0); fd = creat ("conftest.mmap", 0600); if (fd < 0) return 2; if (write (fd, data, pagesize) != pagesize) return 3; close (fd); /* Next, check that the tail of a page is zero-filled. File must have non-zero length, otherwise we risk SIGBUS for entire page. */ fd2 = open ("conftest.txt", O_RDWR | O_CREAT | O_TRUNC, 0600); if (fd2 < 0) return 4; cdata2 = ""; if (write (fd2, cdata2, 1) != 1) return 5; data2 = (char *) mmap (0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd2, 0L); if (data2 == MAP_FAILED) return 6; for (i = 0; i < pagesize; ++i) if (*(data2 + i)) return 7; close (fd2); if (munmap (data2, pagesize)) return 8; /* Next, try to mmap the file at a fixed address which already has something else allocated at it. If we can, also make sure that we see the same garbage. */ fd = open ("conftest.mmap", O_RDWR); if (fd < 0) return 9; if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0L)) return 10; for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data2 + i)) return 11; /* Finally, make sure that changes to the mapped area do not percolate back to the file as seen by read(). (This is a bug on some variants of i386 svr4.0.) */ for (i = 0; i < pagesize; ++i) *(data2 + i) = *(data2 + i) + 1; data3 = (char *) malloc (pagesize); if (!data3) return 12; if (read (fd, data3, pagesize) != pagesize) return 13; for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data3 + i)) return 14; close (fd); return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_mmap_fixed_mapped=yes else ac_cv_func_mmap_fixed_mapped=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_mmap_fixed_mapped" >&5 $as_echo "$ac_cv_func_mmap_fixed_mapped" >&6; } if test $ac_cv_func_mmap_fixed_mapped = yes; then $as_echo "#define HAVE_MMAP 1" >>confdefs.h fi rm -f conftest.mmap conftest.txt for ac_header in stdlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" if test "x$ac_cv_header_stdlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDLIB_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible realloc" >&5 $as_echo_n "checking for GNU libc compatible realloc... " >&6; } if ${ac_cv_func_realloc_0_nonnull+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_realloc_0_nonnull=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined STDC_HEADERS || defined HAVE_STDLIB_H # include #else char *realloc (); #endif int main () { return ! realloc (0, 0); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_realloc_0_nonnull=yes else ac_cv_func_realloc_0_nonnull=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_realloc_0_nonnull" >&5 $as_echo "$ac_cv_func_realloc_0_nonnull" >&6; } if test $ac_cv_func_realloc_0_nonnull = yes; then : $as_echo "#define HAVE_REALLOC 1" >>confdefs.h else $as_echo "#define HAVE_REALLOC 0" >>confdefs.h case " $LIBOBJS " in *" realloc.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS realloc.$ac_objext" ;; esac $as_echo "#define realloc rpl_realloc" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for obstacks" >&5 $as_echo_n "checking for obstacks... " >&6; } if ${ac_cv_func_obstack+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default #include "obstack.h" int main () { struct obstack mem; #define obstack_chunk_alloc malloc #define obstack_chunk_free free obstack_init (&mem); obstack_free (&mem, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_func_obstack=yes else ac_cv_func_obstack=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_obstack" >&5 $as_echo "$ac_cv_func_obstack" >&6; } if test $ac_cv_func_obstack = yes; then $as_echo "#define HAVE_OBSTACK 1" >>confdefs.h else case " $LIBOBJS " in *" obstack.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS obstack.$ac_objext" ;; esac fi for ac_func in closesocket socket gethostbyname select do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in pthread_create _begin_thread do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in strchr strerror strrchr strstr strlcpy isascii do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in strcasecmp strncasecmp do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in strdup _strdup stricmp _stricmp strnicmp _strnicmp do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in filelength stat fstat getcwd _getcwd unlink _unlink mkdir _mkdir do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in pow sqrt floor do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in memmove memset munmap mremap do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in gettimeofday clock_gettime do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in putenv _putenv do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done if test -z "$BUILD_UNIX_TRUE"; then : case ${unix_host} in #( darwin ) : if test x"${gl_dlopen_path}" = xdefault ; then : $as_echo "#define OPENGL_DRIVER \"libGL.dylib\"" >>confdefs.h else cat >>confdefs.h <<_ACEOF #define OPENGL_DRIVER "${gl_dlopen_path}/libGL.dylib" _ACEOF fi $as_echo "#define OPENAL_DRIVER \"/System/Library/Frameworks/OpenAL.framework/OpenAL\"" >>confdefs.h ;; #( *) : $as_echo "#define OPENGL_DRIVER \"libGL.so.1\"" >>confdefs.h $as_echo "#define OPENAL_DRIVER \"libopenal.so.1\"" >>confdefs.h ;; esac fi if test -z "$BUILD_WIN32_TRUE"; then : $as_echo "#define OPENGL_DRIVER \"opengl32\"" >>confdefs.h $as_echo "#define OPENAL_DRIVER \"OpenAL32.dll\"" >>confdefs.h fi # # required gcc/g++ options. # fast-math because strict adherence to IEEE standard is not needed. # no-strict-aliasing because strict aliasing is not adhered to in places. # if ${CFLAGS+:} false; then : case " $CFLAGS " in *" -ffast-math "*) { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains -ffast-math"; } >&5 (: CFLAGS already contains -ffast-math) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } ;; *) { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS -ffast-math\""; } >&5 (: CFLAGS="$CFLAGS -ffast-math") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } CFLAGS="$CFLAGS -ffast-math" ;; esac else CFLAGS="-ffast-math" fi if ${CXXFLAGS+:} false; then : case " $CXXFLAGS " in *" -ffast-math "*) { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains -ffast-math"; } >&5 (: CXXFLAGS already contains -ffast-math) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } ;; *) { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS -ffast-math\""; } >&5 (: CXXFLAGS="$CXXFLAGS -ffast-math") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } CXXFLAGS="$CXXFLAGS -ffast-math" ;; esac else CXXFLAGS="-ffast-math" fi if ${CFLAGS+:} false; then : case " $CFLAGS " in *" -fno-strict-aliasing "*) { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains -fno-strict-aliasing"; } >&5 (: CFLAGS already contains -fno-strict-aliasing) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } ;; *) { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS -fno-strict-aliasing\""; } >&5 (: CFLAGS="$CFLAGS -fno-strict-aliasing") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } CFLAGS="$CFLAGS -fno-strict-aliasing" ;; esac else CFLAGS="-fno-strict-aliasing" fi if ${CXXFLAGS+:} false; then : case " $CXXFLAGS " in *" -fno-strict-aliasing "*) { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains -fno-strict-aliasing"; } >&5 (: CXXFLAGS already contains -fno-strict-aliasing) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } ;; *) { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS -fno-strict-aliasing\""; } >&5 (: CXXFLAGS="$CXXFLAGS -fno-strict-aliasing") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } CXXFLAGS="$CXXFLAGS -fno-strict-aliasing" ;; esac else CXXFLAGS="-fno-strict-aliasing" fi # outputs ac_config_files="$ac_config_files Makefile source/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_WIN32_TRUE}" && test -z "${BUILD_WIN32_FALSE}"; then as_fn_error $? "conditional \"BUILD_WIN32\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_UNIX_TRUE}" && test -z "${BUILD_UNIX_FALSE}"; then as_fn_error $? "conditional \"BUILD_UNIX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_CLIENT_TRUE}" && test -z "${BUILD_CLIENT_FALSE}"; then as_fn_error $? "conditional \"BUILD_CLIENT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ALTERNATE_INSTALL_TRUE}" && test -z "${ALTERNATE_INSTALL_FALSE}"; then as_fn_error $? "conditional \"ALTERNATE_INSTALL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${INSTALL_DOCS_TRUE}" && test -z "${INSTALL_DOCS_FALSE}"; then as_fn_error $? "conditional \"INSTALL_DOCS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${USE_SYSTEM_LIBODE_TRUE}" && test -z "${USE_SYSTEM_LIBODE_FALSE}"; then as_fn_error $? "conditional \"USE_SYSTEM_LIBODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by alienarena $as_me 7.66, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ alienarena config.status 7.66 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config/config.h") CONFIG_HEADERS="$CONFIG_HEADERS config/config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "source/Makefile") CONFIG_FILES="$CONFIG_FILES source/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi # Check whether --enable-build-status was given. if test "${enable_build_status+set}" = set; then : enableval=$enable_build_status; hide_status=${enableval} else hide_status=no fi if test "x$hide_status" = "xno"; then : $as_echo $as_echo "-------------------------------------------" $as_echo "Package: ${PACKAGE_NAME} Version: ${PACKAGE_VERSION}" $as_echo " OS: .................... ${host_os}" $as_echo " CPU: ................... ${host_cpu}" if test -z "$BUILD_WIN32_TRUE"; then : else if test "x$build_client" = "xyes" ; then : dedicated_only=no else dedicated_only=yes fi $as_echo " Dedicated Only: ........ ${dedicated_only}" $as_echo " Server terminal color: . ${ansi_color}" fi $as_echo " Alternate install: ..... ${alternate_install}" if test -z "$ALTERNATE_INSTALL_TRUE"; then : if test -z "$BUILD_CLIENT_TRUE"; then : $as_echo " System ODE library ..... ${system_ode}" $as_echo " XF86 DGA support: ...... ${have_Xxf86dga}" $as_echo " XF86 VidMode support: .. ${have_Xxf86vm}" $as_echo " Zlib support: .......... ${have_zlib}" fi $as_echo " Shared Data ............ ${srcdir}" $as_echo " note: with alternate install, data is located relative to CWD." $as_echo " User Home R/W Data ..... ${alienarena_homedir}" else game_data=${datadir}/${PACKAGE_NAME} game_data_a=`eval "echo ${game_data}"` game_data=`eval "echo ${game_data_a}"` if test -z "$BUILD_CLIENT_TRUE"; then : $as_echo " System ODE library ..... ${system_ode}" $as_echo " XF86 DGA support: ...... ${have_Xxf86dga}" $as_echo " XF86 VidMode support: .. ${have_Xxf86vm}" $as_echo " Zlib support: .......... ${have_zlib}" if test x"${unix_host}" = xdarwin ; then : $as_echo " GL_LIBDIR: ............. ${gl_dlopen_path}" fi fi $as_echo " Prefix ................. ${prefix}" $as_echo " Shared RO Data: ........ ${game_data}" $as_echo " User Home R/W Data ..... ${alienarena_homedir}" fi $as_echo if test -z "$ALTERNATE_INSTALL_TRUE"; then : $as_echo "Run \"make\" to build, then \"make install-alternate\" to install." else $as_echo "Run \"make\" to build, then \"sudo make install\" to install." fi $as_echo $as_echo "Advanced Build Information:" $as_echo " See README for information and recommendations." $as_echo " Run ./configure --help for configure options." $as_echo " Compiler options:" $as_echo " CFLAGS:.... ${CFLAGS}" $as_echo " CXXFLAGS:.. ${CXXFLAGS}" $as_echo $as_echo "--------------------------------------------" fi alien-arena-7.66+dfsg/README0000600000175000017500000003711612207136704014511 0ustar zero79zero79 Alien Arena Version 7.66 1. Scope This document includes information about the GNU-Linux/Unix version of Alien Arena. Custom options and other information specific to Alien Arena are included here. For general information, licensing, and contributers, see the README.txt and license.txt documents (in the docs/ subdirectory in the distribution archive). For generic information about installation, see the GNU INSTALL document. 2. Version 7.66 - For Players The performance of Alien Arena 7.66 is much better that previous versions. Recent desktop and notebook computers with 3D acceleration for OpenGL will perform well. Use the Video Settings menu to override the automatically selected performance level. Alien Arena installation alternatives: * Your distribution's package manager. * PlayDeb or Desura distribution service. PlayDeb is at http://www.playdeb.net/. Desura is at http://www.desura.com/. * Build from source. See the "Installation from Distribution Archive" section below. For more detail see these sections * Help and Support * Configuration and Troubleshooting * Network Information * Running the Program 3. Version 7.66 - For Packagers * The incompatibility with ODE 0.12 has been corrected. The configure option to use the system libode is --with-system-libode. If the system libode causes problems with ragdoll animation, configure the program to use the integrated libode. * There is now direct dependency on zlib. The configure option --with-zlib should be used. * The configure.ac status report has more information. * Some little used options have been removed from configure.ac * The documentation installation override configure option should work now. The configure option is --disable-documents. * --with-xf86vm is the default. * --without-xf86dga is the default. * The Autotools build used autoconf 2.68, and automake 1.11.6. The default standard install follows this file system scheme: * ${bindir}/alienarena (the client program) * ${bindir}/alienarena-ded (the dedicated server program) * ${pkgdatadir}/arena/ (read only configuration files) * ${pkgdatadir}/botinfo/ (read only bot control files) * ${pkgdatadir}/data1/ (read only resource files) * ${datadir}/icons/alienarena.png (the official icon) The configure option is --with-icondir=DIR * ${docdir}/ (documents, licenses) The shared directory is defined at build time to be exactly $(pkgdatadir). The preprocessor symbol, DATADIR, is set to $(pkgdatadir), The program expects the arena, botinfo, and data1 shared, read-only subdirectories to be there. The program defaults for the user's home directory are: * ${HOME}/.codered/arena/ (read/write configuration and resource files) * ${HOME}/.codered/botinfo/ (read/write bot control files) * ${HOME}/.codered/data1/ (read/write resource files, rarely created) At build time, the environment variable, ALIENARENA_HOMEDIR, can be used to override the default .codered user home subdirectory. At run time, the environment variable, COR_GAME, will override the user home subdirectory program setting. This should normally be left as a user option. The arena subdirectory in the user home directory receives most of automatic resource downloads. By convention, it is where 3rd party maps are placed. The files in the user home have priority over the same name files in the read-only, shared directories. 4. Help and Support The Alien Arena Home Page URL is: http://red.planetarena.org/ There are links there to the Alien Arena Forum and other helpful Internet resources. The Alien Arena IRC (Internet Relay Chat) channel is now served by: irc.planetarena.org The in-game IRC connects to #alienarena there. There are web sites with 3rd party maps, skins, etc. See the Home Page for links. There is a Subversion (SVN) repository for Alien Arena. See the topic "Getting Alien Arena from SVN" below. Alien Arena is on IndieDB. http://www.indiedb.com/games/alien-arena-2008 Alien Arena is on Facebook and Twitter. See the Homepage for links. 5. Network Information These ports are used by the program: * UDP 27900 for the master server. Used for getting server list. * UDP 27901 for the client. * UDP 27902 for account/stats system password validation. * UDP 27910 is the default for a server, but is often configured otherwise. * TCP 6667 is the default for in-game connection to the IRC channel. The cURL library is used to retrieve game resources, player ranking information, and current version information from these URLs: * http://red.planetarena.org/sv_downloadurl * http://stats.planetarena.org/playerrank.db * http://red.planetarena.org/version/crx_version Online performance will vary depending on the network connection between the your computer (the client) and the server. Servers with *lower* ping are better. Playing online may require firewall configuration. 6. Installation from Distribution Archive This describes the standard installation. There is another installation method described below in section, "Alternate Install". If you are reading this, you may have already unpacked the distribution archive (aka, "tarball") into your HOME directory. Otherwise, the terminal command line for unpacking the archive is: $ tar -xzf alienarena-.tar.gz Or, using the graphical file browser, right click on the file name, and left click on "Extract Here." Then follow the instructions below to build the program. To build Alien Arena requires the compiler and various libraries. If you have built other programs these will probably be installed. If they are not there will be errors and the configure procedure will fail. If it fails, check the error messages for required software packages that may be missing. Check the forum for easy ways to install the required libraries for the operating system you are using. Alien Arena uses these components (in parentheses: some example file name variations): *X11 (libx11-dev, libX11, libxxf86dga-dev, libxxf86vm-dev, libXxf86vm) *OpenGL (libgl1-mesa-dev, libGL) *OpenAL 1.1 (libopenal, libopenal-dev) *Ogg-Vorbis, (libogg-dev, libvorbis-dev. libogg, libvorbis, libvorbisfile) *cURL, (libcurl, libcurl4-gnutls-dev) *FreeType2 (libfreetype, libfreetype6-dev) *JPEG (libjpeg8-dev) *ZLib (libz) *ODE (libode, libode-dev) Using the terminal, change to the "alienarena-7.66" directory and enter these commands: --- Simple Version --- $ ./configure $ make $ sudo make install --- Not-so-Simple Version --- In the following the command options are listed on separate lines with short explanations. They are entered on one line with the command, of course. $ export CFLAGS= -O3 (more optimization than -O2) -pipe (faster compile) --march=native (tuned for CPU on this machine) -DNDEBUG (remove assert statements) -Wp,-D_FORTIFY_SOURCE=2 (improved security) -fstack-protector --param=ssp-buffer-size=4 (improved security) If not configuring with the --with-system-libode option then set the same options for the c++ compiler: $ export CXXLAGS= -O3 -pipe --march=native -DNDEBUG -Wp,-D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 $./configure --with-system-libode (use the system libode) --disable-silent-rules (verbose output) --disable-dependency-tracking (speed up one-time build) ALIENARENA_HOMEDIR=some_other_dir (override default ~/.codered) $ make $ sudo make install The variable, ALIENARENA_HOMEDIR, is relative to the user home, NOT the full path. For example: $ ./configure ALIENARENA_HOMEDIR=my_alienarena Check the notes about using the system libode in the "Custom Configure Options" section, if ragdolls do not work right, or if enabling ragdolls crashes the program. By default, 'sudo make install' will install the game programs and data like this: /usr/local/ bin/ alienarena alienarena-ded (dedicated server) share/ alienarena/ arena/ botinfo/ data1/ doc/ alienarena/ icons/ alienarena.png Following installation, intermediate files generated by the build may be removed using: $ make clean To uninstall the program and data that 'sudo make install' installed, run: $ sudo make uninstall The uninstall procedure may not remove all files and directories. Some manual removal may be required. 7. Running the Program To run: $ alienarena In the menu, Single Player will run a simple pre-configured local game. For more single player options, go to the Host Server menu. Setting "public server" to "no" will keep your local game from being broadcast with the master server list. For multiplayer, online play, first enter your player name and a password in the Player Setup menu. Then go to the Join Server menu to find a Server. Bots will always show ping of 0. They have some mean sounding, but amusing, taunts. Do not let it bother you, just frag 'em. They may attack with the "probe", if you let them get close, watch out! Command line options to alienarena are NOT standard. They follow a format inherited from Alien Arena's Quake 2 roots. Command line options are the same as console commands, normally using a '+' character prefix. The details are beyond the scope of this document; but a simple example is: $ alienarena +set maxclients 10 When the program is run, a directory is created in the user HOME directory. Various kinds of data (config files, downloaded data, custom bot setups) are written there. The default directory name is ".codered/". That can be changed using an environment variable, COR_GAME. For example: $ export COR_GAME=/home/user/.my_codered 8. Configuration and Troubleshooting When the game program exits, it stores settings in "config.cfg". The default location for this file is "/home//.codered/arena/", but it might be elsewhere depending on your distribution or configuration. For custom settings, create a file, "autoexec.cfg" in the same directory as "config.cfg". Settings in "autoexec.cfg" will override settings in "config.cfg". Details about settings are beyond the scope of this document. Go to the websites, the forum and the IRC channel for more information. If there are problems, sometimes it helps to delete "config.cfg", and then re-enter menu settings. Alien Arena is based on Quake games. Many of the cvars are the same as Quake 2. More information can be found on the Forum and on the Web. Version 7.66 adds new console variables related to new features. The important ones are set using the menu. Check the forum for more info. Or ask the friendly people in the IRC channel. If the game does not run smoothly, graphics settings may need to be adjusted. It is best to start with the video card's setup utility, then adjust the Alien Arena settings. A different or updated video driver may be needed. There are settings in both the "Game Options" and "Video Options" sections that affect performance. Enable the video frame rate display in the "Game Options" menu by setting "display fps" to yes. The maximum frame rate is set with the console variable ("cvar"), "cl_maxfps". Get more information on the Forum, Websites, and IRC channel. For sound problems, check OpenAL documentation about configuration settings in the "alsoftrc" file. If you have a high resolution mouse, you may need to set the mouse sensitivity cvar. The cvar name is "sensitivity" and it may be set to fractional values between 0.0 and 1.0. Use the console to determine the value, then put it in autoexec.cfg. The mouse may behave badly (always pointing up, for instance). This can usually be fixed by setting the console variable (cvar), "in_dgamouse", to zero. Put this line into the "autoexec.cfg" file: set in_dgamouse "0" By default, the program is built without DGA, so this only applies if the following configure option was set. --with-xf86dga If the display will not go into full screen mode, it is likely the Xxf86vm library (libxxf86vm-dev or libXxf86vm) is missing on your system. 9. Custom Configure Options Run './configure --help' for a list of options. Note that many of the options are built-in and some are not meaningful or useful for Alien Arena. Options are entered on the command line in the usual way; the help output has the details. Refer to the GNU INSTALL document for general details. To build the dedicated server only, use the following configure option: --disable-client By default, configure produces a status message giving information on the configuration. To hide that message, use: --disable-build-status To rename the programs, use the standard configure option. For example: --program-transform-name='s/alienarena/alien-arena/' To install to a different location, use the standard configure option. For example: --prefix=/usr/local/games To specify an installation location for the icon, use the following option. --with-icondir=DIR To use the system-supplied libode, rather than the integrated ODE, use this option: --with-system-libode If 'pkg-config --cflags ode' returns -DdDOUBLE, it is probably safe to use the system library. The integrated ODE is built using these compile options: * -DdDOUBLE * -DdTRIMESH_ENABLED * -DdTRIMESH_OPCODE * -DNDEBUG and -DdNODEBUG Using a libode built with -DdSINGLE makes ragdolls excessively "raggedy". Other libode build variations will likely result in program failure. To disable installation of documents, use the following option. --disable-documents The server terminal will output color if the following option is used. This converts Quake-style color codes to ANSI color escapes. --enable-ansi-color Other Alien Arena custom options are intended mostly for developer use. If you use them, it is assumed that you know what you are doing. 10. Tools Tools/fuse.tar.gz contains a game server browser. See documents in that package for details. Tools/LinuxScripts contains tools for server management. See the README there for details. 11. Alternate Install This configures the installation to use the "traditional", single directory, in-place install. It does not define DATADIR, and the executables need to be in the top game directory. Normally, this install would be done somewhere in your HOME directory. Root privileges would not be required to write the game data. The configure option for renaming of the executables is not supported. If you are a map-builder, you should use this option. Some mapping tools may not work with the "standard" install. If you regularly update to the latest development code from the Subversion Repository, you may prefer this option. The two install methods are not mutually exclusive. With some care, it is possible to use both. The configure option is: --enable-alternate-install Following the usual 'make', it requires $ make install-alternate This just copies the executables to the top game directory. The effect of using any other 'install' make target is "undefined". 12. Getting Alien Arena from SVN The repository has the latest development version of Alien Arena. It contains tools and other resources that are not a part of the regular distribution. The SVN repository may be browsed at: http://svn.icculus.org/alienarena/trunk/ Anonymous read-only checkout is available using this command: svn co svn://svn.icculus.org/alienarena/trunk alienarena More information about Subversion may be found at: http://subversion.apache.org/ alien-arena-7.66+dfsg/COPYING0000600000175000017500000004325412161402016014653 0ustar zero79zero79 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. alien-arena-7.66+dfsg/game_data.am0000600000175000017500000045524012204314303016042 0ustar zero79zero79# include this file in the top level Makefile.am # # Copyright (C) 2010 COR Entertainment, LLC # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # # ------------------------------------------------------------- # Note: the GPL applies to this file, but not the files listed. # See license.txt for details, which states, in part: # "It is only permissible to distribute the game data(models, # maps, textures, sound, etc) as a whole, and with the # intention of being used with Alien Arena. It is not # permissible to distribute individual portions or items ofthe # game data without express consent from COR Entertainment." #-------------------------------------------------------------- # # Game data for distribution package # arenadir=$(pkgdatadir) nobase_dist_arena_DATA = \ arena/motd.txt \ arena/server.cfg botinfodir = $(pkgdatadir) nobase_dist_botinfo_DATA = \ botinfo/^1Squirtney.cfg \ botinfo/^3Marty.cfg \ botinfo/^3Shploik!.cfg \ botinfo/^4Invad^6ur.cfg \ botinfo/^5Beavis.cfg \ botinfo/^7Ruh^4Lur.cfg \ botinfo/^7The^1Zapp.cfg \ botinfo/Astral.cfg \ botinfo/Beavis.cfg \ botinfo/Butthead.cfg \ botinfo/Cyborg.cfg \ botinfo/Destoroyah.cfg \ botinfo/Fafa.cfg \ botinfo/Gamara.cfg \ botinfo/Ghidora.cfg \ botinfo/Hedorah.cfg \ botinfo/Johnny.cfg \ botinfo/Mogera.cfg \ botinfo/Mothra.cfg \ botinfo/Squirtney.cfg \ botinfo/Stryker.cfg \ botinfo/Yoz.cfg \ botinfo/sample.cfg \ botinfo/allbots.tmp \ botinfo/team.tmp \ botinfo/aoa-atlantis.tmp \ botinfo/aoa-corrosion.tmp \ botinfo/aoa-frost2k9.tmp \ botinfo/aoa-morpheus.tmp \ botinfo/aoa-zorn.tmp \ botinfo/db-chromium.tmp \ botinfo/db-icarus.tmp \ botinfo/db-vesuvius.tmp \ botinfo/dm-annihilation.tmp \ botinfo/dm-atlantis2k8.tmp \ botinfo/dm-babel2k11.tmp \ botinfo/dm-bloodfactory2k12.tmp \ botinfo/dm-chasmatic2k9.tmp \ botinfo/dm-command2k9.tmp \ botinfo/dm-corrosion.tmp \ botinfo/dm-crucible2k12.tmp \ botinfo/dm-deathray.tmp \ botinfo/dm-deimos2k9.tmp \ botinfo/dm-dismal2k11.tmp \ botinfo/dm-downfall.tmp \ botinfo/dm-dynamo2k12.tmp \ botinfo/dm-eternal.tmp \ botinfo/dm-extermination.tmp \ botinfo/dm-furious2k8.tmp \ botinfo/dm-goregrinder.tmp \ botinfo/dm-horus.tmp \ botinfo/dm-impact.tmp \ botinfo/dm-invasion.tmp \ botinfo/dm-leviathan2k12.tmp \ botinfo/dm-liberation.tmp \ botinfo/dm-neptune.tmp \ botinfo/dm-oblivion.tmp \ botinfo/dm-omega2k8.tmp \ botinfo/dm-purgatory.tmp \ botinfo/dm-saucer2k9.tmp \ botinfo/dm-turbo2k8.tmp \ botinfo/dm-vesuvius2k11.tmp \ botinfo/dm-violator2k11.tmp \ botinfo/dm-warmachine2k10.tmp \ botinfo/dm-zion2k9.tmp \ botinfo/dm-zorn2k11.tmp \ botinfo/tac-extermination.tmp \ botinfo/nav/aoa-atlantis.nod \ botinfo/nav/aoa-corrosion.nod \ botinfo/nav/aoa-frost2k9.nod \ botinfo/nav/aoa-morpheus.nod \ botinfo/nav/aoa-zorn.nod \ botinfo/nav/cp-ribeye.nod \ botinfo/nav/ctf-corrosion.nod \ botinfo/nav/ctf-cryogenic.nod \ botinfo/nav/ctf-europa2k8.nod \ botinfo/nav/ctf-frostbyte.nod \ botinfo/nav/ctf-goregrinder.nod \ botinfo/nav/ctf-invasion.nod \ botinfo/nav/ctf-oblivion.nod \ botinfo/nav/ctf-purgatory.nod \ botinfo/nav/ctf-titan2k8.nod \ botinfo/nav/ctf-vesuvius2k11.nod \ botinfo/nav/ctf-violator.nod \ botinfo/nav/ctf-zion2k9.nod \ botinfo/nav/db-chromium.nod \ botinfo/nav/db-icarus.nod \ botinfo/nav/db-vesuvius.nod \ botinfo/nav/dm-annihilation.nod \ botinfo/nav/dm-atlantis2k8.nod \ botinfo/nav/dm-babel2k11.nod \ botinfo/nav/dm-bloodfactory2k12.nod \ botinfo/nav/dm-chasmatic2k9.nod \ botinfo/nav/dm-command2k9.nod \ botinfo/nav/dm-corrosion.nod \ botinfo/nav/dm-crucible2k12.nod \ botinfo/nav/dm-deathray.nod \ botinfo/nav/dm-deimos2k9.nod \ botinfo/nav/dm-dismal2k11.nod \ botinfo/nav/dm-downfall.nod \ botinfo/nav/dm-dynamo2k12.nod \ botinfo/nav/dm-eternal.nod \ botinfo/nav/dm-europa2k8.nod \ botinfo/nav/dm-extermination.nod \ botinfo/nav/dm-furious2k8.nod \ botinfo/nav/dm-goregrinder.nod \ botinfo/nav/dm-horus.nod \ botinfo/nav/dm-impact.nod \ botinfo/nav/dm-invasion.nod \ botinfo/nav/dm-leviathan2k12.nod \ botinfo/nav/dm-liberation.nod \ botinfo/nav/dm-neptune.nod \ botinfo/nav/dm-oblivion.nod \ botinfo/nav/dm-omega2k8.nod \ botinfo/nav/dm-purgatory.nod \ botinfo/nav/dm-saucer2k9.nod \ botinfo/nav/dm-titan2k8.nod \ botinfo/nav/dm-turbo2k8.nod \ botinfo/nav/dm-vesuvius2k11.nod \ botinfo/nav/dm-violator2k11.nod \ botinfo/nav/dm-warmachine2k10.nod \ botinfo/nav/dm-zion2k9.nod \ botinfo/nav/dm-zorn2k11.nod \ botinfo/nav/tac-extermination.nod \ botinfo/nav/tca-corrosion.nod \ botinfo/nav/tca-cryogenic.nod \ botinfo/nav/tca-europa2k8.nod \ botinfo/nav/tca-frost.nod \ botinfo/nav/tca-invasion.nod \ botinfo/nav/tca-purgatory.nod \ botinfo/nav/tca-titan2k8.nod \ botinfo/nav/tca-zion.nod \ botinfo/nav/tca-zion2k9.nod data1dir = $(pkgdatadir) nobase_dist_data1_DATA = \ data1/default.cfg \ data1/maps.lst # Note: partitioning the data files like this keeps the command line length # in legal range for installation. However it does not work for creation # of the distribution package. Hence, "nodist" is specified and data is # copied to the distribution directory in "dist-hook:" # envdir = $(pkgdatadir) nobase_nodist_env_DATA = \ data1/env/alienbk.tga \ data1/env/aliendn.tga \ data1/env/alienft.tga \ data1/env/alienlf.tga \ data1/env/alienrt.tga \ data1/env/alienup.tga \ data1/env/deadcitybk.tga \ data1/env/deadcitydn.tga \ data1/env/deadcityft.tga \ data1/env/deadcitylf.tga \ data1/env/deadcityrt.tga \ data1/env/deadcityup.tga \ data1/env/egyptbk.tga \ data1/env/egyptdn.tga \ data1/env/egyptft.tga \ data1/env/egyptlf.tga \ data1/env/egyptrt.tga \ data1/env/egyptup.tga \ data1/env/greenbk.tga \ data1/env/greendn.tga \ data1/env/greenft.tga \ data1/env/greenlf.tga \ data1/env/greenrt.tga \ data1/env/greenup.tga \ data1/env/hellbk.tga \ data1/env/helldn.tga \ data1/env/hellft.tga \ data1/env/helllf.tga \ data1/env/hellrt.tga \ data1/env/hellup.tga \ data1/env/martianbk.tga \ data1/env/martiandn.tga \ data1/env/martianft.tga \ data1/env/martianlf.tga \ data1/env/martianrt.tga \ data1/env/martianup.tga \ data1/env/seabk.tga \ data1/env/seadn.tga \ data1/env/seaft.tga \ data1/env/sealf.tga \ data1/env/seart.tga \ data1/env/seaup.tga \ data1/env/space1bk.tga \ data1/env/space1dn.tga \ data1/env/space1ft.tga \ data1/env/space1lf.tga \ data1/env/space1rt.tga \ data1/env/space1up.tga \ data1/env/tekcitybk.tga \ data1/env/tekcitydn.tga \ data1/env/tekcityft.tga \ data1/env/tekcitylf.tga \ data1/env/tekcityrt.tga \ data1/env/tekcityup.tga fontsdir = $(pkgdatadir) nobase_nodist_fonts_DATA = \ data1/fonts/agentred.ttf \ data1/fonts/bluehigd.ttf \ data1/fonts/chicomono.ttf \ data1/fonts/creativeblock.ttf \ data1/fonts/freemono.ttf \ data1/fonts/freesans.ttf \ data1/fonts/orbitron.ttf \ data1/fonts/crackdown.ttf \ data1/fonts/bendable.ttf gfxdir = $(pkgdatadir) nobase_nodist_gfx_DATA = \ data1/gfx/aaglow.tga \ data1/gfx/adrenalbase.tga \ data1/gfx/adrenalmask.tga \ data1/gfx/annhiliationreflection.jpg \ data1/gfx/alienarena2gl.tga \ data1/gfx/bannerfx.tga \ data1/gfx/bconsole2.tga \ data1/gfx/bconsole.tga \ data1/gfx/beam1.tga \ data1/gfx/beam2.tga \ data1/gfx/beam3.tga \ data1/gfx/beam4.tga \ data1/gfx/beamfx.tga \ data1/gfx/beamgunfx.tga \ data1/gfx/blasterfx.tga \ data1/gfx/blooddrops.jpg \ data1/gfx/blooddrops_nm.jpg \ data1/gfx/bluecyborgfx.tga \ data1/gfx/bluelightning2.tga \ data1/gfx/bluelightning.tga \ data1/gfx/bluemartianfx.tga \ data1/gfx/blueoverlordfx.tga \ data1/gfx/bluewarriorfx.tga \ data1/gfx/bubbles.tga \ data1/gfx/caustics.tga \ data1/gfx/chrome2.tga \ data1/gfx/chrome.tga \ data1/gfx/citymask.tga \ data1/gfx/cloudsspace.tga \ data1/gfx/clouds.tga \ data1/gfx/cloudsthick.tga \ data1/gfx/comp1.tga \ data1/gfx/comp2.tga \ data1/gfx/cpribeyereflection.tga \ data1/gfx/defaultcommanderfx.tga \ data1/gfx/defaultcyborgfx.tga \ data1/gfx/defaultenforcerfx.tga \ data1/gfx/defaultlaurenfx.tga \ data1/gfx/defaultmartianfx.tga \ data1/gfx/defaultoverlordfx.tga \ data1/gfx/defaultslashbotfx.tga \ data1/gfx/defaultwarriorfx.tga \ data1/gfx/disruptorfx.tga \ data1/gfx/disruptormask.tga \ data1/gfx/distortwave.jpg \ data1/gfx/dmaquousreflection.tga \ data1/gfx/dmbeyondreflection.tga \ data1/gfx/dmdreadreflection.tga \ data1/gfx/dmturboreflection.tga \ data1/gfx/droplets.jpg \ data1/gfx/e6launchengine_fx.tga \ data1/gfx/e6launchengine_glow.tga \ data1/gfx/e6launchengine_mask.tga \ data1/gfx/e8_jumppad02_fx.tga \ data1/gfx/e8_jumppad02_mask.tga \ data1/gfx/e8_launchpad1_fx1.tga \ data1/gfx/e8_launchpad1_fx2.tga \ data1/gfx/e8_launchpad1_mask2.tga \ data1/gfx/egypt5_mask.tga \ data1/gfx/electrics2.tga \ data1/gfx/electrics3a.tga \ data1/gfx/electrics3b.tga \ data1/gfx/electrics3d.tga \ data1/gfx/electrics3.tga \ data1/gfx/electrics.tga \ data1/gfx/flares/flare0.tga \ data1/gfx/flares/flare1.tga \ data1/gfx/flares/flare2.tga \ data1/gfx/flash_noise.jpg \ data1/gfx/flash.tga \ data1/gfx/gamarafx.tga \ data1/gfx/glightning.tga \ data1/gfx/gold.tga \ data1/gfx/grapplefx.tga \ data1/gfx/grass.tga \ data1/gfx/grchrome.tga \ data1/gfx/greencircuit2.tga \ data1/gfx/greencircuit.tga \ data1/gfx/greenlightning.tga \ data1/gfx/greenline.tga \ data1/gfx/hconsole2.tga \ data1/gfx/hconsole3.tga \ data1/gfx/hconsole.tga \ data1/gfx/hoverfx.tga \ data1/gfx/leaves1.tga \ data1/gfx/lightning.tga \ data1/gfx/m_banner_main_mask.tga \ data1/gfx/menubar1.tga \ data1/gfx/menubar2.tga \ data1/gfx/menubar3.tga \ data1/gfx/menubar4.tga \ data1/gfx/metal3glow.tga \ data1/gfx/metalenvmap.jpg \ data1/gfx/minderaser_fx.tga \ data1/gfx/mirrorspec.tga \ data1/gfx/noise.tga \ data1/gfx/plate5fx.tga \ data1/gfx/purpleline.tga \ data1/gfx/quadbase.tga \ data1/gfx/radar/around.tga \ data1/gfx/radar/radarmap.tga \ data1/gfx/rain_a.tga \ data1/gfx/rainfxa.tga \ data1/gfx/rainfxb.tga \ data1/gfx/rainfxc.tga \ data1/gfx/rainfxd.tga \ data1/gfx/rainfxe.tga \ data1/gfx/rainfxf.tga \ data1/gfx/rainfxg.tga \ data1/gfx/rainfxh.tga \ data1/gfx/rain.tga \ data1/gfx/rayfx.tga \ data1/gfx/redcommanderfx.tga \ data1/gfx/redcircuit.tga \ data1/gfx/redlightning.tga \ data1/gfx/reflect.tga \ data1/gfx/rlauncherfx.tga \ data1/gfx/r_lightning.tga \ data1/gfx/sconsole.tga \ data1/gfx/shard_fx.tga \ data1/gfx/shardmask.tga \ data1/gfx/skullglow.tga \ data1/gfx/smartgunmask.tga \ data1/gfx/stepside_mtl4light_fx1.tga \ data1/gfx/sun1.jpg \ data1/gfx/sun2.jpg \ data1/gfx/sun.jpg \ data1/gfx/tekwallmask.tga \ data1/gfx/trim2mask.tga \ data1/gfx/tron2_commanderfx.tga \ data1/gfx/tron2_cyborgfx.tga \ data1/gfx/tron2_enforcerfx.tga \ data1/gfx/tron2_laurenfx.tga \ data1/gfx/tron2_martianfx.tga \ data1/gfx/tron2_overlordfx.tga \ data1/gfx/tron2_slashbotfx.tga \ data1/gfx/tron2_warriorfx.tga \ data1/gfx/tron3_commanderfx.tga \ data1/gfx/tron3_cyborgfx.tga \ data1/gfx/tron3_enforcerfx.tga \ data1/gfx/tron3_laurenfx.tga \ data1/gfx/tron3_martianfx.tga \ data1/gfx/tron3_overlordfx.tga \ data1/gfx/tron3_slashbotfx.tga \ data1/gfx/tron3_warriorfx.tga \ data1/gfx/tron_commanderfx.tga \ data1/gfx/tron_cyborgfx.tga \ data1/gfx/tron_enforcerfx.tga \ data1/gfx/tron_laurenfx.tga \ data1/gfx/tron_martianfx.tga \ data1/gfx/tron_overlordfx.tga \ data1/gfx/tron_slashbotfx.tga \ data1/gfx/tron_warriorfx.tga \ data1/gfx/vaporbase.tga \ data1/gfx/vapormask.tga \ data1/gfx/violator2fx.tga \ data1/gfx/violatorfx.tga \ data1/gfx/water/distort1.tga \ data1/gfx/water/normal1.tga \ data1/gfx/yellowline.tga levelshotsdir = $(pkgdatadir) nobase_nodist_levelshots_DATA = \ data1/levelshots/aoa-atlantis.jpg \ data1/levelshots/aoa-atlantis.txt \ data1/levelshots/aoa-corrosion.jpg \ data1/levelshots/aoa-corrosion.txt \ data1/levelshots/aoa-frost2k9.jpg \ data1/levelshots/aoa-frost2k9.txt \ data1/levelshots/aoa-morpheus.jpg \ data1/levelshots/aoa-morpheus.txt \ data1/levelshots/aoa-zorn.jpg \ data1/levelshots/aoa-zorn.txt \ data1/levelshots/cp-ribeye.jpg \ data1/levelshots/cp-ribeye.txt \ data1/levelshots/ctf-corrosion.jpg \ data1/levelshots/ctf-corrosion.txt \ data1/levelshots/ctf-cryogenic.jpg \ data1/levelshots/ctf-cryogenic.txt \ data1/levelshots/ctf-extermination.jpg \ data1/levelshots/ctf-extermination.txt \ data1/levelshots/ctf-frostbyte.jpg \ data1/levelshots/ctf-frostbyte.txt \ data1/levelshots/ctf-goregrinder.jpg \ data1/levelshots/ctf-goregrinder.txt \ data1/levelshots/ctf-invasion.jpg \ data1/levelshots/ctf-invasion.txt \ data1/levelshots/ctf-oblivion.jpg \ data1/levelshots/ctf-oblivion.txt \ data1/levelshots/ctf-purgatory.jpg \ data1/levelshots/ctf-purgatory.txt \ data1/levelshots/ctf-titan2k8.jpg \ data1/levelshots/ctf-titan2k8.txt \ data1/levelshots/ctf-vesuvius2k11.jpg \ data1/levelshots/ctf-vesuvius2k11.txt \ data1/levelshots/ctf-violator.jpg \ data1/levelshots/ctf-violator.txt \ data1/levelshots/ctf-zion2k9.jpg \ data1/levelshots/ctf-zion2k9.txt \ data1/levelshots/db-chromium.jpg \ data1/levelshots/db-chromium.txt \ data1/levelshots/db-icarus.jpg \ data1/levelshots/db-icarus.txt \ data1/levelshots/db-vesuvius.jpg \ data1/levelshots/db-vesuvius.txt \ data1/levelshots/dm-annihilation.jpg \ data1/levelshots/dm-annihilation.txt \ data1/levelshots/dm-atlantis2k8.jpg \ data1/levelshots/dm-atlantis2k8.txt \ data1/levelshots/dm-babel2k11.jpg \ data1/levelshots/dm-babel2k11.txt \ data1/levelshots/dm-bloodfactory2k12.jpg \ data1/levelshots/dm-bloodfactory2k12.txt \ data1/levelshots/dm-chasmatic2k9.jpg \ data1/levelshots/dm-chasmatic2k9.txt \ data1/levelshots/dm-command2k9.jpg \ data1/levelshots/dm-command2k9.txt \ data1/levelshots/dm-corrosion.jpg \ data1/levelshots/dm-corrosion.txt \ data1/levelshots/dm-crucible2k12.jpg \ data1/levelshots/dm-crucible2k12.txt \ data1/levelshots/dm-deathray.jpg \ data1/levelshots/dm-deathray.txt \ data1/levelshots/dm-deimos2k9.jpg \ data1/levelshots/dm-deimos2k9.txt \ data1/levelshots/dm-dismal2k11.jpg \ data1/levelshots/dm-dismal2k11.txt \ data1/levelshots/dm-downfall.jpg \ data1/levelshots/dm-downfall.txt \ data1/levelshots/dm-dynamo2k12.jpg \ data1/levelshots/dm-dynamo2k12.txt \ data1/levelshots/dm-eternal.jpg \ data1/levelshots/dm-eternal.txt \ data1/levelshots/dm-extermination.jpg \ data1/levelshots/dm-extermination.txt \ data1/levelshots/dm-furious2k8.jpg \ data1/levelshots/dm-furious2k8.txt \ data1/levelshots/dm-goregrinder.jpg \ data1/levelshots/dm-goregrinder.txt \ data1/levelshots/dm-horus.jpg \ data1/levelshots/dm-horus.txt \ data1/levelshots/dm-impact.jpg \ data1/levelshots/dm-impact.txt \ data1/levelshots/dm-invasion.jpg \ data1/levelshots/dm-invasion.txt \ data1/levelshots/dm-leviathan2k12.jpg \ data1/levelshots/dm-leviathan2k12.txt \ data1/levelshots/dm-liberation.jpg \ data1/levelshots/dm-liberation.txt \ data1/levelshots/dm-neptune.jpg \ data1/levelshots/dm-neptune.txt \ data1/levelshots/dm-oblivion.jpg \ data1/levelshots/dm-oblivion.txt \ data1/levelshots/dm-omega2k8.jpg \ data1/levelshots/dm-omega2k8.txt \ data1/levelshots/dm-purgatory.jpg \ data1/levelshots/dm-purgatory.txt \ data1/levelshots/dm-saucer2k9.jpg \ data1/levelshots/dm-saucer2k9.txt \ data1/levelshots/dm-turbo2k8.jpg \ data1/levelshots/dm-turbo2k8.txt \ data1/levelshots/dm-vesuvius2k11.jpg \ data1/levelshots/dm-vesuvius2k11.txt \ data1/levelshots/dm-violator2k11.jpg \ data1/levelshots/dm-violator2k11.txt \ data1/levelshots/dm-warmachine2k10.jpg \ data1/levelshots/dm-warmachine2k10.txt \ data1/levelshots/dm-zorn2k11.jpg \ data1/levelshots/dm-zorn2k11.txt \ data1/levelshots/dm-zion2k9.jpg \ data1/levelshots/dm-zion2k9.txt \ data1/levelshots/tac-extermination.jpg \ data1/levelshots/tac-extermination.txt \ data1/levelshots/tca-corrosion.jpg \ data1/levelshots/tca-corrosion.txt \ data1/levelshots/tca-cryogenic.jpg \ data1/levelshots/tca-cryogenic.txt \ data1/levelshots/tca-extermination.jpg \ data1/levelshots/tca-extermination.txt \ data1/levelshots/tca-frost.jpg \ data1/levelshots/tca-frost.txt \ data1/levelshots/tca-purgatory.jpg \ data1/levelshots/tca-purgatory.txt \ data1/levelshots/tca-titan2k8.jpg \ data1/levelshots/tca-titan2k8.txt \ data1/levelshots/tca-zion2k9.jpg \ data1/levelshots/tca-zion2k9.txt mapsdir = $(pkgdatadir) nobase_nodist_maps_DATA = \ data1/maps/aoa-atlantis.bsp \ data1/maps/aoa-corrosion.bsp \ data1/maps/aoa-frost2k9.bsp \ data1/maps/aoa-morpheus.bsp \ data1/maps/aoa-zorn.bsp \ data1/maps/cp-ribeye.bsp \ data1/maps/ctf-corrosion.bsp \ data1/maps/ctf-corrosion.lightmap \ data1/maps/ctf-cryogenic.bsp \ data1/maps/ctf-extermination.bsp \ data1/maps/ctf-extermination.lightmap \ data1/maps/ctf-frostbyte.bsp \ data1/maps/ctf-goregrinder.bsp \ data1/maps/ctf-invasion.bsp \ data1/maps/ctf-invasion.lightmap \ data1/maps/ctf-oblivion.bsp \ data1/maps/ctf-oblivion.lightmap \ data1/maps/ctf-purgatory.bsp \ data1/maps/ctf-titan2k8.bsp \ data1/maps/ctf-vesuvius2k11.bsp \ data1/maps/ctf-vesuvius2k11.lightmap \ data1/maps/ctf-violator.bsp \ data1/maps/ctf-zion2k9.bsp \ data1/maps/db-chromium.bsp \ data1/maps/db-icarus.bsp \ data1/maps/db-vesuvius.bsp \ data1/maps/dm-annihilation.bsp \ data1/maps/dm-annihilation.lightmap \ data1/maps/dm-atlantis2k8.bsp \ data1/maps/dm-babel2k11.bsp \ data1/maps/dm-bloodfactory2k12.bsp \ data1/maps/dm-chasmatic2k9.bsp \ data1/maps/dm-command2k9.bsp \ data1/maps/dm-corrosion.bsp \ data1/maps/dm-corrosion.lightmap \ data1/maps/dm-crucible2k12.bsp \ data1/maps/dm-crucible2k12.lightmap \ data1/maps/dm-deathray.bsp \ data1/maps/dm-deimos2k9.bsp \ data1/maps/dm-deimos2k9.lightmap \ data1/maps/dm-dismal2k11.bsp \ data1/maps/dm-downfall.bsp \ data1/maps/dm-dynamo2k12.bsp \ data1/maps/dm-dynamo2k12.lightmap \ data1/maps/dm-eternal.bsp \ data1/maps/dm-extermination.bsp \ data1/maps/dm-extermination.lightmap \ data1/maps/dm-furious2k8.bsp \ data1/maps/dm-furious2k8.lightmap \ data1/maps/dm-goregrinder.bsp \ data1/maps/dm-goregrinder.lightmap \ data1/maps/dm-horus.bsp \ data1/maps/dm-impact.bsp \ data1/maps/dm-impact.lightmap \ data1/maps/dm-invasion.bsp \ data1/maps/dm-invasion.lightmap \ data1/maps/dm-leviathan2k12.bsp \ data1/maps/dm-liberation.bsp \ data1/maps/dm-neptune.bsp \ data1/maps/dm-neptune.lightmap \ data1/maps/dm-oblivion.bsp \ data1/maps/dm-oblivion.lightmap \ data1/maps/dm-omega2k8.bsp \ data1/maps/dm-omega2k8.lightmap \ data1/maps/dm-purgatory.bsp \ data1/maps/dm-saucer2k9.bsp \ data1/maps/dm-turbo2k8.bsp \ data1/maps/dm-vesuvius2k11.bsp \ data1/maps/dm-vesuvius2k11.lightmap \ data1/maps/dm-violator2k11.bsp \ data1/maps/dm-violator2k11.lightmap \ data1/maps/dm-warmachine2k10.bsp \ data1/maps/dm-warmachine2k10.lightmap \ data1/maps/dm-zorn2k11.bsp \ data1/maps/dm-zion2k9.bsp \ data1/maps/tac-extermination.bsp \ data1/maps/tac-extermination.lightmap \ data1/maps/tca-corrosion.bsp \ data1/maps/tca-corrosion.lightmap \ data1/maps/tca-cryogenic.bsp \ data1/maps/tca-extermination.bsp \ data1/maps/tca-invasion \ data1/maps/tca-invasion.entdef \ data1/maps/tca-purgatory.bsp \ data1/maps/tca-titan2k8.bsp \ data1/maps/tca-zion2k9.bsp \ data1/maps/meshes/arch_fx.tga \ data1/maps/meshes/arch.md2 \ data1/maps/meshes/arch_normal.jpg \ data1/maps/meshes/arch.tga \ data1/maps/meshes/barrel.jpg \ data1/maps/meshes/barrel.md2 \ data1/maps/meshes/barrel_normal.jpg \ data1/maps/meshes/bentconduit.md2 \ data1/maps/meshes/bignode_fx.tga \ data1/maps/meshes/bignode.jpg \ data1/maps/meshes/bignode.md2 \ data1/maps/meshes/bignode_normal.jpg \ data1/maps/meshes/bigribpipe.jpg \ data1/maps/meshes/bigribpipe.md2 \ data1/maps/meshes/bigribpipe_normal.jpg \ data1/maps/meshes/brainjarcover.md2 \ data1/maps/meshes/brainjar.md2 \ data1/maps/meshes/brainjar_normal.tga \ data1/maps/meshes/brainjar.tga \ data1/maps/meshes/cables2.md2 \ data1/maps/meshes/cables3.md2 \ data1/maps/meshes/cables4.md2 \ data1/maps/meshes/cables.jpg \ data1/maps/meshes/cables.md2 \ data1/maps/meshes/cables_normal.jpg \ data1/maps/meshes/cannister.jpg \ data1/maps/meshes/cannister.md2 \ data1/maps/meshes/cannister_normal.jpg \ data1/maps/meshes/clamps.jpg \ data1/maps/meshes/clamps.md2 \ data1/maps/meshes/clamps_normal.jpg \ data1/maps/meshes/cmdconsole_fx.tga \ data1/maps/meshes/cmdconsole.jpg \ data1/maps/meshes/cmdconsole.md2 \ data1/maps/meshes/cmdconsole_normal.jpg \ data1/maps/meshes/conduit.jpg \ data1/maps/meshes/conduit_normal.jpg \ data1/maps/meshes/controls_fx.tga \ data1/maps/meshes/controls.md2 \ data1/maps/meshes/controls_normal.tga \ data1/maps/meshes/controls.tga \ data1/maps/meshes/dome.md2 \ data1/maps/meshes/dualpipes.jpg \ data1/maps/meshes/dualpipes.md2 \ data1/maps/meshes/dualpipes_normal.jpg \ data1/maps/meshes/electrodecover.md2 \ data1/maps/meshes/electrode.md2 \ data1/maps/meshes/electrode.tga \ data1/maps/meshes/electrode_normal.tga \ data1/maps/meshes/eyejar_fx.tga \ data1/maps/meshes/eyejarglass.md2 \ data1/maps/meshes/eyejar.md2 \ data1/maps/meshes/eyejar_normal.tga \ data1/maps/meshes/eyejar.tga \ data1/maps/meshes/flagpad_fx.tga \ data1/maps/meshes/flagpad.md2 \ data1/maps/meshes/flagpad_normal.tga \ data1/maps/meshes/flagpad.tga \ data1/maps/meshes/floorcables.md2 \ data1/maps/meshes/generator.jpg \ data1/maps/meshes/generator.md2 \ data1/maps/meshes/generator_normal.jpg \ data1/maps/meshes/gothic/blade.jpg \ data1/maps/meshes/gothic/blade.md2 \ data1/maps/meshes/gothic/blade_normal.jpg \ data1/maps/meshes/gothic/ceillamp.md2 \ data1/maps/meshes/gothic/column1.jpg \ data1/maps/meshes/gothic/column1.md2 \ data1/maps/meshes/gothic/column1_normal.jpg \ data1/maps/meshes/gothic/dragon.jpg \ data1/maps/meshes/gothic/dragon.md2 \ data1/maps/meshes/gothic/dragon_normal.jpg \ data1/maps/meshes/gothic/fdstatue_green.md2 \ data1/maps/meshes/gothic/fd_statue_normal.jpg \ data1/maps/meshes/gothic/fdstatue_red.md2 \ data1/maps/meshes/gothic/freedom_statue_green.jpg \ data1/maps/meshes/gothic/freedom_statue_red.jpg \ data1/maps/meshes/gothic/lamp2b_fx.tga \ data1/maps/meshes/gothic/lamp2b.md2 \ data1/maps/meshes/gothic/lamp2b.tga \ data1/maps/meshes/gothic/lamp2_fx.tga \ data1/maps/meshes/gothic/lamp2.md2 \ data1/maps/meshes/gothic/lamp2_normal.tga \ data1/maps/meshes/gothic/lamp2.tga \ data1/maps/meshes/gothic/lamp_fx.tga \ data1/maps/meshes/gothic/lamp.md2 \ data1/maps/meshes/gothic/lamp_normal.tga \ data1/maps/meshes/gothic/lamp.tga \ data1/maps/meshes/gothic/meat1.jpg \ data1/maps/meshes/gothic/meat1.md2 \ data1/maps/meshes/gothic/meat1_normal.jpg \ data1/maps/meshes/gothic/meat2.jpg \ data1/maps/meshes/gothic/meat2.md2 \ data1/maps/meshes/gothic/meat2_normal.jpg \ data1/maps/meshes/gothic/meat3.jpg \ data1/maps/meshes/gothic/meat3.md2 \ data1/maps/meshes/gothic/meat3_normal.jpg \ data1/maps/meshes/gothic/neptune.jpg \ data1/maps/meshes/gothic/neptune.md2 \ data1/maps/meshes/gothic/neptune_normal.jpg \ data1/maps/meshes/gothic/root.jpg \ data1/maps/meshes/gothic/root.md2 \ data1/maps/meshes/gothic/root_normal.jpg \ data1/maps/meshes/gothic/skeleton1.md2 \ data1/maps/meshes/gothic/skeleton2.md2 \ data1/maps/meshes/gothic/skeleton3.md2 \ data1/maps/meshes/gothic/skeleton.jpg \ data1/maps/meshes/gothic/skeleton_normal.jpg \ data1/maps/meshes/gothic/throne.jpg \ data1/maps/meshes/gothic/throne.md2 \ data1/maps/meshes/gothic/throne_normal.jpg \ data1/maps/meshes/greenblob_fx.tga \ data1/maps/meshes/greenblob.jpg \ data1/maps/meshes/greenblob.md2 \ data1/maps/meshes/hanger.md2 \ data1/maps/meshes/hanger_normal.jpg \ data1/maps/meshes/hanger.tga \ data1/maps/meshes/hangingmartian.md2 \ data1/maps/meshes/hangingmhelmet.md2 \ data1/maps/meshes/hatch.jpg \ data1/maps/meshes/hatch.md2 \ data1/maps/meshes/hatch_normal.jpg \ data1/maps/meshes/injector.jpg \ data1/maps/meshes/injector.md2 \ data1/maps/meshes/injector_normal.jpg \ data1/maps/meshes/lamp2_fx.tga \ data1/maps/meshes/lamp2.jpg \ data1/maps/meshes/lamp2.md2 \ data1/maps/meshes/lamp2_normal.jpg \ data1/maps/meshes/martian.jpg \ data1/maps/meshes/martian.md2 \ data1/maps/meshes/martian_normal.jpg \ data1/maps/meshes/metpipe1.md2 \ data1/maps/meshes/metpipe2.md2 \ data1/maps/meshes/metpipe3.md2 \ data1/maps/meshes/mhelmet.md2 \ data1/maps/meshes/monitor2.md2 \ data1/maps/meshes/monitor_normal.tga \ data1/maps/meshes/monitor.jpg \ data1/maps/meshes/monitormask.tga \ data1/maps/meshes/monitor.md2 \ data1/maps/meshes/mpa1.jpg \ data1/maps/meshes/mpa1_normal.jpg \ data1/maps/meshes/mpa2.jpg \ data1/maps/meshes/mpa2_normal.jpg \ data1/maps/meshes/pipes1.jpg \ data1/maps/meshes/pipes1_normal.jpg \ data1/maps/meshes/pipes.md2 \ data1/maps/meshes/piston.md2 \ data1/maps/meshes/piston_normal.jpg \ data1/maps/meshes/piston.tga \ data1/maps/meshes/pulsar.md2 \ data1/maps/meshes/pulsar_normal.jpg \ data1/maps/meshes/pulsar.tga \ data1/maps/meshes/railcarglass.md2 \ data1/maps/meshes/railcar.jpg \ data1/maps/meshes/railcarmartian.md2 \ data1/maps/meshes/railcar.md2 \ data1/maps/meshes/railcarmhelmet.md2 \ data1/maps/meshes/railcar_normal.jpg \ data1/maps/meshes/redblob_fx.tga \ data1/maps/meshes/redblob.jpg \ data1/maps/meshes/redblob.md2 \ data1/maps/meshes/redblob_normal.jpg \ data1/maps/meshes/ribtube1.md2 \ data1/maps/meshes/ribtube2.md2 \ data1/maps/meshes/ribtube3.md2 \ data1/maps/meshes/ribtube.jpg \ data1/maps/meshes/ribtube_normal.jpg \ data1/maps/meshes/sconduit1.md2 \ data1/maps/meshes/sconduit2.md2 \ data1/maps/meshes/scopecover.md2 \ data1/maps/meshes/scope.md2 \ data1/maps/meshes/scope_normal.tga \ data1/maps/meshes/scope.tga \ data1/maps/meshes/spingear_fx.tga \ data1/maps/meshes/spingear.jpg \ data1/maps/meshes/spingear.md2 \ data1/maps/meshes/spingear_normal.jpg \ data1/maps/meshes/spintube.jpg \ data1/maps/meshes/spintube.md2 \ data1/maps/meshes/spintube_normal.jpg \ data1/maps/meshes/straightconduit.md2 \ data1/maps/meshes/tech/bigribtube.jpg \ data1/maps/meshes/tech/bigribtube_normal.jpg \ data1/maps/meshes/tech/blueribtube1.md2 \ data1/maps/meshes/tech/blueribtube_fx.tga \ data1/maps/meshes/tech/blueribtube.jpg \ data1/maps/meshes/tech/glasstube.md2 \ data1/maps/meshes/tech/railing2.md2 \ data1/maps/meshes/tech/railing3.md2 \ data1/maps/meshes/tech/railing4.md2 \ data1/maps/meshes/tech/railing5.md2 \ data1/maps/meshes/tech/railing.jpg \ data1/maps/meshes/tech/railing.md2 \ data1/maps/meshes/tech/railing_normal.jpg \ data1/maps/meshes/tech/redribtube1.md2 \ data1/maps/meshes/tech/redribtube_fx.tga \ data1/maps/meshes/tech/redribtube.jpg \ data1/maps/meshes/tech/ribtubebig1.md2 \ data1/maps/meshes/tech/ribtubebig2.md2 \ data1/maps/meshes/tech/ribtubebig3.md2 \ data1/maps/meshes/tech/ribtubebig4.md2 \ data1/maps/meshes/tech/ribtubebig5.md2 \ data1/maps/meshes/tech/ribtubebig6.md2 \ data1/maps/meshes/tech/ribtubebig7.md2 \ data1/maps/meshes/tech/ribtubebig8.md2 \ data1/maps/meshes/tech/rotator_fx.tga \ data1/maps/meshes/tech/rotatorglass.md2 \ data1/maps/meshes/tech/rotatorimage1.md2 \ data1/maps/meshes/tech/rotatorimage2.md2 \ data1/maps/meshes/tech/rotatorimage3.md2 \ data1/maps/meshes/tech/rotatorimage4.md2 \ data1/maps/meshes/tech/rotator.jpg \ data1/maps/meshes/tech/rotator.md2 \ data1/maps/meshes/tech/rotator_normal.jpg \ data1/maps/meshes/tech/rotimage1_normal.tga \ data1/maps/meshes/tech/rotimage1.tga \ data1/maps/meshes/tech/rotimage2_normal.tga \ data1/maps/meshes/tech/rotimage2.tga \ data1/maps/meshes/tech/rotimage3_normal.tga \ data1/maps/meshes/tech/rotimage3.tga \ data1/maps/meshes/tech/rotimage4_normal.tga \ data1/maps/meshes/tech/rotimage4.tga \ data1/maps/meshes/tech/slimegen2.md2 \ data1/maps/meshes/tech/slimegen.jpg \ data1/maps/meshes/tech/slimegen.md2 \ data1/maps/meshes/tech/slimegen_fx.tga \ data1/maps/meshes/tech/slimegenblue_fx.tga \ data1/maps/meshes/tech/slimegenblue.jpg \ data1/maps/meshes/tech/slimegenblue.md2 \ data1/maps/meshes/tech/slimegen_normal.jpg \ data1/maps/meshes/tech/slimegenred_fx.tga \ data1/maps/meshes/tech/slimegenred.jpg \ data1/maps/meshes/tech/slimegenred.md2 \ data1/maps/meshes/tech/slimegen_s.md2 \ data1/maps/meshes/tech/slimetube1.md2 \ data1/maps/meshes/tech/turbinefan.jpg \ data1/maps/meshes/tech/turbinefan.md2 \ data1/maps/meshes/tech/turbinefan_normal.jpg \ data1/maps/meshes/toxicbarrell.jpg \ data1/maps/meshes/toxicbarrell.md2 \ data1/maps/meshes/toxicbarrell_normal.jpg \ data1/maps/meshes/tubecover.md2 \ data1/maps/meshes/tube.md2 \ data1/maps/meshes/tube.tga \ data1/maps/meshes/unit.jpg \ data1/maps/meshes/unit.md2 \ data1/maps/meshes/unit_normal.jpg \ data1/maps/meshes/urban/bluelantern_fx.tga \ data1/maps/meshes/urban/bluelantern.jpg \ data1/maps/meshes/urban/bluelantern.md2 \ data1/maps/meshes/urban/lantern_normal.jpg \ data1/maps/meshes/urban/mercedes.jpg \ data1/maps/meshes/urban/mercedes.md2 \ data1/maps/meshes/urban/orangelantern_fx.tga \ data1/maps/meshes/urban/orangelantern.jpg \ data1/maps/meshes/urban/orangelantern.md2 \ data1/maps/meshes/urban/rioblue.jpg \ data1/maps/meshes/urban/rioblue.md2 \ data1/maps/meshes/urban/rio_normal.jpg \ data1/maps/meshes/urban/riored.jpg \ data1/maps/meshes/urban/riored.md2 \ data1/maps/meshes/urban/riosilver.jpg \ data1/maps/meshes/urban/riosilver.md2 \ data1/maps/meshes/urban/roadbarrell.jpg \ data1/maps/meshes/urban/roadbarrell.md2 \ data1/maps/meshes/urban/roadbarrell_normal.jpg \ data1/maps/meshes/urban/rope.jpg \ data1/maps/meshes/urban/rope.md2 \ data1/maps/meshes/urban/yellowlantern_fx.tga \ data1/maps/meshes/urban/yellowlantern.jpg \ data1/maps/meshes/urban/yellowlantern.md2 \ data1/maps/meshes/weaponpad_fx.tga \ data1/maps/meshes/weaponpad.md2 \ data1/maps/meshes/weaponpad_normal.tga \ data1/maps/meshes/weaponpad.tga \ data1/maps/meshes/xempx/ceillightbig.md2 \ data1/maps/meshes/xempx/ceillight_fx.tga \ data1/maps/meshes/xempx/ceillight.jpg \ data1/maps/meshes/xempx/ceillight.md2 \ data1/maps/meshes/xempx/ceillight_normal.jpg \ data1/maps/meshes/xempx/crate32.md2 \ data1/maps/meshes/xempx/crate64.md2 \ data1/maps/meshes/xempx/crate96.md2 \ data1/maps/meshes/xempx/crate.jpg \ data1/maps/meshes/xempx/crate_normal.jpg \ data1/maps/meshes/xempx/doorway1b.jpg \ data1/maps/meshes/xempx/doorway1b.md2 \ data1/maps/meshes/xempx/floorfan.jpg \ data1/maps/meshes/xempx/floorfan.md2 \ data1/maps/meshes/xempx/floorfan_normal.jpg \ data1/maps/meshes/xempx/lightbomb45.md2 \ data1/maps/meshes/xempx/lightbomb_fx.tga \ data1/maps/meshes/xempx/lightbomb.jpg \ data1/maps/meshes/xempx/lightbomb.md2 \ data1/maps/meshes/xempx/lightbomb_normal.jpg \ data1/maps/meshes/xempx/powercore_fx.tga \ data1/maps/meshes/xempx/powercore.jpg \ data1/maps/meshes/xempx/powercore.md2 \ data1/maps/meshes/xempx/powercore_normal.jpg \ data1/maps/meshes/xempx/powercorering.md2 \ data1/maps/meshes/xempx/qtube2.md2 \ data1/maps/meshes/xempx/qtube.jpg \ data1/maps/meshes/xempx/qtube.md2 \ data1/maps/meshes/xempx/qtube_normal.jpg \ data1/maps/meshes/xempx/tripes1.jpg \ data1/maps/meshes/xempx/tripes1.md2 \ data1/maps/meshes/xempx/tripes1_normal.jpg \ data1/maps/scripts/aoa-atlantis.mus \ data1/maps/scripts/aoa-corrosion.fog \ data1/maps/scripts/aoa-corrosion.mus \ data1/maps/scripts/aoa-frost2k9.fog \ data1/maps/scripts/aoa-frost2k9.mus \ data1/maps/scripts/aoa-morpheus.mus \ data1/maps/scripts/aoa-zorn.mus \ data1/maps/scripts/cp-ribeye.mus \ data1/maps/scripts/ctf-corrosion.fog \ data1/maps/scripts/ctf-corrosion.mus \ data1/maps/scripts/ctf-cryogenic.fog \ data1/maps/scripts/ctf-cryogenic.mus \ data1/maps/scripts/ctf-europa2k8.mus \ data1/maps/scripts/ctf-extermination.fog \ data1/maps/scripts/ctf-extermination.mus \ data1/maps/scripts/ctf-frostbyte.fog \ data1/maps/scripts/ctf-frostbyte.mus \ data1/maps/scripts/ctf-goregrinder.fog \ data1/maps/scripts/ctf-goregrinder.mus \ data1/maps/scripts/ctf-invasion.fog \ data1/maps/scripts/ctf-invasion.mus \ data1/maps/scripts/ctf-oblivion.fog \ data1/maps/scripts/ctf-oblivion.mus \ data1/maps/scripts/ctf-purgatory.fog \ data1/maps/scripts/ctf-purgatory.mus \ data1/maps/scripts/ctf-titan2k8.mus \ data1/maps/scripts/ctf-vesuvius2k11.fog \ data1/maps/scripts/ctf-vesuvius2k11.mus \ data1/maps/scripts/ctf-violator.fog \ data1/maps/scripts/ctf-violator.mus \ data1/maps/scripts/ctf-zion2k9.mus \ data1/maps/scripts/db-chromium.mus \ data1/maps/scripts/db-icarus.mus \ data1/maps/scripts/db-vesuvius.fog \ data1/maps/scripts/db-vesuvius.mus \ data1/maps/scripts/dm-atlantis2k8.mus \ data1/maps/scripts/dm-annihilation.fog \ data1/maps/scripts/dm-annihilation.mus \ data1/maps/scripts/dm-babel2k11.fog \ data1/maps/scripts/dm-babel2k11.mus \ data1/maps/scripts/dm-bloodfactory2k12.fog \ data1/maps/scripts/dm-bloodfactory2k12.mus \ data1/maps/scripts/dm-chasmatic2k9.fog \ data1/maps/scripts/dm-chasmatic2k9.mus \ data1/maps/scripts/dm-command2k9.fog \ data1/maps/scripts/dm-command2k9.mus \ data1/maps/scripts/dm-corrosion.fog \ data1/maps/scripts/dm-corrosion.mus \ data1/maps/scripts/dm-crucible2k12.fog \ data1/maps/scripts/dm-crucible2k12.mus \ data1/maps/scripts/dm-deathray.fog \ data1/maps/scripts/dm-deathray.mus \ data1/maps/scripts/dm-deimos2k9.mus \ data1/maps/scripts/dm-dismal2k11.fog \ data1/maps/scripts/dm-dismal2k11.mus \ data1/maps/scripts/dm-downfall.fog \ data1/maps/scripts/dm-downfall.mus \ data1/maps/scripts/dm-dynamo2k12.fog \ data1/maps/scripts/dm-dynamo2k12.mus \ data1/maps/scripts/dm-eternal.fog \ data1/maps/scripts/dm-eternal.mus \ data1/maps/scripts/dm-extermination.fog \ data1/maps/scripts/dm-extermination.mus \ data1/maps/scripts/dm-furious2k8.fog \ data1/maps/scripts/dm-furious2k8.mus \ data1/maps/scripts/dm-goregrinder.fog \ data1/maps/scripts/dm-goregrinder.mus \ data1/maps/scripts/dm-horus.mus \ data1/maps/scripts/dm-impact.fog \ data1/maps/scripts/dm-impact.mus \ data1/maps/scripts/dm-invasion.fog \ data1/maps/scripts/dm-invasion.mus \ data1/maps/scripts/dm-leviathan2k12.fog \ data1/maps/scripts/dm-leviathan2k12.mus \ data1/maps/scripts/dm-liberation.fog \ data1/maps/scripts/dm-liberation.mus \ data1/maps/scripts/dm-neptune.mus \ data1/maps/scripts/dm-oblivion.fog \ data1/maps/scripts/dm-oblivion.mus \ data1/maps/scripts/dm-omega2k8.mus \ data1/maps/scripts/dm-purgatory.fog \ data1/maps/scripts/dm-purgatory.mus \ data1/maps/scripts/dm-saucer2k9.fog \ data1/maps/scripts/dm-saucer2k9.mus \ data1/maps/scripts/dm-turbo2k8.fog \ data1/maps/scripts/dm-turbo2k8.mus \ data1/maps/scripts/dm-vesuvius2k11.fog \ data1/maps/scripts/dm-vesuvius2k11.mus \ data1/maps/scripts/dm-violator2k11.mus \ data1/maps/scripts/dm-violator2k11.fog \ data1/maps/scripts/dm-warmachine2k10.fog \ data1/maps/scripts/dm-warmachine2k10.mus \ data1/maps/scripts/dm-zorn2k11.fog \ data1/maps/scripts/dm-zorn2k11.mus \ data1/maps/scripts/dm-zion2k9.mus \ data1/maps/scripts/tac-extermination.fog \ data1/maps/scripts/tac-extermination.mus \ data1/maps/scripts/tca-corrosion.fog \ data1/maps/scripts/tca-corrosion.mus \ data1/maps/scripts/tca-cryogenic.fog \ data1/maps/scripts/tca-cryogenic.mus \ data1/maps/scripts/tca-extermination.fog \ data1/maps/scripts/tca-extermination.mus \ data1/maps/scripts/tca-purgatory.fog \ data1/maps/scripts/tca-purgatory.mus \ data1/maps/scripts/tca-zion2k9.mus modelsdir = $(pkgdatadir) nobase_nodist_models_DATA = \ data1/models/cow/helmet.md2 \ data1/models/cow/skin.tga \ data1/models/cow/tris.md2 \ data1/models/items/adrenaline/skin_normal.tga \ data1/models/items/adrenaline/skin.tga \ data1/models/items/adrenaline/tris.md2 \ data1/models/items/ammo/bullets/medium/skin.tga \ data1/models/items/ammo/bullets/medium/tris.md2 \ data1/models/items/ammo/cells/medium/cell.tga \ data1/models/items/ammo/cells/medium/tris.md2 \ data1/models/items/ammo/grenades/medium/skin.tga \ data1/models/items/ammo/grenades/medium/tris.md2 \ data1/models/items/ammo/rockets/medium/skin.tga \ data1/models/items/ammo/rockets/medium/tris.md2 \ data1/models/items/ammo/shells/medium/skin.tga \ data1/models/items/ammo/shells/medium/tris.md2 \ data1/models/items/ammo/skin_normal.tga \ data1/models/items/armor/body/skin.jpg \ data1/models/items/armor/body/tris.md2 \ data1/models/items/armor/combat/skin.jpg \ data1/models/items/armor/combat/tris.md2 \ data1/models/items/armor/jacket/skin.jpg \ data1/models/items/armor/jacket/tris.md2 \ data1/models/items/armor/shard/skin_normal.tga \ data1/models/items/armor/shard/skin.tga \ data1/models/items/armor/shard/tris.md2 \ data1/models/items/armor/skin_fx.tga \ data1/models/items/armor/skin_normal.tga \ data1/models/items/flags/blue.tga \ data1/models/items/flags/flag1.md2 \ data1/models/items/flags/flag2.md2 \ data1/models/items/flags/red.tga \ data1/models/items/haste/skin.jpg \ data1/models/items/haste/skin_fx.tga \ data1/models/items/haste/skin_normal.jpg \ data1/models/items/haste/tris.md2 \ data1/models/items/healing/globe/skin.tga \ data1/models/items/healing/globe/tris.md2 \ data1/models/items/healing/health_normal.tga \ data1/models/items/healing/large/skin.tga \ data1/models/items/healing/large/tris.md2 \ data1/models/items/healing/medium/skin.tga \ data1/models/items/healing/medium/tris.md2 \ data1/models/items/healing/small/skin.tga \ data1/models/items/healing/small/tris.md2 \ data1/models/items/invulner/skin_fx.tga \ data1/models/items/invulner/skin.jpg \ data1/models/items/invulner/skin_normal.jpg \ data1/models/items/invulner/tris.md2 \ data1/models/items/mega_h/skin_fx.tga \ data1/models/items/mega_h/skin.jpg \ data1/models/items/mega_h/skin_normal.jpg \ data1/models/items/mega_h/tris.md2 \ data1/models/items/quaddama/skin_normal.tga \ data1/models/items/quaddama/skin.tga \ data1/models/items/quaddama/tris.md2 \ data1/models/items/quaddama/unit.md2 \ data1/models/items/sproing/skin.jpg \ data1/models/items/sproing/skin_fx.tga \ data1/models/items/sproing/skin_normal.jpg \ data1/models/items/sproing/tris.md2 \ data1/models/misc/deathray/deathray.md2 \ data1/models/misc/deathray/deathray_normal.tga \ data1/models/misc/deathray/deathray.tga \ data1/models/misc/electrode/cover.md2 \ data1/models/misc/electrode/electrode.tga \ data1/models/misc/electrode/tris.md2 \ data1/models/misc/lamp2/lamp2.tga \ data1/models/misc/lamp2/tris.md2 \ data1/models/misc/lamp/lamp.tga \ data1/models/misc/lamp/tris.md2 \ data1/models/misc/pod/pod.tga \ data1/models/misc/pod/tris.md2 \ data1/models/misc/receptor/bulb.md2 \ data1/models/misc/receptor/receptor.tga \ data1/models/misc/receptor/tris.md2 \ data1/models/misc/scope/cover.md2 \ data1/models/misc/scope/scope.tga \ data1/models/misc/scope/tris.md2 \ data1/models/misc/spiderpod/helmet.iqm \ data1/models/misc/spiderpod/helmet.md2 \ data1/models/misc/spiderpod/skin.tga \ data1/models/misc/spiderpod/spider_fx.tga \ data1/models/misc/spiderpod/spider.jpg \ data1/models/misc/spiderpod/spider_normal.jpg \ data1/models/misc/spiderpod/tris.iqm \ data1/models/misc/spiderpod/tris.md2 \ data1/models/misc/spiderpod/tris.skin \ data1/models/misc/tube/cover.md2 \ data1/models/misc/tube/tris.md2 \ data1/models/misc/tube/tube.tga \ data1/models/objects/blank/skin.tga \ data1/models/objects/blank/tris.md2 \ data1/models/objects/brass/skin.jpg \ data1/models/objects/brass/tris.md2 \ data1/models/objects/debris1/skin.tga \ data1/models/objects/debris1/tris.md2 \ data1/models/objects/debris2/skin.tga \ data1/models/objects/debris2/tris.md2 \ data1/models/objects/debris3/skin.tga \ data1/models/objects/debris3/tris.md2 \ data1/models/objects/dmspot/skin_normal.tga \ data1/models/objects/dmspot/skin.tga \ data1/models/objects/dmspot/tris.md2 \ data1/models/objects/electroball/skin_fx.tga \ data1/models/objects/electroball/skin.jpg \ data1/models/objects/electroball/skin_normal.jpg \ data1/models/objects/electroball/tris.md2 \ data1/models/objects/fireball/skin.tga \ data1/models/objects/fireball/tris.md2 \ data1/models/objects/gibs/mart_gut/skin.jpg \ data1/models/objects/gibs/mart_gut/tris.md2 \ data1/models/objects/gibs/skin_normal.jpg \ data1/models/objects/gibs/sm_meat/skin.jpg \ data1/models/objects/gibs/sm_meat/tris.md2 \ data1/models/objects/icon/icon.jpg \ data1/models/objects/icon/icon_normal.jpg \ data1/models/objects/icon/tris.md2 \ data1/models/objects/laser/skin.tga \ data1/models/objects/laser/tris.md2 \ data1/models/objects/rocket/skin.tga \ data1/models/objects/rocket/tris.md2 \ data1/models/objects/spider/helmet.iqm \ data1/models/objects/spider/helmet.md2 \ data1/models/objects/spider/tris.iqm \ data1/models/objects/spider/tris.md2 \ data1/models/objects/spider/tris.skin \ data1/models/objects/spud/skin_fx2.tga \ data1/models/objects/spud/skin_fx.tga \ data1/models/objects/spud/skin_normal.jpg \ data1/models/objects/spud/skin.tga \ data1/models/objects/spud/spud.mdo \ data1/models/objects/spud/tris.md2 \ data1/models/tactical/abackupgen_fx.tga \ data1/models/tactical/abackupgen.jpg \ data1/models/tactical/abackupgen_normal.jpg \ data1/models/tactical/abomb_fx.tga \ data1/models/tactical/abomb.jpg \ data1/models/tactical/abomb_normal.tga \ data1/models/tactical/acomputer_fx.tga \ data1/models/tactical/acomputer_normal.tga \ data1/models/tactical/acomputer.tga \ data1/models/tactical/alaser_fx.tga \ data1/models/tactical/alaser.jpg \ data1/models/tactical/alien_backupgen.iqm \ data1/models/tactical/alien_backupgen.skin \ data1/models/tactical/alien_bomb.iqm \ data1/models/tactical/alien_bomb.skin \ data1/models/tactical/alien_computer.iqm \ data1/models/tactical/alien_computer.skin \ data1/models/tactical/alien_laser.iqm \ data1/models/tactical/alien_laser.md2 \ data1/models/tactical/alien_laser.skin \ data1/models/tactical/alien_powersrc.iqm \ data1/models/tactical/alien_powersrc.skin \ data1/models/tactical/ammopad.md2 \ data1/models/tactical/apowersrc_fx.tga \ data1/models/tactical/apowersrc.jpg \ data1/models/tactical/apowersrc_normal.jpg \ data1/models/tactical/hbackupgen.jpg \ data1/models/tactical/hbackupgen_normal.jpg \ data1/models/tactical/hbomb_fx.tga \ data1/models/tactical/hbomb.jpg \ data1/models/tactical/hbomb_normal.jpg \ data1/models/tactical/hcomputer_fx.tga \ data1/models/tactical/hcomputer.jpg \ data1/models/tactical/hcomputer_normal.jpg \ data1/models/tactical/hlaser_fx.tga \ data1/models/tactical/hlaser.jpg \ data1/models/tactical/hpowersrc_fx.tga \ data1/models/tactical/hpowersrc.jpg \ data1/models/tactical/hpowersrc_normal.jpg \ data1/models/tactical/human_backupgen.iqm \ data1/models/tactical/human_backupgen.skin \ data1/models/tactical/human_bomb.iqm \ data1/models/tactical/human_bomb.skin \ data1/models/tactical/human_computer.iqm \ data1/models/tactical/human_computer.skin \ data1/models/tactical/human_laser.iqm \ data1/models/tactical/human_laser.md2 \ data1/models/tactical/human_laser.skin \ data1/models/tactical/human_powersrc.iqm \ data1/models/tactical/human_powersrc.skin \ data1/models/tactical/laser_normal.jpg \ data1/models/weapons/g_bfg/tris.md2 \ data1/models/weapons/g_chain/tris.md2 \ data1/models/weapons/g_hyperb/cover.md2 \ data1/models/weapons/g_hyperb/tris.md2 \ data1/models/weapons/g_launch/skin.tga \ data1/models/weapons/g_launch/tris.md2 \ data1/models/weapons/g_machn/tris.md2 \ data1/models/weapons/g_minderaser/tris.md2 \ data1/models/weapons/g_rail/tris.md2 \ data1/models/weapons/g_rocket/cover.md2 \ data1/models/weapons/g_rocket/tris.md2 \ data1/models/weapons/g_shotg2/tris.md2 \ data1/models/weapons/g_shotg/tris.md2 \ data1/models/weapons/v_alienblast/cover.md2 \ data1/models/weapons/v_alienblast/skin_fx.tga \ data1/models/weapons/v_alienblast/skin_normal.jpg \ data1/models/weapons/v_alienblast/skin.jpg \ data1/models/weapons/v_alienblast/tris.md2 \ data1/models/weapons/v_bfg/skin.jpg \ data1/models/weapons/v_bfg/skin_normal.tga \ data1/models/weapons/v_bfg/tris.md2 \ data1/models/weapons/v_blast/cover.md2 \ data1/models/weapons/v_blast/skin.jpg \ data1/models/weapons/v_blast/skin_normal.tga \ data1/models/weapons/v_blast/tris.md2 \ data1/models/weapons/v_chain/skin.jpg \ data1/models/weapons/v_chain/skin_normal.tga \ data1/models/weapons/v_chain/tris.md2 \ data1/models/weapons/v_hyperb/cover.md2 \ data1/models/weapons/v_hyperb/disruptor.jpg \ data1/models/weapons/v_hyperb/disruptor_normal.tga \ data1/models/weapons/v_hyperb/tris.md2 \ data1/models/weapons/v_machn/tris.md2 \ data1/models/weapons/v_minderaser/minderaser.jpg \ data1/models/weapons/v_minderaser/minderaser_normal.tga \ data1/models/weapons/v_minderaser/tris.md2 \ data1/models/weapons/v_rail/beamgun.jpg \ data1/models/weapons/v_rail/beamgun_normal.tga \ data1/models/weapons/v_rail/tris.md2 \ data1/models/weapons/v_rocket/cover.md2 \ data1/models/weapons/v_rocket/skin.jpg \ data1/models/weapons/v_rocket/skin_normal.tga \ data1/models/weapons/v_rocket/tris.md2 \ data1/models/weapons/v_shotg2/skin.jpg \ data1/models/weapons/v_shotg2/skin_normal.tga \ data1/models/weapons/v_shotg2/tris.md2 \ data1/models/weapons/v_shotg/skin.jpg \ data1/models/weapons/v_shotg/skin_normal.tga \ data1/models/weapons/v_shotg/tris.md2 \ data1/models/weapons/v_violator/skin.jpg \ data1/models/weapons/v_violator/skin_normal.jpg \ data1/models/weapons/v_violator/tris.md2 \ data1/models/weapons/v_violator/violator.jpg \ data1/models/weapons/v_violator/violator_normal.tga particlesdir = $(pkgdatadir) nobase_nodist_particles_DATA = \ data1/particles/aflash.tga \ data1/particles/basic.tga \ data1/particles/beam.tga \ data1/particles/bflash.tga \ data1/particles/blood.tga \ data1/particles/bubble.tga \ data1/particles/bullethole2.tga \ data1/particles/bullethole.tga \ data1/particles/cflash.tga \ data1/particles/deathfield2.tga \ data1/particles/deathfield.tga \ data1/particles/dflash.tga \ data1/particles/disbeam1.tga \ data1/particles/disbeam2.tga \ data1/particles/disbeam3.tga \ data1/particles/explosion.tga \ data1/particles/flag.tga \ data1/particles/flare.tga \ data1/particles/leaderfield.tga \ data1/particles/leaf.tga \ data1/particles/logo.tga \ data1/particles/puff.tga \ data1/particles/reflect.tga \ data1/particles/r_explod_1.tga \ data1/particles/r_explod_2.tga \ data1/particles/r_explod_3.tga \ data1/particles/r_explod_4.tga \ data1/particles/r_explod_5.tga \ data1/particles/r_explod_6.tga \ data1/particles/r_explod_7.tga \ data1/particles/ring.tga \ data1/particles/ripples.tga \ data1/particles/sayicon.tga \ data1/particles/shell2_normal.tga \ data1/particles/shell2.tga \ data1/particles/shell.tga \ data1/particles/smoke_org.tga \ data1/particles/smoke.tga \ data1/particles/trash.tga \ data1/particles/voltage.tga \ data1/particles/watersplash.tga picsdir = $(pkgdatadir) nobase_nodist_pics_DATA = \ data1/pics/a_bullets.tga \ data1/pics/a_cells.tga \ data1/pics/a_grenades.tga \ data1/pics/anum_0.tga \ data1/pics/anum_1.tga \ data1/pics/anum_2.tga \ data1/pics/anum_3.tga \ data1/pics/anum_4.tga \ data1/pics/anum_5.tga \ data1/pics/anum_6.tga \ data1/pics/anum_7.tga \ data1/pics/anum_8.tga \ data1/pics/anum_9.tga \ data1/pics/anum_minus.tga \ data1/pics/a_rockets.tga \ data1/pics/a_shells.tga \ data1/pics/a_slugs.tga \ data1/pics/backtile.pcx \ data1/pics/bar_background.tga \ data1/pics/bar_loading.tga \ data1/pics/beamgun.tga \ data1/pics/blaster.tga \ data1/pics/blood_ring.tga \ data1/pics/blueplayerbox.tga \ data1/pics/bomber.tga \ data1/pics/bots/enforcer/blue_i.jpg \ data1/pics/bots/enforcer/default_i.jpg \ data1/pics/bots/enforcer/red_i.jpg \ data1/pics/bots/enforcer/stryker_i.jpg \ data1/pics/bots/martiancyborg/blue_i.jpg \ data1/pics/bots/martiancyborg/default_i.jpg \ data1/pics/bots/martiancyborg/red_i.jpg \ data1/pics/bots/martianenforcer/blue_i.jpg \ data1/pics/bots/martianenforcer/default_i.jpg \ data1/pics/bots/martianenforcer/gamara_i.jpg \ data1/pics/bots/martianenforcer/red_i.jpg \ data1/pics/ch1.tga \ data1/pics/ch2.tga \ data1/pics/ch3.tga \ data1/pics/chaingun.tga \ data1/pics/colormap.pcx \ data1/pics/conback.tga \ data1/pics/conchars.tga \ data1/pics/crosshairs/alien2a.tga \ data1/pics/crosshairs/alien2b.tga \ data1/pics/crosshairs/alien2.tga \ data1/pics/crosshairs/alien.tga \ data1/pics/crosshairs/chexcross.tga \ data1/pics/crosshairs/dot1.tga \ data1/pics/crosshairs/hardcorech.tga \ data1/pics/crosshairs/havoc2.tga \ data1/pics/crosshairs/havoc3.tga \ data1/pics/crosshairs/havoc.tga \ data1/pics/crosshairs/intimidator2.tga \ data1/pics/crosshairs/intimidator3.tga \ data1/pics/crosshairs/intimidator.tga \ data1/pics/crosshairs/mechano.tga \ data1/pics/crosshairs/ncool.tga \ data1/pics/crosshairs/nile2.tga \ data1/pics/crosshairs/nile3.tga \ data1/pics/crosshairs/nile.tga \ data1/pics/crosshairs/rage_cross.tga \ data1/pics/crosshairs/rgb.tga \ data1/pics/crosshairs/robot.tga \ data1/pics/crosshairs/sniper.tga \ data1/pics/crosshairs/sungod.tga \ data1/pics/crosshairs/tech2.tga \ data1/pics/crosshairs/tech.tga \ data1/pics/crosshairs/transcircle.tga \ data1/pics/crosshairs/vista.tga \ data1/pics/ctf1.tga \ data1/pics/ctf2.tga \ data1/pics/disruptor.tga \ data1/pics/dnarrow.tga \ data1/pics/flamethrower.tga \ data1/pics/grapple.tga \ data1/pics/help.tga \ data1/pics/hover.tga \ data1/pics/hud_bomber_fx.tga \ data1/pics/hud_bomber.tga \ data1/pics/hud_hover_fx.tga \ data1/pics/hud_hover.tga \ data1/pics/hud_strafer_fx.tga \ data1/pics/hud_strafer.tga \ data1/pics/huds/20061.tga \ data1/pics/huds/20062.tga \ data1/pics/huds/20071.tga \ data1/pics/huds/20072.tga \ data1/pics/huds/8bit1.tga \ data1/pics/huds/8bit2.tga \ data1/pics/huds/alien1.tga \ data1/pics/huds/alien2.tga \ data1/pics/huds/alienblood1.tga \ data1/pics/huds/alienblood2.tga \ data1/pics/huds/blood1.tga \ data1/pics/huds/blood2.tga \ data1/pics/huds/classic1.tga \ data1/pics/huds/classic2.tga \ data1/pics/huds/cleanblue1.tga \ data1/pics/huds/cleanblue2.tga \ data1/pics/huds/cleangreen1.tga \ data1/pics/huds/cleangreen2.tga \ data1/pics/huds/cleanred1.tga \ data1/pics/huds/cleanred2.tga \ data1/pics/huds/corpse1.tga \ data1/pics/huds/corpse2.tga \ data1/pics/huds/cpu1.tga \ data1/pics/huds/cpu2.tga \ data1/pics/huds/freezy1.tga \ data1/pics/huds/freezy2.tga \ data1/pics/huds/gtv1.tga \ data1/pics/huds/gtv2.tga \ data1/pics/huds/marscreen1.tga \ data1/pics/huds/marscreen2.tga \ data1/pics/huds/mechanic1.tga \ data1/pics/huds/mechanic2.tga \ data1/pics/huds/nki_dark1.tga \ data1/pics/huds/nki_dark2.tga \ data1/pics/huds/nki_darkb1.tga \ data1/pics/huds/nki_darkb2.tga \ data1/pics/huds/oldskool1.tga \ data1/pics/huds/oldskool2.tga \ data1/pics/huds/retro1.tga \ data1/pics/huds/retro2.tga \ data1/pics/huds/talon1.tga \ data1/pics/huds/talon2.tga \ data1/pics/huds/terminal-blue1.tga \ data1/pics/huds/terminal-blue2.tga \ data1/pics/huds/terminal-green1.tga \ data1/pics/huds/terminal-green2.tga \ data1/pics/huds/terminal-purple1.tga \ data1/pics/huds/terminal-purple2.tga \ data1/pics/huds/terminal-red1.tga \ data1/pics/huds/terminal-red2.tga \ data1/pics/huds/therock1.tga \ data1/pics/huds/therock2.tga \ data1/pics/i_beamgun.tga \ data1/pics/i_bodyarmor.tga \ data1/pics/i_chaingun.tga \ data1/pics/i_combatarmor.tga \ data1/pics/i_disruptor.tga \ data1/pics/i_flag1.tga \ data1/pics/i_flag2.tga \ data1/pics/i_flamegun.tga \ data1/pics/i_health.tga \ data1/pics/i_jacketarmor.tga \ data1/pics/i_minderaser.tga \ data1/pics/inventory.tga \ data1/pics/i_rocketlauncher.tga \ data1/pics/i_score.tga \ data1/pics/i_smartgun.tga \ data1/pics/i_tactical.tga \ data1/pics/i_team1.tga \ data1/pics/i_team2.tga \ data1/pics/i_vaporizer.tga \ data1/pics/m_bots.tga \ data1/pics/m_controls.tga \ data1/pics/m_cursor0.tga \ data1/pics/m_dmoptions.tga \ data1/pics/menu_back.jpg \ data1/pics/menu_back_fx.tga \ data1/pics/m_irc.tga \ data1/pics/m_joinserver.tga \ data1/pics/m_main_credits.tga \ data1/pics/m_main_credits_fx.tga \ data1/pics/m_main_credits_sel.tga \ data1/pics/m_main_game_fx.tga \ data1/pics/m_main_game_sel.tga \ data1/pics/m_main_game.tga \ data1/pics/m_main_host_fx.tga \ data1/pics/m_main_host_sel.tga \ data1/pics/m_main_host.tga \ data1/pics/m_main_irc_fx.tga \ data1/pics/m_main_irc_sel.tga \ data1/pics/m_main_irc.tga \ data1/pics/m_main_join_fx.tga \ data1/pics/m_main_join_sel.tga \ data1/pics/m_main_join.tga \ data1/pics/m_main_mont0.tga \ data1/pics/m_main_mont1.tga \ data1/pics/m_main_mont2.tga \ data1/pics/m_main_mont3.tga \ data1/pics/m_main_mont4.tga \ data1/pics/m_main_mont5.tga \ data1/pics/m_main_options_fx.tga \ data1/pics/m_main_options_sel.tga \ data1/pics/m_main_options.tga \ data1/pics/m_main_player_fx.tga \ data1/pics/m_main_player_sel.tga \ data1/pics/m_main_player.tga \ data1/pics/m_main_quit_fx.tga \ data1/pics/m_main_quit_sel.tga \ data1/pics/m_main_quit.tga \ data1/pics/m_main_tactical.tga \ data1/pics/m_main.tga \ data1/pics/m_main_video_fx.tga \ data1/pics/m_main_video_sel.tga \ data1/pics/m_main_video.tga \ data1/pics/m_mouse_cursor.tga \ data1/pics/m_mutators.tga \ data1/pics/m_options.tga \ data1/pics/m_player.tga \ data1/pics/m_quit.tga \ data1/pics/m_single.tga \ data1/pics/m_startserver.tga \ data1/pics/m_tactical.tga \ data1/pics/m_video.tga \ data1/pics/menu/button_border_end.tga \ data1/pics/menu/button_border.tga \ data1/pics/menu/dnarrow.tga \ data1/pics/menu/field_cursor.tga \ data1/pics/menu/icon_border.tga \ data1/pics/menu/m_background.tga \ data1/pics/menu/m_bottomcorner.tga \ data1/pics/menu/m_bottom.tga \ data1/pics/menu/midarrow.tga \ data1/pics/menu/m_side.tga \ data1/pics/menu/m_topcorner.tga \ data1/pics/menu/m_top.tga \ data1/pics/menu/on.tga \ data1/pics/menu/radio_border.tga \ data1/pics/menu/scroll_border_end.tga \ data1/pics/menu/scroll_border.tga \ data1/pics/menu/scroll_cursor_end.tga \ data1/pics/menu/scroll_cursor.tga \ data1/pics/menu/slide_border_end.tga \ data1/pics/menu/slide_border.tga \ data1/pics/menu/slide_cursor_end.tga \ data1/pics/menu/slide_cursor.tga \ data1/pics/menu/sm_background.tga \ data1/pics/menu/sm_bottomcorner.tga \ data1/pics/menu/sm_bottom.tga \ data1/pics/menu/sm_side.tga \ data1/pics/menu/sm_topcorner.tga \ data1/pics/menu/sm_top.tga \ data1/pics/menu/uparrow.tga \ data1/pics/net.tga \ data1/pics/num_0.tga \ data1/pics/num_1.tga \ data1/pics/num_2.tga \ data1/pics/num_3.tga \ data1/pics/num_4.tga \ data1/pics/num_5.tga \ data1/pics/num_6.tga \ data1/pics/num_7.tga \ data1/pics/num_8.tga \ data1/pics/num_9.tga \ data1/pics/num_minus.tga \ data1/pics/p_adrenaline.tga \ data1/pics/p_body.tga \ data1/pics/p_combat.tga \ data1/pics/p_haste.tga \ data1/pics/p_health.tga \ data1/pics/p_invis.tga \ data1/pics/p_invulnerability.tga \ data1/pics/p_jacket.tga \ data1/pics/playerbox.tga \ data1/pics/p_powered.tga \ data1/pics/p_quad.tga \ data1/pics/p_rewardpts.tga \ data1/pics/p_shard.tga \ data1/pics/p_sproing.tga \ data1/pics/redplayerbox.tga \ data1/pics/rocketlauncher.tga \ data1/pics/sbfctf1.tga \ data1/pics/sbfctf2.tga \ data1/pics/smartgun.tga \ data1/pics/statbox.tga \ data1/pics/strafer.tga \ data1/pics/tag1.tga \ data1/pics/tag2.tga \ data1/pics/team1.tga \ data1/pics/team2.tga \ data1/pics/timer.tga \ data1/pics/uparrow.tga \ data1/pics/vaporizor.tga \ data1/pics/violator.tga \ data1/pics/votebox.tga \ data1/pics/w_bfg.tga \ data1/pics/w_blaster.tga \ data1/pics/w_chaingun.tga \ data1/pics/w_glauncher.tga \ data1/pics/w_hyperblaster.tga \ data1/pics/w_machinegun.tga \ data1/pics/w_railgun.tga \ data1/pics/w_rlauncher.tga \ data1/pics/w_shotgun.tga \ data1/pics/w_sshotgun.tga \ data1/pics/zoomscope1.tga \ data1/pics/zoomscope2.tga \ data1/pics/zoomscope3.tga playersdir = $(pkgdatadir) nobase_nodist_players_DATA = \ data1/players/commander/blue_i.jpg \ data1/players/commander/blue.jpg \ data1/players/commander/bump1.wav \ data1/players/commander/death1.wav \ data1/players/commander/death2.wav \ data1/players/commander/death3.wav \ data1/players/commander/death4.wav \ data1/players/commander/default_i.jpg \ data1/players/commander/default.jpg \ data1/players/commander/default_normal.tga \ data1/players/commander/drown1.wav \ data1/players/commander/fall1.wav \ data1/players/commander/fall2.wav \ data1/players/commander/gurp1.wav \ data1/players/commander/gurp2.wav \ data1/players/commander/human \ data1/players/commander/jump1.wav \ data1/players/commander/lod1.iqm \ data1/players/commander/lod1.md2 \ data1/players/commander/lod1.rgd \ data1/players/commander/lod2.iqm \ data1/players/commander/lod2.md2 \ data1/players/commander/lod2.rgd \ data1/players/commander/pain100_1.wav \ data1/players/commander/pain100_2.wav \ data1/players/commander/pain25_1.wav \ data1/players/commander/pain25_2.wav \ data1/players/commander/pain50_1.wav \ data1/players/commander/pain50_2.wav \ data1/players/commander/pain75_1.wav \ data1/players/commander/pain75_2.wav \ data1/players/commander/red_i.jpg \ data1/players/commander/red.jpg \ data1/players/commander/tris.iqm \ data1/players/commander/tris.md2 \ data1/players/commander/tris.rgd \ data1/players/commander/tron2_i.jpg \ data1/players/commander/tron2.jpg \ data1/players/commander/tron3_i.jpg \ data1/players/commander/tron3.jpg \ data1/players/commander/tron_i.jpg \ data1/players/commander/tron.jpg \ data1/players/commander/tron_normal.tga \ data1/players/commander/w_bfg.iqm \ data1/players/commander/w_bfg.md2 \ data1/players/commander/w_bfg.skin \ data1/players/commander/w_blaster.iqm \ data1/players/commander/w_blaster.md2 \ data1/players/commander/w_blaster.skin \ data1/players/commander/w_chaingun.iqm \ data1/players/commander/w_chaingun.md2 \ data1/players/commander/w_chaingun.skin \ data1/players/commander/weapon.iqm \ data1/players/commander/weapon.jpg \ data1/players/commander/weapon.md2 \ data1/players/commander/weapon.skin \ data1/players/commander/w_hyperblaster.iqm \ data1/players/commander/w_hyperblaster.md2 \ data1/players/commander/w_hyperblaster.skin \ data1/players/commander/w_machinegun.iqm \ data1/players/commander/w_machinegun.md2 \ data1/players/commander/w_machinegun.skin \ data1/players/commander/w_minderaser.iqm \ data1/players/commander/w_minderaser.md2 \ data1/players/commander/w_minderaser.skin \ data1/players/commander/w_railgun.iqm \ data1/players/commander/w_railgun.md2 \ data1/players/commander/w_railgun.skin \ data1/players/commander/w_rlauncher.iqm \ data1/players/commander/w_rlauncher.md2 \ data1/players/commander/w_rlauncher.skin \ data1/players/commander/w_shotgun.iqm \ data1/players/commander/w_shotgun.md2 \ data1/players/commander/w_shotgun.skin \ data1/players/commander/w_sshotgun.iqm \ data1/players/commander/w_sshotgun.md2 \ data1/players/commander/w_sshotgun.skin \ data1/players/commander/w_violator.iqm \ data1/players/commander/w_violator.md2 \ data1/players/commander/w_violator.skin \ data1/players/enforcer/arm.md2 \ data1/players/enforcer/blue_i.jpg \ data1/players/enforcer/blue.jpg \ data1/players/enforcer/body.md2 \ data1/players/enforcer/bump1.wav \ data1/players/enforcer/death1.wav \ data1/players/enforcer/death2.wav \ data1/players/enforcer/death3.wav \ data1/players/enforcer/death4.wav \ data1/players/enforcer/default_i.jpg \ data1/players/enforcer/default.jpg \ data1/players/enforcer/default_normal.tga \ data1/players/enforcer/drown1.wav \ data1/players/enforcer/fall1.wav \ data1/players/enforcer/fall2.wav \ data1/players/enforcer/gurp1.wav \ data1/players/enforcer/gurp2.wav \ data1/players/enforcer/head.md2 \ data1/players/enforcer/helmet.iqm \ data1/players/enforcer/helmet.md2 \ data1/players/enforcer/human \ data1/players/enforcer/jump1.wav \ data1/players/enforcer/leg.md2 \ data1/players/enforcer/lod1.iqm \ data1/players/enforcer/lod1.md2 \ data1/players/enforcer/lod1.rgd \ data1/players/enforcer/lod2.iqm \ data1/players/enforcer/lod2.md2 \ data1/players/enforcer/lod2.rgd \ data1/players/enforcer/pain100_1.wav \ data1/players/enforcer/pain100_2.wav \ data1/players/enforcer/pain25_1.wav \ data1/players/enforcer/pain25_2.wav \ data1/players/enforcer/pain50_1.wav \ data1/players/enforcer/pain50_2.wav \ data1/players/enforcer/pain75_1.wav \ data1/players/enforcer/pain75_2.wav \ data1/players/enforcer/red_i.jpg \ data1/players/enforcer/red.jpg \ data1/players/enforcer/stryker_i.jpg \ data1/players/enforcer/stryker.jpg \ data1/players/enforcer/tris.iqm \ data1/players/enforcer/tris.md2 \ data1/players/enforcer/tris.rgd \ data1/players/enforcer/tron2_i.jpg \ data1/players/enforcer/tron2.jpg \ data1/players/enforcer/tron3_i.jpg \ data1/players/enforcer/tron3.jpg \ data1/players/enforcer/tron_i.jpg \ data1/players/enforcer/tron.jpg \ data1/players/enforcer/tron_normal.tga \ data1/players/enforcer/usegibs \ data1/players/enforcer/w_bfg.iqm \ data1/players/enforcer/w_bfg.md2 \ data1/players/enforcer/w_bfg.skin \ data1/players/enforcer/w_blaster.iqm \ data1/players/enforcer/w_blaster.md2 \ data1/players/enforcer/w_blaster.skin \ data1/players/enforcer/w_chaingun.iqm \ data1/players/enforcer/w_chaingun.md2 \ data1/players/enforcer/w_chaingun.skin \ data1/players/enforcer/weapon.iqm \ data1/players/enforcer/weapon.jpg \ data1/players/enforcer/weapon.md2 \ data1/players/enforcer/weapon.skin \ data1/players/enforcer/w_hyperblaster.iqm \ data1/players/enforcer/w_hyperblaster.md2 \ data1/players/enforcer/w_hyperblaster.skin \ data1/players/enforcer/w_machinegun.iqm \ data1/players/enforcer/w_machinegun.md2 \ data1/players/enforcer/w_machinegun.skin \ data1/players/enforcer/w_minderaser.iqm \ data1/players/enforcer/w_minderaser.md2 \ data1/players/enforcer/w_minderaser.skin \ data1/players/enforcer/w_railgun.iqm \ data1/players/enforcer/w_railgun.md2 \ data1/players/enforcer/w_railgun.skin \ data1/players/enforcer/w_rlauncher.iqm \ data1/players/enforcer/w_rlauncher.md2 \ data1/players/enforcer/w_rlauncher.skin \ data1/players/enforcer/w_shotgun.iqm \ data1/players/enforcer/w_shotgun.md2 \ data1/players/enforcer/w_shotgun.skin \ data1/players/enforcer/w_sshotgun.iqm \ data1/players/enforcer/w_sshotgun.md2 \ data1/players/enforcer/w_sshotgun.skin \ data1/players/enforcer/w_violator.iqm \ data1/players/enforcer/w_violator.md2 \ data1/players/enforcer/w_violator.skin \ data1/players/lauren/arm.md2 \ data1/players/lauren/blue_i.jpg \ data1/players/lauren/blue.jpg \ data1/players/lauren/body.md2 \ data1/players/lauren/bump1.wav \ data1/players/lauren/death1.wav \ data1/players/lauren/death2.wav \ data1/players/lauren/death3.wav \ data1/players/lauren/death4.wav \ data1/players/lauren/default_i.jpg \ data1/players/lauren/default.jpg \ data1/players/lauren/default_normal.tga \ data1/players/lauren/drown1.wav \ data1/players/lauren/fall1.wav \ data1/players/lauren/fall2.wav \ data1/players/lauren/gurp1.wav \ data1/players/lauren/gurp2.wav \ data1/players/lauren/head.md2 \ data1/players/lauren/human \ data1/players/lauren/jump1.wav \ data1/players/lauren/leg.md2 \ data1/players/lauren/lod1.iqm \ data1/players/lauren/lod1.rgd \ data1/players/lauren/lod2.iqm \ data1/players/lauren/lod2.rgd \ data1/players/lauren/pain100_1.wav \ data1/players/lauren/pain100_2.wav \ data1/players/lauren/pain25_1.wav \ data1/players/lauren/pain25_2.wav \ data1/players/lauren/pain50_1.wav \ data1/players/lauren/pain50_2.wav \ data1/players/lauren/pain75_1.wav \ data1/players/lauren/pain75_2.wav \ data1/players/lauren/red_i.jpg \ data1/players/lauren/red.jpg \ data1/players/lauren/tris.iqm \ data1/players/lauren/tris.md2 \ data1/players/lauren/tris.rgd \ data1/players/lauren/tron2_i.jpg \ data1/players/lauren/tron2.jpg \ data1/players/lauren/tron3_i.jpg \ data1/players/lauren/tron3.jpg \ data1/players/lauren/tron_i.jpg \ data1/players/lauren/tron.jpg \ data1/players/lauren/tron_normal.tga \ data1/players/lauren/usegibs \ data1/players/lauren/w_bfg.iqm \ data1/players/lauren/w_bfg.md2 \ data1/players/lauren/w_bfg.skin \ data1/players/lauren/w_blaster.iqm \ data1/players/lauren/w_blaster.md2 \ data1/players/lauren/w_blaster.skin \ data1/players/lauren/w_chaingun.iqm \ data1/players/lauren/w_chaingun.md2 \ data1/players/lauren/w_chaingun.skin \ data1/players/lauren/weapon.iqm \ data1/players/lauren/weapon.jpg \ data1/players/lauren/weapon.md2 \ data1/players/lauren/weapon.skin \ data1/players/lauren/w_hyperblaster.iqm \ data1/players/lauren/w_hyperblaster.md2 \ data1/players/lauren/w_hyperblaster.skin \ data1/players/lauren/w_machinegun.iqm \ data1/players/lauren/w_machinegun.md2 \ data1/players/lauren/w_machinegun.skin \ data1/players/lauren/w_minderaser.iqm \ data1/players/lauren/w_minderaser.md2 \ data1/players/lauren/w_minderaser.skin \ data1/players/lauren/w_railgun.iqm \ data1/players/lauren/w_railgun.md2 \ data1/players/lauren/w_railgun.skin \ data1/players/lauren/w_rlauncher.iqm \ data1/players/lauren/w_rlauncher.md2 \ data1/players/lauren/w_rlauncher.skin \ data1/players/lauren/w_shotgun.iqm \ data1/players/lauren/w_shotgun.md2 \ data1/players/lauren/w_shotgun.skin \ data1/players/lauren/w_sshotgun.iqm \ data1/players/lauren/w_sshotgun.md2 \ data1/players/lauren/w_sshotgun.skin \ data1/players/lauren/w_violator.iqm \ data1/players/lauren/w_violator.md2 \ data1/players/lauren/w_violator.skin \ data1/players/martiancyborg/blue_i.jpg \ data1/players/martiancyborg/blue.jpg \ data1/players/martiancyborg/bump1.wav \ data1/players/martiancyborg/death1.wav \ data1/players/martiancyborg/death2.wav \ data1/players/martiancyborg/death3.wav \ data1/players/martiancyborg/death4.wav \ data1/players/martiancyborg/default_i.jpg \ data1/players/martiancyborg/default.jpg \ data1/players/martiancyborg/default_normal.tga \ data1/players/martiancyborg/drown1.wav \ data1/players/martiancyborg/fall1.wav \ data1/players/martiancyborg/fall2.wav \ data1/players/martiancyborg/gurp1.wav \ data1/players/martiancyborg/gurp2.wav \ data1/players/martiancyborg/helmet.iqm \ data1/players/martiancyborg/helmet.md2 \ data1/players/martiancyborg/jump1.wav \ data1/players/martiancyborg/lod1.iqm \ data1/players/martiancyborg/lod1.md2 \ data1/players/martiancyborg/lod1.rgd \ data1/players/martiancyborg/lod2.iqm \ data1/players/martiancyborg/lod2.md2 \ data1/players/martiancyborg/lod2.rgd \ data1/players/martiancyborg/pain100_1.wav \ data1/players/martiancyborg/pain100_2.wav \ data1/players/martiancyborg/pain25_1.wav \ data1/players/martiancyborg/pain25_2.wav \ data1/players/martiancyborg/pain50_1.wav \ data1/players/martiancyborg/pain50_2.wav \ data1/players/martiancyborg/pain75_1.wav \ data1/players/martiancyborg/pain75_2.wav \ data1/players/martiancyborg/red_i.jpg \ data1/players/martiancyborg/red.jpg \ data1/players/martiancyborg/robot \ data1/players/martiancyborg/tris.iqm \ data1/players/martiancyborg/tris.md2 \ data1/players/martiancyborg/tris.rgd \ data1/players/martiancyborg/tron2_i.jpg \ data1/players/martiancyborg/tron2.jpg \ data1/players/martiancyborg/tron3_i.jpg \ data1/players/martiancyborg/tron3.jpg \ data1/players/martiancyborg/tron_i.jpg \ data1/players/martiancyborg/tron.jpg \ data1/players/martiancyborg/tron_normal.tga \ data1/players/martiancyborg/w_alienblaster.iqm \ data1/players/martiancyborg/w_alienblaster.skin \ data1/players/martiancyborg/w_bfg.iqm \ data1/players/martiancyborg/w_bfg.md2 \ data1/players/martiancyborg/w_bfg.skin \ data1/players/martiancyborg/w_blaster.iqm \ data1/players/martiancyborg/w_blaster.md2 \ data1/players/martiancyborg/w_blaster.skin \ data1/players/martiancyborg/w_chaingun.iqm \ data1/players/martiancyborg/w_chaingun.md2 \ data1/players/martiancyborg/w_chaingun.skin \ data1/players/martiancyborg/weapon.iqm \ data1/players/martiancyborg/weapon.jpg \ data1/players/martiancyborg/weapon.md2 \ data1/players/martiancyborg/weapon.skin \ data1/players/martiancyborg/w_hyperblaster.iqm \ data1/players/martiancyborg/w_hyperblaster.md2 \ data1/players/martiancyborg/w_hyperblaster.skin \ data1/players/martiancyborg/w_machinegun.iqm \ data1/players/martiancyborg/w_machinegun.md2 \ data1/players/martiancyborg/w_machinegun.skin \ data1/players/martiancyborg/w_minderaser.iqm \ data1/players/martiancyborg/w_minderaser.md2 \ data1/players/martiancyborg/w_minderaser.skin \ data1/players/martiancyborg/w_railgun.iqm \ data1/players/martiancyborg/w_railgun.md2 \ data1/players/martiancyborg/w_railgun.skin \ data1/players/martiancyborg/w_rlauncher.iqm \ data1/players/martiancyborg/w_rlauncher.md2 \ data1/players/martiancyborg/w_rlauncher.skin \ data1/players/martiancyborg/w_shotgun.iqm \ data1/players/martiancyborg/w_shotgun.md2 \ data1/players/martiancyborg/w_shotgun.skin \ data1/players/martiancyborg/w_sshotgun.iqm \ data1/players/martiancyborg/w_sshotgun.md2 \ data1/players/martiancyborg/w_sshotgun.skin \ data1/players/martiancyborg/w_violator.iqm \ data1/players/martiancyborg/w_violator.md2 \ data1/players/martiancyborg/w_violator.skin \ data1/players/martianenforcer/alien \ data1/players/martianenforcer/arm.md2 \ data1/players/martianenforcer/blue_i.jpg \ data1/players/martianenforcer/blue.jpg \ data1/players/martianenforcer/body.md2 \ data1/players/martianenforcer/bump1.wav \ data1/players/martianenforcer/death1.wav \ data1/players/martianenforcer/death2.wav \ data1/players/martianenforcer/death3.wav \ data1/players/martianenforcer/death4.wav \ data1/players/martianenforcer/default_i.jpg \ data1/players/martianenforcer/default.jpg \ data1/players/martianenforcer/default_normal.tga \ data1/players/martianenforcer/drown1.wav \ data1/players/martianenforcer/fall1.wav \ data1/players/martianenforcer/fall2.wav \ data1/players/martianenforcer/gamara_i.jpg \ data1/players/martianenforcer/gamara.jpg \ data1/players/martianenforcer/gamara_normal.tga \ data1/players/martianenforcer/gasp1.wav \ data1/players/martianenforcer/gasp2.wav \ data1/players/martianenforcer/gurp1.wav \ data1/players/martianenforcer/gurp2.wav \ data1/players/martianenforcer/head.md2 \ data1/players/martianenforcer/helmet.iqm \ data1/players/martianenforcer/helmet.md2 \ data1/players/martianenforcer/jump1.wav \ data1/players/martianenforcer/leg.md2 \ data1/players/martianenforcer/lod1.iqm \ data1/players/martianenforcer/lod1.md2 \ data1/players/martianenforcer/lod1.rgd \ data1/players/martianenforcer/lod2.iqm \ data1/players/martianenforcer/lod2.md2 \ data1/players/martianenforcer/lod2.rgd \ data1/players/martianenforcer/pain100_1.wav \ data1/players/martianenforcer/pain100_2.wav \ data1/players/martianenforcer/pain25_1.wav \ data1/players/martianenforcer/pain25_2.wav \ data1/players/martianenforcer/pain50_1.wav \ data1/players/martianenforcer/pain50_2.wav \ data1/players/martianenforcer/pain75_1.wav \ data1/players/martianenforcer/pain75_2.wav \ data1/players/martianenforcer/red_i.jpg \ data1/players/martianenforcer/red.jpg \ data1/players/martianenforcer/tris.iqm \ data1/players/martianenforcer/tris.md2 \ data1/players/martianenforcer/tris.rgd \ data1/players/martianenforcer/tron2_i.jpg \ data1/players/martianenforcer/tron2.jpg \ data1/players/martianenforcer/tron3_i.jpg \ data1/players/martianenforcer/tron3.jpg \ data1/players/martianenforcer/tron_i.jpg \ data1/players/martianenforcer/tron.jpg \ data1/players/martianenforcer/tron_normal.tga \ data1/players/martianenforcer/usegibs \ data1/players/martianenforcer/w_alienblaster.iqm \ data1/players/martianenforcer/w_alienblaster.skin \ data1/players/martianenforcer/w_bfg.iqm \ data1/players/martianenforcer/w_bfg.md2 \ data1/players/martianenforcer/w_bfg.skin \ data1/players/martianenforcer/w_blaster.iqm \ data1/players/martianenforcer/w_blaster.md2 \ data1/players/martianenforcer/w_blaster.skin \ data1/players/martianenforcer/w_chaingun.iqm \ data1/players/martianenforcer/w_chaingun.md2 \ data1/players/martianenforcer/w_chaingun.skin \ data1/players/martianenforcer/weapon.iqm \ data1/players/martianenforcer/weapon.jpg \ data1/players/martianenforcer/weapon.md2 \ data1/players/martianenforcer/weapon.skin \ data1/players/martianenforcer/w_hyperblaster.iqm \ data1/players/martianenforcer/w_hyperblaster.md2 \ data1/players/martianenforcer/w_hyperblaster.skin \ data1/players/martianenforcer/w_machinegun.iqm \ data1/players/martianenforcer/w_machinegun.md2 \ data1/players/martianenforcer/w_machinegun.skin \ data1/players/martianenforcer/w_minderaser.iqm \ data1/players/martianenforcer/w_minderaser.md2 \ data1/players/martianenforcer/w_minderaser.skin \ data1/players/martianenforcer/w_railgun.iqm \ data1/players/martianenforcer/w_railgun.md2 \ data1/players/martianenforcer/w_railgun.skin \ data1/players/martianenforcer/w_rlauncher.iqm \ data1/players/martianenforcer/w_rlauncher.md2 \ data1/players/martianenforcer/w_rlauncher.skin \ data1/players/martianenforcer/w_shotgun.iqm \ data1/players/martianenforcer/w_shotgun.md2 \ data1/players/martianenforcer/w_shotgun.skin \ data1/players/martianenforcer/w_sshotgun.iqm \ data1/players/martianenforcer/w_sshotgun.md2 \ data1/players/martianenforcer/w_sshotgun.skin \ data1/players/martianenforcer/w_violator.iqm \ data1/players/martianenforcer/w_violator.md2 \ data1/players/martianenforcer/w_violator.skin \ data1/players/martianoverlord/alien \ data1/players/martianoverlord/blue_i.jpg \ data1/players/martianoverlord/blue.jpg \ data1/players/martianoverlord/bump1.wav \ data1/players/martianoverlord/death1.wav \ data1/players/martianoverlord/death2.wav \ data1/players/martianoverlord/death3.wav \ data1/players/martianoverlord/death4.wav \ data1/players/martianoverlord/default_i.jpg \ data1/players/martianoverlord/default.jpg \ data1/players/martianoverlord/default_normal.tga \ data1/players/martianoverlord/drown1.wav \ data1/players/martianoverlord/fall1.wav \ data1/players/martianoverlord/fall2.wav \ data1/players/martianoverlord/gasp1.wav \ data1/players/martianoverlord/gasp2.wav \ data1/players/martianoverlord/gurp1.wav \ data1/players/martianoverlord/gurp2.wav \ data1/players/martianoverlord/helmet.iqm \ data1/players/martianoverlord/helmet.md2 \ data1/players/martianoverlord/jump1.wav \ data1/players/martianoverlord/lod1.iqm \ data1/players/martianoverlord/lod1.rgd \ data1/players/martianoverlord/lod2.iqm \ data1/players/martianoverlord/lod2.rgd \ data1/players/martianoverlord/pain100_1.wav \ data1/players/martianoverlord/pain100_2.wav \ data1/players/martianoverlord/pain25_1.wav \ data1/players/martianoverlord/pain25_2.wav \ data1/players/martianoverlord/pain50_1.wav \ data1/players/martianoverlord/pain50_2.wav \ data1/players/martianoverlord/pain75_1.wav \ data1/players/martianoverlord/pain75_2.wav \ data1/players/martianoverlord/red_i.jpg \ data1/players/martianoverlord/red.jpg \ data1/players/martianoverlord/tris.iqm \ data1/players/martianoverlord/tris.md2 \ data1/players/martianoverlord/tris.rgd \ data1/players/martianoverlord/tron2_i.jpg \ data1/players/martianoverlord/tron2.jpg \ data1/players/martianoverlord/tron3_i.jpg \ data1/players/martianoverlord/tron3.jpg \ data1/players/martianoverlord/tron_i.jpg \ data1/players/martianoverlord/tron.jpg \ data1/players/martianoverlord/tron_normal.tga \ data1/players/martianoverlord/w_alienblaster.iqm \ data1/players/martianoverlord/w_alienblaster.skin \ data1/players/martianoverlord/w_bfg.iqm \ data1/players/martianoverlord/w_bfg.md2 \ data1/players/martianoverlord/w_bfg.skin \ data1/players/martianoverlord/w_blaster.iqm \ data1/players/martianoverlord/w_blaster.md2 \ data1/players/martianoverlord/w_blaster.skin \ data1/players/martianoverlord/w_chaingun.iqm \ data1/players/martianoverlord/w_chaingun.md2 \ data1/players/martianoverlord/w_chaingun.skin \ data1/players/martianoverlord/weapon.iqm \ data1/players/martianoverlord/weapon.jpg \ data1/players/martianoverlord/weapon.md2 \ data1/players/martianoverlord/weapon.skin \ data1/players/martianoverlord/w_hyperblaster.iqm \ data1/players/martianoverlord/w_hyperblaster.md2 \ data1/players/martianoverlord/w_hyperblaster.skin \ data1/players/martianoverlord/w_machinegun.iqm \ data1/players/martianoverlord/w_machinegun.md2 \ data1/players/martianoverlord/w_machinegun.skin \ data1/players/martianoverlord/w_minderaser.iqm \ data1/players/martianoverlord/w_minderaser.md2 \ data1/players/martianoverlord/w_minderaser.skin \ data1/players/martianoverlord/w_railgun.iqm \ data1/players/martianoverlord/w_railgun.md2 \ data1/players/martianoverlord/w_railgun.skin \ data1/players/martianoverlord/w_rlauncher.iqm \ data1/players/martianoverlord/w_rlauncher.md2 \ data1/players/martianoverlord/w_rlauncher.skin \ data1/players/martianoverlord/w_shotgun.iqm \ data1/players/martianoverlord/w_shotgun.md2 \ data1/players/martianoverlord/w_shotgun.skin \ data1/players/martianoverlord/w_sshotgun.iqm \ data1/players/martianoverlord/w_sshotgun.md2 \ data1/players/martianoverlord/w_sshotgun.skin \ data1/players/martianoverlord/w_violator.iqm \ data1/players/martianoverlord/w_violator.md2 \ data1/players/martianoverlord/w_violator.skin \ data1/players/martianwarrior/alien \ data1/players/martianwarrior/blue_i.jpg \ data1/players/martianwarrior/blue.jpg \ data1/players/martianwarrior/bump1.wav \ data1/players/martianwarrior/death1.wav \ data1/players/martianwarrior/death2.wav \ data1/players/martianwarrior/death3.wav \ data1/players/martianwarrior/death4.wav \ data1/players/martianwarrior/default_i.jpg \ data1/players/martianwarrior/default.jpg \ data1/players/martianwarrior/default_normal.tga \ data1/players/martianwarrior/drown1.wav \ data1/players/martianwarrior/fall1.wav \ data1/players/martianwarrior/fall2.wav \ data1/players/martianwarrior/gasp1.wav \ data1/players/martianwarrior/gasp2.wav \ data1/players/martianwarrior/gurp1.wav \ data1/players/martianwarrior/gurp2.wav \ data1/players/martianwarrior/helmet.iqm \ data1/players/martianwarrior/helmet.md2 \ data1/players/martianwarrior/jump1.wav \ data1/players/martianwarrior/lod1.iqm \ data1/players/martianwarrior/lod1.md2 \ data1/players/martianwarrior/lod1.rgd \ data1/players/martianwarrior/lod2.iqm \ data1/players/martianwarrior/lod2.md2 \ data1/players/martianwarrior/lod2.rgd \ data1/players/martianwarrior/pain100_1.wav \ data1/players/martianwarrior/pain100_2.wav \ data1/players/martianwarrior/pain25_1.wav \ data1/players/martianwarrior/pain25_2.wav \ data1/players/martianwarrior/pain50_1.wav \ data1/players/martianwarrior/pain50_2.wav \ data1/players/martianwarrior/pain75_1.wav \ data1/players/martianwarrior/pain75_2.wav \ data1/players/martianwarrior/red_i.jpg \ data1/players/martianwarrior/red.jpg \ data1/players/martianwarrior/tris.iqm \ data1/players/martianwarrior/tris.md2 \ data1/players/martianwarrior/tris.rgd \ data1/players/martianwarrior/tron2_i.jpg \ data1/players/martianwarrior/tron2.jpg \ data1/players/martianwarrior/tron3_i.jpg \ data1/players/martianwarrior/tron3.jpg \ data1/players/martianwarrior/tron_i.jpg \ data1/players/martianwarrior/tron.jpg \ data1/players/martianwarrior/tron_normal.tga \ data1/players/martianwarrior/w_alienblaster.iqm \ data1/players/martianwarrior/w_alienblaster.skin \ data1/players/martianwarrior/w_bfg.iqm \ data1/players/martianwarrior/w_bfg.md2 \ data1/players/martianwarrior/w_bfg.skin \ data1/players/martianwarrior/w_blaster.iqm \ data1/players/martianwarrior/w_blaster.md2 \ data1/players/martianwarrior/w_blaster.skin \ data1/players/martianwarrior/w_chaingun.iqm \ data1/players/martianwarrior/w_chaingun.md2 \ data1/players/martianwarrior/w_chaingun.skin \ data1/players/martianwarrior/weapon.iqm \ data1/players/martianwarrior/weapon.jpg \ data1/players/martianwarrior/weapon.md2 \ data1/players/martianwarrior/weapon.skin \ data1/players/martianwarrior/w_hyperblaster.iqm \ data1/players/martianwarrior/w_hyperblaster.md2 \ data1/players/martianwarrior/w_hyperblaster.skin \ data1/players/martianwarrior/w_machinegun.iqm \ data1/players/martianwarrior/w_machinegun.md2 \ data1/players/martianwarrior/w_machinegun.skin \ data1/players/martianwarrior/w_minderaser.iqm \ data1/players/martianwarrior/w_minderaser.md2 \ data1/players/martianwarrior/w_minderaser.skin \ data1/players/martianwarrior/w_railgun.iqm \ data1/players/martianwarrior/w_railgun.md2 \ data1/players/martianwarrior/w_railgun.skin \ data1/players/martianwarrior/w_rlauncher.iqm \ data1/players/martianwarrior/w_rlauncher.md2 \ data1/players/martianwarrior/w_rlauncher.skin \ data1/players/martianwarrior/w_shotgun.iqm \ data1/players/martianwarrior/w_shotgun.md2 \ data1/players/martianwarrior/w_shotgun.skin \ data1/players/martianwarrior/w_sshotgun.iqm \ data1/players/martianwarrior/w_sshotgun.md2 \ data1/players/martianwarrior/w_sshotgun.skin \ data1/players/martianwarrior/w_violator.iqm \ data1/players/martianwarrior/w_violator.md2 \ data1/players/martianwarrior/w_violator.skin \ data1/players/slashbot/blue_i.jpg \ data1/players/slashbot/blue.jpg \ data1/players/slashbot/bump1.wav \ data1/players/slashbot/death1.wav \ data1/players/slashbot/death2.wav \ data1/players/slashbot/death3.wav \ data1/players/slashbot/death4.wav \ data1/players/slashbot/default_i.jpg \ data1/players/slashbot/default.jpg \ data1/players/slashbot/default_normal.jpg \ data1/players/slashbot/drown1.wav \ data1/players/slashbot/fall1.wav \ data1/players/slashbot/fall2.wav \ data1/players/slashbot/gurp1.wav \ data1/players/slashbot/gurp2.wav \ data1/players/slashbot/jump1.wav \ data1/players/slashbot/lod1.iqm \ data1/players/slashbot/lod2.iqm \ data1/players/slashbot/lod1.rgd \ data1/players/slashbot/lod2.rgd \ data1/players/slashbot/pain100_1.wav \ data1/players/slashbot/pain100_2.wav \ data1/players/slashbot/pain25_1.wav \ data1/players/slashbot/pain25_2.wav \ data1/players/slashbot/pain50_1.wav \ data1/players/slashbot/pain50_2.wav \ data1/players/slashbot/pain75_1.wav \ data1/players/slashbot/pain75_2.wav \ data1/players/slashbot/red_i.jpg \ data1/players/slashbot/red.jpg \ data1/players/slashbot/robot \ data1/players/slashbot/tris.iqm \ data1/players/slashbot/tris.md2 \ data1/players/slashbot/tris.rgd \ data1/players/slashbot/tron2_i.jpg \ data1/players/slashbot/tron2.jpg \ data1/players/slashbot/tron3_i.jpg \ data1/players/slashbot/tron3.jpg \ data1/players/slashbot/tron_i.jpg \ data1/players/slashbot/tron.jpg \ data1/players/slashbot/tron_normal.tga \ data1/players/slashbot/w_bfg.iqm \ data1/players/slashbot/w_bfg.md2 \ data1/players/slashbot/w_bfg.skin \ data1/players/slashbot/w_blaster.iqm \ data1/players/slashbot/w_blaster.md2 \ data1/players/slashbot/w_blaster.skin \ data1/players/slashbot/w_chaingun.iqm \ data1/players/slashbot/w_chaingun.md2 \ data1/players/slashbot/w_chaingun.skin \ data1/players/slashbot/weapon.iqm \ data1/players/slashbot/weapon.jpg \ data1/players/slashbot/weapon.md2 \ data1/players/slashbot/weapon.skin \ data1/players/slashbot/w_hyperblaster.iqm \ data1/players/slashbot/w_hyperblaster.md2 \ data1/players/slashbot/w_hyperblaster.skin \ data1/players/slashbot/w_machinegun.iqm \ data1/players/slashbot/w_machinegun.md2 \ data1/players/slashbot/w_machinegun.skin \ data1/players/slashbot/w_minderaser.iqm \ data1/players/slashbot/w_minderaser.md2 \ data1/players/slashbot/w_minderaser.skin \ data1/players/slashbot/w_railgun.iqm \ data1/players/slashbot/w_railgun.md2 \ data1/players/slashbot/w_railgun.skin \ data1/players/slashbot/w_rlauncher.iqm \ data1/players/slashbot/w_rlauncher.md2 \ data1/players/slashbot/w_rlauncher.skin \ data1/players/slashbot/w_shotgun.iqm \ data1/players/slashbot/w_shotgun.md2 \ data1/players/slashbot/w_shotgun.skin \ data1/players/slashbot/w_sshotgun.iqm \ data1/players/slashbot/w_sshotgun.md2 \ data1/players/slashbot/w_sshotgun.skin \ data1/players/slashbot/w_violator.iqm \ data1/players/slashbot/w_violator.md2 \ data1/players/slashbot/w_violator.skin scriptsdir = $(pkgdatadir) nobase_nodist_scripts_DATA = \ data1/scripts/caustics.rscript \ data1/scripts/consoles.rscript \ data1/scripts/interactive/textures.rscript \ data1/scripts/maps/aoa-atlantis.rscript \ data1/scripts/maps/aoa-corrosion.rscript \ data1/scripts/maps/aoa-frost2k9.rscript \ data1/scripts/maps/aoa-morpheus.rscript \ data1/scripts/maps/aoa-zorn.rscript \ data1/scripts/maps/cp-ribeye.rscript \ data1/scripts/maps/ctf-corrosion.rscript \ data1/scripts/maps/ctf-cryogenic.rscript \ data1/scripts/maps/ctf-extermination.rscript \ data1/scripts/maps/ctf-frostbyte.rscript \ data1/scripts/maps/ctf-goregrinder.rscript \ data1/scripts/maps/ctf-invasion.rscript \ data1/scripts/maps/ctf-oblivion.rscript \ data1/scripts/maps/ctf-purgatory.rscript \ data1/scripts/maps/ctf-titan2k8.rscript \ data1/scripts/maps/ctf-vesuvius2k11.rscript \ data1/scripts/maps/ctf-violator.rscript \ data1/scripts/maps/ctf-zion2k9.rscript \ data1/scripts/maps/db-chromium.rscript \ data1/scripts/maps/db-icarus.rscript \ data1/scripts/maps/db-vesuvius.rscript \ data1/scripts/maps/dm-annihilation.rscript \ data1/scripts/maps/dm-atlantis2k8.rscript \ data1/scripts/maps/dm-babel2k11.rscript \ data1/scripts/maps/dm-bloodfactory2k12.rscript \ data1/scripts/maps/dm-chasmatic2k9.rscript \ data1/scripts/maps/dm-command2k9.rscript \ data1/scripts/maps/dm-corrosion.rscript \ data1/scripts/maps/dm-crucible2k12.rscript \ data1/scripts/maps/dm-deathray.rscript \ data1/scripts/maps/dm-deimos2k9.rscript \ data1/scripts/maps/dm-dismal2k11.rscript \ data1/scripts/maps/dm-downfall.rscript \ data1/scripts/maps/dm-dynamo2k12.rscript \ data1/scripts/maps/dm-eternal.rscript \ data1/scripts/maps/dm-extermination.rscript \ data1/scripts/maps/dm-furious2k8.rscript \ data1/scripts/maps/dm-goregrinder.rscript \ data1/scripts/maps/dm-horus.rscript \ data1/scripts/maps/dm-impact.rscript \ data1/scripts/maps/dm-invasion.rscript \ data1/scripts/maps/dm-leviathan2k12.rscript \ data1/scripts/maps/dm-liberation.rscript \ data1/scripts/maps/dm-neptune.rscript \ data1/scripts/maps/dm-oblivion.rscript \ data1/scripts/maps/dm-omega2k8.rscript \ data1/scripts/maps/dm-purgatory.rscript \ data1/scripts/maps/dm-saucer2k9.rscript \ data1/scripts/maps/dm-turbo2k8.rscript \ data1/scripts/maps/dm-vesuvius2k11.rscript \ data1/scripts/maps/dm-violator2k11.rscript \ data1/scripts/maps/dm-warmachine2k10.rscript \ data1/scripts/maps/dm-zorn2k11.rscript \ data1/scripts/maps/dm-zion2k9.rscript \ data1/scripts/maps/tac-extermination.rscript \ data1/scripts/maps/tca-corrosion.rscript \ data1/scripts/maps/tca-cryogenic.rscript \ data1/scripts/maps/tca-extermination.rscript \ data1/scripts/maps/tca-purgatory.rscript \ data1/scripts/maps/tca-zion2k9.rscript \ data1/scripts/menu.rscript \ data1/scripts/models.rscript \ data1/scripts/normals/normals.rscript \ data1/scripts/normals/tron.rscript \ data1/scripts/textures.rscript sounddir = $(pkgdatadir) nobase_nodist_sound_DATA = \ data1/sound/doors/dr1_end.wav \ data1/sound/doors/dr1_mid.wav \ data1/sound/doors/dr1_strt.wav \ data1/sound/items/damage2.wav \ data1/sound/items/damage3.wav \ data1/sound/items/damage.wav \ data1/sound/items/hasteout.wav \ data1/sound/items/haste.wav \ data1/sound/items/l_health.wav \ data1/sound/items/m_health.wav \ data1/sound/items/n_health.wav \ data1/sound/items/powerup.wav \ data1/sound/items/protect2.wav \ data1/sound/items/protect3.wav \ data1/sound/items/protect4.wav \ data1/sound/items/protect.wav \ data1/sound/items/respawn1.wav \ data1/sound/items/s_health.wav \ data1/sound/items/sproingout.wav \ data1/sound/items/sproing.wav \ data1/sound/misc/1frags.wav \ data1/sound/misc/2frags.wav \ data1/sound/misc/3frags.wav \ data1/sound/misc/am_pkup.wav \ data1/sound/misc/ar1_pkup.wav \ data1/sound/misc/ar2_pkup.wav \ data1/sound/misc/ar3_pkup.wav \ data1/sound/misc/bigtele.wav \ data1/sound/misc/blue_increases.wav \ data1/sound/misc/blue_picked.wav \ data1/sound/misc/bluepndisabled.wav \ data1/sound/misc/bluepnenabled.wav \ data1/sound/misc/blue_returned.wav \ data1/sound/misc/blue_scores.wav \ data1/sound/misc/blue_takes.wav \ data1/sound/misc/bluevulnerable.wav \ data1/sound/misc/blue_wins_ctf.wav \ data1/sound/misc/blue_wins.wav \ data1/sound/misc/cow/groan.wav \ data1/sound/misc/cow/moo.wav \ data1/sound/misc/cow/step1.wav \ data1/sound/misc/db_pickup.wav \ data1/sound/misc/db_score.wav \ data1/sound/misc/deathray/fizz.wav \ data1/sound/misc/deathray/shoot.wav \ data1/sound/misc/deathray/weird2.wav \ data1/sound/misc/death.wav \ data1/sound/misc/fight.wav \ data1/sound/misc/game_tied_ctf.wav \ data1/sound/misc/game_tied.wav \ data1/sound/misc/godlike.wav \ data1/sound/misc/headshot.wav \ data1/sound/misc/hit2.wav \ data1/sound/misc/hit.wav \ data1/sound/misc/lasfly.wav \ data1/sound/misc/menu1.wav \ data1/sound/misc/menu2.wav \ data1/sound/misc/menu3.wav \ data1/sound/misc/minderaser.wav \ data1/sound/misc/one.wav \ data1/sound/misc/pc_up.wav \ data1/sound/misc/rampage.wav \ data1/sound/misc/red_increases.wav \ data1/sound/misc/red_picked.wav \ data1/sound/misc/redpndisabled.wav \ data1/sound/misc/redpnenabled.wav \ data1/sound/misc/red_returned.wav \ data1/sound/misc/red_scores.wav \ data1/sound/misc/red_takes.wav \ data1/sound/misc/redvulnerable.wav \ data1/sound/misc/red_wins_ctf.wav \ data1/sound/misc/red_wins.wav \ data1/sound/misc/reject.wav \ data1/sound/misc/scores_tied.wav \ data1/sound/misc/spawn1.wav \ data1/sound/misc/talk1.wav \ data1/sound/misc/talk.wav \ data1/sound/misc/tele1.wav \ data1/sound/misc/tele_up.wav \ data1/sound/misc/three.wav \ data1/sound/misc/trigger1.wav \ data1/sound/misc/two.wav \ data1/sound/misc/w_pkup.wav \ data1/sound/music/adrenaline.ogg \ data1/sound/music/cp-ribeye.ogg \ data1/sound/music/Divinity_lack_of_success.ogg \ data1/sound/music/Divinity_misunderstood.ogg \ data1/sound/music/Divinity_never_ending.ogg \ data1/sound/music/dm-annihilation.ogg \ data1/sound/music/dm-deathray.ogg \ data1/sound/music/dm-deimos.ogg \ data1/sound/music/dm-dismal.ogg \ data1/sound/music/dm-dynamo.ogg \ data1/sound/music/dm-eternal.ogg \ data1/sound/music/dm-extermination.ogg \ data1/sound/music/dm-frontier.ogg \ data1/sound/music/dm-horus.ogg \ data1/sound/music/dm-inferno.ogg \ data1/sound/music/dm-redred.ogg \ data1/sound/music/dm-saucer.ogg \ data1/sound/music/dm-turbo.ogg \ data1/sound/music/dm-warmachine.ogg \ data1/sound/music/joyce1.ogg \ data1/sound/music/joyce2.ogg \ data1/sound/music/joyce3.ogg \ data1/sound/music/menumusic.ogg \ data1/sound/player/burn1.wav \ data1/sound/player/burn2.wav \ data1/sound/player/death1.wav \ data1/sound/player/death4.wav \ data1/sound/player/drown1.wav \ data1/sound/player/fall1.wav \ data1/sound/player/fall2.wav \ data1/sound/player/fry.wav \ data1/sound/player/gasp1.wav \ data1/sound/player/gasp2.wav \ data1/sound/player/jump1.wav \ data1/sound/player/land1.wav \ data1/sound/player/lava1.wav \ data1/sound/player/lava2.wav \ data1/sound/player/lava_in.wav \ data1/sound/player/male/bump1.wav \ data1/sound/player/male/death1.wav \ data1/sound/player/male/death2.wav \ data1/sound/player/male/death3.wav \ data1/sound/player/male/death4.wav \ data1/sound/player/male/drown1.wav \ data1/sound/player/male/fall1.wav \ data1/sound/player/male/fall2.wav \ data1/sound/player/male/gurp1.wav \ data1/sound/player/male/gurp2.wav \ data1/sound/player/male/jump1.wav \ data1/sound/player/male/pain100_1.wav \ data1/sound/player/male/pain100_2.wav \ data1/sound/player/male/pain25_1.wav \ data1/sound/player/male/pain25_2.wav \ data1/sound/player/male/pain50_1.wav \ data1/sound/player/male/pain50_2.wav \ data1/sound/player/male/pain75_1.wav \ data1/sound/player/male/pain75_2.wav \ data1/sound/player/step1.wav \ data1/sound/player/step2.wav \ data1/sound/player/step3.wav \ data1/sound/player/step4.wav \ data1/sound/player/step_metal1.wav \ data1/sound/player/step_metal2.wav \ data1/sound/player/step_metal3.wav \ data1/sound/player/step_metal4.wav \ data1/sound/player/wade1.wav \ data1/sound/player/wade2.wav \ data1/sound/player/wade3.wav \ data1/sound/player/watr_in.wav \ data1/sound/player/watr_out.wav \ data1/sound/player/watr_un.wav \ data1/sound/smallmech/sight.wav \ data1/sound/taunts/commander/taunt1.wav \ data1/sound/taunts/commander/taunt2.wav \ data1/sound/taunts/commander/taunt3.wav \ data1/sound/taunts/commander/taunt4.wav \ data1/sound/taunts/commander/taunt5.wav \ data1/sound/taunts/enforcer/taunt1.wav \ data1/sound/taunts/enforcer/taunt2.wav \ data1/sound/taunts/enforcer/taunt3.wav \ data1/sound/taunts/enforcer/taunt4.wav \ data1/sound/taunts/enforcer/taunt5.wav \ data1/sound/taunts/lauren/taunt1.wav \ data1/sound/taunts/lauren/taunt2.wav \ data1/sound/taunts/lauren/taunt3.wav \ data1/sound/taunts/lauren/taunt4.wav \ data1/sound/taunts/lauren/taunt5.wav \ data1/sound/taunts/martiancyborg/taunt1.wav \ data1/sound/taunts/martiancyborg/taunt2.wav \ data1/sound/taunts/martiancyborg/taunt3.wav \ data1/sound/taunts/martiancyborg/taunt4.wav \ data1/sound/taunts/martiancyborg/taunt5.wav \ data1/sound/taunts/martianenforcer/taunt1.wav \ data1/sound/taunts/martianenforcer/taunt2.wav \ data1/sound/taunts/martianenforcer/taunt3.wav \ data1/sound/taunts/martianenforcer/taunt4.wav \ data1/sound/taunts/martianenforcer/taunt5.wav \ data1/sound/taunts/martianoverlord/taunt1.wav \ data1/sound/taunts/martianoverlord/taunt2.wav \ data1/sound/taunts/martianoverlord/taunt3.wav \ data1/sound/taunts/martianoverlord/taunt4.wav \ data1/sound/taunts/martianoverlord/taunt5.wav \ data1/sound/taunts/martianwarrior/taunt1.wav \ data1/sound/taunts/martianwarrior/taunt2.wav \ data1/sound/taunts/martianwarrior/taunt3.wav \ data1/sound/taunts/martianwarrior/taunt4.wav \ data1/sound/taunts/martianwarrior/taunt5.wav \ data1/sound/taunts/slashbot/taunt1.wav \ data1/sound/taunts/slashbot/taunt2.wav \ data1/sound/taunts/slashbot/taunt3.wav \ data1/sound/taunts/slashbot/taunt4.wav \ data1/sound/taunts/slashbot/taunt5.wav \ data1/sound/vehicles/bomberidle.wav \ data1/sound/vehicles/explodebomb.wav \ data1/sound/vehicles/flybomb.wav \ data1/sound/vehicles/got_in.wav \ data1/sound/vehicles/shootbomb.wav \ data1/sound/vehicles/shootlaser.wav \ data1/sound/vehicles/warning.wav \ data1/sound/weapons/adetonatordown.wav \ data1/sound/weapons/adetonatorup.wav \ data1/sound/weapons/biglaser.wav \ data1/sound/weapons/blastf1a.wav \ data1/sound/weapons/clank.wav \ data1/sound/weapons/clink01.wav \ data1/sound/weapons/clink02.wav \ data1/sound/weapons/electroball.wav \ data1/sound/weapons/energyfield.wav \ data1/sound/weapons/grenlb1b.wav \ data1/sound/weapons/grenlf1a.wav \ data1/sound/weapons/grenlr1b.wav \ data1/sound/weapons/grenlx1a.wav \ data1/sound/weapons/hypbrl1a.wav \ data1/sound/weapons/hyprbf1a.wav \ data1/sound/weapons/lightoff.wav \ data1/sound/weapons/lighton.wav \ data1/sound/weapons/machgf1b.wav \ data1/sound/weapons/machgf2b.wav \ data1/sound/weapons/machgf3b.wav \ data1/sound/weapons/machgf4b.wav \ data1/sound/weapons/machgf5b.wav \ data1/sound/weapons/minderaserfire.wav \ data1/sound/weapons/noammo.wav \ data1/sound/weapons/railgf1a.wav \ data1/sound/weapons/rockfly.wav \ data1/sound/weapons/rocklf1a.wav \ data1/sound/weapons/rocklr1b.wav \ data1/sound/weapons/rocklx1a.wav \ data1/sound/weapons/seeker_fast.wav \ data1/sound/weapons/seeker.wav \ data1/sound/weapons/seeker_zap.wav \ data1/sound/weapons/shotgf1b.wav \ data1/sound/weapons/smartgun_hum.wav \ data1/sound/weapons/spidermov.wav \ data1/sound/weapons/vaporizer_hum.wav \ data1/sound/weapons/viofire1.wav \ data1/sound/weapons/viofire2.wav \ data1/sound/weapons/whoosh.wav \ data1/sound/world/botwon.wav \ data1/sound/world/button1.wav \ data1/sound/world/button2.wav \ data1/sound/world/distantjet.wav \ data1/sound/world/electricity.wav \ data1/sound/world/explosion1.wav \ data1/sound/world/explosion2.wav \ data1/sound/world/forcefield.wav \ data1/sound/world/hyprbf1a.wav \ data1/sound/world/jumppad1.wav \ data1/sound/world/laser1.wav \ data1/sound/world/platstop.wav \ data1/sound/world/rcktfly.wav \ data1/sound/world/ric1.wav \ data1/sound/world/ric2.wav \ data1/sound/world/ric3.wav \ data1/sound/world/rocket.wav \ data1/sound/world/steam1.wav \ data1/sound/world/steam2.wav \ data1/sound/world/turbine1.wav \ data1/sound/world/vents.wav \ data1/sound/world/water1.wav \ data1/sound/world/weird.wav \ data1/sound/world/youwin.wav texturesdir = $(pkgdatadir) nobase_nodist_textures_DATA = \ data1/textures/alien/support5.tga \ data1/textures/arena10/bluetile_hm.tga \ data1/textures/arena10/bluetile_nm.tga \ data1/textures/arena10/bluetile.tga \ data1/textures/arena10/bricks1_nm.tga \ data1/textures/arena10/bricks1.tga \ data1/textures/arena10/bricks2_broken_nm.tga \ data1/textures/arena10/bricks2_broken.tga \ data1/textures/arena10/bricks2_hm.tga \ data1/textures/arena10/bricks2_nm.tga \ data1/textures/arena10/bricks2.tga \ data1/textures/arena10/bricks3.tga \ data1/textures/arena10/building10_broken2_nm.tga \ data1/textures/arena10/building10_broken2.tga \ data1/textures/arena10/building10_broken_nm.tga \ data1/textures/arena10/building10_broken.tga \ data1/textures/arena10/building10_nm.tga \ data1/textures/arena10/building10.tga \ data1/textures/arena10/building11_nm.tga \ data1/textures/arena10/building11.tga \ data1/textures/arena10/building12_nm.tga \ data1/textures/arena10/building12.tga \ data1/textures/arena10/building13_nm.tga \ data1/textures/arena10/building13.tga \ data1/textures/arena10/building14_nm.tga \ data1/textures/arena10/building14.tga \ data1/textures/arena10/building15_nm.tga \ data1/textures/arena10/building15.tga \ data1/textures/arena10/building1_broken_nm.tga \ data1/textures/arena10/building1_broken.tga \ data1/textures/arena10/building1_nm.tga \ data1/textures/arena10/building1.tga \ data1/textures/arena10/building2_nm.tga \ data1/textures/arena10/building2.tga \ data1/textures/arena10/building3_hm.tga \ data1/textures/arena10/building3_nm.tga \ data1/textures/arena10/building3ns_hm.tga \ data1/textures/arena10/building3ns_nm.tga \ data1/textures/arena10/building3ns.tga \ data1/textures/arena10/building3.tga \ data1/textures/arena10/building4_nm.tga \ data1/textures/arena10/building4.tga \ data1/textures/arena10/building5_nm.tga \ data1/textures/arena10/building5.tga \ data1/textures/arena10/building6_nm.tga \ data1/textures/arena10/building6.tga \ data1/textures/arena10/building7_nm.tga \ data1/textures/arena10/building7s_hm.tga \ data1/textures/arena10/building7s_nm.tga \ data1/textures/arena10/building7s.tga \ data1/textures/arena10/building7.tga \ data1/textures/arena10/building8_nm.tga \ data1/textures/arena10/building8.tga \ data1/textures/arena10/building9_nm.tga \ data1/textures/arena10/building9.tga \ data1/textures/arena10/cement1_hm.tga \ data1/textures/arena10/cement1_nm.tga \ data1/textures/arena10/cement1ns_nm.tga \ data1/textures/arena10/cement1ns.tga \ data1/textures/arena10/cement1.tga \ data1/textures/arena10/cobblestone_hm.tga \ data1/textures/arena10/cobblestoneng_hm.tga \ data1/textures/arena10/cobblestoneng_nm.tga \ data1/textures/arena10/cobblestoneng.tga \ data1/textures/arena10/cobblestone_nm.tga \ data1/textures/arena10/cobblestonens_nm.tga \ data1/textures/arena10/cobblestonens.tga \ data1/textures/arena10/cobblestone.tga \ data1/textures/arena10/cobwebs2.tga \ data1/textures/arena10/cobwebs.tga \ data1/textures/arena10/cocacola.tga \ data1/textures/arena10/container1_hm.tga \ data1/textures/arena10/container1_nm.tga \ data1/textures/arena10/container1.tga \ data1/textures/arena10/container2_hm.tga \ data1/textures/arena10/container2_nm.tga \ data1/textures/arena10/container2.tga \ data1/textures/arena10/container3_hm.tga \ data1/textures/arena10/container3_nm.tga \ data1/textures/arena10/container3.tga \ data1/textures/arena10/container4_hm.tga \ data1/textures/arena10/container4_nm.tga \ data1/textures/arena10/container4.tga \ data1/textures/arena10/cretewall1_nm.tga \ data1/textures/arena10/cretewall1.tga \ data1/textures/arena10/cretewall2_nm.tga \ data1/textures/arena10/cretewall2.tga \ data1/textures/arena10/elecpanel1_hm.tga \ data1/textures/arena10/elecpanel1_nm.tga \ data1/textures/arena10/elecpanel1.tga \ data1/textures/arena10/elecpanel2_hm.tga \ data1/textures/arena10/elecpanel2_nm.tga \ data1/textures/arena10/elecpanel2.tga \ data1/textures/arena10/elecpanel3_hm.tga \ data1/textures/arena10/elecpanel3_nm.tga \ data1/textures/arena10/elecpanel3.tga \ data1/textures/arena10/elecpanel4_hm.tga \ data1/textures/arena10/elecpanel4_nm.tga \ data1/textures/arena10/elecpanel4.tga \ data1/textures/arena10/elecvents_hm.tga \ data1/textures/arena10/elecvents_nm.tga \ data1/textures/arena10/elecvents.tga \ data1/textures/arena10/elecwall1_nm.tga \ data1/textures/arena10/elecwall1.tga \ data1/textures/arena10/elecwall2_nm.tga \ data1/textures/arena10/elecwall2.tga \ data1/textures/arena10/floortile10_hm.tga \ data1/textures/arena10/floortile10_nm.tga \ data1/textures/arena10/floortile10.tga \ data1/textures/arena10/floortile10w_hm.tga \ data1/textures/arena10/floortile10w_nm.tga \ data1/textures/arena10/floortile10w.tga \ data1/textures/arena10/gothceil1_hm.tga \ data1/textures/arena10/gothceil1_nm.tga \ data1/textures/arena10/gothceil1.tga \ data1/textures/arena10/gothmetal1.tga \ data1/textures/arena10/gothwindow1_hm.tga \ data1/textures/arena10/gothwindow1.tga \ data1/textures/arena10/gothwindow2_hm.tga \ data1/textures/arena10/gothwindow2.tga \ data1/textures/arena10/gothwindow2r_hm.tga \ data1/textures/arena10/gothwindow2r.tga \ data1/textures/arena10/gothwindow3_hm.tga \ data1/textures/arena10/gothwindow3.tga \ data1/textures/arena10/gothwindow3r_hm.tga \ data1/textures/arena10/gothwindow3r.tga \ data1/textures/arena10/graffitiwall1.tga \ data1/textures/arena10/grafittiwall2.tga \ data1/textures/arena10/heap1_nm.tga \ data1/textures/arena10/heap1.tga \ data1/textures/arena10/heap2_nm.tga \ data1/textures/arena10/heap2.tga \ data1/textures/arena10/heap3_nm.tga \ data1/textures/arena10/heap3.tga \ data1/textures/arena10/heap4_nm.tga \ data1/textures/arena10/heap4.tga \ data1/textures/arena10/ivy1_nm.tga \ data1/textures/arena10/ivy1.tga \ data1/textures/arena10/ivy2_nm.tga \ data1/textures/arena10/ivy2.tga \ data1/textures/arena10/metalfence1.tga \ data1/textures/arena10/metalfence2.tga \ data1/textures/arena10/metalfloor20_hm.tga \ data1/textures/arena10/metalfloor20_nm.tga \ data1/textures/arena10/metalfloor20.tga \ data1/textures/arena10/metalfloor21_hm.tga \ data1/textures/arena10/metalfloor21_nm.tga \ data1/textures/arena10/metalfloor21.tga \ data1/textures/arena10/metalfloor21w_hm.tga \ data1/textures/arena10/metalfloor21w_nm.tga \ data1/textures/arena10/metalfloor21w.tga \ data1/textures/arena10/metalwall20_hm.tga \ data1/textures/arena10/metalwall20_nm.tga \ data1/textures/arena10/metalwall20.tga \ data1/textures/arena10/moltenrock_nm.tga \ data1/textures/arena10/moltenrock.tga \ data1/textures/arena10/neonsign10r.tga \ data1/textures/arena10/neonsign10.tga \ data1/textures/arena10/neonsign11b.tga \ data1/textures/arena10/neonsign11.tga \ data1/textures/arena10/neonsign12.tga \ data1/textures/arena10/neonsign13.tga \ data1/textures/arena10/neonsign14.tga \ data1/textures/arena10/neonsign15.tga \ data1/textures/arena10/neonsign16r.tga \ data1/textures/arena10/neonsign16.tga \ data1/textures/arena10/neonsign17.tga \ data1/textures/arena10/neonsign18r.tga \ data1/textures/arena10/neonsign18.tga \ data1/textures/arena10/neonsign19.tga \ data1/textures/arena10/neonsign1.tga \ data1/textures/arena10/neonsign20r.tga \ data1/textures/arena10/neonsign20.tga \ data1/textures/arena10/neonsign21.tga \ data1/textures/arena10/neonsign22.tga \ data1/textures/arena10/neonsign23.tga \ data1/textures/arena10/neonsign24.tga \ data1/textures/arena10/neonsign2.tga \ data1/textures/arena10/neonsign3.tga \ data1/textures/arena10/neonsign4.tga \ data1/textures/arena10/neonsign5.tga \ data1/textures/arena10/neonsign6r.tga \ data1/textures/arena10/neonsign6.tga \ data1/textures/arena10/neonsign7r.tga \ data1/textures/arena10/neonsign7.tga \ data1/textures/arena10/neonsign8.tga \ data1/textures/arena10/neonsign9.tga \ data1/textures/arena10/pipes1.tga \ data1/textures/arena10/planks_nm.tga \ data1/textures/arena10/planks.tga \ data1/textures/arena10/redtile_hm.tga \ data1/textures/arena10/redtile_nm.tga \ data1/textures/arena10/redtile.tga \ data1/textures/arena10/road1_hm.tga \ data1/textures/arena10/road1_nm.tga \ data1/textures/arena10/road1.tga \ data1/textures/arena10/road2_hm.tga \ data1/textures/arena10/road2_nm.tga \ data1/textures/arena10/road2.tga \ data1/textures/arena10/road3_hm.tga \ data1/textures/arena10/road3_nm.tga \ data1/textures/arena10/road3.tga \ data1/textures/arena10/roadbarrier_hm.tga \ data1/textures/arena10/roadbarrier_nm.tga \ data1/textures/arena10/roadbarrier.tga \ data1/textures/arena10/rockdirt1_hm.tga \ data1/textures/arena10/rockdirt1ng_hm.tga \ data1/textures/arena10/rockdirt1ng_nm.tga \ data1/textures/arena10/rockdirt1ng.tga \ data1/textures/arena10/rockdirt1_nm.tga \ data1/textures/arena10/rockdirt1ns_nm.tga \ data1/textures/arena10/rockdirt1ns.tga \ data1/textures/arena10/rockdirt1.tga \ data1/textures/arena10/rustdoor1_hm.tga \ data1/textures/arena10/rustdoor1_nm.tga \ data1/textures/arena10/rustdoor1.tga \ data1/textures/arena10/rustwall1_hm.tga \ data1/textures/arena10/rustwall1_nm.tga \ data1/textures/arena10/rustwall1.tga \ data1/textures/arena10/sevenup.tga \ data1/textures/arena10/sewergrate1_nm.tga \ data1/textures/arena10/sewergrate1.tga \ data1/textures/arena10/sign1.tga \ data1/textures/arena10/sign2.tga \ data1/textures/arena10/sign3.tga \ data1/textures/arena10/sign4.tga \ data1/textures/arena10/sign5r.tga \ data1/textures/arena10/sign5.tga \ data1/textures/arena10/sign6r.tga \ data1/textures/arena10/sign6.tga \ data1/textures/arena10/sign7_hm.tga \ data1/textures/arena10/sign7_nm.tga \ data1/textures/arena10/sign7.tga \ data1/textures/arena10/skyscraper1_hm.tga \ data1/textures/arena10/skyscraper1_nm.tga \ data1/textures/arena10/skyscraper1.tga \ data1/textures/arena10/skyscraper2_nm.tga \ data1/textures/arena10/skyscraper2.tga \ data1/textures/arena10/skyscraper3_nm.tga \ data1/textures/arena10/skyscraper3.tga \ data1/textures/arena10/skyscraper4_nm.tga \ data1/textures/arena10/skyscraper4.tga \ data1/textures/arena10/skyscraper5_nm.tga \ data1/textures/arena10/skyscraper5.tga \ data1/textures/arena10/skyscraper6_hm.tga \ data1/textures/arena10/skyscraper6_nm.tga \ data1/textures/arena10/skyscraper6.tga \ data1/textures/arena10/skyscraper7_nm.tga \ data1/textures/arena10/skyscraper7.tga \ data1/textures/arena10/skyscraper8_hm.tga \ data1/textures/arena10/skyscraper8_nm.tga \ data1/textures/arena10/skyscraper8.tga \ data1/textures/arena10/skyscraper9_hm.tga \ data1/textures/arena10/skyscraper9_nm.tga \ data1/textures/arena10/skyscraper9.tga \ data1/textures/arena10/stacks1.tga \ data1/textures/arena10/stacks2.tga \ data1/textures/arena10/starsign_hm.tga \ data1/textures/arena10/starsign_nm.tga \ data1/textures/arena10/starsign.tga \ data1/textures/arena10/stonewall1_nm.tga \ data1/textures/arena10/stonewall1.tga \ data1/textures/arena10/stonewall2_hm.tga \ data1/textures/arena10/stonewall2_nm.tga \ data1/textures/arena10/stonewall2.tga \ data1/textures/arena10/stonewall3_nm.tga \ data1/textures/arena10/stonewall3.tga \ data1/textures/arena10/storefront_nm.tga \ data1/textures/arena10/storefront.tga \ data1/textures/arena10/trash1_nm.tga \ data1/textures/arena10/trash1.tga \ data1/textures/arena10/trash2_nm.tga \ data1/textures/arena10/trash2.tga \ data1/textures/arena10/vine1_nm.tga \ data1/textures/arena10/vine1.tga \ data1/textures/arena10/vinewall1_hm.tga \ data1/textures/arena10/vinewall1_nm.tga \ data1/textures/arena10/vinewall1.tga \ data1/textures/arena10/wires1_nm.tga \ data1/textures/arena10/wires1.tga \ data1/textures/arena10/wires2_nm.tga \ data1/textures/arena10/wires2.tga \ data1/textures/arena1/jpad1a.tga \ data1/textures/arena1/jpad1a.wal \ data1/textures/arena1/jpad1b.tga \ data1/textures/arena1/jpad1b.wal \ data1/textures/arena1/jpad1c.tga \ data1/textures/arena1/jpad1c.wal \ data1/textures/arena1/jpad1d.tga \ data1/textures/arena1/jpad1d.wal \ data1/textures/arena1/jpad1e.tga \ data1/textures/arena1/jpad1e.wal \ data1/textures/arena1/metalbrick1.tga \ data1/textures/arena1/metalbrick2.tga \ data1/textures/arena1/metalbrick3a.tga \ data1/textures/arena1/metalbrick3b.tga \ data1/textures/arena1/metalbrick3c.tga \ data1/textures/arena1/metalbrick3d.tga \ data1/textures/arena1/metalbrick4a.tga \ data1/textures/arena1/metalbrick4b.tga \ data1/textures/arena1/metalbrick4c.tga \ data1/textures/arena1/metalbrick4d.tga \ data1/textures/arena1/metalbrick5.tga \ data1/textures/arena1/o3arch1.tga \ data1/textures/arena1/o3bricks12.tga \ data1/textures/arena1/o3bricks21.tga \ data1/textures/arena1/o3bricks22.tga \ data1/textures/arena1/o3bricks23.tga \ data1/textures/arena1/o3bricks2.tga \ data1/textures/arena1/o3bricks3.tga \ data1/textures/arena1/o3bricks6.tga \ data1/textures/arena1/o3bricks.tga \ data1/textures/arena1/o3ice1.tga \ data1/textures/arena1/o3ice2.tga \ data1/textures/arena1/o3ice3.tga \ data1/textures/arena1/o3ice4.tga \ data1/textures/arena1/o3rocks1.tga \ data1/textures/arena2/grid2.tga \ data1/textures/arena2/grid3.tga \ data1/textures/arena2/grida.tga \ data1/textures/arena2/gridb.tga \ data1/textures/arena2/gridc.tga \ data1/textures/arena2/gridd.tga \ data1/textures/arena2/gride.tga \ data1/textures/arena2/lava_nm.tga \ data1/textures/arena2/lava.tga \ data1/textures/arena2/lava_small.tga \ data1/textures/arena2/metal1.tga \ data1/textures/arena2/metal2.tga \ data1/textures/arena2/metal3.tga \ data1/textures/arena2/metal4.tga \ data1/textures/arena2/metal5.tga \ data1/textures/arena2/metal6.tga \ data1/textures/arena3/acceleratora.tga \ data1/textures/arena3/acceleratora.wal \ data1/textures/arena3/acceleratorb.tga \ data1/textures/arena3/acceleratorb.wal \ data1/textures/arena3/acceleratorc.tga \ data1/textures/arena3/acceleratorc.wal \ data1/textures/arena3/acceleratord.tga \ data1/textures/arena3/acceleratord.wal \ data1/textures/arena3/acceleratore.tga \ data1/textures/arena3/acceleratore.wal \ data1/textures/arena3/acceleratorf.tga \ data1/textures/arena3/acceleratorf.wal \ data1/textures/arena3/acceleratorg.tga \ data1/textures/arena3/acceleratorg.wal \ data1/textures/arena3/ceiling1.tga \ data1/textures/arena3/ceiling2.tga \ data1/textures/arena3/door1.tga \ data1/textures/arena3/floor1.tga \ data1/textures/arena3/floor2_nm.tga \ data1/textures/arena3/floor2.tga \ data1/textures/arena3/floor3.tga \ data1/textures/arena3/floor4.tga \ data1/textures/arena3/light1.tga \ data1/textures/arena3/light2.tga \ data1/textures/arena3/orba.tga \ data1/textures/arena3/orba.wal \ data1/textures/arena3/orbb.tga \ data1/textures/arena3/orbb.wal \ data1/textures/arena3/orbc.tga \ data1/textures/arena3/orbc.wal \ data1/textures/arena3/orbd.tga \ data1/textures/arena3/orbd.wal \ data1/textures/arena3/orbe.tga \ data1/textures/arena3/orbe.wal \ data1/textures/arena3/orbf.tga \ data1/textures/arena3/orbf.wal \ data1/textures/arena3/orbg.tga \ data1/textures/arena3/orbg.wal \ data1/textures/arena3/orbh.tga \ data1/textures/arena3/orbh.wal \ data1/textures/arena3/trim1.tga \ data1/textures/arena3/trim2.tga \ data1/textures/arena3/trimlite1.tga \ data1/textures/arena3/trimlite2.tga \ data1/textures/arena3/wall1.tga \ data1/textures/arena3/wall2.tga \ data1/textures/arena3/wall3.tga \ data1/textures/arena3/wall4.tga \ data1/textures/arena3/wall5.tga \ data1/textures/arena3/water_nm.tga \ data1/textures/arena3/water.tga \ data1/textures/arena4/bricks1_nm.tga \ data1/textures/arena4/bricks1.tga \ data1/textures/arena4/comp1_nm.tga \ data1/textures/arena4/comp1.tga \ data1/textures/arena4/floor1.cpt \ data1/textures/arena4/floor1_nm.tga \ data1/textures/arena4/floor1.tga \ data1/textures/arena4/floor2.tga \ data1/textures/arena4/floor3_nm.tga \ data1/textures/arena4/floor3.tga \ data1/textures/arena4/light1.tga \ data1/textures/arena4/light2.tga \ data1/textures/arena4/light3.tga \ data1/textures/arena4/support1_nm.tga \ data1/textures/arena4/support1.tga \ data1/textures/arena4/support2.tga \ data1/textures/arena4/wall1_nm.tga \ data1/textures/arena4/wall1.tga \ data1/textures/arena4/wall2_nm.tga \ data1/textures/arena4/wall2.tga \ data1/textures/arena5/bast1_nm.tga \ data1/textures/arena5/bast1.tga \ data1/textures/arena5/bast2.tga \ data1/textures/arena5/bricks4_1_nm.tga \ data1/textures/arena5/bricks4_1.tga \ data1/textures/arena5/cave_nm.tga \ data1/textures/arena5/cave.tga \ data1/textures/arena5/chain.tga \ data1/textures/arena5/cobweb.tga \ data1/textures/arena5/egypt1.tga \ data1/textures/arena5/egypt2.tga \ data1/textures/arena5/egypt3.tga \ data1/textures/arena5/egypt4.tga \ data1/textures/arena5/egypt5.tga \ data1/textures/arena5/egypt6_nm.tga \ data1/textures/arena5/egypt6.tga \ data1/textures/arena5/egypt7.tga \ data1/textures/arena5/fod.tga \ data1/textures/arena5/ground1_nm.tga \ data1/textures/arena5/ground1.tga \ data1/textures/arena5/light1.tga \ data1/textures/arena5/light2.tga \ data1/textures/arena5/lighta.tga \ data1/textures/arena5/lighta.wal \ data1/textures/arena5/lightb.tga \ data1/textures/arena5/lightb.wal \ data1/textures/arena5/lightc.tga \ data1/textures/arena5/lightc.wal \ data1/textures/arena5/lightd.tga \ data1/textures/arena5/lightd.wal \ data1/textures/arena5/lighte.tga \ data1/textures/arena5/lighte.wal \ data1/textures/arena5/lightf.tga \ data1/textures/arena5/lightf.wal \ data1/textures/arena5/o3cath11.tga \ data1/textures/arena5/o3cath3.tga \ data1/textures/arena5/o3cath5.tga \ data1/textures/arena5/o3cath8.tga \ data1/textures/arena5/o3rock5_nm.tga \ data1/textures/arena5/o3rock5.tga \ data1/textures/arena5/o3win12.tga \ data1/textures/arena5/rock2_nm.tga \ data1/textures/arena5/rock2.tga \ data1/textures/arena5/rock_3b_nm.tga \ data1/textures/arena5/rock_3b.tga \ data1/textures/arena5/sekhmet3.tga \ data1/textures/arena5/trim_nm.tga \ data1/textures/arena5/trim_sm.tga \ data1/textures/arena5/trim.tga \ data1/textures/arena6/alienarena2.tga \ data1/textures/arena6/alienarena.tga \ data1/textures/arena6/blacktrans.tga \ data1/textures/arena6/bricks1_hm.tga \ data1/textures/arena6/bricks1_nm.tga \ data1/textures/arena6/bricks1_sm.tga \ data1/textures/arena6/bricks1.tga \ data1/textures/arena6/city20.tga \ data1/textures/arena6/ctfwinblue.tga \ data1/textures/arena6/ctfwinred.tga \ data1/textures/arena6/flamejet.tga \ data1/textures/arena6/flare.tga \ data1/textures/arena6/fodblue.tga \ data1/textures/arena6/girder1.tga \ data1/textures/arena6/girder2.tga \ data1/textures/arena6/icerock2_nm.tga \ data1/textures/arena6/icerock2.tga \ data1/textures/arena6/icerock_nm.tga \ data1/textures/arena6/icerock.tga \ data1/textures/arena6/ice.tga \ data1/textures/arena6/plate1_nm.tga \ data1/textures/arena6/plate1_hm.tga \ data1/textures/arena6/plate1.tga \ data1/textures/arena6/plate2_nm.tga \ data1/textures/arena6/plate2_hm.tga \ data1/textures/arena6/plate2.tga \ data1/textures/arena6/plate3_nm.tga \ data1/textures/arena6/plate3_hm.tga \ data1/textures/arena6/plate3.tga \ data1/textures/arena6/plate4_nm.tga \ data1/textures/arena6/plate4_hm.tga \ data1/textures/arena6/plate4.tga \ data1/textures/arena6/plate5_nm.tga \ data1/textures/arena6/plate5_hm.tga \ data1/textures/arena6/plate5_sm.tga \ data1/textures/arena6/plate5.tga \ data1/textures/arena6/rimlight2.tga \ data1/textures/arena6/rimlight.tga \ data1/textures/arena6/rings.tga \ data1/textures/arena6/skullite_hm.tga \ data1/textures/arena6/skullite_nm.tga \ data1/textures/arena6/skullite.tga \ data1/textures/arena6/skull_nm.tga \ data1/textures/arena6/skull.tga \ data1/textures/arena6/snow_nm.tga \ data1/textures/arena6/snow.tga \ data1/textures/arena6/tech1_hm.tga \ data1/textures/arena6/tech1_nm.tga \ data1/textures/arena6/tech1.tga \ data1/textures/arena6/wires1_hm.tga \ data1/textures/arena6/wires1_nm.tga \ data1/textures/arena6/wires1.tga \ data1/textures/arena7/bluefloro_hm.tga \ data1/textures/arena7/bluefloro_nm.tga \ data1/textures/arena7/bluefloro.tga \ data1/textures/arena7/bluegrid.tga \ data1/textures/arena7/ceiling1.tga \ data1/textures/arena7/floor1_hm.tga \ data1/textures/arena7/floor1_nm.tga \ data1/textures/arena7/floor1.tga \ data1/textures/arena7/floor2_hm.tga \ data1/textures/arena7/floor2_nm.tga \ data1/textures/arena7/floor2.tga \ data1/textures/arena7/glass.tga \ data1/textures/arena7/grate1.tga \ data1/textures/arena7/light10.tga \ data1/textures/arena7/light11.tga \ data1/textures/arena7/light12.tga \ data1/textures/arena7/light13.tga \ data1/textures/arena7/light14.tga \ data1/textures/arena7/light1r.tga \ data1/textures/arena7/light1.tga \ data1/textures/arena7/light2.tga \ data1/textures/arena7/light3.tga \ data1/textures/arena7/light4.tga \ data1/textures/arena7/light5.tga \ data1/textures/arena7/light6.tga \ data1/textures/arena7/light7.tga \ data1/textures/arena7/light8.tga \ data1/textures/arena7/light9.tga \ data1/textures/arena7/lightgid2.tga \ data1/textures/arena7/lightgid.tga \ data1/textures/arena7/metal1.tga \ data1/textures/arena7/metal2_nm.tga \ data1/textures/arena7/metal2.tga \ data1/textures/arena7/metal3.tga \ data1/textures/arena7/piston1.tga \ data1/textures/arena7/redfloro_hm.tga \ data1/textures/arena7/redfloro_nm.tga \ data1/textures/arena7/redfloro.tga \ data1/textures/arena7/redgrid.tga \ data1/textures/arena7/tekfloor1_nm.tga \ data1/textures/arena7/tekfloor1.tga \ data1/textures/arena7/tekwall1_nm.tga \ data1/textures/arena7/tekwall1.tga \ data1/textures/arena7/tekwall2_nm.tga \ data1/textures/arena7/tekwall2.tga \ data1/textures/arena7/tekwall3_hm.tga \ data1/textures/arena7/tekwall3_nm.tga \ data1/textures/arena7/tekwall3r_hm.tga \ data1/textures/arena7/tekwall3r_nm.tga \ data1/textures/arena7/tekwall3r.tga \ data1/textures/arena7/tekwall3.tga \ data1/textures/arena7/tekwall4_nm.tga \ data1/textures/arena7/tekwall4r_nm.tga \ data1/textures/arena7/tekwall4r.tga \ data1/textures/arena7/tekwall4.tga \ data1/textures/arena7/tekwall5_nm.tga \ data1/textures/arena7/tekwall5.tga \ data1/textures/arena7/tekwall6_nm.tga \ data1/textures/arena7/tekwall6.tga \ data1/textures/arena7/tekwall7_nm.tga \ data1/textures/arena7/tekwall7.tga \ data1/textures/arena7/tekwall8_nm.tga \ data1/textures/arena7/tekwall8.tga \ data1/textures/arena7/tekwall9_hm.tga \ data1/textures/arena7/tekwall9_nm.tga \ data1/textures/arena7/tekwall9.tga \ data1/textures/arena7/warning.tga \ data1/textures/arena8/bark1_hm.tga \ data1/textures/arena8/bark1_nm.tga \ data1/textures/arena8/bark1.tga \ data1/textures/arena8/barnroof_nm.tga \ data1/textures/arena8/barnroof.tga \ data1/textures/arena8/barnwindows.tga \ data1/textures/arena8/barnwood2_nm.TGA \ data1/textures/arena8/barnwood2.tga \ data1/textures/arena8/barnwood_nm.tga \ data1/textures/arena8/barnwood.tga \ data1/textures/arena8/blackbrick1_nm.tga \ data1/textures/arena8/blackbrick1.tga \ data1/textures/arena8/blackbrick2_hm.tga \ data1/textures/arena8/blackbrick2_nm.tga \ data1/textures/arena8/blackbrick2.tga \ data1/textures/arena8/blackbrick3.tga \ data1/textures/arena8/brickwall1_hm.tga \ data1/textures/arena8/brickwall1_nm.tga \ data1/textures/arena8/brickwall1.tga \ data1/textures/arena8/cinderblocks_hm.tga \ data1/textures/arena8/cinderblocks_nm.tga \ data1/textures/arena8/cinderblocks.tga \ data1/textures/arena8/crackedrock1_hm.tga \ data1/textures/arena8/crackedrock1_nm.tga \ data1/textures/arena8/crackedrock1.tga \ data1/textures/arena8/crackedrock2_hm.tga \ data1/textures/arena8/crackedrock2_nm.tga \ data1/textures/arena8/crackedrock2.tga \ data1/textures/arena8/crackedrock3_hm.tga \ data1/textures/arena8/crackedrock3_nm.tga \ data1/textures/arena8/crackedrock3.tga \ data1/textures/arena8/crackedrock4_hm.tga \ data1/textures/arena8/crackedrock4_nm.tga \ data1/textures/arena8/crackedrock4.tga \ data1/textures/arena8/egyptbrick1_hm.tga \ data1/textures/arena8/egyptbrick1_nm.tga \ data1/textures/arena8/egyptbrick1.tga \ data1/textures/arena8/egyptfloor1_nm.tga \ data1/textures/arena8/egyptfloor1.tga \ data1/textures/arena8/egyptrock1_hm.tga \ data1/textures/arena8/egyptrock1_nm.tga \ data1/textures/arena8/egyptrock1.tga \ data1/textures/arena8/egyptrock2_nm.tga \ data1/textures/arena8/egyptrock2.tga \ data1/textures/arena8/fern.tga \ data1/textures/arena8/floor3_hm.tga \ data1/textures/arena8/floor3_nm.tga \ data1/textures/arena8/floor3.tga \ data1/textures/arena8/floor4_hm.tga \ data1/textures/arena8/floor4_nm.tga \ data1/textures/arena8/floor4.tga \ data1/textures/arena8/grass2_nm.tga \ data1/textures/arena8/grass2.tga \ data1/textures/arena8/grate1.tga \ data1/textures/arena8/ice.tga \ data1/textures/arena8/lavalmetal_nm.tga \ data1/textures/arena8/lavalmetal.tga \ data1/textures/arena8/leaves1.tga \ data1/textures/arena8/metal1_nm.tga \ data1/textures/arena8/metal1.tga \ data1/textures/arena8/metalroof_hm.tga \ data1/textures/arena8/metalroof_nm.tga \ data1/textures/arena8/metalroof.tga \ data1/textures/arena8/metaltrim1_hm.tga \ data1/textures/arena8/metaltrim1_nm.tga \ data1/textures/arena8/metaltrim1.tga \ data1/textures/arena8/metaltrim2_hm.tga \ data1/textures/arena8/metaltrim2_nm.tga \ data1/textures/arena8/metaltrim2.tga \ data1/textures/arena8/rock1_nm.tga \ data1/textures/arena8/rock1.tga \ data1/textures/arena8/roughwood_nm.tga \ data1/textures/arena8/roughwood.tga \ data1/textures/arena8/sand1.tga \ data1/textures/arena8/sand2.tga \ data1/textures/arena8/slime_nm.tga \ data1/textures/arena8/slime.tga \ data1/textures/arena8/snow_hm.tga \ data1/textures/arena8/snow_nm.tga \ data1/textures/arena8/snow.tga \ data1/textures/arena8/stonefloor1_hm.tga \ data1/textures/arena8/stonefloor1_nm.tga \ data1/textures/arena8/stonefloor1.tga \ data1/textures/arena8/wood1_hm.tga \ data1/textures/arena8/wood1_nm.tga \ data1/textures/arena8/wood1.tga \ data1/textures/arena9/beam_metal_nm.tga \ data1/textures/arena9/beam_metal.tga \ data1/textures/arena9/biggrate1_hm.tga \ data1/textures/arena9/biggrate1_nm.tga \ data1/textures/arena9/biggrate1.tga \ data1/textures/arena9/blueglass.tga \ data1/textures/arena9/boxmetal_hm.tga \ data1/textures/arena9/boxmetal_nm.tga \ data1/textures/arena9/boxmetal.tga \ data1/textures/arena9/brokencement1_nm.tga \ data1/textures/arena9/brokencement1.tga \ data1/textures/arena9/cable1.tga \ data1/textures/arena9/cable2.tga \ data1/textures/arena9/cable3.tga \ data1/textures/arena9/cable4.tga \ data1/textures/arena9/cementwall1_hm.tga \ data1/textures/arena9/cementwall1_nm.tga \ data1/textures/arena9/cementwall1.tga \ data1/textures/arena9/chainlinkfence.tga \ data1/textures/arena9/circuitwall1_hm.jpg \ data1/textures/arena9/circuitwall1_nm.jpg \ data1/textures/arena9/circuitwall1_nm.tga \ data1/textures/arena9/circuitwall1.tga \ data1/textures/arena9/comppanel2.tga \ data1/textures/arena9/comppanel.tga \ data1/textures/arena9/dmpltfloor1_hm.tga \ data1/textures/arena9/dmpltfloor1_nm.tga \ data1/textures/arena9/dmpltfloor1.tga \ data1/textures/arena9/factorybricks1_hm.tga \ data1/textures/arena9/factorybricks1_nm.tga \ data1/textures/arena9/factorybricks1.tga \ data1/textures/arena9/floor1_hm.tga \ data1/textures/arena9/floor1_nm.tga \ data1/textures/arena9/floor1.tga \ data1/textures/arena9/floor2_hm.tga \ data1/textures/arena9/floor2_nm.tga \ data1/textures/arena9/floor2.tga \ data1/textures/arena9/floor3_hm.tga \ data1/textures/arena9/floor3_nm.tga \ data1/textures/arena9/floor3.tga \ data1/textures/arena9/grate1_nm.tga \ data1/textures/arena9/grate1.tga \ data1/textures/arena9/grate2.tga \ data1/textures/arena9/grate3.tga \ data1/textures/arena9/greenfloor_nm.tga \ data1/textures/arena9/greenfloor.tga \ data1/textures/arena9/greenglass.tga \ data1/textures/arena9/greenmetal_nm.tga \ data1/textures/arena9/greenmetal.tga \ data1/textures/arena9/greenwall1_nm.tga \ data1/textures/arena9/greenwall1.tga \ data1/textures/arena9/greenwall2_hm.tga \ data1/textures/arena9/greenwall2_nm.tga \ data1/textures/arena9/greenwall2.tga \ data1/textures/arena9/greenwall3_nm.tga \ data1/textures/arena9/greenwall3.tga \ data1/textures/arena9/greenwall4_nm.tga \ data1/textures/arena9/greenwall4.tga \ data1/textures/arena9/greenwall5_hm.jpg \ data1/textures/arena9/greenwall5_nm.tga \ data1/textures/arena9/greenwall5.tga \ data1/textures/arena9/greenwall6_nm.tga \ data1/textures/arena9/greenwall6.tga \ data1/textures/arena9/hexfloor1_hm.tga \ data1/textures/arena9/hexfloor1_nm.tga \ data1/textures/arena9/hexfloor1.tga \ data1/textures/arena9/hexfloor2_hm.tga \ data1/textures/arena9/hexfloor2_nm.tga \ data1/textures/arena9/hexfloor2.tga \ data1/textures/arena9/hexfloor3_hm.tga \ data1/textures/arena9/hexfloor3_nm.tga \ data1/textures/arena9/hexfloor3.tga \ data1/textures/arena9/hexglass.tga \ data1/textures/arena9/hexgratefloor_hm.tga \ data1/textures/arena9/hexgratefloor_nm.tga \ data1/textures/arena9/hexgratefloor.tga \ data1/textures/arena9/icefloor1_nm.tga \ data1/textures/arena9/icefloor1.tga \ data1/textures/arena9/icemetal1_hm.tga \ data1/textures/arena9/icemetal1_nm.tga \ data1/textures/arena9/icemetal1.tga \ data1/textures/arena9/icemetal2_hm.tga \ data1/textures/arena9/icemetal2_nm.tga \ data1/textures/arena9/icemetal2.tga \ data1/textures/arena9/iceplate_hm.tga \ data1/textures/arena9/iceplate_nm.tga \ data1/textures/arena9/iceplate.tga \ data1/textures/arena9/icetrim1_hm.tga \ data1/textures/arena9/icetrim1_nm.tga \ data1/textures/arena9/icetrim1.tga \ data1/textures/arena9/icetrim2_hm.tga \ data1/textures/arena9/icetrim2_nm.tga \ data1/textures/arena9/icetrim2.tga \ data1/textures/arena9/icewall1_hm.tga \ data1/textures/arena9/icewall1_nm.tga \ data1/textures/arena9/icewall1.tga \ data1/textures/arena9/icicles.tga \ data1/textures/arena9/lightwall2_hm.tga \ data1/textures/arena9/lightwall2_nm.tga \ data1/textures/arena9/lightwall2.tga \ data1/textures/arena9/lightwhite.tga \ data1/textures/arena9/metal1_nm.tga \ data1/textures/arena9/metal1.tga \ data1/textures/arena9/metal2_nm.tga \ data1/textures/arena9/metal2.tga \ data1/textures/arena9/metal3_nm.tga \ data1/textures/arena9/metal3.tga \ data1/textures/arena9/metal4_nm.tga \ data1/textures/arena9/metal4.tga \ data1/textures/arena9/metal5_nm.tga \ data1/textures/arena9/metal5.tga \ data1/textures/arena9/metal6_nm.tga \ data1/textures/arena9/metal6.tga \ data1/textures/arena9/metalfloor1_hm.tga \ data1/textures/arena9/metalfloor1_nm.tga \ data1/textures/arena9/metalfloor1.tga \ data1/textures/arena9/metalgrate1.tga \ data1/textures/arena9/metalhole.tga \ data1/textures/arena9/metalplate1_nm.tga \ data1/textures/arena9/metalplate1.tga \ data1/textures/arena9/metalscale_hm.tga \ data1/textures/arena9/metalscale_nm.tga \ data1/textures/arena9/metalscale.tga \ data1/textures/arena9/metaltilefloor1_hm.tga \ data1/textures/arena9/metaltilefloor1_nm.tga \ data1/textures/arena9/metaltilefloor1.tga \ data1/textures/arena9/metaltrim1_hm.tga \ data1/textures/arena9/metaltrim1_nm.tga \ data1/textures/arena9/metaltrim1.tga \ data1/textures/arena9/metalwall1_hm.tga \ data1/textures/arena9/metalwall1_nm.tga \ data1/textures/arena9/metalwall1.tga \ data1/textures/arena9/metalwall2_hm.tga \ data1/textures/arena9/metalwall2_nm.tga \ data1/textures/arena9/metalwall2.tga \ data1/textures/arena9/metalwall3_hm.tga \ data1/textures/arena9/metalwall3_nm.tga \ data1/textures/arena9/metalwall3.tga \ data1/textures/arena9/metalwall4_hm.tga \ data1/textures/arena9/metalwall4_nm.tga \ data1/textures/arena9/metalwall4.tga \ data1/textures/arena9/metalwall5_hm.tga \ data1/textures/arena9/metalwall5_nm.tga \ data1/textures/arena9/metalwall5.tga \ data1/textures/arena9/metalwall6_hm.tga \ data1/textures/arena9/metalwall6_nm.tga \ data1/textures/arena9/metalwall6.tga \ data1/textures/arena9/metalwall7_hm.tga \ data1/textures/arena9/metalwall7_nm.tga \ data1/textures/arena9/metalwall7.tga \ data1/textures/arena9/metalwall8_hm.tga \ data1/textures/arena9/metalwall8_nm.tga \ data1/textures/arena9/metalwall8.tga \ data1/textures/arena9/panel1_nm.tga \ data1/textures/arena9/panel1.tga \ data1/textures/arena9/panel2_nm.tga \ data1/textures/arena9/panel2.tga \ data1/textures/arena9/panel3_hm.tga \ data1/textures/arena9/panel3_nm.tga \ data1/textures/arena9/panel3.tga \ data1/textures/arena9/panel4_hm.tga \ data1/textures/arena9/panel4_nm.tga \ data1/textures/arena9/panel4.tga \ data1/textures/arena9/panel5_nm.tga \ data1/textures/arena9/panel5.tga \ data1/textures/arena9/platefloor1_hm.tga \ data1/textures/arena9/platefloor1_nm.tga \ data1/textures/arena9/platefloor1.tga \ data1/textures/arena9/platefloor2_hm.tga \ data1/textures/arena9/platefloor2_nm.tga \ data1/textures/arena9/platefloor2.tga \ data1/textures/arena9/platefloor3_hm.tga \ data1/textures/arena9/platefloor3_nm.tga \ data1/textures/arena9/platefloor3.tga \ data1/textures/arena9/platefloor4_hm.tga \ data1/textures/arena9/platefloor4_nm.tga \ data1/textures/arena9/platefloor4.tga \ data1/textures/arena9/platefloor5_hm.tga \ data1/textures/arena9/platefloor5_nm.tga \ data1/textures/arena9/platefloor5.tga \ data1/textures/arena9/platefloor6_hm.tga \ data1/textures/arena9/platefloor6_nm.tga \ data1/textures/arena9/platefloor6.tga \ data1/textures/arena9/platefloor7_hm.tga \ data1/textures/arena9/platefloor7_nm.tga \ data1/textures/arena9/platefloor7.tga \ data1/textures/arena9/platefloor8_hm.tga \ data1/textures/arena9/platefloor8_nm.tga \ data1/textures/arena9/platefloor8.tga \ data1/textures/arena9/purpleglass.tga \ data1/textures/arena9/redglass.tga \ data1/textures/arena9/redtechwall2_hm.tga \ data1/textures/arena9/redtechwall2_nm.tga \ data1/textures/arena9/redtechwall2.tga \ data1/textures/arena9/redwall1_nm.tga \ data1/textures/arena9/redwall1.tga \ data1/textures/arena9/roundlightb.tga \ data1/textures/arena9/roundlightr.tga \ data1/textures/arena9/roundlight.tga \ data1/textures/arena9/rustmetal1_nm.tga \ data1/textures/arena9/rustmetal1.tga \ data1/textures/arena9/techfloor1_hm.tga \ data1/textures/arena9/techfloor1_nm.tga \ data1/textures/arena9/techfloor1.tga \ data1/textures/arena9/techwall1_hm.tga \ data1/textures/arena9/techwall1_nm.tga \ data1/textures/arena9/techwall1.tga \ data1/textures/arena9/techwall2_hm.tga \ data1/textures/arena9/techwall2_nm.tga \ data1/textures/arena9/techwall2.tga \ data1/textures/arena9/techwall3_hm.tga \ data1/textures/arena9/techwall3_nm.tga \ data1/textures/arena9/techwall3.tga \ data1/textures/arena9/trim1_nm.tga \ data1/textures/arena9/trim1.tga \ data1/textures/arena9/trim2_nm.tga \ data1/textures/arena9/trim2.tga \ data1/textures/arena9/wall1_nm.tga \ data1/textures/arena9/wall1.tga \ data1/textures/arena9/wall2_hm.tga \ data1/textures/arena9/wall2_nm.tga \ data1/textures/arena9/wall2.tga \ data1/textures/arena9/weapongrate.tga \ data1/textures/arena9/wetbricks1_hm.tga \ data1/textures/arena9/wetbricks1_nm.tga \ data1/textures/arena9/wetbricks1.tga \ data1/textures/arena9/wires1.tga \ data1/textures/arena9/wires2.tga \ data1/textures/arena9/wires3.tga \ data1/textures/arena9/wires4.tga \ data1/textures/arena9/wires5.tga \ data1/textures/arena9/wires6.tga \ data1/textures/arena9/wires7.tga \ data1/textures/arena9/wires8.tga \ data1/textures/arena9/yellowmetal_nm.tga \ data1/textures/arena9/yellowmetal.tga \ data1/textures/arena9/yellowwall1_hm.jpg \ data1/textures/arena9/yellowwall1_nm.tga \ data1/textures/arena9/yellowwall1.tga \ data1/textures/billboards/billboard1.tga \ data1/textures/billboards/billboard2.tga \ data1/textures/billboards/billboard3.tga \ data1/textures/billboards/billboard4.tga \ data1/textures/blanks/blank1.tga \ data1/textures/blanks/blank2.tga \ data1/textures/blanks/blank3.tga \ data1/textures/blanks/blank4.tga \ data1/textures/blanks/blank5.tga \ data1/textures/blanks/blank6.tga \ data1/textures/blanks/blank7.tga \ data1/textures/blood/blood_handprint.tga \ data1/textures/blood/blood_splatter1.tga \ data1/textures/blood/blood_splatter2.tga \ data1/textures/blood/blood_splatter3.tga \ data1/textures/blood/blood_splatter4.tga \ data1/textures/common/0_clip.tga \ data1/textures/common/0_hint.tga \ data1/textures/common/0_sky1.tga \ data1/textures/common/areaportal.tga \ data1/textures/common/caulk.tga \ data1/textures/common/clip.tga \ data1/textures/common/cushion.tga \ data1/textures/common/full_clip.tga \ data1/textures/common/hint.tga \ data1/textures/common/missileclip.tga \ data1/textures/common/nodraw.tga \ data1/textures/common/nodrop.tga \ data1/textures/common/nolightmap.tga \ data1/textures/common/origin.tga \ data1/textures/common/qer_portal.tga \ data1/textures/common/slick.tga \ data1/textures/common/trigger.tga \ data1/textures/common/weapclip.tga \ data1/textures/common/white.tga \ data1/textures/cr3blankclear.wal \ data1/textures/dalek/column1.tga \ data1/textures/dalek/console1.tga \ data1/textures/dalek/floor2.tga \ data1/textures/dalek/floor3.tga \ data1/textures/dalek/floor4.tga \ data1/textures/dalek/wall1.tga \ data1/textures/dalek/wall2.tga \ data1/textures/dalek/wall3.tga \ data1/textures/dalek/wall4.tga \ data1/textures/dalek/wall5.tga \ data1/textures/dalek/wall6.tga \ data1/textures/dalek/wall7.tga \ data1/textures/evil/confllrtile2pad_nm.tga \ data1/textures/evil/confllrtile2pad.tga \ data1/textures/evil/drktek_symb_hm.tga \ data1/textures/evil/drktek_symb_nm.tga \ data1/textures/evil/drktek_symb.tga \ data1/textures/evil/e5stepside_hm.tga \ data1/textures/evil/e5stepside_nm.tga \ data1/textures/evil/e5stepside.tga \ data1/textures/evil/e6basegrate_nm.tga \ data1/textures/evil/e6basegrate.tga \ data1/textures/evil/e6drstmetal_b_hm.tga \ data1/textures/evil/e6drstmetal_b_nm.tga \ data1/textures/evil/e6drstmetal_b.tga \ data1/textures/evil/e6dtrimnd_nm.tga \ data1/textures/evil/e6dtrimnd.tga \ data1/textures/evil/e6grate_flr_hm.tga \ data1/textures/evil/e6grate_flr_nm.tga \ data1/textures/evil/e6grate_flr.tga \ data1/textures/evil/e6horzlight_green.tga \ data1/textures/evil/e6horzlight.tga \ data1/textures/evil/e6launchengine_hm.tga \ data1/textures/evil/e6launchengine_nm.tga \ data1/textures/evil/e6launchengine.tga \ data1/textures/evil/e6metalfan.tga \ data1/textures/evil/e6simpwallsupp_rst_hm.tga \ data1/textures/evil/e6simpwallsupp_rst_nm.tga \ data1/textures/evil/e6simpwallsupp_rst.tga \ data1/textures/evil/e6supptrim128_hm.tga \ data1/textures/evil/e6supptrim128_nm.tga \ data1/textures/evil/e6supptrim128.tga \ data1/textures/evil/e6trim_basic128_nm.tga \ data1/textures/evil/e6trim_basic128.tga \ data1/textures/evil/e7beam01_hm.tga \ data1/textures/evil/e7beam01_nm.tga \ data1/textures/evil/e7beam01.tga \ data1/textures/evil/e8_btrim04_hm.tga \ data1/textures/evil/e8_btrim04_nm.tga \ data1/textures/evil/e8_btrim04.tga \ data1/textures/evil/e8crete01stair1_hm.tga \ data1/textures/evil/e8crete01stair1_nm.tga \ data1/textures/evil/e8crete01stair1.tga \ data1/textures/evil/e8crete03b_hm.tga \ data1/textures/evil/e8crete03b_nm.tga \ data1/textures/evil/e8crete03b.tga \ data1/textures/evil/e8crete03_hm.tga \ data1/textures/evil/e8crete03_nm.tga \ data1/textures/evil/e8crete03.tga \ data1/textures/evil/e8_jumppad02_hm.tga \ data1/textures/evil/e8_jumppad02_nm.tga \ data1/textures/evil/e8_jumppad02.tga \ data1/textures/evil/e8_launchpad1_hm.tga \ data1/textures/evil/e8_launchpad1_nm.tga \ data1/textures/evil/e8_launchpad1.tga \ data1/textures/evil/e8_mtlwall1_hm.tga \ data1/textures/evil/e8_mtlwall1_nm.tga \ data1/textures/evil/e8_mtlwall1.tga \ data1/textures/evil/e8tinylightblue.tga \ data1/textures/evil/e8warning_hm.tga \ data1/textures/evil/e8warning_nm.tga \ data1/textures/evil/e8warning.tga \ data1/textures/evil/e8xgirder_small.tga \ data1/textures/evil/e8xgirder.tga \ data1/textures/evil/ex_cretefloor_01_hm.tga \ data1/textures/evil/ex_cretefloor_01_nm.tga \ data1/textures/evil/ex_cretefloor_01.tga \ data1/textures/evil/ex_floor_mtl_grate_01_hm.tga \ data1/textures/evil/ex_floor_mtl_grate_01_nm.tga \ data1/textures/evil/ex_floor_mtl_grate_01.tga \ data1/textures/evil/ex_floor_tile_03_hm.tga \ data1/textures/evil/ex_floor_tile_03_nm.tga \ data1/textures/evil/ex_floor_tile_03.tga \ data1/textures/evil/ex_lightpanel_01_d.tga \ data1/textures/evil/exmetal_plate01b_d_hm.tga \ data1/textures/evil/exmetal_plate01b_d_nm.tga \ data1/textures/evil/exmetal_plate01b_d.tga \ data1/textures/evil/exmetalrib01_d_hm.tga \ data1/textures/evil/exmetalrib01_d_nm.tga \ data1/textures/evil/exmetalrib01_d.tga \ data1/textures/evil/ex_metalsupp01_d_hm.tga \ data1/textures/evil/ex_metalsupp01_d_nm.tga \ data1/textures/evil/ex_metalsupp01_d.tga \ data1/textures/evil/ex_rndfloor_01_d_hm.tga \ data1/textures/evil/ex_rndfloor_01_d_nm.tga \ data1/textures/evil/ex_rndfloor_01_d.tga \ data1/textures/evil/ex_steptop_01_d_hm.tga \ data1/textures/evil/ex_steptop_01_d_nm.tga \ data1/textures/evil/ex_steptop_01_d.tga \ data1/textures/evil/ex_trim_psimple_04_d_hm.tga \ data1/textures/evil/ex_trim_psimple_04_d_nm.tga \ data1/textures/evil/ex_trim_psimple_04_d.tga \ data1/textures/evil/ex_trim_psimple_05_d_hm.tga \ data1/textures/evil/ex_trim_psimple_05_d_nm.tga \ data1/textures/evil/ex_trim_psimple_05_d.tga \ data1/textures/evil/ex_trim_support_03_d_hm.tga \ data1/textures/evil/ex_trim_support_03_d_nm.tga \ data1/textures/evil/ex_trim_support_03_d.tga \ data1/textures/evil/ex_wall_01b_d_hm.tga \ data1/textures/evil/ex_wall_01b_d_nm.tga \ data1/textures/evil/ex_wall_01b_d.tga \ data1/textures/evil/ex_wall_panel_05_d_hm.tga \ data1/textures/evil/ex_wall_panel_05_d_nm.tga \ data1/textures/evil/ex_wall_panel_05_d.tga \ data1/textures/evil/ex_wall_pipe_d_hm.tga \ data1/textures/evil/ex_wall_pipe_d_nm.tga \ data1/textures/evil/ex_wall_pipe_d.tga \ data1/textures/evil/stepside_mtl2_hm.tga \ data1/textures/evil/stepside_mtl2_nm.tga \ data1/textures/evil/stepside_mtl2.tga \ data1/textures/evil/stepside_mtl3_hm.tga \ data1/textures/evil/stepside_mtl3_nm.tga \ data1/textures/evil/stepside_mtl3.tga \ data1/textures/evil/stepside_mtl4light_hm.tga \ data1/textures/evil/stepside_mtl4light_nm.tga \ data1/textures/evil/stepside_mtl4light.tga \ data1/textures/evil/stepside_mtl5_nm.tga \ data1/textures/evil/stepside_mtl5.tga \ data1/textures/evil/stepside_mtl_nm.tga \ data1/textures/evil/stepside_mtl.tga \ data1/textures/evil/steptop_mtl2_hm.tga \ data1/textures/evil/steptop_mtl2_nm.tga \ data1/textures/evil/steptop_mtl2.tga \ data1/textures/evil/steptop_mtl3_hm.tga \ data1/textures/evil/steptop_mtl3_nm.tga \ data1/textures/evil/steptop_mtl3.tga \ data1/textures/evil/techallmix_hm.tga \ data1/textures/evil/techallmix_nm.tga \ data1/textures/evil/techallmix.tga \ data1/textures/evil/trim_drkmtl_nm.tga \ data1/textures/evil/trim_drkmtl.tga \ data1/textures/evil/trimrstmtlpipes_nm.tga \ data1/textures/evil/trimrstmtlpipes.tga \ data1/textures/evil/trstmtl_panelbig_hm.tga \ data1/textures/evil/trstmtl_panelbig_nm.tga \ data1/textures/evil/trstmtl_panelbig.tga \ data1/textures/forsaken/glass.tga \ data1/textures/martian/biometal1_hm.tga \ data1/textures/martian/biometal1_nm.tga \ data1/textures/martian/biometal1.tga \ data1/textures/martian/chains.tga \ data1/textures/martian/coiledwire.tga \ data1/textures/martian/console1.tga \ data1/textures/martian/console2.tga \ data1/textures/martian/console3.tga \ data1/textures/martian/console4.tga \ data1/textures/martian/floor1.tga \ data1/textures/martian/floor2.tga \ data1/textures/martian/glass1.tga \ data1/textures/martian/grass.tga \ data1/textures/martian/grass_tga.tga \ data1/textures/martian/light1.tga \ data1/textures/martian/light2.tga \ data1/textures/martian/light3.tga \ data1/textures/martian/light4.tga \ data1/textures/martian/light5.tga \ data1/textures/martian/light6.tga \ data1/textures/martian/metal1.tga \ data1/textures/martian/metal2.tga \ data1/textures/martian/metal3.tga \ data1/textures/martian/metal4.tga \ data1/textures/martian/metal5.tga \ data1/textures/martian/metalrings1.tga \ data1/textures/martian/metalrings2.tga \ data1/textures/martian/ribtubeswirl_hm.jpg \ data1/textures/martian/ribtubeswirl_nm.jpg \ data1/textures/martian/ribtubeswirl.tga \ data1/textures/martian/saucerwall1_nm.tga \ data1/textures/martian/saucerwall1.tga \ data1/textures/martian/shiphull2_hm.tga \ data1/textures/martian/shiphull2_nm.tga \ data1/textures/martian/shiphull2.tga \ data1/textures/martian/shiphull_hm.tga \ data1/textures/martian/shiphull_nm.tga \ data1/textures/martian/shiphull.tga \ data1/textures/martian/skytrees.tga \ data1/textures/martian/skytrees_tga.tga \ data1/textures/martian/tree2_tga.tga \ data1/textures/martian/tree_bottom.tga \ data1/textures/martian/tree_bottom_tga.tga \ data1/textures/martian/tree_tga.tga \ data1/textures/martian/tree_top.tga \ data1/textures/martian/tree_top_tga.tga \ data1/textures/metal/bigconduit.tga \ data1/textures/metal/ceiling1.tga \ data1/textures/metal/door1.tga \ data1/textures/metal/doorjam.tga \ data1/textures/metal/fade1.tga \ data1/textures/metal/fade2.tga \ data1/textures/metal/floor.tga \ data1/textures/metal/light1_s.tga \ data1/textures/metal/light1.tga \ data1/textures/metal/light2_s.tga \ data1/textures/metal/light2.tga \ data1/textures/metal/light3_s.tga \ data1/textures/metal/light3.tga \ data1/textures/metal/light4.tga \ data1/textures/metal/light5_s.tga \ data1/textures/metal/light5.tga \ data1/textures/metal/medconduit.tga \ data1/textures/metal/metal1.tga \ data1/textures/metal/metal2.tga \ data1/textures/metal/metal3.tga \ data1/textures/metal/metal4.tga \ data1/textures/metal/metal5.tga \ data1/textures/metal/openfloor2.tga \ data1/textures/metal/openfloor.tga \ data1/textures/metal/plat.tga \ data1/textures/metal/saucer1.tga \ data1/textures/metal/saucer2.tga \ data1/textures/metal/silo.tga \ data1/textures/metal/smallconduit.tga \ data1/textures/metal/trim1.tga \ data1/textures/metal/trim2.tga \ data1/textures/metal/wall1_nm.tga \ data1/textures/metal/wall1_sm.tga \ data1/textures/metal/wall1.tga \ data1/textures/metal/wall2_nm.tga \ data1/textures/metal/wall2_sm.tga \ data1/textures/metal/wall2.tga \ data1/textures/metal/wall3.tga \ data1/textures/metal/wall4.tga \ data1/textures/metal/wall5.tga \ data1/textures/metal/wall6.tga \ data1/textures/metal/walllite.tga \ data1/textures/null.tga \ data1/textures/phillipk/pk01_panel01a_hm.tga \ data1/textures/phillipk/pk01_panel01a.tga \ data1/textures/phillipk/pk01_panel01b_hm.tga \ data1/textures/phillipk/pk01_panel01b.tga \ data1/textures/phillipk/pk01_panel03a_hm.tga \ data1/textures/phillipk/pk01_panel03a_nm.tga \ data1/textures/phillipk/pk01_panel03a.tga \ data1/textures/phillipk/pk01_panel03b_hm.tga \ data1/textures/phillipk/pk01_panel03b_nm.tga \ data1/textures/phillipk/pk01_panel03b.tga \ data1/textures/phillipk/pk01_panel_small01_hm.tga \ data1/textures/phillipk/pk01_panel_small01_nm.tga \ data1/textures/phillipk/pk01_panel_small01.tga \ data1/textures/phillipk/pk01_pan_wall02a1_hm.tga \ data1/textures/phillipk/pk01_pan_wall02a1_nm.tga \ data1/textures/phillipk/pk01_pan_wall02a1.tga \ data1/textures/phillipk/pk01_pan_wall02b1_hm.tga \ data1/textures/phillipk/pk01_pan_wall02b1_nm.tga \ data1/textures/phillipk/pk01_pan_wall02b1.tga \ data1/textures/phillipk/pk01_thin_wall01b_hm.tga \ data1/textures/phillipk/pk01_thin_wall01b_nm.tga \ data1/textures/phillipk/pk01_thin_wall01b.tga \ data1/textures/phillipk/pk01_thin_wall02b_hm.tga \ data1/textures/phillipk/pk01_thin_wall02b_nm.tga \ data1/textures/phillipk/pk01_thin_wall02b.tga \ data1/textures/phillipk/pk01_trims01a_hm.tga \ data1/textures/phillipk/pk01_trims01a_nm.tga \ data1/textures/phillipk/pk01_trims01a.tga \ data1/textures/phillipk/pk01_trims01b_hm.tga \ data1/textures/phillipk/pk01_trims01b_nm.tga \ data1/textures/phillipk/pk01_trims01b.tga \ data1/textures/phillipk/pk01_vent_wall01a_hm.tga \ data1/textures/phillipk/pk01_vent_wall01a.tga \ data1/textures/phillipk/pk01_vent_wall01_nm.tga \ data1/textures/phillipk/pk01_wall02a_hm.tga \ data1/textures/phillipk/pk01_wall02a_nm.tga \ data1/textures/phillipk/pk01_wall02a.tga \ data1/textures/phillipk/pk01_wall02b_hm.tga \ data1/textures/phillipk/pk01_wall02b.tga \ data1/textures/phillipk/pk01_wall02_nm.tga \ data1/textures/phillipk/pk01_wall04b_hm.tga \ data1/textures/phillipk/pk01_wall04b_nm.tga \ data1/textures/phillipk/pk01_wall04b.tga \ data1/textures/phillipk/pk02_ceiling02_fx.tga \ data1/textures/phillipk/pk02_ceiling02_nm.tga \ data1/textures/phillipk/pk02_ceiling02.tga \ data1/textures/phillipk/pk02_ceiling02r_nm.tga \ data1/textures/phillipk/pk02_ceiling02r.tga \ data1/textures/phillipk/pk02_computer01a_hm.tga \ data1/textures/phillipk/pk02_computer01a_nm.tga \ data1/textures/phillipk/pk02_computer01a.tga \ data1/textures/phillipk/pk02_floor08a_hm.tga \ data1/textures/phillipk/pk02_floor08a_nm.tga \ data1/textures/phillipk/pk02_floor08b_hm.tga \ data1/textures/phillipk/pk02_floor08b_nm.tga \ data1/textures/phillipk/pk02_floor08b.tga \ data1/textures/phillipk/pk02_floor08.tga \ data1/textures/phillipk/pk02_switches01a_nm.tga \ data1/textures/phillipk/pk02_switches01a.tga \ data1/textures/phillipk/pk02_switches01b_nm.tga \ data1/textures/phillipk/pk02_switches01b.tga \ data1/textures/phillipk/pk02_switches01c_nm.tga \ data1/textures/phillipk/pk02_switches01c.tga \ data1/textures/phillipk/pk02_wall07a_nm.tga \ data1/textures/phillipk/pk02_wall07a.tga \ data1/textures/phillipk/pk02_wall07b_nm.tga \ data1/textures/phillipk/pk02_wall07b.tga \ data1/textures/phillipk/pk02_wall_big02a_nm.tga \ data1/textures/phillipk/pk02_wall_big02a.tga \ data1/textures/phillipk/pk02_wall_big02b_nm.tga \ data1/textures/phillipk/pk02_wall_big02b.tga \ data1/textures/rage/beam_purple_hm.tga \ data1/textures/rage/beam_purple_nm.tga \ data1/textures/rage/beam_purple.tga \ data1/textures/rage/ceiling2_nm.tga \ data1/textures/rage/ceiling2.tga \ data1/textures/rage/ceiling_nm.tga \ data1/textures/rage/ceiling.tga \ data1/textures/rage/floor2.tga \ data1/textures/rage/floor5.tga \ data1/textures/rage/fod1.tga \ data1/textures/rage/grid1.tga \ data1/textures/rage/hexfloor_blue.tga \ data1/textures/rage/hexfloor_hm.tga \ data1/textures/rage/hexfloor_nm.tga \ data1/textures/rage/hexfloor_red.tga \ data1/textures/rage/hexfloor.tga \ data1/textures/rage/jpad1a.tga \ data1/textures/rage/lava.tga \ data1/textures/rage/light10.tga \ data1/textures/rage/light12.tga \ data1/textures/rage/light1.tga \ data1/textures/rage/light5.tga \ data1/textures/rage/light7.tga \ data1/textures/rage/light8.tga \ data1/textures/rage/metallight_2.tga \ data1/textures/rage/metal_panel.tga \ data1/textures/rage/rimlightpurple.tga \ data1/textures/rage/support_beam.tga \ data1/textures/rage/support_column_hm.tga \ data1/textures/rage/support_column_nm.tga \ data1/textures/rage/support_column.tga \ data1/textures/rage/support_trim.tga \ data1/textures/rage/trimlight_blue.tga \ data1/textures/rage/trimlight_purple.tga \ data1/textures/rage/trimlight_red.tga \ data1/textures/rage/wall_blue.tga \ data1/textures/ramp1b.tga \ data1/textures/ramp1b.wal \ data1/textures/ramp1c.tga \ data1/textures/ramp1c.wal \ data1/textures/ramp1d.tga \ data1/textures/ramp1d.wal \ data1/textures/ramp1e.tga \ data1/textures/ramp1e.wal \ data1/textures/ramp1f.tga \ data1/textures/ramp1f.wal \ data1/textures/ramp1.tga \ data1/textures/ramp1.wal \ data1/textures/rigel/baselightblue.tga \ data1/textures/rigel/baselightred.tga \ data1/textures/water/blood_nm.tga \ data1/textures/water/blood.tga \ data1/textures/water/bluewater_nm.tga \ data1/textures/water/bluewater.tga \ data1/textures/water/clearwater_nm.tga \ data1/textures/water/clearwater.tga \ data1/textures/water/flowingwater.tga \ data1/textures/water/waterpx.tga \ data1/textures/xempx/a3light1b.tga \ data1/textures/xempx/a6bt.tga \ data1/textures/xempx/a7light10.tga \ data1/textures/xempx/a7light1b.tga \ data1/textures/xempx/a7light1.tga \ data1/textures/xempx/a7light2.tga \ data1/textures/xempx/a7light3.tga \ data1/textures/xempx/a7light4.tga \ data1/textures/xempx/a9metal5.tga \ data1/textures/xempx/cretered_128_hm.tga \ data1/textures/xempx/cretered_128_nm.tga \ data1/textures/xempx/cretered_128.tga \ data1/textures/xempx/droplet_fx.tga \ data1/textures/xempx/e7trim_hm.tga \ data1/textures/xempx/e7trimlight_blue_hm.tga \ data1/textures/xempx/e7trimlight_blue_nm.tga \ data1/textures/xempx/e7trimlight_blue.tga \ data1/textures/xempx/e7trim_nm.tga \ data1/textures/xempx/e7trim.tga \ data1/textures/xempx/e8crete03ccred_hm.tga \ data1/textures/xempx/e8crete03ccred_nm.tga \ data1/textures/xempx/e8crete03ccred.tga \ data1/textures/xempx/emtl3-1_hm.tga \ data1/textures/xempx/emtl3-1_nm.tga \ data1/textures/xempx/emtl3-1.tga \ data1/textures/xempx/full_clip.tga \ data1/textures/xempx/ivy3_nm.tga \ data1/textures/xempx/ivy3.tga \ data1/textures/xempx/light1.tga \ data1/textures/xempx/lightbeam1.tga \ data1/textures/xempx/sign-electro_hm.tga \ data1/textures/xempx/sign-electro.tga \ data1/textures/xempx/sign_radioactive_hm.tga \ data1/textures/xempx/sign_radioactive.tga vehiclesdir = $(pkgdatadir) nobase_nodist_vehicles_DATA = \ data1/vehicles/bomber/bomb.md2 \ data1/vehicles/bomber/bomb.tga \ data1/vehicles/bomber/console_normal.tga \ data1/vehicles/bomber/console.tga \ data1/vehicles/bomber/helmet.md2 \ data1/vehicles/bomber/skin_normal.tga \ data1/vehicles/bomber/skin_fx.tga \ data1/vehicles/bomber/skin.tga \ data1/vehicles/bomber/tris.md2 \ data1/vehicles/bomber/v_wep.md2 \ data1/vehicles/bomber/window.md2 \ data1/vehicles/deathball/deathball.md2 \ data1/vehicles/deathball/deathball.tga \ data1/vehicles/deathball/deathmask.tga \ data1/vehicles/deathball/skin_fx.tga \ data1/vehicles/deathball/skin_normal.tga \ data1/vehicles/deathball/skin.tga \ data1/vehicles/deathball/v_wep.md2 \ data1/vehicles/hover/console_normal.tga \ data1/vehicles/hover/console.tga \ data1/vehicles/hover/flames.md2 \ data1/vehicles/hover/skin_fx.tga \ data1/vehicles/hover/skin.jpg \ data1/vehicles/hover/skin_normal.tga \ data1/vehicles/hover/tris.md2 \ data1/vehicles/hover/v_wep.md2 \ data1/vehicles/hover/window.md2 \ data1/vehicles/strafer/console_normal.tga \ data1/vehicles/strafer/console.tga \ data1/vehicles/strafer/skin_fx.tga \ data1/vehicles/strafer/skin_normal.tga \ data1/vehicles/strafer/skin.tga \ data1/vehicles/strafer/tris.md2 \ data1/vehicles/strafer/v_wep.md2 \ data1/vehicles/strafer/window.md2 graphical_presetsdir = $(pkgdatadir) nobase_nodist_graphical_presets_DATA = \ data1/graphical_presets/compatibility.cfg \ data1/graphical_presets/maxperformance.cfg \ data1/graphical_presets/performance.cfg \ data1/graphical_presets/quality.cfg \ data1/graphical_presets/maxquality.cfg tacticaldir = $(pkgdatadir) nobase_nodist_tactical_DATA = \ tactical/maps.lst \ tactical/motd.txt \ tactical/default.cfg \ tactical/server.cfg gamedata_files = \ $(nobase_nodist_env_DATA) \ $(nobase_nodist_fonts_DATA) \ $(nobase_nodist_gfx_DATA) \ $(nobase_nodist_levelshots_DATA) \ $(nobase_nodist_maps_DATA) \ $(nobase_nodist_models_DATA) \ $(nobase_nodist_particles_DATA) \ $(nobase_nodist_pics_DATA) \ $(nobase_nodist_players_DATA) \ $(nobase_nodist_scripts_DATA) \ $(nobase_nodist_sound_DATA) \ $(nobase_nodist_textures_DATA) \ $(nobase_nodist_vehicles_DATA) \ $(nobase_nodist_graphical_presets_DATA) \ $(nobase_nodist_tactical_DATA) alien-arena-7.66+dfsg/m4/0000700000175000017500000000000012207204656014141 5ustar zero79zero79alien-arena-7.66+dfsg/m4/ax_append_flag.m40000600000175000017500000000530412161401602017324 0ustar zero79zero79# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_append_flag.html # =========================================================================== # # SYNOPSIS # # AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE]) # # DESCRIPTION # # FLAG is appended to the FLAGS-VARIABLE shell variable, with a space # added in between. # # If FLAGS-VARIABLE is not specified, the current language's flags (e.g. # CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains # FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly # FLAG. # # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. # # LICENSE # # Copyright (c) 2008 Guido U. Draheim # Copyright (c) 2011 Maarten Bosmans # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 2 AC_DEFUN([AX_APPEND_FLAG], [AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])dnl AS_VAR_SET_IF(FLAGS, [case " AS_VAR_GET(FLAGS) " in *" $1 "*) AC_RUN_LOG([: FLAGS already contains $1]) ;; *) AC_RUN_LOG([: FLAGS="$FLAGS $1"]) AS_VAR_SET(FLAGS, ["AS_VAR_GET(FLAGS) $1"]) ;; esac], [AS_VAR_SET(FLAGS,["$1"])]) AS_VAR_POPDEF([FLAGS])dnl ])dnl AX_APPEND_FLAG alien-arena-7.66+dfsg/m4/ax_expand_prefix.m40000600000175000017500000000614412161401602017723 0ustar zero79zero79# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_expand_prefix.html # =========================================================================== # # SYNOPSIS # # AX_EXPAND_PREFIX # # DESCRIPTION # # When $prefix and $exec_prefix are still set to NONE then set them to the # usual default values - being based on $ac_default_prefix. - this macro # can be AC_REQUIREd by other macros that need to compute values for # installation directories. It has been observed that it was done wrong # over and over again, so this is a bit more safe to do. # # remember - setting exec_prefix='${prefix}' needs you interpolate # directories multiple times, it is not sufficient to just say # MYVAR="${datadir}/putter" but you do have to run `eval` a few times, # sth. like MYVAR=`eval "echo \"$MYVAR\""` done atleast two times. # # The implementation of this macro simply picks up the lines that would be # run at the start of AC_OUTPUT anyway to set the prefix/exec_prefix # defaults. Between AC_INIT and the first command to AC_REQUIRE this macro # you can set the two variables to something explicit instead. Probably, # any command to compute installation directories should be run _after_ # AM_INIT_AUTOMAKE # # LICENSE # # Copyright (c) 2008 Guido U. Draheim # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 7 AC_DEFUN([AX_EXPAND_PREFIX],[dnl # The prefix default can be set in configure.ac (otherwise it is /usr/local) test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. Allows to override the makevar 'prefix' later test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' ]) alien-arena-7.66+dfsg/m4/ax_pthread.m40000600000175000017500000003036612161401602016521 0ustar zero79zero79# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_pthread.html # =========================================================================== # # SYNOPSIS # # AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) # # DESCRIPTION # # This macro figures out how to build C programs using POSIX threads. It # sets the PTHREAD_LIBS output variable to the threads library and linker # flags, and the PTHREAD_CFLAGS output variable to any special C compiler # flags that are needed. (The user can also force certain compiler # flags/libs to be tested by setting these environment variables.) # # Also sets PTHREAD_CC to any special C compiler that is needed for # multi-threaded programs (defaults to the value of CC otherwise). (This # is necessary on AIX to use the special cc_r compiler alias.) # # NOTE: You are assumed to not only compile your program with these flags, # but also link it with them as well. e.g. you should link with # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # # If you are only building threads programs, you may wish to use these # variables in your default LIBS, CFLAGS, and CC: # # LIBS="$PTHREAD_LIBS $LIBS" # CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # CC="$PTHREAD_CC" # # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant # has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name # (e.g. PTHREAD_CREATE_UNDETACHED on AIX). # # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the # PTHREAD_PRIO_INHERIT symbol is defined when compiling with # PTHREAD_CFLAGS. # # ACTION-IF-FOUND is a list of shell commands to run if a threads library # is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it # is not found. If ACTION-IF-FOUND is not specified, the default action # will define HAVE_PTHREAD. # # Please let the authors know if this macro fails on any platform, or if # you have any other suggestions or comments. This macro was based on work # by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help # from M. Frigo), as well as ac_pthread and hb_pthread macros posted by # Alejandro Forero Cuervo to the autoconf macro repository. We are also # grateful for the helpful feedback of numerous users. # # Updated for Autoconf 2.68 by Daniel Richard G. # # LICENSE # # Copyright (c) 2008 Steven G. Johnson # Copyright (c) 2011 Daniel Richard G. # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 18 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_LANG_PUSH([C]) ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on True64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes) AC_MSG_RESULT($ax_pthread_ok) if test x"$ax_pthread_ok" = xno; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) # -pthreads: Solaris/gcc # -mthreads: Mingw32/gcc, Lynx/gcc # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads too; # also defines -D_REENTRANT) # ... -mt is also the pthreads flag for HP/aCC # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case ${host_os} in solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (We need to link with -pthreads/-mt/ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather # a function called by this macro, so we could check for that, but # who knows whether they'll stub that too in a future libc.) So, # we'll just look for -pthreads and -lpthread first: ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" ;; darwin*) ax_pthread_flags="-pthread $ax_pthread_flags" ;; esac if test x"$ax_pthread_ok" = xno; then for flag in $ax_pthread_flags; do case $flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; -*) AC_MSG_CHECKING([whether pthreads work with $flag]) PTHREAD_CFLAGS="$flag" ;; pthread-config) AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no) if test x"$ax_pthread_config" = xno; then continue; fi PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) AC_MSG_CHECKING([for the pthreads library -l$flag]) PTHREAD_LIBS="-l$flag" ;; esac save_LIBS="$LIBS" save_CFLAGS="$CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. AC_LINK_IFELSE([AC_LANG_PROGRAM([#include static void routine(void *a) { a = 0; } static void *start_routine(void *a) { return a; }], [pthread_t th; pthread_attr_t attr; pthread_create(&th, 0, start_routine, 0); pthread_join(th, 0); pthread_attr_init(&attr); pthread_cleanup_push(routine, 0); pthread_cleanup_pop(0) /* ; */])], [ax_pthread_ok=yes], []) LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" AC_MSG_RESULT($ax_pthread_ok) if test "x$ax_pthread_ok" = xyes; then break; fi PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$ax_pthread_ok" = xyes; then save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. AC_MSG_CHECKING([for joinable pthread attribute]) attr_name=unknown for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], [int attr = $attr; return attr /* ; */])], [attr_name=$attr; break], []) done AC_MSG_RESULT($attr_name) if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, [Define to necessary symbol if this constant uses a non-standard name on your system.]) fi AC_MSG_CHECKING([if more special flags are required for pthreads]) flag=no case ${host_os} in aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; osf* | hpux*) flag="-D_REENTRANT";; solaris*) if test "$GCC" = "yes"; then flag="-D_REENTRANT" else flag="-mt -D_REENTRANT" fi ;; esac AC_MSG_RESULT(${flag}) if test "x$flag" != xno; then PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" fi AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], ax_cv_PTHREAD_PRIO_INHERIT, [ AC_LINK_IFELSE([ AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT;]])], [ax_cv_PTHREAD_PRIO_INHERIT=yes], [ax_cv_PTHREAD_PRIO_INHERIT=no]) ]) AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.])) LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" # More AIX lossage: must compile with xlc_r or cc_r if test x"$GCC" != xyes; then AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) else PTHREAD_CC=$CC fi else PTHREAD_CC="$CC" fi AC_SUBST(PTHREAD_LIBS) AC_SUBST(PTHREAD_CFLAGS) AC_SUBST(PTHREAD_CC) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test x"$ax_pthread_ok" = xyes; then ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) : else ax_pthread_ok=no $2 fi AC_LANG_POP ])dnl AX_PTHREAD alien-arena-7.66+dfsg/m4/pkg.m40000600000175000017500000001623112161401602015156 0ustar zero79zero79# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- # serial 1 (pkg-config-0.24) # # Copyright © 2004 Scott James Remnant . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # PKG_PROG_PKG_CONFIG([MIN-VERSION]) # ---------------------------------- AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])# PKG_PROG_PKG_CONFIG # PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # # Check to see whether a particular set of modules exists. Similar # to PKG_CHECK_MODULES(), but does not set variables or print errors. # # Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) # only at the first occurence in configure.ac, so if the first place # it's called might be skipped (such as if it is within an "if", you # have to call PKG_CHECK_EXISTS manually # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_default([$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) # _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) # --------------------------------------------- m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes ], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])# _PKG_CONFIG # _PKG_SHORT_ERRORS_SUPPORTED # ----------------------------- AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])# _PKG_SHORT_ERRORS_SUPPORTED # PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], # [ACTION-IF-NOT-FOUND]) # # # Note that if there is a possibility the first call to # PKG_CHECK_MODULES might not happen, you should be sure to include an # explicit call to PKG_PROG_PKG_CONFIG in your configure.ac # # # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD m4_default([$4], [AC_MSG_ERROR( [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see .])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) $3 fi[]dnl ])# PKG_CHECK_MODULES # PKG_INSTALLDIR(DIRECTORY) # ------------------------- # Substitutes the variable pkgconfigdir as the location where a module # should install pkg-config .pc files. By default the directory is # $libdir/pkgconfig, but the default can be changed by passing # DIRECTORY. The user can override through the --with-pkgconfigdir # parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([pkgconfigdir], [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, [with_pkgconfigdir=]pkg_default) AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ]) dnl PKG_INSTALLDIR # PKG_NOARCH_INSTALLDIR(DIRECTORY) # ------------------------- # Substitutes the variable noarch_pkgconfigdir as the location where a # module should install arch-independent pkg-config .pc files. By # default the directory is $datadir/pkgconfig, but the default can be # changed by passing DIRECTORY. The user can override through the # --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([noarch-pkgconfigdir], [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, [with_noarch_pkgconfigdir=]pkg_default) AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ]) dnl PKG_NOARCH_INSTALLDIR alien-arena-7.66+dfsg/Makefile.in0000600000175000017500000063304312207204614015673 0ustar zero79zero79# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # Process this file with automake to produce Makefile.in # # Copyright (C) 2010 COR Entertainment, LLC. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # # include this file in the top level Makefile.am # # Copyright (C) 2010 COR Entertainment, LLC # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # # ------------------------------------------------------------- # Note: the GPL applies to this file, but not the files listed. # See license.txt for details, which states, in part: # "It is only permissible to distribute the game data(models, # maps, textures, sound, etc) as a whole, and with the # intention of being used with Alien Arena. It is not # permissible to distribute individual portions or items ofthe # game data without express consent from COR Entertainment." #-------------------------------------------------------------- # # Game data for distribution package # VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ DIST_COMMON = $(srcdir)/game_data.am $(srcdir)/Makefile.in \ $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(top_srcdir)/config/config.h.in \ $(am__dist_doc_DATA_DIST) $(dist_icon_DATA) \ $(nobase_dist_arena_DATA) $(nobase_dist_botinfo_DATA) \ $(nobase_dist_data1_DATA) COPYING INSTALL README \ config/compile config/config.guess config/config.sub \ config/depcomp config/install-sh config/missing \ $(top_srcdir)/config/compile $(top_srcdir)/config/config.guess \ $(top_srcdir)/config/config.sub \ $(top_srcdir)/config/install-sh $(top_srcdir)/config/missing subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_flag.m4 \ $(top_srcdir)/m4/ax_expand_prefix.m4 \ $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/pkg.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__dist_doc_DATA_DIST = docs/license.txt docs/README.txt README am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(docdir)" "$(DESTDIR)$(icondir)" \ "$(DESTDIR)$(arenadir)" "$(DESTDIR)$(botinfodir)" \ "$(DESTDIR)$(data1dir)" "$(DESTDIR)$(envdir)" \ "$(DESTDIR)$(fontsdir)" "$(DESTDIR)$(gfxdir)" \ "$(DESTDIR)$(graphical_presetsdir)" \ "$(DESTDIR)$(levelshotsdir)" "$(DESTDIR)$(mapsdir)" \ "$(DESTDIR)$(modelsdir)" "$(DESTDIR)$(particlesdir)" \ "$(DESTDIR)$(picsdir)" "$(DESTDIR)$(playersdir)" \ "$(DESTDIR)$(scriptsdir)" "$(DESTDIR)$(sounddir)" \ "$(DESTDIR)$(tacticaldir)" "$(DESTDIR)$(texturesdir)" \ "$(DESTDIR)$(vehiclesdir)" DATA = $(dist_doc_DATA) $(dist_icon_DATA) $(nobase_dist_arena_DATA) \ $(nobase_dist_botinfo_DATA) $(nobase_dist_data1_DATA) \ $(nobase_nodist_env_DATA) $(nobase_nodist_fonts_DATA) \ $(nobase_nodist_gfx_DATA) \ $(nobase_nodist_graphical_presets_DATA) \ $(nobase_nodist_levelshots_DATA) $(nobase_nodist_maps_DATA) \ $(nobase_nodist_models_DATA) $(nobase_nodist_particles_DATA) \ $(nobase_nodist_pics_DATA) $(nobase_nodist_players_DATA) \ $(nobase_nodist_scripts_DATA) $(nobase_nodist_sound_DATA) \ $(nobase_nodist_tactical_DATA) $(nobase_nodist_textures_DATA) \ $(nobase_nodist_vehicles_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ ALIENARENA_HOMEDIR = @ALIENARENA_HOMEDIR@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DEPS_CFLAGS = @DEPS_CFLAGS@ DEPS_LIBS = @DEPS_LIBS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GL_LIBDIR = @GL_LIBDIR@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ ODE_CFLAGS = @ODE_CFLAGS@ ODE_LIBS = @ODE_LIBS@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WIN32_LIBS = @WIN32_LIBS@ X11_CFLAGS = @X11_CFLAGS@ X11_LIBS = @X11_LIBS@ XMKMF = @XMKMF@ XXF86DGA_CFLAGS = @XXF86DGA_CFLAGS@ XXF86DGA_LIBS = @XXF86DGA_LIBS@ XXF86VM_CFLAGS = @XXF86VM_CFLAGS@ XXF86VM_LIBS = @XXF86VM_LIBS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ icondir = @icondir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = source ACLOCAL_AMFLAGS = -I m4 # Alien Arena documents to be installed in $docdir @INSTALL_DOCS_TRUE@dist_doc_DATA = \ @INSTALL_DOCS_TRUE@ docs/license.txt \ @INSTALL_DOCS_TRUE@ docs/README.txt \ @INSTALL_DOCS_TRUE@ README # Alien Arena icon dist_icon_DATA = alienarena.png # FUSE game server browser and Server management scripts # COPYING and INSTALL are GNU/FSF-supplied documents. EXTRA_DIST = \ Tools/fuse.tar.gz \ Tools/LinuxScripts \ COPYING \ INSTALL arenadir = $(pkgdatadir) nobase_dist_arena_DATA = \ arena/motd.txt \ arena/server.cfg botinfodir = $(pkgdatadir) nobase_dist_botinfo_DATA = \ botinfo/^1Squirtney.cfg \ botinfo/^3Marty.cfg \ botinfo/^3Shploik!.cfg \ botinfo/^4Invad^6ur.cfg \ botinfo/^5Beavis.cfg \ botinfo/^7Ruh^4Lur.cfg \ botinfo/^7The^1Zapp.cfg \ botinfo/Astral.cfg \ botinfo/Beavis.cfg \ botinfo/Butthead.cfg \ botinfo/Cyborg.cfg \ botinfo/Destoroyah.cfg \ botinfo/Fafa.cfg \ botinfo/Gamara.cfg \ botinfo/Ghidora.cfg \ botinfo/Hedorah.cfg \ botinfo/Johnny.cfg \ botinfo/Mogera.cfg \ botinfo/Mothra.cfg \ botinfo/Squirtney.cfg \ botinfo/Stryker.cfg \ botinfo/Yoz.cfg \ botinfo/sample.cfg \ botinfo/allbots.tmp \ botinfo/team.tmp \ botinfo/aoa-atlantis.tmp \ botinfo/aoa-corrosion.tmp \ botinfo/aoa-frost2k9.tmp \ botinfo/aoa-morpheus.tmp \ botinfo/aoa-zorn.tmp \ botinfo/db-chromium.tmp \ botinfo/db-icarus.tmp \ botinfo/db-vesuvius.tmp \ botinfo/dm-annihilation.tmp \ botinfo/dm-atlantis2k8.tmp \ botinfo/dm-babel2k11.tmp \ botinfo/dm-bloodfactory2k12.tmp \ botinfo/dm-chasmatic2k9.tmp \ botinfo/dm-command2k9.tmp \ botinfo/dm-corrosion.tmp \ botinfo/dm-crucible2k12.tmp \ botinfo/dm-deathray.tmp \ botinfo/dm-deimos2k9.tmp \ botinfo/dm-dismal2k11.tmp \ botinfo/dm-downfall.tmp \ botinfo/dm-dynamo2k12.tmp \ botinfo/dm-eternal.tmp \ botinfo/dm-extermination.tmp \ botinfo/dm-furious2k8.tmp \ botinfo/dm-goregrinder.tmp \ botinfo/dm-horus.tmp \ botinfo/dm-impact.tmp \ botinfo/dm-invasion.tmp \ botinfo/dm-leviathan2k12.tmp \ botinfo/dm-liberation.tmp \ botinfo/dm-neptune.tmp \ botinfo/dm-oblivion.tmp \ botinfo/dm-omega2k8.tmp \ botinfo/dm-purgatory.tmp \ botinfo/dm-saucer2k9.tmp \ botinfo/dm-turbo2k8.tmp \ botinfo/dm-vesuvius2k11.tmp \ botinfo/dm-violator2k11.tmp \ botinfo/dm-warmachine2k10.tmp \ botinfo/dm-zion2k9.tmp \ botinfo/dm-zorn2k11.tmp \ botinfo/tac-extermination.tmp \ botinfo/nav/aoa-atlantis.nod \ botinfo/nav/aoa-corrosion.nod \ botinfo/nav/aoa-frost2k9.nod \ botinfo/nav/aoa-morpheus.nod \ botinfo/nav/aoa-zorn.nod \ botinfo/nav/cp-ribeye.nod \ botinfo/nav/ctf-corrosion.nod \ botinfo/nav/ctf-cryogenic.nod \ botinfo/nav/ctf-europa2k8.nod \ botinfo/nav/ctf-frostbyte.nod \ botinfo/nav/ctf-goregrinder.nod \ botinfo/nav/ctf-invasion.nod \ botinfo/nav/ctf-oblivion.nod \ botinfo/nav/ctf-purgatory.nod \ botinfo/nav/ctf-titan2k8.nod \ botinfo/nav/ctf-vesuvius2k11.nod \ botinfo/nav/ctf-violator.nod \ botinfo/nav/ctf-zion2k9.nod \ botinfo/nav/db-chromium.nod \ botinfo/nav/db-icarus.nod \ botinfo/nav/db-vesuvius.nod \ botinfo/nav/dm-annihilation.nod \ botinfo/nav/dm-atlantis2k8.nod \ botinfo/nav/dm-babel2k11.nod \ botinfo/nav/dm-bloodfactory2k12.nod \ botinfo/nav/dm-chasmatic2k9.nod \ botinfo/nav/dm-command2k9.nod \ botinfo/nav/dm-corrosion.nod \ botinfo/nav/dm-crucible2k12.nod \ botinfo/nav/dm-deathray.nod \ botinfo/nav/dm-deimos2k9.nod \ botinfo/nav/dm-dismal2k11.nod \ botinfo/nav/dm-downfall.nod \ botinfo/nav/dm-dynamo2k12.nod \ botinfo/nav/dm-eternal.nod \ botinfo/nav/dm-europa2k8.nod \ botinfo/nav/dm-extermination.nod \ botinfo/nav/dm-furious2k8.nod \ botinfo/nav/dm-goregrinder.nod \ botinfo/nav/dm-horus.nod \ botinfo/nav/dm-impact.nod \ botinfo/nav/dm-invasion.nod \ botinfo/nav/dm-leviathan2k12.nod \ botinfo/nav/dm-liberation.nod \ botinfo/nav/dm-neptune.nod \ botinfo/nav/dm-oblivion.nod \ botinfo/nav/dm-omega2k8.nod \ botinfo/nav/dm-purgatory.nod \ botinfo/nav/dm-saucer2k9.nod \ botinfo/nav/dm-titan2k8.nod \ botinfo/nav/dm-turbo2k8.nod \ botinfo/nav/dm-vesuvius2k11.nod \ botinfo/nav/dm-violator2k11.nod \ botinfo/nav/dm-warmachine2k10.nod \ botinfo/nav/dm-zion2k9.nod \ botinfo/nav/dm-zorn2k11.nod \ botinfo/nav/tac-extermination.nod \ botinfo/nav/tca-corrosion.nod \ botinfo/nav/tca-cryogenic.nod \ botinfo/nav/tca-europa2k8.nod \ botinfo/nav/tca-frost.nod \ botinfo/nav/tca-invasion.nod \ botinfo/nav/tca-purgatory.nod \ botinfo/nav/tca-titan2k8.nod \ botinfo/nav/tca-zion.nod \ botinfo/nav/tca-zion2k9.nod data1dir = $(pkgdatadir) nobase_dist_data1_DATA = \ data1/default.cfg \ data1/maps.lst # Note: partitioning the data files like this keeps the command line length # in legal range for installation. However it does not work for creation # of the distribution package. Hence, "nodist" is specified and data is # copied to the distribution directory in "dist-hook:" # envdir = $(pkgdatadir) nobase_nodist_env_DATA = \ data1/env/alienbk.tga \ data1/env/aliendn.tga \ data1/env/alienft.tga \ data1/env/alienlf.tga \ data1/env/alienrt.tga \ data1/env/alienup.tga \ data1/env/deadcitybk.tga \ data1/env/deadcitydn.tga \ data1/env/deadcityft.tga \ data1/env/deadcitylf.tga \ data1/env/deadcityrt.tga \ data1/env/deadcityup.tga \ data1/env/egyptbk.tga \ data1/env/egyptdn.tga \ data1/env/egyptft.tga \ data1/env/egyptlf.tga \ data1/env/egyptrt.tga \ data1/env/egyptup.tga \ data1/env/greenbk.tga \ data1/env/greendn.tga \ data1/env/greenft.tga \ data1/env/greenlf.tga \ data1/env/greenrt.tga \ data1/env/greenup.tga \ data1/env/hellbk.tga \ data1/env/helldn.tga \ data1/env/hellft.tga \ data1/env/helllf.tga \ data1/env/hellrt.tga \ data1/env/hellup.tga \ data1/env/martianbk.tga \ data1/env/martiandn.tga \ data1/env/martianft.tga \ data1/env/martianlf.tga \ data1/env/martianrt.tga \ data1/env/martianup.tga \ data1/env/seabk.tga \ data1/env/seadn.tga \ data1/env/seaft.tga \ data1/env/sealf.tga \ data1/env/seart.tga \ data1/env/seaup.tga \ data1/env/space1bk.tga \ data1/env/space1dn.tga \ data1/env/space1ft.tga \ data1/env/space1lf.tga \ data1/env/space1rt.tga \ data1/env/space1up.tga \ data1/env/tekcitybk.tga \ data1/env/tekcitydn.tga \ data1/env/tekcityft.tga \ data1/env/tekcitylf.tga \ data1/env/tekcityrt.tga \ data1/env/tekcityup.tga fontsdir = $(pkgdatadir) nobase_nodist_fonts_DATA = \ data1/fonts/agentred.ttf \ data1/fonts/bluehigd.ttf \ data1/fonts/chicomono.ttf \ data1/fonts/creativeblock.ttf \ data1/fonts/freemono.ttf \ data1/fonts/freesans.ttf \ data1/fonts/orbitron.ttf \ data1/fonts/crackdown.ttf \ data1/fonts/bendable.ttf gfxdir = $(pkgdatadir) nobase_nodist_gfx_DATA = \ data1/gfx/aaglow.tga \ data1/gfx/adrenalbase.tga \ data1/gfx/adrenalmask.tga \ data1/gfx/annhiliationreflection.jpg \ data1/gfx/alienarena2gl.tga \ data1/gfx/bannerfx.tga \ data1/gfx/bconsole2.tga \ data1/gfx/bconsole.tga \ data1/gfx/beam1.tga \ data1/gfx/beam2.tga \ data1/gfx/beam3.tga \ data1/gfx/beam4.tga \ data1/gfx/beamfx.tga \ data1/gfx/beamgunfx.tga \ data1/gfx/blasterfx.tga \ data1/gfx/blooddrops.jpg \ data1/gfx/blooddrops_nm.jpg \ data1/gfx/bluecyborgfx.tga \ data1/gfx/bluelightning2.tga \ data1/gfx/bluelightning.tga \ data1/gfx/bluemartianfx.tga \ data1/gfx/blueoverlordfx.tga \ data1/gfx/bluewarriorfx.tga \ data1/gfx/bubbles.tga \ data1/gfx/caustics.tga \ data1/gfx/chrome2.tga \ data1/gfx/chrome.tga \ data1/gfx/citymask.tga \ data1/gfx/cloudsspace.tga \ data1/gfx/clouds.tga \ data1/gfx/cloudsthick.tga \ data1/gfx/comp1.tga \ data1/gfx/comp2.tga \ data1/gfx/cpribeyereflection.tga \ data1/gfx/defaultcommanderfx.tga \ data1/gfx/defaultcyborgfx.tga \ data1/gfx/defaultenforcerfx.tga \ data1/gfx/defaultlaurenfx.tga \ data1/gfx/defaultmartianfx.tga \ data1/gfx/defaultoverlordfx.tga \ data1/gfx/defaultslashbotfx.tga \ data1/gfx/defaultwarriorfx.tga \ data1/gfx/disruptorfx.tga \ data1/gfx/disruptormask.tga \ data1/gfx/distortwave.jpg \ data1/gfx/dmaquousreflection.tga \ data1/gfx/dmbeyondreflection.tga \ data1/gfx/dmdreadreflection.tga \ data1/gfx/dmturboreflection.tga \ data1/gfx/droplets.jpg \ data1/gfx/e6launchengine_fx.tga \ data1/gfx/e6launchengine_glow.tga \ data1/gfx/e6launchengine_mask.tga \ data1/gfx/e8_jumppad02_fx.tga \ data1/gfx/e8_jumppad02_mask.tga \ data1/gfx/e8_launchpad1_fx1.tga \ data1/gfx/e8_launchpad1_fx2.tga \ data1/gfx/e8_launchpad1_mask2.tga \ data1/gfx/egypt5_mask.tga \ data1/gfx/electrics2.tga \ data1/gfx/electrics3a.tga \ data1/gfx/electrics3b.tga \ data1/gfx/electrics3d.tga \ data1/gfx/electrics3.tga \ data1/gfx/electrics.tga \ data1/gfx/flares/flare0.tga \ data1/gfx/flares/flare1.tga \ data1/gfx/flares/flare2.tga \ data1/gfx/flash_noise.jpg \ data1/gfx/flash.tga \ data1/gfx/gamarafx.tga \ data1/gfx/glightning.tga \ data1/gfx/gold.tga \ data1/gfx/grapplefx.tga \ data1/gfx/grass.tga \ data1/gfx/grchrome.tga \ data1/gfx/greencircuit2.tga \ data1/gfx/greencircuit.tga \ data1/gfx/greenlightning.tga \ data1/gfx/greenline.tga \ data1/gfx/hconsole2.tga \ data1/gfx/hconsole3.tga \ data1/gfx/hconsole.tga \ data1/gfx/hoverfx.tga \ data1/gfx/leaves1.tga \ data1/gfx/lightning.tga \ data1/gfx/m_banner_main_mask.tga \ data1/gfx/menubar1.tga \ data1/gfx/menubar2.tga \ data1/gfx/menubar3.tga \ data1/gfx/menubar4.tga \ data1/gfx/metal3glow.tga \ data1/gfx/metalenvmap.jpg \ data1/gfx/minderaser_fx.tga \ data1/gfx/mirrorspec.tga \ data1/gfx/noise.tga \ data1/gfx/plate5fx.tga \ data1/gfx/purpleline.tga \ data1/gfx/quadbase.tga \ data1/gfx/radar/around.tga \ data1/gfx/radar/radarmap.tga \ data1/gfx/rain_a.tga \ data1/gfx/rainfxa.tga \ data1/gfx/rainfxb.tga \ data1/gfx/rainfxc.tga \ data1/gfx/rainfxd.tga \ data1/gfx/rainfxe.tga \ data1/gfx/rainfxf.tga \ data1/gfx/rainfxg.tga \ data1/gfx/rainfxh.tga \ data1/gfx/rain.tga \ data1/gfx/rayfx.tga \ data1/gfx/redcommanderfx.tga \ data1/gfx/redcircuit.tga \ data1/gfx/redlightning.tga \ data1/gfx/reflect.tga \ data1/gfx/rlauncherfx.tga \ data1/gfx/r_lightning.tga \ data1/gfx/sconsole.tga \ data1/gfx/shard_fx.tga \ data1/gfx/shardmask.tga \ data1/gfx/skullglow.tga \ data1/gfx/smartgunmask.tga \ data1/gfx/stepside_mtl4light_fx1.tga \ data1/gfx/sun1.jpg \ data1/gfx/sun2.jpg \ data1/gfx/sun.jpg \ data1/gfx/tekwallmask.tga \ data1/gfx/trim2mask.tga \ data1/gfx/tron2_commanderfx.tga \ data1/gfx/tron2_cyborgfx.tga \ data1/gfx/tron2_enforcerfx.tga \ data1/gfx/tron2_laurenfx.tga \ data1/gfx/tron2_martianfx.tga \ data1/gfx/tron2_overlordfx.tga \ data1/gfx/tron2_slashbotfx.tga \ data1/gfx/tron2_warriorfx.tga \ data1/gfx/tron3_commanderfx.tga \ data1/gfx/tron3_cyborgfx.tga \ data1/gfx/tron3_enforcerfx.tga \ data1/gfx/tron3_laurenfx.tga \ data1/gfx/tron3_martianfx.tga \ data1/gfx/tron3_overlordfx.tga \ data1/gfx/tron3_slashbotfx.tga \ data1/gfx/tron3_warriorfx.tga \ data1/gfx/tron_commanderfx.tga \ data1/gfx/tron_cyborgfx.tga \ data1/gfx/tron_enforcerfx.tga \ data1/gfx/tron_laurenfx.tga \ data1/gfx/tron_martianfx.tga \ data1/gfx/tron_overlordfx.tga \ data1/gfx/tron_slashbotfx.tga \ data1/gfx/tron_warriorfx.tga \ data1/gfx/vaporbase.tga \ data1/gfx/vapormask.tga \ data1/gfx/violator2fx.tga \ data1/gfx/violatorfx.tga \ data1/gfx/water/distort1.tga \ data1/gfx/water/normal1.tga \ data1/gfx/yellowline.tga levelshotsdir = $(pkgdatadir) nobase_nodist_levelshots_DATA = \ data1/levelshots/aoa-atlantis.jpg \ data1/levelshots/aoa-atlantis.txt \ data1/levelshots/aoa-corrosion.jpg \ data1/levelshots/aoa-corrosion.txt \ data1/levelshots/aoa-frost2k9.jpg \ data1/levelshots/aoa-frost2k9.txt \ data1/levelshots/aoa-morpheus.jpg \ data1/levelshots/aoa-morpheus.txt \ data1/levelshots/aoa-zorn.jpg \ data1/levelshots/aoa-zorn.txt \ data1/levelshots/cp-ribeye.jpg \ data1/levelshots/cp-ribeye.txt \ data1/levelshots/ctf-corrosion.jpg \ data1/levelshots/ctf-corrosion.txt \ data1/levelshots/ctf-cryogenic.jpg \ data1/levelshots/ctf-cryogenic.txt \ data1/levelshots/ctf-extermination.jpg \ data1/levelshots/ctf-extermination.txt \ data1/levelshots/ctf-frostbyte.jpg \ data1/levelshots/ctf-frostbyte.txt \ data1/levelshots/ctf-goregrinder.jpg \ data1/levelshots/ctf-goregrinder.txt \ data1/levelshots/ctf-invasion.jpg \ data1/levelshots/ctf-invasion.txt \ data1/levelshots/ctf-oblivion.jpg \ data1/levelshots/ctf-oblivion.txt \ data1/levelshots/ctf-purgatory.jpg \ data1/levelshots/ctf-purgatory.txt \ data1/levelshots/ctf-titan2k8.jpg \ data1/levelshots/ctf-titan2k8.txt \ data1/levelshots/ctf-vesuvius2k11.jpg \ data1/levelshots/ctf-vesuvius2k11.txt \ data1/levelshots/ctf-violator.jpg \ data1/levelshots/ctf-violator.txt \ data1/levelshots/ctf-zion2k9.jpg \ data1/levelshots/ctf-zion2k9.txt \ data1/levelshots/db-chromium.jpg \ data1/levelshots/db-chromium.txt \ data1/levelshots/db-icarus.jpg \ data1/levelshots/db-icarus.txt \ data1/levelshots/db-vesuvius.jpg \ data1/levelshots/db-vesuvius.txt \ data1/levelshots/dm-annihilation.jpg \ data1/levelshots/dm-annihilation.txt \ data1/levelshots/dm-atlantis2k8.jpg \ data1/levelshots/dm-atlantis2k8.txt \ data1/levelshots/dm-babel2k11.jpg \ data1/levelshots/dm-babel2k11.txt \ data1/levelshots/dm-bloodfactory2k12.jpg \ data1/levelshots/dm-bloodfactory2k12.txt \ data1/levelshots/dm-chasmatic2k9.jpg \ data1/levelshots/dm-chasmatic2k9.txt \ data1/levelshots/dm-command2k9.jpg \ data1/levelshots/dm-command2k9.txt \ data1/levelshots/dm-corrosion.jpg \ data1/levelshots/dm-corrosion.txt \ data1/levelshots/dm-crucible2k12.jpg \ data1/levelshots/dm-crucible2k12.txt \ data1/levelshots/dm-deathray.jpg \ data1/levelshots/dm-deathray.txt \ data1/levelshots/dm-deimos2k9.jpg \ data1/levelshots/dm-deimos2k9.txt \ data1/levelshots/dm-dismal2k11.jpg \ data1/levelshots/dm-dismal2k11.txt \ data1/levelshots/dm-downfall.jpg \ data1/levelshots/dm-downfall.txt \ data1/levelshots/dm-dynamo2k12.jpg \ data1/levelshots/dm-dynamo2k12.txt \ data1/levelshots/dm-eternal.jpg \ data1/levelshots/dm-eternal.txt \ data1/levelshots/dm-extermination.jpg \ data1/levelshots/dm-extermination.txt \ data1/levelshots/dm-furious2k8.jpg \ data1/levelshots/dm-furious2k8.txt \ data1/levelshots/dm-goregrinder.jpg \ data1/levelshots/dm-goregrinder.txt \ data1/levelshots/dm-horus.jpg \ data1/levelshots/dm-horus.txt \ data1/levelshots/dm-impact.jpg \ data1/levelshots/dm-impact.txt \ data1/levelshots/dm-invasion.jpg \ data1/levelshots/dm-invasion.txt \ data1/levelshots/dm-leviathan2k12.jpg \ data1/levelshots/dm-leviathan2k12.txt \ data1/levelshots/dm-liberation.jpg \ data1/levelshots/dm-liberation.txt \ data1/levelshots/dm-neptune.jpg \ data1/levelshots/dm-neptune.txt \ data1/levelshots/dm-oblivion.jpg \ data1/levelshots/dm-oblivion.txt \ data1/levelshots/dm-omega2k8.jpg \ data1/levelshots/dm-omega2k8.txt \ data1/levelshots/dm-purgatory.jpg \ data1/levelshots/dm-purgatory.txt \ data1/levelshots/dm-saucer2k9.jpg \ data1/levelshots/dm-saucer2k9.txt \ data1/levelshots/dm-turbo2k8.jpg \ data1/levelshots/dm-turbo2k8.txt \ data1/levelshots/dm-vesuvius2k11.jpg \ data1/levelshots/dm-vesuvius2k11.txt \ data1/levelshots/dm-violator2k11.jpg \ data1/levelshots/dm-violator2k11.txt \ data1/levelshots/dm-warmachine2k10.jpg \ data1/levelshots/dm-warmachine2k10.txt \ data1/levelshots/dm-zorn2k11.jpg \ data1/levelshots/dm-zorn2k11.txt \ data1/levelshots/dm-zion2k9.jpg \ data1/levelshots/dm-zion2k9.txt \ data1/levelshots/tac-extermination.jpg \ data1/levelshots/tac-extermination.txt \ data1/levelshots/tca-corrosion.jpg \ data1/levelshots/tca-corrosion.txt \ data1/levelshots/tca-cryogenic.jpg \ data1/levelshots/tca-cryogenic.txt \ data1/levelshots/tca-extermination.jpg \ data1/levelshots/tca-extermination.txt \ data1/levelshots/tca-frost.jpg \ data1/levelshots/tca-frost.txt \ data1/levelshots/tca-purgatory.jpg \ data1/levelshots/tca-purgatory.txt \ data1/levelshots/tca-titan2k8.jpg \ data1/levelshots/tca-titan2k8.txt \ data1/levelshots/tca-zion2k9.jpg \ data1/levelshots/tca-zion2k9.txt mapsdir = $(pkgdatadir) nobase_nodist_maps_DATA = \ data1/maps/aoa-atlantis.bsp \ data1/maps/aoa-corrosion.bsp \ data1/maps/aoa-frost2k9.bsp \ data1/maps/aoa-morpheus.bsp \ data1/maps/aoa-zorn.bsp \ data1/maps/cp-ribeye.bsp \ data1/maps/ctf-corrosion.bsp \ data1/maps/ctf-corrosion.lightmap \ data1/maps/ctf-cryogenic.bsp \ data1/maps/ctf-extermination.bsp \ data1/maps/ctf-extermination.lightmap \ data1/maps/ctf-frostbyte.bsp \ data1/maps/ctf-goregrinder.bsp \ data1/maps/ctf-invasion.bsp \ data1/maps/ctf-invasion.lightmap \ data1/maps/ctf-oblivion.bsp \ data1/maps/ctf-oblivion.lightmap \ data1/maps/ctf-purgatory.bsp \ data1/maps/ctf-titan2k8.bsp \ data1/maps/ctf-vesuvius2k11.bsp \ data1/maps/ctf-vesuvius2k11.lightmap \ data1/maps/ctf-violator.bsp \ data1/maps/ctf-zion2k9.bsp \ data1/maps/db-chromium.bsp \ data1/maps/db-icarus.bsp \ data1/maps/db-vesuvius.bsp \ data1/maps/dm-annihilation.bsp \ data1/maps/dm-annihilation.lightmap \ data1/maps/dm-atlantis2k8.bsp \ data1/maps/dm-babel2k11.bsp \ data1/maps/dm-bloodfactory2k12.bsp \ data1/maps/dm-chasmatic2k9.bsp \ data1/maps/dm-command2k9.bsp \ data1/maps/dm-corrosion.bsp \ data1/maps/dm-corrosion.lightmap \ data1/maps/dm-crucible2k12.bsp \ data1/maps/dm-crucible2k12.lightmap \ data1/maps/dm-deathray.bsp \ data1/maps/dm-deimos2k9.bsp \ data1/maps/dm-deimos2k9.lightmap \ data1/maps/dm-dismal2k11.bsp \ data1/maps/dm-downfall.bsp \ data1/maps/dm-dynamo2k12.bsp \ data1/maps/dm-dynamo2k12.lightmap \ data1/maps/dm-eternal.bsp \ data1/maps/dm-extermination.bsp \ data1/maps/dm-extermination.lightmap \ data1/maps/dm-furious2k8.bsp \ data1/maps/dm-furious2k8.lightmap \ data1/maps/dm-goregrinder.bsp \ data1/maps/dm-goregrinder.lightmap \ data1/maps/dm-horus.bsp \ data1/maps/dm-impact.bsp \ data1/maps/dm-impact.lightmap \ data1/maps/dm-invasion.bsp \ data1/maps/dm-invasion.lightmap \ data1/maps/dm-leviathan2k12.bsp \ data1/maps/dm-liberation.bsp \ data1/maps/dm-neptune.bsp \ data1/maps/dm-neptune.lightmap \ data1/maps/dm-oblivion.bsp \ data1/maps/dm-oblivion.lightmap \ data1/maps/dm-omega2k8.bsp \ data1/maps/dm-omega2k8.lightmap \ data1/maps/dm-purgatory.bsp \ data1/maps/dm-saucer2k9.bsp \ data1/maps/dm-turbo2k8.bsp \ data1/maps/dm-vesuvius2k11.bsp \ data1/maps/dm-vesuvius2k11.lightmap \ data1/maps/dm-violator2k11.bsp \ data1/maps/dm-violator2k11.lightmap \ data1/maps/dm-warmachine2k10.bsp \ data1/maps/dm-warmachine2k10.lightmap \ data1/maps/dm-zorn2k11.bsp \ data1/maps/dm-zion2k9.bsp \ data1/maps/tac-extermination.bsp \ data1/maps/tac-extermination.lightmap \ data1/maps/tca-corrosion.bsp \ data1/maps/tca-corrosion.lightmap \ data1/maps/tca-cryogenic.bsp \ data1/maps/tca-extermination.bsp \ data1/maps/tca-invasion \ data1/maps/tca-invasion.entdef \ data1/maps/tca-purgatory.bsp \ data1/maps/tca-titan2k8.bsp \ data1/maps/tca-zion2k9.bsp \ data1/maps/meshes/arch_fx.tga \ data1/maps/meshes/arch.md2 \ data1/maps/meshes/arch_normal.jpg \ data1/maps/meshes/arch.tga \ data1/maps/meshes/barrel.jpg \ data1/maps/meshes/barrel.md2 \ data1/maps/meshes/barrel_normal.jpg \ data1/maps/meshes/bentconduit.md2 \ data1/maps/meshes/bignode_fx.tga \ data1/maps/meshes/bignode.jpg \ data1/maps/meshes/bignode.md2 \ data1/maps/meshes/bignode_normal.jpg \ data1/maps/meshes/bigribpipe.jpg \ data1/maps/meshes/bigribpipe.md2 \ data1/maps/meshes/bigribpipe_normal.jpg \ data1/maps/meshes/brainjarcover.md2 \ data1/maps/meshes/brainjar.md2 \ data1/maps/meshes/brainjar_normal.tga \ data1/maps/meshes/brainjar.tga \ data1/maps/meshes/cables2.md2 \ data1/maps/meshes/cables3.md2 \ data1/maps/meshes/cables4.md2 \ data1/maps/meshes/cables.jpg \ data1/maps/meshes/cables.md2 \ data1/maps/meshes/cables_normal.jpg \ data1/maps/meshes/cannister.jpg \ data1/maps/meshes/cannister.md2 \ data1/maps/meshes/cannister_normal.jpg \ data1/maps/meshes/clamps.jpg \ data1/maps/meshes/clamps.md2 \ data1/maps/meshes/clamps_normal.jpg \ data1/maps/meshes/cmdconsole_fx.tga \ data1/maps/meshes/cmdconsole.jpg \ data1/maps/meshes/cmdconsole.md2 \ data1/maps/meshes/cmdconsole_normal.jpg \ data1/maps/meshes/conduit.jpg \ data1/maps/meshes/conduit_normal.jpg \ data1/maps/meshes/controls_fx.tga \ data1/maps/meshes/controls.md2 \ data1/maps/meshes/controls_normal.tga \ data1/maps/meshes/controls.tga \ data1/maps/meshes/dome.md2 \ data1/maps/meshes/dualpipes.jpg \ data1/maps/meshes/dualpipes.md2 \ data1/maps/meshes/dualpipes_normal.jpg \ data1/maps/meshes/electrodecover.md2 \ data1/maps/meshes/electrode.md2 \ data1/maps/meshes/electrode.tga \ data1/maps/meshes/electrode_normal.tga \ data1/maps/meshes/eyejar_fx.tga \ data1/maps/meshes/eyejarglass.md2 \ data1/maps/meshes/eyejar.md2 \ data1/maps/meshes/eyejar_normal.tga \ data1/maps/meshes/eyejar.tga \ data1/maps/meshes/flagpad_fx.tga \ data1/maps/meshes/flagpad.md2 \ data1/maps/meshes/flagpad_normal.tga \ data1/maps/meshes/flagpad.tga \ data1/maps/meshes/floorcables.md2 \ data1/maps/meshes/generator.jpg \ data1/maps/meshes/generator.md2 \ data1/maps/meshes/generator_normal.jpg \ data1/maps/meshes/gothic/blade.jpg \ data1/maps/meshes/gothic/blade.md2 \ data1/maps/meshes/gothic/blade_normal.jpg \ data1/maps/meshes/gothic/ceillamp.md2 \ data1/maps/meshes/gothic/column1.jpg \ data1/maps/meshes/gothic/column1.md2 \ data1/maps/meshes/gothic/column1_normal.jpg \ data1/maps/meshes/gothic/dragon.jpg \ data1/maps/meshes/gothic/dragon.md2 \ data1/maps/meshes/gothic/dragon_normal.jpg \ data1/maps/meshes/gothic/fdstatue_green.md2 \ data1/maps/meshes/gothic/fd_statue_normal.jpg \ data1/maps/meshes/gothic/fdstatue_red.md2 \ data1/maps/meshes/gothic/freedom_statue_green.jpg \ data1/maps/meshes/gothic/freedom_statue_red.jpg \ data1/maps/meshes/gothic/lamp2b_fx.tga \ data1/maps/meshes/gothic/lamp2b.md2 \ data1/maps/meshes/gothic/lamp2b.tga \ data1/maps/meshes/gothic/lamp2_fx.tga \ data1/maps/meshes/gothic/lamp2.md2 \ data1/maps/meshes/gothic/lamp2_normal.tga \ data1/maps/meshes/gothic/lamp2.tga \ data1/maps/meshes/gothic/lamp_fx.tga \ data1/maps/meshes/gothic/lamp.md2 \ data1/maps/meshes/gothic/lamp_normal.tga \ data1/maps/meshes/gothic/lamp.tga \ data1/maps/meshes/gothic/meat1.jpg \ data1/maps/meshes/gothic/meat1.md2 \ data1/maps/meshes/gothic/meat1_normal.jpg \ data1/maps/meshes/gothic/meat2.jpg \ data1/maps/meshes/gothic/meat2.md2 \ data1/maps/meshes/gothic/meat2_normal.jpg \ data1/maps/meshes/gothic/meat3.jpg \ data1/maps/meshes/gothic/meat3.md2 \ data1/maps/meshes/gothic/meat3_normal.jpg \ data1/maps/meshes/gothic/neptune.jpg \ data1/maps/meshes/gothic/neptune.md2 \ data1/maps/meshes/gothic/neptune_normal.jpg \ data1/maps/meshes/gothic/root.jpg \ data1/maps/meshes/gothic/root.md2 \ data1/maps/meshes/gothic/root_normal.jpg \ data1/maps/meshes/gothic/skeleton1.md2 \ data1/maps/meshes/gothic/skeleton2.md2 \ data1/maps/meshes/gothic/skeleton3.md2 \ data1/maps/meshes/gothic/skeleton.jpg \ data1/maps/meshes/gothic/skeleton_normal.jpg \ data1/maps/meshes/gothic/throne.jpg \ data1/maps/meshes/gothic/throne.md2 \ data1/maps/meshes/gothic/throne_normal.jpg \ data1/maps/meshes/greenblob_fx.tga \ data1/maps/meshes/greenblob.jpg \ data1/maps/meshes/greenblob.md2 \ data1/maps/meshes/hanger.md2 \ data1/maps/meshes/hanger_normal.jpg \ data1/maps/meshes/hanger.tga \ data1/maps/meshes/hangingmartian.md2 \ data1/maps/meshes/hangingmhelmet.md2 \ data1/maps/meshes/hatch.jpg \ data1/maps/meshes/hatch.md2 \ data1/maps/meshes/hatch_normal.jpg \ data1/maps/meshes/injector.jpg \ data1/maps/meshes/injector.md2 \ data1/maps/meshes/injector_normal.jpg \ data1/maps/meshes/lamp2_fx.tga \ data1/maps/meshes/lamp2.jpg \ data1/maps/meshes/lamp2.md2 \ data1/maps/meshes/lamp2_normal.jpg \ data1/maps/meshes/martian.jpg \ data1/maps/meshes/martian.md2 \ data1/maps/meshes/martian_normal.jpg \ data1/maps/meshes/metpipe1.md2 \ data1/maps/meshes/metpipe2.md2 \ data1/maps/meshes/metpipe3.md2 \ data1/maps/meshes/mhelmet.md2 \ data1/maps/meshes/monitor2.md2 \ data1/maps/meshes/monitor_normal.tga \ data1/maps/meshes/monitor.jpg \ data1/maps/meshes/monitormask.tga \ data1/maps/meshes/monitor.md2 \ data1/maps/meshes/mpa1.jpg \ data1/maps/meshes/mpa1_normal.jpg \ data1/maps/meshes/mpa2.jpg \ data1/maps/meshes/mpa2_normal.jpg \ data1/maps/meshes/pipes1.jpg \ data1/maps/meshes/pipes1_normal.jpg \ data1/maps/meshes/pipes.md2 \ data1/maps/meshes/piston.md2 \ data1/maps/meshes/piston_normal.jpg \ data1/maps/meshes/piston.tga \ data1/maps/meshes/pulsar.md2 \ data1/maps/meshes/pulsar_normal.jpg \ data1/maps/meshes/pulsar.tga \ data1/maps/meshes/railcarglass.md2 \ data1/maps/meshes/railcar.jpg \ data1/maps/meshes/railcarmartian.md2 \ data1/maps/meshes/railcar.md2 \ data1/maps/meshes/railcarmhelmet.md2 \ data1/maps/meshes/railcar_normal.jpg \ data1/maps/meshes/redblob_fx.tga \ data1/maps/meshes/redblob.jpg \ data1/maps/meshes/redblob.md2 \ data1/maps/meshes/redblob_normal.jpg \ data1/maps/meshes/ribtube1.md2 \ data1/maps/meshes/ribtube2.md2 \ data1/maps/meshes/ribtube3.md2 \ data1/maps/meshes/ribtube.jpg \ data1/maps/meshes/ribtube_normal.jpg \ data1/maps/meshes/sconduit1.md2 \ data1/maps/meshes/sconduit2.md2 \ data1/maps/meshes/scopecover.md2 \ data1/maps/meshes/scope.md2 \ data1/maps/meshes/scope_normal.tga \ data1/maps/meshes/scope.tga \ data1/maps/meshes/spingear_fx.tga \ data1/maps/meshes/spingear.jpg \ data1/maps/meshes/spingear.md2 \ data1/maps/meshes/spingear_normal.jpg \ data1/maps/meshes/spintube.jpg \ data1/maps/meshes/spintube.md2 \ data1/maps/meshes/spintube_normal.jpg \ data1/maps/meshes/straightconduit.md2 \ data1/maps/meshes/tech/bigribtube.jpg \ data1/maps/meshes/tech/bigribtube_normal.jpg \ data1/maps/meshes/tech/blueribtube1.md2 \ data1/maps/meshes/tech/blueribtube_fx.tga \ data1/maps/meshes/tech/blueribtube.jpg \ data1/maps/meshes/tech/glasstube.md2 \ data1/maps/meshes/tech/railing2.md2 \ data1/maps/meshes/tech/railing3.md2 \ data1/maps/meshes/tech/railing4.md2 \ data1/maps/meshes/tech/railing5.md2 \ data1/maps/meshes/tech/railing.jpg \ data1/maps/meshes/tech/railing.md2 \ data1/maps/meshes/tech/railing_normal.jpg \ data1/maps/meshes/tech/redribtube1.md2 \ data1/maps/meshes/tech/redribtube_fx.tga \ data1/maps/meshes/tech/redribtube.jpg \ data1/maps/meshes/tech/ribtubebig1.md2 \ data1/maps/meshes/tech/ribtubebig2.md2 \ data1/maps/meshes/tech/ribtubebig3.md2 \ data1/maps/meshes/tech/ribtubebig4.md2 \ data1/maps/meshes/tech/ribtubebig5.md2 \ data1/maps/meshes/tech/ribtubebig6.md2 \ data1/maps/meshes/tech/ribtubebig7.md2 \ data1/maps/meshes/tech/ribtubebig8.md2 \ data1/maps/meshes/tech/rotator_fx.tga \ data1/maps/meshes/tech/rotatorglass.md2 \ data1/maps/meshes/tech/rotatorimage1.md2 \ data1/maps/meshes/tech/rotatorimage2.md2 \ data1/maps/meshes/tech/rotatorimage3.md2 \ data1/maps/meshes/tech/rotatorimage4.md2 \ data1/maps/meshes/tech/rotator.jpg \ data1/maps/meshes/tech/rotator.md2 \ data1/maps/meshes/tech/rotator_normal.jpg \ data1/maps/meshes/tech/rotimage1_normal.tga \ data1/maps/meshes/tech/rotimage1.tga \ data1/maps/meshes/tech/rotimage2_normal.tga \ data1/maps/meshes/tech/rotimage2.tga \ data1/maps/meshes/tech/rotimage3_normal.tga \ data1/maps/meshes/tech/rotimage3.tga \ data1/maps/meshes/tech/rotimage4_normal.tga \ data1/maps/meshes/tech/rotimage4.tga \ data1/maps/meshes/tech/slimegen2.md2 \ data1/maps/meshes/tech/slimegen.jpg \ data1/maps/meshes/tech/slimegen.md2 \ data1/maps/meshes/tech/slimegen_fx.tga \ data1/maps/meshes/tech/slimegenblue_fx.tga \ data1/maps/meshes/tech/slimegenblue.jpg \ data1/maps/meshes/tech/slimegenblue.md2 \ data1/maps/meshes/tech/slimegen_normal.jpg \ data1/maps/meshes/tech/slimegenred_fx.tga \ data1/maps/meshes/tech/slimegenred.jpg \ data1/maps/meshes/tech/slimegenred.md2 \ data1/maps/meshes/tech/slimegen_s.md2 \ data1/maps/meshes/tech/slimetube1.md2 \ data1/maps/meshes/tech/turbinefan.jpg \ data1/maps/meshes/tech/turbinefan.md2 \ data1/maps/meshes/tech/turbinefan_normal.jpg \ data1/maps/meshes/toxicbarrell.jpg \ data1/maps/meshes/toxicbarrell.md2 \ data1/maps/meshes/toxicbarrell_normal.jpg \ data1/maps/meshes/tubecover.md2 \ data1/maps/meshes/tube.md2 \ data1/maps/meshes/tube.tga \ data1/maps/meshes/unit.jpg \ data1/maps/meshes/unit.md2 \ data1/maps/meshes/unit_normal.jpg \ data1/maps/meshes/urban/bluelantern_fx.tga \ data1/maps/meshes/urban/bluelantern.jpg \ data1/maps/meshes/urban/bluelantern.md2 \ data1/maps/meshes/urban/lantern_normal.jpg \ data1/maps/meshes/urban/mercedes.jpg \ data1/maps/meshes/urban/mercedes.md2 \ data1/maps/meshes/urban/orangelantern_fx.tga \ data1/maps/meshes/urban/orangelantern.jpg \ data1/maps/meshes/urban/orangelantern.md2 \ data1/maps/meshes/urban/rioblue.jpg \ data1/maps/meshes/urban/rioblue.md2 \ data1/maps/meshes/urban/rio_normal.jpg \ data1/maps/meshes/urban/riored.jpg \ data1/maps/meshes/urban/riored.md2 \ data1/maps/meshes/urban/riosilver.jpg \ data1/maps/meshes/urban/riosilver.md2 \ data1/maps/meshes/urban/roadbarrell.jpg \ data1/maps/meshes/urban/roadbarrell.md2 \ data1/maps/meshes/urban/roadbarrell_normal.jpg \ data1/maps/meshes/urban/rope.jpg \ data1/maps/meshes/urban/rope.md2 \ data1/maps/meshes/urban/yellowlantern_fx.tga \ data1/maps/meshes/urban/yellowlantern.jpg \ data1/maps/meshes/urban/yellowlantern.md2 \ data1/maps/meshes/weaponpad_fx.tga \ data1/maps/meshes/weaponpad.md2 \ data1/maps/meshes/weaponpad_normal.tga \ data1/maps/meshes/weaponpad.tga \ data1/maps/meshes/xempx/ceillightbig.md2 \ data1/maps/meshes/xempx/ceillight_fx.tga \ data1/maps/meshes/xempx/ceillight.jpg \ data1/maps/meshes/xempx/ceillight.md2 \ data1/maps/meshes/xempx/ceillight_normal.jpg \ data1/maps/meshes/xempx/crate32.md2 \ data1/maps/meshes/xempx/crate64.md2 \ data1/maps/meshes/xempx/crate96.md2 \ data1/maps/meshes/xempx/crate.jpg \ data1/maps/meshes/xempx/crate_normal.jpg \ data1/maps/meshes/xempx/doorway1b.jpg \ data1/maps/meshes/xempx/doorway1b.md2 \ data1/maps/meshes/xempx/floorfan.jpg \ data1/maps/meshes/xempx/floorfan.md2 \ data1/maps/meshes/xempx/floorfan_normal.jpg \ data1/maps/meshes/xempx/lightbomb45.md2 \ data1/maps/meshes/xempx/lightbomb_fx.tga \ data1/maps/meshes/xempx/lightbomb.jpg \ data1/maps/meshes/xempx/lightbomb.md2 \ data1/maps/meshes/xempx/lightbomb_normal.jpg \ data1/maps/meshes/xempx/powercore_fx.tga \ data1/maps/meshes/xempx/powercore.jpg \ data1/maps/meshes/xempx/powercore.md2 \ data1/maps/meshes/xempx/powercore_normal.jpg \ data1/maps/meshes/xempx/powercorering.md2 \ data1/maps/meshes/xempx/qtube2.md2 \ data1/maps/meshes/xempx/qtube.jpg \ data1/maps/meshes/xempx/qtube.md2 \ data1/maps/meshes/xempx/qtube_normal.jpg \ data1/maps/meshes/xempx/tripes1.jpg \ data1/maps/meshes/xempx/tripes1.md2 \ data1/maps/meshes/xempx/tripes1_normal.jpg \ data1/maps/scripts/aoa-atlantis.mus \ data1/maps/scripts/aoa-corrosion.fog \ data1/maps/scripts/aoa-corrosion.mus \ data1/maps/scripts/aoa-frost2k9.fog \ data1/maps/scripts/aoa-frost2k9.mus \ data1/maps/scripts/aoa-morpheus.mus \ data1/maps/scripts/aoa-zorn.mus \ data1/maps/scripts/cp-ribeye.mus \ data1/maps/scripts/ctf-corrosion.fog \ data1/maps/scripts/ctf-corrosion.mus \ data1/maps/scripts/ctf-cryogenic.fog \ data1/maps/scripts/ctf-cryogenic.mus \ data1/maps/scripts/ctf-europa2k8.mus \ data1/maps/scripts/ctf-extermination.fog \ data1/maps/scripts/ctf-extermination.mus \ data1/maps/scripts/ctf-frostbyte.fog \ data1/maps/scripts/ctf-frostbyte.mus \ data1/maps/scripts/ctf-goregrinder.fog \ data1/maps/scripts/ctf-goregrinder.mus \ data1/maps/scripts/ctf-invasion.fog \ data1/maps/scripts/ctf-invasion.mus \ data1/maps/scripts/ctf-oblivion.fog \ data1/maps/scripts/ctf-oblivion.mus \ data1/maps/scripts/ctf-purgatory.fog \ data1/maps/scripts/ctf-purgatory.mus \ data1/maps/scripts/ctf-titan2k8.mus \ data1/maps/scripts/ctf-vesuvius2k11.fog \ data1/maps/scripts/ctf-vesuvius2k11.mus \ data1/maps/scripts/ctf-violator.fog \ data1/maps/scripts/ctf-violator.mus \ data1/maps/scripts/ctf-zion2k9.mus \ data1/maps/scripts/db-chromium.mus \ data1/maps/scripts/db-icarus.mus \ data1/maps/scripts/db-vesuvius.fog \ data1/maps/scripts/db-vesuvius.mus \ data1/maps/scripts/dm-atlantis2k8.mus \ data1/maps/scripts/dm-annihilation.fog \ data1/maps/scripts/dm-annihilation.mus \ data1/maps/scripts/dm-babel2k11.fog \ data1/maps/scripts/dm-babel2k11.mus \ data1/maps/scripts/dm-bloodfactory2k12.fog \ data1/maps/scripts/dm-bloodfactory2k12.mus \ data1/maps/scripts/dm-chasmatic2k9.fog \ data1/maps/scripts/dm-chasmatic2k9.mus \ data1/maps/scripts/dm-command2k9.fog \ data1/maps/scripts/dm-command2k9.mus \ data1/maps/scripts/dm-corrosion.fog \ data1/maps/scripts/dm-corrosion.mus \ data1/maps/scripts/dm-crucible2k12.fog \ data1/maps/scripts/dm-crucible2k12.mus \ data1/maps/scripts/dm-deathray.fog \ data1/maps/scripts/dm-deathray.mus \ data1/maps/scripts/dm-deimos2k9.mus \ data1/maps/scripts/dm-dismal2k11.fog \ data1/maps/scripts/dm-dismal2k11.mus \ data1/maps/scripts/dm-downfall.fog \ data1/maps/scripts/dm-downfall.mus \ data1/maps/scripts/dm-dynamo2k12.fog \ data1/maps/scripts/dm-dynamo2k12.mus \ data1/maps/scripts/dm-eternal.fog \ data1/maps/scripts/dm-eternal.mus \ data1/maps/scripts/dm-extermination.fog \ data1/maps/scripts/dm-extermination.mus \ data1/maps/scripts/dm-furious2k8.fog \ data1/maps/scripts/dm-furious2k8.mus \ data1/maps/scripts/dm-goregrinder.fog \ data1/maps/scripts/dm-goregrinder.mus \ data1/maps/scripts/dm-horus.mus \ data1/maps/scripts/dm-impact.fog \ data1/maps/scripts/dm-impact.mus \ data1/maps/scripts/dm-invasion.fog \ data1/maps/scripts/dm-invasion.mus \ data1/maps/scripts/dm-leviathan2k12.fog \ data1/maps/scripts/dm-leviathan2k12.mus \ data1/maps/scripts/dm-liberation.fog \ data1/maps/scripts/dm-liberation.mus \ data1/maps/scripts/dm-neptune.mus \ data1/maps/scripts/dm-oblivion.fog \ data1/maps/scripts/dm-oblivion.mus \ data1/maps/scripts/dm-omega2k8.mus \ data1/maps/scripts/dm-purgatory.fog \ data1/maps/scripts/dm-purgatory.mus \ data1/maps/scripts/dm-saucer2k9.fog \ data1/maps/scripts/dm-saucer2k9.mus \ data1/maps/scripts/dm-turbo2k8.fog \ data1/maps/scripts/dm-turbo2k8.mus \ data1/maps/scripts/dm-vesuvius2k11.fog \ data1/maps/scripts/dm-vesuvius2k11.mus \ data1/maps/scripts/dm-violator2k11.mus \ data1/maps/scripts/dm-violator2k11.fog \ data1/maps/scripts/dm-warmachine2k10.fog \ data1/maps/scripts/dm-warmachine2k10.mus \ data1/maps/scripts/dm-zorn2k11.fog \ data1/maps/scripts/dm-zorn2k11.mus \ data1/maps/scripts/dm-zion2k9.mus \ data1/maps/scripts/tac-extermination.fog \ data1/maps/scripts/tac-extermination.mus \ data1/maps/scripts/tca-corrosion.fog \ data1/maps/scripts/tca-corrosion.mus \ data1/maps/scripts/tca-cryogenic.fog \ data1/maps/scripts/tca-cryogenic.mus \ data1/maps/scripts/tca-extermination.fog \ data1/maps/scripts/tca-extermination.mus \ data1/maps/scripts/tca-purgatory.fog \ data1/maps/scripts/tca-purgatory.mus \ data1/maps/scripts/tca-zion2k9.mus modelsdir = $(pkgdatadir) nobase_nodist_models_DATA = \ data1/models/cow/helmet.md2 \ data1/models/cow/skin.tga \ data1/models/cow/tris.md2 \ data1/models/items/adrenaline/skin_normal.tga \ data1/models/items/adrenaline/skin.tga \ data1/models/items/adrenaline/tris.md2 \ data1/models/items/ammo/bullets/medium/skin.tga \ data1/models/items/ammo/bullets/medium/tris.md2 \ data1/models/items/ammo/cells/medium/cell.tga \ data1/models/items/ammo/cells/medium/tris.md2 \ data1/models/items/ammo/grenades/medium/skin.tga \ data1/models/items/ammo/grenades/medium/tris.md2 \ data1/models/items/ammo/rockets/medium/skin.tga \ data1/models/items/ammo/rockets/medium/tris.md2 \ data1/models/items/ammo/shells/medium/skin.tga \ data1/models/items/ammo/shells/medium/tris.md2 \ data1/models/items/ammo/skin_normal.tga \ data1/models/items/armor/body/skin.jpg \ data1/models/items/armor/body/tris.md2 \ data1/models/items/armor/combat/skin.jpg \ data1/models/items/armor/combat/tris.md2 \ data1/models/items/armor/jacket/skin.jpg \ data1/models/items/armor/jacket/tris.md2 \ data1/models/items/armor/shard/skin_normal.tga \ data1/models/items/armor/shard/skin.tga \ data1/models/items/armor/shard/tris.md2 \ data1/models/items/armor/skin_fx.tga \ data1/models/items/armor/skin_normal.tga \ data1/models/items/flags/blue.tga \ data1/models/items/flags/flag1.md2 \ data1/models/items/flags/flag2.md2 \ data1/models/items/flags/red.tga \ data1/models/items/haste/skin.jpg \ data1/models/items/haste/skin_fx.tga \ data1/models/items/haste/skin_normal.jpg \ data1/models/items/haste/tris.md2 \ data1/models/items/healing/globe/skin.tga \ data1/models/items/healing/globe/tris.md2 \ data1/models/items/healing/health_normal.tga \ data1/models/items/healing/large/skin.tga \ data1/models/items/healing/large/tris.md2 \ data1/models/items/healing/medium/skin.tga \ data1/models/items/healing/medium/tris.md2 \ data1/models/items/healing/small/skin.tga \ data1/models/items/healing/small/tris.md2 \ data1/models/items/invulner/skin_fx.tga \ data1/models/items/invulner/skin.jpg \ data1/models/items/invulner/skin_normal.jpg \ data1/models/items/invulner/tris.md2 \ data1/models/items/mega_h/skin_fx.tga \ data1/models/items/mega_h/skin.jpg \ data1/models/items/mega_h/skin_normal.jpg \ data1/models/items/mega_h/tris.md2 \ data1/models/items/quaddama/skin_normal.tga \ data1/models/items/quaddama/skin.tga \ data1/models/items/quaddama/tris.md2 \ data1/models/items/quaddama/unit.md2 \ data1/models/items/sproing/skin.jpg \ data1/models/items/sproing/skin_fx.tga \ data1/models/items/sproing/skin_normal.jpg \ data1/models/items/sproing/tris.md2 \ data1/models/misc/deathray/deathray.md2 \ data1/models/misc/deathray/deathray_normal.tga \ data1/models/misc/deathray/deathray.tga \ data1/models/misc/electrode/cover.md2 \ data1/models/misc/electrode/electrode.tga \ data1/models/misc/electrode/tris.md2 \ data1/models/misc/lamp2/lamp2.tga \ data1/models/misc/lamp2/tris.md2 \ data1/models/misc/lamp/lamp.tga \ data1/models/misc/lamp/tris.md2 \ data1/models/misc/pod/pod.tga \ data1/models/misc/pod/tris.md2 \ data1/models/misc/receptor/bulb.md2 \ data1/models/misc/receptor/receptor.tga \ data1/models/misc/receptor/tris.md2 \ data1/models/misc/scope/cover.md2 \ data1/models/misc/scope/scope.tga \ data1/models/misc/scope/tris.md2 \ data1/models/misc/spiderpod/helmet.iqm \ data1/models/misc/spiderpod/helmet.md2 \ data1/models/misc/spiderpod/skin.tga \ data1/models/misc/spiderpod/spider_fx.tga \ data1/models/misc/spiderpod/spider.jpg \ data1/models/misc/spiderpod/spider_normal.jpg \ data1/models/misc/spiderpod/tris.iqm \ data1/models/misc/spiderpod/tris.md2 \ data1/models/misc/spiderpod/tris.skin \ data1/models/misc/tube/cover.md2 \ data1/models/misc/tube/tris.md2 \ data1/models/misc/tube/tube.tga \ data1/models/objects/blank/skin.tga \ data1/models/objects/blank/tris.md2 \ data1/models/objects/brass/skin.jpg \ data1/models/objects/brass/tris.md2 \ data1/models/objects/debris1/skin.tga \ data1/models/objects/debris1/tris.md2 \ data1/models/objects/debris2/skin.tga \ data1/models/objects/debris2/tris.md2 \ data1/models/objects/debris3/skin.tga \ data1/models/objects/debris3/tris.md2 \ data1/models/objects/dmspot/skin_normal.tga \ data1/models/objects/dmspot/skin.tga \ data1/models/objects/dmspot/tris.md2 \ data1/models/objects/electroball/skin_fx.tga \ data1/models/objects/electroball/skin.jpg \ data1/models/objects/electroball/skin_normal.jpg \ data1/models/objects/electroball/tris.md2 \ data1/models/objects/fireball/skin.tga \ data1/models/objects/fireball/tris.md2 \ data1/models/objects/gibs/mart_gut/skin.jpg \ data1/models/objects/gibs/mart_gut/tris.md2 \ data1/models/objects/gibs/skin_normal.jpg \ data1/models/objects/gibs/sm_meat/skin.jpg \ data1/models/objects/gibs/sm_meat/tris.md2 \ data1/models/objects/icon/icon.jpg \ data1/models/objects/icon/icon_normal.jpg \ data1/models/objects/icon/tris.md2 \ data1/models/objects/laser/skin.tga \ data1/models/objects/laser/tris.md2 \ data1/models/objects/rocket/skin.tga \ data1/models/objects/rocket/tris.md2 \ data1/models/objects/spider/helmet.iqm \ data1/models/objects/spider/helmet.md2 \ data1/models/objects/spider/tris.iqm \ data1/models/objects/spider/tris.md2 \ data1/models/objects/spider/tris.skin \ data1/models/objects/spud/skin_fx2.tga \ data1/models/objects/spud/skin_fx.tga \ data1/models/objects/spud/skin_normal.jpg \ data1/models/objects/spud/skin.tga \ data1/models/objects/spud/spud.mdo \ data1/models/objects/spud/tris.md2 \ data1/models/tactical/abackupgen_fx.tga \ data1/models/tactical/abackupgen.jpg \ data1/models/tactical/abackupgen_normal.jpg \ data1/models/tactical/abomb_fx.tga \ data1/models/tactical/abomb.jpg \ data1/models/tactical/abomb_normal.tga \ data1/models/tactical/acomputer_fx.tga \ data1/models/tactical/acomputer_normal.tga \ data1/models/tactical/acomputer.tga \ data1/models/tactical/alaser_fx.tga \ data1/models/tactical/alaser.jpg \ data1/models/tactical/alien_backupgen.iqm \ data1/models/tactical/alien_backupgen.skin \ data1/models/tactical/alien_bomb.iqm \ data1/models/tactical/alien_bomb.skin \ data1/models/tactical/alien_computer.iqm \ data1/models/tactical/alien_computer.skin \ data1/models/tactical/alien_laser.iqm \ data1/models/tactical/alien_laser.md2 \ data1/models/tactical/alien_laser.skin \ data1/models/tactical/alien_powersrc.iqm \ data1/models/tactical/alien_powersrc.skin \ data1/models/tactical/ammopad.md2 \ data1/models/tactical/apowersrc_fx.tga \ data1/models/tactical/apowersrc.jpg \ data1/models/tactical/apowersrc_normal.jpg \ data1/models/tactical/hbackupgen.jpg \ data1/models/tactical/hbackupgen_normal.jpg \ data1/models/tactical/hbomb_fx.tga \ data1/models/tactical/hbomb.jpg \ data1/models/tactical/hbomb_normal.jpg \ data1/models/tactical/hcomputer_fx.tga \ data1/models/tactical/hcomputer.jpg \ data1/models/tactical/hcomputer_normal.jpg \ data1/models/tactical/hlaser_fx.tga \ data1/models/tactical/hlaser.jpg \ data1/models/tactical/hpowersrc_fx.tga \ data1/models/tactical/hpowersrc.jpg \ data1/models/tactical/hpowersrc_normal.jpg \ data1/models/tactical/human_backupgen.iqm \ data1/models/tactical/human_backupgen.skin \ data1/models/tactical/human_bomb.iqm \ data1/models/tactical/human_bomb.skin \ data1/models/tactical/human_computer.iqm \ data1/models/tactical/human_computer.skin \ data1/models/tactical/human_laser.iqm \ data1/models/tactical/human_laser.md2 \ data1/models/tactical/human_laser.skin \ data1/models/tactical/human_powersrc.iqm \ data1/models/tactical/human_powersrc.skin \ data1/models/tactical/laser_normal.jpg \ data1/models/weapons/g_bfg/tris.md2 \ data1/models/weapons/g_chain/tris.md2 \ data1/models/weapons/g_hyperb/cover.md2 \ data1/models/weapons/g_hyperb/tris.md2 \ data1/models/weapons/g_launch/skin.tga \ data1/models/weapons/g_launch/tris.md2 \ data1/models/weapons/g_machn/tris.md2 \ data1/models/weapons/g_minderaser/tris.md2 \ data1/models/weapons/g_rail/tris.md2 \ data1/models/weapons/g_rocket/cover.md2 \ data1/models/weapons/g_rocket/tris.md2 \ data1/models/weapons/g_shotg2/tris.md2 \ data1/models/weapons/g_shotg/tris.md2 \ data1/models/weapons/v_alienblast/cover.md2 \ data1/models/weapons/v_alienblast/skin_fx.tga \ data1/models/weapons/v_alienblast/skin_normal.jpg \ data1/models/weapons/v_alienblast/skin.jpg \ data1/models/weapons/v_alienblast/tris.md2 \ data1/models/weapons/v_bfg/skin.jpg \ data1/models/weapons/v_bfg/skin_normal.tga \ data1/models/weapons/v_bfg/tris.md2 \ data1/models/weapons/v_blast/cover.md2 \ data1/models/weapons/v_blast/skin.jpg \ data1/models/weapons/v_blast/skin_normal.tga \ data1/models/weapons/v_blast/tris.md2 \ data1/models/weapons/v_chain/skin.jpg \ data1/models/weapons/v_chain/skin_normal.tga \ data1/models/weapons/v_chain/tris.md2 \ data1/models/weapons/v_hyperb/cover.md2 \ data1/models/weapons/v_hyperb/disruptor.jpg \ data1/models/weapons/v_hyperb/disruptor_normal.tga \ data1/models/weapons/v_hyperb/tris.md2 \ data1/models/weapons/v_machn/tris.md2 \ data1/models/weapons/v_minderaser/minderaser.jpg \ data1/models/weapons/v_minderaser/minderaser_normal.tga \ data1/models/weapons/v_minderaser/tris.md2 \ data1/models/weapons/v_rail/beamgun.jpg \ data1/models/weapons/v_rail/beamgun_normal.tga \ data1/models/weapons/v_rail/tris.md2 \ data1/models/weapons/v_rocket/cover.md2 \ data1/models/weapons/v_rocket/skin.jpg \ data1/models/weapons/v_rocket/skin_normal.tga \ data1/models/weapons/v_rocket/tris.md2 \ data1/models/weapons/v_shotg2/skin.jpg \ data1/models/weapons/v_shotg2/skin_normal.tga \ data1/models/weapons/v_shotg2/tris.md2 \ data1/models/weapons/v_shotg/skin.jpg \ data1/models/weapons/v_shotg/skin_normal.tga \ data1/models/weapons/v_shotg/tris.md2 \ data1/models/weapons/v_violator/skin.jpg \ data1/models/weapons/v_violator/skin_normal.jpg \ data1/models/weapons/v_violator/tris.md2 \ data1/models/weapons/v_violator/violator.jpg \ data1/models/weapons/v_violator/violator_normal.tga particlesdir = $(pkgdatadir) nobase_nodist_particles_DATA = \ data1/particles/aflash.tga \ data1/particles/basic.tga \ data1/particles/beam.tga \ data1/particles/bflash.tga \ data1/particles/blood.tga \ data1/particles/bubble.tga \ data1/particles/bullethole2.tga \ data1/particles/bullethole.tga \ data1/particles/cflash.tga \ data1/particles/deathfield2.tga \ data1/particles/deathfield.tga \ data1/particles/dflash.tga \ data1/particles/disbeam1.tga \ data1/particles/disbeam2.tga \ data1/particles/disbeam3.tga \ data1/particles/explosion.tga \ data1/particles/flag.tga \ data1/particles/flare.tga \ data1/particles/leaderfield.tga \ data1/particles/leaf.tga \ data1/particles/logo.tga \ data1/particles/puff.tga \ data1/particles/reflect.tga \ data1/particles/r_explod_1.tga \ data1/particles/r_explod_2.tga \ data1/particles/r_explod_3.tga \ data1/particles/r_explod_4.tga \ data1/particles/r_explod_5.tga \ data1/particles/r_explod_6.tga \ data1/particles/r_explod_7.tga \ data1/particles/ring.tga \ data1/particles/ripples.tga \ data1/particles/sayicon.tga \ data1/particles/shell2_normal.tga \ data1/particles/shell2.tga \ data1/particles/shell.tga \ data1/particles/smoke_org.tga \ data1/particles/smoke.tga \ data1/particles/trash.tga \ data1/particles/voltage.tga \ data1/particles/watersplash.tga picsdir = $(pkgdatadir) nobase_nodist_pics_DATA = \ data1/pics/a_bullets.tga \ data1/pics/a_cells.tga \ data1/pics/a_grenades.tga \ data1/pics/anum_0.tga \ data1/pics/anum_1.tga \ data1/pics/anum_2.tga \ data1/pics/anum_3.tga \ data1/pics/anum_4.tga \ data1/pics/anum_5.tga \ data1/pics/anum_6.tga \ data1/pics/anum_7.tga \ data1/pics/anum_8.tga \ data1/pics/anum_9.tga \ data1/pics/anum_minus.tga \ data1/pics/a_rockets.tga \ data1/pics/a_shells.tga \ data1/pics/a_slugs.tga \ data1/pics/backtile.pcx \ data1/pics/bar_background.tga \ data1/pics/bar_loading.tga \ data1/pics/beamgun.tga \ data1/pics/blaster.tga \ data1/pics/blood_ring.tga \ data1/pics/blueplayerbox.tga \ data1/pics/bomber.tga \ data1/pics/bots/enforcer/blue_i.jpg \ data1/pics/bots/enforcer/default_i.jpg \ data1/pics/bots/enforcer/red_i.jpg \ data1/pics/bots/enforcer/stryker_i.jpg \ data1/pics/bots/martiancyborg/blue_i.jpg \ data1/pics/bots/martiancyborg/default_i.jpg \ data1/pics/bots/martiancyborg/red_i.jpg \ data1/pics/bots/martianenforcer/blue_i.jpg \ data1/pics/bots/martianenforcer/default_i.jpg \ data1/pics/bots/martianenforcer/gamara_i.jpg \ data1/pics/bots/martianenforcer/red_i.jpg \ data1/pics/ch1.tga \ data1/pics/ch2.tga \ data1/pics/ch3.tga \ data1/pics/chaingun.tga \ data1/pics/colormap.pcx \ data1/pics/conback.tga \ data1/pics/conchars.tga \ data1/pics/crosshairs/alien2a.tga \ data1/pics/crosshairs/alien2b.tga \ data1/pics/crosshairs/alien2.tga \ data1/pics/crosshairs/alien.tga \ data1/pics/crosshairs/chexcross.tga \ data1/pics/crosshairs/dot1.tga \ data1/pics/crosshairs/hardcorech.tga \ data1/pics/crosshairs/havoc2.tga \ data1/pics/crosshairs/havoc3.tga \ data1/pics/crosshairs/havoc.tga \ data1/pics/crosshairs/intimidator2.tga \ data1/pics/crosshairs/intimidator3.tga \ data1/pics/crosshairs/intimidator.tga \ data1/pics/crosshairs/mechano.tga \ data1/pics/crosshairs/ncool.tga \ data1/pics/crosshairs/nile2.tga \ data1/pics/crosshairs/nile3.tga \ data1/pics/crosshairs/nile.tga \ data1/pics/crosshairs/rage_cross.tga \ data1/pics/crosshairs/rgb.tga \ data1/pics/crosshairs/robot.tga \ data1/pics/crosshairs/sniper.tga \ data1/pics/crosshairs/sungod.tga \ data1/pics/crosshairs/tech2.tga \ data1/pics/crosshairs/tech.tga \ data1/pics/crosshairs/transcircle.tga \ data1/pics/crosshairs/vista.tga \ data1/pics/ctf1.tga \ data1/pics/ctf2.tga \ data1/pics/disruptor.tga \ data1/pics/dnarrow.tga \ data1/pics/flamethrower.tga \ data1/pics/grapple.tga \ data1/pics/help.tga \ data1/pics/hover.tga \ data1/pics/hud_bomber_fx.tga \ data1/pics/hud_bomber.tga \ data1/pics/hud_hover_fx.tga \ data1/pics/hud_hover.tga \ data1/pics/hud_strafer_fx.tga \ data1/pics/hud_strafer.tga \ data1/pics/huds/20061.tga \ data1/pics/huds/20062.tga \ data1/pics/huds/20071.tga \ data1/pics/huds/20072.tga \ data1/pics/huds/8bit1.tga \ data1/pics/huds/8bit2.tga \ data1/pics/huds/alien1.tga \ data1/pics/huds/alien2.tga \ data1/pics/huds/alienblood1.tga \ data1/pics/huds/alienblood2.tga \ data1/pics/huds/blood1.tga \ data1/pics/huds/blood2.tga \ data1/pics/huds/classic1.tga \ data1/pics/huds/classic2.tga \ data1/pics/huds/cleanblue1.tga \ data1/pics/huds/cleanblue2.tga \ data1/pics/huds/cleangreen1.tga \ data1/pics/huds/cleangreen2.tga \ data1/pics/huds/cleanred1.tga \ data1/pics/huds/cleanred2.tga \ data1/pics/huds/corpse1.tga \ data1/pics/huds/corpse2.tga \ data1/pics/huds/cpu1.tga \ data1/pics/huds/cpu2.tga \ data1/pics/huds/freezy1.tga \ data1/pics/huds/freezy2.tga \ data1/pics/huds/gtv1.tga \ data1/pics/huds/gtv2.tga \ data1/pics/huds/marscreen1.tga \ data1/pics/huds/marscreen2.tga \ data1/pics/huds/mechanic1.tga \ data1/pics/huds/mechanic2.tga \ data1/pics/huds/nki_dark1.tga \ data1/pics/huds/nki_dark2.tga \ data1/pics/huds/nki_darkb1.tga \ data1/pics/huds/nki_darkb2.tga \ data1/pics/huds/oldskool1.tga \ data1/pics/huds/oldskool2.tga \ data1/pics/huds/retro1.tga \ data1/pics/huds/retro2.tga \ data1/pics/huds/talon1.tga \ data1/pics/huds/talon2.tga \ data1/pics/huds/terminal-blue1.tga \ data1/pics/huds/terminal-blue2.tga \ data1/pics/huds/terminal-green1.tga \ data1/pics/huds/terminal-green2.tga \ data1/pics/huds/terminal-purple1.tga \ data1/pics/huds/terminal-purple2.tga \ data1/pics/huds/terminal-red1.tga \ data1/pics/huds/terminal-red2.tga \ data1/pics/huds/therock1.tga \ data1/pics/huds/therock2.tga \ data1/pics/i_beamgun.tga \ data1/pics/i_bodyarmor.tga \ data1/pics/i_chaingun.tga \ data1/pics/i_combatarmor.tga \ data1/pics/i_disruptor.tga \ data1/pics/i_flag1.tga \ data1/pics/i_flag2.tga \ data1/pics/i_flamegun.tga \ data1/pics/i_health.tga \ data1/pics/i_jacketarmor.tga \ data1/pics/i_minderaser.tga \ data1/pics/inventory.tga \ data1/pics/i_rocketlauncher.tga \ data1/pics/i_score.tga \ data1/pics/i_smartgun.tga \ data1/pics/i_tactical.tga \ data1/pics/i_team1.tga \ data1/pics/i_team2.tga \ data1/pics/i_vaporizer.tga \ data1/pics/m_bots.tga \ data1/pics/m_controls.tga \ data1/pics/m_cursor0.tga \ data1/pics/m_dmoptions.tga \ data1/pics/menu_back.jpg \ data1/pics/menu_back_fx.tga \ data1/pics/m_irc.tga \ data1/pics/m_joinserver.tga \ data1/pics/m_main_credits.tga \ data1/pics/m_main_credits_fx.tga \ data1/pics/m_main_credits_sel.tga \ data1/pics/m_main_game_fx.tga \ data1/pics/m_main_game_sel.tga \ data1/pics/m_main_game.tga \ data1/pics/m_main_host_fx.tga \ data1/pics/m_main_host_sel.tga \ data1/pics/m_main_host.tga \ data1/pics/m_main_irc_fx.tga \ data1/pics/m_main_irc_sel.tga \ data1/pics/m_main_irc.tga \ data1/pics/m_main_join_fx.tga \ data1/pics/m_main_join_sel.tga \ data1/pics/m_main_join.tga \ data1/pics/m_main_mont0.tga \ data1/pics/m_main_mont1.tga \ data1/pics/m_main_mont2.tga \ data1/pics/m_main_mont3.tga \ data1/pics/m_main_mont4.tga \ data1/pics/m_main_mont5.tga \ data1/pics/m_main_options_fx.tga \ data1/pics/m_main_options_sel.tga \ data1/pics/m_main_options.tga \ data1/pics/m_main_player_fx.tga \ data1/pics/m_main_player_sel.tga \ data1/pics/m_main_player.tga \ data1/pics/m_main_quit_fx.tga \ data1/pics/m_main_quit_sel.tga \ data1/pics/m_main_quit.tga \ data1/pics/m_main_tactical.tga \ data1/pics/m_main.tga \ data1/pics/m_main_video_fx.tga \ data1/pics/m_main_video_sel.tga \ data1/pics/m_main_video.tga \ data1/pics/m_mouse_cursor.tga \ data1/pics/m_mutators.tga \ data1/pics/m_options.tga \ data1/pics/m_player.tga \ data1/pics/m_quit.tga \ data1/pics/m_single.tga \ data1/pics/m_startserver.tga \ data1/pics/m_tactical.tga \ data1/pics/m_video.tga \ data1/pics/menu/button_border_end.tga \ data1/pics/menu/button_border.tga \ data1/pics/menu/dnarrow.tga \ data1/pics/menu/field_cursor.tga \ data1/pics/menu/icon_border.tga \ data1/pics/menu/m_background.tga \ data1/pics/menu/m_bottomcorner.tga \ data1/pics/menu/m_bottom.tga \ data1/pics/menu/midarrow.tga \ data1/pics/menu/m_side.tga \ data1/pics/menu/m_topcorner.tga \ data1/pics/menu/m_top.tga \ data1/pics/menu/on.tga \ data1/pics/menu/radio_border.tga \ data1/pics/menu/scroll_border_end.tga \ data1/pics/menu/scroll_border.tga \ data1/pics/menu/scroll_cursor_end.tga \ data1/pics/menu/scroll_cursor.tga \ data1/pics/menu/slide_border_end.tga \ data1/pics/menu/slide_border.tga \ data1/pics/menu/slide_cursor_end.tga \ data1/pics/menu/slide_cursor.tga \ data1/pics/menu/sm_background.tga \ data1/pics/menu/sm_bottomcorner.tga \ data1/pics/menu/sm_bottom.tga \ data1/pics/menu/sm_side.tga \ data1/pics/menu/sm_topcorner.tga \ data1/pics/menu/sm_top.tga \ data1/pics/menu/uparrow.tga \ data1/pics/net.tga \ data1/pics/num_0.tga \ data1/pics/num_1.tga \ data1/pics/num_2.tga \ data1/pics/num_3.tga \ data1/pics/num_4.tga \ data1/pics/num_5.tga \ data1/pics/num_6.tga \ data1/pics/num_7.tga \ data1/pics/num_8.tga \ data1/pics/num_9.tga \ data1/pics/num_minus.tga \ data1/pics/p_adrenaline.tga \ data1/pics/p_body.tga \ data1/pics/p_combat.tga \ data1/pics/p_haste.tga \ data1/pics/p_health.tga \ data1/pics/p_invis.tga \ data1/pics/p_invulnerability.tga \ data1/pics/p_jacket.tga \ data1/pics/playerbox.tga \ data1/pics/p_powered.tga \ data1/pics/p_quad.tga \ data1/pics/p_rewardpts.tga \ data1/pics/p_shard.tga \ data1/pics/p_sproing.tga \ data1/pics/redplayerbox.tga \ data1/pics/rocketlauncher.tga \ data1/pics/sbfctf1.tga \ data1/pics/sbfctf2.tga \ data1/pics/smartgun.tga \ data1/pics/statbox.tga \ data1/pics/strafer.tga \ data1/pics/tag1.tga \ data1/pics/tag2.tga \ data1/pics/team1.tga \ data1/pics/team2.tga \ data1/pics/timer.tga \ data1/pics/uparrow.tga \ data1/pics/vaporizor.tga \ data1/pics/violator.tga \ data1/pics/votebox.tga \ data1/pics/w_bfg.tga \ data1/pics/w_blaster.tga \ data1/pics/w_chaingun.tga \ data1/pics/w_glauncher.tga \ data1/pics/w_hyperblaster.tga \ data1/pics/w_machinegun.tga \ data1/pics/w_railgun.tga \ data1/pics/w_rlauncher.tga \ data1/pics/w_shotgun.tga \ data1/pics/w_sshotgun.tga \ data1/pics/zoomscope1.tga \ data1/pics/zoomscope2.tga \ data1/pics/zoomscope3.tga playersdir = $(pkgdatadir) nobase_nodist_players_DATA = \ data1/players/commander/blue_i.jpg \ data1/players/commander/blue.jpg \ data1/players/commander/bump1.wav \ data1/players/commander/death1.wav \ data1/players/commander/death2.wav \ data1/players/commander/death3.wav \ data1/players/commander/death4.wav \ data1/players/commander/default_i.jpg \ data1/players/commander/default.jpg \ data1/players/commander/default_normal.tga \ data1/players/commander/drown1.wav \ data1/players/commander/fall1.wav \ data1/players/commander/fall2.wav \ data1/players/commander/gurp1.wav \ data1/players/commander/gurp2.wav \ data1/players/commander/human \ data1/players/commander/jump1.wav \ data1/players/commander/lod1.iqm \ data1/players/commander/lod1.md2 \ data1/players/commander/lod1.rgd \ data1/players/commander/lod2.iqm \ data1/players/commander/lod2.md2 \ data1/players/commander/lod2.rgd \ data1/players/commander/pain100_1.wav \ data1/players/commander/pain100_2.wav \ data1/players/commander/pain25_1.wav \ data1/players/commander/pain25_2.wav \ data1/players/commander/pain50_1.wav \ data1/players/commander/pain50_2.wav \ data1/players/commander/pain75_1.wav \ data1/players/commander/pain75_2.wav \ data1/players/commander/red_i.jpg \ data1/players/commander/red.jpg \ data1/players/commander/tris.iqm \ data1/players/commander/tris.md2 \ data1/players/commander/tris.rgd \ data1/players/commander/tron2_i.jpg \ data1/players/commander/tron2.jpg \ data1/players/commander/tron3_i.jpg \ data1/players/commander/tron3.jpg \ data1/players/commander/tron_i.jpg \ data1/players/commander/tron.jpg \ data1/players/commander/tron_normal.tga \ data1/players/commander/w_bfg.iqm \ data1/players/commander/w_bfg.md2 \ data1/players/commander/w_bfg.skin \ data1/players/commander/w_blaster.iqm \ data1/players/commander/w_blaster.md2 \ data1/players/commander/w_blaster.skin \ data1/players/commander/w_chaingun.iqm \ data1/players/commander/w_chaingun.md2 \ data1/players/commander/w_chaingun.skin \ data1/players/commander/weapon.iqm \ data1/players/commander/weapon.jpg \ data1/players/commander/weapon.md2 \ data1/players/commander/weapon.skin \ data1/players/commander/w_hyperblaster.iqm \ data1/players/commander/w_hyperblaster.md2 \ data1/players/commander/w_hyperblaster.skin \ data1/players/commander/w_machinegun.iqm \ data1/players/commander/w_machinegun.md2 \ data1/players/commander/w_machinegun.skin \ data1/players/commander/w_minderaser.iqm \ data1/players/commander/w_minderaser.md2 \ data1/players/commander/w_minderaser.skin \ data1/players/commander/w_railgun.iqm \ data1/players/commander/w_railgun.md2 \ data1/players/commander/w_railgun.skin \ data1/players/commander/w_rlauncher.iqm \ data1/players/commander/w_rlauncher.md2 \ data1/players/commander/w_rlauncher.skin \ data1/players/commander/w_shotgun.iqm \ data1/players/commander/w_shotgun.md2 \ data1/players/commander/w_shotgun.skin \ data1/players/commander/w_sshotgun.iqm \ data1/players/commander/w_sshotgun.md2 \ data1/players/commander/w_sshotgun.skin \ data1/players/commander/w_violator.iqm \ data1/players/commander/w_violator.md2 \ data1/players/commander/w_violator.skin \ data1/players/enforcer/arm.md2 \ data1/players/enforcer/blue_i.jpg \ data1/players/enforcer/blue.jpg \ data1/players/enforcer/body.md2 \ data1/players/enforcer/bump1.wav \ data1/players/enforcer/death1.wav \ data1/players/enforcer/death2.wav \ data1/players/enforcer/death3.wav \ data1/players/enforcer/death4.wav \ data1/players/enforcer/default_i.jpg \ data1/players/enforcer/default.jpg \ data1/players/enforcer/default_normal.tga \ data1/players/enforcer/drown1.wav \ data1/players/enforcer/fall1.wav \ data1/players/enforcer/fall2.wav \ data1/players/enforcer/gurp1.wav \ data1/players/enforcer/gurp2.wav \ data1/players/enforcer/head.md2 \ data1/players/enforcer/helmet.iqm \ data1/players/enforcer/helmet.md2 \ data1/players/enforcer/human \ data1/players/enforcer/jump1.wav \ data1/players/enforcer/leg.md2 \ data1/players/enforcer/lod1.iqm \ data1/players/enforcer/lod1.md2 \ data1/players/enforcer/lod1.rgd \ data1/players/enforcer/lod2.iqm \ data1/players/enforcer/lod2.md2 \ data1/players/enforcer/lod2.rgd \ data1/players/enforcer/pain100_1.wav \ data1/players/enforcer/pain100_2.wav \ data1/players/enforcer/pain25_1.wav \ data1/players/enforcer/pain25_2.wav \ data1/players/enforcer/pain50_1.wav \ data1/players/enforcer/pain50_2.wav \ data1/players/enforcer/pain75_1.wav \ data1/players/enforcer/pain75_2.wav \ data1/players/enforcer/red_i.jpg \ data1/players/enforcer/red.jpg \ data1/players/enforcer/stryker_i.jpg \ data1/players/enforcer/stryker.jpg \ data1/players/enforcer/tris.iqm \ data1/players/enforcer/tris.md2 \ data1/players/enforcer/tris.rgd \ data1/players/enforcer/tron2_i.jpg \ data1/players/enforcer/tron2.jpg \ data1/players/enforcer/tron3_i.jpg \ data1/players/enforcer/tron3.jpg \ data1/players/enforcer/tron_i.jpg \ data1/players/enforcer/tron.jpg \ data1/players/enforcer/tron_normal.tga \ data1/players/enforcer/usegibs \ data1/players/enforcer/w_bfg.iqm \ data1/players/enforcer/w_bfg.md2 \ data1/players/enforcer/w_bfg.skin \ data1/players/enforcer/w_blaster.iqm \ data1/players/enforcer/w_blaster.md2 \ data1/players/enforcer/w_blaster.skin \ data1/players/enforcer/w_chaingun.iqm \ data1/players/enforcer/w_chaingun.md2 \ data1/players/enforcer/w_chaingun.skin \ data1/players/enforcer/weapon.iqm \ data1/players/enforcer/weapon.jpg \ data1/players/enforcer/weapon.md2 \ data1/players/enforcer/weapon.skin \ data1/players/enforcer/w_hyperblaster.iqm \ data1/players/enforcer/w_hyperblaster.md2 \ data1/players/enforcer/w_hyperblaster.skin \ data1/players/enforcer/w_machinegun.iqm \ data1/players/enforcer/w_machinegun.md2 \ data1/players/enforcer/w_machinegun.skin \ data1/players/enforcer/w_minderaser.iqm \ data1/players/enforcer/w_minderaser.md2 \ data1/players/enforcer/w_minderaser.skin \ data1/players/enforcer/w_railgun.iqm \ data1/players/enforcer/w_railgun.md2 \ data1/players/enforcer/w_railgun.skin \ data1/players/enforcer/w_rlauncher.iqm \ data1/players/enforcer/w_rlauncher.md2 \ data1/players/enforcer/w_rlauncher.skin \ data1/players/enforcer/w_shotgun.iqm \ data1/players/enforcer/w_shotgun.md2 \ data1/players/enforcer/w_shotgun.skin \ data1/players/enforcer/w_sshotgun.iqm \ data1/players/enforcer/w_sshotgun.md2 \ data1/players/enforcer/w_sshotgun.skin \ data1/players/enforcer/w_violator.iqm \ data1/players/enforcer/w_violator.md2 \ data1/players/enforcer/w_violator.skin \ data1/players/lauren/arm.md2 \ data1/players/lauren/blue_i.jpg \ data1/players/lauren/blue.jpg \ data1/players/lauren/body.md2 \ data1/players/lauren/bump1.wav \ data1/players/lauren/death1.wav \ data1/players/lauren/death2.wav \ data1/players/lauren/death3.wav \ data1/players/lauren/death4.wav \ data1/players/lauren/default_i.jpg \ data1/players/lauren/default.jpg \ data1/players/lauren/default_normal.tga \ data1/players/lauren/drown1.wav \ data1/players/lauren/fall1.wav \ data1/players/lauren/fall2.wav \ data1/players/lauren/gurp1.wav \ data1/players/lauren/gurp2.wav \ data1/players/lauren/head.md2 \ data1/players/lauren/human \ data1/players/lauren/jump1.wav \ data1/players/lauren/leg.md2 \ data1/players/lauren/lod1.iqm \ data1/players/lauren/lod1.rgd \ data1/players/lauren/lod2.iqm \ data1/players/lauren/lod2.rgd \ data1/players/lauren/pain100_1.wav \ data1/players/lauren/pain100_2.wav \ data1/players/lauren/pain25_1.wav \ data1/players/lauren/pain25_2.wav \ data1/players/lauren/pain50_1.wav \ data1/players/lauren/pain50_2.wav \ data1/players/lauren/pain75_1.wav \ data1/players/lauren/pain75_2.wav \ data1/players/lauren/red_i.jpg \ data1/players/lauren/red.jpg \ data1/players/lauren/tris.iqm \ data1/players/lauren/tris.md2 \ data1/players/lauren/tris.rgd \ data1/players/lauren/tron2_i.jpg \ data1/players/lauren/tron2.jpg \ data1/players/lauren/tron3_i.jpg \ data1/players/lauren/tron3.jpg \ data1/players/lauren/tron_i.jpg \ data1/players/lauren/tron.jpg \ data1/players/lauren/tron_normal.tga \ data1/players/lauren/usegibs \ data1/players/lauren/w_bfg.iqm \ data1/players/lauren/w_bfg.md2 \ data1/players/lauren/w_bfg.skin \ data1/players/lauren/w_blaster.iqm \ data1/players/lauren/w_blaster.md2 \ data1/players/lauren/w_blaster.skin \ data1/players/lauren/w_chaingun.iqm \ data1/players/lauren/w_chaingun.md2 \ data1/players/lauren/w_chaingun.skin \ data1/players/lauren/weapon.iqm \ data1/players/lauren/weapon.jpg \ data1/players/lauren/weapon.md2 \ data1/players/lauren/weapon.skin \ data1/players/lauren/w_hyperblaster.iqm \ data1/players/lauren/w_hyperblaster.md2 \ data1/players/lauren/w_hyperblaster.skin \ data1/players/lauren/w_machinegun.iqm \ data1/players/lauren/w_machinegun.md2 \ data1/players/lauren/w_machinegun.skin \ data1/players/lauren/w_minderaser.iqm \ data1/players/lauren/w_minderaser.md2 \ data1/players/lauren/w_minderaser.skin \ data1/players/lauren/w_railgun.iqm \ data1/players/lauren/w_railgun.md2 \ data1/players/lauren/w_railgun.skin \ data1/players/lauren/w_rlauncher.iqm \ data1/players/lauren/w_rlauncher.md2 \ data1/players/lauren/w_rlauncher.skin \ data1/players/lauren/w_shotgun.iqm \ data1/players/lauren/w_shotgun.md2 \ data1/players/lauren/w_shotgun.skin \ data1/players/lauren/w_sshotgun.iqm \ data1/players/lauren/w_sshotgun.md2 \ data1/players/lauren/w_sshotgun.skin \ data1/players/lauren/w_violator.iqm \ data1/players/lauren/w_violator.md2 \ data1/players/lauren/w_violator.skin \ data1/players/martiancyborg/blue_i.jpg \ data1/players/martiancyborg/blue.jpg \ data1/players/martiancyborg/bump1.wav \ data1/players/martiancyborg/death1.wav \ data1/players/martiancyborg/death2.wav \ data1/players/martiancyborg/death3.wav \ data1/players/martiancyborg/death4.wav \ data1/players/martiancyborg/default_i.jpg \ data1/players/martiancyborg/default.jpg \ data1/players/martiancyborg/default_normal.tga \ data1/players/martiancyborg/drown1.wav \ data1/players/martiancyborg/fall1.wav \ data1/players/martiancyborg/fall2.wav \ data1/players/martiancyborg/gurp1.wav \ data1/players/martiancyborg/gurp2.wav \ data1/players/martiancyborg/helmet.iqm \ data1/players/martiancyborg/helmet.md2 \ data1/players/martiancyborg/jump1.wav \ data1/players/martiancyborg/lod1.iqm \ data1/players/martiancyborg/lod1.md2 \ data1/players/martiancyborg/lod1.rgd \ data1/players/martiancyborg/lod2.iqm \ data1/players/martiancyborg/lod2.md2 \ data1/players/martiancyborg/lod2.rgd \ data1/players/martiancyborg/pain100_1.wav \ data1/players/martiancyborg/pain100_2.wav \ data1/players/martiancyborg/pain25_1.wav \ data1/players/martiancyborg/pain25_2.wav \ data1/players/martiancyborg/pain50_1.wav \ data1/players/martiancyborg/pain50_2.wav \ data1/players/martiancyborg/pain75_1.wav \ data1/players/martiancyborg/pain75_2.wav \ data1/players/martiancyborg/red_i.jpg \ data1/players/martiancyborg/red.jpg \ data1/players/martiancyborg/robot \ data1/players/martiancyborg/tris.iqm \ data1/players/martiancyborg/tris.md2 \ data1/players/martiancyborg/tris.rgd \ data1/players/martiancyborg/tron2_i.jpg \ data1/players/martiancyborg/tron2.jpg \ data1/players/martiancyborg/tron3_i.jpg \ data1/players/martiancyborg/tron3.jpg \ data1/players/martiancyborg/tron_i.jpg \ data1/players/martiancyborg/tron.jpg \ data1/players/martiancyborg/tron_normal.tga \ data1/players/martiancyborg/w_alienblaster.iqm \ data1/players/martiancyborg/w_alienblaster.skin \ data1/players/martiancyborg/w_bfg.iqm \ data1/players/martiancyborg/w_bfg.md2 \ data1/players/martiancyborg/w_bfg.skin \ data1/players/martiancyborg/w_blaster.iqm \ data1/players/martiancyborg/w_blaster.md2 \ data1/players/martiancyborg/w_blaster.skin \ data1/players/martiancyborg/w_chaingun.iqm \ data1/players/martiancyborg/w_chaingun.md2 \ data1/players/martiancyborg/w_chaingun.skin \ data1/players/martiancyborg/weapon.iqm \ data1/players/martiancyborg/weapon.jpg \ data1/players/martiancyborg/weapon.md2 \ data1/players/martiancyborg/weapon.skin \ data1/players/martiancyborg/w_hyperblaster.iqm \ data1/players/martiancyborg/w_hyperblaster.md2 \ data1/players/martiancyborg/w_hyperblaster.skin \ data1/players/martiancyborg/w_machinegun.iqm \ data1/players/martiancyborg/w_machinegun.md2 \ data1/players/martiancyborg/w_machinegun.skin \ data1/players/martiancyborg/w_minderaser.iqm \ data1/players/martiancyborg/w_minderaser.md2 \ data1/players/martiancyborg/w_minderaser.skin \ data1/players/martiancyborg/w_railgun.iqm \ data1/players/martiancyborg/w_railgun.md2 \ data1/players/martiancyborg/w_railgun.skin \ data1/players/martiancyborg/w_rlauncher.iqm \ data1/players/martiancyborg/w_rlauncher.md2 \ data1/players/martiancyborg/w_rlauncher.skin \ data1/players/martiancyborg/w_shotgun.iqm \ data1/players/martiancyborg/w_shotgun.md2 \ data1/players/martiancyborg/w_shotgun.skin \ data1/players/martiancyborg/w_sshotgun.iqm \ data1/players/martiancyborg/w_sshotgun.md2 \ data1/players/martiancyborg/w_sshotgun.skin \ data1/players/martiancyborg/w_violator.iqm \ data1/players/martiancyborg/w_violator.md2 \ data1/players/martiancyborg/w_violator.skin \ data1/players/martianenforcer/alien \ data1/players/martianenforcer/arm.md2 \ data1/players/martianenforcer/blue_i.jpg \ data1/players/martianenforcer/blue.jpg \ data1/players/martianenforcer/body.md2 \ data1/players/martianenforcer/bump1.wav \ data1/players/martianenforcer/death1.wav \ data1/players/martianenforcer/death2.wav \ data1/players/martianenforcer/death3.wav \ data1/players/martianenforcer/death4.wav \ data1/players/martianenforcer/default_i.jpg \ data1/players/martianenforcer/default.jpg \ data1/players/martianenforcer/default_normal.tga \ data1/players/martianenforcer/drown1.wav \ data1/players/martianenforcer/fall1.wav \ data1/players/martianenforcer/fall2.wav \ data1/players/martianenforcer/gamara_i.jpg \ data1/players/martianenforcer/gamara.jpg \ data1/players/martianenforcer/gamara_normal.tga \ data1/players/martianenforcer/gasp1.wav \ data1/players/martianenforcer/gasp2.wav \ data1/players/martianenforcer/gurp1.wav \ data1/players/martianenforcer/gurp2.wav \ data1/players/martianenforcer/head.md2 \ data1/players/martianenforcer/helmet.iqm \ data1/players/martianenforcer/helmet.md2 \ data1/players/martianenforcer/jump1.wav \ data1/players/martianenforcer/leg.md2 \ data1/players/martianenforcer/lod1.iqm \ data1/players/martianenforcer/lod1.md2 \ data1/players/martianenforcer/lod1.rgd \ data1/players/martianenforcer/lod2.iqm \ data1/players/martianenforcer/lod2.md2 \ data1/players/martianenforcer/lod2.rgd \ data1/players/martianenforcer/pain100_1.wav \ data1/players/martianenforcer/pain100_2.wav \ data1/players/martianenforcer/pain25_1.wav \ data1/players/martianenforcer/pain25_2.wav \ data1/players/martianenforcer/pain50_1.wav \ data1/players/martianenforcer/pain50_2.wav \ data1/players/martianenforcer/pain75_1.wav \ data1/players/martianenforcer/pain75_2.wav \ data1/players/martianenforcer/red_i.jpg \ data1/players/martianenforcer/red.jpg \ data1/players/martianenforcer/tris.iqm \ data1/players/martianenforcer/tris.md2 \ data1/players/martianenforcer/tris.rgd \ data1/players/martianenforcer/tron2_i.jpg \ data1/players/martianenforcer/tron2.jpg \ data1/players/martianenforcer/tron3_i.jpg \ data1/players/martianenforcer/tron3.jpg \ data1/players/martianenforcer/tron_i.jpg \ data1/players/martianenforcer/tron.jpg \ data1/players/martianenforcer/tron_normal.tga \ data1/players/martianenforcer/usegibs \ data1/players/martianenforcer/w_alienblaster.iqm \ data1/players/martianenforcer/w_alienblaster.skin \ data1/players/martianenforcer/w_bfg.iqm \ data1/players/martianenforcer/w_bfg.md2 \ data1/players/martianenforcer/w_bfg.skin \ data1/players/martianenforcer/w_blaster.iqm \ data1/players/martianenforcer/w_blaster.md2 \ data1/players/martianenforcer/w_blaster.skin \ data1/players/martianenforcer/w_chaingun.iqm \ data1/players/martianenforcer/w_chaingun.md2 \ data1/players/martianenforcer/w_chaingun.skin \ data1/players/martianenforcer/weapon.iqm \ data1/players/martianenforcer/weapon.jpg \ data1/players/martianenforcer/weapon.md2 \ data1/players/martianenforcer/weapon.skin \ data1/players/martianenforcer/w_hyperblaster.iqm \ data1/players/martianenforcer/w_hyperblaster.md2 \ data1/players/martianenforcer/w_hyperblaster.skin \ data1/players/martianenforcer/w_machinegun.iqm \ data1/players/martianenforcer/w_machinegun.md2 \ data1/players/martianenforcer/w_machinegun.skin \ data1/players/martianenforcer/w_minderaser.iqm \ data1/players/martianenforcer/w_minderaser.md2 \ data1/players/martianenforcer/w_minderaser.skin \ data1/players/martianenforcer/w_railgun.iqm \ data1/players/martianenforcer/w_railgun.md2 \ data1/players/martianenforcer/w_railgun.skin \ data1/players/martianenforcer/w_rlauncher.iqm \ data1/players/martianenforcer/w_rlauncher.md2 \ data1/players/martianenforcer/w_rlauncher.skin \ data1/players/martianenforcer/w_shotgun.iqm \ data1/players/martianenforcer/w_shotgun.md2 \ data1/players/martianenforcer/w_shotgun.skin \ data1/players/martianenforcer/w_sshotgun.iqm \ data1/players/martianenforcer/w_sshotgun.md2 \ data1/players/martianenforcer/w_sshotgun.skin \ data1/players/martianenforcer/w_violator.iqm \ data1/players/martianenforcer/w_violator.md2 \ data1/players/martianenforcer/w_violator.skin \ data1/players/martianoverlord/alien \ data1/players/martianoverlord/blue_i.jpg \ data1/players/martianoverlord/blue.jpg \ data1/players/martianoverlord/bump1.wav \ data1/players/martianoverlord/death1.wav \ data1/players/martianoverlord/death2.wav \ data1/players/martianoverlord/death3.wav \ data1/players/martianoverlord/death4.wav \ data1/players/martianoverlord/default_i.jpg \ data1/players/martianoverlord/default.jpg \ data1/players/martianoverlord/default_normal.tga \ data1/players/martianoverlord/drown1.wav \ data1/players/martianoverlord/fall1.wav \ data1/players/martianoverlord/fall2.wav \ data1/players/martianoverlord/gasp1.wav \ data1/players/martianoverlord/gasp2.wav \ data1/players/martianoverlord/gurp1.wav \ data1/players/martianoverlord/gurp2.wav \ data1/players/martianoverlord/helmet.iqm \ data1/players/martianoverlord/helmet.md2 \ data1/players/martianoverlord/jump1.wav \ data1/players/martianoverlord/lod1.iqm \ data1/players/martianoverlord/lod1.rgd \ data1/players/martianoverlord/lod2.iqm \ data1/players/martianoverlord/lod2.rgd \ data1/players/martianoverlord/pain100_1.wav \ data1/players/martianoverlord/pain100_2.wav \ data1/players/martianoverlord/pain25_1.wav \ data1/players/martianoverlord/pain25_2.wav \ data1/players/martianoverlord/pain50_1.wav \ data1/players/martianoverlord/pain50_2.wav \ data1/players/martianoverlord/pain75_1.wav \ data1/players/martianoverlord/pain75_2.wav \ data1/players/martianoverlord/red_i.jpg \ data1/players/martianoverlord/red.jpg \ data1/players/martianoverlord/tris.iqm \ data1/players/martianoverlord/tris.md2 \ data1/players/martianoverlord/tris.rgd \ data1/players/martianoverlord/tron2_i.jpg \ data1/players/martianoverlord/tron2.jpg \ data1/players/martianoverlord/tron3_i.jpg \ data1/players/martianoverlord/tron3.jpg \ data1/players/martianoverlord/tron_i.jpg \ data1/players/martianoverlord/tron.jpg \ data1/players/martianoverlord/tron_normal.tga \ data1/players/martianoverlord/w_alienblaster.iqm \ data1/players/martianoverlord/w_alienblaster.skin \ data1/players/martianoverlord/w_bfg.iqm \ data1/players/martianoverlord/w_bfg.md2 \ data1/players/martianoverlord/w_bfg.skin \ data1/players/martianoverlord/w_blaster.iqm \ data1/players/martianoverlord/w_blaster.md2 \ data1/players/martianoverlord/w_blaster.skin \ data1/players/martianoverlord/w_chaingun.iqm \ data1/players/martianoverlord/w_chaingun.md2 \ data1/players/martianoverlord/w_chaingun.skin \ data1/players/martianoverlord/weapon.iqm \ data1/players/martianoverlord/weapon.jpg \ data1/players/martianoverlord/weapon.md2 \ data1/players/martianoverlord/weapon.skin \ data1/players/martianoverlord/w_hyperblaster.iqm \ data1/players/martianoverlord/w_hyperblaster.md2 \ data1/players/martianoverlord/w_hyperblaster.skin \ data1/players/martianoverlord/w_machinegun.iqm \ data1/players/martianoverlord/w_machinegun.md2 \ data1/players/martianoverlord/w_machinegun.skin \ data1/players/martianoverlord/w_minderaser.iqm \ data1/players/martianoverlord/w_minderaser.md2 \ data1/players/martianoverlord/w_minderaser.skin \ data1/players/martianoverlord/w_railgun.iqm \ data1/players/martianoverlord/w_railgun.md2 \ data1/players/martianoverlord/w_railgun.skin \ data1/players/martianoverlord/w_rlauncher.iqm \ data1/players/martianoverlord/w_rlauncher.md2 \ data1/players/martianoverlord/w_rlauncher.skin \ data1/players/martianoverlord/w_shotgun.iqm \ data1/players/martianoverlord/w_shotgun.md2 \ data1/players/martianoverlord/w_shotgun.skin \ data1/players/martianoverlord/w_sshotgun.iqm \ data1/players/martianoverlord/w_sshotgun.md2 \ data1/players/martianoverlord/w_sshotgun.skin \ data1/players/martianoverlord/w_violator.iqm \ data1/players/martianoverlord/w_violator.md2 \ data1/players/martianoverlord/w_violator.skin \ data1/players/martianwarrior/alien \ data1/players/martianwarrior/blue_i.jpg \ data1/players/martianwarrior/blue.jpg \ data1/players/martianwarrior/bump1.wav \ data1/players/martianwarrior/death1.wav \ data1/players/martianwarrior/death2.wav \ data1/players/martianwarrior/death3.wav \ data1/players/martianwarrior/death4.wav \ data1/players/martianwarrior/default_i.jpg \ data1/players/martianwarrior/default.jpg \ data1/players/martianwarrior/default_normal.tga \ data1/players/martianwarrior/drown1.wav \ data1/players/martianwarrior/fall1.wav \ data1/players/martianwarrior/fall2.wav \ data1/players/martianwarrior/gasp1.wav \ data1/players/martianwarrior/gasp2.wav \ data1/players/martianwarrior/gurp1.wav \ data1/players/martianwarrior/gurp2.wav \ data1/players/martianwarrior/helmet.iqm \ data1/players/martianwarrior/helmet.md2 \ data1/players/martianwarrior/jump1.wav \ data1/players/martianwarrior/lod1.iqm \ data1/players/martianwarrior/lod1.md2 \ data1/players/martianwarrior/lod1.rgd \ data1/players/martianwarrior/lod2.iqm \ data1/players/martianwarrior/lod2.md2 \ data1/players/martianwarrior/lod2.rgd \ data1/players/martianwarrior/pain100_1.wav \ data1/players/martianwarrior/pain100_2.wav \ data1/players/martianwarrior/pain25_1.wav \ data1/players/martianwarrior/pain25_2.wav \ data1/players/martianwarrior/pain50_1.wav \ data1/players/martianwarrior/pain50_2.wav \ data1/players/martianwarrior/pain75_1.wav \ data1/players/martianwarrior/pain75_2.wav \ data1/players/martianwarrior/red_i.jpg \ data1/players/martianwarrior/red.jpg \ data1/players/martianwarrior/tris.iqm \ data1/players/martianwarrior/tris.md2 \ data1/players/martianwarrior/tris.rgd \ data1/players/martianwarrior/tron2_i.jpg \ data1/players/martianwarrior/tron2.jpg \ data1/players/martianwarrior/tron3_i.jpg \ data1/players/martianwarrior/tron3.jpg \ data1/players/martianwarrior/tron_i.jpg \ data1/players/martianwarrior/tron.jpg \ data1/players/martianwarrior/tron_normal.tga \ data1/players/martianwarrior/w_alienblaster.iqm \ data1/players/martianwarrior/w_alienblaster.skin \ data1/players/martianwarrior/w_bfg.iqm \ data1/players/martianwarrior/w_bfg.md2 \ data1/players/martianwarrior/w_bfg.skin \ data1/players/martianwarrior/w_blaster.iqm \ data1/players/martianwarrior/w_blaster.md2 \ data1/players/martianwarrior/w_blaster.skin \ data1/players/martianwarrior/w_chaingun.iqm \ data1/players/martianwarrior/w_chaingun.md2 \ data1/players/martianwarrior/w_chaingun.skin \ data1/players/martianwarrior/weapon.iqm \ data1/players/martianwarrior/weapon.jpg \ data1/players/martianwarrior/weapon.md2 \ data1/players/martianwarrior/weapon.skin \ data1/players/martianwarrior/w_hyperblaster.iqm \ data1/players/martianwarrior/w_hyperblaster.md2 \ data1/players/martianwarrior/w_hyperblaster.skin \ data1/players/martianwarrior/w_machinegun.iqm \ data1/players/martianwarrior/w_machinegun.md2 \ data1/players/martianwarrior/w_machinegun.skin \ data1/players/martianwarrior/w_minderaser.iqm \ data1/players/martianwarrior/w_minderaser.md2 \ data1/players/martianwarrior/w_minderaser.skin \ data1/players/martianwarrior/w_railgun.iqm \ data1/players/martianwarrior/w_railgun.md2 \ data1/players/martianwarrior/w_railgun.skin \ data1/players/martianwarrior/w_rlauncher.iqm \ data1/players/martianwarrior/w_rlauncher.md2 \ data1/players/martianwarrior/w_rlauncher.skin \ data1/players/martianwarrior/w_shotgun.iqm \ data1/players/martianwarrior/w_shotgun.md2 \ data1/players/martianwarrior/w_shotgun.skin \ data1/players/martianwarrior/w_sshotgun.iqm \ data1/players/martianwarrior/w_sshotgun.md2 \ data1/players/martianwarrior/w_sshotgun.skin \ data1/players/martianwarrior/w_violator.iqm \ data1/players/martianwarrior/w_violator.md2 \ data1/players/martianwarrior/w_violator.skin \ data1/players/slashbot/blue_i.jpg \ data1/players/slashbot/blue.jpg \ data1/players/slashbot/bump1.wav \ data1/players/slashbot/death1.wav \ data1/players/slashbot/death2.wav \ data1/players/slashbot/death3.wav \ data1/players/slashbot/death4.wav \ data1/players/slashbot/default_i.jpg \ data1/players/slashbot/default.jpg \ data1/players/slashbot/default_normal.jpg \ data1/players/slashbot/drown1.wav \ data1/players/slashbot/fall1.wav \ data1/players/slashbot/fall2.wav \ data1/players/slashbot/gurp1.wav \ data1/players/slashbot/gurp2.wav \ data1/players/slashbot/jump1.wav \ data1/players/slashbot/lod1.iqm \ data1/players/slashbot/lod2.iqm \ data1/players/slashbot/lod1.rgd \ data1/players/slashbot/lod2.rgd \ data1/players/slashbot/pain100_1.wav \ data1/players/slashbot/pain100_2.wav \ data1/players/slashbot/pain25_1.wav \ data1/players/slashbot/pain25_2.wav \ data1/players/slashbot/pain50_1.wav \ data1/players/slashbot/pain50_2.wav \ data1/players/slashbot/pain75_1.wav \ data1/players/slashbot/pain75_2.wav \ data1/players/slashbot/red_i.jpg \ data1/players/slashbot/red.jpg \ data1/players/slashbot/robot \ data1/players/slashbot/tris.iqm \ data1/players/slashbot/tris.md2 \ data1/players/slashbot/tris.rgd \ data1/players/slashbot/tron2_i.jpg \ data1/players/slashbot/tron2.jpg \ data1/players/slashbot/tron3_i.jpg \ data1/players/slashbot/tron3.jpg \ data1/players/slashbot/tron_i.jpg \ data1/players/slashbot/tron.jpg \ data1/players/slashbot/tron_normal.tga \ data1/players/slashbot/w_bfg.iqm \ data1/players/slashbot/w_bfg.md2 \ data1/players/slashbot/w_bfg.skin \ data1/players/slashbot/w_blaster.iqm \ data1/players/slashbot/w_blaster.md2 \ data1/players/slashbot/w_blaster.skin \ data1/players/slashbot/w_chaingun.iqm \ data1/players/slashbot/w_chaingun.md2 \ data1/players/slashbot/w_chaingun.skin \ data1/players/slashbot/weapon.iqm \ data1/players/slashbot/weapon.jpg \ data1/players/slashbot/weapon.md2 \ data1/players/slashbot/weapon.skin \ data1/players/slashbot/w_hyperblaster.iqm \ data1/players/slashbot/w_hyperblaster.md2 \ data1/players/slashbot/w_hyperblaster.skin \ data1/players/slashbot/w_machinegun.iqm \ data1/players/slashbot/w_machinegun.md2 \ data1/players/slashbot/w_machinegun.skin \ data1/players/slashbot/w_minderaser.iqm \ data1/players/slashbot/w_minderaser.md2 \ data1/players/slashbot/w_minderaser.skin \ data1/players/slashbot/w_railgun.iqm \ data1/players/slashbot/w_railgun.md2 \ data1/players/slashbot/w_railgun.skin \ data1/players/slashbot/w_rlauncher.iqm \ data1/players/slashbot/w_rlauncher.md2 \ data1/players/slashbot/w_rlauncher.skin \ data1/players/slashbot/w_shotgun.iqm \ data1/players/slashbot/w_shotgun.md2 \ data1/players/slashbot/w_shotgun.skin \ data1/players/slashbot/w_sshotgun.iqm \ data1/players/slashbot/w_sshotgun.md2 \ data1/players/slashbot/w_sshotgun.skin \ data1/players/slashbot/w_violator.iqm \ data1/players/slashbot/w_violator.md2 \ data1/players/slashbot/w_violator.skin scriptsdir = $(pkgdatadir) nobase_nodist_scripts_DATA = \ data1/scripts/caustics.rscript \ data1/scripts/consoles.rscript \ data1/scripts/interactive/textures.rscript \ data1/scripts/maps/aoa-atlantis.rscript \ data1/scripts/maps/aoa-corrosion.rscript \ data1/scripts/maps/aoa-frost2k9.rscript \ data1/scripts/maps/aoa-morpheus.rscript \ data1/scripts/maps/aoa-zorn.rscript \ data1/scripts/maps/cp-ribeye.rscript \ data1/scripts/maps/ctf-corrosion.rscript \ data1/scripts/maps/ctf-cryogenic.rscript \ data1/scripts/maps/ctf-extermination.rscript \ data1/scripts/maps/ctf-frostbyte.rscript \ data1/scripts/maps/ctf-goregrinder.rscript \ data1/scripts/maps/ctf-invasion.rscript \ data1/scripts/maps/ctf-oblivion.rscript \ data1/scripts/maps/ctf-purgatory.rscript \ data1/scripts/maps/ctf-titan2k8.rscript \ data1/scripts/maps/ctf-vesuvius2k11.rscript \ data1/scripts/maps/ctf-violator.rscript \ data1/scripts/maps/ctf-zion2k9.rscript \ data1/scripts/maps/db-chromium.rscript \ data1/scripts/maps/db-icarus.rscript \ data1/scripts/maps/db-vesuvius.rscript \ data1/scripts/maps/dm-annihilation.rscript \ data1/scripts/maps/dm-atlantis2k8.rscript \ data1/scripts/maps/dm-babel2k11.rscript \ data1/scripts/maps/dm-bloodfactory2k12.rscript \ data1/scripts/maps/dm-chasmatic2k9.rscript \ data1/scripts/maps/dm-command2k9.rscript \ data1/scripts/maps/dm-corrosion.rscript \ data1/scripts/maps/dm-crucible2k12.rscript \ data1/scripts/maps/dm-deathray.rscript \ data1/scripts/maps/dm-deimos2k9.rscript \ data1/scripts/maps/dm-dismal2k11.rscript \ data1/scripts/maps/dm-downfall.rscript \ data1/scripts/maps/dm-dynamo2k12.rscript \ data1/scripts/maps/dm-eternal.rscript \ data1/scripts/maps/dm-extermination.rscript \ data1/scripts/maps/dm-furious2k8.rscript \ data1/scripts/maps/dm-goregrinder.rscript \ data1/scripts/maps/dm-horus.rscript \ data1/scripts/maps/dm-impact.rscript \ data1/scripts/maps/dm-invasion.rscript \ data1/scripts/maps/dm-leviathan2k12.rscript \ data1/scripts/maps/dm-liberation.rscript \ data1/scripts/maps/dm-neptune.rscript \ data1/scripts/maps/dm-oblivion.rscript \ data1/scripts/maps/dm-omega2k8.rscript \ data1/scripts/maps/dm-purgatory.rscript \ data1/scripts/maps/dm-saucer2k9.rscript \ data1/scripts/maps/dm-turbo2k8.rscript \ data1/scripts/maps/dm-vesuvius2k11.rscript \ data1/scripts/maps/dm-violator2k11.rscript \ data1/scripts/maps/dm-warmachine2k10.rscript \ data1/scripts/maps/dm-zorn2k11.rscript \ data1/scripts/maps/dm-zion2k9.rscript \ data1/scripts/maps/tac-extermination.rscript \ data1/scripts/maps/tca-corrosion.rscript \ data1/scripts/maps/tca-cryogenic.rscript \ data1/scripts/maps/tca-extermination.rscript \ data1/scripts/maps/tca-purgatory.rscript \ data1/scripts/maps/tca-zion2k9.rscript \ data1/scripts/menu.rscript \ data1/scripts/models.rscript \ data1/scripts/normals/normals.rscript \ data1/scripts/normals/tron.rscript \ data1/scripts/textures.rscript sounddir = $(pkgdatadir) nobase_nodist_sound_DATA = \ data1/sound/doors/dr1_end.wav \ data1/sound/doors/dr1_mid.wav \ data1/sound/doors/dr1_strt.wav \ data1/sound/items/damage2.wav \ data1/sound/items/damage3.wav \ data1/sound/items/damage.wav \ data1/sound/items/hasteout.wav \ data1/sound/items/haste.wav \ data1/sound/items/l_health.wav \ data1/sound/items/m_health.wav \ data1/sound/items/n_health.wav \ data1/sound/items/powerup.wav \ data1/sound/items/protect2.wav \ data1/sound/items/protect3.wav \ data1/sound/items/protect4.wav \ data1/sound/items/protect.wav \ data1/sound/items/respawn1.wav \ data1/sound/items/s_health.wav \ data1/sound/items/sproingout.wav \ data1/sound/items/sproing.wav \ data1/sound/misc/1frags.wav \ data1/sound/misc/2frags.wav \ data1/sound/misc/3frags.wav \ data1/sound/misc/am_pkup.wav \ data1/sound/misc/ar1_pkup.wav \ data1/sound/misc/ar2_pkup.wav \ data1/sound/misc/ar3_pkup.wav \ data1/sound/misc/bigtele.wav \ data1/sound/misc/blue_increases.wav \ data1/sound/misc/blue_picked.wav \ data1/sound/misc/bluepndisabled.wav \ data1/sound/misc/bluepnenabled.wav \ data1/sound/misc/blue_returned.wav \ data1/sound/misc/blue_scores.wav \ data1/sound/misc/blue_takes.wav \ data1/sound/misc/bluevulnerable.wav \ data1/sound/misc/blue_wins_ctf.wav \ data1/sound/misc/blue_wins.wav \ data1/sound/misc/cow/groan.wav \ data1/sound/misc/cow/moo.wav \ data1/sound/misc/cow/step1.wav \ data1/sound/misc/db_pickup.wav \ data1/sound/misc/db_score.wav \ data1/sound/misc/deathray/fizz.wav \ data1/sound/misc/deathray/shoot.wav \ data1/sound/misc/deathray/weird2.wav \ data1/sound/misc/death.wav \ data1/sound/misc/fight.wav \ data1/sound/misc/game_tied_ctf.wav \ data1/sound/misc/game_tied.wav \ data1/sound/misc/godlike.wav \ data1/sound/misc/headshot.wav \ data1/sound/misc/hit2.wav \ data1/sound/misc/hit.wav \ data1/sound/misc/lasfly.wav \ data1/sound/misc/menu1.wav \ data1/sound/misc/menu2.wav \ data1/sound/misc/menu3.wav \ data1/sound/misc/minderaser.wav \ data1/sound/misc/one.wav \ data1/sound/misc/pc_up.wav \ data1/sound/misc/rampage.wav \ data1/sound/misc/red_increases.wav \ data1/sound/misc/red_picked.wav \ data1/sound/misc/redpndisabled.wav \ data1/sound/misc/redpnenabled.wav \ data1/sound/misc/red_returned.wav \ data1/sound/misc/red_scores.wav \ data1/sound/misc/red_takes.wav \ data1/sound/misc/redvulnerable.wav \ data1/sound/misc/red_wins_ctf.wav \ data1/sound/misc/red_wins.wav \ data1/sound/misc/reject.wav \ data1/sound/misc/scores_tied.wav \ data1/sound/misc/spawn1.wav \ data1/sound/misc/talk1.wav \ data1/sound/misc/talk.wav \ data1/sound/misc/tele1.wav \ data1/sound/misc/tele_up.wav \ data1/sound/misc/three.wav \ data1/sound/misc/trigger1.wav \ data1/sound/misc/two.wav \ data1/sound/misc/w_pkup.wav \ data1/sound/music/adrenaline.ogg \ data1/sound/music/cp-ribeye.ogg \ data1/sound/music/Divinity_lack_of_success.ogg \ data1/sound/music/Divinity_misunderstood.ogg \ data1/sound/music/Divinity_never_ending.ogg \ data1/sound/music/dm-annihilation.ogg \ data1/sound/music/dm-deathray.ogg \ data1/sound/music/dm-deimos.ogg \ data1/sound/music/dm-dismal.ogg \ data1/sound/music/dm-dynamo.ogg \ data1/sound/music/dm-eternal.ogg \ data1/sound/music/dm-extermination.ogg \ data1/sound/music/dm-frontier.ogg \ data1/sound/music/dm-horus.ogg \ data1/sound/music/dm-inferno.ogg \ data1/sound/music/dm-redred.ogg \ data1/sound/music/dm-saucer.ogg \ data1/sound/music/dm-turbo.ogg \ data1/sound/music/dm-warmachine.ogg \ data1/sound/music/joyce1.ogg \ data1/sound/music/joyce2.ogg \ data1/sound/music/joyce3.ogg \ data1/sound/music/menumusic.ogg \ data1/sound/player/burn1.wav \ data1/sound/player/burn2.wav \ data1/sound/player/death1.wav \ data1/sound/player/death4.wav \ data1/sound/player/drown1.wav \ data1/sound/player/fall1.wav \ data1/sound/player/fall2.wav \ data1/sound/player/fry.wav \ data1/sound/player/gasp1.wav \ data1/sound/player/gasp2.wav \ data1/sound/player/jump1.wav \ data1/sound/player/land1.wav \ data1/sound/player/lava1.wav \ data1/sound/player/lava2.wav \ data1/sound/player/lava_in.wav \ data1/sound/player/male/bump1.wav \ data1/sound/player/male/death1.wav \ data1/sound/player/male/death2.wav \ data1/sound/player/male/death3.wav \ data1/sound/player/male/death4.wav \ data1/sound/player/male/drown1.wav \ data1/sound/player/male/fall1.wav \ data1/sound/player/male/fall2.wav \ data1/sound/player/male/gurp1.wav \ data1/sound/player/male/gurp2.wav \ data1/sound/player/male/jump1.wav \ data1/sound/player/male/pain100_1.wav \ data1/sound/player/male/pain100_2.wav \ data1/sound/player/male/pain25_1.wav \ data1/sound/player/male/pain25_2.wav \ data1/sound/player/male/pain50_1.wav \ data1/sound/player/male/pain50_2.wav \ data1/sound/player/male/pain75_1.wav \ data1/sound/player/male/pain75_2.wav \ data1/sound/player/step1.wav \ data1/sound/player/step2.wav \ data1/sound/player/step3.wav \ data1/sound/player/step4.wav \ data1/sound/player/step_metal1.wav \ data1/sound/player/step_metal2.wav \ data1/sound/player/step_metal3.wav \ data1/sound/player/step_metal4.wav \ data1/sound/player/wade1.wav \ data1/sound/player/wade2.wav \ data1/sound/player/wade3.wav \ data1/sound/player/watr_in.wav \ data1/sound/player/watr_out.wav \ data1/sound/player/watr_un.wav \ data1/sound/smallmech/sight.wav \ data1/sound/taunts/commander/taunt1.wav \ data1/sound/taunts/commander/taunt2.wav \ data1/sound/taunts/commander/taunt3.wav \ data1/sound/taunts/commander/taunt4.wav \ data1/sound/taunts/commander/taunt5.wav \ data1/sound/taunts/enforcer/taunt1.wav \ data1/sound/taunts/enforcer/taunt2.wav \ data1/sound/taunts/enforcer/taunt3.wav \ data1/sound/taunts/enforcer/taunt4.wav \ data1/sound/taunts/enforcer/taunt5.wav \ data1/sound/taunts/lauren/taunt1.wav \ data1/sound/taunts/lauren/taunt2.wav \ data1/sound/taunts/lauren/taunt3.wav \ data1/sound/taunts/lauren/taunt4.wav \ data1/sound/taunts/lauren/taunt5.wav \ data1/sound/taunts/martiancyborg/taunt1.wav \ data1/sound/taunts/martiancyborg/taunt2.wav \ data1/sound/taunts/martiancyborg/taunt3.wav \ data1/sound/taunts/martiancyborg/taunt4.wav \ data1/sound/taunts/martiancyborg/taunt5.wav \ data1/sound/taunts/martianenforcer/taunt1.wav \ data1/sound/taunts/martianenforcer/taunt2.wav \ data1/sound/taunts/martianenforcer/taunt3.wav \ data1/sound/taunts/martianenforcer/taunt4.wav \ data1/sound/taunts/martianenforcer/taunt5.wav \ data1/sound/taunts/martianoverlord/taunt1.wav \ data1/sound/taunts/martianoverlord/taunt2.wav \ data1/sound/taunts/martianoverlord/taunt3.wav \ data1/sound/taunts/martianoverlord/taunt4.wav \ data1/sound/taunts/martianoverlord/taunt5.wav \ data1/sound/taunts/martianwarrior/taunt1.wav \ data1/sound/taunts/martianwarrior/taunt2.wav \ data1/sound/taunts/martianwarrior/taunt3.wav \ data1/sound/taunts/martianwarrior/taunt4.wav \ data1/sound/taunts/martianwarrior/taunt5.wav \ data1/sound/taunts/slashbot/taunt1.wav \ data1/sound/taunts/slashbot/taunt2.wav \ data1/sound/taunts/slashbot/taunt3.wav \ data1/sound/taunts/slashbot/taunt4.wav \ data1/sound/taunts/slashbot/taunt5.wav \ data1/sound/vehicles/bomberidle.wav \ data1/sound/vehicles/explodebomb.wav \ data1/sound/vehicles/flybomb.wav \ data1/sound/vehicles/got_in.wav \ data1/sound/vehicles/shootbomb.wav \ data1/sound/vehicles/shootlaser.wav \ data1/sound/vehicles/warning.wav \ data1/sound/weapons/adetonatordown.wav \ data1/sound/weapons/adetonatorup.wav \ data1/sound/weapons/biglaser.wav \ data1/sound/weapons/blastf1a.wav \ data1/sound/weapons/clank.wav \ data1/sound/weapons/clink01.wav \ data1/sound/weapons/clink02.wav \ data1/sound/weapons/electroball.wav \ data1/sound/weapons/energyfield.wav \ data1/sound/weapons/grenlb1b.wav \ data1/sound/weapons/grenlf1a.wav \ data1/sound/weapons/grenlr1b.wav \ data1/sound/weapons/grenlx1a.wav \ data1/sound/weapons/hypbrl1a.wav \ data1/sound/weapons/hyprbf1a.wav \ data1/sound/weapons/lightoff.wav \ data1/sound/weapons/lighton.wav \ data1/sound/weapons/machgf1b.wav \ data1/sound/weapons/machgf2b.wav \ data1/sound/weapons/machgf3b.wav \ data1/sound/weapons/machgf4b.wav \ data1/sound/weapons/machgf5b.wav \ data1/sound/weapons/minderaserfire.wav \ data1/sound/weapons/noammo.wav \ data1/sound/weapons/railgf1a.wav \ data1/sound/weapons/rockfly.wav \ data1/sound/weapons/rocklf1a.wav \ data1/sound/weapons/rocklr1b.wav \ data1/sound/weapons/rocklx1a.wav \ data1/sound/weapons/seeker_fast.wav \ data1/sound/weapons/seeker.wav \ data1/sound/weapons/seeker_zap.wav \ data1/sound/weapons/shotgf1b.wav \ data1/sound/weapons/smartgun_hum.wav \ data1/sound/weapons/spidermov.wav \ data1/sound/weapons/vaporizer_hum.wav \ data1/sound/weapons/viofire1.wav \ data1/sound/weapons/viofire2.wav \ data1/sound/weapons/whoosh.wav \ data1/sound/world/botwon.wav \ data1/sound/world/button1.wav \ data1/sound/world/button2.wav \ data1/sound/world/distantjet.wav \ data1/sound/world/electricity.wav \ data1/sound/world/explosion1.wav \ data1/sound/world/explosion2.wav \ data1/sound/world/forcefield.wav \ data1/sound/world/hyprbf1a.wav \ data1/sound/world/jumppad1.wav \ data1/sound/world/laser1.wav \ data1/sound/world/platstop.wav \ data1/sound/world/rcktfly.wav \ data1/sound/world/ric1.wav \ data1/sound/world/ric2.wav \ data1/sound/world/ric3.wav \ data1/sound/world/rocket.wav \ data1/sound/world/steam1.wav \ data1/sound/world/steam2.wav \ data1/sound/world/turbine1.wav \ data1/sound/world/vents.wav \ data1/sound/world/water1.wav \ data1/sound/world/weird.wav \ data1/sound/world/youwin.wav texturesdir = $(pkgdatadir) nobase_nodist_textures_DATA = \ data1/textures/alien/support5.tga \ data1/textures/arena10/bluetile_hm.tga \ data1/textures/arena10/bluetile_nm.tga \ data1/textures/arena10/bluetile.tga \ data1/textures/arena10/bricks1_nm.tga \ data1/textures/arena10/bricks1.tga \ data1/textures/arena10/bricks2_broken_nm.tga \ data1/textures/arena10/bricks2_broken.tga \ data1/textures/arena10/bricks2_hm.tga \ data1/textures/arena10/bricks2_nm.tga \ data1/textures/arena10/bricks2.tga \ data1/textures/arena10/bricks3.tga \ data1/textures/arena10/building10_broken2_nm.tga \ data1/textures/arena10/building10_broken2.tga \ data1/textures/arena10/building10_broken_nm.tga \ data1/textures/arena10/building10_broken.tga \ data1/textures/arena10/building10_nm.tga \ data1/textures/arena10/building10.tga \ data1/textures/arena10/building11_nm.tga \ data1/textures/arena10/building11.tga \ data1/textures/arena10/building12_nm.tga \ data1/textures/arena10/building12.tga \ data1/textures/arena10/building13_nm.tga \ data1/textures/arena10/building13.tga \ data1/textures/arena10/building14_nm.tga \ data1/textures/arena10/building14.tga \ data1/textures/arena10/building15_nm.tga \ data1/textures/arena10/building15.tga \ data1/textures/arena10/building1_broken_nm.tga \ data1/textures/arena10/building1_broken.tga \ data1/textures/arena10/building1_nm.tga \ data1/textures/arena10/building1.tga \ data1/textures/arena10/building2_nm.tga \ data1/textures/arena10/building2.tga \ data1/textures/arena10/building3_hm.tga \ data1/textures/arena10/building3_nm.tga \ data1/textures/arena10/building3ns_hm.tga \ data1/textures/arena10/building3ns_nm.tga \ data1/textures/arena10/building3ns.tga \ data1/textures/arena10/building3.tga \ data1/textures/arena10/building4_nm.tga \ data1/textures/arena10/building4.tga \ data1/textures/arena10/building5_nm.tga \ data1/textures/arena10/building5.tga \ data1/textures/arena10/building6_nm.tga \ data1/textures/arena10/building6.tga \ data1/textures/arena10/building7_nm.tga \ data1/textures/arena10/building7s_hm.tga \ data1/textures/arena10/building7s_nm.tga \ data1/textures/arena10/building7s.tga \ data1/textures/arena10/building7.tga \ data1/textures/arena10/building8_nm.tga \ data1/textures/arena10/building8.tga \ data1/textures/arena10/building9_nm.tga \ data1/textures/arena10/building9.tga \ data1/textures/arena10/cement1_hm.tga \ data1/textures/arena10/cement1_nm.tga \ data1/textures/arena10/cement1ns_nm.tga \ data1/textures/arena10/cement1ns.tga \ data1/textures/arena10/cement1.tga \ data1/textures/arena10/cobblestone_hm.tga \ data1/textures/arena10/cobblestoneng_hm.tga \ data1/textures/arena10/cobblestoneng_nm.tga \ data1/textures/arena10/cobblestoneng.tga \ data1/textures/arena10/cobblestone_nm.tga \ data1/textures/arena10/cobblestonens_nm.tga \ data1/textures/arena10/cobblestonens.tga \ data1/textures/arena10/cobblestone.tga \ data1/textures/arena10/cobwebs2.tga \ data1/textures/arena10/cobwebs.tga \ data1/textures/arena10/cocacola.tga \ data1/textures/arena10/container1_hm.tga \ data1/textures/arena10/container1_nm.tga \ data1/textures/arena10/container1.tga \ data1/textures/arena10/container2_hm.tga \ data1/textures/arena10/container2_nm.tga \ data1/textures/arena10/container2.tga \ data1/textures/arena10/container3_hm.tga \ data1/textures/arena10/container3_nm.tga \ data1/textures/arena10/container3.tga \ data1/textures/arena10/container4_hm.tga \ data1/textures/arena10/container4_nm.tga \ data1/textures/arena10/container4.tga \ data1/textures/arena10/cretewall1_nm.tga \ data1/textures/arena10/cretewall1.tga \ data1/textures/arena10/cretewall2_nm.tga \ data1/textures/arena10/cretewall2.tga \ data1/textures/arena10/elecpanel1_hm.tga \ data1/textures/arena10/elecpanel1_nm.tga \ data1/textures/arena10/elecpanel1.tga \ data1/textures/arena10/elecpanel2_hm.tga \ data1/textures/arena10/elecpanel2_nm.tga \ data1/textures/arena10/elecpanel2.tga \ data1/textures/arena10/elecpanel3_hm.tga \ data1/textures/arena10/elecpanel3_nm.tga \ data1/textures/arena10/elecpanel3.tga \ data1/textures/arena10/elecpanel4_hm.tga \ data1/textures/arena10/elecpanel4_nm.tga \ data1/textures/arena10/elecpanel4.tga \ data1/textures/arena10/elecvents_hm.tga \ data1/textures/arena10/elecvents_nm.tga \ data1/textures/arena10/elecvents.tga \ data1/textures/arena10/elecwall1_nm.tga \ data1/textures/arena10/elecwall1.tga \ data1/textures/arena10/elecwall2_nm.tga \ data1/textures/arena10/elecwall2.tga \ data1/textures/arena10/floortile10_hm.tga \ data1/textures/arena10/floortile10_nm.tga \ data1/textures/arena10/floortile10.tga \ data1/textures/arena10/floortile10w_hm.tga \ data1/textures/arena10/floortile10w_nm.tga \ data1/textures/arena10/floortile10w.tga \ data1/textures/arena10/gothceil1_hm.tga \ data1/textures/arena10/gothceil1_nm.tga \ data1/textures/arena10/gothceil1.tga \ data1/textures/arena10/gothmetal1.tga \ data1/textures/arena10/gothwindow1_hm.tga \ data1/textures/arena10/gothwindow1.tga \ data1/textures/arena10/gothwindow2_hm.tga \ data1/textures/arena10/gothwindow2.tga \ data1/textures/arena10/gothwindow2r_hm.tga \ data1/textures/arena10/gothwindow2r.tga \ data1/textures/arena10/gothwindow3_hm.tga \ data1/textures/arena10/gothwindow3.tga \ data1/textures/arena10/gothwindow3r_hm.tga \ data1/textures/arena10/gothwindow3r.tga \ data1/textures/arena10/graffitiwall1.tga \ data1/textures/arena10/grafittiwall2.tga \ data1/textures/arena10/heap1_nm.tga \ data1/textures/arena10/heap1.tga \ data1/textures/arena10/heap2_nm.tga \ data1/textures/arena10/heap2.tga \ data1/textures/arena10/heap3_nm.tga \ data1/textures/arena10/heap3.tga \ data1/textures/arena10/heap4_nm.tga \ data1/textures/arena10/heap4.tga \ data1/textures/arena10/ivy1_nm.tga \ data1/textures/arena10/ivy1.tga \ data1/textures/arena10/ivy2_nm.tga \ data1/textures/arena10/ivy2.tga \ data1/textures/arena10/metalfence1.tga \ data1/textures/arena10/metalfence2.tga \ data1/textures/arena10/metalfloor20_hm.tga \ data1/textures/arena10/metalfloor20_nm.tga \ data1/textures/arena10/metalfloor20.tga \ data1/textures/arena10/metalfloor21_hm.tga \ data1/textures/arena10/metalfloor21_nm.tga \ data1/textures/arena10/metalfloor21.tga \ data1/textures/arena10/metalfloor21w_hm.tga \ data1/textures/arena10/metalfloor21w_nm.tga \ data1/textures/arena10/metalfloor21w.tga \ data1/textures/arena10/metalwall20_hm.tga \ data1/textures/arena10/metalwall20_nm.tga \ data1/textures/arena10/metalwall20.tga \ data1/textures/arena10/moltenrock_nm.tga \ data1/textures/arena10/moltenrock.tga \ data1/textures/arena10/neonsign10r.tga \ data1/textures/arena10/neonsign10.tga \ data1/textures/arena10/neonsign11b.tga \ data1/textures/arena10/neonsign11.tga \ data1/textures/arena10/neonsign12.tga \ data1/textures/arena10/neonsign13.tga \ data1/textures/arena10/neonsign14.tga \ data1/textures/arena10/neonsign15.tga \ data1/textures/arena10/neonsign16r.tga \ data1/textures/arena10/neonsign16.tga \ data1/textures/arena10/neonsign17.tga \ data1/textures/arena10/neonsign18r.tga \ data1/textures/arena10/neonsign18.tga \ data1/textures/arena10/neonsign19.tga \ data1/textures/arena10/neonsign1.tga \ data1/textures/arena10/neonsign20r.tga \ data1/textures/arena10/neonsign20.tga \ data1/textures/arena10/neonsign21.tga \ data1/textures/arena10/neonsign22.tga \ data1/textures/arena10/neonsign23.tga \ data1/textures/arena10/neonsign24.tga \ data1/textures/arena10/neonsign2.tga \ data1/textures/arena10/neonsign3.tga \ data1/textures/arena10/neonsign4.tga \ data1/textures/arena10/neonsign5.tga \ data1/textures/arena10/neonsign6r.tga \ data1/textures/arena10/neonsign6.tga \ data1/textures/arena10/neonsign7r.tga \ data1/textures/arena10/neonsign7.tga \ data1/textures/arena10/neonsign8.tga \ data1/textures/arena10/neonsign9.tga \ data1/textures/arena10/pipes1.tga \ data1/textures/arena10/planks_nm.tga \ data1/textures/arena10/planks.tga \ data1/textures/arena10/redtile_hm.tga \ data1/textures/arena10/redtile_nm.tga \ data1/textures/arena10/redtile.tga \ data1/textures/arena10/road1_hm.tga \ data1/textures/arena10/road1_nm.tga \ data1/textures/arena10/road1.tga \ data1/textures/arena10/road2_hm.tga \ data1/textures/arena10/road2_nm.tga \ data1/textures/arena10/road2.tga \ data1/textures/arena10/road3_hm.tga \ data1/textures/arena10/road3_nm.tga \ data1/textures/arena10/road3.tga \ data1/textures/arena10/roadbarrier_hm.tga \ data1/textures/arena10/roadbarrier_nm.tga \ data1/textures/arena10/roadbarrier.tga \ data1/textures/arena10/rockdirt1_hm.tga \ data1/textures/arena10/rockdirt1ng_hm.tga \ data1/textures/arena10/rockdirt1ng_nm.tga \ data1/textures/arena10/rockdirt1ng.tga \ data1/textures/arena10/rockdirt1_nm.tga \ data1/textures/arena10/rockdirt1ns_nm.tga \ data1/textures/arena10/rockdirt1ns.tga \ data1/textures/arena10/rockdirt1.tga \ data1/textures/arena10/rustdoor1_hm.tga \ data1/textures/arena10/rustdoor1_nm.tga \ data1/textures/arena10/rustdoor1.tga \ data1/textures/arena10/rustwall1_hm.tga \ data1/textures/arena10/rustwall1_nm.tga \ data1/textures/arena10/rustwall1.tga \ data1/textures/arena10/sevenup.tga \ data1/textures/arena10/sewergrate1_nm.tga \ data1/textures/arena10/sewergrate1.tga \ data1/textures/arena10/sign1.tga \ data1/textures/arena10/sign2.tga \ data1/textures/arena10/sign3.tga \ data1/textures/arena10/sign4.tga \ data1/textures/arena10/sign5r.tga \ data1/textures/arena10/sign5.tga \ data1/textures/arena10/sign6r.tga \ data1/textures/arena10/sign6.tga \ data1/textures/arena10/sign7_hm.tga \ data1/textures/arena10/sign7_nm.tga \ data1/textures/arena10/sign7.tga \ data1/textures/arena10/skyscraper1_hm.tga \ data1/textures/arena10/skyscraper1_nm.tga \ data1/textures/arena10/skyscraper1.tga \ data1/textures/arena10/skyscraper2_nm.tga \ data1/textures/arena10/skyscraper2.tga \ data1/textures/arena10/skyscraper3_nm.tga \ data1/textures/arena10/skyscraper3.tga \ data1/textures/arena10/skyscraper4_nm.tga \ data1/textures/arena10/skyscraper4.tga \ data1/textures/arena10/skyscraper5_nm.tga \ data1/textures/arena10/skyscraper5.tga \ data1/textures/arena10/skyscraper6_hm.tga \ data1/textures/arena10/skyscraper6_nm.tga \ data1/textures/arena10/skyscraper6.tga \ data1/textures/arena10/skyscraper7_nm.tga \ data1/textures/arena10/skyscraper7.tga \ data1/textures/arena10/skyscraper8_hm.tga \ data1/textures/arena10/skyscraper8_nm.tga \ data1/textures/arena10/skyscraper8.tga \ data1/textures/arena10/skyscraper9_hm.tga \ data1/textures/arena10/skyscraper9_nm.tga \ data1/textures/arena10/skyscraper9.tga \ data1/textures/arena10/stacks1.tga \ data1/textures/arena10/stacks2.tga \ data1/textures/arena10/starsign_hm.tga \ data1/textures/arena10/starsign_nm.tga \ data1/textures/arena10/starsign.tga \ data1/textures/arena10/stonewall1_nm.tga \ data1/textures/arena10/stonewall1.tga \ data1/textures/arena10/stonewall2_hm.tga \ data1/textures/arena10/stonewall2_nm.tga \ data1/textures/arena10/stonewall2.tga \ data1/textures/arena10/stonewall3_nm.tga \ data1/textures/arena10/stonewall3.tga \ data1/textures/arena10/storefront_nm.tga \ data1/textures/arena10/storefront.tga \ data1/textures/arena10/trash1_nm.tga \ data1/textures/arena10/trash1.tga \ data1/textures/arena10/trash2_nm.tga \ data1/textures/arena10/trash2.tga \ data1/textures/arena10/vine1_nm.tga \ data1/textures/arena10/vine1.tga \ data1/textures/arena10/vinewall1_hm.tga \ data1/textures/arena10/vinewall1_nm.tga \ data1/textures/arena10/vinewall1.tga \ data1/textures/arena10/wires1_nm.tga \ data1/textures/arena10/wires1.tga \ data1/textures/arena10/wires2_nm.tga \ data1/textures/arena10/wires2.tga \ data1/textures/arena1/jpad1a.tga \ data1/textures/arena1/jpad1a.wal \ data1/textures/arena1/jpad1b.tga \ data1/textures/arena1/jpad1b.wal \ data1/textures/arena1/jpad1c.tga \ data1/textures/arena1/jpad1c.wal \ data1/textures/arena1/jpad1d.tga \ data1/textures/arena1/jpad1d.wal \ data1/textures/arena1/jpad1e.tga \ data1/textures/arena1/jpad1e.wal \ data1/textures/arena1/metalbrick1.tga \ data1/textures/arena1/metalbrick2.tga \ data1/textures/arena1/metalbrick3a.tga \ data1/textures/arena1/metalbrick3b.tga \ data1/textures/arena1/metalbrick3c.tga \ data1/textures/arena1/metalbrick3d.tga \ data1/textures/arena1/metalbrick4a.tga \ data1/textures/arena1/metalbrick4b.tga \ data1/textures/arena1/metalbrick4c.tga \ data1/textures/arena1/metalbrick4d.tga \ data1/textures/arena1/metalbrick5.tga \ data1/textures/arena1/o3arch1.tga \ data1/textures/arena1/o3bricks12.tga \ data1/textures/arena1/o3bricks21.tga \ data1/textures/arena1/o3bricks22.tga \ data1/textures/arena1/o3bricks23.tga \ data1/textures/arena1/o3bricks2.tga \ data1/textures/arena1/o3bricks3.tga \ data1/textures/arena1/o3bricks6.tga \ data1/textures/arena1/o3bricks.tga \ data1/textures/arena1/o3ice1.tga \ data1/textures/arena1/o3ice2.tga \ data1/textures/arena1/o3ice3.tga \ data1/textures/arena1/o3ice4.tga \ data1/textures/arena1/o3rocks1.tga \ data1/textures/arena2/grid2.tga \ data1/textures/arena2/grid3.tga \ data1/textures/arena2/grida.tga \ data1/textures/arena2/gridb.tga \ data1/textures/arena2/gridc.tga \ data1/textures/arena2/gridd.tga \ data1/textures/arena2/gride.tga \ data1/textures/arena2/lava_nm.tga \ data1/textures/arena2/lava.tga \ data1/textures/arena2/lava_small.tga \ data1/textures/arena2/metal1.tga \ data1/textures/arena2/metal2.tga \ data1/textures/arena2/metal3.tga \ data1/textures/arena2/metal4.tga \ data1/textures/arena2/metal5.tga \ data1/textures/arena2/metal6.tga \ data1/textures/arena3/acceleratora.tga \ data1/textures/arena3/acceleratora.wal \ data1/textures/arena3/acceleratorb.tga \ data1/textures/arena3/acceleratorb.wal \ data1/textures/arena3/acceleratorc.tga \ data1/textures/arena3/acceleratorc.wal \ data1/textures/arena3/acceleratord.tga \ data1/textures/arena3/acceleratord.wal \ data1/textures/arena3/acceleratore.tga \ data1/textures/arena3/acceleratore.wal \ data1/textures/arena3/acceleratorf.tga \ data1/textures/arena3/acceleratorf.wal \ data1/textures/arena3/acceleratorg.tga \ data1/textures/arena3/acceleratorg.wal \ data1/textures/arena3/ceiling1.tga \ data1/textures/arena3/ceiling2.tga \ data1/textures/arena3/door1.tga \ data1/textures/arena3/floor1.tga \ data1/textures/arena3/floor2_nm.tga \ data1/textures/arena3/floor2.tga \ data1/textures/arena3/floor3.tga \ data1/textures/arena3/floor4.tga \ data1/textures/arena3/light1.tga \ data1/textures/arena3/light2.tga \ data1/textures/arena3/orba.tga \ data1/textures/arena3/orba.wal \ data1/textures/arena3/orbb.tga \ data1/textures/arena3/orbb.wal \ data1/textures/arena3/orbc.tga \ data1/textures/arena3/orbc.wal \ data1/textures/arena3/orbd.tga \ data1/textures/arena3/orbd.wal \ data1/textures/arena3/orbe.tga \ data1/textures/arena3/orbe.wal \ data1/textures/arena3/orbf.tga \ data1/textures/arena3/orbf.wal \ data1/textures/arena3/orbg.tga \ data1/textures/arena3/orbg.wal \ data1/textures/arena3/orbh.tga \ data1/textures/arena3/orbh.wal \ data1/textures/arena3/trim1.tga \ data1/textures/arena3/trim2.tga \ data1/textures/arena3/trimlite1.tga \ data1/textures/arena3/trimlite2.tga \ data1/textures/arena3/wall1.tga \ data1/textures/arena3/wall2.tga \ data1/textures/arena3/wall3.tga \ data1/textures/arena3/wall4.tga \ data1/textures/arena3/wall5.tga \ data1/textures/arena3/water_nm.tga \ data1/textures/arena3/water.tga \ data1/textures/arena4/bricks1_nm.tga \ data1/textures/arena4/bricks1.tga \ data1/textures/arena4/comp1_nm.tga \ data1/textures/arena4/comp1.tga \ data1/textures/arena4/floor1.cpt \ data1/textures/arena4/floor1_nm.tga \ data1/textures/arena4/floor1.tga \ data1/textures/arena4/floor2.tga \ data1/textures/arena4/floor3_nm.tga \ data1/textures/arena4/floor3.tga \ data1/textures/arena4/light1.tga \ data1/textures/arena4/light2.tga \ data1/textures/arena4/light3.tga \ data1/textures/arena4/support1_nm.tga \ data1/textures/arena4/support1.tga \ data1/textures/arena4/support2.tga \ data1/textures/arena4/wall1_nm.tga \ data1/textures/arena4/wall1.tga \ data1/textures/arena4/wall2_nm.tga \ data1/textures/arena4/wall2.tga \ data1/textures/arena5/bast1_nm.tga \ data1/textures/arena5/bast1.tga \ data1/textures/arena5/bast2.tga \ data1/textures/arena5/bricks4_1_nm.tga \ data1/textures/arena5/bricks4_1.tga \ data1/textures/arena5/cave_nm.tga \ data1/textures/arena5/cave.tga \ data1/textures/arena5/chain.tga \ data1/textures/arena5/cobweb.tga \ data1/textures/arena5/egypt1.tga \ data1/textures/arena5/egypt2.tga \ data1/textures/arena5/egypt3.tga \ data1/textures/arena5/egypt4.tga \ data1/textures/arena5/egypt5.tga \ data1/textures/arena5/egypt6_nm.tga \ data1/textures/arena5/egypt6.tga \ data1/textures/arena5/egypt7.tga \ data1/textures/arena5/fod.tga \ data1/textures/arena5/ground1_nm.tga \ data1/textures/arena5/ground1.tga \ data1/textures/arena5/light1.tga \ data1/textures/arena5/light2.tga \ data1/textures/arena5/lighta.tga \ data1/textures/arena5/lighta.wal \ data1/textures/arena5/lightb.tga \ data1/textures/arena5/lightb.wal \ data1/textures/arena5/lightc.tga \ data1/textures/arena5/lightc.wal \ data1/textures/arena5/lightd.tga \ data1/textures/arena5/lightd.wal \ data1/textures/arena5/lighte.tga \ data1/textures/arena5/lighte.wal \ data1/textures/arena5/lightf.tga \ data1/textures/arena5/lightf.wal \ data1/textures/arena5/o3cath11.tga \ data1/textures/arena5/o3cath3.tga \ data1/textures/arena5/o3cath5.tga \ data1/textures/arena5/o3cath8.tga \ data1/textures/arena5/o3rock5_nm.tga \ data1/textures/arena5/o3rock5.tga \ data1/textures/arena5/o3win12.tga \ data1/textures/arena5/rock2_nm.tga \ data1/textures/arena5/rock2.tga \ data1/textures/arena5/rock_3b_nm.tga \ data1/textures/arena5/rock_3b.tga \ data1/textures/arena5/sekhmet3.tga \ data1/textures/arena5/trim_nm.tga \ data1/textures/arena5/trim_sm.tga \ data1/textures/arena5/trim.tga \ data1/textures/arena6/alienarena2.tga \ data1/textures/arena6/alienarena.tga \ data1/textures/arena6/blacktrans.tga \ data1/textures/arena6/bricks1_hm.tga \ data1/textures/arena6/bricks1_nm.tga \ data1/textures/arena6/bricks1_sm.tga \ data1/textures/arena6/bricks1.tga \ data1/textures/arena6/city20.tga \ data1/textures/arena6/ctfwinblue.tga \ data1/textures/arena6/ctfwinred.tga \ data1/textures/arena6/flamejet.tga \ data1/textures/arena6/flare.tga \ data1/textures/arena6/fodblue.tga \ data1/textures/arena6/girder1.tga \ data1/textures/arena6/girder2.tga \ data1/textures/arena6/icerock2_nm.tga \ data1/textures/arena6/icerock2.tga \ data1/textures/arena6/icerock_nm.tga \ data1/textures/arena6/icerock.tga \ data1/textures/arena6/ice.tga \ data1/textures/arena6/plate1_nm.tga \ data1/textures/arena6/plate1_hm.tga \ data1/textures/arena6/plate1.tga \ data1/textures/arena6/plate2_nm.tga \ data1/textures/arena6/plate2_hm.tga \ data1/textures/arena6/plate2.tga \ data1/textures/arena6/plate3_nm.tga \ data1/textures/arena6/plate3_hm.tga \ data1/textures/arena6/plate3.tga \ data1/textures/arena6/plate4_nm.tga \ data1/textures/arena6/plate4_hm.tga \ data1/textures/arena6/plate4.tga \ data1/textures/arena6/plate5_nm.tga \ data1/textures/arena6/plate5_hm.tga \ data1/textures/arena6/plate5_sm.tga \ data1/textures/arena6/plate5.tga \ data1/textures/arena6/rimlight2.tga \ data1/textures/arena6/rimlight.tga \ data1/textures/arena6/rings.tga \ data1/textures/arena6/skullite_hm.tga \ data1/textures/arena6/skullite_nm.tga \ data1/textures/arena6/skullite.tga \ data1/textures/arena6/skull_nm.tga \ data1/textures/arena6/skull.tga \ data1/textures/arena6/snow_nm.tga \ data1/textures/arena6/snow.tga \ data1/textures/arena6/tech1_hm.tga \ data1/textures/arena6/tech1_nm.tga \ data1/textures/arena6/tech1.tga \ data1/textures/arena6/wires1_hm.tga \ data1/textures/arena6/wires1_nm.tga \ data1/textures/arena6/wires1.tga \ data1/textures/arena7/bluefloro_hm.tga \ data1/textures/arena7/bluefloro_nm.tga \ data1/textures/arena7/bluefloro.tga \ data1/textures/arena7/bluegrid.tga \ data1/textures/arena7/ceiling1.tga \ data1/textures/arena7/floor1_hm.tga \ data1/textures/arena7/floor1_nm.tga \ data1/textures/arena7/floor1.tga \ data1/textures/arena7/floor2_hm.tga \ data1/textures/arena7/floor2_nm.tga \ data1/textures/arena7/floor2.tga \ data1/textures/arena7/glass.tga \ data1/textures/arena7/grate1.tga \ data1/textures/arena7/light10.tga \ data1/textures/arena7/light11.tga \ data1/textures/arena7/light12.tga \ data1/textures/arena7/light13.tga \ data1/textures/arena7/light14.tga \ data1/textures/arena7/light1r.tga \ data1/textures/arena7/light1.tga \ data1/textures/arena7/light2.tga \ data1/textures/arena7/light3.tga \ data1/textures/arena7/light4.tga \ data1/textures/arena7/light5.tga \ data1/textures/arena7/light6.tga \ data1/textures/arena7/light7.tga \ data1/textures/arena7/light8.tga \ data1/textures/arena7/light9.tga \ data1/textures/arena7/lightgid2.tga \ data1/textures/arena7/lightgid.tga \ data1/textures/arena7/metal1.tga \ data1/textures/arena7/metal2_nm.tga \ data1/textures/arena7/metal2.tga \ data1/textures/arena7/metal3.tga \ data1/textures/arena7/piston1.tga \ data1/textures/arena7/redfloro_hm.tga \ data1/textures/arena7/redfloro_nm.tga \ data1/textures/arena7/redfloro.tga \ data1/textures/arena7/redgrid.tga \ data1/textures/arena7/tekfloor1_nm.tga \ data1/textures/arena7/tekfloor1.tga \ data1/textures/arena7/tekwall1_nm.tga \ data1/textures/arena7/tekwall1.tga \ data1/textures/arena7/tekwall2_nm.tga \ data1/textures/arena7/tekwall2.tga \ data1/textures/arena7/tekwall3_hm.tga \ data1/textures/arena7/tekwall3_nm.tga \ data1/textures/arena7/tekwall3r_hm.tga \ data1/textures/arena7/tekwall3r_nm.tga \ data1/textures/arena7/tekwall3r.tga \ data1/textures/arena7/tekwall3.tga \ data1/textures/arena7/tekwall4_nm.tga \ data1/textures/arena7/tekwall4r_nm.tga \ data1/textures/arena7/tekwall4r.tga \ data1/textures/arena7/tekwall4.tga \ data1/textures/arena7/tekwall5_nm.tga \ data1/textures/arena7/tekwall5.tga \ data1/textures/arena7/tekwall6_nm.tga \ data1/textures/arena7/tekwall6.tga \ data1/textures/arena7/tekwall7_nm.tga \ data1/textures/arena7/tekwall7.tga \ data1/textures/arena7/tekwall8_nm.tga \ data1/textures/arena7/tekwall8.tga \ data1/textures/arena7/tekwall9_hm.tga \ data1/textures/arena7/tekwall9_nm.tga \ data1/textures/arena7/tekwall9.tga \ data1/textures/arena7/warning.tga \ data1/textures/arena8/bark1_hm.tga \ data1/textures/arena8/bark1_nm.tga \ data1/textures/arena8/bark1.tga \ data1/textures/arena8/barnroof_nm.tga \ data1/textures/arena8/barnroof.tga \ data1/textures/arena8/barnwindows.tga \ data1/textures/arena8/barnwood2_nm.TGA \ data1/textures/arena8/barnwood2.tga \ data1/textures/arena8/barnwood_nm.tga \ data1/textures/arena8/barnwood.tga \ data1/textures/arena8/blackbrick1_nm.tga \ data1/textures/arena8/blackbrick1.tga \ data1/textures/arena8/blackbrick2_hm.tga \ data1/textures/arena8/blackbrick2_nm.tga \ data1/textures/arena8/blackbrick2.tga \ data1/textures/arena8/blackbrick3.tga \ data1/textures/arena8/brickwall1_hm.tga \ data1/textures/arena8/brickwall1_nm.tga \ data1/textures/arena8/brickwall1.tga \ data1/textures/arena8/cinderblocks_hm.tga \ data1/textures/arena8/cinderblocks_nm.tga \ data1/textures/arena8/cinderblocks.tga \ data1/textures/arena8/crackedrock1_hm.tga \ data1/textures/arena8/crackedrock1_nm.tga \ data1/textures/arena8/crackedrock1.tga \ data1/textures/arena8/crackedrock2_hm.tga \ data1/textures/arena8/crackedrock2_nm.tga \ data1/textures/arena8/crackedrock2.tga \ data1/textures/arena8/crackedrock3_hm.tga \ data1/textures/arena8/crackedrock3_nm.tga \ data1/textures/arena8/crackedrock3.tga \ data1/textures/arena8/crackedrock4_hm.tga \ data1/textures/arena8/crackedrock4_nm.tga \ data1/textures/arena8/crackedrock4.tga \ data1/textures/arena8/egyptbrick1_hm.tga \ data1/textures/arena8/egyptbrick1_nm.tga \ data1/textures/arena8/egyptbrick1.tga \ data1/textures/arena8/egyptfloor1_nm.tga \ data1/textures/arena8/egyptfloor1.tga \ data1/textures/arena8/egyptrock1_hm.tga \ data1/textures/arena8/egyptrock1_nm.tga \ data1/textures/arena8/egyptrock1.tga \ data1/textures/arena8/egyptrock2_nm.tga \ data1/textures/arena8/egyptrock2.tga \ data1/textures/arena8/fern.tga \ data1/textures/arena8/floor3_hm.tga \ data1/textures/arena8/floor3_nm.tga \ data1/textures/arena8/floor3.tga \ data1/textures/arena8/floor4_hm.tga \ data1/textures/arena8/floor4_nm.tga \ data1/textures/arena8/floor4.tga \ data1/textures/arena8/grass2_nm.tga \ data1/textures/arena8/grass2.tga \ data1/textures/arena8/grate1.tga \ data1/textures/arena8/ice.tga \ data1/textures/arena8/lavalmetal_nm.tga \ data1/textures/arena8/lavalmetal.tga \ data1/textures/arena8/leaves1.tga \ data1/textures/arena8/metal1_nm.tga \ data1/textures/arena8/metal1.tga \ data1/textures/arena8/metalroof_hm.tga \ data1/textures/arena8/metalroof_nm.tga \ data1/textures/arena8/metalroof.tga \ data1/textures/arena8/metaltrim1_hm.tga \ data1/textures/arena8/metaltrim1_nm.tga \ data1/textures/arena8/metaltrim1.tga \ data1/textures/arena8/metaltrim2_hm.tga \ data1/textures/arena8/metaltrim2_nm.tga \ data1/textures/arena8/metaltrim2.tga \ data1/textures/arena8/rock1_nm.tga \ data1/textures/arena8/rock1.tga \ data1/textures/arena8/roughwood_nm.tga \ data1/textures/arena8/roughwood.tga \ data1/textures/arena8/sand1.tga \ data1/textures/arena8/sand2.tga \ data1/textures/arena8/slime_nm.tga \ data1/textures/arena8/slime.tga \ data1/textures/arena8/snow_hm.tga \ data1/textures/arena8/snow_nm.tga \ data1/textures/arena8/snow.tga \ data1/textures/arena8/stonefloor1_hm.tga \ data1/textures/arena8/stonefloor1_nm.tga \ data1/textures/arena8/stonefloor1.tga \ data1/textures/arena8/wood1_hm.tga \ data1/textures/arena8/wood1_nm.tga \ data1/textures/arena8/wood1.tga \ data1/textures/arena9/beam_metal_nm.tga \ data1/textures/arena9/beam_metal.tga \ data1/textures/arena9/biggrate1_hm.tga \ data1/textures/arena9/biggrate1_nm.tga \ data1/textures/arena9/biggrate1.tga \ data1/textures/arena9/blueglass.tga \ data1/textures/arena9/boxmetal_hm.tga \ data1/textures/arena9/boxmetal_nm.tga \ data1/textures/arena9/boxmetal.tga \ data1/textures/arena9/brokencement1_nm.tga \ data1/textures/arena9/brokencement1.tga \ data1/textures/arena9/cable1.tga \ data1/textures/arena9/cable2.tga \ data1/textures/arena9/cable3.tga \ data1/textures/arena9/cable4.tga \ data1/textures/arena9/cementwall1_hm.tga \ data1/textures/arena9/cementwall1_nm.tga \ data1/textures/arena9/cementwall1.tga \ data1/textures/arena9/chainlinkfence.tga \ data1/textures/arena9/circuitwall1_hm.jpg \ data1/textures/arena9/circuitwall1_nm.jpg \ data1/textures/arena9/circuitwall1_nm.tga \ data1/textures/arena9/circuitwall1.tga \ data1/textures/arena9/comppanel2.tga \ data1/textures/arena9/comppanel.tga \ data1/textures/arena9/dmpltfloor1_hm.tga \ data1/textures/arena9/dmpltfloor1_nm.tga \ data1/textures/arena9/dmpltfloor1.tga \ data1/textures/arena9/factorybricks1_hm.tga \ data1/textures/arena9/factorybricks1_nm.tga \ data1/textures/arena9/factorybricks1.tga \ data1/textures/arena9/floor1_hm.tga \ data1/textures/arena9/floor1_nm.tga \ data1/textures/arena9/floor1.tga \ data1/textures/arena9/floor2_hm.tga \ data1/textures/arena9/floor2_nm.tga \ data1/textures/arena9/floor2.tga \ data1/textures/arena9/floor3_hm.tga \ data1/textures/arena9/floor3_nm.tga \ data1/textures/arena9/floor3.tga \ data1/textures/arena9/grate1_nm.tga \ data1/textures/arena9/grate1.tga \ data1/textures/arena9/grate2.tga \ data1/textures/arena9/grate3.tga \ data1/textures/arena9/greenfloor_nm.tga \ data1/textures/arena9/greenfloor.tga \ data1/textures/arena9/greenglass.tga \ data1/textures/arena9/greenmetal_nm.tga \ data1/textures/arena9/greenmetal.tga \ data1/textures/arena9/greenwall1_nm.tga \ data1/textures/arena9/greenwall1.tga \ data1/textures/arena9/greenwall2_hm.tga \ data1/textures/arena9/greenwall2_nm.tga \ data1/textures/arena9/greenwall2.tga \ data1/textures/arena9/greenwall3_nm.tga \ data1/textures/arena9/greenwall3.tga \ data1/textures/arena9/greenwall4_nm.tga \ data1/textures/arena9/greenwall4.tga \ data1/textures/arena9/greenwall5_hm.jpg \ data1/textures/arena9/greenwall5_nm.tga \ data1/textures/arena9/greenwall5.tga \ data1/textures/arena9/greenwall6_nm.tga \ data1/textures/arena9/greenwall6.tga \ data1/textures/arena9/hexfloor1_hm.tga \ data1/textures/arena9/hexfloor1_nm.tga \ data1/textures/arena9/hexfloor1.tga \ data1/textures/arena9/hexfloor2_hm.tga \ data1/textures/arena9/hexfloor2_nm.tga \ data1/textures/arena9/hexfloor2.tga \ data1/textures/arena9/hexfloor3_hm.tga \ data1/textures/arena9/hexfloor3_nm.tga \ data1/textures/arena9/hexfloor3.tga \ data1/textures/arena9/hexglass.tga \ data1/textures/arena9/hexgratefloor_hm.tga \ data1/textures/arena9/hexgratefloor_nm.tga \ data1/textures/arena9/hexgratefloor.tga \ data1/textures/arena9/icefloor1_nm.tga \ data1/textures/arena9/icefloor1.tga \ data1/textures/arena9/icemetal1_hm.tga \ data1/textures/arena9/icemetal1_nm.tga \ data1/textures/arena9/icemetal1.tga \ data1/textures/arena9/icemetal2_hm.tga \ data1/textures/arena9/icemetal2_nm.tga \ data1/textures/arena9/icemetal2.tga \ data1/textures/arena9/iceplate_hm.tga \ data1/textures/arena9/iceplate_nm.tga \ data1/textures/arena9/iceplate.tga \ data1/textures/arena9/icetrim1_hm.tga \ data1/textures/arena9/icetrim1_nm.tga \ data1/textures/arena9/icetrim1.tga \ data1/textures/arena9/icetrim2_hm.tga \ data1/textures/arena9/icetrim2_nm.tga \ data1/textures/arena9/icetrim2.tga \ data1/textures/arena9/icewall1_hm.tga \ data1/textures/arena9/icewall1_nm.tga \ data1/textures/arena9/icewall1.tga \ data1/textures/arena9/icicles.tga \ data1/textures/arena9/lightwall2_hm.tga \ data1/textures/arena9/lightwall2_nm.tga \ data1/textures/arena9/lightwall2.tga \ data1/textures/arena9/lightwhite.tga \ data1/textures/arena9/metal1_nm.tga \ data1/textures/arena9/metal1.tga \ data1/textures/arena9/metal2_nm.tga \ data1/textures/arena9/metal2.tga \ data1/textures/arena9/metal3_nm.tga \ data1/textures/arena9/metal3.tga \ data1/textures/arena9/metal4_nm.tga \ data1/textures/arena9/metal4.tga \ data1/textures/arena9/metal5_nm.tga \ data1/textures/arena9/metal5.tga \ data1/textures/arena9/metal6_nm.tga \ data1/textures/arena9/metal6.tga \ data1/textures/arena9/metalfloor1_hm.tga \ data1/textures/arena9/metalfloor1_nm.tga \ data1/textures/arena9/metalfloor1.tga \ data1/textures/arena9/metalgrate1.tga \ data1/textures/arena9/metalhole.tga \ data1/textures/arena9/metalplate1_nm.tga \ data1/textures/arena9/metalplate1.tga \ data1/textures/arena9/metalscale_hm.tga \ data1/textures/arena9/metalscale_nm.tga \ data1/textures/arena9/metalscale.tga \ data1/textures/arena9/metaltilefloor1_hm.tga \ data1/textures/arena9/metaltilefloor1_nm.tga \ data1/textures/arena9/metaltilefloor1.tga \ data1/textures/arena9/metaltrim1_hm.tga \ data1/textures/arena9/metaltrim1_nm.tga \ data1/textures/arena9/metaltrim1.tga \ data1/textures/arena9/metalwall1_hm.tga \ data1/textures/arena9/metalwall1_nm.tga \ data1/textures/arena9/metalwall1.tga \ data1/textures/arena9/metalwall2_hm.tga \ data1/textures/arena9/metalwall2_nm.tga \ data1/textures/arena9/metalwall2.tga \ data1/textures/arena9/metalwall3_hm.tga \ data1/textures/arena9/metalwall3_nm.tga \ data1/textures/arena9/metalwall3.tga \ data1/textures/arena9/metalwall4_hm.tga \ data1/textures/arena9/metalwall4_nm.tga \ data1/textures/arena9/metalwall4.tga \ data1/textures/arena9/metalwall5_hm.tga \ data1/textures/arena9/metalwall5_nm.tga \ data1/textures/arena9/metalwall5.tga \ data1/textures/arena9/metalwall6_hm.tga \ data1/textures/arena9/metalwall6_nm.tga \ data1/textures/arena9/metalwall6.tga \ data1/textures/arena9/metalwall7_hm.tga \ data1/textures/arena9/metalwall7_nm.tga \ data1/textures/arena9/metalwall7.tga \ data1/textures/arena9/metalwall8_hm.tga \ data1/textures/arena9/metalwall8_nm.tga \ data1/textures/arena9/metalwall8.tga \ data1/textures/arena9/panel1_nm.tga \ data1/textures/arena9/panel1.tga \ data1/textures/arena9/panel2_nm.tga \ data1/textures/arena9/panel2.tga \ data1/textures/arena9/panel3_hm.tga \ data1/textures/arena9/panel3_nm.tga \ data1/textures/arena9/panel3.tga \ data1/textures/arena9/panel4_hm.tga \ data1/textures/arena9/panel4_nm.tga \ data1/textures/arena9/panel4.tga \ data1/textures/arena9/panel5_nm.tga \ data1/textures/arena9/panel5.tga \ data1/textures/arena9/platefloor1_hm.tga \ data1/textures/arena9/platefloor1_nm.tga \ data1/textures/arena9/platefloor1.tga \ data1/textures/arena9/platefloor2_hm.tga \ data1/textures/arena9/platefloor2_nm.tga \ data1/textures/arena9/platefloor2.tga \ data1/textures/arena9/platefloor3_hm.tga \ data1/textures/arena9/platefloor3_nm.tga \ data1/textures/arena9/platefloor3.tga \ data1/textures/arena9/platefloor4_hm.tga \ data1/textures/arena9/platefloor4_nm.tga \ data1/textures/arena9/platefloor4.tga \ data1/textures/arena9/platefloor5_hm.tga \ data1/textures/arena9/platefloor5_nm.tga \ data1/textures/arena9/platefloor5.tga \ data1/textures/arena9/platefloor6_hm.tga \ data1/textures/arena9/platefloor6_nm.tga \ data1/textures/arena9/platefloor6.tga \ data1/textures/arena9/platefloor7_hm.tga \ data1/textures/arena9/platefloor7_nm.tga \ data1/textures/arena9/platefloor7.tga \ data1/textures/arena9/platefloor8_hm.tga \ data1/textures/arena9/platefloor8_nm.tga \ data1/textures/arena9/platefloor8.tga \ data1/textures/arena9/purpleglass.tga \ data1/textures/arena9/redglass.tga \ data1/textures/arena9/redtechwall2_hm.tga \ data1/textures/arena9/redtechwall2_nm.tga \ data1/textures/arena9/redtechwall2.tga \ data1/textures/arena9/redwall1_nm.tga \ data1/textures/arena9/redwall1.tga \ data1/textures/arena9/roundlightb.tga \ data1/textures/arena9/roundlightr.tga \ data1/textures/arena9/roundlight.tga \ data1/textures/arena9/rustmetal1_nm.tga \ data1/textures/arena9/rustmetal1.tga \ data1/textures/arena9/techfloor1_hm.tga \ data1/textures/arena9/techfloor1_nm.tga \ data1/textures/arena9/techfloor1.tga \ data1/textures/arena9/techwall1_hm.tga \ data1/textures/arena9/techwall1_nm.tga \ data1/textures/arena9/techwall1.tga \ data1/textures/arena9/techwall2_hm.tga \ data1/textures/arena9/techwall2_nm.tga \ data1/textures/arena9/techwall2.tga \ data1/textures/arena9/techwall3_hm.tga \ data1/textures/arena9/techwall3_nm.tga \ data1/textures/arena9/techwall3.tga \ data1/textures/arena9/trim1_nm.tga \ data1/textures/arena9/trim1.tga \ data1/textures/arena9/trim2_nm.tga \ data1/textures/arena9/trim2.tga \ data1/textures/arena9/wall1_nm.tga \ data1/textures/arena9/wall1.tga \ data1/textures/arena9/wall2_hm.tga \ data1/textures/arena9/wall2_nm.tga \ data1/textures/arena9/wall2.tga \ data1/textures/arena9/weapongrate.tga \ data1/textures/arena9/wetbricks1_hm.tga \ data1/textures/arena9/wetbricks1_nm.tga \ data1/textures/arena9/wetbricks1.tga \ data1/textures/arena9/wires1.tga \ data1/textures/arena9/wires2.tga \ data1/textures/arena9/wires3.tga \ data1/textures/arena9/wires4.tga \ data1/textures/arena9/wires5.tga \ data1/textures/arena9/wires6.tga \ data1/textures/arena9/wires7.tga \ data1/textures/arena9/wires8.tga \ data1/textures/arena9/yellowmetal_nm.tga \ data1/textures/arena9/yellowmetal.tga \ data1/textures/arena9/yellowwall1_hm.jpg \ data1/textures/arena9/yellowwall1_nm.tga \ data1/textures/arena9/yellowwall1.tga \ data1/textures/billboards/billboard1.tga \ data1/textures/billboards/billboard2.tga \ data1/textures/billboards/billboard3.tga \ data1/textures/billboards/billboard4.tga \ data1/textures/blanks/blank1.tga \ data1/textures/blanks/blank2.tga \ data1/textures/blanks/blank3.tga \ data1/textures/blanks/blank4.tga \ data1/textures/blanks/blank5.tga \ data1/textures/blanks/blank6.tga \ data1/textures/blanks/blank7.tga \ data1/textures/blood/blood_handprint.tga \ data1/textures/blood/blood_splatter1.tga \ data1/textures/blood/blood_splatter2.tga \ data1/textures/blood/blood_splatter3.tga \ data1/textures/blood/blood_splatter4.tga \ data1/textures/common/0_clip.tga \ data1/textures/common/0_hint.tga \ data1/textures/common/0_sky1.tga \ data1/textures/common/areaportal.tga \ data1/textures/common/caulk.tga \ data1/textures/common/clip.tga \ data1/textures/common/cushion.tga \ data1/textures/common/full_clip.tga \ data1/textures/common/hint.tga \ data1/textures/common/missileclip.tga \ data1/textures/common/nodraw.tga \ data1/textures/common/nodrop.tga \ data1/textures/common/nolightmap.tga \ data1/textures/common/origin.tga \ data1/textures/common/qer_portal.tga \ data1/textures/common/slick.tga \ data1/textures/common/trigger.tga \ data1/textures/common/weapclip.tga \ data1/textures/common/white.tga \ data1/textures/cr3blankclear.wal \ data1/textures/dalek/column1.tga \ data1/textures/dalek/console1.tga \ data1/textures/dalek/floor2.tga \ data1/textures/dalek/floor3.tga \ data1/textures/dalek/floor4.tga \ data1/textures/dalek/wall1.tga \ data1/textures/dalek/wall2.tga \ data1/textures/dalek/wall3.tga \ data1/textures/dalek/wall4.tga \ data1/textures/dalek/wall5.tga \ data1/textures/dalek/wall6.tga \ data1/textures/dalek/wall7.tga \ data1/textures/evil/confllrtile2pad_nm.tga \ data1/textures/evil/confllrtile2pad.tga \ data1/textures/evil/drktek_symb_hm.tga \ data1/textures/evil/drktek_symb_nm.tga \ data1/textures/evil/drktek_symb.tga \ data1/textures/evil/e5stepside_hm.tga \ data1/textures/evil/e5stepside_nm.tga \ data1/textures/evil/e5stepside.tga \ data1/textures/evil/e6basegrate_nm.tga \ data1/textures/evil/e6basegrate.tga \ data1/textures/evil/e6drstmetal_b_hm.tga \ data1/textures/evil/e6drstmetal_b_nm.tga \ data1/textures/evil/e6drstmetal_b.tga \ data1/textures/evil/e6dtrimnd_nm.tga \ data1/textures/evil/e6dtrimnd.tga \ data1/textures/evil/e6grate_flr_hm.tga \ data1/textures/evil/e6grate_flr_nm.tga \ data1/textures/evil/e6grate_flr.tga \ data1/textures/evil/e6horzlight_green.tga \ data1/textures/evil/e6horzlight.tga \ data1/textures/evil/e6launchengine_hm.tga \ data1/textures/evil/e6launchengine_nm.tga \ data1/textures/evil/e6launchengine.tga \ data1/textures/evil/e6metalfan.tga \ data1/textures/evil/e6simpwallsupp_rst_hm.tga \ data1/textures/evil/e6simpwallsupp_rst_nm.tga \ data1/textures/evil/e6simpwallsupp_rst.tga \ data1/textures/evil/e6supptrim128_hm.tga \ data1/textures/evil/e6supptrim128_nm.tga \ data1/textures/evil/e6supptrim128.tga \ data1/textures/evil/e6trim_basic128_nm.tga \ data1/textures/evil/e6trim_basic128.tga \ data1/textures/evil/e7beam01_hm.tga \ data1/textures/evil/e7beam01_nm.tga \ data1/textures/evil/e7beam01.tga \ data1/textures/evil/e8_btrim04_hm.tga \ data1/textures/evil/e8_btrim04_nm.tga \ data1/textures/evil/e8_btrim04.tga \ data1/textures/evil/e8crete01stair1_hm.tga \ data1/textures/evil/e8crete01stair1_nm.tga \ data1/textures/evil/e8crete01stair1.tga \ data1/textures/evil/e8crete03b_hm.tga \ data1/textures/evil/e8crete03b_nm.tga \ data1/textures/evil/e8crete03b.tga \ data1/textures/evil/e8crete03_hm.tga \ data1/textures/evil/e8crete03_nm.tga \ data1/textures/evil/e8crete03.tga \ data1/textures/evil/e8_jumppad02_hm.tga \ data1/textures/evil/e8_jumppad02_nm.tga \ data1/textures/evil/e8_jumppad02.tga \ data1/textures/evil/e8_launchpad1_hm.tga \ data1/textures/evil/e8_launchpad1_nm.tga \ data1/textures/evil/e8_launchpad1.tga \ data1/textures/evil/e8_mtlwall1_hm.tga \ data1/textures/evil/e8_mtlwall1_nm.tga \ data1/textures/evil/e8_mtlwall1.tga \ data1/textures/evil/e8tinylightblue.tga \ data1/textures/evil/e8warning_hm.tga \ data1/textures/evil/e8warning_nm.tga \ data1/textures/evil/e8warning.tga \ data1/textures/evil/e8xgirder_small.tga \ data1/textures/evil/e8xgirder.tga \ data1/textures/evil/ex_cretefloor_01_hm.tga \ data1/textures/evil/ex_cretefloor_01_nm.tga \ data1/textures/evil/ex_cretefloor_01.tga \ data1/textures/evil/ex_floor_mtl_grate_01_hm.tga \ data1/textures/evil/ex_floor_mtl_grate_01_nm.tga \ data1/textures/evil/ex_floor_mtl_grate_01.tga \ data1/textures/evil/ex_floor_tile_03_hm.tga \ data1/textures/evil/ex_floor_tile_03_nm.tga \ data1/textures/evil/ex_floor_tile_03.tga \ data1/textures/evil/ex_lightpanel_01_d.tga \ data1/textures/evil/exmetal_plate01b_d_hm.tga \ data1/textures/evil/exmetal_plate01b_d_nm.tga \ data1/textures/evil/exmetal_plate01b_d.tga \ data1/textures/evil/exmetalrib01_d_hm.tga \ data1/textures/evil/exmetalrib01_d_nm.tga \ data1/textures/evil/exmetalrib01_d.tga \ data1/textures/evil/ex_metalsupp01_d_hm.tga \ data1/textures/evil/ex_metalsupp01_d_nm.tga \ data1/textures/evil/ex_metalsupp01_d.tga \ data1/textures/evil/ex_rndfloor_01_d_hm.tga \ data1/textures/evil/ex_rndfloor_01_d_nm.tga \ data1/textures/evil/ex_rndfloor_01_d.tga \ data1/textures/evil/ex_steptop_01_d_hm.tga \ data1/textures/evil/ex_steptop_01_d_nm.tga \ data1/textures/evil/ex_steptop_01_d.tga \ data1/textures/evil/ex_trim_psimple_04_d_hm.tga \ data1/textures/evil/ex_trim_psimple_04_d_nm.tga \ data1/textures/evil/ex_trim_psimple_04_d.tga \ data1/textures/evil/ex_trim_psimple_05_d_hm.tga \ data1/textures/evil/ex_trim_psimple_05_d_nm.tga \ data1/textures/evil/ex_trim_psimple_05_d.tga \ data1/textures/evil/ex_trim_support_03_d_hm.tga \ data1/textures/evil/ex_trim_support_03_d_nm.tga \ data1/textures/evil/ex_trim_support_03_d.tga \ data1/textures/evil/ex_wall_01b_d_hm.tga \ data1/textures/evil/ex_wall_01b_d_nm.tga \ data1/textures/evil/ex_wall_01b_d.tga \ data1/textures/evil/ex_wall_panel_05_d_hm.tga \ data1/textures/evil/ex_wall_panel_05_d_nm.tga \ data1/textures/evil/ex_wall_panel_05_d.tga \ data1/textures/evil/ex_wall_pipe_d_hm.tga \ data1/textures/evil/ex_wall_pipe_d_nm.tga \ data1/textures/evil/ex_wall_pipe_d.tga \ data1/textures/evil/stepside_mtl2_hm.tga \ data1/textures/evil/stepside_mtl2_nm.tga \ data1/textures/evil/stepside_mtl2.tga \ data1/textures/evil/stepside_mtl3_hm.tga \ data1/textures/evil/stepside_mtl3_nm.tga \ data1/textures/evil/stepside_mtl3.tga \ data1/textures/evil/stepside_mtl4light_hm.tga \ data1/textures/evil/stepside_mtl4light_nm.tga \ data1/textures/evil/stepside_mtl4light.tga \ data1/textures/evil/stepside_mtl5_nm.tga \ data1/textures/evil/stepside_mtl5.tga \ data1/textures/evil/stepside_mtl_nm.tga \ data1/textures/evil/stepside_mtl.tga \ data1/textures/evil/steptop_mtl2_hm.tga \ data1/textures/evil/steptop_mtl2_nm.tga \ data1/textures/evil/steptop_mtl2.tga \ data1/textures/evil/steptop_mtl3_hm.tga \ data1/textures/evil/steptop_mtl3_nm.tga \ data1/textures/evil/steptop_mtl3.tga \ data1/textures/evil/techallmix_hm.tga \ data1/textures/evil/techallmix_nm.tga \ data1/textures/evil/techallmix.tga \ data1/textures/evil/trim_drkmtl_nm.tga \ data1/textures/evil/trim_drkmtl.tga \ data1/textures/evil/trimrstmtlpipes_nm.tga \ data1/textures/evil/trimrstmtlpipes.tga \ data1/textures/evil/trstmtl_panelbig_hm.tga \ data1/textures/evil/trstmtl_panelbig_nm.tga \ data1/textures/evil/trstmtl_panelbig.tga \ data1/textures/forsaken/glass.tga \ data1/textures/martian/biometal1_hm.tga \ data1/textures/martian/biometal1_nm.tga \ data1/textures/martian/biometal1.tga \ data1/textures/martian/chains.tga \ data1/textures/martian/coiledwire.tga \ data1/textures/martian/console1.tga \ data1/textures/martian/console2.tga \ data1/textures/martian/console3.tga \ data1/textures/martian/console4.tga \ data1/textures/martian/floor1.tga \ data1/textures/martian/floor2.tga \ data1/textures/martian/glass1.tga \ data1/textures/martian/grass.tga \ data1/textures/martian/grass_tga.tga \ data1/textures/martian/light1.tga \ data1/textures/martian/light2.tga \ data1/textures/martian/light3.tga \ data1/textures/martian/light4.tga \ data1/textures/martian/light5.tga \ data1/textures/martian/light6.tga \ data1/textures/martian/metal1.tga \ data1/textures/martian/metal2.tga \ data1/textures/martian/metal3.tga \ data1/textures/martian/metal4.tga \ data1/textures/martian/metal5.tga \ data1/textures/martian/metalrings1.tga \ data1/textures/martian/metalrings2.tga \ data1/textures/martian/ribtubeswirl_hm.jpg \ data1/textures/martian/ribtubeswirl_nm.jpg \ data1/textures/martian/ribtubeswirl.tga \ data1/textures/martian/saucerwall1_nm.tga \ data1/textures/martian/saucerwall1.tga \ data1/textures/martian/shiphull2_hm.tga \ data1/textures/martian/shiphull2_nm.tga \ data1/textures/martian/shiphull2.tga \ data1/textures/martian/shiphull_hm.tga \ data1/textures/martian/shiphull_nm.tga \ data1/textures/martian/shiphull.tga \ data1/textures/martian/skytrees.tga \ data1/textures/martian/skytrees_tga.tga \ data1/textures/martian/tree2_tga.tga \ data1/textures/martian/tree_bottom.tga \ data1/textures/martian/tree_bottom_tga.tga \ data1/textures/martian/tree_tga.tga \ data1/textures/martian/tree_top.tga \ data1/textures/martian/tree_top_tga.tga \ data1/textures/metal/bigconduit.tga \ data1/textures/metal/ceiling1.tga \ data1/textures/metal/door1.tga \ data1/textures/metal/doorjam.tga \ data1/textures/metal/fade1.tga \ data1/textures/metal/fade2.tga \ data1/textures/metal/floor.tga \ data1/textures/metal/light1_s.tga \ data1/textures/metal/light1.tga \ data1/textures/metal/light2_s.tga \ data1/textures/metal/light2.tga \ data1/textures/metal/light3_s.tga \ data1/textures/metal/light3.tga \ data1/textures/metal/light4.tga \ data1/textures/metal/light5_s.tga \ data1/textures/metal/light5.tga \ data1/textures/metal/medconduit.tga \ data1/textures/metal/metal1.tga \ data1/textures/metal/metal2.tga \ data1/textures/metal/metal3.tga \ data1/textures/metal/metal4.tga \ data1/textures/metal/metal5.tga \ data1/textures/metal/openfloor2.tga \ data1/textures/metal/openfloor.tga \ data1/textures/metal/plat.tga \ data1/textures/metal/saucer1.tga \ data1/textures/metal/saucer2.tga \ data1/textures/metal/silo.tga \ data1/textures/metal/smallconduit.tga \ data1/textures/metal/trim1.tga \ data1/textures/metal/trim2.tga \ data1/textures/metal/wall1_nm.tga \ data1/textures/metal/wall1_sm.tga \ data1/textures/metal/wall1.tga \ data1/textures/metal/wall2_nm.tga \ data1/textures/metal/wall2_sm.tga \ data1/textures/metal/wall2.tga \ data1/textures/metal/wall3.tga \ data1/textures/metal/wall4.tga \ data1/textures/metal/wall5.tga \ data1/textures/metal/wall6.tga \ data1/textures/metal/walllite.tga \ data1/textures/null.tga \ data1/textures/phillipk/pk01_panel01a_hm.tga \ data1/textures/phillipk/pk01_panel01a.tga \ data1/textures/phillipk/pk01_panel01b_hm.tga \ data1/textures/phillipk/pk01_panel01b.tga \ data1/textures/phillipk/pk01_panel03a_hm.tga \ data1/textures/phillipk/pk01_panel03a_nm.tga \ data1/textures/phillipk/pk01_panel03a.tga \ data1/textures/phillipk/pk01_panel03b_hm.tga \ data1/textures/phillipk/pk01_panel03b_nm.tga \ data1/textures/phillipk/pk01_panel03b.tga \ data1/textures/phillipk/pk01_panel_small01_hm.tga \ data1/textures/phillipk/pk01_panel_small01_nm.tga \ data1/textures/phillipk/pk01_panel_small01.tga \ data1/textures/phillipk/pk01_pan_wall02a1_hm.tga \ data1/textures/phillipk/pk01_pan_wall02a1_nm.tga \ data1/textures/phillipk/pk01_pan_wall02a1.tga \ data1/textures/phillipk/pk01_pan_wall02b1_hm.tga \ data1/textures/phillipk/pk01_pan_wall02b1_nm.tga \ data1/textures/phillipk/pk01_pan_wall02b1.tga \ data1/textures/phillipk/pk01_thin_wall01b_hm.tga \ data1/textures/phillipk/pk01_thin_wall01b_nm.tga \ data1/textures/phillipk/pk01_thin_wall01b.tga \ data1/textures/phillipk/pk01_thin_wall02b_hm.tga \ data1/textures/phillipk/pk01_thin_wall02b_nm.tga \ data1/textures/phillipk/pk01_thin_wall02b.tga \ data1/textures/phillipk/pk01_trims01a_hm.tga \ data1/textures/phillipk/pk01_trims01a_nm.tga \ data1/textures/phillipk/pk01_trims01a.tga \ data1/textures/phillipk/pk01_trims01b_hm.tga \ data1/textures/phillipk/pk01_trims01b_nm.tga \ data1/textures/phillipk/pk01_trims01b.tga \ data1/textures/phillipk/pk01_vent_wall01a_hm.tga \ data1/textures/phillipk/pk01_vent_wall01a.tga \ data1/textures/phillipk/pk01_vent_wall01_nm.tga \ data1/textures/phillipk/pk01_wall02a_hm.tga \ data1/textures/phillipk/pk01_wall02a_nm.tga \ data1/textures/phillipk/pk01_wall02a.tga \ data1/textures/phillipk/pk01_wall02b_hm.tga \ data1/textures/phillipk/pk01_wall02b.tga \ data1/textures/phillipk/pk01_wall02_nm.tga \ data1/textures/phillipk/pk01_wall04b_hm.tga \ data1/textures/phillipk/pk01_wall04b_nm.tga \ data1/textures/phillipk/pk01_wall04b.tga \ data1/textures/phillipk/pk02_ceiling02_fx.tga \ data1/textures/phillipk/pk02_ceiling02_nm.tga \ data1/textures/phillipk/pk02_ceiling02.tga \ data1/textures/phillipk/pk02_ceiling02r_nm.tga \ data1/textures/phillipk/pk02_ceiling02r.tga \ data1/textures/phillipk/pk02_computer01a_hm.tga \ data1/textures/phillipk/pk02_computer01a_nm.tga \ data1/textures/phillipk/pk02_computer01a.tga \ data1/textures/phillipk/pk02_floor08a_hm.tga \ data1/textures/phillipk/pk02_floor08a_nm.tga \ data1/textures/phillipk/pk02_floor08b_hm.tga \ data1/textures/phillipk/pk02_floor08b_nm.tga \ data1/textures/phillipk/pk02_floor08b.tga \ data1/textures/phillipk/pk02_floor08.tga \ data1/textures/phillipk/pk02_switches01a_nm.tga \ data1/textures/phillipk/pk02_switches01a.tga \ data1/textures/phillipk/pk02_switches01b_nm.tga \ data1/textures/phillipk/pk02_switches01b.tga \ data1/textures/phillipk/pk02_switches01c_nm.tga \ data1/textures/phillipk/pk02_switches01c.tga \ data1/textures/phillipk/pk02_wall07a_nm.tga \ data1/textures/phillipk/pk02_wall07a.tga \ data1/textures/phillipk/pk02_wall07b_nm.tga \ data1/textures/phillipk/pk02_wall07b.tga \ data1/textures/phillipk/pk02_wall_big02a_nm.tga \ data1/textures/phillipk/pk02_wall_big02a.tga \ data1/textures/phillipk/pk02_wall_big02b_nm.tga \ data1/textures/phillipk/pk02_wall_big02b.tga \ data1/textures/rage/beam_purple_hm.tga \ data1/textures/rage/beam_purple_nm.tga \ data1/textures/rage/beam_purple.tga \ data1/textures/rage/ceiling2_nm.tga \ data1/textures/rage/ceiling2.tga \ data1/textures/rage/ceiling_nm.tga \ data1/textures/rage/ceiling.tga \ data1/textures/rage/floor2.tga \ data1/textures/rage/floor5.tga \ data1/textures/rage/fod1.tga \ data1/textures/rage/grid1.tga \ data1/textures/rage/hexfloor_blue.tga \ data1/textures/rage/hexfloor_hm.tga \ data1/textures/rage/hexfloor_nm.tga \ data1/textures/rage/hexfloor_red.tga \ data1/textures/rage/hexfloor.tga \ data1/textures/rage/jpad1a.tga \ data1/textures/rage/lava.tga \ data1/textures/rage/light10.tga \ data1/textures/rage/light12.tga \ data1/textures/rage/light1.tga \ data1/textures/rage/light5.tga \ data1/textures/rage/light7.tga \ data1/textures/rage/light8.tga \ data1/textures/rage/metallight_2.tga \ data1/textures/rage/metal_panel.tga \ data1/textures/rage/rimlightpurple.tga \ data1/textures/rage/support_beam.tga \ data1/textures/rage/support_column_hm.tga \ data1/textures/rage/support_column_nm.tga \ data1/textures/rage/support_column.tga \ data1/textures/rage/support_trim.tga \ data1/textures/rage/trimlight_blue.tga \ data1/textures/rage/trimlight_purple.tga \ data1/textures/rage/trimlight_red.tga \ data1/textures/rage/wall_blue.tga \ data1/textures/ramp1b.tga \ data1/textures/ramp1b.wal \ data1/textures/ramp1c.tga \ data1/textures/ramp1c.wal \ data1/textures/ramp1d.tga \ data1/textures/ramp1d.wal \ data1/textures/ramp1e.tga \ data1/textures/ramp1e.wal \ data1/textures/ramp1f.tga \ data1/textures/ramp1f.wal \ data1/textures/ramp1.tga \ data1/textures/ramp1.wal \ data1/textures/rigel/baselightblue.tga \ data1/textures/rigel/baselightred.tga \ data1/textures/water/blood_nm.tga \ data1/textures/water/blood.tga \ data1/textures/water/bluewater_nm.tga \ data1/textures/water/bluewater.tga \ data1/textures/water/clearwater_nm.tga \ data1/textures/water/clearwater.tga \ data1/textures/water/flowingwater.tga \ data1/textures/water/waterpx.tga \ data1/textures/xempx/a3light1b.tga \ data1/textures/xempx/a6bt.tga \ data1/textures/xempx/a7light10.tga \ data1/textures/xempx/a7light1b.tga \ data1/textures/xempx/a7light1.tga \ data1/textures/xempx/a7light2.tga \ data1/textures/xempx/a7light3.tga \ data1/textures/xempx/a7light4.tga \ data1/textures/xempx/a9metal5.tga \ data1/textures/xempx/cretered_128_hm.tga \ data1/textures/xempx/cretered_128_nm.tga \ data1/textures/xempx/cretered_128.tga \ data1/textures/xempx/droplet_fx.tga \ data1/textures/xempx/e7trim_hm.tga \ data1/textures/xempx/e7trimlight_blue_hm.tga \ data1/textures/xempx/e7trimlight_blue_nm.tga \ data1/textures/xempx/e7trimlight_blue.tga \ data1/textures/xempx/e7trim_nm.tga \ data1/textures/xempx/e7trim.tga \ data1/textures/xempx/e8crete03ccred_hm.tga \ data1/textures/xempx/e8crete03ccred_nm.tga \ data1/textures/xempx/e8crete03ccred.tga \ data1/textures/xempx/emtl3-1_hm.tga \ data1/textures/xempx/emtl3-1_nm.tga \ data1/textures/xempx/emtl3-1.tga \ data1/textures/xempx/full_clip.tga \ data1/textures/xempx/ivy3_nm.tga \ data1/textures/xempx/ivy3.tga \ data1/textures/xempx/light1.tga \ data1/textures/xempx/lightbeam1.tga \ data1/textures/xempx/sign-electro_hm.tga \ data1/textures/xempx/sign-electro.tga \ data1/textures/xempx/sign_radioactive_hm.tga \ data1/textures/xempx/sign_radioactive.tga vehiclesdir = $(pkgdatadir) nobase_nodist_vehicles_DATA = \ data1/vehicles/bomber/bomb.md2 \ data1/vehicles/bomber/bomb.tga \ data1/vehicles/bomber/console_normal.tga \ data1/vehicles/bomber/console.tga \ data1/vehicles/bomber/helmet.md2 \ data1/vehicles/bomber/skin_normal.tga \ data1/vehicles/bomber/skin_fx.tga \ data1/vehicles/bomber/skin.tga \ data1/vehicles/bomber/tris.md2 \ data1/vehicles/bomber/v_wep.md2 \ data1/vehicles/bomber/window.md2 \ data1/vehicles/deathball/deathball.md2 \ data1/vehicles/deathball/deathball.tga \ data1/vehicles/deathball/deathmask.tga \ data1/vehicles/deathball/skin_fx.tga \ data1/vehicles/deathball/skin_normal.tga \ data1/vehicles/deathball/skin.tga \ data1/vehicles/deathball/v_wep.md2 \ data1/vehicles/hover/console_normal.tga \ data1/vehicles/hover/console.tga \ data1/vehicles/hover/flames.md2 \ data1/vehicles/hover/skin_fx.tga \ data1/vehicles/hover/skin.jpg \ data1/vehicles/hover/skin_normal.tga \ data1/vehicles/hover/tris.md2 \ data1/vehicles/hover/v_wep.md2 \ data1/vehicles/hover/window.md2 \ data1/vehicles/strafer/console_normal.tga \ data1/vehicles/strafer/console.tga \ data1/vehicles/strafer/skin_fx.tga \ data1/vehicles/strafer/skin_normal.tga \ data1/vehicles/strafer/skin.tga \ data1/vehicles/strafer/tris.md2 \ data1/vehicles/strafer/v_wep.md2 \ data1/vehicles/strafer/window.md2 graphical_presetsdir = $(pkgdatadir) nobase_nodist_graphical_presets_DATA = \ data1/graphical_presets/compatibility.cfg \ data1/graphical_presets/maxperformance.cfg \ data1/graphical_presets/performance.cfg \ data1/graphical_presets/quality.cfg \ data1/graphical_presets/maxquality.cfg tacticaldir = $(pkgdatadir) nobase_nodist_tactical_DATA = \ tactical/maps.lst \ tactical/motd.txt \ tactical/default.cfg \ tactical/server.cfg gamedata_files = \ $(nobase_nodist_env_DATA) \ $(nobase_nodist_fonts_DATA) \ $(nobase_nodist_gfx_DATA) \ $(nobase_nodist_levelshots_DATA) \ $(nobase_nodist_maps_DATA) \ $(nobase_nodist_models_DATA) \ $(nobase_nodist_particles_DATA) \ $(nobase_nodist_pics_DATA) \ $(nobase_nodist_players_DATA) \ $(nobase_nodist_scripts_DATA) \ $(nobase_nodist_sound_DATA) \ $(nobase_nodist_textures_DATA) \ $(nobase_nodist_vehicles_DATA) \ $(nobase_nodist_graphical_presets_DATA) \ $(nobase_nodist_tactical_DATA) all: all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/game_data.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(srcdir)/game_data.am: $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config/config.h: config/stamp-h1 @test -f $@ || rm -f config/stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) config/stamp-h1 config/stamp-h1: $(top_srcdir)/config/config.h.in $(top_builddir)/config.status @rm -f config/stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config/config.h $(top_srcdir)/config/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f config/stamp-h1 touch $@ distclean-hdr: -rm -f config/config.h config/stamp-h1 install-dist_docDATA: $(dist_doc_DATA) @$(NORMAL_INSTALL) @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ done uninstall-dist_docDATA: @$(NORMAL_UNINSTALL) @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) install-dist_iconDATA: $(dist_icon_DATA) @$(NORMAL_INSTALL) @list='$(dist_icon_DATA)'; test -n "$(icondir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(icondir)'"; \ $(MKDIR_P) "$(DESTDIR)$(icondir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(icondir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(icondir)" || exit $$?; \ done uninstall-dist_iconDATA: @$(NORMAL_UNINSTALL) @list='$(dist_icon_DATA)'; test -n "$(icondir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(icondir)'; $(am__uninstall_files_from_dir) install-nobase_dist_arenaDATA: $(nobase_dist_arena_DATA) @$(NORMAL_INSTALL) @list='$(nobase_dist_arena_DATA)'; test -n "$(arenadir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(arenadir)'"; \ $(MKDIR_P) "$(DESTDIR)$(arenadir)" || exit 1; \ fi; \ $(am__nobase_list) | while read dir files; do \ xfiles=; for file in $$files; do \ if test -f "$$file"; then xfiles="$$xfiles $$file"; \ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ test -z "$$xfiles" || { \ test "x$$dir" = x. || { \ echo " $(MKDIR_P) '$(DESTDIR)$(arenadir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(arenadir)/$$dir"; }; \ echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(arenadir)/$$dir'"; \ $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(arenadir)/$$dir" || exit $$?; }; \ done uninstall-nobase_dist_arenaDATA: @$(NORMAL_UNINSTALL) @list='$(nobase_dist_arena_DATA)'; test -n "$(arenadir)" || list=; \ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ dir='$(DESTDIR)$(arenadir)'; $(am__uninstall_files_from_dir) install-nobase_dist_botinfoDATA: $(nobase_dist_botinfo_DATA) @$(NORMAL_INSTALL) @list='$(nobase_dist_botinfo_DATA)'; test -n "$(botinfodir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(botinfodir)'"; \ $(MKDIR_P) "$(DESTDIR)$(botinfodir)" || exit 1; \ fi; \ $(am__nobase_list) | while read dir files; do \ xfiles=; for file in $$files; do \ if test -f "$$file"; then xfiles="$$xfiles $$file"; \ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ test -z "$$xfiles" || { \ test "x$$dir" = x. || { \ echo " $(MKDIR_P) '$(DESTDIR)$(botinfodir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(botinfodir)/$$dir"; }; \ echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(botinfodir)/$$dir'"; \ $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(botinfodir)/$$dir" || exit $$?; }; \ done uninstall-nobase_dist_botinfoDATA: @$(NORMAL_UNINSTALL) @list='$(nobase_dist_botinfo_DATA)'; test -n "$(botinfodir)" || list=; \ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ dir='$(DESTDIR)$(botinfodir)'; $(am__uninstall_files_from_dir) install-nobase_dist_data1DATA: $(nobase_dist_data1_DATA) @$(NORMAL_INSTALL) @list='$(nobase_dist_data1_DATA)'; test -n "$(data1dir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(data1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(data1dir)" || exit 1; \ fi; \ $(am__nobase_list) | while read dir files; do \ xfiles=; for file in $$files; do \ if test -f "$$file"; then xfiles="$$xfiles $$file"; \ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ test -z "$$xfiles" || { \ test "x$$dir" = x. || { \ echo " $(MKDIR_P) '$(DESTDIR)$(data1dir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(data1dir)/$$dir"; }; \ echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(data1dir)/$$dir'"; \ $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(data1dir)/$$dir" || exit $$?; }; \ done uninstall-nobase_dist_data1DATA: @$(NORMAL_UNINSTALL) @list='$(nobase_dist_data1_DATA)'; test -n "$(data1dir)" || list=; \ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ dir='$(DESTDIR)$(data1dir)'; $(am__uninstall_files_from_dir) install-nobase_nodist_envDATA: $(nobase_nodist_env_DATA) @$(NORMAL_INSTALL) @list='$(nobase_nodist_env_DATA)'; test -n "$(envdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(envdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(envdir)" || exit 1; \ fi; \ $(am__nobase_list) | while read dir files; do \ xfiles=; for file in $$files; do \ if test -f "$$file"; then xfiles="$$xfiles $$file"; \ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ test -z "$$xfiles" || { \ test "x$$dir" = x. || { \ echo " $(MKDIR_P) '$(DESTDIR)$(envdir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(envdir)/$$dir"; }; \ echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(envdir)/$$dir'"; \ $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(envdir)/$$dir" || exit $$?; }; \ done uninstall-nobase_nodist_envDATA: @$(NORMAL_UNINSTALL) @list='$(nobase_nodist_env_DATA)'; test -n "$(envdir)" || list=; \ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ dir='$(DESTDIR)$(envdir)'; $(am__uninstall_files_from_dir) install-nobase_nodist_fontsDATA: $(nobase_nodist_fonts_DATA) @$(NORMAL_INSTALL) @list='$(nobase_nodist_fonts_DATA)'; test -n "$(fontsdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(fontsdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(fontsdir)" || exit 1; \ fi; \ $(am__nobase_list) | while read dir files; do \ xfiles=; for file in $$files; do \ if test -f "$$file"; then xfiles="$$xfiles $$file"; \ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ test -z "$$xfiles" || { \ test "x$$dir" = x. || { \ echo " $(MKDIR_P) '$(DESTDIR)$(fontsdir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(fontsdir)/$$dir"; }; \ echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(fontsdir)/$$dir'"; \ $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(fontsdir)/$$dir" || exit $$?; }; \ done uninstall-nobase_nodist_fontsDATA: @$(NORMAL_UNINSTALL) @list='$(nobase_nodist_fonts_DATA)'; test -n "$(fontsdir)" || list=; \ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ dir='$(DESTDIR)$(fontsdir)'; $(am__uninstall_files_from_dir) install-nobase_nodist_gfxDATA: $(nobase_nodist_gfx_DATA) @$(NORMAL_INSTALL) @list='$(nobase_nodist_gfx_DATA)'; test -n "$(gfxdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(gfxdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(gfxdir)" || exit 1; \ fi; \ $(am__nobase_list) | while read dir files; do \ xfiles=; for file in $$files; do \ if test -f "$$file"; then xfiles="$$xfiles $$file"; \ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ test -z "$$xfiles" || { \ test "x$$dir" = x. || { \ echo " $(MKDIR_P) '$(DESTDIR)$(gfxdir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(gfxdir)/$$dir"; }; \ echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(gfxdir)/$$dir'"; \ $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(gfxdir)/$$dir" || exit $$?; }; \ done uninstall-nobase_nodist_gfxDATA: @$(NORMAL_UNINSTALL) @list='$(nobase_nodist_gfx_DATA)'; test -n "$(gfxdir)" || list=; \ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ dir='$(DESTDIR)$(gfxdir)'; $(am__uninstall_files_from_dir) install-nobase_nodist_graphical_presetsDATA: $(nobase_nodist_graphical_presets_DATA) @$(NORMAL_INSTALL) @list='$(nobase_nodist_graphical_presets_DATA)'; test -n "$(graphical_presetsdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(graphical_presetsdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(graphical_presetsdir)" || exit 1; \ fi; \ $(am__nobase_list) | while read dir files; do \ xfiles=; for file in $$files; do \ if test -f "$$file"; then xfiles="$$xfiles $$file"; \ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ test -z "$$xfiles" || { \ test "x$$dir" = x. || { \ echo " $(MKDIR_P) '$(DESTDIR)$(graphical_presetsdir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(graphical_presetsdir)/$$dir"; }; \ echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(graphical_presetsdir)/$$dir'"; \ $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(graphical_presetsdir)/$$dir" || exit $$?; }; \ done uninstall-nobase_nodist_graphical_presetsDATA: @$(NORMAL_UNINSTALL) @list='$(nobase_nodist_graphical_presets_DATA)'; test -n "$(graphical_presetsdir)" || list=; \ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ dir='$(DESTDIR)$(graphical_presetsdir)'; $(am__uninstall_files_from_dir) install-nobase_nodist_levelshotsDATA: $(nobase_nodist_levelshots_DATA) @$(NORMAL_INSTALL) @list='$(nobase_nodist_levelshots_DATA)'; test -n "$(levelshotsdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(levelshotsdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(levelshotsdir)" || exit 1; \ fi; \ $(am__nobase_list) | while read dir files; do \ xfiles=; for file in $$files; do \ if test -f "$$file"; then xfiles="$$xfiles $$file"; \ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ test -z "$$xfiles" || { \ test "x$$dir" = x. || { \ echo " $(MKDIR_P) '$(DESTDIR)$(levelshotsdir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(levelshotsdir)/$$dir"; }; \ echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(levelshotsdir)/$$dir'"; \ $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(levelshotsdir)/$$dir" || exit $$?; }; \ done uninstall-nobase_nodist_levelshotsDATA: @$(NORMAL_UNINSTALL) @list='$(nobase_nodist_levelshots_DATA)'; test -n "$(levelshotsdir)" || list=; \ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ dir='$(DESTDIR)$(levelshotsdir)'; $(am__uninstall_files_from_dir) install-nobase_nodist_mapsDATA: $(nobase_nodist_maps_DATA) @$(NORMAL_INSTALL) @list='$(nobase_nodist_maps_DATA)'; test -n "$(mapsdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(mapsdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(mapsdir)" || exit 1; \ fi; \ $(am__nobase_list) | while read dir files; do \ xfiles=; for file in $$files; do \ if test -f "$$file"; then xfiles="$$xfiles $$file"; \ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ test -z "$$xfiles" || { \ test "x$$dir" = x. || { \ echo " $(MKDIR_P) '$(DESTDIR)$(mapsdir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(mapsdir)/$$dir"; }; \ echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(mapsdir)/$$dir'"; \ $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(mapsdir)/$$dir" || exit $$?; }; \ done uninstall-nobase_nodist_mapsDATA: @$(NORMAL_UNINSTALL) @list='$(nobase_nodist_maps_DATA)'; test -n "$(mapsdir)" || list=; \ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ dir='$(DESTDIR)$(mapsdir)'; $(am__uninstall_files_from_dir) install-nobase_nodist_modelsDATA: $(nobase_nodist_models_DATA) @$(NORMAL_INSTALL) @list='$(nobase_nodist_models_DATA)'; test -n "$(modelsdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(modelsdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(modelsdir)" || exit 1; \ fi; \ $(am__nobase_list) | while read dir files; do \ xfiles=; for file in $$files; do \ if test -f "$$file"; then xfiles="$$xfiles $$file"; \ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ test -z "$$xfiles" || { \ test "x$$dir" = x. || { \ echo " $(MKDIR_P) '$(DESTDIR)$(modelsdir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(modelsdir)/$$dir"; }; \ echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(modelsdir)/$$dir'"; \ $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(modelsdir)/$$dir" || exit $$?; }; \ done uninstall-nobase_nodist_modelsDATA: @$(NORMAL_UNINSTALL) @list='$(nobase_nodist_models_DATA)'; test -n "$(modelsdir)" || list=; \ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ dir='$(DESTDIR)$(modelsdir)'; $(am__uninstall_files_from_dir) install-nobase_nodist_particlesDATA: $(nobase_nodist_particles_DATA) @$(NORMAL_INSTALL) @list='$(nobase_nodist_particles_DATA)'; test -n "$(particlesdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(particlesdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(particlesdir)" || exit 1; \ fi; \ $(am__nobase_list) | while read dir files; do \ xfiles=; for file in $$files; do \ if test -f "$$file"; then xfiles="$$xfiles $$file"; \ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ test -z "$$xfiles" || { \ test "x$$dir" = x. || { \ echo " $(MKDIR_P) '$(DESTDIR)$(particlesdir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(particlesdir)/$$dir"; }; \ echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(particlesdir)/$$dir'"; \ $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(particlesdir)/$$dir" || exit $$?; }; \ done uninstall-nobase_nodist_particlesDATA: @$(NORMAL_UNINSTALL) @list='$(nobase_nodist_particles_DATA)'; test -n "$(particlesdir)" || list=; \ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ dir='$(DESTDIR)$(particlesdir)'; $(am__uninstall_files_from_dir) install-nobase_nodist_picsDATA: $(nobase_nodist_pics_DATA) @$(NORMAL_INSTALL) @list='$(nobase_nodist_pics_DATA)'; test -n "$(picsdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(picsdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(picsdir)" || exit 1; \ fi; \ $(am__nobase_list) | while read dir files; do \ xfiles=; for file in $$files; do \ if test -f "$$file"; then xfiles="$$xfiles $$file"; \ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ test -z "$$xfiles" || { \ test "x$$dir" = x. || { \ echo " $(MKDIR_P) '$(DESTDIR)$(picsdir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(picsdir)/$$dir"; }; \ echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(picsdir)/$$dir'"; \ $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(picsdir)/$$dir" || exit $$?; }; \ done uninstall-nobase_nodist_picsDATA: @$(NORMAL_UNINSTALL) @list='$(nobase_nodist_pics_DATA)'; test -n "$(picsdir)" || list=; \ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ dir='$(DESTDIR)$(picsdir)'; $(am__uninstall_files_from_dir) install-nobase_nodist_playersDATA: $(nobase_nodist_players_DATA) @$(NORMAL_INSTALL) @list='$(nobase_nodist_players_DATA)'; test -n "$(playersdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(playersdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(playersdir)" || exit 1; \ fi; \ $(am__nobase_list) | while read dir files; do \ xfiles=; for file in $$files; do \ if test -f "$$file"; then xfiles="$$xfiles $$file"; \ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ test -z "$$xfiles" || { \ test "x$$dir" = x. || { \ echo " $(MKDIR_P) '$(DESTDIR)$(playersdir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(playersdir)/$$dir"; }; \ echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(playersdir)/$$dir'"; \ $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(playersdir)/$$dir" || exit $$?; }; \ done uninstall-nobase_nodist_playersDATA: @$(NORMAL_UNINSTALL) @list='$(nobase_nodist_players_DATA)'; test -n "$(playersdir)" || list=; \ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ dir='$(DESTDIR)$(playersdir)'; $(am__uninstall_files_from_dir) install-nobase_nodist_scriptsDATA: $(nobase_nodist_scripts_DATA) @$(NORMAL_INSTALL) @list='$(nobase_nodist_scripts_DATA)'; test -n "$(scriptsdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(scriptsdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(scriptsdir)" || exit 1; \ fi; \ $(am__nobase_list) | while read dir files; do \ xfiles=; for file in $$files; do \ if test -f "$$file"; then xfiles="$$xfiles $$file"; \ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ test -z "$$xfiles" || { \ test "x$$dir" = x. || { \ echo " $(MKDIR_P) '$(DESTDIR)$(scriptsdir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(scriptsdir)/$$dir"; }; \ echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(scriptsdir)/$$dir'"; \ $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(scriptsdir)/$$dir" || exit $$?; }; \ done uninstall-nobase_nodist_scriptsDATA: @$(NORMAL_UNINSTALL) @list='$(nobase_nodist_scripts_DATA)'; test -n "$(scriptsdir)" || list=; \ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ dir='$(DESTDIR)$(scriptsdir)'; $(am__uninstall_files_from_dir) install-nobase_nodist_soundDATA: $(nobase_nodist_sound_DATA) @$(NORMAL_INSTALL) @list='$(nobase_nodist_sound_DATA)'; test -n "$(sounddir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(sounddir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sounddir)" || exit 1; \ fi; \ $(am__nobase_list) | while read dir files; do \ xfiles=; for file in $$files; do \ if test -f "$$file"; then xfiles="$$xfiles $$file"; \ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ test -z "$$xfiles" || { \ test "x$$dir" = x. || { \ echo " $(MKDIR_P) '$(DESTDIR)$(sounddir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(sounddir)/$$dir"; }; \ echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(sounddir)/$$dir'"; \ $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(sounddir)/$$dir" || exit $$?; }; \ done uninstall-nobase_nodist_soundDATA: @$(NORMAL_UNINSTALL) @list='$(nobase_nodist_sound_DATA)'; test -n "$(sounddir)" || list=; \ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ dir='$(DESTDIR)$(sounddir)'; $(am__uninstall_files_from_dir) install-nobase_nodist_tacticalDATA: $(nobase_nodist_tactical_DATA) @$(NORMAL_INSTALL) @list='$(nobase_nodist_tactical_DATA)'; test -n "$(tacticaldir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(tacticaldir)'"; \ $(MKDIR_P) "$(DESTDIR)$(tacticaldir)" || exit 1; \ fi; \ $(am__nobase_list) | while read dir files; do \ xfiles=; for file in $$files; do \ if test -f "$$file"; then xfiles="$$xfiles $$file"; \ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ test -z "$$xfiles" || { \ test "x$$dir" = x. || { \ echo " $(MKDIR_P) '$(DESTDIR)$(tacticaldir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(tacticaldir)/$$dir"; }; \ echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(tacticaldir)/$$dir'"; \ $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(tacticaldir)/$$dir" || exit $$?; }; \ done uninstall-nobase_nodist_tacticalDATA: @$(NORMAL_UNINSTALL) @list='$(nobase_nodist_tactical_DATA)'; test -n "$(tacticaldir)" || list=; \ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ dir='$(DESTDIR)$(tacticaldir)'; $(am__uninstall_files_from_dir) install-nobase_nodist_texturesDATA: $(nobase_nodist_textures_DATA) @$(NORMAL_INSTALL) @list='$(nobase_nodist_textures_DATA)'; test -n "$(texturesdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(texturesdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(texturesdir)" || exit 1; \ fi; \ $(am__nobase_list) | while read dir files; do \ xfiles=; for file in $$files; do \ if test -f "$$file"; then xfiles="$$xfiles $$file"; \ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ test -z "$$xfiles" || { \ test "x$$dir" = x. || { \ echo " $(MKDIR_P) '$(DESTDIR)$(texturesdir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(texturesdir)/$$dir"; }; \ echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(texturesdir)/$$dir'"; \ $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(texturesdir)/$$dir" || exit $$?; }; \ done uninstall-nobase_nodist_texturesDATA: @$(NORMAL_UNINSTALL) @list='$(nobase_nodist_textures_DATA)'; test -n "$(texturesdir)" || list=; \ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ dir='$(DESTDIR)$(texturesdir)'; $(am__uninstall_files_from_dir) install-nobase_nodist_vehiclesDATA: $(nobase_nodist_vehicles_DATA) @$(NORMAL_INSTALL) @list='$(nobase_nodist_vehicles_DATA)'; test -n "$(vehiclesdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(vehiclesdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(vehiclesdir)" || exit 1; \ fi; \ $(am__nobase_list) | while read dir files; do \ xfiles=; for file in $$files; do \ if test -f "$$file"; then xfiles="$$xfiles $$file"; \ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ test -z "$$xfiles" || { \ test "x$$dir" = x. || { \ echo " $(MKDIR_P) '$(DESTDIR)$(vehiclesdir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(vehiclesdir)/$$dir"; }; \ echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(vehiclesdir)/$$dir'"; \ $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(vehiclesdir)/$$dir" || exit $$?; }; \ done uninstall-nobase_nodist_vehiclesDATA: @$(NORMAL_UNINSTALL) @list='$(nobase_nodist_vehicles_DATA)'; test -n "$(vehiclesdir)" || list=; \ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ dir='$(DESTDIR)$(vehiclesdir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile $(DATA) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(docdir)" "$(DESTDIR)$(icondir)" "$(DESTDIR)$(arenadir)" "$(DESTDIR)$(botinfodir)" "$(DESTDIR)$(data1dir)" "$(DESTDIR)$(envdir)" "$(DESTDIR)$(fontsdir)" "$(DESTDIR)$(gfxdir)" "$(DESTDIR)$(graphical_presetsdir)" "$(DESTDIR)$(levelshotsdir)" "$(DESTDIR)$(mapsdir)" "$(DESTDIR)$(modelsdir)" "$(DESTDIR)$(particlesdir)" "$(DESTDIR)$(picsdir)" "$(DESTDIR)$(playersdir)" "$(DESTDIR)$(scriptsdir)" "$(DESTDIR)$(sounddir)" "$(DESTDIR)$(tacticaldir)" "$(DESTDIR)$(texturesdir)" "$(DESTDIR)$(vehiclesdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-data-local install-dist_docDATA \ install-dist_iconDATA install-nobase_dist_arenaDATA \ install-nobase_dist_botinfoDATA install-nobase_dist_data1DATA \ install-nobase_nodist_envDATA install-nobase_nodist_fontsDATA \ install-nobase_nodist_gfxDATA \ install-nobase_nodist_graphical_presetsDATA \ install-nobase_nodist_levelshotsDATA \ install-nobase_nodist_mapsDATA \ install-nobase_nodist_modelsDATA \ install-nobase_nodist_particlesDATA \ install-nobase_nodist_picsDATA \ install-nobase_nodist_playersDATA \ install-nobase_nodist_scriptsDATA \ install-nobase_nodist_soundDATA \ install-nobase_nodist_tacticalDATA \ install-nobase_nodist_texturesDATA \ install-nobase_nodist_vehiclesDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-dist_docDATA uninstall-dist_iconDATA \ uninstall-local uninstall-nobase_dist_arenaDATA \ uninstall-nobase_dist_botinfoDATA \ uninstall-nobase_dist_data1DATA \ uninstall-nobase_nodist_envDATA \ uninstall-nobase_nodist_fontsDATA \ uninstall-nobase_nodist_gfxDATA \ uninstall-nobase_nodist_graphical_presetsDATA \ uninstall-nobase_nodist_levelshotsDATA \ uninstall-nobase_nodist_mapsDATA \ uninstall-nobase_nodist_modelsDATA \ uninstall-nobase_nodist_particlesDATA \ uninstall-nobase_nodist_picsDATA \ uninstall-nobase_nodist_playersDATA \ uninstall-nobase_nodist_scriptsDATA \ uninstall-nobase_nodist_soundDATA \ uninstall-nobase_nodist_tacticalDATA \ uninstall-nobase_nodist_texturesDATA \ uninstall-nobase_nodist_vehiclesDATA .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ dist-gzip dist-hook dist-lzip dist-shar dist-tarZ dist-xz \ dist-zip distcheck distclean distclean-generic distclean-hdr \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-data-local \ install-dist_docDATA install-dist_iconDATA install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-nobase_dist_arenaDATA install-nobase_dist_botinfoDATA \ install-nobase_dist_data1DATA install-nobase_nodist_envDATA \ install-nobase_nodist_fontsDATA install-nobase_nodist_gfxDATA \ install-nobase_nodist_graphical_presetsDATA \ install-nobase_nodist_levelshotsDATA \ install-nobase_nodist_mapsDATA \ install-nobase_nodist_modelsDATA \ install-nobase_nodist_particlesDATA \ install-nobase_nodist_picsDATA \ install-nobase_nodist_playersDATA \ install-nobase_nodist_scriptsDATA \ install-nobase_nodist_soundDATA \ install-nobase_nodist_tacticalDATA \ install-nobase_nodist_texturesDATA \ install-nobase_nodist_vehiclesDATA install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags tags-am uninstall uninstall-am \ uninstall-dist_docDATA uninstall-dist_iconDATA uninstall-local \ uninstall-nobase_dist_arenaDATA \ uninstall-nobase_dist_botinfoDATA \ uninstall-nobase_dist_data1DATA \ uninstall-nobase_nodist_envDATA \ uninstall-nobase_nodist_fontsDATA \ uninstall-nobase_nodist_gfxDATA \ uninstall-nobase_nodist_graphical_presetsDATA \ uninstall-nobase_nodist_levelshotsDATA \ uninstall-nobase_nodist_mapsDATA \ uninstall-nobase_nodist_modelsDATA \ uninstall-nobase_nodist_particlesDATA \ uninstall-nobase_nodist_picsDATA \ uninstall-nobase_nodist_playersDATA \ uninstall-nobase_nodist_scriptsDATA \ uninstall-nobase_nodist_soundDATA \ uninstall-nobase_nodist_tacticalDATA \ uninstall-nobase_nodist_texturesDATA \ uninstall-nobase_nodist_vehiclesDATA # remove svn directories from distribution staging area after creating # distribution in staging area and before running archiver # but, it is probably a better idea to export the repository to the # staging area since export does not include the .svn parts # # copy noinst DATA to the distribution directory. while partitioning the # data files into subdirectory groups solves the problem with exceeding # command length limits for installation, it does not help with tarball # creation. # dist-hook: rm -rf `find $(distdir) -name .svn` $(foreach GAMEDIR, $(sort $(dir $(gamedata_files))),$(shell mkdir -p $(distdir)/$(GAMEDIR) )) $(foreach GAMEFILE, $(gamedata_files), $(shell cp -p $(srcdir)/$(GAMEFILE) $(distdir)/$(GAMEFILE))) # # Alternate Install # This non-standard target is used for traditional single directory, # in-place install. Good for map makers, frequent SVN updates. # Also, maybe the preferable installation for Game Server Providers doing # dedicated server only builds # # Use: # ./configure --enable-alternate-install && make && make install-alternate # # Note: this does not support program name translation and other autoconf # features. # install-alternate: @ALTERNATE_INSTALL_TRUE@@BUILD_CLIENT_TRUE@ cp $(top_builddir)/source/alienarena@EXEEXT@ $(srcdir)/alienarena@EXEEXT@ @ALTERNATE_INSTALL_TRUE@@BUILD_UNIX_TRUE@ cp $(top_builddir)/source/alienarena-ded $(srcdir)/alienarena-ded @ALTERNATE_INSTALL_FALSE@ @echo "make install-alternate requires configuring with --enable-alternate-install" # # install/uninstall added rules for alternate-install to prevent "undefined" behaviour. # install-data-local: @ALTERNATE_INSTALL_TRUE@ @echo "Alternate install: Use "make install-alternate"!!! @ALTERNATE_INSTALL_TRUE@ exit 1 uninstall-local: @ALTERNATE_INSTALL_TRUE@ @echo "Alternate install. Manual uninstall required!!!" @ALTERNATE_INSTALL_TRUE@ exit 1 # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: alien-arena-7.66+dfsg/config/0000700000175000017500000000000012207204656015066 5ustar zero79zero79alien-arena-7.66+dfsg/config/missing0000700000175000017500000001533112207204614016462 0ustar zero79zero79#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2012-06-26.16; # UTC # Copyright (C) 1996-2013 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=http://www.perl.org/ flex_URL=http://flex.sourceforge.net/ gnu_software_URL=http://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'automa4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: alien-arena-7.66+dfsg/config/config.sub0000700000175000017500000010530112207204614017043 0ustar zero79zero79#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2013 Free Software Foundation, Inc. timestamp='2013-04-24' # This file 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 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches with a ChangeLog entry to config-patches@gnu.org. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | be32 | be64 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 \ | or1k | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i386-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or1k-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: alien-arena-7.66+dfsg/config/compile0000700000175000017500000001624512207204614016446 0ustar zero79zero79#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2012-10-14.11; # UTC # Copyright (C) 1999-2013 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: alien-arena-7.66+dfsg/config/config.h.in0000600000175000017500000002543412207204613017114 0ustar zero79zero79/* config/config.h.in. Generated from configure.ac by autoheader. */ /* Enable ANSI terminal color codes in stdout */ #undef ANSI_COLOR /* Canonical OS identification */ #undef BUILDSTRING /* Canonical CPU identification */ #undef CPUSTRING /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP systems. This function is required for `alloca.c' support on those systems. */ #undef CRAY_STACKSEG_END /* Define to 1 if using `alloca.c'. */ #undef C_ALLOCA /* darwin-specific conditional compile */ #undef DARWIN_SPECIAL_CASE /* non-specific unix conditional compile */ #undef GENERIC_UNIX /* Define to 1 if you have the header file. */ #undef HAVE_ALC_H /* Define to 1 if you have `alloca', as a function or macro. */ #undef HAVE_ALLOCA /* Define to 1 if you have and it should be used (not on Ultrix). */ #undef HAVE_ALLOCA_H /* Define to 1 if you have the header file. */ #undef HAVE_AL_ALC_H /* Define to 1 if you have the header file. */ #undef HAVE_AL_AL_H /* Define to 1 if you have the header file. */ #undef HAVE_AL_H /* Define to 1 if you have the header file. */ #undef HAVE_ARPA_INET_H /* Define to 1 if you have the `clock_gettime' function. */ #undef HAVE_CLOCK_GETTIME /* Define to 1 if you have the `closesocket' function. */ #undef HAVE_CLOSESOCKET /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if you have the `filelength' function. */ #undef HAVE_FILELENGTH /* Define to 1 if you have the header file. */ #undef HAVE_FLOAT_H /* Define to 1 if you have the `floor' function. */ #undef HAVE_FLOOR /* Define to 1 if you have the `fstat' function. */ #undef HAVE_FSTAT /* Define to 1 if you have the `getcwd' function. */ #undef HAVE_GETCWD /* Define to 1 if you have the `gethostbyname' function. */ #undef HAVE_GETHOSTBYNAME /* Define to 1 if you have the `getpagesize' function. */ #undef HAVE_GETPAGESIZE /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY /* Define to 1 if you have the header file. */ #undef HAVE_GL_GLX_H /* Define to 1 if you have the header file. */ #undef HAVE_GL_GL_H /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `isascii' function. */ #undef HAVE_ISASCII /* Define to 1 if you have the header file. */ #undef HAVE_JPEGLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_JPEG_JPEGLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_LIMITS_H /* Define to 1 if your system has a GNU libc compatible `malloc' function, and to 0 otherwise. */ #undef HAVE_MALLOC /* Define to 1 if you have the header file. */ #undef HAVE_MALLOC_H /* Define to 1 if you have the `memmove' function. */ #undef HAVE_MEMMOVE /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `memset' function. */ #undef HAVE_MEMSET /* Define to 1 if you have the `mkdir' function. */ #undef HAVE_MKDIR /* Define to 1 if you have a working `mmap' system call. */ #undef HAVE_MMAP /* Define to 1 if you have the `mremap' function. */ #undef HAVE_MREMAP /* Define to 1 if you have the `munmap' function. */ #undef HAVE_MUNMAP /* Define to 1 if you have the header file. */ #undef HAVE_NETDB_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IN_H /* Define to 1 if libc includes obstacks. */ #undef HAVE_OBSTACK /* Define to 1 if you have the header file. */ #undef HAVE_OPENAL_ALC_H /* Define to 1 if you have the header file. */ #undef HAVE_OPENAL_AL_H /* Define to 1 if you have the `pow' function. */ #undef HAVE_POW /* Define if you have POSIX threads libraries and header files. */ #undef HAVE_PTHREAD /* Define to 1 if you have the `pthread_create' function. */ #undef HAVE_PTHREAD_CREATE /* Have PTHREAD_PRIO_INHERIT. */ #undef HAVE_PTHREAD_PRIO_INHERIT /* Define to 1 if the system has the type `ptrdiff_t'. */ #undef HAVE_PTRDIFF_T /* Define to 1 if you have the `putenv' function. */ #undef HAVE_PUTENV /* Define to 1 if your system has a GNU libc compatible `realloc' function, and to 0 otherwise. */ #undef HAVE_REALLOC /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT /* Define to 1 if you have the `socket' function. */ #undef HAVE_SOCKET /* Define to 1 if you have the `sqrt' function. */ #undef HAVE_SQRT /* Define to 1 if you have the `stat' function. */ #undef HAVE_STAT /* Define to 1 if stdbool.h conforms to C99. */ #undef HAVE_STDBOOL_H /* Define to 1 if you have the header file. */ #undef HAVE_STDDEF_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strcasecmp' function. */ #undef HAVE_STRCASECMP /* Define to 1 if you have the `strchr' function. */ #undef HAVE_STRCHR /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP /* Define to 1 if you have the `strerror' function. */ #undef HAVE_STRERROR /* Define to 1 if you have the `stricmp' function. */ #undef HAVE_STRICMP /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strlcpy' function. */ #undef HAVE_STRLCPY /* Define to 1 if you have the `strncasecmp' function. */ #undef HAVE_STRNCASECMP /* Define to 1 if you have the `strnicmp' function. */ #undef HAVE_STRNICMP /* Define to 1 if you have the `strrchr' function. */ #undef HAVE_STRRCHR /* Define to 1 if you have the `strstr' function. */ #undef HAVE_STRSTR /* Define to 1 if you have the header file. */ #undef HAVE_SYS_IOCTL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PARAM_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SELECT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_TERMIOS_H /* Define to 1 if you have the header file. */ #undef HAVE_TIME_H /* Define to 1 if the system has the type `uintptr_t'. */ #undef HAVE_UINTPTR_T /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `unlink' function. */ #undef HAVE_UNLINK /* Define to 1 if you have the header file. */ #undef HAVE_WINDOWS_H /* Define to 1 if you have the header file. */ #undef HAVE_WINSOCK2_H /* Define to 1 if you have the header file. */ #undef HAVE_WINSOCK_H /* Define to 1 if you have the header file. */ #undef HAVE_X11_EXTENSIONS_XXF86DGA_H /* Enable X86 DGA support */ #undef HAVE_XXF86DGA /* Enable X86 VidMode support */ #undef HAVE_XXF86VM /* Enable ZLib support */ #undef HAVE_ZLIB /* Define to 1 if you have the `_begin_thread' function. */ #undef HAVE__BEGIN_THREAD /* Define to 1 if the system has the type `_Bool'. */ #undef HAVE__BOOL /* Define to 1 if you have the `_getcwd' function. */ #undef HAVE__GETCWD /* Define to 1 if you have the `_mkdir' function. */ #undef HAVE__MKDIR /* Define to 1 if you have the `_putenv' function. */ #undef HAVE__PUTENV /* Define to 1 if you have the `_strdup' function. */ #undef HAVE__STRDUP /* Define to 1 if you have the `_stricmp' function. */ #undef HAVE__STRICMP /* Define to 1 if you have the `_strnicmp' function. */ #undef HAVE__STRNICMP /* Define to 1 if you have the `_unlink' function. */ #undef HAVE__UNLINK /* linux-specific conditional compile */ #undef LINUX_SPECIAL_CASE /* OpenAL dll name */ #undef OPENAL_DRIVER /* OpenGL DLL name */ #undef OPENGL_DRIVER /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to necessary symbol if this constant uses a non-standard name on your system. */ #undef PTHREAD_CREATE_JOINABLE /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at runtime. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #undef STACK_DIRECTION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* unix-specific conditional compile */ #undef UNIX_VARIANT /* User data and cfg subdirectory in $HOME */ #undef USER_GAMEDATA /* Version number of package */ #undef VERSION /* win32-specific conditional compile */ #undef WIN32_VARIANT /* see select (2) man page for Mac OS X */ #undef _DARWIN_UNLIMITED_SELECT /* Define for Solaris 2.5.1 so the uint64_t typedef from , , or is not used. If the typedef were allowed, the #define below would cause a syntax error. */ #undef _UINT64_T /* Define to DBL_EPSILON for ODE */ #undef dEpsilon /* Define to `int' if doesn't define. */ #undef gid_t /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus #undef inline #endif /* Define to the type of a signed integer type of width exactly 32 bits if such a type exists and the standard includes do not define it. */ #undef int32_t /* Define to the type of a signed integer type of width exactly 64 bits if such a type exists and the standard includes do not define it. */ #undef int64_t /* Define to rpl_malloc if the replacement function should be used. */ #undef malloc /* Define to rpl_realloc if the replacement function should be used. */ #undef realloc /* Define to `unsigned int' if does not define. */ #undef size_t /* Define to `int' if doesn't define. */ #undef uid_t /* Define to the type of an unsigned integer type of width exactly 64 bits if such a type exists and the standard includes do not define it. */ #undef uint64_t alien-arena-7.66+dfsg/config/install-sh0000700000175000017500000003325512207204614017074 0ustar zero79zero79#!/bin/sh # install - install a program, script, or datafile scriptversion=2011-11-20.07; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: alien-arena-7.66+dfsg/config/depcomp0000700000175000017500000005601612207204614016445 0ustar zero79zero79#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2013-05-30.07; # UTC # Copyright (C) 1999-2013 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz digits=0123456789 alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interferences from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: alien-arena-7.66+dfsg/config/config.guess0000700000175000017500000013036112207204614017404 0ustar zero79zero79#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2013 Free Software Foundation, Inc. timestamp='2013-06-10' # This file 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 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD # # Please send patches with a ChangeLog entry to config-patches@gnu.org. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_SYSTEM}" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval $set_cc_for_build cat <<-EOF > $dummy.c #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` ;; esac # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW64*:*) echo ${UNAME_MACHINE}-pc-mingw64 exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="gnulibc1" ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; or1k:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; or32:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-${LIBC} exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown eval $set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; esac eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: alien-arena-7.66+dfsg/source/0000700000175000017500000000000012207204656015121 5ustar zero79zero79alien-arena-7.66+dfsg/source/server/0000700000175000017500000000000012207204657016430 5ustar zero79zero79alien-arena-7.66+dfsg/source/server/sv_main.c0000600000175000017500000011054212161402010020213 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "server.h" master_sv_t master_status[MAX_MASTERS]; // status of master servers client_t *sv_client; // current client cvar_t *sv_paused; cvar_t *sv_timedemo; cvar_t *sv_enforcetime; cvar_t *timeout; // seconds without any message cvar_t *zombietime; // seconds to sink messages after disconnect cvar_t *rcon_password; // password for remote server commands cvar_t *allow_download; cvar_t *allow_download_players; cvar_t *allow_download_models; cvar_t *allow_download_sounds; cvar_t *allow_download_maps; cvar_t *sv_airaccelerate; cvar_t *sv_joustmode; cvar_t *sv_tactical; cvar_t *sv_excessive; cvar_t *sv_noreload; // don't reload level state when reentering cvar_t *maxclients; // FIXME: rename sv_maxclients cvar_t *sv_showclamp; cvar_t *hostname; cvar_t *public_server; // should heartbeats be sent cvar_t *sv_reconnect_limit; // minimum seconds between connect messages cvar_t *sv_ratelimit_status; //new security measures cvar_t *sv_iplimit; cvar_t *sv_downloadurl; cvar_t *sv_iplogfile; // Log file by IP address int sv_numbots; void Master_Shutdown (void); short ShortSwap (short l); //============================================================================ /* ===================== SV_LogEvent Logs an event to the IP log. ===================== */ static void SV_LogEvent( netadr_t address , const char * event , const char * name ) { FILE * file; if ( !( sv_iplogfile && sv_iplogfile->string[0] ) ) return; file = fopen( sv_iplogfile->string , "a" ); if ( !file ) { Com_DPrintf( "Failed to write to IP log file '%s'\n" , sv_iplogfile->string ); return; } fprintf( file , "%s\t%s\t%d\t%s\r\n" , NET_AdrToString(address) , event , ( name != NULL ) , ( name != NULL ) ? name : "" ); fclose( file ); } /* ===================== SV_DropClient Called when the player is totally leaving the server, either willingly or unwillingly. This is NOT called if the entire server is quiting or crashing. ===================== */ void SV_DropClient (client_t *drop) { // add the disconnect MSG_WriteByte (&drop->netchan.message, svc_disconnect); if (drop->state == cs_spawned) { // call the prog function for removing a client // this will remove the body, among other things ge->ClientDisconnect (drop->edict); } if (drop->download) { FS_FreeFile (drop->download); drop->download = NULL; } SV_LogEvent( drop->netchan.remote_address , "DCN" , drop->name ); drop->state = cs_zombie; // become free in a few seconds drop->name[0] = 0; } /* ============================================================================== CONNECTIONLESS COMMANDS ============================================================================== */ /* =============== SV_StatusString Builds the string that is sent as heartbeats and status replies =============== */ char *SV_StatusString (void) { static char status[MAX_MSGLEN - 16]; // static buffer for the status string qboolean msg_overflow = false; char player[MAX_INFO_STRING]; client_t *cl; size_t count; // server info string. MAX_INFO_STRING is always < sizeof(status) strcpy( status, Cvar_Serverinfo() ); strcat( status, "\n" ); // real player score info for ( cl=svs.clients, count=maxclients->integer ; count-- ; cl++ ) { if (cl->state == cs_connected || cl->state == cs_spawned ) { /* send score of 0 for spectators and players not yet in game * statistics program uses this data when polling for scores */ int cl_score = 0; if ( cl->state == cs_spawned && cl->edict->client->ps.stats[STAT_SPECTATOR] == 0 ) { cl_score = cl->edict->client->ps.stats[STAT_FRAGS];; } /* * send color characters * do not send actual ip addresses for security/privacy reasons */ Com_sprintf( player, sizeof(player), "%i %i \"%s\" \"127.0.0.1\"\n", cl_score, cl->ping, cl->name); if ( (strlen(status) + strlen(player) + 1) < sizeof(status) ) { strncat( status, player, strlen(player) ); } else { msg_overflow = true; break; } } } // bot score info if ( !msg_overflow ) { for ( cl=svs.clients, count=maxclients->integer ; count-- ; cl++ ) { size_t bot_count; bot_count = cl->edict->client->ps.botnum; if ( bot_count ) { // normally, first client contains the bot names and scores bot_t* ps_bot; for ( ps_bot = cl->edict->client->ps.bots ; bot_count-- ; ps_bot++ ) { int bot_score = ps_bot->score; Com_sprintf( player, sizeof(player), "%i %i \"%s\" \"127.0.0.1\"\n", bot_score, 0, // bot ping ps_bot->name ); if ( (strlen(status) + strlen(player) + 1) < sizeof(status) ) { strncat( status, player, strlen(player) ); } else { msg_overflow = true; break; } } } break; } } if ( msg_overflow ) { Com_DPrintf("SV_StatusString overflowed\n"); } return status; } /* ================ SVC_Status Responds with all the info that qplug or qspy can see ================ */ /*void SVC_Status (void) { Netchan_OutOfBandPrint (NS_SERVER, net_from, "print\n%s", SV_StatusString()); #if 0 Com_BeginRedirect (RD_PACKET, sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_FlushRedirect); Com_Printf (SV_StatusString()); Com_EndRedirect (); #endif }*/ static qboolean RateLimited (ratelimit_t *limit, int maxCount) { int diff; diff = sv.time - limit->time; //a new sampling period if (diff > limit->period || diff < 0) { limit->time = sv.time; limit->count = 0; } else { if (limit->count >= maxCount) return true; } return false; } static void RateSample (ratelimit_t *limit) { int diff; diff = sv.time - limit->time; //a new sampling period if (diff > limit->period || diff < 0) { limit->time = sv.time; limit->count = 1; } else { limit->count++; } } static void SVC_Status (void) { RateSample (&svs.ratelimit_status); if (RateLimited (&svs.ratelimit_status, sv_ratelimit_status->integer)) { Com_DPrintf ("SVC_Status: Dropped status request from %s\n", NET_AdrToString (net_from)); return; } Netchan_OutOfBandPrint (NS_SERVER, net_from, "print\n%s", SV_StatusString()); } /* ================ SVC_Ack ================ */ void SVC_Ack (void) { int i; Com_Printf ("Ping acknowledge from %s\n", NET_AdrToString(net_from)); for ( i = 0 ; i < MAX_MASTERS ; i ++ ) { if ( master_status[i].name[0] == 0 ) break; if ( master_status[i].addr.port == 0 ) continue; if ( NET_CompareAdr (master_status[i].addr, net_from) ) master_status[i].last_ping_ack = 2; } } /* ================ SVC_Info Responds with short info for broadcast scans The second parameter should be the current protocol version number. ================ */ void SVC_Info (void) { char string[64]; int i, count; int version; client_t *cl; if (maxclients->integer == 1) return; // ignore in single player version = atoi (Cmd_Argv(1)); if (version != PROTOCOL_VERSION) { Com_sprintf (string, sizeof(string), "%s: wrong version\n", hostname->string, sizeof(string)); //r1: return instead of sending another packet. prevents spoofed udp packet // causing server <-> server info loops. return; } else { count = 0; for (i=0 ; iinteger ; i++) if (svs.clients[i].state >= cs_connected) count++; //bot score info for (i=0 ; iinteger ; i++) { cl = &svs.clients[i]; if(cl->edict->client->ps.botnum > 0) { count += cl->edict->client->ps.botnum; //add the bots break; } } //end bot score info Com_sprintf (string, sizeof(string), "%16s %8s %2i/%2i\n", hostname->string, sv.name, count, maxclients->integer); } Netchan_OutOfBandPrint (NS_SERVER, net_from, "info\n%s", string); } /* ================ SVC_Ping Just responds with an acknowledgement ================ */ void SVC_Ping (void) { Netchan_OutOfBandPrint (NS_SERVER, net_from, "ack"); } void SV_KickClient (client_t *cl, const char /*@null@*/*reason, const char /*@null@*/*cprintf) { if (reason && cl->state == cs_spawned && cl->name[0]) SV_BroadcastPrintf (PRINT_HIGH, "%s was dropped: %s\n", cl->name, reason); if (cprintf) SV_ClientPrintf (cl, PRINT_HIGH, "%s", cprintf); Com_Printf ("Dropping %s, %s.\n", cl->name, reason ? reason : "SV_KickClient"); SV_DropClient (cl); } /* ================= SVC_GetChallenge Returns a challenge number that can be used in a subsequent client_connect command. We do this to prevent denial of service attacks that flood the server with invalid connection IPs. With a challenge, they must give a valid IP address. ================= */ void SVC_GetChallenge (void) { int i; int oldest; int oldestTime; oldest = 0; oldestTime = 0x7fffffff; // see if we already have a challenge for this ip for (i = 0 ; i < MAX_CHALLENGES ; i++) { if (NET_CompareBaseAdr (net_from, svs.challenges[i].adr)) break; if (svs.challenges[i].time < oldestTime) { oldestTime = svs.challenges[i].time; oldest = i; } } if (i == MAX_CHALLENGES) { // overwrite the oldest svs.challenges[oldest].challenge = rand() & 0x7fff; svs.challenges[oldest].adr = net_from; svs.challenges[oldest].time = curtime; i = oldest; } // send it back Netchan_OutOfBandPrint (NS_SERVER, net_from, "challenge %i", svs.challenges[i].challenge); } /* ================== SVC_DirectConnect A connection request that did not come from the master ================== */ void SVC_DirectConnect (void) { char userinfo[MAX_INFO_STRING]; netadr_t adr; int i; client_t *cl, *newcl; client_t temp; edict_t *ent; int edictnum; int version; int qport; int challenge; int previousclients; int botnum, botkick; adr = net_from; Com_DPrintf ("SVC_DirectConnect ()\n"); version = atoi(Cmd_Argv(1)); if (version != PROTOCOL_VERSION) { Netchan_OutOfBandPrint (NS_SERVER, adr, "print\nServer is protocol version %s\n", PROTOCOL_VERSION); Com_DPrintf (" rejected connect from protocol version %i\n", version); SV_LogEvent( adr , "RVR" , NULL ); return; } qport = atoi(Cmd_Argv(2)); challenge = atoi(Cmd_Argv(3)); //security, overflow fixes //limit connections from a single IP previousclients = 0; for (i=0,cl=svs.clients ; iinteger ; i++,cl++) { if (cl->state == cs_free) continue; if (NET_CompareBaseAdr (adr, cl->netchan.remote_address)) { //zombies are less dangerous if (cl->state == cs_zombie) previousclients++; else previousclients += 2; } } if (previousclients >= sv_iplimit->integer * 2) { Netchan_OutOfBandPrint (NS_SERVER, adr, "print\nToo many connections from your host.\n"); Com_DPrintf (" too many connections\n"); SV_LogEvent( adr , "R00" , NULL ); return; } // sku - reserve 32 bytes for the IP address strncpy (userinfo, Cmd_Argv(4), sizeof(userinfo)-32); userinfo[sizeof(userinfo) - 32] = 0; //check it is not overflowed, save enough bytes for /ip/111.222.333.444:55555 if (strlen(userinfo) + 25 >= sizeof(userinfo)-1) { Com_DPrintf (" userinfo length exceeded\n"); Netchan_OutOfBandPrint (NS_SERVER, adr, "print\nUserinfo string length exceeded.\n"); SV_LogEvent( adr , "R01" , NULL ); return; } else if (!userinfo[0]) { Com_DPrintf (" empty userinfo string\n"); Netchan_OutOfBandPrint (NS_SERVER, adr, "print\nBad userinfo string.\n"); SV_LogEvent( adr , "R02" , NULL ); return; } //block anyone trying to use the end-of-message-in-string exploit if (strchr(userinfo, '\xFF')) { char *ptr; ptr = strchr (userinfo, '\xFF'); ptr -= 8; if (ptr < userinfo) ptr = userinfo; Netchan_OutOfBandPrint (NS_SERVER, adr, "print\nConnection refused due to attempted exploit!\n"); SV_LogEvent( adr , "R03" , NULL ); return; } if (Info_KeyExists (userinfo, "ip")) { char *p; p = Info_ValueForKey(userinfo, "ip"); Com_Printf ("EXPLOIT: Client %s attempted to spoof IP address: %s\n", Info_ValueForKey (userinfo, "name"), NET_AdrToString(adr)); SV_LogEvent( adr , "R04" , NULL ); return; } // force the IP key/value pair so the game can filter based on ip Info_SetValueForKey (userinfo, "ip", NET_AdrToString(net_from)); // attractloop servers are ONLY for local clients if (sv.attractloop) { if (!NET_IsLocalAddress (adr)) { Com_Printf ("Remote connect in attract loop. Ignored.\n"); Netchan_OutOfBandPrint (NS_SERVER, adr, "print\nConnection refused.\n"); SV_LogEvent( adr , "R05" , NULL ); return; } } // see if the challenge is valid if (!NET_IsLocalAddress (adr)) { for (i=0 ; iinteger ; i++,cl++) { if (cl->state == cs_free) continue; if (NET_CompareAdr (adr, cl->netchan.remote_address)) { //r1: !! fix nasty bug where non-disconnected clients (from dropped disconnect //packets) could be overwritten! if (cl->state != cs_zombie) { Com_DPrintf (" client already found\n"); Netchan_OutOfBandPrint (NS_SERVER, adr, "print\nPlayer '%s' is already connected from %s.\n", cl->name, NET_AdrToString(adr)); SV_LogEvent( adr , "R08" , cl->name ); return; } if (!NET_IsLocalAddress (adr) && (svs.realtime - cl->lastconnect) < ((int)sv_reconnect_limit->integer * 1000)) { Com_DPrintf ("%s:reconnect rejected : too soon\n", NET_AdrToString (adr)); SV_LogEvent( adr , "R09" , NULL ); return; } Com_Printf ("%s:reconnect\n", NET_AdrToString (adr)); SV_LogEvent( adr , "RCN" , NULL ); newcl = cl; goto gotnewcl; } } // find a client slot //get number of bots for (i=botnum=0 ; iinteger ; i++) { cl = &svs.clients[i]; botnum = cl->edict->client->ps.botnum; if(botnum > 0) break; } //still need to reserve one slot newcl = NULL; //are we using botkickthreshold? botkick = Cvar_VariableValue("sv_botkickthreshold"); //prevent client slot overwrites with bots rejoining after map change if(botkick) { if(botkick < sv_numbots) botnum = botkick; else botnum = sv_numbots; } for (i=0,cl=svs.clients ; iinteger-botnum; i++,cl++) { if (cl->state == cs_free) { newcl = cl; break; } } if (!newcl) { Netchan_OutOfBandPrint (NS_SERVER, adr, "print\nServer is full.\n"); Com_DPrintf ("Rejected a connection.\n"); SV_LogEvent( adr , "R10" , NULL ); return; } SV_LogEvent( adr , "NCN" , NULL ); gotnewcl: // build a new connection // accept the new client // this is the only place a client_t is ever initialized *newcl = temp; sv_client = newcl; edictnum = (newcl-svs.clients)+1; ent = EDICT_NUM(edictnum); newcl->edict = ent; newcl->challenge = challenge; // save challenge for checksumming // get the game a chance to reject this connection or modify the userinfo if (!(ge->ClientConnect (ent, userinfo))) { if (*Info_ValueForKey (userinfo, "rejmsg")) Netchan_OutOfBandPrint (NS_SERVER, adr, "print\n%s\nConnection refused.\n", Info_ValueForKey (userinfo, "rejmsg")); else Netchan_OutOfBandPrint (NS_SERVER, adr, "print\nConnection refused.\n" ); SV_LogEvent( adr , "GRJ" , NULL ); Com_DPrintf ("Game rejected a connection.\n"); return; } // parse some info from the info strings Q_strncpyz2( newcl->userinfo, userinfo, sizeof(newcl->userinfo) ); SV_UserinfoChanged (newcl); SV_LogEvent( adr , "UUS" , newcl->name ); // send the connect packet to the client Netchan_OutOfBandPrint(NS_SERVER, adr, "client_connect %s", sv_downloadurl->string); Netchan_Setup (NS_SERVER, &newcl->netchan , adr, qport); newcl->state = cs_connected; SZ_Init (&newcl->datagram, newcl->datagram_buf, sizeof(newcl->datagram_buf) ); SZ_SetName (&newcl->datagram, va("Datagram buffer %s", NET_AdrToString(adr)), true); newcl->datagram.allowoverflow = true; newcl->lastmessage = svs.realtime; // don't timeout newcl->lastconnect = svs.realtime; ge->ForceExitIntermission (); Cbuf_Execute (); } int Rcon_Validate (void) { if (!strlen (rcon_password->string)) return 0; if (strcmp (Cmd_Argv(1), rcon_password->string) ) return 0; return 1; } /* =============== SVC_RemoteCommand A client issued an rcon command. Shift down the remaining args Redirect all printfs =============== */ void SVC_RemoteCommand (void) { int i; char remaining[1024]; i = Rcon_Validate (); if (i == 0) Com_Printf ("Bad rcon from %s:\n%s\n", NET_AdrToString (net_from), net_message.data+4); else Com_Printf ("Rcon from %s:\n%s\n", NET_AdrToString (net_from), net_message.data+4); Com_BeginRedirect (RD_PACKET, sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_FlushRedirect); if (!Rcon_Validate ()) { Com_Printf ("Bad rcon_password.\n"); } else { remaining[0] = 0; for (i=2 ; iping variables =================== */ void SV_CalcPings (void) { int i, j; client_t *cl; int total, count; for (i=0 ; iinteger ; i++) { cl = &svs.clients[i]; if (cl->state != cs_spawned ) continue; #if 0 if (cl->lastframe > 0) cl->frame_latency[sv.framenum&(LATENCY_COUNTS-1)] = sv.framenum - cl->lastframe + 1; else cl->frame_latency[sv.framenum&(LATENCY_COUNTS-1)] = 0; #endif total = 0; count = 0; for (j=0 ; jframe_latency[j] > 0) { count++; total += cl->frame_latency[j]; } } if (!count) cl->ping = 0; else #if 0 cl->ping = total*100/count - 100; #else cl->ping = total / count; #endif // let the game dll know about the ping cl->edict->client->ping = cl->ping; } } /* =================== SV_GiveMsec Every few frames, gives all clients an allotment of milliseconds for their command moves. If they exceed it, assume cheating. =================== */ void SV_GiveMsec (void) { int i; client_t *cl; if (sv.framenum & 15) return; for (i=0 ; iinteger ; i++) { cl = &svs.clients[i]; if (cl->state == cs_free ) continue; cl->commandMsec = 1800; // 1600 + some slop } } /* ================= SV_ReadPackets ================= */ extern int sys_msec_as_of_packet_read; void SV_ReadPackets (void) { int i; client_t *cl; int qport; sys_msec_as_of_packet_read = Sys_Milliseconds (); while (NET_GetPacket (NS_SERVER, &net_from, &net_message)) { // check for connectionless packet (0xffffffff) first if (*(int *)net_message.data == -1) { SV_ConnectionlessPacket (); continue; } // read the qport out of the message so we can fix up // stupid address translating routers MSG_BeginReading (&net_message); MSG_ReadLong (&net_message); // sequence number MSG_ReadLong (&net_message); // sequence number qport = MSG_ReadShort (&net_message) & 0xffff; // check for packets from connected clients for (i=0, cl=svs.clients ; iinteger ; i++,cl++) { if (cl->state == cs_free) continue; if (!NET_CompareBaseAdr (net_from, cl->netchan.remote_address)) continue; if (cl->netchan.qport != qport) continue; if (cl->netchan.remote_address.port != net_from.port) { Com_Printf ("SV_ReadPackets: fixing up a translated port\n"); cl->netchan.remote_address.port = net_from.port; } if (Netchan_Process(&cl->netchan, &net_message)) { // this is a valid, sequenced packet, so process it if (cl->state != cs_zombie) { cl->lastmessage = svs.realtime; // don't timeout SV_ExecuteClientMessage (cl); } } break; } if (i != maxclients->integer) continue; } } /* ================== SV_CheckTimeouts If a packet has not been received from a client for timeout->value seconds, drop the conneciton. Server frames are used instead of realtime to avoid dropping the local client while debugging. When a client is normally dropped, the client_t goes into a zombie state for a few seconds to make sure any final reliable message gets resent if necessary ================== */ void SV_CheckTimeouts (void) { int i; client_t *cl; int droppoint; int zombiepoint; droppoint = svs.realtime - 1000*timeout->value; zombiepoint = svs.realtime - 1000*zombietime->value; for (i=0,cl=svs.clients ; iinteger ; i++,cl++) { // message times may be wrong across a changelevel if (cl->lastmessage > svs.realtime) cl->lastmessage = svs.realtime; if (cl->state == cs_zombie && cl->lastmessage < zombiepoint) { cl->state = cs_free; // can now be reused continue; } if ( (cl->state == cs_connected || cl->state == cs_spawned) && cl->lastmessage < droppoint) { SV_BroadcastPrintf (PRINT_HIGH, "%s timed out\n", cl->name); SV_DropClient (cl); cl->state = cs_free; // don't bother with zombie state } } } /* ================ SV_PrepWorldFrame This has to be done before the world logic, because player processing happens outside RunWorldFrame ================ */ void SV_PrepWorldFrame (void) { edict_t *ent; int i; for (i=0 ; inum_edicts ; i++, ent++) { ent = EDICT_NUM(i); // events only last for a single message ent->s.event = 0; } } /* ================= SV_RunGameFrame ================= */ void SV_RunGameFrame (void) { if (host_speeds->integer) time_before_game = Sys_Milliseconds (); // we always need to bump framenum, even if we // don't run the world, otherwise the delta // compression can get confused when a client // has the "current" frame sv.framenum++; sv.time = sv.framenum*100; // don't run if paused if (!sv_paused->integer || maxclients->integer > 1) { ge->RunFrame (); // never get more than one tic behind if (sv.time < svs.realtime) { if (sv_showclamp->integer) Com_Printf ("sv highclamp\n"); svs.realtime = sv.time; } } if (host_speeds->integer) time_after_game = Sys_Milliseconds (); } /* ================== SV_Frame ================== */ extern int sys_lasthang; void SV_Frame (int msec) { int tmp_systime, tmp_hangtime; static int old_systime = 0; if (!old_systime) old_systime = Sys_Milliseconds (); time_before_game = time_after_game = 0; // if server is not active, do nothing if (!svs.initialized) return; svs.realtime += msec; // keep the random time dependent rand (); // check timeouts SV_CheckTimeouts (); // get packets from clients SV_ReadPackets (); // move autonomous things around if enough time has passed if (!sv_timedemo->integer && svs.realtime < sv.time) { // never let the time get too far off if (sv.time - svs.realtime > 100) { if (sv_showclamp->integer) Com_Printf ("sv lowclamp\n"); svs.realtime = sv.time - 100; } NET_Sleep(sv.time - svs.realtime); return; } // update ping based on the last known frame from all clients SV_CalcPings (); // give the clients some timeslices SV_GiveMsec (); // let everything in the world think and move SV_RunGameFrame (); // send messages back to the clients that had packets read this frame SV_SendClientMessages (); // save the entire world state if recording a serverdemo SV_RecordDemoMessage (); // send a heartbeat to the master if needed Master_Heartbeat (); // clear teleport flags, etc for next frame SV_PrepWorldFrame (); tmp_systime = Sys_Milliseconds (); tmp_hangtime = tmp_systime-old_systime; old_systime = tmp_systime; if (tmp_hangtime > 150) { sys_lasthang = tmp_systime; } } //============================================================================ /* ================ Master_Heartbeat Send a message to the master every few minutes to let it know we are alive, and log information ================ */ #define HEARTBEAT_SECONDS 300 void Master_Heartbeat (void) { char string[MAX_MSGLEN]; // pgm post3.19 change, cvar pointer not validated before dereferencing if(!public_server || !public_server->integer) return; // check for time wraparound if (svs.last_heartbeat > svs.realtime) svs.last_heartbeat = svs.realtime; if (svs.realtime - svs.last_heartbeat < HEARTBEAT_SECONDS*1000) return; // not time to send yet svs.last_heartbeat = svs.realtime; // send the same string that we would give for a status OOB command Com_sprintf (string, MAX_MSGLEN, "heartbeat\n%s", SV_StatusString ()); SV_HandleMasters (string, "heartbeat"); } /* ================= Master_Shutdown Informs all masters that this server is going down ================= */ void Master_Shutdown (void) { // pgm post3.19 change, cvar pointer not validated before dereferencing if (!public_server || !public_server->integer) return; // a private dedicated game SV_HandleMasters ("shutdown", "shutdown"); } /* ================= SV_HandleMasters Sends a message to all master servers, looking up the master servers' addresses if appropriate. ================= */ void SV_HandleMasters (const char *message, const char *console_message) { int i; qboolean updated_master; // if the server is not dedicated, we need to check cl_master if ( !( dedicated && dedicated->integer ) ) { if ( !sv_master ) { sv_master = Cvar_Get ("cl_master", "master.corservers.com", CVAR_ARCHIVE); updated_master = true; } else if ( sv_master->modified ) { sv_master->modified = false; updated_master = true; } else { updated_master = false; } if ( updated_master ) { memset (&master_status[0], 0, sizeof(master_sv_t)); strncpy (master_status[0].name, sv_master->string, MAX_MASTER_LEN); } } // first we need to loop through the master servers // in order to find the ones that need (re-)resolving for ( i = 0; i < MAX_MASTERS ; i ++ ) { if ( master_status[i].name[0] == 0 ) break; // if we already sent a ping and didn't get // any acknowledgement packet, we need to try // re-resolving if ( master_status[i].resolved && master_status[i].last_ping_sent > master_status[i].last_ping_ack ) { Com_Printf ("No acknowledgement from %s - re-resolving\n", master_status[i].name); master_status[i].resolved = false; } if ( master_status[i].resolved ) continue; if (!NET_StringToAdr (master_status[i].name, &master_status[i].addr)) { // resolution failed, did we say so already? if ( !master_status[i].failed ) { Com_Printf ("Bad master address: %s\n", master_status[i].name); master_status[i].failed = true; } master_status[i].addr.port = 0; } else { master_status[i].failed = false; master_status[i].resolved = true; if (master_status[i].addr.port == 0) master_status[i].addr.port = BigShort (PORT_MASTER); Com_Printf ("Master server at %s\n", NET_AdrToString (master_status[i].addr)); } } // send the message we needed to send for ( i = 0 ; i < MAX_MASTERS ; i ++ ) { if ( master_status[i].name[0] == 0 ) break; if ( master_status[i].addr.port == 0 ) continue; Com_Printf ("Sending %s to %s\n", console_message, NET_AdrToString (master_status[i].addr)); Netchan_OutOfBandPrint (NS_SERVER, master_status[i].addr, "%s", message); master_status[i].last_ping_sent = 1; master_status[i].last_ping_ack = 0; } } //============================================================================ /* ================= SV_UserinfoChanged Pull specific info from a newly changed userinfo string into a more C freindly form. ================= */ void SV_UserinfoChanged (client_t *cl) { char *val; int i; // call prog code to allow overrides ge->ClientUserinfoChanged (cl->edict, cl->userinfo, 0); // name for C code Q_strncpyz2( cl->name, Info_ValueForKey (cl->userinfo, "name"), sizeof(cl->name) ); // mask off high bit for (i=0 ; iname) ; i++) cl->name[i] &= 127; // rate command val = Info_ValueForKey (cl->userinfo, "rate"); if (strlen(val)) { i = atoi(val); cl->rate = i; if (cl->rate < 100) cl->rate = 100; if (cl->rate > 15000) cl->rate = 15000; } else cl->rate = 5000; // msg command val = Info_ValueForKey (cl->userinfo, "msg"); if (strlen(val)) { cl->messagelevel = atoi(val); } } //============================================================================ /* =============== SV_Init Only called at quake2.exe startup, not for each game =============== */ void SV_Init (void) { SV_InitOperatorCommands (); rcon_password = Cvar_Get ("rcon_password", "", 0); Cvar_Get ("skill", "1", 0); Cvar_Get ("deathmatch", "1", CVAR_LATCH); //Alien Arena is *always* deathmatch Cvar_Get ("ctf", "0", CVAR_LATCH); Cvar_Get ("dmflags", va("%i", DF_INSTANT_ITEMS+DF_BOT_LEVELAD), CVAR_SERVERINFO); Cvar_Get ("fraglimit", "0", CVAR_SERVERINFO); Cvar_Get ("timelimit", "0", CVAR_SERVERINFO); Cvar_Get ("cheats", "0", CVAR_SERVERINFO|CVAR_LATCH); Cvar_Get ("protocol", va("%i", PROTOCOL_VERSION), CVAR_SERVERINFO|CVAR_NOSET);; maxclients = Cvar_Get ("maxclients", "1", CVAR_SERVERINFO | CVAR_LATCH); hostname = Cvar_Get ("hostname", "noname", CVAR_SERVERINFO | CVAR_ARCHIVE); timeout = Cvar_Get ("timeout", "125", 0); zombietime = Cvar_Get ("zombietime", "2", 0); sv_showclamp = Cvar_Get ("showclamp", "0", 0); sv_paused = Cvar_Get ("paused", "0", 0); sv_timedemo = Cvar_Get ("timedemo", "0", 0); sv_enforcetime = Cvar_Get ("sv_enforcetime", "0", 0); allow_download = Cvar_Get ("allow_download", "1", CVAR_ARCHIVE); allow_download_players = Cvar_Get ("allow_download_players", "0", CVAR_ARCHIVE); allow_download_models = Cvar_Get ("allow_download_models", "1", CVAR_ARCHIVE); allow_download_sounds = Cvar_Get ("allow_download_sounds", "1", CVAR_ARCHIVE); allow_download_maps = Cvar_Get ("allow_download_maps", "1", CVAR_ARCHIVE); sv_downloadurl = Cvar_Get("sv_downloadurl", "http://red.planetarena.org/sv_downloadurl", CVAR_SERVERINFO); sv_iplogfile = Cvar_Get("sv_iplogfile" , "" , CVAR_ARCHIVE); sv_noreload = Cvar_Get ("sv_noreload", "0", 0); sv_airaccelerate = Cvar_Get("sv_airaccelerate", "0", CVAR_LATCH); sv_joustmode = Cvar_Get("sv_joustmode", "0", CVAR_SERVERINFO); sv_tactical = Cvar_Get("g_tactical", "0", CVAR_LATCH | CVAR_GAMEINFO); sv_excessive = Cvar_Get("excessive", "0", CVAR_LATCH | CVAR_GAMEINFO); public_server = Cvar_Get ("sv_public", "1", 0); sv_reconnect_limit = Cvar_Get ("sv_reconnect_limit", "3", CVAR_ARCHIVE); sv_ratelimit_status = Cvar_Get ("sv_ratelimit_status", "15", 0); sv_iplimit = Cvar_Get ("sv_iplimit", "3", 0); SZ_Init (&net_message, net_message_buffer, sizeof(net_message_buffer)); SZ_SetName (&net_message, "Net message buffer", true); remoteserver_runspeed = 300; //default } /* ================== SV_FinalMessage Used by SV_Shutdown to send a final message to all connected clients before the server goes down. The messages are sent immediately, not just stuck on the outgoing message list, because the server is going to totally exit after returning from this function. ================== */ void SV_FinalMessage (char *message, qboolean reconnect) { int i; client_t *cl; SZ_Clear (&net_message); MSG_WriteByte (&net_message, svc_print); MSG_WriteByte (&net_message, PRINT_HIGH); MSG_WriteString (&net_message, message); if (reconnect) MSG_WriteByte (&net_message, svc_reconnect); else MSG_WriteByte (&net_message, svc_disconnect); // send it twice // stagger the packets to crutch operating system limited buffers for (i=0, cl = svs.clients ; iinteger ; i++, cl++) if (cl->state >= cs_connected) Netchan_Transmit (&cl->netchan, net_message.cursize , net_message.data); for (i=0, cl = svs.clients ; iinteger ; i++, cl++) if (cl->state >= cs_connected) Netchan_Transmit (&cl->netchan, net_message.cursize , net_message.data); } /* ================ SV_Shutdown Called when each game quits, before Sys_Quit or Sys_Error ================ */ void SV_Shutdown (char *finalmsg, qboolean reconnect) { extern void Con_Clear_f (void); if (svs.clients) SV_FinalMessage (finalmsg, reconnect); Master_Shutdown (); SV_ShutdownGameProgs (); // free current level if (sv.demofile) fclose (sv.demofile); memset (&sv, 0, sizeof(sv)); Com_SetServerState (sv.state); // free server static data if (svs.clients) Z_Free (svs.clients); if (svs.client_entities) Z_Free (svs.client_entities); if (svs.demofile) fclose (svs.demofile); memset (&svs, 0, sizeof(svs)); } qboolean IsVisible(vec3_t org1,vec3_t org2) { trace_t trace; trace = SV_Trace2 (org1, NULL, NULL, org2, NULL, MASK_VISIBILILITY); if (trace.fraction != 1) return false; return true; } alien-arena-7.66+dfsg/source/server/server.h0000600000175000017500000002727412161402010020103 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // server.h //define PARANOID // speed sapping error checking #include "qcommon/qcommon.h" #include "game/game.h" //============================================================================= typedef enum { ss_dead, // no map loaded ss_loading, // spawning level edicts ss_game, // actively running ss_cinematic, ss_demo, ss_pic } server_state_t; // some qc commands are only valid before the server has finished // initializing (precache commands, static sounds / objects, etc) typedef struct { server_state_t state; // precache commands are only valid during load qboolean attractloop; // running cinematics and demos for the local system only qboolean loadgame; // client begins should reuse existing entity unsigned time; // always sv.framenum * 100 msec int framenum; char name[MAX_QPATH]; // map name, or cinematic name struct cmodel_s *models[MAX_MODELS]; // client/server protocol depends on MAX_QPATH being 64. char configstrings[MAX_CONFIGSTRINGS][MAX_QPATH]; entity_state_t baselines[MAX_EDICTS]; // the multicast buffer is used to send a message to a set of clients // it is only used to marshall data until SV_Multicast is called sizebuf_t multicast; byte multicast_buf[MAX_MSGLEN]; // demo server information FILE *demofile; qboolean timedemo; // don't time sync size_t demosize; // in bytes size_t demo_ofs; // in bytes byte *demobuf; // full demo file contents } server_t; #define EDICT_NUM(n) ((edict_t *)((byte *)ge->edicts + ge->edict_size*(n))) #define NUM_FOR_EDICT(e) ( ((byte *)(e)-(byte *)ge->edicts ) / ge->edict_size) typedef unsigned long uint32; typedef struct ratelimit_s { int count; int period; uint32 time; } ratelimit_t; typedef enum { cs_free, // can be reused for a new connection cs_zombie, // client has been disconnected, but don't reuse // connection for a couple seconds cs_connected, // has been assigned to a client_t, but not in game yet cs_spawned // client is fully in game } client_state_t; typedef struct { int areabytes; byte areabits[MAX_MAP_AREAS/8]; // portalarea visibility bits player_state_t ps; int num_entities; int first_entity; // into the circular sv_packet_entities[] int senttime; // for ping calculations } client_frame_t; #define LATENCY_COUNTS 16 #define RATE_MESSAGES 10 typedef struct client_s { client_state_t state; char userinfo[MAX_INFO_STRING]; // name, etc int lastframe; // for delta compression usercmd_t lastcmd; // for filling in big drops int commandMsec; // every seconds this is reset, if user // commands exhaust it, assume time cheating int frame_latency[LATENCY_COUNTS]; int ping; int message_size[RATE_MESSAGES]; // used to rate drop packets int rate; int surpressCount; // number of messages rate supressed edict_t *edict; // EDICT_NUM(clientnum+1) char name[PLAYERNAME_SIZE]; // extracted from userinfo, high bits masked int messagelevel; // for filtering printed messages // The datagram is written to by sound calls, prints, temp ents, etc. // It can be harmlessly overflowed. sizebuf_t datagram; byte datagram_buf[MAX_MSGLEN]; client_frame_t frames[UPDATE_BACKUP]; // updates can be delta'd from here byte *download; // file being downloaded int downloadsize; // total bytes (can't use EOF because of paks) int downloadcount; // bytes sent int lastmessage; // sv.framenum when packet was last received int lastconnect; int challenge; // challenge of this user, randomly generated netchan_t netchan; //speed cheat detection; these numbers get reset every 12 seconds. int claimedmsec; // how many msec claimed by the client int lastresettime; // keeps track of 12-sec cycle int lasthang; // msec since last server hang } client_t; // a client can leave the server in one of four ways: // dropping properly by quiting or disconnecting // timing out if no valid messages are received for timeout.value seconds // getting kicked off by the server operator // a program error, like an overflowed reliable buffer //============================================================================= // MAX_CHALLENGES is made large to prevent a denial // of service attack that could cycle all of them // out before legitimate users connected #define MAX_CHALLENGES 1024 typedef struct { netadr_t adr; int challenge; int time; } challenge_t; typedef struct { qboolean initialized; // sv_init has completed int realtime; // always increasing, no clamping, etc char mapcmd[MAX_TOKEN_CHARS]; // ie: *intro.cin+base int spawncount; // incremented each server start // used to check late spawns client_t *clients; // [maxclients->value]; int num_client_entities; // maxclients->value*UPDATE_BACKUP*MAX_PACKET_ENTITIES int next_client_entities; // next client_entity to use entity_state_t *client_entities; // [num_client_entities] int last_heartbeat; challenge_t challenges[MAX_CHALLENGES]; // to prevent invalid IPs from connecting // serverrecord values FILE *demofile; sizebuf_t demo_multicast; byte demo_multicast_buf[MAX_MSGLEN]; // rate limit status requests ratelimit_t ratelimit_status; } server_static_t; //============================================================================= #define MAX_MASTERS 8 // max recipients for heartbeat packets #define MAX_MASTER_LEN 256 // Maximal length for the name of a master server typedef struct { qboolean resolved; // True if the server's address has been resolved once // and the server hasn't been unresponsive since then qboolean failed; // True if name resolution failed char name[MAX_MASTER_LEN]; // Name of the server from setmaster or cl_master netadr_t addr; // Resolved address of the server int last_ping_sent; // Time at which the last ping was sent int last_ping_ack; // Time at which the last ping acknowledgement was received } master_sv_t; extern master_sv_t master_status[MAX_MASTERS]; //============================================================================= extern netadr_t net_from; extern sizebuf_t net_message; extern server_static_t svs; // persistant server info extern server_t sv; // local server extern cvar_t *sv_paused; extern cvar_t *maxclients; extern cvar_t *sv_noreload; // don't reload level state when reentering extern cvar_t *sv_airaccelerate; // don't reload level state when reentering // development tool extern cvar_t *sv_enforcetime; extern client_t *sv_client; extern edict_t *sv_player; extern int sv_numbots; //=========================================================== // // sv_main.c // void SV_FinalMessage (char *message, qboolean reconnect); void SV_DropClient (client_t *drop); int SV_ModelIndex (char *name); int SV_SoundIndex (char *name); int SV_ImageIndex (char *name); int SV_CheckModelIndex (char *name); int SV_CheckSoundIndex (char *name); int SV_CheckImageIndex (char *name); void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg); void SV_ExecuteUserCommand (char *s); void SV_InitOperatorCommands (void); void SV_SendServerinfo (client_t *client); void SV_UserinfoChanged (client_t *cl); void SV_HandleMasters (const char *message, const char * console_message); void Master_Heartbeat (void); void Master_Packet (void); void SV_KickClient (client_t *cl, const char /*@null@*/*reason, const char /*@null@*/*cprintf); // // sv_init.c // void SV_InitGame (void); void SV_Map (qboolean attractloop, char *levelstring, qboolean loadgame); extern int server_port; cvar_t *sv_master; // // sv_phys.c // void SV_PrepWorldFrame (void); // // sv_send.c // typedef enum {RD_NONE, RD_CLIENT, RD_PACKET} redirect_t; #define SV_OUTPUTBUF_LENGTH (MAX_MSGLEN - 16) extern char sv_outputbuf[SV_OUTPUTBUF_LENGTH]; void SV_FlushRedirect (int sv_redirected, char *outputbuf); void SV_DemoCompleted (void); void SV_SendClientMessages (void); void SV_Multicast (vec3_t origin, multicast_t to); void SV_StartSound (vec3_t origin, edict_t *entity, int channel, int soundindex, float volume, float attenuation, float timeofs); void SV_ClientPrintf (client_t *cl, int level, char *fmt, ...); void SV_BroadcastPrintf (int level, char *fmt, ...); void SV_BroadcastCommand (char *fmt, ...); // // sv_user.c // void SV_Nextserver (void); void SV_ExecuteClientMessage (client_t *cl); // // sv_ccmds.c // void SV_Status_f (void); // // sv_ents.c // void SV_WriteFrameToClient (client_t *client, sizebuf_t *msg); void SV_RecordDemoMessage (void); void SV_BuildClientFrame (client_t *client); void SV_Error (char *error, ...); // // sv_game.c // extern game_export_t *ge; void SV_InitGameProgs (void); void SV_ShutdownGameProgs (void); void SV_InitEdict (edict_t *e); //============================================================ // // high level object sorting to reduce interaction tests // void SV_ClearWorld (void); // called after the world model has been loaded, before linking any entities void SV_UnlinkEdict (edict_t *ent); // call before removing an entity, and before trying to move one, // so it doesn't clip against itself void SV_LinkEdict (edict_t *ent); // Needs to be called any time an entity changes origin, mins, maxs, // or solid. Automatically unlinks if needed. // sets ent->v.absmin and ent->v.absmax // sets ent->leafnums[] for pvs determination even if the entity // is not solid int SV_AreaEdicts (vec3_t mins, vec3_t maxs, edict_t **list, int maxcount, int areatype); // fills in a table of edict pointers with edicts that have bounding boxes // that intersect the given area. It is possible for a non-axial bmodel // to be returned that doesn't actually intersect the area on an exact // test. // returns the number of pointers filled in // ??? does this always return the world? //=================================================================== // // functions that interact with everything apropriate // int SV_PointContents (vec3_t p); // returns the CONTENTS_* value from the world at the given point. // Quake 2 extends this to also check entities, to allow moving liquids trace_t SV_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passedict, int contentmask); // mins and maxs are relative // if the entire move stays in a solid volume, trace.allsolid will be set, // trace.startsolid will be set, and trace.fraction will be 0 // if the starting point is in a solid, it will be allowed to move out // to an open area // passedict is explicitly excluded from clipping checks (normally NULL) //trace without worrying about entities trace_t SV_Trace2 (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passedict, int contentmask); alien-arena-7.66+dfsg/source/server/sv_game.c0000600000175000017500000001737112161402010020206 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // sv_game.c -- interface to the game module #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "server.h" game_export_t *ge; /* =============== PF_Unicast Sends the contents of the mutlicast buffer to a single client =============== */ void PF_Unicast (edict_t *ent, qboolean reliable) { int p; client_t *client; if (!ent) return; p = NUM_FOR_EDICT(ent); if (p < 1 || p > maxclients->value) return; client = svs.clients + (p-1); if (reliable) SZ_Write (&client->netchan.message, sv.multicast.data, sv.multicast.cursize); else SZ_Write (&client->datagram, sv.multicast.data, sv.multicast.cursize); SZ_Clear (&sv.multicast); } /* =============== PF_dprintf Debug print to server console =============== */ void PF_dprintf (char *fmt, ...) { char msg[1024]; va_list argptr; va_start (argptr,fmt); vsnprintf(msg, sizeof(msg), fmt, argptr); va_end (argptr); Com_Printf ("%s", msg); } /* =============== PF_cprintf Print to a single client =============== */ void PF_cprintf (edict_t *ent, int level, char *fmt, ...) { char msg[1024]; va_list argptr; int n; if (ent) { n = NUM_FOR_EDICT(ent); if (n < 1 || n > maxclients->value) Com_Error (ERR_DROP, "cprintf to a non-client"); } va_start (argptr,fmt); vsnprintf(msg, sizeof(msg), fmt, argptr); va_end (argptr); if (ent) SV_ClientPrintf (svs.clients+(n-1), level, "%s", msg); else Com_Printf ("%s", msg); } /* =============== PF_centerprintf centerprint to a single client =============== */ void PF_centerprintf (edict_t *ent, char *fmt, ...) { char msg[1024]; va_list argptr; int n; n = NUM_FOR_EDICT(ent); if (n < 1 || n > maxclients->value) return; // Com_Error (ERR_DROP, "centerprintf to a non-client"); va_start (argptr,fmt); vsnprintf(msg, sizeof(msg), fmt, argptr); va_end (argptr); MSG_WriteByte (&sv.multicast,svc_centerprint); MSG_WriteString (&sv.multicast,msg); PF_Unicast (ent, true); } /* =============== PF_error Abort the server with a game error =============== */ void PF_error (char *fmt, ...) { char msg[1024]; va_list argptr; va_start (argptr,fmt); vsnprintf(msg, sizeof(msg), fmt, argptr); va_end (argptr); Com_Error (ERR_DROP, "Game Error: %s", msg); } /* ================= PF_setmodel Also sets mins and maxs for inline bmodels ================= */ void PF_setmodel (edict_t *ent, char *name) { int i; cmodel_t *mod; if (!name) return; //Com_Error (ERR_DROP, "PF_setmodel: NULL"); i = SV_ModelIndex (name); // ent->model = name; ent->s.modelindex = i; // if it is an inline model, get the size information for it if (name[0] == '*') { mod = CM_InlineModel (name); VectorCopy (mod->mins, ent->mins); VectorCopy (mod->maxs, ent->maxs); SV_LinkEdict (ent); } } /* =============== PF_Configstring =============== */ void PF_Configstring (int index, char *val) { if (index < 0 || index >= MAX_CONFIGSTRINGS) Com_Error (ERR_DROP, "configstring: bad index %i\n", index); if (!val) val = ""; // change the string in sv strcpy (sv.configstrings[index], val); if (sv.state != ss_loading) { // send the update to everyone SZ_Clear (&sv.multicast); MSG_WriteChar (&sv.multicast, svc_configstring); MSG_WriteShort (&sv.multicast, index); MSG_WriteString (&sv.multicast, val); SV_Multicast (vec3_origin, MULTICAST_ALL_R); } } void PF_WriteChar (int c) {MSG_WriteChar (&sv.multicast, c);} void PF_WriteByte (int c) {MSG_WriteByte (&sv.multicast, c);} void PF_WriteShort (int c) {MSG_WriteShort (&sv.multicast, c);} void PF_WriteLong (int c) {MSG_WriteLong (&sv.multicast, c);} void PF_WriteFloat (float f) {MSG_WriteFloat (&sv.multicast, f);} void PF_WriteString (char *s) {MSG_WriteString (&sv.multicast, s);} void PF_WritePos (vec3_t pos) {MSG_WritePos (&sv.multicast, pos);} void PF_WriteDir (vec3_t dir) {MSG_WriteDir (&sv.multicast, dir);} void PF_WriteAngle (float f) {MSG_WriteAngle (&sv.multicast, f);} void PF_StartSound (edict_t *entity, int channel, int sound_num, float volume, float attenuation, float timeofs) { if (!entity) return; SV_StartSound (NULL, entity, channel, sound_num, volume, attenuation, timeofs); } //============================================== /* =============== SV_ShutdownGameProgs Called when either the entire server is being killed, or it is changing to a different game directory. =============== */ void SV_ShutdownGameProgs (void) { if (!ge) return; ge->Shutdown (); Sys_UnloadGame (); ge = NULL; } /* =============== SV_InitGameProgs Init the game subsystem for a new map =============== */ void SCR_DebugGraph (float value, const float color[]); void SV_InitGameProgs (void) { game_import_t import; // unload anything we have now if (ge) SV_ShutdownGameProgs (); // load a new game dll import.multicast = SV_Multicast; import.unicast = PF_Unicast; import.bprintf = SV_BroadcastPrintf; import.dprintf = PF_dprintf; import.cprintf = PF_cprintf; import.centerprintf = PF_centerprintf; import.error = PF_error; import.linkentity = SV_LinkEdict; import.unlinkentity = SV_UnlinkEdict; import.BoxEdicts = SV_AreaEdicts; import.trace = SV_Trace; import.pointcontents = SV_PointContents; import.setmodel = PF_setmodel; import.inPVS = CM_inPVS; import.inPHS = CM_inPHS; import.Pmove = Pmove; import.modelindex = SV_ModelIndex; import.soundindex = SV_SoundIndex; import.imageindex = SV_ImageIndex; import.checkmodelindex = SV_CheckModelIndex; import.checksoundindex = SV_CheckSoundIndex; import.checkimageindex = SV_CheckImageIndex; import.configstring = PF_Configstring; import.sound = PF_StartSound; import.positioned_sound = SV_StartSound; import.WriteChar = PF_WriteChar; import.WriteByte = PF_WriteByte; import.WriteShort = PF_WriteShort; import.WriteLong = PF_WriteLong; import.WriteFloat = PF_WriteFloat; import.WriteString = PF_WriteString; import.WritePosition = PF_WritePos; import.WriteDir = PF_WriteDir; import.WriteAngle = PF_WriteAngle; import.TagMalloc = Z_TagMalloc; import.TagFree = Z_Free; import.FreeTags = Z_FreeTags; import.cvar = Cvar_Get; import.cvar_set = Cvar_Set; import.cvar_forceset = Cvar_ForceSet; import.cvar_describe = Cvar_Describe; import.argc = Cmd_Argc; import.argv = Cmd_Argv; import.args = Cmd_Args; import.AddCommandString = Cbuf_AddText; import.DebugGraph = SCR_DebugGraph; import.SetAreaPortalState = CM_SetAreaPortalState; import.AreasConnected = CM_AreasConnected; import.Sys_Milliseconds = Sys_Milliseconds; import.FullPath = FS_FullPath; import.FullWritePath = FS_FullWritePath; ge = (game_export_t *)Sys_GetGameAPI (&import); if (!ge) Com_Error (ERR_DROP, "failed to load game module"); if (ge->apiversion != GAME_API_VERSION) Com_Error (ERR_DROP, "game is version %i, not %i", ge->apiversion, GAME_API_VERSION); ge->Init (); } alien-arena-7.66+dfsg/source/server/sv_user.c0000600000175000017500000004722312161402010020252 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // sv_user.c -- server code for moving users #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "server.h" edict_t *sv_player; /* ============================================================ USER STRINGCMD EXECUTION sv_client and sv_player will be valid. ============================================================ */ /* ================== SV_BeginDemoServer ================== */ void SV_BeginDemoserver (void) { char name[MAX_OSPATH]; Com_sprintf (name, sizeof(name), "demos/%s", sv.name); FS_FOpenFile (name, &sv.demofile); if (!sv.demofile) Com_Error (ERR_DROP, "Couldn't open %s\n", name); sv.demo_ofs = 0; sv.demosize = FS_LoadFile (name, (void **)&sv.demobuf); } /* ================ SV_New_f Sends the first message from the server to a connected client. This will be sent on the initial connection and upon each server load. ================ */ void SV_New_f (void) { char *gamedir; int playernum; edict_t *ent; Com_DPrintf ("New() from %s\n", sv_client->name); if (sv_client->state != cs_connected) { Com_Printf ("New not valid -- already spawned\n"); return; } // demo servers just dump the file message if (sv.state == ss_demo) { SV_BeginDemoserver (); return; } // // serverdata needs to go over for all types of servers // to make sure the protocol is right, and to set the gamedir // gamedir = Cvar_VariableString ("gamedir"); // send the serverdata MSG_WriteByte (&sv_client->netchan.message, svc_serverdata); MSG_WriteLong (&sv_client->netchan.message, PROTOCOL_VERSION); MSG_WriteLong (&sv_client->netchan.message, svs.spawncount); MSG_WriteByte (&sv_client->netchan.message, sv.attractloop); MSG_WriteString (&sv_client->netchan.message, gamedir); if (sv.state == ss_cinematic || sv.state == ss_pic) playernum = -1; else playernum = sv_client - svs.clients; MSG_WriteShort (&sv_client->netchan.message, playernum); // send full levelname MSG_WriteString (&sv_client->netchan.message, sv.configstrings[CS_NAME]); // // game server // if (sv.state == ss_game) { // set up the entity for the client ent = EDICT_NUM(playernum+1); ent->s.number = playernum+1; sv_client->edict = ent; memset (&sv_client->lastcmd, 0, sizeof(sv_client->lastcmd)); // begin fetching configstrings MSG_WriteByte (&sv_client->netchan.message, svc_stufftext); MSG_WriteString (&sv_client->netchan.message, va("cmd configstrings %i 0\n",svs.spawncount) ); } } /* ================== SV_Configstrings_f ================== */ void SV_Configstrings_f (void) { int start; Com_DPrintf ("Configstrings() from %s\n", sv_client->name); if (sv_client->state != cs_connected) { Com_Printf ("configstrings not valid -- already spawned\n"); return; } // handle the case of a level changing while a client was connecting if ( atoi(Cmd_Argv(1)) != svs.spawncount ) { Com_Printf ("SV_Configstrings_f from different level\n"); SV_New_f (); return; } start = atoi(Cmd_Argv(2)); if( start < 0 ) { start = 0; // sku - catch negative offsets } // write a packet full of data while ( sv_client->netchan.message.cursize < MAX_MSGLEN/4 && start < MAX_CONFIGSTRINGS) { if (sv.configstrings[start][0]) { int length; // sku - write configstrings that exceed MAX_QPATH in proper-sized chunks length = strlen( sv.configstrings[start] ); if( length > MAX_QPATH ) { length = MAX_QPATH; } MSG_WriteByte (&sv_client->netchan.message, svc_configstring); MSG_WriteShort (&sv_client->netchan.message, start); SZ_Write (&sv_client->netchan.message, sv.configstrings[start], length); MSG_WriteByte (&sv_client->netchan.message, 0); } start++; } // send next command if (start == MAX_CONFIGSTRINGS) { MSG_WriteByte (&sv_client->netchan.message, svc_stufftext); MSG_WriteString (&sv_client->netchan.message, va("cmd baselines %i 0\n",svs.spawncount) ); } else { MSG_WriteByte (&sv_client->netchan.message, svc_stufftext); MSG_WriteString (&sv_client->netchan.message, va("cmd configstrings %i %i\n",svs.spawncount, start) ); } } /* ================== SV_Baselines_f ================== */ void SV_Baselines_f (void) { int start; entity_state_t nullstate; entity_state_t *base; Com_DPrintf ("Baselines() from %s\n", sv_client->name); if (sv_client->state != cs_connected) { Com_Printf ("baselines not valid -- already spawned\n"); return; } // handle the case of a level changing while a client was connecting if ( atoi(Cmd_Argv(1)) != svs.spawncount ) { Com_Printf ("SV_Baselines_f from different level\n"); SV_New_f (); return; } start = atoi(Cmd_Argv(2)); if( start < 0 ) { start = 0; } memset (&nullstate, 0, sizeof(nullstate)); // write a packet full of data while ( sv_client->netchan.message.cursize < MAX_MSGLEN/4 && start < MAX_EDICTS) { base = &sv.baselines[start]; if (base->modelindex || base->sound || base->effects) { MSG_WriteByte (&sv_client->netchan.message, svc_spawnbaseline); MSG_WriteDeltaEntity (&nullstate, base, &sv_client->netchan.message, true, true); } start++; } // send next command if (start == MAX_EDICTS) { MSG_WriteByte (&sv_client->netchan.message, svc_stufftext); MSG_WriteString (&sv_client->netchan.message, va("precache %i\n", svs.spawncount) ); } else { MSG_WriteByte (&sv_client->netchan.message, svc_stufftext); MSG_WriteString (&sv_client->netchan.message, va("cmd baselines %i %i\n",svs.spawncount, start) ); } } /* ================== SV_Begin_f ================== */ void SV_Begin_f (void) { Com_DPrintf ("Begin() from %s\n", sv_client->name); // handle the case of a level changing while a client was connecting if ( atoi(Cmd_Argv(1)) != svs.spawncount ) { Com_Printf ("SV_Begin_f from different level\n"); SV_New_f (); return; } sv_client->state = cs_spawned; // call the game begin function ge->ClientBegin (sv_player); Cbuf_InsertFromDefer (); } //============================================================================= /* ================== SV_NextDownload_f ================== */ void SV_NextDownload_f (void) { int r; int percent; int size; if (!sv_client->download) return; r = sv_client->downloadsize - sv_client->downloadcount; if (r > 1280) //was 1024 should speed up r = 1280; MSG_WriteByte (&sv_client->netchan.message, svc_download); MSG_WriteShort (&sv_client->netchan.message, r); sv_client->downloadcount += r; size = sv_client->downloadsize; if (!size) size = 1; percent = sv_client->downloadcount*100/size; MSG_WriteByte (&sv_client->netchan.message, percent); SZ_Write (&sv_client->netchan.message, sv_client->download + sv_client->downloadcount - r, r); if (sv_client->downloadcount != sv_client->downloadsize) return; FS_FreeFile (sv_client->download); sv_client->download = NULL; } /* ================== SV_BeginDownload_f ================== */ void SV_BeginDownload_f(void) { char *name; extern cvar_t *allow_download; extern cvar_t *allow_download_players; extern cvar_t *allow_download_models; extern cvar_t *allow_download_sounds; extern cvar_t *allow_download_maps; int name_length; // For getting the final character. int offset = 0; name = Cmd_Argv(1); if (Cmd_Argc() > 2) offset = atoi(Cmd_Argv(2)); // downloaded offset // hacked by zoid to allow more conrol over download // first off, no .. or global allow check if (strstr (name, "..") || !allow_download->value // prevent config downloading on Win32 systems || name[0] == '\\' // negative offset causes crashing || offset < 0 // leading dot is no good || *name == '.' // leading slash bad as well, must be in subdir || *name == '/' // next up, skin check || (strncmp(name, "players/", 8) == 0 && !allow_download_players->value) // now models || (strncmp(name, "models/", 7) == 0 && !allow_download_models->value) // now sounds || (strncmp(name, "sound/", 6) == 0 && !allow_download_sounds->value) // now maps (note special case for maps, must not be in pak) || (strncmp(name, "maps/", 5) == 0 && !allow_download_maps->value) // MUST be in a subdirectory || !strstr (name, "/") ) { // don't allow anything with .. path MSG_WriteByte (&sv_client->netchan.message, svc_download); MSG_WriteShort (&sv_client->netchan.message, -1); MSG_WriteByte (&sv_client->netchan.message, 0); return; } // If the name ends in a slash or dot, hack it off. Continue to do so just // in case some tricky fellow puts multiple slashes or dots. while (name[(name_length = strlen(name))] == '.' || name[name_length] == '/' ) name[name_length] = '\0'; if (sv_client->download) FS_FreeFile (sv_client->download); sv_client->downloadsize = FS_LoadFile (name, (void **)&sv_client->download); sv_client->downloadcount = offset; if (offset > sv_client->downloadsize) sv_client->downloadcount = sv_client->downloadsize; if ( !sv_client->download ) { Com_DPrintf ("Could not download %s to %s\n", name, sv_client->name); if (sv_client->download) { FS_FreeFile (sv_client->download); sv_client->download = NULL; } MSG_WriteByte (&sv_client->netchan.message, svc_download); MSG_WriteShort (&sv_client->netchan.message, -1); MSG_WriteByte (&sv_client->netchan.message, 0); return; } SV_NextDownload_f (); Com_DPrintf ("Downloading %s to %s\n", name, sv_client->name); } //============================================================================ /* ================= SV_Disconnect_f The client is going to disconnect, so remove the connection immediately ================= */ void SV_Disconnect_f (void) { // SV_EndRedirect (); SV_DropClient (sv_client); } /* ================== SV_ShowServerinfo_f Dumps the serverinfo info string ================== */ void SV_ShowServerinfo_f (void) { //Info_Print (Cvar_Serverinfo()); } void SV_Nextserver (void) { char *v; //ZOID, ss_pic can be nextserver'd in coop mode if (sv.state == ss_game || sv.state == ss_pic) return; // can't nextserver while playing a normal game svs.spawncount++; // make sure another doesn't sneak in v = Cvar_VariableString ("nextserver"); if (!v[0]) Cbuf_AddText ("killserver\n"); else { Cbuf_AddText (v); Cbuf_AddText ("\n"); } Cvar_Set ("nextserver",""); } /* ================== SV_Nextserver_f A cinematic has completed or been aborted by a client, so move to the next server, ================== */ void SV_Nextserver_f (void) { if ( atoi(Cmd_Argv(1)) != svs.spawncount ) { Com_DPrintf ("Nextserver() from wrong level, from %s\n", sv_client->name); return; // leftover from last server } Com_DPrintf ("Nextserver() from %s\n", sv_client->name); SV_Nextserver (); } typedef struct { char *name; void (*func) (void); } ucmd_t; ucmd_t ucmds[] = { // auto issued {"new", SV_New_f}, {"configstrings", SV_Configstrings_f}, {"baselines", SV_Baselines_f}, {"begin", SV_Begin_f}, {"nextserver", SV_Nextserver_f}, {"disconnect", SV_Disconnect_f}, // issued by hand at client consoles {"info", SV_ShowServerinfo_f}, {"download", SV_BeginDownload_f}, {"nextdl", SV_NextDownload_f}, {NULL, NULL} }; /* ================== SV_ExecuteUserCommand ================== */ void SV_ExecuteUserCommand (char *s) { ucmd_t *u; Cmd_TokenizeString (s, false); sv_player = sv_client->edict; // SV_BeginRedirect (RD_CLIENT); for (u=ucmds ; u->name ; u++) if (!strcmp (Cmd_Argv(0), u->name) ) { u->func (); break; } if (!u->name && sv.state == ss_game) ge->ClientCommand (sv_player); // SV_EndRedirect (); } /* =========================================================================== USER CMD EXECUTION =========================================================================== */ void SV_ClientThink (client_t *cl, usercmd_t *cmd) { cl->commandMsec -= cmd->msec; ge->ClientThink (cl->edict, cmd); } #define MAX_STRINGCMDS 8 /* =================== SV_ExecuteClientMessage The current net_message is parsed for the given client =================== */ int sys_msec_as_of_packet_read = 0; int sys_lasthang = 0; static char *timestamp( void ) { static char utc_string[256]; struct tm *utc; time_t now; now = time( NULL ); utc = gmtime( &now ); sprintf( utc_string, "%s", asctime( utc ) ); utc_string[ strlen(utc_string)-1] = '\0'; // remove \n return utc_string; } static char *ipaddr( client_t *cl ) { return NET_AdrToString( cl->netchan.remote_address ); } void SV_ExecuteClientMessage (client_t *cl) { int c; char *s; usercmd_t nullcmd; usercmd_t oldest, oldcmd, newcmd; int net_drop; int stringCmdCount; int checksum, calculatedChecksum; int checksumIndex; qboolean move_issued; int lastframe; float timeratio; sv_client = cl; sv_player = sv_client->edict; // only allow one move command move_issued = false; stringCmdCount = 0; while (1) { if (net_message.readcount > net_message.cursize) { Com_Printf( "PACKET: readcount > cursize from %s[%s] (UTC: %s)\n", cl->name, ipaddr(cl), timestamp() ); //formerly was drop client and return break; } c = MSG_ReadByte (&net_message); if (c == -1) break; switch (c) { default: Com_Printf ("PACKET: invalid command byte from %s[%s] (UTC: %s)\n", cl->name, ipaddr(cl), timestamp() ); //formerly was drop client and return break; case clc_nop: break; case clc_userinfo: Q_strncpyz2( cl->userinfo, MSG_ReadString (&net_message), sizeof(cl->userinfo) ); SV_UserinfoChanged (cl); break; case clc_move: checksumIndex = net_message.readcount; checksum = MSG_ReadByte (&net_message); lastframe = MSG_ReadLong (&net_message); if ( lastframe != cl->lastframe ) { cl->lastframe = lastframe; if ( cl->lastframe > 0 ) { cl->frame_latency[cl->lastframe & (LATENCY_COUNTS - 1)] = svs.realtime - cl->frames[cl->lastframe & UPDATE_MASK].senttime; } } memset (&nullcmd, 0, sizeof(nullcmd)); MSG_ReadDeltaUsercmd (&net_message, &nullcmd, &oldest); MSG_ReadDeltaUsercmd (&net_message, &oldest, &oldcmd); MSG_ReadDeltaUsercmd (&net_message, &oldcmd, &newcmd); // checks the lastframe and deltauser parts of command calculatedChecksum = COM_BlockSequenceCRCByte( net_message.data + checksumIndex + 1, // base net_message.readcount - checksumIndex - 1, // length cl->netchan.incoming_sequence ); // sequence if ( calculatedChecksum != checksum ) { Com_Printf( "PACKET: Failed command checksum for %s[%s] (%d != %d)/%d (UTC: %s)\n", cl->name, ipaddr(cl), calculatedChecksum, checksum, cl->netchan.incoming_sequence, timestamp() ); break; } if (cl->state == cs_spawned) { if ( move_issued ) { //only one clc_move per message Com_Printf( "EXPLOIT: multiple clc_move from %s[%s] (UTC: %s)\n", cl->name, ipaddr(cl), timestamp() ); SV_KickClient(cl, "illegal multiple clc_move commands", NULL ); return; } move_issued = true; //client clamps the msec byte to 250. should never issue msec //byte of zero. if (newcmd.msec > 250) { Com_Printf( "EXPLOIT: illegal msec value from %s[%s], %d (UTC: %s)\n", cl->name, ipaddr(cl), newcmd.msec, timestamp() ); SV_KickClient (cl, "illegal pmove msec detected", NULL); return; } else if (newcmd.msec == 0) { Com_Printf( "EXPLOIT: 0 msec move from %s[%s] (UTC: %s)\n", cl->name, ipaddr(cl), timestamp() ); SV_KickClient (cl, "zero pmove msec detected", NULL); return; } if (sv_enforcetime->integer) { //Speed cheat detection-- speed cheats work by increasing //the amount of time a client says to simulate. This code //does a sanity check; if over any period of 12 seconds, //the client claims significantly more time than actually //elapsed, it is probably cheating. cl->claimedmsec += newcmd.msec; if (cl->lasthang > sys_lasthang) { //This can happen with an integer overflow cl->lasthang = sys_lasthang; } if (sys_msec_as_of_packet_read < cl->lastresettime) { //This can happen with either a map change or an //integer overflow after around 25 days on the same //map. In this case, we just throw out all the data. cl->lastresettime = sys_msec_as_of_packet_read; cl->claimedmsec = 0; } else if (sys_lasthang > cl->lasthang) { //The server has hung on the boundary of the 12- //second interval. The data is invalid. cl->lastresettime = sys_msec_as_of_packet_read; cl->claimedmsec = 0; cl->lasthang = sys_lasthang; } else if (sys_msec_as_of_packet_read - cl->lastresettime >= 12000) { //This ratio should almost never be more than 1. If //it's more than 1.05, someone's probably trying to //cheat. timeratio = (float)cl->claimedmsec/(float)(sys_msec_as_of_packet_read - cl->lastresettime); if (timeratio > 1.05) { Com_Printf ( "EXPLOIT: Client %s[%s] is trying to go approximately %4.2f times faster than normal! (UTC: %s)\n", cl->name, ipaddr( cl ), timeratio, timestamp() ); SV_KickClient (cl, va ("illegal pmove msec scaling by %4.2f detected", timeratio), NULL); return; } cl->lastresettime = sys_msec_as_of_packet_read; cl->claimedmsec = 0; } } } if ( cl->state != cs_spawned ) { cl->lastframe = -1; break; } if (!sv_paused->value) { net_drop = cl->netchan.dropped; if ( net_drop > 0 ) { /* when packets are dropped, or out of sequence * execute backup commands. if drop is more than * 2, there is a problem; formerly, was executing * the last command multiple times, but that does * not seem to make sense. */ if ( net_drop > 2 ) { Com_Printf( "PACKET: net_drop is %i for %s[%s] (UTC: %s)\n", net_drop, cl->name, ipaddr( cl ), timestamp() ); } if (net_drop > 1) SV_ClientThink (cl, &oldest); SV_ClientThink (cl, &oldcmd); } SV_ClientThink (cl, &newcmd); } cl->lastcmd = newcmd; break; case clc_stringcmd: s = MSG_ReadString (&net_message); // malicious users may try using too many string commands if (++stringCmdCount < MAX_STRINGCMDS) SV_ExecuteUserCommand (s); else { Com_Printf( "EXPLOIT: too many clc_stringcmd from %s[%s] (UTC: %s)\n", cl->name, ipaddr( cl ), timestamp() ); } if (cl->state == cs_zombie) return; // disconnect command break; } } } alien-arena-7.66+dfsg/source/server/sv_send.c0000600000175000017500000003404712161402010020225 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // sv_send.c #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "server.h" #include "stdint.h" /* ============================================================================= Com_Printf redirection ============================================================================= */ char sv_outputbuf[SV_OUTPUTBUF_LENGTH]; void SV_FlushRedirect (int sv_redirected, char *outputbuf) { if (sv_redirected == RD_PACKET) { Netchan_OutOfBandPrint (NS_SERVER, net_from, "print\n%s", outputbuf); } else if (sv_redirected == RD_CLIENT) { MSG_WriteByte (&sv_client->netchan.message, svc_print); MSG_WriteByte (&sv_client->netchan.message, PRINT_HIGH); MSG_WriteString (&sv_client->netchan.message, outputbuf); } } /* ============================================================================= EVENT MESSAGES ============================================================================= */ /* ================= SV_ClientPrintf Sends text across to be displayed if the level passes ================= */ void SV_ClientPrintf (client_t *cl, int level, char *fmt, ...) { va_list argptr; char string[1024]; if (level < cl->messagelevel) return; va_start (argptr,fmt); vsnprintf(string, sizeof(string), fmt, argptr); va_end (argptr); MSG_WriteByte (&cl->netchan.message, svc_print); MSG_WriteByte (&cl->netchan.message, level); MSG_WriteString (&cl->netchan.message, string); } /* ================= SV_BroadcastPrintf Sends text to all active clients ================= */ void SV_BroadcastPrintf (int level, char *fmt, ...) { va_list argptr; char string[2048]; client_t *cl; int i; va_start (argptr,fmt); vsnprintf(string, sizeof(string), fmt, argptr); va_end (argptr); // echo to console if (dedicated->value) { char copy[1024]; int i; // mask off high bits for (i=0 ; i<1023 && string[i] ; i++) copy[i] = string[i]&127; copy[i] = 0; Com_Printf ("%s", copy); } for (i=0, cl = svs.clients ; ivalue; i++, cl++) { if (level < cl->messagelevel) continue; if (cl->state != cs_spawned) continue; MSG_WriteByte (&cl->netchan.message, svc_print); MSG_WriteByte (&cl->netchan.message, level); MSG_WriteString (&cl->netchan.message, string); } } /* ================= SV_BroadcastCommand Sends text to all active clients ================= */ void SV_BroadcastCommand (char *fmt, ...) { va_list argptr; char string[1024]; if (!sv.state) return; va_start (argptr,fmt); vsnprintf(string, sizeof(string), fmt, argptr); va_end (argptr); MSG_WriteByte (&sv.multicast, svc_stufftext); MSG_WriteString (&sv.multicast, string); SV_Multicast (NULL, MULTICAST_ALL_R); } /* ================= SV_Multicast Sends the contents of sv.multicast to a subset of the clients, then clears sv.multicast. MULTICAST_ALL same as broadcast (origin can be NULL) MULTICAST_PVS send to clients potentially visible from org MULTICAST_PHS send to clients potentially hearable from org ================= */ void SV_Multicast (vec3_t origin, multicast_t to) { client_t *client; byte *mask; int leafnum, cluster; int j; qboolean reliable; int area1, area2; /* 2011-11 Remove redundancy, was calling CM_PointLeafnum(origin) twice * for every PVS/PHS message. Was doing unnecessary check on client * location for PVS/PHS. Both minor performance hits. */ // if doing a serverrecord, store everything if (svs.demofile) SZ_Write (&svs.demo_multicast, sv.multicast.data, sv.multicast.cursize); reliable = false; mask = NULL; area1 = 0; switch (to) { case MULTICAST_ALL_R: reliable = true; // intentional fallthrough case MULTICAST_ALL: break; case MULTICAST_PHS_R: reliable = true; // intentional fallthrough case MULTICAST_PHS: // location for source of the sound that may be hearable leafnum = CM_PointLeafnum (origin); area1 = CM_LeafArea (leafnum); cluster = CM_LeafCluster (leafnum); mask = CM_ClusterPHS (cluster); break; case MULTICAST_PVS_R: reliable = true; // intentional fallthrough case MULTICAST_PVS: // location for entity or effect that may be visible leafnum = CM_PointLeafnum (origin); area1 = CM_LeafArea (leafnum); cluster = CM_LeafCluster (leafnum); mask = CM_ClusterPVS (cluster); break; default: Com_Error (ERR_FATAL, "SV_Multicast: bad to:%i", to); } // send the data to all relevent clients for ( j=maxclients->integer, client=svs.clients ; j-- ; client++ ) { if (client->state == cs_free || client->state == cs_zombie) continue; if (client->state != cs_spawned && !reliable) continue; if (mask) { // check for "hearable" or "visible" // find cluster player is in leafnum = CM_PointLeafnum (client->edict->s.origin); cluster = CM_LeafCluster (leafnum); if ( !(mask[cluster>>3] & (1<<(cluster & 7))) ) continue; // by cluster mask, player cannot see/hear this area2 = CM_LeafArea (leafnum); if (!CM_AreasConnected (area1, area2)) continue; // by leaf, player cannot see/hear this } if (reliable) SZ_Write (&client->netchan.message, sv.multicast.data, sv.multicast.cursize); else SZ_Write (&client->datagram, sv.multicast.data, sv.multicast.cursize); } SZ_Clear (&sv.multicast); } /* ================== SV_StartSound Each entity can have eight independant sound sources, like voice, weapon, feet, etc. If cahnnel & 8, the sound will be sent to everyone, not just things in the PHS. FIXME: if entity isn't in PHS, they must be forced to be sent or have the origin explicitly sent. Channel 0 is an auto-allocate channel, the others override anything already running on that entity/channel pair. An attenuation of 0 will play full volume everywhere in the level. Larger attenuations will drop off. (max 4 attenuation) Timeofs can range from 0.0 to 0.1 to cause sounds to be started later in the frame than they normally would. If origin is NULL, the origin is determined from the entity origin or the midpoint of the entity box for bmodels. ================== */ void SV_StartSound (vec3_t origin, edict_t *entity, int channel, int soundindex, float volume, float attenuation, float timeofs) { int sendchan; int flags; int i; int ent; vec3_t origin_v; qboolean use_phs; if (volume < 0 || volume > 1.0) Com_Error (ERR_FATAL, "SV_StartSound: volume = %f", volume); if (attenuation < 0 || attenuation > 4) Com_Error (ERR_FATAL, "SV_StartSound: attenuation = %f", attenuation); // if (channel < 0 || channel > 15) // Com_Error (ERR_FATAL, "SV_StartSound: channel = %i", channel); if (timeofs < 0 || timeofs > 0.255) Com_Error (ERR_FATAL, "SV_StartSound: timeofs = %f", timeofs); ent = NUM_FOR_EDICT(entity); if (channel & 8) // no PHS flag { use_phs = false; channel &= 7; } else use_phs = true; sendchan = (ent<<3) | (channel&7); flags = 0; if (volume != DEFAULT_SOUND_PACKET_VOLUME) flags |= SND_VOLUME; if (attenuation != DEFAULT_SOUND_PACKET_ATTENUATION) flags |= SND_ATTENUATION; // the client doesn't know that bmodels have weird origins // the origin can also be explicitly set if ( (entity->svflags & SVF_NOCLIENT) || (entity->solid == SOLID_BSP) || origin ) flags |= SND_POS; // always send the entity number for channel overrides flags |= SND_ENT; if (timeofs) flags |= SND_OFFSET; // use the entity origin unless it is a bmodel or explicitly specified if (!origin) { origin = origin_v; if (entity->solid == SOLID_BSP) { for (i=0 ; i<3 ; i++) origin_v[i] = entity->s.origin[i]+0.5*(entity->mins[i]+entity->maxs[i]); } else { VectorCopy (entity->s.origin, origin_v); } } MSG_WriteByte (&sv.multicast, svc_sound); MSG_WriteByte (&sv.multicast, flags); MSG_WriteByte (&sv.multicast, soundindex); if (flags & SND_VOLUME) MSG_WriteByte (&sv.multicast, volume*255); if (flags & SND_ATTENUATION) MSG_WriteByte (&sv.multicast, attenuation*64); if (flags & SND_OFFSET) MSG_WriteByte (&sv.multicast, timeofs*1000); if (flags & SND_ENT) MSG_WriteShort (&sv.multicast, sendchan); if (flags & SND_POS) MSG_WritePos (&sv.multicast, origin); // if the sound doesn't attenuate,send it to everyone // (global radio chatter, voiceovers, etc) if (attenuation == ATTN_NONE) use_phs = false; if (channel & CHAN_RELIABLE) { if (use_phs) SV_Multicast (origin, MULTICAST_PHS_R); else SV_Multicast (origin, MULTICAST_ALL_R); } else { if (use_phs) SV_Multicast (origin, MULTICAST_PHS); else SV_Multicast (origin, MULTICAST_ALL); } } /* =============================================================================== FRAME UPDATES =============================================================================== */ /* ======================= SV_SendClientDatagram ======================= */ qboolean SV_SendClientDatagram (client_t *client) { byte msg_buf[MAX_MSGLEN]; sizebuf_t msg; SV_BuildClientFrame (client); SZ_Init (&msg, msg_buf, sizeof(msg_buf)); SZ_SetName (&msg, va("Client msg out buffer (%s)", NET_AdrToString(client->netchan.remote_address)), false); msg.allowoverflow = true; // send over all the relevant entity_state_t // and the player_state_t SV_WriteFrameToClient (client, &msg); // copy the accumulated multicast datagram // for this client out to the message // it is necessary for this to be after the WriteEntities // so that entity references will be current if (client->datagram.overflowed) Com_Printf ("WARNING: datagram overflowed for %s\n", client->name); else SZ_Write (&msg, client->datagram.data, client->datagram.cursize); SZ_Clear (&client->datagram); if (msg.overflowed) { // must have room left for the packet header Com_Printf ("WARNING: msg overflowed for %s\n", client->name); SZ_Clear (&msg); } // send the datagram Netchan_Transmit (&client->netchan, msg.cursize, msg.data); // record the size for rate estimation client->message_size[sv.framenum % RATE_MESSAGES] = msg.cursize; return true; } /* ================== SV_DemoCompleted ================== */ void SV_DemoCompleted (void) { if (sv.demofile) { fclose (sv.demofile); sv.demofile = NULL; FS_FreeFile (sv.demobuf); sv.demosize = sv.demo_ofs = 0; } SV_Nextserver (); } /* ======================= SV_RateDrop Returns true if the client is over its current bandwidth estimation and should not be sent another packet ======================= */ qboolean SV_RateDrop (client_t *c) { int total; int i; // never drop over the loopback if (c->netchan.remote_address.type == NA_LOOPBACK) return false; total = 0; for (i = 0 ; i < RATE_MESSAGES ; i++) { total += c->message_size[i]; } if (total > c->rate) { c->surpressCount++; c->message_size[sv.framenum % RATE_MESSAGES] = 0; return true; } return false; } /* ======================= SV_SendClientMessages ======================= */ void SV_SendClientMessages (void) { int i; client_t *c; int msglen; byte msgbuf[MAX_MSGLEN]; msglen = 0; // read the next demo message if needed if (sv.state == ss_demo && sv.demofile) { if (sv_paused->value) msglen = 0; else { // get the next message if (sv.demo_ofs+4 >= sv.demosize) { SV_DemoCompleted (); return; } msglen = *(int32_t *)(sv.demobuf+sv.demo_ofs); msglen = LittleLong (msglen); sv.demo_ofs += sizeof (int32_t); if (msglen == -1) { SV_DemoCompleted (); return; } if (msglen > MAX_MSGLEN) Com_Error (ERR_DROP, "SV_SendClientMessages: msglen > MAX_MSGLEN"); if (sv.demo_ofs+msglen >= sv.demosize) { SV_DemoCompleted (); return; } memcpy (msgbuf, sv.demobuf+sv.demo_ofs, msglen); sv.demo_ofs += msglen; } } // send a message to each connected client for (i=0, c = svs.clients ; ivalue; i++, c++) { if (!c->state) continue; // if the reliable message overflowed, // drop the client if (c->netchan.message.overflowed) { SZ_Clear (&c->netchan.message); SZ_Clear (&c->datagram); SV_BroadcastPrintf (PRINT_HIGH, "%s overflowed\n", c->name); SV_DropClient (c); } if (sv.state == ss_cinematic || sv.state == ss_demo || sv.state == ss_pic ) Netchan_Transmit (&c->netchan, msglen, msgbuf); else if (c->state == cs_spawned) { // don't overrun bandwidth if (SV_RateDrop (c)) continue; SV_SendClientDatagram (c); } else { // not spawned /* send accumulated reliable messages when buffer has enough data * or when a time limit is reached whichever comes first. * time limit is 1 sec, buffer size trigger is 2800/4 = 700 * keeps UDP packets mostly below 1000 bytes. some capture data * collected 2012-11 indicated packets occasionally could exceed * 1500 bytes which is not good. Possible cause of some overflow * disconnects and other net comm problems. */ int timeout = curtime - c->netchan.last_sent ; int cursize = c->netchan.message.cursize ; if ( timeout > 1000 || cursize >= (MAX_MSGLEN)/4 ) { Netchan_Transmit( &c->netchan, 0, NULL ); } } } } alien-arena-7.66+dfsg/source/server/sv_world.c0000600000175000017500000003725312161402010020425 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // sv_world.c -- world query functions #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "server.h" /* =============================================================================== ENTITY AREA CHECKING FIXME: this use of "area" is different from the bsp file use =============================================================================== */ // (type *)STRUCT_FROM_LINK(link_t *link, type, member) // ent = STRUCT_FROM_LINK(link,entity_t,order) // FIXME: remove this mess! #define STRUCT_FROM_LINK(l,t,m) ((t *)((byte *)l - (ptrdiff_t)&(((t *)0)->m))) #define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area) typedef struct areanode_s { int axis; // -1 = leaf node float dist; struct areanode_s *children[2]; link_t trigger_edicts; link_t solid_edicts; } areanode_t; #define AREA_DEPTH 4 #define AREA_NODES 32 areanode_t sv_areanodes[AREA_NODES]; int sv_numareanodes; float *area_mins, *area_maxs; edict_t **area_list; int area_count, area_maxcount; int area_type; int SV_HullForEntity (edict_t *ent); // ClearLink is used for new headnodes void ClearLink (link_t *l) { l->prev = l->next = l; } void RemoveLink (link_t *l) { l->next->prev = l->prev; l->prev->next = l->next; } void InsertLinkBefore (link_t *l, link_t *before) { l->next = before; l->prev = before->prev; l->prev->next = l; l->next->prev = l; } /* =============== SV_CreateAreaNode Builds a uniformly subdivided tree for the given world size =============== */ areanode_t *SV_CreateAreaNode (int depth, vec3_t mins, vec3_t maxs) { areanode_t *anode; vec3_t size; vec3_t mins1, maxs1, mins2, maxs2; anode = &sv_areanodes[sv_numareanodes]; sv_numareanodes++; ClearLink (&anode->trigger_edicts); ClearLink (&anode->solid_edicts); if (depth == AREA_DEPTH) { anode->axis = -1; anode->children[0] = anode->children[1] = NULL; return anode; } VectorSubtract (maxs, mins, size); if (size[0] > size[1]) anode->axis = 0; else anode->axis = 1; anode->dist = 0.5 * (maxs[anode->axis] + mins[anode->axis]); VectorCopy (mins, mins1); VectorCopy (mins, mins2); VectorCopy (maxs, maxs1); VectorCopy (maxs, maxs2); maxs1[anode->axis] = mins2[anode->axis] = anode->dist; anode->children[0] = SV_CreateAreaNode (depth+1, mins2, maxs2); anode->children[1] = SV_CreateAreaNode (depth+1, mins1, maxs1); return anode; } /* =============== SV_ClearWorld =============== */ void SV_ClearWorld (void) { memset (sv_areanodes, 0, sizeof(sv_areanodes)); sv_numareanodes = 0; SV_CreateAreaNode (0, sv.models[1]->mins, sv.models[1]->maxs); } /* =============== SV_UnlinkEdict =============== */ void SV_UnlinkEdict (edict_t *ent) { if (!ent->area.prev) return; // not linked in anywhere RemoveLink (&ent->area); ent->area.prev = ent->area.next = NULL; } /* =============== SV_LinkEdict =============== */ #define MAX_TOTAL_ENT_LEAFS 128 void SV_LinkEdict (edict_t *ent) { areanode_t *node; int leafs[MAX_TOTAL_ENT_LEAFS]; int clusters[MAX_TOTAL_ENT_LEAFS]; int num_leafs; int i, j, k; int area; int topnode; if (ent->area.prev) SV_UnlinkEdict (ent); // unlink from old position if (ent == ge->edicts) return; // don't add the world if (!ent->inuse) return; // set the size VectorSubtract (ent->maxs, ent->mins, ent->size); // encode the size into the entity_state for client prediction if (ent->solid == SOLID_BBOX && !(ent->svflags & SVF_DEADMONSTER)) { // assume that x/y are equal and symetric i = ent->maxs[0]/8; if (i<1) i = 1; if (i>31) i = 31; // z is not symetric j = (-ent->mins[2])/8; if (j<1) j = 1; if (j>31) j = 31; // and z maxs can be negative... k = (ent->maxs[2]+32)/8; if (k<1) k = 1; if (k>63) k = 63; ent->s.solid = (k<<10) | (j<<5) | i; } else if (ent->solid == SOLID_BSP) { ent->s.solid = 31; // a solid_bbox will never create this value } else ent->s.solid = 0; // set the abs box if (ent->solid == SOLID_BSP && (ent->s.angles[0] || ent->s.angles[1] || ent->s.angles[2]) ) { // expand for rotation float max, v; int i; max = 0; for (i=0 ; i<3 ; i++) { v =fabs( ent->mins[i]); if (v > max) max = v; v =fabs( ent->maxs[i]); if (v > max) max = v; } for (i=0 ; i<3 ; i++) { ent->absmin[i] = ent->s.origin[i] - max; ent->absmax[i] = ent->s.origin[i] + max; } } else { // normal VectorAdd (ent->s.origin, ent->mins, ent->absmin); VectorAdd (ent->s.origin, ent->maxs, ent->absmax); } // because movement is clipped an epsilon away from an actual edge, // we must fully check even when bounding boxes don't quite touch ent->absmin[0] -= 1; ent->absmin[1] -= 1; ent->absmin[2] -= 1; ent->absmax[0] += 1; ent->absmax[1] += 1; ent->absmax[2] += 1; // link to PVS leafs ent->num_clusters = 0; ent->areanum = 0; ent->areanum2 = 0; //get all leafs, including solids num_leafs = CM_BoxLeafnums (ent->absmin, ent->absmax, leafs, MAX_TOTAL_ENT_LEAFS, &topnode); // set areas for (i=0 ; iareanum && ent->areanum != area) { if (ent->areanum2 && ent->areanum2 != area && sv.state == ss_loading) Com_DPrintf ("Object touching 3 areas at %f %f %f\n", ent->absmin[0], ent->absmin[1], ent->absmin[2]); ent->areanum2 = area; } else ent->areanum = area; } } if (num_leafs >= MAX_TOTAL_ENT_LEAFS) { // assume we missed some leafs, and mark by headnode ent->num_clusters = -1; ent->headnode = topnode; } else { ent->num_clusters = 0; for (i=0 ; inum_clusters == MAX_ENT_CLUSTERS) { // assume we missed some leafs, and mark by headnode ent->num_clusters = -1; ent->headnode = topnode; break; } ent->clusternums[ent->num_clusters++] = clusters[i]; } } } // if first time, make sure old_origin is valid if (!ent->linkcount) { VectorCopy (ent->s.origin, ent->s.old_origin); } ent->linkcount++; if (ent->solid == SOLID_NOT) return; // find the first node that the ent's box crosses node = sv_areanodes; while (1) { if (node->axis == -1) break; if (ent->absmin[node->axis] > node->dist) node = node->children[0]; else if (ent->absmax[node->axis] < node->dist) node = node->children[1]; else break; // crosses the node } // link it in if (ent->solid == SOLID_TRIGGER) InsertLinkBefore (&ent->area, &node->trigger_edicts); else InsertLinkBefore (&ent->area, &node->solid_edicts); } /* ==================== SV_AreaEdicts_r ==================== */ void SV_AreaEdicts_r (areanode_t *node) { link_t *l, *next, *start; edict_t *check; int count; count = 0; // touch linked edicts if (area_type == AREA_SOLID) start = &node->solid_edicts; else start = &node->trigger_edicts; for (l=start->next ; l != start ; l = next) { next = l->next; check = EDICT_FROM_AREA(l); if (check->solid == SOLID_NOT) continue; // deactivated if (check->absmin[0] > area_maxs[0] || check->absmin[1] > area_maxs[1] || check->absmin[2] > area_maxs[2] || check->absmax[0] < area_mins[0] || check->absmax[1] < area_mins[1] || check->absmax[2] < area_mins[2]) continue; // not touching if (area_count == area_maxcount) { Com_Printf ("SV_AreaEdicts: MAXCOUNT\n"); return; } area_list[area_count] = check; area_count++; } if (node->axis == -1) return; // terminal node // recurse down both sides if ( area_maxs[node->axis] > node->dist ) SV_AreaEdicts_r ( node->children[0] ); if ( area_mins[node->axis] < node->dist ) SV_AreaEdicts_r ( node->children[1] ); } /* ================ SV_AreaEdicts ================ */ int SV_AreaEdicts (vec3_t mins, vec3_t maxs, edict_t **list, int maxcount, int areatype) { area_mins = mins; area_maxs = maxs; area_list = list; area_count = 0; area_maxcount = maxcount; area_type = areatype; SV_AreaEdicts_r (sv_areanodes); return area_count; } //=========================================================================== /* ============= SV_PointContents ============= */ int SV_PointContents (vec3_t p) { edict_t *touch[MAX_EDICTS], *hit; int i, num; int contents, c2; int headnode; float *angles; // get base contents from world contents = CM_PointContents (p, sv.models[1]->headnode); // or in contents from all the other entities num = SV_AreaEdicts (p, p, touch, MAX_EDICTS, AREA_SOLID); for (i=0 ; is.angles; if (hit->solid != SOLID_BSP) angles = vec3_origin; // boxes don't rotate c2 = CM_TransformedPointContents (p, headnode, hit->s.origin, hit->s.angles); contents |= c2; } return contents; } typedef struct { vec3_t boxmins, boxmaxs;// enclose the test object along entire move float *mins, *maxs; // size of the moving object vec3_t mins2, maxs2; // size when clipping against mosnters float *start, *end; trace_t trace; edict_t *passedict; int contentmask; } moveclip_t; /* ================ SV_HullForEntity Returns a headnode that can be used for testing or clipping an object of mins/maxs size. Offset is filled in to contain the adjustment that must be added to the testing object's origin to get a point to use with the returned hull. ================ */ int SV_HullForEntity (edict_t *ent) { cmodel_t *model; // decide which clipping hull to use, based on the size if (ent->solid == SOLID_BSP) { // explicit hulls in the BSP model model = sv.models[ ent->s.modelindex ]; if (!model) Com_Error (ERR_FATAL, "MOVETYPE_PUSH with a non bsp model"); return model->headnode; } // create a temp hull from bounding box sizes return CM_HeadnodeForBox (ent->mins, ent->maxs); } //=========================================================================== /* ==================== SV_ClipMoveToEntities ==================== */ void SV_ClipMoveToEntities ( moveclip_t *clip ) { int i, num; edict_t *touchlist[MAX_EDICTS], *touch; trace_t trace; int headnode; float *angles; num = SV_AreaEdicts (clip->boxmins, clip->boxmaxs, touchlist , MAX_EDICTS, AREA_SOLID); // be careful, it is possible to have an entity in this // list removed before we get to it (killtriggered) for (i=0 ; isolid == SOLID_NOT) continue; if (touch == clip->passedict) continue; if (clip->trace.allsolid) return; if (clip->passedict) { if (touch->owner == clip->passedict) continue; // don't clip against own missiles if (clip->passedict->owner == touch) continue; // don't clip against owner // don't clip against teammates { int n, n2; n = NUM_FOR_EDICT (clip->passedict); n2 = NUM_FOR_EDICT (touch); if ( n > 0 && n <= maxclients->integer && n2 > 0 && n2 <= maxclients->integer && clip->passedict->teamset && touch->teamset && clip->passedict->dmteam != NO_TEAM && clip->passedict->dmteam == touch->dmteam ) continue; } } if ( !(clip->contentmask & CONTENTS_DEADMONSTER) && (touch->svflags & SVF_DEADMONSTER) ) continue; // might intersect, so do an exact clip headnode = SV_HullForEntity (touch); angles = touch->s.angles; if (touch->solid != SOLID_BSP) angles = vec3_origin; // boxes don't rotate if (touch->svflags & SVF_MONSTER) trace = CM_TransformedBoxTrace (clip->start, clip->end, clip->mins2, clip->maxs2, headnode, clip->contentmask, touch->s.origin, angles); else trace = CM_TransformedBoxTrace (clip->start, clip->end, clip->mins, clip->maxs, headnode, clip->contentmask, touch->s.origin, angles); if (trace.allsolid || trace.startsolid || trace.fraction < clip->trace.fraction) { trace.ent = touch; if (clip->trace.startsolid) { clip->trace = trace; clip->trace.startsolid = true; } else clip->trace = trace; } else if (trace.startsolid) clip->trace.startsolid = true; } } /* ================== SV_TraceBounds ================== */ void SV_TraceBounds (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, vec3_t boxmins, vec3_t boxmaxs) { int i; for (i=0 ; i<3 ; i++) { if (end[i] > start[i]) { boxmins[i] = start[i] + mins[i] - 1; boxmaxs[i] = end[i] + maxs[i] + 1; } else { boxmins[i] = end[i] + mins[i] - 1; boxmaxs[i] = start[i] + maxs[i] + 1; } } } /* ================== SV_Trace Moves the given mins/maxs volume through the world from start to end. Passedict and edicts owned by passedict are explicitly not checked. ================== */ trace_t SV_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passedict, int contentmask) { moveclip_t clip; if (!mins) mins = vec3_origin; if (!maxs) maxs = vec3_origin; memset ( &clip, 0, sizeof ( moveclip_t ) ); // clip to world clip.trace = CM_BoxTrace (start, end, mins, maxs, 0, contentmask); clip.trace.ent = ge->edicts; if (clip.trace.fraction == 0) return clip.trace; // blocked by the world clip.contentmask = contentmask; clip.start = start; clip.end = end; clip.mins = mins; clip.maxs = maxs; clip.passedict = passedict; VectorCopy (mins, clip.mins2); VectorCopy (maxs, clip.maxs2); // create the bounding box of the entire move SV_TraceBounds ( start, clip.mins2, clip.maxs2, end, clip.boxmins, clip.boxmaxs ); // clip to other solid entities SV_ClipMoveToEntities ( &clip ); return clip.trace; } trace_t SV_Trace2 (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passedict, int contentmask) { moveclip_t clip; if (!mins) mins = vec3_origin; if (!maxs) maxs = vec3_origin; memset ( &clip, 0, sizeof ( moveclip_t ) ); // clip to world clip.trace = CM_BoxTrace (start, end, mins, maxs, 0, contentmask); if (clip.trace.fraction == 0) return clip.trace; // blocked by the world clip.contentmask = contentmask; clip.start = start; clip.end = end; clip.mins = mins; clip.maxs = maxs; clip.passedict = passedict; VectorCopy (mins, clip.mins2); VectorCopy (maxs, clip.maxs2); // create the bounding box of the entire move SV_TraceBounds ( start, clip.mins2, clip.maxs2, end, clip.boxmins, clip.boxmaxs ); return clip.trace; } alien-arena-7.66+dfsg/source/server/sv_init.c0000600000175000017500000002524412161402010020236 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "server.h" server_static_t svs; // persistant server info server_t sv; // local server extern cvar_t *public_server; cvar_t *sv_excessive; cvar_t *sv_playerspeed; cvar_t *sv_tactical; extern float pm_maxspeed; extern void SV_SetMaster_f(void); /* ================ SV_FindIndex ================ */ int SV_FindIndex (char *name, int start, int max, qboolean create) { int i; if (!name || !name[0]) return 0; for (i=1 ; inum_edicts ; entnum++) { svent = EDICT_NUM(entnum); if (!svent->inuse) continue; if (!svent->s.modelindex && !svent->s.sound && !svent->s.effects) continue; svent->s.number = entnum; // // take current state as baseline // VectorCopy (svent->s.origin, svent->s.old_origin); sv.baselines[entnum] = svent->s; } } /* ================ SV_SpawnServer Change the server to a new map, taking all connected clients along with it. ================ */ void SV_SpawnServer (char *server, char *spawnpoint, server_state_t serverstate, qboolean attractloop, qboolean loadgame) { int i; unsigned checksum; if (attractloop) Cvar_Set ("paused", "0"); Com_Printf ("------- Server Initialization -------\n"); Com_DPrintf ("SpawnServer: %s\n",server); if (sv.demofile) { FS_FreeFile (sv.demobuf); sv.demosize = sv.demo_ofs = 0; fclose (sv.demofile); } svs.spawncount++; // any partially connected client will be // restarted sv.state = ss_dead; Com_SetServerState (sv.state); // wipe the entire per-level structure memset (&sv, 0, sizeof(sv)); svs.realtime = 0; sv.attractloop = attractloop; // save name for levels that don't set message strcpy (sv.configstrings[CS_NAME], server); if ((Cvar_VariableValue ("deathmatch")) || (Cvar_VariableValue ("ctf"))) { sprintf(sv.configstrings[CS_AIRACCEL], "%g", sv_airaccelerate->value); pm_airaccelerate = sv_airaccelerate->value; } else { strcpy(sv.configstrings[CS_AIRACCEL], "0"); pm_airaccelerate = 0; } SZ_Init (&sv.multicast, sv.multicast_buf, sizeof(sv.multicast_buf)); SZ_SetName (&sv.multicast, "Server multicast buffer", true); strcpy (sv.name, server); // leave slots at start for clients only for (i=0 ; ivalue ; i++) { // needs to reconnect if (svs.clients[i].state > cs_connected) svs.clients[i].state = cs_connected; svs.clients[i].lastframe = -1; } sv.time = 1000; strcpy (sv.name, server); strcpy (sv.configstrings[CS_NAME], server); if (serverstate != ss_game) { sv.models[1] = CM_LoadMap ("", false, &checksum); // no real map } else { Com_sprintf (sv.configstrings[CS_MODELS+1],sizeof(sv.configstrings[CS_MODELS+1]), "maps/%s", server); sv.models[1] = CM_LoadMap (sv.configstrings[CS_MODELS+1], false, &checksum); Com_sprintf (sv.configstrings[CS_MODELS+1],sizeof(sv.configstrings[CS_MODELS+1]), "%s", map_name); } Com_sprintf (sv.configstrings[CS_MAPCHECKSUM],sizeof(sv.configstrings[CS_MAPCHECKSUM]), "%i", checksum); // // clear physics interaction links // SV_ClearWorld (); for (i=1 ; i< CM_NumInlineModels() ; i++) { Com_sprintf (sv.configstrings[CS_MODELS+1+i], sizeof(sv.configstrings[CS_MODELS+1+i]), "*%i", i); sv.models[i+1] = CM_InlineModel (sv.configstrings[CS_MODELS+1+i]); } // // spawn the rest of the entities on the map // // precache and static commands can be issued during // map initialization sv.state = ss_loading; Com_SetServerState (sv.state); // load and spawn all other entities ge->SpawnEntities ( sv.name, CM_EntityString(), spawnpoint ); // run two frames to allow everything to settle ge->RunFrame (); ge->RunFrame (); // all precaches are complete sv.state = serverstate; Com_SetServerState (sv.state); // create a baseline for more efficient communications SV_CreateBaseline (); // set serverinfo variable Cvar_FullSet ("mapname", sv.name, CVAR_SERVERINFO | CVAR_NOSET); //get number of bots for bot kicking threshold cases sv_numbots = ge->ACESP_FindBotNum(); Com_Printf ("-------------------------------------\n"); } /* ============== SV_InitGame A brand new game has been started ============== */ void SV_InitGame (void) { int i; edict_t *ent; if (svs.initialized) { // cause any connected clients to reconnect SV_Shutdown ("Server restarted\n", true); } else { // make sure the client is down CL_Drop (); SCR_BeginLoadingPlaque (); } // get any latched variable changes (maxclients, etc) Cvar_GetLatchedVars (); svs.initialized = true; // dedicated servers are always deathmatch if (dedicated->value) { Cvar_FullSet ("deathmatch", "1", CVAR_SERVERINFO | CVAR_LATCH); } //set player move speed according to excessive value sv_excessive = Cvar_Get ("excessive", "0", CVAR_LATCH|CVAR_GAMEINFO); sv_playerspeed = Cvar_Get ("playerspeed", "0", CVAR_LATCH|CVAR_GAMEINFO); sv_tactical = Cvar_Get ("g_tactical", "0", CVAR_LATCH|CVAR_GAMEINFO); if(sv_excessive->value || sv_playerspeed->value) pm_maxspeed = 450; else if(sv_tactical->value) pm_maxspeed = 200; else pm_maxspeed = 300; // init clients if (Cvar_VariableValue ("deathmatch") || Cvar_VariableValue ("ctf")) { if (maxclients->value <= 0) Cvar_FullSet ("maxclients", "8", CVAR_SERVERINFO | CVAR_LATCH); else if (maxclients->value > MAX_CLIENTS) Cvar_FullSet ("maxclients", va("%i", MAX_CLIENTS), CVAR_SERVERINFO | CVAR_LATCH); } svs.spawncount = rand(); svs.clients = Z_Malloc (sizeof(client_t)*maxclients->value); svs.num_client_entities = maxclients->value*UPDATE_BACKUP*64; svs.client_entities = Z_Malloc (sizeof(entity_state_t)*svs.num_client_entities); // init network stuff NET_Config ( (maxclients->value > 1) ); // heartbeats will always be sent to the COR master svs.last_heartbeat = -999999; // send immediately // init game SV_InitGameProgs (); for (i=0 ; ivalue ; i++) { ent = EDICT_NUM(i+1); ent->s.number = i+1; svs.clients[i].edict = ent; memset (&svs.clients[i].lastcmd, 0, sizeof(svs.clients[i].lastcmd)); } if (!dedicated->value && Cvar_VariableValue ("deathmatch") && public_server->value) { SV_SetMaster_f(); //for listen servers } } /* ====================== SV_Map the full syntax is: map [*]$+ command from the console or progs. Map can also be a.cin, .pcx, or .dm2 file Nextserver is used to allow a cinematic to play, then proceed to another level: map tram.cin+jail_e3 ====================== */ void SV_Map (qboolean attractloop, char *levelstring, qboolean loadgame) { char level[MAX_QPATH]; char *ch; int l; char spawnpoint[MAX_QPATH]; sv.attractloop = attractloop; if ( loadgame || !svs.initialized ) { SV_InitGame(); // the game is just starting } strcpy (level, levelstring); // if there is a + in the map, set nextserver to the remainder ch = strstr(level, "+"); if (ch) { *ch = 0; Cvar_Set ("nextserver", va("map \"%s\"", ch+1)); } else Cvar_Set ("nextserver", ""); // if there is a $, use the remainder as a spawnpoint ch = strstr(level, "$"); if (ch) { *ch = 0; strcpy (spawnpoint, ch+1); } else spawnpoint[0] = 0; // skip the end-of-unit flag if necessary if (level[0] == '*') strcpy (level, level+1); l = strlen( level ); if ( l > 4 && !strcmp( level + l - 4, ".dm2" ) ) { // --- Run client-side demo --- if ( !dedicated->value ) { //this prevents the client from restarting SCR_BeginLoadingPlaque(); // for local system } SV_BroadcastCommand( "changing\n" ); // make sure attract loop is set. loadgame may be unused. // disable warmup sequence! otherwise, countdown announcements mess up // configstrings attractloop = true; loadgame = false; Cvar_ForceSet( "warmuptime", "0" ); SV_SpawnServer( level, spawnpoint, ss_demo, attractloop, loadgame ); } else { if ( !dedicated->value ) //this prevents the client from restarting SCR_BeginLoadingPlaque(); // for local system SV_BroadcastCommand( "changing\n" ); SV_SendClientMessages(); SV_SpawnServer( level, spawnpoint, ss_game, attractloop, loadgame ); Cbuf_CopyToDefer(); } SV_BroadcastCommand ("reconnect\n"); } alien-arena-7.66+dfsg/source/server/sv_ents.c0000600000175000017500000004135312161402010020243 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "server.h" static size_t szr; // just for quieting unused result warnings /* ============================================================================= Encode a client frame onto the network channel ============================================================================= */ /* ============= SV_EmitPacketEntities Writes a delta update of an entity_state_t list to the message. ============= */ void SV_EmitPacketEntities (client_frame_t *from, client_frame_t *to, sizebuf_t *msg) { entity_state_t *oldent=NULL, *newent=NULL; int oldindex, newindex; int oldnum, newnum; int from_num_entities; int bits; #if 0 if (numprojs) MSG_WriteByte (msg, svc_packetentities2); else #endif MSG_WriteByte (msg, svc_packetentities); if (!from) from_num_entities = 0; else from_num_entities = from->num_entities; newindex = 0; oldindex = 0; while (newindex < to->num_entities || oldindex < from_num_entities) { if (newindex >= to->num_entities) newnum = 9999; else { newent = &svs.client_entities[(to->first_entity+newindex)%svs.num_client_entities]; newnum = newent->number; } if (oldindex >= from_num_entities) oldnum = 9999; else { oldent = &svs.client_entities[(from->first_entity+oldindex)%svs.num_client_entities]; oldnum = oldent->number; } if (newnum == oldnum) { // delta update from old position // because the force parm is false, this will not result // in any bytes being emited if the entity has not changed at all // note that players are always 'newentities', this updates their oldorigin always // and prevents warping MSG_WriteDeltaEntity (oldent, newent, msg, false, newent->number <= maxclients->value); oldindex++; newindex++; continue; } if (newnum < oldnum) { // this is a new entity, send it from the baseline MSG_WriteDeltaEntity (&sv.baselines[newnum], newent, msg, true, true); newindex++; continue; } if (newnum > oldnum) { // the old entity isn't present in the new message bits = U_REMOVE; if (oldnum >= 256) bits |= U_NUMBER16 | U_MOREBITS1; MSG_WriteByte (msg, bits&255 ); if (bits & 0x0000ff00) MSG_WriteByte (msg, (bits>>8)&255 ); if (bits & U_NUMBER16) MSG_WriteShort (msg, oldnum); else MSG_WriteByte (msg, oldnum); oldindex++; continue; } } MSG_WriteShort (msg, 0); // end of packetentities } /* ============= SV_WritePlayerstateToClient ============= */ void SV_WritePlayerstateToClient (client_frame_t *from, client_frame_t *to, sizebuf_t *msg) { int i; int pflags; player_state_t *ps, *ops; player_state_t dummy; int statbits; ps = &to->ps; if (!from) { memset (&dummy, 0, sizeof(dummy)); ops = &dummy; } else ops = &from->ps; // // determine what needs to be sent // pflags = 0; if (ps->pmove.pm_type != ops->pmove.pm_type) pflags |= PS_M_TYPE; if (ps->pmove.origin[0] != ops->pmove.origin[0] || ps->pmove.origin[1] != ops->pmove.origin[1] || ps->pmove.origin[2] != ops->pmove.origin[2] ) pflags |= PS_M_ORIGIN; if (ps->pmove.velocity[0] != ops->pmove.velocity[0] || ps->pmove.velocity[1] != ops->pmove.velocity[1] || ps->pmove.velocity[2] != ops->pmove.velocity[2] ) pflags |= PS_M_VELOCITY; if (ps->pmove.pm_time != ops->pmove.pm_time) pflags |= PS_M_TIME; if (ps->pmove.pm_flags != ops->pmove.pm_flags) pflags |= PS_M_FLAGS; if (ps->pmove.gravity != ops->pmove.gravity) pflags |= PS_M_GRAVITY; if (ps->pmove.delta_angles[0] != ops->pmove.delta_angles[0] || ps->pmove.delta_angles[1] != ops->pmove.delta_angles[1] || ps->pmove.delta_angles[2] != ops->pmove.delta_angles[2] ) pflags |= PS_M_DELTA_ANGLES; if (ps->viewoffset[0] != ops->viewoffset[0] || ps->viewoffset[1] != ops->viewoffset[1] || ps->viewoffset[2] != ops->viewoffset[2] ) pflags |= PS_VIEWOFFSET; if (ps->viewangles[0] != ops->viewangles[0] || ps->viewangles[1] != ops->viewangles[1] || ps->viewangles[2] != ops->viewangles[2] ) pflags |= PS_VIEWANGLES; if (ps->kick_angles[0] != ops->kick_angles[0] || ps->kick_angles[1] != ops->kick_angles[1] || ps->kick_angles[2] != ops->kick_angles[2] ) pflags |= PS_KICKANGLES; if (ps->blend[0] != ops->blend[0] || ps->blend[1] != ops->blend[1] || ps->blend[2] != ops->blend[2] || ps->blend[3] != ops->blend[3] ) pflags |= PS_BLEND; if (ps->fov != ops->fov) pflags |= PS_FOV; if (ps->rdflags != ops->rdflags) pflags |= PS_RDFLAGS; if (ps->gunframe != ops->gunframe || (int)(ops->gunoffset[0]*4) != (int)(ps->gunoffset[0]*4) || (int)(ops->gunoffset[1]*4) != (int)(ps->gunoffset[1]*4) || (int)(ops->gunoffset[2]*4) != (int)(ps->gunoffset[2]*4) || (int)(ops->gunangles[0]*4) != (int)(ps->gunangles[0]*4) || (int)(ops->gunangles[1]*4) != (int)(ps->gunangles[1]*4) || (int)(ops->gunangles[2]*4) != (int)(ps->gunangles[2]*4) ) pflags |= PS_WEAPONFRAME; pflags |= PS_WEAPONINDEX; // // write it // MSG_WriteByte (msg, svc_playerinfo); MSG_WriteShort (msg, pflags); // // write the pmove_state_t // if (pflags & PS_M_TYPE) MSG_WriteByte (msg, ps->pmove.pm_type); if (pflags & PS_M_ORIGIN) { MSG_WriteSizeInt (msg, coord_bytes, ps->pmove.origin[0]); MSG_WriteSizeInt (msg, coord_bytes, ps->pmove.origin[1]); MSG_WriteSizeInt (msg, coord_bytes, ps->pmove.origin[2]); } if (pflags & PS_M_VELOCITY) { MSG_WriteShort (msg, ps->pmove.velocity[0]); MSG_WriteShort (msg, ps->pmove.velocity[1]); MSG_WriteShort (msg, ps->pmove.velocity[2]); } if (pflags & PS_M_TIME) MSG_WriteByte (msg, ps->pmove.pm_time); if (pflags & PS_M_FLAGS) MSG_WriteByte (msg, ps->pmove.pm_flags); if (pflags & PS_M_GRAVITY) MSG_WriteShort (msg, ps->pmove.gravity); if (pflags & PS_M_DELTA_ANGLES) { MSG_WriteShort (msg, ps->pmove.delta_angles[0]); MSG_WriteShort (msg, ps->pmove.delta_angles[1]); MSG_WriteShort (msg, ps->pmove.delta_angles[2]); } // // write the rest of the player_state_t // if (pflags & PS_VIEWOFFSET) { MSG_WriteChar (msg, ps->viewoffset[0]*4); MSG_WriteChar (msg, ps->viewoffset[1]*4); MSG_WriteChar (msg, ps->viewoffset[2]*4); } if (pflags & PS_VIEWANGLES) { MSG_WriteAngle16 (msg, ps->viewangles[0]); MSG_WriteAngle16 (msg, ps->viewangles[1]); MSG_WriteAngle16 (msg, ps->viewangles[2]); } if (pflags & PS_KICKANGLES) { MSG_WriteChar (msg, ps->kick_angles[0]*4); MSG_WriteChar (msg, ps->kick_angles[1]*4); MSG_WriteChar (msg, ps->kick_angles[2]*4); } if (pflags & PS_WEAPONINDEX) { MSG_WriteByte (msg, ps->gunindex); } if (pflags & PS_WEAPONFRAME) { MSG_WriteByte (msg, ps->gunframe); MSG_WriteChar (msg, ps->gunoffset[0]*4); MSG_WriteChar (msg, ps->gunoffset[1]*4); MSG_WriteChar (msg, ps->gunoffset[2]*4); MSG_WriteChar (msg, ps->gunangles[0]*4); MSG_WriteChar (msg, ps->gunangles[1]*4); MSG_WriteChar (msg, ps->gunangles[2]*4); } if (pflags & PS_BLEND) { MSG_WriteByte (msg, ps->blend[0]*255); MSG_WriteByte (msg, ps->blend[1]*255); MSG_WriteByte (msg, ps->blend[2]*255); MSG_WriteByte (msg, ps->blend[3]*255); } if (pflags & PS_FOV) MSG_WriteByte (msg, ps->fov); if (pflags & PS_RDFLAGS) MSG_WriteByte (msg, ps->rdflags); // send stats statbits = 0; for (i=0 ; istats[i] != ops->stats[i]) statbits |= 1<stats[i]); } /* ================== SV_WriteFrameToClient ================== */ void SV_WriteFrameToClient (client_t *client, sizebuf_t *msg) { client_frame_t *frame, *oldframe; int lastframe; //Com_Printf ("%i -> %i\n", client->lastframe, sv.framenum); // this is the frame we are creating frame = &client->frames[sv.framenum & UPDATE_MASK]; if (client->lastframe <= 0) { // client is asking for a retransmit oldframe = NULL; lastframe = -1; } else if (sv.framenum - client->lastframe >= (UPDATE_BACKUP - 3) ) { // client hasn't gotten a good message through in a long time // Com_Printf ("%s: Delta request from out-of-date packet.\n", client->name); oldframe = NULL; lastframe = -1; } else { // we have a valid message to delta from oldframe = &client->frames[client->lastframe & UPDATE_MASK]; lastframe = client->lastframe; } MSG_WriteByte (msg, svc_frame); MSG_WriteLong (msg, sv.framenum); MSG_WriteLong (msg, lastframe); // what we are delta'ing from MSG_WriteByte (msg, client->surpressCount); // rate dropped packets client->surpressCount = 0; // send over the areabits MSG_WriteByte (msg, frame->areabytes); SZ_Write (msg, frame->areabits, frame->areabytes); // delta encode the playerstate SV_WritePlayerstateToClient (oldframe, frame, msg); // delta encode the entities SV_EmitPacketEntities (oldframe, frame, msg); } /* ============================================================================= Build a client frame structure ============================================================================= */ byte fatpvs[65536/8]; // 32767 is MAX_MAP_LEAFS /* ============ SV_FatPVS The client will interpolate the view position, so we can't use a single PVS point =========== */ void SV_FatPVS (vec3_t org) { int leafs[64]; int i, j, count; int longs; byte *src; vec3_t mins, maxs; for (i=0 ; i<3 ; i++) { mins[i] = org[i] - 8; maxs[i] = org[i] + 8; } count = CM_BoxLeafnums (mins, maxs, leafs, 64, NULL); if (count < 1) Com_Error (ERR_FATAL, "SV_FatPVS: count < 1"); longs = (CM_NumClusters()+31)>>5; // convert leafs to clusters for (i=0 ; iedict; if (!orig_clent->client) return; // not in game yet redir_num = client->edict->redirect_number; if (redir_num != client->edict->s.number) { for (i=0, redir_client = svs.clients ; iinteger; i++, redir_client++) if (redir_num == redir_client->edict->s.number) break; if (i == maxclients->integer) redir_client = client; } else redir_client = client; clent = redir_client->edict; if (!clent->client) return; // not in game yet // this is the frame we are creating frame = &client->frames[sv.framenum & UPDATE_MASK]; frame->senttime = svs.realtime; // save it for ping calc later // find the client's PVS for (i=0 ; i<3 ; i++) org[i] = clent->client->ps.pmove.origin[i]*0.125 + clent->client->ps.viewoffset[i]; leafnum = CM_PointLeafnum (org); clientarea = CM_LeafArea (leafnum); clientcluster = CM_LeafCluster (leafnum); // calculate the visible areas frame->areabytes = CM_WriteAreaBits (frame->areabits, clientarea); // grab the current player_state_t frame->ps = clent->client->ps; if (client != redir_client) { //some adjustments for ghost mode if (frame->ps.pmove.pm_type != PM_DEAD) frame->ps.pmove.pm_type = PM_FREEZE; frame->ps.fov = client->edict->client->ps.fov; } SV_FatPVS (org); clientphs = CM_ClusterPHS (clientcluster); // build up the list of visible entities frame->num_entities = 0; frame->first_entity = svs.next_client_entities; c_fullsend = 0; for (e=1 ; enum_edicts ; e++) { ent = EDICT_NUM(e); // ignore ents without visible models if (ent->svflags & SVF_NOCLIENT) continue; // ignore ents without visible models unless they have an effect if (!ent->s.modelindex && !ent->s.effects && !ent->s.sound && !ent->s.event) continue; // ignore if not touching a PV leaf if (ent != clent) { // check area if (!CM_AreasConnected (clientarea, ent->areanum)) { // doors can legally straddle two areas, so // we may need to check another one if (!ent->areanum2 || !CM_AreasConnected (clientarea, ent->areanum2)) continue; // blocked by a door } // FIXME: if an ent has a model and a sound, but isn't // in the PVS, only the PHS, clear the model if (ent->s.sound) { bitvector = fatpvs; //clientphs; } else bitvector = fatpvs; if (ent->num_clusters == -1) { // too many leafs for individual check, go by headnode if (!CM_HeadnodeVisible (ent->headnode, bitvector)) continue; c_fullsend++; } else { // check individual leafs for (i=0 ; i < ent->num_clusters ; i++) { l = ent->clusternums[i]; if (bitvector[l >> 3] & (1 << (l&7) )) break; } if (i == ent->num_clusters) continue; // not visible } if (!ent->s.modelindex) { // don't send sounds if they will be attenuated away vec3_t delta; float len; VectorSubtract (org, ent->s.origin, delta); len = VectorLength (delta); if (len > 400) continue; } } if (ent->s.number != e) { // note: server has limited info about entities Com_DPrintf("Fixing ent->s.number: %i to %i for a %s\n", ent->s.number, e, (ent->client ? "client" : "non-client") ); ent->s.number = e; } if (ent == orig_clent && orig_clent != clent) { Com_Printf ("CAN'T HAPPEN?\n"); continue; } // add it to the circular client_entities array state = &svs.client_entities[svs.next_client_entities%svs.num_client_entities]; *state = ent->s; if (ent == clent && orig_clent != clent) state->number = orig_clent->s.number; // don't mark players missiles as solid if (ent->owner == client->edict) state->solid = 0; svs.next_client_entities++; frame->num_entities++; } } /* ================== SV_RecordDemoMessage Save everything in the world out without deltas. Used for recording footage for merged or assembled demos ================== */ void SV_RecordDemoMessage (void) { int e; edict_t *ent; entity_state_t nostate; sizebuf_t buf; byte buf_data[32768]; int len; if (!svs.demofile) return; memset (&nostate, 0, sizeof(nostate)); SZ_Init (&buf, buf_data, sizeof(buf_data)); SZ_SetName (&buf, "Demo message buffer", false); // write a frame message that doesn't contain a player_state_t MSG_WriteByte (&buf, svc_frame); MSG_WriteLong (&buf, sv.framenum); MSG_WriteByte (&buf, svc_packetentities); e = 1; ent = EDICT_NUM(e); while (e < ge->num_edicts) { // ignore ents without visible models unless they have an effect if (ent->inuse && ent->s.number && (ent->s.modelindex || ent->s.effects || ent->s.sound || ent->s.event) && !(ent->svflags & SVF_NOCLIENT)) MSG_WriteDeltaEntity (&nostate, &ent->s, &buf, false, true); e++; ent = EDICT_NUM(e); } MSG_WriteShort (&buf, 0); // end of packetentities // now add the accumulated multicast information SZ_Write (&buf, svs.demo_multicast.data, svs.demo_multicast.cursize); SZ_Clear (&svs.demo_multicast); // now write the entire message to the file, prefixed by the length len = LittleLong (buf.cursize); szr = fwrite (&len, 4, 1, svs.demofile); szr = fwrite (buf.data, buf.cursize, 1, svs.demofile); } alien-arena-7.66+dfsg/source/server/sv_ccmds.c0000600000175000017500000003071612161402010020364 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "server.h" static size_t szr; // just for quieting unused result warnings /* =============================================================================== OPERATOR CONSOLE ONLY COMMANDS These commands can only be entered from stdin or by a remote operator datagram =============================================================================== */ /* ==================== SV_SetMaster_f Specify a list of master servers ==================== */ void SV_SetMaster_f (void) { int i; // make sure the server is listed public Cvar_Set ("public", "1"); // Clear the master server status array memset (master_status, 0, sizeof(master_status)); if ( dedicated && dedicated->value ) { // Dedicated server, get the names from the command line arguments for ( i = 1; i < Cmd_Argc() && i < MAX_MASTERS + 1 ; i++ ) { strncpy (master_status[i - 1].name, Cmd_Argv(i), MAX_MASTER_LEN); } } svs.last_heartbeat = -9999999; // Resolve the names and send a ping SV_HandleMasters ( "ping" , "ping" ); } /* ================== SV_SetPlayer Sets sv_client and sv_player to the player with idnum Cmd_Argv(1) ================== */ qboolean SV_SetPlayer (void) { client_t *cl; int i; int idnum; char *s; if (Cmd_Argc() < 2) return false; if ( svs.clients == NULL ) return false; // unlikely, but possible, to call here before initialized s = Cmd_Argv(1); // numeric values are just slot numbers if (s[0] >= '0' && s[0] <= '9') { idnum = atoi(Cmd_Argv(1)); if (idnum < 0 || idnum >= maxclients->value) { Com_Printf ("Bad client slot: %i\n", idnum); return false; } sv_client = &svs.clients[idnum]; sv_player = sv_client->edict; if (!sv_client->state) { Com_Printf ("Client %i is not active\n", idnum); return false; } return true; } // check for a name match for (i=0,cl=svs.clients ; ivalue; i++,cl++) { if (!cl->state) continue; if (!strcmp(cl->name, s)) { sv_client = cl; sv_player = sv_client->edict; return true; } } Com_Printf ("Userid %s is not on the server\n", s); return false; } /* ================== SV_DemoMap_f Puts the server in demo mode on a specific map/cinematic ================== */ void SV_DemoMap_f (void) { SV_Map (true, Cmd_Argv(1), false ); } /* ================== SV_Map_f Goes directly to a given map without any savegame archiving. For development work ================== */ void SV_Map_f (void) { char *map; char expanded[MAX_QPATH]; // if not a pcx, demo, or cinematic, check to make sure the level exists map = Cmd_Argv(1); if (!strstr (map, ".")) { Com_sprintf (expanded, sizeof(expanded), "maps/%s", map); if (FS_LoadFile (expanded, NULL) == -1) { Com_sprintf (expanded, sizeof(expanded), "maps/%s.bsp", map); if (FS_LoadFile (expanded, NULL) == -1) { Com_Printf ("Cannot find %s\n", expanded); return; } } } // start up the next map SV_Map (false, Cmd_Argv(1), false ); // archive server state strncpy (svs.mapcmd, Cmd_Argv(1), sizeof(svs.mapcmd)-1); } void SV_StartMap_f (void) { char *map; char expanded[MAX_QPATH]; // if not a pcx, demo, or cinematic, check to make sure the level exists map = Cmd_Argv(1); if (!strstr (map, ".")) { Com_sprintf (expanded, sizeof(expanded), "maps/%s", map); if (FS_LoadFile (expanded, NULL) == -1) { Com_sprintf (expanded, sizeof(expanded), "maps/%s.bsp", map); if (FS_LoadFile (expanded, NULL) == -1) { Com_Printf ("Cannot find %s\n", expanded); return; } } } // start up the next map(and initialize a server) SV_Map (false, Cmd_Argv(1), true ); // archive server state strncpy (svs.mapcmd, Cmd_Argv(1), sizeof(svs.mapcmd)-1); } //=============================================================== /* ================== SV_Kick_f Kick a user off of the server ================== */ void SV_Kick_f (void) { if (!svs.initialized) { Com_Printf ("No server running.\n"); return; } if (Cmd_Argc() != 2) { Com_Printf ("Usage: kick \n"); return; } if (!SV_SetPlayer ()) return; SV_BroadcastPrintf (PRINT_HIGH, "%s was kicked\n", sv_client->name); // print directly, because the dropped client won't get the // SV_BroadcastPrintf message SV_ClientPrintf (sv_client, PRINT_HIGH, "You were kicked from the game\n"); SV_DropClient (sv_client); sv_client->lastmessage = svs.realtime; // min case there is a funny zombie } /* ================ SV_Status_f ================ */ void SV_Status_f (void) { int i, j, k , l; client_t *cl; char *s; int ping; qboolean expectColor; if (!svs.clients) { Com_Printf ("No server running.\n"); return; } Com_Printf ("map : %s\n", sv.name); Com_Printf ("num score ping name lastmsg address qport \n"); Com_Printf ("--- ----- ---- --------------- ------- --------------------- ------\n"); for (i=0,cl=svs.clients ; ivalue; i++,cl++) { if (!cl->state) continue; Com_Printf ("%3i ", i); if ( cl->edict->client->ps.stats[STAT_SPECTATOR] == 0 ) { Com_Printf ("%5i ", cl->edict->client->ps.stats[STAT_FRAGS]); } else { Com_Printf ("%s ", "SPEC"); } if (cl->state == cs_connected) Com_Printf ("CNCT "); else if (cl->state == cs_zombie) Com_Printf ("ZMBI "); else { ping = cl->ping < 9999 ? cl->ping : 9999; Com_Printf ("%4i ", ping); } Com_Printf ("%s", cl->name); l = strlen( cl->name ); expectColor = false; for ( j = k = 0 ; j < l ; j ++ ) { if ( expectColor ) { if ( cl->name[ j ] == '^' ) { k ++; } expectColor = false; } else if ( cl->name[ j ] == '^' ) { expectColor = true; } else { k ++; } } if ( expectColor ) { k ++; } l = 16 - k; for (j=0 ; jlastmessage ); s = NET_AdrToString ( cl->netchan.remote_address); Com_Printf ("%s", s); l = 22 - strlen(s); for (j=0 ; jnetchan.qport); Com_Printf ("\n"); } Com_Printf ("\n"); } /* ================== SV_ConSay_f ================== */ void SV_ConSay_f(void) { client_t *client; int j; char *p; char text[1024]; if (Cmd_Argc () < 2) return; strcpy (text, "console: "); p = Cmd_Args(); if (*p == '"') { p++; p[strlen(p)-1] = 0; } strcat(text, p); for (j = 0, client = svs.clients; j < maxclients->value; j++, client++) { if (client->state != cs_spawned) continue; SV_ClientPrintf(client, PRINT_CHAT, "%s\n", text); } } /* ================== SV_Heartbeat_f ================== */ void SV_Heartbeat_f (void) { svs.last_heartbeat = -9999999; } /* =========== SV_Serverinfo_f Examine or change the serverinfo string =========== */ extern netadr_t *CL_GetRemoteServer (void); void SV_Serverinfo_f (void) { netadr_t *remoteserver; Com_Printf ("Server info settings:\n"); if (!(svs.clients || dedicated->value)) { remoteserver = CL_GetRemoteServer (); if (remoteserver) { Netchan_OutOfBandPrint (NS_CLIENT, *remoteserver, va("status %i", PROTOCOL_VERSION)); return; } Com_Printf ("(No remote server connected, printing local cvars.)\n"); } Info_Print (Cvar_Serverinfo()); } /* =========== SV_DumpUser_f Examine all a users info strings =========== */ void SV_DumpUser_f (void) { if (Cmd_Argc() != 2) { Com_Printf ("Usage: info \n"); return; } if (!SV_SetPlayer ()) return; Com_Printf ("userinfo\n"); Com_Printf ("--------\n"); Info_Print (sv_client->userinfo); } /* ============== SV_ServerRecord_f Begins server demo recording. Every entity and every message will be recorded, but no playerinfo will be stored. Primarily for demo merging. ============== */ void SV_ServerRecord_f (void) { char name[MAX_OSPATH]; char buf_data[32768]; sizebuf_t buf; int len; int i; if (Cmd_Argc() != 2) { Com_Printf ("serverrecord \n"); return; } if (svs.demofile) { Com_Printf ("Already recording.\n"); return; } if (sv.state != ss_game) { Com_Printf ("You must be in a level to record.\n"); return; } // // open the demo file // Com_sprintf (name, sizeof(name), "%s/demos/%s.dm2", FS_Gamedir(), Cmd_Argv(1)); Com_Printf ("recording to %s.\n", name); FS_CreatePath (name); svs.demofile = fopen (name, "wb"); if (!svs.demofile) { Com_Printf ("ERROR: couldn't open.\n"); return; } // setup a buffer to catch all multicasts SZ_Init (&svs.demo_multicast, svs.demo_multicast_buf, sizeof(svs.demo_multicast_buf)); SZ_SetName (&svs.demo_multicast, "Demo multicast buffer", true); // // write a single giant fake message with all the startup info // SZ_Init (&buf, (byte *)buf_data, (int)(sizeof(buf_data))); SZ_SetName (&buf, "Giant fake msg buffer", true); // // serverdata needs to go over for all types of servers // to make sure the protocol is right, and to set the gamedir // // send the serverdata MSG_WriteByte (&buf, svc_serverdata); MSG_WriteLong (&buf, PROTOCOL_VERSION); MSG_WriteLong (&buf, svs.spawncount); // 2 means server demo MSG_WriteByte (&buf, 2); // demos are always attract loops MSG_WriteString (&buf, Cvar_VariableString ("gamedir")); MSG_WriteShort (&buf, -1); // send full levelname MSG_WriteString (&buf, sv.configstrings[CS_NAME]); for (i=0 ; iServerCommand(); } //=========================================================== /* ================== SV_InitOperatorCommands ================== */ void SV_InitOperatorCommands (void) { Cmd_AddCommand ("heartbeat", SV_Heartbeat_f); Cmd_AddCommand ("kick", SV_Kick_f); Cmd_AddCommand ("status", SV_Status_f); Cmd_AddCommand ("serverinfo", SV_Serverinfo_f); Cmd_AddCommand ("dumpuser", SV_DumpUser_f); Cmd_AddCommand ("map", SV_Map_f); Cmd_AddCommand ("startmap", SV_StartMap_f); Cmd_AddCommand ("demomap", SV_DemoMap_f); Cmd_AddCommand ("setmaster", SV_SetMaster_f); if ( dedicated->value ) Cmd_AddCommand ("say", SV_ConSay_f); Cmd_AddCommand ("serverrecord", SV_ServerRecord_f); Cmd_AddCommand ("serverstop", SV_ServerStop_f); Cmd_AddCommand ("killserver", SV_KillServer_f); Cmd_AddCommand ("sv", SV_ServerCommand_f); } alien-arena-7.66+dfsg/source/win32/0000700000175000017500000000000012207204657016064 5ustar zero79zero79alien-arena-7.66+dfsg/source/win32/conproc.h0000600000175000017500000000153312161402010017662 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // conproc.h -- support for qhost void InitConProc (int argc, char **argv); void DeinitConProc (void); alien-arena-7.66+dfsg/source/win32/q_shwin.c0000600000175000017500000001232212161402010017660 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "qcommon/qcommon.h" #include "winquake.h" #include #include #include #include #include #include //=============================================================================== int hunkcount; byte *membase; int hunkmaxsize; int cursize; #define VIRTUAL_ALLOC void *Hunk_Begin (int maxsize) { // reserve a huge chunk of memory, but don't commit any yet cursize = 0; hunkmaxsize = maxsize; #ifdef VIRTUAL_ALLOC membase = VirtualAlloc (NULL, maxsize, MEM_RESERVE|MEM_TOP_DOWN, PAGE_NOACCESS); #else membase = malloc (maxsize); memset (membase, 0, maxsize); #endif if (!membase) Sys_Error ("VirtualAlloc reserve failed"); return (void *)membase; } void *Hunk_Alloc (int size) { void *buf; // round to cacheline size = (size+31)&~31; #ifdef VIRTUAL_ALLOC // commit pages as needed // buf = VirtualAlloc (membase+cursize, size, MEM_COMMIT, PAGE_READWRITE); buf = VirtualAlloc (membase, cursize+size, MEM_COMMIT, PAGE_READWRITE); if (!buf) { FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &buf, 0, NULL); Sys_Error ("VirtualAlloc commit failed.\n%s", buf); } #endif cursize += size; if (cursize > hunkmaxsize) Sys_Error ("Hunk_Alloc overflow"); return (void *)(membase+cursize-size); } int Hunk_End (void) { // free the remaining unused virtual memory #if 0 void *buf; // write protect it buf = VirtualAlloc (membase, cursize, MEM_COMMIT, PAGE_READONLY); if (!buf) Sys_Error ("VirtualAlloc commit failed"); #endif hunkcount++; //Com_Printf ("hunkcount: %i\n", hunkcount); return cursize; } void Hunk_Free (void *base) { if ( base ) #ifdef VIRTUAL_ALLOC VirtualFree (base, 0, MEM_RELEASE); #else free (base); #endif hunkcount--; } //=============================================================================== /* ================ Sys_Milliseconds ================ */ int curtime; int Sys_Milliseconds (void) { static int base; static qboolean initialized = false; int timeofday; if (!initialized) { // let base retain 16 bits of effectively random data base = timeGetTime() & 0xffff0000; initialized = true; } timeofday = timeGetTime() - base; return timeofday; } void Sys_Mkdir (char *path) { _mkdir (path); } //============================================ char findbase[MAX_OSPATH]; char findpath[MAX_OSPATH]; int findhandle; static qboolean CompareAttributes( unsigned found, unsigned musthave, unsigned canthave ) { if ( ( found & _A_RDONLY ) && ( canthave & SFF_RDONLY ) ) return false; if ( ( found & _A_HIDDEN ) && ( canthave & SFF_HIDDEN ) ) return false; if ( ( found & _A_SYSTEM ) && ( canthave & SFF_SYSTEM ) ) return false; if ( ( found & _A_SUBDIR ) && ( canthave & SFF_SUBDIR ) ) return false; if ( ( found & _A_ARCH ) && ( canthave & SFF_ARCH ) ) return false; if ( ( musthave & SFF_RDONLY ) && !( found & _A_RDONLY ) ) return false; if ( ( musthave & SFF_HIDDEN ) && !( found & _A_HIDDEN ) ) return false; if ( ( musthave & SFF_SYSTEM ) && !( found & _A_SYSTEM ) ) return false; if ( ( musthave & SFF_SUBDIR ) && !( found & _A_SUBDIR ) ) return false; if ( ( musthave & SFF_ARCH ) && !( found & _A_ARCH ) ) return false; return true; } char *Sys_FindFirst (char *path, unsigned musthave, unsigned canthave ) { struct _finddata_t findinfo; if (findhandle) Sys_Error ("Sys_BeginFind without close"); findhandle = 0; COM_FilePath (path, findbase); findhandle = _findfirst (path, &findinfo); if (findhandle == -1) return NULL; if ( !CompareAttributes( findinfo.attrib, musthave, canthave ) ) return NULL; Com_sprintf (findpath, sizeof(findpath), "%s/%s", findbase, findinfo.name); return findpath; } char *Sys_FindNext ( unsigned musthave, unsigned canthave ) { struct _finddata_t findinfo; if (findhandle == -1) return NULL; if (_findnext (findhandle, &findinfo) == -1) return NULL; if ( !CompareAttributes( findinfo.attrib, musthave, canthave ) ) return NULL; Com_sprintf (findpath, sizeof(findpath), "%s/%s", findbase, findinfo.name); return findpath; } void Sys_FindClose (void) { if (findhandle != -1) _findclose (findhandle); findhandle = 0; } //============================================ alien-arena-7.66+dfsg/source/win32/conproc.c0000600000175000017500000002062612161402010017661 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // conproc.c -- support for qhost #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "conproc.h" #define CCOM_WRITE_TEXT 0x2 // Param1 : Text #define CCOM_GET_TEXT 0x3 // Param1 : Begin line // Param2 : End line #define CCOM_GET_SCR_LINES 0x4 // No params #define CCOM_SET_SCR_LINES 0x5 // Param1 : Number of lines HANDLE heventDone; HANDLE hfileBuffer; HANDLE heventChildSend; HANDLE heventParentSend; HANDLE hStdout; HANDLE hStdin; unsigned _stdcall RequestProc (void *arg); LPVOID GetMappedBuffer (HANDLE hfileBuffer); void ReleaseMappedBuffer (LPVOID pBuffer); BOOL GetScreenBufferLines (int *piLines); BOOL SetScreenBufferLines (int iLines); BOOL ReadText (LPTSTR pszText, int iBeginLine, int iEndLine); BOOL WriteText (LPCTSTR szText); int CharToCode (char c); BOOL SetConsoleCXCY(HANDLE hStdout, int cx, int cy); int ccom_argc; char **ccom_argv; /* ================ CCheckParm Returns the position (1 to argc-1) in the program's argument list where the given parameter apears, or 0 if not present ================ */ int CCheckParm (char *parm) { int i; for (i=1 ; i 0) { if (t < argc) hFile = (HANDLE)atoi (ccom_argv[t+1]); } if ((t = CCheckParm ("-HPARENT")) > 0) { if (t < argc) heventParent = (HANDLE)atoi (ccom_argv[t+1]); } if ((t = CCheckParm ("-HCHILD")) > 0) { if (t < argc) heventChild = (HANDLE)atoi (ccom_argv[t+1]); } // ignore if we don't have all the events. if (!hFile || !heventParent || !heventChild) { printf ("Qhost not present.\n"); return; } printf ("Initializing for qhost.\n"); hfileBuffer = hFile; heventParentSend = heventParent; heventChildSend = heventChild; // so we'll know when to go away. heventDone = CreateEvent (NULL, FALSE, FALSE, NULL); if (!heventDone) { printf ("Couldn't create heventDone\n"); return; } if (!_beginthreadex (NULL, 0, RequestProc, NULL, 0, &threadAddr)) { CloseHandle (heventDone); printf ("Couldn't create QHOST thread\n"); return; } // save off the input/output handles. hStdout = GetStdHandle (STD_OUTPUT_HANDLE); hStdin = GetStdHandle (STD_INPUT_HANDLE); // force 80 character width, at least 25 character height SetConsoleCXCY (hStdout, 80, 25); } void DeinitConProc (void) { if (heventDone) SetEvent (heventDone); } unsigned _stdcall RequestProc (void *arg) { int *pBuffer; DWORD dwRet; HANDLE heventWait[2]; int iBeginLine, iEndLine; heventWait[0] = heventParentSend; heventWait[1] = heventDone; while (1) { dwRet = WaitForMultipleObjects (2, heventWait, FALSE, INFINITE); // heventDone fired, so we're exiting. if (dwRet == WAIT_OBJECT_0 + 1) break; pBuffer = (int *) GetMappedBuffer (hfileBuffer); // hfileBuffer is invalid. Just leave. if (!pBuffer) { printf ("Invalid hfileBuffer\n"); break; } switch (pBuffer[0]) { case CCOM_WRITE_TEXT: // Param1 : Text pBuffer[0] = WriteText ((LPCTSTR) (pBuffer + 1)); break; case CCOM_GET_TEXT: // Param1 : Begin line // Param2 : End line iBeginLine = pBuffer[1]; iEndLine = pBuffer[2]; pBuffer[0] = ReadText ((LPTSTR) (pBuffer + 1), iBeginLine, iEndLine); break; case CCOM_GET_SCR_LINES: // No params pBuffer[0] = GetScreenBufferLines (&pBuffer[1]); break; case CCOM_SET_SCR_LINES: // Param1 : Number of lines pBuffer[0] = SetScreenBufferLines (pBuffer[1]); break; } ReleaseMappedBuffer (pBuffer); SetEvent (heventChildSend); } _endthreadex (0); return 0; } LPVOID GetMappedBuffer (HANDLE hfileBuffer) { LPVOID pBuffer; pBuffer = MapViewOfFile (hfileBuffer, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); return pBuffer; } void ReleaseMappedBuffer (LPVOID pBuffer) { UnmapViewOfFile (pBuffer); } BOOL GetScreenBufferLines (int *piLines) { CONSOLE_SCREEN_BUFFER_INFO info; BOOL bRet; bRet = GetConsoleScreenBufferInfo (hStdout, &info); if (bRet) *piLines = info.dwSize.Y; return bRet; } BOOL SetScreenBufferLines (int iLines) { return SetConsoleCXCY (hStdout, 80, iLines); } BOOL ReadText (LPTSTR pszText, int iBeginLine, int iEndLine) { COORD coord; DWORD dwRead; BOOL bRet; coord.X = 0; coord.Y = iBeginLine; bRet = ReadConsoleOutputCharacter( hStdout, pszText, 80 * (iEndLine - iBeginLine + 1), coord, &dwRead); // Make sure it's null terminated. if (bRet) pszText[dwRead] = '\0'; return bRet; } BOOL WriteText (LPCTSTR szText) { DWORD dwWritten; INPUT_RECORD rec; char upper, *sz; sz = (LPTSTR) szText; while (*sz) { // 13 is the code for a carriage return (\n) instead of 10. if (*sz == 10) *sz = 13; upper = toupper(*sz); rec.EventType = KEY_EVENT; rec.Event.KeyEvent.bKeyDown = TRUE; rec.Event.KeyEvent.wRepeatCount = 1; rec.Event.KeyEvent.wVirtualKeyCode = upper; rec.Event.KeyEvent.wVirtualScanCode = CharToCode (*sz); rec.Event.KeyEvent.uChar.AsciiChar = *sz; rec.Event.KeyEvent.uChar.UnicodeChar = *sz; rec.Event.KeyEvent.dwControlKeyState = isupper(*sz) ? 0x80 : 0x0; WriteConsoleInput( hStdin, &rec, 1, &dwWritten); rec.Event.KeyEvent.bKeyDown = FALSE; WriteConsoleInput( hStdin, &rec, 1, &dwWritten); sz++; } return TRUE; } int CharToCode (char c) { char upper; upper = toupper(c); switch (c) { case 13: return 28; default: break; } if (isalpha(c)) return (30 + upper - 65); if (isdigit(c)) return (1 + upper - 47); return c; } BOOL SetConsoleCXCY(HANDLE hStdout, int cx, int cy) { CONSOLE_SCREEN_BUFFER_INFO info; COORD coordMax; coordMax = GetLargestConsoleWindowSize(hStdout); if (cy > coordMax.Y) cy = coordMax.Y; if (cx > coordMax.X) cx = coordMax.X; if (!GetConsoleScreenBufferInfo(hStdout, &info)) return FALSE; // height info.srWindow.Left = 0; info.srWindow.Right = info.dwSize.X - 1; info.srWindow.Top = 0; info.srWindow.Bottom = cy - 1; if (cy < info.dwSize.Y) { if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow)) return FALSE; info.dwSize.Y = cy; if (!SetConsoleScreenBufferSize(hStdout, info.dwSize)) return FALSE; } else if (cy > info.dwSize.Y) { info.dwSize.Y = cy; if (!SetConsoleScreenBufferSize(hStdout, info.dwSize)) return FALSE; if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow)) return FALSE; } if (!GetConsoleScreenBufferInfo(hStdout, &info)) return FALSE; // width info.srWindow.Left = 0; info.srWindow.Right = cx - 1; info.srWindow.Top = 0; info.srWindow.Bottom = info.dwSize.Y - 1; if (cx < info.dwSize.X) { if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow)) return FALSE; info.dwSize.X = cx; if (!SetConsoleScreenBufferSize(hStdout, info.dwSize)) return FALSE; } else if (cx > info.dwSize.X) { info.dwSize.X = cx; if (!SetConsoleScreenBufferSize(hStdout, info.dwSize)) return FALSE; if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow)) return FALSE; } return TRUE; } alien-arena-7.66+dfsg/source/win32/winquake.h0000600000175000017500000000267712161402010020055 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // winquake.h: Win32-specific Quake header file #pragma warning( disable : 4229 ) // mgraph gets this #include // not used // #include #define WINDOW_STYLE (WS_OVERLAPPED|WS_BORDER|WS_CAPTION|WS_VISIBLE) extern HINSTANCE global_hInstance; /* old sound stuff (2010-08) extern LPDIRECTSOUND pDS; extern LPDIRECTSOUNDBUFFER pDSBuf; extern DWORD gSndBufSize; */ extern HWND cl_hwnd; extern int ActiveApp; extern qboolean Minimized; void IN_Activate (qboolean active); void IN_MouseEvent (int mstate); extern int window_center_x, window_center_y; extern RECT window_rect; LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); alien-arena-7.66+dfsg/source/win32/resource.h0000600000175000017500000000116312161402010020045 0ustar zero79zero79//{{NO_DEPENDENCIES}} // Microsoft Developer Studio generated include file. // Used by q2.rc // #define IDS_STRING1 1 #define IDS_STRING2 2 #define IDI_ICON1 101 #define IDD_DIALOG1 103 #define IDD_DIALOG2 104 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 105 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1000 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif alien-arena-7.66+dfsg/source/win32/qal_win.c0000600000175000017500000002362212161402010017647 0ustar zero79zero79/* Copyright (C) 2009 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * qal_win.c */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "client/client.h" #include "client/qal.h" /* * OpenAL Library */ const char libopenal_name[] = OPENAL_DRIVER ; HINSTANCE hinstOpenAL; // HINSTANCE for the OpenAL library qboolean dlsym_error; /* == get_dlsym() get symbol from DLL == */ static void get_dlsym( const char* symbol_name, void** symbol_addr ) { char *buf = NULL; *symbol_addr = GetProcAddress( hinstOpenAL, symbol_name ); if ( *symbol_addr == NULL ) { FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), ( LPTSTR ) & buf, 0, NULL ); Com_Printf( "%s\n", buf ); dlsym_error = true; } } /* == QAL_Init() QAL_Shutdown() Dynamically link/unlink OpenAL .dll == */ qboolean QAL_Init( void ) { char *buf = NULL; hinstOpenAL = LoadLibrary( libopenal_name ); if( hinstOpenAL == NULL ) { FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), ( LPTSTR ) & buf, 0, NULL ); Com_Printf( "%s\n", buf ); return false; } dlsym_error = false; get_dlsym( "alEnable", (void**) &pqalEnable ); get_dlsym( "alDisable", (void**) &pqalDisable ); get_dlsym( "alIsEnabled", (void**) &pqalIsEnabled ); get_dlsym( "alGetBooleanv", (void**) &pqalGetBooleanv ); get_dlsym( "alGetIntegerv", (void**) &pqalGetIntegerv ); get_dlsym( "alGetString", (void**) &pqalGetString ); get_dlsym( "alGetFloatv", (void**) &pqalGetFloatv ); get_dlsym( "alGetDoublev", (void**) &pqalGetDoublev ); get_dlsym( "alGetBoolean", (void**) &pqalGetBoolean ); get_dlsym( "alGetInteger", (void**) &pqalGetInteger ); get_dlsym( "alGetFloat", (void**) &pqalGetFloat ); get_dlsym( "alGetDouble", (void**) &pqalGetDouble ); get_dlsym( "alGetError", (void**) &pqalGetError ); get_dlsym( "alIsExtensionPresent", (void**) &pqalIsExtensionPresent ); get_dlsym( "alGetProcAddress", (void**) &pqalGetProcAddress ); get_dlsym( "alGetEnumValue", (void**) &pqalGetEnumValue ); get_dlsym( "alListenerf", (void**) &pqalListenerf ); get_dlsym( "alListener3f", (void**) &pqalListener3f ); get_dlsym( "alListenerfv", (void**) &pqalListenerfv ); get_dlsym( "alListeneri", (void**) &pqalListeneri ); get_dlsym( "alListener3i", (void**) &pqalListener3i ); get_dlsym( "alListeneriv", (void**) &pqalListeneriv ); get_dlsym( "alGetListenerf", (void**) &pqalGetListenerf ); get_dlsym( "alGetListener3f", (void**) &pqalGetListener3f ); get_dlsym( "alGetListenerfv", (void**) &pqalGetListenerfv ); get_dlsym( "alGetListeneri", (void**) &pqalGetListeneri ); get_dlsym( "alGetListener3i", (void**) &pqalGetListener3i ); get_dlsym( "alGetListeneriv", (void**) &pqalGetListeneriv ); get_dlsym( "alGenSources", (void**) &pqalGenSources ); get_dlsym( "alDeleteSources", (void**) &pqalDeleteSources ); get_dlsym( "alIsSource", (void**) &pqalIsSource ); get_dlsym( "alSourcef", (void**) &pqalSourcef ); get_dlsym( "alSource3f", (void**) &pqalSource3f ); get_dlsym( "alSourcefv", (void**) &pqalSourcefv ); get_dlsym( "alSourcei", (void**) &pqalSourcei ); get_dlsym( "alSource3i", (void**) &pqalSource3i ); get_dlsym( "alSourceiv", (void**) &pqalSourceiv ); get_dlsym( "alGetSourcef", (void**) &pqalGetSourcef ); get_dlsym( "alGetSource3f", (void**) &pqalGetSource3f ); get_dlsym( "alGetSourcefv", (void**) &pqalGetSourcefv ); get_dlsym( "alGetSourcei", (void**) &pqalGetSourcei ); get_dlsym( "alGetSource3i", (void**) &pqalGetSource3i ); get_dlsym( "alGetSourceiv", (void**) &pqalGetSourceiv ); get_dlsym( "alSourcePlayv", (void**) &pqalSourcePlayv ); get_dlsym( "alSourceStopv", (void**) &pqalSourceStopv ); get_dlsym( "alSourceRewindv", (void**) &pqalSourceRewindv ); get_dlsym( "alSourcePausev", (void**) &pqalSourcePausev ); get_dlsym( "alSourcePlay", (void**) &pqalSourcePlay ); get_dlsym( "alSourceStop", (void**) &pqalSourceStop ); get_dlsym( "alSourceRewind", (void**) &pqalSourceRewind ); get_dlsym( "alSourcePause", (void**) &pqalSourcePause ); get_dlsym( "alSourceQueueBuffers", (void**) &pqalSourceQueueBuffers ); get_dlsym( "alSourceUnqueueBuffers", (void**) &pqalSourceUnqueueBuffers ); get_dlsym( "alGenBuffers", (void**) &pqalGenBuffers ); get_dlsym( "alDeleteBuffers", (void**) &pqalDeleteBuffers ); get_dlsym( "alIsBuffer", (void**) &pqalIsBuffer ); get_dlsym( "alBufferData", (void**) &pqalBufferData ); get_dlsym( "alBufferf", (void**) &pqalBufferf ); get_dlsym( "alBuffer3f", (void**) &pqalBuffer3f ); get_dlsym( "alBufferfv", (void**) &pqalBufferfv ); get_dlsym( "alBufferi", (void**) &pqalBufferi ); get_dlsym( "alBuffer3i", (void**) &pqalBuffer3i ); get_dlsym( "alBufferiv", (void**) &pqalBufferiv ); get_dlsym( "alGetBufferf", (void**) &pqalGetBufferf ); get_dlsym( "alGetBuffer3f", (void**) &pqalGetBuffer3f ); get_dlsym( "alGetBufferfv", (void**) &pqalGetBufferfv ); get_dlsym( "alGetBufferi", (void**) &pqalGetBufferi ); get_dlsym( "alGetBuffer3i", (void**) &pqalGetBuffer3i ); get_dlsym( "alGetBufferiv", (void**) &pqalGetBufferiv ); get_dlsym( "alDopplerFactor", (void**) &pqalDopplerFactor ); get_dlsym( "alDopplerVelocity", (void**) &pqalDopplerVelocity ); get_dlsym( "alSpeedOfSound", (void**) &pqalSpeedOfSound ); get_dlsym( "alDistanceModel", (void**) &pqalDistanceModel ); get_dlsym( "alcCreateContext", (void**) &pqalcCreateContext ); get_dlsym( "alcMakeContextCurrent", (void**) &pqalcMakeContextCurrent ); get_dlsym( "alcProcessContext", (void**) &pqalcProcessContext ); get_dlsym( "alcSuspendContext", (void**) &pqalcSuspendContext ); get_dlsym( "alcDestroyContext", (void**) &pqalcDestroyContext ); get_dlsym( "alcGetCurrentContext", (void**) &pqalcGetCurrentContext ); get_dlsym( "alcGetContextsDevice", (void**) &pqalcGetContextsDevice ); get_dlsym( "alcOpenDevice", (void**) &pqalcOpenDevice ); get_dlsym( "alcCloseDevice", (void**) &pqalcCloseDevice ); get_dlsym( "alcGetError", (void**) &pqalcGetError ); get_dlsym( "alcIsExtensionPresent", (void**) &pqalcIsExtensionPresent ); get_dlsym( "alcGetProcAddress", (void**) &pqalcGetProcAddress ); get_dlsym( "alcGetEnumValue", (void**) &pqalcGetEnumValue ); get_dlsym( "alcGetString", (void**) &pqalcGetString ); get_dlsym( "alcGetIntegerv", (void**) &pqalcGetIntegerv ); get_dlsym( "alcCaptureOpenDevice", (void**) &pqalcCaptureOpenDevice ); get_dlsym( "alcCaptureCloseDevice", (void**) &pqalcCaptureCloseDevice ); get_dlsym( "alcCaptureStart", (void**) &pqalcCaptureStart ); get_dlsym( "alcCaptureStop", (void**) &pqalcCaptureStop ); get_dlsym( "alcCaptureSamples", (void**) &pqalcCaptureSamples ); return !dlsym_error; } void QAL_Shutdown( void ) { if ( hinstOpenAL != NULL ) { FreeLibrary( hinstOpenAL ); hinstOpenAL = NULL; } pqalEnable = NULL; pqalDisable = NULL; pqalIsEnabled = NULL; pqalGetBooleanv = NULL; pqalGetIntegerv = NULL; pqalGetString = NULL; pqalGetFloatv = NULL; pqalGetDoublev = NULL; pqalGetBoolean = NULL; pqalGetInteger = NULL; pqalGetFloat = NULL; pqalGetDouble = NULL; pqalGetError = NULL; pqalIsExtensionPresent = NULL; pqalGetProcAddress = NULL; pqalGetEnumValue = NULL; pqalListenerf = NULL; pqalListener3f = NULL; pqalListenerfv = NULL; pqalListeneri = NULL; pqalListener3i = NULL; pqalListeneriv = NULL; pqalGetListenerf = NULL; pqalGetListener3f = NULL; pqalGetListenerfv = NULL; pqalGetListeneri = NULL; pqalGetListener3i = NULL; pqalGetListeneriv = NULL; pqalGenSources = NULL; pqalDeleteSources = NULL; pqalIsSource = NULL; pqalSourcef = NULL; pqalSource3f = NULL; pqalSourcefv = NULL; pqalSourcei = NULL; pqalSource3i = NULL; pqalSourceiv = NULL; pqalGetSourcef = NULL; pqalGetSource3f = NULL; pqalGetSourcefv = NULL; pqalGetSourcei = NULL; pqalGetSource3i = NULL; pqalGetSourceiv = NULL; pqalSourcePlayv = NULL; pqalSourceStopv = NULL; pqalSourceRewindv = NULL; pqalSourcePausev = NULL; pqalSourcePlay = NULL; pqalSourceStop = NULL; pqalSourceRewind = NULL; pqalSourcePause = NULL; pqalSourceQueueBuffers = NULL; pqalSourceUnqueueBuffers = NULL; pqalGenBuffers = NULL; pqalDeleteBuffers = NULL; pqalIsBuffer = NULL; pqalBufferData = NULL; pqalBufferf = NULL; pqalBuffer3f = NULL; pqalBufferfv = NULL; pqalBufferi = NULL; pqalBuffer3i = NULL; pqalBufferiv = NULL; pqalGetBufferf = NULL; pqalGetBuffer3f = NULL; pqalGetBufferfv = NULL; pqalGetBufferi = NULL; pqalGetBuffer3i = NULL; pqalGetBufferiv = NULL; pqalDopplerFactor = NULL; pqalDopplerVelocity = NULL; pqalSpeedOfSound = NULL; pqalDistanceModel = NULL; pqalcCreateContext = NULL; pqalcMakeContextCurrent = NULL; pqalcProcessContext = NULL; pqalcSuspendContext = NULL; pqalcDestroyContext = NULL; pqalcGetCurrentContext = NULL; pqalcGetContextsDevice = NULL; pqalcOpenDevice = NULL; pqalcCloseDevice = NULL; pqalcGetError = NULL; pqalcIsExtensionPresent = NULL; pqalcGetProcAddress = NULL; pqalcGetEnumValue = NULL; pqalcGetString = NULL; pqalcGetIntegerv = NULL; pqalcCaptureOpenDevice = NULL; pqalcCaptureCloseDevice = NULL; pqalcCaptureStart = NULL; pqalcCaptureStop = NULL; pqalcCaptureSamples = NULL; } /* == QAL_Loaded() check for OpenAL DLL load == */ qboolean QAL_Loaded( void ) { return ( hinstOpenAL != NULL && !dlsym_error ); } alien-arena-7.66+dfsg/source/win32/glw_win.h0000600000175000017500000000244012161402010017663 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _WIN32 # error You should not be including this file on this platform #endif #ifndef __GLW_WIN_H__ #define __GLW_WIN_H__ typedef struct { HINSTANCE hInstance; void *wndproc; HDC hDC; // handle to device context HWND hWnd; // handle to window HGLRC hGLRC; // handle to GL rendering context HINSTANCE hinstOpenGL; // HINSTANCE for the OpenGL library qboolean minidriver; qboolean allowdisplaydepthchange; qboolean mcd_accelerated; FILE *log_fp; } glwstate_t; extern glwstate_t glw_state; #endif alien-arena-7.66+dfsg/source/win32/net_wins.c0000600000175000017500000004737712161402010020060 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // net_wins.c #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "winsock.h" #include "wsipx.h" #include "qcommon/qcommon.h" #define MAX_LOOPBACK 4 typedef struct { byte data[MAX_MSGLEN]; int datalen; } loopmsg_t; typedef struct { loopmsg_t msgs[MAX_LOOPBACK]; int get, send; } loopback_t; cvar_t *net_shownet; static cvar_t *noudp; static cvar_t *noipx; loopback_t loopbacks[2]; int ip_sockets[2]; int ipx_sockets[2]; int server_port; char *NET_ErrorString (void); //============================================================================= void NetadrToSockadr (netadr_t *a, struct sockaddr *s) { memset (s, 0, sizeof(*s)); if (a->type == NA_BROADCAST) { ((struct sockaddr_in *)s)->sin_family = AF_INET; ((struct sockaddr_in *)s)->sin_port = a->port; ((struct sockaddr_in *)s)->sin_addr.s_addr = INADDR_BROADCAST; } else if (a->type == NA_IP) { ((struct sockaddr_in *)s)->sin_family = AF_INET; ((struct sockaddr_in *)s)->sin_addr.s_addr = *(int *)&a->ip; ((struct sockaddr_in *)s)->sin_port = a->port; } else if (a->type == NA_IPX) { ((struct sockaddr_ipx *)s)->sa_family = AF_IPX; memcpy(((struct sockaddr_ipx *)s)->sa_netnum, &a->ipx[0], 4); memcpy(((struct sockaddr_ipx *)s)->sa_nodenum, &a->ipx[4], 6); ((struct sockaddr_ipx *)s)->sa_socket = a->port; } else if (a->type == NA_BROADCAST_IPX) { ((struct sockaddr_ipx *)s)->sa_family = AF_IPX; memset(((struct sockaddr_ipx *)s)->sa_netnum, 0, 4); memset(((struct sockaddr_ipx *)s)->sa_nodenum, 0xff, 6); ((struct sockaddr_ipx *)s)->sa_socket = a->port; } } void SockadrToNetadr (struct sockaddr *s, netadr_t *a) { if (s->sa_family == AF_INET) { a->type = NA_IP; *(int *)&a->ip = ((struct sockaddr_in *)s)->sin_addr.s_addr; a->port = ((struct sockaddr_in *)s)->sin_port; } else if (s->sa_family == AF_IPX) { a->type = NA_IPX; memcpy(&a->ipx[0], ((struct sockaddr_ipx *)s)->sa_netnum, 4); memcpy(&a->ipx[4], ((struct sockaddr_ipx *)s)->sa_nodenum, 6); a->port = ((struct sockaddr_ipx *)s)->sa_socket; } } qboolean NET_CompareAdr (netadr_t a, netadr_t b) { if (a.type != b.type) return false; if (a.type == NA_LOOPBACK) return TRUE; if (a.type == NA_IP) { if (a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3] && a.port == b.port) return true; } if (a.type == NA_IPX) { if ((memcmp(a.ipx, b.ipx, 10) == 0) && a.port == b.port) return true; } return false; } /* =================== NET_CompareBaseAdr Compares without the port =================== */ qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b) { if (a.type != b.type) return false; if (a.type == NA_LOOPBACK) return TRUE; if (a.type == NA_IP) { if (a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3]) return true; } if (a.type == NA_IPX) { if ((memcmp(a.ipx, b.ipx, 10) == 0)) return true; } return false; } char *NET_AdrToString (netadr_t a) { static char s[64]; if (a.type == NA_LOOPBACK) Com_sprintf (s, sizeof(s), "loopback"); else if (a.type == NA_IP) Com_sprintf (s, sizeof(s), "%i.%i.%i.%i:%i", a.ip[0], a.ip[1], a.ip[2], a.ip[3], ntohs(a.port)); else Com_sprintf (s, sizeof(s), "%02x%02x%02x%02x:%02x%02x%02x%02x%02x%02x:%i", a.ipx[0], a.ipx[1], a.ipx[2], a.ipx[3], a.ipx[4], a.ipx[5], a.ipx[6], a.ipx[7], a.ipx[8], a.ipx[9], ntohs(a.port)); return s; } /* ============= NET_StringToAdr localhost idnewt idnewt:28000 192.246.40.70 192.246.40.70:28000 ============= */ #define DO(src,dest) \ copy[0] = s[src]; \ copy[1] = s[src + 1]; \ sscanf (copy, "%x", &val); \ ((struct sockaddr_ipx *)sadr)->dest = val qboolean NET_StringToSockaddr (char *s, struct sockaddr *sadr) { struct hostent *h; char *colon; int val; char copy[128]; memset (sadr, 0, sizeof(*sadr)); if ((strlen(s) >= 23) && (s[8] == ':') && (s[21] == ':')) // check for an IPX address { ((struct sockaddr_ipx *)sadr)->sa_family = AF_IPX; copy[2] = 0; DO(0, sa_netnum[0]); DO(2, sa_netnum[1]); DO(4, sa_netnum[2]); DO(6, sa_netnum[3]); DO(9, sa_nodenum[0]); DO(11, sa_nodenum[1]); DO(13, sa_nodenum[2]); DO(15, sa_nodenum[3]); DO(17, sa_nodenum[4]); DO(19, sa_nodenum[5]); sscanf (&s[22], "%u", &val); ((struct sockaddr_ipx *)sadr)->sa_socket = htons((unsigned short)val); } else { ((struct sockaddr_in *)sadr)->sin_family = AF_INET; ((struct sockaddr_in *)sadr)->sin_port = 0; strcpy (copy, s); // strip off a trailing :port if present for (colon = copy ; *colon ; colon++) if (*colon == ':') { *colon = 0; ((struct sockaddr_in *)sadr)->sin_port = htons((short)atoi(colon+1)); } if (copy[0] >= '0' && copy[0] <= '9') { *(int *)&((struct sockaddr_in *)sadr)->sin_addr = inet_addr(copy); } else { if (! (h = gethostbyname(copy)) ) return 0; *(int *)&((struct sockaddr_in *)sadr)->sin_addr = *(int *)h->h_addr_list[0]; } } return true; } #undef DO /* ============= NET_StringToAdr localhost idnewt idnewt:28000 192.246.40.70 192.246.40.70:28000 ============= */ qboolean NET_StringToAdr (char *s, netadr_t *a) { struct sockaddr sadr; if (!strcmp (s, "localhost")) { memset (a, 0, sizeof(*a)); a->type = NA_LOOPBACK; return true; } if (!NET_StringToSockaddr (s, &sadr)) return false; SockadrToNetadr (&sadr, a); return true; } qboolean NET_IsLocalAddress (netadr_t adr) { return adr.type == NA_LOOPBACK; } /* ============================================================================= LOOPBACK BUFFERS FOR LOCAL PLAYER ============================================================================= */ qboolean NET_GetLoopPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message) { int i; loopback_t *loop; loop = &loopbacks[sock]; if (loop->send - loop->get > MAX_LOOPBACK) loop->get = loop->send - MAX_LOOPBACK; if (loop->get >= loop->send) return false; i = loop->get & (MAX_LOOPBACK-1); loop->get++; memcpy (net_message->data, loop->msgs[i].data, loop->msgs[i].datalen); net_message->cursize = loop->msgs[i].datalen; memset (net_from, 0, sizeof(*net_from)); net_from->type = NA_LOOPBACK; return true; } void NET_SendLoopPacket (netsrc_t sock, int length, void *data, netadr_t to) { int i; loopback_t *loop; loop = &loopbacks[sock^1]; i = loop->send & (MAX_LOOPBACK-1); loop->send++; memcpy (loop->msgs[i].data, data, length); loop->msgs[i].datalen = length; } //============================================================================= qboolean NET_GetPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message) { int ret; struct sockaddr from; int fromlen; int net_socket; int protocol; int err; if (NET_GetLoopPacket (sock, net_from, net_message)) return true; for (protocol = 0 ; protocol < 2 ; protocol++) { if (protocol == 0) net_socket = ip_sockets[sock]; else net_socket = ipx_sockets[sock]; if (!net_socket) continue; fromlen = sizeof(from); ret = recvfrom (net_socket, net_message->data, net_message->maxsize , 0, (struct sockaddr *)&from, &fromlen); SockadrToNetadr (&from, net_from); if (ret == -1) { err = WSAGetLastError(); if (err == WSAEWOULDBLOCK) continue; if (err == WSAEMSGSIZE) { Com_Printf ("Warning: Oversize packet from %s\n", NET_AdrToString(*net_from)); continue; } if (dedicated->value) // let dedicated servers continue after errors Com_Printf ("NET_GetPacket: %s from %s\n", NET_ErrorString(), NET_AdrToString(*net_from)); else // Com_Error (ERR_DROP, "NET_GetPacket: %s from %s", // NET_ErrorString(), NET_AdrToString(*net_from)); Com_Printf ("NET_GetPacket: %s from %s\n", NET_ErrorString(), NET_AdrToString(*net_from)); continue; } if (ret == net_message->maxsize) { Com_Printf ("Oversize packet from %s\n", NET_AdrToString (*net_from)); continue; } net_message->cursize = ret; return true; } return false; } //============================================================================= void NET_SendPacket (netsrc_t sock, int length, void *data, netadr_t to) { int ret; struct sockaddr addr; int net_socket; if ( to.type == NA_LOOPBACK ) { NET_SendLoopPacket (sock, length, data, to); return; } if (to.type == NA_BROADCAST) { net_socket = ip_sockets[sock]; if (!net_socket) return; } else if (to.type == NA_IP) { net_socket = ip_sockets[sock]; if (!net_socket) return; } else if (to.type == NA_IPX) { net_socket = ipx_sockets[sock]; if (!net_socket) return; } else if (to.type == NA_BROADCAST_IPX) { net_socket = ipx_sockets[sock]; if (!net_socket) return; } else Com_Error (ERR_FATAL, "NET_SendPacket: bad address type"); NetadrToSockadr (&to, &addr); ret = sendto (net_socket, data, length, 0, &addr, sizeof(addr) ); if (ret == -1) { int err = WSAGetLastError(); // wouldblock is silent if (err == WSAEWOULDBLOCK) return; // some PPP links dont allow broadcasts if ((err == WSAEADDRNOTAVAIL) && ((to.type == NA_BROADCAST) || (to.type == NA_BROADCAST_IPX))) return; if (dedicated->value) // let dedicated servers continue after errors { Com_Printf ("NET_SendPacket ERROR: %s to %s\n", NET_ErrorString(), NET_AdrToString (to)); } else { if (err == WSAEADDRNOTAVAIL) { Com_DPrintf ("NET_SendPacket Warning: %s : %s\n", NET_ErrorString(), NET_AdrToString (to)); } else { //Com_Error (ERR_DROP, "NET_SendPacket ERROR: %s to %s\n", // NET_ErrorString(), NET_AdrToString (to)); Com_DPrintf ("NET_SendPacket Warning: %s : %s\n", //don't want the game to stop NET_ErrorString(), NET_AdrToString (to)); } } } } //============================================================================= /* ==================== NET_Socket ==================== */ int NET_IPSocket (char *net_interface, int port) { int newsocket; struct sockaddr_in address; u_long _true = true; int i = 1; int err; if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { err = WSAGetLastError(); if (err != WSAEAFNOSUPPORT) Com_Printf ("WARNING: UDP_OpenSocket: socket: %s", NET_ErrorString()); return 0; } // make it non-blocking if (ioctlsocket (newsocket, FIONBIO, &_true) == -1) { Com_Printf ("WARNING: UDP_OpenSocket: ioctl FIONBIO: %s\n", NET_ErrorString()); return 0; } // make it broadcast capable if (setsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) == -1) { Com_Printf ("WARNING: UDP_OpenSocket: setsockopt SO_BROADCAST: %s\n", NET_ErrorString()); return 0; } if (!net_interface || !net_interface[0] || !Q_strcasecmp(net_interface, "localhost")) address.sin_addr.s_addr = INADDR_ANY; else NET_StringToSockaddr (net_interface, (struct sockaddr *)&address); if (port == PORT_ANY) address.sin_port = 0; else address.sin_port = htons((short)port); address.sin_family = AF_INET; if( bind (newsocket, (void *)&address, sizeof(address)) == -1) { Com_Printf ("WARNING: UDP_OpenSocket: bind: %s\n", NET_ErrorString()); closesocket (newsocket); return 0; } return newsocket; } /* ==================== NET_OpenIP ==================== */ void NET_OpenIP (void) { cvar_t *ip; int port; int dedicated; ip = Cvar_Get ("ip", "localhost", CVAR_NOSET); dedicated = Cvar_VariableValue ("dedicated"); if (!ip_sockets[NS_SERVER]) { port = Cvar_Get("ip_hostport", "0", CVAR_NOSET)->value; if (!port) { port = Cvar_Get("hostport", "0", CVAR_NOSET)->value; if (!port) { port = Cvar_Get("port", va("%i", PORT_SERVER), CVAR_NOSET)->value; } } server_port = (ptrdiff_t)port; ip_sockets[NS_SERVER] = NET_IPSocket (ip->string, port); if (!ip_sockets[NS_SERVER] && dedicated) Com_Error (ERR_FATAL, "Couldn't allocate dedicated server IP port"); } // dedicated servers don't need client ports if (dedicated) return; if (!ip_sockets[NS_CLIENT]) { port = Cvar_Get("ip_clientport", "0", CVAR_NOSET)->value; if (!port) { port = Cvar_Get("clientport", va("%i", PORT_CLIENT), CVAR_NOSET)->value; if (!port) port = PORT_ANY; } ip_sockets[NS_CLIENT] = NET_IPSocket (ip->string, port); if (!ip_sockets[NS_CLIENT]) ip_sockets[NS_CLIENT] = NET_IPSocket (ip->string, PORT_ANY); } } /* ==================== IPX_Socket ==================== */ int NET_IPXSocket (int port) { int newsocket; struct sockaddr_ipx address; int _true = 1; int err; if ((newsocket = socket (PF_IPX, SOCK_DGRAM, NSPROTO_IPX)) == -1) { err = WSAGetLastError(); if (err != WSAEAFNOSUPPORT) Com_Printf ("WARNING: IPX_Socket: socket: %s\n", NET_ErrorString()); return 0; } // make it non-blocking if (ioctlsocket (newsocket, FIONBIO, &_true) == -1) { Com_Printf ("WARNING: IPX_Socket: ioctl FIONBIO: %s\n", NET_ErrorString()); return 0; } // make it broadcast capable if (setsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&_true, sizeof(_true)) == -1) { Com_Printf ("WARNING: IPX_Socket: setsockopt SO_BROADCAST: %s\n", NET_ErrorString()); return 0; } address.sa_family = AF_IPX; memset (address.sa_netnum, 0, 4); memset (address.sa_nodenum, 0, 6); if (port == PORT_ANY) address.sa_socket = 0; else address.sa_socket = htons((short)port); if( bind (newsocket, (void *)&address, sizeof(address)) == -1) { Com_Printf ("WARNING: IPX_Socket: bind: %s\n", NET_ErrorString()); closesocket (newsocket); return 0; } return newsocket; } /* ==================== NET_OpenIPX ==================== */ void NET_OpenIPX (void) { int port; int dedicated; dedicated = Cvar_VariableValue ("dedicated"); if (!ipx_sockets[NS_SERVER]) { port = Cvar_Get("ipx_hostport", "0", CVAR_NOSET)->value; if (!port) { port = Cvar_Get("hostport", "0", CVAR_NOSET)->value; if (!port) { port = Cvar_Get("port", va("%i", PORT_SERVER), CVAR_NOSET)->value; } } ipx_sockets[NS_SERVER] = NET_IPXSocket (port); } // dedicated servers don't need client ports if (dedicated) return; if (!ipx_sockets[NS_CLIENT]) { port = Cvar_Get("ipx_clientport", "0", CVAR_NOSET)->value; if (!port) { port = Cvar_Get("clientport", va("%i", PORT_CLIENT), CVAR_NOSET)->value; if (!port) port = PORT_ANY; } ipx_sockets[NS_CLIENT] = NET_IPXSocket (port); if (!ipx_sockets[NS_CLIENT]) ipx_sockets[NS_CLIENT] = NET_IPXSocket (PORT_ANY); } } /* ==================== NET_Config A single player game will only use the loopback code ==================== */ void NET_Config (qboolean multiplayer) { int i; static qboolean old_config; if (old_config == multiplayer) return; old_config = multiplayer; if (!multiplayer) { // shut down any existing sockets for (i=0 ; i<2 ; i++) { if (ip_sockets[i]) { closesocket (ip_sockets[i]); ip_sockets[i] = 0; } if (ipx_sockets[i]) { closesocket (ipx_sockets[i]); ipx_sockets[i] = 0; } } } else { // open sockets if (! noudp->value) NET_OpenIP (); if (! noipx->value) NET_OpenIPX (); } } // sleeps msec or until net socket is ready void NET_Sleep(int msec) { struct timeval timeout; fd_set fdset; extern cvar_t *dedicated; int i; if (!dedicated || !dedicated->value) return; // we're not a server, just run full speed FD_ZERO(&fdset); i = 0; if (ip_sockets[NS_SERVER]) { FD_SET(ip_sockets[NS_SERVER], &fdset); // network socket i = ip_sockets[NS_SERVER]; } if (ipx_sockets[NS_SERVER]) { FD_SET(ipx_sockets[NS_SERVER], &fdset); // network socket if (ipx_sockets[NS_SERVER] > i) i = ipx_sockets[NS_SERVER]; } timeout.tv_sec = msec/1000; timeout.tv_usec = (msec%1000)*1000; select(i+1, &fdset, NULL, NULL, &timeout); } //=================================================================== static WSADATA winsockdata; /* ==================== NET_Init ==================== */ void NET_Init (void) { WORD wVersionRequested; int r; wVersionRequested = MAKEWORD(1, 1); r = WSAStartup (MAKEWORD(1, 1), &winsockdata); if (r) Com_Error (ERR_FATAL,"Winsock initialization failed."); Com_Printf("Winsock Initialized\n"); noudp = Cvar_Get ("noudp", "0", CVAR_NOSET); noipx = Cvar_Get ("noipx", "0", CVAR_NOSET); net_shownet = Cvar_Get ("net_shownet", "0", 0); } /* ==================== NET_Shutdown ==================== */ void NET_Shutdown (void) { NET_Config (false); // close sockets WSACleanup (); } /* ==================== NET_ErrorString ==================== */ char *NET_ErrorString (void) { int code; code = WSAGetLastError (); switch (code) { case WSAEINTR: return "WSAEINTR"; case WSAEBADF: return "WSAEBADF"; case WSAEACCES: return "WSAEACCES"; case WSAEDISCON: return "WSAEDISCON"; case WSAEFAULT: return "WSAEFAULT"; case WSAEINVAL: return "WSAEINVAL"; case WSAEMFILE: return "WSAEMFILE"; case WSAEWOULDBLOCK: return "WSAEWOULDBLOCK"; case WSAEINPROGRESS: return "WSAEINPROGRESS"; case WSAEALREADY: return "WSAEALREADY"; case WSAENOTSOCK: return "WSAENOTSOCK"; case WSAEDESTADDRREQ: return "WSAEDESTADDRREQ"; case WSAEMSGSIZE: return "WSAEMSGSIZE"; case WSAEPROTOTYPE: return "WSAEPROTOTYPE"; case WSAENOPROTOOPT: return "WSAENOPROTOOPT"; case WSAEPROTONOSUPPORT: return "WSAEPROTONOSUPPORT"; case WSAESOCKTNOSUPPORT: return "WSAESOCKTNOSUPPORT"; case WSAEOPNOTSUPP: return "WSAEOPNOTSUPP"; case WSAEPFNOSUPPORT: return "WSAEPFNOSUPPORT"; case WSAEAFNOSUPPORT: return "WSAEAFNOSUPPORT"; case WSAEADDRINUSE: return "WSAEADDRINUSE"; case WSAEADDRNOTAVAIL: return "WSAEADDRNOTAVAIL"; case WSAENETDOWN: return "WSAENETDOWN"; case WSAENETUNREACH: return "WSAENETUNREACH"; case WSAENETRESET: return "WSAENETRESET"; case WSAECONNABORTED: return "WSWSAECONNABORTEDAEINTR"; case WSAECONNRESET: return "WSAECONNRESET"; case WSAENOBUFS: return "WSAENOBUFS"; case WSAEISCONN: return "WSAEISCONN"; case WSAENOTCONN: return "WSAENOTCONN"; case WSAESHUTDOWN: return "WSAESHUTDOWN"; case WSAETOOMANYREFS: return "WSAETOOMANYREFS"; case WSAETIMEDOUT: return "WSAETIMEDOUT"; case WSAECONNREFUSED: return "WSAECONNREFUSED"; case WSAELOOP: return "WSAELOOP"; case WSAENAMETOOLONG: return "WSAENAMETOOLONG"; case WSAEHOSTDOWN: return "WSAEHOSTDOWN"; case WSASYSNOTREADY: return "WSASYSNOTREADY"; case WSAVERNOTSUPPORTED: return "WSAVERNOTSUPPORTED"; case WSANOTINITIALISED: return "WSANOTINITIALISED"; case WSAHOST_NOT_FOUND: return "WSAHOST_NOT_FOUND"; case WSATRY_AGAIN: return "WSATRY_AGAIN"; case WSANO_RECOVERY: return "WSANO_RECOVERY"; case WSANO_DATA: return "WSANO_DATA"; default: return "NO ERROR"; } } alien-arena-7.66+dfsg/source/win32/in_win.c0000600000175000017500000004766112161402010017511 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // in_win.c -- windows 95 mouse and joystick code // 02/21/97 JCB Added extended DirectInput code to support external controllers. #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "client/client.h" #include "winquake.h" extern unsigned sys_msg_time; extern cursor_t cursor; extern qboolean mouse_available; // joystick defines and variables // where should defines be moved? #define JOY_ABSOLUTE_AXIS 0x00000000 // control like a joystick #define JOY_RELATIVE_AXIS 0x00000010 // control like a mouse, spinner, trackball #define JOY_MAX_AXES 6 // X, Y, Z, R, U, V #define JOY_AXIS_X 0 #define JOY_AXIS_Y 1 #define JOY_AXIS_Z 2 #define JOY_AXIS_R 3 #define JOY_AXIS_U 4 #define JOY_AXIS_V 5 enum _ControlList { AxisNada = 0, AxisForward, AxisLook, AxisSide, AxisTurn, AxisUp }; DWORD dwAxisFlags[JOY_MAX_AXES] = { JOY_RETURNX, JOY_RETURNY, JOY_RETURNZ, JOY_RETURNR, JOY_RETURNU, JOY_RETURNV }; DWORD dwAxisMap[JOY_MAX_AXES]; DWORD dwControlMap[JOY_MAX_AXES]; PDWORD pdwRawValue[JOY_MAX_AXES]; cvar_t *in_mouse; cvar_t *in_joystick; // none of these cvars are saved over a session // this means that advanced controller configuration needs to be executed // each time. this avoids any problems with getting back to a default usage // or when changing from one controller to another. this way at least something // works. cvar_t *joy_name; cvar_t *joy_advanced; cvar_t *joy_advaxisx; cvar_t *joy_advaxisy; cvar_t *joy_advaxisz; cvar_t *joy_advaxisr; cvar_t *joy_advaxisu; cvar_t *joy_advaxisv; cvar_t *joy_forwardthreshold; cvar_t *joy_sidethreshold; cvar_t *joy_pitchthreshold; cvar_t *joy_yawthreshold; cvar_t *joy_forwardsensitivity; cvar_t *joy_sidesensitivity; cvar_t *joy_pitchsensitivity; cvar_t *joy_yawsensitivity; cvar_t *joy_upthreshold; cvar_t *joy_upsensitivity; qboolean joy_avail, joy_advancedinit, joy_haspov; DWORD joy_oldbuttonstate, joy_oldpovstate; int joy_id; DWORD joy_flags; DWORD joy_numbuttons; static JOYINFOEX ji; qboolean in_appactive; // forward-referenced functions void IN_StartupJoystick (void); void Joy_AdvancedUpdate_f (void); void IN_JoyMove (usercmd_t *cmd); /* ============================================================ MOUSE CONTROL ============================================================ */ // mouse variables cvar_t *m_filter; cvar_t *m_accel; qboolean mlooking; int mouse_buttons; int mouse_oldbuttonstate; qboolean restore_spi; qboolean mouseinitialized; int originalmouseparms[3], newmouseparms[3] = {0, 0, 1}, noaccelmouseparms[3] = {0, 0, 0}; qboolean mouseparmsvalid; int window_center_x, window_center_y; RECT window_rect; /* =========== IN_ActivateMouse Called when the window gains focus or changes in some way =========== */ void IN_ActivateMouse (void) { int width, height; if (!mouseinitialized) return; if (!in_mouse->value) { mouse_available = false; return; } if (mouse_available) return; mouse_available = true; if (mouseparmsvalid) { switch(m_accel->integer) { case 0: restore_spi = SystemParametersInfo (SPI_SETMOUSE, 0, noaccelmouseparms, 0); break; case 1: default: restore_spi = SystemParametersInfo (SPI_SETMOUSE, 0, newmouseparms, 0); break; } } width = GetSystemMetrics (SM_CXSCREEN); height = GetSystemMetrics (SM_CYSCREEN); GetWindowRect ( cl_hwnd, &window_rect); if (window_rect.left < 0) window_rect.left = 0; if (window_rect.top < 0) window_rect.top = 0; if (window_rect.right >= width) window_rect.right = width-1; if (window_rect.bottom >= height-1) window_rect.bottom = height-1; window_center_x = (window_rect.right + window_rect.left)/2; window_center_y = (window_rect.top + window_rect.bottom)/2; SetCursorPos (window_center_x, window_center_y); SetCapture ( cl_hwnd ); ClipCursor (&window_rect); while (ShowCursor (FALSE) >= 0) ; } /* =========== IN_DeactivateMouse Called when the window loses focus =========== */ void IN_DeactivateMouse (void) { if (!mouseinitialized) return; if (!mouse_available) return; if (restore_spi) SystemParametersInfo (SPI_SETMOUSE, 0, originalmouseparms, 0); mouse_available = false; ClipCursor (NULL); ReleaseCapture (); while (ShowCursor (TRUE) < 0) ; } /* =========== IN_StartupMouse =========== */ void refreshCursorLink (void); void IN_StartupMouse (void) { cvar_t *cv; cv = Cvar_Get ("in_initmouse", "1", CVAR_NOSET); if ( !cv->value ) return; refreshCursorLink(); cursor.mouseaction = false; mouseinitialized = true; mouseparmsvalid = SystemParametersInfo (SPI_GETMOUSE, 0, originalmouseparms, 0); mouse_buttons = 7; /* TODO: Are 9 possible? Do 7 work now? */ } /* =========== IN_MouseEvent =========== */ void M_Think_MouseCursor (void); void IN_MouseEvent (int mstate) { int i; if (!mouseinitialized) return; // perform button actions for (i=0 ; i MENU_CURSOR_BUTTON_MAX) max = MENU_CURSOR_BUTTON_MAX; for (i=0 ; imax) cursor.buttonclicks[i] = max; cursor.buttontime[i] = sys_msg_time; cursor.buttondown[i] = true; cursor.buttonused[i] = false; cursor.mouseaction = true; } else if ( !(mstate & (1<value ) return; // verify joystick driver is present if ((numdevs = joyGetNumDevs ()) == 0) { // Com_Printf ("\njoystick not found -- driver not present\n\n"); return; } // cycle through the joystick ids for the first valid one for (joy_id=0 ; joy_idvalue == 0.0) { // default joystick initialization // 2 axes only with joystick control dwAxisMap[JOY_AXIS_X] = AxisTurn; // dwControlMap[JOY_AXIS_X] = JOY_ABSOLUTE_AXIS; dwAxisMap[JOY_AXIS_Y] = AxisForward; // dwControlMap[JOY_AXIS_Y] = JOY_ABSOLUTE_AXIS; } else { if (strcmp (joy_name->string, "joystick") != 0) { // notify user of advanced controller Com_Printf ("\n%s configured\n\n", joy_name->string); } // advanced initialization here // data supplied by user via joy_axisn cvars dwTemp = (DWORD) joy_advaxisx->value; dwAxisMap[JOY_AXIS_X] = dwTemp & 0x0000000f; dwControlMap[JOY_AXIS_X] = dwTemp & JOY_RELATIVE_AXIS; dwTemp = (DWORD) joy_advaxisy->value; dwAxisMap[JOY_AXIS_Y] = dwTemp & 0x0000000f; dwControlMap[JOY_AXIS_Y] = dwTemp & JOY_RELATIVE_AXIS; dwTemp = (DWORD) joy_advaxisz->value; dwAxisMap[JOY_AXIS_Z] = dwTemp & 0x0000000f; dwControlMap[JOY_AXIS_Z] = dwTemp & JOY_RELATIVE_AXIS; dwTemp = (DWORD) joy_advaxisr->value; dwAxisMap[JOY_AXIS_R] = dwTemp & 0x0000000f; dwControlMap[JOY_AXIS_R] = dwTemp & JOY_RELATIVE_AXIS; dwTemp = (DWORD) joy_advaxisu->value; dwAxisMap[JOY_AXIS_U] = dwTemp & 0x0000000f; dwControlMap[JOY_AXIS_U] = dwTemp & JOY_RELATIVE_AXIS; dwTemp = (DWORD) joy_advaxisv->value; dwAxisMap[JOY_AXIS_V] = dwTemp & 0x0000000f; dwControlMap[JOY_AXIS_V] = dwTemp & JOY_RELATIVE_AXIS; } // compute the axes to collect from DirectInput joy_flags = JOY_RETURNCENTERED | JOY_RETURNBUTTONS | JOY_RETURNPOV; for (i = 0; i < JOY_MAX_AXES; i++) { if (dwAxisMap[i] != AxisNada) { joy_flags |= dwAxisFlags[i]; } } } /* =========== IN_Commands =========== */ void IN_Commands (void) { int i, key_index; DWORD buttonstate, povstate; if (!joy_avail) { return; } // loop through the joystick buttons // key a joystick event or auxillary event for higher number buttons for each state change buttonstate = ji.dwButtons; for (i=0 ; i < joy_numbuttons ; i++) { if ( (buttonstate & (1<value) { return; } // collect the joystick data, if possible if (IN_ReadJoystick () != true) { return; } if (!cl.tactical && ( (in_speed.state & 1) ^ cl_run->integer)) speed = 2; else speed = 1; aspeed = speed * cls.frametime; // loop through the axes for (i = 0; i < JOY_MAX_AXES; i++) { // get the floating point zero-centered, potentially-inverted data for the current axis fAxisValue = (float) *pdwRawValue[i]; // move centerpoint to zero fAxisValue -= 32768.0; // convert range from -32768..32767 to -1..1 fAxisValue /= 32768.0; switch (dwAxisMap[i]) { case AxisForward: if ((joy_advanced->value == 0.0) && mlooking) { // user wants forward control to become look control if (fabs(fAxisValue) > joy_pitchthreshold->value) { // if mouse invert is on, invert the joystick pitch value // only absolute control support here (joy_advanced is false) if (m_pitch->value < 0.0) { cl.viewangles[PITCH] -= (fAxisValue * joy_pitchsensitivity->value) * aspeed * cl_pitchspeed->value; } else { cl.viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity->value) * aspeed * cl_pitchspeed->value; } } } else { // user wants forward control to be forward control if (fabs(fAxisValue) > joy_forwardthreshold->value) { cmd->forwardmove += (fAxisValue * joy_forwardsensitivity->value) * speed * cl_forwardspeed->value; } } break; case AxisSide: if (fabs(fAxisValue) > joy_sidethreshold->value) { cmd->sidemove += (fAxisValue * joy_sidesensitivity->value) * speed * cl_sidespeed->value; } break; case AxisUp: if (fabs(fAxisValue) > joy_upthreshold->value) { cmd->upmove += (fAxisValue * joy_upsensitivity->value) * speed * cl_upspeed->value; } break; case AxisTurn: if ((in_strafe.state & 1) || (lookstrafe->value && mlooking)) { // user wants turn control to become side control if (fabs(fAxisValue) > joy_sidethreshold->value) { cmd->sidemove -= (fAxisValue * joy_sidesensitivity->value) * speed * cl_sidespeed->value; } } else { // user wants turn control to be turn control if (fabs(fAxisValue) > joy_yawthreshold->value) { if(dwControlMap[i] == JOY_ABSOLUTE_AXIS) { cl.viewangles[YAW] += (fAxisValue * joy_yawsensitivity->value) * aspeed * cl_yawspeed->value; } else { cl.viewangles[YAW] += (fAxisValue * joy_yawsensitivity->value) * speed * 180.0; } } } break; case AxisLook: if (mlooking) { if (fabs(fAxisValue) > joy_pitchthreshold->value) { // pitch movement detected and pitch movement desired by user if(dwControlMap[i] == JOY_ABSOLUTE_AXIS) { cl.viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity->value) * aspeed * cl_pitchspeed->value; } else { cl.viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity->value) * speed * 180.0; } } } break; default: break; } } } alien-arena-7.66+dfsg/source/win32/glw_imp.c0000600000175000017500000005021012161402010017644 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* ** GLW_IMP.C ** ** This file contains ALL Win32 specific stuff having to do with the ** OpenGL refresh. When a port is being made the following functions ** must be implemented by the port: ** ** GLimp_EndFrame ** GLimp_Init ** GLimp_Shutdown ** GLimp_SwitchFullscreen ** */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "ref_gl/r_local.h" #include "glw_win.h" #include "winquake.h" #include "resource.h" static qboolean GLimp_SwitchFullscreen( int width, int height ); qboolean GLimp_InitGL (void); glwstate_t glw_state; extern cvar_t *vid_fullscreen; extern cvar_t *vid_ref; extern cvar_t *vid_displayfrequency; qboolean have_stencil = false; // Stencil shadows - MrG static qboolean VerifyDriver( void ) { char buffer[1024]; strcpy( buffer, qglGetString( GL_RENDERER ) ); _strlwr( buffer ); if ( strcmp( buffer, "gdi generic" ) == 0 ) if ( !glw_state.mcd_accelerated ) return false; return true; } /* ** VID_CreateWindow */ #define WINDOW_CLASS_NAME "Quake 2" qboolean VID_CreateWindow( int width, int height, qboolean fullscreen ) { WNDCLASS wc; RECT r; cvar_t *vid_xpos, *vid_ypos; int stylebits; int x, y, w, h; int exstyle; /* Register the frame class */ wc.style = 0; wc.lpfnWndProc = (WNDPROC)glw_state.wndproc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = glw_state.hInstance; wc.hIcon = 0; wc.hCursor = LoadCursor (NULL,IDC_ARROW); wc.hbrBackground = (void *)COLOR_GRAYTEXT; wc.lpszMenuName = 0; wc.lpszClassName = WINDOW_CLASS_NAME; if (!RegisterClass (&wc) ) Com_Error (ERR_FATAL, "Couldn't register window class"); if (fullscreen) { exstyle = WS_EX_TOPMOST; stylebits = WS_POPUP|WS_VISIBLE; } else { exstyle = 0; stylebits = WINDOW_STYLE; } r.left = 0; r.top = 0; r.right = width; r.bottom = height; AdjustWindowRect (&r, stylebits, FALSE); w = r.right - r.left; h = r.bottom - r.top; if (fullscreen) { x = 0; y = 0; } else { vid_xpos = Cvar_Get ("vid_xpos", "0", 0); vid_ypos = Cvar_Get ("vid_ypos", "0", 0); x = vid_xpos->value; y = vid_ypos->value; } glw_state.hWnd = CreateWindowEx ( exstyle, WINDOW_CLASS_NAME, "CRX", stylebits, x, y, w, h, NULL, NULL, glw_state.hInstance, NULL); if (!glw_state.hWnd) Com_Error (ERR_FATAL, "Couldn't create window"); ShowWindow( glw_state.hWnd, SW_SHOW ); UpdateWindow( glw_state.hWnd ); // init all the gl stuff for the window if (!GLimp_InitGL ()) { Com_Printf ("VID_CreateWindow() - GLimp_InitGL failed\n"); return false; } SetForegroundWindow( glw_state.hWnd ); SetFocus( glw_state.hWnd ); // let the sound and input subsystems know about the new window VID_NewWindow (width, height); return true; } /* ** GLimp_SetMode */ rserr_t GLimp_SetMode( unsigned *pwidth, unsigned *pheight, int mode, qboolean fullscreen ) { int width, height; const char *win_fs[] = { "W", "FS" }; Com_Printf ("Initializing OpenGL display\n"); Com_Printf ("...setting mode %d:", mode ); if ( !VID_GetModeInfo( &width, &height, mode ) ) { Com_Printf( " invalid mode\n" ); return rserr_invalid_mode; } Com_Printf (" %d %d %s\n", width, height, win_fs[fullscreen] ); // destroy the existing window if (glw_state.hWnd) { GLimp_Shutdown (); } // do a CDS if needed if ( fullscreen ) { DEVMODE dm; Com_Printf ("...attempting fullscreen\n" ); memset( &dm, 0, sizeof( dm ) ); dm.dmSize = sizeof( dm ); dm.dmPelsWidth = width; dm.dmPelsHeight = height; dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; if ( gl_bitdepth->value != 0 ) { dm.dmBitsPerPel = gl_bitdepth->value; dm.dmFields |= DM_BITSPERPEL; Com_Printf( "...using gl_bitdepth of %d\n", ( int ) gl_bitdepth->value ); } else { HDC hdc = GetDC( NULL ); int bitspixel = GetDeviceCaps( hdc, BITSPIXEL ); Com_Printf ("...using desktop display depth of %d\n", bitspixel ); ReleaseDC( 0, hdc ); } if ( vid_displayfrequency->integer > 0 ) { dm.dmFields |= DM_DISPLAYFREQUENCY; dm.dmDisplayFrequency = vid_displayfrequency->integer; Com_Printf ( "...using display frequency %i\n", dm.dmDisplayFrequency ); } Com_Printf ("...calling CDS: " ); if ( ChangeDisplaySettings( &dm, CDS_FULLSCREEN ) == DISP_CHANGE_SUCCESSFUL ) { *pwidth = width; *pheight = height; gl_state.fullscreen = true; Com_Printf ("ok\n" ); if ( !VID_CreateWindow (width, height, true) ) return rserr_invalid_mode; return rserr_ok; } else { *pwidth = width; *pheight = height; Com_Printf ("failed\n" ); Com_Printf ("...calling CDS assuming dual monitors:" ); dm.dmPelsWidth = width * 2; dm.dmPelsHeight = height; dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; if ( gl_bitdepth->value != 0 ) { dm.dmBitsPerPel = gl_bitdepth->value; dm.dmFields |= DM_BITSPERPEL; } if ( vid_displayfrequency->integer > 0 ) { dm.dmFields |= DM_DISPLAYFREQUENCY; dm.dmDisplayFrequency = vid_displayfrequency->integer; Com_Printf ( "...using display frequency %i\n", dm.dmDisplayFrequency ); } /* ** our first CDS failed, so maybe we're running on some weird dual monitor ** system */ if ( ChangeDisplaySettings( &dm, CDS_FULLSCREEN ) != DISP_CHANGE_SUCCESSFUL ) { Com_Printf (" failed\n" ); Com_Printf ("...setting windowed mode\n" ); ChangeDisplaySettings( 0, 0 ); *pwidth = width; *pheight = height; gl_state.fullscreen = false; if ( !VID_CreateWindow (width, height, false) ) return rserr_invalid_mode; return rserr_invalid_fullscreen; } else { Com_Printf (" ok\n" ); if ( !VID_CreateWindow (width, height, true) ) return rserr_invalid_mode; gl_state.fullscreen = true; return rserr_ok; } } } else { Com_Printf ("...setting windowed mode\n" ); ChangeDisplaySettings( 0, 0 ); *pwidth = width; *pheight = height; gl_state.fullscreen = false; if ( !VID_CreateWindow (width, height, false) ) return rserr_invalid_mode; } return rserr_ok; } /* ** GLimp_Shutdown ** ** This routine does all OS specific shutdown procedures for the OpenGL ** subsystem. Under OpenGL this means NULLing out the current DC and ** HGLRC, deleting the rendering context, and releasing the DC acquired ** for the window. The state structure is also nulled out. ** */ void GLimp_Shutdown( void ) { if ( qwglMakeCurrent && !qwglMakeCurrent( NULL, NULL ) ) Com_Printf ("ref_gl::R_Shutdown() - wglMakeCurrent failed\n"); if ( glw_state.hGLRC ) { if ( qwglDeleteContext && !qwglDeleteContext( glw_state.hGLRC ) ) Com_Printf ("ref_gl::R_Shutdown() - wglDeleteContext failed\n"); glw_state.hGLRC = NULL; } if (glw_state.hDC) { if ( !ReleaseDC( glw_state.hWnd, glw_state.hDC ) ) Com_Printf ("ref_gl::R_Shutdown() - ReleaseDC failed\n" ); glw_state.hDC = NULL; } if (glw_state.hWnd) { ShowWindow (glw_state.hWnd, SW_HIDE); DestroyWindow ( glw_state.hWnd ); glw_state.hWnd = NULL; } if ( glw_state.log_fp ) { fclose( glw_state.log_fp ); glw_state.log_fp = 0; } UnregisterClass (WINDOW_CLASS_NAME, glw_state.hInstance); if ( gl_state.fullscreen ) { ChangeDisplaySettings( 0, 0 ); gl_state.fullscreen = false; } } /* =================== CPU Detect from Q2E =================== */ // does not appear to be used /* extern void Q_strncpyz( char *dest, const char *src, size_t size ); extern void Q_strncatz( char *dest, const char *src, size_t size ); qboolean Sys_DetectCPU (char *cpuString, int maxSize) { char vendor[16]; int stdBits, features, extFeatures; int family, model; unsigned __int64 start, end, counter, stop, frequency; unsigned speed; qboolean hasMMX, hasMMXExt, has3DNow, has3DNowExt, hasSSE, hasSSE2; // Check if CPUID instruction is supported __try { __asm { mov eax, 0 cpuid } } __except (EXCEPTION_EXECUTE_HANDLER){ return false; } // Get CPU info __asm { ; // Get vendor identifier mov eax, 0 cpuid mov dword ptr[vendor+0], ebx mov dword ptr[vendor+4], edx mov dword ptr[vendor+8], ecx mov dword ptr[vendor+12], 0 ; // Get standard bits and features mov eax, 1 cpuid mov stdBits, eax mov features, edx ; // Check if extended functions are present mov extFeatures, 0 mov eax, 80000000h cpuid cmp eax, 80000000h jbe NoExtFunction ; // Get extended features mov eax, 80000001h cpuid mov extFeatures, edx NoExtFunction: } // Get CPU name family = (stdBits >> 8) & 15; model = (stdBits >> 4) & 15; if (!Q_strcasecmp(vendor, "AuthenticAMD")){ Q_strncpyz(cpuString, "AMD", maxSize); switch (family){ case 5: switch (model){ case 0: case 1: case 2: case 3: Q_strncatz(cpuString, " K5", maxSize); break; case 6: case 7: Q_strncatz(cpuString, " K6", maxSize); break; case 8: Q_strncatz(cpuString, " K6-2", maxSize); break; case 9: case 10: case 11: case 12: case 13: case 14: case 15: Q_strncatz(cpuString, " K6-III", maxSize); break; } break; case 6: switch (model){ case 1: // 0.25 core case 2: // 0.18 core Q_strncatz(cpuString, " Athlon", maxSize); break; case 3: // Spitfire core Q_strncatz(cpuString, " Duron", maxSize); break; case 4: // Thunderbird core case 6: // Palomino core Q_strncatz(cpuString, " Athlon", maxSize); break; case 7: // Morgan core Q_strncatz(cpuString, " Duron", maxSize); break; case 8: // Thoroughbred core case 10: // Barton core Q_strncatz(cpuString, " Athlon", maxSize); break; } break; } } else if (!Q_strcasecmp(vendor, "GenuineIntel")){ Q_strncpyz(cpuString, "Intel", maxSize); switch (family){ case 5: switch (model){ case 0: case 1: case 2: case 3: case 4: case 7: case 8: Q_strncatz(cpuString, " Pentium", maxSize); break; } break; case 6: switch (model){ case 0: case 1: Q_strncatz(cpuString, " Pentium Pro", maxSize); break; case 3: case 5: // Actual differentiation depends on cache settings Q_strncatz(cpuString, " Pentium II", maxSize); break; case 6: Q_strncatz(cpuString, " Celeron", maxSize); break; case 7: case 8: case 9: case 10: case 11: // Actual differentiation depends on cache settings Q_strncatz(cpuString, " Pentium III", maxSize); break; } break; case 15: Q_strncatz(cpuString, " Pentium 4", maxSize); break; } } else return false; // Check if RDTSC instruction is supported if ((features >> 4) & 1){ // Measure CPU speed QueryPerformanceFrequency((LARGE_INTEGER *)&frequency); __asm { rdtsc mov dword ptr[start+0], eax mov dword ptr[start+4], edx } QueryPerformanceCounter((LARGE_INTEGER *)&stop); stop += frequency; do { QueryPerformanceCounter((LARGE_INTEGER *)&counter); } while (counter < stop); __asm { rdtsc mov dword ptr[end+0], eax mov dword ptr[end+4], edx } speed = (unsigned)((end - start) / 1000000); Q_strncatz(cpuString, va(" %u MHz", speed), maxSize); } // Get extended instruction sets supported hasMMX = (features >> 23) & 1; hasMMXExt = (extFeatures >> 22) & 1; has3DNow = (extFeatures >> 31) & 1; has3DNowExt = (extFeatures >> 30) & 1; hasSSE = (features >> 25) & 1; hasSSE2 = (features >> 26) & 1; if (hasMMX || has3DNow || hasSSE){ Q_strncatz(cpuString, " w/", maxSize); if (hasMMX){ Q_strncatz(cpuString, " MMX", maxSize); if (hasMMXExt) Q_strncatz(cpuString, "+", maxSize); } if (has3DNow){ Q_strncatz(cpuString, " 3DNow!", maxSize); if (has3DNowExt) Q_strncatz(cpuString, "+", maxSize); } if (hasSSE){ Q_strncatz(cpuString, " SSE", maxSize); if (hasSSE2) Q_strncatz(cpuString, "2", maxSize); } } return true; } */ static void Sys_SetCpuCore (void) { SYSTEM_INFO cpuInfo; /* cpumask=1 - use core #0 cpumask=2 - use core #1 cpumask=3 - use cores #0 & #1 */ if(!sys_affinity->value) return; if(sys_affinity->value >3) Cvar_SetValue("sys_affinity", 3); GetSystemInfo(&cpuInfo); /* if number of cpu core > 1 we can run run game on second core or use both cores*/ if (cpuInfo.dwNumberOfProcessors > 1) SetProcessAffinityMask(GetCurrentProcess(), (DWORD32)sys_affinity->value); CloseHandle(GetCurrentProcess()); } /* ** GLimp_Init ** ** This routine is responsible for initializing the OS specific portions ** of OpenGL. Under Win32 this means dealing with the pixelformats and ** doing the wgl interface stuff. */ qboolean GLimp_Init( void *hinstance, void *wndproc ) { #define OSR2_BUILD_NUMBER 1111 OSVERSIONINFO vinfo; vinfo.dwOSVersionInfoSize = sizeof(vinfo); glw_state.allowdisplaydepthchange = false; //set high process priority for fullscreen mode if(vid_fullscreen->value && sys_priority->value ) SetPriorityClass (GetCurrentProcess(), HIGH_PRIORITY_CLASS); else SetPriorityClass (GetCurrentProcess(), NORMAL_PRIORITY_CLASS); Sys_SetCpuCore(); if ( GetVersionEx( &vinfo) ) { if ( vinfo.dwMajorVersion > 4 ) { glw_state.allowdisplaydepthchange = true; } else if ( vinfo.dwMajorVersion == 4 ) { if ( vinfo.dwPlatformId == VER_PLATFORM_WIN32_NT ) { glw_state.allowdisplaydepthchange = true; } else if ( vinfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) { if ( LOWORD( vinfo.dwBuildNumber ) >= OSR2_BUILD_NUMBER ) { glw_state.allowdisplaydepthchange = true; } } } } else { Com_Printf ("GLimp_Init() - GetVersionEx failed\n" ); return false; } glw_state.hInstance = ( HINSTANCE ) hinstance; glw_state.wndproc = wndproc; return true; } qboolean GLimp_InitGL (void) { PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd 1, // version number PFD_DRAW_TO_WINDOW | // support window PFD_SUPPORT_OPENGL | // support OpenGL PFD_DOUBLEBUFFER, // double buffered PFD_TYPE_RGBA, // RGBA type 24, // 24-bit color depth 0, 0, 0, 0, 0, 0, // color bits ignored 0, // no alpha buffer 0, // shift bit ignored 0, // no accumulation buffer 0, 0, 0, 0, // accum bits ignored 24, // 24-bit z-buffer 8, // 8 bit stencil buffer 0, // no auxiliary buffer PFD_MAIN_PLANE, // main layer 0, // reserved 0, 0, 0 // layer masks ignored }; int pixelformat; cvar_t *stereo; stereo = Cvar_Get( "cl_stereo", "0", 0 ); /* ** set PFD_STEREO if necessary */ if ( stereo->value != 0 ) { Com_Printf ("...attempting to use stereo\n" ); pfd.dwFlags |= PFD_STEREO; gl_state.stereo_enabled = true; } else { gl_state.stereo_enabled = false; } /* ** figure out if we're running on a minidriver or not */ if ( strstr( gl_driver->string, "opengl32" ) != 0 ) glw_state.minidriver = false; else glw_state.minidriver = true; /* ** Get a DC for the specified window */ if ( glw_state.hDC != NULL ) Com_Printf ("GLimp_Init() - non-NULL DC exists\n" ); if ( ( glw_state.hDC = GetDC( glw_state.hWnd ) ) == NULL ) { Com_Printf ("GLimp_Init() - GetDC failed\n" ); return false; } if ( glw_state.minidriver ) { if ( (pixelformat = qwglChoosePixelFormat( glw_state.hDC, &pfd)) == 0 ) { Com_Printf ("GLimp_Init() - qwglChoosePixelFormat failed\n"); return false; } if ( qwglSetPixelFormat( glw_state.hDC, pixelformat, &pfd) == FALSE ) { Com_Printf ("GLimp_Init() - qwglSetPixelFormat failed\n"); return false; } qwglDescribePixelFormat( glw_state.hDC, pixelformat, sizeof( pfd ), &pfd ); } else { if ( ( pixelformat = ChoosePixelFormat( glw_state.hDC, &pfd)) == 0 ) { Com_Printf ("GLimp_Init() - ChoosePixelFormat failed\n"); return false; } if ( SetPixelFormat( glw_state.hDC, pixelformat, &pfd) == FALSE ) { Com_Printf ("GLimp_Init() - SetPixelFormat failed\n"); return false; } DescribePixelFormat( glw_state.hDC, pixelformat, sizeof( pfd ), &pfd ); if ( !( pfd.dwFlags & PFD_GENERIC_ACCELERATED ) ) { glw_state.mcd_accelerated = false; } else { glw_state.mcd_accelerated = true; } } /* ** report if stereo is desired but unavailable */ if ( !( pfd.dwFlags & PFD_STEREO ) && ( stereo->value != 0 ) ) { Com_Printf ("...failed to select stereo pixel format\n" ); Cvar_SetValue( "cl_stereo", 0 ); gl_state.stereo_enabled = false; } /* ** startup the OpenGL subsystem by creating a context and making ** it current */ if ( ( glw_state.hGLRC = qwglCreateContext( glw_state.hDC ) ) == 0 ) { Com_Printf ( "GLimp_Init() - qwglCreateContext failed\n"); goto fail; } if ( !qwglMakeCurrent( glw_state.hDC, glw_state.hGLRC ) ) { Com_Printf ("GLimp_Init() - qwglMakeCurrent failed\n"); goto fail; } if ( !VerifyDriver() ) { Com_Printf ("GLimp_Init() - no hardware acceleration detected\n" ); goto fail; } RS_ScanPathForScripts(); // load all found scripts /* ** print out PFD specifics */ Com_Printf ("GL PFD: color(%d-bits) Z(%d-bit)\n", ( int ) pfd.cColorBits, ( int ) pfd.cDepthBits ); if (pfd.cStencilBits) have_stencil = true; // Stencil shadows - MrG return true; fail: if ( glw_state.hGLRC ) { qwglDeleteContext( glw_state.hGLRC ); glw_state.hGLRC = NULL; } if ( glw_state.hDC ) { ReleaseDC( glw_state.hWnd, glw_state.hDC ); glw_state.hDC = NULL; } return false; } /* ** GLimp_BeginFrame */ void GLimp_BeginFrame( float camera_separation ) { if ( gl_bitdepth->modified ) { if ( gl_bitdepth->value != 0 && !glw_state.allowdisplaydepthchange ) { Cvar_SetValue( "gl_bitdepth", 0 ); Com_Printf ("gl_bitdepth requires Win95 OSR2.x or WinNT 4.x\n" ); } gl_bitdepth->modified = false; } if ( camera_separation < 0 && gl_state.stereo_enabled ) { qglDrawBuffer( GL_BACK_LEFT ); } else if ( camera_separation > 0 && gl_state.stereo_enabled ) { qglDrawBuffer( GL_BACK_RIGHT ); } else { qglDrawBuffer( GL_BACK ); } } /* ** GLimp_EndFrame ** ** Responsible for doing a swapbuffers and possibly for other stuff ** as yet to be determined. Probably better not to make this a GLimp ** function and instead do a call to GLimp_SwapBuffers. */ void GLimp_EndFrame (void) { int err; err = qglGetError(); assert( err == GL_NO_ERROR ); // 2010-08 This assert is happening if ( Q_strcasecmp( gl_drawbuffer->string, "GL_BACK" ) == 0 ) { if ( !qwglSwapBuffers( glw_state.hDC ) ) Com_Error( ERR_FATAL, "GLimp_EndFrame() - SwapBuffers() failed!\n" ); } // rscript - MrG rs_realtime=Sys_Milliseconds() * 0.0005f; } /* ** GLimp_AppActivate */ void GLimp_AppActivate( qboolean active ) { if ( active ) { SetForegroundWindow( glw_state.hWnd ); ShowWindow( glw_state.hWnd, SW_RESTORE ); } else { if ( vid_fullscreen->value ) ShowWindow( glw_state.hWnd, SW_MINIMIZE ); } } alien-arena-7.66+dfsg/source/win32/vid_dll.c0000600000175000017500000003756112161402010017641 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // Main windowed and fullscreen graphics interface module. This module // is used for both the software and OpenGL rendering versions of the // Quake refresh engine. #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "client\client.h" #include "winquake.h" //#include "zmouse.h" cvar_t *win_noalttab; #ifndef WM_MOUSEWHEEL #define WM_MOUSEWHEEL (WM_MOUSELAST+1) // message that will be supported by the OS #endif static UINT MSH_MOUSEWHEEL; // Console variables that we need to access from this module cvar_t *vid_gamma; cvar_t *vid_ref; // Name of Refresh DLL loaded cvar_t *vid_xpos; // X coordinate of window position cvar_t *vid_ypos; // Y coordinate of window position cvar_t *vid_fullscreen; cvar_t *vid_width; cvar_t *vid_height; cvar_t *vid_displayfrequency; // Global variables used internally by this module viddef_t viddef; // global video state; used by other modules qboolean reflib_active = 0; HWND cl_hwnd; // Main window handle for life of program LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); static qboolean s_alttab_disabled; extern unsigned sys_msg_time; /* ** WIN32 helper functions */ extern qboolean s_win95; static void WIN_DisableAltTab( void ) { if ( s_alttab_disabled ) return; if ( s_win95 ) { BOOL old; SystemParametersInfo( SPI_SETSCREENSAVERRUNNING, 1, &old, 0 ); // using MinGW compatible equivalent SPI constant } else { RegisterHotKey( 0, 0, MOD_ALT, VK_TAB ); RegisterHotKey( 0, 1, MOD_ALT, VK_RETURN ); } s_alttab_disabled = true; } static void WIN_EnableAltTab( void ) { if ( s_alttab_disabled ) { if ( s_win95 ) { BOOL old; SystemParametersInfo( SPI_SETSCREENSAVERRUNNING, 0, &old, 0 ); // using MinGW compatible equivalent SPI constant } else { UnregisterHotKey( 0, 0 ); UnregisterHotKey( 0, 1 ); } s_alttab_disabled = false; } } //========================================================================== byte scantokey[128] = { // 0 1 2 3 4 5 6 7 // 8 9 A B C D E F 0 , 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', K_BACKSPACE, 9, // 0 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 13 , K_CTRL,'a', 's', // 1 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'' , '`', K_SHIFT,'\\', 'z', 'x', 'c', 'v', // 2 'b', 'n', 'm', ',', '.', '/', K_SHIFT,'*', K_ALT,' ', 0 , K_F1, K_F2, K_F3, K_F4, K_F5, // 3 K_F6, K_F7, K_F8, K_F9, K_F10, K_PAUSE, 0 , K_HOME, K_UPARROW,K_PGUP,K_KP_MINUS,K_LEFTARROW,K_KP_5,K_RIGHTARROW, K_KP_PLUS,K_END, //4 K_DOWNARROW,K_PGDN,K_INS,K_DEL,0,0, 0, K_F11, K_F12,0 , 0 , 0 , 0 , 0 , 0 , 0, // 5 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, // 6 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 // 7 }; /* ======= MapKey Map from windows to quake keynums ======= */ int MapKey (int key) { int result; int modified = ( key >> 16 ) & 255; qboolean is_extended = false; if ( modified > 127) return 0; if ( key & ( 1 << 24 ) ) is_extended = true; result = scantokey[modified]; if ( !is_extended ) { switch ( result ) { case K_HOME: return K_KP_HOME; case K_UPARROW: return K_KP_UPARROW; case K_PGUP: return K_KP_PGUP; case K_LEFTARROW: return K_KP_LEFTARROW; case K_RIGHTARROW: return K_KP_RIGHTARROW; case K_END: return K_KP_END; case K_DOWNARROW: return K_KP_DOWNARROW; case K_PGDN: return K_KP_PGDN; case K_INS: return K_KP_INS; case K_DEL: return K_KP_DEL; default: return result; } } else { switch ( result ) { case 0x0D: return K_KP_ENTER; case 0x2F: return K_KP_SLASH; case 0xAF: return K_KP_PLUS; } return result; } } void AppActivate(BOOL fActive, BOOL minimize) { Minimized = minimize; Key_ClearStates(); // we don't want to act like we're active if we're minimized if (fActive && !Minimized) ActiveApp = true; else ActiveApp = false; // minimize/restore mouse-capture on demand if (!ActiveApp) { IN_Activate (false); S_Activate (false); if ( win_noalttab->value ) { WIN_EnableAltTab(); } } else { IN_Activate (true); S_Activate (true); if ( win_noalttab->value ) { WIN_DisableAltTab(); } } } /* ==================== MainWndProc main window procedure ==================== */ LONG WINAPI MainWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { LONG lRet = 0; if ( uMsg == MSH_MOUSEWHEEL ) { if ( ( ( int ) wParam ) > 0 ) { Key_Event( K_MWHEELUP, true, sys_msg_time ); Key_Event( K_MWHEELUP, false, sys_msg_time ); } else { Key_Event( K_MWHEELDOWN, true, sys_msg_time ); Key_Event( K_MWHEELDOWN, false, sys_msg_time ); } return DefWindowProc (hWnd, uMsg, wParam, lParam); } switch (uMsg) { case WM_MOUSEWHEEL: /* ** this chunk of code theoretically only works under NT4 and Win98 ** since this message doesn't exist under Win95 */ if ( ( short ) HIWORD( wParam ) > 0 ) { Key_Event( K_MWHEELUP, true, sys_msg_time ); Key_Event( K_MWHEELUP, false, sys_msg_time ); } else { Key_Event( K_MWHEELDOWN, true, sys_msg_time ); Key_Event( K_MWHEELDOWN, false, sys_msg_time ); } break; case WM_HOTKEY: return 0; case WM_CREATE: cl_hwnd = hWnd; MSH_MOUSEWHEEL = RegisterWindowMessage("MSWHEEL_ROLLMSG"); return DefWindowProc (hWnd, uMsg, wParam, lParam); case WM_PAINT: return DefWindowProc (hWnd, uMsg, wParam, lParam); case WM_DESTROY: // let sound and input know about this? cl_hwnd = NULL; return DefWindowProc (hWnd, uMsg, wParam, lParam); case WM_ACTIVATE: { int fActive, fMinimized; // KJB: Watch this for problems in fullscreen modes with Alt-tabbing. fActive = LOWORD(wParam); fMinimized = (BOOL) HIWORD(wParam); AppActivate( fActive != WA_INACTIVE, fMinimized); if ( reflib_active ) R_AppActivate( !( fActive == WA_INACTIVE ) ); } return DefWindowProc (hWnd, uMsg, wParam, lParam); case WM_MOVE: { int xPos, yPos; RECT r; int style; if (!vid_fullscreen->value) { xPos = (short) LOWORD(lParam); // horizontal position yPos = (short) HIWORD(lParam); // vertical position r.left = 0; r.top = 0; r.right = 1; r.bottom = 1; style = GetWindowLong( hWnd, GWL_STYLE ); AdjustWindowRect( &r, style, FALSE ); Cvar_SetValue( "vid_xpos", xPos + r.left); Cvar_SetValue( "vid_ypos", yPos + r.top); vid_xpos->modified = false; vid_ypos->modified = false; if (ActiveApp) IN_Activate (true); } } return DefWindowProc (hWnd, uMsg, wParam, lParam); // this is complicated because Win32 seems to pack multiple mouse events into // one update sometimes, so we always check all states and look for events case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_RBUTTONDOWN: case WM_RBUTTONUP: case WM_MBUTTONDOWN: case WM_MBUTTONUP: case WM_MOUSEMOVE: { int temp; temp = 0; if (wParam & MK_LBUTTON) temp |= 1; if (wParam & MK_RBUTTON) temp |= 2; if (wParam & MK_MBUTTON) temp |= 4; /* TODO: Research Windows mouse button support. * * MK_XBUTTON1 and MK_XBUTTON2 are 2 additional. Meaning TBD * * (why was mousebuttons set to 7?, ) * (how many does win support. 5 for sure, more how?) * * MK_LBUTTON 0x01 * MK_RBUTTON 0x02 * MK_MBUTTION 0x10 * MK_XBUTTON1 0x20 * MK_XBUTTON2 0x40 * */ IN_MouseEvent (temp); } break; case WM_SYSCOMMAND: if ( wParam == SC_SCREENSAVE ) return 0; return DefWindowProc (hWnd, uMsg, wParam, lParam); case WM_SYSKEYDOWN: if ( wParam == 13 ) { if ( vid_fullscreen ) { Cvar_SetValue( "vid_fullscreen", !vid_fullscreen->value ); } return 0; } // fall through case WM_KEYDOWN: Key_Event( MapKey( lParam ), true, sys_msg_time); break; case WM_SYSKEYUP: case WM_KEYUP: Key_Event( MapKey( lParam ), false, sys_msg_time); break; default: // pass all unhandled messages to DefWindowProc return DefWindowProc (hWnd, uMsg, wParam, lParam); } /* return 0 if handled message, 1 if not */ return DefWindowProc( hWnd, uMsg, wParam, lParam ); } /* ============ VID_Restart_f Console command to re-start the video mode and refresh DLL. We do this simply by setting the modified flag for the vid_ref variable, which will cause the entire video mode and refresh DLL to be reset on the next frame. ============ */ void VID_Restart_f (void) { vid_ref->modified = true; } void VID_Front_f( void ) { SetWindowLong( cl_hwnd, GWL_EXSTYLE, WS_EX_TOPMOST ); SetForegroundWindow( cl_hwnd ); } /* ** VID_GetModeInfo */ typedef struct vidmode_s { const char *description; int width, height; int mode; } vidmode_t; //Gonna get rid of the lower resolution - so that the HUD doesn't get knocked off the screen //besides, who the hell wants to play at anything less than 640x480 vidmode_t vid_modes[] = { { "Mode 0: 640x480", 640, 480, 0 }, { "Mode 1: 800x600", 800, 600, 1 }, { "Mode 2: 960x720", 960, 720, 2 }, { "Mode 3: 1024x768", 1024, 768, 3 }, { "Mode 4: 1152x864", 1152, 864, 4 }, { "Mode 5: 1280x960", 1280, 960, 5 }, { "Mode 6: 1280x1024", 1280, 1024, 6 }, { "Mode 7: 1360x768", 1360, 768, 7 }, { "Mode 8: 1366x768", 1366, 768, 8 }, { "Mode 9: 1600x1200", 1600, 1200, 9 }, { "Mode 10: 1680x1050", 1680, 1050, 10 }, { "Mode 11: 1920x1080", 1920, 1080, 11 }, { "Mode 12: 2048x1536", 2048, 1536, 12 } }; static int s_numVidModes = ( sizeof(vid_modes) / sizeof(vid_modes[0])); qboolean VID_GetModeInfo ( int *width, int *height, int mode) { vidmode_t *vm; if ( mode < -1 ) { return false; } if ( mode >= s_numVidModes ) { return false; } if ( mode == -1 ) { *width = vid_width->value; *height = vid_height->value; return true; } vm = &vid_modes[mode]; *width = vm->width; *height = vm->height; return true; } void VID_ModeList_f(void) { int i; for ( i = 0; i < s_numVidModes; i++) { Com_Printf ( "%s\n", vid_modes[i].description ); } Com_Printf("For custom resolutions, set 'gl_mode' to -1 and use 'vid_width' / 'vid_height'\n"); } /* ** VID_UpdateWindowPosAndSize */ void VID_UpdateWindowPosAndSize( int x, int y ) { RECT r; int style; int w, h; r.left = 0; r.top = 0; r.right = viddef.width; r.bottom = viddef.height; style = GetWindowLong( cl_hwnd, GWL_STYLE ); AdjustWindowRect( &r, style, FALSE ); w = r.right - r.left; h = r.bottom - r.top; MoveWindow( cl_hwnd, vid_xpos->value, vid_ypos->value, w, h, TRUE ); } /* ** VID_NewWindow */ void VID_NewWindow ( int width, int height) { viddef.width = width; viddef.height = height; cl.force_refdef = true; // can't use a paused refdef } void VID_FreeReflib (void) { reflib_active = false; } /* ============== VID_LoadRefresh ============== */ qboolean VID_LoadRefresh(void) { if ( reflib_active ) { R_Shutdown(); VID_FreeReflib (); } if ( R_Init( global_hInstance, MainWndProc ) == -1 ) { R_Shutdown(); VID_FreeReflib (); Com_Error (ERR_FATAL, "Couldn't initialize OpenGL renderer!\nUpdate your video drivers and be sure opengl is enabled!\n"); return false; } Com_Printf( "------------------------------------\n"); reflib_active = true; return true; } /* ============ VID_CheckChanges This function gets called once just before drawing each frame, and it's sole purpose in life is to check to see if any of the video mode parameters have changed, and if they have to update the rendering DLL and/or video mode to match. ============ */ void VID_CheckChanges (void) { if ( win_noalttab->modified ) { if ( win_noalttab->value ) { WIN_DisableAltTab(); } else { WIN_EnableAltTab(); } win_noalttab->modified = false; } if ( vid_ref->modified ) { cl.force_refdef = true; // can't use a paused refdef S_StopAllSounds(); } while (vid_ref->modified) { /* ** refresh has changed */ vid_ref->modified = false; vid_fullscreen->modified = true; cl.refresh_prepped = false; cls.disable_screen = true; if ( !VID_LoadRefresh() ) { /* ** drop the console if we fail to load a refresh */ if ( cls.key_dest != key_console ) { CON_ToggleConsole(); } } cls.disable_screen = false; } /* ** update our window position */ if ( vid_xpos->modified || vid_ypos->modified ) { if (!vid_fullscreen->value) VID_UpdateWindowPosAndSize( vid_xpos->value, vid_ypos->value ); vid_xpos->modified = false; vid_ypos->modified = false; } } /* ============ VID_Init ============ */ void VID_Init (void) { /* Create the video variables so we know how to start the graphics drivers */ vid_ref = Cvar_Get ("vid_ref", "soft", CVAR_ARCHIVE); vid_xpos = Cvar_Get ("vid_xpos", "3", CVAR_ARCHIVE); vid_ypos = Cvar_Get ("vid_ypos", "22", CVAR_ARCHIVE); vid_fullscreen = Cvar_Get ("vid_fullscreen", "1", CVAR_ARCHIVE); vid_gamma = Cvar_Get ( "vid_gamma", "1", CVAR_ARCHIVE ); vid_width = Cvar_Get ( "vid_width", "1024", CVAR_ARCHIVE ); vid_height = Cvar_Get ( "vid_height", "768", CVAR_ARCHIVE ); win_noalttab = Cvar_Get( "win_noalttab", "0", CVAR_ARCHIVE ); vid_displayfrequency = Cvar_Get( "vid_displayfrequency", "0", CVAR_ARCHIVE ); /* Add some console commands that we want to handle */ Cmd_AddCommand ("vid_restart", VID_Restart_f); Cmd_AddCommand ("vid_front", VID_Front_f); /* ** this is a gross hack but necessary to clamp the mode for 3Dfx */ #if 0 { cvar_t *gl_driver = Cvar_Get( "gl_driver", "opengl32", 0 ); cvar_t *gl_mode = Cvar_Get( "gl_mode", "3", 0 ); if ( Q_strcasecmp( gl_driver->string, "3dfxgl" ) == 0 ) { Cvar_SetValue( "gl_mode", 3 ); viddef.width = 640; viddef.height = 480; } } #endif /* Disable the 3Dfx splash screen */ _putenv("FX_GLIDE_NO_SPLASH=0"); /* Start the graphics mode and load refresh DLL */ VID_CheckChanges(); } /* ============ VID_Shutdown ============ */ void VID_Shutdown (void) { if ( reflib_active ) { R_Shutdown (); VID_FreeReflib (); } } alien-arena-7.66+dfsg/source/win32/sys_win.c0000600000175000017500000006133212161402010017710 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // sys_win.c #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "qcommon/qcommon.h" #include "winquake.h" #include "resource.h" #include #include #include #include #include #include #include "conproc.h" #define MINIMUM_WIN_MEMORY 0x0a00000 #define MAXIMUM_WIN_MEMORY 0x1000000 //#define DEMO qboolean s_win95; int ActiveApp; qboolean Minimized; static HANDLE hinput, houtput; unsigned sys_msg_time; unsigned sys_frame_time; // attachment to statically linked game library extern void *GetGameAPI ( void *import); extern void Q_strncpyz( char *dest, const char *src, size_t size ); extern int window_center_x, window_center_y; extern qboolean mouse_available; extern int mouse_diff_x; extern int mouse_diff_y; static HANDLE qwclsemaphore; #define MAX_NUM_ARGVS 128 int argc; char *argv[MAX_NUM_ARGVS]; #define CONSOLE_WINDOW_CLASS_NAME "CRX Console" #define CONSOLE_WINDOW_NAME "Alien Arena Console" #define CONSOLE_WINDOW_STYLE (WS_OVERLAPPED|WS_BORDER|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_CLIPCHILDREN|WS_GROUP) #define MAX_OUTPUT 32768 #define MAX_INPUT 256 #define MAX_PRINTMSG 8192 typedef struct { int outLen; // To keep track of output buffer len char cmdBuffer[MAX_INPUT]; // Buffered input from dedicated console qboolean timerActive; // Timer is active (for fatal errors) qboolean flashColor; // If true, flash error message to red // Window stuff HWND hWnd; HWND hWndCopy; HWND hWndClear; HWND hWndQuit; HWND hWndOutput; HWND hWndInput; HWND hWndMsg; HFONT hFont; HFONT hFontBold; HBRUSH hBrushMsg; HBRUSH hBrushOutput; HBRUSH hBrushInput; WNDPROC defOutputProc; WNDPROC defInputProc; } sysConsole_t; static sysConsole_t sys_console; void Sys_ShowConsole (qboolean show); HINSTANCE sys_hInstance; unsigned sys_msgTime; unsigned sys_frameTime; /* ======================================================================= DEDICATED CONSOLE ======================================================================= */ /* ================= Sys_GetCommand ================= */ char *Sys_GetCommand (void){ static char buffer[MAX_INPUT]; if (!sys_console.cmdBuffer[0]) return NULL; Q_strncpyz(buffer, sys_console.cmdBuffer, sizeof(buffer)); sys_console.cmdBuffer[0] = 0; return buffer; } /* ================= Sys_Print ================= */ void Sys_Print (const char *text){ char buffer[MAX_PRINTMSG]; int len = 0; //FIXME: add a check for text == NULL and print an error message //without potentially creating an infinite recursion loop // Change \n to \r\n so it displays properly in the edit box and // remove color escapes while (*text){ if (*text == '\n'){ buffer[len++] = '\r'; buffer[len++] = '\n'; } else if (Q_IsColorString(text)) text++; else buffer[len++] = *text; text++; } buffer[len] = 0; sys_console.outLen += len; if (sys_console.outLen >= MAX_OUTPUT){ SendMessage(sys_console.hWndOutput, EM_SETSEL, 0, -1); sys_console.outLen = len; } SendMessage(sys_console.hWndOutput, EM_REPLACESEL, FALSE, (LPARAM)buffer); // Scroll down SendMessage(sys_console.hWndOutput, EM_LINESCROLL, 0, 0xFFFF); SendMessage(sys_console.hWndOutput, EM_SCROLLCARET, 0, 0); } void MessageBoxForce (char *name, char *msg) { MessageBox(NULL, name, name, 0 ); } void Sys_Error (char *error, ...) { va_list argptr; char text[1024]; CL_Shutdown (); Qcommon_Shutdown (); va_start (argptr, error); vsnprintf (text, sizeof(text), error, argptr); va_end (argptr); MessageBox(NULL, text, "Error", 0 /* MB_OK */ ); if (qwclsemaphore) CloseHandle (qwclsemaphore); // shut down QHOST hooks if necessary DeinitConProc (); exit (1); } /* ================= Sys_ShowConsole ================= */ void Sys_ShowConsole (qboolean show){ if (!show){ ShowWindow(sys_console.hWnd, SW_HIDE); return; } ShowWindow(sys_console.hWnd, SW_SHOW); UpdateWindow(sys_console.hWnd); SetForegroundWindow(sys_console.hWnd); SetFocus(sys_console.hWnd); // Set the focus to the input edit box if possible SetFocus(sys_console.hWndInput); // Scroll down SendMessage(sys_console.hWndOutput, EM_LINESCROLL, 0, 0xFFFF); SendMessage(sys_console.hWndOutput, EM_SCROLLCARET, 0, 0); } /* ================= Sys_ConsoleProc ================= */ static LONG WINAPI Sys_ConsoleProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ switch (uMsg){ case WM_ACTIVATE: if (LOWORD(wParam) != WA_INACTIVE){ SetFocus(sys_console.hWndInput); return 0; } break; case WM_CLOSE: Sys_Quit(); break; case WM_COMMAND: if (HIWORD(wParam) == BN_CLICKED){ if ((HWND)lParam == sys_console.hWndCopy){ SendMessage(sys_console.hWndOutput, EM_SETSEL, 0, -1); SendMessage(sys_console.hWndOutput, WM_COPY, 0, 0); } else if ((HWND)lParam == sys_console.hWndClear){ SendMessage(sys_console.hWndOutput, EM_SETSEL, 0, -1); SendMessage(sys_console.hWndOutput, WM_CLEAR, 0, 0); } else if ((HWND)lParam == sys_console.hWndQuit) Sys_Quit(); } else if (HIWORD(wParam) == EN_VSCROLL) InvalidateRect(sys_console.hWndOutput, NULL, TRUE); break; case WM_CTLCOLOREDIT: if ((HWND)lParam == sys_console.hWndOutput){ SetBkMode((HDC)wParam, TRANSPARENT); SetBkColor((HDC)wParam, RGB(54, 66, 83)); SetTextColor((HDC)wParam, RGB(255, 255, 255)); return (LONG)sys_console.hBrushOutput; } else if ((HWND)lParam == sys_console.hWndInput){ SetBkMode((HDC)wParam, TRANSPARENT); SetBkColor((HDC)wParam, RGB(255, 255, 255)); SetTextColor((HDC)wParam, RGB(0, 0, 0)); return (LONG)sys_console.hBrushInput; } break; case WM_CTLCOLORSTATIC: if ((HWND)lParam == sys_console.hWndMsg){ SetBkMode((HDC)wParam, TRANSPARENT); SetBkColor((HDC)wParam, RGB(127, 127, 127)); if (sys_console.flashColor) SetTextColor((HDC)wParam, RGB(255, 0, 0)); else SetTextColor((HDC)wParam, RGB(0, 0, 0)); return (LONG)sys_console.hBrushMsg; } break; case WM_TIMER: sys_console.flashColor = !sys_console.flashColor; InvalidateRect(sys_console.hWndMsg, NULL, TRUE); break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); } /* ================= Sys_ConsoleEditProc ================= */ static LONG WINAPI Sys_ConsoleEditProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ switch (uMsg){ case WM_CHAR: if (hWnd == sys_console.hWndInput){ if (wParam == VK_RETURN){ if (GetWindowText(sys_console.hWndInput, sys_console.cmdBuffer, sizeof(sys_console.cmdBuffer))){ SetWindowText(sys_console.hWndInput, ""); Com_Printf("]%s\n", sys_console.cmdBuffer); } return 0; // Keep it from beeping } } else if (hWnd == sys_console.hWndOutput) return 0; // Read only break; case WM_VSCROLL: if (LOWORD(wParam) == SB_THUMBTRACK) return 0; break; } if (hWnd == sys_console.hWndOutput) return CallWindowProc(sys_console.defOutputProc, hWnd, uMsg, wParam, lParam); else if (hWnd == sys_console.hWndInput) return CallWindowProc(sys_console.defInputProc, hWnd, uMsg, wParam, lParam); return 0; } /* ================= Sys_ShutdownConsole ================= */ static void Sys_ShutdownConsole (void){ if (sys_console.timerActive) KillTimer(sys_console.hWnd, 1); if (sys_console.hBrushMsg) DeleteObject(sys_console.hBrushMsg); if (sys_console.hBrushOutput) DeleteObject(sys_console.hBrushOutput); if (sys_console.hBrushInput) DeleteObject(sys_console.hBrushInput); if (sys_console.hFont) DeleteObject(sys_console.hFont); if (sys_console.hFontBold) DeleteObject(sys_console.hFontBold); if (sys_console.defOutputProc) SetWindowLong(sys_console.hWndOutput, GWL_WNDPROC, (LONG)sys_console.defOutputProc); if (sys_console.defInputProc) SetWindowLong(sys_console.hWndInput, GWL_WNDPROC, (LONG)sys_console.defInputProc); ShowWindow(sys_console.hWnd, SW_HIDE); DestroyWindow(sys_console.hWnd); UnregisterClass(CONSOLE_WINDOW_CLASS_NAME, sys_hInstance); } /* ================= Sys_InitConsole ================= */ static void Sys_InitConsole (void){ WNDCLASSEX wc; HDC hDC; RECT r; int x, y, w, h; // Center the window in the desktop hDC = GetDC(0); w = GetDeviceCaps(hDC, HORZRES); h = GetDeviceCaps(hDC, VERTRES); ReleaseDC(0, hDC); r.left = (w - 540) / 2; r.top = (h - 455) / 2; r.right = r.left + 540; r.bottom = r.top + 455; AdjustWindowRect(&r, CONSOLE_WINDOW_STYLE, FALSE); x = r.left; y = r.top; w = r.right - r.left; h = r.bottom - r.top; wc.style = 0; wc.lpfnWndProc = (WNDPROC)Sys_ConsoleProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = sys_hInstance; wc.hIcon = 0;//LoadIcon(sys_hInstance, MAKEINTRESOURCE(IDI_ICON1)); wc.hIconSm = 0; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)COLOR_WINDOW; wc.lpszMenuName = 0; wc.lpszClassName = CONSOLE_WINDOW_CLASS_NAME; wc.cbSize = sizeof(WNDCLASSEX); if (!RegisterClassEx(&wc)){ MessageBox(NULL, "Could not register console window class", "ERROR", MB_OK | MB_ICONERROR | MB_TASKMODAL); exit(0); } sys_console.hWnd = CreateWindowEx(0, CONSOLE_WINDOW_CLASS_NAME, CONSOLE_WINDOW_NAME, CONSOLE_WINDOW_STYLE, x, y, w, h, NULL, NULL, sys_hInstance, NULL); if (!sys_console.hWnd){ UnregisterClass(CONSOLE_WINDOW_CLASS_NAME, sys_hInstance); MessageBox(NULL, "Could not create console window", "ERROR", MB_OK | MB_ICONERROR | MB_TASKMODAL); exit(0); } sys_console.hWndMsg = CreateWindowEx(0, "STATIC", "", WS_CHILD | SS_SUNKEN, 5, 5, 530, 30, sys_console.hWnd, NULL, sys_hInstance, NULL); sys_console.hWndOutput = CreateWindowEx(0, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | ES_MULTILINE, 5, 40, 530, 350, sys_console.hWnd, NULL, sys_hInstance, NULL); sys_console.hWndInput = CreateWindowEx(0, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL, 5, 395, 530, 20, sys_console.hWnd, NULL, sys_hInstance, NULL); sys_console.hWndCopy = CreateWindowEx(0, "BUTTON", "copy", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 5, 425, 70, 25, sys_console.hWnd, NULL, sys_hInstance, NULL); sys_console.hWndClear = CreateWindowEx(0, "BUTTON", "clear", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 80, 425, 70, 25, sys_console.hWnd, NULL, sys_hInstance, NULL); sys_console.hWndQuit = CreateWindowEx(0, "BUTTON", "quit", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 465, 425, 70, 25, sys_console.hWnd, NULL, sys_hInstance, NULL); // Create and set fonts sys_console.hFont = CreateFont(14, 0, 0, 0, FW_LIGHT, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "Courier New"); sys_console.hFontBold = CreateFont(20, 0, 0, 0, FW_SEMIBOLD, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "System"); SendMessage(sys_console.hWndMsg, WM_SETFONT, (WPARAM)sys_console.hFont, FALSE); SendMessage(sys_console.hWndOutput, WM_SETFONT, (WPARAM)sys_console.hFont, FALSE); SendMessage(sys_console.hWndInput, WM_SETFONT, (WPARAM)sys_console.hFont, FALSE); SendMessage(sys_console.hWndCopy, WM_SETFONT, (WPARAM)sys_console.hFontBold, FALSE); SendMessage(sys_console.hWndClear, WM_SETFONT, (WPARAM)sys_console.hFontBold, FALSE); SendMessage(sys_console.hWndQuit, WM_SETFONT, (WPARAM)sys_console.hFontBold, FALSE); // Create brushes sys_console.hBrushMsg = CreateSolidBrush(RGB(127, 127, 127)); sys_console.hBrushOutput = CreateSolidBrush(RGB(54, 66, 83)); sys_console.hBrushInput = CreateSolidBrush(RGB(255, 255, 255)); // Subclass edit boxes sys_console.defOutputProc = (WNDPROC)SetWindowLong(sys_console.hWndOutput, GWL_WNDPROC, (LONG)Sys_ConsoleEditProc); sys_console.defInputProc = (WNDPROC)SetWindowLong(sys_console.hWndInput, GWL_WNDPROC, (LONG)Sys_ConsoleEditProc); // Set text limit for input edit box SendMessage(sys_console.hWndInput, EM_SETLIMITTEXT, (WPARAM)(MAX_INPUT-1), 0); // Show it Sys_ShowConsole(true); } // ===================================================================== /* =============================================================================== SYSTEM IO =============================================================================== */ /* ================= Sys_GetClipboardText ================= */ char *Sys_GetClipboardText (void){ HANDLE hClipboardData; LPVOID lpData; DWORD dwSize; char *text; if (!OpenClipboard(NULL)) return NULL; hClipboardData = GetClipboardData(CF_TEXT); if (!hClipboardData){ CloseClipboard(); return NULL; } lpData = GlobalLock(hClipboardData); if (!lpData){ CloseClipboard(); return NULL; } dwSize = GlobalSize(hClipboardData); text = Z_Malloc(dwSize+1); memcpy(text, lpData, dwSize); GlobalUnlock(hClipboardData); CloseClipboard(); return text; } /* ================= Sys_PumpMessages Pump window messages ================= */ void Sys_PumpMessages (void){ MSG msg; while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)){ if (!GetMessage(&msg, NULL, 0, 0)) Sys_Quit(); sys_msgTime = msg.time; TranslateMessage(&msg); DispatchMessage(&msg); } // Grab frame time sys_frameTime = timeGetTime(); // FIXME: should this be at start? } void Sys_Quit (void) { timeEndPeriod( 1 ); CL_Shutdown(); Qcommon_Shutdown (); CloseHandle (qwclsemaphore); if (dedicated && dedicated->value) FreeConsole (); // shut down QHOST hooks if necessary DeinitConProc (); exit (0); } void WinError (void) { LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL ); // Display the string. MessageBox( NULL, lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION ); // Free the buffer. LocalFree( lpMsgBuf ); } /* ================ Sys_Init ================ */ void Sys_Init (void) { OSVERSIONINFO vinfo; #if 0 // allocate a named semaphore on the client so the // front end can tell if it is alive // mutex will fail if semephore already exists qwclsemaphore = CreateMutex( NULL, /* Security attributes */ 0, /* owner */ "qwcl"); /* Semaphore name */ if (!qwclsemaphore) Sys_Error ("QWCL is already running on this system"); CloseHandle (qwclsemaphore); qwclsemaphore = CreateSemaphore( NULL, /* Security attributes */ 0, /* Initial count */ 1, /* Maximum count */ "qwcl"); /* Semaphore name */ #endif timeBeginPeriod( 1 ); Cvar_Get("sys_hInstance", va("%i", sys_hInstance), CVAR_ROM); Cvar_Get("sys_wndProc", va("%i", MainWndProc), CVAR_ROM); vinfo.dwOSVersionInfoSize = sizeof(vinfo); if (!GetVersionEx (&vinfo)) Sys_Error ("Couldn't get OS info"); if (vinfo.dwMajorVersion < 4) Sys_Error ("Alien Arena requires windows version 4 or greater"); if (vinfo.dwPlatformId == VER_PLATFORM_WIN32s) Sys_Error ("Alien Arena doesn't run on Win32s"); else if ( vinfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) s_win95 = true; } static char console_text[256]; static int console_textlen; /* ================ Sys_ConsoleInput ================ */ char *Sys_ConsoleInput (void) { INPUT_RECORD recs[1024]; int dummy; int ch, numread, numevents; if (!dedicated || !dedicated->value) return NULL; for ( ;; ) { if (!GetNumberOfConsoleInputEvents (hinput, &numevents)) Sys_Error ("Error getting # of console events"); if (numevents <= 0) break; if (!ReadConsoleInput(hinput, recs, 1, &numread)) Sys_Error ("Error reading console input"); if (numread != 1) Sys_Error ("Couldn't read console input"); if (recs[0].EventType == KEY_EVENT) { if (!recs[0].Event.KeyEvent.bKeyDown) { ch = recs[0].Event.KeyEvent.uChar.AsciiChar; switch (ch) { case '\r': WriteFile(houtput, "\r\n", 2, &dummy, NULL); if (console_textlen) { console_text[console_textlen] = 0; console_textlen = 0; return console_text; } break; case '\b': if (console_textlen) { console_textlen--; WriteFile(houtput, "\b \b", 3, &dummy, NULL); } break; default: if (ch >= ' ') { if (console_textlen < sizeof(console_text)-2) { WriteFile(houtput, &ch, 1, &dummy, NULL); console_text[console_textlen] = ch; console_textlen++; } } break; } } } } return NULL; } /* ================ Sys_ConsoleOutput Print text to the dedicated console ================ */ void Sys_ConsoleOutput (char *string) { int dummy; char text[256]; if (!dedicated || !dedicated->value) return; if (console_textlen) { text[0] = '\r'; memset(&text[1], ' ', console_textlen); text[console_textlen+1] = '\r'; text[console_textlen+2] = 0; WriteFile(houtput, text, console_textlen+2, &dummy, NULL); } WriteFile(houtput, string, strlen(string), &dummy, NULL); if (console_textlen) WriteFile(houtput, console_text, console_textlen, &dummy, NULL); } /* ================ Sys_SendKeyEvents Send Key_Event calls ================ */ void Sys_SendKeyEvents (void) { MSG msg; POINT current_pos; while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE)) { if (!GetMessage (&msg, NULL, 0, 0)) Sys_Quit (); sys_msg_time = msg.time; TranslateMessage (&msg); DispatchMessage (&msg); } if ( mouse_available && GetCursorPos( ¤t_pos) ) { mouse_diff_x += current_pos.x - window_center_x; mouse_diff_y += current_pos.y - window_center_y; if ( mouse_diff_x || mouse_diff_y ) { SetCursorPos( window_center_x, window_center_y ); } } // grab frame time sys_frame_time = timeGetTime(); // FIXME: should this be at start? } /* ================ Sys_GetClipboardData ================ */ char *Sys_GetClipboardData( void ) { char *data = NULL; char *cliptext; if ( OpenClipboard( NULL ) != 0 ) { HANDLE hClipboardData; if ( ( hClipboardData = GetClipboardData( CF_TEXT ) ) != 0 ) { if ( ( cliptext = GlobalLock( hClipboardData ) ) != 0 ) { data = malloc( GlobalSize( hClipboardData ) + 1 ); strcpy( data, cliptext ); GlobalUnlock( hClipboardData ); } } CloseClipboard(); } return data; } /* ============================================================================== WINDOWS CRAP ============================================================================== */ /* ================= Sys_AppActivate ================= */ void Sys_AppActivate (void) { ShowWindow ( cl_hwnd, SW_RESTORE); SetForegroundWindow ( cl_hwnd ); } /* ======================================================================== GAME DLL ======================================================================== */ static HINSTANCE game_library = NULL; /* ================= Sys_UnloadGame ================= */ void Sys_UnloadGame (void) { if ( game_library != NULL ) { if (!FreeLibrary (game_library)) Com_Error (ERR_FATAL, "FreeLibrary failed for game library"); } game_library = NULL; } /* ================= Sys_GetGameAPI Loads the game module 2010-08 : Implements a statically linked game module. Loading a game module DLL is supported if it exists. To prevent problems with attempting to load an older, incompatible version, a DLL will not be loaded from arena/ nor data1/ ================= */ void *Sys_GetGameAPI (void *parms) { void *(*ptrGetGameAPI) (void *) = NULL; char name[MAX_OSPATH]; char *path; size_t pathlen; // char cwd[MAX_OSPATH]; const char *gamename = "gamex86.dll"; /* #ifdef NDEBUG const char *debugdir = "release"; #else const char *debugdir = "debug"; #endif if (game_library != NULL) Com_Error (ERR_FATAL, "Sys_GetGameAPI without Sys_UnloadingGame"); // check the current debug directory first for development purposes _getcwd (cwd, sizeof(cwd)); Com_sprintf (name, sizeof(name), "%s/%s/%s", cwd, debugdir, gamename); game_library = LoadLibrary ( name ); if (game_library != NULL ) { Com_DPrintf ("LoadLibrary (%s)\n", name); } else { #ifdef DEBUG // check the current directory for other development purposes Com_sprintf (name, sizeof(name), "%s/%s", cwd, gamename); game_library = LoadLibrary ( name ); if (game_library) { Com_DPrintf ("LoadLibrary (%s)\n", name); } else #endif { // now run through the search paths path = NULL; while (1) { path = FS_NextPath (path); if (!path) break; // Search did not turn up a game DLL Com_sprintf (name, sizeof(name), "%s/%s", path, gamename); game_library = LoadLibrary (name); if (game_library) { Com_DPrintf ("LoadLibrary (%s)\n",name); break; } } } } */ // 2010-08 if (game_library != NULL) Com_Error (ERR_FATAL, "Sys_GetGameAPI without Sys_UnloadingGame"); path = NULL; for (;;) { path = FS_NextPath( path ); if ( !path ) break; pathlen = strlen( path ); // old game DLL in data1 is a problem if ( !Q_strncasecmp( "data1", &path[ pathlen-5 ], 5 ) ) continue; // may want to have a game DLL in arena, but disable for now if ( !Q_strncasecmp( "arena", &path[ pathlen-5 ], 5 ) ) continue; Com_sprintf (name, sizeof(name), "%s/%s", path, gamename); game_library = LoadLibrary (name); if (game_library) { // found a game module DLL break; } } if ( game_library != NULL ) { // game module from DLL Com_Printf ("LoadLibrary (%s)\n",name); ptrGetGameAPI = (void *)GetProcAddress (game_library, "GetGameAPI"); } /* * No game DLL found, use statically linked game */ if ( ptrGetGameAPI == NULL ) { ptrGetGameAPI = &GetGameAPI; } if ( ptrGetGameAPI == NULL ) { // program error Sys_UnloadGame (); return NULL; } return ptrGetGameAPI (parms); } //======================================================================= /* ================== ParseCommandLine ================== */ void ParseCommandLine (LPSTR lpCmdLine) { argc = 1; argv[0] = "exe"; while (*lpCmdLine && (argc < MAX_NUM_ARGVS)) { while (*lpCmdLine && ((*lpCmdLine <= 32) || (*lpCmdLine > 126))) lpCmdLine++; if (*lpCmdLine) { argv[argc] = lpCmdLine; argc++; while (*lpCmdLine && ((*lpCmdLine > 32) && (*lpCmdLine <= 126))) lpCmdLine++; if (*lpCmdLine) { *lpCmdLine = 0; lpCmdLine++; } } } } /* ================== WinMain ================== */ HINSTANCE global_hInstance; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { int time, oldtime, newtime; /* previous instances do not exist in Win32 */ if (hPrevInstance) return 0; global_hInstance = hInstance; ParseCommandLine (lpCmdLine); // Initialize the dedicated console Sys_InitConsole(); Qcommon_Init (argc, argv); oldtime = Sys_Milliseconds (); /* main window message loop */ while (1) { // if at a full screen console, don't update unless needed if (Minimized || (dedicated && dedicated->value) ) { Sleep (5); } Sys_PumpMessages(); do { newtime = Sys_Milliseconds(); time = newtime - oldtime; } while (time < 1); // curtime setting moved from Sys_Milliseconds() // so it consistent for entire frame curtime = newtime; _controlfp(_PC_24, _MCW_PC); Qcommon_Frame(time); oldtime = newtime; } // never gets here return TRUE; } alien-arena-7.66+dfsg/source/win32/qgl_win.c0000600000175000017500000055423712161402010017670 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* ** QGL_WIN.C ** ** This file implements the operating system binding of GL to QGL function ** pointers. When doing a port of Quake2 you must implement the following ** two functions: ** ** QGL_Init() - loads libraries, assigns function pointers, etc. ** QGL_Shutdown() - unloads libraries, NULLs function pointers */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "ref_gl/r_local.h" #include "glw_win.h" int ( WINAPI * qwglChoosePixelFormat )(HDC, CONST PIXELFORMATDESCRIPTOR *); int ( WINAPI * qwglDescribePixelFormat) (HDC, int, UINT, LPPIXELFORMATDESCRIPTOR); int ( WINAPI * qwglGetPixelFormat)(HDC); BOOL ( WINAPI * qwglSetPixelFormat)(HDC, int, CONST PIXELFORMATDESCRIPTOR *); BOOL ( WINAPI * qwglSwapBuffers)(HDC); BOOL ( WINAPI * qwglCopyContext)(HGLRC, HGLRC, UINT); HGLRC ( WINAPI * qwglCreateContext)(HDC); HGLRC ( WINAPI * qwglCreateLayerContext)(HDC, int); BOOL ( WINAPI * qwglDeleteContext)(HGLRC); HGLRC ( WINAPI * qwglGetCurrentContext)(VOID); HDC ( WINAPI * qwglGetCurrentDC)(VOID); PROC ( WINAPI * qwglGetProcAddress)(LPCSTR); BOOL ( WINAPI * qwglMakeCurrent)(HDC, HGLRC); BOOL ( WINAPI * qwglShareLists)(HGLRC, HGLRC); BOOL ( WINAPI * qwglUseFontBitmaps)(HDC, DWORD, DWORD, DWORD); BOOL ( WINAPI * qwglUseFontOutlines)(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT); BOOL ( WINAPI * qwglDescribeLayerPlane)(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR); int ( WINAPI * qwglSetLayerPaletteEntries)(HDC, int, int, int, CONST COLORREF *); int ( WINAPI * qwglGetLayerPaletteEntries)(HDC, int, int, int, COLORREF *); BOOL ( WINAPI * qwglRealizeLayerPalette)(HDC, int, BOOL); BOOL ( WINAPI * qwglSwapLayerBuffers)(HDC, UINT); void ( APIENTRY * qglAccum )(GLenum op, GLfloat value); void ( APIENTRY * qglAlphaFunc )(GLenum func, GLclampf ref); GLboolean ( APIENTRY * qglAreTexturesResident )(GLsizei n, const GLuint *textures, GLboolean *residences); void ( APIENTRY * qglArrayElement )(GLint i); void ( APIENTRY * qglBegin )(GLenum mode); void ( APIENTRY * qglBindTexture )(GLenum target, GLuint texture); void ( APIENTRY * qglBitmap )(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); void ( APIENTRY * qglBlendFunc )(GLenum sfactor, GLenum dfactor); void ( APIENTRY * qglCallList )(GLuint list); void ( APIENTRY * qglCallLists )(GLsizei n, GLenum type, const GLvoid *lists); void ( APIENTRY * qglClear )(GLbitfield mask); void ( APIENTRY * qglClearAccum )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); void ( APIENTRY * qglClearColor )(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); void ( APIENTRY * qglClearDepth )(GLclampd depth); void ( APIENTRY * qglClearIndex )(GLfloat c); void ( APIENTRY * qglClearStencil )(GLint s); void ( APIENTRY * qglClipPlane )(GLenum plane, const GLdouble *equation); void ( APIENTRY * qglColor3b )(GLbyte red, GLbyte green, GLbyte blue); void ( APIENTRY * qglColor3bv )(const GLbyte *v); void ( APIENTRY * qglColor3d )(GLdouble red, GLdouble green, GLdouble blue); void ( APIENTRY * qglColor3dv )(const GLdouble *v); void ( APIENTRY * qglColor3f )(GLfloat red, GLfloat green, GLfloat blue); void ( APIENTRY * qglColor3fv )(const GLfloat *v); void ( APIENTRY * qglColor3i )(GLint red, GLint green, GLint blue); void ( APIENTRY * qglColor3iv )(const GLint *v); void ( APIENTRY * qglColor3s )(GLshort red, GLshort green, GLshort blue); void ( APIENTRY * qglColor3sv )(const GLshort *v); void ( APIENTRY * qglColor3ub )(GLubyte red, GLubyte green, GLubyte blue); void ( APIENTRY * qglColor3ubv )(const GLubyte *v); void ( APIENTRY * qglColor3ui )(GLuint red, GLuint green, GLuint blue); void ( APIENTRY * qglColor3uiv )(const GLuint *v); void ( APIENTRY * qglColor3us )(GLushort red, GLushort green, GLushort blue); void ( APIENTRY * qglColor3usv )(const GLushort *v); void ( APIENTRY * qglColor4b )(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); void ( APIENTRY * qglColor4bv )(const GLbyte *v); void ( APIENTRY * qglColor4d )(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); void ( APIENTRY * qglColor4dv )(const GLdouble *v); void ( APIENTRY * qglColor4f )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); void ( APIENTRY * qglColor4fv )(const GLfloat *v); void ( APIENTRY * qglColor4i )(GLint red, GLint green, GLint blue, GLint alpha); void ( APIENTRY * qglColor4iv )(const GLint *v); void ( APIENTRY * qglColor4s )(GLshort red, GLshort green, GLshort blue, GLshort alpha); void ( APIENTRY * qglColor4sv )(const GLshort *v); void ( APIENTRY * qglColor4ub )(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); void ( APIENTRY * qglColor4ubv )(const GLubyte *v); void ( APIENTRY * qglColor4ui )(GLuint red, GLuint green, GLuint blue, GLuint alpha); void ( APIENTRY * qglColor4uiv )(const GLuint *v); void ( APIENTRY * qglColor4us )(GLushort red, GLushort green, GLushort blue, GLushort alpha); void ( APIENTRY * qglColor4usv )(const GLushort *v); void ( APIENTRY * qglColorMask )(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); void ( APIENTRY * qglColorMaterial )(GLenum face, GLenum mode); void ( APIENTRY * qglColorPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); void ( APIENTRY * qglCopyPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); void ( APIENTRY * qglCopyTexImage1D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); void ( APIENTRY * qglCopyTexImage2D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); void ( APIENTRY * qglCopyTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); void ( APIENTRY * qglCopyTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); void ( APIENTRY * qglCullFace )(GLenum mode); void ( APIENTRY * qglDeleteLists )(GLuint list, GLsizei range); void ( APIENTRY * qglDeleteTextures )(GLsizei n, const GLuint *textures); void ( APIENTRY * qglDepthFunc )(GLenum func); void ( APIENTRY * qglDepthMask )(GLboolean flag); void ( APIENTRY * qglDepthRange )(GLclampd zNear, GLclampd zFar); void ( APIENTRY * qglDisable )(GLenum cap); void ( APIENTRY * qglDisableClientState )(GLenum array); void ( APIENTRY * qglDrawArrays )(GLenum mode, GLint first, GLsizei count); void ( APIENTRY * qglDrawBuffer )(GLenum mode); void ( APIENTRY * qglDrawElements )(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); void ( APIENTRY * qglDrawPixels )(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); void ( APIENTRY * qglEdgeFlag )(GLboolean flag); void ( APIENTRY * qglEdgeFlagPointer )(GLsizei stride, const GLvoid *pointer); void ( APIENTRY * qglEdgeFlagv )(const GLboolean *flag); void ( APIENTRY * qglEnable )(GLenum cap); void ( APIENTRY * qglEnableClientState )(GLenum array); void ( APIENTRY * qglEnd )(void); void ( APIENTRY * qglEndList )(void); void ( APIENTRY * qglEvalCoord1d )(GLdouble u); void ( APIENTRY * qglEvalCoord1dv )(const GLdouble *u); void ( APIENTRY * qglEvalCoord1f )(GLfloat u); void ( APIENTRY * qglEvalCoord1fv )(const GLfloat *u); void ( APIENTRY * qglEvalCoord2d )(GLdouble u, GLdouble v); void ( APIENTRY * qglEvalCoord2dv )(const GLdouble *u); void ( APIENTRY * qglEvalCoord2f )(GLfloat u, GLfloat v); void ( APIENTRY * qglEvalCoord2fv )(const GLfloat *u); void ( APIENTRY * qglEvalMesh1 )(GLenum mode, GLint i1, GLint i2); void ( APIENTRY * qglEvalMesh2 )(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); void ( APIENTRY * qglEvalPoint1 )(GLint i); void ( APIENTRY * qglEvalPoint2 )(GLint i, GLint j); void ( APIENTRY * qglFeedbackBuffer )(GLsizei size, GLenum type, GLfloat *buffer); void ( APIENTRY * qglFinish )(void); void ( APIENTRY * qglFlush )(void); void ( APIENTRY * qglFogf )(GLenum pname, GLfloat param); void ( APIENTRY * qglFogfv )(GLenum pname, const GLfloat *params); void ( APIENTRY * qglFogi )(GLenum pname, GLint param); void ( APIENTRY * qglFogiv )(GLenum pname, const GLint *params); void ( APIENTRY * qglFrontFace )(GLenum mode); void ( APIENTRY * qglFrustum )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); GLuint ( APIENTRY * qglGenLists )(GLsizei range); void ( APIENTRY * qglGenTextures )(GLsizei n, GLuint *textures); void ( APIENTRY * qglGetBooleanv )(GLenum pname, GLboolean *params); void ( APIENTRY * qglGetClipPlane )(GLenum plane, GLdouble *equation); void ( APIENTRY * qglGetDoublev )(GLenum pname, GLdouble *params); GLenum ( APIENTRY * qglGetError )(void); void ( APIENTRY * qglGetFloatv )(GLenum pname, GLfloat *params); void ( APIENTRY * qglGetIntegerv )(GLenum pname, GLint *params); void ( APIENTRY * qglGetLightfv )(GLenum light, GLenum pname, GLfloat *params); void ( APIENTRY * qglGetLightiv )(GLenum light, GLenum pname, GLint *params); void ( APIENTRY * qglGetMapdv )(GLenum target, GLenum query, GLdouble *v); void ( APIENTRY * qglGetMapfv )(GLenum target, GLenum query, GLfloat *v); void ( APIENTRY * qglGetMapiv )(GLenum target, GLenum query, GLint *v); void ( APIENTRY * qglGetMaterialfv )(GLenum face, GLenum pname, GLfloat *params); void ( APIENTRY * qglGetMaterialiv )(GLenum face, GLenum pname, GLint *params); void ( APIENTRY * qglGetPixelMapfv )(GLenum map, GLfloat *values); void ( APIENTRY * qglGetPixelMapuiv )(GLenum map, GLuint *values); void ( APIENTRY * qglGetPixelMapusv )(GLenum map, GLushort *values); void ( APIENTRY * qglGetPointerv )(GLenum pname, GLvoid* *params); void ( APIENTRY * qglGetPolygonStipple )(GLubyte *mask); const GLubyte * ( APIENTRY * qglGetString )(GLenum name); void ( APIENTRY * qglGetTexEnvfv )(GLenum target, GLenum pname, GLfloat *params); void ( APIENTRY * qglGetTexEnviv )(GLenum target, GLenum pname, GLint *params); void ( APIENTRY * qglGetTexGendv )(GLenum coord, GLenum pname, GLdouble *params); void ( APIENTRY * qglGetTexGenfv )(GLenum coord, GLenum pname, GLfloat *params); void ( APIENTRY * qglGetTexGeniv )(GLenum coord, GLenum pname, GLint *params); void ( APIENTRY * qglGetTexImage )(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); void ( APIENTRY * qglGetTexLevelParameterfv )(GLenum target, GLint level, GLenum pname, GLfloat *params); void ( APIENTRY * qglGetTexLevelParameteriv )(GLenum target, GLint level, GLenum pname, GLint *params); void ( APIENTRY * qglGetTexParameterfv )(GLenum target, GLenum pname, GLfloat *params); void ( APIENTRY * qglGetTexParameteriv )(GLenum target, GLenum pname, GLint *params); void ( APIENTRY * qglHint )(GLenum target, GLenum mode); void ( APIENTRY * qglIndexMask )(GLuint mask); void ( APIENTRY * qglIndexPointer )(GLenum type, GLsizei stride, const GLvoid *pointer); void ( APIENTRY * qglIndexd )(GLdouble c); void ( APIENTRY * qglIndexdv )(const GLdouble *c); void ( APIENTRY * qglIndexf )(GLfloat c); void ( APIENTRY * qglIndexfv )(const GLfloat *c); void ( APIENTRY * qglIndexi )(GLint c); void ( APIENTRY * qglIndexiv )(const GLint *c); void ( APIENTRY * qglIndexs )(GLshort c); void ( APIENTRY * qglIndexsv )(const GLshort *c); void ( APIENTRY * qglIndexub )(GLubyte c); void ( APIENTRY * qglIndexubv )(const GLubyte *c); void ( APIENTRY * qglInitNames )(void); void ( APIENTRY * qglInterleavedArrays )(GLenum format, GLsizei stride, const GLvoid *pointer); GLboolean ( APIENTRY * qglIsEnabled )(GLenum cap); GLboolean ( APIENTRY * qglIsList )(GLuint list); GLboolean ( APIENTRY * qglIsTexture )(GLuint texture); void ( APIENTRY * qglLightModelf )(GLenum pname, GLfloat param); void ( APIENTRY * qglLightModelfv )(GLenum pname, const GLfloat *params); void ( APIENTRY * qglLightModeli )(GLenum pname, GLint param); void ( APIENTRY * qglLightModeliv )(GLenum pname, const GLint *params); void ( APIENTRY * qglLightf )(GLenum light, GLenum pname, GLfloat param); void ( APIENTRY * qglLightfv )(GLenum light, GLenum pname, const GLfloat *params); void ( APIENTRY * qglLighti )(GLenum light, GLenum pname, GLint param); void ( APIENTRY * qglLightiv )(GLenum light, GLenum pname, const GLint *params); void ( APIENTRY * qglLineStipple )(GLint factor, GLushort pattern); void ( APIENTRY * qglLineWidth )(GLfloat width); void ( APIENTRY * qglListBase )(GLuint base); void ( APIENTRY * qglLoadIdentity )(void); void ( APIENTRY * qglLoadMatrixd )(const GLdouble *m); void ( APIENTRY * qglLoadMatrixf )(const GLfloat *m); void ( APIENTRY * qglLoadName )(GLuint name); void ( APIENTRY * qglLogicOp )(GLenum opcode); void ( APIENTRY * qglMap1d )(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); void ( APIENTRY * qglMap1f )(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); void ( APIENTRY * qglMap2d )(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); void ( APIENTRY * qglMap2f )(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); void ( APIENTRY * qglMapGrid1d )(GLint un, GLdouble u1, GLdouble u2); void ( APIENTRY * qglMapGrid1f )(GLint un, GLfloat u1, GLfloat u2); void ( APIENTRY * qglMapGrid2d )(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); void ( APIENTRY * qglMapGrid2f )(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); void ( APIENTRY * qglMaterialf )(GLenum face, GLenum pname, GLfloat param); void ( APIENTRY * qglMaterialfv )(GLenum face, GLenum pname, const GLfloat *params); void ( APIENTRY * qglMateriali )(GLenum face, GLenum pname, GLint param); void ( APIENTRY * qglMaterialiv )(GLenum face, GLenum pname, const GLint *params); void ( APIENTRY * qglMatrixMode )(GLenum mode); void ( APIENTRY * qglMultMatrixd )(const GLdouble *m); void ( APIENTRY * qglMultMatrixf )(const GLfloat *m); void ( APIENTRY * qglNewList )(GLuint list, GLenum mode); void ( APIENTRY * qglNormal3b )(GLbyte nx, GLbyte ny, GLbyte nz); void ( APIENTRY * qglNormal3bv )(const GLbyte *v); void ( APIENTRY * qglNormal3d )(GLdouble nx, GLdouble ny, GLdouble nz); void ( APIENTRY * qglNormal3dv )(const GLdouble *v); void ( APIENTRY * qglNormal3f )(GLfloat nx, GLfloat ny, GLfloat nz); void ( APIENTRY * qglNormal3fv )(const GLfloat *v); void ( APIENTRY * qglNormal3i )(GLint nx, GLint ny, GLint nz); void ( APIENTRY * qglNormal3iv )(const GLint *v); void ( APIENTRY * qglNormal3s )(GLshort nx, GLshort ny, GLshort nz); void ( APIENTRY * qglNormal3sv )(const GLshort *v); void ( APIENTRY * qglNormalPointer )(GLenum type, GLsizei stride, const GLvoid *pointer); void ( APIENTRY * qglOrtho )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); void ( APIENTRY * qglPassThrough )(GLfloat token); void ( APIENTRY * qglPixelMapfv )(GLenum map, GLsizei mapsize, const GLfloat *values); void ( APIENTRY * qglPixelMapuiv )(GLenum map, GLsizei mapsize, const GLuint *values); void ( APIENTRY * qglPixelMapusv )(GLenum map, GLsizei mapsize, const GLushort *values); void ( APIENTRY * qglPixelStoref )(GLenum pname, GLfloat param); void ( APIENTRY * qglPixelStorei )(GLenum pname, GLint param); void ( APIENTRY * qglPixelTransferf )(GLenum pname, GLfloat param); void ( APIENTRY * qglPixelTransferi )(GLenum pname, GLint param); void ( APIENTRY * qglPixelZoom )(GLfloat xfactor, GLfloat yfactor); void ( APIENTRY * qglPointSize )(GLfloat size); void ( APIENTRY * qglPolygonMode )(GLenum face, GLenum mode); void ( APIENTRY * qglPolygonOffset )(GLfloat factor, GLfloat units); void ( APIENTRY * qglPolygonStipple )(const GLubyte *mask); void ( APIENTRY * qglPopAttrib )(void); void ( APIENTRY * qglPopClientAttrib )(void); void ( APIENTRY * qglPopMatrix )(void); void ( APIENTRY * qglPopName )(void); void ( APIENTRY * qglPrioritizeTextures )(GLsizei n, const GLuint *textures, const GLclampf *priorities); void ( APIENTRY * qglPushAttrib )(GLbitfield mask); void ( APIENTRY * qglPushClientAttrib )(GLbitfield mask); void ( APIENTRY * qglPushMatrix )(void); void ( APIENTRY * qglPushName )(GLuint name); void ( APIENTRY * qglRasterPos2d )(GLdouble x, GLdouble y); void ( APIENTRY * qglRasterPos2dv )(const GLdouble *v); void ( APIENTRY * qglRasterPos2f )(GLfloat x, GLfloat y); void ( APIENTRY * qglRasterPos2fv )(const GLfloat *v); void ( APIENTRY * qglRasterPos2i )(GLint x, GLint y); void ( APIENTRY * qglRasterPos2iv )(const GLint *v); void ( APIENTRY * qglRasterPos2s )(GLshort x, GLshort y); void ( APIENTRY * qglRasterPos2sv )(const GLshort *v); void ( APIENTRY * qglRasterPos3d )(GLdouble x, GLdouble y, GLdouble z); void ( APIENTRY * qglRasterPos3dv )(const GLdouble *v); void ( APIENTRY * qglRasterPos3f )(GLfloat x, GLfloat y, GLfloat z); void ( APIENTRY * qglRasterPos3fv )(const GLfloat *v); void ( APIENTRY * qglRasterPos3i )(GLint x, GLint y, GLint z); void ( APIENTRY * qglRasterPos3iv )(const GLint *v); void ( APIENTRY * qglRasterPos3s )(GLshort x, GLshort y, GLshort z); void ( APIENTRY * qglRasterPos3sv )(const GLshort *v); void ( APIENTRY * qglRasterPos4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w); void ( APIENTRY * qglRasterPos4dv )(const GLdouble *v); void ( APIENTRY * qglRasterPos4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w); void ( APIENTRY * qglRasterPos4fv )(const GLfloat *v); void ( APIENTRY * qglRasterPos4i )(GLint x, GLint y, GLint z, GLint w); void ( APIENTRY * qglRasterPos4iv )(const GLint *v); void ( APIENTRY * qglRasterPos4s )(GLshort x, GLshort y, GLshort z, GLshort w); void ( APIENTRY * qglRasterPos4sv )(const GLshort *v); void ( APIENTRY * qglReadBuffer )(GLenum mode); void ( APIENTRY * qglReadPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); void ( APIENTRY * qglRectd )(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); void ( APIENTRY * qglRectdv )(const GLdouble *v1, const GLdouble *v2); void ( APIENTRY * qglRectf )(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); void ( APIENTRY * qglRectfv )(const GLfloat *v1, const GLfloat *v2); void ( APIENTRY * qglRecti )(GLint x1, GLint y1, GLint x2, GLint y2); void ( APIENTRY * qglRectiv )(const GLint *v1, const GLint *v2); void ( APIENTRY * qglRects )(GLshort x1, GLshort y1, GLshort x2, GLshort y2); void ( APIENTRY * qglRectsv )(const GLshort *v1, const GLshort *v2); GLint ( APIENTRY * qglRenderMode )(GLenum mode); void ( APIENTRY * qglRotated )(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); void ( APIENTRY * qglRotatef )(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); void ( APIENTRY * qglScaled )(GLdouble x, GLdouble y, GLdouble z); void ( APIENTRY * qglScalef )(GLfloat x, GLfloat y, GLfloat z); void ( APIENTRY * qglScissor )(GLint x, GLint y, GLsizei width, GLsizei height); void ( APIENTRY * qglSelectBuffer )(GLsizei size, GLuint *buffer); void ( APIENTRY * qglShadeModel )(GLenum mode); void ( APIENTRY * qglStencilFunc )(GLenum func, GLint ref, GLuint mask); void ( APIENTRY * qglStencilMask )(GLuint mask); void ( APIENTRY * qglStencilOp )(GLenum fail, GLenum zfail, GLenum zpass); void ( APIENTRY * qglTexCoord1d )(GLdouble s); void ( APIENTRY * qglTexCoord1dv )(const GLdouble *v); void ( APIENTRY * qglTexCoord1f )(GLfloat s); void ( APIENTRY * qglTexCoord1fv )(const GLfloat *v); void ( APIENTRY * qglTexCoord1i )(GLint s); void ( APIENTRY * qglTexCoord1iv )(const GLint *v); void ( APIENTRY * qglTexCoord1s )(GLshort s); void ( APIENTRY * qglTexCoord1sv )(const GLshort *v); void ( APIENTRY * qglTexCoord2d )(GLdouble s, GLdouble t); void ( APIENTRY * qglTexCoord2dv )(const GLdouble *v); void ( APIENTRY * qglTexCoord2f )(GLfloat s, GLfloat t); void ( APIENTRY * qglTexCoord2fv )(const GLfloat *v); void ( APIENTRY * qglTexCoord2i )(GLint s, GLint t); void ( APIENTRY * qglTexCoord2iv )(const GLint *v); void ( APIENTRY * qglTexCoord2s )(GLshort s, GLshort t); void ( APIENTRY * qglTexCoord2sv )(const GLshort *v); void ( APIENTRY * qglTexCoord3d )(GLdouble s, GLdouble t, GLdouble r); void ( APIENTRY * qglTexCoord3dv )(const GLdouble *v); void ( APIENTRY * qglTexCoord3f )(GLfloat s, GLfloat t, GLfloat r); void ( APIENTRY * qglTexCoord3fv )(const GLfloat *v); void ( APIENTRY * qglTexCoord3i )(GLint s, GLint t, GLint r); void ( APIENTRY * qglTexCoord3iv )(const GLint *v); void ( APIENTRY * qglTexCoord3s )(GLshort s, GLshort t, GLshort r); void ( APIENTRY * qglTexCoord3sv )(const GLshort *v); void ( APIENTRY * qglTexCoord4d )(GLdouble s, GLdouble t, GLdouble r, GLdouble q); void ( APIENTRY * qglTexCoord4dv )(const GLdouble *v); void ( APIENTRY * qglTexCoord4f )(GLfloat s, GLfloat t, GLfloat r, GLfloat q); void ( APIENTRY * qglTexCoord4fv )(const GLfloat *v); void ( APIENTRY * qglTexCoord4i )(GLint s, GLint t, GLint r, GLint q); void ( APIENTRY * qglTexCoord4iv )(const GLint *v); void ( APIENTRY * qglTexCoord4s )(GLshort s, GLshort t, GLshort r, GLshort q); void ( APIENTRY * qglTexCoord4sv )(const GLshort *v); void ( APIENTRY * qglTexCoordPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); void ( APIENTRY * qglTexEnvf )(GLenum target, GLenum pname, GLfloat param); void ( APIENTRY * qglTexEnvfv )(GLenum target, GLenum pname, const GLfloat *params); void ( APIENTRY * qglTexEnvi )(GLenum target, GLenum pname, GLint param); void ( APIENTRY * qglTexEnviv )(GLenum target, GLenum pname, const GLint *params); void ( APIENTRY * qglTexGend )(GLenum coord, GLenum pname, GLdouble param); void ( APIENTRY * qglTexGendv )(GLenum coord, GLenum pname, const GLdouble *params); void ( APIENTRY * qglTexGenf )(GLenum coord, GLenum pname, GLfloat param); void ( APIENTRY * qglTexGenfv )(GLenum coord, GLenum pname, const GLfloat *params); void ( APIENTRY * qglTexGeni )(GLenum coord, GLenum pname, GLint param); void ( APIENTRY * qglTexGeniv )(GLenum coord, GLenum pname, const GLint *params); void ( APIENTRY * qglTexImage1D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); void ( APIENTRY * qglTexImage2D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); void ( APIENTRY * qglTexParameterf )(GLenum target, GLenum pname, GLfloat param); void ( APIENTRY * qglTexParameterfv )(GLenum target, GLenum pname, const GLfloat *params); void ( APIENTRY * qglTexParameteri )(GLenum target, GLenum pname, GLint param); void ( APIENTRY * qglTexParameteriv )(GLenum target, GLenum pname, const GLint *params); void ( APIENTRY * qglTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); void ( APIENTRY * qglTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); void ( APIENTRY * qglTranslated )(GLdouble x, GLdouble y, GLdouble z); void ( APIENTRY * qglTranslatef )(GLfloat x, GLfloat y, GLfloat z); void ( APIENTRY * qglVertex2d )(GLdouble x, GLdouble y); void ( APIENTRY * qglVertex2dv )(const GLdouble *v); void ( APIENTRY * qglVertex2f )(GLfloat x, GLfloat y); void ( APIENTRY * qglVertex2fv )(const GLfloat *v); void ( APIENTRY * qglVertex2i )(GLint x, GLint y); void ( APIENTRY * qglVertex2iv )(const GLint *v); void ( APIENTRY * qglVertex2s )(GLshort x, GLshort y); void ( APIENTRY * qglVertex2sv )(const GLshort *v); void ( APIENTRY * qglVertex3d )(GLdouble x, GLdouble y, GLdouble z); void ( APIENTRY * qglVertex3dv )(const GLdouble *v); void ( APIENTRY * qglVertex3f )(GLfloat x, GLfloat y, GLfloat z); void ( APIENTRY * qglVertex3fv )(const GLfloat *v); void ( APIENTRY * qglVertex3i )(GLint x, GLint y, GLint z); void ( APIENTRY * qglVertex3iv )(const GLint *v); void ( APIENTRY * qglVertex3s )(GLshort x, GLshort y, GLshort z); void ( APIENTRY * qglVertex3sv )(const GLshort *v); void ( APIENTRY * qglVertex4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w); void ( APIENTRY * qglVertex4dv )(const GLdouble *v); void ( APIENTRY * qglVertex4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w); void ( APIENTRY * qglVertex4fv )(const GLfloat *v); void ( APIENTRY * qglVertex4i )(GLint x, GLint y, GLint z, GLint w); void ( APIENTRY * qglVertex4iv )(const GLint *v); void ( APIENTRY * qglVertex4s )(GLshort x, GLshort y, GLshort z, GLshort w); void ( APIENTRY * qglVertex4sv )(const GLshort *v); void ( APIENTRY * qglVertexPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); void ( APIENTRY * qglViewport )(GLint x, GLint y, GLsizei width, GLsizei height); void ( APIENTRY * qglLockArraysEXT)( int, int); void ( APIENTRY * qglUnlockArraysEXT) ( void ); BOOL ( WINAPI * qwglSwapIntervalEXT)( int interval ); BOOL ( WINAPI * qwglGetDeviceGammaRampEXT)( unsigned char *, unsigned char *, unsigned char * ); BOOL ( WINAPI * qwglSetDeviceGammaRampEXT)( const unsigned char *, const unsigned char *, const unsigned char * ); void ( APIENTRY * qglPointParameterfEXT)( GLenum param, GLfloat value ); void ( APIENTRY * qglPointParameterfvEXT)( GLenum param, const GLfloat *value ); void ( APIENTRY * qglColorTableEXT)( int, int, int, int, int, const void * ); void ( APIENTRY * qglSelectTextureARB)( GLenum ); void ( APIENTRY * qglMTexCoord2fARB)( GLenum, GLfloat, GLfloat ); void ( APIENTRY * qglMTexCoord3fARB)( GLenum, GLfloat, GLfloat, GLfloat ); void ( APIENTRY * qglActiveTextureARB) ( GLenum ); void ( APIENTRY * qglClientActiveTextureARB) ( GLenum ); void ( APIENTRY * qglMultiTexCoord3fvARB)( GLenum, GLfloat * ); static void ( APIENTRY * dllAccum )(GLenum op, GLfloat value); static void ( APIENTRY * dllAlphaFunc )(GLenum func, GLclampf ref); GLboolean ( APIENTRY * dllAreTexturesResident )(GLsizei n, const GLuint *textures, GLboolean *residences); static void ( APIENTRY * dllArrayElement )(GLint i); static void ( APIENTRY * dllBegin )(GLenum mode); static void ( APIENTRY * dllBindTexture )(GLenum target, GLuint texture); static void ( APIENTRY * dllBitmap )(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); static void ( APIENTRY * dllBlendFunc )(GLenum sfactor, GLenum dfactor); static void ( APIENTRY * dllCallList )(GLuint list); static void ( APIENTRY * dllCallLists )(GLsizei n, GLenum type, const GLvoid *lists); static void ( APIENTRY * dllClear )(GLbitfield mask); static void ( APIENTRY * dllClearAccum )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); static void ( APIENTRY * dllClearColor )(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); static void ( APIENTRY * dllClearDepth )(GLclampd depth); static void ( APIENTRY * dllClearIndex )(GLfloat c); static void ( APIENTRY * dllClearStencil )(GLint s); static void ( APIENTRY * dllClipPlane )(GLenum plane, const GLdouble *equation); static void ( APIENTRY * dllColor3b )(GLbyte red, GLbyte green, GLbyte blue); static void ( APIENTRY * dllColor3bv )(const GLbyte *v); static void ( APIENTRY * dllColor3d )(GLdouble red, GLdouble green, GLdouble blue); static void ( APIENTRY * dllColor3dv )(const GLdouble *v); static void ( APIENTRY * dllColor3f )(GLfloat red, GLfloat green, GLfloat blue); static void ( APIENTRY * dllColor3fv )(const GLfloat *v); static void ( APIENTRY * dllColor3i )(GLint red, GLint green, GLint blue); static void ( APIENTRY * dllColor3iv )(const GLint *v); static void ( APIENTRY * dllColor3s )(GLshort red, GLshort green, GLshort blue); static void ( APIENTRY * dllColor3sv )(const GLshort *v); static void ( APIENTRY * dllColor3ub )(GLubyte red, GLubyte green, GLubyte blue); static void ( APIENTRY * dllColor3ubv )(const GLubyte *v); static void ( APIENTRY * dllColor3ui )(GLuint red, GLuint green, GLuint blue); static void ( APIENTRY * dllColor3uiv )(const GLuint *v); static void ( APIENTRY * dllColor3us )(GLushort red, GLushort green, GLushort blue); static void ( APIENTRY * dllColor3usv )(const GLushort *v); static void ( APIENTRY * dllColor4b )(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); static void ( APIENTRY * dllColor4bv )(const GLbyte *v); static void ( APIENTRY * dllColor4d )(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); static void ( APIENTRY * dllColor4dv )(const GLdouble *v); static void ( APIENTRY * dllColor4f )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); static void ( APIENTRY * dllColor4fv )(const GLfloat *v); static void ( APIENTRY * dllColor4i )(GLint red, GLint green, GLint blue, GLint alpha); static void ( APIENTRY * dllColor4iv )(const GLint *v); static void ( APIENTRY * dllColor4s )(GLshort red, GLshort green, GLshort blue, GLshort alpha); static void ( APIENTRY * dllColor4sv )(const GLshort *v); static void ( APIENTRY * dllColor4ub )(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); static void ( APIENTRY * dllColor4ubv )(const GLubyte *v); static void ( APIENTRY * dllColor4ui )(GLuint red, GLuint green, GLuint blue, GLuint alpha); static void ( APIENTRY * dllColor4uiv )(const GLuint *v); static void ( APIENTRY * dllColor4us )(GLushort red, GLushort green, GLushort blue, GLushort alpha); static void ( APIENTRY * dllColor4usv )(const GLushort *v); static void ( APIENTRY * dllColorMask )(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); static void ( APIENTRY * dllColorMaterial )(GLenum face, GLenum mode); static void ( APIENTRY * dllColorPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); static void ( APIENTRY * dllCopyPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); static void ( APIENTRY * dllCopyTexImage1D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); static void ( APIENTRY * dllCopyTexImage2D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); static void ( APIENTRY * dllCopyTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); static void ( APIENTRY * dllCopyTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); static void ( APIENTRY * dllCullFace )(GLenum mode); static void ( APIENTRY * dllDeleteLists )(GLuint list, GLsizei range); static void ( APIENTRY * dllDeleteTextures )(GLsizei n, const GLuint *textures); static void ( APIENTRY * dllDepthFunc )(GLenum func); static void ( APIENTRY * dllDepthMask )(GLboolean flag); static void ( APIENTRY * dllDepthRange )(GLclampd zNear, GLclampd zFar); static void ( APIENTRY * dllDisable )(GLenum cap); static void ( APIENTRY * dllDisableClientState )(GLenum array); static void ( APIENTRY * dllDrawArrays )(GLenum mode, GLint first, GLsizei count); static void ( APIENTRY * dllDrawBuffer )(GLenum mode); static void ( APIENTRY * dllDrawElements )(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); static void ( APIENTRY * dllDrawPixels )(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); static void ( APIENTRY * dllEdgeFlag )(GLboolean flag); static void ( APIENTRY * dllEdgeFlagPointer )(GLsizei stride, const GLvoid *pointer); static void ( APIENTRY * dllEdgeFlagv )(const GLboolean *flag); static void ( APIENTRY * dllEnable )(GLenum cap); static void ( APIENTRY * dllEnableClientState )(GLenum array); static void ( APIENTRY * dllEnd )(void); static void ( APIENTRY * dllEndList )(void); static void ( APIENTRY * dllEvalCoord1d )(GLdouble u); static void ( APIENTRY * dllEvalCoord1dv )(const GLdouble *u); static void ( APIENTRY * dllEvalCoord1f )(GLfloat u); static void ( APIENTRY * dllEvalCoord1fv )(const GLfloat *u); static void ( APIENTRY * dllEvalCoord2d )(GLdouble u, GLdouble v); static void ( APIENTRY * dllEvalCoord2dv )(const GLdouble *u); static void ( APIENTRY * dllEvalCoord2f )(GLfloat u, GLfloat v); static void ( APIENTRY * dllEvalCoord2fv )(const GLfloat *u); static void ( APIENTRY * dllEvalMesh1 )(GLenum mode, GLint i1, GLint i2); static void ( APIENTRY * dllEvalMesh2 )(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); static void ( APIENTRY * dllEvalPoint1 )(GLint i); static void ( APIENTRY * dllEvalPoint2 )(GLint i, GLint j); static void ( APIENTRY * dllFeedbackBuffer )(GLsizei size, GLenum type, GLfloat *buffer); static void ( APIENTRY * dllFinish )(void); static void ( APIENTRY * dllFlush )(void); static void ( APIENTRY * dllFogf )(GLenum pname, GLfloat param); static void ( APIENTRY * dllFogfv )(GLenum pname, const GLfloat *params); static void ( APIENTRY * dllFogi )(GLenum pname, GLint param); static void ( APIENTRY * dllFogiv )(GLenum pname, const GLint *params); static void ( APIENTRY * dllFrontFace )(GLenum mode); static void ( APIENTRY * dllFrustum )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); GLuint ( APIENTRY * dllGenLists )(GLsizei range); static void ( APIENTRY * dllGenTextures )(GLsizei n, GLuint *textures); static void ( APIENTRY * dllGetBooleanv )(GLenum pname, GLboolean *params); static void ( APIENTRY * dllGetClipPlane )(GLenum plane, GLdouble *equation); static void ( APIENTRY * dllGetDoublev )(GLenum pname, GLdouble *params); GLenum ( APIENTRY * dllGetError )(void); static void ( APIENTRY * dllGetFloatv )(GLenum pname, GLfloat *params); static void ( APIENTRY * dllGetIntegerv )(GLenum pname, GLint *params); static void ( APIENTRY * dllGetLightfv )(GLenum light, GLenum pname, GLfloat *params); static void ( APIENTRY * dllGetLightiv )(GLenum light, GLenum pname, GLint *params); static void ( APIENTRY * dllGetMapdv )(GLenum target, GLenum query, GLdouble *v); static void ( APIENTRY * dllGetMapfv )(GLenum target, GLenum query, GLfloat *v); static void ( APIENTRY * dllGetMapiv )(GLenum target, GLenum query, GLint *v); static void ( APIENTRY * dllGetMaterialfv )(GLenum face, GLenum pname, GLfloat *params); static void ( APIENTRY * dllGetMaterialiv )(GLenum face, GLenum pname, GLint *params); static void ( APIENTRY * dllGetPixelMapfv )(GLenum map, GLfloat *values); static void ( APIENTRY * dllGetPixelMapuiv )(GLenum map, GLuint *values); static void ( APIENTRY * dllGetPixelMapusv )(GLenum map, GLushort *values); static void ( APIENTRY * dllGetPointerv )(GLenum pname, GLvoid* *params); static void ( APIENTRY * dllGetPolygonStipple )(GLubyte *mask); const GLubyte * ( APIENTRY * dllGetString )(GLenum name); static void ( APIENTRY * dllGetTexEnvfv )(GLenum target, GLenum pname, GLfloat *params); static void ( APIENTRY * dllGetTexEnviv )(GLenum target, GLenum pname, GLint *params); static void ( APIENTRY * dllGetTexGendv )(GLenum coord, GLenum pname, GLdouble *params); static void ( APIENTRY * dllGetTexGenfv )(GLenum coord, GLenum pname, GLfloat *params); static void ( APIENTRY * dllGetTexGeniv )(GLenum coord, GLenum pname, GLint *params); static void ( APIENTRY * dllGetTexImage )(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); static void ( APIENTRY * dllGetTexLevelParameterfv )(GLenum target, GLint level, GLenum pname, GLfloat *params); static void ( APIENTRY * dllGetTexLevelParameteriv )(GLenum target, GLint level, GLenum pname, GLint *params); static void ( APIENTRY * dllGetTexParameterfv )(GLenum target, GLenum pname, GLfloat *params); static void ( APIENTRY * dllGetTexParameteriv )(GLenum target, GLenum pname, GLint *params); static void ( APIENTRY * dllHint )(GLenum target, GLenum mode); static void ( APIENTRY * dllIndexMask )(GLuint mask); static void ( APIENTRY * dllIndexPointer )(GLenum type, GLsizei stride, const GLvoid *pointer); static void ( APIENTRY * dllIndexd )(GLdouble c); static void ( APIENTRY * dllIndexdv )(const GLdouble *c); static void ( APIENTRY * dllIndexf )(GLfloat c); static void ( APIENTRY * dllIndexfv )(const GLfloat *c); static void ( APIENTRY * dllIndexi )(GLint c); static void ( APIENTRY * dllIndexiv )(const GLint *c); static void ( APIENTRY * dllIndexs )(GLshort c); static void ( APIENTRY * dllIndexsv )(const GLshort *c); static void ( APIENTRY * dllIndexub )(GLubyte c); static void ( APIENTRY * dllIndexubv )(const GLubyte *c); static void ( APIENTRY * dllInitNames )(void); static void ( APIENTRY * dllInterleavedArrays )(GLenum format, GLsizei stride, const GLvoid *pointer); GLboolean ( APIENTRY * dllIsEnabled )(GLenum cap); GLboolean ( APIENTRY * dllIsList )(GLuint list); GLboolean ( APIENTRY * dllIsTexture )(GLuint texture); static void ( APIENTRY * dllLightModelf )(GLenum pname, GLfloat param); static void ( APIENTRY * dllLightModelfv )(GLenum pname, const GLfloat *params); static void ( APIENTRY * dllLightModeli )(GLenum pname, GLint param); static void ( APIENTRY * dllLightModeliv )(GLenum pname, const GLint *params); static void ( APIENTRY * dllLightf )(GLenum light, GLenum pname, GLfloat param); static void ( APIENTRY * dllLightfv )(GLenum light, GLenum pname, const GLfloat *params); static void ( APIENTRY * dllLighti )(GLenum light, GLenum pname, GLint param); static void ( APIENTRY * dllLightiv )(GLenum light, GLenum pname, const GLint *params); static void ( APIENTRY * dllLineStipple )(GLint factor, GLushort pattern); static void ( APIENTRY * dllLineWidth )(GLfloat width); static void ( APIENTRY * dllListBase )(GLuint base); static void ( APIENTRY * dllLoadIdentity )(void); static void ( APIENTRY * dllLoadMatrixd )(const GLdouble *m); static void ( APIENTRY * dllLoadMatrixf )(const GLfloat *m); static void ( APIENTRY * dllLoadName )(GLuint name); static void ( APIENTRY * dllLogicOp )(GLenum opcode); static void ( APIENTRY * dllMap1d )(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); static void ( APIENTRY * dllMap1f )(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); static void ( APIENTRY * dllMap2d )(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); static void ( APIENTRY * dllMap2f )(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); static void ( APIENTRY * dllMapGrid1d )(GLint un, GLdouble u1, GLdouble u2); static void ( APIENTRY * dllMapGrid1f )(GLint un, GLfloat u1, GLfloat u2); static void ( APIENTRY * dllMapGrid2d )(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); static void ( APIENTRY * dllMapGrid2f )(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); static void ( APIENTRY * dllMaterialf )(GLenum face, GLenum pname, GLfloat param); static void ( APIENTRY * dllMaterialfv )(GLenum face, GLenum pname, const GLfloat *params); static void ( APIENTRY * dllMateriali )(GLenum face, GLenum pname, GLint param); static void ( APIENTRY * dllMaterialiv )(GLenum face, GLenum pname, const GLint *params); static void ( APIENTRY * dllMatrixMode )(GLenum mode); static void ( APIENTRY * dllMultMatrixd )(const GLdouble *m); static void ( APIENTRY * dllMultMatrixf )(const GLfloat *m); static void ( APIENTRY * dllNewList )(GLuint list, GLenum mode); static void ( APIENTRY * dllNormal3b )(GLbyte nx, GLbyte ny, GLbyte nz); static void ( APIENTRY * dllNormal3bv )(const GLbyte *v); static void ( APIENTRY * dllNormal3d )(GLdouble nx, GLdouble ny, GLdouble nz); static void ( APIENTRY * dllNormal3dv )(const GLdouble *v); static void ( APIENTRY * dllNormal3f )(GLfloat nx, GLfloat ny, GLfloat nz); static void ( APIENTRY * dllNormal3fv )(const GLfloat *v); static void ( APIENTRY * dllNormal3i )(GLint nx, GLint ny, GLint nz); static void ( APIENTRY * dllNormal3iv )(const GLint *v); static void ( APIENTRY * dllNormal3s )(GLshort nx, GLshort ny, GLshort nz); static void ( APIENTRY * dllNormal3sv )(const GLshort *v); static void ( APIENTRY * dllNormalPointer )(GLenum type, GLsizei stride, const GLvoid *pointer); static void ( APIENTRY * dllOrtho )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); static void ( APIENTRY * dllPassThrough )(GLfloat token); static void ( APIENTRY * dllPixelMapfv )(GLenum map, GLsizei mapsize, const GLfloat *values); static void ( APIENTRY * dllPixelMapuiv )(GLenum map, GLsizei mapsize, const GLuint *values); static void ( APIENTRY * dllPixelMapusv )(GLenum map, GLsizei mapsize, const GLushort *values); static void ( APIENTRY * dllPixelStoref )(GLenum pname, GLfloat param); static void ( APIENTRY * dllPixelStorei )(GLenum pname, GLint param); static void ( APIENTRY * dllPixelTransferf )(GLenum pname, GLfloat param); static void ( APIENTRY * dllPixelTransferi )(GLenum pname, GLint param); static void ( APIENTRY * dllPixelZoom )(GLfloat xfactor, GLfloat yfactor); static void ( APIENTRY * dllPointSize )(GLfloat size); static void ( APIENTRY * dllPolygonMode )(GLenum face, GLenum mode); static void ( APIENTRY * dllPolygonOffset )(GLfloat factor, GLfloat units); static void ( APIENTRY * dllPolygonStipple )(const GLubyte *mask); static void ( APIENTRY * dllPopAttrib )(void); static void ( APIENTRY * dllPopClientAttrib )(void); static void ( APIENTRY * dllPopMatrix )(void); static void ( APIENTRY * dllPopName )(void); static void ( APIENTRY * dllPrioritizeTextures )(GLsizei n, const GLuint *textures, const GLclampf *priorities); static void ( APIENTRY * dllPushAttrib )(GLbitfield mask); static void ( APIENTRY * dllPushClientAttrib )(GLbitfield mask); static void ( APIENTRY * dllPushMatrix )(void); static void ( APIENTRY * dllPushName )(GLuint name); static void ( APIENTRY * dllRasterPos2d )(GLdouble x, GLdouble y); static void ( APIENTRY * dllRasterPos2dv )(const GLdouble *v); static void ( APIENTRY * dllRasterPos2f )(GLfloat x, GLfloat y); static void ( APIENTRY * dllRasterPos2fv )(const GLfloat *v); static void ( APIENTRY * dllRasterPos2i )(GLint x, GLint y); static void ( APIENTRY * dllRasterPos2iv )(const GLint *v); static void ( APIENTRY * dllRasterPos2s )(GLshort x, GLshort y); static void ( APIENTRY * dllRasterPos2sv )(const GLshort *v); static void ( APIENTRY * dllRasterPos3d )(GLdouble x, GLdouble y, GLdouble z); static void ( APIENTRY * dllRasterPos3dv )(const GLdouble *v); static void ( APIENTRY * dllRasterPos3f )(GLfloat x, GLfloat y, GLfloat z); static void ( APIENTRY * dllRasterPos3fv )(const GLfloat *v); static void ( APIENTRY * dllRasterPos3i )(GLint x, GLint y, GLint z); static void ( APIENTRY * dllRasterPos3iv )(const GLint *v); static void ( APIENTRY * dllRasterPos3s )(GLshort x, GLshort y, GLshort z); static void ( APIENTRY * dllRasterPos3sv )(const GLshort *v); static void ( APIENTRY * dllRasterPos4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w); static void ( APIENTRY * dllRasterPos4dv )(const GLdouble *v); static void ( APIENTRY * dllRasterPos4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w); static void ( APIENTRY * dllRasterPos4fv )(const GLfloat *v); static void ( APIENTRY * dllRasterPos4i )(GLint x, GLint y, GLint z, GLint w); static void ( APIENTRY * dllRasterPos4iv )(const GLint *v); static void ( APIENTRY * dllRasterPos4s )(GLshort x, GLshort y, GLshort z, GLshort w); static void ( APIENTRY * dllRasterPos4sv )(const GLshort *v); static void ( APIENTRY * dllReadBuffer )(GLenum mode); static void ( APIENTRY * dllReadPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); static void ( APIENTRY * dllRectd )(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); static void ( APIENTRY * dllRectdv )(const GLdouble *v1, const GLdouble *v2); static void ( APIENTRY * dllRectf )(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); static void ( APIENTRY * dllRectfv )(const GLfloat *v1, const GLfloat *v2); static void ( APIENTRY * dllRecti )(GLint x1, GLint y1, GLint x2, GLint y2); static void ( APIENTRY * dllRectiv )(const GLint *v1, const GLint *v2); static void ( APIENTRY * dllRects )(GLshort x1, GLshort y1, GLshort x2, GLshort y2); static void ( APIENTRY * dllRectsv )(const GLshort *v1, const GLshort *v2); GLint ( APIENTRY * dllRenderMode )(GLenum mode); static void ( APIENTRY * dllRotated )(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); static void ( APIENTRY * dllRotatef )(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); static void ( APIENTRY * dllScaled )(GLdouble x, GLdouble y, GLdouble z); static void ( APIENTRY * dllScalef )(GLfloat x, GLfloat y, GLfloat z); static void ( APIENTRY * dllScissor )(GLint x, GLint y, GLsizei width, GLsizei height); static void ( APIENTRY * dllSelectBuffer )(GLsizei size, GLuint *buffer); static void ( APIENTRY * dllShadeModel )(GLenum mode); static void ( APIENTRY * dllStencilFunc )(GLenum func, GLint ref, GLuint mask); static void ( APIENTRY * dllStencilMask )(GLuint mask); static void ( APIENTRY * dllStencilOp )(GLenum fail, GLenum zfail, GLenum zpass); static void ( APIENTRY * dllTexCoord1d )(GLdouble s); static void ( APIENTRY * dllTexCoord1dv )(const GLdouble *v); static void ( APIENTRY * dllTexCoord1f )(GLfloat s); static void ( APIENTRY * dllTexCoord1fv )(const GLfloat *v); static void ( APIENTRY * dllTexCoord1i )(GLint s); static void ( APIENTRY * dllTexCoord1iv )(const GLint *v); static void ( APIENTRY * dllTexCoord1s )(GLshort s); static void ( APIENTRY * dllTexCoord1sv )(const GLshort *v); static void ( APIENTRY * dllTexCoord2d )(GLdouble s, GLdouble t); static void ( APIENTRY * dllTexCoord2dv )(const GLdouble *v); static void ( APIENTRY * dllTexCoord2f )(GLfloat s, GLfloat t); static void ( APIENTRY * dllTexCoord2fv )(const GLfloat *v); static void ( APIENTRY * dllTexCoord2i )(GLint s, GLint t); static void ( APIENTRY * dllTexCoord2iv )(const GLint *v); static void ( APIENTRY * dllTexCoord2s )(GLshort s, GLshort t); static void ( APIENTRY * dllTexCoord2sv )(const GLshort *v); static void ( APIENTRY * dllTexCoord3d )(GLdouble s, GLdouble t, GLdouble r); static void ( APIENTRY * dllTexCoord3dv )(const GLdouble *v); static void ( APIENTRY * dllTexCoord3f )(GLfloat s, GLfloat t, GLfloat r); static void ( APIENTRY * dllTexCoord3fv )(const GLfloat *v); static void ( APIENTRY * dllTexCoord3i )(GLint s, GLint t, GLint r); static void ( APIENTRY * dllTexCoord3iv )(const GLint *v); static void ( APIENTRY * dllTexCoord3s )(GLshort s, GLshort t, GLshort r); static void ( APIENTRY * dllTexCoord3sv )(const GLshort *v); static void ( APIENTRY * dllTexCoord4d )(GLdouble s, GLdouble t, GLdouble r, GLdouble q); static void ( APIENTRY * dllTexCoord4dv )(const GLdouble *v); static void ( APIENTRY * dllTexCoord4f )(GLfloat s, GLfloat t, GLfloat r, GLfloat q); static void ( APIENTRY * dllTexCoord4fv )(const GLfloat *v); static void ( APIENTRY * dllTexCoord4i )(GLint s, GLint t, GLint r, GLint q); static void ( APIENTRY * dllTexCoord4iv )(const GLint *v); static void ( APIENTRY * dllTexCoord4s )(GLshort s, GLshort t, GLshort r, GLshort q); static void ( APIENTRY * dllTexCoord4sv )(const GLshort *v); static void ( APIENTRY * dllTexCoordPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); static void ( APIENTRY * dllTexEnvf )(GLenum target, GLenum pname, GLfloat param); static void ( APIENTRY * dllTexEnvfv )(GLenum target, GLenum pname, const GLfloat *params); static void ( APIENTRY * dllTexEnvi )(GLenum target, GLenum pname, GLint param); static void ( APIENTRY * dllTexEnviv )(GLenum target, GLenum pname, const GLint *params); static void ( APIENTRY * dllTexGend )(GLenum coord, GLenum pname, GLdouble param); static void ( APIENTRY * dllTexGendv )(GLenum coord, GLenum pname, const GLdouble *params); static void ( APIENTRY * dllTexGenf )(GLenum coord, GLenum pname, GLfloat param); static void ( APIENTRY * dllTexGenfv )(GLenum coord, GLenum pname, const GLfloat *params); static void ( APIENTRY * dllTexGeni )(GLenum coord, GLenum pname, GLint param); static void ( APIENTRY * dllTexGeniv )(GLenum coord, GLenum pname, const GLint *params); static void ( APIENTRY * dllTexImage1D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); static void ( APIENTRY * dllTexImage2D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); static void ( APIENTRY * dllTexParameterf )(GLenum target, GLenum pname, GLfloat param); static void ( APIENTRY * dllTexParameterfv )(GLenum target, GLenum pname, const GLfloat *params); static void ( APIENTRY * dllTexParameteri )(GLenum target, GLenum pname, GLint param); static void ( APIENTRY * dllTexParameteriv )(GLenum target, GLenum pname, const GLint *params); static void ( APIENTRY * dllTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); static void ( APIENTRY * dllTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); static void ( APIENTRY * dllTranslated )(GLdouble x, GLdouble y, GLdouble z); static void ( APIENTRY * dllTranslatef )(GLfloat x, GLfloat y, GLfloat z); static void ( APIENTRY * dllVertex2d )(GLdouble x, GLdouble y); static void ( APIENTRY * dllVertex2dv )(const GLdouble *v); static void ( APIENTRY * dllVertex2f )(GLfloat x, GLfloat y); static void ( APIENTRY * dllVertex2fv )(const GLfloat *v); static void ( APIENTRY * dllVertex2i )(GLint x, GLint y); static void ( APIENTRY * dllVertex2iv )(const GLint *v); static void ( APIENTRY * dllVertex2s )(GLshort x, GLshort y); static void ( APIENTRY * dllVertex2sv )(const GLshort *v); static void ( APIENTRY * dllVertex3d )(GLdouble x, GLdouble y, GLdouble z); static void ( APIENTRY * dllVertex3dv )(const GLdouble *v); static void ( APIENTRY * dllVertex3f )(GLfloat x, GLfloat y, GLfloat z); static void ( APIENTRY * dllVertex3fv )(const GLfloat *v); static void ( APIENTRY * dllVertex3i )(GLint x, GLint y, GLint z); static void ( APIENTRY * dllVertex3iv )(const GLint *v); static void ( APIENTRY * dllVertex3s )(GLshort x, GLshort y, GLshort z); static void ( APIENTRY * dllVertex3sv )(const GLshort *v); static void ( APIENTRY * dllVertex4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w); static void ( APIENTRY * dllVertex4dv )(const GLdouble *v); static void ( APIENTRY * dllVertex4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w); static void ( APIENTRY * dllVertex4fv )(const GLfloat *v); static void ( APIENTRY * dllVertex4i )(GLint x, GLint y, GLint z, GLint w); static void ( APIENTRY * dllVertex4iv )(const GLint *v); static void ( APIENTRY * dllVertex4s )(GLshort x, GLshort y, GLshort z, GLshort w); static void ( APIENTRY * dllVertex4sv )(const GLshort *v); static void ( APIENTRY * dllVertexPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); static void ( APIENTRY * dllViewport )(GLint x, GLint y, GLsizei width, GLsizei height); static void APIENTRY logAccum(GLenum op, GLfloat value) { fprintf( glw_state.log_fp, "glAccum\n" ); dllAccum( op, value ); } static void APIENTRY logAlphaFunc(GLenum func, GLclampf ref) { fprintf( glw_state.log_fp, "glAlphaFunc( 0x%x, %f )\n", func, ref ); dllAlphaFunc( func, ref ); } static GLboolean APIENTRY logAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences) { fprintf( glw_state.log_fp, "glAreTexturesResident\n" ); return dllAreTexturesResident( n, textures, residences ); } static void APIENTRY logArrayElement(GLint i) { fprintf( glw_state.log_fp, "glArrayElement\n" ); dllArrayElement( i ); } static void APIENTRY logBegin(GLenum mode) { fprintf( glw_state.log_fp, "glBegin( 0x%x )\n", mode ); dllBegin( mode ); } static void APIENTRY logBindTexture(GLenum target, GLuint texture) { fprintf( glw_state.log_fp, "glBindTexture( 0x%x, %u )\n", target, texture ); dllBindTexture( target, texture ); } static void APIENTRY logBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap) { fprintf( glw_state.log_fp, "glBitmap\n" ); dllBitmap( width, height, xorig, yorig, xmove, ymove, bitmap ); } static void APIENTRY logBlendFunc(GLenum sfactor, GLenum dfactor) { fprintf( glw_state.log_fp, "glBlendFunc( 0x%x, 0x%x )\n", sfactor, dfactor ); dllBlendFunc( sfactor, dfactor ); } static void APIENTRY logCallList(GLuint list) { fprintf( glw_state.log_fp, "glCallList( %u )\n", list ); dllCallList( list ); } static void APIENTRY logCallLists(GLsizei n, GLenum type, const void *lists) { fprintf( glw_state.log_fp, "glCallLists\n" ); dllCallLists( n, type, lists ); } static void APIENTRY logClear(GLbitfield mask) { fprintf( glw_state.log_fp, "glClear\n" ); dllClear( mask ); } static void APIENTRY logClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { fprintf( glw_state.log_fp, "glClearAccum\n" ); dllClearAccum( red, green, blue, alpha ); } static void APIENTRY logClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { fprintf( glw_state.log_fp, "glClearColor\n" ); dllClearColor( red, green, blue, alpha ); } static void APIENTRY logClearDepth(GLclampd depth) { fprintf( glw_state.log_fp, "glClearDepth\n" ); dllClearDepth( depth ); } static void APIENTRY logClearIndex(GLfloat c) { fprintf( glw_state.log_fp, "glClearIndex\n" ); dllClearIndex( c ); } static void APIENTRY logClearStencil(GLint s) { fprintf( glw_state.log_fp, "glClearStencil\n" ); dllClearStencil( s ); } static void APIENTRY logClipPlane(GLenum plane, const GLdouble *equation) { fprintf( glw_state.log_fp, "glClipPlane\n" ); dllClipPlane( plane, equation ); } static void APIENTRY logColor3b(GLbyte red, GLbyte green, GLbyte blue) { fprintf( glw_state.log_fp, "glColor3b\n" ); dllColor3b( red, green, blue ); } static void APIENTRY logColor3bv(const GLbyte *v) { fprintf( glw_state.log_fp, "glColor3bv\n" ); dllColor3bv( v ); } static void APIENTRY logColor3d(GLdouble red, GLdouble green, GLdouble blue) { fprintf( glw_state.log_fp, "glColor3d\n" ); dllColor3d( red, green, blue ); } static void APIENTRY logColor3dv(const GLdouble *v) { fprintf( glw_state.log_fp, "glColor3dv\n" ); dllColor3dv( v ); } static void APIENTRY logColor3f(GLfloat red, GLfloat green, GLfloat blue) { fprintf( glw_state.log_fp, "glColor3f\n" ); dllColor3f( red, green, blue ); } static void APIENTRY logColor3fv(const GLfloat *v) { fprintf( glw_state.log_fp, "glColor3fv\n" ); dllColor3fv( v ); } static void APIENTRY logColor3i(GLint red, GLint green, GLint blue) { fprintf( glw_state.log_fp, "glColor3i\n" ); dllColor3i( red, green, blue ); } static void APIENTRY logColor3iv(const GLint *v) { fprintf( glw_state.log_fp, "glColor3iv\n" ); dllColor3iv( v ); } static void APIENTRY logColor3s(GLshort red, GLshort green, GLshort blue) { fprintf( glw_state.log_fp, "glColor3s\n" ); dllColor3s( red, green, blue ); } static void APIENTRY logColor3sv(const GLshort *v) { fprintf( glw_state.log_fp, "glColor3sv\n" ); dllColor3sv( v ); } static void APIENTRY logColor3ub(GLubyte red, GLubyte green, GLubyte blue) { fprintf( glw_state.log_fp, "glColor3ub\n" ); dllColor3ub( red, green, blue ); } static void APIENTRY logColor3ubv(const GLubyte *v) { fprintf( glw_state.log_fp, "glColor3ubv\n" ); dllColor3ubv( v ); } #define SIG( x ) fprintf( glw_state.log_fp, x "\n" ) static void APIENTRY logColor3ui(GLuint red, GLuint green, GLuint blue) { SIG( "glColor3ui" ); dllColor3ui( red, green, blue ); } static void APIENTRY logColor3uiv(const GLuint *v) { SIG( "glColor3uiv" ); dllColor3uiv( v ); } static void APIENTRY logColor3us(GLushort red, GLushort green, GLushort blue) { SIG( "glColor3us" ); dllColor3us( red, green, blue ); } static void APIENTRY logColor3usv(const GLushort *v) { SIG( "glColor3usv" ); dllColor3usv( v ); } static void APIENTRY logColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha) { SIG( "glColor4b" ); dllColor4b( red, green, blue, alpha ); } static void APIENTRY logColor4bv(const GLbyte *v) { SIG( "glColor4bv" ); dllColor4bv( v ); } static void APIENTRY logColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha) { SIG( "glColor4d" ); dllColor4d( red, green, blue, alpha ); } static void APIENTRY logColor4dv(const GLdouble *v) { SIG( "glColor4dv" ); dllColor4dv( v ); } static void APIENTRY logColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { fprintf( glw_state.log_fp, "glColor4f( %f,%f,%f,%f )\n", red, green, blue, alpha ); dllColor4f( red, green, blue, alpha ); } static void APIENTRY logColor4fv(const GLfloat *v) { fprintf( glw_state.log_fp, "glColor4fv( %f,%f,%f,%f )\n", v[0], v[1], v[2], v[3] ); dllColor4fv( v ); } static void APIENTRY logColor4i(GLint red, GLint green, GLint blue, GLint alpha) { SIG( "glColor4i" ); dllColor4i( red, green, blue, alpha ); } static void APIENTRY logColor4iv(const GLint *v) { SIG( "glColor4iv" ); dllColor4iv( v ); } static void APIENTRY logColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha) { SIG( "glColor4s" ); dllColor4s( red, green, blue, alpha ); } static void APIENTRY logColor4sv(const GLshort *v) { SIG( "glColor4sv" ); dllColor4sv( v ); } static void APIENTRY logColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) { SIG( "glColor4b" ); dllColor4b( red, green, blue, alpha ); } static void APIENTRY logColor4ubv(const GLubyte *v) { SIG( "glColor4ubv" ); dllColor4ubv( v ); } static void APIENTRY logColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha) { SIG( "glColor4ui" ); dllColor4ui( red, green, blue, alpha ); } static void APIENTRY logColor4uiv(const GLuint *v) { SIG( "glColor4uiv" ); dllColor4uiv( v ); } static void APIENTRY logColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha) { SIG( "glColor4us" ); dllColor4us( red, green, blue, alpha ); } static void APIENTRY logColor4usv(const GLushort *v) { SIG( "glColor4usv" ); dllColor4usv( v ); } static void APIENTRY logColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { SIG( "glColorMask" ); dllColorMask( red, green, blue, alpha ); } static void APIENTRY logColorMaterial(GLenum face, GLenum mode) { SIG( "glColorMaterial" ); dllColorMaterial( face, mode ); } static void APIENTRY logColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) { SIG( "glColorPointer" ); dllColorPointer( size, type, stride, pointer ); } static void APIENTRY logCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type) { SIG( "glCopyPixels" ); dllCopyPixels( x, y, width, height, type ); } static void APIENTRY logCopyTexImage1D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border) { SIG( "glCopyTexImage1D" ); dllCopyTexImage1D( target, level, internalFormat, x, y, width, border ); } static void APIENTRY logCopyTexImage2D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { SIG( "glCopyTexImage2D" ); dllCopyTexImage2D( target, level, internalFormat, x, y, width, height, border ); } static void APIENTRY logCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) { SIG( "glCopyTexSubImage1D" ); dllCopyTexSubImage1D( target, level, xoffset, x, y, width ); } static void APIENTRY logCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { SIG( "glCopyTexSubImage2D" ); dllCopyTexSubImage2D( target, level, xoffset, yoffset, x, y, width, height ); } static void APIENTRY logCullFace(GLenum mode) { SIG( "glCullFace" ); dllCullFace( mode ); } static void APIENTRY logDeleteLists(GLuint list, GLsizei range) { SIG( "glDeleteLists" ); dllDeleteLists( list, range ); } static void APIENTRY logDeleteTextures(GLsizei n, const GLuint *textures) { SIG( "glDeleteTextures" ); dllDeleteTextures( n, textures ); } static void APIENTRY logDepthFunc(GLenum func) { SIG( "glDepthFunc" ); dllDepthFunc( func ); } static void APIENTRY logDepthMask(GLboolean flag) { SIG( "glDepthMask" ); dllDepthMask( flag ); } static void APIENTRY logDepthRange(GLclampd zNear, GLclampd zFar) { SIG( "glDepthRange" ); dllDepthRange( zNear, zFar ); } static void APIENTRY logDisable(GLenum cap) { fprintf( glw_state.log_fp, "glDisable( 0x%x )\n", cap ); dllDisable( cap ); } static void APIENTRY logDisableClientState(GLenum array) { SIG( "glDisableClientState" ); dllDisableClientState( array ); } static void APIENTRY logDrawArrays(GLenum mode, GLint first, GLsizei count) { SIG( "glDrawArrays" ); dllDrawArrays( mode, first, count ); } static void APIENTRY logDrawBuffer(GLenum mode) { SIG( "glDrawBuffer" ); dllDrawBuffer( mode ); } static void APIENTRY logDrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) { SIG( "glDrawElements" ); dllDrawElements( mode, count, type, indices ); } static void APIENTRY logDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) { SIG( "glDrawPixels" ); dllDrawPixels( width, height, format, type, pixels ); } static void APIENTRY logEdgeFlag(GLboolean flag) { SIG( "glEdgeFlag" ); dllEdgeFlag( flag ); } static void APIENTRY logEdgeFlagPointer(GLsizei stride, const void *pointer) { SIG( "glEdgeFlagPointer" ); dllEdgeFlagPointer( stride, pointer ); } static void APIENTRY logEdgeFlagv(const GLboolean *flag) { SIG( "glEdgeFlagv" ); dllEdgeFlagv( flag ); } static void APIENTRY logEnable(GLenum cap) { fprintf( glw_state.log_fp, "glEnable( 0x%x )\n", cap ); dllEnable( cap ); } static void APIENTRY logEnableClientState(GLenum array) { SIG( "glEnableClientState" ); dllEnableClientState( array ); } static void APIENTRY logEnd(void) { SIG( "glEnd" ); dllEnd(); } static void APIENTRY logEndList(void) { SIG( "glEndList" ); dllEndList(); } static void APIENTRY logEvalCoord1d(GLdouble u) { SIG( "glEvalCoord1d" ); dllEvalCoord1d( u ); } static void APIENTRY logEvalCoord1dv(const GLdouble *u) { SIG( "glEvalCoord1dv" ); dllEvalCoord1dv( u ); } static void APIENTRY logEvalCoord1f(GLfloat u) { SIG( "glEvalCoord1f" ); dllEvalCoord1f( u ); } static void APIENTRY logEvalCoord1fv(const GLfloat *u) { SIG( "glEvalCoord1fv" ); dllEvalCoord1fv( u ); } static void APIENTRY logEvalCoord2d(GLdouble u, GLdouble v) { SIG( "glEvalCoord2d" ); dllEvalCoord2d( u, v ); } static void APIENTRY logEvalCoord2dv(const GLdouble *u) { SIG( "glEvalCoord2dv" ); dllEvalCoord2dv( u ); } static void APIENTRY logEvalCoord2f(GLfloat u, GLfloat v) { SIG( "glEvalCoord2f" ); dllEvalCoord2f( u, v ); } static void APIENTRY logEvalCoord2fv(const GLfloat *u) { SIG( "glEvalCoord2fv" ); dllEvalCoord2fv( u ); } static void APIENTRY logEvalMesh1(GLenum mode, GLint i1, GLint i2) { SIG( "glEvalMesh1" ); dllEvalMesh1( mode, i1, i2 ); } static void APIENTRY logEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) { SIG( "glEvalMesh2" ); dllEvalMesh2( mode, i1, i2, j1, j2 ); } static void APIENTRY logEvalPoint1(GLint i) { SIG( "glEvalPoint1" ); dllEvalPoint1( i ); } static void APIENTRY logEvalPoint2(GLint i, GLint j) { SIG( "glEvalPoint2" ); dllEvalPoint2( i, j ); } static void APIENTRY logFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer) { SIG( "glFeedbackBuffer" ); dllFeedbackBuffer( size, type, buffer ); } static void APIENTRY logFinish(void) { SIG( "glFinish" ); dllFinish(); } static void APIENTRY logFlush(void) { SIG( "glFlush" ); dllFlush(); } static void APIENTRY logFogf(GLenum pname, GLfloat param) { SIG( "glFogf" ); dllFogf( pname, param ); } static void APIENTRY logFogfv(GLenum pname, const GLfloat *params) { SIG( "glFogfv" ); dllFogfv( pname, params ); } static void APIENTRY logFogi(GLenum pname, GLint param) { SIG( "glFogi" ); dllFogi( pname, param ); } static void APIENTRY logFogiv(GLenum pname, const GLint *params) { SIG( "glFogiv" ); dllFogiv( pname, params ); } static void APIENTRY logFrontFace(GLenum mode) { SIG( "glFrontFace" ); dllFrontFace( mode ); } static void APIENTRY logFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) { SIG( "glFrustum" ); dllFrustum( left, right, bottom, top, zNear, zFar ); } static GLuint APIENTRY logGenLists(GLsizei range) { SIG( "glGenLists" ); return dllGenLists( range ); } static void APIENTRY logGenTextures(GLsizei n, GLuint *textures) { SIG( "glGenTextures" ); dllGenTextures( n, textures ); } static void APIENTRY logGetBooleanv(GLenum pname, GLboolean *params) { SIG( "glGetBooleanv" ); dllGetBooleanv( pname, params ); } static void APIENTRY logGetClipPlane(GLenum plane, GLdouble *equation) { SIG( "glGetClipPlane" ); dllGetClipPlane( plane, equation ); } static void APIENTRY logGetDoublev(GLenum pname, GLdouble *params) { SIG( "glGetDoublev" ); dllGetDoublev( pname, params ); } static GLenum APIENTRY logGetError(void) { SIG( "glGetError" ); return dllGetError(); } static void APIENTRY logGetFloatv(GLenum pname, GLfloat *params) { SIG( "glGetFloatv" ); dllGetFloatv( pname, params ); } static void APIENTRY logGetIntegerv(GLenum pname, GLint *params) { SIG( "glGetIntegerv" ); dllGetIntegerv( pname, params ); } static void APIENTRY logGetLightfv(GLenum light, GLenum pname, GLfloat *params) { SIG( "glGetLightfv" ); dllGetLightfv( light, pname, params ); } static void APIENTRY logGetLightiv(GLenum light, GLenum pname, GLint *params) { SIG( "glGetLightiv" ); dllGetLightiv( light, pname, params ); } static void APIENTRY logGetMapdv(GLenum target, GLenum query, GLdouble *v) { SIG( "glGetMapdv" ); dllGetMapdv( target, query, v ); } static void APIENTRY logGetMapfv(GLenum target, GLenum query, GLfloat *v) { SIG( "glGetMapfv" ); dllGetMapfv( target, query, v ); } static void APIENTRY logGetMapiv(GLenum target, GLenum query, GLint *v) { SIG( "glGetMapiv" ); dllGetMapiv( target, query, v ); } static void APIENTRY logGetMaterialfv(GLenum face, GLenum pname, GLfloat *params) { SIG( "glGetMaterialfv" ); dllGetMaterialfv( face, pname, params ); } static void APIENTRY logGetMaterialiv(GLenum face, GLenum pname, GLint *params) { SIG( "glGetMaterialiv" ); dllGetMaterialiv( face, pname, params ); } static void APIENTRY logGetPixelMapfv(GLenum map, GLfloat *values) { SIG( "glGetPixelMapfv" ); dllGetPixelMapfv( map, values ); } static void APIENTRY logGetPixelMapuiv(GLenum map, GLuint *values) { SIG( "glGetPixelMapuiv" ); dllGetPixelMapuiv( map, values ); } static void APIENTRY logGetPixelMapusv(GLenum map, GLushort *values) { SIG( "glGetPixelMapusv" ); dllGetPixelMapusv( map, values ); } static void APIENTRY logGetPointerv(GLenum pname, GLvoid* *params) { SIG( "glGetPointerv" ); dllGetPointerv( pname, params ); } static void APIENTRY logGetPolygonStipple(GLubyte *mask) { SIG( "glGetPolygonStipple" ); dllGetPolygonStipple( mask ); } static const GLubyte * APIENTRY logGetString(GLenum name) { SIG( "glGetString" ); return dllGetString( name ); } static void APIENTRY logGetTexEnvfv(GLenum target, GLenum pname, GLfloat *params) { SIG( "glGetTexEnvfv" ); dllGetTexEnvfv( target, pname, params ); } static void APIENTRY logGetTexEnviv(GLenum target, GLenum pname, GLint *params) { SIG( "glGetTexEnviv" ); dllGetTexEnviv( target, pname, params ); } static void APIENTRY logGetTexGendv(GLenum coord, GLenum pname, GLdouble *params) { SIG( "glGetTexGendv" ); dllGetTexGendv( coord, pname, params ); } static void APIENTRY logGetTexGenfv(GLenum coord, GLenum pname, GLfloat *params) { SIG( "glGetTexGenfv" ); dllGetTexGenfv( coord, pname, params ); } static void APIENTRY logGetTexGeniv(GLenum coord, GLenum pname, GLint *params) { SIG( "glGetTexGeniv" ); dllGetTexGeniv( coord, pname, params ); } static void APIENTRY logGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, void *pixels) { SIG( "glGetTexImage" ); dllGetTexImage( target, level, format, type, pixels ); } static void APIENTRY logGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params ) { SIG( "glGetTexLevelParameterfv" ); dllGetTexLevelParameterfv( target, level, pname, params ); } static void APIENTRY logGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) { SIG( "glGetTexLevelParameteriv" ); dllGetTexLevelParameteriv( target, level, pname, params ); } static void APIENTRY logGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params) { SIG( "glGetTexParameterfv" ); dllGetTexParameterfv( target, pname, params ); } static void APIENTRY logGetTexParameteriv(GLenum target, GLenum pname, GLint *params) { SIG( "glGetTexParameteriv" ); dllGetTexParameteriv( target, pname, params ); } static void APIENTRY logHint(GLenum target, GLenum mode) { fprintf( glw_state.log_fp, "glHint( 0x%x, 0x%x )\n", target, mode ); dllHint( target, mode ); } static void APIENTRY logIndexMask(GLuint mask) { SIG( "glIndexMask" ); dllIndexMask( mask ); } static void APIENTRY logIndexPointer(GLenum type, GLsizei stride, const void *pointer) { SIG( "glIndexPointer" ); dllIndexPointer( type, stride, pointer ); } static void APIENTRY logIndexd(GLdouble c) { SIG( "glIndexd" ); dllIndexd( c ); } static void APIENTRY logIndexdv(const GLdouble *c) { SIG( "glIndexdv" ); dllIndexdv( c ); } static void APIENTRY logIndexf(GLfloat c) { SIG( "glIndexf" ); dllIndexf( c ); } static void APIENTRY logIndexfv(const GLfloat *c) { SIG( "glIndexfv" ); dllIndexfv( c ); } static void APIENTRY logIndexi(GLint c) { SIG( "glIndexi" ); dllIndexi( c ); } static void APIENTRY logIndexiv(const GLint *c) { SIG( "glIndexiv" ); dllIndexiv( c ); } static void APIENTRY logIndexs(GLshort c) { SIG( "glIndexs" ); dllIndexs( c ); } static void APIENTRY logIndexsv(const GLshort *c) { SIG( "glIndexsv" ); dllIndexsv( c ); } static void APIENTRY logIndexub(GLubyte c) { SIG( "glIndexub" ); dllIndexub( c ); } static void APIENTRY logIndexubv(const GLubyte *c) { SIG( "glIndexubv" ); dllIndexubv( c ); } static void APIENTRY logInitNames(void) { SIG( "glInitNames" ); dllInitNames(); } static void APIENTRY logInterleavedArrays(GLenum format, GLsizei stride, const void *pointer) { SIG( "glInterleavedArrays" ); dllInterleavedArrays( format, stride, pointer ); } static GLboolean APIENTRY logIsEnabled(GLenum cap) { SIG( "glIsEnabled" ); return dllIsEnabled( cap ); } static GLboolean APIENTRY logIsList(GLuint list) { SIG( "glIsList" ); return dllIsList( list ); } static GLboolean APIENTRY logIsTexture(GLuint texture) { SIG( "glIsTexture" ); return dllIsTexture( texture ); } static void APIENTRY logLightModelf(GLenum pname, GLfloat param) { SIG( "glLightModelf" ); dllLightModelf( pname, param ); } static void APIENTRY logLightModelfv(GLenum pname, const GLfloat *params) { SIG( "glLightModelfv" ); dllLightModelfv( pname, params ); } static void APIENTRY logLightModeli(GLenum pname, GLint param) { SIG( "glLightModeli" ); dllLightModeli( pname, param ); } static void APIENTRY logLightModeliv(GLenum pname, const GLint *params) { SIG( "glLightModeliv" ); dllLightModeliv( pname, params ); } static void APIENTRY logLightf(GLenum light, GLenum pname, GLfloat param) { SIG( "glLightf" ); dllLightf( light, pname, param ); } static void APIENTRY logLightfv(GLenum light, GLenum pname, const GLfloat *params) { SIG( "glLightfv" ); dllLightfv( light, pname, params ); } static void APIENTRY logLighti(GLenum light, GLenum pname, GLint param) { SIG( "glLighti" ); dllLighti( light, pname, param ); } static void APIENTRY logLightiv(GLenum light, GLenum pname, const GLint *params) { SIG( "glLightiv" ); dllLightiv( light, pname, params ); } static void APIENTRY logLineStipple(GLint factor, GLushort pattern) { SIG( "glLineStipple" ); dllLineStipple( factor, pattern ); } static void APIENTRY logLineWidth(GLfloat width) { SIG( "glLineWidth" ); dllLineWidth( width ); } static void APIENTRY logListBase(GLuint base) { SIG( "glListBase" ); dllListBase( base ); } static void APIENTRY logLoadIdentity(void) { SIG( "glLoadIdentity" ); dllLoadIdentity(); } static void APIENTRY logLoadMatrixd(const GLdouble *m) { SIG( "glLoadMatrixd" ); dllLoadMatrixd( m ); } static void APIENTRY logLoadMatrixf(const GLfloat *m) { SIG( "glLoadMatrixf" ); dllLoadMatrixf( m ); } static void APIENTRY logLoadName(GLuint name) { SIG( "glLoadName" ); dllLoadName( name ); } static void APIENTRY logLogicOp(GLenum opcode) { SIG( "glLogicOp" ); dllLogicOp( opcode ); } static void APIENTRY logMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points) { SIG( "glMap1d" ); dllMap1d( target, u1, u2, stride, order, points ); } static void APIENTRY logMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points) { SIG( "glMap1f" ); dllMap1f( target, u1, u2, stride, order, points ); } static void APIENTRY logMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points) { SIG( "glMap2d" ); dllMap2d( target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points ); } static void APIENTRY logMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points) { SIG( "glMap2f" ); dllMap2f( target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points ); } static void APIENTRY logMapGrid1d(GLint un, GLdouble u1, GLdouble u2) { SIG( "glMapGrid1d" ); dllMapGrid1d( un, u1, u2 ); } static void APIENTRY logMapGrid1f(GLint un, GLfloat u1, GLfloat u2) { SIG( "glMapGrid1f" ); dllMapGrid1f( un, u1, u2 ); } static void APIENTRY logMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2) { SIG( "glMapGrid2d" ); dllMapGrid2d( un, u1, u2, vn, v1, v2 ); } static void APIENTRY logMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2) { SIG( "glMapGrid2f" ); dllMapGrid2f( un, u1, u2, vn, v1, v2 ); } static void APIENTRY logMaterialf(GLenum face, GLenum pname, GLfloat param) { SIG( "glMaterialf" ); dllMaterialf( face, pname, param ); } static void APIENTRY logMaterialfv(GLenum face, GLenum pname, const GLfloat *params) { SIG( "glMaterialfv" ); dllMaterialfv( face, pname, params ); } static void APIENTRY logMateriali(GLenum face, GLenum pname, GLint param) { SIG( "glMateriali" ); dllMateriali( face, pname, param ); } static void APIENTRY logMaterialiv(GLenum face, GLenum pname, const GLint *params) { SIG( "glMaterialiv" ); dllMaterialiv( face, pname, params ); } static void APIENTRY logMatrixMode(GLenum mode) { SIG( "glMatrixMode" ); dllMatrixMode( mode ); } static void APIENTRY logMultMatrixd(const GLdouble *m) { SIG( "glMultMatrixd" ); dllMultMatrixd( m ); } static void APIENTRY logMultMatrixf(const GLfloat *m) { SIG( "glMultMatrixf" ); dllMultMatrixf( m ); } static void APIENTRY logNewList(GLuint list, GLenum mode) { SIG( "glNewList" ); dllNewList( list, mode ); } static void APIENTRY logNormal3b(GLbyte nx, GLbyte ny, GLbyte nz) { SIG ("glNormal3b" ); dllNormal3b( nx, ny, nz ); } static void APIENTRY logNormal3bv(const GLbyte *v) { SIG( "glNormal3bv" ); dllNormal3bv( v ); } static void APIENTRY logNormal3d(GLdouble nx, GLdouble ny, GLdouble nz) { SIG( "glNormal3d" ); dllNormal3d( nx, ny, nz ); } static void APIENTRY logNormal3dv(const GLdouble *v) { SIG( "glNormal3dv" ); dllNormal3dv( v ); } static void APIENTRY logNormal3f(GLfloat nx, GLfloat ny, GLfloat nz) { SIG( "glNormal3f" ); dllNormal3f( nx, ny, nz ); } static void APIENTRY logNormal3fv(const GLfloat *v) { SIG( "glNormal3fv" ); dllNormal3fv( v ); } static void APIENTRY logNormal3i(GLint nx, GLint ny, GLint nz) { SIG( "glNormal3i" ); dllNormal3i( nx, ny, nz ); } static void APIENTRY logNormal3iv(const GLint *v) { SIG( "glNormal3iv" ); dllNormal3iv( v ); } static void APIENTRY logNormal3s(GLshort nx, GLshort ny, GLshort nz) { SIG( "glNormal3s" ); dllNormal3s( nx, ny, nz ); } static void APIENTRY logNormal3sv(const GLshort *v) { SIG( "glNormal3sv" ); dllNormal3sv( v ); } static void APIENTRY logNormalPointer(GLenum type, GLsizei stride, const void *pointer) { SIG( "glNormalPointer" ); dllNormalPointer( type, stride, pointer ); } static void APIENTRY logOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) { SIG( "glOrtho" ); dllOrtho( left, right, bottom, top, zNear, zFar ); } static void APIENTRY logPassThrough(GLfloat token) { SIG( "glPassThrough" ); dllPassThrough( token ); } static void APIENTRY logPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat *values) { SIG( "glPixelMapfv" ); dllPixelMapfv( map, mapsize, values ); } static void APIENTRY logPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values) { SIG( "glPixelMapuiv" ); dllPixelMapuiv( map, mapsize, values ); } static void APIENTRY logPixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values) { SIG( "glPixelMapusv" ); dllPixelMapusv( map, mapsize, values ); } static void APIENTRY logPixelStoref(GLenum pname, GLfloat param) { SIG( "glPixelStoref" ); dllPixelStoref( pname, param ); } static void APIENTRY logPixelStorei(GLenum pname, GLint param) { SIG( "glPixelStorei" ); dllPixelStorei( pname, param ); } static void APIENTRY logPixelTransferf(GLenum pname, GLfloat param) { SIG( "glPixelTransferf" ); dllPixelTransferf( pname, param ); } static void APIENTRY logPixelTransferi(GLenum pname, GLint param) { SIG( "glPixelTransferi" ); dllPixelTransferi( pname, param ); } static void APIENTRY logPixelZoom(GLfloat xfactor, GLfloat yfactor) { SIG( "glPixelZoom" ); dllPixelZoom( xfactor, yfactor ); } static void APIENTRY logPointSize(GLfloat size) { SIG( "glPointSize" ); dllPointSize( size ); } static void APIENTRY logPolygonMode(GLenum face, GLenum mode) { fprintf( glw_state.log_fp, "glPolygonMode( 0x%x, 0x%x )\n", face, mode ); dllPolygonMode( face, mode ); } static void APIENTRY logPolygonOffset(GLfloat factor, GLfloat units) { SIG( "glPolygonOffset" ); dllPolygonOffset( factor, units ); } static void APIENTRY logPolygonStipple(const GLubyte *mask ) { SIG( "glPolygonStipple" ); dllPolygonStipple( mask ); } static void APIENTRY logPopAttrib(void) { SIG( "glPopAttrib" ); dllPopAttrib(); } static void APIENTRY logPopClientAttrib(void) { SIG( "glPopClientAttrib" ); dllPopClientAttrib(); } static void APIENTRY logPopMatrix(void) { SIG( "glPopMatrix" ); dllPopMatrix(); } static void APIENTRY logPopName(void) { SIG( "glPopName" ); dllPopName(); } static void APIENTRY logPrioritizeTextures(GLsizei n, const GLuint *textures, const GLclampf *priorities) { SIG( "glPrioritizeTextures" ); dllPrioritizeTextures( n, textures, priorities ); } static void APIENTRY logPushAttrib(GLbitfield mask) { SIG( "glPushAttrib" ); dllPushAttrib( mask ); } static void APIENTRY logPushClientAttrib(GLbitfield mask) { SIG( "glPushClientAttrib" ); dllPushClientAttrib( mask ); } static void APIENTRY logPushMatrix(void) { SIG( "glPushMatrix" ); dllPushMatrix(); } static void APIENTRY logPushName(GLuint name) { SIG( "glPushName" ); dllPushName( name ); } static void APIENTRY logRasterPos2d(GLdouble x, GLdouble y) { SIG ("glRasterPot2d" ); dllRasterPos2d( x, y ); } static void APIENTRY logRasterPos2dv(const GLdouble *v) { SIG( "glRasterPos2dv" ); dllRasterPos2dv( v ); } static void APIENTRY logRasterPos2f(GLfloat x, GLfloat y) { SIG( "glRasterPos2f" ); dllRasterPos2f( x, y ); } static void APIENTRY logRasterPos2fv(const GLfloat *v) { SIG( "glRasterPos2dv" ); dllRasterPos2fv( v ); } static void APIENTRY logRasterPos2i(GLint x, GLint y) { SIG( "glRasterPos2if" ); dllRasterPos2i( x, y ); } static void APIENTRY logRasterPos2iv(const GLint *v) { SIG( "glRasterPos2iv" ); dllRasterPos2iv( v ); } static void APIENTRY logRasterPos2s(GLshort x, GLshort y) { SIG( "glRasterPos2s" ); dllRasterPos2s( x, y ); } static void APIENTRY logRasterPos2sv(const GLshort *v) { SIG( "glRasterPos2sv" ); dllRasterPos2sv( v ); } static void APIENTRY logRasterPos3d(GLdouble x, GLdouble y, GLdouble z) { SIG( "glRasterPos3d" ); dllRasterPos3d( x, y, z ); } static void APIENTRY logRasterPos3dv(const GLdouble *v) { SIG( "glRasterPos3dv" ); dllRasterPos3dv( v ); } static void APIENTRY logRasterPos3f(GLfloat x, GLfloat y, GLfloat z) { SIG( "glRasterPos3f" ); dllRasterPos3f( x, y, z ); } static void APIENTRY logRasterPos3fv(const GLfloat *v) { SIG( "glRasterPos3fv" ); dllRasterPos3fv( v ); } static void APIENTRY logRasterPos3i(GLint x, GLint y, GLint z) { SIG( "glRasterPos3i" ); dllRasterPos3i( x, y, z ); } static void APIENTRY logRasterPos3iv(const GLint *v) { SIG( "glRasterPos3iv" ); dllRasterPos3iv( v ); } static void APIENTRY logRasterPos3s(GLshort x, GLshort y, GLshort z) { SIG( "glRasterPos3s" ); dllRasterPos3s( x, y, z ); } static void APIENTRY logRasterPos3sv(const GLshort *v) { SIG( "glRasterPos3sv" ); dllRasterPos3sv( v ); } static void APIENTRY logRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w) { SIG( "glRasterPos4d" ); dllRasterPos4d( x, y, z, w ); } static void APIENTRY logRasterPos4dv(const GLdouble *v) { SIG( "glRasterPos4dv" ); dllRasterPos4dv( v ); } static void APIENTRY logRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) { SIG( "glRasterPos4f" ); dllRasterPos4f( x, y, z, w ); } static void APIENTRY logRasterPos4fv(const GLfloat *v) { SIG( "glRasterPos4fv" ); dllRasterPos4fv( v ); } static void APIENTRY logRasterPos4i(GLint x, GLint y, GLint z, GLint w) { SIG( "glRasterPos4i" ); dllRasterPos4i( x, y, z, w ); } static void APIENTRY logRasterPos4iv(const GLint *v) { SIG( "glRasterPos4iv" ); dllRasterPos4iv( v ); } static void APIENTRY logRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w) { SIG( "glRasterPos4s" ); dllRasterPos4s( x, y, z, w ); } static void APIENTRY logRasterPos4sv(const GLshort *v) { SIG( "glRasterPos4sv" ); dllRasterPos4sv( v ); } static void APIENTRY logReadBuffer(GLenum mode) { SIG( "glReadBuffer" ); dllReadBuffer( mode ); } static void APIENTRY logReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels) { SIG( "glReadPixels" ); dllReadPixels( x, y, width, height, format, type, pixels ); } static void APIENTRY logRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) { SIG( "glRectd" ); dllRectd( x1, y1, x2, y2 ); } static void APIENTRY logRectdv(const GLdouble *v1, const GLdouble *v2) { SIG( "glRectdv" ); dllRectdv( v1, v2 ); } static void APIENTRY logRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) { SIG( "glRectf" ); dllRectf( x1, y1, x2, y2 ); } static void APIENTRY logRectfv(const GLfloat *v1, const GLfloat *v2) { SIG( "glRectfv" ); dllRectfv( v1, v2 ); } static void APIENTRY logRecti(GLint x1, GLint y1, GLint x2, GLint y2) { SIG( "glRecti" ); dllRecti( x1, y1, x2, y2 ); } static void APIENTRY logRectiv(const GLint *v1, const GLint *v2) { SIG( "glRectiv" ); dllRectiv( v1, v2 ); } static void APIENTRY logRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2) { SIG( "glRects" ); dllRects( x1, y1, x2, y2 ); } static void APIENTRY logRectsv(const GLshort *v1, const GLshort *v2) { SIG( "glRectsv" ); dllRectsv( v1, v2 ); } static GLint APIENTRY logRenderMode(GLenum mode) { SIG( "glRenderMode" ); return dllRenderMode( mode ); } static void APIENTRY logRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) { SIG( "glRotated" ); dllRotated( angle, x, y, z ); } static void APIENTRY logRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { SIG( "glRotatef" ); dllRotatef( angle, x, y, z ); } static void APIENTRY logScaled(GLdouble x, GLdouble y, GLdouble z) { SIG( "glScaled" ); dllScaled( x, y, z ); } static void APIENTRY logScalef(GLfloat x, GLfloat y, GLfloat z) { SIG( "glScalef" ); dllScalef( x, y, z ); } static void APIENTRY logScissor(GLint x, GLint y, GLsizei width, GLsizei height) { SIG( "glScissor" ); dllScissor( x, y, width, height ); } static void APIENTRY logSelectBuffer(GLsizei size, GLuint *buffer) { SIG( "glSelectBuffer" ); dllSelectBuffer( size, buffer ); } static void APIENTRY logShadeModel(GLenum mode) { SIG( "glShadeModel" ); dllShadeModel( mode ); } static void APIENTRY logStencilFunc(GLenum func, GLint ref, GLuint mask) { SIG( "glStencilFunc" ); dllStencilFunc( func, ref, mask ); } static void APIENTRY logStencilMask(GLuint mask) { SIG( "glStencilMask" ); dllStencilMask( mask ); } static void APIENTRY logStencilOp(GLenum fail, GLenum zfail, GLenum zpass) { SIG( "glStencilOp" ); dllStencilOp( fail, zfail, zpass ); } static void APIENTRY logTexCoord1d(GLdouble s) { SIG( "glTexCoord1d" ); dllTexCoord1d( s ); } static void APIENTRY logTexCoord1dv(const GLdouble *v) { SIG( "glTexCoord1dv" ); dllTexCoord1dv( v ); } static void APIENTRY logTexCoord1f(GLfloat s) { SIG( "glTexCoord1f" ); dllTexCoord1f( s ); } static void APIENTRY logTexCoord1fv(const GLfloat *v) { SIG( "glTexCoord1fv" ); dllTexCoord1fv( v ); } static void APIENTRY logTexCoord1i(GLint s) { SIG( "glTexCoord1i" ); dllTexCoord1i( s ); } static void APIENTRY logTexCoord1iv(const GLint *v) { SIG( "glTexCoord1iv" ); dllTexCoord1iv( v ); } static void APIENTRY logTexCoord1s(GLshort s) { SIG( "glTexCoord1s" ); dllTexCoord1s( s ); } static void APIENTRY logTexCoord1sv(const GLshort *v) { SIG( "glTexCoord1sv" ); dllTexCoord1sv( v ); } static void APIENTRY logTexCoord2d(GLdouble s, GLdouble t) { SIG( "glTexCoord2d" ); dllTexCoord2d( s, t ); } static void APIENTRY logTexCoord2dv(const GLdouble *v) { SIG( "glTexCoord2dv" ); dllTexCoord2dv( v ); } static void APIENTRY logTexCoord2f(GLfloat s, GLfloat t) { SIG( "glTexCoord2f" ); dllTexCoord2f( s, t ); } static void APIENTRY logTexCoord2fv(const GLfloat *v) { SIG( "glTexCoord2fv" ); dllTexCoord2fv( v ); } static void APIENTRY logTexCoord2i(GLint s, GLint t) { SIG( "glTexCoord2i" ); dllTexCoord2i( s, t ); } static void APIENTRY logTexCoord2iv(const GLint *v) { SIG( "glTexCoord2iv" ); dllTexCoord2iv( v ); } static void APIENTRY logTexCoord2s(GLshort s, GLshort t) { SIG( "glTexCoord2s" ); dllTexCoord2s( s, t ); } static void APIENTRY logTexCoord2sv(const GLshort *v) { SIG( "glTexCoord2sv" ); dllTexCoord2sv( v ); } static void APIENTRY logTexCoord3d(GLdouble s, GLdouble t, GLdouble r) { SIG( "glTexCoord3d" ); dllTexCoord3d( s, t, r ); } static void APIENTRY logTexCoord3dv(const GLdouble *v) { SIG( "glTexCoord3dv" ); dllTexCoord3dv( v ); } static void APIENTRY logTexCoord3f(GLfloat s, GLfloat t, GLfloat r) { SIG( "glTexCoord3f" ); dllTexCoord3f( s, t, r ); } static void APIENTRY logTexCoord3fv(const GLfloat *v) { SIG( "glTexCoord3fv" ); dllTexCoord3fv( v ); } static void APIENTRY logTexCoord3i(GLint s, GLint t, GLint r) { SIG( "glTexCoord3i" ); dllTexCoord3i( s, t, r ); } static void APIENTRY logTexCoord3iv(const GLint *v) { SIG( "glTexCoord3iv" ); dllTexCoord3iv( v ); } static void APIENTRY logTexCoord3s(GLshort s, GLshort t, GLshort r) { SIG( "glTexCoord3s" ); dllTexCoord3s( s, t, r ); } static void APIENTRY logTexCoord3sv(const GLshort *v) { SIG( "glTexCoord3sv" ); dllTexCoord3sv( v ); } static void APIENTRY logTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q) { SIG( "glTexCoord4d" ); dllTexCoord4d( s, t, r, q ); } static void APIENTRY logTexCoord4dv(const GLdouble *v) { SIG( "glTexCoord4dv" ); dllTexCoord4dv( v ); } static void APIENTRY logTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q) { SIG( "glTexCoord4f" ); dllTexCoord4f( s, t, r, q ); } static void APIENTRY logTexCoord4fv(const GLfloat *v) { SIG( "glTexCoord4fv" ); dllTexCoord4fv( v ); } static void APIENTRY logTexCoord4i(GLint s, GLint t, GLint r, GLint q) { SIG( "glTexCoord4i" ); dllTexCoord4i( s, t, r, q ); } static void APIENTRY logTexCoord4iv(const GLint *v) { SIG( "glTexCoord4iv" ); dllTexCoord4iv( v ); } static void APIENTRY logTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q) { SIG( "glTexCoord4s" ); dllTexCoord4s( s, t, r, q ); } static void APIENTRY logTexCoord4sv(const GLshort *v) { SIG( "glTexCoord4sv" ); dllTexCoord4sv( v ); } static void APIENTRY logTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) { SIG( "glTexCoordPointer" ); dllTexCoordPointer( size, type, stride, pointer ); } static void APIENTRY logTexEnvf(GLenum target, GLenum pname, GLfloat param) { fprintf( glw_state.log_fp, "glTexEnvf( 0x%x, 0x%x, %f )\n", target, pname, param ); dllTexEnvf( target, pname, param ); } static void APIENTRY logTexEnvfv(GLenum target, GLenum pname, const GLfloat *params) { SIG( "glTexEnvfv" ); dllTexEnvfv( target, pname, params ); } static void APIENTRY logTexEnvi(GLenum target, GLenum pname, GLint param) { fprintf( glw_state.log_fp, "glTexEnvi( 0x%x, 0x%x, 0x%x )\n", target, pname, param ); dllTexEnvi( target, pname, param ); } static void APIENTRY logTexEnviv(GLenum target, GLenum pname, const GLint *params) { SIG( "glTexEnviv" ); dllTexEnviv( target, pname, params ); } static void APIENTRY logTexGend(GLenum coord, GLenum pname, GLdouble param) { SIG( "glTexGend" ); dllTexGend( coord, pname, param ); } static void APIENTRY logTexGendv(GLenum coord, GLenum pname, const GLdouble *params) { SIG( "glTexGendv" ); dllTexGendv( coord, pname, params ); } static void APIENTRY logTexGenf(GLenum coord, GLenum pname, GLfloat param) { SIG( "glTexGenf" ); dllTexGenf( coord, pname, param ); } static void APIENTRY logTexGenfv(GLenum coord, GLenum pname, const GLfloat *params) { SIG( "glTexGenfv" ); dllTexGenfv( coord, pname, params ); } static void APIENTRY logTexGeni(GLenum coord, GLenum pname, GLint param) { SIG( "glTexGeni" ); dllTexGeni( coord, pname, param ); } static void APIENTRY logTexGeniv(GLenum coord, GLenum pname, const GLint *params) { SIG( "glTexGeniv" ); dllTexGeniv( coord, pname, params ); } static void APIENTRY logTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels) { SIG( "glTexImage1D" ); dllTexImage1D( target, level, internalformat, width, border, format, type, pixels ); } static void APIENTRY logTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels) { SIG( "glTexImage2D" ); dllTexImage2D( target, level, internalformat, width, height, border, format, type, pixels ); } static void APIENTRY logTexParameterf(GLenum target, GLenum pname, GLfloat param) { fprintf( glw_state.log_fp, "glTexParameterf( 0x%x, 0x%x, %f )\n", target, pname, param ); dllTexParameterf( target, pname, param ); } static void APIENTRY logTexParameterfv(GLenum target, GLenum pname, const GLfloat *params) { SIG( "glTexParameterfv" ); dllTexParameterfv( target, pname, params ); } static void APIENTRY logTexParameteri(GLenum target, GLenum pname, GLint param) { fprintf( glw_state.log_fp, "glTexParameteri( 0x%x, 0x%x, 0x%x )\n", target, pname, param ); dllTexParameteri( target, pname, param ); } static void APIENTRY logTexParameteriv(GLenum target, GLenum pname, const GLint *params) { SIG( "glTexParameteriv" ); dllTexParameteriv( target, pname, params ); } static void APIENTRY logTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels) { SIG( "glTexSubImage1D" ); dllTexSubImage1D( target, level, xoffset, width, format, type, pixels ); } static void APIENTRY logTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) { SIG( "glTexSubImage2D" ); dllTexSubImage2D( target, level, xoffset, yoffset, width, height, format, type, pixels ); } static void APIENTRY logTranslated(GLdouble x, GLdouble y, GLdouble z) { SIG( "glTranslated" ); dllTranslated( x, y, z ); } static void APIENTRY logTranslatef(GLfloat x, GLfloat y, GLfloat z) { SIG( "glTranslatef" ); dllTranslatef( x, y, z ); } static void APIENTRY logVertex2d(GLdouble x, GLdouble y) { SIG( "glVertex2d" ); dllVertex2d( x, y ); } static void APIENTRY logVertex2dv(const GLdouble *v) { SIG( "glVertex2dv" ); dllVertex2dv( v ); } static void APIENTRY logVertex2f(GLfloat x, GLfloat y) { SIG( "glVertex2f" ); dllVertex2f( x, y ); } static void APIENTRY logVertex2fv(const GLfloat *v) { SIG( "glVertex2fv" ); dllVertex2fv( v ); } static void APIENTRY logVertex2i(GLint x, GLint y) { SIG( "glVertex2i" ); dllVertex2i( x, y ); } static void APIENTRY logVertex2iv(const GLint *v) { SIG( "glVertex2iv" ); dllVertex2iv( v ); } static void APIENTRY logVertex2s(GLshort x, GLshort y) { SIG( "glVertex2s" ); dllVertex2s( x, y ); } static void APIENTRY logVertex2sv(const GLshort *v) { SIG( "glVertex2sv" ); dllVertex2sv( v ); } static void APIENTRY logVertex3d(GLdouble x, GLdouble y, GLdouble z) { SIG( "glVertex3d" ); dllVertex3d( x, y, z ); } static void APIENTRY logVertex3dv(const GLdouble *v) { SIG( "glVertex3dv" ); dllVertex3dv( v ); } static void APIENTRY logVertex3f(GLfloat x, GLfloat y, GLfloat z) { SIG( "glVertex3f" ); dllVertex3f( x, y, z ); } static void APIENTRY logVertex3fv(const GLfloat *v) { SIG( "glVertex3fv" ); dllVertex3fv( v ); } static void APIENTRY logVertex3i(GLint x, GLint y, GLint z) { SIG( "glVertex3i" ); dllVertex3i( x, y, z ); } static void APIENTRY logVertex3iv(const GLint *v) { SIG( "glVertex3iv" ); dllVertex3iv( v ); } static void APIENTRY logVertex3s(GLshort x, GLshort y, GLshort z) { SIG( "glVertex3s" ); dllVertex3s( x, y, z ); } static void APIENTRY logVertex3sv(const GLshort *v) { SIG( "glVertex3sv" ); dllVertex3sv( v ); } static void APIENTRY logVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w) { SIG( "glVertex4d" ); dllVertex4d( x, y, z, w ); } static void APIENTRY logVertex4dv(const GLdouble *v) { SIG( "glVertex4dv" ); dllVertex4dv( v ); } static void APIENTRY logVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) { SIG( "glVertex4f" ); dllVertex4f( x, y, z, w ); } static void APIENTRY logVertex4fv(const GLfloat *v) { SIG( "glVertex4fv" ); dllVertex4fv( v ); } static void APIENTRY logVertex4i(GLint x, GLint y, GLint z, GLint w) { SIG( "glVertex4i" ); dllVertex4i( x, y, z, w ); } static void APIENTRY logVertex4iv(const GLint *v) { SIG( "glVertex4iv" ); dllVertex4iv( v ); } static void APIENTRY logVertex4s(GLshort x, GLshort y, GLshort z, GLshort w) { SIG( "glVertex4s" ); dllVertex4s( x, y, z, w ); } static void APIENTRY logVertex4sv(const GLshort *v) { SIG( "glVertex4sv" ); dllVertex4sv( v ); } static void APIENTRY logVertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) { SIG( "glVertexPointer" ); dllVertexPointer( size, type, stride, pointer ); } static void APIENTRY logViewport(GLint x, GLint y, GLsizei width, GLsizei height) { SIG( "glViewport" ); dllViewport( x, y, width, height ); } /* ** QGL_Shutdown ** ** Unloads the specified DLL then nulls out all the proc pointers. */ void QGL_Shutdown( void ) { if ( glw_state.hinstOpenGL ) { FreeLibrary( glw_state.hinstOpenGL ); glw_state.hinstOpenGL = NULL; } glw_state.hinstOpenGL = NULL; qglAccum = NULL; qglAlphaFunc = NULL; qglAreTexturesResident = NULL; qglArrayElement = NULL; qglBegin = NULL; qglBindTexture = NULL; qglBitmap = NULL; qglBlendFunc = NULL; qglCallList = NULL; qglCallLists = NULL; qglClear = NULL; qglClearAccum = NULL; qglClearColor = NULL; qglClearDepth = NULL; qglClearIndex = NULL; qglClearStencil = NULL; qglClipPlane = NULL; qglColor3b = NULL; qglColor3bv = NULL; qglColor3d = NULL; qglColor3dv = NULL; qglColor3f = NULL; qglColor3fv = NULL; qglColor3i = NULL; qglColor3iv = NULL; qglColor3s = NULL; qglColor3sv = NULL; qglColor3ub = NULL; qglColor3ubv = NULL; qglColor3ui = NULL; qglColor3uiv = NULL; qglColor3us = NULL; qglColor3usv = NULL; qglColor4b = NULL; qglColor4bv = NULL; qglColor4d = NULL; qglColor4dv = NULL; qglColor4f = NULL; qglColor4fv = NULL; qglColor4i = NULL; qglColor4iv = NULL; qglColor4s = NULL; qglColor4sv = NULL; qglColor4ub = NULL; qglColor4ubv = NULL; qglColor4ui = NULL; qglColor4uiv = NULL; qglColor4us = NULL; qglColor4usv = NULL; qglColorMask = NULL; qglColorMaterial = NULL; qglColorPointer = NULL; qglCopyPixels = NULL; qglCopyTexImage1D = NULL; qglCopyTexImage2D = NULL; qglCopyTexSubImage1D = NULL; qglCopyTexSubImage2D = NULL; qglCullFace = NULL; qglDeleteLists = NULL; qglDeleteTextures = NULL; qglDepthFunc = NULL; qglDepthMask = NULL; qglDepthRange = NULL; qglDisable = NULL; qglDisableClientState = NULL; qglDrawArrays = NULL; qglDrawBuffer = NULL; qglDrawElements = NULL; qglDrawPixels = NULL; qglEdgeFlag = NULL; qglEdgeFlagPointer = NULL; qglEdgeFlagv = NULL; qglEnable = NULL; qglEnableClientState = NULL; qglEnd = NULL; qglEndList = NULL; qglEvalCoord1d = NULL; qglEvalCoord1dv = NULL; qglEvalCoord1f = NULL; qglEvalCoord1fv = NULL; qglEvalCoord2d = NULL; qglEvalCoord2dv = NULL; qglEvalCoord2f = NULL; qglEvalCoord2fv = NULL; qglEvalMesh1 = NULL; qglEvalMesh2 = NULL; qglEvalPoint1 = NULL; qglEvalPoint2 = NULL; qglFeedbackBuffer = NULL; qglFinish = NULL; qglFlush = NULL; qglFogf = NULL; qglFogfv = NULL; qglFogi = NULL; qglFogiv = NULL; qglFrontFace = NULL; qglFrustum = NULL; qglGenLists = NULL; qglGenTextures = NULL; qglGetBooleanv = NULL; qglGetClipPlane = NULL; qglGetDoublev = NULL; qglGetError = NULL; qglGetFloatv = NULL; qglGetIntegerv = NULL; qglGetLightfv = NULL; qglGetLightiv = NULL; qglGetMapdv = NULL; qglGetMapfv = NULL; qglGetMapiv = NULL; qglGetMaterialfv = NULL; qglGetMaterialiv = NULL; qglGetPixelMapfv = NULL; qglGetPixelMapuiv = NULL; qglGetPixelMapusv = NULL; qglGetPointerv = NULL; qglGetPolygonStipple = NULL; qglGetString = NULL; qglGetTexEnvfv = NULL; qglGetTexEnviv = NULL; qglGetTexGendv = NULL; qglGetTexGenfv = NULL; qglGetTexGeniv = NULL; qglGetTexImage = NULL; qglGetTexLevelParameterfv = NULL; qglGetTexLevelParameteriv = NULL; qglGetTexParameterfv = NULL; qglGetTexParameteriv = NULL; qglHint = NULL; qglIndexMask = NULL; qglIndexPointer = NULL; qglIndexd = NULL; qglIndexdv = NULL; qglIndexf = NULL; qglIndexfv = NULL; qglIndexi = NULL; qglIndexiv = NULL; qglIndexs = NULL; qglIndexsv = NULL; qglIndexub = NULL; qglIndexubv = NULL; qglInitNames = NULL; qglInterleavedArrays = NULL; qglIsEnabled = NULL; qglIsList = NULL; qglIsTexture = NULL; qglLightModelf = NULL; qglLightModelfv = NULL; qglLightModeli = NULL; qglLightModeliv = NULL; qglLightf = NULL; qglLightfv = NULL; qglLighti = NULL; qglLightiv = NULL; qglLineStipple = NULL; qglLineWidth = NULL; qglListBase = NULL; qglLoadIdentity = NULL; qglLoadMatrixd = NULL; qglLoadMatrixf = NULL; qglLoadName = NULL; qglLogicOp = NULL; qglMap1d = NULL; qglMap1f = NULL; qglMap2d = NULL; qglMap2f = NULL; qglMapGrid1d = NULL; qglMapGrid1f = NULL; qglMapGrid2d = NULL; qglMapGrid2f = NULL; qglMaterialf = NULL; qglMaterialfv = NULL; qglMateriali = NULL; qglMaterialiv = NULL; qglMatrixMode = NULL; qglMultMatrixd = NULL; qglMultMatrixf = NULL; qglNewList = NULL; qglNormal3b = NULL; qglNormal3bv = NULL; qglNormal3d = NULL; qglNormal3dv = NULL; qglNormal3f = NULL; qglNormal3fv = NULL; qglNormal3i = NULL; qglNormal3iv = NULL; qglNormal3s = NULL; qglNormal3sv = NULL; qglNormalPointer = NULL; qglOrtho = NULL; qglPassThrough = NULL; qglPixelMapfv = NULL; qglPixelMapuiv = NULL; qglPixelMapusv = NULL; qglPixelStoref = NULL; qglPixelStorei = NULL; qglPixelTransferf = NULL; qglPixelTransferi = NULL; qglPixelZoom = NULL; qglPointSize = NULL; qglPolygonMode = NULL; qglPolygonOffset = NULL; qglPolygonStipple = NULL; qglPopAttrib = NULL; qglPopClientAttrib = NULL; qglPopMatrix = NULL; qglPopName = NULL; qglPrioritizeTextures = NULL; qglPushAttrib = NULL; qglPushClientAttrib = NULL; qglPushMatrix = NULL; qglPushName = NULL; qglRasterPos2d = NULL; qglRasterPos2dv = NULL; qglRasterPos2f = NULL; qglRasterPos2fv = NULL; qglRasterPos2i = NULL; qglRasterPos2iv = NULL; qglRasterPos2s = NULL; qglRasterPos2sv = NULL; qglRasterPos3d = NULL; qglRasterPos3dv = NULL; qglRasterPos3f = NULL; qglRasterPos3fv = NULL; qglRasterPos3i = NULL; qglRasterPos3iv = NULL; qglRasterPos3s = NULL; qglRasterPos3sv = NULL; qglRasterPos4d = NULL; qglRasterPos4dv = NULL; qglRasterPos4f = NULL; qglRasterPos4fv = NULL; qglRasterPos4i = NULL; qglRasterPos4iv = NULL; qglRasterPos4s = NULL; qglRasterPos4sv = NULL; qglReadBuffer = NULL; qglReadPixels = NULL; qglRectd = NULL; qglRectdv = NULL; qglRectf = NULL; qglRectfv = NULL; qglRecti = NULL; qglRectiv = NULL; qglRects = NULL; qglRectsv = NULL; qglRenderMode = NULL; qglRotated = NULL; qglRotatef = NULL; qglScaled = NULL; qglScalef = NULL; qglScissor = NULL; qglSelectBuffer = NULL; qglShadeModel = NULL; qglStencilFunc = NULL; qglStencilMask = NULL; qglStencilOp = NULL; qglTexCoord1d = NULL; qglTexCoord1dv = NULL; qglTexCoord1f = NULL; qglTexCoord1fv = NULL; qglTexCoord1i = NULL; qglTexCoord1iv = NULL; qglTexCoord1s = NULL; qglTexCoord1sv = NULL; qglTexCoord2d = NULL; qglTexCoord2dv = NULL; qglTexCoord2f = NULL; qglTexCoord2fv = NULL; qglTexCoord2i = NULL; qglTexCoord2iv = NULL; qglTexCoord2s = NULL; qglTexCoord2sv = NULL; qglTexCoord3d = NULL; qglTexCoord3dv = NULL; qglTexCoord3f = NULL; qglTexCoord3fv = NULL; qglTexCoord3i = NULL; qglTexCoord3iv = NULL; qglTexCoord3s = NULL; qglTexCoord3sv = NULL; qglTexCoord4d = NULL; qglTexCoord4dv = NULL; qglTexCoord4f = NULL; qglTexCoord4fv = NULL; qglTexCoord4i = NULL; qglTexCoord4iv = NULL; qglTexCoord4s = NULL; qglTexCoord4sv = NULL; qglTexCoordPointer = NULL; qglTexEnvf = NULL; qglTexEnvfv = NULL; qglTexEnvi = NULL; qglTexEnviv = NULL; qglTexGend = NULL; qglTexGendv = NULL; qglTexGenf = NULL; qglTexGenfv = NULL; qglTexGeni = NULL; qglTexGeniv = NULL; qglTexImage1D = NULL; qglTexImage2D = NULL; qglTexParameterf = NULL; qglTexParameterfv = NULL; qglTexParameteri = NULL; qglTexParameteriv = NULL; qglTexSubImage1D = NULL; qglTexSubImage2D = NULL; qglTranslated = NULL; qglTranslatef = NULL; qglVertex2d = NULL; qglVertex2dv = NULL; qglVertex2f = NULL; qglVertex2fv = NULL; qglVertex2i = NULL; qglVertex2iv = NULL; qglVertex2s = NULL; qglVertex2sv = NULL; qglVertex3d = NULL; qglVertex3dv = NULL; qglVertex3f = NULL; qglVertex3fv = NULL; qglVertex3i = NULL; qglVertex3iv = NULL; qglVertex3s = NULL; qglVertex3sv = NULL; qglVertex4d = NULL; qglVertex4dv = NULL; qglVertex4f = NULL; qglVertex4fv = NULL; qglVertex4i = NULL; qglVertex4iv = NULL; qglVertex4s = NULL; qglVertex4sv = NULL; qglVertexPointer = NULL; qglViewport = NULL; qwglCopyContext = NULL; qwglCreateContext = NULL; qwglCreateLayerContext = NULL; qwglDeleteContext = NULL; qwglDescribeLayerPlane = NULL; qwglGetCurrentContext = NULL; qwglGetCurrentDC = NULL; qwglGetLayerPaletteEntries = NULL; qwglGetProcAddress = NULL; qwglMakeCurrent = NULL; qwglRealizeLayerPalette = NULL; qwglSetLayerPaletteEntries = NULL; qwglShareLists = NULL; qwglSwapLayerBuffers = NULL; qwglUseFontBitmaps = NULL; qwglUseFontOutlines = NULL; qwglChoosePixelFormat = NULL; qwglDescribePixelFormat = NULL; qwglGetPixelFormat = NULL; qwglSetPixelFormat = NULL; qwglSwapBuffers = NULL; qwglSwapIntervalEXT = NULL; qwglGetDeviceGammaRampEXT = NULL; qwglSetDeviceGammaRampEXT = NULL; } # pragma warning (disable : 4113 4133 4047 ) # define GPA( a ) GetProcAddress( glw_state.hinstOpenGL, a ) /* ** QGL_Init ** ** This is responsible for binding our qgl function pointers to ** the appropriate GL stuff. In Windows this means doing a ** LoadLibrary and a bunch of calls to GetProcAddress. On other ** operating systems we need to do the right thing, whatever that ** might be. ** */ qboolean QGL_Init( const char *dllname ) { static int firsttime = TRUE; // update 3Dfx gamma irrespective of underlying DLL if ( firsttime ) { // VC++ 2008 Express debugger memory checking failed on second entry. // redoing putenv()'s on video restart probably not a good idea. char envbuffer[1024]; float g; g = 2.00 * ( 0.8 - ( vid_gamma->value - 0.5 ) ) + 1.0F; Com_sprintf( envbuffer, sizeof(envbuffer), "SSTV2_GAMMA=%f", g ); _putenv( envbuffer ); Com_sprintf( envbuffer, sizeof(envbuffer), "SST_GAMMA=%f", g ); _putenv( envbuffer ); firsttime = FALSE; } if ( ( glw_state.hinstOpenGL = LoadLibrary( dllname ) ) == 0 ) { char *buf = NULL; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &buf, 0, NULL); Com_Printf ("%s\n", buf ); return false; } gl_config.allow_cds = true; qglAccum = dllAccum = GPA( "glAccum" ); qglAlphaFunc = dllAlphaFunc = GPA( "glAlphaFunc" ); qglAreTexturesResident = dllAreTexturesResident = GPA( "glAreTexturesResident" ); qglArrayElement = dllArrayElement = GPA( "glArrayElement" ); qglBegin = dllBegin = GPA( "glBegin" ); qglBindTexture = dllBindTexture = GPA( "glBindTexture" ); qglBitmap = dllBitmap = GPA( "glBitmap" ); qglBlendFunc = dllBlendFunc = GPA( "glBlendFunc" ); qglCallList = dllCallList = GPA( "glCallList" ); qglCallLists = dllCallLists = GPA( "glCallLists" ); qglClear = dllClear = GPA( "glClear" ); qglClearAccum = dllClearAccum = GPA( "glClearAccum" ); qglClearColor = dllClearColor = GPA( "glClearColor" ); qglClearDepth = dllClearDepth = GPA( "glClearDepth" ); qglClearIndex = dllClearIndex = GPA( "glClearIndex" ); qglClearStencil = dllClearStencil = GPA( "glClearStencil" ); qglClipPlane = dllClipPlane = GPA( "glClipPlane" ); qglColor3b = dllColor3b = GPA( "glColor3b" ); qglColor3bv = dllColor3bv = GPA( "glColor3bv" ); qglColor3d = dllColor3d = GPA( "glColor3d" ); qglColor3dv = dllColor3dv = GPA( "glColor3dv" ); qglColor3f = dllColor3f = GPA( "glColor3f" ); qglColor3fv = dllColor3fv = GPA( "glColor3fv" ); qglColor3i = dllColor3i = GPA( "glColor3i" ); qglColor3iv = dllColor3iv = GPA( "glColor3iv" ); qglColor3s = dllColor3s = GPA( "glColor3s" ); qglColor3sv = dllColor3sv = GPA( "glColor3sv" ); qglColor3ub = dllColor3ub = GPA( "glColor3ub" ); qglColor3ubv = dllColor3ubv = GPA( "glColor3ubv" ); qglColor3ui = dllColor3ui = GPA( "glColor3ui" ); qglColor3uiv = dllColor3uiv = GPA( "glColor3uiv" ); qglColor3us = dllColor3us = GPA( "glColor3us" ); qglColor3usv = dllColor3usv = GPA( "glColor3usv" ); qglColor4b = dllColor4b = GPA( "glColor4b" ); qglColor4bv = dllColor4bv = GPA( "glColor4bv" ); qglColor4d = dllColor4d = GPA( "glColor4d" ); qglColor4dv = dllColor4dv = GPA( "glColor4dv" ); qglColor4f = dllColor4f = GPA( "glColor4f" ); qglColor4fv = dllColor4fv = GPA( "glColor4fv" ); qglColor4i = dllColor4i = GPA( "glColor4i" ); qglColor4iv = dllColor4iv = GPA( "glColor4iv" ); qglColor4s = dllColor4s = GPA( "glColor4s" ); qglColor4sv = dllColor4sv = GPA( "glColor4sv" ); qglColor4ub = dllColor4ub = GPA( "glColor4ub" ); qglColor4ubv = dllColor4ubv = GPA( "glColor4ubv" ); qglColor4ui = dllColor4ui = GPA( "glColor4ui" ); qglColor4uiv = dllColor4uiv = GPA( "glColor4uiv" ); qglColor4us = dllColor4us = GPA( "glColor4us" ); qglColor4usv = dllColor4usv = GPA( "glColor4usv" ); qglColorMask = dllColorMask = GPA( "glColorMask" ); qglColorMaterial = dllColorMaterial = GPA( "glColorMaterial" ); qglColorPointer = dllColorPointer = GPA( "glColorPointer" ); qglCopyPixels = dllCopyPixels = GPA( "glCopyPixels" ); qglCopyTexImage1D = dllCopyTexImage1D = GPA( "glCopyTexImage1D" ); qglCopyTexImage2D = dllCopyTexImage2D = GPA( "glCopyTexImage2D" ); qglCopyTexSubImage1D = dllCopyTexSubImage1D = GPA( "glCopyTexSubImage1D" ); qglCopyTexSubImage2D = dllCopyTexSubImage2D = GPA( "glCopyTexSubImage2D" ); qglCullFace = dllCullFace = GPA( "glCullFace" ); qglDeleteLists = dllDeleteLists = GPA( "glDeleteLists" ); qglDeleteTextures = dllDeleteTextures = GPA( "glDeleteTextures" ); qglDepthFunc = dllDepthFunc = GPA( "glDepthFunc" ); qglDepthMask = dllDepthMask = GPA( "glDepthMask" ); qglDepthRange = dllDepthRange = GPA( "glDepthRange" ); qglDisable = dllDisable = GPA( "glDisable" ); qglDisableClientState = dllDisableClientState = GPA( "glDisableClientState" ); qglDrawArrays = dllDrawArrays = GPA( "glDrawArrays" ); qglDrawBuffer = dllDrawBuffer = GPA( "glDrawBuffer" ); qglDrawElements = dllDrawElements = GPA( "glDrawElements" ); qglDrawPixels = dllDrawPixels = GPA( "glDrawPixels" ); qglEdgeFlag = dllEdgeFlag = GPA( "glEdgeFlag" ); qglEdgeFlagPointer = dllEdgeFlagPointer = GPA( "glEdgeFlagPointer" ); qglEdgeFlagv = dllEdgeFlagv = GPA( "glEdgeFlagv" ); qglEnable = dllEnable = GPA( "glEnable" ); qglEnableClientState = dllEnableClientState = GPA( "glEnableClientState" ); qglEnd = dllEnd = GPA( "glEnd" ); qglEndList = dllEndList = GPA( "glEndList" ); qglEvalCoord1d = dllEvalCoord1d = GPA( "glEvalCoord1d" ); qglEvalCoord1dv = dllEvalCoord1dv = GPA( "glEvalCoord1dv" ); qglEvalCoord1f = dllEvalCoord1f = GPA( "glEvalCoord1f" ); qglEvalCoord1fv = dllEvalCoord1fv = GPA( "glEvalCoord1fv" ); qglEvalCoord2d = dllEvalCoord2d = GPA( "glEvalCoord2d" ); qglEvalCoord2dv = dllEvalCoord2dv = GPA( "glEvalCoord2dv" ); qglEvalCoord2f = dllEvalCoord2f = GPA( "glEvalCoord2f" ); qglEvalCoord2fv = dllEvalCoord2fv = GPA( "glEvalCoord2fv" ); qglEvalMesh1 = dllEvalMesh1 = GPA( "glEvalMesh1" ); qglEvalMesh2 = dllEvalMesh2 = GPA( "glEvalMesh2" ); qglEvalPoint1 = dllEvalPoint1 = GPA( "glEvalPoint1" ); qglEvalPoint2 = dllEvalPoint2 = GPA( "glEvalPoint2" ); qglFeedbackBuffer = dllFeedbackBuffer = GPA( "glFeedbackBuffer" ); qglFinish = dllFinish = GPA( "glFinish" ); qglFlush = dllFlush = GPA( "glFlush" ); qglFogf = dllFogf = GPA( "glFogf" ); qglFogfv = dllFogfv = GPA( "glFogfv" ); qglFogi = dllFogi = GPA( "glFogi" ); qglFogiv = dllFogiv = GPA( "glFogiv" ); qglFrontFace = dllFrontFace = GPA( "glFrontFace" ); qglFrustum = dllFrustum = GPA( "glFrustum" ); qglGenLists = dllGenLists = GPA( "glGenLists" ); qglGenTextures = dllGenTextures = GPA( "glGenTextures" ); qglGetBooleanv = dllGetBooleanv = GPA( "glGetBooleanv" ); qglGetClipPlane = dllGetClipPlane = GPA( "glGetClipPlane" ); qglGetDoublev = dllGetDoublev = GPA( "glGetDoublev" ); qglGetError = dllGetError = GPA( "glGetError" ); qglGetFloatv = dllGetFloatv = GPA( "glGetFloatv" ); qglGetIntegerv = dllGetIntegerv = GPA( "glGetIntegerv" ); qglGetLightfv = dllGetLightfv = GPA( "glGetLightfv" ); qglGetLightiv = dllGetLightiv = GPA( "glGetLightiv" ); qglGetMapdv = dllGetMapdv = GPA( "glGetMapdv" ); qglGetMapfv = dllGetMapfv = GPA( "glGetMapfv" ); qglGetMapiv = dllGetMapiv = GPA( "glGetMapiv" ); qglGetMaterialfv = dllGetMaterialfv = GPA( "glGetMaterialfv" ); qglGetMaterialiv = dllGetMaterialiv = GPA( "glGetMaterialiv" ); qglGetPixelMapfv = dllGetPixelMapfv = GPA( "glGetPixelMapfv" ); qglGetPixelMapuiv = dllGetPixelMapuiv = GPA( "glGetPixelMapuiv" ); qglGetPixelMapusv = dllGetPixelMapusv = GPA( "glGetPixelMapusv" ); qglGetPointerv = dllGetPointerv = GPA( "glGetPointerv" ); qglGetPolygonStipple = dllGetPolygonStipple = GPA( "glGetPolygonStipple" ); qglGetString = dllGetString = GPA( "glGetString" ); qglGetTexEnvfv = dllGetTexEnvfv = GPA( "glGetTexEnvfv" ); qglGetTexEnviv = dllGetTexEnviv = GPA( "glGetTexEnviv" ); qglGetTexGendv = dllGetTexGendv = GPA( "glGetTexGendv" ); qglGetTexGenfv = dllGetTexGenfv = GPA( "glGetTexGenfv" ); qglGetTexGeniv = dllGetTexGeniv = GPA( "glGetTexGeniv" ); qglGetTexImage = dllGetTexImage = GPA( "glGetTexImage" ); qglGetTexLevelParameterfv = dllGetTexLevelParameterfv = GPA( "glGetLevelParameterfv" ); qglGetTexLevelParameteriv = dllGetTexLevelParameteriv = GPA( "glGetLevelParameteriv" ); qglGetTexParameterfv = dllGetTexParameterfv = GPA( "glGetTexParameterfv" ); qglGetTexParameteriv = dllGetTexParameteriv = GPA( "glGetTexParameteriv" ); qglHint = dllHint = GPA( "glHint" ); qglIndexMask = dllIndexMask = GPA( "glIndexMask" ); qglIndexPointer = dllIndexPointer = GPA( "glIndexPointer" ); qglIndexd = dllIndexd = GPA( "glIndexd" ); qglIndexdv = dllIndexdv = GPA( "glIndexdv" ); qglIndexf = dllIndexf = GPA( "glIndexf" ); qglIndexfv = dllIndexfv = GPA( "glIndexfv" ); qglIndexi = dllIndexi = GPA( "glIndexi" ); qglIndexiv = dllIndexiv = GPA( "glIndexiv" ); qglIndexs = dllIndexs = GPA( "glIndexs" ); qglIndexsv = dllIndexsv = GPA( "glIndexsv" ); qglIndexub = dllIndexub = GPA( "glIndexub" ); qglIndexubv = dllIndexubv = GPA( "glIndexubv" ); qglInitNames = dllInitNames = GPA( "glInitNames" ); qglInterleavedArrays = dllInterleavedArrays = GPA( "glInterleavedArrays" ); qglIsEnabled = dllIsEnabled = GPA( "glIsEnabled" ); qglIsList = dllIsList = GPA( "glIsList" ); qglIsTexture = dllIsTexture = GPA( "glIsTexture" ); qglLightModelf = dllLightModelf = GPA( "glLightModelf" ); qglLightModelfv = dllLightModelfv = GPA( "glLightModelfv" ); qglLightModeli = dllLightModeli = GPA( "glLightModeli" ); qglLightModeliv = dllLightModeliv = GPA( "glLightModeliv" ); qglLightf = dllLightf = GPA( "glLightf" ); qglLightfv = dllLightfv = GPA( "glLightfv" ); qglLighti = dllLighti = GPA( "glLighti" ); qglLightiv = dllLightiv = GPA( "glLightiv" ); qglLineStipple = dllLineStipple = GPA( "glLineStipple" ); qglLineWidth = dllLineWidth = GPA( "glLineWidth" ); qglListBase = dllListBase = GPA( "glListBase" ); qglLoadIdentity = dllLoadIdentity = GPA( "glLoadIdentity" ); qglLoadMatrixd = dllLoadMatrixd = GPA( "glLoadMatrixd" ); qglLoadMatrixf = dllLoadMatrixf = GPA( "glLoadMatrixf" ); qglLoadName = dllLoadName = GPA( "glLoadName" ); qglLogicOp = dllLogicOp = GPA( "glLogicOp" ); qglMap1d = dllMap1d = GPA( "glMap1d" ); qglMap1f = dllMap1f = GPA( "glMap1f" ); qglMap2d = dllMap2d = GPA( "glMap2d" ); qglMap2f = dllMap2f = GPA( "glMap2f" ); qglMapGrid1d = dllMapGrid1d = GPA( "glMapGrid1d" ); qglMapGrid1f = dllMapGrid1f = GPA( "glMapGrid1f" ); qglMapGrid2d = dllMapGrid2d = GPA( "glMapGrid2d" ); qglMapGrid2f = dllMapGrid2f = GPA( "glMapGrid2f" ); qglMaterialf = dllMaterialf = GPA( "glMaterialf" ); qglMaterialfv = dllMaterialfv = GPA( "glMaterialfv" ); qglMateriali = dllMateriali = GPA( "glMateriali" ); qglMaterialiv = dllMaterialiv = GPA( "glMaterialiv" ); qglMatrixMode = dllMatrixMode = GPA( "glMatrixMode" ); qglMultMatrixd = dllMultMatrixd = GPA( "glMultMatrixd" ); qglMultMatrixf = dllMultMatrixf = GPA( "glMultMatrixf" ); qglNewList = dllNewList = GPA( "glNewList" ); qglNormal3b = dllNormal3b = GPA( "glNormal3b" ); qglNormal3bv = dllNormal3bv = GPA( "glNormal3bv" ); qglNormal3d = dllNormal3d = GPA( "glNormal3d" ); qglNormal3dv = dllNormal3dv = GPA( "glNormal3dv" ); qglNormal3f = dllNormal3f = GPA( "glNormal3f" ); qglNormal3fv = dllNormal3fv = GPA( "glNormal3fv" ); qglNormal3i = dllNormal3i = GPA( "glNormal3i" ); qglNormal3iv = dllNormal3iv = GPA( "glNormal3iv" ); qglNormal3s = dllNormal3s = GPA( "glNormal3s" ); qglNormal3sv = dllNormal3sv = GPA( "glNormal3sv" ); qglNormalPointer = dllNormalPointer = GPA( "glNormalPointer" ); qglOrtho = dllOrtho = GPA( "glOrtho" ); qglPassThrough = dllPassThrough = GPA( "glPassThrough" ); qglPixelMapfv = dllPixelMapfv = GPA( "glPixelMapfv" ); qglPixelMapuiv = dllPixelMapuiv = GPA( "glPixelMapuiv" ); qglPixelMapusv = dllPixelMapusv = GPA( "glPixelMapusv" ); qglPixelStoref = dllPixelStoref = GPA( "glPixelStoref" ); qglPixelStorei = dllPixelStorei = GPA( "glPixelStorei" ); qglPixelTransferf = dllPixelTransferf = GPA( "glPixelTransferf" ); qglPixelTransferi = dllPixelTransferi = GPA( "glPixelTransferi" ); qglPixelZoom = dllPixelZoom = GPA( "glPixelZoom" ); qglPointSize = dllPointSize = GPA( "glPointSize" ); qglPolygonMode = dllPolygonMode = GPA( "glPolygonMode" ); qglPolygonOffset = dllPolygonOffset = GPA( "glPolygonOffset" ); qglPolygonStipple = dllPolygonStipple = GPA( "glPolygonStipple" ); qglPopAttrib = dllPopAttrib = GPA( "glPopAttrib" ); qglPopClientAttrib = dllPopClientAttrib = GPA( "glPopClientAttrib" ); qglPopMatrix = dllPopMatrix = GPA( "glPopMatrix" ); qglPopName = dllPopName = GPA( "glPopName" ); qglPrioritizeTextures = dllPrioritizeTextures = GPA( "glPrioritizeTextures" ); qglPushAttrib = dllPushAttrib = GPA( "glPushAttrib" ); qglPushClientAttrib = dllPushClientAttrib = GPA( "glPushClientAttrib" ); qglPushMatrix = dllPushMatrix = GPA( "glPushMatrix" ); qglPushName = dllPushName = GPA( "glPushName" ); qglRasterPos2d = dllRasterPos2d = GPA( "glRasterPos2d" ); qglRasterPos2dv = dllRasterPos2dv = GPA( "glRasterPos2dv" ); qglRasterPos2f = dllRasterPos2f = GPA( "glRasterPos2f" ); qglRasterPos2fv = dllRasterPos2fv = GPA( "glRasterPos2fv" ); qglRasterPos2i = dllRasterPos2i = GPA( "glRasterPos2i" ); qglRasterPos2iv = dllRasterPos2iv = GPA( "glRasterPos2iv" ); qglRasterPos2s = dllRasterPos2s = GPA( "glRasterPos2s" ); qglRasterPos2sv = dllRasterPos2sv = GPA( "glRasterPos2sv" ); qglRasterPos3d = dllRasterPos3d = GPA( "glRasterPos3d" ); qglRasterPos3dv = dllRasterPos3dv = GPA( "glRasterPos3dv" ); qglRasterPos3f = dllRasterPos3f = GPA( "glRasterPos3f" ); qglRasterPos3fv = dllRasterPos3fv = GPA( "glRasterPos3fv" ); qglRasterPos3i = dllRasterPos3i = GPA( "glRasterPos3i" ); qglRasterPos3iv = dllRasterPos3iv = GPA( "glRasterPos3iv" ); qglRasterPos3s = dllRasterPos3s = GPA( "glRasterPos3s" ); qglRasterPos3sv = dllRasterPos3sv = GPA( "glRasterPos3sv" ); qglRasterPos4d = dllRasterPos4d = GPA( "glRasterPos4d" ); qglRasterPos4dv = dllRasterPos4dv = GPA( "glRasterPos4dv" ); qglRasterPos4f = dllRasterPos4f = GPA( "glRasterPos4f" ); qglRasterPos4fv = dllRasterPos4fv = GPA( "glRasterPos4fv" ); qglRasterPos4i = dllRasterPos4i = GPA( "glRasterPos4i" ); qglRasterPos4iv = dllRasterPos4iv = GPA( "glRasterPos4iv" ); qglRasterPos4s = dllRasterPos4s = GPA( "glRasterPos4s" ); qglRasterPos4sv = dllRasterPos4sv = GPA( "glRasterPos4sv" ); qglReadBuffer = dllReadBuffer = GPA( "glReadBuffer" ); qglReadPixels = dllReadPixels = GPA( "glReadPixels" ); qglRectd = dllRectd = GPA( "glRectd" ); qglRectdv = dllRectdv = GPA( "glRectdv" ); qglRectf = dllRectf = GPA( "glRectf" ); qglRectfv = dllRectfv = GPA( "glRectfv" ); qglRecti = dllRecti = GPA( "glRecti" ); qglRectiv = dllRectiv = GPA( "glRectiv" ); qglRects = dllRects = GPA( "glRects" ); qglRectsv = dllRectsv = GPA( "glRectsv" ); qglRenderMode = dllRenderMode = GPA( "glRenderMode" ); qglRotated = dllRotated = GPA( "glRotated" ); qglRotatef = dllRotatef = GPA( "glRotatef" ); qglScaled = dllScaled = GPA( "glScaled" ); qglScalef = dllScalef = GPA( "glScalef" ); qglScissor = dllScissor = GPA( "glScissor" ); qglSelectBuffer = dllSelectBuffer = GPA( "glSelectBuffer" ); qglShadeModel = dllShadeModel = GPA( "glShadeModel" ); qglStencilFunc = dllStencilFunc = GPA( "glStencilFunc" ); qglStencilMask = dllStencilMask = GPA( "glStencilMask" ); qglStencilOp = dllStencilOp = GPA( "glStencilOp" ); qglTexCoord1d = dllTexCoord1d = GPA( "glTexCoord1d" ); qglTexCoord1dv = dllTexCoord1dv = GPA( "glTexCoord1dv" ); qglTexCoord1f = dllTexCoord1f = GPA( "glTexCoord1f" ); qglTexCoord1fv = dllTexCoord1fv = GPA( "glTexCoord1fv" ); qglTexCoord1i = dllTexCoord1i = GPA( "glTexCoord1i" ); qglTexCoord1iv = dllTexCoord1iv = GPA( "glTexCoord1iv" ); qglTexCoord1s = dllTexCoord1s = GPA( "glTexCoord1s" ); qglTexCoord1sv = dllTexCoord1sv = GPA( "glTexCoord1sv" ); qglTexCoord2d = dllTexCoord2d = GPA( "glTexCoord2d" ); qglTexCoord2dv = dllTexCoord2dv = GPA( "glTexCoord2dv" ); qglTexCoord2f = dllTexCoord2f = GPA( "glTexCoord2f" ); qglTexCoord2fv = dllTexCoord2fv = GPA( "glTexCoord2fv" ); qglTexCoord2i = dllTexCoord2i = GPA( "glTexCoord2i" ); qglTexCoord2iv = dllTexCoord2iv = GPA( "glTexCoord2iv" ); qglTexCoord2s = dllTexCoord2s = GPA( "glTexCoord2s" ); qglTexCoord2sv = dllTexCoord2sv = GPA( "glTexCoord2sv" ); qglTexCoord3d = dllTexCoord3d = GPA( "glTexCoord3d" ); qglTexCoord3dv = dllTexCoord3dv = GPA( "glTexCoord3dv" ); qglTexCoord3f = dllTexCoord3f = GPA( "glTexCoord3f" ); qglTexCoord3fv = dllTexCoord3fv = GPA( "glTexCoord3fv" ); qglTexCoord3i = dllTexCoord3i = GPA( "glTexCoord3i" ); qglTexCoord3iv = dllTexCoord3iv = GPA( "glTexCoord3iv" ); qglTexCoord3s = dllTexCoord3s = GPA( "glTexCoord3s" ); qglTexCoord3sv = dllTexCoord3sv = GPA( "glTexCoord3sv" ); qglTexCoord4d = dllTexCoord4d = GPA( "glTexCoord4d" ); qglTexCoord4dv = dllTexCoord4dv = GPA( "glTexCoord4dv" ); qglTexCoord4f = dllTexCoord4f = GPA( "glTexCoord4f" ); qglTexCoord4fv = dllTexCoord4fv = GPA( "glTexCoord4fv" ); qglTexCoord4i = dllTexCoord4i = GPA( "glTexCoord4i" ); qglTexCoord4iv = dllTexCoord4iv = GPA( "glTexCoord4iv" ); qglTexCoord4s = dllTexCoord4s = GPA( "glTexCoord4s" ); qglTexCoord4sv = dllTexCoord4sv = GPA( "glTexCoord4sv" ); qglTexCoordPointer = dllTexCoordPointer = GPA( "glTexCoordPointer" ); qglTexEnvf = dllTexEnvf = GPA( "glTexEnvf" ); qglTexEnvfv = dllTexEnvfv = GPA( "glTexEnvfv" ); qglTexEnvi = dllTexEnvi = GPA( "glTexEnvi" ); qglTexEnviv = dllTexEnviv = GPA( "glTexEnviv" ); qglTexGend = dllTexGend = GPA( "glTexGend" ); qglTexGendv = dllTexGendv = GPA( "glTexGendv" ); qglTexGenf = dllTexGenf = GPA( "glTexGenf" ); qglTexGenfv = dllTexGenfv = GPA( "glTexGenfv" ); qglTexGeni = dllTexGeni = GPA( "glTexGeni" ); qglTexGeniv = dllTexGeniv = GPA( "glTexGeniv" ); qglTexImage1D = dllTexImage1D = GPA( "glTexImage1D" ); qglTexImage2D = dllTexImage2D = GPA( "glTexImage2D" ); qglTexParameterf = dllTexParameterf = GPA( "glTexParameterf" ); qglTexParameterfv = dllTexParameterfv = GPA( "glTexParameterfv" ); qglTexParameteri = dllTexParameteri = GPA( "glTexParameteri" ); qglTexParameteriv = dllTexParameteriv = GPA( "glTexParameteriv" ); qglTexSubImage1D = dllTexSubImage1D = GPA( "glTexSubImage1D" ); qglTexSubImage2D = dllTexSubImage2D = GPA( "glTexSubImage2D" ); qglTranslated = dllTranslated = GPA( "glTranslated" ); qglTranslatef = dllTranslatef = GPA( "glTranslatef" ); qglVertex2d = dllVertex2d = GPA( "glVertex2d" ); qglVertex2dv = dllVertex2dv = GPA( "glVertex2dv" ); qglVertex2f = dllVertex2f = GPA( "glVertex2f" ); qglVertex2fv = dllVertex2fv = GPA( "glVertex2fv" ); qglVertex2i = dllVertex2i = GPA( "glVertex2i" ); qglVertex2iv = dllVertex2iv = GPA( "glVertex2iv" ); qglVertex2s = dllVertex2s = GPA( "glVertex2s" ); qglVertex2sv = dllVertex2sv = GPA( "glVertex2sv" ); qglVertex3d = dllVertex3d = GPA( "glVertex3d" ); qglVertex3dv = dllVertex3dv = GPA( "glVertex3dv" ); qglVertex3f = dllVertex3f = GPA( "glVertex3f" ); qglVertex3fv = dllVertex3fv = GPA( "glVertex3fv" ); qglVertex3i = dllVertex3i = GPA( "glVertex3i" ); qglVertex3iv = dllVertex3iv = GPA( "glVertex3iv" ); qglVertex3s = dllVertex3s = GPA( "glVertex3s" ); qglVertex3sv = dllVertex3sv = GPA( "glVertex3sv" ); qglVertex4d = dllVertex4d = GPA( "glVertex4d" ); qglVertex4dv = dllVertex4dv = GPA( "glVertex4dv" ); qglVertex4f = dllVertex4f = GPA( "glVertex4f" ); qglVertex4fv = dllVertex4fv = GPA( "glVertex4fv" ); qglVertex4i = dllVertex4i = GPA( "glVertex4i" ); qglVertex4iv = dllVertex4iv = GPA( "glVertex4iv" ); qglVertex4s = dllVertex4s = GPA( "glVertex4s" ); qglVertex4sv = dllVertex4sv = GPA( "glVertex4sv" ); qglVertexPointer = dllVertexPointer = GPA( "glVertexPointer" ); qglViewport = dllViewport = GPA( "glViewport" ); qwglCopyContext = GPA( "wglCopyContext" ); qwglCreateContext = GPA( "wglCreateContext" ); qwglCreateLayerContext = GPA( "wglCreateLayerContext" ); qwglDeleteContext = GPA( "wglDeleteContext" ); qwglDescribeLayerPlane = GPA( "wglDescribeLayerPlane" ); qwglGetCurrentContext = GPA( "wglGetCurrentContext" ); qwglGetCurrentDC = GPA( "wglGetCurrentDC" ); qwglGetLayerPaletteEntries = GPA( "wglGetLayerPaletteEntries" ); qwglGetProcAddress = GPA( "wglGetProcAddress" ); qwglMakeCurrent = GPA( "wglMakeCurrent" ); qwglRealizeLayerPalette = GPA( "wglRealizeLayerPalette" ); qwglSetLayerPaletteEntries = GPA( "wglSetLayerPaletteEntries" ); qwglShareLists = GPA( "wglShareLists" ); qwglSwapLayerBuffers = GPA( "wglSwapLayerBuffers" ); qwglUseFontBitmaps = GPA( "wglUseFontBitmapsA" ); qwglUseFontOutlines = GPA( "wglUseFontOutlinesA" ); qwglChoosePixelFormat = GPA( "wglChoosePixelFormat" ); qwglDescribePixelFormat = GPA( "wglDescribePixelFormat" ); qwglGetPixelFormat = GPA( "wglGetPixelFormat" ); qwglSetPixelFormat = GPA( "wglSetPixelFormat" ); qwglSwapBuffers = GPA( "wglSwapBuffers" ); qwglSwapIntervalEXT = 0; qglPointParameterfEXT = 0; qglPointParameterfvEXT = 0; qglColorTableEXT = 0; qglSelectTextureARB = 0; qglMTexCoord2fARB = 0; qglMTexCoord3fARB = 0; qglMultiTexCoord3fvARB = 0; return true; } void GLimp_EnableLogging( qboolean enable ) { if ( enable ) { if ( !glw_state.log_fp ) { struct tm *newtime; time_t aclock; char buffer[1024]; time( &aclock ); newtime = localtime( &aclock ); asctime( newtime ); Com_sprintf( buffer, sizeof(buffer), "%s/gl.log", FS_Gamedir() ); glw_state.log_fp = fopen( buffer, "wt" ); fprintf( glw_state.log_fp, "%s\n", asctime( newtime ) ); } qglAccum = logAccum; qglAlphaFunc = logAlphaFunc; qglAreTexturesResident = logAreTexturesResident; qglArrayElement = logArrayElement; qglBegin = logBegin; qglBindTexture = logBindTexture; qglBitmap = logBitmap; qglBlendFunc = logBlendFunc; qglCallList = logCallList; qglCallLists = logCallLists; qglClear = logClear; qglClearAccum = logClearAccum; qglClearColor = logClearColor; qglClearDepth = logClearDepth; qglClearIndex = logClearIndex; qglClearStencil = logClearStencil; qglClipPlane = logClipPlane; qglColor3b = logColor3b; qglColor3bv = logColor3bv; qglColor3d = logColor3d; qglColor3dv = logColor3dv; qglColor3f = logColor3f; qglColor3fv = logColor3fv; qglColor3i = logColor3i; qglColor3iv = logColor3iv; qglColor3s = logColor3s; qglColor3sv = logColor3sv; qglColor3ub = logColor3ub; qglColor3ubv = logColor3ubv; qglColor3ui = logColor3ui; qglColor3uiv = logColor3uiv; qglColor3us = logColor3us; qglColor3usv = logColor3usv; qglColor4b = logColor4b; qglColor4bv = logColor4bv; qglColor4d = logColor4d; qglColor4dv = logColor4dv; qglColor4f = logColor4f; qglColor4fv = logColor4fv; qglColor4i = logColor4i; qglColor4iv = logColor4iv; qglColor4s = logColor4s; qglColor4sv = logColor4sv; qglColor4ub = logColor4ub; qglColor4ubv = logColor4ubv; qglColor4ui = logColor4ui; qglColor4uiv = logColor4uiv; qglColor4us = logColor4us; qglColor4usv = logColor4usv; qglColorMask = logColorMask; qglColorMaterial = logColorMaterial; qglColorPointer = logColorPointer; qglCopyPixels = logCopyPixels; qglCopyTexImage1D = logCopyTexImage1D; qglCopyTexImage2D = logCopyTexImage2D; qglCopyTexSubImage1D = logCopyTexSubImage1D; qglCopyTexSubImage2D = logCopyTexSubImage2D; qglCullFace = logCullFace; qglDeleteLists = logDeleteLists ; qglDeleteTextures = logDeleteTextures ; qglDepthFunc = logDepthFunc ; qglDepthMask = logDepthMask ; qglDepthRange = logDepthRange ; qglDisable = logDisable ; qglDisableClientState = logDisableClientState ; qglDrawArrays = logDrawArrays ; qglDrawBuffer = logDrawBuffer ; qglDrawElements = logDrawElements ; qglDrawPixels = logDrawPixels ; qglEdgeFlag = logEdgeFlag ; qglEdgeFlagPointer = logEdgeFlagPointer ; qglEdgeFlagv = logEdgeFlagv ; qglEnable = logEnable ; qglEnableClientState = logEnableClientState ; qglEnd = logEnd ; qglEndList = logEndList ; qglEvalCoord1d = logEvalCoord1d ; qglEvalCoord1dv = logEvalCoord1dv ; qglEvalCoord1f = logEvalCoord1f ; qglEvalCoord1fv = logEvalCoord1fv ; qglEvalCoord2d = logEvalCoord2d ; qglEvalCoord2dv = logEvalCoord2dv ; qglEvalCoord2f = logEvalCoord2f ; qglEvalCoord2fv = logEvalCoord2fv ; qglEvalMesh1 = logEvalMesh1 ; qglEvalMesh2 = logEvalMesh2 ; qglEvalPoint1 = logEvalPoint1 ; qglEvalPoint2 = logEvalPoint2 ; qglFeedbackBuffer = logFeedbackBuffer ; qglFinish = logFinish ; qglFlush = logFlush ; qglFogf = logFogf ; qglFogfv = logFogfv ; qglFogi = logFogi ; qglFogiv = logFogiv ; qglFrontFace = logFrontFace ; qglFrustum = logFrustum ; qglGenLists = logGenLists ; qglGenTextures = logGenTextures ; qglGetBooleanv = logGetBooleanv ; qglGetClipPlane = logGetClipPlane ; qglGetDoublev = logGetDoublev ; qglGetError = logGetError ; qglGetFloatv = logGetFloatv ; qglGetIntegerv = logGetIntegerv ; qglGetLightfv = logGetLightfv ; qglGetLightiv = logGetLightiv ; qglGetMapdv = logGetMapdv ; qglGetMapfv = logGetMapfv ; qglGetMapiv = logGetMapiv ; qglGetMaterialfv = logGetMaterialfv ; qglGetMaterialiv = logGetMaterialiv ; qglGetPixelMapfv = logGetPixelMapfv ; qglGetPixelMapuiv = logGetPixelMapuiv ; qglGetPixelMapusv = logGetPixelMapusv ; qglGetPointerv = logGetPointerv ; qglGetPolygonStipple = logGetPolygonStipple ; qglGetString = logGetString ; qglGetTexEnvfv = logGetTexEnvfv ; qglGetTexEnviv = logGetTexEnviv ; qglGetTexGendv = logGetTexGendv ; qglGetTexGenfv = logGetTexGenfv ; qglGetTexGeniv = logGetTexGeniv ; qglGetTexImage = logGetTexImage ; qglGetTexLevelParameterfv = logGetTexLevelParameterfv ; qglGetTexLevelParameteriv = logGetTexLevelParameteriv ; qglGetTexParameterfv = logGetTexParameterfv ; qglGetTexParameteriv = logGetTexParameteriv ; qglHint = logHint ; qglIndexMask = logIndexMask ; qglIndexPointer = logIndexPointer ; qglIndexd = logIndexd ; qglIndexdv = logIndexdv ; qglIndexf = logIndexf ; qglIndexfv = logIndexfv ; qglIndexi = logIndexi ; qglIndexiv = logIndexiv ; qglIndexs = logIndexs ; qglIndexsv = logIndexsv ; qglIndexub = logIndexub ; qglIndexubv = logIndexubv ; qglInitNames = logInitNames ; qglInterleavedArrays = logInterleavedArrays ; qglIsEnabled = logIsEnabled ; qglIsList = logIsList ; qglIsTexture = logIsTexture ; qglLightModelf = logLightModelf ; qglLightModelfv = logLightModelfv ; qglLightModeli = logLightModeli ; qglLightModeliv = logLightModeliv ; qglLightf = logLightf ; qglLightfv = logLightfv ; qglLighti = logLighti ; qglLightiv = logLightiv ; qglLineStipple = logLineStipple ; qglLineWidth = logLineWidth ; qglListBase = logListBase ; qglLoadIdentity = logLoadIdentity ; qglLoadMatrixd = logLoadMatrixd ; qglLoadMatrixf = logLoadMatrixf ; qglLoadName = logLoadName ; qglLogicOp = logLogicOp ; qglMap1d = logMap1d ; qglMap1f = logMap1f ; qglMap2d = logMap2d ; qglMap2f = logMap2f ; qglMapGrid1d = logMapGrid1d ; qglMapGrid1f = logMapGrid1f ; qglMapGrid2d = logMapGrid2d ; qglMapGrid2f = logMapGrid2f ; qglMaterialf = logMaterialf ; qglMaterialfv = logMaterialfv ; qglMateriali = logMateriali ; qglMaterialiv = logMaterialiv ; qglMatrixMode = logMatrixMode ; qglMultMatrixd = logMultMatrixd ; qglMultMatrixf = logMultMatrixf ; qglNewList = logNewList ; qglNormal3b = logNormal3b ; qglNormal3bv = logNormal3bv ; qglNormal3d = logNormal3d ; qglNormal3dv = logNormal3dv ; qglNormal3f = logNormal3f ; qglNormal3fv = logNormal3fv ; qglNormal3i = logNormal3i ; qglNormal3iv = logNormal3iv ; qglNormal3s = logNormal3s ; qglNormal3sv = logNormal3sv ; qglNormalPointer = logNormalPointer ; qglOrtho = logOrtho ; qglPassThrough = logPassThrough ; qglPixelMapfv = logPixelMapfv ; qglPixelMapuiv = logPixelMapuiv ; qglPixelMapusv = logPixelMapusv ; qglPixelStoref = logPixelStoref ; qglPixelStorei = logPixelStorei ; qglPixelTransferf = logPixelTransferf ; qglPixelTransferi = logPixelTransferi ; qglPixelZoom = logPixelZoom ; qglPointSize = logPointSize ; qglPolygonMode = logPolygonMode ; qglPolygonOffset = logPolygonOffset ; qglPolygonStipple = logPolygonStipple ; qglPopAttrib = logPopAttrib ; qglPopClientAttrib = logPopClientAttrib ; qglPopMatrix = logPopMatrix ; qglPopName = logPopName ; qglPrioritizeTextures = logPrioritizeTextures ; qglPushAttrib = logPushAttrib ; qglPushClientAttrib = logPushClientAttrib ; qglPushMatrix = logPushMatrix ; qglPushName = logPushName ; qglRasterPos2d = logRasterPos2d ; qglRasterPos2dv = logRasterPos2dv ; qglRasterPos2f = logRasterPos2f ; qglRasterPos2fv = logRasterPos2fv ; qglRasterPos2i = logRasterPos2i ; qglRasterPos2iv = logRasterPos2iv ; qglRasterPos2s = logRasterPos2s ; qglRasterPos2sv = logRasterPos2sv ; qglRasterPos3d = logRasterPos3d ; qglRasterPos3dv = logRasterPos3dv ; qglRasterPos3f = logRasterPos3f ; qglRasterPos3fv = logRasterPos3fv ; qglRasterPos3i = logRasterPos3i ; qglRasterPos3iv = logRasterPos3iv ; qglRasterPos3s = logRasterPos3s ; qglRasterPos3sv = logRasterPos3sv ; qglRasterPos4d = logRasterPos4d ; qglRasterPos4dv = logRasterPos4dv ; qglRasterPos4f = logRasterPos4f ; qglRasterPos4fv = logRasterPos4fv ; qglRasterPos4i = logRasterPos4i ; qglRasterPos4iv = logRasterPos4iv ; qglRasterPos4s = logRasterPos4s ; qglRasterPos4sv = logRasterPos4sv ; qglReadBuffer = logReadBuffer ; qglReadPixels = logReadPixels ; qglRectd = logRectd ; qglRectdv = logRectdv ; qglRectf = logRectf ; qglRectfv = logRectfv ; qglRecti = logRecti ; qglRectiv = logRectiv ; qglRects = logRects ; qglRectsv = logRectsv ; qglRenderMode = logRenderMode ; qglRotated = logRotated ; qglRotatef = logRotatef ; qglScaled = logScaled ; qglScalef = logScalef ; qglScissor = logScissor ; qglSelectBuffer = logSelectBuffer ; qglShadeModel = logShadeModel ; qglStencilFunc = logStencilFunc ; qglStencilMask = logStencilMask ; qglStencilOp = logStencilOp ; qglTexCoord1d = logTexCoord1d ; qglTexCoord1dv = logTexCoord1dv ; qglTexCoord1f = logTexCoord1f ; qglTexCoord1fv = logTexCoord1fv ; qglTexCoord1i = logTexCoord1i ; qglTexCoord1iv = logTexCoord1iv ; qglTexCoord1s = logTexCoord1s ; qglTexCoord1sv = logTexCoord1sv ; qglTexCoord2d = logTexCoord2d ; qglTexCoord2dv = logTexCoord2dv ; qglTexCoord2f = logTexCoord2f ; qglTexCoord2fv = logTexCoord2fv ; qglTexCoord2i = logTexCoord2i ; qglTexCoord2iv = logTexCoord2iv ; qglTexCoord2s = logTexCoord2s ; qglTexCoord2sv = logTexCoord2sv ; qglTexCoord3d = logTexCoord3d ; qglTexCoord3dv = logTexCoord3dv ; qglTexCoord3f = logTexCoord3f ; qglTexCoord3fv = logTexCoord3fv ; qglTexCoord3i = logTexCoord3i ; qglTexCoord3iv = logTexCoord3iv ; qglTexCoord3s = logTexCoord3s ; qglTexCoord3sv = logTexCoord3sv ; qglTexCoord4d = logTexCoord4d ; qglTexCoord4dv = logTexCoord4dv ; qglTexCoord4f = logTexCoord4f ; qglTexCoord4fv = logTexCoord4fv ; qglTexCoord4i = logTexCoord4i ; qglTexCoord4iv = logTexCoord4iv ; qglTexCoord4s = logTexCoord4s ; qglTexCoord4sv = logTexCoord4sv ; qglTexCoordPointer = logTexCoordPointer ; qglTexEnvf = logTexEnvf ; qglTexEnvfv = logTexEnvfv ; qglTexEnvi = logTexEnvi ; qglTexEnviv = logTexEnviv ; qglTexGend = logTexGend ; qglTexGendv = logTexGendv ; qglTexGenf = logTexGenf ; qglTexGenfv = logTexGenfv ; qglTexGeni = logTexGeni ; qglTexGeniv = logTexGeniv ; qglTexImage1D = logTexImage1D ; qglTexImage2D = logTexImage2D ; qglTexParameterf = logTexParameterf ; qglTexParameterfv = logTexParameterfv ; qglTexParameteri = logTexParameteri ; qglTexParameteriv = logTexParameteriv ; qglTexSubImage1D = logTexSubImage1D ; qglTexSubImage2D = logTexSubImage2D ; qglTranslated = logTranslated ; qglTranslatef = logTranslatef ; qglVertex2d = logVertex2d ; qglVertex2dv = logVertex2dv ; qglVertex2f = logVertex2f ; qglVertex2fv = logVertex2fv ; qglVertex2i = logVertex2i ; qglVertex2iv = logVertex2iv ; qglVertex2s = logVertex2s ; qglVertex2sv = logVertex2sv ; qglVertex3d = logVertex3d ; qglVertex3dv = logVertex3dv ; qglVertex3f = logVertex3f ; qglVertex3fv = logVertex3fv ; qglVertex3i = logVertex3i ; qglVertex3iv = logVertex3iv ; qglVertex3s = logVertex3s ; qglVertex3sv = logVertex3sv ; qglVertex4d = logVertex4d ; qglVertex4dv = logVertex4dv ; qglVertex4f = logVertex4f ; qglVertex4fv = logVertex4fv ; qglVertex4i = logVertex4i ; qglVertex4iv = logVertex4iv ; qglVertex4s = logVertex4s ; qglVertex4sv = logVertex4sv ; qglVertexPointer = logVertexPointer ; qglViewport = logViewport ; } else { qglAccum = dllAccum; qglAlphaFunc = dllAlphaFunc; qglAreTexturesResident = dllAreTexturesResident; qglArrayElement = dllArrayElement; qglBegin = dllBegin; qglBindTexture = dllBindTexture; qglBitmap = dllBitmap; qglBlendFunc = dllBlendFunc; qglCallList = dllCallList; qglCallLists = dllCallLists; qglClear = dllClear; qglClearAccum = dllClearAccum; qglClearColor = dllClearColor; qglClearDepth = dllClearDepth; qglClearIndex = dllClearIndex; qglClearStencil = dllClearStencil; qglClipPlane = dllClipPlane; qglColor3b = dllColor3b; qglColor3bv = dllColor3bv; qglColor3d = dllColor3d; qglColor3dv = dllColor3dv; qglColor3f = dllColor3f; qglColor3fv = dllColor3fv; qglColor3i = dllColor3i; qglColor3iv = dllColor3iv; qglColor3s = dllColor3s; qglColor3sv = dllColor3sv; qglColor3ub = dllColor3ub; qglColor3ubv = dllColor3ubv; qglColor3ui = dllColor3ui; qglColor3uiv = dllColor3uiv; qglColor3us = dllColor3us; qglColor3usv = dllColor3usv; qglColor4b = dllColor4b; qglColor4bv = dllColor4bv; qglColor4d = dllColor4d; qglColor4dv = dllColor4dv; qglColor4f = dllColor4f; qglColor4fv = dllColor4fv; qglColor4i = dllColor4i; qglColor4iv = dllColor4iv; qglColor4s = dllColor4s; qglColor4sv = dllColor4sv; qglColor4ub = dllColor4ub; qglColor4ubv = dllColor4ubv; qglColor4ui = dllColor4ui; qglColor4uiv = dllColor4uiv; qglColor4us = dllColor4us; qglColor4usv = dllColor4usv; qglColorMask = dllColorMask; qglColorMaterial = dllColorMaterial; qglColorPointer = dllColorPointer; qglCopyPixels = dllCopyPixels; qglCopyTexImage1D = dllCopyTexImage1D; qglCopyTexImage2D = dllCopyTexImage2D; qglCopyTexSubImage1D = dllCopyTexSubImage1D; qglCopyTexSubImage2D = dllCopyTexSubImage2D; qglCullFace = dllCullFace; qglDeleteLists = dllDeleteLists ; qglDeleteTextures = dllDeleteTextures ; qglDepthFunc = dllDepthFunc ; qglDepthMask = dllDepthMask ; qglDepthRange = dllDepthRange ; qglDisable = dllDisable ; qglDisableClientState = dllDisableClientState ; qglDrawArrays = dllDrawArrays ; qglDrawBuffer = dllDrawBuffer ; qglDrawElements = dllDrawElements ; qglDrawPixels = dllDrawPixels ; qglEdgeFlag = dllEdgeFlag ; qglEdgeFlagPointer = dllEdgeFlagPointer ; qglEdgeFlagv = dllEdgeFlagv ; qglEnable = dllEnable ; qglEnableClientState = dllEnableClientState ; qglEnd = dllEnd ; qglEndList = dllEndList ; qglEvalCoord1d = dllEvalCoord1d ; qglEvalCoord1dv = dllEvalCoord1dv ; qglEvalCoord1f = dllEvalCoord1f ; qglEvalCoord1fv = dllEvalCoord1fv ; qglEvalCoord2d = dllEvalCoord2d ; qglEvalCoord2dv = dllEvalCoord2dv ; qglEvalCoord2f = dllEvalCoord2f ; qglEvalCoord2fv = dllEvalCoord2fv ; qglEvalMesh1 = dllEvalMesh1 ; qglEvalMesh2 = dllEvalMesh2 ; qglEvalPoint1 = dllEvalPoint1 ; qglEvalPoint2 = dllEvalPoint2 ; qglFeedbackBuffer = dllFeedbackBuffer ; qglFinish = dllFinish ; qglFlush = dllFlush ; qglFogf = dllFogf ; qglFogfv = dllFogfv ; qglFogi = dllFogi ; qglFogiv = dllFogiv ; qglFrontFace = dllFrontFace ; qglFrustum = dllFrustum ; qglGenLists = dllGenLists ; qglGenTextures = dllGenTextures ; qglGetBooleanv = dllGetBooleanv ; qglGetClipPlane = dllGetClipPlane ; qglGetDoublev = dllGetDoublev ; qglGetError = dllGetError ; qglGetFloatv = dllGetFloatv ; qglGetIntegerv = dllGetIntegerv ; qglGetLightfv = dllGetLightfv ; qglGetLightiv = dllGetLightiv ; qglGetMapdv = dllGetMapdv ; qglGetMapfv = dllGetMapfv ; qglGetMapiv = dllGetMapiv ; qglGetMaterialfv = dllGetMaterialfv ; qglGetMaterialiv = dllGetMaterialiv ; qglGetPixelMapfv = dllGetPixelMapfv ; qglGetPixelMapuiv = dllGetPixelMapuiv ; qglGetPixelMapusv = dllGetPixelMapusv ; qglGetPointerv = dllGetPointerv ; qglGetPolygonStipple = dllGetPolygonStipple ; qglGetString = dllGetString ; qglGetTexEnvfv = dllGetTexEnvfv ; qglGetTexEnviv = dllGetTexEnviv ; qglGetTexGendv = dllGetTexGendv ; qglGetTexGenfv = dllGetTexGenfv ; qglGetTexGeniv = dllGetTexGeniv ; qglGetTexImage = dllGetTexImage ; qglGetTexLevelParameterfv = dllGetTexLevelParameterfv ; qglGetTexLevelParameteriv = dllGetTexLevelParameteriv ; qglGetTexParameterfv = dllGetTexParameterfv ; qglGetTexParameteriv = dllGetTexParameteriv ; qglHint = dllHint ; qglIndexMask = dllIndexMask ; qglIndexPointer = dllIndexPointer ; qglIndexd = dllIndexd ; qglIndexdv = dllIndexdv ; qglIndexf = dllIndexf ; qglIndexfv = dllIndexfv ; qglIndexi = dllIndexi ; qglIndexiv = dllIndexiv ; qglIndexs = dllIndexs ; qglIndexsv = dllIndexsv ; qglIndexub = dllIndexub ; qglIndexubv = dllIndexubv ; qglInitNames = dllInitNames ; qglInterleavedArrays = dllInterleavedArrays ; qglIsEnabled = dllIsEnabled ; qglIsList = dllIsList ; qglIsTexture = dllIsTexture ; qglLightModelf = dllLightModelf ; qglLightModelfv = dllLightModelfv ; qglLightModeli = dllLightModeli ; qglLightModeliv = dllLightModeliv ; qglLightf = dllLightf ; qglLightfv = dllLightfv ; qglLighti = dllLighti ; qglLightiv = dllLightiv ; qglLineStipple = dllLineStipple ; qglLineWidth = dllLineWidth ; qglListBase = dllListBase ; qglLoadIdentity = dllLoadIdentity ; qglLoadMatrixd = dllLoadMatrixd ; qglLoadMatrixf = dllLoadMatrixf ; qglLoadName = dllLoadName ; qglLogicOp = dllLogicOp ; qglMap1d = dllMap1d ; qglMap1f = dllMap1f ; qglMap2d = dllMap2d ; qglMap2f = dllMap2f ; qglMapGrid1d = dllMapGrid1d ; qglMapGrid1f = dllMapGrid1f ; qglMapGrid2d = dllMapGrid2d ; qglMapGrid2f = dllMapGrid2f ; qglMaterialf = dllMaterialf ; qglMaterialfv = dllMaterialfv ; qglMateriali = dllMateriali ; qglMaterialiv = dllMaterialiv ; qglMatrixMode = dllMatrixMode ; qglMultMatrixd = dllMultMatrixd ; qglMultMatrixf = dllMultMatrixf ; qglNewList = dllNewList ; qglNormal3b = dllNormal3b ; qglNormal3bv = dllNormal3bv ; qglNormal3d = dllNormal3d ; qglNormal3dv = dllNormal3dv ; qglNormal3f = dllNormal3f ; qglNormal3fv = dllNormal3fv ; qglNormal3i = dllNormal3i ; qglNormal3iv = dllNormal3iv ; qglNormal3s = dllNormal3s ; qglNormal3sv = dllNormal3sv ; qglNormalPointer = dllNormalPointer ; qglOrtho = dllOrtho ; qglPassThrough = dllPassThrough ; qglPixelMapfv = dllPixelMapfv ; qglPixelMapuiv = dllPixelMapuiv ; qglPixelMapusv = dllPixelMapusv ; qglPixelStoref = dllPixelStoref ; qglPixelStorei = dllPixelStorei ; qglPixelTransferf = dllPixelTransferf ; qglPixelTransferi = dllPixelTransferi ; qglPixelZoom = dllPixelZoom ; qglPointSize = dllPointSize ; qglPolygonMode = dllPolygonMode ; qglPolygonOffset = dllPolygonOffset ; qglPolygonStipple = dllPolygonStipple ; qglPopAttrib = dllPopAttrib ; qglPopClientAttrib = dllPopClientAttrib ; qglPopMatrix = dllPopMatrix ; qglPopName = dllPopName ; qglPrioritizeTextures = dllPrioritizeTextures ; qglPushAttrib = dllPushAttrib ; qglPushClientAttrib = dllPushClientAttrib ; qglPushMatrix = dllPushMatrix ; qglPushName = dllPushName ; qglRasterPos2d = dllRasterPos2d ; qglRasterPos2dv = dllRasterPos2dv ; qglRasterPos2f = dllRasterPos2f ; qglRasterPos2fv = dllRasterPos2fv ; qglRasterPos2i = dllRasterPos2i ; qglRasterPos2iv = dllRasterPos2iv ; qglRasterPos2s = dllRasterPos2s ; qglRasterPos2sv = dllRasterPos2sv ; qglRasterPos3d = dllRasterPos3d ; qglRasterPos3dv = dllRasterPos3dv ; qglRasterPos3f = dllRasterPos3f ; qglRasterPos3fv = dllRasterPos3fv ; qglRasterPos3i = dllRasterPos3i ; qglRasterPos3iv = dllRasterPos3iv ; qglRasterPos3s = dllRasterPos3s ; qglRasterPos3sv = dllRasterPos3sv ; qglRasterPos4d = dllRasterPos4d ; qglRasterPos4dv = dllRasterPos4dv ; qglRasterPos4f = dllRasterPos4f ; qglRasterPos4fv = dllRasterPos4fv ; qglRasterPos4i = dllRasterPos4i ; qglRasterPos4iv = dllRasterPos4iv ; qglRasterPos4s = dllRasterPos4s ; qglRasterPos4sv = dllRasterPos4sv ; qglReadBuffer = dllReadBuffer ; qglReadPixels = dllReadPixels ; qglRectd = dllRectd ; qglRectdv = dllRectdv ; qglRectf = dllRectf ; qglRectfv = dllRectfv ; qglRecti = dllRecti ; qglRectiv = dllRectiv ; qglRects = dllRects ; qglRectsv = dllRectsv ; qglRenderMode = dllRenderMode ; qglRotated = dllRotated ; qglRotatef = dllRotatef ; qglScaled = dllScaled ; qglScalef = dllScalef ; qglScissor = dllScissor ; qglSelectBuffer = dllSelectBuffer ; qglShadeModel = dllShadeModel ; qglStencilFunc = dllStencilFunc ; qglStencilMask = dllStencilMask ; qglStencilOp = dllStencilOp ; qglTexCoord1d = dllTexCoord1d ; qglTexCoord1dv = dllTexCoord1dv ; qglTexCoord1f = dllTexCoord1f ; qglTexCoord1fv = dllTexCoord1fv ; qglTexCoord1i = dllTexCoord1i ; qglTexCoord1iv = dllTexCoord1iv ; qglTexCoord1s = dllTexCoord1s ; qglTexCoord1sv = dllTexCoord1sv ; qglTexCoord2d = dllTexCoord2d ; qglTexCoord2dv = dllTexCoord2dv ; qglTexCoord2f = dllTexCoord2f ; qglTexCoord2fv = dllTexCoord2fv ; qglTexCoord2i = dllTexCoord2i ; qglTexCoord2iv = dllTexCoord2iv ; qglTexCoord2s = dllTexCoord2s ; qglTexCoord2sv = dllTexCoord2sv ; qglTexCoord3d = dllTexCoord3d ; qglTexCoord3dv = dllTexCoord3dv ; qglTexCoord3f = dllTexCoord3f ; qglTexCoord3fv = dllTexCoord3fv ; qglTexCoord3i = dllTexCoord3i ; qglTexCoord3iv = dllTexCoord3iv ; qglTexCoord3s = dllTexCoord3s ; qglTexCoord3sv = dllTexCoord3sv ; qglTexCoord4d = dllTexCoord4d ; qglTexCoord4dv = dllTexCoord4dv ; qglTexCoord4f = dllTexCoord4f ; qglTexCoord4fv = dllTexCoord4fv ; qglTexCoord4i = dllTexCoord4i ; qglTexCoord4iv = dllTexCoord4iv ; qglTexCoord4s = dllTexCoord4s ; qglTexCoord4sv = dllTexCoord4sv ; qglTexCoordPointer = dllTexCoordPointer ; qglTexEnvf = dllTexEnvf ; qglTexEnvfv = dllTexEnvfv ; qglTexEnvi = dllTexEnvi ; qglTexEnviv = dllTexEnviv ; qglTexGend = dllTexGend ; qglTexGendv = dllTexGendv ; qglTexGenf = dllTexGenf ; qglTexGenfv = dllTexGenfv ; qglTexGeni = dllTexGeni ; qglTexGeniv = dllTexGeniv ; qglTexImage1D = dllTexImage1D ; qglTexImage2D = dllTexImage2D ; qglTexParameterf = dllTexParameterf ; qglTexParameterfv = dllTexParameterfv ; qglTexParameteri = dllTexParameteri ; qglTexParameteriv = dllTexParameteriv ; qglTexSubImage1D = dllTexSubImage1D ; qglTexSubImage2D = dllTexSubImage2D ; qglTranslated = dllTranslated ; qglTranslatef = dllTranslatef ; qglVertex2d = dllVertex2d ; qglVertex2dv = dllVertex2dv ; qglVertex2f = dllVertex2f ; qglVertex2fv = dllVertex2fv ; qglVertex2i = dllVertex2i ; qglVertex2iv = dllVertex2iv ; qglVertex2s = dllVertex2s ; qglVertex2sv = dllVertex2sv ; qglVertex3d = dllVertex3d ; qglVertex3dv = dllVertex3dv ; qglVertex3f = dllVertex3f ; qglVertex3fv = dllVertex3fv ; qglVertex3i = dllVertex3i ; qglVertex3iv = dllVertex3iv ; qglVertex3s = dllVertex3s ; qglVertex3sv = dllVertex3sv ; qglVertex4d = dllVertex4d ; qglVertex4dv = dllVertex4dv ; qglVertex4f = dllVertex4f ; qglVertex4fv = dllVertex4fv ; qglVertex4i = dllVertex4i ; qglVertex4iv = dllVertex4iv ; qglVertex4s = dllVertex4s ; qglVertex4sv = dllVertex4sv ; qglVertexPointer = dllVertexPointer ; qglViewport = dllViewport ; } } void GLimp_LogNewFrame( void ) { fprintf( glw_state.log_fp, "*** R_BeginFrame ***\n" ); } #pragma warning (default : 4113 4133 4047 ) alien-arena-7.66+dfsg/source/null/0000700000175000017500000000000012207204657016074 5ustar zero79zero79alien-arena-7.66+dfsg/source/null/cl_null.c0000600000175000017500000000301412161402010017646 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // cl_null.c -- this file can stub out the entire client system // for pure dedicated servers #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "../qcommon/qcommon.h" void Key_Bind_Null_f(void) { } void CL_Init (void) { } void CL_Drop (void) { } void CL_Shutdown (void) { } void CL_Frame (int msec) { } void CON_Print (const char *text) { } void Cmd_ForwardToServer (void) { char *cmd; cmd = Cmd_Argv(0); Com_Printf ("Unknown command \"%s\"\n", cmd); } void SCR_DebugGraph (float value, const float color[]) { } void SCR_BeginLoadingPlaque (void) { } void SCR_EndLoadingPlaque (void) { } void Key_Init (void) { Cmd_AddCommand ("bind", Key_Bind_Null_f); } netadr_t *CL_GetRemoteServer (void) { return NULL; } alien-arena-7.66+dfsg/source/Makefile.in0000600000175000017500000213363212207204615017175 0ustar zero79zero79# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # Process this file with automake to produce Makefile.in # # Copyright (C) 2010 COR Entertainment, LLC # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ # CPP flags for standard installation @ALTERNATE_INSTALL_FALSE@am__append_1 = -DDATADIR='"$(pkgdatadir)"' @BUILD_WIN32_FALSE@bin_PROGRAMS = alienarena-ded$(EXEEXT) \ @BUILD_WIN32_FALSE@ $(am__EXEEXT_1) @BUILD_WIN32_TRUE@bin_PROGRAMS = alienarena$(EXEEXT) $(am__EXEEXT_1) @BUILD_WIN32_TRUE@am__append_2 = $(WIN32_LIBS) @BUILD_WIN32_TRUE@am__append_3 = -DCURL_STATICLIB -DNDEBUG @BUILD_CLIENT_TRUE@@BUILD_WIN32_FALSE@am__append_4 = alienarena # Unix Client sources @BUILD_UNIX_TRUE@am__append_5 = \ @BUILD_UNIX_TRUE@ unix/gl_glx.c \ @BUILD_UNIX_TRUE@ unix/glw_unix.h \ @BUILD_UNIX_TRUE@ unix/net_udp.c \ @BUILD_UNIX_TRUE@ unix/qal_unix.c \ @BUILD_UNIX_TRUE@ unix/qgl_unix.c \ @BUILD_UNIX_TRUE@ unix/q_shunix.c \ @BUILD_UNIX_TRUE@ unix/rw_unix.c \ @BUILD_UNIX_TRUE@ unix/rw_unix.h \ @BUILD_UNIX_TRUE@ unix/sys_unix.c \ @BUILD_UNIX_TRUE@ unix/vid_so.c # Win32 MinGW Client sources @BUILD_WIN32_TRUE@am__append_6 = \ @BUILD_WIN32_TRUE@ win32/conproc.c \ @BUILD_WIN32_TRUE@ win32/conproc.h \ @BUILD_WIN32_TRUE@ win32/glw_imp.c \ @BUILD_WIN32_TRUE@ win32/glw_win.h \ @BUILD_WIN32_TRUE@ win32/in_win.c \ @BUILD_WIN32_TRUE@ win32/net_wins.c \ @BUILD_WIN32_TRUE@ win32/qal_win.c \ @BUILD_WIN32_TRUE@ win32/qgl_win.c \ @BUILD_WIN32_TRUE@ win32/q_shwin.c \ @BUILD_WIN32_TRUE@ win32/sys_win.c \ @BUILD_WIN32_TRUE@ win32/vid_dll.c \ @BUILD_WIN32_TRUE@ win32/winquake.h \ @BUILD_WIN32_TRUE@ win32/resource.h subdir = source DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_flag.m4 \ $(top_srcdir)/m4/ax_expand_prefix.m4 \ $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/pkg.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru AM_V_AR = $(am__v_AR_@AM_V@) am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) am__v_AR_0 = @echo " AR " $@; am__v_AR_1 = libgame_a_AR = $(AR) $(ARFLAGS) libgame_a_LIBADD = am__dirstamp = $(am__leading_dot)dirstamp am_libgame_a_OBJECTS = game/acesrc/acebot_ai.$(OBJEXT) \ game/acesrc/acebot_cmds.$(OBJEXT) \ game/acesrc/acebot_items.$(OBJEXT) \ game/acesrc/acebot_movement.$(OBJEXT) \ game/acesrc/acebot_nodes.$(OBJEXT) \ game/acesrc/acebot_spawn.$(OBJEXT) game/c_cam.$(OBJEXT) \ game/g_ai.$(OBJEXT) game/g_chase.$(OBJEXT) \ game/g_cmds.$(OBJEXT) game/g_combat.$(OBJEXT) \ game/g_cow.$(OBJEXT) game/g_ctf.$(OBJEXT) \ game/g_deathball.$(OBJEXT) game/g_deathray.$(OBJEXT) \ game/g_func.$(OBJEXT) game/g_items.$(OBJEXT) \ game/g_main.$(OBJEXT) game/g_misc.$(OBJEXT) \ game/g_monster.$(OBJEXT) game/g_phys.$(OBJEXT) \ game/g_save.$(OBJEXT) game/g_spawn.$(OBJEXT) \ game/g_svcmds.$(OBJEXT) game/g_target.$(OBJEXT) \ game/g_trigger.$(OBJEXT) game/g_unlagged.$(OBJEXT) \ game/g_utils.$(OBJEXT) game/g_vehicles.$(OBJEXT) \ game/g_spider.$(OBJEXT) game/g_weapon.$(OBJEXT) \ game/m_move.$(OBJEXT) game/p_client.$(OBJEXT) \ game/p_hud.$(OBJEXT) game/p_trail.$(OBJEXT) \ game/p_view.$(OBJEXT) game/p_weapon.$(OBJEXT) \ game/q_shared.$(OBJEXT) libgame_a_OBJECTS = $(am_libgame_a_OBJECTS) libode_a_AR = $(AR) $(ARFLAGS) libode_a_LIBADD = am_libode_a_OBJECTS = unix/odesrc/libode_a-array.$(OBJEXT) \ unix/odesrc/libode_a-box.$(OBJEXT) \ unix/odesrc/libode_a-capsule.$(OBJEXT) \ unix/odesrc/libode_a-collision_cylinder_box.$(OBJEXT) \ unix/odesrc/libode_a-collision_cylinder_plane.$(OBJEXT) \ unix/odesrc/libode_a-collision_cylinder_sphere.$(OBJEXT) \ unix/odesrc/libode_a-collision_kernel.$(OBJEXT) \ unix/odesrc/libode_a-collision_quadtreespace.$(OBJEXT) \ unix/odesrc/libode_a-collision_sapspace.$(OBJEXT) \ unix/odesrc/libode_a-collision_space.$(OBJEXT) \ unix/odesrc/libode_a-collision_transform.$(OBJEXT) \ unix/odesrc/libode_a-collision_trimesh_disabled.$(OBJEXT) \ unix/odesrc/libode_a-collision_util.$(OBJEXT) \ unix/odesrc/libode_a-convex.$(OBJEXT) \ unix/odesrc/libode_a-cylinder.$(OBJEXT) \ unix/odesrc/libode_a-error.$(OBJEXT) \ unix/odesrc/libode_a-export-dif.$(OBJEXT) \ unix/odesrc/libode_a-heightfield.$(OBJEXT) \ unix/odesrc/libode_a-lcp.$(OBJEXT) \ unix/odesrc/libode_a-mass.$(OBJEXT) \ unix/odesrc/libode_a-mat.$(OBJEXT) \ unix/odesrc/libode_a-matrix.$(OBJEXT) \ unix/odesrc/libode_a-memory.$(OBJEXT) \ unix/odesrc/libode_a-misc.$(OBJEXT) \ unix/odesrc/libode_a-obstack.$(OBJEXT) \ unix/odesrc/libode_a-ode.$(OBJEXT) \ unix/odesrc/libode_a-odeinit.$(OBJEXT) \ unix/odesrc/libode_a-odemath.$(OBJEXT) \ unix/odesrc/libode_a-plane.$(OBJEXT) \ unix/odesrc/libode_a-quickstep.$(OBJEXT) \ unix/odesrc/libode_a-ray.$(OBJEXT) \ unix/odesrc/libode_a-rotation.$(OBJEXT) \ unix/odesrc/libode_a-sphere.$(OBJEXT) \ unix/odesrc/libode_a-step.$(OBJEXT) \ unix/odesrc/libode_a-stepfast.$(OBJEXT) \ unix/odesrc/libode_a-testing.$(OBJEXT) \ unix/odesrc/libode_a-timer.$(OBJEXT) \ unix/odesrc/libode_a-util.$(OBJEXT) \ unix/odesrc/libode_a-fastldlt.$(OBJEXT) \ unix/odesrc/libode_a-fastltsolve.$(OBJEXT) \ unix/odesrc/libode_a-fastdot.$(OBJEXT) \ unix/odesrc/libode_a-fastlsolve.$(OBJEXT) \ unix/odesrc/libode_a-collision_cylinder_trimesh.$(OBJEXT) \ unix/odesrc/libode_a-collision_trimesh_box.$(OBJEXT) \ unix/odesrc/libode_a-collision_trimesh_ccylinder.$(OBJEXT) \ unix/odesrc/libode_a-collision_trimesh_distance.$(OBJEXT) \ unix/odesrc/libode_a-collision_trimesh_opcode.$(OBJEXT) \ unix/odesrc/libode_a-collision_trimesh_plane.$(OBJEXT) \ unix/odesrc/libode_a-collision_trimesh_ray.$(OBJEXT) \ unix/odesrc/libode_a-collision_trimesh_sphere.$(OBJEXT) \ unix/odesrc/libode_a-collision_trimesh_trimesh.$(OBJEXT) \ unix/odesrc/libode_a-collision_trimesh_trimesh_new.$(OBJEXT) \ unix/odesrc/joints/libode_a-amotor.$(OBJEXT) \ unix/odesrc/joints/libode_a-ball.$(OBJEXT) \ unix/odesrc/joints/libode_a-contact.$(OBJEXT) \ unix/odesrc/joints/libode_a-fixed.$(OBJEXT) \ unix/odesrc/joints/libode_a-hinge2.$(OBJEXT) \ unix/odesrc/joints/libode_a-hinge.$(OBJEXT) \ unix/odesrc/joints/libode_a-joint.$(OBJEXT) \ unix/odesrc/joints/libode_a-lmotor.$(OBJEXT) \ unix/odesrc/joints/libode_a-null.$(OBJEXT) \ unix/odesrc/joints/libode_a-piston.$(OBJEXT) \ unix/odesrc/joints/libode_a-plane2d.$(OBJEXT) \ unix/odesrc/joints/libode_a-pr.$(OBJEXT) \ unix/odesrc/joints/libode_a-pu.$(OBJEXT) \ unix/odesrc/joints/libode_a-slider.$(OBJEXT) \ unix/odesrc/joints/libode_a-universal.$(OBJEXT) \ unix/odesrc/OPCODE/libode_a-OPC_AABBCollider.$(OBJEXT) \ unix/odesrc/OPCODE/libode_a-OPC_AABBTree.$(OBJEXT) \ unix/odesrc/OPCODE/libode_a-OPC_BaseModel.$(OBJEXT) \ unix/odesrc/OPCODE/libode_a-OPC_Collider.$(OBJEXT) \ unix/odesrc/OPCODE/libode_a-OPC_Common.$(OBJEXT) \ unix/odesrc/OPCODE/libode_a-OPC_HybridModel.$(OBJEXT) \ unix/odesrc/OPCODE/libode_a-OPC_LSSCollider.$(OBJEXT) \ unix/odesrc/OPCODE/libode_a-OPC_MeshInterface.$(OBJEXT) \ unix/odesrc/OPCODE/libode_a-OPC_Model.$(OBJEXT) \ unix/odesrc/OPCODE/libode_a-OPC_OBBCollider.$(OBJEXT) \ unix/odesrc/OPCODE/libode_a-Opcode.$(OBJEXT) \ unix/odesrc/OPCODE/libode_a-OPC_OptimizedTree.$(OBJEXT) \ unix/odesrc/OPCODE/libode_a-OPC_Picking.$(OBJEXT) \ unix/odesrc/OPCODE/libode_a-OPC_PlanesCollider.$(OBJEXT) \ unix/odesrc/OPCODE/libode_a-OPC_RayCollider.$(OBJEXT) \ unix/odesrc/OPCODE/libode_a-OPC_SphereCollider.$(OBJEXT) \ unix/odesrc/OPCODE/libode_a-OPC_TreeBuilders.$(OBJEXT) \ unix/odesrc/OPCODE/libode_a-OPC_TreeCollider.$(OBJEXT) \ unix/odesrc/OPCODE/libode_a-OPC_VolumeCollider.$(OBJEXT) \ unix/odesrc/OPCODE/Ice/libode_a-IceAABB.$(OBJEXT) \ unix/odesrc/OPCODE/Ice/libode_a-IceContainer.$(OBJEXT) \ unix/odesrc/OPCODE/Ice/libode_a-IceHPoint.$(OBJEXT) \ unix/odesrc/OPCODE/Ice/libode_a-IceIndexedTriangle.$(OBJEXT) \ unix/odesrc/OPCODE/Ice/libode_a-IceMatrix3x3.$(OBJEXT) \ unix/odesrc/OPCODE/Ice/libode_a-IceMatrix4x4.$(OBJEXT) \ unix/odesrc/OPCODE/Ice/libode_a-IceOBB.$(OBJEXT) \ unix/odesrc/OPCODE/Ice/libode_a-IcePlane.$(OBJEXT) \ unix/odesrc/OPCODE/Ice/libode_a-IcePoint.$(OBJEXT) \ unix/odesrc/OPCODE/Ice/libode_a-IceRandom.$(OBJEXT) \ unix/odesrc/OPCODE/Ice/libode_a-IceRay.$(OBJEXT) \ unix/odesrc/OPCODE/Ice/libode_a-IceRevisitedRadix.$(OBJEXT) \ unix/odesrc/OPCODE/Ice/libode_a-IceSegment.$(OBJEXT) \ unix/odesrc/OPCODE/Ice/libode_a-IceTriangle.$(OBJEXT) \ unix/odesrc/OPCODE/Ice/libode_a-IceUtils.$(OBJEXT) libode_a_OBJECTS = $(am_libode_a_OBJECTS) @BUILD_CLIENT_TRUE@@BUILD_WIN32_FALSE@am__EXEEXT_1 = \ @BUILD_CLIENT_TRUE@@BUILD_WIN32_FALSE@ alienarena$(EXEEXT) am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am__alienarena_SOURCES_DIST = client/anorms.h client/cl_ents.c \ client/cl_fx.c client/cl_http.c client/client.h \ client/cl_input.c client/cl_inv.c client/cl_irc.c \ client/cl_main.c client/cl_parse.c client/cl_pred.c \ client/cl_scrn.c client/cl_stats.c client/cl_updates.c \ client/cl_tent.c client/cl_view.c client/console.c \ client/console.h client/input.h client/keys.c client/keys.h \ client/menu.c client/qal.c client/qal.h client/qmenu.c \ client/qmenu.h client/ref.h client/screen.h client/snd_file.c \ client/snd_openal.c client/sound.h client/vid.h game/game.h \ game/q_shared.c game/q_shared.h qcommon/cmd.c qcommon/cmodel.c \ qcommon/common.c qcommon/crc.c qcommon/crc.h qcommon/cvar.c \ qcommon/files.c qcommon/htable.c qcommon/htable.h \ qcommon/md5.c qcommon/md5.h qcommon/mdfour.c \ qcommon/net_chan.c qcommon/pmove.c qcommon/qcommon.h \ qcommon/qfiles.h ref_gl/anorms.h ref_gl/anormtab.h \ ref_gl/glext.h ref_gl/qgl.h ref_gl/r_bloom.c ref_gl/r_draw.c \ ref_gl/r_image.c ref_gl/r_image.h ref_gl/r_iqm.h \ ref_gl/r_iqm.c ref_gl/r_light.c ref_gl/r_local.h \ ref_gl/r_lodcalc.h ref_gl/r_main.c ref_gl/r_math.c \ ref_gl/r_math.h ref_gl/r_mesh.c ref_gl/r_misc.c \ ref_gl/r_model.c ref_gl/r_model.h ref_gl/r_particle.c \ ref_gl/r_postprocess.c ref_gl/r_program.c ref_gl/r_ragdoll.c \ ref_gl/r_ragdoll.h ref_gl/r_script.c ref_gl/r_script.h \ ref_gl/r_shadowmaps.c ref_gl/r_shadows.c ref_gl/r_surf.c \ ref_gl/r_text.c ref_gl/r_text.h ref_gl/r_ttf.c ref_gl/r_ttf.h \ ref_gl/r_varray.c ref_gl/r_vbo.c ref_gl/r_vlights.c \ ref_gl/r_warp.c ref_gl/warpsin.h server/server.h \ server/sv_ccmds.c server/sv_ents.c server/sv_game.c \ server/sv_init.c server/sv_main.c server/sv_send.c \ server/sv_user.c server/sv_world.c unix/glob.c unix/glob.h \ unix/gl_glx.c unix/glw_unix.h unix/net_udp.c unix/qal_unix.c \ unix/qgl_unix.c unix/q_shunix.c unix/rw_unix.c unix/rw_unix.h \ unix/sys_unix.c unix/vid_so.c win32/conproc.c win32/conproc.h \ win32/glw_imp.c win32/glw_win.h win32/in_win.c \ win32/net_wins.c win32/qal_win.c win32/qgl_win.c \ win32/q_shwin.c win32/sys_win.c win32/vid_dll.c \ win32/winquake.h win32/resource.h @BUILD_UNIX_TRUE@am__objects_1 = unix/alienarena-gl_glx.$(OBJEXT) \ @BUILD_UNIX_TRUE@ unix/alienarena-net_udp.$(OBJEXT) \ @BUILD_UNIX_TRUE@ unix/alienarena-qal_unix.$(OBJEXT) \ @BUILD_UNIX_TRUE@ unix/alienarena-qgl_unix.$(OBJEXT) \ @BUILD_UNIX_TRUE@ unix/alienarena-q_shunix.$(OBJEXT) \ @BUILD_UNIX_TRUE@ unix/alienarena-rw_unix.$(OBJEXT) \ @BUILD_UNIX_TRUE@ unix/alienarena-sys_unix.$(OBJEXT) \ @BUILD_UNIX_TRUE@ unix/alienarena-vid_so.$(OBJEXT) @BUILD_WIN32_TRUE@am__objects_2 = win32/alienarena-conproc.$(OBJEXT) \ @BUILD_WIN32_TRUE@ win32/alienarena-glw_imp.$(OBJEXT) \ @BUILD_WIN32_TRUE@ win32/alienarena-in_win.$(OBJEXT) \ @BUILD_WIN32_TRUE@ win32/alienarena-net_wins.$(OBJEXT) \ @BUILD_WIN32_TRUE@ win32/alienarena-qal_win.$(OBJEXT) \ @BUILD_WIN32_TRUE@ win32/alienarena-qgl_win.$(OBJEXT) \ @BUILD_WIN32_TRUE@ win32/alienarena-q_shwin.$(OBJEXT) \ @BUILD_WIN32_TRUE@ win32/alienarena-sys_win.$(OBJEXT) \ @BUILD_WIN32_TRUE@ win32/alienarena-vid_dll.$(OBJEXT) am_alienarena_OBJECTS = client/alienarena-cl_ents.$(OBJEXT) \ client/alienarena-cl_fx.$(OBJEXT) \ client/alienarena-cl_http.$(OBJEXT) \ client/alienarena-cl_input.$(OBJEXT) \ client/alienarena-cl_inv.$(OBJEXT) \ client/alienarena-cl_irc.$(OBJEXT) \ client/alienarena-cl_main.$(OBJEXT) \ client/alienarena-cl_parse.$(OBJEXT) \ client/alienarena-cl_pred.$(OBJEXT) \ client/alienarena-cl_scrn.$(OBJEXT) \ client/alienarena-cl_stats.$(OBJEXT) \ client/alienarena-cl_updates.$(OBJEXT) \ client/alienarena-cl_tent.$(OBJEXT) \ client/alienarena-cl_view.$(OBJEXT) \ client/alienarena-console.$(OBJEXT) \ client/alienarena-keys.$(OBJEXT) \ client/alienarena-menu.$(OBJEXT) \ client/alienarena-qal.$(OBJEXT) \ client/alienarena-qmenu.$(OBJEXT) \ client/alienarena-snd_file.$(OBJEXT) \ client/alienarena-snd_openal.$(OBJEXT) \ game/alienarena-q_shared.$(OBJEXT) \ qcommon/alienarena-cmd.$(OBJEXT) \ qcommon/alienarena-cmodel.$(OBJEXT) \ qcommon/alienarena-common.$(OBJEXT) \ qcommon/alienarena-crc.$(OBJEXT) \ qcommon/alienarena-cvar.$(OBJEXT) \ qcommon/alienarena-files.$(OBJEXT) \ qcommon/alienarena-htable.$(OBJEXT) \ qcommon/alienarena-md5.$(OBJEXT) \ qcommon/alienarena-mdfour.$(OBJEXT) \ qcommon/alienarena-net_chan.$(OBJEXT) \ qcommon/alienarena-pmove.$(OBJEXT) \ ref_gl/alienarena-r_bloom.$(OBJEXT) \ ref_gl/alienarena-r_draw.$(OBJEXT) \ ref_gl/alienarena-r_image.$(OBJEXT) \ ref_gl/alienarena-r_iqm.$(OBJEXT) \ ref_gl/alienarena-r_light.$(OBJEXT) \ ref_gl/alienarena-r_main.$(OBJEXT) \ ref_gl/alienarena-r_math.$(OBJEXT) \ ref_gl/alienarena-r_mesh.$(OBJEXT) \ ref_gl/alienarena-r_misc.$(OBJEXT) \ ref_gl/alienarena-r_model.$(OBJEXT) \ ref_gl/alienarena-r_particle.$(OBJEXT) \ ref_gl/alienarena-r_postprocess.$(OBJEXT) \ ref_gl/alienarena-r_program.$(OBJEXT) \ ref_gl/alienarena-r_ragdoll.$(OBJEXT) \ ref_gl/alienarena-r_script.$(OBJEXT) \ ref_gl/alienarena-r_shadowmaps.$(OBJEXT) \ ref_gl/alienarena-r_shadows.$(OBJEXT) \ ref_gl/alienarena-r_surf.$(OBJEXT) \ ref_gl/alienarena-r_text.$(OBJEXT) \ ref_gl/alienarena-r_ttf.$(OBJEXT) \ ref_gl/alienarena-r_varray.$(OBJEXT) \ ref_gl/alienarena-r_vbo.$(OBJEXT) \ ref_gl/alienarena-r_vlights.$(OBJEXT) \ ref_gl/alienarena-r_warp.$(OBJEXT) \ server/alienarena-sv_ccmds.$(OBJEXT) \ server/alienarena-sv_ents.$(OBJEXT) \ server/alienarena-sv_game.$(OBJEXT) \ server/alienarena-sv_init.$(OBJEXT) \ server/alienarena-sv_main.$(OBJEXT) \ server/alienarena-sv_send.$(OBJEXT) \ server/alienarena-sv_user.$(OBJEXT) \ server/alienarena-sv_world.$(OBJEXT) \ unix/alienarena-glob.$(OBJEXT) $(am__objects_1) \ $(am__objects_2) alienarena_OBJECTS = $(am_alienarena_OBJECTS) am__DEPENDENCIES_1 = @BUILD_WIN32_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) @USE_SYSTEM_LIBODE_FALSE@alienarena_DEPENDENCIES = libgame.a libode.a \ @USE_SYSTEM_LIBODE_FALSE@ $(am__DEPENDENCIES_1) \ @USE_SYSTEM_LIBODE_FALSE@ $(am__DEPENDENCIES_1) \ @USE_SYSTEM_LIBODE_FALSE@ $(am__DEPENDENCIES_1) \ @USE_SYSTEM_LIBODE_FALSE@ $(am__DEPENDENCIES_1) \ @USE_SYSTEM_LIBODE_FALSE@ $(am__DEPENDENCIES_1) \ @USE_SYSTEM_LIBODE_FALSE@ $(am__DEPENDENCIES_1) \ @USE_SYSTEM_LIBODE_FALSE@ $(am__DEPENDENCIES_2) @USE_SYSTEM_LIBODE_TRUE@alienarena_DEPENDENCIES = libgame.a \ @USE_SYSTEM_LIBODE_TRUE@ $(am__DEPENDENCIES_1) \ @USE_SYSTEM_LIBODE_TRUE@ $(am__DEPENDENCIES_1) \ @USE_SYSTEM_LIBODE_TRUE@ $(am__DEPENDENCIES_1) \ @USE_SYSTEM_LIBODE_TRUE@ $(am__DEPENDENCIES_1) \ @USE_SYSTEM_LIBODE_TRUE@ $(am__DEPENDENCIES_1) \ @USE_SYSTEM_LIBODE_TRUE@ $(am__DEPENDENCIES_1) \ @USE_SYSTEM_LIBODE_TRUE@ $(am__DEPENDENCIES_1) \ @USE_SYSTEM_LIBODE_TRUE@ $(am__DEPENDENCIES_2) am_alienarena_ded_OBJECTS = game/alienarena_ded-q_shared.$(OBJEXT) \ null/alienarena_ded-cl_null.$(OBJEXT) \ qcommon/alienarena_ded-cmd.$(OBJEXT) \ qcommon/alienarena_ded-cmodel.$(OBJEXT) \ qcommon/alienarena_ded-common.$(OBJEXT) \ qcommon/alienarena_ded-crc.$(OBJEXT) \ qcommon/alienarena_ded-cvar.$(OBJEXT) \ qcommon/alienarena_ded-files.$(OBJEXT) \ qcommon/alienarena_ded-htable.$(OBJEXT) \ qcommon/alienarena_ded-mdfour.$(OBJEXT) \ qcommon/alienarena_ded-net_chan.$(OBJEXT) \ qcommon/alienarena_ded-pmove.$(OBJEXT) \ server/alienarena_ded-sv_ccmds.$(OBJEXT) \ server/alienarena_ded-sv_ents.$(OBJEXT) \ server/alienarena_ded-sv_game.$(OBJEXT) \ server/alienarena_ded-sv_init.$(OBJEXT) \ server/alienarena_ded-sv_main.$(OBJEXT) \ server/alienarena_ded-sv_send.$(OBJEXT) \ server/alienarena_ded-sv_user.$(OBJEXT) \ server/alienarena_ded-sv_world.$(OBJEXT) \ unix/alienarena_ded-glob.$(OBJEXT) \ unix/alienarena_ded-net_udp.$(OBJEXT) \ unix/alienarena_ded-q_shunix.$(OBJEXT) \ unix/alienarena_ded-sys_unix.$(OBJEXT) alienarena_ded_OBJECTS = $(am_alienarena_ded_OBJECTS) alienarena_ded_DEPENDENCIES = libgame.a AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/config depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(libgame_a_SOURCES) $(libode_a_SOURCES) \ $(alienarena_SOURCES) $(alienarena_ded_SOURCES) DIST_SOURCES = $(libgame_a_SOURCES) $(libode_a_SOURCES) \ $(am__alienarena_SOURCES_DIST) $(alienarena_ded_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALIENARENA_HOMEDIR = @ALIENARENA_HOMEDIR@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DEPS_CFLAGS = @DEPS_CFLAGS@ DEPS_LIBS = @DEPS_LIBS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GL_LIBDIR = @GL_LIBDIR@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ ODE_CFLAGS = @ODE_CFLAGS@ ODE_LIBS = @ODE_LIBS@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WIN32_LIBS = @WIN32_LIBS@ X11_CFLAGS = @X11_CFLAGS@ X11_LIBS = @X11_LIBS@ XMKMF = @XMKMF@ XXF86DGA_CFLAGS = @XXF86DGA_CFLAGS@ XXF86DGA_LIBS = @XXF86DGA_LIBS@ XXF86VM_CFLAGS = @XXF86VM_CFLAGS@ XXF86VM_LIBS = @XXF86VM_LIBS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ icondir = @icondir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @BUILD_CLIENT_FALSE@@USE_SYSTEM_LIBODE_FALSE@noinst_LIBRARIES = libgame.a @BUILD_CLIENT_TRUE@@USE_SYSTEM_LIBODE_FALSE@noinst_LIBRARIES = libgame.a libode.a @USE_SYSTEM_LIBODE_TRUE@noinst_LIBRARIES = libgame.a @USE_SYSTEM_LIBODE_FALSE@AM_CPPFLAGS = -I $(top_srcdir)/source \ @USE_SYSTEM_LIBODE_FALSE@ -isystem $(top_srcdir)/source/unix \ @USE_SYSTEM_LIBODE_FALSE@ $(am__append_1) # # Setup the integrated ODE library. # note: the -isystem option is for making #include look in # the build directory before the system directory. # @USE_SYSTEM_LIBODE_TRUE@AM_CPPFLAGS = -I $(top_srcdir)/source \ @USE_SYSTEM_LIBODE_TRUE@ $(am__append_1) # Dedicated Server libraries and flags alienarena_ded_LDADD = libgame.a alienarena_ded_CPPFLAGS = $(AM_CPPFLAGS) -DDEDICATED_ONLY # Client libraries and flags alienarena_CPPFLAGS = $(AM_CPPFLAGS) $(PTHREAD_CFLAGS) $(X11_CLAGS) \ $(DEPS_CFLAGS) $(ODE_CFLAGS) $(XXF86VM_CFLAGS) \ $(XXF86DGA_CFLAGS) $(ZLIB_CFLAGS) $(am__append_3) # # alienarena with integrated libode # @USE_SYSTEM_LIBODE_FALSE@alienarena_LDADD = libgame.a libode.a \ @USE_SYSTEM_LIBODE_FALSE@ $(PTHREAD_LIBS) $(X11_LIBS) \ @USE_SYSTEM_LIBODE_FALSE@ $(DEPS_LIBS) $(XXF86VM_LIBS) \ @USE_SYSTEM_LIBODE_FALSE@ $(XXF86DGA_LIBS) $(ZLIB_LIBS) \ @USE_SYSTEM_LIBODE_FALSE@ -lstdc++ $(am__append_2) # # alienarena with system libode # @USE_SYSTEM_LIBODE_TRUE@alienarena_LDADD = libgame.a $(PTHREAD_LIBS) \ @USE_SYSTEM_LIBODE_TRUE@ $(X11_LIBS) $(DEPS_LIBS) $(ODE_LIBS) \ @USE_SYSTEM_LIBODE_TRUE@ $(XXF86VM_LIBS) $(XXF86DGA_LIBS) \ @USE_SYSTEM_LIBODE_TRUE@ $(ZLIB_LIBS) $(am__append_2) # ODE has an additional custom "no debug" variable @USE_SYSTEM_LIBODE_FALSE@libode_a_CPPFLAGS = -I$(top_srcdir)/source/unix/odesrc/OPCODE \ @USE_SYSTEM_LIBODE_FALSE@ -isystem $(top_srcdir)/source/unix \ @USE_SYSTEM_LIBODE_FALSE@ -DdDOUBLE -DdTRIMESH_ENABLED \ @USE_SYSTEM_LIBODE_FALSE@ -DdTRIMESH_OPCODE -DNDEBUG -DdNODEBUG # common client sources alienarena_SOURCES = client/anorms.h client/cl_ents.c client/cl_fx.c \ client/cl_http.c client/client.h client/cl_input.c \ client/cl_inv.c client/cl_irc.c client/cl_main.c \ client/cl_parse.c client/cl_pred.c client/cl_scrn.c \ client/cl_stats.c client/cl_updates.c client/cl_tent.c \ client/cl_view.c client/console.c client/console.h \ client/input.h client/keys.c client/keys.h client/menu.c \ client/qal.c client/qal.h client/qmenu.c client/qmenu.h \ client/ref.h client/screen.h client/snd_file.c \ client/snd_openal.c client/sound.h client/vid.h game/game.h \ game/q_shared.c game/q_shared.h qcommon/cmd.c qcommon/cmodel.c \ qcommon/common.c qcommon/crc.c qcommon/crc.h qcommon/cvar.c \ qcommon/files.c qcommon/htable.c qcommon/htable.h \ qcommon/md5.c qcommon/md5.h qcommon/mdfour.c \ qcommon/net_chan.c qcommon/pmove.c qcommon/qcommon.h \ qcommon/qfiles.h ref_gl/anorms.h ref_gl/anormtab.h \ ref_gl/glext.h ref_gl/qgl.h ref_gl/r_bloom.c ref_gl/r_draw.c \ ref_gl/r_image.c ref_gl/r_image.h ref_gl/r_iqm.h \ ref_gl/r_iqm.c ref_gl/r_light.c ref_gl/r_local.h \ ref_gl/r_lodcalc.h ref_gl/r_main.c ref_gl/r_math.c \ ref_gl/r_math.h ref_gl/r_mesh.c ref_gl/r_misc.c \ ref_gl/r_model.c ref_gl/r_model.h ref_gl/r_particle.c \ ref_gl/r_postprocess.c ref_gl/r_program.c ref_gl/r_ragdoll.c \ ref_gl/r_ragdoll.h ref_gl/r_script.c ref_gl/r_script.h \ ref_gl/r_shadowmaps.c ref_gl/r_shadows.c ref_gl/r_surf.c \ ref_gl/r_text.c ref_gl/r_text.h ref_gl/r_ttf.c ref_gl/r_ttf.h \ ref_gl/r_varray.c ref_gl/r_vbo.c ref_gl/r_vlights.c \ ref_gl/r_warp.c ref_gl/warpsin.h server/server.h \ server/sv_ccmds.c server/sv_ents.c server/sv_game.c \ server/sv_init.c server/sv_main.c server/sv_send.c \ server/sv_user.c server/sv_world.c unix/glob.c unix/glob.h \ $(am__append_5) $(am__append_6) # Dedicated Server sources (Unix only) alienarena_ded_SOURCES = \ client/anorms.h \ game/game.h \ game/q_shared.c \ game/q_shared.h \ null/cl_null.c \ qcommon/cmd.c \ qcommon/cmodel.c \ qcommon/common.c \ qcommon/crc.c \ qcommon/cvar.c \ qcommon/files.c \ qcommon/htable.c \ qcommon/htable.h \ qcommon/mdfour.c \ qcommon/net_chan.c \ qcommon/pmove.c \ qcommon/qcommon.h \ qcommon/qfiles.h \ server/server.h \ server/sv_ccmds.c \ server/sv_ents.c \ server/sv_game.c \ server/sv_init.c \ server/sv_main.c \ server/sv_send.c \ server/sv_user.c \ server/sv_world.c \ unix/glob.c \ unix/glob.h \ unix/net_udp.c \ unix/q_shunix.c \ unix/rw_unix.h \ unix/sys_unix.c # Game module sources libgame_a_SOURCES = \ client/anorms.h \ game/acesrc/acebot_ai.c \ game/acesrc/acebot_cmds.c \ game/acesrc/acebot.h \ game/acesrc/acebot_items.c \ game/acesrc/acebot_movement.c \ game/acesrc/acebot_nodes.c \ game/acesrc/acebot_spawn.c \ game/c_cam.c \ game/cow.h \ game/g_ai.c \ game/game.h \ game/g_chase.c \ game/g_cmds.c \ game/g_combat.c \ game/g_cow.c \ game/g_ctf.c \ game/g_deathball.c \ game/g_deathray.c \ game/g_deathray.h \ game/g_func.c \ game/g_items.c \ game/g_local.h \ game/g_main.c \ game/g_misc.c \ game/g_monster.c \ game/g_phys.c \ game/g_save.c \ game/g_spawn.c \ game/g_svcmds.c \ game/g_target.c \ game/g_trigger.c \ game/g_unlagged.c \ game/g_utils.c \ game/g_vehicles.c \ game/g_spider.c \ game/g_spider.h \ game/g_weapon.c \ game/m_move.c \ game/m_player.h \ game/p_client.c \ game/p_hud.c \ game/p_trail.c \ game/p_view.c \ game/p_weapon.c \ game/q_shared.c \ game/q_shared.h \ qcommon/qfiles.h # # Integrated Open Dynamic Engine (ODE) Library # libode_a_SOURCES = unix/ode/collision.h unix/ode/collision_space.h \ unix/ode/collision_trimesh.h unix/ode/common.h \ unix/ode/compatibility.h unix/ode/contact.h unix/ode/error.h \ unix/ode/export-dif.h unix/ode/mass.h unix/ode/matrix.h \ unix/ode/memory.h unix/ode/misc.h unix/ode/objects.h \ unix/ode/odeconfig.h unix/ode/odecpp_collision.h \ unix/ode/odecpp.h unix/ode/ode.h unix/ode/odeinit.h \ unix/ode/odemath.h unix/ode/rotation.h unix/ode/timer.h \ unix/odesrc/array.cpp unix/odesrc/array.h unix/odesrc/box.cpp \ unix/odesrc/capsule.cpp unix/odesrc/collision_cylinder_box.cpp \ unix/odesrc/collision_cylinder_plane.cpp \ unix/odesrc/collision_cylinder_sphere.cpp \ unix/odesrc/collision_kernel.cpp \ unix/odesrc/collision_kernel.h \ unix/odesrc/collision_quadtreespace.cpp \ unix/odesrc/collision_sapspace.cpp \ unix/odesrc/collision_space.cpp \ unix/odesrc/collision_space_internal.h \ unix/odesrc/collision_std.h \ unix/odesrc/collision_transform.cpp \ unix/odesrc/collision_transform.h \ unix/odesrc/collision_trimesh_colliders.h \ unix/odesrc/collision_trimesh_disabled.cpp \ unix/odesrc/collision_trimesh_internal.h \ unix/odesrc/collision_util.cpp unix/odesrc/collision_util.h \ unix/odesrc/convex.cpp unix/odesrc/cylinder.cpp \ unix/odesrc/error.cpp unix/odesrc/export-dif.cpp \ unix/odesrc/heightfield.cpp unix/odesrc/heightfield.h \ unix/odesrc/lcp.cpp unix/odesrc/lcp.h unix/odesrc/mass.cpp \ unix/odesrc/mat.cpp unix/odesrc/mat.h unix/odesrc/matrix.cpp \ unix/odesrc/memory.cpp unix/odesrc/misc.cpp \ unix/odesrc/objects.h unix/odesrc/obstack.cpp \ unix/odesrc/obstack.h unix/odesrc/ode.cpp \ unix/odesrc/odeinit.cpp unix/odesrc/odemath.cpp \ unix/odesrc/odeou.h unix/odesrc/odetls.h unix/odesrc/plane.cpp \ unix/odesrc/quickstep.cpp unix/odesrc/quickstep.h \ unix/odesrc/ray.cpp unix/odesrc/rotation.cpp \ unix/odesrc/sphere.cpp unix/odesrc/step.cpp \ unix/odesrc/stepfast.cpp unix/odesrc/step.h \ unix/odesrc/testing.cpp unix/odesrc/testing.h \ unix/odesrc/timer.cpp unix/odesrc/util.cpp unix/odesrc/util.h \ unix/odesrc/fastldlt.c unix/odesrc/fastltsolve.c \ unix/odesrc/fastdot.c unix/odesrc/fastlsolve.c \ unix/odesrc/collision_cylinder_trimesh.cpp \ unix/odesrc/collision_trimesh_box.cpp \ unix/odesrc/collision_trimesh_ccylinder.cpp \ unix/odesrc/collision_trimesh_distance.cpp \ unix/odesrc/collision_trimesh_internal.h \ unix/odesrc/collision_trimesh_opcode.cpp \ unix/odesrc/collision_trimesh_plane.cpp \ unix/odesrc/collision_trimesh_ray.cpp \ unix/odesrc/collision_trimesh_sphere.cpp \ unix/odesrc/collision_trimesh_trimesh.cpp \ unix/odesrc/collision_trimesh_trimesh_new.cpp \ unix/odesrc/joints/amotor.cpp unix/odesrc/joints/amotor.h \ unix/odesrc/joints/ball.cpp unix/odesrc/joints/ball.h \ unix/odesrc/joints/contact.cpp unix/odesrc/joints/contact.h \ unix/odesrc/joints/fixed.cpp unix/odesrc/joints/fixed.h \ unix/odesrc/joints/hinge2.cpp unix/odesrc/joints/hinge2.h \ unix/odesrc/joints/hinge.cpp unix/odesrc/joints/hinge.h \ unix/odesrc/joints/joint.cpp unix/odesrc/joints/joint.h \ unix/odesrc/joints/joint_internal.h \ unix/odesrc/joints/joints.h unix/odesrc/joints/lmotor.cpp \ unix/odesrc/joints/lmotor.h unix/odesrc/joints/null.cpp \ unix/odesrc/joints/null.h unix/odesrc/joints/piston.cpp \ unix/odesrc/joints/piston.h unix/odesrc/joints/plane2d.cpp \ unix/odesrc/joints/plane2d.h unix/odesrc/joints/pr.cpp \ unix/odesrc/joints/pr.h unix/odesrc/joints/pu.cpp \ unix/odesrc/joints/pu.h unix/odesrc/joints/slider.cpp \ unix/odesrc/joints/slider.h unix/odesrc/joints/universal.cpp \ unix/odesrc/joints/universal.h \ unix/odesrc/OPCODE/OPC_AABBCollider.cpp \ unix/odesrc/OPCODE/OPC_AABBCollider.h \ unix/odesrc/OPCODE/OPC_AABBTree.cpp \ unix/odesrc/OPCODE/OPC_AABBTree.h \ unix/odesrc/OPCODE/OPC_BaseModel.cpp \ unix/odesrc/OPCODE/OPC_BaseModel.h \ unix/odesrc/OPCODE/OPC_BoxBoxOverlap.h \ unix/odesrc/OPCODE/OPC_Collider.cpp \ unix/odesrc/OPCODE/OPC_Collider.h \ unix/odesrc/OPCODE/OPC_Common.cpp \ unix/odesrc/OPCODE/OPC_Common.h \ unix/odesrc/OPCODE/OPC_HybridModel.cpp \ unix/odesrc/OPCODE/OPC_HybridModel.h \ unix/odesrc/OPCODE/OPC_IceHook.h \ unix/odesrc/OPCODE/OPC_LSSAABBOverlap.h \ unix/odesrc/OPCODE/OPC_LSSCollider.cpp \ unix/odesrc/OPCODE/OPC_LSSCollider.h \ unix/odesrc/OPCODE/OPC_LSSTriOverlap.h \ unix/odesrc/OPCODE/OPC_MeshInterface.cpp \ unix/odesrc/OPCODE/OPC_MeshInterface.h \ unix/odesrc/OPCODE/OPC_Model.cpp \ unix/odesrc/OPCODE/OPC_Model.h \ unix/odesrc/OPCODE/OPC_OBBCollider.cpp \ unix/odesrc/OPCODE/OPC_OBBCollider.h \ unix/odesrc/OPCODE/Opcode.cpp unix/odesrc/OPCODE/Opcode.h \ unix/odesrc/OPCODE/OPC_OptimizedTree.cpp \ unix/odesrc/OPCODE/OPC_OptimizedTree.h \ unix/odesrc/OPCODE/OPC_Picking.cpp \ unix/odesrc/OPCODE/OPC_Picking.h \ unix/odesrc/OPCODE/OPC_PlanesAABBOverlap.h \ unix/odesrc/OPCODE/OPC_PlanesCollider.cpp \ unix/odesrc/OPCODE/OPC_PlanesCollider.h \ unix/odesrc/OPCODE/OPC_PlanesTriOverlap.h \ unix/odesrc/OPCODE/OPC_RayAABBOverlap.h \ unix/odesrc/OPCODE/OPC_RayCollider.cpp \ unix/odesrc/OPCODE/OPC_RayCollider.h \ unix/odesrc/OPCODE/OPC_RayTriOverlap.h \ unix/odesrc/OPCODE/OPC_Settings.h \ unix/odesrc/OPCODE/OPC_SphereAABBOverlap.h \ unix/odesrc/OPCODE/OPC_SphereCollider.cpp \ unix/odesrc/OPCODE/OPC_SphereCollider.h \ unix/odesrc/OPCODE/OPC_SphereTriOverlap.h \ unix/odesrc/OPCODE/OPC_TreeBuilders.cpp \ unix/odesrc/OPCODE/OPC_TreeBuilders.h \ unix/odesrc/OPCODE/OPC_TreeCollider.cpp \ unix/odesrc/OPCODE/OPC_TreeCollider.h \ unix/odesrc/OPCODE/OPC_TriBoxOverlap.h \ unix/odesrc/OPCODE/OPC_TriTriOverlap.h \ unix/odesrc/OPCODE/OPC_VolumeCollider.cpp \ unix/odesrc/OPCODE/OPC_VolumeCollider.h \ unix/odesrc/OPCODE/Stdafx.h unix/odesrc/OPCODE/Ice/IceAABB.cpp \ unix/odesrc/OPCODE/Ice/IceAABB.h \ unix/odesrc/OPCODE/Ice/IceAxes.h \ unix/odesrc/OPCODE/Ice/IceBoundingSphere.h \ unix/odesrc/OPCODE/Ice/IceContainer.cpp \ unix/odesrc/OPCODE/Ice/IceContainer.h \ unix/odesrc/OPCODE/Ice/IceFPU.h \ unix/odesrc/OPCODE/Ice/IceHPoint.cpp \ unix/odesrc/OPCODE/Ice/IceHPoint.h \ unix/odesrc/OPCODE/Ice/IceIndexedTriangle.cpp \ unix/odesrc/OPCODE/Ice/IceIndexedTriangle.h \ unix/odesrc/OPCODE/Ice/IceLSS.h \ unix/odesrc/OPCODE/Ice/IceMatrix3x3.cpp \ unix/odesrc/OPCODE/Ice/IceMatrix3x3.h \ unix/odesrc/OPCODE/Ice/IceMatrix4x4.cpp \ unix/odesrc/OPCODE/Ice/IceMatrix4x4.h \ unix/odesrc/OPCODE/Ice/IceMemoryMacros.h \ unix/odesrc/OPCODE/Ice/IceOBB.cpp \ unix/odesrc/OPCODE/Ice/IceOBB.h \ unix/odesrc/OPCODE/Ice/IcePairs.h \ unix/odesrc/OPCODE/Ice/IcePlane.cpp \ unix/odesrc/OPCODE/Ice/IcePlane.h \ unix/odesrc/OPCODE/Ice/IcePoint.cpp \ unix/odesrc/OPCODE/Ice/IcePoint.h \ unix/odesrc/OPCODE/Ice/IcePreprocessor.h \ unix/odesrc/OPCODE/Ice/IceRandom.cpp \ unix/odesrc/OPCODE/Ice/IceRandom.h \ unix/odesrc/OPCODE/Ice/IceRay.cpp \ unix/odesrc/OPCODE/Ice/IceRay.h \ unix/odesrc/OPCODE/Ice/IceRevisitedRadix.cpp \ unix/odesrc/OPCODE/Ice/IceRevisitedRadix.h \ unix/odesrc/OPCODE/Ice/IceSegment.cpp \ unix/odesrc/OPCODE/Ice/IceSegment.h \ unix/odesrc/OPCODE/Ice/IceTriangle.cpp \ unix/odesrc/OPCODE/Ice/IceTriangle.h \ unix/odesrc/OPCODE/Ice/IceTriList.h \ unix/odesrc/OPCODE/Ice/IceTypes.h \ unix/odesrc/OPCODE/Ice/IceUtils.cpp \ unix/odesrc/OPCODE/Ice/IceUtils.h all: all-am .SUFFIXES: .SUFFIXES: .c .cpp .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign source/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign source/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) game/acesrc/$(am__dirstamp): @$(MKDIR_P) game/acesrc @: > game/acesrc/$(am__dirstamp) game/acesrc/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) game/acesrc/$(DEPDIR) @: > game/acesrc/$(DEPDIR)/$(am__dirstamp) game/acesrc/acebot_ai.$(OBJEXT): game/acesrc/$(am__dirstamp) \ game/acesrc/$(DEPDIR)/$(am__dirstamp) game/acesrc/acebot_cmds.$(OBJEXT): game/acesrc/$(am__dirstamp) \ game/acesrc/$(DEPDIR)/$(am__dirstamp) game/acesrc/acebot_items.$(OBJEXT): game/acesrc/$(am__dirstamp) \ game/acesrc/$(DEPDIR)/$(am__dirstamp) game/acesrc/acebot_movement.$(OBJEXT): game/acesrc/$(am__dirstamp) \ game/acesrc/$(DEPDIR)/$(am__dirstamp) game/acesrc/acebot_nodes.$(OBJEXT): game/acesrc/$(am__dirstamp) \ game/acesrc/$(DEPDIR)/$(am__dirstamp) game/acesrc/acebot_spawn.$(OBJEXT): game/acesrc/$(am__dirstamp) \ game/acesrc/$(DEPDIR)/$(am__dirstamp) game/$(am__dirstamp): @$(MKDIR_P) game @: > game/$(am__dirstamp) game/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) game/$(DEPDIR) @: > game/$(DEPDIR)/$(am__dirstamp) game/c_cam.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/g_ai.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/g_chase.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/g_cmds.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/g_combat.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/g_cow.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/g_ctf.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/g_deathball.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/g_deathray.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/g_func.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/g_items.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/g_main.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/g_misc.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/g_monster.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/g_phys.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/g_save.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/g_spawn.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/g_svcmds.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/g_target.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/g_trigger.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/g_unlagged.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/g_utils.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/g_vehicles.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/g_spider.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/g_weapon.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/m_move.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/p_client.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/p_hud.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/p_trail.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/p_view.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/p_weapon.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) game/q_shared.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) libgame.a: $(libgame_a_OBJECTS) $(libgame_a_DEPENDENCIES) $(EXTRA_libgame_a_DEPENDENCIES) $(AM_V_at)-rm -f libgame.a $(AM_V_AR)$(libgame_a_AR) libgame.a $(libgame_a_OBJECTS) $(libgame_a_LIBADD) $(AM_V_at)$(RANLIB) libgame.a unix/odesrc/$(am__dirstamp): @$(MKDIR_P) unix/odesrc @: > unix/odesrc/$(am__dirstamp) unix/odesrc/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) unix/odesrc/$(DEPDIR) @: > unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-array.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-box.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-capsule.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-collision_cylinder_box.$(OBJEXT): \ unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-collision_cylinder_plane.$(OBJEXT): \ unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-collision_cylinder_sphere.$(OBJEXT): \ unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-collision_kernel.$(OBJEXT): \ unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-collision_quadtreespace.$(OBJEXT): \ unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-collision_sapspace.$(OBJEXT): \ unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-collision_space.$(OBJEXT): \ unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-collision_transform.$(OBJEXT): \ unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-collision_trimesh_disabled.$(OBJEXT): \ unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-collision_util.$(OBJEXT): \ unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-convex.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-cylinder.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-error.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-export-dif.$(OBJEXT): \ unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-heightfield.$(OBJEXT): \ unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-lcp.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-mass.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-mat.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-matrix.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-memory.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-misc.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-obstack.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-ode.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-odeinit.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-odemath.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-plane.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-quickstep.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-ray.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-rotation.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-sphere.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-step.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-stepfast.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-testing.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-timer.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-util.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-fastldlt.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-fastltsolve.$(OBJEXT): \ unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-fastdot.$(OBJEXT): unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-fastlsolve.$(OBJEXT): \ unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-collision_cylinder_trimesh.$(OBJEXT): \ unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-collision_trimesh_box.$(OBJEXT): \ unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-collision_trimesh_ccylinder.$(OBJEXT): \ unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-collision_trimesh_distance.$(OBJEXT): \ unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-collision_trimesh_opcode.$(OBJEXT): \ unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-collision_trimesh_plane.$(OBJEXT): \ unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-collision_trimesh_ray.$(OBJEXT): \ unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-collision_trimesh_sphere.$(OBJEXT): \ unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-collision_trimesh_trimesh.$(OBJEXT): \ unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/libode_a-collision_trimesh_trimesh_new.$(OBJEXT): \ unix/odesrc/$(am__dirstamp) \ unix/odesrc/$(DEPDIR)/$(am__dirstamp) unix/odesrc/joints/$(am__dirstamp): @$(MKDIR_P) unix/odesrc/joints @: > unix/odesrc/joints/$(am__dirstamp) unix/odesrc/joints/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) unix/odesrc/joints/$(DEPDIR) @: > unix/odesrc/joints/$(DEPDIR)/$(am__dirstamp) unix/odesrc/joints/libode_a-amotor.$(OBJEXT): \ unix/odesrc/joints/$(am__dirstamp) \ unix/odesrc/joints/$(DEPDIR)/$(am__dirstamp) unix/odesrc/joints/libode_a-ball.$(OBJEXT): \ unix/odesrc/joints/$(am__dirstamp) \ unix/odesrc/joints/$(DEPDIR)/$(am__dirstamp) unix/odesrc/joints/libode_a-contact.$(OBJEXT): \ unix/odesrc/joints/$(am__dirstamp) \ unix/odesrc/joints/$(DEPDIR)/$(am__dirstamp) unix/odesrc/joints/libode_a-fixed.$(OBJEXT): \ unix/odesrc/joints/$(am__dirstamp) \ unix/odesrc/joints/$(DEPDIR)/$(am__dirstamp) unix/odesrc/joints/libode_a-hinge2.$(OBJEXT): \ unix/odesrc/joints/$(am__dirstamp) \ unix/odesrc/joints/$(DEPDIR)/$(am__dirstamp) unix/odesrc/joints/libode_a-hinge.$(OBJEXT): \ unix/odesrc/joints/$(am__dirstamp) \ unix/odesrc/joints/$(DEPDIR)/$(am__dirstamp) unix/odesrc/joints/libode_a-joint.$(OBJEXT): \ unix/odesrc/joints/$(am__dirstamp) \ unix/odesrc/joints/$(DEPDIR)/$(am__dirstamp) unix/odesrc/joints/libode_a-lmotor.$(OBJEXT): \ unix/odesrc/joints/$(am__dirstamp) \ unix/odesrc/joints/$(DEPDIR)/$(am__dirstamp) unix/odesrc/joints/libode_a-null.$(OBJEXT): \ unix/odesrc/joints/$(am__dirstamp) \ unix/odesrc/joints/$(DEPDIR)/$(am__dirstamp) unix/odesrc/joints/libode_a-piston.$(OBJEXT): \ unix/odesrc/joints/$(am__dirstamp) \ unix/odesrc/joints/$(DEPDIR)/$(am__dirstamp) unix/odesrc/joints/libode_a-plane2d.$(OBJEXT): \ unix/odesrc/joints/$(am__dirstamp) \ unix/odesrc/joints/$(DEPDIR)/$(am__dirstamp) unix/odesrc/joints/libode_a-pr.$(OBJEXT): \ unix/odesrc/joints/$(am__dirstamp) \ unix/odesrc/joints/$(DEPDIR)/$(am__dirstamp) unix/odesrc/joints/libode_a-pu.$(OBJEXT): \ unix/odesrc/joints/$(am__dirstamp) \ unix/odesrc/joints/$(DEPDIR)/$(am__dirstamp) unix/odesrc/joints/libode_a-slider.$(OBJEXT): \ unix/odesrc/joints/$(am__dirstamp) \ unix/odesrc/joints/$(DEPDIR)/$(am__dirstamp) unix/odesrc/joints/libode_a-universal.$(OBJEXT): \ unix/odesrc/joints/$(am__dirstamp) \ unix/odesrc/joints/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/$(am__dirstamp): @$(MKDIR_P) unix/odesrc/OPCODE @: > unix/odesrc/OPCODE/$(am__dirstamp) unix/odesrc/OPCODE/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) unix/odesrc/OPCODE/$(DEPDIR) @: > unix/odesrc/OPCODE/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/libode_a-OPC_AABBCollider.$(OBJEXT): \ unix/odesrc/OPCODE/$(am__dirstamp) \ unix/odesrc/OPCODE/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/libode_a-OPC_AABBTree.$(OBJEXT): \ unix/odesrc/OPCODE/$(am__dirstamp) \ unix/odesrc/OPCODE/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/libode_a-OPC_BaseModel.$(OBJEXT): \ unix/odesrc/OPCODE/$(am__dirstamp) \ unix/odesrc/OPCODE/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/libode_a-OPC_Collider.$(OBJEXT): \ unix/odesrc/OPCODE/$(am__dirstamp) \ unix/odesrc/OPCODE/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/libode_a-OPC_Common.$(OBJEXT): \ unix/odesrc/OPCODE/$(am__dirstamp) \ unix/odesrc/OPCODE/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/libode_a-OPC_HybridModel.$(OBJEXT): \ unix/odesrc/OPCODE/$(am__dirstamp) \ unix/odesrc/OPCODE/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/libode_a-OPC_LSSCollider.$(OBJEXT): \ unix/odesrc/OPCODE/$(am__dirstamp) \ unix/odesrc/OPCODE/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/libode_a-OPC_MeshInterface.$(OBJEXT): \ unix/odesrc/OPCODE/$(am__dirstamp) \ unix/odesrc/OPCODE/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/libode_a-OPC_Model.$(OBJEXT): \ unix/odesrc/OPCODE/$(am__dirstamp) \ unix/odesrc/OPCODE/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/libode_a-OPC_OBBCollider.$(OBJEXT): \ unix/odesrc/OPCODE/$(am__dirstamp) \ unix/odesrc/OPCODE/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/libode_a-Opcode.$(OBJEXT): \ unix/odesrc/OPCODE/$(am__dirstamp) \ unix/odesrc/OPCODE/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/libode_a-OPC_OptimizedTree.$(OBJEXT): \ unix/odesrc/OPCODE/$(am__dirstamp) \ unix/odesrc/OPCODE/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/libode_a-OPC_Picking.$(OBJEXT): \ unix/odesrc/OPCODE/$(am__dirstamp) \ unix/odesrc/OPCODE/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/libode_a-OPC_PlanesCollider.$(OBJEXT): \ unix/odesrc/OPCODE/$(am__dirstamp) \ unix/odesrc/OPCODE/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/libode_a-OPC_RayCollider.$(OBJEXT): \ unix/odesrc/OPCODE/$(am__dirstamp) \ unix/odesrc/OPCODE/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/libode_a-OPC_SphereCollider.$(OBJEXT): \ unix/odesrc/OPCODE/$(am__dirstamp) \ unix/odesrc/OPCODE/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/libode_a-OPC_TreeBuilders.$(OBJEXT): \ unix/odesrc/OPCODE/$(am__dirstamp) \ unix/odesrc/OPCODE/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/libode_a-OPC_TreeCollider.$(OBJEXT): \ unix/odesrc/OPCODE/$(am__dirstamp) \ unix/odesrc/OPCODE/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/libode_a-OPC_VolumeCollider.$(OBJEXT): \ unix/odesrc/OPCODE/$(am__dirstamp) \ unix/odesrc/OPCODE/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/Ice/$(am__dirstamp): @$(MKDIR_P) unix/odesrc/OPCODE/Ice @: > unix/odesrc/OPCODE/Ice/$(am__dirstamp) unix/odesrc/OPCODE/Ice/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) unix/odesrc/OPCODE/Ice/$(DEPDIR) @: > unix/odesrc/OPCODE/Ice/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/Ice/libode_a-IceAABB.$(OBJEXT): \ unix/odesrc/OPCODE/Ice/$(am__dirstamp) \ unix/odesrc/OPCODE/Ice/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/Ice/libode_a-IceContainer.$(OBJEXT): \ unix/odesrc/OPCODE/Ice/$(am__dirstamp) \ unix/odesrc/OPCODE/Ice/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/Ice/libode_a-IceHPoint.$(OBJEXT): \ unix/odesrc/OPCODE/Ice/$(am__dirstamp) \ unix/odesrc/OPCODE/Ice/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/Ice/libode_a-IceIndexedTriangle.$(OBJEXT): \ unix/odesrc/OPCODE/Ice/$(am__dirstamp) \ unix/odesrc/OPCODE/Ice/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/Ice/libode_a-IceMatrix3x3.$(OBJEXT): \ unix/odesrc/OPCODE/Ice/$(am__dirstamp) \ unix/odesrc/OPCODE/Ice/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/Ice/libode_a-IceMatrix4x4.$(OBJEXT): \ unix/odesrc/OPCODE/Ice/$(am__dirstamp) \ unix/odesrc/OPCODE/Ice/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/Ice/libode_a-IceOBB.$(OBJEXT): \ unix/odesrc/OPCODE/Ice/$(am__dirstamp) \ unix/odesrc/OPCODE/Ice/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/Ice/libode_a-IcePlane.$(OBJEXT): \ unix/odesrc/OPCODE/Ice/$(am__dirstamp) \ unix/odesrc/OPCODE/Ice/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/Ice/libode_a-IcePoint.$(OBJEXT): \ unix/odesrc/OPCODE/Ice/$(am__dirstamp) \ unix/odesrc/OPCODE/Ice/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/Ice/libode_a-IceRandom.$(OBJEXT): \ unix/odesrc/OPCODE/Ice/$(am__dirstamp) \ unix/odesrc/OPCODE/Ice/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/Ice/libode_a-IceRay.$(OBJEXT): \ unix/odesrc/OPCODE/Ice/$(am__dirstamp) \ unix/odesrc/OPCODE/Ice/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/Ice/libode_a-IceRevisitedRadix.$(OBJEXT): \ unix/odesrc/OPCODE/Ice/$(am__dirstamp) \ unix/odesrc/OPCODE/Ice/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/Ice/libode_a-IceSegment.$(OBJEXT): \ unix/odesrc/OPCODE/Ice/$(am__dirstamp) \ unix/odesrc/OPCODE/Ice/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/Ice/libode_a-IceTriangle.$(OBJEXT): \ unix/odesrc/OPCODE/Ice/$(am__dirstamp) \ unix/odesrc/OPCODE/Ice/$(DEPDIR)/$(am__dirstamp) unix/odesrc/OPCODE/Ice/libode_a-IceUtils.$(OBJEXT): \ unix/odesrc/OPCODE/Ice/$(am__dirstamp) \ unix/odesrc/OPCODE/Ice/$(DEPDIR)/$(am__dirstamp) libode.a: $(libode_a_OBJECTS) $(libode_a_DEPENDENCIES) $(EXTRA_libode_a_DEPENDENCIES) $(AM_V_at)-rm -f libode.a $(AM_V_AR)$(libode_a_AR) libode.a $(libode_a_OBJECTS) $(libode_a_LIBADD) $(AM_V_at)$(RANLIB) libode.a install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) client/$(am__dirstamp): @$(MKDIR_P) client @: > client/$(am__dirstamp) client/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) client/$(DEPDIR) @: > client/$(DEPDIR)/$(am__dirstamp) client/alienarena-cl_ents.$(OBJEXT): client/$(am__dirstamp) \ client/$(DEPDIR)/$(am__dirstamp) client/alienarena-cl_fx.$(OBJEXT): client/$(am__dirstamp) \ client/$(DEPDIR)/$(am__dirstamp) client/alienarena-cl_http.$(OBJEXT): client/$(am__dirstamp) \ client/$(DEPDIR)/$(am__dirstamp) client/alienarena-cl_input.$(OBJEXT): client/$(am__dirstamp) \ client/$(DEPDIR)/$(am__dirstamp) client/alienarena-cl_inv.$(OBJEXT): client/$(am__dirstamp) \ client/$(DEPDIR)/$(am__dirstamp) client/alienarena-cl_irc.$(OBJEXT): client/$(am__dirstamp) \ client/$(DEPDIR)/$(am__dirstamp) client/alienarena-cl_main.$(OBJEXT): client/$(am__dirstamp) \ client/$(DEPDIR)/$(am__dirstamp) client/alienarena-cl_parse.$(OBJEXT): client/$(am__dirstamp) \ client/$(DEPDIR)/$(am__dirstamp) client/alienarena-cl_pred.$(OBJEXT): client/$(am__dirstamp) \ client/$(DEPDIR)/$(am__dirstamp) client/alienarena-cl_scrn.$(OBJEXT): client/$(am__dirstamp) \ client/$(DEPDIR)/$(am__dirstamp) client/alienarena-cl_stats.$(OBJEXT): client/$(am__dirstamp) \ client/$(DEPDIR)/$(am__dirstamp) client/alienarena-cl_updates.$(OBJEXT): client/$(am__dirstamp) \ client/$(DEPDIR)/$(am__dirstamp) client/alienarena-cl_tent.$(OBJEXT): client/$(am__dirstamp) \ client/$(DEPDIR)/$(am__dirstamp) client/alienarena-cl_view.$(OBJEXT): client/$(am__dirstamp) \ client/$(DEPDIR)/$(am__dirstamp) client/alienarena-console.$(OBJEXT): client/$(am__dirstamp) \ client/$(DEPDIR)/$(am__dirstamp) client/alienarena-keys.$(OBJEXT): client/$(am__dirstamp) \ client/$(DEPDIR)/$(am__dirstamp) client/alienarena-menu.$(OBJEXT): client/$(am__dirstamp) \ client/$(DEPDIR)/$(am__dirstamp) client/alienarena-qal.$(OBJEXT): client/$(am__dirstamp) \ client/$(DEPDIR)/$(am__dirstamp) client/alienarena-qmenu.$(OBJEXT): client/$(am__dirstamp) \ client/$(DEPDIR)/$(am__dirstamp) client/alienarena-snd_file.$(OBJEXT): client/$(am__dirstamp) \ client/$(DEPDIR)/$(am__dirstamp) client/alienarena-snd_openal.$(OBJEXT): client/$(am__dirstamp) \ client/$(DEPDIR)/$(am__dirstamp) game/alienarena-q_shared.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) qcommon/$(am__dirstamp): @$(MKDIR_P) qcommon @: > qcommon/$(am__dirstamp) qcommon/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) qcommon/$(DEPDIR) @: > qcommon/$(DEPDIR)/$(am__dirstamp) qcommon/alienarena-cmd.$(OBJEXT): qcommon/$(am__dirstamp) \ qcommon/$(DEPDIR)/$(am__dirstamp) qcommon/alienarena-cmodel.$(OBJEXT): qcommon/$(am__dirstamp) \ qcommon/$(DEPDIR)/$(am__dirstamp) qcommon/alienarena-common.$(OBJEXT): qcommon/$(am__dirstamp) \ qcommon/$(DEPDIR)/$(am__dirstamp) qcommon/alienarena-crc.$(OBJEXT): qcommon/$(am__dirstamp) \ qcommon/$(DEPDIR)/$(am__dirstamp) qcommon/alienarena-cvar.$(OBJEXT): qcommon/$(am__dirstamp) \ qcommon/$(DEPDIR)/$(am__dirstamp) qcommon/alienarena-files.$(OBJEXT): qcommon/$(am__dirstamp) \ qcommon/$(DEPDIR)/$(am__dirstamp) qcommon/alienarena-htable.$(OBJEXT): qcommon/$(am__dirstamp) \ qcommon/$(DEPDIR)/$(am__dirstamp) qcommon/alienarena-md5.$(OBJEXT): qcommon/$(am__dirstamp) \ qcommon/$(DEPDIR)/$(am__dirstamp) qcommon/alienarena-mdfour.$(OBJEXT): qcommon/$(am__dirstamp) \ qcommon/$(DEPDIR)/$(am__dirstamp) qcommon/alienarena-net_chan.$(OBJEXT): qcommon/$(am__dirstamp) \ qcommon/$(DEPDIR)/$(am__dirstamp) qcommon/alienarena-pmove.$(OBJEXT): qcommon/$(am__dirstamp) \ qcommon/$(DEPDIR)/$(am__dirstamp) ref_gl/$(am__dirstamp): @$(MKDIR_P) ref_gl @: > ref_gl/$(am__dirstamp) ref_gl/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) ref_gl/$(DEPDIR) @: > ref_gl/$(DEPDIR)/$(am__dirstamp) ref_gl/alienarena-r_bloom.$(OBJEXT): ref_gl/$(am__dirstamp) \ ref_gl/$(DEPDIR)/$(am__dirstamp) ref_gl/alienarena-r_draw.$(OBJEXT): ref_gl/$(am__dirstamp) \ ref_gl/$(DEPDIR)/$(am__dirstamp) ref_gl/alienarena-r_image.$(OBJEXT): ref_gl/$(am__dirstamp) \ ref_gl/$(DEPDIR)/$(am__dirstamp) ref_gl/alienarena-r_iqm.$(OBJEXT): ref_gl/$(am__dirstamp) \ ref_gl/$(DEPDIR)/$(am__dirstamp) ref_gl/alienarena-r_light.$(OBJEXT): ref_gl/$(am__dirstamp) \ ref_gl/$(DEPDIR)/$(am__dirstamp) ref_gl/alienarena-r_main.$(OBJEXT): ref_gl/$(am__dirstamp) \ ref_gl/$(DEPDIR)/$(am__dirstamp) ref_gl/alienarena-r_math.$(OBJEXT): ref_gl/$(am__dirstamp) \ ref_gl/$(DEPDIR)/$(am__dirstamp) ref_gl/alienarena-r_mesh.$(OBJEXT): ref_gl/$(am__dirstamp) \ ref_gl/$(DEPDIR)/$(am__dirstamp) ref_gl/alienarena-r_misc.$(OBJEXT): ref_gl/$(am__dirstamp) \ ref_gl/$(DEPDIR)/$(am__dirstamp) ref_gl/alienarena-r_model.$(OBJEXT): ref_gl/$(am__dirstamp) \ ref_gl/$(DEPDIR)/$(am__dirstamp) ref_gl/alienarena-r_particle.$(OBJEXT): ref_gl/$(am__dirstamp) \ ref_gl/$(DEPDIR)/$(am__dirstamp) ref_gl/alienarena-r_postprocess.$(OBJEXT): ref_gl/$(am__dirstamp) \ ref_gl/$(DEPDIR)/$(am__dirstamp) ref_gl/alienarena-r_program.$(OBJEXT): ref_gl/$(am__dirstamp) \ ref_gl/$(DEPDIR)/$(am__dirstamp) ref_gl/alienarena-r_ragdoll.$(OBJEXT): ref_gl/$(am__dirstamp) \ ref_gl/$(DEPDIR)/$(am__dirstamp) ref_gl/alienarena-r_script.$(OBJEXT): ref_gl/$(am__dirstamp) \ ref_gl/$(DEPDIR)/$(am__dirstamp) ref_gl/alienarena-r_shadowmaps.$(OBJEXT): ref_gl/$(am__dirstamp) \ ref_gl/$(DEPDIR)/$(am__dirstamp) ref_gl/alienarena-r_shadows.$(OBJEXT): ref_gl/$(am__dirstamp) \ ref_gl/$(DEPDIR)/$(am__dirstamp) ref_gl/alienarena-r_surf.$(OBJEXT): ref_gl/$(am__dirstamp) \ ref_gl/$(DEPDIR)/$(am__dirstamp) ref_gl/alienarena-r_text.$(OBJEXT): ref_gl/$(am__dirstamp) \ ref_gl/$(DEPDIR)/$(am__dirstamp) ref_gl/alienarena-r_ttf.$(OBJEXT): ref_gl/$(am__dirstamp) \ ref_gl/$(DEPDIR)/$(am__dirstamp) ref_gl/alienarena-r_varray.$(OBJEXT): ref_gl/$(am__dirstamp) \ ref_gl/$(DEPDIR)/$(am__dirstamp) ref_gl/alienarena-r_vbo.$(OBJEXT): ref_gl/$(am__dirstamp) \ ref_gl/$(DEPDIR)/$(am__dirstamp) ref_gl/alienarena-r_vlights.$(OBJEXT): ref_gl/$(am__dirstamp) \ ref_gl/$(DEPDIR)/$(am__dirstamp) ref_gl/alienarena-r_warp.$(OBJEXT): ref_gl/$(am__dirstamp) \ ref_gl/$(DEPDIR)/$(am__dirstamp) server/$(am__dirstamp): @$(MKDIR_P) server @: > server/$(am__dirstamp) server/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) server/$(DEPDIR) @: > server/$(DEPDIR)/$(am__dirstamp) server/alienarena-sv_ccmds.$(OBJEXT): server/$(am__dirstamp) \ server/$(DEPDIR)/$(am__dirstamp) server/alienarena-sv_ents.$(OBJEXT): server/$(am__dirstamp) \ server/$(DEPDIR)/$(am__dirstamp) server/alienarena-sv_game.$(OBJEXT): server/$(am__dirstamp) \ server/$(DEPDIR)/$(am__dirstamp) server/alienarena-sv_init.$(OBJEXT): server/$(am__dirstamp) \ server/$(DEPDIR)/$(am__dirstamp) server/alienarena-sv_main.$(OBJEXT): server/$(am__dirstamp) \ server/$(DEPDIR)/$(am__dirstamp) server/alienarena-sv_send.$(OBJEXT): server/$(am__dirstamp) \ server/$(DEPDIR)/$(am__dirstamp) server/alienarena-sv_user.$(OBJEXT): server/$(am__dirstamp) \ server/$(DEPDIR)/$(am__dirstamp) server/alienarena-sv_world.$(OBJEXT): server/$(am__dirstamp) \ server/$(DEPDIR)/$(am__dirstamp) unix/$(am__dirstamp): @$(MKDIR_P) unix @: > unix/$(am__dirstamp) unix/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) unix/$(DEPDIR) @: > unix/$(DEPDIR)/$(am__dirstamp) unix/alienarena-glob.$(OBJEXT): unix/$(am__dirstamp) \ unix/$(DEPDIR)/$(am__dirstamp) unix/alienarena-gl_glx.$(OBJEXT): unix/$(am__dirstamp) \ unix/$(DEPDIR)/$(am__dirstamp) unix/alienarena-net_udp.$(OBJEXT): unix/$(am__dirstamp) \ unix/$(DEPDIR)/$(am__dirstamp) unix/alienarena-qal_unix.$(OBJEXT): unix/$(am__dirstamp) \ unix/$(DEPDIR)/$(am__dirstamp) unix/alienarena-qgl_unix.$(OBJEXT): unix/$(am__dirstamp) \ unix/$(DEPDIR)/$(am__dirstamp) unix/alienarena-q_shunix.$(OBJEXT): unix/$(am__dirstamp) \ unix/$(DEPDIR)/$(am__dirstamp) unix/alienarena-rw_unix.$(OBJEXT): unix/$(am__dirstamp) \ unix/$(DEPDIR)/$(am__dirstamp) unix/alienarena-sys_unix.$(OBJEXT): unix/$(am__dirstamp) \ unix/$(DEPDIR)/$(am__dirstamp) unix/alienarena-vid_so.$(OBJEXT): unix/$(am__dirstamp) \ unix/$(DEPDIR)/$(am__dirstamp) win32/$(am__dirstamp): @$(MKDIR_P) win32 @: > win32/$(am__dirstamp) win32/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) win32/$(DEPDIR) @: > win32/$(DEPDIR)/$(am__dirstamp) win32/alienarena-conproc.$(OBJEXT): win32/$(am__dirstamp) \ win32/$(DEPDIR)/$(am__dirstamp) win32/alienarena-glw_imp.$(OBJEXT): win32/$(am__dirstamp) \ win32/$(DEPDIR)/$(am__dirstamp) win32/alienarena-in_win.$(OBJEXT): win32/$(am__dirstamp) \ win32/$(DEPDIR)/$(am__dirstamp) win32/alienarena-net_wins.$(OBJEXT): win32/$(am__dirstamp) \ win32/$(DEPDIR)/$(am__dirstamp) win32/alienarena-qal_win.$(OBJEXT): win32/$(am__dirstamp) \ win32/$(DEPDIR)/$(am__dirstamp) win32/alienarena-qgl_win.$(OBJEXT): win32/$(am__dirstamp) \ win32/$(DEPDIR)/$(am__dirstamp) win32/alienarena-q_shwin.$(OBJEXT): win32/$(am__dirstamp) \ win32/$(DEPDIR)/$(am__dirstamp) win32/alienarena-sys_win.$(OBJEXT): win32/$(am__dirstamp) \ win32/$(DEPDIR)/$(am__dirstamp) win32/alienarena-vid_dll.$(OBJEXT): win32/$(am__dirstamp) \ win32/$(DEPDIR)/$(am__dirstamp) alienarena$(EXEEXT): $(alienarena_OBJECTS) $(alienarena_DEPENDENCIES) $(EXTRA_alienarena_DEPENDENCIES) @rm -f alienarena$(EXEEXT) $(AM_V_CCLD)$(LINK) $(alienarena_OBJECTS) $(alienarena_LDADD) $(LIBS) game/alienarena_ded-q_shared.$(OBJEXT): game/$(am__dirstamp) \ game/$(DEPDIR)/$(am__dirstamp) null/$(am__dirstamp): @$(MKDIR_P) null @: > null/$(am__dirstamp) null/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) null/$(DEPDIR) @: > null/$(DEPDIR)/$(am__dirstamp) null/alienarena_ded-cl_null.$(OBJEXT): null/$(am__dirstamp) \ null/$(DEPDIR)/$(am__dirstamp) qcommon/alienarena_ded-cmd.$(OBJEXT): qcommon/$(am__dirstamp) \ qcommon/$(DEPDIR)/$(am__dirstamp) qcommon/alienarena_ded-cmodel.$(OBJEXT): qcommon/$(am__dirstamp) \ qcommon/$(DEPDIR)/$(am__dirstamp) qcommon/alienarena_ded-common.$(OBJEXT): qcommon/$(am__dirstamp) \ qcommon/$(DEPDIR)/$(am__dirstamp) qcommon/alienarena_ded-crc.$(OBJEXT): qcommon/$(am__dirstamp) \ qcommon/$(DEPDIR)/$(am__dirstamp) qcommon/alienarena_ded-cvar.$(OBJEXT): qcommon/$(am__dirstamp) \ qcommon/$(DEPDIR)/$(am__dirstamp) qcommon/alienarena_ded-files.$(OBJEXT): qcommon/$(am__dirstamp) \ qcommon/$(DEPDIR)/$(am__dirstamp) qcommon/alienarena_ded-htable.$(OBJEXT): qcommon/$(am__dirstamp) \ qcommon/$(DEPDIR)/$(am__dirstamp) qcommon/alienarena_ded-mdfour.$(OBJEXT): qcommon/$(am__dirstamp) \ qcommon/$(DEPDIR)/$(am__dirstamp) qcommon/alienarena_ded-net_chan.$(OBJEXT): qcommon/$(am__dirstamp) \ qcommon/$(DEPDIR)/$(am__dirstamp) qcommon/alienarena_ded-pmove.$(OBJEXT): qcommon/$(am__dirstamp) \ qcommon/$(DEPDIR)/$(am__dirstamp) server/alienarena_ded-sv_ccmds.$(OBJEXT): server/$(am__dirstamp) \ server/$(DEPDIR)/$(am__dirstamp) server/alienarena_ded-sv_ents.$(OBJEXT): server/$(am__dirstamp) \ server/$(DEPDIR)/$(am__dirstamp) server/alienarena_ded-sv_game.$(OBJEXT): server/$(am__dirstamp) \ server/$(DEPDIR)/$(am__dirstamp) server/alienarena_ded-sv_init.$(OBJEXT): server/$(am__dirstamp) \ server/$(DEPDIR)/$(am__dirstamp) server/alienarena_ded-sv_main.$(OBJEXT): server/$(am__dirstamp) \ server/$(DEPDIR)/$(am__dirstamp) server/alienarena_ded-sv_send.$(OBJEXT): server/$(am__dirstamp) \ server/$(DEPDIR)/$(am__dirstamp) server/alienarena_ded-sv_user.$(OBJEXT): server/$(am__dirstamp) \ server/$(DEPDIR)/$(am__dirstamp) server/alienarena_ded-sv_world.$(OBJEXT): server/$(am__dirstamp) \ server/$(DEPDIR)/$(am__dirstamp) unix/alienarena_ded-glob.$(OBJEXT): unix/$(am__dirstamp) \ unix/$(DEPDIR)/$(am__dirstamp) unix/alienarena_ded-net_udp.$(OBJEXT): unix/$(am__dirstamp) \ unix/$(DEPDIR)/$(am__dirstamp) unix/alienarena_ded-q_shunix.$(OBJEXT): unix/$(am__dirstamp) \ unix/$(DEPDIR)/$(am__dirstamp) unix/alienarena_ded-sys_unix.$(OBJEXT): unix/$(am__dirstamp) \ unix/$(DEPDIR)/$(am__dirstamp) alienarena-ded$(EXEEXT): $(alienarena_ded_OBJECTS) $(alienarena_ded_DEPENDENCIES) $(EXTRA_alienarena_ded_DEPENDENCIES) @rm -f alienarena-ded$(EXEEXT) $(AM_V_CCLD)$(LINK) $(alienarena_ded_OBJECTS) $(alienarena_ded_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f client/*.$(OBJEXT) -rm -f game/*.$(OBJEXT) -rm -f game/acesrc/*.$(OBJEXT) -rm -f null/*.$(OBJEXT) -rm -f qcommon/*.$(OBJEXT) -rm -f ref_gl/*.$(OBJEXT) -rm -f server/*.$(OBJEXT) -rm -f unix/*.$(OBJEXT) -rm -f unix/odesrc/*.$(OBJEXT) -rm -f unix/odesrc/OPCODE/*.$(OBJEXT) -rm -f unix/odesrc/OPCODE/Ice/*.$(OBJEXT) -rm -f unix/odesrc/joints/*.$(OBJEXT) -rm -f win32/*.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/alienarena-cl_ents.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/alienarena-cl_fx.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/alienarena-cl_http.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/alienarena-cl_input.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/alienarena-cl_inv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/alienarena-cl_irc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/alienarena-cl_main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/alienarena-cl_parse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/alienarena-cl_pred.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/alienarena-cl_scrn.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/alienarena-cl_stats.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/alienarena-cl_tent.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/alienarena-cl_updates.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/alienarena-cl_view.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/alienarena-console.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/alienarena-keys.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/alienarena-menu.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/alienarena-qal.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/alienarena-qmenu.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/alienarena-snd_file.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/alienarena-snd_openal.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/alienarena-q_shared.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/alienarena_ded-q_shared.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/c_cam.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/g_ai.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/g_chase.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/g_cmds.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/g_combat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/g_cow.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/g_ctf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/g_deathball.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/g_deathray.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/g_func.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/g_items.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/g_main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/g_misc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/g_monster.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/g_phys.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/g_save.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/g_spawn.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/g_spider.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/g_svcmds.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/g_target.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/g_trigger.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/g_unlagged.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/g_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/g_vehicles.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/g_weapon.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/m_move.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/p_client.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/p_hud.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/p_trail.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/p_view.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/p_weapon.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/$(DEPDIR)/q_shared.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/acesrc/$(DEPDIR)/acebot_ai.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/acesrc/$(DEPDIR)/acebot_cmds.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/acesrc/$(DEPDIR)/acebot_items.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/acesrc/$(DEPDIR)/acebot_movement.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/acesrc/$(DEPDIR)/acebot_nodes.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@game/acesrc/$(DEPDIR)/acebot_spawn.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@null/$(DEPDIR)/alienarena_ded-cl_null.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@qcommon/$(DEPDIR)/alienarena-cmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@qcommon/$(DEPDIR)/alienarena-cmodel.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@qcommon/$(DEPDIR)/alienarena-common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@qcommon/$(DEPDIR)/alienarena-crc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@qcommon/$(DEPDIR)/alienarena-cvar.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@qcommon/$(DEPDIR)/alienarena-files.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@qcommon/$(DEPDIR)/alienarena-htable.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@qcommon/$(DEPDIR)/alienarena-md5.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@qcommon/$(DEPDIR)/alienarena-mdfour.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@qcommon/$(DEPDIR)/alienarena-net_chan.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@qcommon/$(DEPDIR)/alienarena-pmove.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@qcommon/$(DEPDIR)/alienarena_ded-cmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@qcommon/$(DEPDIR)/alienarena_ded-cmodel.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@qcommon/$(DEPDIR)/alienarena_ded-common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@qcommon/$(DEPDIR)/alienarena_ded-crc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@qcommon/$(DEPDIR)/alienarena_ded-cvar.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@qcommon/$(DEPDIR)/alienarena_ded-files.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@qcommon/$(DEPDIR)/alienarena_ded-htable.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@qcommon/$(DEPDIR)/alienarena_ded-mdfour.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@qcommon/$(DEPDIR)/alienarena_ded-net_chan.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@qcommon/$(DEPDIR)/alienarena_ded-pmove.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ref_gl/$(DEPDIR)/alienarena-r_bloom.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ref_gl/$(DEPDIR)/alienarena-r_draw.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ref_gl/$(DEPDIR)/alienarena-r_image.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ref_gl/$(DEPDIR)/alienarena-r_iqm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ref_gl/$(DEPDIR)/alienarena-r_light.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ref_gl/$(DEPDIR)/alienarena-r_main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ref_gl/$(DEPDIR)/alienarena-r_math.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ref_gl/$(DEPDIR)/alienarena-r_mesh.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ref_gl/$(DEPDIR)/alienarena-r_misc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ref_gl/$(DEPDIR)/alienarena-r_model.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ref_gl/$(DEPDIR)/alienarena-r_particle.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ref_gl/$(DEPDIR)/alienarena-r_postprocess.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ref_gl/$(DEPDIR)/alienarena-r_program.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ref_gl/$(DEPDIR)/alienarena-r_ragdoll.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ref_gl/$(DEPDIR)/alienarena-r_script.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ref_gl/$(DEPDIR)/alienarena-r_shadowmaps.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ref_gl/$(DEPDIR)/alienarena-r_shadows.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ref_gl/$(DEPDIR)/alienarena-r_surf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ref_gl/$(DEPDIR)/alienarena-r_text.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ref_gl/$(DEPDIR)/alienarena-r_ttf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ref_gl/$(DEPDIR)/alienarena-r_varray.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ref_gl/$(DEPDIR)/alienarena-r_vbo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ref_gl/$(DEPDIR)/alienarena-r_vlights.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ref_gl/$(DEPDIR)/alienarena-r_warp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@server/$(DEPDIR)/alienarena-sv_ccmds.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@server/$(DEPDIR)/alienarena-sv_ents.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@server/$(DEPDIR)/alienarena-sv_game.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@server/$(DEPDIR)/alienarena-sv_init.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@server/$(DEPDIR)/alienarena-sv_main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@server/$(DEPDIR)/alienarena-sv_send.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@server/$(DEPDIR)/alienarena-sv_user.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@server/$(DEPDIR)/alienarena-sv_world.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@server/$(DEPDIR)/alienarena_ded-sv_ccmds.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@server/$(DEPDIR)/alienarena_ded-sv_ents.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@server/$(DEPDIR)/alienarena_ded-sv_game.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@server/$(DEPDIR)/alienarena_ded-sv_init.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@server/$(DEPDIR)/alienarena_ded-sv_main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@server/$(DEPDIR)/alienarena_ded-sv_send.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@server/$(DEPDIR)/alienarena_ded-sv_user.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@server/$(DEPDIR)/alienarena_ded-sv_world.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/$(DEPDIR)/alienarena-gl_glx.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/$(DEPDIR)/alienarena-glob.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/$(DEPDIR)/alienarena-net_udp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/$(DEPDIR)/alienarena-q_shunix.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/$(DEPDIR)/alienarena-qal_unix.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/$(DEPDIR)/alienarena-qgl_unix.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/$(DEPDIR)/alienarena-rw_unix.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/$(DEPDIR)/alienarena-sys_unix.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/$(DEPDIR)/alienarena-vid_so.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/$(DEPDIR)/alienarena_ded-glob.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/$(DEPDIR)/alienarena_ded-net_udp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/$(DEPDIR)/alienarena_ded-q_shunix.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/$(DEPDIR)/alienarena_ded-sys_unix.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-array.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-box.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-capsule.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_box.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_plane.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_sphere.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_trimesh.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-collision_kernel.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-collision_quadtreespace.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-collision_sapspace.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-collision_space.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-collision_transform.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_box.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_ccylinder.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_disabled.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_distance.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_opcode.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_plane.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_ray.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_sphere.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_trimesh.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_trimesh_new.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-collision_util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-convex.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-cylinder.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-error.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-export-dif.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-fastdot.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-fastldlt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-fastlsolve.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-fastltsolve.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-heightfield.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-lcp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-mass.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-mat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-matrix.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-memory.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-misc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-obstack.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-ode.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-odeinit.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-odemath.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-plane.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-quickstep.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-ray.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-rotation.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-sphere.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-step.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-stepfast.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-testing.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-timer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/$(DEPDIR)/libode_a-util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_AABBCollider.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_AABBTree.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_BaseModel.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Collider.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_HybridModel.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_LSSCollider.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_MeshInterface.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Model.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_OBBCollider.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_OptimizedTree.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Picking.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_PlanesCollider.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_RayCollider.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_SphereCollider.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_TreeBuilders.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_TreeCollider.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_VolumeCollider.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/$(DEPDIR)/libode_a-Opcode.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceAABB.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceContainer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceHPoint.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceIndexedTriangle.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceMatrix3x3.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceMatrix4x4.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceOBB.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IcePlane.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IcePoint.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceRandom.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceRay.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceRevisitedRadix.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceSegment.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceTriangle.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceUtils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/joints/$(DEPDIR)/libode_a-amotor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/joints/$(DEPDIR)/libode_a-ball.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/joints/$(DEPDIR)/libode_a-contact.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/joints/$(DEPDIR)/libode_a-fixed.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/joints/$(DEPDIR)/libode_a-hinge.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/joints/$(DEPDIR)/libode_a-hinge2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/joints/$(DEPDIR)/libode_a-joint.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/joints/$(DEPDIR)/libode_a-lmotor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/joints/$(DEPDIR)/libode_a-null.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/joints/$(DEPDIR)/libode_a-piston.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/joints/$(DEPDIR)/libode_a-plane2d.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/joints/$(DEPDIR)/libode_a-pr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/joints/$(DEPDIR)/libode_a-pu.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/joints/$(DEPDIR)/libode_a-slider.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unix/odesrc/joints/$(DEPDIR)/libode_a-universal.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@win32/$(DEPDIR)/alienarena-conproc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@win32/$(DEPDIR)/alienarena-glw_imp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@win32/$(DEPDIR)/alienarena-in_win.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@win32/$(DEPDIR)/alienarena-net_wins.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@win32/$(DEPDIR)/alienarena-q_shwin.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@win32/$(DEPDIR)/alienarena-qal_win.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@win32/$(DEPDIR)/alienarena-qgl_win.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@win32/$(DEPDIR)/alienarena-sys_win.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@win32/$(DEPDIR)/alienarena-vid_dll.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` unix/odesrc/libode_a-fastldlt.o: unix/odesrc/fastldlt.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/odesrc/libode_a-fastldlt.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-fastldlt.Tpo -c -o unix/odesrc/libode_a-fastldlt.o `test -f 'unix/odesrc/fastldlt.c' || echo '$(srcdir)/'`unix/odesrc/fastldlt.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-fastldlt.Tpo unix/odesrc/$(DEPDIR)/libode_a-fastldlt.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/odesrc/fastldlt.c' object='unix/odesrc/libode_a-fastldlt.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/odesrc/libode_a-fastldlt.o `test -f 'unix/odesrc/fastldlt.c' || echo '$(srcdir)/'`unix/odesrc/fastldlt.c unix/odesrc/libode_a-fastldlt.obj: unix/odesrc/fastldlt.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/odesrc/libode_a-fastldlt.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-fastldlt.Tpo -c -o unix/odesrc/libode_a-fastldlt.obj `if test -f 'unix/odesrc/fastldlt.c'; then $(CYGPATH_W) 'unix/odesrc/fastldlt.c'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/fastldlt.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-fastldlt.Tpo unix/odesrc/$(DEPDIR)/libode_a-fastldlt.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/odesrc/fastldlt.c' object='unix/odesrc/libode_a-fastldlt.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/odesrc/libode_a-fastldlt.obj `if test -f 'unix/odesrc/fastldlt.c'; then $(CYGPATH_W) 'unix/odesrc/fastldlt.c'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/fastldlt.c'; fi` unix/odesrc/libode_a-fastltsolve.o: unix/odesrc/fastltsolve.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/odesrc/libode_a-fastltsolve.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-fastltsolve.Tpo -c -o unix/odesrc/libode_a-fastltsolve.o `test -f 'unix/odesrc/fastltsolve.c' || echo '$(srcdir)/'`unix/odesrc/fastltsolve.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-fastltsolve.Tpo unix/odesrc/$(DEPDIR)/libode_a-fastltsolve.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/odesrc/fastltsolve.c' object='unix/odesrc/libode_a-fastltsolve.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/odesrc/libode_a-fastltsolve.o `test -f 'unix/odesrc/fastltsolve.c' || echo '$(srcdir)/'`unix/odesrc/fastltsolve.c unix/odesrc/libode_a-fastltsolve.obj: unix/odesrc/fastltsolve.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/odesrc/libode_a-fastltsolve.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-fastltsolve.Tpo -c -o unix/odesrc/libode_a-fastltsolve.obj `if test -f 'unix/odesrc/fastltsolve.c'; then $(CYGPATH_W) 'unix/odesrc/fastltsolve.c'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/fastltsolve.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-fastltsolve.Tpo unix/odesrc/$(DEPDIR)/libode_a-fastltsolve.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/odesrc/fastltsolve.c' object='unix/odesrc/libode_a-fastltsolve.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/odesrc/libode_a-fastltsolve.obj `if test -f 'unix/odesrc/fastltsolve.c'; then $(CYGPATH_W) 'unix/odesrc/fastltsolve.c'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/fastltsolve.c'; fi` unix/odesrc/libode_a-fastdot.o: unix/odesrc/fastdot.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/odesrc/libode_a-fastdot.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-fastdot.Tpo -c -o unix/odesrc/libode_a-fastdot.o `test -f 'unix/odesrc/fastdot.c' || echo '$(srcdir)/'`unix/odesrc/fastdot.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-fastdot.Tpo unix/odesrc/$(DEPDIR)/libode_a-fastdot.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/odesrc/fastdot.c' object='unix/odesrc/libode_a-fastdot.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/odesrc/libode_a-fastdot.o `test -f 'unix/odesrc/fastdot.c' || echo '$(srcdir)/'`unix/odesrc/fastdot.c unix/odesrc/libode_a-fastdot.obj: unix/odesrc/fastdot.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/odesrc/libode_a-fastdot.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-fastdot.Tpo -c -o unix/odesrc/libode_a-fastdot.obj `if test -f 'unix/odesrc/fastdot.c'; then $(CYGPATH_W) 'unix/odesrc/fastdot.c'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/fastdot.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-fastdot.Tpo unix/odesrc/$(DEPDIR)/libode_a-fastdot.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/odesrc/fastdot.c' object='unix/odesrc/libode_a-fastdot.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/odesrc/libode_a-fastdot.obj `if test -f 'unix/odesrc/fastdot.c'; then $(CYGPATH_W) 'unix/odesrc/fastdot.c'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/fastdot.c'; fi` unix/odesrc/libode_a-fastlsolve.o: unix/odesrc/fastlsolve.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/odesrc/libode_a-fastlsolve.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-fastlsolve.Tpo -c -o unix/odesrc/libode_a-fastlsolve.o `test -f 'unix/odesrc/fastlsolve.c' || echo '$(srcdir)/'`unix/odesrc/fastlsolve.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-fastlsolve.Tpo unix/odesrc/$(DEPDIR)/libode_a-fastlsolve.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/odesrc/fastlsolve.c' object='unix/odesrc/libode_a-fastlsolve.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/odesrc/libode_a-fastlsolve.o `test -f 'unix/odesrc/fastlsolve.c' || echo '$(srcdir)/'`unix/odesrc/fastlsolve.c unix/odesrc/libode_a-fastlsolve.obj: unix/odesrc/fastlsolve.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/odesrc/libode_a-fastlsolve.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-fastlsolve.Tpo -c -o unix/odesrc/libode_a-fastlsolve.obj `if test -f 'unix/odesrc/fastlsolve.c'; then $(CYGPATH_W) 'unix/odesrc/fastlsolve.c'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/fastlsolve.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-fastlsolve.Tpo unix/odesrc/$(DEPDIR)/libode_a-fastlsolve.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/odesrc/fastlsolve.c' object='unix/odesrc/libode_a-fastlsolve.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/odesrc/libode_a-fastlsolve.obj `if test -f 'unix/odesrc/fastlsolve.c'; then $(CYGPATH_W) 'unix/odesrc/fastlsolve.c'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/fastlsolve.c'; fi` client/alienarena-cl_ents.o: client/cl_ents.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_ents.o -MD -MP -MF client/$(DEPDIR)/alienarena-cl_ents.Tpo -c -o client/alienarena-cl_ents.o `test -f 'client/cl_ents.c' || echo '$(srcdir)/'`client/cl_ents.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_ents.Tpo client/$(DEPDIR)/alienarena-cl_ents.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_ents.c' object='client/alienarena-cl_ents.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_ents.o `test -f 'client/cl_ents.c' || echo '$(srcdir)/'`client/cl_ents.c client/alienarena-cl_ents.obj: client/cl_ents.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_ents.obj -MD -MP -MF client/$(DEPDIR)/alienarena-cl_ents.Tpo -c -o client/alienarena-cl_ents.obj `if test -f 'client/cl_ents.c'; then $(CYGPATH_W) 'client/cl_ents.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_ents.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_ents.Tpo client/$(DEPDIR)/alienarena-cl_ents.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_ents.c' object='client/alienarena-cl_ents.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_ents.obj `if test -f 'client/cl_ents.c'; then $(CYGPATH_W) 'client/cl_ents.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_ents.c'; fi` client/alienarena-cl_fx.o: client/cl_fx.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_fx.o -MD -MP -MF client/$(DEPDIR)/alienarena-cl_fx.Tpo -c -o client/alienarena-cl_fx.o `test -f 'client/cl_fx.c' || echo '$(srcdir)/'`client/cl_fx.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_fx.Tpo client/$(DEPDIR)/alienarena-cl_fx.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_fx.c' object='client/alienarena-cl_fx.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_fx.o `test -f 'client/cl_fx.c' || echo '$(srcdir)/'`client/cl_fx.c client/alienarena-cl_fx.obj: client/cl_fx.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_fx.obj -MD -MP -MF client/$(DEPDIR)/alienarena-cl_fx.Tpo -c -o client/alienarena-cl_fx.obj `if test -f 'client/cl_fx.c'; then $(CYGPATH_W) 'client/cl_fx.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_fx.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_fx.Tpo client/$(DEPDIR)/alienarena-cl_fx.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_fx.c' object='client/alienarena-cl_fx.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_fx.obj `if test -f 'client/cl_fx.c'; then $(CYGPATH_W) 'client/cl_fx.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_fx.c'; fi` client/alienarena-cl_http.o: client/cl_http.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_http.o -MD -MP -MF client/$(DEPDIR)/alienarena-cl_http.Tpo -c -o client/alienarena-cl_http.o `test -f 'client/cl_http.c' || echo '$(srcdir)/'`client/cl_http.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_http.Tpo client/$(DEPDIR)/alienarena-cl_http.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_http.c' object='client/alienarena-cl_http.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_http.o `test -f 'client/cl_http.c' || echo '$(srcdir)/'`client/cl_http.c client/alienarena-cl_http.obj: client/cl_http.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_http.obj -MD -MP -MF client/$(DEPDIR)/alienarena-cl_http.Tpo -c -o client/alienarena-cl_http.obj `if test -f 'client/cl_http.c'; then $(CYGPATH_W) 'client/cl_http.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_http.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_http.Tpo client/$(DEPDIR)/alienarena-cl_http.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_http.c' object='client/alienarena-cl_http.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_http.obj `if test -f 'client/cl_http.c'; then $(CYGPATH_W) 'client/cl_http.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_http.c'; fi` client/alienarena-cl_input.o: client/cl_input.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_input.o -MD -MP -MF client/$(DEPDIR)/alienarena-cl_input.Tpo -c -o client/alienarena-cl_input.o `test -f 'client/cl_input.c' || echo '$(srcdir)/'`client/cl_input.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_input.Tpo client/$(DEPDIR)/alienarena-cl_input.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_input.c' object='client/alienarena-cl_input.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_input.o `test -f 'client/cl_input.c' || echo '$(srcdir)/'`client/cl_input.c client/alienarena-cl_input.obj: client/cl_input.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_input.obj -MD -MP -MF client/$(DEPDIR)/alienarena-cl_input.Tpo -c -o client/alienarena-cl_input.obj `if test -f 'client/cl_input.c'; then $(CYGPATH_W) 'client/cl_input.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_input.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_input.Tpo client/$(DEPDIR)/alienarena-cl_input.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_input.c' object='client/alienarena-cl_input.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_input.obj `if test -f 'client/cl_input.c'; then $(CYGPATH_W) 'client/cl_input.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_input.c'; fi` client/alienarena-cl_inv.o: client/cl_inv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_inv.o -MD -MP -MF client/$(DEPDIR)/alienarena-cl_inv.Tpo -c -o client/alienarena-cl_inv.o `test -f 'client/cl_inv.c' || echo '$(srcdir)/'`client/cl_inv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_inv.Tpo client/$(DEPDIR)/alienarena-cl_inv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_inv.c' object='client/alienarena-cl_inv.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_inv.o `test -f 'client/cl_inv.c' || echo '$(srcdir)/'`client/cl_inv.c client/alienarena-cl_inv.obj: client/cl_inv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_inv.obj -MD -MP -MF client/$(DEPDIR)/alienarena-cl_inv.Tpo -c -o client/alienarena-cl_inv.obj `if test -f 'client/cl_inv.c'; then $(CYGPATH_W) 'client/cl_inv.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_inv.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_inv.Tpo client/$(DEPDIR)/alienarena-cl_inv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_inv.c' object='client/alienarena-cl_inv.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_inv.obj `if test -f 'client/cl_inv.c'; then $(CYGPATH_W) 'client/cl_inv.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_inv.c'; fi` client/alienarena-cl_irc.o: client/cl_irc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_irc.o -MD -MP -MF client/$(DEPDIR)/alienarena-cl_irc.Tpo -c -o client/alienarena-cl_irc.o `test -f 'client/cl_irc.c' || echo '$(srcdir)/'`client/cl_irc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_irc.Tpo client/$(DEPDIR)/alienarena-cl_irc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_irc.c' object='client/alienarena-cl_irc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_irc.o `test -f 'client/cl_irc.c' || echo '$(srcdir)/'`client/cl_irc.c client/alienarena-cl_irc.obj: client/cl_irc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_irc.obj -MD -MP -MF client/$(DEPDIR)/alienarena-cl_irc.Tpo -c -o client/alienarena-cl_irc.obj `if test -f 'client/cl_irc.c'; then $(CYGPATH_W) 'client/cl_irc.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_irc.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_irc.Tpo client/$(DEPDIR)/alienarena-cl_irc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_irc.c' object='client/alienarena-cl_irc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_irc.obj `if test -f 'client/cl_irc.c'; then $(CYGPATH_W) 'client/cl_irc.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_irc.c'; fi` client/alienarena-cl_main.o: client/cl_main.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_main.o -MD -MP -MF client/$(DEPDIR)/alienarena-cl_main.Tpo -c -o client/alienarena-cl_main.o `test -f 'client/cl_main.c' || echo '$(srcdir)/'`client/cl_main.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_main.Tpo client/$(DEPDIR)/alienarena-cl_main.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_main.c' object='client/alienarena-cl_main.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_main.o `test -f 'client/cl_main.c' || echo '$(srcdir)/'`client/cl_main.c client/alienarena-cl_main.obj: client/cl_main.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_main.obj -MD -MP -MF client/$(DEPDIR)/alienarena-cl_main.Tpo -c -o client/alienarena-cl_main.obj `if test -f 'client/cl_main.c'; then $(CYGPATH_W) 'client/cl_main.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_main.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_main.Tpo client/$(DEPDIR)/alienarena-cl_main.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_main.c' object='client/alienarena-cl_main.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_main.obj `if test -f 'client/cl_main.c'; then $(CYGPATH_W) 'client/cl_main.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_main.c'; fi` client/alienarena-cl_parse.o: client/cl_parse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_parse.o -MD -MP -MF client/$(DEPDIR)/alienarena-cl_parse.Tpo -c -o client/alienarena-cl_parse.o `test -f 'client/cl_parse.c' || echo '$(srcdir)/'`client/cl_parse.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_parse.Tpo client/$(DEPDIR)/alienarena-cl_parse.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_parse.c' object='client/alienarena-cl_parse.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_parse.o `test -f 'client/cl_parse.c' || echo '$(srcdir)/'`client/cl_parse.c client/alienarena-cl_parse.obj: client/cl_parse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_parse.obj -MD -MP -MF client/$(DEPDIR)/alienarena-cl_parse.Tpo -c -o client/alienarena-cl_parse.obj `if test -f 'client/cl_parse.c'; then $(CYGPATH_W) 'client/cl_parse.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_parse.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_parse.Tpo client/$(DEPDIR)/alienarena-cl_parse.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_parse.c' object='client/alienarena-cl_parse.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_parse.obj `if test -f 'client/cl_parse.c'; then $(CYGPATH_W) 'client/cl_parse.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_parse.c'; fi` client/alienarena-cl_pred.o: client/cl_pred.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_pred.o -MD -MP -MF client/$(DEPDIR)/alienarena-cl_pred.Tpo -c -o client/alienarena-cl_pred.o `test -f 'client/cl_pred.c' || echo '$(srcdir)/'`client/cl_pred.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_pred.Tpo client/$(DEPDIR)/alienarena-cl_pred.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_pred.c' object='client/alienarena-cl_pred.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_pred.o `test -f 'client/cl_pred.c' || echo '$(srcdir)/'`client/cl_pred.c client/alienarena-cl_pred.obj: client/cl_pred.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_pred.obj -MD -MP -MF client/$(DEPDIR)/alienarena-cl_pred.Tpo -c -o client/alienarena-cl_pred.obj `if test -f 'client/cl_pred.c'; then $(CYGPATH_W) 'client/cl_pred.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_pred.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_pred.Tpo client/$(DEPDIR)/alienarena-cl_pred.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_pred.c' object='client/alienarena-cl_pred.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_pred.obj `if test -f 'client/cl_pred.c'; then $(CYGPATH_W) 'client/cl_pred.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_pred.c'; fi` client/alienarena-cl_scrn.o: client/cl_scrn.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_scrn.o -MD -MP -MF client/$(DEPDIR)/alienarena-cl_scrn.Tpo -c -o client/alienarena-cl_scrn.o `test -f 'client/cl_scrn.c' || echo '$(srcdir)/'`client/cl_scrn.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_scrn.Tpo client/$(DEPDIR)/alienarena-cl_scrn.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_scrn.c' object='client/alienarena-cl_scrn.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_scrn.o `test -f 'client/cl_scrn.c' || echo '$(srcdir)/'`client/cl_scrn.c client/alienarena-cl_scrn.obj: client/cl_scrn.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_scrn.obj -MD -MP -MF client/$(DEPDIR)/alienarena-cl_scrn.Tpo -c -o client/alienarena-cl_scrn.obj `if test -f 'client/cl_scrn.c'; then $(CYGPATH_W) 'client/cl_scrn.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_scrn.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_scrn.Tpo client/$(DEPDIR)/alienarena-cl_scrn.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_scrn.c' object='client/alienarena-cl_scrn.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_scrn.obj `if test -f 'client/cl_scrn.c'; then $(CYGPATH_W) 'client/cl_scrn.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_scrn.c'; fi` client/alienarena-cl_stats.o: client/cl_stats.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_stats.o -MD -MP -MF client/$(DEPDIR)/alienarena-cl_stats.Tpo -c -o client/alienarena-cl_stats.o `test -f 'client/cl_stats.c' || echo '$(srcdir)/'`client/cl_stats.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_stats.Tpo client/$(DEPDIR)/alienarena-cl_stats.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_stats.c' object='client/alienarena-cl_stats.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_stats.o `test -f 'client/cl_stats.c' || echo '$(srcdir)/'`client/cl_stats.c client/alienarena-cl_stats.obj: client/cl_stats.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_stats.obj -MD -MP -MF client/$(DEPDIR)/alienarena-cl_stats.Tpo -c -o client/alienarena-cl_stats.obj `if test -f 'client/cl_stats.c'; then $(CYGPATH_W) 'client/cl_stats.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_stats.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_stats.Tpo client/$(DEPDIR)/alienarena-cl_stats.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_stats.c' object='client/alienarena-cl_stats.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_stats.obj `if test -f 'client/cl_stats.c'; then $(CYGPATH_W) 'client/cl_stats.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_stats.c'; fi` client/alienarena-cl_updates.o: client/cl_updates.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_updates.o -MD -MP -MF client/$(DEPDIR)/alienarena-cl_updates.Tpo -c -o client/alienarena-cl_updates.o `test -f 'client/cl_updates.c' || echo '$(srcdir)/'`client/cl_updates.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_updates.Tpo client/$(DEPDIR)/alienarena-cl_updates.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_updates.c' object='client/alienarena-cl_updates.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_updates.o `test -f 'client/cl_updates.c' || echo '$(srcdir)/'`client/cl_updates.c client/alienarena-cl_updates.obj: client/cl_updates.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_updates.obj -MD -MP -MF client/$(DEPDIR)/alienarena-cl_updates.Tpo -c -o client/alienarena-cl_updates.obj `if test -f 'client/cl_updates.c'; then $(CYGPATH_W) 'client/cl_updates.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_updates.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_updates.Tpo client/$(DEPDIR)/alienarena-cl_updates.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_updates.c' object='client/alienarena-cl_updates.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_updates.obj `if test -f 'client/cl_updates.c'; then $(CYGPATH_W) 'client/cl_updates.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_updates.c'; fi` client/alienarena-cl_tent.o: client/cl_tent.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_tent.o -MD -MP -MF client/$(DEPDIR)/alienarena-cl_tent.Tpo -c -o client/alienarena-cl_tent.o `test -f 'client/cl_tent.c' || echo '$(srcdir)/'`client/cl_tent.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_tent.Tpo client/$(DEPDIR)/alienarena-cl_tent.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_tent.c' object='client/alienarena-cl_tent.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_tent.o `test -f 'client/cl_tent.c' || echo '$(srcdir)/'`client/cl_tent.c client/alienarena-cl_tent.obj: client/cl_tent.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_tent.obj -MD -MP -MF client/$(DEPDIR)/alienarena-cl_tent.Tpo -c -o client/alienarena-cl_tent.obj `if test -f 'client/cl_tent.c'; then $(CYGPATH_W) 'client/cl_tent.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_tent.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_tent.Tpo client/$(DEPDIR)/alienarena-cl_tent.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_tent.c' object='client/alienarena-cl_tent.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_tent.obj `if test -f 'client/cl_tent.c'; then $(CYGPATH_W) 'client/cl_tent.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_tent.c'; fi` client/alienarena-cl_view.o: client/cl_view.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_view.o -MD -MP -MF client/$(DEPDIR)/alienarena-cl_view.Tpo -c -o client/alienarena-cl_view.o `test -f 'client/cl_view.c' || echo '$(srcdir)/'`client/cl_view.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_view.Tpo client/$(DEPDIR)/alienarena-cl_view.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_view.c' object='client/alienarena-cl_view.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_view.o `test -f 'client/cl_view.c' || echo '$(srcdir)/'`client/cl_view.c client/alienarena-cl_view.obj: client/cl_view.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-cl_view.obj -MD -MP -MF client/$(DEPDIR)/alienarena-cl_view.Tpo -c -o client/alienarena-cl_view.obj `if test -f 'client/cl_view.c'; then $(CYGPATH_W) 'client/cl_view.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_view.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-cl_view.Tpo client/$(DEPDIR)/alienarena-cl_view.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/cl_view.c' object='client/alienarena-cl_view.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-cl_view.obj `if test -f 'client/cl_view.c'; then $(CYGPATH_W) 'client/cl_view.c'; else $(CYGPATH_W) '$(srcdir)/client/cl_view.c'; fi` client/alienarena-console.o: client/console.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-console.o -MD -MP -MF client/$(DEPDIR)/alienarena-console.Tpo -c -o client/alienarena-console.o `test -f 'client/console.c' || echo '$(srcdir)/'`client/console.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-console.Tpo client/$(DEPDIR)/alienarena-console.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/console.c' object='client/alienarena-console.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-console.o `test -f 'client/console.c' || echo '$(srcdir)/'`client/console.c client/alienarena-console.obj: client/console.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-console.obj -MD -MP -MF client/$(DEPDIR)/alienarena-console.Tpo -c -o client/alienarena-console.obj `if test -f 'client/console.c'; then $(CYGPATH_W) 'client/console.c'; else $(CYGPATH_W) '$(srcdir)/client/console.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-console.Tpo client/$(DEPDIR)/alienarena-console.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/console.c' object='client/alienarena-console.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-console.obj `if test -f 'client/console.c'; then $(CYGPATH_W) 'client/console.c'; else $(CYGPATH_W) '$(srcdir)/client/console.c'; fi` client/alienarena-keys.o: client/keys.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-keys.o -MD -MP -MF client/$(DEPDIR)/alienarena-keys.Tpo -c -o client/alienarena-keys.o `test -f 'client/keys.c' || echo '$(srcdir)/'`client/keys.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-keys.Tpo client/$(DEPDIR)/alienarena-keys.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/keys.c' object='client/alienarena-keys.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-keys.o `test -f 'client/keys.c' || echo '$(srcdir)/'`client/keys.c client/alienarena-keys.obj: client/keys.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-keys.obj -MD -MP -MF client/$(DEPDIR)/alienarena-keys.Tpo -c -o client/alienarena-keys.obj `if test -f 'client/keys.c'; then $(CYGPATH_W) 'client/keys.c'; else $(CYGPATH_W) '$(srcdir)/client/keys.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-keys.Tpo client/$(DEPDIR)/alienarena-keys.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/keys.c' object='client/alienarena-keys.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-keys.obj `if test -f 'client/keys.c'; then $(CYGPATH_W) 'client/keys.c'; else $(CYGPATH_W) '$(srcdir)/client/keys.c'; fi` client/alienarena-menu.o: client/menu.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-menu.o -MD -MP -MF client/$(DEPDIR)/alienarena-menu.Tpo -c -o client/alienarena-menu.o `test -f 'client/menu.c' || echo '$(srcdir)/'`client/menu.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-menu.Tpo client/$(DEPDIR)/alienarena-menu.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/menu.c' object='client/alienarena-menu.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-menu.o `test -f 'client/menu.c' || echo '$(srcdir)/'`client/menu.c client/alienarena-menu.obj: client/menu.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-menu.obj -MD -MP -MF client/$(DEPDIR)/alienarena-menu.Tpo -c -o client/alienarena-menu.obj `if test -f 'client/menu.c'; then $(CYGPATH_W) 'client/menu.c'; else $(CYGPATH_W) '$(srcdir)/client/menu.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-menu.Tpo client/$(DEPDIR)/alienarena-menu.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/menu.c' object='client/alienarena-menu.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-menu.obj `if test -f 'client/menu.c'; then $(CYGPATH_W) 'client/menu.c'; else $(CYGPATH_W) '$(srcdir)/client/menu.c'; fi` client/alienarena-qal.o: client/qal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-qal.o -MD -MP -MF client/$(DEPDIR)/alienarena-qal.Tpo -c -o client/alienarena-qal.o `test -f 'client/qal.c' || echo '$(srcdir)/'`client/qal.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-qal.Tpo client/$(DEPDIR)/alienarena-qal.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/qal.c' object='client/alienarena-qal.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-qal.o `test -f 'client/qal.c' || echo '$(srcdir)/'`client/qal.c client/alienarena-qal.obj: client/qal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-qal.obj -MD -MP -MF client/$(DEPDIR)/alienarena-qal.Tpo -c -o client/alienarena-qal.obj `if test -f 'client/qal.c'; then $(CYGPATH_W) 'client/qal.c'; else $(CYGPATH_W) '$(srcdir)/client/qal.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-qal.Tpo client/$(DEPDIR)/alienarena-qal.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/qal.c' object='client/alienarena-qal.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-qal.obj `if test -f 'client/qal.c'; then $(CYGPATH_W) 'client/qal.c'; else $(CYGPATH_W) '$(srcdir)/client/qal.c'; fi` client/alienarena-qmenu.o: client/qmenu.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-qmenu.o -MD -MP -MF client/$(DEPDIR)/alienarena-qmenu.Tpo -c -o client/alienarena-qmenu.o `test -f 'client/qmenu.c' || echo '$(srcdir)/'`client/qmenu.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-qmenu.Tpo client/$(DEPDIR)/alienarena-qmenu.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/qmenu.c' object='client/alienarena-qmenu.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-qmenu.o `test -f 'client/qmenu.c' || echo '$(srcdir)/'`client/qmenu.c client/alienarena-qmenu.obj: client/qmenu.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-qmenu.obj -MD -MP -MF client/$(DEPDIR)/alienarena-qmenu.Tpo -c -o client/alienarena-qmenu.obj `if test -f 'client/qmenu.c'; then $(CYGPATH_W) 'client/qmenu.c'; else $(CYGPATH_W) '$(srcdir)/client/qmenu.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-qmenu.Tpo client/$(DEPDIR)/alienarena-qmenu.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/qmenu.c' object='client/alienarena-qmenu.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-qmenu.obj `if test -f 'client/qmenu.c'; then $(CYGPATH_W) 'client/qmenu.c'; else $(CYGPATH_W) '$(srcdir)/client/qmenu.c'; fi` client/alienarena-snd_file.o: client/snd_file.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-snd_file.o -MD -MP -MF client/$(DEPDIR)/alienarena-snd_file.Tpo -c -o client/alienarena-snd_file.o `test -f 'client/snd_file.c' || echo '$(srcdir)/'`client/snd_file.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-snd_file.Tpo client/$(DEPDIR)/alienarena-snd_file.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/snd_file.c' object='client/alienarena-snd_file.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-snd_file.o `test -f 'client/snd_file.c' || echo '$(srcdir)/'`client/snd_file.c client/alienarena-snd_file.obj: client/snd_file.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-snd_file.obj -MD -MP -MF client/$(DEPDIR)/alienarena-snd_file.Tpo -c -o client/alienarena-snd_file.obj `if test -f 'client/snd_file.c'; then $(CYGPATH_W) 'client/snd_file.c'; else $(CYGPATH_W) '$(srcdir)/client/snd_file.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-snd_file.Tpo client/$(DEPDIR)/alienarena-snd_file.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/snd_file.c' object='client/alienarena-snd_file.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-snd_file.obj `if test -f 'client/snd_file.c'; then $(CYGPATH_W) 'client/snd_file.c'; else $(CYGPATH_W) '$(srcdir)/client/snd_file.c'; fi` client/alienarena-snd_openal.o: client/snd_openal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-snd_openal.o -MD -MP -MF client/$(DEPDIR)/alienarena-snd_openal.Tpo -c -o client/alienarena-snd_openal.o `test -f 'client/snd_openal.c' || echo '$(srcdir)/'`client/snd_openal.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-snd_openal.Tpo client/$(DEPDIR)/alienarena-snd_openal.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/snd_openal.c' object='client/alienarena-snd_openal.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-snd_openal.o `test -f 'client/snd_openal.c' || echo '$(srcdir)/'`client/snd_openal.c client/alienarena-snd_openal.obj: client/snd_openal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/alienarena-snd_openal.obj -MD -MP -MF client/$(DEPDIR)/alienarena-snd_openal.Tpo -c -o client/alienarena-snd_openal.obj `if test -f 'client/snd_openal.c'; then $(CYGPATH_W) 'client/snd_openal.c'; else $(CYGPATH_W) '$(srcdir)/client/snd_openal.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/alienarena-snd_openal.Tpo client/$(DEPDIR)/alienarena-snd_openal.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='client/snd_openal.c' object='client/alienarena-snd_openal.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/alienarena-snd_openal.obj `if test -f 'client/snd_openal.c'; then $(CYGPATH_W) 'client/snd_openal.c'; else $(CYGPATH_W) '$(srcdir)/client/snd_openal.c'; fi` game/alienarena-q_shared.o: game/q_shared.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT game/alienarena-q_shared.o -MD -MP -MF game/$(DEPDIR)/alienarena-q_shared.Tpo -c -o game/alienarena-q_shared.o `test -f 'game/q_shared.c' || echo '$(srcdir)/'`game/q_shared.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) game/$(DEPDIR)/alienarena-q_shared.Tpo game/$(DEPDIR)/alienarena-q_shared.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='game/q_shared.c' object='game/alienarena-q_shared.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o game/alienarena-q_shared.o `test -f 'game/q_shared.c' || echo '$(srcdir)/'`game/q_shared.c game/alienarena-q_shared.obj: game/q_shared.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT game/alienarena-q_shared.obj -MD -MP -MF game/$(DEPDIR)/alienarena-q_shared.Tpo -c -o game/alienarena-q_shared.obj `if test -f 'game/q_shared.c'; then $(CYGPATH_W) 'game/q_shared.c'; else $(CYGPATH_W) '$(srcdir)/game/q_shared.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) game/$(DEPDIR)/alienarena-q_shared.Tpo game/$(DEPDIR)/alienarena-q_shared.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='game/q_shared.c' object='game/alienarena-q_shared.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o game/alienarena-q_shared.obj `if test -f 'game/q_shared.c'; then $(CYGPATH_W) 'game/q_shared.c'; else $(CYGPATH_W) '$(srcdir)/game/q_shared.c'; fi` qcommon/alienarena-cmd.o: qcommon/cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena-cmd.o -MD -MP -MF qcommon/$(DEPDIR)/alienarena-cmd.Tpo -c -o qcommon/alienarena-cmd.o `test -f 'qcommon/cmd.c' || echo '$(srcdir)/'`qcommon/cmd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena-cmd.Tpo qcommon/$(DEPDIR)/alienarena-cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/cmd.c' object='qcommon/alienarena-cmd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena-cmd.o `test -f 'qcommon/cmd.c' || echo '$(srcdir)/'`qcommon/cmd.c qcommon/alienarena-cmd.obj: qcommon/cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena-cmd.obj -MD -MP -MF qcommon/$(DEPDIR)/alienarena-cmd.Tpo -c -o qcommon/alienarena-cmd.obj `if test -f 'qcommon/cmd.c'; then $(CYGPATH_W) 'qcommon/cmd.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/cmd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena-cmd.Tpo qcommon/$(DEPDIR)/alienarena-cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/cmd.c' object='qcommon/alienarena-cmd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena-cmd.obj `if test -f 'qcommon/cmd.c'; then $(CYGPATH_W) 'qcommon/cmd.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/cmd.c'; fi` qcommon/alienarena-cmodel.o: qcommon/cmodel.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena-cmodel.o -MD -MP -MF qcommon/$(DEPDIR)/alienarena-cmodel.Tpo -c -o qcommon/alienarena-cmodel.o `test -f 'qcommon/cmodel.c' || echo '$(srcdir)/'`qcommon/cmodel.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena-cmodel.Tpo qcommon/$(DEPDIR)/alienarena-cmodel.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/cmodel.c' object='qcommon/alienarena-cmodel.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena-cmodel.o `test -f 'qcommon/cmodel.c' || echo '$(srcdir)/'`qcommon/cmodel.c qcommon/alienarena-cmodel.obj: qcommon/cmodel.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena-cmodel.obj -MD -MP -MF qcommon/$(DEPDIR)/alienarena-cmodel.Tpo -c -o qcommon/alienarena-cmodel.obj `if test -f 'qcommon/cmodel.c'; then $(CYGPATH_W) 'qcommon/cmodel.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/cmodel.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena-cmodel.Tpo qcommon/$(DEPDIR)/alienarena-cmodel.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/cmodel.c' object='qcommon/alienarena-cmodel.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena-cmodel.obj `if test -f 'qcommon/cmodel.c'; then $(CYGPATH_W) 'qcommon/cmodel.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/cmodel.c'; fi` qcommon/alienarena-common.o: qcommon/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena-common.o -MD -MP -MF qcommon/$(DEPDIR)/alienarena-common.Tpo -c -o qcommon/alienarena-common.o `test -f 'qcommon/common.c' || echo '$(srcdir)/'`qcommon/common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena-common.Tpo qcommon/$(DEPDIR)/alienarena-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/common.c' object='qcommon/alienarena-common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena-common.o `test -f 'qcommon/common.c' || echo '$(srcdir)/'`qcommon/common.c qcommon/alienarena-common.obj: qcommon/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena-common.obj -MD -MP -MF qcommon/$(DEPDIR)/alienarena-common.Tpo -c -o qcommon/alienarena-common.obj `if test -f 'qcommon/common.c'; then $(CYGPATH_W) 'qcommon/common.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena-common.Tpo qcommon/$(DEPDIR)/alienarena-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/common.c' object='qcommon/alienarena-common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena-common.obj `if test -f 'qcommon/common.c'; then $(CYGPATH_W) 'qcommon/common.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/common.c'; fi` qcommon/alienarena-crc.o: qcommon/crc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena-crc.o -MD -MP -MF qcommon/$(DEPDIR)/alienarena-crc.Tpo -c -o qcommon/alienarena-crc.o `test -f 'qcommon/crc.c' || echo '$(srcdir)/'`qcommon/crc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena-crc.Tpo qcommon/$(DEPDIR)/alienarena-crc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/crc.c' object='qcommon/alienarena-crc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena-crc.o `test -f 'qcommon/crc.c' || echo '$(srcdir)/'`qcommon/crc.c qcommon/alienarena-crc.obj: qcommon/crc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena-crc.obj -MD -MP -MF qcommon/$(DEPDIR)/alienarena-crc.Tpo -c -o qcommon/alienarena-crc.obj `if test -f 'qcommon/crc.c'; then $(CYGPATH_W) 'qcommon/crc.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/crc.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena-crc.Tpo qcommon/$(DEPDIR)/alienarena-crc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/crc.c' object='qcommon/alienarena-crc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena-crc.obj `if test -f 'qcommon/crc.c'; then $(CYGPATH_W) 'qcommon/crc.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/crc.c'; fi` qcommon/alienarena-cvar.o: qcommon/cvar.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena-cvar.o -MD -MP -MF qcommon/$(DEPDIR)/alienarena-cvar.Tpo -c -o qcommon/alienarena-cvar.o `test -f 'qcommon/cvar.c' || echo '$(srcdir)/'`qcommon/cvar.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena-cvar.Tpo qcommon/$(DEPDIR)/alienarena-cvar.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/cvar.c' object='qcommon/alienarena-cvar.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena-cvar.o `test -f 'qcommon/cvar.c' || echo '$(srcdir)/'`qcommon/cvar.c qcommon/alienarena-cvar.obj: qcommon/cvar.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena-cvar.obj -MD -MP -MF qcommon/$(DEPDIR)/alienarena-cvar.Tpo -c -o qcommon/alienarena-cvar.obj `if test -f 'qcommon/cvar.c'; then $(CYGPATH_W) 'qcommon/cvar.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/cvar.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena-cvar.Tpo qcommon/$(DEPDIR)/alienarena-cvar.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/cvar.c' object='qcommon/alienarena-cvar.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena-cvar.obj `if test -f 'qcommon/cvar.c'; then $(CYGPATH_W) 'qcommon/cvar.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/cvar.c'; fi` qcommon/alienarena-files.o: qcommon/files.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena-files.o -MD -MP -MF qcommon/$(DEPDIR)/alienarena-files.Tpo -c -o qcommon/alienarena-files.o `test -f 'qcommon/files.c' || echo '$(srcdir)/'`qcommon/files.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena-files.Tpo qcommon/$(DEPDIR)/alienarena-files.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/files.c' object='qcommon/alienarena-files.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena-files.o `test -f 'qcommon/files.c' || echo '$(srcdir)/'`qcommon/files.c qcommon/alienarena-files.obj: qcommon/files.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena-files.obj -MD -MP -MF qcommon/$(DEPDIR)/alienarena-files.Tpo -c -o qcommon/alienarena-files.obj `if test -f 'qcommon/files.c'; then $(CYGPATH_W) 'qcommon/files.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/files.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena-files.Tpo qcommon/$(DEPDIR)/alienarena-files.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/files.c' object='qcommon/alienarena-files.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena-files.obj `if test -f 'qcommon/files.c'; then $(CYGPATH_W) 'qcommon/files.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/files.c'; fi` qcommon/alienarena-htable.o: qcommon/htable.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena-htable.o -MD -MP -MF qcommon/$(DEPDIR)/alienarena-htable.Tpo -c -o qcommon/alienarena-htable.o `test -f 'qcommon/htable.c' || echo '$(srcdir)/'`qcommon/htable.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena-htable.Tpo qcommon/$(DEPDIR)/alienarena-htable.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/htable.c' object='qcommon/alienarena-htable.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena-htable.o `test -f 'qcommon/htable.c' || echo '$(srcdir)/'`qcommon/htable.c qcommon/alienarena-htable.obj: qcommon/htable.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena-htable.obj -MD -MP -MF qcommon/$(DEPDIR)/alienarena-htable.Tpo -c -o qcommon/alienarena-htable.obj `if test -f 'qcommon/htable.c'; then $(CYGPATH_W) 'qcommon/htable.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/htable.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena-htable.Tpo qcommon/$(DEPDIR)/alienarena-htable.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/htable.c' object='qcommon/alienarena-htable.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena-htable.obj `if test -f 'qcommon/htable.c'; then $(CYGPATH_W) 'qcommon/htable.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/htable.c'; fi` qcommon/alienarena-md5.o: qcommon/md5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena-md5.o -MD -MP -MF qcommon/$(DEPDIR)/alienarena-md5.Tpo -c -o qcommon/alienarena-md5.o `test -f 'qcommon/md5.c' || echo '$(srcdir)/'`qcommon/md5.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena-md5.Tpo qcommon/$(DEPDIR)/alienarena-md5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/md5.c' object='qcommon/alienarena-md5.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena-md5.o `test -f 'qcommon/md5.c' || echo '$(srcdir)/'`qcommon/md5.c qcommon/alienarena-md5.obj: qcommon/md5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena-md5.obj -MD -MP -MF qcommon/$(DEPDIR)/alienarena-md5.Tpo -c -o qcommon/alienarena-md5.obj `if test -f 'qcommon/md5.c'; then $(CYGPATH_W) 'qcommon/md5.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/md5.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena-md5.Tpo qcommon/$(DEPDIR)/alienarena-md5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/md5.c' object='qcommon/alienarena-md5.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena-md5.obj `if test -f 'qcommon/md5.c'; then $(CYGPATH_W) 'qcommon/md5.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/md5.c'; fi` qcommon/alienarena-mdfour.o: qcommon/mdfour.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena-mdfour.o -MD -MP -MF qcommon/$(DEPDIR)/alienarena-mdfour.Tpo -c -o qcommon/alienarena-mdfour.o `test -f 'qcommon/mdfour.c' || echo '$(srcdir)/'`qcommon/mdfour.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena-mdfour.Tpo qcommon/$(DEPDIR)/alienarena-mdfour.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/mdfour.c' object='qcommon/alienarena-mdfour.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena-mdfour.o `test -f 'qcommon/mdfour.c' || echo '$(srcdir)/'`qcommon/mdfour.c qcommon/alienarena-mdfour.obj: qcommon/mdfour.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena-mdfour.obj -MD -MP -MF qcommon/$(DEPDIR)/alienarena-mdfour.Tpo -c -o qcommon/alienarena-mdfour.obj `if test -f 'qcommon/mdfour.c'; then $(CYGPATH_W) 'qcommon/mdfour.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/mdfour.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena-mdfour.Tpo qcommon/$(DEPDIR)/alienarena-mdfour.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/mdfour.c' object='qcommon/alienarena-mdfour.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena-mdfour.obj `if test -f 'qcommon/mdfour.c'; then $(CYGPATH_W) 'qcommon/mdfour.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/mdfour.c'; fi` qcommon/alienarena-net_chan.o: qcommon/net_chan.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena-net_chan.o -MD -MP -MF qcommon/$(DEPDIR)/alienarena-net_chan.Tpo -c -o qcommon/alienarena-net_chan.o `test -f 'qcommon/net_chan.c' || echo '$(srcdir)/'`qcommon/net_chan.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena-net_chan.Tpo qcommon/$(DEPDIR)/alienarena-net_chan.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/net_chan.c' object='qcommon/alienarena-net_chan.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena-net_chan.o `test -f 'qcommon/net_chan.c' || echo '$(srcdir)/'`qcommon/net_chan.c qcommon/alienarena-net_chan.obj: qcommon/net_chan.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena-net_chan.obj -MD -MP -MF qcommon/$(DEPDIR)/alienarena-net_chan.Tpo -c -o qcommon/alienarena-net_chan.obj `if test -f 'qcommon/net_chan.c'; then $(CYGPATH_W) 'qcommon/net_chan.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/net_chan.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena-net_chan.Tpo qcommon/$(DEPDIR)/alienarena-net_chan.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/net_chan.c' object='qcommon/alienarena-net_chan.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena-net_chan.obj `if test -f 'qcommon/net_chan.c'; then $(CYGPATH_W) 'qcommon/net_chan.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/net_chan.c'; fi` qcommon/alienarena-pmove.o: qcommon/pmove.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena-pmove.o -MD -MP -MF qcommon/$(DEPDIR)/alienarena-pmove.Tpo -c -o qcommon/alienarena-pmove.o `test -f 'qcommon/pmove.c' || echo '$(srcdir)/'`qcommon/pmove.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena-pmove.Tpo qcommon/$(DEPDIR)/alienarena-pmove.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/pmove.c' object='qcommon/alienarena-pmove.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena-pmove.o `test -f 'qcommon/pmove.c' || echo '$(srcdir)/'`qcommon/pmove.c qcommon/alienarena-pmove.obj: qcommon/pmove.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena-pmove.obj -MD -MP -MF qcommon/$(DEPDIR)/alienarena-pmove.Tpo -c -o qcommon/alienarena-pmove.obj `if test -f 'qcommon/pmove.c'; then $(CYGPATH_W) 'qcommon/pmove.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/pmove.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena-pmove.Tpo qcommon/$(DEPDIR)/alienarena-pmove.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/pmove.c' object='qcommon/alienarena-pmove.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena-pmove.obj `if test -f 'qcommon/pmove.c'; then $(CYGPATH_W) 'qcommon/pmove.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/pmove.c'; fi` ref_gl/alienarena-r_bloom.o: ref_gl/r_bloom.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_bloom.o -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_bloom.Tpo -c -o ref_gl/alienarena-r_bloom.o `test -f 'ref_gl/r_bloom.c' || echo '$(srcdir)/'`ref_gl/r_bloom.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_bloom.Tpo ref_gl/$(DEPDIR)/alienarena-r_bloom.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_bloom.c' object='ref_gl/alienarena-r_bloom.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_bloom.o `test -f 'ref_gl/r_bloom.c' || echo '$(srcdir)/'`ref_gl/r_bloom.c ref_gl/alienarena-r_bloom.obj: ref_gl/r_bloom.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_bloom.obj -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_bloom.Tpo -c -o ref_gl/alienarena-r_bloom.obj `if test -f 'ref_gl/r_bloom.c'; then $(CYGPATH_W) 'ref_gl/r_bloom.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_bloom.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_bloom.Tpo ref_gl/$(DEPDIR)/alienarena-r_bloom.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_bloom.c' object='ref_gl/alienarena-r_bloom.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_bloom.obj `if test -f 'ref_gl/r_bloom.c'; then $(CYGPATH_W) 'ref_gl/r_bloom.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_bloom.c'; fi` ref_gl/alienarena-r_draw.o: ref_gl/r_draw.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_draw.o -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_draw.Tpo -c -o ref_gl/alienarena-r_draw.o `test -f 'ref_gl/r_draw.c' || echo '$(srcdir)/'`ref_gl/r_draw.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_draw.Tpo ref_gl/$(DEPDIR)/alienarena-r_draw.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_draw.c' object='ref_gl/alienarena-r_draw.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_draw.o `test -f 'ref_gl/r_draw.c' || echo '$(srcdir)/'`ref_gl/r_draw.c ref_gl/alienarena-r_draw.obj: ref_gl/r_draw.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_draw.obj -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_draw.Tpo -c -o ref_gl/alienarena-r_draw.obj `if test -f 'ref_gl/r_draw.c'; then $(CYGPATH_W) 'ref_gl/r_draw.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_draw.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_draw.Tpo ref_gl/$(DEPDIR)/alienarena-r_draw.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_draw.c' object='ref_gl/alienarena-r_draw.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_draw.obj `if test -f 'ref_gl/r_draw.c'; then $(CYGPATH_W) 'ref_gl/r_draw.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_draw.c'; fi` ref_gl/alienarena-r_image.o: ref_gl/r_image.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_image.o -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_image.Tpo -c -o ref_gl/alienarena-r_image.o `test -f 'ref_gl/r_image.c' || echo '$(srcdir)/'`ref_gl/r_image.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_image.Tpo ref_gl/$(DEPDIR)/alienarena-r_image.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_image.c' object='ref_gl/alienarena-r_image.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_image.o `test -f 'ref_gl/r_image.c' || echo '$(srcdir)/'`ref_gl/r_image.c ref_gl/alienarena-r_image.obj: ref_gl/r_image.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_image.obj -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_image.Tpo -c -o ref_gl/alienarena-r_image.obj `if test -f 'ref_gl/r_image.c'; then $(CYGPATH_W) 'ref_gl/r_image.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_image.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_image.Tpo ref_gl/$(DEPDIR)/alienarena-r_image.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_image.c' object='ref_gl/alienarena-r_image.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_image.obj `if test -f 'ref_gl/r_image.c'; then $(CYGPATH_W) 'ref_gl/r_image.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_image.c'; fi` ref_gl/alienarena-r_iqm.o: ref_gl/r_iqm.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_iqm.o -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_iqm.Tpo -c -o ref_gl/alienarena-r_iqm.o `test -f 'ref_gl/r_iqm.c' || echo '$(srcdir)/'`ref_gl/r_iqm.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_iqm.Tpo ref_gl/$(DEPDIR)/alienarena-r_iqm.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_iqm.c' object='ref_gl/alienarena-r_iqm.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_iqm.o `test -f 'ref_gl/r_iqm.c' || echo '$(srcdir)/'`ref_gl/r_iqm.c ref_gl/alienarena-r_iqm.obj: ref_gl/r_iqm.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_iqm.obj -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_iqm.Tpo -c -o ref_gl/alienarena-r_iqm.obj `if test -f 'ref_gl/r_iqm.c'; then $(CYGPATH_W) 'ref_gl/r_iqm.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_iqm.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_iqm.Tpo ref_gl/$(DEPDIR)/alienarena-r_iqm.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_iqm.c' object='ref_gl/alienarena-r_iqm.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_iqm.obj `if test -f 'ref_gl/r_iqm.c'; then $(CYGPATH_W) 'ref_gl/r_iqm.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_iqm.c'; fi` ref_gl/alienarena-r_light.o: ref_gl/r_light.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_light.o -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_light.Tpo -c -o ref_gl/alienarena-r_light.o `test -f 'ref_gl/r_light.c' || echo '$(srcdir)/'`ref_gl/r_light.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_light.Tpo ref_gl/$(DEPDIR)/alienarena-r_light.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_light.c' object='ref_gl/alienarena-r_light.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_light.o `test -f 'ref_gl/r_light.c' || echo '$(srcdir)/'`ref_gl/r_light.c ref_gl/alienarena-r_light.obj: ref_gl/r_light.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_light.obj -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_light.Tpo -c -o ref_gl/alienarena-r_light.obj `if test -f 'ref_gl/r_light.c'; then $(CYGPATH_W) 'ref_gl/r_light.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_light.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_light.Tpo ref_gl/$(DEPDIR)/alienarena-r_light.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_light.c' object='ref_gl/alienarena-r_light.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_light.obj `if test -f 'ref_gl/r_light.c'; then $(CYGPATH_W) 'ref_gl/r_light.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_light.c'; fi` ref_gl/alienarena-r_main.o: ref_gl/r_main.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_main.o -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_main.Tpo -c -o ref_gl/alienarena-r_main.o `test -f 'ref_gl/r_main.c' || echo '$(srcdir)/'`ref_gl/r_main.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_main.Tpo ref_gl/$(DEPDIR)/alienarena-r_main.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_main.c' object='ref_gl/alienarena-r_main.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_main.o `test -f 'ref_gl/r_main.c' || echo '$(srcdir)/'`ref_gl/r_main.c ref_gl/alienarena-r_main.obj: ref_gl/r_main.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_main.obj -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_main.Tpo -c -o ref_gl/alienarena-r_main.obj `if test -f 'ref_gl/r_main.c'; then $(CYGPATH_W) 'ref_gl/r_main.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_main.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_main.Tpo ref_gl/$(DEPDIR)/alienarena-r_main.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_main.c' object='ref_gl/alienarena-r_main.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_main.obj `if test -f 'ref_gl/r_main.c'; then $(CYGPATH_W) 'ref_gl/r_main.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_main.c'; fi` ref_gl/alienarena-r_math.o: ref_gl/r_math.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_math.o -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_math.Tpo -c -o ref_gl/alienarena-r_math.o `test -f 'ref_gl/r_math.c' || echo '$(srcdir)/'`ref_gl/r_math.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_math.Tpo ref_gl/$(DEPDIR)/alienarena-r_math.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_math.c' object='ref_gl/alienarena-r_math.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_math.o `test -f 'ref_gl/r_math.c' || echo '$(srcdir)/'`ref_gl/r_math.c ref_gl/alienarena-r_math.obj: ref_gl/r_math.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_math.obj -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_math.Tpo -c -o ref_gl/alienarena-r_math.obj `if test -f 'ref_gl/r_math.c'; then $(CYGPATH_W) 'ref_gl/r_math.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_math.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_math.Tpo ref_gl/$(DEPDIR)/alienarena-r_math.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_math.c' object='ref_gl/alienarena-r_math.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_math.obj `if test -f 'ref_gl/r_math.c'; then $(CYGPATH_W) 'ref_gl/r_math.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_math.c'; fi` ref_gl/alienarena-r_mesh.o: ref_gl/r_mesh.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_mesh.o -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_mesh.Tpo -c -o ref_gl/alienarena-r_mesh.o `test -f 'ref_gl/r_mesh.c' || echo '$(srcdir)/'`ref_gl/r_mesh.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_mesh.Tpo ref_gl/$(DEPDIR)/alienarena-r_mesh.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_mesh.c' object='ref_gl/alienarena-r_mesh.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_mesh.o `test -f 'ref_gl/r_mesh.c' || echo '$(srcdir)/'`ref_gl/r_mesh.c ref_gl/alienarena-r_mesh.obj: ref_gl/r_mesh.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_mesh.obj -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_mesh.Tpo -c -o ref_gl/alienarena-r_mesh.obj `if test -f 'ref_gl/r_mesh.c'; then $(CYGPATH_W) 'ref_gl/r_mesh.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_mesh.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_mesh.Tpo ref_gl/$(DEPDIR)/alienarena-r_mesh.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_mesh.c' object='ref_gl/alienarena-r_mesh.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_mesh.obj `if test -f 'ref_gl/r_mesh.c'; then $(CYGPATH_W) 'ref_gl/r_mesh.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_mesh.c'; fi` ref_gl/alienarena-r_misc.o: ref_gl/r_misc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_misc.o -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_misc.Tpo -c -o ref_gl/alienarena-r_misc.o `test -f 'ref_gl/r_misc.c' || echo '$(srcdir)/'`ref_gl/r_misc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_misc.Tpo ref_gl/$(DEPDIR)/alienarena-r_misc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_misc.c' object='ref_gl/alienarena-r_misc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_misc.o `test -f 'ref_gl/r_misc.c' || echo '$(srcdir)/'`ref_gl/r_misc.c ref_gl/alienarena-r_misc.obj: ref_gl/r_misc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_misc.obj -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_misc.Tpo -c -o ref_gl/alienarena-r_misc.obj `if test -f 'ref_gl/r_misc.c'; then $(CYGPATH_W) 'ref_gl/r_misc.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_misc.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_misc.Tpo ref_gl/$(DEPDIR)/alienarena-r_misc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_misc.c' object='ref_gl/alienarena-r_misc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_misc.obj `if test -f 'ref_gl/r_misc.c'; then $(CYGPATH_W) 'ref_gl/r_misc.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_misc.c'; fi` ref_gl/alienarena-r_model.o: ref_gl/r_model.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_model.o -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_model.Tpo -c -o ref_gl/alienarena-r_model.o `test -f 'ref_gl/r_model.c' || echo '$(srcdir)/'`ref_gl/r_model.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_model.Tpo ref_gl/$(DEPDIR)/alienarena-r_model.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_model.c' object='ref_gl/alienarena-r_model.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_model.o `test -f 'ref_gl/r_model.c' || echo '$(srcdir)/'`ref_gl/r_model.c ref_gl/alienarena-r_model.obj: ref_gl/r_model.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_model.obj -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_model.Tpo -c -o ref_gl/alienarena-r_model.obj `if test -f 'ref_gl/r_model.c'; then $(CYGPATH_W) 'ref_gl/r_model.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_model.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_model.Tpo ref_gl/$(DEPDIR)/alienarena-r_model.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_model.c' object='ref_gl/alienarena-r_model.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_model.obj `if test -f 'ref_gl/r_model.c'; then $(CYGPATH_W) 'ref_gl/r_model.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_model.c'; fi` ref_gl/alienarena-r_particle.o: ref_gl/r_particle.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_particle.o -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_particle.Tpo -c -o ref_gl/alienarena-r_particle.o `test -f 'ref_gl/r_particle.c' || echo '$(srcdir)/'`ref_gl/r_particle.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_particle.Tpo ref_gl/$(DEPDIR)/alienarena-r_particle.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_particle.c' object='ref_gl/alienarena-r_particle.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_particle.o `test -f 'ref_gl/r_particle.c' || echo '$(srcdir)/'`ref_gl/r_particle.c ref_gl/alienarena-r_particle.obj: ref_gl/r_particle.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_particle.obj -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_particle.Tpo -c -o ref_gl/alienarena-r_particle.obj `if test -f 'ref_gl/r_particle.c'; then $(CYGPATH_W) 'ref_gl/r_particle.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_particle.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_particle.Tpo ref_gl/$(DEPDIR)/alienarena-r_particle.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_particle.c' object='ref_gl/alienarena-r_particle.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_particle.obj `if test -f 'ref_gl/r_particle.c'; then $(CYGPATH_W) 'ref_gl/r_particle.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_particle.c'; fi` ref_gl/alienarena-r_postprocess.o: ref_gl/r_postprocess.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_postprocess.o -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_postprocess.Tpo -c -o ref_gl/alienarena-r_postprocess.o `test -f 'ref_gl/r_postprocess.c' || echo '$(srcdir)/'`ref_gl/r_postprocess.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_postprocess.Tpo ref_gl/$(DEPDIR)/alienarena-r_postprocess.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_postprocess.c' object='ref_gl/alienarena-r_postprocess.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_postprocess.o `test -f 'ref_gl/r_postprocess.c' || echo '$(srcdir)/'`ref_gl/r_postprocess.c ref_gl/alienarena-r_postprocess.obj: ref_gl/r_postprocess.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_postprocess.obj -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_postprocess.Tpo -c -o ref_gl/alienarena-r_postprocess.obj `if test -f 'ref_gl/r_postprocess.c'; then $(CYGPATH_W) 'ref_gl/r_postprocess.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_postprocess.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_postprocess.Tpo ref_gl/$(DEPDIR)/alienarena-r_postprocess.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_postprocess.c' object='ref_gl/alienarena-r_postprocess.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_postprocess.obj `if test -f 'ref_gl/r_postprocess.c'; then $(CYGPATH_W) 'ref_gl/r_postprocess.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_postprocess.c'; fi` ref_gl/alienarena-r_program.o: ref_gl/r_program.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_program.o -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_program.Tpo -c -o ref_gl/alienarena-r_program.o `test -f 'ref_gl/r_program.c' || echo '$(srcdir)/'`ref_gl/r_program.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_program.Tpo ref_gl/$(DEPDIR)/alienarena-r_program.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_program.c' object='ref_gl/alienarena-r_program.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_program.o `test -f 'ref_gl/r_program.c' || echo '$(srcdir)/'`ref_gl/r_program.c ref_gl/alienarena-r_program.obj: ref_gl/r_program.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_program.obj -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_program.Tpo -c -o ref_gl/alienarena-r_program.obj `if test -f 'ref_gl/r_program.c'; then $(CYGPATH_W) 'ref_gl/r_program.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_program.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_program.Tpo ref_gl/$(DEPDIR)/alienarena-r_program.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_program.c' object='ref_gl/alienarena-r_program.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_program.obj `if test -f 'ref_gl/r_program.c'; then $(CYGPATH_W) 'ref_gl/r_program.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_program.c'; fi` ref_gl/alienarena-r_ragdoll.o: ref_gl/r_ragdoll.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_ragdoll.o -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_ragdoll.Tpo -c -o ref_gl/alienarena-r_ragdoll.o `test -f 'ref_gl/r_ragdoll.c' || echo '$(srcdir)/'`ref_gl/r_ragdoll.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_ragdoll.Tpo ref_gl/$(DEPDIR)/alienarena-r_ragdoll.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_ragdoll.c' object='ref_gl/alienarena-r_ragdoll.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_ragdoll.o `test -f 'ref_gl/r_ragdoll.c' || echo '$(srcdir)/'`ref_gl/r_ragdoll.c ref_gl/alienarena-r_ragdoll.obj: ref_gl/r_ragdoll.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_ragdoll.obj -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_ragdoll.Tpo -c -o ref_gl/alienarena-r_ragdoll.obj `if test -f 'ref_gl/r_ragdoll.c'; then $(CYGPATH_W) 'ref_gl/r_ragdoll.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_ragdoll.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_ragdoll.Tpo ref_gl/$(DEPDIR)/alienarena-r_ragdoll.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_ragdoll.c' object='ref_gl/alienarena-r_ragdoll.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_ragdoll.obj `if test -f 'ref_gl/r_ragdoll.c'; then $(CYGPATH_W) 'ref_gl/r_ragdoll.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_ragdoll.c'; fi` ref_gl/alienarena-r_script.o: ref_gl/r_script.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_script.o -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_script.Tpo -c -o ref_gl/alienarena-r_script.o `test -f 'ref_gl/r_script.c' || echo '$(srcdir)/'`ref_gl/r_script.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_script.Tpo ref_gl/$(DEPDIR)/alienarena-r_script.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_script.c' object='ref_gl/alienarena-r_script.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_script.o `test -f 'ref_gl/r_script.c' || echo '$(srcdir)/'`ref_gl/r_script.c ref_gl/alienarena-r_script.obj: ref_gl/r_script.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_script.obj -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_script.Tpo -c -o ref_gl/alienarena-r_script.obj `if test -f 'ref_gl/r_script.c'; then $(CYGPATH_W) 'ref_gl/r_script.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_script.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_script.Tpo ref_gl/$(DEPDIR)/alienarena-r_script.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_script.c' object='ref_gl/alienarena-r_script.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_script.obj `if test -f 'ref_gl/r_script.c'; then $(CYGPATH_W) 'ref_gl/r_script.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_script.c'; fi` ref_gl/alienarena-r_shadowmaps.o: ref_gl/r_shadowmaps.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_shadowmaps.o -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_shadowmaps.Tpo -c -o ref_gl/alienarena-r_shadowmaps.o `test -f 'ref_gl/r_shadowmaps.c' || echo '$(srcdir)/'`ref_gl/r_shadowmaps.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_shadowmaps.Tpo ref_gl/$(DEPDIR)/alienarena-r_shadowmaps.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_shadowmaps.c' object='ref_gl/alienarena-r_shadowmaps.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_shadowmaps.o `test -f 'ref_gl/r_shadowmaps.c' || echo '$(srcdir)/'`ref_gl/r_shadowmaps.c ref_gl/alienarena-r_shadowmaps.obj: ref_gl/r_shadowmaps.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_shadowmaps.obj -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_shadowmaps.Tpo -c -o ref_gl/alienarena-r_shadowmaps.obj `if test -f 'ref_gl/r_shadowmaps.c'; then $(CYGPATH_W) 'ref_gl/r_shadowmaps.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_shadowmaps.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_shadowmaps.Tpo ref_gl/$(DEPDIR)/alienarena-r_shadowmaps.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_shadowmaps.c' object='ref_gl/alienarena-r_shadowmaps.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_shadowmaps.obj `if test -f 'ref_gl/r_shadowmaps.c'; then $(CYGPATH_W) 'ref_gl/r_shadowmaps.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_shadowmaps.c'; fi` ref_gl/alienarena-r_shadows.o: ref_gl/r_shadows.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_shadows.o -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_shadows.Tpo -c -o ref_gl/alienarena-r_shadows.o `test -f 'ref_gl/r_shadows.c' || echo '$(srcdir)/'`ref_gl/r_shadows.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_shadows.Tpo ref_gl/$(DEPDIR)/alienarena-r_shadows.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_shadows.c' object='ref_gl/alienarena-r_shadows.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_shadows.o `test -f 'ref_gl/r_shadows.c' || echo '$(srcdir)/'`ref_gl/r_shadows.c ref_gl/alienarena-r_shadows.obj: ref_gl/r_shadows.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_shadows.obj -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_shadows.Tpo -c -o ref_gl/alienarena-r_shadows.obj `if test -f 'ref_gl/r_shadows.c'; then $(CYGPATH_W) 'ref_gl/r_shadows.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_shadows.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_shadows.Tpo ref_gl/$(DEPDIR)/alienarena-r_shadows.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_shadows.c' object='ref_gl/alienarena-r_shadows.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_shadows.obj `if test -f 'ref_gl/r_shadows.c'; then $(CYGPATH_W) 'ref_gl/r_shadows.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_shadows.c'; fi` ref_gl/alienarena-r_surf.o: ref_gl/r_surf.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_surf.o -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_surf.Tpo -c -o ref_gl/alienarena-r_surf.o `test -f 'ref_gl/r_surf.c' || echo '$(srcdir)/'`ref_gl/r_surf.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_surf.Tpo ref_gl/$(DEPDIR)/alienarena-r_surf.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_surf.c' object='ref_gl/alienarena-r_surf.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_surf.o `test -f 'ref_gl/r_surf.c' || echo '$(srcdir)/'`ref_gl/r_surf.c ref_gl/alienarena-r_surf.obj: ref_gl/r_surf.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_surf.obj -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_surf.Tpo -c -o ref_gl/alienarena-r_surf.obj `if test -f 'ref_gl/r_surf.c'; then $(CYGPATH_W) 'ref_gl/r_surf.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_surf.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_surf.Tpo ref_gl/$(DEPDIR)/alienarena-r_surf.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_surf.c' object='ref_gl/alienarena-r_surf.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_surf.obj `if test -f 'ref_gl/r_surf.c'; then $(CYGPATH_W) 'ref_gl/r_surf.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_surf.c'; fi` ref_gl/alienarena-r_text.o: ref_gl/r_text.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_text.o -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_text.Tpo -c -o ref_gl/alienarena-r_text.o `test -f 'ref_gl/r_text.c' || echo '$(srcdir)/'`ref_gl/r_text.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_text.Tpo ref_gl/$(DEPDIR)/alienarena-r_text.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_text.c' object='ref_gl/alienarena-r_text.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_text.o `test -f 'ref_gl/r_text.c' || echo '$(srcdir)/'`ref_gl/r_text.c ref_gl/alienarena-r_text.obj: ref_gl/r_text.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_text.obj -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_text.Tpo -c -o ref_gl/alienarena-r_text.obj `if test -f 'ref_gl/r_text.c'; then $(CYGPATH_W) 'ref_gl/r_text.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_text.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_text.Tpo ref_gl/$(DEPDIR)/alienarena-r_text.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_text.c' object='ref_gl/alienarena-r_text.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_text.obj `if test -f 'ref_gl/r_text.c'; then $(CYGPATH_W) 'ref_gl/r_text.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_text.c'; fi` ref_gl/alienarena-r_ttf.o: ref_gl/r_ttf.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_ttf.o -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_ttf.Tpo -c -o ref_gl/alienarena-r_ttf.o `test -f 'ref_gl/r_ttf.c' || echo '$(srcdir)/'`ref_gl/r_ttf.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_ttf.Tpo ref_gl/$(DEPDIR)/alienarena-r_ttf.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_ttf.c' object='ref_gl/alienarena-r_ttf.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_ttf.o `test -f 'ref_gl/r_ttf.c' || echo '$(srcdir)/'`ref_gl/r_ttf.c ref_gl/alienarena-r_ttf.obj: ref_gl/r_ttf.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_ttf.obj -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_ttf.Tpo -c -o ref_gl/alienarena-r_ttf.obj `if test -f 'ref_gl/r_ttf.c'; then $(CYGPATH_W) 'ref_gl/r_ttf.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_ttf.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_ttf.Tpo ref_gl/$(DEPDIR)/alienarena-r_ttf.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_ttf.c' object='ref_gl/alienarena-r_ttf.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_ttf.obj `if test -f 'ref_gl/r_ttf.c'; then $(CYGPATH_W) 'ref_gl/r_ttf.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_ttf.c'; fi` ref_gl/alienarena-r_varray.o: ref_gl/r_varray.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_varray.o -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_varray.Tpo -c -o ref_gl/alienarena-r_varray.o `test -f 'ref_gl/r_varray.c' || echo '$(srcdir)/'`ref_gl/r_varray.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_varray.Tpo ref_gl/$(DEPDIR)/alienarena-r_varray.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_varray.c' object='ref_gl/alienarena-r_varray.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_varray.o `test -f 'ref_gl/r_varray.c' || echo '$(srcdir)/'`ref_gl/r_varray.c ref_gl/alienarena-r_varray.obj: ref_gl/r_varray.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_varray.obj -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_varray.Tpo -c -o ref_gl/alienarena-r_varray.obj `if test -f 'ref_gl/r_varray.c'; then $(CYGPATH_W) 'ref_gl/r_varray.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_varray.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_varray.Tpo ref_gl/$(DEPDIR)/alienarena-r_varray.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_varray.c' object='ref_gl/alienarena-r_varray.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_varray.obj `if test -f 'ref_gl/r_varray.c'; then $(CYGPATH_W) 'ref_gl/r_varray.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_varray.c'; fi` ref_gl/alienarena-r_vbo.o: ref_gl/r_vbo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_vbo.o -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_vbo.Tpo -c -o ref_gl/alienarena-r_vbo.o `test -f 'ref_gl/r_vbo.c' || echo '$(srcdir)/'`ref_gl/r_vbo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_vbo.Tpo ref_gl/$(DEPDIR)/alienarena-r_vbo.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_vbo.c' object='ref_gl/alienarena-r_vbo.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_vbo.o `test -f 'ref_gl/r_vbo.c' || echo '$(srcdir)/'`ref_gl/r_vbo.c ref_gl/alienarena-r_vbo.obj: ref_gl/r_vbo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_vbo.obj -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_vbo.Tpo -c -o ref_gl/alienarena-r_vbo.obj `if test -f 'ref_gl/r_vbo.c'; then $(CYGPATH_W) 'ref_gl/r_vbo.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_vbo.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_vbo.Tpo ref_gl/$(DEPDIR)/alienarena-r_vbo.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_vbo.c' object='ref_gl/alienarena-r_vbo.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_vbo.obj `if test -f 'ref_gl/r_vbo.c'; then $(CYGPATH_W) 'ref_gl/r_vbo.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_vbo.c'; fi` ref_gl/alienarena-r_vlights.o: ref_gl/r_vlights.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_vlights.o -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_vlights.Tpo -c -o ref_gl/alienarena-r_vlights.o `test -f 'ref_gl/r_vlights.c' || echo '$(srcdir)/'`ref_gl/r_vlights.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_vlights.Tpo ref_gl/$(DEPDIR)/alienarena-r_vlights.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_vlights.c' object='ref_gl/alienarena-r_vlights.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_vlights.o `test -f 'ref_gl/r_vlights.c' || echo '$(srcdir)/'`ref_gl/r_vlights.c ref_gl/alienarena-r_vlights.obj: ref_gl/r_vlights.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_vlights.obj -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_vlights.Tpo -c -o ref_gl/alienarena-r_vlights.obj `if test -f 'ref_gl/r_vlights.c'; then $(CYGPATH_W) 'ref_gl/r_vlights.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_vlights.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_vlights.Tpo ref_gl/$(DEPDIR)/alienarena-r_vlights.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_vlights.c' object='ref_gl/alienarena-r_vlights.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_vlights.obj `if test -f 'ref_gl/r_vlights.c'; then $(CYGPATH_W) 'ref_gl/r_vlights.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_vlights.c'; fi` ref_gl/alienarena-r_warp.o: ref_gl/r_warp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_warp.o -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_warp.Tpo -c -o ref_gl/alienarena-r_warp.o `test -f 'ref_gl/r_warp.c' || echo '$(srcdir)/'`ref_gl/r_warp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_warp.Tpo ref_gl/$(DEPDIR)/alienarena-r_warp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_warp.c' object='ref_gl/alienarena-r_warp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_warp.o `test -f 'ref_gl/r_warp.c' || echo '$(srcdir)/'`ref_gl/r_warp.c ref_gl/alienarena-r_warp.obj: ref_gl/r_warp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ref_gl/alienarena-r_warp.obj -MD -MP -MF ref_gl/$(DEPDIR)/alienarena-r_warp.Tpo -c -o ref_gl/alienarena-r_warp.obj `if test -f 'ref_gl/r_warp.c'; then $(CYGPATH_W) 'ref_gl/r_warp.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_warp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ref_gl/$(DEPDIR)/alienarena-r_warp.Tpo ref_gl/$(DEPDIR)/alienarena-r_warp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ref_gl/r_warp.c' object='ref_gl/alienarena-r_warp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ref_gl/alienarena-r_warp.obj `if test -f 'ref_gl/r_warp.c'; then $(CYGPATH_W) 'ref_gl/r_warp.c'; else $(CYGPATH_W) '$(srcdir)/ref_gl/r_warp.c'; fi` server/alienarena-sv_ccmds.o: server/sv_ccmds.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena-sv_ccmds.o -MD -MP -MF server/$(DEPDIR)/alienarena-sv_ccmds.Tpo -c -o server/alienarena-sv_ccmds.o `test -f 'server/sv_ccmds.c' || echo '$(srcdir)/'`server/sv_ccmds.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena-sv_ccmds.Tpo server/$(DEPDIR)/alienarena-sv_ccmds.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_ccmds.c' object='server/alienarena-sv_ccmds.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena-sv_ccmds.o `test -f 'server/sv_ccmds.c' || echo '$(srcdir)/'`server/sv_ccmds.c server/alienarena-sv_ccmds.obj: server/sv_ccmds.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena-sv_ccmds.obj -MD -MP -MF server/$(DEPDIR)/alienarena-sv_ccmds.Tpo -c -o server/alienarena-sv_ccmds.obj `if test -f 'server/sv_ccmds.c'; then $(CYGPATH_W) 'server/sv_ccmds.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_ccmds.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena-sv_ccmds.Tpo server/$(DEPDIR)/alienarena-sv_ccmds.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_ccmds.c' object='server/alienarena-sv_ccmds.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena-sv_ccmds.obj `if test -f 'server/sv_ccmds.c'; then $(CYGPATH_W) 'server/sv_ccmds.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_ccmds.c'; fi` server/alienarena-sv_ents.o: server/sv_ents.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena-sv_ents.o -MD -MP -MF server/$(DEPDIR)/alienarena-sv_ents.Tpo -c -o server/alienarena-sv_ents.o `test -f 'server/sv_ents.c' || echo '$(srcdir)/'`server/sv_ents.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena-sv_ents.Tpo server/$(DEPDIR)/alienarena-sv_ents.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_ents.c' object='server/alienarena-sv_ents.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena-sv_ents.o `test -f 'server/sv_ents.c' || echo '$(srcdir)/'`server/sv_ents.c server/alienarena-sv_ents.obj: server/sv_ents.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena-sv_ents.obj -MD -MP -MF server/$(DEPDIR)/alienarena-sv_ents.Tpo -c -o server/alienarena-sv_ents.obj `if test -f 'server/sv_ents.c'; then $(CYGPATH_W) 'server/sv_ents.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_ents.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena-sv_ents.Tpo server/$(DEPDIR)/alienarena-sv_ents.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_ents.c' object='server/alienarena-sv_ents.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena-sv_ents.obj `if test -f 'server/sv_ents.c'; then $(CYGPATH_W) 'server/sv_ents.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_ents.c'; fi` server/alienarena-sv_game.o: server/sv_game.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena-sv_game.o -MD -MP -MF server/$(DEPDIR)/alienarena-sv_game.Tpo -c -o server/alienarena-sv_game.o `test -f 'server/sv_game.c' || echo '$(srcdir)/'`server/sv_game.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena-sv_game.Tpo server/$(DEPDIR)/alienarena-sv_game.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_game.c' object='server/alienarena-sv_game.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena-sv_game.o `test -f 'server/sv_game.c' || echo '$(srcdir)/'`server/sv_game.c server/alienarena-sv_game.obj: server/sv_game.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena-sv_game.obj -MD -MP -MF server/$(DEPDIR)/alienarena-sv_game.Tpo -c -o server/alienarena-sv_game.obj `if test -f 'server/sv_game.c'; then $(CYGPATH_W) 'server/sv_game.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_game.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena-sv_game.Tpo server/$(DEPDIR)/alienarena-sv_game.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_game.c' object='server/alienarena-sv_game.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena-sv_game.obj `if test -f 'server/sv_game.c'; then $(CYGPATH_W) 'server/sv_game.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_game.c'; fi` server/alienarena-sv_init.o: server/sv_init.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena-sv_init.o -MD -MP -MF server/$(DEPDIR)/alienarena-sv_init.Tpo -c -o server/alienarena-sv_init.o `test -f 'server/sv_init.c' || echo '$(srcdir)/'`server/sv_init.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena-sv_init.Tpo server/$(DEPDIR)/alienarena-sv_init.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_init.c' object='server/alienarena-sv_init.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena-sv_init.o `test -f 'server/sv_init.c' || echo '$(srcdir)/'`server/sv_init.c server/alienarena-sv_init.obj: server/sv_init.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena-sv_init.obj -MD -MP -MF server/$(DEPDIR)/alienarena-sv_init.Tpo -c -o server/alienarena-sv_init.obj `if test -f 'server/sv_init.c'; then $(CYGPATH_W) 'server/sv_init.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_init.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena-sv_init.Tpo server/$(DEPDIR)/alienarena-sv_init.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_init.c' object='server/alienarena-sv_init.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena-sv_init.obj `if test -f 'server/sv_init.c'; then $(CYGPATH_W) 'server/sv_init.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_init.c'; fi` server/alienarena-sv_main.o: server/sv_main.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena-sv_main.o -MD -MP -MF server/$(DEPDIR)/alienarena-sv_main.Tpo -c -o server/alienarena-sv_main.o `test -f 'server/sv_main.c' || echo '$(srcdir)/'`server/sv_main.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena-sv_main.Tpo server/$(DEPDIR)/alienarena-sv_main.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_main.c' object='server/alienarena-sv_main.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena-sv_main.o `test -f 'server/sv_main.c' || echo '$(srcdir)/'`server/sv_main.c server/alienarena-sv_main.obj: server/sv_main.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena-sv_main.obj -MD -MP -MF server/$(DEPDIR)/alienarena-sv_main.Tpo -c -o server/alienarena-sv_main.obj `if test -f 'server/sv_main.c'; then $(CYGPATH_W) 'server/sv_main.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_main.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena-sv_main.Tpo server/$(DEPDIR)/alienarena-sv_main.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_main.c' object='server/alienarena-sv_main.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena-sv_main.obj `if test -f 'server/sv_main.c'; then $(CYGPATH_W) 'server/sv_main.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_main.c'; fi` server/alienarena-sv_send.o: server/sv_send.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena-sv_send.o -MD -MP -MF server/$(DEPDIR)/alienarena-sv_send.Tpo -c -o server/alienarena-sv_send.o `test -f 'server/sv_send.c' || echo '$(srcdir)/'`server/sv_send.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena-sv_send.Tpo server/$(DEPDIR)/alienarena-sv_send.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_send.c' object='server/alienarena-sv_send.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena-sv_send.o `test -f 'server/sv_send.c' || echo '$(srcdir)/'`server/sv_send.c server/alienarena-sv_send.obj: server/sv_send.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena-sv_send.obj -MD -MP -MF server/$(DEPDIR)/alienarena-sv_send.Tpo -c -o server/alienarena-sv_send.obj `if test -f 'server/sv_send.c'; then $(CYGPATH_W) 'server/sv_send.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_send.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena-sv_send.Tpo server/$(DEPDIR)/alienarena-sv_send.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_send.c' object='server/alienarena-sv_send.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena-sv_send.obj `if test -f 'server/sv_send.c'; then $(CYGPATH_W) 'server/sv_send.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_send.c'; fi` server/alienarena-sv_user.o: server/sv_user.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena-sv_user.o -MD -MP -MF server/$(DEPDIR)/alienarena-sv_user.Tpo -c -o server/alienarena-sv_user.o `test -f 'server/sv_user.c' || echo '$(srcdir)/'`server/sv_user.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena-sv_user.Tpo server/$(DEPDIR)/alienarena-sv_user.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_user.c' object='server/alienarena-sv_user.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena-sv_user.o `test -f 'server/sv_user.c' || echo '$(srcdir)/'`server/sv_user.c server/alienarena-sv_user.obj: server/sv_user.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena-sv_user.obj -MD -MP -MF server/$(DEPDIR)/alienarena-sv_user.Tpo -c -o server/alienarena-sv_user.obj `if test -f 'server/sv_user.c'; then $(CYGPATH_W) 'server/sv_user.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_user.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena-sv_user.Tpo server/$(DEPDIR)/alienarena-sv_user.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_user.c' object='server/alienarena-sv_user.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena-sv_user.obj `if test -f 'server/sv_user.c'; then $(CYGPATH_W) 'server/sv_user.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_user.c'; fi` server/alienarena-sv_world.o: server/sv_world.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena-sv_world.o -MD -MP -MF server/$(DEPDIR)/alienarena-sv_world.Tpo -c -o server/alienarena-sv_world.o `test -f 'server/sv_world.c' || echo '$(srcdir)/'`server/sv_world.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena-sv_world.Tpo server/$(DEPDIR)/alienarena-sv_world.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_world.c' object='server/alienarena-sv_world.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena-sv_world.o `test -f 'server/sv_world.c' || echo '$(srcdir)/'`server/sv_world.c server/alienarena-sv_world.obj: server/sv_world.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena-sv_world.obj -MD -MP -MF server/$(DEPDIR)/alienarena-sv_world.Tpo -c -o server/alienarena-sv_world.obj `if test -f 'server/sv_world.c'; then $(CYGPATH_W) 'server/sv_world.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_world.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena-sv_world.Tpo server/$(DEPDIR)/alienarena-sv_world.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_world.c' object='server/alienarena-sv_world.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena-sv_world.obj `if test -f 'server/sv_world.c'; then $(CYGPATH_W) 'server/sv_world.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_world.c'; fi` unix/alienarena-glob.o: unix/glob.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena-glob.o -MD -MP -MF unix/$(DEPDIR)/alienarena-glob.Tpo -c -o unix/alienarena-glob.o `test -f 'unix/glob.c' || echo '$(srcdir)/'`unix/glob.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena-glob.Tpo unix/$(DEPDIR)/alienarena-glob.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/glob.c' object='unix/alienarena-glob.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena-glob.o `test -f 'unix/glob.c' || echo '$(srcdir)/'`unix/glob.c unix/alienarena-glob.obj: unix/glob.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena-glob.obj -MD -MP -MF unix/$(DEPDIR)/alienarena-glob.Tpo -c -o unix/alienarena-glob.obj `if test -f 'unix/glob.c'; then $(CYGPATH_W) 'unix/glob.c'; else $(CYGPATH_W) '$(srcdir)/unix/glob.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena-glob.Tpo unix/$(DEPDIR)/alienarena-glob.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/glob.c' object='unix/alienarena-glob.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena-glob.obj `if test -f 'unix/glob.c'; then $(CYGPATH_W) 'unix/glob.c'; else $(CYGPATH_W) '$(srcdir)/unix/glob.c'; fi` unix/alienarena-gl_glx.o: unix/gl_glx.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena-gl_glx.o -MD -MP -MF unix/$(DEPDIR)/alienarena-gl_glx.Tpo -c -o unix/alienarena-gl_glx.o `test -f 'unix/gl_glx.c' || echo '$(srcdir)/'`unix/gl_glx.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena-gl_glx.Tpo unix/$(DEPDIR)/alienarena-gl_glx.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/gl_glx.c' object='unix/alienarena-gl_glx.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena-gl_glx.o `test -f 'unix/gl_glx.c' || echo '$(srcdir)/'`unix/gl_glx.c unix/alienarena-gl_glx.obj: unix/gl_glx.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena-gl_glx.obj -MD -MP -MF unix/$(DEPDIR)/alienarena-gl_glx.Tpo -c -o unix/alienarena-gl_glx.obj `if test -f 'unix/gl_glx.c'; then $(CYGPATH_W) 'unix/gl_glx.c'; else $(CYGPATH_W) '$(srcdir)/unix/gl_glx.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena-gl_glx.Tpo unix/$(DEPDIR)/alienarena-gl_glx.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/gl_glx.c' object='unix/alienarena-gl_glx.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena-gl_glx.obj `if test -f 'unix/gl_glx.c'; then $(CYGPATH_W) 'unix/gl_glx.c'; else $(CYGPATH_W) '$(srcdir)/unix/gl_glx.c'; fi` unix/alienarena-net_udp.o: unix/net_udp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena-net_udp.o -MD -MP -MF unix/$(DEPDIR)/alienarena-net_udp.Tpo -c -o unix/alienarena-net_udp.o `test -f 'unix/net_udp.c' || echo '$(srcdir)/'`unix/net_udp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena-net_udp.Tpo unix/$(DEPDIR)/alienarena-net_udp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/net_udp.c' object='unix/alienarena-net_udp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena-net_udp.o `test -f 'unix/net_udp.c' || echo '$(srcdir)/'`unix/net_udp.c unix/alienarena-net_udp.obj: unix/net_udp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena-net_udp.obj -MD -MP -MF unix/$(DEPDIR)/alienarena-net_udp.Tpo -c -o unix/alienarena-net_udp.obj `if test -f 'unix/net_udp.c'; then $(CYGPATH_W) 'unix/net_udp.c'; else $(CYGPATH_W) '$(srcdir)/unix/net_udp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena-net_udp.Tpo unix/$(DEPDIR)/alienarena-net_udp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/net_udp.c' object='unix/alienarena-net_udp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena-net_udp.obj `if test -f 'unix/net_udp.c'; then $(CYGPATH_W) 'unix/net_udp.c'; else $(CYGPATH_W) '$(srcdir)/unix/net_udp.c'; fi` unix/alienarena-qal_unix.o: unix/qal_unix.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena-qal_unix.o -MD -MP -MF unix/$(DEPDIR)/alienarena-qal_unix.Tpo -c -o unix/alienarena-qal_unix.o `test -f 'unix/qal_unix.c' || echo '$(srcdir)/'`unix/qal_unix.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena-qal_unix.Tpo unix/$(DEPDIR)/alienarena-qal_unix.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/qal_unix.c' object='unix/alienarena-qal_unix.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena-qal_unix.o `test -f 'unix/qal_unix.c' || echo '$(srcdir)/'`unix/qal_unix.c unix/alienarena-qal_unix.obj: unix/qal_unix.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena-qal_unix.obj -MD -MP -MF unix/$(DEPDIR)/alienarena-qal_unix.Tpo -c -o unix/alienarena-qal_unix.obj `if test -f 'unix/qal_unix.c'; then $(CYGPATH_W) 'unix/qal_unix.c'; else $(CYGPATH_W) '$(srcdir)/unix/qal_unix.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena-qal_unix.Tpo unix/$(DEPDIR)/alienarena-qal_unix.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/qal_unix.c' object='unix/alienarena-qal_unix.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena-qal_unix.obj `if test -f 'unix/qal_unix.c'; then $(CYGPATH_W) 'unix/qal_unix.c'; else $(CYGPATH_W) '$(srcdir)/unix/qal_unix.c'; fi` unix/alienarena-qgl_unix.o: unix/qgl_unix.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena-qgl_unix.o -MD -MP -MF unix/$(DEPDIR)/alienarena-qgl_unix.Tpo -c -o unix/alienarena-qgl_unix.o `test -f 'unix/qgl_unix.c' || echo '$(srcdir)/'`unix/qgl_unix.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena-qgl_unix.Tpo unix/$(DEPDIR)/alienarena-qgl_unix.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/qgl_unix.c' object='unix/alienarena-qgl_unix.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena-qgl_unix.o `test -f 'unix/qgl_unix.c' || echo '$(srcdir)/'`unix/qgl_unix.c unix/alienarena-qgl_unix.obj: unix/qgl_unix.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena-qgl_unix.obj -MD -MP -MF unix/$(DEPDIR)/alienarena-qgl_unix.Tpo -c -o unix/alienarena-qgl_unix.obj `if test -f 'unix/qgl_unix.c'; then $(CYGPATH_W) 'unix/qgl_unix.c'; else $(CYGPATH_W) '$(srcdir)/unix/qgl_unix.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena-qgl_unix.Tpo unix/$(DEPDIR)/alienarena-qgl_unix.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/qgl_unix.c' object='unix/alienarena-qgl_unix.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena-qgl_unix.obj `if test -f 'unix/qgl_unix.c'; then $(CYGPATH_W) 'unix/qgl_unix.c'; else $(CYGPATH_W) '$(srcdir)/unix/qgl_unix.c'; fi` unix/alienarena-q_shunix.o: unix/q_shunix.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena-q_shunix.o -MD -MP -MF unix/$(DEPDIR)/alienarena-q_shunix.Tpo -c -o unix/alienarena-q_shunix.o `test -f 'unix/q_shunix.c' || echo '$(srcdir)/'`unix/q_shunix.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena-q_shunix.Tpo unix/$(DEPDIR)/alienarena-q_shunix.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/q_shunix.c' object='unix/alienarena-q_shunix.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena-q_shunix.o `test -f 'unix/q_shunix.c' || echo '$(srcdir)/'`unix/q_shunix.c unix/alienarena-q_shunix.obj: unix/q_shunix.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena-q_shunix.obj -MD -MP -MF unix/$(DEPDIR)/alienarena-q_shunix.Tpo -c -o unix/alienarena-q_shunix.obj `if test -f 'unix/q_shunix.c'; then $(CYGPATH_W) 'unix/q_shunix.c'; else $(CYGPATH_W) '$(srcdir)/unix/q_shunix.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena-q_shunix.Tpo unix/$(DEPDIR)/alienarena-q_shunix.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/q_shunix.c' object='unix/alienarena-q_shunix.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena-q_shunix.obj `if test -f 'unix/q_shunix.c'; then $(CYGPATH_W) 'unix/q_shunix.c'; else $(CYGPATH_W) '$(srcdir)/unix/q_shunix.c'; fi` unix/alienarena-rw_unix.o: unix/rw_unix.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena-rw_unix.o -MD -MP -MF unix/$(DEPDIR)/alienarena-rw_unix.Tpo -c -o unix/alienarena-rw_unix.o `test -f 'unix/rw_unix.c' || echo '$(srcdir)/'`unix/rw_unix.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena-rw_unix.Tpo unix/$(DEPDIR)/alienarena-rw_unix.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/rw_unix.c' object='unix/alienarena-rw_unix.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena-rw_unix.o `test -f 'unix/rw_unix.c' || echo '$(srcdir)/'`unix/rw_unix.c unix/alienarena-rw_unix.obj: unix/rw_unix.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena-rw_unix.obj -MD -MP -MF unix/$(DEPDIR)/alienarena-rw_unix.Tpo -c -o unix/alienarena-rw_unix.obj `if test -f 'unix/rw_unix.c'; then $(CYGPATH_W) 'unix/rw_unix.c'; else $(CYGPATH_W) '$(srcdir)/unix/rw_unix.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena-rw_unix.Tpo unix/$(DEPDIR)/alienarena-rw_unix.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/rw_unix.c' object='unix/alienarena-rw_unix.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena-rw_unix.obj `if test -f 'unix/rw_unix.c'; then $(CYGPATH_W) 'unix/rw_unix.c'; else $(CYGPATH_W) '$(srcdir)/unix/rw_unix.c'; fi` unix/alienarena-sys_unix.o: unix/sys_unix.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena-sys_unix.o -MD -MP -MF unix/$(DEPDIR)/alienarena-sys_unix.Tpo -c -o unix/alienarena-sys_unix.o `test -f 'unix/sys_unix.c' || echo '$(srcdir)/'`unix/sys_unix.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena-sys_unix.Tpo unix/$(DEPDIR)/alienarena-sys_unix.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/sys_unix.c' object='unix/alienarena-sys_unix.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena-sys_unix.o `test -f 'unix/sys_unix.c' || echo '$(srcdir)/'`unix/sys_unix.c unix/alienarena-sys_unix.obj: unix/sys_unix.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena-sys_unix.obj -MD -MP -MF unix/$(DEPDIR)/alienarena-sys_unix.Tpo -c -o unix/alienarena-sys_unix.obj `if test -f 'unix/sys_unix.c'; then $(CYGPATH_W) 'unix/sys_unix.c'; else $(CYGPATH_W) '$(srcdir)/unix/sys_unix.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena-sys_unix.Tpo unix/$(DEPDIR)/alienarena-sys_unix.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/sys_unix.c' object='unix/alienarena-sys_unix.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena-sys_unix.obj `if test -f 'unix/sys_unix.c'; then $(CYGPATH_W) 'unix/sys_unix.c'; else $(CYGPATH_W) '$(srcdir)/unix/sys_unix.c'; fi` unix/alienarena-vid_so.o: unix/vid_so.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena-vid_so.o -MD -MP -MF unix/$(DEPDIR)/alienarena-vid_so.Tpo -c -o unix/alienarena-vid_so.o `test -f 'unix/vid_so.c' || echo '$(srcdir)/'`unix/vid_so.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena-vid_so.Tpo unix/$(DEPDIR)/alienarena-vid_so.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/vid_so.c' object='unix/alienarena-vid_so.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena-vid_so.o `test -f 'unix/vid_so.c' || echo '$(srcdir)/'`unix/vid_so.c unix/alienarena-vid_so.obj: unix/vid_so.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena-vid_so.obj -MD -MP -MF unix/$(DEPDIR)/alienarena-vid_so.Tpo -c -o unix/alienarena-vid_so.obj `if test -f 'unix/vid_so.c'; then $(CYGPATH_W) 'unix/vid_so.c'; else $(CYGPATH_W) '$(srcdir)/unix/vid_so.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena-vid_so.Tpo unix/$(DEPDIR)/alienarena-vid_so.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/vid_so.c' object='unix/alienarena-vid_so.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena-vid_so.obj `if test -f 'unix/vid_so.c'; then $(CYGPATH_W) 'unix/vid_so.c'; else $(CYGPATH_W) '$(srcdir)/unix/vid_so.c'; fi` win32/alienarena-conproc.o: win32/conproc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT win32/alienarena-conproc.o -MD -MP -MF win32/$(DEPDIR)/alienarena-conproc.Tpo -c -o win32/alienarena-conproc.o `test -f 'win32/conproc.c' || echo '$(srcdir)/'`win32/conproc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) win32/$(DEPDIR)/alienarena-conproc.Tpo win32/$(DEPDIR)/alienarena-conproc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='win32/conproc.c' object='win32/alienarena-conproc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o win32/alienarena-conproc.o `test -f 'win32/conproc.c' || echo '$(srcdir)/'`win32/conproc.c win32/alienarena-conproc.obj: win32/conproc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT win32/alienarena-conproc.obj -MD -MP -MF win32/$(DEPDIR)/alienarena-conproc.Tpo -c -o win32/alienarena-conproc.obj `if test -f 'win32/conproc.c'; then $(CYGPATH_W) 'win32/conproc.c'; else $(CYGPATH_W) '$(srcdir)/win32/conproc.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) win32/$(DEPDIR)/alienarena-conproc.Tpo win32/$(DEPDIR)/alienarena-conproc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='win32/conproc.c' object='win32/alienarena-conproc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o win32/alienarena-conproc.obj `if test -f 'win32/conproc.c'; then $(CYGPATH_W) 'win32/conproc.c'; else $(CYGPATH_W) '$(srcdir)/win32/conproc.c'; fi` win32/alienarena-glw_imp.o: win32/glw_imp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT win32/alienarena-glw_imp.o -MD -MP -MF win32/$(DEPDIR)/alienarena-glw_imp.Tpo -c -o win32/alienarena-glw_imp.o `test -f 'win32/glw_imp.c' || echo '$(srcdir)/'`win32/glw_imp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) win32/$(DEPDIR)/alienarena-glw_imp.Tpo win32/$(DEPDIR)/alienarena-glw_imp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='win32/glw_imp.c' object='win32/alienarena-glw_imp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o win32/alienarena-glw_imp.o `test -f 'win32/glw_imp.c' || echo '$(srcdir)/'`win32/glw_imp.c win32/alienarena-glw_imp.obj: win32/glw_imp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT win32/alienarena-glw_imp.obj -MD -MP -MF win32/$(DEPDIR)/alienarena-glw_imp.Tpo -c -o win32/alienarena-glw_imp.obj `if test -f 'win32/glw_imp.c'; then $(CYGPATH_W) 'win32/glw_imp.c'; else $(CYGPATH_W) '$(srcdir)/win32/glw_imp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) win32/$(DEPDIR)/alienarena-glw_imp.Tpo win32/$(DEPDIR)/alienarena-glw_imp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='win32/glw_imp.c' object='win32/alienarena-glw_imp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o win32/alienarena-glw_imp.obj `if test -f 'win32/glw_imp.c'; then $(CYGPATH_W) 'win32/glw_imp.c'; else $(CYGPATH_W) '$(srcdir)/win32/glw_imp.c'; fi` win32/alienarena-in_win.o: win32/in_win.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT win32/alienarena-in_win.o -MD -MP -MF win32/$(DEPDIR)/alienarena-in_win.Tpo -c -o win32/alienarena-in_win.o `test -f 'win32/in_win.c' || echo '$(srcdir)/'`win32/in_win.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) win32/$(DEPDIR)/alienarena-in_win.Tpo win32/$(DEPDIR)/alienarena-in_win.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='win32/in_win.c' object='win32/alienarena-in_win.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o win32/alienarena-in_win.o `test -f 'win32/in_win.c' || echo '$(srcdir)/'`win32/in_win.c win32/alienarena-in_win.obj: win32/in_win.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT win32/alienarena-in_win.obj -MD -MP -MF win32/$(DEPDIR)/alienarena-in_win.Tpo -c -o win32/alienarena-in_win.obj `if test -f 'win32/in_win.c'; then $(CYGPATH_W) 'win32/in_win.c'; else $(CYGPATH_W) '$(srcdir)/win32/in_win.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) win32/$(DEPDIR)/alienarena-in_win.Tpo win32/$(DEPDIR)/alienarena-in_win.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='win32/in_win.c' object='win32/alienarena-in_win.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o win32/alienarena-in_win.obj `if test -f 'win32/in_win.c'; then $(CYGPATH_W) 'win32/in_win.c'; else $(CYGPATH_W) '$(srcdir)/win32/in_win.c'; fi` win32/alienarena-net_wins.o: win32/net_wins.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT win32/alienarena-net_wins.o -MD -MP -MF win32/$(DEPDIR)/alienarena-net_wins.Tpo -c -o win32/alienarena-net_wins.o `test -f 'win32/net_wins.c' || echo '$(srcdir)/'`win32/net_wins.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) win32/$(DEPDIR)/alienarena-net_wins.Tpo win32/$(DEPDIR)/alienarena-net_wins.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='win32/net_wins.c' object='win32/alienarena-net_wins.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o win32/alienarena-net_wins.o `test -f 'win32/net_wins.c' || echo '$(srcdir)/'`win32/net_wins.c win32/alienarena-net_wins.obj: win32/net_wins.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT win32/alienarena-net_wins.obj -MD -MP -MF win32/$(DEPDIR)/alienarena-net_wins.Tpo -c -o win32/alienarena-net_wins.obj `if test -f 'win32/net_wins.c'; then $(CYGPATH_W) 'win32/net_wins.c'; else $(CYGPATH_W) '$(srcdir)/win32/net_wins.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) win32/$(DEPDIR)/alienarena-net_wins.Tpo win32/$(DEPDIR)/alienarena-net_wins.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='win32/net_wins.c' object='win32/alienarena-net_wins.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o win32/alienarena-net_wins.obj `if test -f 'win32/net_wins.c'; then $(CYGPATH_W) 'win32/net_wins.c'; else $(CYGPATH_W) '$(srcdir)/win32/net_wins.c'; fi` win32/alienarena-qal_win.o: win32/qal_win.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT win32/alienarena-qal_win.o -MD -MP -MF win32/$(DEPDIR)/alienarena-qal_win.Tpo -c -o win32/alienarena-qal_win.o `test -f 'win32/qal_win.c' || echo '$(srcdir)/'`win32/qal_win.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) win32/$(DEPDIR)/alienarena-qal_win.Tpo win32/$(DEPDIR)/alienarena-qal_win.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='win32/qal_win.c' object='win32/alienarena-qal_win.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o win32/alienarena-qal_win.o `test -f 'win32/qal_win.c' || echo '$(srcdir)/'`win32/qal_win.c win32/alienarena-qal_win.obj: win32/qal_win.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT win32/alienarena-qal_win.obj -MD -MP -MF win32/$(DEPDIR)/alienarena-qal_win.Tpo -c -o win32/alienarena-qal_win.obj `if test -f 'win32/qal_win.c'; then $(CYGPATH_W) 'win32/qal_win.c'; else $(CYGPATH_W) '$(srcdir)/win32/qal_win.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) win32/$(DEPDIR)/alienarena-qal_win.Tpo win32/$(DEPDIR)/alienarena-qal_win.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='win32/qal_win.c' object='win32/alienarena-qal_win.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o win32/alienarena-qal_win.obj `if test -f 'win32/qal_win.c'; then $(CYGPATH_W) 'win32/qal_win.c'; else $(CYGPATH_W) '$(srcdir)/win32/qal_win.c'; fi` win32/alienarena-qgl_win.o: win32/qgl_win.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT win32/alienarena-qgl_win.o -MD -MP -MF win32/$(DEPDIR)/alienarena-qgl_win.Tpo -c -o win32/alienarena-qgl_win.o `test -f 'win32/qgl_win.c' || echo '$(srcdir)/'`win32/qgl_win.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) win32/$(DEPDIR)/alienarena-qgl_win.Tpo win32/$(DEPDIR)/alienarena-qgl_win.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='win32/qgl_win.c' object='win32/alienarena-qgl_win.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o win32/alienarena-qgl_win.o `test -f 'win32/qgl_win.c' || echo '$(srcdir)/'`win32/qgl_win.c win32/alienarena-qgl_win.obj: win32/qgl_win.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT win32/alienarena-qgl_win.obj -MD -MP -MF win32/$(DEPDIR)/alienarena-qgl_win.Tpo -c -o win32/alienarena-qgl_win.obj `if test -f 'win32/qgl_win.c'; then $(CYGPATH_W) 'win32/qgl_win.c'; else $(CYGPATH_W) '$(srcdir)/win32/qgl_win.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) win32/$(DEPDIR)/alienarena-qgl_win.Tpo win32/$(DEPDIR)/alienarena-qgl_win.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='win32/qgl_win.c' object='win32/alienarena-qgl_win.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o win32/alienarena-qgl_win.obj `if test -f 'win32/qgl_win.c'; then $(CYGPATH_W) 'win32/qgl_win.c'; else $(CYGPATH_W) '$(srcdir)/win32/qgl_win.c'; fi` win32/alienarena-q_shwin.o: win32/q_shwin.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT win32/alienarena-q_shwin.o -MD -MP -MF win32/$(DEPDIR)/alienarena-q_shwin.Tpo -c -o win32/alienarena-q_shwin.o `test -f 'win32/q_shwin.c' || echo '$(srcdir)/'`win32/q_shwin.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) win32/$(DEPDIR)/alienarena-q_shwin.Tpo win32/$(DEPDIR)/alienarena-q_shwin.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='win32/q_shwin.c' object='win32/alienarena-q_shwin.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o win32/alienarena-q_shwin.o `test -f 'win32/q_shwin.c' || echo '$(srcdir)/'`win32/q_shwin.c win32/alienarena-q_shwin.obj: win32/q_shwin.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT win32/alienarena-q_shwin.obj -MD -MP -MF win32/$(DEPDIR)/alienarena-q_shwin.Tpo -c -o win32/alienarena-q_shwin.obj `if test -f 'win32/q_shwin.c'; then $(CYGPATH_W) 'win32/q_shwin.c'; else $(CYGPATH_W) '$(srcdir)/win32/q_shwin.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) win32/$(DEPDIR)/alienarena-q_shwin.Tpo win32/$(DEPDIR)/alienarena-q_shwin.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='win32/q_shwin.c' object='win32/alienarena-q_shwin.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o win32/alienarena-q_shwin.obj `if test -f 'win32/q_shwin.c'; then $(CYGPATH_W) 'win32/q_shwin.c'; else $(CYGPATH_W) '$(srcdir)/win32/q_shwin.c'; fi` win32/alienarena-sys_win.o: win32/sys_win.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT win32/alienarena-sys_win.o -MD -MP -MF win32/$(DEPDIR)/alienarena-sys_win.Tpo -c -o win32/alienarena-sys_win.o `test -f 'win32/sys_win.c' || echo '$(srcdir)/'`win32/sys_win.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) win32/$(DEPDIR)/alienarena-sys_win.Tpo win32/$(DEPDIR)/alienarena-sys_win.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='win32/sys_win.c' object='win32/alienarena-sys_win.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o win32/alienarena-sys_win.o `test -f 'win32/sys_win.c' || echo '$(srcdir)/'`win32/sys_win.c win32/alienarena-sys_win.obj: win32/sys_win.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT win32/alienarena-sys_win.obj -MD -MP -MF win32/$(DEPDIR)/alienarena-sys_win.Tpo -c -o win32/alienarena-sys_win.obj `if test -f 'win32/sys_win.c'; then $(CYGPATH_W) 'win32/sys_win.c'; else $(CYGPATH_W) '$(srcdir)/win32/sys_win.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) win32/$(DEPDIR)/alienarena-sys_win.Tpo win32/$(DEPDIR)/alienarena-sys_win.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='win32/sys_win.c' object='win32/alienarena-sys_win.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o win32/alienarena-sys_win.obj `if test -f 'win32/sys_win.c'; then $(CYGPATH_W) 'win32/sys_win.c'; else $(CYGPATH_W) '$(srcdir)/win32/sys_win.c'; fi` win32/alienarena-vid_dll.o: win32/vid_dll.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT win32/alienarena-vid_dll.o -MD -MP -MF win32/$(DEPDIR)/alienarena-vid_dll.Tpo -c -o win32/alienarena-vid_dll.o `test -f 'win32/vid_dll.c' || echo '$(srcdir)/'`win32/vid_dll.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) win32/$(DEPDIR)/alienarena-vid_dll.Tpo win32/$(DEPDIR)/alienarena-vid_dll.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='win32/vid_dll.c' object='win32/alienarena-vid_dll.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o win32/alienarena-vid_dll.o `test -f 'win32/vid_dll.c' || echo '$(srcdir)/'`win32/vid_dll.c win32/alienarena-vid_dll.obj: win32/vid_dll.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT win32/alienarena-vid_dll.obj -MD -MP -MF win32/$(DEPDIR)/alienarena-vid_dll.Tpo -c -o win32/alienarena-vid_dll.obj `if test -f 'win32/vid_dll.c'; then $(CYGPATH_W) 'win32/vid_dll.c'; else $(CYGPATH_W) '$(srcdir)/win32/vid_dll.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) win32/$(DEPDIR)/alienarena-vid_dll.Tpo win32/$(DEPDIR)/alienarena-vid_dll.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='win32/vid_dll.c' object='win32/alienarena-vid_dll.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o win32/alienarena-vid_dll.obj `if test -f 'win32/vid_dll.c'; then $(CYGPATH_W) 'win32/vid_dll.c'; else $(CYGPATH_W) '$(srcdir)/win32/vid_dll.c'; fi` game/alienarena_ded-q_shared.o: game/q_shared.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT game/alienarena_ded-q_shared.o -MD -MP -MF game/$(DEPDIR)/alienarena_ded-q_shared.Tpo -c -o game/alienarena_ded-q_shared.o `test -f 'game/q_shared.c' || echo '$(srcdir)/'`game/q_shared.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) game/$(DEPDIR)/alienarena_ded-q_shared.Tpo game/$(DEPDIR)/alienarena_ded-q_shared.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='game/q_shared.c' object='game/alienarena_ded-q_shared.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o game/alienarena_ded-q_shared.o `test -f 'game/q_shared.c' || echo '$(srcdir)/'`game/q_shared.c game/alienarena_ded-q_shared.obj: game/q_shared.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT game/alienarena_ded-q_shared.obj -MD -MP -MF game/$(DEPDIR)/alienarena_ded-q_shared.Tpo -c -o game/alienarena_ded-q_shared.obj `if test -f 'game/q_shared.c'; then $(CYGPATH_W) 'game/q_shared.c'; else $(CYGPATH_W) '$(srcdir)/game/q_shared.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) game/$(DEPDIR)/alienarena_ded-q_shared.Tpo game/$(DEPDIR)/alienarena_ded-q_shared.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='game/q_shared.c' object='game/alienarena_ded-q_shared.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o game/alienarena_ded-q_shared.obj `if test -f 'game/q_shared.c'; then $(CYGPATH_W) 'game/q_shared.c'; else $(CYGPATH_W) '$(srcdir)/game/q_shared.c'; fi` null/alienarena_ded-cl_null.o: null/cl_null.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT null/alienarena_ded-cl_null.o -MD -MP -MF null/$(DEPDIR)/alienarena_ded-cl_null.Tpo -c -o null/alienarena_ded-cl_null.o `test -f 'null/cl_null.c' || echo '$(srcdir)/'`null/cl_null.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) null/$(DEPDIR)/alienarena_ded-cl_null.Tpo null/$(DEPDIR)/alienarena_ded-cl_null.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='null/cl_null.c' object='null/alienarena_ded-cl_null.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o null/alienarena_ded-cl_null.o `test -f 'null/cl_null.c' || echo '$(srcdir)/'`null/cl_null.c null/alienarena_ded-cl_null.obj: null/cl_null.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT null/alienarena_ded-cl_null.obj -MD -MP -MF null/$(DEPDIR)/alienarena_ded-cl_null.Tpo -c -o null/alienarena_ded-cl_null.obj `if test -f 'null/cl_null.c'; then $(CYGPATH_W) 'null/cl_null.c'; else $(CYGPATH_W) '$(srcdir)/null/cl_null.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) null/$(DEPDIR)/alienarena_ded-cl_null.Tpo null/$(DEPDIR)/alienarena_ded-cl_null.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='null/cl_null.c' object='null/alienarena_ded-cl_null.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o null/alienarena_ded-cl_null.obj `if test -f 'null/cl_null.c'; then $(CYGPATH_W) 'null/cl_null.c'; else $(CYGPATH_W) '$(srcdir)/null/cl_null.c'; fi` qcommon/alienarena_ded-cmd.o: qcommon/cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena_ded-cmd.o -MD -MP -MF qcommon/$(DEPDIR)/alienarena_ded-cmd.Tpo -c -o qcommon/alienarena_ded-cmd.o `test -f 'qcommon/cmd.c' || echo '$(srcdir)/'`qcommon/cmd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena_ded-cmd.Tpo qcommon/$(DEPDIR)/alienarena_ded-cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/cmd.c' object='qcommon/alienarena_ded-cmd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena_ded-cmd.o `test -f 'qcommon/cmd.c' || echo '$(srcdir)/'`qcommon/cmd.c qcommon/alienarena_ded-cmd.obj: qcommon/cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena_ded-cmd.obj -MD -MP -MF qcommon/$(DEPDIR)/alienarena_ded-cmd.Tpo -c -o qcommon/alienarena_ded-cmd.obj `if test -f 'qcommon/cmd.c'; then $(CYGPATH_W) 'qcommon/cmd.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/cmd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena_ded-cmd.Tpo qcommon/$(DEPDIR)/alienarena_ded-cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/cmd.c' object='qcommon/alienarena_ded-cmd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena_ded-cmd.obj `if test -f 'qcommon/cmd.c'; then $(CYGPATH_W) 'qcommon/cmd.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/cmd.c'; fi` qcommon/alienarena_ded-cmodel.o: qcommon/cmodel.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena_ded-cmodel.o -MD -MP -MF qcommon/$(DEPDIR)/alienarena_ded-cmodel.Tpo -c -o qcommon/alienarena_ded-cmodel.o `test -f 'qcommon/cmodel.c' || echo '$(srcdir)/'`qcommon/cmodel.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena_ded-cmodel.Tpo qcommon/$(DEPDIR)/alienarena_ded-cmodel.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/cmodel.c' object='qcommon/alienarena_ded-cmodel.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena_ded-cmodel.o `test -f 'qcommon/cmodel.c' || echo '$(srcdir)/'`qcommon/cmodel.c qcommon/alienarena_ded-cmodel.obj: qcommon/cmodel.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena_ded-cmodel.obj -MD -MP -MF qcommon/$(DEPDIR)/alienarena_ded-cmodel.Tpo -c -o qcommon/alienarena_ded-cmodel.obj `if test -f 'qcommon/cmodel.c'; then $(CYGPATH_W) 'qcommon/cmodel.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/cmodel.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena_ded-cmodel.Tpo qcommon/$(DEPDIR)/alienarena_ded-cmodel.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/cmodel.c' object='qcommon/alienarena_ded-cmodel.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena_ded-cmodel.obj `if test -f 'qcommon/cmodel.c'; then $(CYGPATH_W) 'qcommon/cmodel.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/cmodel.c'; fi` qcommon/alienarena_ded-common.o: qcommon/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena_ded-common.o -MD -MP -MF qcommon/$(DEPDIR)/alienarena_ded-common.Tpo -c -o qcommon/alienarena_ded-common.o `test -f 'qcommon/common.c' || echo '$(srcdir)/'`qcommon/common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena_ded-common.Tpo qcommon/$(DEPDIR)/alienarena_ded-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/common.c' object='qcommon/alienarena_ded-common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena_ded-common.o `test -f 'qcommon/common.c' || echo '$(srcdir)/'`qcommon/common.c qcommon/alienarena_ded-common.obj: qcommon/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena_ded-common.obj -MD -MP -MF qcommon/$(DEPDIR)/alienarena_ded-common.Tpo -c -o qcommon/alienarena_ded-common.obj `if test -f 'qcommon/common.c'; then $(CYGPATH_W) 'qcommon/common.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena_ded-common.Tpo qcommon/$(DEPDIR)/alienarena_ded-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/common.c' object='qcommon/alienarena_ded-common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena_ded-common.obj `if test -f 'qcommon/common.c'; then $(CYGPATH_W) 'qcommon/common.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/common.c'; fi` qcommon/alienarena_ded-crc.o: qcommon/crc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena_ded-crc.o -MD -MP -MF qcommon/$(DEPDIR)/alienarena_ded-crc.Tpo -c -o qcommon/alienarena_ded-crc.o `test -f 'qcommon/crc.c' || echo '$(srcdir)/'`qcommon/crc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena_ded-crc.Tpo qcommon/$(DEPDIR)/alienarena_ded-crc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/crc.c' object='qcommon/alienarena_ded-crc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena_ded-crc.o `test -f 'qcommon/crc.c' || echo '$(srcdir)/'`qcommon/crc.c qcommon/alienarena_ded-crc.obj: qcommon/crc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena_ded-crc.obj -MD -MP -MF qcommon/$(DEPDIR)/alienarena_ded-crc.Tpo -c -o qcommon/alienarena_ded-crc.obj `if test -f 'qcommon/crc.c'; then $(CYGPATH_W) 'qcommon/crc.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/crc.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena_ded-crc.Tpo qcommon/$(DEPDIR)/alienarena_ded-crc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/crc.c' object='qcommon/alienarena_ded-crc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena_ded-crc.obj `if test -f 'qcommon/crc.c'; then $(CYGPATH_W) 'qcommon/crc.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/crc.c'; fi` qcommon/alienarena_ded-cvar.o: qcommon/cvar.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena_ded-cvar.o -MD -MP -MF qcommon/$(DEPDIR)/alienarena_ded-cvar.Tpo -c -o qcommon/alienarena_ded-cvar.o `test -f 'qcommon/cvar.c' || echo '$(srcdir)/'`qcommon/cvar.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena_ded-cvar.Tpo qcommon/$(DEPDIR)/alienarena_ded-cvar.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/cvar.c' object='qcommon/alienarena_ded-cvar.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena_ded-cvar.o `test -f 'qcommon/cvar.c' || echo '$(srcdir)/'`qcommon/cvar.c qcommon/alienarena_ded-cvar.obj: qcommon/cvar.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena_ded-cvar.obj -MD -MP -MF qcommon/$(DEPDIR)/alienarena_ded-cvar.Tpo -c -o qcommon/alienarena_ded-cvar.obj `if test -f 'qcommon/cvar.c'; then $(CYGPATH_W) 'qcommon/cvar.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/cvar.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena_ded-cvar.Tpo qcommon/$(DEPDIR)/alienarena_ded-cvar.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/cvar.c' object='qcommon/alienarena_ded-cvar.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena_ded-cvar.obj `if test -f 'qcommon/cvar.c'; then $(CYGPATH_W) 'qcommon/cvar.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/cvar.c'; fi` qcommon/alienarena_ded-files.o: qcommon/files.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena_ded-files.o -MD -MP -MF qcommon/$(DEPDIR)/alienarena_ded-files.Tpo -c -o qcommon/alienarena_ded-files.o `test -f 'qcommon/files.c' || echo '$(srcdir)/'`qcommon/files.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena_ded-files.Tpo qcommon/$(DEPDIR)/alienarena_ded-files.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/files.c' object='qcommon/alienarena_ded-files.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena_ded-files.o `test -f 'qcommon/files.c' || echo '$(srcdir)/'`qcommon/files.c qcommon/alienarena_ded-files.obj: qcommon/files.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena_ded-files.obj -MD -MP -MF qcommon/$(DEPDIR)/alienarena_ded-files.Tpo -c -o qcommon/alienarena_ded-files.obj `if test -f 'qcommon/files.c'; then $(CYGPATH_W) 'qcommon/files.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/files.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena_ded-files.Tpo qcommon/$(DEPDIR)/alienarena_ded-files.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/files.c' object='qcommon/alienarena_ded-files.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena_ded-files.obj `if test -f 'qcommon/files.c'; then $(CYGPATH_W) 'qcommon/files.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/files.c'; fi` qcommon/alienarena_ded-htable.o: qcommon/htable.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena_ded-htable.o -MD -MP -MF qcommon/$(DEPDIR)/alienarena_ded-htable.Tpo -c -o qcommon/alienarena_ded-htable.o `test -f 'qcommon/htable.c' || echo '$(srcdir)/'`qcommon/htable.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena_ded-htable.Tpo qcommon/$(DEPDIR)/alienarena_ded-htable.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/htable.c' object='qcommon/alienarena_ded-htable.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena_ded-htable.o `test -f 'qcommon/htable.c' || echo '$(srcdir)/'`qcommon/htable.c qcommon/alienarena_ded-htable.obj: qcommon/htable.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena_ded-htable.obj -MD -MP -MF qcommon/$(DEPDIR)/alienarena_ded-htable.Tpo -c -o qcommon/alienarena_ded-htable.obj `if test -f 'qcommon/htable.c'; then $(CYGPATH_W) 'qcommon/htable.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/htable.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena_ded-htable.Tpo qcommon/$(DEPDIR)/alienarena_ded-htable.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/htable.c' object='qcommon/alienarena_ded-htable.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena_ded-htable.obj `if test -f 'qcommon/htable.c'; then $(CYGPATH_W) 'qcommon/htable.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/htable.c'; fi` qcommon/alienarena_ded-mdfour.o: qcommon/mdfour.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena_ded-mdfour.o -MD -MP -MF qcommon/$(DEPDIR)/alienarena_ded-mdfour.Tpo -c -o qcommon/alienarena_ded-mdfour.o `test -f 'qcommon/mdfour.c' || echo '$(srcdir)/'`qcommon/mdfour.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena_ded-mdfour.Tpo qcommon/$(DEPDIR)/alienarena_ded-mdfour.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/mdfour.c' object='qcommon/alienarena_ded-mdfour.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena_ded-mdfour.o `test -f 'qcommon/mdfour.c' || echo '$(srcdir)/'`qcommon/mdfour.c qcommon/alienarena_ded-mdfour.obj: qcommon/mdfour.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena_ded-mdfour.obj -MD -MP -MF qcommon/$(DEPDIR)/alienarena_ded-mdfour.Tpo -c -o qcommon/alienarena_ded-mdfour.obj `if test -f 'qcommon/mdfour.c'; then $(CYGPATH_W) 'qcommon/mdfour.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/mdfour.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena_ded-mdfour.Tpo qcommon/$(DEPDIR)/alienarena_ded-mdfour.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/mdfour.c' object='qcommon/alienarena_ded-mdfour.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena_ded-mdfour.obj `if test -f 'qcommon/mdfour.c'; then $(CYGPATH_W) 'qcommon/mdfour.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/mdfour.c'; fi` qcommon/alienarena_ded-net_chan.o: qcommon/net_chan.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena_ded-net_chan.o -MD -MP -MF qcommon/$(DEPDIR)/alienarena_ded-net_chan.Tpo -c -o qcommon/alienarena_ded-net_chan.o `test -f 'qcommon/net_chan.c' || echo '$(srcdir)/'`qcommon/net_chan.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena_ded-net_chan.Tpo qcommon/$(DEPDIR)/alienarena_ded-net_chan.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/net_chan.c' object='qcommon/alienarena_ded-net_chan.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena_ded-net_chan.o `test -f 'qcommon/net_chan.c' || echo '$(srcdir)/'`qcommon/net_chan.c qcommon/alienarena_ded-net_chan.obj: qcommon/net_chan.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena_ded-net_chan.obj -MD -MP -MF qcommon/$(DEPDIR)/alienarena_ded-net_chan.Tpo -c -o qcommon/alienarena_ded-net_chan.obj `if test -f 'qcommon/net_chan.c'; then $(CYGPATH_W) 'qcommon/net_chan.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/net_chan.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena_ded-net_chan.Tpo qcommon/$(DEPDIR)/alienarena_ded-net_chan.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/net_chan.c' object='qcommon/alienarena_ded-net_chan.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena_ded-net_chan.obj `if test -f 'qcommon/net_chan.c'; then $(CYGPATH_W) 'qcommon/net_chan.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/net_chan.c'; fi` qcommon/alienarena_ded-pmove.o: qcommon/pmove.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena_ded-pmove.o -MD -MP -MF qcommon/$(DEPDIR)/alienarena_ded-pmove.Tpo -c -o qcommon/alienarena_ded-pmove.o `test -f 'qcommon/pmove.c' || echo '$(srcdir)/'`qcommon/pmove.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena_ded-pmove.Tpo qcommon/$(DEPDIR)/alienarena_ded-pmove.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/pmove.c' object='qcommon/alienarena_ded-pmove.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena_ded-pmove.o `test -f 'qcommon/pmove.c' || echo '$(srcdir)/'`qcommon/pmove.c qcommon/alienarena_ded-pmove.obj: qcommon/pmove.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qcommon/alienarena_ded-pmove.obj -MD -MP -MF qcommon/$(DEPDIR)/alienarena_ded-pmove.Tpo -c -o qcommon/alienarena_ded-pmove.obj `if test -f 'qcommon/pmove.c'; then $(CYGPATH_W) 'qcommon/pmove.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/pmove.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) qcommon/$(DEPDIR)/alienarena_ded-pmove.Tpo qcommon/$(DEPDIR)/alienarena_ded-pmove.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qcommon/pmove.c' object='qcommon/alienarena_ded-pmove.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qcommon/alienarena_ded-pmove.obj `if test -f 'qcommon/pmove.c'; then $(CYGPATH_W) 'qcommon/pmove.c'; else $(CYGPATH_W) '$(srcdir)/qcommon/pmove.c'; fi` server/alienarena_ded-sv_ccmds.o: server/sv_ccmds.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena_ded-sv_ccmds.o -MD -MP -MF server/$(DEPDIR)/alienarena_ded-sv_ccmds.Tpo -c -o server/alienarena_ded-sv_ccmds.o `test -f 'server/sv_ccmds.c' || echo '$(srcdir)/'`server/sv_ccmds.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena_ded-sv_ccmds.Tpo server/$(DEPDIR)/alienarena_ded-sv_ccmds.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_ccmds.c' object='server/alienarena_ded-sv_ccmds.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena_ded-sv_ccmds.o `test -f 'server/sv_ccmds.c' || echo '$(srcdir)/'`server/sv_ccmds.c server/alienarena_ded-sv_ccmds.obj: server/sv_ccmds.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena_ded-sv_ccmds.obj -MD -MP -MF server/$(DEPDIR)/alienarena_ded-sv_ccmds.Tpo -c -o server/alienarena_ded-sv_ccmds.obj `if test -f 'server/sv_ccmds.c'; then $(CYGPATH_W) 'server/sv_ccmds.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_ccmds.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena_ded-sv_ccmds.Tpo server/$(DEPDIR)/alienarena_ded-sv_ccmds.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_ccmds.c' object='server/alienarena_ded-sv_ccmds.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena_ded-sv_ccmds.obj `if test -f 'server/sv_ccmds.c'; then $(CYGPATH_W) 'server/sv_ccmds.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_ccmds.c'; fi` server/alienarena_ded-sv_ents.o: server/sv_ents.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena_ded-sv_ents.o -MD -MP -MF server/$(DEPDIR)/alienarena_ded-sv_ents.Tpo -c -o server/alienarena_ded-sv_ents.o `test -f 'server/sv_ents.c' || echo '$(srcdir)/'`server/sv_ents.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena_ded-sv_ents.Tpo server/$(DEPDIR)/alienarena_ded-sv_ents.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_ents.c' object='server/alienarena_ded-sv_ents.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena_ded-sv_ents.o `test -f 'server/sv_ents.c' || echo '$(srcdir)/'`server/sv_ents.c server/alienarena_ded-sv_ents.obj: server/sv_ents.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena_ded-sv_ents.obj -MD -MP -MF server/$(DEPDIR)/alienarena_ded-sv_ents.Tpo -c -o server/alienarena_ded-sv_ents.obj `if test -f 'server/sv_ents.c'; then $(CYGPATH_W) 'server/sv_ents.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_ents.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena_ded-sv_ents.Tpo server/$(DEPDIR)/alienarena_ded-sv_ents.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_ents.c' object='server/alienarena_ded-sv_ents.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena_ded-sv_ents.obj `if test -f 'server/sv_ents.c'; then $(CYGPATH_W) 'server/sv_ents.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_ents.c'; fi` server/alienarena_ded-sv_game.o: server/sv_game.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena_ded-sv_game.o -MD -MP -MF server/$(DEPDIR)/alienarena_ded-sv_game.Tpo -c -o server/alienarena_ded-sv_game.o `test -f 'server/sv_game.c' || echo '$(srcdir)/'`server/sv_game.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena_ded-sv_game.Tpo server/$(DEPDIR)/alienarena_ded-sv_game.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_game.c' object='server/alienarena_ded-sv_game.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena_ded-sv_game.o `test -f 'server/sv_game.c' || echo '$(srcdir)/'`server/sv_game.c server/alienarena_ded-sv_game.obj: server/sv_game.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena_ded-sv_game.obj -MD -MP -MF server/$(DEPDIR)/alienarena_ded-sv_game.Tpo -c -o server/alienarena_ded-sv_game.obj `if test -f 'server/sv_game.c'; then $(CYGPATH_W) 'server/sv_game.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_game.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena_ded-sv_game.Tpo server/$(DEPDIR)/alienarena_ded-sv_game.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_game.c' object='server/alienarena_ded-sv_game.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena_ded-sv_game.obj `if test -f 'server/sv_game.c'; then $(CYGPATH_W) 'server/sv_game.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_game.c'; fi` server/alienarena_ded-sv_init.o: server/sv_init.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena_ded-sv_init.o -MD -MP -MF server/$(DEPDIR)/alienarena_ded-sv_init.Tpo -c -o server/alienarena_ded-sv_init.o `test -f 'server/sv_init.c' || echo '$(srcdir)/'`server/sv_init.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena_ded-sv_init.Tpo server/$(DEPDIR)/alienarena_ded-sv_init.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_init.c' object='server/alienarena_ded-sv_init.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena_ded-sv_init.o `test -f 'server/sv_init.c' || echo '$(srcdir)/'`server/sv_init.c server/alienarena_ded-sv_init.obj: server/sv_init.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena_ded-sv_init.obj -MD -MP -MF server/$(DEPDIR)/alienarena_ded-sv_init.Tpo -c -o server/alienarena_ded-sv_init.obj `if test -f 'server/sv_init.c'; then $(CYGPATH_W) 'server/sv_init.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_init.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena_ded-sv_init.Tpo server/$(DEPDIR)/alienarena_ded-sv_init.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_init.c' object='server/alienarena_ded-sv_init.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena_ded-sv_init.obj `if test -f 'server/sv_init.c'; then $(CYGPATH_W) 'server/sv_init.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_init.c'; fi` server/alienarena_ded-sv_main.o: server/sv_main.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena_ded-sv_main.o -MD -MP -MF server/$(DEPDIR)/alienarena_ded-sv_main.Tpo -c -o server/alienarena_ded-sv_main.o `test -f 'server/sv_main.c' || echo '$(srcdir)/'`server/sv_main.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena_ded-sv_main.Tpo server/$(DEPDIR)/alienarena_ded-sv_main.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_main.c' object='server/alienarena_ded-sv_main.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena_ded-sv_main.o `test -f 'server/sv_main.c' || echo '$(srcdir)/'`server/sv_main.c server/alienarena_ded-sv_main.obj: server/sv_main.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena_ded-sv_main.obj -MD -MP -MF server/$(DEPDIR)/alienarena_ded-sv_main.Tpo -c -o server/alienarena_ded-sv_main.obj `if test -f 'server/sv_main.c'; then $(CYGPATH_W) 'server/sv_main.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_main.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena_ded-sv_main.Tpo server/$(DEPDIR)/alienarena_ded-sv_main.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_main.c' object='server/alienarena_ded-sv_main.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena_ded-sv_main.obj `if test -f 'server/sv_main.c'; then $(CYGPATH_W) 'server/sv_main.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_main.c'; fi` server/alienarena_ded-sv_send.o: server/sv_send.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena_ded-sv_send.o -MD -MP -MF server/$(DEPDIR)/alienarena_ded-sv_send.Tpo -c -o server/alienarena_ded-sv_send.o `test -f 'server/sv_send.c' || echo '$(srcdir)/'`server/sv_send.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena_ded-sv_send.Tpo server/$(DEPDIR)/alienarena_ded-sv_send.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_send.c' object='server/alienarena_ded-sv_send.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena_ded-sv_send.o `test -f 'server/sv_send.c' || echo '$(srcdir)/'`server/sv_send.c server/alienarena_ded-sv_send.obj: server/sv_send.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena_ded-sv_send.obj -MD -MP -MF server/$(DEPDIR)/alienarena_ded-sv_send.Tpo -c -o server/alienarena_ded-sv_send.obj `if test -f 'server/sv_send.c'; then $(CYGPATH_W) 'server/sv_send.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_send.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena_ded-sv_send.Tpo server/$(DEPDIR)/alienarena_ded-sv_send.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_send.c' object='server/alienarena_ded-sv_send.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena_ded-sv_send.obj `if test -f 'server/sv_send.c'; then $(CYGPATH_W) 'server/sv_send.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_send.c'; fi` server/alienarena_ded-sv_user.o: server/sv_user.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena_ded-sv_user.o -MD -MP -MF server/$(DEPDIR)/alienarena_ded-sv_user.Tpo -c -o server/alienarena_ded-sv_user.o `test -f 'server/sv_user.c' || echo '$(srcdir)/'`server/sv_user.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena_ded-sv_user.Tpo server/$(DEPDIR)/alienarena_ded-sv_user.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_user.c' object='server/alienarena_ded-sv_user.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena_ded-sv_user.o `test -f 'server/sv_user.c' || echo '$(srcdir)/'`server/sv_user.c server/alienarena_ded-sv_user.obj: server/sv_user.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena_ded-sv_user.obj -MD -MP -MF server/$(DEPDIR)/alienarena_ded-sv_user.Tpo -c -o server/alienarena_ded-sv_user.obj `if test -f 'server/sv_user.c'; then $(CYGPATH_W) 'server/sv_user.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_user.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena_ded-sv_user.Tpo server/$(DEPDIR)/alienarena_ded-sv_user.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_user.c' object='server/alienarena_ded-sv_user.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena_ded-sv_user.obj `if test -f 'server/sv_user.c'; then $(CYGPATH_W) 'server/sv_user.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_user.c'; fi` server/alienarena_ded-sv_world.o: server/sv_world.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena_ded-sv_world.o -MD -MP -MF server/$(DEPDIR)/alienarena_ded-sv_world.Tpo -c -o server/alienarena_ded-sv_world.o `test -f 'server/sv_world.c' || echo '$(srcdir)/'`server/sv_world.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena_ded-sv_world.Tpo server/$(DEPDIR)/alienarena_ded-sv_world.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_world.c' object='server/alienarena_ded-sv_world.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena_ded-sv_world.o `test -f 'server/sv_world.c' || echo '$(srcdir)/'`server/sv_world.c server/alienarena_ded-sv_world.obj: server/sv_world.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server/alienarena_ded-sv_world.obj -MD -MP -MF server/$(DEPDIR)/alienarena_ded-sv_world.Tpo -c -o server/alienarena_ded-sv_world.obj `if test -f 'server/sv_world.c'; then $(CYGPATH_W) 'server/sv_world.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_world.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) server/$(DEPDIR)/alienarena_ded-sv_world.Tpo server/$(DEPDIR)/alienarena_ded-sv_world.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server/sv_world.c' object='server/alienarena_ded-sv_world.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server/alienarena_ded-sv_world.obj `if test -f 'server/sv_world.c'; then $(CYGPATH_W) 'server/sv_world.c'; else $(CYGPATH_W) '$(srcdir)/server/sv_world.c'; fi` unix/alienarena_ded-glob.o: unix/glob.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena_ded-glob.o -MD -MP -MF unix/$(DEPDIR)/alienarena_ded-glob.Tpo -c -o unix/alienarena_ded-glob.o `test -f 'unix/glob.c' || echo '$(srcdir)/'`unix/glob.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena_ded-glob.Tpo unix/$(DEPDIR)/alienarena_ded-glob.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/glob.c' object='unix/alienarena_ded-glob.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena_ded-glob.o `test -f 'unix/glob.c' || echo '$(srcdir)/'`unix/glob.c unix/alienarena_ded-glob.obj: unix/glob.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena_ded-glob.obj -MD -MP -MF unix/$(DEPDIR)/alienarena_ded-glob.Tpo -c -o unix/alienarena_ded-glob.obj `if test -f 'unix/glob.c'; then $(CYGPATH_W) 'unix/glob.c'; else $(CYGPATH_W) '$(srcdir)/unix/glob.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena_ded-glob.Tpo unix/$(DEPDIR)/alienarena_ded-glob.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/glob.c' object='unix/alienarena_ded-glob.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena_ded-glob.obj `if test -f 'unix/glob.c'; then $(CYGPATH_W) 'unix/glob.c'; else $(CYGPATH_W) '$(srcdir)/unix/glob.c'; fi` unix/alienarena_ded-net_udp.o: unix/net_udp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena_ded-net_udp.o -MD -MP -MF unix/$(DEPDIR)/alienarena_ded-net_udp.Tpo -c -o unix/alienarena_ded-net_udp.o `test -f 'unix/net_udp.c' || echo '$(srcdir)/'`unix/net_udp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena_ded-net_udp.Tpo unix/$(DEPDIR)/alienarena_ded-net_udp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/net_udp.c' object='unix/alienarena_ded-net_udp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena_ded-net_udp.o `test -f 'unix/net_udp.c' || echo '$(srcdir)/'`unix/net_udp.c unix/alienarena_ded-net_udp.obj: unix/net_udp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena_ded-net_udp.obj -MD -MP -MF unix/$(DEPDIR)/alienarena_ded-net_udp.Tpo -c -o unix/alienarena_ded-net_udp.obj `if test -f 'unix/net_udp.c'; then $(CYGPATH_W) 'unix/net_udp.c'; else $(CYGPATH_W) '$(srcdir)/unix/net_udp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena_ded-net_udp.Tpo unix/$(DEPDIR)/alienarena_ded-net_udp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/net_udp.c' object='unix/alienarena_ded-net_udp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena_ded-net_udp.obj `if test -f 'unix/net_udp.c'; then $(CYGPATH_W) 'unix/net_udp.c'; else $(CYGPATH_W) '$(srcdir)/unix/net_udp.c'; fi` unix/alienarena_ded-q_shunix.o: unix/q_shunix.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena_ded-q_shunix.o -MD -MP -MF unix/$(DEPDIR)/alienarena_ded-q_shunix.Tpo -c -o unix/alienarena_ded-q_shunix.o `test -f 'unix/q_shunix.c' || echo '$(srcdir)/'`unix/q_shunix.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena_ded-q_shunix.Tpo unix/$(DEPDIR)/alienarena_ded-q_shunix.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/q_shunix.c' object='unix/alienarena_ded-q_shunix.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena_ded-q_shunix.o `test -f 'unix/q_shunix.c' || echo '$(srcdir)/'`unix/q_shunix.c unix/alienarena_ded-q_shunix.obj: unix/q_shunix.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena_ded-q_shunix.obj -MD -MP -MF unix/$(DEPDIR)/alienarena_ded-q_shunix.Tpo -c -o unix/alienarena_ded-q_shunix.obj `if test -f 'unix/q_shunix.c'; then $(CYGPATH_W) 'unix/q_shunix.c'; else $(CYGPATH_W) '$(srcdir)/unix/q_shunix.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena_ded-q_shunix.Tpo unix/$(DEPDIR)/alienarena_ded-q_shunix.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/q_shunix.c' object='unix/alienarena_ded-q_shunix.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena_ded-q_shunix.obj `if test -f 'unix/q_shunix.c'; then $(CYGPATH_W) 'unix/q_shunix.c'; else $(CYGPATH_W) '$(srcdir)/unix/q_shunix.c'; fi` unix/alienarena_ded-sys_unix.o: unix/sys_unix.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena_ded-sys_unix.o -MD -MP -MF unix/$(DEPDIR)/alienarena_ded-sys_unix.Tpo -c -o unix/alienarena_ded-sys_unix.o `test -f 'unix/sys_unix.c' || echo '$(srcdir)/'`unix/sys_unix.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena_ded-sys_unix.Tpo unix/$(DEPDIR)/alienarena_ded-sys_unix.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/sys_unix.c' object='unix/alienarena_ded-sys_unix.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena_ded-sys_unix.o `test -f 'unix/sys_unix.c' || echo '$(srcdir)/'`unix/sys_unix.c unix/alienarena_ded-sys_unix.obj: unix/sys_unix.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix/alienarena_ded-sys_unix.obj -MD -MP -MF unix/$(DEPDIR)/alienarena_ded-sys_unix.Tpo -c -o unix/alienarena_ded-sys_unix.obj `if test -f 'unix/sys_unix.c'; then $(CYGPATH_W) 'unix/sys_unix.c'; else $(CYGPATH_W) '$(srcdir)/unix/sys_unix.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unix/$(DEPDIR)/alienarena_ded-sys_unix.Tpo unix/$(DEPDIR)/alienarena_ded-sys_unix.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix/sys_unix.c' object='unix/alienarena_ded-sys_unix.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(alienarena_ded_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix/alienarena_ded-sys_unix.obj `if test -f 'unix/sys_unix.c'; then $(CYGPATH_W) 'unix/sys_unix.c'; else $(CYGPATH_W) '$(srcdir)/unix/sys_unix.c'; fi` .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` unix/odesrc/libode_a-array.o: unix/odesrc/array.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-array.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-array.Tpo -c -o unix/odesrc/libode_a-array.o `test -f 'unix/odesrc/array.cpp' || echo '$(srcdir)/'`unix/odesrc/array.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-array.Tpo unix/odesrc/$(DEPDIR)/libode_a-array.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/array.cpp' object='unix/odesrc/libode_a-array.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-array.o `test -f 'unix/odesrc/array.cpp' || echo '$(srcdir)/'`unix/odesrc/array.cpp unix/odesrc/libode_a-array.obj: unix/odesrc/array.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-array.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-array.Tpo -c -o unix/odesrc/libode_a-array.obj `if test -f 'unix/odesrc/array.cpp'; then $(CYGPATH_W) 'unix/odesrc/array.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/array.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-array.Tpo unix/odesrc/$(DEPDIR)/libode_a-array.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/array.cpp' object='unix/odesrc/libode_a-array.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-array.obj `if test -f 'unix/odesrc/array.cpp'; then $(CYGPATH_W) 'unix/odesrc/array.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/array.cpp'; fi` unix/odesrc/libode_a-box.o: unix/odesrc/box.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-box.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-box.Tpo -c -o unix/odesrc/libode_a-box.o `test -f 'unix/odesrc/box.cpp' || echo '$(srcdir)/'`unix/odesrc/box.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-box.Tpo unix/odesrc/$(DEPDIR)/libode_a-box.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/box.cpp' object='unix/odesrc/libode_a-box.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-box.o `test -f 'unix/odesrc/box.cpp' || echo '$(srcdir)/'`unix/odesrc/box.cpp unix/odesrc/libode_a-box.obj: unix/odesrc/box.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-box.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-box.Tpo -c -o unix/odesrc/libode_a-box.obj `if test -f 'unix/odesrc/box.cpp'; then $(CYGPATH_W) 'unix/odesrc/box.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/box.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-box.Tpo unix/odesrc/$(DEPDIR)/libode_a-box.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/box.cpp' object='unix/odesrc/libode_a-box.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-box.obj `if test -f 'unix/odesrc/box.cpp'; then $(CYGPATH_W) 'unix/odesrc/box.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/box.cpp'; fi` unix/odesrc/libode_a-capsule.o: unix/odesrc/capsule.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-capsule.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-capsule.Tpo -c -o unix/odesrc/libode_a-capsule.o `test -f 'unix/odesrc/capsule.cpp' || echo '$(srcdir)/'`unix/odesrc/capsule.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-capsule.Tpo unix/odesrc/$(DEPDIR)/libode_a-capsule.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/capsule.cpp' object='unix/odesrc/libode_a-capsule.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-capsule.o `test -f 'unix/odesrc/capsule.cpp' || echo '$(srcdir)/'`unix/odesrc/capsule.cpp unix/odesrc/libode_a-capsule.obj: unix/odesrc/capsule.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-capsule.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-capsule.Tpo -c -o unix/odesrc/libode_a-capsule.obj `if test -f 'unix/odesrc/capsule.cpp'; then $(CYGPATH_W) 'unix/odesrc/capsule.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/capsule.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-capsule.Tpo unix/odesrc/$(DEPDIR)/libode_a-capsule.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/capsule.cpp' object='unix/odesrc/libode_a-capsule.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-capsule.obj `if test -f 'unix/odesrc/capsule.cpp'; then $(CYGPATH_W) 'unix/odesrc/capsule.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/capsule.cpp'; fi` unix/odesrc/libode_a-collision_cylinder_box.o: unix/odesrc/collision_cylinder_box.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_cylinder_box.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_box.Tpo -c -o unix/odesrc/libode_a-collision_cylinder_box.o `test -f 'unix/odesrc/collision_cylinder_box.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_cylinder_box.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_box.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_box.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_cylinder_box.cpp' object='unix/odesrc/libode_a-collision_cylinder_box.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_cylinder_box.o `test -f 'unix/odesrc/collision_cylinder_box.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_cylinder_box.cpp unix/odesrc/libode_a-collision_cylinder_box.obj: unix/odesrc/collision_cylinder_box.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_cylinder_box.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_box.Tpo -c -o unix/odesrc/libode_a-collision_cylinder_box.obj `if test -f 'unix/odesrc/collision_cylinder_box.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_cylinder_box.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_cylinder_box.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_box.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_box.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_cylinder_box.cpp' object='unix/odesrc/libode_a-collision_cylinder_box.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_cylinder_box.obj `if test -f 'unix/odesrc/collision_cylinder_box.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_cylinder_box.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_cylinder_box.cpp'; fi` unix/odesrc/libode_a-collision_cylinder_plane.o: unix/odesrc/collision_cylinder_plane.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_cylinder_plane.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_plane.Tpo -c -o unix/odesrc/libode_a-collision_cylinder_plane.o `test -f 'unix/odesrc/collision_cylinder_plane.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_cylinder_plane.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_plane.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_plane.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_cylinder_plane.cpp' object='unix/odesrc/libode_a-collision_cylinder_plane.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_cylinder_plane.o `test -f 'unix/odesrc/collision_cylinder_plane.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_cylinder_plane.cpp unix/odesrc/libode_a-collision_cylinder_plane.obj: unix/odesrc/collision_cylinder_plane.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_cylinder_plane.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_plane.Tpo -c -o unix/odesrc/libode_a-collision_cylinder_plane.obj `if test -f 'unix/odesrc/collision_cylinder_plane.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_cylinder_plane.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_cylinder_plane.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_plane.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_plane.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_cylinder_plane.cpp' object='unix/odesrc/libode_a-collision_cylinder_plane.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_cylinder_plane.obj `if test -f 'unix/odesrc/collision_cylinder_plane.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_cylinder_plane.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_cylinder_plane.cpp'; fi` unix/odesrc/libode_a-collision_cylinder_sphere.o: unix/odesrc/collision_cylinder_sphere.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_cylinder_sphere.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_sphere.Tpo -c -o unix/odesrc/libode_a-collision_cylinder_sphere.o `test -f 'unix/odesrc/collision_cylinder_sphere.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_cylinder_sphere.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_sphere.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_sphere.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_cylinder_sphere.cpp' object='unix/odesrc/libode_a-collision_cylinder_sphere.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_cylinder_sphere.o `test -f 'unix/odesrc/collision_cylinder_sphere.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_cylinder_sphere.cpp unix/odesrc/libode_a-collision_cylinder_sphere.obj: unix/odesrc/collision_cylinder_sphere.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_cylinder_sphere.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_sphere.Tpo -c -o unix/odesrc/libode_a-collision_cylinder_sphere.obj `if test -f 'unix/odesrc/collision_cylinder_sphere.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_cylinder_sphere.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_cylinder_sphere.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_sphere.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_sphere.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_cylinder_sphere.cpp' object='unix/odesrc/libode_a-collision_cylinder_sphere.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_cylinder_sphere.obj `if test -f 'unix/odesrc/collision_cylinder_sphere.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_cylinder_sphere.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_cylinder_sphere.cpp'; fi` unix/odesrc/libode_a-collision_kernel.o: unix/odesrc/collision_kernel.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_kernel.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_kernel.Tpo -c -o unix/odesrc/libode_a-collision_kernel.o `test -f 'unix/odesrc/collision_kernel.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_kernel.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_kernel.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_kernel.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_kernel.cpp' object='unix/odesrc/libode_a-collision_kernel.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_kernel.o `test -f 'unix/odesrc/collision_kernel.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_kernel.cpp unix/odesrc/libode_a-collision_kernel.obj: unix/odesrc/collision_kernel.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_kernel.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_kernel.Tpo -c -o unix/odesrc/libode_a-collision_kernel.obj `if test -f 'unix/odesrc/collision_kernel.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_kernel.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_kernel.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_kernel.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_kernel.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_kernel.cpp' object='unix/odesrc/libode_a-collision_kernel.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_kernel.obj `if test -f 'unix/odesrc/collision_kernel.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_kernel.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_kernel.cpp'; fi` unix/odesrc/libode_a-collision_quadtreespace.o: unix/odesrc/collision_quadtreespace.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_quadtreespace.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_quadtreespace.Tpo -c -o unix/odesrc/libode_a-collision_quadtreespace.o `test -f 'unix/odesrc/collision_quadtreespace.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_quadtreespace.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_quadtreespace.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_quadtreespace.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_quadtreespace.cpp' object='unix/odesrc/libode_a-collision_quadtreespace.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_quadtreespace.o `test -f 'unix/odesrc/collision_quadtreespace.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_quadtreespace.cpp unix/odesrc/libode_a-collision_quadtreespace.obj: unix/odesrc/collision_quadtreespace.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_quadtreespace.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_quadtreespace.Tpo -c -o unix/odesrc/libode_a-collision_quadtreespace.obj `if test -f 'unix/odesrc/collision_quadtreespace.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_quadtreespace.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_quadtreespace.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_quadtreespace.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_quadtreespace.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_quadtreespace.cpp' object='unix/odesrc/libode_a-collision_quadtreespace.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_quadtreespace.obj `if test -f 'unix/odesrc/collision_quadtreespace.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_quadtreespace.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_quadtreespace.cpp'; fi` unix/odesrc/libode_a-collision_sapspace.o: unix/odesrc/collision_sapspace.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_sapspace.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_sapspace.Tpo -c -o unix/odesrc/libode_a-collision_sapspace.o `test -f 'unix/odesrc/collision_sapspace.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_sapspace.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_sapspace.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_sapspace.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_sapspace.cpp' object='unix/odesrc/libode_a-collision_sapspace.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_sapspace.o `test -f 'unix/odesrc/collision_sapspace.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_sapspace.cpp unix/odesrc/libode_a-collision_sapspace.obj: unix/odesrc/collision_sapspace.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_sapspace.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_sapspace.Tpo -c -o unix/odesrc/libode_a-collision_sapspace.obj `if test -f 'unix/odesrc/collision_sapspace.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_sapspace.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_sapspace.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_sapspace.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_sapspace.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_sapspace.cpp' object='unix/odesrc/libode_a-collision_sapspace.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_sapspace.obj `if test -f 'unix/odesrc/collision_sapspace.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_sapspace.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_sapspace.cpp'; fi` unix/odesrc/libode_a-collision_space.o: unix/odesrc/collision_space.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_space.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_space.Tpo -c -o unix/odesrc/libode_a-collision_space.o `test -f 'unix/odesrc/collision_space.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_space.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_space.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_space.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_space.cpp' object='unix/odesrc/libode_a-collision_space.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_space.o `test -f 'unix/odesrc/collision_space.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_space.cpp unix/odesrc/libode_a-collision_space.obj: unix/odesrc/collision_space.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_space.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_space.Tpo -c -o unix/odesrc/libode_a-collision_space.obj `if test -f 'unix/odesrc/collision_space.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_space.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_space.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_space.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_space.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_space.cpp' object='unix/odesrc/libode_a-collision_space.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_space.obj `if test -f 'unix/odesrc/collision_space.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_space.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_space.cpp'; fi` unix/odesrc/libode_a-collision_transform.o: unix/odesrc/collision_transform.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_transform.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_transform.Tpo -c -o unix/odesrc/libode_a-collision_transform.o `test -f 'unix/odesrc/collision_transform.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_transform.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_transform.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_transform.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_transform.cpp' object='unix/odesrc/libode_a-collision_transform.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_transform.o `test -f 'unix/odesrc/collision_transform.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_transform.cpp unix/odesrc/libode_a-collision_transform.obj: unix/odesrc/collision_transform.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_transform.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_transform.Tpo -c -o unix/odesrc/libode_a-collision_transform.obj `if test -f 'unix/odesrc/collision_transform.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_transform.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_transform.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_transform.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_transform.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_transform.cpp' object='unix/odesrc/libode_a-collision_transform.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_transform.obj `if test -f 'unix/odesrc/collision_transform.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_transform.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_transform.cpp'; fi` unix/odesrc/libode_a-collision_trimesh_disabled.o: unix/odesrc/collision_trimesh_disabled.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_trimesh_disabled.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_disabled.Tpo -c -o unix/odesrc/libode_a-collision_trimesh_disabled.o `test -f 'unix/odesrc/collision_trimesh_disabled.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_trimesh_disabled.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_disabled.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_disabled.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_trimesh_disabled.cpp' object='unix/odesrc/libode_a-collision_trimesh_disabled.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_trimesh_disabled.o `test -f 'unix/odesrc/collision_trimesh_disabled.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_trimesh_disabled.cpp unix/odesrc/libode_a-collision_trimesh_disabled.obj: unix/odesrc/collision_trimesh_disabled.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_trimesh_disabled.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_disabled.Tpo -c -o unix/odesrc/libode_a-collision_trimesh_disabled.obj `if test -f 'unix/odesrc/collision_trimesh_disabled.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_trimesh_disabled.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_trimesh_disabled.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_disabled.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_disabled.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_trimesh_disabled.cpp' object='unix/odesrc/libode_a-collision_trimesh_disabled.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_trimesh_disabled.obj `if test -f 'unix/odesrc/collision_trimesh_disabled.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_trimesh_disabled.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_trimesh_disabled.cpp'; fi` unix/odesrc/libode_a-collision_util.o: unix/odesrc/collision_util.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_util.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_util.Tpo -c -o unix/odesrc/libode_a-collision_util.o `test -f 'unix/odesrc/collision_util.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_util.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_util.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_util.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_util.cpp' object='unix/odesrc/libode_a-collision_util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_util.o `test -f 'unix/odesrc/collision_util.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_util.cpp unix/odesrc/libode_a-collision_util.obj: unix/odesrc/collision_util.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_util.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_util.Tpo -c -o unix/odesrc/libode_a-collision_util.obj `if test -f 'unix/odesrc/collision_util.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_util.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_util.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_util.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_util.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_util.cpp' object='unix/odesrc/libode_a-collision_util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_util.obj `if test -f 'unix/odesrc/collision_util.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_util.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_util.cpp'; fi` unix/odesrc/libode_a-convex.o: unix/odesrc/convex.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-convex.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-convex.Tpo -c -o unix/odesrc/libode_a-convex.o `test -f 'unix/odesrc/convex.cpp' || echo '$(srcdir)/'`unix/odesrc/convex.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-convex.Tpo unix/odesrc/$(DEPDIR)/libode_a-convex.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/convex.cpp' object='unix/odesrc/libode_a-convex.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-convex.o `test -f 'unix/odesrc/convex.cpp' || echo '$(srcdir)/'`unix/odesrc/convex.cpp unix/odesrc/libode_a-convex.obj: unix/odesrc/convex.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-convex.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-convex.Tpo -c -o unix/odesrc/libode_a-convex.obj `if test -f 'unix/odesrc/convex.cpp'; then $(CYGPATH_W) 'unix/odesrc/convex.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/convex.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-convex.Tpo unix/odesrc/$(DEPDIR)/libode_a-convex.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/convex.cpp' object='unix/odesrc/libode_a-convex.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-convex.obj `if test -f 'unix/odesrc/convex.cpp'; then $(CYGPATH_W) 'unix/odesrc/convex.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/convex.cpp'; fi` unix/odesrc/libode_a-cylinder.o: unix/odesrc/cylinder.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-cylinder.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-cylinder.Tpo -c -o unix/odesrc/libode_a-cylinder.o `test -f 'unix/odesrc/cylinder.cpp' || echo '$(srcdir)/'`unix/odesrc/cylinder.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-cylinder.Tpo unix/odesrc/$(DEPDIR)/libode_a-cylinder.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/cylinder.cpp' object='unix/odesrc/libode_a-cylinder.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-cylinder.o `test -f 'unix/odesrc/cylinder.cpp' || echo '$(srcdir)/'`unix/odesrc/cylinder.cpp unix/odesrc/libode_a-cylinder.obj: unix/odesrc/cylinder.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-cylinder.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-cylinder.Tpo -c -o unix/odesrc/libode_a-cylinder.obj `if test -f 'unix/odesrc/cylinder.cpp'; then $(CYGPATH_W) 'unix/odesrc/cylinder.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/cylinder.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-cylinder.Tpo unix/odesrc/$(DEPDIR)/libode_a-cylinder.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/cylinder.cpp' object='unix/odesrc/libode_a-cylinder.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-cylinder.obj `if test -f 'unix/odesrc/cylinder.cpp'; then $(CYGPATH_W) 'unix/odesrc/cylinder.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/cylinder.cpp'; fi` unix/odesrc/libode_a-error.o: unix/odesrc/error.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-error.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-error.Tpo -c -o unix/odesrc/libode_a-error.o `test -f 'unix/odesrc/error.cpp' || echo '$(srcdir)/'`unix/odesrc/error.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-error.Tpo unix/odesrc/$(DEPDIR)/libode_a-error.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/error.cpp' object='unix/odesrc/libode_a-error.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-error.o `test -f 'unix/odesrc/error.cpp' || echo '$(srcdir)/'`unix/odesrc/error.cpp unix/odesrc/libode_a-error.obj: unix/odesrc/error.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-error.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-error.Tpo -c -o unix/odesrc/libode_a-error.obj `if test -f 'unix/odesrc/error.cpp'; then $(CYGPATH_W) 'unix/odesrc/error.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/error.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-error.Tpo unix/odesrc/$(DEPDIR)/libode_a-error.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/error.cpp' object='unix/odesrc/libode_a-error.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-error.obj `if test -f 'unix/odesrc/error.cpp'; then $(CYGPATH_W) 'unix/odesrc/error.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/error.cpp'; fi` unix/odesrc/libode_a-export-dif.o: unix/odesrc/export-dif.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-export-dif.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-export-dif.Tpo -c -o unix/odesrc/libode_a-export-dif.o `test -f 'unix/odesrc/export-dif.cpp' || echo '$(srcdir)/'`unix/odesrc/export-dif.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-export-dif.Tpo unix/odesrc/$(DEPDIR)/libode_a-export-dif.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/export-dif.cpp' object='unix/odesrc/libode_a-export-dif.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-export-dif.o `test -f 'unix/odesrc/export-dif.cpp' || echo '$(srcdir)/'`unix/odesrc/export-dif.cpp unix/odesrc/libode_a-export-dif.obj: unix/odesrc/export-dif.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-export-dif.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-export-dif.Tpo -c -o unix/odesrc/libode_a-export-dif.obj `if test -f 'unix/odesrc/export-dif.cpp'; then $(CYGPATH_W) 'unix/odesrc/export-dif.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/export-dif.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-export-dif.Tpo unix/odesrc/$(DEPDIR)/libode_a-export-dif.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/export-dif.cpp' object='unix/odesrc/libode_a-export-dif.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-export-dif.obj `if test -f 'unix/odesrc/export-dif.cpp'; then $(CYGPATH_W) 'unix/odesrc/export-dif.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/export-dif.cpp'; fi` unix/odesrc/libode_a-heightfield.o: unix/odesrc/heightfield.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-heightfield.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-heightfield.Tpo -c -o unix/odesrc/libode_a-heightfield.o `test -f 'unix/odesrc/heightfield.cpp' || echo '$(srcdir)/'`unix/odesrc/heightfield.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-heightfield.Tpo unix/odesrc/$(DEPDIR)/libode_a-heightfield.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/heightfield.cpp' object='unix/odesrc/libode_a-heightfield.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-heightfield.o `test -f 'unix/odesrc/heightfield.cpp' || echo '$(srcdir)/'`unix/odesrc/heightfield.cpp unix/odesrc/libode_a-heightfield.obj: unix/odesrc/heightfield.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-heightfield.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-heightfield.Tpo -c -o unix/odesrc/libode_a-heightfield.obj `if test -f 'unix/odesrc/heightfield.cpp'; then $(CYGPATH_W) 'unix/odesrc/heightfield.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/heightfield.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-heightfield.Tpo unix/odesrc/$(DEPDIR)/libode_a-heightfield.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/heightfield.cpp' object='unix/odesrc/libode_a-heightfield.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-heightfield.obj `if test -f 'unix/odesrc/heightfield.cpp'; then $(CYGPATH_W) 'unix/odesrc/heightfield.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/heightfield.cpp'; fi` unix/odesrc/libode_a-lcp.o: unix/odesrc/lcp.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-lcp.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-lcp.Tpo -c -o unix/odesrc/libode_a-lcp.o `test -f 'unix/odesrc/lcp.cpp' || echo '$(srcdir)/'`unix/odesrc/lcp.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-lcp.Tpo unix/odesrc/$(DEPDIR)/libode_a-lcp.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/lcp.cpp' object='unix/odesrc/libode_a-lcp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-lcp.o `test -f 'unix/odesrc/lcp.cpp' || echo '$(srcdir)/'`unix/odesrc/lcp.cpp unix/odesrc/libode_a-lcp.obj: unix/odesrc/lcp.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-lcp.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-lcp.Tpo -c -o unix/odesrc/libode_a-lcp.obj `if test -f 'unix/odesrc/lcp.cpp'; then $(CYGPATH_W) 'unix/odesrc/lcp.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/lcp.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-lcp.Tpo unix/odesrc/$(DEPDIR)/libode_a-lcp.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/lcp.cpp' object='unix/odesrc/libode_a-lcp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-lcp.obj `if test -f 'unix/odesrc/lcp.cpp'; then $(CYGPATH_W) 'unix/odesrc/lcp.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/lcp.cpp'; fi` unix/odesrc/libode_a-mass.o: unix/odesrc/mass.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-mass.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-mass.Tpo -c -o unix/odesrc/libode_a-mass.o `test -f 'unix/odesrc/mass.cpp' || echo '$(srcdir)/'`unix/odesrc/mass.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-mass.Tpo unix/odesrc/$(DEPDIR)/libode_a-mass.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/mass.cpp' object='unix/odesrc/libode_a-mass.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-mass.o `test -f 'unix/odesrc/mass.cpp' || echo '$(srcdir)/'`unix/odesrc/mass.cpp unix/odesrc/libode_a-mass.obj: unix/odesrc/mass.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-mass.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-mass.Tpo -c -o unix/odesrc/libode_a-mass.obj `if test -f 'unix/odesrc/mass.cpp'; then $(CYGPATH_W) 'unix/odesrc/mass.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/mass.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-mass.Tpo unix/odesrc/$(DEPDIR)/libode_a-mass.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/mass.cpp' object='unix/odesrc/libode_a-mass.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-mass.obj `if test -f 'unix/odesrc/mass.cpp'; then $(CYGPATH_W) 'unix/odesrc/mass.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/mass.cpp'; fi` unix/odesrc/libode_a-mat.o: unix/odesrc/mat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-mat.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-mat.Tpo -c -o unix/odesrc/libode_a-mat.o `test -f 'unix/odesrc/mat.cpp' || echo '$(srcdir)/'`unix/odesrc/mat.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-mat.Tpo unix/odesrc/$(DEPDIR)/libode_a-mat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/mat.cpp' object='unix/odesrc/libode_a-mat.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-mat.o `test -f 'unix/odesrc/mat.cpp' || echo '$(srcdir)/'`unix/odesrc/mat.cpp unix/odesrc/libode_a-mat.obj: unix/odesrc/mat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-mat.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-mat.Tpo -c -o unix/odesrc/libode_a-mat.obj `if test -f 'unix/odesrc/mat.cpp'; then $(CYGPATH_W) 'unix/odesrc/mat.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/mat.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-mat.Tpo unix/odesrc/$(DEPDIR)/libode_a-mat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/mat.cpp' object='unix/odesrc/libode_a-mat.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-mat.obj `if test -f 'unix/odesrc/mat.cpp'; then $(CYGPATH_W) 'unix/odesrc/mat.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/mat.cpp'; fi` unix/odesrc/libode_a-matrix.o: unix/odesrc/matrix.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-matrix.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-matrix.Tpo -c -o unix/odesrc/libode_a-matrix.o `test -f 'unix/odesrc/matrix.cpp' || echo '$(srcdir)/'`unix/odesrc/matrix.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-matrix.Tpo unix/odesrc/$(DEPDIR)/libode_a-matrix.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/matrix.cpp' object='unix/odesrc/libode_a-matrix.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-matrix.o `test -f 'unix/odesrc/matrix.cpp' || echo '$(srcdir)/'`unix/odesrc/matrix.cpp unix/odesrc/libode_a-matrix.obj: unix/odesrc/matrix.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-matrix.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-matrix.Tpo -c -o unix/odesrc/libode_a-matrix.obj `if test -f 'unix/odesrc/matrix.cpp'; then $(CYGPATH_W) 'unix/odesrc/matrix.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/matrix.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-matrix.Tpo unix/odesrc/$(DEPDIR)/libode_a-matrix.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/matrix.cpp' object='unix/odesrc/libode_a-matrix.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-matrix.obj `if test -f 'unix/odesrc/matrix.cpp'; then $(CYGPATH_W) 'unix/odesrc/matrix.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/matrix.cpp'; fi` unix/odesrc/libode_a-memory.o: unix/odesrc/memory.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-memory.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-memory.Tpo -c -o unix/odesrc/libode_a-memory.o `test -f 'unix/odesrc/memory.cpp' || echo '$(srcdir)/'`unix/odesrc/memory.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-memory.Tpo unix/odesrc/$(DEPDIR)/libode_a-memory.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/memory.cpp' object='unix/odesrc/libode_a-memory.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-memory.o `test -f 'unix/odesrc/memory.cpp' || echo '$(srcdir)/'`unix/odesrc/memory.cpp unix/odesrc/libode_a-memory.obj: unix/odesrc/memory.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-memory.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-memory.Tpo -c -o unix/odesrc/libode_a-memory.obj `if test -f 'unix/odesrc/memory.cpp'; then $(CYGPATH_W) 'unix/odesrc/memory.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/memory.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-memory.Tpo unix/odesrc/$(DEPDIR)/libode_a-memory.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/memory.cpp' object='unix/odesrc/libode_a-memory.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-memory.obj `if test -f 'unix/odesrc/memory.cpp'; then $(CYGPATH_W) 'unix/odesrc/memory.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/memory.cpp'; fi` unix/odesrc/libode_a-misc.o: unix/odesrc/misc.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-misc.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-misc.Tpo -c -o unix/odesrc/libode_a-misc.o `test -f 'unix/odesrc/misc.cpp' || echo '$(srcdir)/'`unix/odesrc/misc.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-misc.Tpo unix/odesrc/$(DEPDIR)/libode_a-misc.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/misc.cpp' object='unix/odesrc/libode_a-misc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-misc.o `test -f 'unix/odesrc/misc.cpp' || echo '$(srcdir)/'`unix/odesrc/misc.cpp unix/odesrc/libode_a-misc.obj: unix/odesrc/misc.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-misc.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-misc.Tpo -c -o unix/odesrc/libode_a-misc.obj `if test -f 'unix/odesrc/misc.cpp'; then $(CYGPATH_W) 'unix/odesrc/misc.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/misc.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-misc.Tpo unix/odesrc/$(DEPDIR)/libode_a-misc.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/misc.cpp' object='unix/odesrc/libode_a-misc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-misc.obj `if test -f 'unix/odesrc/misc.cpp'; then $(CYGPATH_W) 'unix/odesrc/misc.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/misc.cpp'; fi` unix/odesrc/libode_a-obstack.o: unix/odesrc/obstack.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-obstack.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-obstack.Tpo -c -o unix/odesrc/libode_a-obstack.o `test -f 'unix/odesrc/obstack.cpp' || echo '$(srcdir)/'`unix/odesrc/obstack.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-obstack.Tpo unix/odesrc/$(DEPDIR)/libode_a-obstack.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/obstack.cpp' object='unix/odesrc/libode_a-obstack.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-obstack.o `test -f 'unix/odesrc/obstack.cpp' || echo '$(srcdir)/'`unix/odesrc/obstack.cpp unix/odesrc/libode_a-obstack.obj: unix/odesrc/obstack.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-obstack.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-obstack.Tpo -c -o unix/odesrc/libode_a-obstack.obj `if test -f 'unix/odesrc/obstack.cpp'; then $(CYGPATH_W) 'unix/odesrc/obstack.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/obstack.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-obstack.Tpo unix/odesrc/$(DEPDIR)/libode_a-obstack.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/obstack.cpp' object='unix/odesrc/libode_a-obstack.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-obstack.obj `if test -f 'unix/odesrc/obstack.cpp'; then $(CYGPATH_W) 'unix/odesrc/obstack.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/obstack.cpp'; fi` unix/odesrc/libode_a-ode.o: unix/odesrc/ode.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-ode.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-ode.Tpo -c -o unix/odesrc/libode_a-ode.o `test -f 'unix/odesrc/ode.cpp' || echo '$(srcdir)/'`unix/odesrc/ode.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-ode.Tpo unix/odesrc/$(DEPDIR)/libode_a-ode.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/ode.cpp' object='unix/odesrc/libode_a-ode.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-ode.o `test -f 'unix/odesrc/ode.cpp' || echo '$(srcdir)/'`unix/odesrc/ode.cpp unix/odesrc/libode_a-ode.obj: unix/odesrc/ode.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-ode.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-ode.Tpo -c -o unix/odesrc/libode_a-ode.obj `if test -f 'unix/odesrc/ode.cpp'; then $(CYGPATH_W) 'unix/odesrc/ode.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/ode.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-ode.Tpo unix/odesrc/$(DEPDIR)/libode_a-ode.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/ode.cpp' object='unix/odesrc/libode_a-ode.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-ode.obj `if test -f 'unix/odesrc/ode.cpp'; then $(CYGPATH_W) 'unix/odesrc/ode.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/ode.cpp'; fi` unix/odesrc/libode_a-odeinit.o: unix/odesrc/odeinit.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-odeinit.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-odeinit.Tpo -c -o unix/odesrc/libode_a-odeinit.o `test -f 'unix/odesrc/odeinit.cpp' || echo '$(srcdir)/'`unix/odesrc/odeinit.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-odeinit.Tpo unix/odesrc/$(DEPDIR)/libode_a-odeinit.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/odeinit.cpp' object='unix/odesrc/libode_a-odeinit.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-odeinit.o `test -f 'unix/odesrc/odeinit.cpp' || echo '$(srcdir)/'`unix/odesrc/odeinit.cpp unix/odesrc/libode_a-odeinit.obj: unix/odesrc/odeinit.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-odeinit.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-odeinit.Tpo -c -o unix/odesrc/libode_a-odeinit.obj `if test -f 'unix/odesrc/odeinit.cpp'; then $(CYGPATH_W) 'unix/odesrc/odeinit.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/odeinit.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-odeinit.Tpo unix/odesrc/$(DEPDIR)/libode_a-odeinit.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/odeinit.cpp' object='unix/odesrc/libode_a-odeinit.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-odeinit.obj `if test -f 'unix/odesrc/odeinit.cpp'; then $(CYGPATH_W) 'unix/odesrc/odeinit.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/odeinit.cpp'; fi` unix/odesrc/libode_a-odemath.o: unix/odesrc/odemath.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-odemath.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-odemath.Tpo -c -o unix/odesrc/libode_a-odemath.o `test -f 'unix/odesrc/odemath.cpp' || echo '$(srcdir)/'`unix/odesrc/odemath.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-odemath.Tpo unix/odesrc/$(DEPDIR)/libode_a-odemath.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/odemath.cpp' object='unix/odesrc/libode_a-odemath.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-odemath.o `test -f 'unix/odesrc/odemath.cpp' || echo '$(srcdir)/'`unix/odesrc/odemath.cpp unix/odesrc/libode_a-odemath.obj: unix/odesrc/odemath.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-odemath.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-odemath.Tpo -c -o unix/odesrc/libode_a-odemath.obj `if test -f 'unix/odesrc/odemath.cpp'; then $(CYGPATH_W) 'unix/odesrc/odemath.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/odemath.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-odemath.Tpo unix/odesrc/$(DEPDIR)/libode_a-odemath.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/odemath.cpp' object='unix/odesrc/libode_a-odemath.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-odemath.obj `if test -f 'unix/odesrc/odemath.cpp'; then $(CYGPATH_W) 'unix/odesrc/odemath.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/odemath.cpp'; fi` unix/odesrc/libode_a-plane.o: unix/odesrc/plane.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-plane.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-plane.Tpo -c -o unix/odesrc/libode_a-plane.o `test -f 'unix/odesrc/plane.cpp' || echo '$(srcdir)/'`unix/odesrc/plane.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-plane.Tpo unix/odesrc/$(DEPDIR)/libode_a-plane.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/plane.cpp' object='unix/odesrc/libode_a-plane.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-plane.o `test -f 'unix/odesrc/plane.cpp' || echo '$(srcdir)/'`unix/odesrc/plane.cpp unix/odesrc/libode_a-plane.obj: unix/odesrc/plane.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-plane.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-plane.Tpo -c -o unix/odesrc/libode_a-plane.obj `if test -f 'unix/odesrc/plane.cpp'; then $(CYGPATH_W) 'unix/odesrc/plane.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/plane.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-plane.Tpo unix/odesrc/$(DEPDIR)/libode_a-plane.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/plane.cpp' object='unix/odesrc/libode_a-plane.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-plane.obj `if test -f 'unix/odesrc/plane.cpp'; then $(CYGPATH_W) 'unix/odesrc/plane.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/plane.cpp'; fi` unix/odesrc/libode_a-quickstep.o: unix/odesrc/quickstep.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-quickstep.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-quickstep.Tpo -c -o unix/odesrc/libode_a-quickstep.o `test -f 'unix/odesrc/quickstep.cpp' || echo '$(srcdir)/'`unix/odesrc/quickstep.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-quickstep.Tpo unix/odesrc/$(DEPDIR)/libode_a-quickstep.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/quickstep.cpp' object='unix/odesrc/libode_a-quickstep.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-quickstep.o `test -f 'unix/odesrc/quickstep.cpp' || echo '$(srcdir)/'`unix/odesrc/quickstep.cpp unix/odesrc/libode_a-quickstep.obj: unix/odesrc/quickstep.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-quickstep.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-quickstep.Tpo -c -o unix/odesrc/libode_a-quickstep.obj `if test -f 'unix/odesrc/quickstep.cpp'; then $(CYGPATH_W) 'unix/odesrc/quickstep.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/quickstep.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-quickstep.Tpo unix/odesrc/$(DEPDIR)/libode_a-quickstep.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/quickstep.cpp' object='unix/odesrc/libode_a-quickstep.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-quickstep.obj `if test -f 'unix/odesrc/quickstep.cpp'; then $(CYGPATH_W) 'unix/odesrc/quickstep.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/quickstep.cpp'; fi` unix/odesrc/libode_a-ray.o: unix/odesrc/ray.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-ray.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-ray.Tpo -c -o unix/odesrc/libode_a-ray.o `test -f 'unix/odesrc/ray.cpp' || echo '$(srcdir)/'`unix/odesrc/ray.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-ray.Tpo unix/odesrc/$(DEPDIR)/libode_a-ray.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/ray.cpp' object='unix/odesrc/libode_a-ray.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-ray.o `test -f 'unix/odesrc/ray.cpp' || echo '$(srcdir)/'`unix/odesrc/ray.cpp unix/odesrc/libode_a-ray.obj: unix/odesrc/ray.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-ray.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-ray.Tpo -c -o unix/odesrc/libode_a-ray.obj `if test -f 'unix/odesrc/ray.cpp'; then $(CYGPATH_W) 'unix/odesrc/ray.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/ray.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-ray.Tpo unix/odesrc/$(DEPDIR)/libode_a-ray.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/ray.cpp' object='unix/odesrc/libode_a-ray.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-ray.obj `if test -f 'unix/odesrc/ray.cpp'; then $(CYGPATH_W) 'unix/odesrc/ray.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/ray.cpp'; fi` unix/odesrc/libode_a-rotation.o: unix/odesrc/rotation.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-rotation.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-rotation.Tpo -c -o unix/odesrc/libode_a-rotation.o `test -f 'unix/odesrc/rotation.cpp' || echo '$(srcdir)/'`unix/odesrc/rotation.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-rotation.Tpo unix/odesrc/$(DEPDIR)/libode_a-rotation.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/rotation.cpp' object='unix/odesrc/libode_a-rotation.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-rotation.o `test -f 'unix/odesrc/rotation.cpp' || echo '$(srcdir)/'`unix/odesrc/rotation.cpp unix/odesrc/libode_a-rotation.obj: unix/odesrc/rotation.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-rotation.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-rotation.Tpo -c -o unix/odesrc/libode_a-rotation.obj `if test -f 'unix/odesrc/rotation.cpp'; then $(CYGPATH_W) 'unix/odesrc/rotation.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/rotation.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-rotation.Tpo unix/odesrc/$(DEPDIR)/libode_a-rotation.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/rotation.cpp' object='unix/odesrc/libode_a-rotation.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-rotation.obj `if test -f 'unix/odesrc/rotation.cpp'; then $(CYGPATH_W) 'unix/odesrc/rotation.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/rotation.cpp'; fi` unix/odesrc/libode_a-sphere.o: unix/odesrc/sphere.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-sphere.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-sphere.Tpo -c -o unix/odesrc/libode_a-sphere.o `test -f 'unix/odesrc/sphere.cpp' || echo '$(srcdir)/'`unix/odesrc/sphere.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-sphere.Tpo unix/odesrc/$(DEPDIR)/libode_a-sphere.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/sphere.cpp' object='unix/odesrc/libode_a-sphere.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-sphere.o `test -f 'unix/odesrc/sphere.cpp' || echo '$(srcdir)/'`unix/odesrc/sphere.cpp unix/odesrc/libode_a-sphere.obj: unix/odesrc/sphere.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-sphere.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-sphere.Tpo -c -o unix/odesrc/libode_a-sphere.obj `if test -f 'unix/odesrc/sphere.cpp'; then $(CYGPATH_W) 'unix/odesrc/sphere.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/sphere.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-sphere.Tpo unix/odesrc/$(DEPDIR)/libode_a-sphere.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/sphere.cpp' object='unix/odesrc/libode_a-sphere.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-sphere.obj `if test -f 'unix/odesrc/sphere.cpp'; then $(CYGPATH_W) 'unix/odesrc/sphere.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/sphere.cpp'; fi` unix/odesrc/libode_a-step.o: unix/odesrc/step.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-step.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-step.Tpo -c -o unix/odesrc/libode_a-step.o `test -f 'unix/odesrc/step.cpp' || echo '$(srcdir)/'`unix/odesrc/step.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-step.Tpo unix/odesrc/$(DEPDIR)/libode_a-step.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/step.cpp' object='unix/odesrc/libode_a-step.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-step.o `test -f 'unix/odesrc/step.cpp' || echo '$(srcdir)/'`unix/odesrc/step.cpp unix/odesrc/libode_a-step.obj: unix/odesrc/step.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-step.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-step.Tpo -c -o unix/odesrc/libode_a-step.obj `if test -f 'unix/odesrc/step.cpp'; then $(CYGPATH_W) 'unix/odesrc/step.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/step.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-step.Tpo unix/odesrc/$(DEPDIR)/libode_a-step.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/step.cpp' object='unix/odesrc/libode_a-step.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-step.obj `if test -f 'unix/odesrc/step.cpp'; then $(CYGPATH_W) 'unix/odesrc/step.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/step.cpp'; fi` unix/odesrc/libode_a-stepfast.o: unix/odesrc/stepfast.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-stepfast.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-stepfast.Tpo -c -o unix/odesrc/libode_a-stepfast.o `test -f 'unix/odesrc/stepfast.cpp' || echo '$(srcdir)/'`unix/odesrc/stepfast.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-stepfast.Tpo unix/odesrc/$(DEPDIR)/libode_a-stepfast.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/stepfast.cpp' object='unix/odesrc/libode_a-stepfast.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-stepfast.o `test -f 'unix/odesrc/stepfast.cpp' || echo '$(srcdir)/'`unix/odesrc/stepfast.cpp unix/odesrc/libode_a-stepfast.obj: unix/odesrc/stepfast.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-stepfast.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-stepfast.Tpo -c -o unix/odesrc/libode_a-stepfast.obj `if test -f 'unix/odesrc/stepfast.cpp'; then $(CYGPATH_W) 'unix/odesrc/stepfast.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/stepfast.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-stepfast.Tpo unix/odesrc/$(DEPDIR)/libode_a-stepfast.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/stepfast.cpp' object='unix/odesrc/libode_a-stepfast.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-stepfast.obj `if test -f 'unix/odesrc/stepfast.cpp'; then $(CYGPATH_W) 'unix/odesrc/stepfast.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/stepfast.cpp'; fi` unix/odesrc/libode_a-testing.o: unix/odesrc/testing.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-testing.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-testing.Tpo -c -o unix/odesrc/libode_a-testing.o `test -f 'unix/odesrc/testing.cpp' || echo '$(srcdir)/'`unix/odesrc/testing.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-testing.Tpo unix/odesrc/$(DEPDIR)/libode_a-testing.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/testing.cpp' object='unix/odesrc/libode_a-testing.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-testing.o `test -f 'unix/odesrc/testing.cpp' || echo '$(srcdir)/'`unix/odesrc/testing.cpp unix/odesrc/libode_a-testing.obj: unix/odesrc/testing.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-testing.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-testing.Tpo -c -o unix/odesrc/libode_a-testing.obj `if test -f 'unix/odesrc/testing.cpp'; then $(CYGPATH_W) 'unix/odesrc/testing.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/testing.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-testing.Tpo unix/odesrc/$(DEPDIR)/libode_a-testing.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/testing.cpp' object='unix/odesrc/libode_a-testing.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-testing.obj `if test -f 'unix/odesrc/testing.cpp'; then $(CYGPATH_W) 'unix/odesrc/testing.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/testing.cpp'; fi` unix/odesrc/libode_a-timer.o: unix/odesrc/timer.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-timer.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-timer.Tpo -c -o unix/odesrc/libode_a-timer.o `test -f 'unix/odesrc/timer.cpp' || echo '$(srcdir)/'`unix/odesrc/timer.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-timer.Tpo unix/odesrc/$(DEPDIR)/libode_a-timer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/timer.cpp' object='unix/odesrc/libode_a-timer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-timer.o `test -f 'unix/odesrc/timer.cpp' || echo '$(srcdir)/'`unix/odesrc/timer.cpp unix/odesrc/libode_a-timer.obj: unix/odesrc/timer.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-timer.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-timer.Tpo -c -o unix/odesrc/libode_a-timer.obj `if test -f 'unix/odesrc/timer.cpp'; then $(CYGPATH_W) 'unix/odesrc/timer.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/timer.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-timer.Tpo unix/odesrc/$(DEPDIR)/libode_a-timer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/timer.cpp' object='unix/odesrc/libode_a-timer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-timer.obj `if test -f 'unix/odesrc/timer.cpp'; then $(CYGPATH_W) 'unix/odesrc/timer.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/timer.cpp'; fi` unix/odesrc/libode_a-util.o: unix/odesrc/util.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-util.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-util.Tpo -c -o unix/odesrc/libode_a-util.o `test -f 'unix/odesrc/util.cpp' || echo '$(srcdir)/'`unix/odesrc/util.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-util.Tpo unix/odesrc/$(DEPDIR)/libode_a-util.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/util.cpp' object='unix/odesrc/libode_a-util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-util.o `test -f 'unix/odesrc/util.cpp' || echo '$(srcdir)/'`unix/odesrc/util.cpp unix/odesrc/libode_a-util.obj: unix/odesrc/util.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-util.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-util.Tpo -c -o unix/odesrc/libode_a-util.obj `if test -f 'unix/odesrc/util.cpp'; then $(CYGPATH_W) 'unix/odesrc/util.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/util.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-util.Tpo unix/odesrc/$(DEPDIR)/libode_a-util.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/util.cpp' object='unix/odesrc/libode_a-util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-util.obj `if test -f 'unix/odesrc/util.cpp'; then $(CYGPATH_W) 'unix/odesrc/util.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/util.cpp'; fi` unix/odesrc/libode_a-collision_cylinder_trimesh.o: unix/odesrc/collision_cylinder_trimesh.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_cylinder_trimesh.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_trimesh.Tpo -c -o unix/odesrc/libode_a-collision_cylinder_trimesh.o `test -f 'unix/odesrc/collision_cylinder_trimesh.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_cylinder_trimesh.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_trimesh.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_trimesh.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_cylinder_trimesh.cpp' object='unix/odesrc/libode_a-collision_cylinder_trimesh.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_cylinder_trimesh.o `test -f 'unix/odesrc/collision_cylinder_trimesh.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_cylinder_trimesh.cpp unix/odesrc/libode_a-collision_cylinder_trimesh.obj: unix/odesrc/collision_cylinder_trimesh.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_cylinder_trimesh.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_trimesh.Tpo -c -o unix/odesrc/libode_a-collision_cylinder_trimesh.obj `if test -f 'unix/odesrc/collision_cylinder_trimesh.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_cylinder_trimesh.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_cylinder_trimesh.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_trimesh.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_cylinder_trimesh.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_cylinder_trimesh.cpp' object='unix/odesrc/libode_a-collision_cylinder_trimesh.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_cylinder_trimesh.obj `if test -f 'unix/odesrc/collision_cylinder_trimesh.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_cylinder_trimesh.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_cylinder_trimesh.cpp'; fi` unix/odesrc/libode_a-collision_trimesh_box.o: unix/odesrc/collision_trimesh_box.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_trimesh_box.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_box.Tpo -c -o unix/odesrc/libode_a-collision_trimesh_box.o `test -f 'unix/odesrc/collision_trimesh_box.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_trimesh_box.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_box.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_box.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_trimesh_box.cpp' object='unix/odesrc/libode_a-collision_trimesh_box.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_trimesh_box.o `test -f 'unix/odesrc/collision_trimesh_box.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_trimesh_box.cpp unix/odesrc/libode_a-collision_trimesh_box.obj: unix/odesrc/collision_trimesh_box.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_trimesh_box.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_box.Tpo -c -o unix/odesrc/libode_a-collision_trimesh_box.obj `if test -f 'unix/odesrc/collision_trimesh_box.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_trimesh_box.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_trimesh_box.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_box.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_box.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_trimesh_box.cpp' object='unix/odesrc/libode_a-collision_trimesh_box.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_trimesh_box.obj `if test -f 'unix/odesrc/collision_trimesh_box.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_trimesh_box.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_trimesh_box.cpp'; fi` unix/odesrc/libode_a-collision_trimesh_ccylinder.o: unix/odesrc/collision_trimesh_ccylinder.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_trimesh_ccylinder.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_ccylinder.Tpo -c -o unix/odesrc/libode_a-collision_trimesh_ccylinder.o `test -f 'unix/odesrc/collision_trimesh_ccylinder.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_trimesh_ccylinder.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_ccylinder.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_ccylinder.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_trimesh_ccylinder.cpp' object='unix/odesrc/libode_a-collision_trimesh_ccylinder.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_trimesh_ccylinder.o `test -f 'unix/odesrc/collision_trimesh_ccylinder.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_trimesh_ccylinder.cpp unix/odesrc/libode_a-collision_trimesh_ccylinder.obj: unix/odesrc/collision_trimesh_ccylinder.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_trimesh_ccylinder.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_ccylinder.Tpo -c -o unix/odesrc/libode_a-collision_trimesh_ccylinder.obj `if test -f 'unix/odesrc/collision_trimesh_ccylinder.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_trimesh_ccylinder.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_trimesh_ccylinder.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_ccylinder.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_ccylinder.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_trimesh_ccylinder.cpp' object='unix/odesrc/libode_a-collision_trimesh_ccylinder.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_trimesh_ccylinder.obj `if test -f 'unix/odesrc/collision_trimesh_ccylinder.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_trimesh_ccylinder.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_trimesh_ccylinder.cpp'; fi` unix/odesrc/libode_a-collision_trimesh_distance.o: unix/odesrc/collision_trimesh_distance.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_trimesh_distance.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_distance.Tpo -c -o unix/odesrc/libode_a-collision_trimesh_distance.o `test -f 'unix/odesrc/collision_trimesh_distance.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_trimesh_distance.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_distance.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_distance.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_trimesh_distance.cpp' object='unix/odesrc/libode_a-collision_trimesh_distance.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_trimesh_distance.o `test -f 'unix/odesrc/collision_trimesh_distance.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_trimesh_distance.cpp unix/odesrc/libode_a-collision_trimesh_distance.obj: unix/odesrc/collision_trimesh_distance.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_trimesh_distance.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_distance.Tpo -c -o unix/odesrc/libode_a-collision_trimesh_distance.obj `if test -f 'unix/odesrc/collision_trimesh_distance.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_trimesh_distance.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_trimesh_distance.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_distance.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_distance.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_trimesh_distance.cpp' object='unix/odesrc/libode_a-collision_trimesh_distance.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_trimesh_distance.obj `if test -f 'unix/odesrc/collision_trimesh_distance.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_trimesh_distance.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_trimesh_distance.cpp'; fi` unix/odesrc/libode_a-collision_trimesh_opcode.o: unix/odesrc/collision_trimesh_opcode.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_trimesh_opcode.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_opcode.Tpo -c -o unix/odesrc/libode_a-collision_trimesh_opcode.o `test -f 'unix/odesrc/collision_trimesh_opcode.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_trimesh_opcode.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_opcode.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_opcode.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_trimesh_opcode.cpp' object='unix/odesrc/libode_a-collision_trimesh_opcode.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_trimesh_opcode.o `test -f 'unix/odesrc/collision_trimesh_opcode.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_trimesh_opcode.cpp unix/odesrc/libode_a-collision_trimesh_opcode.obj: unix/odesrc/collision_trimesh_opcode.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_trimesh_opcode.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_opcode.Tpo -c -o unix/odesrc/libode_a-collision_trimesh_opcode.obj `if test -f 'unix/odesrc/collision_trimesh_opcode.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_trimesh_opcode.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_trimesh_opcode.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_opcode.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_opcode.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_trimesh_opcode.cpp' object='unix/odesrc/libode_a-collision_trimesh_opcode.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_trimesh_opcode.obj `if test -f 'unix/odesrc/collision_trimesh_opcode.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_trimesh_opcode.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_trimesh_opcode.cpp'; fi` unix/odesrc/libode_a-collision_trimesh_plane.o: unix/odesrc/collision_trimesh_plane.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_trimesh_plane.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_plane.Tpo -c -o unix/odesrc/libode_a-collision_trimesh_plane.o `test -f 'unix/odesrc/collision_trimesh_plane.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_trimesh_plane.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_plane.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_plane.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_trimesh_plane.cpp' object='unix/odesrc/libode_a-collision_trimesh_plane.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_trimesh_plane.o `test -f 'unix/odesrc/collision_trimesh_plane.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_trimesh_plane.cpp unix/odesrc/libode_a-collision_trimesh_plane.obj: unix/odesrc/collision_trimesh_plane.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_trimesh_plane.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_plane.Tpo -c -o unix/odesrc/libode_a-collision_trimesh_plane.obj `if test -f 'unix/odesrc/collision_trimesh_plane.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_trimesh_plane.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_trimesh_plane.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_plane.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_plane.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_trimesh_plane.cpp' object='unix/odesrc/libode_a-collision_trimesh_plane.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_trimesh_plane.obj `if test -f 'unix/odesrc/collision_trimesh_plane.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_trimesh_plane.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_trimesh_plane.cpp'; fi` unix/odesrc/libode_a-collision_trimesh_ray.o: unix/odesrc/collision_trimesh_ray.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_trimesh_ray.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_ray.Tpo -c -o unix/odesrc/libode_a-collision_trimesh_ray.o `test -f 'unix/odesrc/collision_trimesh_ray.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_trimesh_ray.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_ray.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_ray.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_trimesh_ray.cpp' object='unix/odesrc/libode_a-collision_trimesh_ray.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_trimesh_ray.o `test -f 'unix/odesrc/collision_trimesh_ray.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_trimesh_ray.cpp unix/odesrc/libode_a-collision_trimesh_ray.obj: unix/odesrc/collision_trimesh_ray.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_trimesh_ray.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_ray.Tpo -c -o unix/odesrc/libode_a-collision_trimesh_ray.obj `if test -f 'unix/odesrc/collision_trimesh_ray.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_trimesh_ray.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_trimesh_ray.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_ray.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_ray.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_trimesh_ray.cpp' object='unix/odesrc/libode_a-collision_trimesh_ray.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_trimesh_ray.obj `if test -f 'unix/odesrc/collision_trimesh_ray.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_trimesh_ray.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_trimesh_ray.cpp'; fi` unix/odesrc/libode_a-collision_trimesh_sphere.o: unix/odesrc/collision_trimesh_sphere.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_trimesh_sphere.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_sphere.Tpo -c -o unix/odesrc/libode_a-collision_trimesh_sphere.o `test -f 'unix/odesrc/collision_trimesh_sphere.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_trimesh_sphere.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_sphere.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_sphere.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_trimesh_sphere.cpp' object='unix/odesrc/libode_a-collision_trimesh_sphere.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_trimesh_sphere.o `test -f 'unix/odesrc/collision_trimesh_sphere.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_trimesh_sphere.cpp unix/odesrc/libode_a-collision_trimesh_sphere.obj: unix/odesrc/collision_trimesh_sphere.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_trimesh_sphere.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_sphere.Tpo -c -o unix/odesrc/libode_a-collision_trimesh_sphere.obj `if test -f 'unix/odesrc/collision_trimesh_sphere.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_trimesh_sphere.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_trimesh_sphere.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_sphere.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_sphere.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_trimesh_sphere.cpp' object='unix/odesrc/libode_a-collision_trimesh_sphere.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_trimesh_sphere.obj `if test -f 'unix/odesrc/collision_trimesh_sphere.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_trimesh_sphere.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_trimesh_sphere.cpp'; fi` unix/odesrc/libode_a-collision_trimesh_trimesh.o: unix/odesrc/collision_trimesh_trimesh.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_trimesh_trimesh.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_trimesh.Tpo -c -o unix/odesrc/libode_a-collision_trimesh_trimesh.o `test -f 'unix/odesrc/collision_trimesh_trimesh.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_trimesh_trimesh.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_trimesh.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_trimesh.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_trimesh_trimesh.cpp' object='unix/odesrc/libode_a-collision_trimesh_trimesh.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_trimesh_trimesh.o `test -f 'unix/odesrc/collision_trimesh_trimesh.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_trimesh_trimesh.cpp unix/odesrc/libode_a-collision_trimesh_trimesh.obj: unix/odesrc/collision_trimesh_trimesh.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_trimesh_trimesh.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_trimesh.Tpo -c -o unix/odesrc/libode_a-collision_trimesh_trimesh.obj `if test -f 'unix/odesrc/collision_trimesh_trimesh.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_trimesh_trimesh.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_trimesh_trimesh.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_trimesh.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_trimesh.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_trimesh_trimesh.cpp' object='unix/odesrc/libode_a-collision_trimesh_trimesh.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_trimesh_trimesh.obj `if test -f 'unix/odesrc/collision_trimesh_trimesh.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_trimesh_trimesh.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_trimesh_trimesh.cpp'; fi` unix/odesrc/libode_a-collision_trimesh_trimesh_new.o: unix/odesrc/collision_trimesh_trimesh_new.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_trimesh_trimesh_new.o -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_trimesh_new.Tpo -c -o unix/odesrc/libode_a-collision_trimesh_trimesh_new.o `test -f 'unix/odesrc/collision_trimesh_trimesh_new.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_trimesh_trimesh_new.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_trimesh_new.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_trimesh_new.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_trimesh_trimesh_new.cpp' object='unix/odesrc/libode_a-collision_trimesh_trimesh_new.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_trimesh_trimesh_new.o `test -f 'unix/odesrc/collision_trimesh_trimesh_new.cpp' || echo '$(srcdir)/'`unix/odesrc/collision_trimesh_trimesh_new.cpp unix/odesrc/libode_a-collision_trimesh_trimesh_new.obj: unix/odesrc/collision_trimesh_trimesh_new.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/libode_a-collision_trimesh_trimesh_new.obj -MD -MP -MF unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_trimesh_new.Tpo -c -o unix/odesrc/libode_a-collision_trimesh_trimesh_new.obj `if test -f 'unix/odesrc/collision_trimesh_trimesh_new.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_trimesh_trimesh_new.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_trimesh_trimesh_new.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_trimesh_new.Tpo unix/odesrc/$(DEPDIR)/libode_a-collision_trimesh_trimesh_new.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/collision_trimesh_trimesh_new.cpp' object='unix/odesrc/libode_a-collision_trimesh_trimesh_new.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/libode_a-collision_trimesh_trimesh_new.obj `if test -f 'unix/odesrc/collision_trimesh_trimesh_new.cpp'; then $(CYGPATH_W) 'unix/odesrc/collision_trimesh_trimesh_new.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/collision_trimesh_trimesh_new.cpp'; fi` unix/odesrc/joints/libode_a-amotor.o: unix/odesrc/joints/amotor.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-amotor.o -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-amotor.Tpo -c -o unix/odesrc/joints/libode_a-amotor.o `test -f 'unix/odesrc/joints/amotor.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/amotor.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-amotor.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-amotor.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/amotor.cpp' object='unix/odesrc/joints/libode_a-amotor.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-amotor.o `test -f 'unix/odesrc/joints/amotor.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/amotor.cpp unix/odesrc/joints/libode_a-amotor.obj: unix/odesrc/joints/amotor.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-amotor.obj -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-amotor.Tpo -c -o unix/odesrc/joints/libode_a-amotor.obj `if test -f 'unix/odesrc/joints/amotor.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/amotor.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/amotor.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-amotor.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-amotor.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/amotor.cpp' object='unix/odesrc/joints/libode_a-amotor.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-amotor.obj `if test -f 'unix/odesrc/joints/amotor.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/amotor.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/amotor.cpp'; fi` unix/odesrc/joints/libode_a-ball.o: unix/odesrc/joints/ball.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-ball.o -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-ball.Tpo -c -o unix/odesrc/joints/libode_a-ball.o `test -f 'unix/odesrc/joints/ball.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/ball.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-ball.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-ball.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/ball.cpp' object='unix/odesrc/joints/libode_a-ball.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-ball.o `test -f 'unix/odesrc/joints/ball.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/ball.cpp unix/odesrc/joints/libode_a-ball.obj: unix/odesrc/joints/ball.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-ball.obj -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-ball.Tpo -c -o unix/odesrc/joints/libode_a-ball.obj `if test -f 'unix/odesrc/joints/ball.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/ball.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/ball.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-ball.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-ball.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/ball.cpp' object='unix/odesrc/joints/libode_a-ball.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-ball.obj `if test -f 'unix/odesrc/joints/ball.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/ball.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/ball.cpp'; fi` unix/odesrc/joints/libode_a-contact.o: unix/odesrc/joints/contact.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-contact.o -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-contact.Tpo -c -o unix/odesrc/joints/libode_a-contact.o `test -f 'unix/odesrc/joints/contact.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/contact.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-contact.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-contact.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/contact.cpp' object='unix/odesrc/joints/libode_a-contact.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-contact.o `test -f 'unix/odesrc/joints/contact.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/contact.cpp unix/odesrc/joints/libode_a-contact.obj: unix/odesrc/joints/contact.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-contact.obj -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-contact.Tpo -c -o unix/odesrc/joints/libode_a-contact.obj `if test -f 'unix/odesrc/joints/contact.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/contact.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/contact.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-contact.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-contact.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/contact.cpp' object='unix/odesrc/joints/libode_a-contact.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-contact.obj `if test -f 'unix/odesrc/joints/contact.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/contact.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/contact.cpp'; fi` unix/odesrc/joints/libode_a-fixed.o: unix/odesrc/joints/fixed.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-fixed.o -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-fixed.Tpo -c -o unix/odesrc/joints/libode_a-fixed.o `test -f 'unix/odesrc/joints/fixed.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/fixed.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-fixed.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-fixed.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/fixed.cpp' object='unix/odesrc/joints/libode_a-fixed.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-fixed.o `test -f 'unix/odesrc/joints/fixed.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/fixed.cpp unix/odesrc/joints/libode_a-fixed.obj: unix/odesrc/joints/fixed.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-fixed.obj -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-fixed.Tpo -c -o unix/odesrc/joints/libode_a-fixed.obj `if test -f 'unix/odesrc/joints/fixed.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/fixed.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/fixed.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-fixed.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-fixed.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/fixed.cpp' object='unix/odesrc/joints/libode_a-fixed.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-fixed.obj `if test -f 'unix/odesrc/joints/fixed.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/fixed.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/fixed.cpp'; fi` unix/odesrc/joints/libode_a-hinge2.o: unix/odesrc/joints/hinge2.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-hinge2.o -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-hinge2.Tpo -c -o unix/odesrc/joints/libode_a-hinge2.o `test -f 'unix/odesrc/joints/hinge2.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/hinge2.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-hinge2.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-hinge2.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/hinge2.cpp' object='unix/odesrc/joints/libode_a-hinge2.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-hinge2.o `test -f 'unix/odesrc/joints/hinge2.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/hinge2.cpp unix/odesrc/joints/libode_a-hinge2.obj: unix/odesrc/joints/hinge2.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-hinge2.obj -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-hinge2.Tpo -c -o unix/odesrc/joints/libode_a-hinge2.obj `if test -f 'unix/odesrc/joints/hinge2.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/hinge2.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/hinge2.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-hinge2.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-hinge2.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/hinge2.cpp' object='unix/odesrc/joints/libode_a-hinge2.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-hinge2.obj `if test -f 'unix/odesrc/joints/hinge2.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/hinge2.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/hinge2.cpp'; fi` unix/odesrc/joints/libode_a-hinge.o: unix/odesrc/joints/hinge.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-hinge.o -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-hinge.Tpo -c -o unix/odesrc/joints/libode_a-hinge.o `test -f 'unix/odesrc/joints/hinge.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/hinge.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-hinge.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-hinge.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/hinge.cpp' object='unix/odesrc/joints/libode_a-hinge.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-hinge.o `test -f 'unix/odesrc/joints/hinge.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/hinge.cpp unix/odesrc/joints/libode_a-hinge.obj: unix/odesrc/joints/hinge.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-hinge.obj -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-hinge.Tpo -c -o unix/odesrc/joints/libode_a-hinge.obj `if test -f 'unix/odesrc/joints/hinge.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/hinge.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/hinge.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-hinge.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-hinge.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/hinge.cpp' object='unix/odesrc/joints/libode_a-hinge.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-hinge.obj `if test -f 'unix/odesrc/joints/hinge.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/hinge.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/hinge.cpp'; fi` unix/odesrc/joints/libode_a-joint.o: unix/odesrc/joints/joint.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-joint.o -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-joint.Tpo -c -o unix/odesrc/joints/libode_a-joint.o `test -f 'unix/odesrc/joints/joint.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/joint.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-joint.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-joint.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/joint.cpp' object='unix/odesrc/joints/libode_a-joint.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-joint.o `test -f 'unix/odesrc/joints/joint.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/joint.cpp unix/odesrc/joints/libode_a-joint.obj: unix/odesrc/joints/joint.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-joint.obj -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-joint.Tpo -c -o unix/odesrc/joints/libode_a-joint.obj `if test -f 'unix/odesrc/joints/joint.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/joint.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/joint.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-joint.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-joint.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/joint.cpp' object='unix/odesrc/joints/libode_a-joint.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-joint.obj `if test -f 'unix/odesrc/joints/joint.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/joint.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/joint.cpp'; fi` unix/odesrc/joints/libode_a-lmotor.o: unix/odesrc/joints/lmotor.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-lmotor.o -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-lmotor.Tpo -c -o unix/odesrc/joints/libode_a-lmotor.o `test -f 'unix/odesrc/joints/lmotor.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/lmotor.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-lmotor.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-lmotor.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/lmotor.cpp' object='unix/odesrc/joints/libode_a-lmotor.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-lmotor.o `test -f 'unix/odesrc/joints/lmotor.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/lmotor.cpp unix/odesrc/joints/libode_a-lmotor.obj: unix/odesrc/joints/lmotor.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-lmotor.obj -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-lmotor.Tpo -c -o unix/odesrc/joints/libode_a-lmotor.obj `if test -f 'unix/odesrc/joints/lmotor.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/lmotor.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/lmotor.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-lmotor.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-lmotor.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/lmotor.cpp' object='unix/odesrc/joints/libode_a-lmotor.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-lmotor.obj `if test -f 'unix/odesrc/joints/lmotor.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/lmotor.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/lmotor.cpp'; fi` unix/odesrc/joints/libode_a-null.o: unix/odesrc/joints/null.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-null.o -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-null.Tpo -c -o unix/odesrc/joints/libode_a-null.o `test -f 'unix/odesrc/joints/null.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/null.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-null.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-null.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/null.cpp' object='unix/odesrc/joints/libode_a-null.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-null.o `test -f 'unix/odesrc/joints/null.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/null.cpp unix/odesrc/joints/libode_a-null.obj: unix/odesrc/joints/null.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-null.obj -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-null.Tpo -c -o unix/odesrc/joints/libode_a-null.obj `if test -f 'unix/odesrc/joints/null.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/null.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/null.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-null.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-null.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/null.cpp' object='unix/odesrc/joints/libode_a-null.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-null.obj `if test -f 'unix/odesrc/joints/null.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/null.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/null.cpp'; fi` unix/odesrc/joints/libode_a-piston.o: unix/odesrc/joints/piston.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-piston.o -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-piston.Tpo -c -o unix/odesrc/joints/libode_a-piston.o `test -f 'unix/odesrc/joints/piston.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/piston.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-piston.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-piston.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/piston.cpp' object='unix/odesrc/joints/libode_a-piston.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-piston.o `test -f 'unix/odesrc/joints/piston.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/piston.cpp unix/odesrc/joints/libode_a-piston.obj: unix/odesrc/joints/piston.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-piston.obj -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-piston.Tpo -c -o unix/odesrc/joints/libode_a-piston.obj `if test -f 'unix/odesrc/joints/piston.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/piston.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/piston.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-piston.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-piston.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/piston.cpp' object='unix/odesrc/joints/libode_a-piston.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-piston.obj `if test -f 'unix/odesrc/joints/piston.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/piston.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/piston.cpp'; fi` unix/odesrc/joints/libode_a-plane2d.o: unix/odesrc/joints/plane2d.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-plane2d.o -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-plane2d.Tpo -c -o unix/odesrc/joints/libode_a-plane2d.o `test -f 'unix/odesrc/joints/plane2d.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/plane2d.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-plane2d.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-plane2d.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/plane2d.cpp' object='unix/odesrc/joints/libode_a-plane2d.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-plane2d.o `test -f 'unix/odesrc/joints/plane2d.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/plane2d.cpp unix/odesrc/joints/libode_a-plane2d.obj: unix/odesrc/joints/plane2d.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-plane2d.obj -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-plane2d.Tpo -c -o unix/odesrc/joints/libode_a-plane2d.obj `if test -f 'unix/odesrc/joints/plane2d.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/plane2d.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/plane2d.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-plane2d.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-plane2d.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/plane2d.cpp' object='unix/odesrc/joints/libode_a-plane2d.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-plane2d.obj `if test -f 'unix/odesrc/joints/plane2d.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/plane2d.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/plane2d.cpp'; fi` unix/odesrc/joints/libode_a-pr.o: unix/odesrc/joints/pr.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-pr.o -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-pr.Tpo -c -o unix/odesrc/joints/libode_a-pr.o `test -f 'unix/odesrc/joints/pr.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/pr.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-pr.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-pr.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/pr.cpp' object='unix/odesrc/joints/libode_a-pr.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-pr.o `test -f 'unix/odesrc/joints/pr.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/pr.cpp unix/odesrc/joints/libode_a-pr.obj: unix/odesrc/joints/pr.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-pr.obj -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-pr.Tpo -c -o unix/odesrc/joints/libode_a-pr.obj `if test -f 'unix/odesrc/joints/pr.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/pr.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/pr.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-pr.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-pr.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/pr.cpp' object='unix/odesrc/joints/libode_a-pr.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-pr.obj `if test -f 'unix/odesrc/joints/pr.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/pr.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/pr.cpp'; fi` unix/odesrc/joints/libode_a-pu.o: unix/odesrc/joints/pu.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-pu.o -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-pu.Tpo -c -o unix/odesrc/joints/libode_a-pu.o `test -f 'unix/odesrc/joints/pu.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/pu.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-pu.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-pu.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/pu.cpp' object='unix/odesrc/joints/libode_a-pu.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-pu.o `test -f 'unix/odesrc/joints/pu.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/pu.cpp unix/odesrc/joints/libode_a-pu.obj: unix/odesrc/joints/pu.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-pu.obj -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-pu.Tpo -c -o unix/odesrc/joints/libode_a-pu.obj `if test -f 'unix/odesrc/joints/pu.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/pu.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/pu.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-pu.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-pu.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/pu.cpp' object='unix/odesrc/joints/libode_a-pu.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-pu.obj `if test -f 'unix/odesrc/joints/pu.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/pu.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/pu.cpp'; fi` unix/odesrc/joints/libode_a-slider.o: unix/odesrc/joints/slider.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-slider.o -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-slider.Tpo -c -o unix/odesrc/joints/libode_a-slider.o `test -f 'unix/odesrc/joints/slider.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/slider.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-slider.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-slider.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/slider.cpp' object='unix/odesrc/joints/libode_a-slider.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-slider.o `test -f 'unix/odesrc/joints/slider.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/slider.cpp unix/odesrc/joints/libode_a-slider.obj: unix/odesrc/joints/slider.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-slider.obj -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-slider.Tpo -c -o unix/odesrc/joints/libode_a-slider.obj `if test -f 'unix/odesrc/joints/slider.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/slider.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/slider.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-slider.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-slider.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/slider.cpp' object='unix/odesrc/joints/libode_a-slider.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-slider.obj `if test -f 'unix/odesrc/joints/slider.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/slider.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/slider.cpp'; fi` unix/odesrc/joints/libode_a-universal.o: unix/odesrc/joints/universal.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-universal.o -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-universal.Tpo -c -o unix/odesrc/joints/libode_a-universal.o `test -f 'unix/odesrc/joints/universal.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/universal.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-universal.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-universal.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/universal.cpp' object='unix/odesrc/joints/libode_a-universal.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-universal.o `test -f 'unix/odesrc/joints/universal.cpp' || echo '$(srcdir)/'`unix/odesrc/joints/universal.cpp unix/odesrc/joints/libode_a-universal.obj: unix/odesrc/joints/universal.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/joints/libode_a-universal.obj -MD -MP -MF unix/odesrc/joints/$(DEPDIR)/libode_a-universal.Tpo -c -o unix/odesrc/joints/libode_a-universal.obj `if test -f 'unix/odesrc/joints/universal.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/universal.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/universal.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/joints/$(DEPDIR)/libode_a-universal.Tpo unix/odesrc/joints/$(DEPDIR)/libode_a-universal.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/joints/universal.cpp' object='unix/odesrc/joints/libode_a-universal.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/joints/libode_a-universal.obj `if test -f 'unix/odesrc/joints/universal.cpp'; then $(CYGPATH_W) 'unix/odesrc/joints/universal.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/joints/universal.cpp'; fi` unix/odesrc/OPCODE/libode_a-OPC_AABBCollider.o: unix/odesrc/OPCODE/OPC_AABBCollider.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_AABBCollider.o -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_AABBCollider.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_AABBCollider.o `test -f 'unix/odesrc/OPCODE/OPC_AABBCollider.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_AABBCollider.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_AABBCollider.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_AABBCollider.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_AABBCollider.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_AABBCollider.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_AABBCollider.o `test -f 'unix/odesrc/OPCODE/OPC_AABBCollider.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_AABBCollider.cpp unix/odesrc/OPCODE/libode_a-OPC_AABBCollider.obj: unix/odesrc/OPCODE/OPC_AABBCollider.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_AABBCollider.obj -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_AABBCollider.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_AABBCollider.obj `if test -f 'unix/odesrc/OPCODE/OPC_AABBCollider.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_AABBCollider.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_AABBCollider.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_AABBCollider.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_AABBCollider.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_AABBCollider.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_AABBCollider.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_AABBCollider.obj `if test -f 'unix/odesrc/OPCODE/OPC_AABBCollider.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_AABBCollider.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_AABBCollider.cpp'; fi` unix/odesrc/OPCODE/libode_a-OPC_AABBTree.o: unix/odesrc/OPCODE/OPC_AABBTree.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_AABBTree.o -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_AABBTree.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_AABBTree.o `test -f 'unix/odesrc/OPCODE/OPC_AABBTree.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_AABBTree.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_AABBTree.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_AABBTree.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_AABBTree.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_AABBTree.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_AABBTree.o `test -f 'unix/odesrc/OPCODE/OPC_AABBTree.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_AABBTree.cpp unix/odesrc/OPCODE/libode_a-OPC_AABBTree.obj: unix/odesrc/OPCODE/OPC_AABBTree.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_AABBTree.obj -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_AABBTree.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_AABBTree.obj `if test -f 'unix/odesrc/OPCODE/OPC_AABBTree.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_AABBTree.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_AABBTree.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_AABBTree.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_AABBTree.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_AABBTree.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_AABBTree.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_AABBTree.obj `if test -f 'unix/odesrc/OPCODE/OPC_AABBTree.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_AABBTree.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_AABBTree.cpp'; fi` unix/odesrc/OPCODE/libode_a-OPC_BaseModel.o: unix/odesrc/OPCODE/OPC_BaseModel.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_BaseModel.o -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_BaseModel.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_BaseModel.o `test -f 'unix/odesrc/OPCODE/OPC_BaseModel.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_BaseModel.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_BaseModel.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_BaseModel.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_BaseModel.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_BaseModel.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_BaseModel.o `test -f 'unix/odesrc/OPCODE/OPC_BaseModel.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_BaseModel.cpp unix/odesrc/OPCODE/libode_a-OPC_BaseModel.obj: unix/odesrc/OPCODE/OPC_BaseModel.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_BaseModel.obj -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_BaseModel.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_BaseModel.obj `if test -f 'unix/odesrc/OPCODE/OPC_BaseModel.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_BaseModel.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_BaseModel.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_BaseModel.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_BaseModel.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_BaseModel.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_BaseModel.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_BaseModel.obj `if test -f 'unix/odesrc/OPCODE/OPC_BaseModel.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_BaseModel.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_BaseModel.cpp'; fi` unix/odesrc/OPCODE/libode_a-OPC_Collider.o: unix/odesrc/OPCODE/OPC_Collider.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_Collider.o -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Collider.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_Collider.o `test -f 'unix/odesrc/OPCODE/OPC_Collider.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_Collider.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Collider.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Collider.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_Collider.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_Collider.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_Collider.o `test -f 'unix/odesrc/OPCODE/OPC_Collider.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_Collider.cpp unix/odesrc/OPCODE/libode_a-OPC_Collider.obj: unix/odesrc/OPCODE/OPC_Collider.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_Collider.obj -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Collider.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_Collider.obj `if test -f 'unix/odesrc/OPCODE/OPC_Collider.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_Collider.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_Collider.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Collider.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Collider.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_Collider.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_Collider.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_Collider.obj `if test -f 'unix/odesrc/OPCODE/OPC_Collider.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_Collider.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_Collider.cpp'; fi` unix/odesrc/OPCODE/libode_a-OPC_Common.o: unix/odesrc/OPCODE/OPC_Common.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_Common.o -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Common.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_Common.o `test -f 'unix/odesrc/OPCODE/OPC_Common.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_Common.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Common.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Common.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_Common.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_Common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_Common.o `test -f 'unix/odesrc/OPCODE/OPC_Common.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_Common.cpp unix/odesrc/OPCODE/libode_a-OPC_Common.obj: unix/odesrc/OPCODE/OPC_Common.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_Common.obj -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Common.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_Common.obj `if test -f 'unix/odesrc/OPCODE/OPC_Common.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_Common.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_Common.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Common.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Common.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_Common.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_Common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_Common.obj `if test -f 'unix/odesrc/OPCODE/OPC_Common.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_Common.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_Common.cpp'; fi` unix/odesrc/OPCODE/libode_a-OPC_HybridModel.o: unix/odesrc/OPCODE/OPC_HybridModel.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_HybridModel.o -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_HybridModel.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_HybridModel.o `test -f 'unix/odesrc/OPCODE/OPC_HybridModel.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_HybridModel.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_HybridModel.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_HybridModel.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_HybridModel.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_HybridModel.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_HybridModel.o `test -f 'unix/odesrc/OPCODE/OPC_HybridModel.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_HybridModel.cpp unix/odesrc/OPCODE/libode_a-OPC_HybridModel.obj: unix/odesrc/OPCODE/OPC_HybridModel.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_HybridModel.obj -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_HybridModel.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_HybridModel.obj `if test -f 'unix/odesrc/OPCODE/OPC_HybridModel.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_HybridModel.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_HybridModel.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_HybridModel.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_HybridModel.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_HybridModel.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_HybridModel.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_HybridModel.obj `if test -f 'unix/odesrc/OPCODE/OPC_HybridModel.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_HybridModel.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_HybridModel.cpp'; fi` unix/odesrc/OPCODE/libode_a-OPC_LSSCollider.o: unix/odesrc/OPCODE/OPC_LSSCollider.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_LSSCollider.o -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_LSSCollider.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_LSSCollider.o `test -f 'unix/odesrc/OPCODE/OPC_LSSCollider.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_LSSCollider.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_LSSCollider.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_LSSCollider.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_LSSCollider.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_LSSCollider.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_LSSCollider.o `test -f 'unix/odesrc/OPCODE/OPC_LSSCollider.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_LSSCollider.cpp unix/odesrc/OPCODE/libode_a-OPC_LSSCollider.obj: unix/odesrc/OPCODE/OPC_LSSCollider.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_LSSCollider.obj -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_LSSCollider.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_LSSCollider.obj `if test -f 'unix/odesrc/OPCODE/OPC_LSSCollider.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_LSSCollider.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_LSSCollider.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_LSSCollider.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_LSSCollider.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_LSSCollider.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_LSSCollider.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_LSSCollider.obj `if test -f 'unix/odesrc/OPCODE/OPC_LSSCollider.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_LSSCollider.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_LSSCollider.cpp'; fi` unix/odesrc/OPCODE/libode_a-OPC_MeshInterface.o: unix/odesrc/OPCODE/OPC_MeshInterface.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_MeshInterface.o -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_MeshInterface.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_MeshInterface.o `test -f 'unix/odesrc/OPCODE/OPC_MeshInterface.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_MeshInterface.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_MeshInterface.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_MeshInterface.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_MeshInterface.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_MeshInterface.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_MeshInterface.o `test -f 'unix/odesrc/OPCODE/OPC_MeshInterface.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_MeshInterface.cpp unix/odesrc/OPCODE/libode_a-OPC_MeshInterface.obj: unix/odesrc/OPCODE/OPC_MeshInterface.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_MeshInterface.obj -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_MeshInterface.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_MeshInterface.obj `if test -f 'unix/odesrc/OPCODE/OPC_MeshInterface.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_MeshInterface.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_MeshInterface.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_MeshInterface.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_MeshInterface.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_MeshInterface.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_MeshInterface.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_MeshInterface.obj `if test -f 'unix/odesrc/OPCODE/OPC_MeshInterface.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_MeshInterface.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_MeshInterface.cpp'; fi` unix/odesrc/OPCODE/libode_a-OPC_Model.o: unix/odesrc/OPCODE/OPC_Model.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_Model.o -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Model.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_Model.o `test -f 'unix/odesrc/OPCODE/OPC_Model.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_Model.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Model.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Model.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_Model.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_Model.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_Model.o `test -f 'unix/odesrc/OPCODE/OPC_Model.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_Model.cpp unix/odesrc/OPCODE/libode_a-OPC_Model.obj: unix/odesrc/OPCODE/OPC_Model.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_Model.obj -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Model.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_Model.obj `if test -f 'unix/odesrc/OPCODE/OPC_Model.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_Model.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_Model.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Model.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Model.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_Model.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_Model.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_Model.obj `if test -f 'unix/odesrc/OPCODE/OPC_Model.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_Model.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_Model.cpp'; fi` unix/odesrc/OPCODE/libode_a-OPC_OBBCollider.o: unix/odesrc/OPCODE/OPC_OBBCollider.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_OBBCollider.o -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_OBBCollider.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_OBBCollider.o `test -f 'unix/odesrc/OPCODE/OPC_OBBCollider.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_OBBCollider.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_OBBCollider.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_OBBCollider.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_OBBCollider.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_OBBCollider.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_OBBCollider.o `test -f 'unix/odesrc/OPCODE/OPC_OBBCollider.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_OBBCollider.cpp unix/odesrc/OPCODE/libode_a-OPC_OBBCollider.obj: unix/odesrc/OPCODE/OPC_OBBCollider.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_OBBCollider.obj -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_OBBCollider.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_OBBCollider.obj `if test -f 'unix/odesrc/OPCODE/OPC_OBBCollider.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_OBBCollider.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_OBBCollider.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_OBBCollider.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_OBBCollider.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_OBBCollider.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_OBBCollider.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_OBBCollider.obj `if test -f 'unix/odesrc/OPCODE/OPC_OBBCollider.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_OBBCollider.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_OBBCollider.cpp'; fi` unix/odesrc/OPCODE/libode_a-Opcode.o: unix/odesrc/OPCODE/Opcode.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-Opcode.o -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-Opcode.Tpo -c -o unix/odesrc/OPCODE/libode_a-Opcode.o `test -f 'unix/odesrc/OPCODE/Opcode.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Opcode.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-Opcode.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-Opcode.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Opcode.cpp' object='unix/odesrc/OPCODE/libode_a-Opcode.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-Opcode.o `test -f 'unix/odesrc/OPCODE/Opcode.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Opcode.cpp unix/odesrc/OPCODE/libode_a-Opcode.obj: unix/odesrc/OPCODE/Opcode.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-Opcode.obj -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-Opcode.Tpo -c -o unix/odesrc/OPCODE/libode_a-Opcode.obj `if test -f 'unix/odesrc/OPCODE/Opcode.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Opcode.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Opcode.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-Opcode.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-Opcode.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Opcode.cpp' object='unix/odesrc/OPCODE/libode_a-Opcode.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-Opcode.obj `if test -f 'unix/odesrc/OPCODE/Opcode.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Opcode.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Opcode.cpp'; fi` unix/odesrc/OPCODE/libode_a-OPC_OptimizedTree.o: unix/odesrc/OPCODE/OPC_OptimizedTree.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_OptimizedTree.o -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_OptimizedTree.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_OptimizedTree.o `test -f 'unix/odesrc/OPCODE/OPC_OptimizedTree.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_OptimizedTree.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_OptimizedTree.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_OptimizedTree.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_OptimizedTree.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_OptimizedTree.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_OptimizedTree.o `test -f 'unix/odesrc/OPCODE/OPC_OptimizedTree.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_OptimizedTree.cpp unix/odesrc/OPCODE/libode_a-OPC_OptimizedTree.obj: unix/odesrc/OPCODE/OPC_OptimizedTree.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_OptimizedTree.obj -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_OptimizedTree.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_OptimizedTree.obj `if test -f 'unix/odesrc/OPCODE/OPC_OptimizedTree.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_OptimizedTree.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_OptimizedTree.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_OptimizedTree.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_OptimizedTree.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_OptimizedTree.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_OptimizedTree.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_OptimizedTree.obj `if test -f 'unix/odesrc/OPCODE/OPC_OptimizedTree.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_OptimizedTree.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_OptimizedTree.cpp'; fi` unix/odesrc/OPCODE/libode_a-OPC_Picking.o: unix/odesrc/OPCODE/OPC_Picking.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_Picking.o -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Picking.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_Picking.o `test -f 'unix/odesrc/OPCODE/OPC_Picking.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_Picking.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Picking.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Picking.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_Picking.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_Picking.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_Picking.o `test -f 'unix/odesrc/OPCODE/OPC_Picking.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_Picking.cpp unix/odesrc/OPCODE/libode_a-OPC_Picking.obj: unix/odesrc/OPCODE/OPC_Picking.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_Picking.obj -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Picking.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_Picking.obj `if test -f 'unix/odesrc/OPCODE/OPC_Picking.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_Picking.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_Picking.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Picking.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_Picking.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_Picking.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_Picking.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_Picking.obj `if test -f 'unix/odesrc/OPCODE/OPC_Picking.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_Picking.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_Picking.cpp'; fi` unix/odesrc/OPCODE/libode_a-OPC_PlanesCollider.o: unix/odesrc/OPCODE/OPC_PlanesCollider.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_PlanesCollider.o -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_PlanesCollider.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_PlanesCollider.o `test -f 'unix/odesrc/OPCODE/OPC_PlanesCollider.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_PlanesCollider.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_PlanesCollider.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_PlanesCollider.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_PlanesCollider.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_PlanesCollider.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_PlanesCollider.o `test -f 'unix/odesrc/OPCODE/OPC_PlanesCollider.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_PlanesCollider.cpp unix/odesrc/OPCODE/libode_a-OPC_PlanesCollider.obj: unix/odesrc/OPCODE/OPC_PlanesCollider.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_PlanesCollider.obj -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_PlanesCollider.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_PlanesCollider.obj `if test -f 'unix/odesrc/OPCODE/OPC_PlanesCollider.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_PlanesCollider.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_PlanesCollider.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_PlanesCollider.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_PlanesCollider.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_PlanesCollider.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_PlanesCollider.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_PlanesCollider.obj `if test -f 'unix/odesrc/OPCODE/OPC_PlanesCollider.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_PlanesCollider.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_PlanesCollider.cpp'; fi` unix/odesrc/OPCODE/libode_a-OPC_RayCollider.o: unix/odesrc/OPCODE/OPC_RayCollider.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_RayCollider.o -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_RayCollider.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_RayCollider.o `test -f 'unix/odesrc/OPCODE/OPC_RayCollider.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_RayCollider.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_RayCollider.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_RayCollider.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_RayCollider.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_RayCollider.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_RayCollider.o `test -f 'unix/odesrc/OPCODE/OPC_RayCollider.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_RayCollider.cpp unix/odesrc/OPCODE/libode_a-OPC_RayCollider.obj: unix/odesrc/OPCODE/OPC_RayCollider.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_RayCollider.obj -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_RayCollider.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_RayCollider.obj `if test -f 'unix/odesrc/OPCODE/OPC_RayCollider.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_RayCollider.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_RayCollider.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_RayCollider.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_RayCollider.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_RayCollider.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_RayCollider.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_RayCollider.obj `if test -f 'unix/odesrc/OPCODE/OPC_RayCollider.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_RayCollider.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_RayCollider.cpp'; fi` unix/odesrc/OPCODE/libode_a-OPC_SphereCollider.o: unix/odesrc/OPCODE/OPC_SphereCollider.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_SphereCollider.o -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_SphereCollider.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_SphereCollider.o `test -f 'unix/odesrc/OPCODE/OPC_SphereCollider.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_SphereCollider.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_SphereCollider.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_SphereCollider.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_SphereCollider.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_SphereCollider.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_SphereCollider.o `test -f 'unix/odesrc/OPCODE/OPC_SphereCollider.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_SphereCollider.cpp unix/odesrc/OPCODE/libode_a-OPC_SphereCollider.obj: unix/odesrc/OPCODE/OPC_SphereCollider.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_SphereCollider.obj -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_SphereCollider.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_SphereCollider.obj `if test -f 'unix/odesrc/OPCODE/OPC_SphereCollider.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_SphereCollider.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_SphereCollider.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_SphereCollider.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_SphereCollider.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_SphereCollider.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_SphereCollider.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_SphereCollider.obj `if test -f 'unix/odesrc/OPCODE/OPC_SphereCollider.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_SphereCollider.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_SphereCollider.cpp'; fi` unix/odesrc/OPCODE/libode_a-OPC_TreeBuilders.o: unix/odesrc/OPCODE/OPC_TreeBuilders.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_TreeBuilders.o -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_TreeBuilders.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_TreeBuilders.o `test -f 'unix/odesrc/OPCODE/OPC_TreeBuilders.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_TreeBuilders.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_TreeBuilders.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_TreeBuilders.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_TreeBuilders.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_TreeBuilders.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_TreeBuilders.o `test -f 'unix/odesrc/OPCODE/OPC_TreeBuilders.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_TreeBuilders.cpp unix/odesrc/OPCODE/libode_a-OPC_TreeBuilders.obj: unix/odesrc/OPCODE/OPC_TreeBuilders.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_TreeBuilders.obj -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_TreeBuilders.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_TreeBuilders.obj `if test -f 'unix/odesrc/OPCODE/OPC_TreeBuilders.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_TreeBuilders.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_TreeBuilders.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_TreeBuilders.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_TreeBuilders.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_TreeBuilders.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_TreeBuilders.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_TreeBuilders.obj `if test -f 'unix/odesrc/OPCODE/OPC_TreeBuilders.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_TreeBuilders.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_TreeBuilders.cpp'; fi` unix/odesrc/OPCODE/libode_a-OPC_TreeCollider.o: unix/odesrc/OPCODE/OPC_TreeCollider.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_TreeCollider.o -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_TreeCollider.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_TreeCollider.o `test -f 'unix/odesrc/OPCODE/OPC_TreeCollider.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_TreeCollider.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_TreeCollider.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_TreeCollider.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_TreeCollider.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_TreeCollider.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_TreeCollider.o `test -f 'unix/odesrc/OPCODE/OPC_TreeCollider.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_TreeCollider.cpp unix/odesrc/OPCODE/libode_a-OPC_TreeCollider.obj: unix/odesrc/OPCODE/OPC_TreeCollider.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_TreeCollider.obj -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_TreeCollider.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_TreeCollider.obj `if test -f 'unix/odesrc/OPCODE/OPC_TreeCollider.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_TreeCollider.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_TreeCollider.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_TreeCollider.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_TreeCollider.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_TreeCollider.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_TreeCollider.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_TreeCollider.obj `if test -f 'unix/odesrc/OPCODE/OPC_TreeCollider.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_TreeCollider.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_TreeCollider.cpp'; fi` unix/odesrc/OPCODE/libode_a-OPC_VolumeCollider.o: unix/odesrc/OPCODE/OPC_VolumeCollider.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_VolumeCollider.o -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_VolumeCollider.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_VolumeCollider.o `test -f 'unix/odesrc/OPCODE/OPC_VolumeCollider.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_VolumeCollider.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_VolumeCollider.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_VolumeCollider.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_VolumeCollider.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_VolumeCollider.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_VolumeCollider.o `test -f 'unix/odesrc/OPCODE/OPC_VolumeCollider.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/OPC_VolumeCollider.cpp unix/odesrc/OPCODE/libode_a-OPC_VolumeCollider.obj: unix/odesrc/OPCODE/OPC_VolumeCollider.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/libode_a-OPC_VolumeCollider.obj -MD -MP -MF unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_VolumeCollider.Tpo -c -o unix/odesrc/OPCODE/libode_a-OPC_VolumeCollider.obj `if test -f 'unix/odesrc/OPCODE/OPC_VolumeCollider.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_VolumeCollider.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_VolumeCollider.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_VolumeCollider.Tpo unix/odesrc/OPCODE/$(DEPDIR)/libode_a-OPC_VolumeCollider.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/OPC_VolumeCollider.cpp' object='unix/odesrc/OPCODE/libode_a-OPC_VolumeCollider.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/libode_a-OPC_VolumeCollider.obj `if test -f 'unix/odesrc/OPCODE/OPC_VolumeCollider.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/OPC_VolumeCollider.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/OPC_VolumeCollider.cpp'; fi` unix/odesrc/OPCODE/Ice/libode_a-IceAABB.o: unix/odesrc/OPCODE/Ice/IceAABB.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceAABB.o -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceAABB.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceAABB.o `test -f 'unix/odesrc/OPCODE/Ice/IceAABB.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceAABB.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceAABB.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceAABB.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceAABB.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceAABB.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceAABB.o `test -f 'unix/odesrc/OPCODE/Ice/IceAABB.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceAABB.cpp unix/odesrc/OPCODE/Ice/libode_a-IceAABB.obj: unix/odesrc/OPCODE/Ice/IceAABB.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceAABB.obj -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceAABB.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceAABB.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceAABB.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceAABB.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceAABB.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceAABB.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceAABB.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceAABB.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceAABB.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceAABB.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceAABB.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceAABB.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceAABB.cpp'; fi` unix/odesrc/OPCODE/Ice/libode_a-IceContainer.o: unix/odesrc/OPCODE/Ice/IceContainer.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceContainer.o -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceContainer.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceContainer.o `test -f 'unix/odesrc/OPCODE/Ice/IceContainer.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceContainer.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceContainer.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceContainer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceContainer.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceContainer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceContainer.o `test -f 'unix/odesrc/OPCODE/Ice/IceContainer.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceContainer.cpp unix/odesrc/OPCODE/Ice/libode_a-IceContainer.obj: unix/odesrc/OPCODE/Ice/IceContainer.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceContainer.obj -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceContainer.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceContainer.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceContainer.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceContainer.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceContainer.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceContainer.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceContainer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceContainer.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceContainer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceContainer.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceContainer.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceContainer.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceContainer.cpp'; fi` unix/odesrc/OPCODE/Ice/libode_a-IceHPoint.o: unix/odesrc/OPCODE/Ice/IceHPoint.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceHPoint.o -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceHPoint.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceHPoint.o `test -f 'unix/odesrc/OPCODE/Ice/IceHPoint.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceHPoint.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceHPoint.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceHPoint.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceHPoint.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceHPoint.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceHPoint.o `test -f 'unix/odesrc/OPCODE/Ice/IceHPoint.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceHPoint.cpp unix/odesrc/OPCODE/Ice/libode_a-IceHPoint.obj: unix/odesrc/OPCODE/Ice/IceHPoint.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceHPoint.obj -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceHPoint.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceHPoint.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceHPoint.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceHPoint.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceHPoint.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceHPoint.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceHPoint.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceHPoint.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceHPoint.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceHPoint.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceHPoint.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceHPoint.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceHPoint.cpp'; fi` unix/odesrc/OPCODE/Ice/libode_a-IceIndexedTriangle.o: unix/odesrc/OPCODE/Ice/IceIndexedTriangle.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceIndexedTriangle.o -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceIndexedTriangle.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceIndexedTriangle.o `test -f 'unix/odesrc/OPCODE/Ice/IceIndexedTriangle.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceIndexedTriangle.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceIndexedTriangle.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceIndexedTriangle.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceIndexedTriangle.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceIndexedTriangle.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceIndexedTriangle.o `test -f 'unix/odesrc/OPCODE/Ice/IceIndexedTriangle.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceIndexedTriangle.cpp unix/odesrc/OPCODE/Ice/libode_a-IceIndexedTriangle.obj: unix/odesrc/OPCODE/Ice/IceIndexedTriangle.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceIndexedTriangle.obj -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceIndexedTriangle.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceIndexedTriangle.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceIndexedTriangle.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceIndexedTriangle.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceIndexedTriangle.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceIndexedTriangle.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceIndexedTriangle.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceIndexedTriangle.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceIndexedTriangle.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceIndexedTriangle.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceIndexedTriangle.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceIndexedTriangle.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceIndexedTriangle.cpp'; fi` unix/odesrc/OPCODE/Ice/libode_a-IceMatrix3x3.o: unix/odesrc/OPCODE/Ice/IceMatrix3x3.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceMatrix3x3.o -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceMatrix3x3.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceMatrix3x3.o `test -f 'unix/odesrc/OPCODE/Ice/IceMatrix3x3.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceMatrix3x3.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceMatrix3x3.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceMatrix3x3.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceMatrix3x3.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceMatrix3x3.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceMatrix3x3.o `test -f 'unix/odesrc/OPCODE/Ice/IceMatrix3x3.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceMatrix3x3.cpp unix/odesrc/OPCODE/Ice/libode_a-IceMatrix3x3.obj: unix/odesrc/OPCODE/Ice/IceMatrix3x3.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceMatrix3x3.obj -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceMatrix3x3.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceMatrix3x3.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceMatrix3x3.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceMatrix3x3.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceMatrix3x3.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceMatrix3x3.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceMatrix3x3.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceMatrix3x3.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceMatrix3x3.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceMatrix3x3.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceMatrix3x3.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceMatrix3x3.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceMatrix3x3.cpp'; fi` unix/odesrc/OPCODE/Ice/libode_a-IceMatrix4x4.o: unix/odesrc/OPCODE/Ice/IceMatrix4x4.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceMatrix4x4.o -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceMatrix4x4.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceMatrix4x4.o `test -f 'unix/odesrc/OPCODE/Ice/IceMatrix4x4.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceMatrix4x4.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceMatrix4x4.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceMatrix4x4.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceMatrix4x4.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceMatrix4x4.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceMatrix4x4.o `test -f 'unix/odesrc/OPCODE/Ice/IceMatrix4x4.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceMatrix4x4.cpp unix/odesrc/OPCODE/Ice/libode_a-IceMatrix4x4.obj: unix/odesrc/OPCODE/Ice/IceMatrix4x4.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceMatrix4x4.obj -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceMatrix4x4.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceMatrix4x4.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceMatrix4x4.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceMatrix4x4.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceMatrix4x4.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceMatrix4x4.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceMatrix4x4.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceMatrix4x4.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceMatrix4x4.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceMatrix4x4.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceMatrix4x4.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceMatrix4x4.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceMatrix4x4.cpp'; fi` unix/odesrc/OPCODE/Ice/libode_a-IceOBB.o: unix/odesrc/OPCODE/Ice/IceOBB.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceOBB.o -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceOBB.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceOBB.o `test -f 'unix/odesrc/OPCODE/Ice/IceOBB.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceOBB.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceOBB.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceOBB.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceOBB.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceOBB.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceOBB.o `test -f 'unix/odesrc/OPCODE/Ice/IceOBB.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceOBB.cpp unix/odesrc/OPCODE/Ice/libode_a-IceOBB.obj: unix/odesrc/OPCODE/Ice/IceOBB.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceOBB.obj -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceOBB.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceOBB.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceOBB.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceOBB.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceOBB.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceOBB.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceOBB.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceOBB.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceOBB.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceOBB.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceOBB.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceOBB.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceOBB.cpp'; fi` unix/odesrc/OPCODE/Ice/libode_a-IcePlane.o: unix/odesrc/OPCODE/Ice/IcePlane.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IcePlane.o -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IcePlane.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IcePlane.o `test -f 'unix/odesrc/OPCODE/Ice/IcePlane.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IcePlane.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IcePlane.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IcePlane.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IcePlane.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IcePlane.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IcePlane.o `test -f 'unix/odesrc/OPCODE/Ice/IcePlane.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IcePlane.cpp unix/odesrc/OPCODE/Ice/libode_a-IcePlane.obj: unix/odesrc/OPCODE/Ice/IcePlane.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IcePlane.obj -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IcePlane.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IcePlane.obj `if test -f 'unix/odesrc/OPCODE/Ice/IcePlane.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IcePlane.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IcePlane.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IcePlane.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IcePlane.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IcePlane.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IcePlane.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IcePlane.obj `if test -f 'unix/odesrc/OPCODE/Ice/IcePlane.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IcePlane.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IcePlane.cpp'; fi` unix/odesrc/OPCODE/Ice/libode_a-IcePoint.o: unix/odesrc/OPCODE/Ice/IcePoint.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IcePoint.o -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IcePoint.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IcePoint.o `test -f 'unix/odesrc/OPCODE/Ice/IcePoint.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IcePoint.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IcePoint.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IcePoint.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IcePoint.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IcePoint.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IcePoint.o `test -f 'unix/odesrc/OPCODE/Ice/IcePoint.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IcePoint.cpp unix/odesrc/OPCODE/Ice/libode_a-IcePoint.obj: unix/odesrc/OPCODE/Ice/IcePoint.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IcePoint.obj -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IcePoint.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IcePoint.obj `if test -f 'unix/odesrc/OPCODE/Ice/IcePoint.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IcePoint.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IcePoint.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IcePoint.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IcePoint.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IcePoint.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IcePoint.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IcePoint.obj `if test -f 'unix/odesrc/OPCODE/Ice/IcePoint.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IcePoint.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IcePoint.cpp'; fi` unix/odesrc/OPCODE/Ice/libode_a-IceRandom.o: unix/odesrc/OPCODE/Ice/IceRandom.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceRandom.o -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceRandom.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceRandom.o `test -f 'unix/odesrc/OPCODE/Ice/IceRandom.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceRandom.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceRandom.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceRandom.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceRandom.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceRandom.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceRandom.o `test -f 'unix/odesrc/OPCODE/Ice/IceRandom.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceRandom.cpp unix/odesrc/OPCODE/Ice/libode_a-IceRandom.obj: unix/odesrc/OPCODE/Ice/IceRandom.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceRandom.obj -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceRandom.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceRandom.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceRandom.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceRandom.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceRandom.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceRandom.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceRandom.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceRandom.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceRandom.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceRandom.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceRandom.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceRandom.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceRandom.cpp'; fi` unix/odesrc/OPCODE/Ice/libode_a-IceRay.o: unix/odesrc/OPCODE/Ice/IceRay.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceRay.o -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceRay.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceRay.o `test -f 'unix/odesrc/OPCODE/Ice/IceRay.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceRay.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceRay.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceRay.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceRay.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceRay.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceRay.o `test -f 'unix/odesrc/OPCODE/Ice/IceRay.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceRay.cpp unix/odesrc/OPCODE/Ice/libode_a-IceRay.obj: unix/odesrc/OPCODE/Ice/IceRay.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceRay.obj -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceRay.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceRay.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceRay.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceRay.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceRay.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceRay.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceRay.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceRay.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceRay.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceRay.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceRay.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceRay.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceRay.cpp'; fi` unix/odesrc/OPCODE/Ice/libode_a-IceRevisitedRadix.o: unix/odesrc/OPCODE/Ice/IceRevisitedRadix.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceRevisitedRadix.o -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceRevisitedRadix.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceRevisitedRadix.o `test -f 'unix/odesrc/OPCODE/Ice/IceRevisitedRadix.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceRevisitedRadix.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceRevisitedRadix.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceRevisitedRadix.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceRevisitedRadix.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceRevisitedRadix.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceRevisitedRadix.o `test -f 'unix/odesrc/OPCODE/Ice/IceRevisitedRadix.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceRevisitedRadix.cpp unix/odesrc/OPCODE/Ice/libode_a-IceRevisitedRadix.obj: unix/odesrc/OPCODE/Ice/IceRevisitedRadix.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceRevisitedRadix.obj -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceRevisitedRadix.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceRevisitedRadix.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceRevisitedRadix.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceRevisitedRadix.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceRevisitedRadix.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceRevisitedRadix.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceRevisitedRadix.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceRevisitedRadix.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceRevisitedRadix.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceRevisitedRadix.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceRevisitedRadix.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceRevisitedRadix.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceRevisitedRadix.cpp'; fi` unix/odesrc/OPCODE/Ice/libode_a-IceSegment.o: unix/odesrc/OPCODE/Ice/IceSegment.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceSegment.o -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceSegment.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceSegment.o `test -f 'unix/odesrc/OPCODE/Ice/IceSegment.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceSegment.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceSegment.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceSegment.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceSegment.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceSegment.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceSegment.o `test -f 'unix/odesrc/OPCODE/Ice/IceSegment.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceSegment.cpp unix/odesrc/OPCODE/Ice/libode_a-IceSegment.obj: unix/odesrc/OPCODE/Ice/IceSegment.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceSegment.obj -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceSegment.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceSegment.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceSegment.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceSegment.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceSegment.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceSegment.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceSegment.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceSegment.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceSegment.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceSegment.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceSegment.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceSegment.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceSegment.cpp'; fi` unix/odesrc/OPCODE/Ice/libode_a-IceTriangle.o: unix/odesrc/OPCODE/Ice/IceTriangle.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceTriangle.o -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceTriangle.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceTriangle.o `test -f 'unix/odesrc/OPCODE/Ice/IceTriangle.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceTriangle.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceTriangle.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceTriangle.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceTriangle.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceTriangle.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceTriangle.o `test -f 'unix/odesrc/OPCODE/Ice/IceTriangle.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceTriangle.cpp unix/odesrc/OPCODE/Ice/libode_a-IceTriangle.obj: unix/odesrc/OPCODE/Ice/IceTriangle.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceTriangle.obj -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceTriangle.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceTriangle.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceTriangle.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceTriangle.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceTriangle.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceTriangle.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceTriangle.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceTriangle.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceTriangle.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceTriangle.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceTriangle.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceTriangle.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceTriangle.cpp'; fi` unix/odesrc/OPCODE/Ice/libode_a-IceUtils.o: unix/odesrc/OPCODE/Ice/IceUtils.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceUtils.o -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceUtils.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceUtils.o `test -f 'unix/odesrc/OPCODE/Ice/IceUtils.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceUtils.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceUtils.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceUtils.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceUtils.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceUtils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceUtils.o `test -f 'unix/odesrc/OPCODE/Ice/IceUtils.cpp' || echo '$(srcdir)/'`unix/odesrc/OPCODE/Ice/IceUtils.cpp unix/odesrc/OPCODE/Ice/libode_a-IceUtils.obj: unix/odesrc/OPCODE/Ice/IceUtils.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unix/odesrc/OPCODE/Ice/libode_a-IceUtils.obj -MD -MP -MF unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceUtils.Tpo -c -o unix/odesrc/OPCODE/Ice/libode_a-IceUtils.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceUtils.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceUtils.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceUtils.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceUtils.Tpo unix/odesrc/OPCODE/Ice/$(DEPDIR)/libode_a-IceUtils.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unix/odesrc/OPCODE/Ice/IceUtils.cpp' object='unix/odesrc/OPCODE/Ice/libode_a-IceUtils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unix/odesrc/OPCODE/Ice/libode_a-IceUtils.obj `if test -f 'unix/odesrc/OPCODE/Ice/IceUtils.cpp'; then $(CYGPATH_W) 'unix/odesrc/OPCODE/Ice/IceUtils.cpp'; else $(CYGPATH_W) '$(srcdir)/unix/odesrc/OPCODE/Ice/IceUtils.cpp'; fi` ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f client/$(DEPDIR)/$(am__dirstamp) -rm -f client/$(am__dirstamp) -rm -f game/$(DEPDIR)/$(am__dirstamp) -rm -f game/$(am__dirstamp) -rm -f game/acesrc/$(DEPDIR)/$(am__dirstamp) -rm -f game/acesrc/$(am__dirstamp) -rm -f null/$(DEPDIR)/$(am__dirstamp) -rm -f null/$(am__dirstamp) -rm -f qcommon/$(DEPDIR)/$(am__dirstamp) -rm -f qcommon/$(am__dirstamp) -rm -f ref_gl/$(DEPDIR)/$(am__dirstamp) -rm -f ref_gl/$(am__dirstamp) -rm -f server/$(DEPDIR)/$(am__dirstamp) -rm -f server/$(am__dirstamp) -rm -f unix/$(DEPDIR)/$(am__dirstamp) -rm -f unix/$(am__dirstamp) -rm -f unix/odesrc/$(DEPDIR)/$(am__dirstamp) -rm -f unix/odesrc/$(am__dirstamp) -rm -f unix/odesrc/OPCODE/$(DEPDIR)/$(am__dirstamp) -rm -f unix/odesrc/OPCODE/$(am__dirstamp) -rm -f unix/odesrc/OPCODE/Ice/$(DEPDIR)/$(am__dirstamp) -rm -f unix/odesrc/OPCODE/Ice/$(am__dirstamp) -rm -f unix/odesrc/joints/$(DEPDIR)/$(am__dirstamp) -rm -f unix/odesrc/joints/$(am__dirstamp) -rm -f win32/$(DEPDIR)/$(am__dirstamp) -rm -f win32/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-noinstLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf client/$(DEPDIR) game/$(DEPDIR) game/acesrc/$(DEPDIR) null/$(DEPDIR) qcommon/$(DEPDIR) ref_gl/$(DEPDIR) server/$(DEPDIR) unix/$(DEPDIR) unix/odesrc/$(DEPDIR) unix/odesrc/OPCODE/$(DEPDIR) unix/odesrc/OPCODE/Ice/$(DEPDIR) unix/odesrc/joints/$(DEPDIR) win32/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf client/$(DEPDIR) game/$(DEPDIR) game/acesrc/$(DEPDIR) null/$(DEPDIR) qcommon/$(DEPDIR) ref_gl/$(DEPDIR) server/$(DEPDIR) unix/$(DEPDIR) unix/odesrc/$(DEPDIR) unix/odesrc/OPCODE/$(DEPDIR) unix/odesrc/OPCODE/Ice/$(DEPDIR) unix/odesrc/joints/$(DEPDIR) win32/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic clean-noinstLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-binPROGRAMS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: alien-arena-7.66+dfsg/source/unix/0000700000175000017500000000000012207204657016105 5ustar zero79zero79alien-arena-7.66+dfsg/source/unix/qal_unix.c0000600000175000017500000002404312161402010020054 0ustar zero79zero79/* Copyright (C) 2009 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * qal_unix.c */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #if defined HAVE_DLFCN_H #include #endif #if defined HAVE_AL_H #include #include #elif defined HAVE_AL_AL_H #include #include #elif defined HAVE_OPENAL_AL_H #include #include #else #error OpenAL header includes not defined. #endif #include "client/client.h" #include "client/qal.h" /* * OpenAL Library * OpenAL 1.1 required. */ #if defined OPENAL_DRIVER const char libopenal_name[] = OPENAL_DRIVER; #else const char libopenal_name[] = "libopenal.so.1"; #endif void *dynlib; qboolean dlsym_error; /* == get_dlsym() get symbol from shared library == */ static void get_dlsym( const char* symbol_name, void** symbol_addr ) { char *dlerror_message; dlerror_message = dlerror(); // clear any error *symbol_addr = dlsym( dynlib, symbol_name ); dlerror_message = dlerror(); if( dlerror_message != NULL ) { printf( "%s\n", dlerror_message ); dlsym_error = true; } } /* == QAL_Init() QAL_Shutdown() Dynamically link/unlink OpenAL shared library == */ qboolean QAL_Init( void ) { dynlib = dlopen( libopenal_name, RTLD_LAZY | RTLD_GLOBAL ); if( dynlib == NULL ) { Com_Printf("dlopen() on %s failed\n", libopenal_name ); return false; } dlsym_error = false; get_dlsym( "alEnable", (void**) &pqalEnable ); get_dlsym( "alDisable", (void**) &pqalDisable ); get_dlsym( "alIsEnabled", (void**) &pqalIsEnabled ); get_dlsym( "alGetBooleanv", (void**) &pqalGetBooleanv ); get_dlsym( "alGetIntegerv", (void**) &pqalGetIntegerv ); get_dlsym( "alGetString", (void**) &pqalGetString ); get_dlsym( "alGetFloatv", (void**) &pqalGetFloatv ); get_dlsym( "alGetDoublev", (void**) &pqalGetDoublev ); get_dlsym( "alGetBoolean", (void**) &pqalGetBoolean ); get_dlsym( "alGetInteger", (void**) &pqalGetInteger ); get_dlsym( "alGetFloat", (void**) &pqalGetFloat ); get_dlsym( "alGetDouble", (void**) &pqalGetDouble ); get_dlsym( "alGetError", (void**) &pqalGetError ); get_dlsym( "alIsExtensionPresent", (void**) &pqalIsExtensionPresent ); get_dlsym( "alGetProcAddress", (void**) &pqalGetProcAddress ); get_dlsym( "alGetEnumValue", (void**) &pqalGetEnumValue ); get_dlsym( "alListenerf", (void**) &pqalListenerf ); get_dlsym( "alListener3f", (void**) &pqalListener3f ); get_dlsym( "alListenerfv", (void**) &pqalListenerfv ); get_dlsym( "alListeneri", (void**) &pqalListeneri ); get_dlsym( "alListener3i", (void**) &pqalListener3i ); get_dlsym( "alListeneriv", (void**) &pqalListeneriv ); get_dlsym( "alGetListenerf", (void**) &pqalGetListenerf ); get_dlsym( "alGetListener3f", (void**) &pqalGetListener3f ); get_dlsym( "alGetListenerfv", (void**) &pqalGetListenerfv ); get_dlsym( "alGetListeneri", (void**) &pqalGetListeneri ); get_dlsym( "alGetListener3i", (void**) &pqalGetListener3i ); get_dlsym( "alGetListeneriv", (void**) &pqalGetListeneriv ); get_dlsym( "alGenSources", (void**) &pqalGenSources ); get_dlsym( "alDeleteSources", (void**) &pqalDeleteSources ); get_dlsym( "alIsSource", (void**) &pqalIsSource ); get_dlsym( "alSourcef", (void**) &pqalSourcef ); get_dlsym( "alSource3f", (void**) &pqalSource3f ); get_dlsym( "alSourcefv", (void**) &pqalSourcefv ); get_dlsym( "alSourcei", (void**) &pqalSourcei ); get_dlsym( "alSource3i", (void**) &pqalSource3i ); get_dlsym( "alSourceiv", (void**) &pqalSourceiv ); get_dlsym( "alGetSourcef", (void**) &pqalGetSourcef ); get_dlsym( "alGetSource3f", (void**) &pqalGetSource3f ); get_dlsym( "alGetSourcefv", (void**) &pqalGetSourcefv ); get_dlsym( "alGetSourcei", (void**) &pqalGetSourcei ); get_dlsym( "alGetSource3i", (void**) &pqalGetSource3i ); get_dlsym( "alGetSourceiv", (void**) &pqalGetSourceiv ); get_dlsym( "alSourcePlayv", (void**) &pqalSourcePlayv ); get_dlsym( "alSourceStopv", (void**) &pqalSourceStopv ); get_dlsym( "alSourceRewindv", (void**) &pqalSourceRewindv ); get_dlsym( "alSourcePausev", (void**) &pqalSourcePausev ); get_dlsym( "alSourcePlay", (void**) &pqalSourcePlay ); get_dlsym( "alSourceStop", (void**) &pqalSourceStop ); get_dlsym( "alSourceRewind", (void**) &pqalSourceRewind ); get_dlsym( "alSourcePause", (void**) &pqalSourcePause ); get_dlsym( "alSourceQueueBuffers", (void**) &pqalSourceQueueBuffers ); get_dlsym( "alSourceUnqueueBuffers", (void**) &pqalSourceUnqueueBuffers ); get_dlsym( "alGenBuffers", (void**) &pqalGenBuffers ); get_dlsym( "alDeleteBuffers", (void**) &pqalDeleteBuffers ); get_dlsym( "alIsBuffer", (void**) &pqalIsBuffer ); get_dlsym( "alBufferData", (void**) &pqalBufferData ); get_dlsym( "alBufferf", (void**) &pqalBufferf ); get_dlsym( "alBuffer3f", (void**) &pqalBuffer3f ); get_dlsym( "alBufferfv", (void**) &pqalBufferfv ); get_dlsym( "alBufferi", (void**) &pqalBufferi ); get_dlsym( "alBuffer3i", (void**) &pqalBuffer3i ); get_dlsym( "alBufferiv", (void**) &pqalBufferiv ); get_dlsym( "alGetBufferf", (void**) &pqalGetBufferf ); get_dlsym( "alGetBuffer3f", (void**) &pqalGetBuffer3f ); get_dlsym( "alGetBufferfv", (void**) &pqalGetBufferfv ); get_dlsym( "alGetBufferi", (void**) &pqalGetBufferi ); get_dlsym( "alGetBuffer3i", (void**) &pqalGetBuffer3i ); get_dlsym( "alGetBufferiv", (void**) &pqalGetBufferiv ); get_dlsym( "alDopplerFactor", (void**) &pqalDopplerFactor ); get_dlsym( "alDopplerVelocity", (void**) &pqalDopplerVelocity ); get_dlsym( "alSpeedOfSound", (void**) &pqalSpeedOfSound ); get_dlsym( "alDistanceModel", (void**) &pqalDistanceModel ); get_dlsym( "alcCreateContext", (void**) &pqalcCreateContext ); get_dlsym( "alcMakeContextCurrent", (void**) &pqalcMakeContextCurrent ); get_dlsym( "alcProcessContext", (void**) &pqalcProcessContext ); get_dlsym( "alcSuspendContext", (void**) &pqalcSuspendContext ); get_dlsym( "alcDestroyContext", (void**) &pqalcDestroyContext ); get_dlsym( "alcGetCurrentContext", (void**) &pqalcGetCurrentContext ); get_dlsym( "alcGetContextsDevice", (void**) &pqalcGetContextsDevice ); get_dlsym( "alcOpenDevice", (void**) &pqalcOpenDevice ); get_dlsym( "alcCloseDevice", (void**) &pqalcCloseDevice ); get_dlsym( "alcGetError", (void**) &pqalcGetError ); get_dlsym( "alcIsExtensionPresent", (void**) &pqalcIsExtensionPresent ); get_dlsym( "alcGetProcAddress", (void**) &pqalcGetProcAddress ); get_dlsym( "alcGetEnumValue", (void**) &pqalcGetEnumValue ); get_dlsym( "alcGetString", (void**) &pqalcGetString ); get_dlsym( "alcGetIntegerv", (void**) &pqalcGetIntegerv ); get_dlsym( "alcCaptureOpenDevice", (void**) &pqalcCaptureOpenDevice ); get_dlsym( "alcCaptureCloseDevice", (void**) &pqalcCaptureCloseDevice ); get_dlsym( "alcCaptureStart", (void**) &pqalcCaptureStart ); get_dlsym( "alcCaptureStop", (void**) &pqalcCaptureStop ); get_dlsym( "alcCaptureSamples", (void**) &pqalcCaptureSamples ); return !dlsym_error; } void QAL_Shutdown( void ) { int result; if( dynlib ) { result = dlclose( dynlib ); if( result ) { Com_Printf( "dlclose() error\n" ); } dynlib = NULL; } pqalEnable = NULL; pqalDisable = NULL; pqalIsEnabled = NULL; pqalGetBooleanv = NULL; pqalGetIntegerv = NULL; pqalGetString = NULL; pqalGetFloatv = NULL; pqalGetDoublev = NULL; pqalGetBoolean = NULL; pqalGetInteger = NULL; pqalGetFloat = NULL; pqalGetDouble = NULL; pqalGetError = NULL; pqalIsExtensionPresent = NULL; pqalGetProcAddress = NULL; pqalGetEnumValue = NULL; pqalListenerf = NULL; pqalListener3f = NULL; pqalListenerfv = NULL; pqalListeneri = NULL; pqalListener3i = NULL; pqalListeneriv = NULL; pqalGetListenerf = NULL; pqalGetListener3f = NULL; pqalGetListenerfv = NULL; pqalGetListeneri = NULL; pqalGetListener3i = NULL; pqalGetListeneriv = NULL; pqalGenSources = NULL; pqalDeleteSources = NULL; pqalIsSource = NULL; pqalSourcef = NULL; pqalSource3f = NULL; pqalSourcefv = NULL; pqalSourcei = NULL; pqalSource3i = NULL; pqalSourceiv = NULL; pqalGetSourcef = NULL; pqalGetSource3f = NULL; pqalGetSourcefv = NULL; pqalGetSourcei = NULL; pqalGetSource3i = NULL; pqalGetSourceiv = NULL; pqalSourcePlayv = NULL; pqalSourceStopv = NULL; pqalSourceRewindv = NULL; pqalSourcePausev = NULL; pqalSourcePlay = NULL; pqalSourceStop = NULL; pqalSourceRewind = NULL; pqalSourcePause = NULL; pqalSourceQueueBuffers = NULL; pqalSourceUnqueueBuffers = NULL; pqalGenBuffers = NULL; pqalDeleteBuffers = NULL; pqalIsBuffer = NULL; pqalBufferData = NULL; pqalBufferf = NULL; pqalBuffer3f = NULL; pqalBufferfv = NULL; pqalBufferi = NULL; pqalBuffer3i = NULL; pqalBufferiv = NULL; pqalGetBufferf = NULL; pqalGetBuffer3f = NULL; pqalGetBufferfv = NULL; pqalGetBufferi = NULL; pqalGetBuffer3i = NULL; pqalGetBufferiv = NULL; pqalDopplerFactor = NULL; pqalDopplerVelocity = NULL; pqalSpeedOfSound = NULL; pqalDistanceModel = NULL; pqalcCreateContext = NULL; pqalcMakeContextCurrent = NULL; pqalcProcessContext = NULL; pqalcSuspendContext = NULL; pqalcDestroyContext = NULL; pqalcGetCurrentContext = NULL; pqalcGetContextsDevice = NULL; pqalcOpenDevice = NULL; pqalcCloseDevice = NULL; pqalcGetError = NULL; pqalcIsExtensionPresent = NULL; pqalcGetProcAddress = NULL; pqalcGetEnumValue = NULL; pqalcGetString = NULL; pqalcGetIntegerv = NULL; pqalcCaptureOpenDevice = NULL; pqalcCaptureCloseDevice = NULL; pqalcCaptureStart = NULL; pqalcCaptureStop = NULL; pqalcCaptureSamples = NULL; } /* == QAL_Loaded() check for OpenAL shared library == */ qboolean QAL_Loaded( void ) { return ( dynlib != NULL && !dlsym_error); } alien-arena-7.66+dfsg/source/unix/glob.h0000600000175000017500000000143112161402010017160 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ int glob_match(char *pattern, char *text); alien-arena-7.66+dfsg/source/unix/rw_unix.c0000600000175000017500000000345212161402010017730 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "client/client.h" cvar_t *m_filter; cvar_t *in_mouse; cvar_t *in_dgamouse; cvar_t *in_joystick; cvar_t *m_accel; void IN_Init(void) { // mouse variables m_filter = Cvar_Get ("m_filter", "0", 0); in_mouse = Cvar_Get ("in_mouse", "1", CVAR_ARCHIVE); in_dgamouse = Cvar_Get ("in_dgamouse", "1", CVAR_ARCHIVE); in_joystick = Cvar_Get ("in_joystick", "0", CVAR_ARCHIVE); Cmd_AddCommand ("+mlook", IN_MLookDown); Cmd_AddCommand ("-mlook", IN_MLookUp); mouse_available = true; refreshCursorLink(); } void IN_Shutdown(void) { if (!mouse_available) return; IN_Activate(false); mouse_available = false; Cmd_RemoveCommand ("+mlook"); Cmd_RemoveCommand ("-mlook"); } /* =========== IN_Commands =========== */ void IN_Commands (void) { } void IN_Frame (void) { if (!mouse_available) return; if ( !cl.refresh_prepped || cls.key_dest == key_console || cls.key_dest == key_menu || cl.attractloop ) IN_Activate(false); else IN_Activate(true); } void IN_JoyMove (usercmd_t *cmd) { // No joystick support for Linux } alien-arena-7.66+dfsg/source/unix/ode/0000700000175000017500000000000012207204656016653 5ustar zero79zero79alien-arena-7.66+dfsg/source/unix/ode/ode.h0000600000175000017500000000414712161402010017562 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_ODE_H_ #define _ODE_ODE_H_ /* include *everything* here */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif alien-arena-7.66+dfsg/source/unix/ode/odecpp.h0000600000175000017500000010701312161402010020261 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* C++ interface for non-collision stuff */ #ifndef _ODE_ODECPP_H_ #define _ODE_ODECPP_H_ #ifdef __cplusplus //namespace ode { class dWorld { dWorldID _id; // intentionally undefined, don't use these dWorld (const dWorld &); void operator= (const dWorld &); public: dWorld() { _id = dWorldCreate(); } ~dWorld() { dWorldDestroy (_id); } dWorldID id() const { return _id; } operator dWorldID() const { return _id; } void setGravity (dReal x, dReal y, dReal z) { dWorldSetGravity (_id,x,y,z); } void setGravity (const dVector3 g) { setGravity (g[0], g[1], g[2]); } void getGravity (dVector3 g) const { dWorldGetGravity (_id,g); } void setERP (dReal erp) { dWorldSetERP(_id, erp); } dReal getERP() const { return dWorldGetERP(_id); } void setCFM (dReal cfm) { dWorldSetCFM(_id, cfm); } dReal getCFM() const { return dWorldGetCFM(_id); } void step (dReal stepsize) { dWorldStep (_id,stepsize); } void stepFast1 (dReal stepsize, int maxiterations) { dWorldStepFast1 (_id,stepsize,maxiterations); } void setAutoEnableDepthSF1(int depth) { dWorldSetAutoEnableDepthSF1 (_id, depth); } int getAutoEnableDepthSF1() const { return dWorldGetAutoEnableDepthSF1 (_id); } void quickStep(dReal stepsize) { dWorldQuickStep (_id, stepsize); } void setQuickStepNumIterations(int num) { dWorldSetQuickStepNumIterations (_id, num); } int getQuickStepNumIterations() const { return dWorldGetQuickStepNumIterations (_id); } void setQuickStepW(dReal over_relaxation) { dWorldSetQuickStepW (_id, over_relaxation); } dReal getQuickStepW() const { return dWorldGetQuickStepW (_id); } void setAutoDisableLinearThreshold (dReal threshold) { dWorldSetAutoDisableLinearThreshold (_id,threshold); } dReal getAutoDisableLinearThreshold() const { return dWorldGetAutoDisableLinearThreshold (_id); } void setAutoDisableAngularThreshold (dReal threshold) { dWorldSetAutoDisableAngularThreshold (_id,threshold); } dReal getAutoDisableAngularThreshold() const { return dWorldGetAutoDisableAngularThreshold (_id); } void setAutoDisableSteps (int steps) { dWorldSetAutoDisableSteps (_id,steps); } int getAutoDisableSteps() const { return dWorldGetAutoDisableSteps (_id); } void setAutoDisableTime (dReal time) { dWorldSetAutoDisableTime (_id,time); } dReal getAutoDisableTime() const { return dWorldGetAutoDisableTime (_id); } void setAutoDisableFlag (int do_auto_disable) { dWorldSetAutoDisableFlag (_id,do_auto_disable); } int getAutoDisableFlag() const { return dWorldGetAutoDisableFlag (_id); } dReal getLinearDampingThreshold() const { return dWorldGetLinearDampingThreshold(_id); } void setLinearDampingThreshold(dReal threshold) { dWorldSetLinearDampingThreshold(_id, threshold); } dReal getAngularDampingThreshold() const { return dWorldGetAngularDampingThreshold(_id); } void setAngularDampingThreshold(dReal threshold) { dWorldSetAngularDampingThreshold(_id, threshold); } dReal getLinearDamping() const { return dWorldGetLinearDamping(_id); } void setLinearDamping(dReal scale) { dWorldSetLinearDamping(_id, scale); } dReal getAngularDamping() const { return dWorldGetAngularDamping(_id); } void setAngularDamping(dReal scale) { dWorldSetAngularDamping(_id, scale); } void setDamping(dReal linear_scale, dReal angular_scale) { dWorldSetDamping(_id, linear_scale, angular_scale); } dReal getMaxAngularSpeed() const { return dWorldGetMaxAngularSpeed(_id); } void setMaxAngularSpeed(dReal max_speed) { dWorldSetMaxAngularSpeed(_id, max_speed); } void setContactSurfaceLayer(dReal depth) { dWorldSetContactSurfaceLayer (_id, depth); } dReal getContactSurfaceLayer() const { return dWorldGetContactSurfaceLayer (_id); } void impulseToForce (dReal stepsize, dReal ix, dReal iy, dReal iz, dVector3 force) { dWorldImpulseToForce (_id,stepsize,ix,iy,iz,force); } }; class dBody { dBodyID _id; // intentionally undefined, don't use these dBody (const dBody &); void operator= (const dBody &); public: dBody() { _id = 0; } dBody (dWorldID world) { _id = dBodyCreate (world); } dBody (dWorld& world) { _id = dBodyCreate (world.id()); } ~dBody() { if (_id) dBodyDestroy (_id); } void create (dWorldID world) { if (_id) dBodyDestroy (_id); _id = dBodyCreate (world); } void create (dWorld& world) { create(world.id()); } dBodyID id() const { return _id; } operator dBodyID() const { return _id; } void setData (void *data) { dBodySetData (_id,data); } void *getData() const { return dBodyGetData (_id); } void setPosition (dReal x, dReal y, dReal z) { dBodySetPosition (_id,x,y,z); } void setPosition (const dVector3 p) { setPosition(p[0], p[1], p[2]); } void setRotation (const dMatrix3 R) { dBodySetRotation (_id,R); } void setQuaternion (const dQuaternion q) { dBodySetQuaternion (_id,q); } void setLinearVel (dReal x, dReal y, dReal z) { dBodySetLinearVel (_id,x,y,z); } void setLinearVel (const dVector3 v) { setLinearVel(v[0], v[1], v[2]); } void setAngularVel (dReal x, dReal y, dReal z) { dBodySetAngularVel (_id,x,y,z); } void setAngularVel (const dVector3 v) { setAngularVel (v[0], v[1], v[2]); } const dReal * getPosition() const { return dBodyGetPosition (_id); } const dReal * getRotation() const { return dBodyGetRotation (_id); } const dReal * getQuaternion() const { return dBodyGetQuaternion (_id); } const dReal * getLinearVel() const { return dBodyGetLinearVel (_id); } const dReal * getAngularVel() const { return dBodyGetAngularVel (_id); } void setMass (const dMass *mass) { dBodySetMass (_id,mass); } void setMass (const dMass &mass) { setMass (&mass); } dMass getMass () const { dMass mass; dBodyGetMass (_id,&mass); return mass; } void addForce (dReal fx, dReal fy, dReal fz) { dBodyAddForce (_id, fx, fy, fz); } void addForce (const dVector3 f) { addForce (f[0], f[1], f[2]); } void addTorque (dReal fx, dReal fy, dReal fz) { dBodyAddTorque (_id, fx, fy, fz); } void addTorque (const dVector3 t) { addTorque(t[0], t[1], t[2]); } void addRelForce (dReal fx, dReal fy, dReal fz) { dBodyAddRelForce (_id, fx, fy, fz); } void addRelForce (const dVector3 f) { addRelForce (f[0], f[1], f[2]); } void addRelTorque (dReal fx, dReal fy, dReal fz) { dBodyAddRelTorque (_id, fx, fy, fz); } void addRelTorque (const dVector3 t) { addRelTorque (t[0], t[1], t[2]); } void addForceAtPos (dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz) { dBodyAddForceAtPos (_id, fx, fy, fz, px, py, pz); } void addForceAtPos (const dVector3 f, const dVector3 p) { addForceAtPos (f[0], f[1], f[2], p[0], p[1], p[2]); } void addForceAtRelPos (dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz) { dBodyAddForceAtRelPos (_id, fx, fy, fz, px, py, pz); } void addForceAtRelPos (const dVector3 f, const dVector3 p) { addForceAtRelPos (f[0], f[1], f[2], p[0], p[1], p[2]); } void addRelForceAtPos (dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz) { dBodyAddRelForceAtPos (_id, fx, fy, fz, px, py, pz); } void addRelForceAtPos (const dVector3 f, const dVector3 p) { addRelForceAtPos (f[0], f[1], f[2], p[0], p[1], p[2]); } void addRelForceAtRelPos (dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz) { dBodyAddRelForceAtRelPos (_id, fx, fy, fz, px, py, pz); } void addRelForceAtRelPos (const dVector3 f, const dVector3 p) { addRelForceAtRelPos (f[0], f[1], f[2], p[0], p[1], p[2]); } const dReal * getForce() const { return dBodyGetForce(_id); } const dReal * getTorque() const { return dBodyGetTorque(_id); } void setForce (dReal x, dReal y, dReal z) { dBodySetForce (_id,x,y,z); } void setForce (const dVector3 f) { setForce (f[0], f[1], f[2]); } void setTorque (dReal x, dReal y, dReal z) { dBodySetTorque (_id,x,y,z); } void setTorque (const dVector3 t) { setTorque (t[0], t[1], t[2]); } void setDynamic() { dBodySetDynamic (_id); } void setKinematic() { dBodySetKinematic (_id); } bool isKinematic() const { return dBodyIsKinematic (_id) != 0; } void enable() { dBodyEnable (_id); } void disable() { dBodyDisable (_id); } bool isEnabled() const { return dBodyIsEnabled (_id) != 0; } void getRelPointPos (dReal px, dReal py, dReal pz, dVector3 result) const { dBodyGetRelPointPos (_id, px, py, pz, result); } void getRelPointPos (const dVector3 p, dVector3 result) const { getRelPointPos (p[0], p[1], p[2], result); } void getRelPointVel (dReal px, dReal py, dReal pz, dVector3 result) const { dBodyGetRelPointVel (_id, px, py, pz, result); } void getRelPointVel (const dVector3 p, dVector3 result) const { getRelPointVel (p[0], p[1], p[2], result); } void getPointVel (dReal px, dReal py, dReal pz, dVector3 result) const { dBodyGetPointVel (_id, px, py, pz, result); } void getPointVel (const dVector3 p, dVector3 result) const { getPointVel (p[0], p[1], p[2], result); } void getPosRelPoint (dReal px, dReal py, dReal pz, dVector3 result) const { dBodyGetPosRelPoint (_id, px, py, pz, result); } void getPosRelPoint (const dVector3 p, dVector3 result) const { getPosRelPoint (p[0], p[1], p[2], result); } void vectorToWorld (dReal px, dReal py, dReal pz, dVector3 result) const { dBodyVectorToWorld (_id, px, py, pz, result); } void vectorToWorld (const dVector3 p, dVector3 result) const { vectorToWorld (p[0], p[1], p[2], result); } void vectorFromWorld (dReal px, dReal py, dReal pz, dVector3 result) const { dBodyVectorFromWorld (_id,px,py,pz,result); } void vectorFromWorld (const dVector3 p, dVector3 result) const { vectorFromWorld (p[0], p[1], p[2], result); } void setFiniteRotationMode (bool mode) { dBodySetFiniteRotationMode (_id, mode); } void setFiniteRotationAxis (dReal x, dReal y, dReal z) { dBodySetFiniteRotationAxis (_id, x, y, z); } void setFiniteRotationAxis (const dVector3 a) { setFiniteRotationAxis (a[0], a[1], a[2]); } bool getFiniteRotationMode() const { return dBodyGetFiniteRotationMode (_id) != 0; } void getFiniteRotationAxis (dVector3 result) const { dBodyGetFiniteRotationAxis (_id, result); } int getNumJoints() const { return dBodyGetNumJoints (_id); } dJointID getJoint (int index) const { return dBodyGetJoint (_id, index); } void setGravityMode (bool mode) { dBodySetGravityMode (_id,mode); } bool getGravityMode() const { return dBodyGetGravityMode (_id) != 0; } bool isConnectedTo (dBodyID body) const { return dAreConnected (_id, body) != 0; } void setAutoDisableLinearThreshold (dReal threshold) { dBodySetAutoDisableLinearThreshold (_id,threshold); } dReal getAutoDisableLinearThreshold() const { return dBodyGetAutoDisableLinearThreshold (_id); } void setAutoDisableAngularThreshold (dReal threshold) { dBodySetAutoDisableAngularThreshold (_id,threshold); } dReal getAutoDisableAngularThreshold() const { return dBodyGetAutoDisableAngularThreshold (_id); } void setAutoDisableSteps (int steps) { dBodySetAutoDisableSteps (_id,steps); } int getAutoDisableSteps() const { return dBodyGetAutoDisableSteps (_id); } void setAutoDisableTime (dReal time) { dBodySetAutoDisableTime (_id,time); } dReal getAutoDisableTime() const { return dBodyGetAutoDisableTime (_id); } void setAutoDisableFlag (bool do_auto_disable) { dBodySetAutoDisableFlag (_id,do_auto_disable); } bool getAutoDisableFlag() const { return dBodyGetAutoDisableFlag (_id) != 0; } dReal getLinearDamping() const { return dBodyGetLinearDamping(_id); } void setLinearDamping(dReal scale) { dBodySetLinearDamping(_id, scale); } dReal getAngularDamping() const { return dBodyGetAngularDamping(_id); } void setAngularDamping(dReal scale) { dBodySetAngularDamping(_id, scale); } void setDamping(dReal linear_scale, dReal angular_scale) { dBodySetDamping(_id, linear_scale, angular_scale); } dReal getLinearDampingThreshold() const { return dBodyGetLinearDampingThreshold(_id); } void setLinearDampingThreshold(dReal threshold) const { dBodySetLinearDampingThreshold(_id, threshold); } dReal getAngularDampingThreshold() const { return dBodyGetAngularDampingThreshold(_id); } void setAngularDampingThreshold(dReal threshold) { dBodySetAngularDampingThreshold(_id, threshold); } void setDampingDefaults() { dBodySetDampingDefaults(_id); } dReal getMaxAngularSpeed() const { return dBodyGetMaxAngularSpeed(_id); } void setMaxAngularSpeed(dReal max_speed) { dBodySetMaxAngularSpeed(_id, max_speed); } bool getGyroscopicMode() const { return dBodyGetGyroscopicMode(_id) != 0; } void setGyroscopicMode(bool mode) { dBodySetGyroscopicMode(_id, mode); } }; class dJointGroup { dJointGroupID _id; // intentionally undefined, don't use these dJointGroup (const dJointGroup &); void operator= (const dJointGroup &); public: dJointGroup () { _id = dJointGroupCreate (0); } ~dJointGroup() { dJointGroupDestroy (_id); } void create () { if (_id) dJointGroupDestroy (_id); _id = dJointGroupCreate (0); } dJointGroupID id() const { return _id; } operator dJointGroupID() const { return _id; } void empty() { dJointGroupEmpty (_id); } void clear() { empty(); } }; class dJoint { private: // intentionally undefined, don't use these dJoint (const dJoint &) ; void operator= (const dJoint &); protected: dJointID _id; dJoint() // don't let user construct pure dJoint objects { _id = 0; } public: virtual ~dJoint() // :( Destructor must be virtual to suppress compiler warning "class XXX has virtual functions but non-virtual destructor" { if (_id) dJointDestroy (_id); } dJointID id() const { return _id; } operator dJointID() const { return _id; } int getNumBodies() const { return dJointGetNumBodies(_id); } void attach (dBodyID body1, dBodyID body2) { dJointAttach (_id, body1, body2); } void attach (dBody& body1, dBody& body2) { attach(body1.id(), body2.id()); } void enable() { dJointEnable (_id); } void disable() { dJointDisable (_id); } bool isEnabled() const { return dJointIsEnabled (_id) != 0; } void setData (void *data) { dJointSetData (_id, data); } void *getData() const { return dJointGetData (_id); } dJointType getType() const { return dJointGetType (_id); } dBodyID getBody (int index) const { return dJointGetBody (_id, index); } void setFeedback(dJointFeedback *fb) { dJointSetFeedback(_id, fb); } dJointFeedback *getFeedback() const { return dJointGetFeedback(_id); } // If not implemented it will do nothing as describe in the doc virtual void setParam (int, dReal) {}; virtual dReal getParam (int) const { return 0; } }; class dBallJoint : public dJoint { private: // intentionally undefined, don't use these dBallJoint (const dBallJoint &); void operator= (const dBallJoint &); public: dBallJoint() { } dBallJoint (dWorldID world, dJointGroupID group=0) { _id = dJointCreateBall (world, group); } dBallJoint (dWorld& world, dJointGroupID group=0) { _id = dJointCreateBall (world.id(), group); } void create (dWorldID world, dJointGroupID group=0) { if (_id) dJointDestroy (_id); _id = dJointCreateBall (world, group); } void create (dWorld& world, dJointGroupID group=0) { create(world.id(), group); } void setAnchor (dReal x, dReal y, dReal z) { dJointSetBallAnchor (_id, x, y, z); } void setAnchor (const dVector3 a) { setAnchor (a[0], a[1], a[2]); } void getAnchor (dVector3 result) const { dJointGetBallAnchor (_id, result); } void getAnchor2 (dVector3 result) const { dJointGetBallAnchor2 (_id, result); } virtual void setParam (int parameter, dReal value) { dJointSetBallParam (_id, parameter, value); } virtual dReal getParam (int parameter) const { return dJointGetBallParam (_id, parameter); } // TODO: expose params through methods } ; class dHingeJoint : public dJoint { // intentionally undefined, don't use these dHingeJoint (const dHingeJoint &); void operator = (const dHingeJoint &); public: dHingeJoint() { } dHingeJoint (dWorldID world, dJointGroupID group=0) { _id = dJointCreateHinge (world, group); } dHingeJoint (dWorld& world, dJointGroupID group=0) { _id = dJointCreateHinge (world.id(), group); } void create (dWorldID world, dJointGroupID group=0) { if (_id) dJointDestroy (_id); _id = dJointCreateHinge (world, group); } void create (dWorld& world, dJointGroupID group=0) { create(world.id(), group); } void setAnchor (dReal x, dReal y, dReal z) { dJointSetHingeAnchor (_id, x, y, z); } void setAnchor (const dVector3 a) { setAnchor (a[0], a[1], a[2]); } void getAnchor (dVector3 result) const { dJointGetHingeAnchor (_id, result); } void getAnchor2 (dVector3 result) const { dJointGetHingeAnchor2 (_id, result); } void setAxis (dReal x, dReal y, dReal z) { dJointSetHingeAxis (_id, x, y, z); } void setAxis (const dVector3 a) { setAxis(a[0], a[1], a[2]); } void getAxis (dVector3 result) const { dJointGetHingeAxis (_id, result); } dReal getAngle() const { return dJointGetHingeAngle (_id); } dReal getAngleRate() const { return dJointGetHingeAngleRate (_id); } virtual void setParam (int parameter, dReal value) { dJointSetHingeParam (_id, parameter, value); } virtual dReal getParam (int parameter) const { return dJointGetHingeParam (_id, parameter); } // TODO: expose params through methods void addTorque (dReal torque) { dJointAddHingeTorque(_id, torque); } }; class dSliderJoint : public dJoint { // intentionally undefined, don't use these dSliderJoint (const dSliderJoint &); void operator = (const dSliderJoint &); public: dSliderJoint() { } dSliderJoint (dWorldID world, dJointGroupID group=0) { _id = dJointCreateSlider (world, group); } dSliderJoint (dWorld& world, dJointGroupID group=0) { _id = dJointCreateSlider (world.id(), group); } void create (dWorldID world, dJointGroupID group=0) { if (_id) dJointDestroy (_id); _id = dJointCreateSlider (world, group); } void create (dWorld& world, dJointGroupID group=0) { create(world.id(), group); } void setAxis (dReal x, dReal y, dReal z) { dJointSetSliderAxis (_id, x, y, z); } void setAxis (const dVector3 a) { setAxis (a[0], a[1], a[2]); } void getAxis (dVector3 result) const { dJointGetSliderAxis (_id, result); } dReal getPosition() const { return dJointGetSliderPosition (_id); } dReal getPositionRate() const { return dJointGetSliderPositionRate (_id); } virtual void setParam (int parameter, dReal value) { dJointSetSliderParam (_id, parameter, value); } virtual dReal getParam (int parameter) const { return dJointGetSliderParam (_id, parameter); } // TODO: expose params through methods void addForce (dReal force) { dJointAddSliderForce(_id, force); } }; class dUniversalJoint : public dJoint { // intentionally undefined, don't use these dUniversalJoint (const dUniversalJoint &); void operator = (const dUniversalJoint &); public: dUniversalJoint() { } dUniversalJoint (dWorldID world, dJointGroupID group=0) { _id = dJointCreateUniversal (world, group); } dUniversalJoint (dWorld& world, dJointGroupID group=0) { _id = dJointCreateUniversal (world.id(), group); } void create (dWorldID world, dJointGroupID group=0) { if (_id) dJointDestroy (_id); _id = dJointCreateUniversal (world, group); } void create (dWorld& world, dJointGroupID group=0) { create(world.id(), group); } void setAnchor (dReal x, dReal y, dReal z) { dJointSetUniversalAnchor (_id, x, y, z); } void setAnchor (const dVector3 a) { setAnchor(a[0], a[1], a[2]); } void setAxis1 (dReal x, dReal y, dReal z) { dJointSetUniversalAxis1 (_id, x, y, z); } void setAxis1 (const dVector3 a) { setAxis1 (a[0], a[1], a[2]); } void setAxis2 (dReal x, dReal y, dReal z) { dJointSetUniversalAxis2 (_id, x, y, z); } void setAxis2 (const dVector3 a) { setAxis2 (a[0], a[1], a[2]); } void getAnchor (dVector3 result) const { dJointGetUniversalAnchor (_id, result); } void getAnchor2 (dVector3 result) const { dJointGetUniversalAnchor2 (_id, result); } void getAxis1 (dVector3 result) const { dJointGetUniversalAxis1 (_id, result); } void getAxis2 (dVector3 result) const { dJointGetUniversalAxis2 (_id, result); } virtual void setParam (int parameter, dReal value) { dJointSetUniversalParam (_id, parameter, value); } virtual dReal getParam (int parameter) const { return dJointGetUniversalParam (_id, parameter); } // TODO: expose params through methods void getAngles(dReal *angle1, dReal *angle2) const { dJointGetUniversalAngles (_id, angle1, angle2); } dReal getAngle1() const { return dJointGetUniversalAngle1 (_id); } dReal getAngle1Rate() const { return dJointGetUniversalAngle1Rate (_id); } dReal getAngle2() const { return dJointGetUniversalAngle2 (_id); } dReal getAngle2Rate() const { return dJointGetUniversalAngle2Rate (_id); } void addTorques (dReal torque1, dReal torque2) { dJointAddUniversalTorques(_id, torque1, torque2); } }; class dHinge2Joint : public dJoint { // intentionally undefined, don't use these dHinge2Joint (const dHinge2Joint &); void operator = (const dHinge2Joint &); public: dHinge2Joint() { } dHinge2Joint (dWorldID world, dJointGroupID group=0) { _id = dJointCreateHinge2 (world, group); } dHinge2Joint (dWorld& world, dJointGroupID group=0) { _id = dJointCreateHinge2 (world.id(), group); } void create (dWorldID world, dJointGroupID group=0) { if (_id) dJointDestroy (_id); _id = dJointCreateHinge2 (world, group); } void create (dWorld& world, dJointGroupID group=0) { create(world.id(), group); } void setAnchor (dReal x, dReal y, dReal z) { dJointSetHinge2Anchor (_id, x, y, z); } void setAnchor (const dVector3 a) { setAnchor(a[0], a[1], a[2]); } void setAxis1 (dReal x, dReal y, dReal z) { dJointSetHinge2Axis1 (_id, x, y, z); } void setAxis1 (const dVector3 a) { setAxis1 (a[0], a[1], a[2]); } void setAxis2 (dReal x, dReal y, dReal z) { dJointSetHinge2Axis2 (_id, x, y, z); } void setAxis2 (const dVector3 a) { setAxis2 (a[0], a[1], a[2]); } void getAnchor (dVector3 result) const { dJointGetHinge2Anchor (_id, result); } void getAnchor2 (dVector3 result) const { dJointGetHinge2Anchor2 (_id, result); } void getAxis1 (dVector3 result) const { dJointGetHinge2Axis1 (_id, result); } void getAxis2 (dVector3 result) const { dJointGetHinge2Axis2 (_id, result); } dReal getAngle1() const { return dJointGetHinge2Angle1 (_id); } dReal getAngle1Rate() const { return dJointGetHinge2Angle1Rate (_id); } dReal getAngle2Rate() const { return dJointGetHinge2Angle2Rate (_id); } virtual void setParam (int parameter, dReal value) { dJointSetHinge2Param (_id, parameter, value); } virtual dReal getParam (int parameter) const { return dJointGetHinge2Param (_id, parameter); } // TODO: expose params through methods void addTorques(dReal torque1, dReal torque2) { dJointAddHinge2Torques(_id, torque1, torque2); } }; class dPRJoint : public dJoint { dPRJoint (const dPRJoint &); void operator = (const dPRJoint &); public: dPRJoint() { } dPRJoint (dWorldID world, dJointGroupID group=0) { _id = dJointCreatePR (world, group); } dPRJoint (dWorld& world, dJointGroupID group=0) { _id = dJointCreatePR (world.id(), group); } void create (dWorldID world, dJointGroupID group=0) { if (_id) dJointDestroy (_id); _id = dJointCreatePR (world, group); } void create (dWorld& world, dJointGroupID group=0) { create(world.id(), group); } void setAnchor (dReal x, dReal y, dReal z) { dJointSetPRAnchor (_id, x, y, z); } void setAnchor (const dVector3 a) { setAnchor (a[0], a[1], a[2]); } void setAxis1 (dReal x, dReal y, dReal z) { dJointSetPRAxis1 (_id, x, y, z); } void setAxis1 (const dVector3 a) { setAxis1(a[0], a[1], a[2]); } void setAxis2 (dReal x, dReal y, dReal z) { dJointSetPRAxis2 (_id, x, y, z); } void setAxis2 (const dVector3 a) { setAxis2(a[0], a[1], a[2]); } void getAnchor (dVector3 result) const { dJointGetPRAnchor (_id, result); } void getAxis1 (dVector3 result) const { dJointGetPRAxis1 (_id, result); } void getAxis2 (dVector3 result) const { dJointGetPRAxis2 (_id, result); } dReal getPosition() const { return dJointGetPRPosition (_id); } dReal getPositionRate() const { return dJointGetPRPositionRate (_id); } dReal getAngle() const { return dJointGetPRAngle (_id); } dReal getAngleRate() const { return dJointGetPRAngleRate (_id); } virtual void setParam (int parameter, dReal value) { dJointSetPRParam (_id, parameter, value); } virtual dReal getParam (int parameter) const { return dJointGetPRParam (_id, parameter); } }; class dPUJoint : public dJoint { dPUJoint (const dPUJoint &); void operator = (const dPUJoint &); public: dPUJoint() { } dPUJoint (dWorldID world, dJointGroupID group=0) { _id = dJointCreatePU (world, group); } dPUJoint (dWorld& world, dJointGroupID group=0) { _id = dJointCreatePU (world.id(), group); } void create (dWorldID world, dJointGroupID group=0) { if (_id) dJointDestroy (_id); _id = dJointCreatePU (world, group); } void create (dWorld& world, dJointGroupID group=0) { create(world.id(), group); } void setAnchor (dReal x, dReal y, dReal z) { dJointSetPUAnchor (_id, x, y, z); } void setAnchor (const dVector3 a) { setAnchor (a[0], a[1], a[2]); } void setAxis1 (dReal x, dReal y, dReal z) { dJointSetPUAxis1 (_id, x, y, z); } void setAxis1 (const dVector3 a) { setAxis1(a[0], a[1], a[2]); } void setAxis2 (dReal x, dReal y, dReal z) { dJointSetPUAxis2 (_id, x, y, z); } void setAxis3 (dReal x, dReal y, dReal z) { dJointSetPUAxis3 (_id, x, y, z); } void setAxis3 (const dVector3 a) { setAxis3(a[0], a[1], a[2]); } void setAxisP (dReal x, dReal y, dReal z) { dJointSetPUAxis3 (_id, x, y, z); } void setAxisP (const dVector3 a) { setAxisP(a[0], a[1], a[2]); } virtual void getAnchor (dVector3 result) const { dJointGetPUAnchor (_id, result); } void getAxis1 (dVector3 result) const { dJointGetPUAxis1 (_id, result); } void getAxis2 (dVector3 result) const { dJointGetPUAxis2 (_id, result); } void getAxis3 (dVector3 result) const { dJointGetPUAxis3 (_id, result); } void getAxisP (dVector3 result) const { dJointGetPUAxis3 (_id, result); } dReal getAngle1() const { return dJointGetPUAngle1 (_id); } dReal getAngle1Rate() const { return dJointGetPUAngle1Rate (_id); } dReal getAngle2() const { return dJointGetPUAngle2 (_id); } dReal getAngle2Rate() const { return dJointGetPUAngle2Rate (_id); } dReal getPosition() const { return dJointGetPUPosition (_id); } dReal getPositionRate() const { return dJointGetPUPositionRate (_id); } virtual void setParam (int parameter, dReal value) { dJointSetPUParam (_id, parameter, value); } virtual dReal getParam (int parameter) const { return dJointGetPUParam (_id, parameter); } // TODO: expose params through methods }; class dPistonJoint : public dJoint { // intentionally undefined, don't use these dPistonJoint (const dPistonJoint &); void operator = (const dPistonJoint &); public: dPistonJoint() { } dPistonJoint (dWorldID world, dJointGroupID group=0) { _id = dJointCreatePiston (world, group); } dPistonJoint (dWorld& world, dJointGroupID group=0) { _id = dJointCreatePiston (world, group); } void create (dWorldID world, dJointGroupID group=0) { if (_id) dJointDestroy (_id); _id = dJointCreatePiston (world, group); } void create (dWorld& world, dJointGroupID group=0) { create(world.id(), group); } void setAnchor (dReal x, dReal y, dReal z) { dJointSetPistonAnchor (_id, x, y, z); } void setAnchor (const dVector3 a) { setAnchor (a[0], a[1], a[2]); } void getAnchor (dVector3 result) const { dJointGetPistonAnchor (_id, result); } void getAnchor2 (dVector3 result) const { dJointGetPistonAnchor2 (_id, result); } void setAxis (dReal x, dReal y, dReal z) { dJointSetPistonAxis (_id, x, y, z); } void setAxis (const dVector3 a) { setAxis(a[0], a[1], a[2]); } void getAxis (dVector3 result) const { dJointGetPistonAxis (_id, result); } dReal getPosition() const { return dJointGetPistonPosition (_id); } dReal getPositionRate() const { return dJointGetPistonPositionRate (_id); } virtual void setParam (int parameter, dReal value) { dJointSetPistonParam (_id, parameter, value); } virtual dReal getParam (int parameter) const { return dJointGetPistonParam (_id, parameter); } // TODO: expose params through methods void addForce (dReal force) { dJointAddPistonForce (_id, force); } }; class dFixedJoint : public dJoint { // intentionally undefined, don't use these dFixedJoint (const dFixedJoint &); void operator = (const dFixedJoint &); public: dFixedJoint() { } dFixedJoint (dWorldID world, dJointGroupID group=0) { _id = dJointCreateFixed (world, group); } dFixedJoint (dWorld& world, dJointGroupID group=0) { _id = dJointCreateFixed (world, group); } void create (dWorldID world, dJointGroupID group=0) { if (_id) dJointDestroy (_id); _id = dJointCreateFixed (world, group); } void create (dWorld& world, dJointGroupID group=0) { create(world.id(), group); } void set() { dJointSetFixed (_id); } virtual void setParam (int parameter, dReal value) { dJointSetFixedParam (_id, parameter, value); } virtual dReal getParam (int parameter) const { return dJointGetFixedParam (_id, parameter); } // TODO: expose params through methods }; class dContactJoint : public dJoint { // intentionally undefined, don't use these dContactJoint (const dContactJoint &); void operator = (const dContactJoint &); public: dContactJoint() { } dContactJoint (dWorldID world, dJointGroupID group, dContact *contact) { _id = dJointCreateContact (world, group, contact); } dContactJoint (dWorld& world, dJointGroupID group, dContact *contact) { _id = dJointCreateContact (world.id(), group, contact); } void create (dWorldID world, dJointGroupID group, dContact *contact) { if (_id) dJointDestroy (_id); _id = dJointCreateContact (world, group, contact); } void create (dWorld& world, dJointGroupID group, dContact *contact) { create(world.id(), group, contact); } }; class dNullJoint : public dJoint { // intentionally undefined, don't use these dNullJoint (const dNullJoint &); void operator = (const dNullJoint &); public: dNullJoint() { } dNullJoint (dWorldID world, dJointGroupID group=0) { _id = dJointCreateNull (world, group); } dNullJoint (dWorld& world, dJointGroupID group=0) { _id = dJointCreateNull (world.id(), group); } void create (dWorldID world, dJointGroupID group=0) { if (_id) dJointDestroy (_id); _id = dJointCreateNull (world, group); } void create (dWorld& world, dJointGroupID group=0) { create(world.id(), group); } }; class dAMotorJoint : public dJoint { // intentionally undefined, don't use these dAMotorJoint (const dAMotorJoint &); void operator = (const dAMotorJoint &); public: dAMotorJoint() { } dAMotorJoint (dWorldID world, dJointGroupID group=0) { _id = dJointCreateAMotor (world, group); } dAMotorJoint (dWorld& world, dJointGroupID group=0) { _id = dJointCreateAMotor (world.id(), group); } void create (dWorldID world, dJointGroupID group=0) { if (_id) dJointDestroy (_id); _id = dJointCreateAMotor (world, group); } void create (dWorld& world, dJointGroupID group=0) { create(world.id(), group); } void setMode (int mode) { dJointSetAMotorMode (_id, mode); } int getMode() const { return dJointGetAMotorMode (_id); } void setNumAxes (int num) { dJointSetAMotorNumAxes (_id, num); } int getNumAxes() const { return dJointGetAMotorNumAxes (_id); } void setAxis (int anum, int rel, dReal x, dReal y, dReal z) { dJointSetAMotorAxis (_id, anum, rel, x, y, z); } void setAxis (int anum, int rel, const dVector3 a) { setAxis(anum, rel, a[0], a[1], a[2]); } void getAxis (int anum, dVector3 result) const { dJointGetAMotorAxis (_id, anum, result); } int getAxisRel (int anum) const { return dJointGetAMotorAxisRel (_id, anum); } void setAngle (int anum, dReal angle) { dJointSetAMotorAngle (_id, anum, angle); } dReal getAngle (int anum) const { return dJointGetAMotorAngle (_id, anum); } dReal getAngleRate (int anum) { return dJointGetAMotorAngleRate (_id,anum); } void setParam (int parameter, dReal value) { dJointSetAMotorParam (_id, parameter, value); } dReal getParam (int parameter) const { return dJointGetAMotorParam (_id, parameter); } // TODO: expose params through methods void addTorques(dReal torque1, dReal torque2, dReal torque3) { dJointAddAMotorTorques(_id, torque1, torque2, torque3); } }; class dLMotorJoint : public dJoint { // intentionally undefined, don't use these dLMotorJoint (const dLMotorJoint &); void operator = (const dLMotorJoint &); public: dLMotorJoint() { } dLMotorJoint (dWorldID world, dJointGroupID group=0) { _id = dJointCreateLMotor (world, group); } dLMotorJoint (dWorld& world, dJointGroupID group=0) { _id = dJointCreateLMotor (world.id(), group); } void create (dWorldID world, dJointGroupID group=0) { if (_id) dJointDestroy (_id); _id = dJointCreateLMotor (world, group); } void create (dWorld& world, dJointGroupID group=0) { create(world.id(), group); } void setNumAxes (int num) { dJointSetLMotorNumAxes (_id, num); } int getNumAxes() const { return dJointGetLMotorNumAxes (_id); } void setAxis (int anum, int rel, dReal x, dReal y, dReal z) { dJointSetLMotorAxis (_id, anum, rel, x, y, z); } void setAxis (int anum, int rel, const dVector3 a) { setAxis(anum, rel, a[0], a[1], a[2]); } void getAxis (int anum, dVector3 result) const { dJointGetLMotorAxis (_id, anum, result); } void setParam (int parameter, dReal value) { dJointSetLMotorParam (_id, parameter, value); } dReal getParam (int parameter) const { return dJointGetLMotorParam (_id, parameter); } // TODO: expose params through methods }; //} #endif #endif // Local variables: // mode:c++ // c-basic-offset:2 // End: alien-arena-7.66+dfsg/source/unix/ode/odecpp_collision.h0000600000175000017500000002672512161402010022346 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* C++ interface for new collision API */ #ifndef _ODE_ODECPP_COLLISION_H_ #define _ODE_ODECPP_COLLISION_H_ #ifdef __cplusplus //#include //namespace ode { class dGeom { // intentionally undefined, don't use these dGeom (dGeom &); void operator= (dGeom &); protected: dGeomID _id; dGeom() { _id = 0; } public: ~dGeom() { if (_id) dGeomDestroy (_id); } dGeomID id() const { return _id; } operator dGeomID() const { return _id; } void destroy() { if (_id) dGeomDestroy (_id); _id = 0; } int getClass() const { return dGeomGetClass (_id); } dSpaceID getSpace() const { return dGeomGetSpace (_id); } void setData (void *data) { dGeomSetData (_id,data); } void *getData() const { return dGeomGetData (_id); } void setBody (dBodyID b) { dGeomSetBody (_id,b); } dBodyID getBody() const { return dGeomGetBody (_id); } void setPosition (dReal x, dReal y, dReal z) { dGeomSetPosition (_id,x,y,z); } const dReal * getPosition() const { return dGeomGetPosition (_id); } void setRotation (const dMatrix3 R) { dGeomSetRotation (_id,R); } const dReal * getRotation() const { return dGeomGetRotation (_id); } void setQuaternion (const dQuaternion quat) { dGeomSetQuaternion (_id,quat); } void getQuaternion (dQuaternion quat) const { dGeomGetQuaternion (_id,quat); } void getAABB (dReal aabb[6]) const { dGeomGetAABB (_id, aabb); } int isSpace() { return dGeomIsSpace (_id); } void setCategoryBits (unsigned long bits) { dGeomSetCategoryBits (_id, bits); } void setCollideBits (unsigned long bits) { dGeomSetCollideBits (_id, bits); } unsigned long getCategoryBits() { return dGeomGetCategoryBits (_id); } unsigned long getCollideBits() { return dGeomGetCollideBits (_id); } void enable() { dGeomEnable (_id); } void disable() { dGeomDisable (_id); } int isEnabled() { return dGeomIsEnabled (_id); } void collide2 (dGeomID g, void *data, dNearCallback *callback) { dSpaceCollide2 (_id,g,data,callback); } }; class dSpace : public dGeom { // intentionally undefined, don't use these dSpace (dSpace &); void operator= (dSpace &); protected: // the default constructor is protected so that you // can't instance this class. you must instance one // of its subclasses instead. dSpace () { _id = 0; } public: dSpaceID id() const { return (dSpaceID) _id; } operator dSpaceID() const { return (dSpaceID) _id; } void setCleanup (int mode) { dSpaceSetCleanup (id(), mode); } int getCleanup() { return dSpaceGetCleanup (id()); } void add (dGeomID x) { dSpaceAdd (id(), x); } void remove (dGeomID x) { dSpaceRemove (id(), x); } int query (dGeomID x) { return dSpaceQuery (id(),x); } int getNumGeoms() { return dSpaceGetNumGeoms (id()); } dGeomID getGeom (int i) { return dSpaceGetGeom (id(),i); } void collide (void *data, dNearCallback *callback) { dSpaceCollide (id(),data,callback); } }; class dSimpleSpace : public dSpace { // intentionally undefined, don't use these dSimpleSpace (dSimpleSpace &); void operator= (dSimpleSpace &); public: dSimpleSpace () { _id = (dGeomID) dSimpleSpaceCreate (0); } dSimpleSpace (dSpace &space) { _id = (dGeomID) dSimpleSpaceCreate (space.id()); } dSimpleSpace (dSpaceID space) { _id = (dGeomID) dSimpleSpaceCreate (space); } }; class dHashSpace : public dSpace { // intentionally undefined, don't use these dHashSpace (dHashSpace &); void operator= (dHashSpace &); public: dHashSpace () { _id = (dGeomID) dHashSpaceCreate (0); } dHashSpace (dSpace &space) { _id = (dGeomID) dHashSpaceCreate (space.id()); } dHashSpace (dSpaceID space) { _id = (dGeomID) dHashSpaceCreate (space); } void setLevels (int minlevel, int maxlevel) { dHashSpaceSetLevels (id(),minlevel,maxlevel); } }; class dQuadTreeSpace : public dSpace { // intentionally undefined, don't use these dQuadTreeSpace (dQuadTreeSpace &); void operator= (dQuadTreeSpace &); public: dQuadTreeSpace (const dVector3 center, const dVector3 extents, int depth) { _id = (dGeomID) dQuadTreeSpaceCreate (0,center,extents,depth); } dQuadTreeSpace (dSpace &space, const dVector3 center, const dVector3 extents, int depth) { _id = (dGeomID) dQuadTreeSpaceCreate (space.id(),center,extents,depth); } dQuadTreeSpace (dSpaceID space, const dVector3 center, const dVector3 extents, int depth) { _id = (dGeomID) dQuadTreeSpaceCreate (space,center,extents,depth); } }; class dSphere : public dGeom { // intentionally undefined, don't use these dSphere (dSphere &); void operator= (dSphere &); public: dSphere () { } dSphere (dReal radius) { _id = dCreateSphere (0, radius); } dSphere (dSpace &space, dReal radius) { _id = dCreateSphere (space.id(), radius); } dSphere (dSpaceID space, dReal radius) { _id = dCreateSphere (space, radius); } void create (dSpaceID space, dReal radius) { if (_id) dGeomDestroy (_id); _id = dCreateSphere (space, radius); } void setRadius (dReal radius) { dGeomSphereSetRadius (_id, radius); } dReal getRadius() const { return dGeomSphereGetRadius (_id); } }; class dBox : public dGeom { // intentionally undefined, don't use these dBox (dBox &); void operator= (dBox &); public: dBox () { } dBox (dReal lx, dReal ly, dReal lz) { _id = dCreateBox (0,lx,ly,lz); } dBox (dSpace &space, dReal lx, dReal ly, dReal lz) { _id = dCreateBox (space,lx,ly,lz); } dBox (dSpaceID space, dReal lx, dReal ly, dReal lz) { _id = dCreateBox (space,lx,ly,lz); } void create (dSpaceID space, dReal lx, dReal ly, dReal lz) { if (_id) dGeomDestroy (_id); _id = dCreateBox (space,lx,ly,lz); } void setLengths (dReal lx, dReal ly, dReal lz) { dGeomBoxSetLengths (_id, lx, ly, lz); } void getLengths (dVector3 result) const { dGeomBoxGetLengths (_id,result); } }; class dPlane : public dGeom { // intentionally undefined, don't use these dPlane (dPlane &); void operator= (dPlane &); public: dPlane() { } dPlane (dReal a, dReal b, dReal c, dReal d) { _id = dCreatePlane (0,a,b,c,d); } dPlane (dSpace &space, dReal a, dReal b, dReal c, dReal d) { _id = dCreatePlane (space.id(),a,b,c,d); } dPlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d) { _id = dCreatePlane (space,a,b,c,d); } void create (dSpaceID space, dReal a, dReal b, dReal c, dReal d) { if (_id) dGeomDestroy (_id); _id = dCreatePlane (space,a,b,c,d); } void setParams (dReal a, dReal b, dReal c, dReal d) { dGeomPlaneSetParams (_id, a, b, c, d); } void getParams (dVector4 result) const { dGeomPlaneGetParams (_id,result); } }; class dCapsule : public dGeom { // intentionally undefined, don't use these dCapsule (dCapsule &); void operator= (dCapsule &); public: dCapsule() { } dCapsule (dReal radius, dReal length) { _id = dCreateCapsule (0,radius,length); } dCapsule (dSpace &space, dReal radius, dReal length) { _id = dCreateCapsule (space.id(),radius,length); } dCapsule (dSpaceID space, dReal radius, dReal length) { _id = dCreateCapsule (space,radius,length); } void create (dSpaceID space, dReal radius, dReal length) { if (_id) dGeomDestroy (_id); _id = dCreateCapsule (space,radius,length); } void setParams (dReal radius, dReal length) { dGeomCapsuleSetParams (_id, radius, length); } void getParams (dReal *radius, dReal *length) const { dGeomCapsuleGetParams (_id,radius,length); } }; class dCylinder : public dGeom { // intentionally undefined, don't use these dCylinder (dCylinder &); void operator= (dCylinder &); public: dCylinder() { } dCylinder (dReal radius, dReal length) { _id = dCreateCylinder (0,radius,length); } dCylinder (dSpace &space, dReal radius, dReal length) { _id = dCreateCylinder (space.id(),radius,length); } dCylinder (dSpaceID space, dReal radius, dReal length) { _id = dCreateCylinder (space,radius,length); } void create (dSpaceID space, dReal radius, dReal length) { if (_id) dGeomDestroy (_id); _id = dCreateCylinder (space,radius,length); } void setParams (dReal radius, dReal length) { dGeomCylinderSetParams (_id, radius, length); } void getParams (dReal *radius, dReal *length) const { dGeomCylinderGetParams (_id,radius,length); } }; class dRay : public dGeom { // intentionally undefined, don't use these dRay (dRay &); void operator= (dRay &); public: dRay() { } dRay (dReal length) { _id = dCreateRay (0,length); } dRay (dSpace &space, dReal length) { _id = dCreateRay (space.id(),length); } dRay (dSpaceID space, dReal length) { _id = dCreateRay (space,length); } void create (dSpaceID space, dReal length) { if (_id) dGeomDestroy (_id); _id = dCreateRay (space,length); } void setLength (dReal length) { dGeomRaySetLength (_id, length); } dReal getLength() { return dGeomRayGetLength (_id); } void set (dReal px, dReal py, dReal pz, dReal dx, dReal dy, dReal dz) { dGeomRaySet (_id, px, py, pz, dx, dy, dz); } void get (dVector3 start, dVector3 dir) { dGeomRayGet (_id, start, dir); } void setParams (int firstContact, int backfaceCull) { dGeomRaySetParams (_id, firstContact, backfaceCull); } void getParams (int *firstContact, int *backfaceCull) { dGeomRayGetParams (_id, firstContact, backfaceCull); } void setClosestHit (int closestHit) { dGeomRaySetClosestHit (_id, closestHit); } int getClosestHit() { return dGeomRayGetClosestHit (_id); } }; class dGeomTransform : public dGeom { // intentionally undefined, don't use these dGeomTransform (dGeomTransform &); void operator= (dGeomTransform &); public: dGeomTransform() { } dGeomTransform (dSpace &space) { _id = dCreateGeomTransform (space.id()); } dGeomTransform (dSpaceID space) { _id = dCreateGeomTransform (space); } void create (dSpaceID space=0) { if (_id) dGeomDestroy (_id); _id = dCreateGeomTransform (space); } void setGeom (dGeomID geom) { dGeomTransformSetGeom (_id, geom); } dGeomID getGeom() const { return dGeomTransformGetGeom (_id); } void setCleanup (int mode) { dGeomTransformSetCleanup (_id,mode); } int getCleanup () { return dGeomTransformGetCleanup (_id); } void setInfo (int mode) { dGeomTransformSetInfo (_id,mode); } int getInfo() { return dGeomTransformGetInfo (_id); } }; //} #endif #endif alien-arena-7.66+dfsg/source/unix/ode/mass.h0000600000175000017500000001247212161402010017756 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_MASS_H_ #define _ODE_MASS_H_ #include #ifdef __cplusplus extern "C" { #endif struct dMass; typedef struct dMass dMass; /** * Check if a mass structure has valid value. * The function check if the mass and innertia matrix are positive definits * * @param m A mass structure to check * * @return 1 if both codition are met */ ODE_API int dMassCheck(const dMass *m); ODE_API void dMassSetZero (dMass *); ODE_API void dMassSetParameters (dMass *, dReal themass, dReal cgx, dReal cgy, dReal cgz, dReal I11, dReal I22, dReal I33, dReal I12, dReal I13, dReal I23); ODE_API void dMassSetSphere (dMass *, dReal density, dReal radius); ODE_API void dMassSetSphereTotal (dMass *, dReal total_mass, dReal radius); ODE_API void dMassSetCapsule (dMass *, dReal density, int direction, dReal radius, dReal length); ODE_API void dMassSetCapsuleTotal (dMass *, dReal total_mass, int direction, dReal radius, dReal length); ODE_API void dMassSetCylinder (dMass *, dReal density, int direction, dReal radius, dReal length); ODE_API void dMassSetCylinderTotal (dMass *, dReal total_mass, int direction, dReal radius, dReal length); ODE_API void dMassSetBox (dMass *, dReal density, dReal lx, dReal ly, dReal lz); ODE_API void dMassSetBoxTotal (dMass *, dReal total_mass, dReal lx, dReal ly, dReal lz); ODE_API void dMassSetTrimesh (dMass *, dReal density, dGeomID g); ODE_API void dMassSetTrimeshTotal (dMass *m, dReal total_mass, dGeomID g); ODE_API void dMassAdjust (dMass *, dReal newmass); ODE_API void dMassTranslate (dMass *, dReal x, dReal y, dReal z); ODE_API void dMassRotate (dMass *, const dMatrix3 R); ODE_API void dMassAdd (dMass *a, const dMass *b); // Backwards compatible API ODE_API ODE_API_DEPRECATED void dMassSetCappedCylinder(dMass *a, dReal b, int c, dReal d, dReal e); ODE_API ODE_API_DEPRECATED void dMassSetCappedCylinderTotal(dMass *a, dReal b, int c, dReal d, dReal e); struct dMass { dReal mass; dVector3 c; dMatrix3 I; #ifdef __cplusplus dMass() { dMassSetZero (this); } void setZero() { dMassSetZero (this); } void setParameters (dReal themass, dReal cgx, dReal cgy, dReal cgz, dReal I11, dReal I22, dReal I33, dReal I12, dReal I13, dReal I23) { dMassSetParameters (this,themass,cgx,cgy,cgz,I11,I22,I33,I12,I13,I23); } void setSphere (dReal density, dReal radius) { dMassSetSphere (this,density,radius); } void setSphereTotal (dReal total, dReal radius) { dMassSetSphereTotal (this,total,radius); } void setCapsule (dReal density, int direction, dReal radius, dReal length) { dMassSetCapsule (this,density,direction,radius,length); } void setCapsuleTotal (dReal total, int direction, dReal radius, dReal length) { dMassSetCapsule (this,total,direction,radius,length); } void setCylinder(dReal density, int direction, dReal radius, dReal length) { dMassSetCylinder (this,density,direction,radius,length); } void setCylinderTotal(dReal total, int direction, dReal radius, dReal length) { dMassSetCylinderTotal (this,total,direction,radius,length); } void setBox (dReal density, dReal lx, dReal ly, dReal lz) { dMassSetBox (this,density,lx,ly,lz); } void setBoxTotal (dReal total, dReal lx, dReal ly, dReal lz) { dMassSetBoxTotal (this,total,lx,ly,lz); } void setTrimesh(dReal density, dGeomID g) { dMassSetTrimesh (this, density, g); } void setTrimeshTotal(dReal total, dGeomID g) { dMassSetTrimeshTotal (this, total, g); } void adjust (dReal newmass) { dMassAdjust (this,newmass); } void translate (dReal x, dReal y, dReal z) { dMassTranslate (this,x,y,z); } void rotate (const dMatrix3 R) { dMassRotate (this,R); } void add (const dMass *b) { dMassAdd (this,b); } #endif }; #ifdef __cplusplus } #endif #endif alien-arena-7.66+dfsg/source/unix/ode/compatibility.h0000600000175000017500000000366112161402010021664 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_COMPATIBILITY_H_ #define _ODE_COMPATIBILITY_H_ /* * ODE's backward compatibility system ensures that as ODE's API * evolves, user code will not break. */ /* * These new rotation function names are more consistent with the * rest of the API. */ #define dQtoR(q,R) dRfromQ((R),(q)) #define dRtoQ(R,q) dQfromR((q),(R)) #define dWtoDQ(w,q,dq) dDQfromW((dq),(w),(q)) #endif alien-arena-7.66+dfsg/source/unix/ode/rotation.h0000600000175000017500000000603412161402010020647 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_ROTATION_H_ #define _ODE_ROTATION_H_ #include #include #ifdef __cplusplus extern "C" { #endif ODE_API void dRSetIdentity (dMatrix3 R); ODE_API void dRFromAxisAndAngle (dMatrix3 R, dReal ax, dReal ay, dReal az, dReal angle); ODE_API void dRFromEulerAngles (dMatrix3 R, dReal phi, dReal theta, dReal psi); ODE_API void dRFrom2Axes (dMatrix3 R, dReal ax, dReal ay, dReal az, dReal bx, dReal by, dReal bz); ODE_API void dRFromZAxis (dMatrix3 R, dReal ax, dReal ay, dReal az); ODE_API void dQSetIdentity (dQuaternion q); ODE_API void dQFromAxisAndAngle (dQuaternion q, dReal ax, dReal ay, dReal az, dReal angle); /* Quaternion multiplication, analogous to the matrix multiplication routines. */ /* qa = rotate by qc, then qb */ ODE_API void dQMultiply0 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc); /* qa = rotate by qc, then by inverse of qb */ ODE_API void dQMultiply1 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc); /* qa = rotate by inverse of qc, then by qb */ ODE_API void dQMultiply2 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc); /* qa = rotate by inverse of qc, then by inverse of qb */ ODE_API void dQMultiply3 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc); ODE_API void dRfromQ (dMatrix3 R, const dQuaternion q); ODE_API void dQfromR (dQuaternion q, const dMatrix3 R); ODE_API void dDQfromW (dReal dq[4], const dVector3 w, const dQuaternion q); #ifdef __cplusplus } #endif #endif alien-arena-7.66+dfsg/source/unix/ode/memory.h0000600000175000017500000000514512161402010020322 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* this comes from the `reuse' library. copy any changes back to the source */ #ifndef _ODE_MEMORY_H_ #define _ODE_MEMORY_H_ #include #ifdef __cplusplus extern "C" { #endif /* function types to allocate and free memory */ typedef void * dAllocFunction (size_t size); typedef void * dReallocFunction (void *ptr, size_t oldsize, size_t newsize); typedef void dFreeFunction (void *ptr, size_t size); /* set new memory management functions. if fn is 0, the default handlers are * used. */ ODE_API void dSetAllocHandler (dAllocFunction *fn); ODE_API void dSetReallocHandler (dReallocFunction *fn); ODE_API void dSetFreeHandler (dFreeFunction *fn); /* get current memory management functions */ ODE_API dAllocFunction *dGetAllocHandler (void); ODE_API dReallocFunction *dGetReallocHandler (void); ODE_API dFreeFunction *dGetFreeHandler (void); /* allocate and free memory. */ ODE_API void * dAlloc (size_t size); ODE_API void * dRealloc (void *ptr, size_t oldsize, size_t newsize); ODE_API void dFree (void *ptr, size_t size); #ifdef __cplusplus } #endif #endif alien-arena-7.66+dfsg/source/unix/ode/error.h0000600000175000017500000000526312161402010020144 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* this comes from the `reuse' library. copy any changes back to the source */ #ifndef _ODE_ERROR_H_ #define _ODE_ERROR_H_ #include #ifdef __cplusplus extern "C" { #endif /* all user defined error functions have this type. error and debug functions * should not return. */ typedef void dMessageFunction (int errnum, const char *msg, va_list ap); /* set a new error, debug or warning handler. if fn is 0, the default handlers * are used. */ ODE_API void dSetErrorHandler (dMessageFunction *fn); ODE_API void dSetDebugHandler (dMessageFunction *fn); ODE_API void dSetMessageHandler (dMessageFunction *fn); /* return the current error, debug or warning handler. if the return value is * 0, the default handlers are in place. */ ODE_API dMessageFunction *dGetErrorHandler(void); ODE_API dMessageFunction *dGetDebugHandler(void); ODE_API dMessageFunction *dGetMessageHandler(void); /* generate a fatal error, debug trap or a message. */ ODE_API void dError (int num, const char *msg, ...); ODE_API void dDebug (int num, const char *msg, ...); ODE_API void dMessage (int num, const char *msg, ...); #ifdef __cplusplus } #endif #endif alien-arena-7.66+dfsg/source/unix/ode/timer.h0000600000175000017500000000556312161402010020136 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_TIMER_H_ #define _ODE_TIMER_H_ #include #ifdef __cplusplus extern "C" { #endif /* stop watch objects */ typedef struct dStopwatch { double time; /* total clock count */ unsigned long cc[2]; /* clock count since last `start' */ } dStopwatch; ODE_API void dStopwatchReset (dStopwatch *); ODE_API void dStopwatchStart (dStopwatch *); ODE_API void dStopwatchStop (dStopwatch *); ODE_API double dStopwatchTime (dStopwatch *); /* returns total time in secs */ /* code timers */ ODE_API void dTimerStart (const char *description); /* pass a static string here */ ODE_API void dTimerNow (const char *description); /* pass a static string here */ ODE_API void dTimerEnd(void); /* print out a timer report. if `average' is nonzero, print out the average * time for each slot (this is only meaningful if the same start-now-end * calls are being made repeatedly. */ ODE_API void dTimerReport (FILE *fout, int average); /* resolution */ /* returns the timer ticks per second implied by the timing hardware or API. * the actual timer resolution may not be this great. */ ODE_API double dTimerTicksPerSecond(void); /* returns an estimate of the actual timer resolution, in seconds. this may * be greater than 1/ticks_per_second. */ ODE_API double dTimerResolution(void); #ifdef __cplusplus } #endif #endif alien-arena-7.66+dfsg/source/unix/ode/collision_trimesh.h0000600000175000017500000002100712161402010022533 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* * TriMesh code by Erwin de Vries. * * Trimesh data. * This is where the actual vertexdata (pointers), and BV tree is stored. * Vertices should be single precision! * This should be more sophisticated, so that the user can easyly implement * another collision library, but this is a lot of work, and also costs some * performance because some data has to be copied. */ #ifndef _ODE_COLLISION_TRIMESH_H_ #define _ODE_COLLISION_TRIMESH_H_ #ifdef __cplusplus extern "C" { #endif /* * Data storage for triangle meshes. */ struct dxTriMeshData; typedef struct dxTriMeshData* dTriMeshDataID; /* * These dont make much sense now, but they will later when we add more * features. */ ODE_API dTriMeshDataID dGeomTriMeshDataCreate(void); ODE_API void dGeomTriMeshDataDestroy(dTriMeshDataID g); enum { TRIMESH_FACE_NORMALS }; ODE_API void dGeomTriMeshDataSet(dTriMeshDataID g, int data_id, void* in_data); ODE_API void* dGeomTriMeshDataGet(dTriMeshDataID g, int data_id); /** * We need to set the last transform after each time step for * accurate collision response. These functions get and set that transform. * It is stored per geom instance, rather than per dTriMeshDataID. */ ODE_API void dGeomTriMeshSetLastTransform( dGeomID g, dMatrix4 last_trans ); ODE_API dReal* dGeomTriMeshGetLastTransform( dGeomID g ); /* * Build a TriMesh data object with single precision vertex data. */ ODE_API void dGeomTriMeshDataBuildSingle(dTriMeshDataID g, const void* Vertices, int VertexStride, int VertexCount, const void* Indices, int IndexCount, int TriStride); /* same again with a normals array (used as trimesh-trimesh optimization) */ ODE_API void dGeomTriMeshDataBuildSingle1(dTriMeshDataID g, const void* Vertices, int VertexStride, int VertexCount, const void* Indices, int IndexCount, int TriStride, const void* Normals); /* * Build a TriMesh data object with double precision vertex data. */ ODE_API void dGeomTriMeshDataBuildDouble(dTriMeshDataID g, const void* Vertices, int VertexStride, int VertexCount, const void* Indices, int IndexCount, int TriStride); /* same again with a normals array (used as trimesh-trimesh optimization) */ ODE_API void dGeomTriMeshDataBuildDouble1(dTriMeshDataID g, const void* Vertices, int VertexStride, int VertexCount, const void* Indices, int IndexCount, int TriStride, const void* Normals); /* * Simple build. Single/double precision based on dSINGLE/dDOUBLE! */ ODE_API void dGeomTriMeshDataBuildSimple(dTriMeshDataID g, const dReal* Vertices, int VertexCount, const dTriIndex* Indices, int IndexCount); /* same again with a normals array (used as trimesh-trimesh optimization) */ ODE_API void dGeomTriMeshDataBuildSimple1(dTriMeshDataID g, const dReal* Vertices, int VertexCount, const dTriIndex* Indices, int IndexCount, const int* Normals); /* Preprocess the trimesh data to remove mark unnecessary edges and vertices */ ODE_API void dGeomTriMeshDataPreprocess(dTriMeshDataID g); /* Get and set the internal preprocessed trimesh data buffer, for loading and saving */ ODE_API void dGeomTriMeshDataGetBuffer(dTriMeshDataID g, unsigned char** buf, int* bufLen); ODE_API void dGeomTriMeshDataSetBuffer(dTriMeshDataID g, unsigned char* buf); /* * Per triangle callback. Allows the user to say if he wants a collision with * a particular triangle. */ typedef int dTriCallback(dGeomID TriMesh, dGeomID RefObject, int TriangleIndex); ODE_API void dGeomTriMeshSetCallback(dGeomID g, dTriCallback* Callback); ODE_API dTriCallback* dGeomTriMeshGetCallback(dGeomID g); /* * Per object callback. Allows the user to get the list of triangles in 1 * shot. Maybe we should remove this one. */ typedef void dTriArrayCallback(dGeomID TriMesh, dGeomID RefObject, const int* TriIndices, int TriCount); ODE_API void dGeomTriMeshSetArrayCallback(dGeomID g, dTriArrayCallback* ArrayCallback); ODE_API dTriArrayCallback* dGeomTriMeshGetArrayCallback(dGeomID g); /* * Ray callback. * Allows the user to say if a ray collides with a triangle on barycentric * coords. The user can for example sample a texture with alpha transparency * to determine if a collision should occur. */ typedef int dTriRayCallback(dGeomID TriMesh, dGeomID Ray, int TriangleIndex, dReal u, dReal v); ODE_API void dGeomTriMeshSetRayCallback(dGeomID g, dTriRayCallback* Callback); ODE_API dTriRayCallback* dGeomTriMeshGetRayCallback(dGeomID g); /* * Triangle merging callback. * Allows the user to generate a fake triangle index for a new contact generated * from merging of two other contacts. That index could later be used by the * user to determine attributes of original triangles used as sources for a * merged contact. */ typedef int dTriTriMergeCallback(dGeomID TriMesh, int FirstTriangleIndex, int SecondTriangleIndex); ODE_API void dGeomTriMeshSetTriMergeCallback(dGeomID g, dTriTriMergeCallback* Callback); ODE_API dTriTriMergeCallback* dGeomTriMeshGetTriMergeCallback(dGeomID g); /* * Trimesh class * Construction. Callbacks are optional. */ ODE_API dGeomID dCreateTriMesh(dSpaceID space, dTriMeshDataID Data, dTriCallback* Callback, dTriArrayCallback* ArrayCallback, dTriRayCallback* RayCallback); ODE_API void dGeomTriMeshSetData(dGeomID g, dTriMeshDataID Data); ODE_API dTriMeshDataID dGeomTriMeshGetData(dGeomID g); // enable/disable/check temporal coherence ODE_API void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable); ODE_API int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass); /* * Clears the internal temporal coherence caches. When a geom has its * collision checked with a trimesh once, data is stored inside the trimesh. * With large worlds with lots of seperate objects this list could get huge. * We should be able to do this automagically. */ ODE_API void dGeomTriMeshClearTCCache(dGeomID g); /* * returns the TriMeshDataID */ ODE_API dTriMeshDataID dGeomTriMeshGetTriMeshDataID(dGeomID g); /* * Gets a triangle. */ ODE_API void dGeomTriMeshGetTriangle(dGeomID g, int Index, dVector3* v0, dVector3* v1, dVector3* v2); /* * Gets the point on the requested triangle and the given barycentric * coordinates. */ ODE_API void dGeomTriMeshGetPoint(dGeomID g, int Index, dReal u, dReal v, dVector3 Out); /* This is how the strided data works: struct StridedVertex{ dVector3 Vertex; // Userdata }; int VertexStride = sizeof(StridedVertex); struct StridedTri{ int Indices[3]; // Userdata }; int TriStride = sizeof(StridedTri); */ ODE_API int dGeomTriMeshGetTriangleCount (dGeomID g); ODE_API void dGeomTriMeshDataUpdate(dTriMeshDataID g); #ifdef __cplusplus } #endif #endif /* _ODE_COLLISION_TRIMESH_H_ */ alien-arena-7.66+dfsg/source/unix/ode/export-dif.h0000600000175000017500000000331612161402010021071 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_EXPORT_DIF_ #define _ODE_EXPORT_DIF_ #include ODE_API void dWorldExportDIF (dWorldID w, FILE *file, const char *world_name); #endif alien-arena-7.66+dfsg/source/unix/ode/common.h0000600000175000017500000002714512161402010020306 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_COMMON_H_ #define _ODE_COMMON_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif /* configuration stuff */ /* constants */ /* pi and 1/sqrt(2) are defined here if necessary because they don't get * defined in on some platforms (like MS-Windows) */ #ifndef M_PI #define M_PI REAL(3.1415926535897932384626433832795029) #endif #ifndef M_SQRT1_2 #define M_SQRT1_2 REAL(0.7071067811865475244008443621048490) #endif /* debugging: * IASSERT is an internal assertion, i.e. a consistency check. if it fails * we want to know where. * UASSERT is a user assertion, i.e. if it fails a nice error message * should be printed for the user. * AASSERT is an arguments assertion, i.e. if it fails "bad argument(s)" * is printed. * DEBUGMSG just prints out a message */ #ifndef dNODEBUG # if defined(__STDC__) && __STDC_VERSION__ >= 199901L # define __FUNCTION__ __func__ # endif # ifdef __GNUC__ # define dIASSERT(a) if (!(a)) dDebug (d_ERR_IASSERT, \ "assertion \"" #a "\" failed in %s() [%s]",__FUNCTION__,__FILE__); # define dUASSERT(a,msg) if (!(a)) dDebug (d_ERR_UASSERT, \ msg " in %s()", __FUNCTION__); # define dDEBUGMSG(msg) dMessage (d_ERR_UASSERT, \ msg " in %s() File %s Line %d", __FUNCTION__, __FILE__,__LINE__); # else // not __GNUC__ # define dIASSERT(a) if (!(a)) dDebug (d_ERR_IASSERT, \ "assertion \"" #a "\" failed in %s:%d",__FILE__,__LINE__); # define dUASSERT(a,msg) if (!(a)) dDebug (d_ERR_UASSERT, \ msg " (%s:%d)", __FILE__,__LINE__); # define dDEBUGMSG(msg) dMessage (d_ERR_UASSERT, \ msg " (%s:%d)", __FILE__,__LINE__); # endif #else # define dIASSERT(a) ; # define dUASSERT(a,msg) ; # define dDEBUGMSG(msg) ; #endif #define dAASSERT(a) dUASSERT(a,"Bad argument(s)") // Macro used to suppress unused variable warning #define dVARIABLEUSED(a) ((void)a) /* floating point data type, vector, matrix and quaternion types */ #if defined(dSINGLE) typedef float dReal; #ifdef dDOUBLE #error You can only #define dSINGLE or dDOUBLE, not both. #endif // dDOUBLE #elif defined(dDOUBLE) typedef double dReal; #else #error You must #define dSINGLE or dDOUBLE #endif // Detect if we've got both trimesh engines enabled. #if dTRIMESH_ENABLED #if dTRIMESH_OPCODE && dTRIMESH_GIMPACT #error You can only #define dTRIMESH_OPCODE or dTRIMESH_GIMPACT, not both. #endif #endif // dTRIMESH_ENABLED // Define a type for indices, either 16 or 32 bit, based on build option // TODO: Currently GIMPACT only supports 32 bit indices. #if dTRIMESH_16BIT_INDICES #if dTRIMESH_GIMPACT typedef uint32 dTriIndex; #else // dTRIMESH_GIMPACT typedef uint16 dTriIndex; #endif // dTRIMESH_GIMPACT #else // dTRIMESH_16BIT_INDICES typedef uint32 dTriIndex; #endif // dTRIMESH_16BIT_INDICES /* round an integer up to a multiple of 4, except that 0 and 1 are unmodified * (used to compute matrix leading dimensions) */ #define dPAD(a) (((a) > 1) ? ((((a)-1)|3)+1) : (a)) /* these types are mainly just used in headers */ typedef dReal dVector3[4]; typedef dReal dVector4[4]; typedef dReal dMatrix3[4*3]; typedef dReal dMatrix4[4*4]; typedef dReal dMatrix6[8*6]; typedef dReal dQuaternion[4]; /* precision dependent scalar math functions */ #if defined(dSINGLE) #define REAL(x) (x ## f) /* form a constant */ #define dRecip(x) ((1.0f/(x))) /* reciprocal */ #define dSqrt(x) (sqrtf(x)) /* square root */ #define dRecipSqrt(x) ((1.0f/sqrtf(x))) /* reciprocal square root */ #define dSin(x) (sinf(x)) /* sine */ #define dCos(x) (cosf(x)) /* cosine */ #define dFabs(x) (fabsf(x)) /* absolute value */ #define dAtan2(y,x) (atan2f(y,x)) /* arc tangent with 2 args */ #define dFMod(a,b) (fmodf(a,b)) /* modulo */ #define dFloor(x) floorf(x) /* floor */ #ifdef HAVE___ISNANF #define dIsNan(x) (__isnanf(x)) #elif defined(HAVE__ISNANF) #define dIsNan(x) (_isnanf(x)) #elif defined(HAVE_ISNANF) #define dIsNan(x) (isnanf(x)) #else /* fall back to _isnan which is the VC way, this may seem redundant since we already checked for _isnan before, but if isnan is detected by configure but is not found during compilation we should always make sure we check for __isnanf, _isnanf and isnanf in that order before falling back to a default */ #define dIsNan(x) (_isnan(x)) #endif #define dCopySign(a,b) ((dReal)copysignf(a,b)) #elif defined(dDOUBLE) #define REAL(x) (x) #define dRecip(x) (1.0/(x)) #define dSqrt(x) sqrt(x) #define dRecipSqrt(x) (1.0/sqrt(x)) #define dSin(x) sin(x) #define dCos(x) cos(x) #define dFabs(x) fabs(x) #define dAtan2(y,x) atan2((y),(x)) #define dFMod(a,b) (fmod((a),(b))) #define dFloor(x) floor(x) #ifdef HAVE___ISNAN #define dIsNan(x) (__isnan(x)) #elif defined(HAVE__ISNAN) #define dIsNan(x) (_isnan(x)) #elif defined(HAVE_ISNAN) #define dIsNan(x) (isnan(x)) #else #define dIsNan(x) (_isnan(x)) #endif #define dCopySign(a,b) (copysign((a),(b))) #else #error You must #define dSINGLE or dDOUBLE #endif /* internal object types (all prefixed with `dx') */ struct dxWorld; /* dynamics world */ struct dxSpace; /* collision space */ struct dxBody; /* rigid body (dynamics object) */ struct dxGeom; /* geometry (collision object) */ struct dxJoint; struct dxJointNode; struct dxJointGroup; typedef struct dxWorld *dWorldID; typedef struct dxSpace *dSpaceID; typedef struct dxBody *dBodyID; typedef struct dxGeom *dGeomID; typedef struct dxJoint *dJointID; typedef struct dxJointGroup *dJointGroupID; /* error numbers */ enum { d_ERR_UNKNOWN = 0, /* unknown error */ d_ERR_IASSERT, /* internal assertion failed */ d_ERR_UASSERT, /* user assertion failed */ d_ERR_LCP /* user assertion failed */ }; /* joint type numbers */ typedef enum { dJointTypeNone = 0, /* or "unknown" */ dJointTypeBall, dJointTypeHinge, dJointTypeSlider, dJointTypeContact, dJointTypeUniversal, dJointTypeHinge2, dJointTypeFixed, dJointTypeNull, dJointTypeAMotor, dJointTypeLMotor, dJointTypePlane2D, dJointTypePR, dJointTypePU, dJointTypePiston } dJointType; /* an alternative way of setting joint parameters, using joint parameter * structures and member constants. we don't actually do this yet. */ /* typedef struct dLimot { int mode; dReal lostop, histop; dReal vel, fmax; dReal fudge_factor; dReal bounce, soft; dReal suspension_erp, suspension_cfm; } dLimot; enum { dLimotLoStop = 0x0001, dLimotHiStop = 0x0002, dLimotVel = 0x0004, dLimotFMax = 0x0008, dLimotFudgeFactor = 0x0010, dLimotBounce = 0x0020, dLimotSoft = 0x0040 }; */ /* standard joint parameter names. why are these here? - because we don't want * to include all the joint function definitions in joint.cpp. hmmmm. * MSVC complains if we call D_ALL_PARAM_NAMES_X with a blank second argument, * which is why we have the D_ALL_PARAM_NAMES macro as well. please copy and * paste between these two. */ #define D_ALL_PARAM_NAMES(start) \ /* parameters for limits and motors */ \ dParamLoStop = start, \ dParamHiStop, \ dParamVel, \ dParamFMax, \ dParamFudgeFactor, \ dParamBounce, \ dParamCFM, \ dParamStopERP, \ dParamStopCFM, \ /* parameters for suspension */ \ dParamSuspensionERP, \ dParamSuspensionCFM, \ dParamERP, \ ////////////////////////////////////////////////////////////////////////////// /// \enum D_ALL_PARAM_NAMES_X /// /// \var dParamGroup This is the starting value of the different group /// (i.e. dParamGroup1, dParamGroup2, dParamGroup3) /// It also helps in the use of parameter /// (dParamGroup2 | dParamFMax) == dParamFMax2 ////////////////////////////////////////////////////////////////////////////// #define D_ALL_PARAM_NAMES_X(start,x) \ dParamGroup ## x = start, \ /* parameters for limits and motors */ \ dParamLoStop ## x = start, \ dParamHiStop ## x, \ dParamVel ## x, \ dParamFMax ## x, \ dParamFudgeFactor ## x, \ dParamBounce ## x, \ dParamCFM ## x, \ dParamStopERP ## x, \ dParamStopCFM ## x, \ /* parameters for suspension */ \ dParamSuspensionERP ## x, \ dParamSuspensionCFM ## x, \ dParamERP ## x, enum { D_ALL_PARAM_NAMES(0) dParamsInGroup, ///< Number of parameter in a group D_ALL_PARAM_NAMES_X(0x000,1) D_ALL_PARAM_NAMES_X(0x100,2) D_ALL_PARAM_NAMES_X(0x200,3) /* add a multiple of this constant to the basic parameter numbers to get * the parameters for the second, third etc axes. */ dParamGroup=0x100 }; /* angular motor mode numbers */ enum { dAMotorUser = 0, dAMotorEuler = 1 }; /* joint force feedback information */ typedef struct dJointFeedback { dVector3 f1; /* force applied to body 1 */ dVector3 t1; /* torque applied to body 1 */ dVector3 f2; /* force applied to body 2 */ dVector3 t2; /* torque applied to body 2 */ } dJointFeedback; /* private functions that must be implemented by the collision library: * (1) indicate that a geom has moved, (2) get the next geom in a body list. * these functions are called whenever the position of geoms connected to a * body have changed, e.g. with dBodySetPosition(), dBodySetRotation(), or * when the ODE step function updates the body state. */ void dGeomMoved (dGeomID); dGeomID dGeomGetBodyNext (dGeomID); /** * dGetConfiguration returns the specific ODE build configuration as * a string of tokens. The string can be parsed in a similar way to * the OpenGL extension mechanism, the naming convention should be * familiar too. The following extensions are reported: * * ODE * ODE_single_precision * ODE_double_precision * ODE_EXT_no_debug * ODE_EXT_trimesh * ODE_EXT_opcode * ODE_EXT_gimpact * ODE_EXT_malloc_not_alloca * ODE_EXT_gyroscopic * ODE_OPC_16bit_indices * ODE_OPC_new_collider */ ODE_API const char* dGetConfiguration (void); /** * Helper to check for a token in the ODE configuration string. * Caution, this function is case sensitive. * * @param token A configuration token, see dGetConfiguration for details * * @return 1 if exact token is present, 0 if not present */ ODE_API int dCheckConfiguration( const char* token ); #ifdef __cplusplus } #endif #endif alien-arena-7.66+dfsg/source/unix/ode/odeconfig.h0000600000175000017500000000400712161402010020743 0ustar zero79zero79#ifndef ODECONFIG_H #define ODECONFIG_H #ifndef dDOUBLE #ifndef dSINGLE #define dSINGLE #endif #endif /* Pull in the standard headers */ #include #include #include #include #include #include #if defined(ODE_DLL) || defined(ODE_LIB) || !defined(_MSC_VER) #define __ODE__ #endif /* Define a DLL export symbol for those platforms that need it */ #if defined(_MSC_VER) #if defined(ODE_DLL) #define ODE_API __declspec(dllexport) #elif !defined(ODE_LIB) #define ODE_DLL_API __declspec(dllimport) #endif #endif #if !defined(ODE_API) #define ODE_API #endif #if defined(_MSC_VER) # define ODE_API_DEPRECATED __declspec(deprecated) #elif defined (__GNUC__) && ( (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) ) # define ODE_API_DEPRECATED __attribute__((__deprecated__)) #else # define ODE_API_DEPRECATED #endif /* Well-defined common data types...need to define for 64 bit systems */ #if defined(_M_IA64) || defined(__ia64__) || defined(_M_AMD64) || defined(__x86_64__) #define X86_64_SYSTEM 1 typedef int int32; typedef unsigned int uint32; typedef short int16; typedef unsigned short uint16; typedef char int8; typedef unsigned char uint8; #else typedef int int32; typedef unsigned int uint32; typedef short int16; typedef unsigned short uint16; typedef char int8; typedef unsigned char uint8; #endif /* Visual C does not define these functions */ #if defined(_MSC_VER) #define copysignf _copysign #define copysign _copysign #endif /* Define the dInfinity macro */ #ifdef INFINITY #define dInfinity INFINITY #elif defined(HUGE_VAL) #ifdef dSINGLE #ifdef HUGE_VALF #define dInfinity HUGE_VALF #else #define dInfinity ((float)HUGE_VAL) #endif #else #define dInfinity HUGE_VAL #endif #else #ifdef dSINGLE #define dInfinity ((float)(1.0/0.0)) #else #define dInfinity (1.0/0.0) #endif #endif #endif alien-arena-7.66+dfsg/source/unix/ode/odemath.h0000600000175000017500000003033412161402010020431 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_ODEMATH_H_ #define _ODE_ODEMATH_H_ #include #ifdef __GNUC__ #define PURE_INLINE extern inline #else #define PURE_INLINE inline #endif /* * macro to access elements i,j in an NxM matrix A, independent of the * matrix storage convention. */ #define dACCESS33(A,i,j) ((A)[(i)*4+(j)]) /* * Macro to test for valid floating point values */ #define dVALIDVEC3(v) (!(dIsNan(v[0]) || dIsNan(v[1]) || dIsNan(v[2]))) #define dVALIDVEC4(v) (!(dIsNan(v[0]) || dIsNan(v[1]) || dIsNan(v[2]) || dIsNan(v[3]))) #define dVALIDMAT3(m) (!(dIsNan(m[0]) || dIsNan(m[1]) || dIsNan(m[2]) || dIsNan(m[3]) || dIsNan(m[4]) || dIsNan(m[5]) || dIsNan(m[6]) || dIsNan(m[7]) || dIsNan(m[8]) || dIsNan(m[9]) || dIsNan(m[10]) || dIsNan(m[11]))) #define dVALIDMAT4(m) (!(dIsNan(m[0]) || dIsNan(m[1]) || dIsNan(m[2]) || dIsNan(m[3]) || dIsNan(m[4]) || dIsNan(m[5]) || dIsNan(m[6]) || dIsNan(m[7]) || dIsNan(m[8]) || dIsNan(m[9]) || dIsNan(m[10]) || dIsNan(m[11]) || dIsNan(m[12]) || dIsNan(m[13]) || dIsNan(m[14]) || dIsNan(m[15]) )) /* * General purpose vector operations with other vectors or constants. */ #define dOP(a,op,b,c) do { \ (a)[0] = ((b)[0]) op ((c)[0]); \ (a)[1] = ((b)[1]) op ((c)[1]); \ (a)[2] = ((b)[2]) op ((c)[2]); \ } while (0) #define dOPC(a,op,b,c) do { \ (a)[0] = ((b)[0]) op (c); \ (a)[1] = ((b)[1]) op (c); \ (a)[2] = ((b)[2]) op (c); \ } while (0) #define dOPE(a,op,b) do {\ (a)[0] op ((b)[0]); \ (a)[1] op ((b)[1]); \ (a)[2] op ((b)[2]); \ } while (0) #define dOPEC(a,op,c) do { \ (a)[0] op (c); \ (a)[1] op (c); \ (a)[2] op (c); \ } while (0) /// Define an equation with operatos /// For example this function can be used to replace ///
/// for (int i=0; i<3; ++i)
///   a[i] += b[i] + c[i];
/// 
#define dOPE2(a,op1,b,op2,c) do { \ (a)[0] op1 ((b)[0]) op2 ((c)[0]); \ (a)[1] op1 ((b)[1]) op2 ((c)[1]); \ (a)[2] op1 ((b)[2]) op2 ((c)[2]); \ } while (0) /* * Length, and squared length helpers. dLENGTH returns the length of a dVector3. * dLENGTHSQUARED return the squared length of a dVector3. */ #define dLENGTHSQUARED(a) (((a)[0])*((a)[0]) + ((a)[1])*((a)[1]) + ((a)[2])*((a)[2])) #ifdef __cplusplus PURE_INLINE dReal dLENGTH (const dReal *a) { return dSqrt(dLENGTHSQUARED(a)); } #else #define dLENGTH(a) ( dSqrt( ((a)[0])*((a)[0]) + ((a)[1])*((a)[1]) + ((a)[2])*((a)[2]) ) ) #endif /* __cplusplus */ /* * 3-way dot product. dDOTpq means that elements of `a' and `b' are spaced * p and q indexes apart respectively. dDOT() means dDOT11. * in C++ we could use function templates to get all the versions of these * functions - but on some compilers this will result in sub-optimal code. */ #define dDOTpq(a,b,p,q) ((a)[0]*(b)[0] + (a)[p]*(b)[q] + (a)[2*(p)]*(b)[2*(q)]) #ifdef __cplusplus PURE_INLINE dReal dDOT (const dReal *a, const dReal *b) { return dDOTpq(a,b,1,1); } PURE_INLINE dReal dDOT13 (const dReal *a, const dReal *b) { return dDOTpq(a,b,1,3); } PURE_INLINE dReal dDOT31 (const dReal *a, const dReal *b) { return dDOTpq(a,b,3,1); } PURE_INLINE dReal dDOT33 (const dReal *a, const dReal *b) { return dDOTpq(a,b,3,3); } PURE_INLINE dReal dDOT14 (const dReal *a, const dReal *b) { return dDOTpq(a,b,1,4); } PURE_INLINE dReal dDOT41 (const dReal *a, const dReal *b) { return dDOTpq(a,b,4,1); } PURE_INLINE dReal dDOT44 (const dReal *a, const dReal *b) { return dDOTpq(a,b,4,4); } #else #define dDOT(a,b) dDOTpq(a,b,1,1) #define dDOT13(a,b) dDOTpq(a,b,1,3) #define dDOT31(a,b) dDOTpq(a,b,3,1) #define dDOT33(a,b) dDOTpq(a,b,3,3) #define dDOT14(a,b) dDOTpq(a,b,1,4) #define dDOT41(a,b) dDOTpq(a,b,4,1) #define dDOT44(a,b) dDOTpq(a,b,4,4) #endif /* __cplusplus */ /* * cross product, set a = b x c. dCROSSpqr means that elements of `a', `b' * and `c' are spaced p, q and r indexes apart respectively. * dCROSS() means dCROSS111. `op' is normally `=', but you can set it to * +=, -= etc to get other effects. */ #define dCROSS(a,op,b,c) \ do { \ (a)[0] op ((b)[1]*(c)[2] - (b)[2]*(c)[1]); \ (a)[1] op ((b)[2]*(c)[0] - (b)[0]*(c)[2]); \ (a)[2] op ((b)[0]*(c)[1] - (b)[1]*(c)[0]); \ } while(0) #define dCROSSpqr(a,op,b,c,p,q,r) \ do { \ (a)[ 0] op ((b)[ q]*(c)[2*r] - (b)[2*q]*(c)[ r]); \ (a)[ p] op ((b)[2*q]*(c)[ 0] - (b)[ 0]*(c)[2*r]); \ (a)[2*p] op ((b)[ 0]*(c)[ r] - (b)[ q]*(c)[ 0]); \ } while(0) #define dCROSS114(a,op,b,c) dCROSSpqr(a,op,b,c,1,1,4) #define dCROSS141(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,1) #define dCROSS144(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,4) #define dCROSS411(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,1) #define dCROSS414(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,4) #define dCROSS441(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,1) #define dCROSS444(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,4) /* * set a 3x3 submatrix of A to a matrix such that submatrix(A)*b = a x b. * A is stored by rows, and has `skip' elements per row. the matrix is * assumed to be already zero, so this does not write zero elements! * if (plus,minus) is (+,-) then a positive version will be written. * if (plus,minus) is (-,+) then a negative version will be written. */ #define dCROSSMAT(A,a,skip,plus,minus) \ do { \ (A)[1] = minus (a)[2]; \ (A)[2] = plus (a)[1]; \ (A)[(skip)+0] = plus (a)[2]; \ (A)[(skip)+2] = minus (a)[0]; \ (A)[2*(skip)+0] = minus (a)[1]; \ (A)[2*(skip)+1] = plus (a)[0]; \ } while(0) /* * compute the distance between two 3D-vectors */ #ifdef __cplusplus PURE_INLINE dReal dDISTANCE (const dVector3 a, const dVector3 b) { return dSqrt( (a[0]-b[0])*(a[0]-b[0]) + (a[1]-b[1])*(a[1]-b[1]) + (a[2]-b[2])*(a[2]-b[2]) ); } #else #define dDISTANCE(a,b) \ (dSqrt( ((a)[0]-(b)[0])*((a)[0]-(b)[0]) + ((a)[1]-(b)[1])*((a)[1]-(b)[1]) + ((a)[2]-(b)[2])*((a)[2]-(b)[2]) )) #endif /* * special case matrix multipication, with operator selection */ #define dMULTIPLYOP0_331(A,op,B,C) \ do { \ (A)[0] op dDOT((B),(C)); \ (A)[1] op dDOT((B+4),(C)); \ (A)[2] op dDOT((B+8),(C)); \ } while(0) #define dMULTIPLYOP1_331(A,op,B,C) \ do { \ (A)[0] op dDOT41((B),(C)); \ (A)[1] op dDOT41((B+1),(C)); \ (A)[2] op dDOT41((B+2),(C)); \ } while(0) #define dMULTIPLYOP0_133(A,op,B,C) \ do { \ (A)[0] op dDOT14((B),(C)); \ (A)[1] op dDOT14((B),(C+1)); \ (A)[2] op dDOT14((B),(C+2)); \ } while(0) #define dMULTIPLYOP0_333(A,op,B,C) \ do { \ (A)[0] op dDOT14((B),(C)); \ (A)[1] op dDOT14((B),(C+1)); \ (A)[2] op dDOT14((B),(C+2)); \ (A)[4] op dDOT14((B+4),(C)); \ (A)[5] op dDOT14((B+4),(C+1)); \ (A)[6] op dDOT14((B+4),(C+2)); \ (A)[8] op dDOT14((B+8),(C)); \ (A)[9] op dDOT14((B+8),(C+1)); \ (A)[10] op dDOT14((B+8),(C+2)); \ } while(0) #define dMULTIPLYOP1_333(A,op,B,C) \ do { \ (A)[0] op dDOT44((B),(C)); \ (A)[1] op dDOT44((B),(C+1)); \ (A)[2] op dDOT44((B),(C+2)); \ (A)[4] op dDOT44((B+1),(C)); \ (A)[5] op dDOT44((B+1),(C+1)); \ (A)[6] op dDOT44((B+1),(C+2)); \ (A)[8] op dDOT44((B+2),(C)); \ (A)[9] op dDOT44((B+2),(C+1)); \ (A)[10] op dDOT44((B+2),(C+2)); \ } while(0) #define dMULTIPLYOP2_333(A,op,B,C) \ do { \ (A)[0] op dDOT((B),(C)); \ (A)[1] op dDOT((B),(C+4)); \ (A)[2] op dDOT((B),(C+8)); \ (A)[4] op dDOT((B+4),(C)); \ (A)[5] op dDOT((B+4),(C+4)); \ (A)[6] op dDOT((B+4),(C+8)); \ (A)[8] op dDOT((B+8),(C)); \ (A)[9] op dDOT((B+8),(C+4)); \ (A)[10] op dDOT((B+8),(C+8)); \ } while(0) #ifdef __cplusplus #define DECL template PURE_INLINE void /* Note: NEVER call any of these functions/macros with the same variable for A and C, it is not equivalent to A*=B. */ DECL dMULTIPLY0_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_331(A,=,B,C); } DECL dMULTIPLY1_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_331(A,=,B,C); } DECL dMULTIPLY0_133(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_133(A,=,B,C); } DECL dMULTIPLY0_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_333(A,=,B,C); } DECL dMULTIPLY1_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_333(A,=,B,C); } DECL dMULTIPLY2_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP2_333(A,=,B,C); } DECL dMULTIPLYADD0_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_331(A,+=,B,C); } DECL dMULTIPLYADD1_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_331(A,+=,B,C); } DECL dMULTIPLYADD0_133(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_133(A,+=,B,C); } DECL dMULTIPLYADD0_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_333(A,+=,B,C); } DECL dMULTIPLYADD1_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_333(A,+=,B,C); } DECL dMULTIPLYADD2_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP2_333(A,+=,B,C); } #undef DECL #else #define dMULTIPLY0_331(A,B,C) dMULTIPLYOP0_331(A,=,B,C) #define dMULTIPLY1_331(A,B,C) dMULTIPLYOP1_331(A,=,B,C) #define dMULTIPLY0_133(A,B,C) dMULTIPLYOP0_133(A,=,B,C) #define dMULTIPLY0_333(A,B,C) dMULTIPLYOP0_333(A,=,B,C) #define dMULTIPLY1_333(A,B,C) dMULTIPLYOP1_333(A,=,B,C) #define dMULTIPLY2_333(A,B,C) dMULTIPLYOP2_333(A,=,B,C) #define dMULTIPLYADD0_331(A,B,C) dMULTIPLYOP0_331(A,+=,B,C) #define dMULTIPLYADD1_331(A,B,C) dMULTIPLYOP1_331(A,+=,B,C) #define dMULTIPLYADD0_133(A,B,C) dMULTIPLYOP0_133(A,+=,B,C) #define dMULTIPLYADD0_333(A,B,C) dMULTIPLYOP0_333(A,+=,B,C) #define dMULTIPLYADD1_333(A,B,C) dMULTIPLYOP1_333(A,+=,B,C) #define dMULTIPLYADD2_333(A,B,C) dMULTIPLYOP2_333(A,+=,B,C) #endif #ifdef __cplusplus extern "C" { #endif /* * normalize 3x1 and 4x1 vectors (i.e. scale them to unit length) */ #if defined(__ODE__) int _dSafeNormalize3 (dVector3 a); int _dSafeNormalize4 (dVector4 a); static __inline void _dNormalize3(dVector3 a) { int bNormalizationResult = _dSafeNormalize3(a); dIASSERT(bNormalizationResult); dVARIABLEUSED(bNormalizationResult); } static __inline void _dNormalize4(dVector4 a) { int bNormalizationResult = _dSafeNormalize4(a); dIASSERT(bNormalizationResult); dVARIABLEUSED(bNormalizationResult); } #endif // defined(__ODE__) // For DLL export ODE_API int dSafeNormalize3 (dVector3 a); ODE_API int dSafeNormalize4 (dVector4 a); ODE_API void dNormalize3 (dVector3 a); // Potentially asserts on zero vec ODE_API void dNormalize4 (dVector4 a); // Potentially asserts on zero vec #if defined(__ODE__) // For internal use #define dSafeNormalize3(a) _dSafeNormalize3(a) #define dSafeNormalize4(a) _dSafeNormalize4(a) #define dNormalize3(a) _dNormalize3(a) #define dNormalize4(a) _dNormalize4(a) #endif // defined(__ODE__) /* * given a unit length "normal" vector n, generate vectors p and q vectors * that are an orthonormal basis for the plane space perpendicular to n. * i.e. this makes p,q such that n,p,q are all perpendicular to each other. * q will equal n x p. if n is not unit length then p will be unit length but * q wont be. */ ODE_API void dPlaneSpace (const dVector3 n, dVector3 p, dVector3 q); /* Makes sure the matrix is a proper rotation */ ODE_API void dOrthogonalizeR(dMatrix3 m); #ifdef __cplusplus } #endif #endif alien-arena-7.66+dfsg/source/unix/ode/matrix.h0000600000175000017500000001721512161402010020317 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* optimized and unoptimized vector and matrix functions */ #ifndef _ODE_MATRIX_H_ #define _ODE_MATRIX_H_ #include #ifdef __cplusplus extern "C" { #endif /* set a vector/matrix of size n to all zeros, or to a specific value. */ ODE_API void dSetZero (dReal *a, int n); ODE_API void dSetValue (dReal *a, int n, dReal value); /* get the dot product of two n*1 vectors. if n <= 0 then * zero will be returned (in which case a and b need not be valid). */ ODE_API dReal dDot (const dReal *a, const dReal *b, int n); /* get the dot products of (a0,b), (a1,b), etc and return them in outsum. * all vectors are n*1. if n <= 0 then zeroes will be returned (in which case * the input vectors need not be valid). this function is somewhat faster * than calling dDot() for all of the combinations separately. */ /* NOT INCLUDED in the library for now. void dMultidot2 (const dReal *a0, const dReal *a1, const dReal *b, dReal *outsum, int n); */ /* matrix multiplication. all matrices are stored in standard row format. * the digit refers to the argument that is transposed: * 0: A = B * C (sizes: A:p*r B:p*q C:q*r) * 1: A = B' * C (sizes: A:p*r B:q*p C:q*r) * 2: A = B * C' (sizes: A:p*r B:p*q C:r*q) * case 1,2 are equivalent to saying that the operation is A=B*C but * B or C are stored in standard column format. */ ODE_API void dMultiply0 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r); ODE_API void dMultiply1 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r); ODE_API void dMultiply2 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r); /* do an in-place cholesky decomposition on the lower triangle of the n*n * symmetric matrix A (which is stored by rows). the resulting lower triangle * will be such that L*L'=A. return 1 on success and 0 on failure (on failure * the matrix is not positive definite). */ ODE_API int dFactorCholesky (dReal *A, int n); /* solve for x: L*L'*x = b, and put the result back into x. * L is size n*n, b is size n*1. only the lower triangle of L is considered. */ ODE_API void dSolveCholesky (const dReal *L, dReal *b, int n); /* compute the inverse of the n*n positive definite matrix A and put it in * Ainv. this is not especially fast. this returns 1 on success (A was * positive definite) or 0 on failure (not PD). */ ODE_API int dInvertPDMatrix (const dReal *A, dReal *Ainv, int n); /* check whether an n*n matrix A is positive definite, return 1/0 (yes/no). * positive definite means that x'*A*x > 0 for any x. this performs a * cholesky decomposition of A. if the decomposition fails then the matrix * is not positive definite. A is stored by rows. A is not altered. */ ODE_API int dIsPositiveDefinite (const dReal *A, int n); /* factorize a matrix A into L*D*L', where L is lower triangular with ones on * the diagonal, and D is diagonal. * A is an n*n matrix stored by rows, with a leading dimension of n rounded * up to 4. L is written into the strict lower triangle of A (the ones are not * written) and the reciprocal of the diagonal elements of D are written into * d. */ ODE_API void dFactorLDLT (dReal *A, dReal *d, int n, int nskip); /* solve L*x=b, where L is n*n lower triangular with ones on the diagonal, * and x,b are n*1. b is overwritten with x. * the leading dimension of L is `nskip'. */ ODE_API void dSolveL1 (const dReal *L, dReal *b, int n, int nskip); /* solve L'*x=b, where L is n*n lower triangular with ones on the diagonal, * and x,b are n*1. b is overwritten with x. * the leading dimension of L is `nskip'. */ ODE_API void dSolveL1T (const dReal *L, dReal *b, int n, int nskip); /* in matlab syntax: a(1:n) = a(1:n) .* d(1:n) */ ODE_API void dVectorScale (dReal *a, const dReal *d, int n); /* given `L', a n*n lower triangular matrix with ones on the diagonal, * and `d', a n*1 vector of the reciprocal diagonal elements of an n*n matrix * D, solve L*D*L'*x=b where x,b are n*1. x overwrites b. * the leading dimension of L is `nskip'. */ ODE_API void dSolveLDLT (const dReal *L, const dReal *d, dReal *b, int n, int nskip); /* given an L*D*L' factorization of an n*n matrix A, return the updated * factorization L2*D2*L2' of A plus the following "top left" matrix: * * [ b a' ] <-- b is a[0] * [ a 0 ] <-- a is a[1..n-1] * * - L has size n*n, its leading dimension is nskip. L is lower triangular * with ones on the diagonal. only the lower triangle of L is referenced. * - d has size n. d contains the reciprocal diagonal elements of D. * - a has size n. * the result is written into L, except that the left column of L and d[0] * are not actually modified. see ldltaddTL.m for further comments. */ ODE_API void dLDLTAddTL (dReal *L, dReal *d, const dReal *a, int n, int nskip); /* given an L*D*L' factorization of a permuted matrix A, produce a new * factorization for row and column `r' removed. * - A has size n1*n1, its leading dimension in nskip. A is symmetric and * positive definite. only the lower triangle of A is referenced. * A itself may actually be an array of row pointers. * - L has size n2*n2, its leading dimension in nskip. L is lower triangular * with ones on the diagonal. only the lower triangle of L is referenced. * - d has size n2. d contains the reciprocal diagonal elements of D. * - p is a permutation vector. it contains n2 indexes into A. each index * must be in the range 0..n1-1. * - r is the row/column of L to remove. * the new L will be written within the old L, i.e. will have the same leading * dimension. the last row and column of L, and the last element of d, are * undefined on exit. * * a fast O(n^2) algorithm is used. see ldltremove.m for further comments. */ ODE_API void dLDLTRemove (dReal **A, const int *p, dReal *L, dReal *d, int n1, int n2, int r, int nskip); /* given an n*n matrix A (with leading dimension nskip), remove the r'th row * and column by moving elements. the new matrix will have the same leading * dimension. the last row and column of A are untouched on exit. */ ODE_API void dRemoveRowCol (dReal *A, int n, int nskip, int r); #ifdef __cplusplus } #endif #endif alien-arena-7.66+dfsg/source/unix/ode/collision.h0000600000175000017500000014005712161402010021007 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_COLLISION_H_ #define _ODE_COLLISION_H_ #include #include #include // Include odeinit.h for backward compatibility as some of initialization APIs // were initally declared in current header. #include #ifdef __cplusplus extern "C" { #endif /** * @defgroup collide Collision Detection * * ODE has two main components: a dynamics simulation engine and a collision * detection engine. The collision engine is given information about the * shape of each body. At each time step it figures out which bodies touch * each other and passes the resulting contact point information to the user. * The user in turn creates contact joints between bodies. * * Using ODE's collision detection is optional - an alternative collision * detection system can be used as long as it can supply the right kinds of * contact information. */ /* ************************************************************************ */ /* general functions */ /** * @brief Destroy a geom, removing it from any space. * * Destroy a geom, removing it from any space it is in first. This one * function destroys a geom of any type, but to create a geom you must call * a creation function for that type. * * When a space is destroyed, if its cleanup mode is 1 (the default) then all * the geoms in that space are automatically destroyed as well. * * @param geom the geom to be destroyed. * @ingroup collide */ ODE_API void dGeomDestroy (dGeomID geom); /** * @brief Set the user-defined data pointer stored in the geom. * * @param geom the geom to hold the data * @param data the data pointer to be stored * @ingroup collide */ ODE_API void dGeomSetData (dGeomID geom, void* data); /** * @brief Get the user-defined data pointer stored in the geom. * * @param geom the geom containing the data * @ingroup collide */ ODE_API void *dGeomGetData (dGeomID geom); /** * @brief Set the body associated with a placeable geom. * * Setting a body on a geom automatically combines the position vector and * rotation matrix of the body and geom, so that setting the position or * orientation of one will set the value for both objects. Setting a body * ID of zero gives the geom its own position and rotation, independent * from any body. If the geom was previously connected to a body then its * new independent position/rotation is set to the current position/rotation * of the body. * * Calling these functions on a non-placeable geom results in a runtime * error in the debug build of ODE. * * @param geom the geom to connect * @param body the body to attach to the geom * @ingroup collide */ ODE_API void dGeomSetBody (dGeomID geom, dBodyID body); /** * @brief Get the body associated with a placeable geom. * @param geom the geom to query. * @sa dGeomSetBody * @ingroup collide */ ODE_API dBodyID dGeomGetBody (dGeomID geom); /** * @brief Set the position vector of a placeable geom. * * If the geom is attached to a body, the body's position will also be changed. * Calling this function on a non-placeable geom results in a runtime error in * the debug build of ODE. * * @param geom the geom to set. * @param x the new X coordinate. * @param y the new Y coordinate. * @param z the new Z coordinate. * @sa dBodySetPosition * @ingroup collide */ ODE_API void dGeomSetPosition (dGeomID geom, dReal x, dReal y, dReal z); /** * @brief Set the rotation matrix of a placeable geom. * * If the geom is attached to a body, the body's rotation will also be changed. * Calling this function on a non-placeable geom results in a runtime error in * the debug build of ODE. * * @param geom the geom to set. * @param R the new rotation matrix. * @sa dBodySetRotation * @ingroup collide */ ODE_API void dGeomSetRotation (dGeomID geom, const dMatrix3 R); /** * @brief Set the rotation of a placeable geom. * * If the geom is attached to a body, the body's rotation will also be changed. * * Calling this function on a non-placeable geom results in a runtime error in * the debug build of ODE. * * @param geom the geom to set. * @param Q the new rotation. * @sa dBodySetQuaternion * @ingroup collide */ ODE_API void dGeomSetQuaternion (dGeomID geom, const dQuaternion Q); /** * @brief Get the position vector of a placeable geom. * * If the geom is attached to a body, the body's position will be returned. * * Calling this function on a non-placeable geom results in a runtime error in * the debug build of ODE. * * @param geom the geom to query. * @returns A pointer to the geom's position vector. * @remarks The returned value is a pointer to the geom's internal * data structure. It is valid until any changes are made * to the geom. * @sa dBodyGetPosition * @ingroup collide */ ODE_API const dReal * dGeomGetPosition (dGeomID geom); /** * @brief Copy the position of a geom into a vector. * @ingroup collide * @param geom the geom to query * @param pos a copy of the geom position * @sa dGeomGetPosition */ ODE_API void dGeomCopyPosition (dGeomID geom, dVector3 pos); /** * @brief Get the rotation matrix of a placeable geom. * * If the geom is attached to a body, the body's rotation will be returned. * * Calling this function on a non-placeable geom results in a runtime error in * the debug build of ODE. * * @param geom the geom to query. * @returns A pointer to the geom's rotation matrix. * @remarks The returned value is a pointer to the geom's internal * data structure. It is valid until any changes are made * to the geom. * @sa dBodyGetRotation * @ingroup collide */ ODE_API const dReal * dGeomGetRotation (dGeomID geom); /** * @brief Get the rotation matrix of a placeable geom. * * If the geom is attached to a body, the body's rotation will be returned. * * Calling this function on a non-placeable geom results in a runtime error in * the debug build of ODE. * * @param geom the geom to query. * @param R a copy of the geom rotation * @sa dGeomGetRotation * @ingroup collide */ ODE_API void dGeomCopyRotation(dGeomID geom, dMatrix3 R); /** * @brief Get the rotation quaternion of a placeable geom. * * If the geom is attached to a body, the body's quaternion will be returned. * * Calling this function on a non-placeable geom results in a runtime error in * the debug build of ODE. * * @param geom the geom to query. * @param result a copy of the rotation quaternion. * @sa dBodyGetQuaternion * @ingroup collide */ ODE_API void dGeomGetQuaternion (dGeomID geom, dQuaternion result); /** * @brief Return the axis-aligned bounding box. * * Return in aabb an axis aligned bounding box that surrounds the given geom. * The aabb array has elements (minx, maxx, miny, maxy, minz, maxz). If the * geom is a space, a bounding box that surrounds all contained geoms is * returned. * * This function may return a pre-computed cached bounding box, if it can * determine that the geom has not moved since the last time the bounding * box was computed. * * @param geom the geom to query * @param aabb the returned bounding box * @ingroup collide */ ODE_API void dGeomGetAABB (dGeomID geom, dReal aabb[6]); /** * @brief Determing if a geom is a space. * @param geom the geom to query * @returns Non-zero if the geom is a space, zero otherwise. * @ingroup collide */ ODE_API int dGeomIsSpace (dGeomID geom); /** * @brief Query for the space containing a particular geom. * @param geom the geom to query * @returns The space that contains the geom, or NULL if the geom is * not contained by a space. * @ingroup collide */ ODE_API dSpaceID dGeomGetSpace (dGeomID); /** * @brief Given a geom, this returns its class. * * The ODE classes are: * @li dSphereClass * @li dBoxClass * @li dCylinderClass * @li dPlaneClass * @li dRayClass * @li dConvexClass * @li dGeomTransformClass * @li dTriMeshClass * @li dSimpleSpaceClass * @li dHashSpaceClass * @li dQuadTreeSpaceClass * @li dFirstUserClass * @li dLastUserClass * * User-defined class will return their own number. * * @param geom the geom to query * @returns The geom class ID. * @ingroup collide */ ODE_API int dGeomGetClass (dGeomID geom); /** * @brief Set the "category" bitfield for the given geom. * * The category bitfield is used by spaces to govern which geoms will * interact with each other. The bitfield is guaranteed to be at least * 32 bits wide. The default category values for newly created geoms * have all bits set. * * @param geom the geom to set * @param bits the new bitfield value * @ingroup collide */ ODE_API void dGeomSetCategoryBits (dGeomID geom, unsigned long bits); /** * @brief Set the "collide" bitfield for the given geom. * * The collide bitfield is used by spaces to govern which geoms will * interact with each other. The bitfield is guaranteed to be at least * 32 bits wide. The default category values for newly created geoms * have all bits set. * * @param geom the geom to set * @param bits the new bitfield value * @ingroup collide */ ODE_API void dGeomSetCollideBits (dGeomID geom, unsigned long bits); /** * @brief Get the "category" bitfield for the given geom. * * @param geom the geom to set * @param bits the new bitfield value * @sa dGeomSetCategoryBits * @ingroup collide */ ODE_API unsigned long dGeomGetCategoryBits (dGeomID); /** * @brief Get the "collide" bitfield for the given geom. * * @param geom the geom to set * @param bits the new bitfield value * @sa dGeomSetCollideBits * @ingroup collide */ ODE_API unsigned long dGeomGetCollideBits (dGeomID); /** * @brief Enable a geom. * * Disabled geoms are completely ignored by dSpaceCollide and dSpaceCollide2, * although they can still be members of a space. New geoms are created in * the enabled state. * * @param geom the geom to enable * @sa dGeomDisable * @sa dGeomIsEnabled * @ingroup collide */ ODE_API void dGeomEnable (dGeomID geom); /** * @brief Disable a geom. * * Disabled geoms are completely ignored by dSpaceCollide and dSpaceCollide2, * although they can still be members of a space. New geoms are created in * the enabled state. * * @param geom the geom to disable * @sa dGeomDisable * @sa dGeomIsEnabled * @ingroup collide */ ODE_API void dGeomDisable (dGeomID geom); /** * @brief Check to see if a geom is enabled. * * Disabled geoms are completely ignored by dSpaceCollide and dSpaceCollide2, * although they can still be members of a space. New geoms are created in * the enabled state. * * @param geom the geom to query * @returns Non-zero if the geom is enabled, zero otherwise. * @sa dGeomDisable * @sa dGeomIsEnabled * @ingroup collide */ ODE_API int dGeomIsEnabled (dGeomID geom); /* ************************************************************************ */ /* geom offset from body */ /** * @brief Set the local offset position of a geom from its body. * * Sets the geom's positional offset in local coordinates. * After this call, the geom will be at a new position determined from the * body's position and the offset. * The geom must be attached to a body. * If the geom did not have an offset, it is automatically created. * * @param geom the geom to set. * @param x the new X coordinate. * @param y the new Y coordinate. * @param z the new Z coordinate. * @ingroup collide */ ODE_API void dGeomSetOffsetPosition (dGeomID geom, dReal x, dReal y, dReal z); /** * @brief Set the local offset rotation matrix of a geom from its body. * * Sets the geom's rotational offset in local coordinates. * After this call, the geom will be at a new position determined from the * body's position and the offset. * The geom must be attached to a body. * If the geom did not have an offset, it is automatically created. * * @param geom the geom to set. * @param R the new rotation matrix. * @ingroup collide */ ODE_API void dGeomSetOffsetRotation (dGeomID geom, const dMatrix3 R); /** * @brief Set the local offset rotation of a geom from its body. * * Sets the geom's rotational offset in local coordinates. * After this call, the geom will be at a new position determined from the * body's position and the offset. * The geom must be attached to a body. * If the geom did not have an offset, it is automatically created. * * @param geom the geom to set. * @param Q the new rotation. * @ingroup collide */ ODE_API void dGeomSetOffsetQuaternion (dGeomID geom, const dQuaternion Q); /** * @brief Set the offset position of a geom from its body. * * Sets the geom's positional offset to move it to the new world * coordinates. * After this call, the geom will be at the world position passed in, * and the offset will be the difference from the current body position. * The geom must be attached to a body. * If the geom did not have an offset, it is automatically created. * * @param geom the geom to set. * @param x the new X coordinate. * @param y the new Y coordinate. * @param z the new Z coordinate. * @ingroup collide */ ODE_API void dGeomSetOffsetWorldPosition (dGeomID geom, dReal x, dReal y, dReal z); /** * @brief Set the offset rotation of a geom from its body. * * Sets the geom's rotational offset to orient it to the new world * rotation matrix. * After this call, the geom will be at the world orientation passed in, * and the offset will be the difference from the current body orientation. * The geom must be attached to a body. * If the geom did not have an offset, it is automatically created. * * @param geom the geom to set. * @param R the new rotation matrix. * @ingroup collide */ ODE_API void dGeomSetOffsetWorldRotation (dGeomID geom, const dMatrix3 R); /** * @brief Set the offset rotation of a geom from its body. * * Sets the geom's rotational offset to orient it to the new world * rotation matrix. * After this call, the geom will be at the world orientation passed in, * and the offset will be the difference from the current body orientation. * The geom must be attached to a body. * If the geom did not have an offset, it is automatically created. * * @param geom the geom to set. * @param Q the new rotation. * @ingroup collide */ ODE_API void dGeomSetOffsetWorldQuaternion (dGeomID geom, const dQuaternion); /** * @brief Clear any offset from the geom. * * If the geom has an offset, it is eliminated and the geom is * repositioned at the body's position. If the geom has no offset, * this function does nothing. * This is more efficient than calling dGeomSetOffsetPosition(zero) * and dGeomSetOffsetRotation(identiy), because this function actually * eliminates the offset, rather than leaving it as the identity transform. * * @param geom the geom to have its offset destroyed. * @ingroup collide */ ODE_API void dGeomClearOffset(dGeomID geom); /** * @brief Check to see whether the geom has an offset. * * This function will return non-zero if the offset has been created. * Note that there is a difference between a geom with no offset, * and a geom with an offset that is the identity transform. * In the latter case, although the observed behaviour is identical, * there is a unnecessary computation involved because the geom will * be applying the transform whenever it needs to recalculate its world * position. * * @param geom the geom to query. * @returns Non-zero if the geom has an offset, zero otherwise. * @ingroup collide */ ODE_API int dGeomIsOffset(dGeomID geom); /** * @brief Get the offset position vector of a geom. * * Returns the positional offset of the geom in local coordinates. * If the geom has no offset, this function returns the zero vector. * * @param geom the geom to query. * @returns A pointer to the geom's offset vector. * @remarks The returned value is a pointer to the geom's internal * data structure. It is valid until any changes are made * to the geom. * @ingroup collide */ ODE_API const dReal * dGeomGetOffsetPosition (dGeomID geom); /** * @brief Copy the offset position vector of a geom. * * Returns the positional offset of the geom in local coordinates. * If the geom has no offset, this function returns the zero vector. * * @param geom the geom to query. * @param pos returns the offset position * @ingroup collide */ ODE_API void dGeomCopyOffsetPosition (dGeomID geom, dVector3 pos); /** * @brief Get the offset rotation matrix of a geom. * * Returns the rotational offset of the geom in local coordinates. * If the geom has no offset, this function returns the identity * matrix. * * @param geom the geom to query. * @returns A pointer to the geom's offset rotation matrix. * @remarks The returned value is a pointer to the geom's internal * data structure. It is valid until any changes are made * to the geom. * @ingroup collide */ ODE_API const dReal * dGeomGetOffsetRotation (dGeomID geom); /** * @brief Copy the offset rotation matrix of a geom. * * Returns the rotational offset of the geom in local coordinates. * If the geom has no offset, this function returns the identity * matrix. * * @param geom the geom to query. * @param R returns the rotation matrix. * @ingroup collide */ ODE_API void dGeomCopyOffsetRotation (dGeomID geom, dMatrix3 R); /** * @brief Get the offset rotation quaternion of a geom. * * Returns the rotation offset of the geom as a quaternion. * If the geom has no offset, the identity quaternion is returned. * * @param geom the geom to query. * @param result a copy of the rotation quaternion. * @ingroup collide */ ODE_API void dGeomGetOffsetQuaternion (dGeomID geom, dQuaternion result); /* ************************************************************************ */ /* collision detection */ /* * Just generate any contacts (disables any contact refining). */ #define CONTACTS_UNIMPORTANT 0x80000000 /** * * @brief Given two geoms o1 and o2 that potentially intersect, * generate contact information for them. * * Internally, this just calls the correct class-specific collision * functions for o1 and o2. * * @param o1 The first geom to test. * @param o2 The second geom to test. * * @param flags The flags specify how contacts should be generated if * the geoms touch. The lower 16 bits of flags is an integer that * specifies the maximum number of contact points to generate. You must * ask for at least one contact. * Additionally, following bits may be set: * CONTACTS_UNIMPORTANT -- just generate any contacts (skip contact refining). * All other bits in flags must be set to zero. In the future the other bits * may be used to select from different contact generation strategies. * * @param contact Points to an array of dContactGeom structures. The array * must be able to hold at least the maximum number of contacts. These * dContactGeom structures may be embedded within larger structures in the * array -- the skip parameter is the byte offset from one dContactGeom to * the next in the array. If skip is sizeof(dContactGeom) then contact * points to a normal (C-style) array. It is an error for skip to be smaller * than sizeof(dContactGeom). * * @returns If the geoms intersect, this function returns the number of contact * points generated (and updates the contact array), otherwise it returns 0 * (and the contact array is not touched). * * @remarks If a space is passed as o1 or o2 then this function will collide * all objects contained in o1 with all objects contained in o2, and return * the resulting contact points. This method for colliding spaces with geoms * (or spaces with spaces) provides no user control over the individual * collisions. To get that control, use dSpaceCollide or dSpaceCollide2 instead. * * @remarks If o1 and o2 are the same geom then this function will do nothing * and return 0. Technically speaking an object intersects with itself, but it * is not useful to find contact points in this case. * * @remarks This function does not care if o1 and o2 are in the same space or not * (or indeed if they are in any space at all). * * @ingroup collide */ ODE_API int dCollide (dGeomID o1, dGeomID o2, int flags, dContactGeom *contact, int skip); /** * @brief Determines which pairs of geoms in a space may potentially intersect, * and calls the callback function for each candidate pair. * * @param space The space to test. * * @param data Passed from dSpaceCollide directly to the callback * function. Its meaning is user defined. The o1 and o2 arguments are the * geoms that may be near each other. * * @param callback A callback function is of type @ref dNearCallback. * * @remarks Other spaces that are contained within the colliding space are * not treated specially, i.e. they are not recursed into. The callback * function may be passed these contained spaces as one or both geom * arguments. * * @remarks dSpaceCollide() is guaranteed to pass all intersecting geom * pairs to the callback function, but may also pass close but * non-intersecting pairs. The number of these calls depends on the * internal algorithms used by the space. Thus you should not expect * that dCollide will return contacts for every pair passed to the * callback. * * @sa dSpaceCollide2 * @ingroup collide */ ODE_API void dSpaceCollide (dSpaceID space, void *data, dNearCallback *callback); /** * @brief Determines which geoms from one space may potentially intersect with * geoms from another space, and calls the callback function for each candidate * pair. * * @param space1 The first space to test. * * @param space2 The second space to test. * * @param data Passed from dSpaceCollide directly to the callback * function. Its meaning is user defined. The o1 and o2 arguments are the * geoms that may be near each other. * * @param callback A callback function is of type @ref dNearCallback. * * @remarks This function can also test a single non-space geom against a * space. This function is useful when there is a collision hierarchy, i.e. * when there are spaces that contain other spaces. * * @remarks Other spaces that are contained within the colliding space are * not treated specially, i.e. they are not recursed into. The callback * function may be passed these contained spaces as one or both geom * arguments. * * @remarks Sublevel value of space affects how the spaces are iterated. * Both spaces are recursed only if their sublevels match. Otherwise, only * the space with greater sublevel is recursed and the one with lesser sublevel * is used as a geom itself. * * @remarks dSpaceCollide2() is guaranteed to pass all intersecting geom * pairs to the callback function, but may also pass close but * non-intersecting pairs. The number of these calls depends on the * internal algorithms used by the space. Thus you should not expect * that dCollide will return contacts for every pair passed to the * callback. * * @sa dSpaceCollide * @sa dSpaceSetSublevel * @ingroup collide */ ODE_API void dSpaceCollide2 (dGeomID space1, dGeomID space2, void *data, dNearCallback *callback); /* ************************************************************************ */ /* standard classes */ /* the maximum number of user classes that are supported */ enum { dMaxUserClasses = 4 }; /* class numbers - each geometry object needs a unique number */ enum { dSphereClass = 0, dBoxClass, dCapsuleClass, dCylinderClass, dPlaneClass, dRayClass, dConvexClass, dGeomTransformClass, dTriMeshClass, dHeightfieldClass, dFirstSpaceClass, dSimpleSpaceClass = dFirstSpaceClass, dHashSpaceClass, dSweepAndPruneSpaceClass, // SAP dQuadTreeSpaceClass, dLastSpaceClass = dQuadTreeSpaceClass, dFirstUserClass, dLastUserClass = dFirstUserClass + dMaxUserClasses - 1, dGeomNumClasses }; /** * @defgroup collide_sphere Sphere Class * @ingroup collide */ /** * @brief Create a sphere geom of the given radius, and return its ID. * * @param space a space to contain the new geom. May be null. * @param radius the radius of the sphere. * * @returns A new sphere geom. * * @remarks The point of reference for a sphere is its center. * * @sa dGeomDestroy * @sa dGeomSphereSetRadius * @ingroup collide_sphere */ ODE_API dGeomID dCreateSphere (dSpaceID space, dReal radius); /** * @brief Set the radius of a sphere geom. * * @param sphere the sphere to set. * @param radius the new radius. * * @sa dGeomSphereGetRadius * @ingroup collide_sphere */ ODE_API void dGeomSphereSetRadius (dGeomID sphere, dReal radius); /** * @brief Retrieves the radius of a sphere geom. * * @param sphere the sphere to query. * * @sa dGeomSphereSetRadius * @ingroup collide_sphere */ ODE_API dReal dGeomSphereGetRadius (dGeomID sphere); /** * @brief Calculate the depth of the a given point within a sphere. * * @param sphere the sphere to query. * @param x the X coordinate of the point. * @param y the Y coordinate of the point. * @param z the Z coordinate of the point. * * @returns The depth of the point. Points inside the sphere will have a * positive depth, points outside it will have a negative depth, and points * on the surface will have a depth of zero. * * @ingroup collide_sphere */ ODE_API dReal dGeomSpherePointDepth (dGeomID sphere, dReal x, dReal y, dReal z); //--> Convex Functions ODE_API dGeomID dCreateConvex (dSpaceID space, dReal *_planes, unsigned int _planecount, dReal *_points, unsigned int _pointcount,unsigned int *_polygons); ODE_API void dGeomSetConvex (dGeomID g, dReal *_planes, unsigned int _count, dReal *_points, unsigned int _pointcount,unsigned int *_polygons); //<-- Convex Functions /** * @defgroup collide_box Box Class * @ingroup collide */ /** * @brief Create a box geom with the provided side lengths. * * @param space a space to contain the new geom. May be null. * @param lx the length of the box along the X axis * @param ly the length of the box along the Y axis * @param lz the length of the box along the Z axis * * @returns A new box geom. * * @remarks The point of reference for a box is its center. * * @sa dGeomDestroy * @sa dGeomBoxSetLengths * @ingroup collide_box */ ODE_API dGeomID dCreateBox (dSpaceID space, dReal lx, dReal ly, dReal lz); /** * @brief Set the side lengths of the given box. * * @param box the box to set * @param lx the length of the box along the X axis * @param ly the length of the box along the Y axis * @param lz the length of the box along the Z axis * * @sa dGeomBoxGetLengths * @ingroup collide_box */ ODE_API void dGeomBoxSetLengths (dGeomID box, dReal lx, dReal ly, dReal lz); /** * @brief Get the side lengths of a box. * * @param box the box to query * @param result the returned side lengths * * @sa dGeomBoxSetLengths * @ingroup collide_box */ ODE_API void dGeomBoxGetLengths (dGeomID box, dVector3 result); /** * @brief Return the depth of a point in a box. * * @param box the box to query * @param x the X coordinate of the point to test. * @param y the Y coordinate of the point to test. * @param z the Z coordinate of the point to test. * * @returns The depth of the point. Points inside the box will have a * positive depth, points outside it will have a negative depth, and points * on the surface will have a depth of zero. */ ODE_API dReal dGeomBoxPointDepth (dGeomID box, dReal x, dReal y, dReal z); ODE_API dGeomID dCreatePlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d); ODE_API void dGeomPlaneSetParams (dGeomID plane, dReal a, dReal b, dReal c, dReal d); ODE_API void dGeomPlaneGetParams (dGeomID plane, dVector4 result); ODE_API dReal dGeomPlanePointDepth (dGeomID plane, dReal x, dReal y, dReal z); ODE_API dGeomID dCreateCapsule (dSpaceID space, dReal radius, dReal length); ODE_API void dGeomCapsuleSetParams (dGeomID ccylinder, dReal radius, dReal length); ODE_API void dGeomCapsuleGetParams (dGeomID ccylinder, dReal *radius, dReal *length); ODE_API dReal dGeomCapsulePointDepth (dGeomID ccylinder, dReal x, dReal y, dReal z); // For now we want to have a backwards compatible C-API, note: C++ API is not. #define dCreateCCylinder dCreateCapsule #define dGeomCCylinderSetParams dGeomCapsuleSetParams #define dGeomCCylinderGetParams dGeomCapsuleGetParams #define dGeomCCylinderPointDepth dGeomCapsulePointDepth #define dCCylinderClass dCapsuleClass ODE_API dGeomID dCreateCylinder (dSpaceID space, dReal radius, dReal length); ODE_API void dGeomCylinderSetParams (dGeomID cylinder, dReal radius, dReal length); ODE_API void dGeomCylinderGetParams (dGeomID cylinder, dReal *radius, dReal *length); ODE_API dGeomID dCreateRay (dSpaceID space, dReal length); ODE_API void dGeomRaySetLength (dGeomID ray, dReal length); ODE_API dReal dGeomRayGetLength (dGeomID ray); ODE_API void dGeomRaySet (dGeomID ray, dReal px, dReal py, dReal pz, dReal dx, dReal dy, dReal dz); ODE_API void dGeomRayGet (dGeomID ray, dVector3 start, dVector3 dir); /* * Set/get ray flags that influence ray collision detection. * These flags are currently only noticed by the trimesh collider, because * they can make a major differences there. */ ODE_API void dGeomRaySetParams (dGeomID g, int FirstContact, int BackfaceCull); ODE_API void dGeomRayGetParams (dGeomID g, int *FirstContact, int *BackfaceCull); ODE_API void dGeomRaySetClosestHit (dGeomID g, int closestHit); ODE_API int dGeomRayGetClosestHit (dGeomID g); #include "collision_trimesh.h" ODE_API dGeomID dCreateGeomTransform (dSpaceID space); ODE_API void dGeomTransformSetGeom (dGeomID g, dGeomID obj); ODE_API dGeomID dGeomTransformGetGeom (dGeomID g); ODE_API void dGeomTransformSetCleanup (dGeomID g, int mode); ODE_API int dGeomTransformGetCleanup (dGeomID g); ODE_API void dGeomTransformSetInfo (dGeomID g, int mode); ODE_API int dGeomTransformGetInfo (dGeomID g); /* ************************************************************************ */ /* heightfield functions */ // Data storage for heightfield data. struct dxHeightfieldData; typedef struct dxHeightfieldData* dHeightfieldDataID; /** * @brief Callback prototype * * Used by the callback heightfield data type to sample a height for a * given cell position. * * @param p_user_data User data specified when creating the dHeightfieldDataID * @param x The index of a sample in the local x axis. It is a value * in the range zero to ( nWidthSamples - 1 ). * @param x The index of a sample in the local z axis. It is a value * in the range zero to ( nDepthSamples - 1 ). * * @return The sample height which is then scaled and offset using the * values specified when the heightfield data was created. * * @ingroup collide */ typedef dReal dHeightfieldGetHeight( void* p_user_data, int x, int z ); /** * @brief Creates a heightfield geom. * * Uses the information in the given dHeightfieldDataID to construct * a geom representing a heightfield in a collision space. * * @param space The space to add the geom to. * @param data The dHeightfieldDataID created by dGeomHeightfieldDataCreate and * setup by dGeomHeightfieldDataBuildCallback, dGeomHeightfieldDataBuildByte, * dGeomHeightfieldDataBuildShort or dGeomHeightfieldDataBuildFloat. * @param bPlaceable If non-zero this geom can be transformed in the world using the * usual functions such as dGeomSetPosition and dGeomSetRotation. If the geom is * not set as placeable, then it uses a fixed orientation where the global y axis * represents the dynamic 'height' of the heightfield. * * @return A geom id to reference this geom in other calls. * * @ingroup collide */ ODE_API dGeomID dCreateHeightfield( dSpaceID space, dHeightfieldDataID data, int bPlaceable ); /** * @brief Creates a new empty dHeightfieldDataID. * * Allocates a new dHeightfieldDataID and returns it. You must call * dGeomHeightfieldDataDestroy to destroy it after the geom has been removed. * The dHeightfieldDataID value is used when specifying a data format type. * * @return A dHeightfieldDataID for use with dGeomHeightfieldDataBuildCallback, * dGeomHeightfieldDataBuildByte, dGeomHeightfieldDataBuildShort or * dGeomHeightfieldDataBuildFloat. * @ingroup collide */ ODE_API dHeightfieldDataID dGeomHeightfieldDataCreate(void); /** * @brief Destroys a dHeightfieldDataID. * * Deallocates a given dHeightfieldDataID and all managed resources. * * @param d A dHeightfieldDataID created by dGeomHeightfieldDataCreate * @ingroup collide */ ODE_API void dGeomHeightfieldDataDestroy( dHeightfieldDataID d ); /** * @brief Configures a dHeightfieldDataID to use a callback to * retrieve height data. * * Before a dHeightfieldDataID can be used by a geom it must be * configured to specify the format of the height data. * This call specifies that the heightfield data is computed by * the user and it should use the given callback when determining * the height of a given element of it's shape. * * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate * * @param width Specifies the total 'width' of the heightfield along * the geom's local x axis. * @param depth Specifies the total 'depth' of the heightfield along * the geom's local z axis. * * @param widthSamples Specifies the number of vertices to sample * along the width of the heightfield. Each vertex has a corresponding * height value which forms the overall shape. * Naturally this value must be at least two or more. * @param depthSamples Specifies the number of vertices to sample * along the depth of the heightfield. * * @param scale A uniform scale applied to all raw height data. * @param offset An offset applied to the scaled height data. * * @param thickness A value subtracted from the lowest height * value which in effect adds an additional cuboid to the base of the * heightfield. This is used to prevent geoms from looping under the * desired terrain and not registering as a collision. Note that the * thickness is not affected by the scale or offset parameters. * * @param bWrap If non-zero the heightfield will infinitely tile in both * directions along the local x and z axes. If zero the heightfield is * bounded from zero to width in the local x axis, and zero to depth in * the local z axis. * * @ingroup collide */ ODE_API void dGeomHeightfieldDataBuildCallback( dHeightfieldDataID d, void* pUserData, dHeightfieldGetHeight* pCallback, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap ); /** * @brief Configures a dHeightfieldDataID to use height data in byte format. * * Before a dHeightfieldDataID can be used by a geom it must be * configured to specify the format of the height data. * This call specifies that the heightfield data is stored as a rectangular * array of bytes (8 bit unsigned) representing the height at each sample point. * * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate * * @param pHeightData A pointer to the height data. * @param bCopyHeightData When non-zero the height data is copied to an * internal store. When zero the height data is accessed by reference and * so must persist throughout the lifetime of the heightfield. * * @param width Specifies the total 'width' of the heightfield along * the geom's local x axis. * @param depth Specifies the total 'depth' of the heightfield along * the geom's local z axis. * * @param widthSamples Specifies the number of vertices to sample * along the width of the heightfield. Each vertex has a corresponding * height value which forms the overall shape. * Naturally this value must be at least two or more. * @param depthSamples Specifies the number of vertices to sample * along the depth of the heightfield. * * @param scale A uniform scale applied to all raw height data. * @param offset An offset applied to the scaled height data. * * @param thickness A value subtracted from the lowest height * value which in effect adds an additional cuboid to the base of the * heightfield. This is used to prevent geoms from looping under the * desired terrain and not registering as a collision. Note that the * thickness is not affected by the scale or offset parameters. * * @param bWrap If non-zero the heightfield will infinitely tile in both * directions along the local x and z axes. If zero the heightfield is * bounded from zero to width in the local x axis, and zero to depth in * the local z axis. * * @ingroup collide */ ODE_API void dGeomHeightfieldDataBuildByte( dHeightfieldDataID d, const unsigned char* pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap ); /** * @brief Configures a dHeightfieldDataID to use height data in short format. * * Before a dHeightfieldDataID can be used by a geom it must be * configured to specify the format of the height data. * This call specifies that the heightfield data is stored as a rectangular * array of shorts (16 bit signed) representing the height at each sample point. * * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate * * @param pHeightData A pointer to the height data. * @param bCopyHeightData When non-zero the height data is copied to an * internal store. When zero the height data is accessed by reference and * so must persist throughout the lifetime of the heightfield. * * @param width Specifies the total 'width' of the heightfield along * the geom's local x axis. * @param depth Specifies the total 'depth' of the heightfield along * the geom's local z axis. * * @param widthSamples Specifies the number of vertices to sample * along the width of the heightfield. Each vertex has a corresponding * height value which forms the overall shape. * Naturally this value must be at least two or more. * @param depthSamples Specifies the number of vertices to sample * along the depth of the heightfield. * * @param scale A uniform scale applied to all raw height data. * @param offset An offset applied to the scaled height data. * * @param thickness A value subtracted from the lowest height * value which in effect adds an additional cuboid to the base of the * heightfield. This is used to prevent geoms from looping under the * desired terrain and not registering as a collision. Note that the * thickness is not affected by the scale or offset parameters. * * @param bWrap If non-zero the heightfield will infinitely tile in both * directions along the local x and z axes. If zero the heightfield is * bounded from zero to width in the local x axis, and zero to depth in * the local z axis. * * @ingroup collide */ ODE_API void dGeomHeightfieldDataBuildShort( dHeightfieldDataID d, const short* pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap ); /** * @brief Configures a dHeightfieldDataID to use height data in * single precision floating point format. * * Before a dHeightfieldDataID can be used by a geom it must be * configured to specify the format of the height data. * This call specifies that the heightfield data is stored as a rectangular * array of single precision floats representing the height at each * sample point. * * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate * * @param pHeightData A pointer to the height data. * @param bCopyHeightData When non-zero the height data is copied to an * internal store. When zero the height data is accessed by reference and * so must persist throughout the lifetime of the heightfield. * * @param width Specifies the total 'width' of the heightfield along * the geom's local x axis. * @param depth Specifies the total 'depth' of the heightfield along * the geom's local z axis. * * @param widthSamples Specifies the number of vertices to sample * along the width of the heightfield. Each vertex has a corresponding * height value which forms the overall shape. * Naturally this value must be at least two or more. * @param depthSamples Specifies the number of vertices to sample * along the depth of the heightfield. * * @param scale A uniform scale applied to all raw height data. * @param offset An offset applied to the scaled height data. * * @param thickness A value subtracted from the lowest height * value which in effect adds an additional cuboid to the base of the * heightfield. This is used to prevent geoms from looping under the * desired terrain and not registering as a collision. Note that the * thickness is not affected by the scale or offset parameters. * * @param bWrap If non-zero the heightfield will infinitely tile in both * directions along the local x and z axes. If zero the heightfield is * bounded from zero to width in the local x axis, and zero to depth in * the local z axis. * * @ingroup collide */ ODE_API void dGeomHeightfieldDataBuildSingle( dHeightfieldDataID d, const float* pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap ); /** * @brief Configures a dHeightfieldDataID to use height data in * double precision floating point format. * * Before a dHeightfieldDataID can be used by a geom it must be * configured to specify the format of the height data. * This call specifies that the heightfield data is stored as a rectangular * array of double precision floats representing the height at each * sample point. * * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate * * @param pHeightData A pointer to the height data. * @param bCopyHeightData When non-zero the height data is copied to an * internal store. When zero the height data is accessed by reference and * so must persist throughout the lifetime of the heightfield. * * @param width Specifies the total 'width' of the heightfield along * the geom's local x axis. * @param depth Specifies the total 'depth' of the heightfield along * the geom's local z axis. * * @param widthSamples Specifies the number of vertices to sample * along the width of the heightfield. Each vertex has a corresponding * height value which forms the overall shape. * Naturally this value must be at least two or more. * @param depthSamples Specifies the number of vertices to sample * along the depth of the heightfield. * * @param scale A uniform scale applied to all raw height data. * @param offset An offset applied to the scaled height data. * * @param thickness A value subtracted from the lowest height * value which in effect adds an additional cuboid to the base of the * heightfield. This is used to prevent geoms from looping under the * desired terrain and not registering as a collision. Note that the * thickness is not affected by the scale or offset parameters. * * @param bWrap If non-zero the heightfield will infinitely tile in both * directions along the local x and z axes. If zero the heightfield is * bounded from zero to width in the local x axis, and zero to depth in * the local z axis. * * @ingroup collide */ ODE_API void dGeomHeightfieldDataBuildDouble( dHeightfieldDataID d, const double* pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap ); /** * @brief Manually set the minimum and maximum height bounds. * * This call allows you to set explicit min / max values after initial * creation typically for callback heightfields which default to +/- infinity, * or those whose data has changed. This must be set prior to binding with a * geom, as the the AABB is not recomputed after it's first generation. * * @remarks The minimum and maximum values are used to compute the AABB * for the heightfield which is used for early rejection of collisions. * A close fit will yield a more efficient collision check. * * @param d A dHeightfieldDataID created by dGeomHeightfieldDataCreate * @param min_height The new minimum height value. Scale, offset and thickness is then applied. * @param max_height The new maximum height value. Scale and offset is then applied. * @ingroup collide */ ODE_API void dGeomHeightfieldDataSetBounds( dHeightfieldDataID d, dReal minHeight, dReal maxHeight ); /** * @brief Assigns a dHeightfieldDataID to a heightfield geom. * * Associates the given dHeightfieldDataID with a heightfield geom. * This is done without affecting the GEOM_PLACEABLE flag. * * @param g A geom created by dCreateHeightfield * @param d A dHeightfieldDataID created by dGeomHeightfieldDataCreate * @ingroup collide */ ODE_API void dGeomHeightfieldSetHeightfieldData( dGeomID g, dHeightfieldDataID d ); /** * @brief Gets the dHeightfieldDataID bound to a heightfield geom. * * Returns the dHeightfieldDataID associated with a heightfield geom. * * @param g A geom created by dCreateHeightfield * @return The dHeightfieldDataID which may be NULL if none was assigned. * @ingroup collide */ ODE_API dHeightfieldDataID dGeomHeightfieldGetHeightfieldData( dGeomID g ); /* ************************************************************************ */ /* utility functions */ ODE_API void dClosestLineSegmentPoints (const dVector3 a1, const dVector3 a2, const dVector3 b1, const dVector3 b2, dVector3 cp1, dVector3 cp2); ODE_API int dBoxTouchesBox (const dVector3 _p1, const dMatrix3 R1, const dVector3 side1, const dVector3 _p2, const dMatrix3 R2, const dVector3 side2); // The meaning of flags parameter is the same as in dCollide() ODE_API int dBoxBox (const dVector3 p1, const dMatrix3 R1, const dVector3 side1, const dVector3 p2, const dMatrix3 R2, const dVector3 side2, dVector3 normal, dReal *depth, int *return_code, int flags, dContactGeom *contact, int skip); ODE_API void dInfiniteAABB (dGeomID geom, dReal aabb[6]); /* ************************************************************************ */ /* custom classes */ typedef void dGetAABBFn (dGeomID, dReal aabb[6]); typedef int dColliderFn (dGeomID o1, dGeomID o2, int flags, dContactGeom *contact, int skip); typedef dColliderFn * dGetColliderFnFn (int num); typedef void dGeomDtorFn (dGeomID o); typedef int dAABBTestFn (dGeomID o1, dGeomID o2, dReal aabb[6]); typedef struct dGeomClass { int bytes; dGetColliderFnFn *collider; dGetAABBFn *aabb; dAABBTestFn *aabb_test; dGeomDtorFn *dtor; } dGeomClass; ODE_API int dCreateGeomClass (const dGeomClass *classptr); ODE_API void * dGeomGetClassData (dGeomID); ODE_API dGeomID dCreateGeom (int classnum); /** * @brief Sets a custom collider function for two geom classes. * * @param i The first geom class handled by this collider * @param j The second geom class handled by this collider * @param fn The collider function to use to determine collisions. * @ingroup collide */ ODE_API void dSetColliderOverride (int i, int j, dColliderFn *fn); /* ************************************************************************ */ #ifdef __cplusplus } #endif #endif alien-arena-7.66+dfsg/source/unix/ode/objects.h0000600000175000017500000025315112161402010020445 0ustar zero79zero79 /************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_OBJECTS_H_ #define _ODE_OBJECTS_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif /** * @defgroup world World * * The world object is a container for rigid bodies and joints. Objects in * different worlds can not interact, for example rigid bodies from two * different worlds can not collide. * * All the objects in a world exist at the same point in time, thus one * reason to use separate worlds is to simulate systems at different rates. * Most applications will only need one world. */ /** * @brief Create a new, empty world and return its ID number. * @return an identifier * @ingroup world */ ODE_API dWorldID dWorldCreate(void); /** * @brief Destroy a world and everything in it. * * This includes all bodies, and all joints that are not part of a joint * group. Joints that are part of a joint group will be deactivated, and * can be destroyed by calling, for example, dJointGroupEmpty(). * @ingroup world * @param world the identifier for the world the be destroyed. */ ODE_API void dWorldDestroy (dWorldID world); /** * @brief Set the world's global gravity vector. * * The units are m/s^2, so Earth's gravity vector would be (0,0,-9.81), * assuming that +z is up. The default is no gravity, i.e. (0,0,0). * * @ingroup world */ ODE_API void dWorldSetGravity (dWorldID, dReal x, dReal y, dReal z); /** * @brief Get the gravity vector for a given world. * @ingroup world */ ODE_API void dWorldGetGravity (dWorldID, dVector3 gravity); /** * @brief Set the global ERP value, that controls how much error * correction is performed in each time step. * @ingroup world * @param dWorldID the identifier of the world. * @param erp Typical values are in the range 0.1--0.8. The default is 0.2. */ ODE_API void dWorldSetERP (dWorldID, dReal erp); /** * @brief Get the error reduction parameter. * @ingroup world * @return ERP value */ ODE_API dReal dWorldGetERP (dWorldID); /** * @brief Set the global CFM (constraint force mixing) value. * @ingroup world * @param cfm Typical values are in the range @m{10^{-9}} -- 1. * The default is 10^-5 if single precision is being used, or 10^-10 * if double precision is being used. */ ODE_API void dWorldSetCFM (dWorldID, dReal cfm); /** * @brief Get the constraint force mixing value. * @ingroup world * @return CFM value */ ODE_API dReal dWorldGetCFM (dWorldID); /** * @brief Step the world. * * This uses a "big matrix" method that takes time on the order of m^3 * and memory on the order of m^2, where m is the total number of constraint * rows. For large systems this will use a lot of memory and can be very slow, * but this is currently the most accurate method. * @ingroup world * @param stepsize The number of seconds that the simulation has to advance. */ ODE_API void dWorldStep (dWorldID, dReal stepsize); /** * @brief Converts an impulse to a force. * @ingroup world * @remarks * If you want to apply a linear or angular impulse to a rigid body, * instead of a force or a torque, then you can use this function to convert * the desired impulse into a force/torque vector before calling the * BodyAdd... function. * The current algorithm simply scales the impulse by 1/stepsize, * where stepsize is the step size for the next step that will be taken. * This function is given a dWorldID because, in the future, the force * computation may depend on integrator parameters that are set as * properties of the world. */ ODE_API void dWorldImpulseToForce ( dWorldID, dReal stepsize, dReal ix, dReal iy, dReal iz, dVector3 force ); /** * @brief Step the world. * @ingroup world * @remarks * This uses an iterative method that takes time on the order of m*N * and memory on the order of m, where m is the total number of constraint * rows N is the number of iterations. * For large systems this is a lot faster than dWorldStep(), * but it is less accurate. * @remarks * QuickStep is great for stacks of objects especially when the * auto-disable feature is used as well. * However, it has poor accuracy for near-singular systems. * Near-singular systems can occur when using high-friction contacts, motors, * or certain articulated structures. For example, a robot with multiple legs * sitting on the ground may be near-singular. * @remarks * There are ways to help overcome QuickStep's inaccuracy problems: * \li Increase CFM. * \li Reduce the number of contacts in your system (e.g. use the minimum * number of contacts for the feet of a robot or creature). * \li Don't use excessive friction in the contacts. * \li Use contact slip if appropriate * \li Avoid kinematic loops (however, kinematic loops are inevitable in * legged creatures). * \li Don't use excessive motor strength. * \liUse force-based motors instead of velocity-based motors. * * Increasing the number of QuickStep iterations may help a little bit, but * it is not going to help much if your system is really near singular. */ ODE_API void dWorldQuickStep (dWorldID w, dReal stepsize); /** * @brief Set the number of iterations that the QuickStep method performs per * step. * @ingroup world * @remarks * More iterations will give a more accurate solution, but will take * longer to compute. * @param num The default is 20 iterations. */ ODE_API void dWorldSetQuickStepNumIterations (dWorldID, int num); /** * @brief Get the number of iterations that the QuickStep method performs per * step. * @ingroup world * @return nr of iterations */ ODE_API int dWorldGetQuickStepNumIterations (dWorldID); /** * @brief Set the SOR over-relaxation parameter * @ingroup world * @param over_relaxation value to use by SOR */ ODE_API void dWorldSetQuickStepW (dWorldID, dReal over_relaxation); /** * @brief Get the SOR over-relaxation parameter * @ingroup world * @returns the over-relaxation setting */ ODE_API dReal dWorldGetQuickStepW (dWorldID); /* World contact parameter functions */ /** * @brief Set the maximum correcting velocity that contacts are allowed * to generate. * @ingroup world * @param vel The default value is infinity (i.e. no limit). * @remarks * Reducing this value can help prevent "popping" of deeply embedded objects. */ ODE_API void dWorldSetContactMaxCorrectingVel (dWorldID, dReal vel); /** * @brief Get the maximum correcting velocity that contacts are allowed * to generated. * @ingroup world */ ODE_API dReal dWorldGetContactMaxCorrectingVel (dWorldID); /** * @brief Set the depth of the surface layer around all geometry objects. * @ingroup world * @remarks * Contacts are allowed to sink into the surface layer up to the given * depth before coming to rest. * @param depth The default value is zero. * @remarks * Increasing this to some small value (e.g. 0.001) can help prevent * jittering problems due to contacts being repeatedly made and broken. */ ODE_API void dWorldSetContactSurfaceLayer (dWorldID, dReal depth); /** * @brief Get the depth of the surface layer around all geometry objects. * @ingroup world * @returns the depth */ ODE_API dReal dWorldGetContactSurfaceLayer (dWorldID); /* StepFast1 functions */ /** * @brief Step the world using the StepFast1 algorithm. * @param stepsize the nr of seconds to advance the simulation. * @param maxiterations The number of iterations to perform. * @ingroup world */ ODE_API void dWorldStepFast1(dWorldID, dReal stepsize, int maxiterations); /** * @defgroup disable Automatic Enabling and Disabling * @ingroup world bodies * * Every body can be enabled or disabled. Enabled bodies participate in the * simulation, while disabled bodies are turned off and do not get updated * during a simulation step. New bodies are always created in the enabled state. * * A disabled body that is connected through a joint to an enabled body will be * automatically re-enabled at the next simulation step. * * Disabled bodies do not consume CPU time, therefore to speed up the simulation * bodies should be disabled when they come to rest. This can be done automatically * with the auto-disable feature. * * If a body has its auto-disable flag turned on, it will automatically disable * itself when * @li It has been idle for a given number of simulation steps. * @li It has also been idle for a given amount of simulation time. * * A body is considered to be idle when the magnitudes of both its * linear average velocity and angular average velocity are below given thresholds. * The sample size for the average defaults to one and can be disabled by setting * to zero with * * Thus, every body has six auto-disable parameters: an enabled flag, a idle step * count, an idle time, linear/angular average velocity thresholds, and the * average samples count. * * Newly created bodies get these parameters from world. */ /** * @brief Set the AutoEnableDepth parameter used by the StepFast1 algorithm. * @ingroup disable */ ODE_API void dWorldSetAutoEnableDepthSF1(dWorldID, int autoEnableDepth); /** * @brief Get the AutoEnableDepth parameter used by the StepFast1 algorithm. * @ingroup disable */ ODE_API int dWorldGetAutoEnableDepthSF1(dWorldID); /** * @brief Get auto disable linear threshold for newly created bodies. * @ingroup disable * @return the threshold */ ODE_API dReal dWorldGetAutoDisableLinearThreshold (dWorldID); /** * @brief Set auto disable linear threshold for newly created bodies. * @param linear_threshold default is 0.01 * @ingroup disable */ ODE_API void dWorldSetAutoDisableLinearThreshold (dWorldID, dReal linear_threshold); /** * @brief Get auto disable angular threshold for newly created bodies. * @ingroup disable * @return the threshold */ ODE_API dReal dWorldGetAutoDisableAngularThreshold (dWorldID); /** * @brief Set auto disable angular threshold for newly created bodies. * @param linear_threshold default is 0.01 * @ingroup disable */ ODE_API void dWorldSetAutoDisableAngularThreshold (dWorldID, dReal angular_threshold); /** * @brief Get auto disable linear average threshold for newly created bodies. * @ingroup disable * @return the threshold */ ODE_API dReal dWorldGetAutoDisableLinearAverageThreshold (dWorldID); /** * @brief Set auto disable linear average threshold for newly created bodies. * @param linear_average_threshold default is 0.01 * @ingroup disable */ ODE_API void dWorldSetAutoDisableLinearAverageThreshold (dWorldID, dReal linear_average_threshold); /** * @brief Get auto disable angular average threshold for newly created bodies. * @ingroup disable * @return the threshold */ ODE_API dReal dWorldGetAutoDisableAngularAverageThreshold (dWorldID); /** * @brief Set auto disable angular average threshold for newly created bodies. * @param linear_average_threshold default is 0.01 * @ingroup disable */ ODE_API void dWorldSetAutoDisableAngularAverageThreshold (dWorldID, dReal angular_average_threshold); /** * @brief Get auto disable sample count for newly created bodies. * @ingroup disable * @return number of samples used */ ODE_API int dWorldGetAutoDisableAverageSamplesCount (dWorldID); /** * @brief Set auto disable average sample count for newly created bodies. * @ingroup disable * @param average_samples_count Default is 1, meaning only instantaneous velocity is used. * Set to zero to disable sampling and thus prevent any body from auto-disabling. */ ODE_API void dWorldSetAutoDisableAverageSamplesCount (dWorldID, unsigned int average_samples_count ); /** * @brief Get auto disable steps for newly created bodies. * @ingroup disable * @return nr of steps */ ODE_API int dWorldGetAutoDisableSteps (dWorldID); /** * @brief Set auto disable steps for newly created bodies. * @ingroup disable * @param steps default is 10 */ ODE_API void dWorldSetAutoDisableSteps (dWorldID, int steps); /** * @brief Get auto disable time for newly created bodies. * @ingroup disable * @return nr of seconds */ ODE_API dReal dWorldGetAutoDisableTime (dWorldID); /** * @brief Set auto disable time for newly created bodies. * @ingroup disable * @param time default is 0 seconds */ ODE_API void dWorldSetAutoDisableTime (dWorldID, dReal time); /** * @brief Get auto disable flag for newly created bodies. * @ingroup disable * @return 0 or 1 */ ODE_API int dWorldGetAutoDisableFlag (dWorldID); /** * @brief Set auto disable flag for newly created bodies. * @ingroup disable * @param do_auto_disable default is false. */ ODE_API void dWorldSetAutoDisableFlag (dWorldID, int do_auto_disable); /** * @defgroup damping Damping * @ingroup bodies world * * Damping serves two purposes: reduce simulation instability, and to allow * the bodies to come to rest (and possibly auto-disabling them). * * Bodies are constructed using the world's current damping parameters. Setting * the scales to 0 disables the damping. * * Here is how it is done: after every time step linear and angular * velocities are tested against the corresponding thresholds. If they * are above, they are multiplied by (1 - scale). So a negative scale value * will actually increase the speed, and values greater than one will * make the object oscillate every step; both can make the simulation unstable. * * To disable damping just set the damping scale to zero. * * You can also limit the maximum angular velocity. In contrast to the damping * functions, the angular velocity is affected before the body is moved. * This means that it will introduce errors in joints that are forcing the body * to rotate too fast. Some bodies have naturally high angular velocities * (like cars' wheels), so you may want to give them a very high (like the default, * dInfinity) limit. * * @note The velocities are damped after the stepper function has moved the * object. Otherwise the damping could introduce errors in joints. First the * joint constraints are processed by the stepper (moving the body), then * the damping is applied. * * @note The damping happens right after the moved callback is called; this way * it still possible use the exact velocities the body has acquired during the * step. You can even use the callback to create your own customized damping. */ /** * @brief Get the world's linear damping threshold. * @ingroup damping */ ODE_API dReal dWorldGetLinearDampingThreshold (dWorldID w); /** * @brief Set the world's linear damping threshold. * @param threshold The damping won't be applied if the linear speed is * below this threshold. Default is 0.01. * @ingroup damping */ ODE_API void dWorldSetLinearDampingThreshold(dWorldID w, dReal threshold); /** * @brief Get the world's angular damping threshold. * @ingroup damping */ ODE_API dReal dWorldGetAngularDampingThreshold (dWorldID w); /** * @brief Set the world's angular damping threshold. * @param threshold The damping won't be applied if the angular speed is * below this threshold. Default is 0.01. * @ingroup damping */ ODE_API void dWorldSetAngularDampingThreshold(dWorldID w, dReal threshold); /** * @brief Get the world's linear damping scale. * @ingroup damping */ ODE_API dReal dWorldGetLinearDamping (dWorldID w); /** * @brief Set the world's linear damping scale. * @param scale The linear damping scale that is to be applied to bodies. * Default is 0 (no damping). Should be in the interval [0, 1]. * @ingroup damping */ ODE_API void dWorldSetLinearDamping (dWorldID w, dReal scale); /** * @brief Get the world's angular damping scale. * @ingroup damping */ ODE_API dReal dWorldGetAngularDamping (dWorldID w); /** * @brief Set the world's angular damping scale. * @param scale The angular damping scale that is to be applied to bodies. * Default is 0 (no damping). Should be in the interval [0, 1]. * @ingroup damping */ ODE_API void dWorldSetAngularDamping(dWorldID w, dReal scale); /** * @brief Convenience function to set body linear and angular scales. * @param linear_scale The linear damping scale that is to be applied to bodies. * @param angular_scale The angular damping scale that is to be applied to bodies. * @ingroup damping */ ODE_API void dWorldSetDamping(dWorldID w, dReal linear_scale, dReal angular_scale); /** * @brief Get the default maximum angular speed. * @ingroup damping * @sa dBodyGetMaxAngularSpeed() */ ODE_API dReal dWorldGetMaxAngularSpeed (dWorldID w); /** * @brief Set the default maximum angular speed for new bodies. * @ingroup damping * @sa dBodySetMaxAngularSpeed() */ ODE_API void dWorldSetMaxAngularSpeed (dWorldID w, dReal max_speed); /** * @defgroup bodies Rigid Bodies * * A rigid body has various properties from the point of view of the * simulation. Some properties change over time: * * @li Position vector (x,y,z) of the body's point of reference. * Currently the point of reference must correspond to the body's center of mass. * @li Linear velocity of the point of reference, a vector (vx,vy,vz). * @li Orientation of a body, represented by a quaternion (qs,qx,qy,qz) or * a 3x3 rotation matrix. * @li Angular velocity vector (wx,wy,wz) which describes how the orientation * changes over time. * * Other body properties are usually constant over time: * * @li Mass of the body. * @li Position of the center of mass with respect to the point of reference. * In the current implementation the center of mass and the point of * reference must coincide. * @li Inertia matrix. This is a 3x3 matrix that describes how the body's mass * is distributed around the center of mass. Conceptually each body has an * x-y-z coordinate frame embedded in it that moves and rotates with the body. * * The origin of this coordinate frame is the body's point of reference. Some values * in ODE (vectors, matrices etc) are relative to the body coordinate frame, and others * are relative to the global coordinate frame. * * Note that the shape of a rigid body is not a dynamical property (except insofar as * it influences the various mass properties). It is only collision detection that cares * about the detailed shape of the body. */ /** * @brief Get auto disable linear average threshold. * @ingroup bodies disable * @return the threshold */ ODE_API dReal dBodyGetAutoDisableLinearThreshold (dBodyID); /** * @brief Set auto disable linear average threshold. * @ingroup bodies disable * @return the threshold */ ODE_API void dBodySetAutoDisableLinearThreshold (dBodyID, dReal linear_average_threshold); /** * @brief Get auto disable angular average threshold. * @ingroup bodies disable * @return the threshold */ ODE_API dReal dBodyGetAutoDisableAngularThreshold (dBodyID); /** * @brief Set auto disable angular average threshold. * @ingroup bodies disable * @return the threshold */ ODE_API void dBodySetAutoDisableAngularThreshold (dBodyID, dReal angular_average_threshold); /** * @brief Get auto disable average size (samples count). * @ingroup bodies disable * @return the nr of steps/size. */ ODE_API int dBodyGetAutoDisableAverageSamplesCount (dBodyID); /** * @brief Set auto disable average buffer size (average steps). * @ingroup bodies disable * @param average_samples_count the nr of samples to review. */ ODE_API void dBodySetAutoDisableAverageSamplesCount (dBodyID, unsigned int average_samples_count); /** * @brief Get auto steps a body must be thought of as idle to disable * @ingroup bodies disable * @return the nr of steps */ ODE_API int dBodyGetAutoDisableSteps (dBodyID); /** * @brief Set auto disable steps. * @ingroup bodies disable * @param steps the nr of steps. */ ODE_API void dBodySetAutoDisableSteps (dBodyID, int steps); /** * @brief Get auto disable time. * @ingroup bodies disable * @return nr of seconds */ ODE_API dReal dBodyGetAutoDisableTime (dBodyID); /** * @brief Set auto disable time. * @ingroup bodies disable * @param time nr of seconds. */ ODE_API void dBodySetAutoDisableTime (dBodyID, dReal time); /** * @brief Get auto disable flag. * @ingroup bodies disable * @return 0 or 1 */ ODE_API int dBodyGetAutoDisableFlag (dBodyID); /** * @brief Set auto disable flag. * @ingroup bodies disable * @param do_auto_disable 0 or 1 */ ODE_API void dBodySetAutoDisableFlag (dBodyID, int do_auto_disable); /** * @brief Set auto disable defaults. * @remarks * Set the values for the body to those set as default for the world. * @ingroup bodies disable */ ODE_API void dBodySetAutoDisableDefaults (dBodyID); /** * @brief Retrieves the world attached to te given body. * @remarks * * @ingroup bodies */ ODE_API dWorldID dBodyGetWorld (dBodyID); /** * @brief Create a body in given world. * @remarks * Default mass parameters are at position (0,0,0). * @ingroup bodies */ ODE_API dBodyID dBodyCreate (dWorldID); /** * @brief Destroy a body. * @remarks * All joints that are attached to this body will be put into limbo: * i.e. unattached and not affecting the simulation, but they will NOT be * deleted. * @ingroup bodies */ ODE_API void dBodyDestroy (dBodyID); /** * @brief Set the body's user-data pointer. * @ingroup bodies * @param data arbitraty pointer */ ODE_API void dBodySetData (dBodyID, void *data); /** * @brief Get the body's user-data pointer. * @ingroup bodies * @return a pointer to the user's data. */ ODE_API void *dBodyGetData (dBodyID); /** * @brief Set position of a body. * @remarks * After setting, the outcome of the simulation is undefined * if the new configuration is inconsistent with the joints/constraints * that are present. * @ingroup bodies */ ODE_API void dBodySetPosition (dBodyID, dReal x, dReal y, dReal z); /** * @brief Set the orientation of a body. * @ingroup bodies * @remarks * After setting, the outcome of the simulation is undefined * if the new configuration is inconsistent with the joints/constraints * that are present. */ ODE_API void dBodySetRotation (dBodyID, const dMatrix3 R); /** * @brief Set the orientation of a body. * @ingroup bodies * @remarks * After setting, the outcome of the simulation is undefined * if the new configuration is inconsistent with the joints/constraints * that are present. */ ODE_API void dBodySetQuaternion (dBodyID, const dQuaternion q); /** * @brief Set the linear velocity of a body. * @ingroup bodies */ ODE_API void dBodySetLinearVel (dBodyID, dReal x, dReal y, dReal z); /** * @brief Set the angular velocity of a body. * @ingroup bodies */ ODE_API void dBodySetAngularVel (dBodyID, dReal x, dReal y, dReal z); /** * @brief Get the position of a body. * @ingroup bodies * @remarks * When getting, the returned values are pointers to internal data structures, * so the vectors are valid until any changes are made to the rigid body * system structure. * @sa dBodyCopyPosition */ ODE_API const dReal * dBodyGetPosition (dBodyID); /** * @brief Copy the position of a body into a vector. * @ingroup bodies * @param body the body to query * @param pos a copy of the body position * @sa dBodyGetPosition */ ODE_API void dBodyCopyPosition (dBodyID body, dVector3 pos); /** * @brief Get the rotation of a body. * @ingroup bodies * @return pointer to a 4x3 rotation matrix. */ ODE_API const dReal * dBodyGetRotation (dBodyID); /** * @brief Copy the rotation of a body. * @ingroup bodies * @param body the body to query * @param R a copy of the rotation matrix * @sa dBodyGetRotation */ ODE_API void dBodyCopyRotation (dBodyID, dMatrix3 R); /** * @brief Get the rotation of a body. * @ingroup bodies * @return pointer to 4 scalars that represent the quaternion. */ ODE_API const dReal * dBodyGetQuaternion (dBodyID); /** * @brief Copy the orientation of a body into a quaternion. * @ingroup bodies * @param body the body to query * @param quat a copy of the orientation quaternion * @sa dBodyGetQuaternion */ ODE_API void dBodyCopyQuaternion(dBodyID body, dQuaternion quat); /** * @brief Get the linear velocity of a body. * @ingroup bodies */ ODE_API const dReal * dBodyGetLinearVel (dBodyID); /** * @brief Get the angular velocity of a body. * @ingroup bodies */ ODE_API const dReal * dBodyGetAngularVel (dBodyID); /** * @brief Set the mass of a body. * @ingroup bodies */ ODE_API void dBodySetMass (dBodyID, const dMass *mass); /** * @brief Get the mass of a body. * @ingroup bodies */ ODE_API void dBodyGetMass (dBodyID, dMass *mass); /** * @brief Add force at centre of mass of body in absolute coordinates. * @ingroup bodies */ ODE_API void dBodyAddForce (dBodyID, dReal fx, dReal fy, dReal fz); /** * @brief Add torque at centre of mass of body in absolute coordinates. * @ingroup bodies */ ODE_API void dBodyAddTorque (dBodyID, dReal fx, dReal fy, dReal fz); /** * @brief Add force at centre of mass of body in coordinates relative to body. * @ingroup bodies */ ODE_API void dBodyAddRelForce (dBodyID, dReal fx, dReal fy, dReal fz); /** * @brief Add torque at centre of mass of body in coordinates relative to body. * @ingroup bodies */ ODE_API void dBodyAddRelTorque (dBodyID, dReal fx, dReal fy, dReal fz); /** * @brief Add force at specified point in body in global coordinates. * @ingroup bodies */ ODE_API void dBodyAddForceAtPos (dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); /** * @brief Add force at specified point in body in local coordinates. * @ingroup bodies */ ODE_API void dBodyAddForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); /** * @brief Add force at specified point in body in global coordinates. * @ingroup bodies */ ODE_API void dBodyAddRelForceAtPos (dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); /** * @brief Add force at specified point in body in local coordinates. * @ingroup bodies */ ODE_API void dBodyAddRelForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); /** * @brief Return the current accumulated force vector. * @return points to an array of 3 reals. * @remarks * The returned values are pointers to internal data structures, so * the vectors are only valid until any changes are made to the rigid * body system. * @ingroup bodies */ ODE_API const dReal * dBodyGetForce (dBodyID); /** * @brief Return the current accumulated torque vector. * @return points to an array of 3 reals. * @remarks * The returned values are pointers to internal data structures, so * the vectors are only valid until any changes are made to the rigid * body system. * @ingroup bodies */ ODE_API const dReal * dBodyGetTorque (dBodyID); /** * @brief Set the body force accumulation vector. * @remarks * This is mostly useful to zero the force and torque for deactivated bodies * before they are reactivated, in the case where the force-adding functions * were called on them while they were deactivated. * @ingroup bodies */ ODE_API void dBodySetForce (dBodyID b, dReal x, dReal y, dReal z); /** * @brief Set the body torque accumulation vector. * @remarks * This is mostly useful to zero the force and torque for deactivated bodies * before they are reactivated, in the case where the force-adding functions * were called on them while they were deactivated. * @ingroup bodies */ ODE_API void dBodySetTorque (dBodyID b, dReal x, dReal y, dReal z); /** * @brief Get world position of a relative point on body. * @ingroup bodies * @param result will contain the result. */ ODE_API void dBodyGetRelPointPos ( dBodyID, dReal px, dReal py, dReal pz, dVector3 result ); /** * @brief Get velocity vector in global coords of a relative point on body. * @ingroup bodies * @param result will contain the result. */ ODE_API void dBodyGetRelPointVel ( dBodyID, dReal px, dReal py, dReal pz, dVector3 result ); /** * @brief Get velocity vector in global coords of a globally * specified point on a body. * @ingroup bodies * @param result will contain the result. */ ODE_API void dBodyGetPointVel ( dBodyID, dReal px, dReal py, dReal pz, dVector3 result ); /** * @brief takes a point in global coordinates and returns * the point's position in body-relative coordinates. * @remarks * This is the inverse of dBodyGetRelPointPos() * @ingroup bodies * @param result will contain the result. */ ODE_API void dBodyGetPosRelPoint ( dBodyID, dReal px, dReal py, dReal pz, dVector3 result ); /** * @brief Convert from local to world coordinates. * @ingroup bodies * @param result will contain the result. */ ODE_API void dBodyVectorToWorld ( dBodyID, dReal px, dReal py, dReal pz, dVector3 result ); /** * @brief Convert from world to local coordinates. * @ingroup bodies * @param result will contain the result. */ ODE_API void dBodyVectorFromWorld ( dBodyID, dReal px, dReal py, dReal pz, dVector3 result ); /** * @brief controls the way a body's orientation is updated at each timestep. * @ingroup bodies * @param mode can be 0 or 1: * \li 0: An ``infinitesimal'' orientation update is used. * This is fast to compute, but it can occasionally cause inaccuracies * for bodies that are rotating at high speed, especially when those * bodies are joined to other bodies. * This is the default for every new body that is created. * \li 1: A ``finite'' orientation update is used. * This is more costly to compute, but will be more accurate for high * speed rotations. * @remarks * Note however that high speed rotations can result in many types of * error in a simulation, and the finite mode will only fix one of those * sources of error. */ ODE_API void dBodySetFiniteRotationMode (dBodyID, int mode); /** * @brief sets the finite rotation axis for a body. * @ingroup bodies * @remarks * This is axis only has meaning when the finite rotation mode is set * If this axis is zero (0,0,0), full finite rotations are performed on * the body. * If this axis is nonzero, the body is rotated by performing a partial finite * rotation along the axis direction followed by an infinitesimal rotation * along an orthogonal direction. * @remarks * This can be useful to alleviate certain sources of error caused by quickly * spinning bodies. For example, if a car wheel is rotating at high speed * you can call this function with the wheel's hinge axis as the argument to * try and improve its behavior. */ ODE_API void dBodySetFiniteRotationAxis (dBodyID, dReal x, dReal y, dReal z); /** * @brief Get the way a body's orientation is updated each timestep. * @ingroup bodies * @return the mode 0 (infitesimal) or 1 (finite). */ ODE_API int dBodyGetFiniteRotationMode (dBodyID); /** * @brief Get the finite rotation axis. * @param result will contain the axis. * @ingroup bodies */ ODE_API void dBodyGetFiniteRotationAxis (dBodyID, dVector3 result); /** * @brief Get the number of joints that are attached to this body. * @ingroup bodies * @return nr of joints */ ODE_API int dBodyGetNumJoints (dBodyID b); /** * @brief Return a joint attached to this body, given by index. * @ingroup bodies * @param index valid range is 0 to n-1 where n is the value returned by * dBodyGetNumJoints(). */ ODE_API dJointID dBodyGetJoint (dBodyID, int index); /** * @brief Set rigid body to dynamic state (default). * @param dBodyID identification of body. * @ingroup bodies */ ODE_API void dBodySetDynamic (dBodyID); /** * @brief Set rigid body to kinematic state. * When in kinematic state the body isn't simulated as a dynamic * body (it's "unstoppable", doesn't respond to forces), * but can still affect dynamic bodies (e.g. in joints). * Kinematic bodies can be controlled by position and velocity. * @note A kinematic body has infinite mass. If you set its mass * to something else, it loses the kinematic state and behaves * as a normal dynamic body. * @param dBodyID identification of body. * @ingroup bodies */ ODE_API void dBodySetKinematic (dBodyID); /** * @brief Check wether a body is in kinematic state. * @ingroup bodies * @return 1 if a body is kinematic or 0 if it is dynamic. */ ODE_API int dBodyIsKinematic (dBodyID); /** * @brief Manually enable a body. * @param dBodyID identification of body. * @ingroup bodies */ ODE_API void dBodyEnable (dBodyID); /** * @brief Manually disable a body. * @ingroup bodies * @remarks * A disabled body that is connected through a joint to an enabled body will * be automatically re-enabled at the next simulation step. */ ODE_API void dBodyDisable (dBodyID); /** * @brief Check wether a body is enabled. * @ingroup bodies * @return 1 if a body is currently enabled or 0 if it is disabled. */ ODE_API int dBodyIsEnabled (dBodyID); /** * @brief Set whether the body is influenced by the world's gravity or not. * @ingroup bodies * @param mode when nonzero gravity affects this body. * @remarks * Newly created bodies are always influenced by the world's gravity. */ ODE_API void dBodySetGravityMode (dBodyID b, int mode); /** * @brief Get whether the body is influenced by the world's gravity or not. * @ingroup bodies * @return nonzero means gravity affects this body. */ ODE_API int dBodyGetGravityMode (dBodyID b); /** * @brief Set the 'moved' callback of a body. * * Whenever a body has its position or rotation changed during the * timestep, the callback will be called (with body as the argument). * Use it to know which body may need an update in an external * structure (like a 3D engine). * * @param b the body that needs to be watched. * @param callback the callback to be invoked when the body moves. Set to zero * to disable. * @ingroup bodies */ ODE_API void dBodySetMovedCallback(dBodyID b, void (*callback)(dBodyID)); /** * @brief Return the first geom associated with the body. * * You can traverse through the geoms by repeatedly calling * dBodyGetNextGeom(). * * @return the first geom attached to this body, or 0. * @ingroup bodies */ ODE_API dGeomID dBodyGetFirstGeom (dBodyID b); /** * @brief returns the next geom associated with the same body. * @param g a geom attached to some body. * @return the next geom attached to the same body, or 0. * @sa dBodyGetFirstGeom * @ingroup bodies */ ODE_API dGeomID dBodyGetNextGeom (dGeomID g); /** * @brief Resets the damping settings to the current world's settings. * @ingroup bodies damping */ ODE_API void dBodySetDampingDefaults(dBodyID b); /** * @brief Get the body's linear damping scale. * @ingroup bodies damping */ ODE_API dReal dBodyGetLinearDamping (dBodyID b); /** * @brief Set the body's linear damping scale. * @param scale The linear damping scale. Should be in the interval [0, 1]. * @ingroup bodies damping * @remarks From now on the body will not use the world's linear damping * scale until dBodySetDampingDefaults() is called. * @sa dBodySetDampingDefaults() */ ODE_API void dBodySetLinearDamping(dBodyID b, dReal scale); /** * @brief Get the body's angular damping scale. * @ingroup bodies damping * @remarks If the body's angular damping scale was not set, this function * returns the world's angular damping scale. */ ODE_API dReal dBodyGetAngularDamping (dBodyID b); /** * @brief Set the body's angular damping scale. * @param scale The angular damping scale. Should be in the interval [0, 1]. * @ingroup bodies damping * @remarks From now on the body will not use the world's angular damping * scale until dBodyResetAngularDamping() is called. * @sa dBodyResetAngularDamping() */ ODE_API void dBodySetAngularDamping(dBodyID b, dReal scale); /** * @brief Convenience function to set linear and angular scales at once. * @param linear_scale The linear damping scale. Should be in the interval [0, 1]. * @param angular_scale The angular damping scale. Should be in the interval [0, 1]. * @ingroup bodies damping * @sa dBodySetLinearDamping() dBodySetAngularDamping() */ ODE_API void dBodySetDamping(dBodyID b, dReal linear_scale, dReal angular_scale); /** * @brief Get the body's linear damping threshold. * @ingroup bodies damping */ ODE_API dReal dBodyGetLinearDampingThreshold (dBodyID b); /** * @brief Set the body's linear damping threshold. * @param threshold The linear threshold to be used. Damping * is only applied if the linear speed is above this limit. * @ingroup bodies damping */ ODE_API void dBodySetLinearDampingThreshold(dBodyID b, dReal threshold); /** * @brief Get the body's angular damping threshold. * @ingroup bodies damping */ ODE_API dReal dBodyGetAngularDampingThreshold (dBodyID b); /** * @brief Set the body's angular damping threshold. * @param threshold The angular threshold to be used. Damping is * only used if the angular speed is above this limit. * @ingroup bodies damping */ ODE_API void dBodySetAngularDampingThreshold(dBodyID b, dReal threshold); /** * @brief Get the body's maximum angular speed. * @ingroup damping bodies * @sa dWorldGetMaxAngularSpeed() */ ODE_API dReal dBodyGetMaxAngularSpeed (dBodyID b); /** * @brief Set the body's maximum angular speed. * @ingroup damping bodies * @sa dWorldSetMaxAngularSpeed() dBodyResetMaxAngularSpeed() * The default value is dInfinity, but it's a good idea to limit * it at less than 500 if the body has the gyroscopic term * enabled. */ ODE_API void dBodySetMaxAngularSpeed(dBodyID b, dReal max_speed); /** * @brief Get the body's gyroscopic state. * * @return nonzero if gyroscopic term computation is enabled (default), * zero otherwise. * @ingroup bodies */ ODE_API int dBodyGetGyroscopicMode(dBodyID b); /** * @brief Enable/disable the body's gyroscopic term. * * Disabling the gyroscopic term of a body usually improves * stability. It also helps turning spining objects, like cars' * wheels. * * @param enabled nonzero (default) to enable gyroscopic term, 0 * to disable. * @ingroup bodies */ ODE_API void dBodySetGyroscopicMode(dBodyID b, int enabled); /** * @defgroup joints Joints * * In real life a joint is something like a hinge, that is used to connect two * objects. * In ODE a joint is very similar: It is a relationship that is enforced between * two bodies so that they can only have certain positions and orientations * relative to each other. * This relationship is called a constraint -- the words joint and * constraint are often used interchangeably. * * A joint has a set of parameters that can be set. These include: * * * \li dParamLoStop Low stop angle or position. Setting this to * -dInfinity (the default value) turns off the low stop. * For rotational joints, this stop must be greater than -pi to be * effective. * \li dParamHiStop High stop angle or position. Setting this to * dInfinity (the default value) turns off the high stop. * For rotational joints, this stop must be less than pi to be * effective. * If the high stop is less than the low stop then both stops will * be ineffective. * \li dParamVel Desired motor velocity (this will be an angular or * linear velocity). * \li dParamFMax The maximum force or torque that the motor will use to * achieve the desired velocity. * This must always be greater than or equal to zero. * Setting this to zero (the default value) turns off the motor. * \li dParamFudgeFactor The current joint stop/motor implementation has * a small problem: * when the joint is at one stop and the motor is set to move it away * from the stop, too much force may be applied for one time step, * causing a ``jumping'' motion. * This fudge factor is used to scale this excess force. * It should have a value between zero and one (the default value). * If the jumping motion is too visible in a joint, the value can be * reduced. * Making this value too small can prevent the motor from being able to * move the joint away from a stop. * \li dParamBounce The bouncyness of the stops. * This is a restitution parameter in the range 0..1. * 0 means the stops are not bouncy at all, 1 means maximum bouncyness. * \li dParamCFM The constraint force mixing (CFM) value used when not * at a stop. * \li dParamStopERP The error reduction parameter (ERP) used by the * stops. * \li dParamStopCFM The constraint force mixing (CFM) value used by the * stops. Together with the ERP value this can be used to get spongy or * soft stops. * Note that this is intended for unpowered joints, it does not really * work as expected when a powered joint reaches its limit. * \li dParamSuspensionERP Suspension error reduction parameter (ERP). * Currently this is only implemented on the hinge-2 joint. * \li dParamSuspensionCFM Suspension constraint force mixing (CFM) value. * Currently this is only implemented on the hinge-2 joint. * * If a particular parameter is not implemented by a given joint, setting it * will have no effect. * These parameter names can be optionally followed by a digit (2 or 3) * to indicate the second or third set of parameters, e.g. for the second axis * in a hinge-2 joint, or the third axis in an AMotor joint. */ /** * @brief Create a new joint of the ball type. * @ingroup joints * @remarks * The joint is initially in "limbo" (i.e. it has no effect on the simulation) * because it does not connect to any bodies. * @param dJointGroupID set to 0 to allocate the joint normally. * If it is nonzero the joint is allocated in the given joint group. */ ODE_API dJointID dJointCreateBall (dWorldID, dJointGroupID); /** * @brief Create a new joint of the hinge type. * @ingroup joints * @param dJointGroupID set to 0 to allocate the joint normally. * If it is nonzero the joint is allocated in the given joint group. */ ODE_API dJointID dJointCreateHinge (dWorldID, dJointGroupID); /** * @brief Create a new joint of the slider type. * @ingroup joints * @param dJointGroupID set to 0 to allocate the joint normally. * If it is nonzero the joint is allocated in the given joint group. */ ODE_API dJointID dJointCreateSlider (dWorldID, dJointGroupID); /** * @brief Create a new joint of the contact type. * @ingroup joints * @param dJointGroupID set to 0 to allocate the joint normally. * If it is nonzero the joint is allocated in the given joint group. */ ODE_API dJointID dJointCreateContact (dWorldID, dJointGroupID, const dContact *); /** * @brief Create a new joint of the hinge2 type. * @ingroup joints * @param dJointGroupID set to 0 to allocate the joint normally. * If it is nonzero the joint is allocated in the given joint group. */ ODE_API dJointID dJointCreateHinge2 (dWorldID, dJointGroupID); /** * @brief Create a new joint of the universal type. * @ingroup joints * @param dJointGroupID set to 0 to allocate the joint normally. * If it is nonzero the joint is allocated in the given joint group. */ ODE_API dJointID dJointCreateUniversal (dWorldID, dJointGroupID); /** * @brief Create a new joint of the PR (Prismatic and Rotoide) type. * @ingroup joints * @param dJointGroupID set to 0 to allocate the joint normally. * If it is nonzero the joint is allocated in the given joint group. */ ODE_API dJointID dJointCreatePR (dWorldID, dJointGroupID); /** * @brief Create a new joint of the PU (Prismatic and Universal) type. * @ingroup joints * @param dJointGroupID set to 0 to allocate the joint normally. * If it is nonzero the joint is allocated in the given joint group. */ ODE_API dJointID dJointCreatePU (dWorldID, dJointGroupID); /** * @brief Create a new joint of the Piston type. * @ingroup joints * @param dJointGroupID set to 0 to allocate the joint normally. * If it is nonzero the joint is allocated in the given * joint group. */ ODE_API dJointID dJointCreatePiston (dWorldID, dJointGroupID); /** * @brief Create a new joint of the fixed type. * @ingroup joints * @param dJointGroupID set to 0 to allocate the joint normally. * If it is nonzero the joint is allocated in the given joint group. */ ODE_API dJointID dJointCreateFixed (dWorldID, dJointGroupID); ODE_API dJointID dJointCreateNull (dWorldID, dJointGroupID); /** * @brief Create a new joint of the A-motor type. * @ingroup joints * @param dJointGroupID set to 0 to allocate the joint normally. * If it is nonzero the joint is allocated in the given joint group. */ ODE_API dJointID dJointCreateAMotor (dWorldID, dJointGroupID); /** * @brief Create a new joint of the L-motor type. * @ingroup joints * @param dJointGroupID set to 0 to allocate the joint normally. * If it is nonzero the joint is allocated in the given joint group. */ ODE_API dJointID dJointCreateLMotor (dWorldID, dJointGroupID); /** * @brief Create a new joint of the plane-2d type. * @ingroup joints * @param dJointGroupID set to 0 to allocate the joint normally. * If it is nonzero the joint is allocated in the given joint group. */ ODE_API dJointID dJointCreatePlane2D (dWorldID, dJointGroupID); /** * @brief Destroy a joint. * @ingroup joints * * disconnects it from its attached bodies and removing it from the world. * However, if the joint is a member of a group then this function has no * effect - to destroy that joint the group must be emptied or destroyed. */ ODE_API void dJointDestroy (dJointID); /** * @brief Create a joint group * @ingroup joints * @param max_size deprecated. Set to 0. */ ODE_API dJointGroupID dJointGroupCreate (int max_size); /** * @brief Destroy a joint group. * @ingroup joints * * All joints in the joint group will be destroyed. */ ODE_API void dJointGroupDestroy (dJointGroupID); /** * @brief Empty a joint group. * @ingroup joints * * All joints in the joint group will be destroyed, * but the joint group itself will not be destroyed. */ ODE_API void dJointGroupEmpty (dJointGroupID); /** * @brief Return the number of bodies attached to the joint * @ingroup joints */ ODE_API int dJointGetNumBodies(dJointID); /** * @brief Attach the joint to some new bodies. * @ingroup joints * * If the joint is already attached, it will be detached from the old bodies * first. * To attach this joint to only one body, set body1 or body2 to zero - a zero * body refers to the static environment. * Setting both bodies to zero puts the joint into "limbo", i.e. it will * have no effect on the simulation. * @remarks * Some joints, like hinge-2 need to be attached to two bodies to work. */ ODE_API void dJointAttach (dJointID, dBodyID body1, dBodyID body2); /** * @brief Manually enable a joint. * @param dJointID identification of joint. * @ingroup joints */ ODE_API void dJointEnable (dJointID); /** * @brief Manually disable a joint. * @ingroup joints * @remarks * A disabled joint will not affect the simulation, but will maintain the anchors and * axes so it can be enabled later. */ ODE_API void dJointDisable (dJointID); /** * @brief Check wether a joint is enabled. * @ingroup joints * @return 1 if a joint is currently enabled or 0 if it is disabled. */ ODE_API int dJointIsEnabled (dJointID); /** * @brief Set the user-data pointer * @ingroup joints */ ODE_API void dJointSetData (dJointID, void *data); /** * @brief Get the user-data pointer * @ingroup joints */ ODE_API void *dJointGetData (dJointID); /** * @brief Get the type of the joint * @ingroup joints * @return the type, being one of these: * \li dJointTypeBall * \li dJointTypeHinge * \li dJointTypeSlider * \li dJointTypeContact * \li dJointTypeUniversal * \li dJointTypeHinge2 * \li dJointTypeFixed * \li dJointTypeNull * \li dJointTypeAMotor * \li dJointTypeLMotor * \li dJointTypePlane2D * \li dJointTypePR * \li dJointTypePU * \li dJointTypePiston */ ODE_API dJointType dJointGetType (dJointID); /** * @brief Return the bodies that this joint connects. * @ingroup joints * @param index return the first (0) or second (1) body. * @remarks * If one of these returned body IDs is zero, the joint connects the other body * to the static environment. * If both body IDs are zero, the joint is in ``limbo'' and has no effect on * the simulation. */ ODE_API dBodyID dJointGetBody (dJointID, int index); /** * @brief Sets the datastructure that is to receive the feedback. * * The feedback can be used by the user, so that it is known how * much force an individual joint exerts. * @ingroup joints */ ODE_API void dJointSetFeedback (dJointID, dJointFeedback *); /** * @brief Gets the datastructure that is to receive the feedback. * @ingroup joints */ ODE_API dJointFeedback *dJointGetFeedback (dJointID); /** * @brief Set the joint anchor point. * @ingroup joints * * The joint will try to keep this point on each body * together. The input is specified in world coordinates. */ ODE_API void dJointSetBallAnchor (dJointID, dReal x, dReal y, dReal z); /** * @brief Set the joint anchor point. * @ingroup joints */ ODE_API void dJointSetBallAnchor2 (dJointID, dReal x, dReal y, dReal z); /** * @brief Param setting for Ball joints * @ingroup joints */ ODE_API void dJointSetBallParam (dJointID, int parameter, dReal value); /** * @brief Set hinge anchor parameter. * @ingroup joints */ ODE_API void dJointSetHingeAnchor (dJointID, dReal x, dReal y, dReal z); ODE_API void dJointSetHingeAnchorDelta (dJointID, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az); /** * @brief Set hinge axis. * @ingroup joints */ ODE_API void dJointSetHingeAxis (dJointID, dReal x, dReal y, dReal z); /** * @brief Set the Hinge axis as if the 2 bodies were already at angle appart. * @ingroup joints * * This function initialize the Axis and the relative orientation of each body * as if body1 was rotated around the axis by the angle value. \br * Ex: *
 * dJointSetHingeAxis(jId, 1, 0, 0);
 * // If you request the position you will have: dJointGetHingeAngle(jId) == 0
 * dJointSetHingeAxisDelta(jId, 1, 0, 0, 0.23);
 * // If you request the position you will have: dJointGetHingeAngle(jId) == 0.23
 * 
* @param j The Hinge joint ID for which the axis will be set * @param x The X component of the axis in world frame * @param y The Y component of the axis in world frame * @param z The Z component of the axis in world frame * @param angle The angle for the offset of the relative orientation. * As if body1 was rotated by angle when the Axis was set (see below). * The rotation is around the new Hinge axis. * * @note Usually the function dJointSetHingeAxis set the current position of body1 * and body2 as the zero angle position. This function set the current position * as the if the 2 bodies where \b angle appart. * @warning Calling dJointSetHingeAnchor or dJointSetHingeAxis will reset the "zero" * angle position. */ ODE_API void dJointSetHingeAxisOffset (dJointID j, dReal x, dReal y, dReal z, dReal angle); /** * @brief set joint parameter * @ingroup joints */ ODE_API void dJointSetHingeParam (dJointID, int parameter, dReal value); /** * @brief Applies the torque about the hinge axis. * * That is, it applies a torque with specified magnitude in the direction * of the hinge axis, to body 1, and with the same magnitude but in opposite * direction to body 2. This function is just a wrapper for dBodyAddTorque()} * @ingroup joints */ ODE_API void dJointAddHingeTorque(dJointID joint, dReal torque); /** * @brief set the joint axis * @ingroup joints */ ODE_API void dJointSetSliderAxis (dJointID, dReal x, dReal y, dReal z); /** * @ingroup joints */ ODE_API void dJointSetSliderAxisDelta (dJointID, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az); /** * @brief set joint parameter * @ingroup joints */ ODE_API void dJointSetSliderParam (dJointID, int parameter, dReal value); /** * @brief Applies the given force in the slider's direction. * * That is, it applies a force with specified magnitude, in the direction of * slider's axis, to body1, and with the same magnitude but opposite * direction to body2. This function is just a wrapper for dBodyAddForce(). * @ingroup joints */ ODE_API void dJointAddSliderForce(dJointID joint, dReal force); /** * @brief set anchor * @ingroup joints */ ODE_API void dJointSetHinge2Anchor (dJointID, dReal x, dReal y, dReal z); /** * @brief set axis * @ingroup joints */ ODE_API void dJointSetHinge2Axis1 (dJointID, dReal x, dReal y, dReal z); /** * @brief set axis * @ingroup joints */ ODE_API void dJointSetHinge2Axis2 (dJointID, dReal x, dReal y, dReal z); /** * @brief set joint parameter * @ingroup joints */ ODE_API void dJointSetHinge2Param (dJointID, int parameter, dReal value); /** * @brief Applies torque1 about the hinge2's axis 1, torque2 about the * hinge2's axis 2. * @remarks This function is just a wrapper for dBodyAddTorque(). * @ingroup joints */ ODE_API void dJointAddHinge2Torques(dJointID joint, dReal torque1, dReal torque2); /** * @brief set anchor * @ingroup joints */ ODE_API void dJointSetUniversalAnchor (dJointID, dReal x, dReal y, dReal z); /** * @brief set axis * @ingroup joints */ ODE_API void dJointSetUniversalAxis1 (dJointID, dReal x, dReal y, dReal z); /** * @brief Set the Universal axis1 as if the 2 bodies were already at * offset1 and offset2 appart with respect to axis1 and axis2. * @ingroup joints * * This function initialize the axis1 and the relative orientation of * each body as if body1 was rotated around the new axis1 by the offset1 * value and as if body2 was rotated around the axis2 by offset2. \br * Ex: *
 * dJointSetHuniversalAxis1(jId, 1, 0, 0);
 * // If you request the position you will have: dJointGetUniversalAngle1(jId) == 0
 * // If you request the position you will have: dJointGetUniversalAngle2(jId) == 0
 * dJointSetHuniversalAxis1Offset(jId, 1, 0, 0, 0.2, 0.17);
 * // If you request the position you will have: dJointGetUniversalAngle1(jId) == 0.2
 * // If you request the position you will have: dJointGetUniversalAngle2(jId) == 0.17
 * 
* * @param j The Hinge joint ID for which the axis will be set * @param x The X component of the axis in world frame * @param y The Y component of the axis in world frame * @param z The Z component of the axis in world frame * @param angle The angle for the offset of the relative orientation. * As if body1 was rotated by angle when the Axis was set (see below). * The rotation is around the new Hinge axis. * * @note Usually the function dJointSetHingeAxis set the current position of body1 * and body2 as the zero angle position. This function set the current position * as the if the 2 bodies where \b offsets appart. * * @note Any previous offsets are erased. * * @warning Calling dJointSetUniversalAnchor, dJointSetUnivesalAxis1, * dJointSetUniversalAxis2, dJointSetUniversalAxis2Offset * will reset the "zero" angle position. */ ODE_API void dJointSetUniversalAxis1Offset (dJointID, dReal x, dReal y, dReal z, dReal offset1, dReal offset2); /** * @brief set axis * @ingroup joints */ ODE_API void dJointSetUniversalAxis2 (dJointID, dReal x, dReal y, dReal z); /** * @brief Set the Universal axis2 as if the 2 bodies were already at * offset1 and offset2 appart with respect to axis1 and axis2. * @ingroup joints * * This function initialize the axis2 and the relative orientation of * each body as if body1 was rotated around the axis1 by the offset1 * value and as if body2 was rotated around the new axis2 by offset2. \br * Ex: *
 * dJointSetHuniversalAxis2(jId, 0, 1, 0);
 * // If you request the position you will have: dJointGetUniversalAngle1(jId) == 0
 * // If you request the position you will have: dJointGetUniversalAngle2(jId) == 0
 * dJointSetHuniversalAxis2Offset(jId, 0, 1, 0, 0.2, 0.17);
 * // If you request the position you will have: dJointGetUniversalAngle1(jId) == 0.2
 * // If you request the position you will have: dJointGetUniversalAngle2(jId) == 0.17
 * 
* @param j The Hinge joint ID for which the axis will be set * @param x The X component of the axis in world frame * @param y The Y component of the axis in world frame * @param z The Z component of the axis in world frame * @param angle The angle for the offset of the relative orientation. * As if body1 was rotated by angle when the Axis was set (see below). * The rotation is around the new Hinge axis. * * @note Usually the function dJointSetHingeAxis set the current position of body1 * and body2 as the zero angle position. This function set the current position * as the if the 2 bodies where \b offsets appart. * * @note Any previous offsets are erased. * * @warning Calling dJointSetUniversalAnchor, dJointSetUnivesalAxis1, * dJointSetUniversalAxis2, dJointSetUniversalAxis2Offset * will reset the "zero" angle position. */ ODE_API void dJointSetUniversalAxis2Offset (dJointID, dReal x, dReal y, dReal z, dReal offset1, dReal offset2); /** * @brief set joint parameter * @ingroup joints */ ODE_API void dJointSetUniversalParam (dJointID, int parameter, dReal value); /** * @brief Applies torque1 about the universal's axis 1, torque2 about the * universal's axis 2. * @remarks This function is just a wrapper for dBodyAddTorque(). * @ingroup joints */ ODE_API void dJointAddUniversalTorques(dJointID joint, dReal torque1, dReal torque2); /** * @brief set anchor * @ingroup joints */ ODE_API void dJointSetPRAnchor (dJointID, dReal x, dReal y, dReal z); /** * @brief set the axis for the prismatic articulation * @ingroup joints */ ODE_API void dJointSetPRAxis1 (dJointID, dReal x, dReal y, dReal z); /** * @brief set the axis for the rotoide articulation * @ingroup joints */ ODE_API void dJointSetPRAxis2 (dJointID, dReal x, dReal y, dReal z); /** * @brief set joint parameter * @ingroup joints * * @note parameterX where X equal 2 refer to parameter for the rotoide articulation */ ODE_API void dJointSetPRParam (dJointID, int parameter, dReal value); /** * @brief Applies the torque about the rotoide axis of the PR joint * * That is, it applies a torque with specified magnitude in the direction * of the rotoide axis, to body 1, and with the same magnitude but in opposite * direction to body 2. This function is just a wrapper for dBodyAddTorque()} * @ingroup joints */ ODE_API void dJointAddPRTorque (dJointID j, dReal torque); /** * @brief set anchor * @ingroup joints */ ODE_API void dJointSetPUAnchor (dJointID, dReal x, dReal y, dReal z); /** * @brief set anchor * @ingroup joints */ ODE_API_DEPRECATED ODE_API void dJointSetPUAnchorDelta (dJointID, dReal x, dReal y, dReal z, dReal dx, dReal dy, dReal dz); /** * @brief Set the PU anchor as if the 2 bodies were already at [dx, dy, dz] appart. * @ingroup joints * * This function initialize the anchor and the relative position of each body * as if the position between body1 and body2 was already the projection of [dx, dy, dz] * along the Piston axis. (i.e as if the body1 was at its current position - [dx,dy,dy] when the * axis is set). * Ex: *
   * dReal offset = 3;
   * dVector3 axis;
   * dJointGetPUAxis(jId, axis);
   * dJointSetPUAnchor(jId, 0, 0, 0);
   * // If you request the position you will have: dJointGetPUPosition(jId) == 0
   * dJointSetPUAnchorOffset(jId, 0, 0, 0, axis[X]*offset, axis[Y]*offset, axis[Z]*offset);
   * // If you request the position you will have: dJointGetPUPosition(jId) == offset
   * 
* @param j The PU joint for which the anchor point will be set * @param x The X position of the anchor point in world frame * @param y The Y position of the anchor point in world frame * @param z The Z position of the anchor point in world frame * @param dx A delta to be substracted to the X position as if the anchor was set * when body1 was at current_position[X] - dx * @param dx A delta to be substracted to the Y position as if the anchor was set * when body1 was at current_position[Y] - dy * @param dx A delta to be substracted to the Z position as if the anchor was set * when body1 was at current_position[Z] - dz */ ODE_API void dJointSetPUAnchorOffset (dJointID, dReal x, dReal y, dReal z, dReal dx, dReal dy, dReal dz); /** * @brief set the axis for the first axis or the universal articulation * @ingroup joints */ ODE_API void dJointSetPUAxis1 (dJointID, dReal x, dReal y, dReal z); /** * @brief set the axis for the second axis or the universal articulation * @ingroup joints */ ODE_API void dJointSetPUAxis2 (dJointID, dReal x, dReal y, dReal z); /** * @brief set the axis for the prismatic articulation * @ingroup joints */ ODE_API void dJointSetPUAxis3 (dJointID, dReal x, dReal y, dReal z); /** * @brief set the axis for the prismatic articulation * @ingroup joints * @note This function was added for convenience it is the same as * dJointSetPUAxis3 */ ODE_API void dJointSetPUAxisP (dJointID id, dReal x, dReal y, dReal z); /** * @brief set joint parameter * @ingroup joints * * @note parameterX where X equal 2 refer to parameter for second axis of the * universal articulation * @note parameterX where X equal 3 refer to parameter for prismatic * articulation */ ODE_API void dJointSetPUParam (dJointID, int parameter, dReal value); /** * @brief Applies the torque about the rotoide axis of the PU joint * * That is, it applies a torque with specified magnitude in the direction * of the rotoide axis, to body 1, and with the same magnitude but in opposite * direction to body 2. This function is just a wrapper for dBodyAddTorque()} * @ingroup joints */ ODE_API void dJointAddPUTorque (dJointID j, dReal torque); /** * @brief set the joint anchor * @ingroup joints */ ODE_API void dJointSetPistonAnchor (dJointID, dReal x, dReal y, dReal z); /** * @brief Set the Piston anchor as if the 2 bodies were already at [dx,dy, dz] appart. * @ingroup joints * * This function initialize the anchor and the relative position of each body * as if the position between body1 and body2 was already the projection of [dx, dy, dz] * along the Piston axis. (i.e as if the body1 was at its current position - [dx,dy,dy] when the * axis is set). * Ex: *
   * dReal offset = 3;
   * dVector3 axis;
   * dJointGetPistonAxis(jId, axis);
   * dJointSetPistonAnchor(jId, 0, 0, 0);
   * // If you request the position you will have: dJointGetPistonPosition(jId) == 0
   * dJointSetPistonAnchorOffset(jId, 0, 0, 0, axis[X]*offset, axis[Y]*offset, axis[Z]*offset);
   * // If you request the position you will have: dJointGetPistonPosition(jId) == offset
   * 
* @param j The Piston joint for which the anchor point will be set * @param x The X position of the anchor point in world frame * @param y The Y position of the anchor point in world frame * @param z The Z position of the anchor point in world frame * @param dx A delta to be substracted to the X position as if the anchor was set * when body1 was at current_position[X] - dx * @param dx A delta to be substracted to the Y position as if the anchor was set * when body1 was at current_position[Y] - dy * @param dx A delta to be substracted to the Z position as if the anchor was set * when body1 was at current_position[Z] - dz */ ODE_API void dJointSetPistonAnchorOffset(dJointID j, dReal x, dReal y, dReal z, dReal dx, dReal dy, dReal dz); /** * @brief set the joint axis * @ingroup joints */ ODE_API void dJointSetPistonAxis (dJointID, dReal x, dReal y, dReal z); /** * This function set prismatic axis of the joint and also set the position * of the joint. * * @ingroup joints * @param j The joint affected by this function * @param x The x component of the axis * @param y The y component of the axis * @param z The z component of the axis * @param dx The Initial position of the prismatic join in the x direction * @param dy The Initial position of the prismatic join in the y direction * @param dz The Initial position of the prismatic join in the z direction */ ODE_API_DEPRECATED ODE_API void dJointSetPistonAxisDelta (dJointID j, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az); /** * @brief set joint parameter * @ingroup joints */ ODE_API void dJointSetPistonParam (dJointID, int parameter, dReal value); /** * @brief Applies the given force in the slider's direction. * * That is, it applies a force with specified magnitude, in the direction of * prismatic's axis, to body1, and with the same magnitude but opposite * direction to body2. This function is just a wrapper for dBodyAddForce(). * @ingroup joints */ ODE_API void dJointAddPistonForce (dJointID joint, dReal force); /** * @brief Call this on the fixed joint after it has been attached to * remember the current desired relative offset and desired relative * rotation between the bodies. * @ingroup joints */ ODE_API void dJointSetFixed (dJointID); /* * @brief Sets joint parameter * * @ingroup joints */ ODE_API void dJointSetFixedParam (dJointID, int parameter, dReal value); /** * @brief set the nr of axes * @param num 0..3 * @ingroup joints */ ODE_API void dJointSetAMotorNumAxes (dJointID, int num); /** * @brief set axis * @ingroup joints */ ODE_API void dJointSetAMotorAxis (dJointID, int anum, int rel, dReal x, dReal y, dReal z); /** * @brief Tell the AMotor what the current angle is along axis anum. * * This function should only be called in dAMotorUser mode, because in this * mode the AMotor has no other way of knowing the joint angles. * The angle information is needed if stops have been set along the axis, * but it is not needed for axis motors. * @ingroup joints */ ODE_API void dJointSetAMotorAngle (dJointID, int anum, dReal angle); /** * @brief set joint parameter * @ingroup joints */ ODE_API void dJointSetAMotorParam (dJointID, int parameter, dReal value); /** * @brief set mode * @ingroup joints */ ODE_API void dJointSetAMotorMode (dJointID, int mode); /** * @brief Applies torque0 about the AMotor's axis 0, torque1 about the * AMotor's axis 1, and torque2 about the AMotor's axis 2. * @remarks * If the motor has fewer than three axes, the higher torques are ignored. * This function is just a wrapper for dBodyAddTorque(). * @ingroup joints */ ODE_API void dJointAddAMotorTorques (dJointID, dReal torque1, dReal torque2, dReal torque3); /** * @brief Set the number of axes that will be controlled by the LMotor. * @param num can range from 0 (which effectively deactivates the joint) to 3. * @ingroup joints */ ODE_API void dJointSetLMotorNumAxes (dJointID, int num); /** * @brief Set the AMotor axes. * @param anum selects the axis to change (0,1 or 2). * @param rel Each axis can have one of three ``relative orientation'' modes * \li 0: The axis is anchored to the global frame. * \li 1: The axis is anchored to the first body. * \li 2: The axis is anchored to the second body. * @remarks The axis vector is always specified in global coordinates * regardless of the setting of rel. * @ingroup joints */ ODE_API void dJointSetLMotorAxis (dJointID, int anum, int rel, dReal x, dReal y, dReal z); /** * @brief set joint parameter * @ingroup joints */ ODE_API void dJointSetLMotorParam (dJointID, int parameter, dReal value); /** * @ingroup joints */ ODE_API void dJointSetPlane2DXParam (dJointID, int parameter, dReal value); /** * @ingroup joints */ ODE_API void dJointSetPlane2DYParam (dJointID, int parameter, dReal value); /** * @ingroup joints */ ODE_API void dJointSetPlane2DAngleParam (dJointID, int parameter, dReal value); /** * @brief Get the joint anchor point, in world coordinates. * * This returns the point on body 1. If the joint is perfectly satisfied, * this will be the same as the point on body 2. */ ODE_API void dJointGetBallAnchor (dJointID, dVector3 result); /** * @brief Get the joint anchor point, in world coordinates. * * This returns the point on body 2. You can think of a ball and socket * joint as trying to keep the result of dJointGetBallAnchor() and * dJointGetBallAnchor2() the same. If the joint is perfectly satisfied, * this function will return the same value as dJointGetBallAnchor() to * within roundoff errors. dJointGetBallAnchor2() can be used, along with * dJointGetBallAnchor(), to see how far the joint has come apart. */ ODE_API void dJointGetBallAnchor2 (dJointID, dVector3 result); /** * @brief get joint parameter * @ingroup joints */ ODE_API dReal dJointGetBallParam (dJointID, int parameter); /** * @brief Get the hinge anchor point, in world coordinates. * * This returns the point on body 1. If the joint is perfectly satisfied, * this will be the same as the point on body 2. * @ingroup joints */ ODE_API void dJointGetHingeAnchor (dJointID, dVector3 result); /** * @brief Get the joint anchor point, in world coordinates. * @return The point on body 2. If the joint is perfectly satisfied, * this will return the same value as dJointGetHingeAnchor(). * If not, this value will be slightly different. * This can be used, for example, to see how far the joint has come apart. * @ingroup joints */ ODE_API void dJointGetHingeAnchor2 (dJointID, dVector3 result); /** * @brief get axis * @ingroup joints */ ODE_API void dJointGetHingeAxis (dJointID, dVector3 result); /** * @brief get joint parameter * @ingroup joints */ ODE_API dReal dJointGetHingeParam (dJointID, int parameter); /** * @brief Get the hinge angle. * * The angle is measured between the two bodies, or between the body and * the static environment. * The angle will be between -pi..pi. * Give the relative rotation with respect to the Hinge axis of Body 1 with * respect to Body 2. * When the hinge anchor or axis is set, the current position of the attached * bodies is examined and that position will be the zero angle. * @ingroup joints */ ODE_API dReal dJointGetHingeAngle (dJointID); /** * @brief Get the hinge angle time derivative. * @ingroup joints */ ODE_API dReal dJointGetHingeAngleRate (dJointID); /** * @brief Get the slider linear position (i.e. the slider's extension) * * When the axis is set, the current position of the attached bodies is * examined and that position will be the zero position. * The position is the distance, with respect to the zero position, * along the slider axis of body 1 with respect to * body 2. (A NULL body is replaced by the world). * @ingroup joints */ ODE_API dReal dJointGetSliderPosition (dJointID); /** * @brief Get the slider linear position's time derivative. * @ingroup joints */ ODE_API dReal dJointGetSliderPositionRate (dJointID); /** * @brief Get the slider axis * @ingroup joints */ ODE_API void dJointGetSliderAxis (dJointID, dVector3 result); /** * @brief get joint parameter * @ingroup joints */ ODE_API dReal dJointGetSliderParam (dJointID, int parameter); /** * @brief Get the joint anchor point, in world coordinates. * @return the point on body 1. If the joint is perfectly satisfied, * this will be the same as the point on body 2. * @ingroup joints */ ODE_API void dJointGetHinge2Anchor (dJointID, dVector3 result); /** * @brief Get the joint anchor point, in world coordinates. * This returns the point on body 2. If the joint is perfectly satisfied, * this will return the same value as dJointGetHinge2Anchor. * If not, this value will be slightly different. * This can be used, for example, to see how far the joint has come apart. * @ingroup joints */ ODE_API void dJointGetHinge2Anchor2 (dJointID, dVector3 result); /** * @brief Get joint axis * @ingroup joints */ ODE_API void dJointGetHinge2Axis1 (dJointID, dVector3 result); /** * @brief Get joint axis * @ingroup joints */ ODE_API void dJointGetHinge2Axis2 (dJointID, dVector3 result); /** * @brief get joint parameter * @ingroup joints */ ODE_API dReal dJointGetHinge2Param (dJointID, int parameter); /** * @brief Get angle * @ingroup joints */ ODE_API dReal dJointGetHinge2Angle1 (dJointID); /** * @brief Get time derivative of angle * @ingroup joints */ ODE_API dReal dJointGetHinge2Angle1Rate (dJointID); /** * @brief Get time derivative of angle * @ingroup joints */ ODE_API dReal dJointGetHinge2Angle2Rate (dJointID); /** * @brief Get the joint anchor point, in world coordinates. * @return the point on body 1. If the joint is perfectly satisfied, * this will be the same as the point on body 2. * @ingroup joints */ ODE_API void dJointGetUniversalAnchor (dJointID, dVector3 result); /** * @brief Get the joint anchor point, in world coordinates. * @return This returns the point on body 2. * @remarks * You can think of the ball and socket part of a universal joint as * trying to keep the result of dJointGetBallAnchor() and * dJointGetBallAnchor2() the same. If the joint is * perfectly satisfied, this function will return the same value * as dJointGetUniversalAnchor() to within roundoff errors. * dJointGetUniversalAnchor2() can be used, along with * dJointGetUniversalAnchor(), to see how far the joint has come apart. * @ingroup joints */ ODE_API void dJointGetUniversalAnchor2 (dJointID, dVector3 result); /** * @brief Get axis * @ingroup joints */ ODE_API void dJointGetUniversalAxis1 (dJointID, dVector3 result); /** * @brief Get axis * @ingroup joints */ ODE_API void dJointGetUniversalAxis2 (dJointID, dVector3 result); /** * @brief get joint parameter * @ingroup joints */ ODE_API dReal dJointGetUniversalParam (dJointID, int parameter); /** * @brief Get both angles at the same time. * @ingroup joints * * @param joint The universal joint for which we want to calculate the angles * @param angle1 The angle between the body1 and the axis 1 * @param angle2 The angle between the body2 and the axis 2 * * @note This function combine getUniversalAngle1 and getUniversalAngle2 together * and try to avoid redundant calculation */ ODE_API void dJointGetUniversalAngles (dJointID, dReal *angle1, dReal *angle2); /** * @brief Get angle * @ingroup joints */ ODE_API dReal dJointGetUniversalAngle1 (dJointID); /** * @brief Get angle * @ingroup joints */ ODE_API dReal dJointGetUniversalAngle2 (dJointID); /** * @brief Get time derivative of angle * @ingroup joints */ ODE_API dReal dJointGetUniversalAngle1Rate (dJointID); /** * @brief Get time derivative of angle * @ingroup joints */ ODE_API dReal dJointGetUniversalAngle2Rate (dJointID); /** * @brief Get the joint anchor point, in world coordinates. * @return the point on body 1. If the joint is perfectly satisfied, * this will be the same as the point on body 2. * @ingroup joints */ ODE_API void dJointGetPRAnchor (dJointID, dVector3 result); /** * @brief Get the PR linear position (i.e. the prismatic's extension) * * When the axis is set, the current position of the attached bodies is * examined and that position will be the zero position. * * The position is the "oriented" length between the * position = (Prismatic axis) dot_product [(body1 + offset) - (body2 + anchor2)] * * @ingroup joints */ ODE_API dReal dJointGetPRPosition (dJointID); /** * @brief Get the PR linear position's time derivative * * @ingroup joints */ ODE_API dReal dJointGetPRPositionRate (dJointID); /** * @brief Get the PR angular position (i.e. the twist between the 2 bodies) * * When the axis is set, the current position of the attached bodies is * examined and that position will be the zero position. * @ingroup joints */ ODE_API dReal dJointGetPRAngle (dJointID); /** * @brief Get the PR angular position's time derivative * * @ingroup joints */ ODE_API dReal dJointGetPRAngleRate (dJointID); /** * @brief Get the prismatic axis * @ingroup joints */ ODE_API void dJointGetPRAxis1 (dJointID, dVector3 result); /** * @brief Get the Rotoide axis * @ingroup joints */ ODE_API void dJointGetPRAxis2 (dJointID, dVector3 result); /** * @brief get joint parameter * @ingroup joints */ ODE_API dReal dJointGetPRParam (dJointID, int parameter); /** * @brief Get the joint anchor point, in world coordinates. * @return the point on body 1. If the joint is perfectly satisfied, * this will be the same as the point on body 2. * @ingroup joints */ ODE_API void dJointGetPUAnchor (dJointID, dVector3 result); /** * @brief Get the PU linear position (i.e. the prismatic's extension) * * When the axis is set, the current position of the attached bodies is * examined and that position will be the zero position. * * The position is the "oriented" length between the * position = (Prismatic axis) dot_product [(body1 + offset) - (body2 + anchor2)] * * @ingroup joints */ ODE_API dReal dJointGetPUPosition (dJointID); /** * @brief Get the PR linear position's time derivative * * @ingroup joints */ ODE_API dReal dJointGetPUPositionRate (dJointID); /** * @brief Get the first axis of the universal component of the joint * @ingroup joints */ ODE_API void dJointGetPUAxis1 (dJointID, dVector3 result); /** * @brief Get the second axis of the Universal component of the joint * @ingroup joints */ ODE_API void dJointGetPUAxis2 (dJointID, dVector3 result); /** * @brief Get the prismatic axis * @ingroup joints */ ODE_API void dJointGetPUAxis3 (dJointID, dVector3 result); /** * @brief Get the prismatic axis * @ingroup joints * * @note This function was added for convenience it is the same as * dJointGetPUAxis3 */ ODE_API void dJointGetPUAxisP (dJointID id, dVector3 result); /** * @brief Get both angles at the same time. * @ingroup joints * * @param joint The Prismatic universal joint for which we want to calculate the angles * @param angle1 The angle between the body1 and the axis 1 * @param angle2 The angle between the body2 and the axis 2 * * @note This function combine dJointGetPUAngle1 and dJointGetPUAngle2 together * and try to avoid redundant calculation */ ODE_API void dJointGetPUAngles (dJointID, dReal *angle1, dReal *angle2); /** * @brief Get angle * @ingroup joints */ ODE_API dReal dJointGetPUAngle1 (dJointID); /** * @brief * @brief Get time derivative of angle1 * * @ingroup joints */ ODE_API dReal dJointGetPUAngle1Rate (dJointID); /** * @brief Get angle * @ingroup joints */ ODE_API dReal dJointGetPUAngle2 (dJointID); /** * @brief * @brief Get time derivative of angle2 * * @ingroup joints */ ODE_API dReal dJointGetPUAngle2Rate (dJointID); /** * @brief get joint parameter * @ingroup joints */ ODE_API dReal dJointGetPUParam (dJointID, int parameter); /** * @brief Get the Piston linear position (i.e. the piston's extension) * * When the axis is set, the current position of the attached bodies is * examined and that position will be the zero position. * @ingroup joints */ ODE_API dReal dJointGetPistonPosition (dJointID); /** * @brief Get the piston linear position's time derivative. * @ingroup joints */ ODE_API dReal dJointGetPistonPositionRate (dJointID); /** * @brief Get the Piston angular position (i.e. the twist between the 2 bodies) * * When the axis is set, the current position of the attached bodies is * examined and that position will be the zero position. * @ingroup joints */ ODE_API dReal dJointGetPistonAngle (dJointID); /** * @brief Get the piston angular position's time derivative. * @ingroup joints */ ODE_API dReal dJointGetPistonAngleRate (dJointID); /** * @brief Get the joint anchor * * This returns the point on body 1. If the joint is perfectly satisfied, * this will be the same as the point on body 2 in direction perpendicular * to the prismatic axis. * * @ingroup joints */ ODE_API void dJointGetPistonAnchor (dJointID, dVector3 result); /** * @brief Get the joint anchor w.r.t. body 2 * * This returns the point on body 2. You can think of a Piston * joint as trying to keep the result of dJointGetPistonAnchor() and * dJointGetPistonAnchor2() the same in the direction perpendicular to the * pirsmatic axis. If the joint is perfectly satisfied, * this function will return the same value as dJointGetPistonAnchor() to * within roundoff errors. dJointGetPistonAnchor2() can be used, along with * dJointGetPistonAnchor(), to see how far the joint has come apart. * * @ingroup joints */ ODE_API void dJointGetPistonAnchor2 (dJointID, dVector3 result); /** * @brief Get the prismatic axis (This is also the rotoide axis. * @ingroup joints */ ODE_API void dJointGetPistonAxis (dJointID, dVector3 result); /** * @brief get joint parameter * @ingroup joints */ ODE_API dReal dJointGetPistonParam (dJointID, int parameter); /** * @brief Get the number of angular axes that will be controlled by the * AMotor. * @param num can range from 0 (which effectively deactivates the * joint) to 3. * This is automatically set to 3 in dAMotorEuler mode. * @ingroup joints */ ODE_API int dJointGetAMotorNumAxes (dJointID); /** * @brief Get the AMotor axes. * @param anum selects the axis to change (0,1 or 2). * @param rel Each axis can have one of three ``relative orientation'' modes. * \li 0: The axis is anchored to the global frame. * \li 1: The axis is anchored to the first body. * \li 2: The axis is anchored to the second body. * @ingroup joints */ ODE_API void dJointGetAMotorAxis (dJointID, int anum, dVector3 result); /** * @brief Get axis * @remarks * The axis vector is always specified in global coordinates regardless * of the setting of rel. * There are two GetAMotorAxis functions, one to return the axis and one to * return the relative mode. * * For dAMotorEuler mode: * \li Only axes 0 and 2 need to be set. Axis 1 will be determined automatically at each time step. * \li Axes 0 and 2 must be perpendicular to each other. * \li Axis 0 must be anchored to the first body, axis 2 must be anchored to the second body. * @ingroup joints */ ODE_API int dJointGetAMotorAxisRel (dJointID, int anum); /** * @brief Get the current angle for axis. * @remarks * In dAMotorUser mode this is simply the value that was set with * dJointSetAMotorAngle(). * In dAMotorEuler mode this is the corresponding euler angle. * @ingroup joints */ ODE_API dReal dJointGetAMotorAngle (dJointID, int anum); /** * @brief Get the current angle rate for axis anum. * @remarks * In dAMotorUser mode this is always zero, as not enough information is * available. * In dAMotorEuler mode this is the corresponding euler angle rate. * @ingroup joints */ ODE_API dReal dJointGetAMotorAngleRate (dJointID, int anum); /** * @brief get joint parameter * @ingroup joints */ ODE_API dReal dJointGetAMotorParam (dJointID, int parameter); /** * @brief Get the angular motor mode. * @param mode must be one of the following constants: * \li dAMotorUser The AMotor axes and joint angle settings are entirely * controlled by the user. This is the default mode. * \li dAMotorEuler Euler angles are automatically computed. * The axis a1 is also automatically computed. * The AMotor axes must be set correctly when in this mode, * as described below. * When this mode is initially set the current relative orientations * of the bodies will correspond to all euler angles at zero. * @ingroup joints */ ODE_API int dJointGetAMotorMode (dJointID); /** * @brief Get nr of axes. * @ingroup joints */ ODE_API int dJointGetLMotorNumAxes (dJointID); /** * @brief Get axis. * @ingroup joints */ ODE_API void dJointGetLMotorAxis (dJointID, int anum, dVector3 result); /** * @brief get joint parameter * @ingroup joints */ ODE_API dReal dJointGetLMotorParam (dJointID, int parameter); /** * @brief get joint parameter * @ingroup joints */ ODE_API dReal dJointGetFixedParam (dJointID, int parameter); /** * @ingroup joints */ ODE_API dJointID dConnectingJoint (dBodyID, dBodyID); /** * @ingroup joints */ ODE_API int dConnectingJointList (dBodyID, dBodyID, dJointID*); /** * @brief Utility function * @return 1 if the two bodies are connected together by * a joint, otherwise return 0. * @ingroup joints */ ODE_API int dAreConnected (dBodyID, dBodyID); /** * @brief Utility function * @return 1 if the two bodies are connected together by * a joint that does not have type @arg{joint_type}, otherwise return 0. * @param body1 A body to check. * @param body2 A body to check. * @param joint_type is a dJointTypeXXX constant. * This is useful for deciding whether to add contact joints between two bodies: * if they are already connected by non-contact joints then it may not be * appropriate to add contacts, however it is okay to add more contact between- * bodies that already have contacts. * @ingroup joints */ ODE_API int dAreConnectedExcluding (dBodyID body1, dBodyID body2, int joint_type); #ifdef __cplusplus } #endif #endif alien-arena-7.66+dfsg/source/unix/ode/collision_space.h0000600000175000017500000001471212161402010022160 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_COLLISION_SPACE_H_ #define _ODE_COLLISION_SPACE_H_ #include #ifdef __cplusplus extern "C" { #endif struct dContactGeom; /** * @brief User callback for geom-geom collision testing. * * @param data The user data object, as passed to dSpaceCollide. * @param o1 The first geom being tested. * @param o2 The second geom being test. * * @remarks The callback function can call dCollide on o1 and o2 to generate * contact points between each pair. Then these contact points may be added * to the simulation as contact joints. The user's callback function can of * course chose not to call dCollide for any pair, e.g. if the user decides * that those pairs should not interact. * * @ingroup collide */ typedef void dNearCallback (void *data, dGeomID o1, dGeomID o2); ODE_API dSpaceID dSimpleSpaceCreate (dSpaceID space); ODE_API dSpaceID dHashSpaceCreate (dSpaceID space); ODE_API dSpaceID dQuadTreeSpaceCreate (dSpaceID space, const dVector3 Center, const dVector3 Extents, int Depth); // SAP // Order XZY or ZXY usually works best, if your Y is up. #define dSAP_AXES_XYZ ((0)|(1<<2)|(2<<4)) #define dSAP_AXES_XZY ((0)|(2<<2)|(1<<4)) #define dSAP_AXES_YXZ ((1)|(0<<2)|(2<<4)) #define dSAP_AXES_YZX ((1)|(2<<2)|(0<<4)) #define dSAP_AXES_ZXY ((2)|(0<<2)|(1<<4)) #define dSAP_AXES_ZYX ((2)|(1<<2)|(0<<4)) ODE_API dSpaceID dSweepAndPruneSpaceCreate( dSpaceID space, int axisorder ); ODE_API void dSpaceDestroy (dSpaceID); ODE_API void dHashSpaceSetLevels (dSpaceID space, int minlevel, int maxlevel); ODE_API void dHashSpaceGetLevels (dSpaceID space, int *minlevel, int *maxlevel); ODE_API void dSpaceSetCleanup (dSpaceID space, int mode); ODE_API int dSpaceGetCleanup (dSpaceID space); /** * @brief Sets sublevel value for a space. * * Sublevel affects how the space is handled in dSpaceCollide2 when it is collided * with another space. If sublevels of both spaces match, the function iterates * geometries of both spaces and collides them with each other. If sublevel of one * space is greater than the sublevel of another one, only the geometries of the * space with greater sublevel are iterated, another space is passed into * collision callback as a geometry itself. By default all the spaces are assigned * zero sublevel. * * @note * The space sublevel @e IS @e NOT automatically updated when one space is inserted * into another or removed from one. It is a client's responsibility to update sublevel * value if necessary. * * @param space the space to modify * @param sublevel the sublevel value to be assigned * @ingroup collide * @see dSpaceGetSublevel * @see dSpaceCollide2 */ ODE_API void dSpaceSetSublevel (dSpaceID space, int sublevel); /** * @brief Gets sublevel value of a space. * * Sublevel affects how the space is handled in dSpaceCollide2 when it is collided * with another space. See @c dSpaceSetSublevel for more details. * * @param space the space to query * @returns the sublevel value of the space * @ingroup collide * @see dSpaceSetSublevel * @see dSpaceCollide2 */ ODE_API int dSpaceGetSublevel (dSpaceID space); /** * @brief Sets manual cleanup flag for a space. * * Manual cleanup flag marks a space as eligible for manual thread data cleanup. * This function should be called for every space object right after creation in * case if ODE has been initialized with @c dInitFlagManualThreadCleanup flag. * * Failure to set manual cleanup flag for a space may lead to some resources * remaining leaked until the program exit. * * @param space the space to modify * @param mode 1 for manual cleanup mode and 0 for default cleanup mode * @ingroup collide * @see dSpaceGetManualCleanup * @see dInitODE2 */ ODE_API void dSpaceSetManualCleanup (dSpaceID space, int mode); /** * @brief Get manual cleanup flag of a space. * * Manual cleanup flag marks a space space as eligible for manual thread data cleanup. * See @c dSpaceSetManualCleanup for more details. * * @param space the space to query * @returns 1 for manual cleanup mode and 0 for default cleanup mode of the space * @ingroup collide * @see dSpaceSetManualCleanup * @see dInitODE2 */ ODE_API int dSpaceGetManualCleanup (dSpaceID space); ODE_API void dSpaceAdd (dSpaceID, dGeomID); ODE_API void dSpaceRemove (dSpaceID, dGeomID); ODE_API int dSpaceQuery (dSpaceID, dGeomID); ODE_API void dSpaceClean (dSpaceID); ODE_API int dSpaceGetNumGeoms (dSpaceID); ODE_API dGeomID dSpaceGetGeom (dSpaceID, int i); /** * @brief Given a space, this returns its class. * * The ODE classes are: * @li dSimpleSpaceClass * @li dHashSpaceClass * @li dSweepAndPruneSpaceClass * @li dQuadTreeSpaceClass * @li dFirstUserClass * @li dLastUserClass * * The class id not defined by the user should be between * dFirstSpaceClass and dLastSpaceClass. * * User-defined class will return their own number. * * @param space the space to query * @returns The space class ID. * @ingroup collide */ ODE_API int dSpaceGetClass(dSpaceID space); #ifdef __cplusplus } #endif #endif alien-arena-7.66+dfsg/source/unix/ode/misc.h0000600000175000017500000000640312161402010017743 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* miscellaneous math functions. these are mostly useful for testing */ #ifndef _ODE_MISC_H_ #define _ODE_MISC_H_ #include #ifdef __cplusplus extern "C" { #endif /* return 1 if the random number generator is working. */ ODE_API int dTestRand(void); /* return next 32 bit random number. this uses a not-very-random linear * congruential method. */ ODE_API unsigned long dRand(void); /* get and set the current random number seed. */ ODE_API unsigned long dRandGetSeed(void); ODE_API void dRandSetSeed (unsigned long s); /* return a random integer between 0..n-1. the distribution will get worse * as n approaches 2^32. */ ODE_API int dRandInt (int n); /* return a random real number between 0..1 */ ODE_API dReal dRandReal(void); /* print out a matrix */ #ifdef __cplusplus ODE_API void dPrintMatrix (const dReal *A, int n, int m, char *fmt = "%10.4f ", FILE *f=stdout); #else ODE_API void dPrintMatrix (const dReal *A, int n, int m, char *fmt, FILE *f); #endif /* make a random vector with entries between +/- range. A has n elements. */ ODE_API void dMakeRandomVector (dReal *A, int n, dReal range); /* make a random matrix with entries between +/- range. A has size n*m. */ ODE_API void dMakeRandomMatrix (dReal *A, int n, int m, dReal range); /* clear the upper triangle of a square matrix */ ODE_API void dClearUpperTriangle (dReal *A, int n); /* return the maximum element difference between the two n*m matrices */ ODE_API dReal dMaxDifference (const dReal *A, const dReal *B, int n, int m); /* return the maximum element difference between the lower triangle of two * n*n matrices */ ODE_API dReal dMaxDifferenceLowerTriangle (const dReal *A, const dReal *B, int n); #ifdef __cplusplus } #endif #endif alien-arena-7.66+dfsg/source/unix/ode/odeinit.h0000600000175000017500000002266412161402010020452 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* Library initialization/finalization functions. */ #ifndef _ODE_ODEINIT_H_ #define _ODE_ODEINIT_H_ #include #ifdef __cplusplus extern "C" { #endif /* ************************************************************************ */ /* Library initialization */ /** * @defgroup init Library Initialization * * Library initialization functions prepare ODE internal data structures for use * and release allocated resources after ODE is not needed any more. */ /** * @brief Library initialization flags. * * These flags define ODE library initialization options. * * @c dInitFlagManualThreadCleanup indicates that resources allocated in TLS for threads * using ODE are to be cleared by library client with explicit call to @c dCleanupODEAllDataForThread. * If this flag is not specified the automatic resource tracking algorithm is used. * * With automatic resource tracking, On Windows, memory allocated for a thread may * remain not freed for some time after the thread exits. The resources may be * released when one of other threads calls @c dAllocateODEDataForThread. Ultimately, * the resources are released when library is closed with @c dCloseODE. On other * operating systems resources are always released by the thread itself on its exit * or on library closure with @c dCloseODE. * * With manual thread data cleanup mode every collision space object must be * explicitly switched to manual cleanup mode with @c dSpaceSetManualCleanup * after creation. See description of the function for more details. * * If @c dInitFlagManualThreadCleanup was not specified during initialization, * calls to @c dCleanupODEAllDataForThread are not allowed. * * @see dInitODE2 * @see dAllocateODEDataForThread * @see dSpaceSetManualCleanup * @see dCloseODE * @ingroup init */ enum dInitODEFlags { dInitFlagManualThreadCleanup = 0x00000001, //@< Thread local data is to be cleared explicitly on @c dCleanupODEAllDataForThread function call }; /** * @brief Initializes ODE library. * * @c dInitODE is obsolete. @c dInitODE2 is to be used for library initialization. * * A call to @c dInitODE is equal to the following initialization sequence * @code * dInitODE2(0); * dAllocateODEDataForThread(dAllocateMaskAll); * @endcode * * @see dInitODE2 * @see dAllocateODEDataForThread * @ingroup init */ ODE_API void dInitODE(void); /** * @brief Initializes ODE library. * @param uiInitFlags Initialization options bitmask * @return A nonzero if initialization succeeded and zero otherwise. * * This function must be called to initialize ODE library before first use. If * initialization succeeds the function may not be called again until library is * closed with a call to @c dCloseODE. * * The @a uiInitFlags parameter specifies initialization options to be used. These * can be combination of zero or more @c dInitODEFlags flags. * * @note * If @c dInitFlagManualThreadCleanup flag is used for initialization, * @c dSpaceSetManualCleanup must be called to set manual cleanup mode for every * space object right after creation. Failure to do so may lead to resource leaks. * * @see dInitODEFlags * @see dCloseODE * @see dSpaceSetManualCleanup * @ingroup init */ ODE_API int dInitODE2(unsigned int uiInitFlags/*=0*/); /** * @brief ODE data allocation flags. * * These flags are used to indicate which data is to be pre-allocated in call to * @c dAllocateODEDataForThread. * * @c dAllocateFlagBasicData tells to allocate the basic data set required for * normal library operation. This flag is equal to zero and is always implicitly * included. * * @c dAllocateFlagCollisionData tells that collision detection data is to be allocated. * Collision detection functions may not be called if the data has not be allocated * in advance. If collision detection is not going to be used, it is not necessary * to specify this flag. * * @c dAllocateMaskAll is a mask that can be used for for allocating all possible * data in cases when it is not known what exactly features of ODE will be used. * The mask may not be used in combination with other flags. It is guaranteed to * include all the current and future legal allocation flags. However, mature * applications should use explicit flags they need rather than allocating everything. * * @see dAllocateODEDataForThread * @ingroup init */ enum dAllocateODEDataFlags { dAllocateFlagBasicData = 0, //@< Allocate basic data required for library to operate dAllocateFlagCollisionData = 0x00000001, //@< Allocate data for collision detection dAllocateMaskAll = ~0U, //@< Allocate all the possible data that is currently defined or will be defined in the future. }; /** * @brief Allocate thread local data to allow the thread calling ODE. * @param uiAllocateFlags Allocation options bitmask. * @return A nonzero if allocation succeeded and zero otherwise. * * The function is required to be called for every thread that is going to use * ODE. This function allocates the data that is required for accessing ODE from * current thread along with optional data required for particular ODE subsystems. * * @a uiAllocateFlags parameter can contain zero or more flags from @c dAllocateODEDataFlags * enumerated type. Multiple calls with different allocation flags are allowed. * The flags that are already allocated are ignored in subsequent calls. If zero * is passed as the parameter, it means to only allocate the set of most important * data the library can not operate without. * * If the function returns failure status it means that none of the requested * data has been allocated. The client may retry allocation attempt with the same * flags when more system resources are available. * * @see dAllocateODEDataFlags * @see dCleanupODEAllDataForThread * @ingroup init */ ODE_API int dAllocateODEDataForThread(unsigned int uiAllocateFlags); /** * @brief Free thread local data that was allocated for current thread. * * If library was initialized with @c dInitFlagManualThreadCleanup flag the function * is required to be called on exit of every thread that was calling @c dAllocateODEDataForThread. * Failure to call @c dCleanupODEAllDataForThread may result in some resources remaining * not freed until program exit. The function may also be called when ODE is still * being used to release resources allocated for all the current subsystems and * possibly proceed with data pre-allocation for other subsystems. * * The function can safely be called several times in a row. The function can be * called without prior invocation of @c dAllocateODEDataForThread. The function * may not be called before ODE is initialized with @c dInitODE2 or after library * has been closed with @c dCloseODE. A call to @c dCloseODE implicitly releases * all the thread local resources that might be allocated for all the threads that * were using ODE. * * If library was initialized without @c dInitFlagManualThreadCleanup flag * @c dCleanupODEAllDataForThread must not be called. * * @see dAllocateODEDataForThread * @see dInitODE2 * @see dCloseODE * @ingroup init */ ODE_API void dCleanupODEAllDataForThread(); /** * @brief Close ODE after it is not needed any more. * * The function is required to be called when program does not need ODE features any more. * The call to @c dCloseODE releases all the resources allocated for library * including all the thread local data that might be allocated for all the threads * that were using ODE. * * @c dCloseODE is a paired function for @c dInitODE2 and must only be called * after successful library initialization. * * @note Important! * Make sure that all the threads that were using ODE have already terminated * before calling @c dCloseODE. In particular it is not allowed to call * @c dCleanupODEAllDataForThread after @c dCloseODE. * * @see dInitODE2 * @see dCleanupODEAllDataForThread * @ingroup init */ ODE_API void dCloseODE(void); #ifdef __cplusplus }; // extern "C" #endif #endif // _ODE_ODEINIT_H_ alien-arena-7.66+dfsg/source/unix/ode/contact.h0000600000175000017500000000654612161402010020453 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_CONTACT_H_ #define _ODE_CONTACT_H_ #include #ifdef __cplusplus extern "C" { #endif enum { dContactMu2 = 0x001, dContactFDir1 = 0x002, dContactBounce = 0x004, dContactSoftERP = 0x008, dContactSoftCFM = 0x010, dContactMotion1 = 0x020, dContactMotion2 = 0x040, dContactMotionN = 0x080, dContactSlip1 = 0x100, dContactSlip2 = 0x200, dContactApprox0 = 0x0000, dContactApprox1_1 = 0x1000, dContactApprox1_2 = 0x2000, dContactApprox1 = 0x3000 }; typedef struct dSurfaceParameters { /* must always be defined */ int mode; dReal mu; /* only defined if the corresponding flag is set in mode */ dReal mu2; dReal bounce; dReal bounce_vel; dReal soft_erp; dReal soft_cfm; dReal motion1,motion2,motionN; dReal slip1,slip2; } dSurfaceParameters; /** * @brief Describe the contact point between two geoms. * * If two bodies touch, or if a body touches a static feature in its * environment, the contact is represented by one or more "contact * points", described by dContactGeom. * * The convention is that if body 1 is moved along the normal vector by * a distance depth (or equivalently if body 2 is moved the same distance * in the opposite direction) then the contact depth will be reduced to * zero. This means that the normal vector points "in" to body 1. * * @ingroup collide */ typedef struct dContactGeom { dVector3 pos; ///< contact position dVector3 normal; ///< normal vector dReal depth; ///< penetration depth dGeomID g1,g2; ///< the colliding geoms int side1,side2; ///< (to be documented) } dContactGeom; /* contact info used by contact joint */ typedef struct dContact { dSurfaceParameters surface; dContactGeom geom; dVector3 fdir1; } dContact; #ifdef __cplusplus } #endif #endif alien-arena-7.66+dfsg/source/unix/qgl_unix.c0000600000175000017500000054160712161402010020074 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* ** QGL_WIN.C ** ** This file implements the operating system binding of GL to QGL function ** pointers. When doing a port of Quake2 you must implement the following ** two functions: ** ** QGL_Init() - loads libraries, assigns function pointers, etc. ** QGL_Shutdown() - unloads libraries, NULLs function pointers */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "ref_gl/r_local.h" #include "glw_unix.h" //#include #include #if defined HAVE_DLFCN_H #include #endif /* //FX Mesa Functions fxMesaContext (*qfxMesaCreateContext)(GLuint win, GrScreenResolution_t, GrScreenRefresh_t, const GLint attribList[]); fxMesaContext (*qfxMesaCreateBestContext)(GLuint win, GLint width, GLint height, const GLint attribList[]); void (*qfxMesaDestroyContext)(fxMesaContext ctx); void (*qfxMesaMakeCurrent)(fxMesaContext ctx); fxMesaContext (*qfxMesaGetCurrentContext)(void); void (*qfxMesaSwapBuffers)(void); */ //GLX Functions XVisualInfo * (*qglXChooseVisual)( Display *dpy, int screen, int *attribList ); GLXContext (*qglXCreateContext)( Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct ); void (*qglXDestroyContext)( Display *dpy, GLXContext ctx ); Bool (*qglXMakeCurrent)( Display *dpy, GLXDrawable drawable, GLXContext ctx); void (*qglXCopyContext)( Display *dpy, GLXContext src, GLXContext dst, GLuint mask ); void (*qglXSwapBuffers)( Display *dpy, GLXDrawable drawable ); void ( APIENTRY * qglAccum )(GLenum op, GLfloat value); void ( APIENTRY * qglAlphaFunc )(GLenum func, GLclampf ref); GLboolean ( APIENTRY * qglAreTexturesResident )(GLsizei n, const GLuint *textures, GLboolean *residences); void ( APIENTRY * qglArrayElement )(GLint i); void ( APIENTRY * qglBegin )(GLenum mode); void ( APIENTRY * qglBindTexture )(GLenum target, GLuint texture); void ( APIENTRY * qglBitmap )(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); void ( APIENTRY * qglBlendFunc )(GLenum sfactor, GLenum dfactor); void ( APIENTRY * qglCallList )(GLuint list); void ( APIENTRY * qglCallLists )(GLsizei n, GLenum type, const GLvoid *lists); void ( APIENTRY * qglClear )(GLbitfield mask); void ( APIENTRY * qglClearAccum )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); void ( APIENTRY * qglClearColor )(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); void ( APIENTRY * qglClearDepth )(GLclampd depth); void ( APIENTRY * qglClearIndex )(GLfloat c); void ( APIENTRY * qglClearStencil )(GLint s); void ( APIENTRY * qglClipPlane )(GLenum plane, const GLdouble *equation); void ( APIENTRY * qglColor3b )(GLbyte red, GLbyte green, GLbyte blue); void ( APIENTRY * qglColor3bv )(const GLbyte *v); void ( APIENTRY * qglColor3d )(GLdouble red, GLdouble green, GLdouble blue); void ( APIENTRY * qglColor3dv )(const GLdouble *v); void ( APIENTRY * qglColor3f )(GLfloat red, GLfloat green, GLfloat blue); void ( APIENTRY * qglColor3fv )(const GLfloat *v); void ( APIENTRY * qglColor3i )(GLint red, GLint green, GLint blue); void ( APIENTRY * qglColor3iv )(const GLint *v); void ( APIENTRY * qglColor3s )(GLshort red, GLshort green, GLshort blue); void ( APIENTRY * qglColor3sv )(const GLshort *v); void ( APIENTRY * qglColor3ub )(GLubyte red, GLubyte green, GLubyte blue); void ( APIENTRY * qglColor3ubv )(const GLubyte *v); void ( APIENTRY * qglColor3ui )(GLuint red, GLuint green, GLuint blue); void ( APIENTRY * qglColor3uiv )(const GLuint *v); void ( APIENTRY * qglColor3us )(GLushort red, GLushort green, GLushort blue); void ( APIENTRY * qglColor3usv )(const GLushort *v); void ( APIENTRY * qglColor4b )(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); void ( APIENTRY * qglColor4bv )(const GLbyte *v); void ( APIENTRY * qglColor4d )(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); void ( APIENTRY * qglColor4dv )(const GLdouble *v); void ( APIENTRY * qglColor4f )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); void ( APIENTRY * qglColor4fv )(const GLfloat *v); void ( APIENTRY * qglColor4i )(GLint red, GLint green, GLint blue, GLint alpha); void ( APIENTRY * qglColor4iv )(const GLint *v); void ( APIENTRY * qglColor4s )(GLshort red, GLshort green, GLshort blue, GLshort alpha); void ( APIENTRY * qglColor4sv )(const GLshort *v); void ( APIENTRY * qglColor4ub )(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); void ( APIENTRY * qglColor4ubv )(const GLubyte *v); void ( APIENTRY * qglColor4ui )(GLuint red, GLuint green, GLuint blue, GLuint alpha); void ( APIENTRY * qglColor4uiv )(const GLuint *v); void ( APIENTRY * qglColor4us )(GLushort red, GLushort green, GLushort blue, GLushort alpha); void ( APIENTRY * qglColor4usv )(const GLushort *v); void ( APIENTRY * qglColorMask )(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); void ( APIENTRY * qglColorMaterial )(GLenum face, GLenum mode); void ( APIENTRY * qglColorPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); void ( APIENTRY * qglCopyPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); void ( APIENTRY * qglCopyTexImage1D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); void ( APIENTRY * qglCopyTexImage2D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); void ( APIENTRY * qglCopyTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); void ( APIENTRY * qglCopyTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); void ( APIENTRY * qglCullFace )(GLenum mode); void ( APIENTRY * qglDeleteLists )(GLuint list, GLsizei range); void ( APIENTRY * qglDeleteTextures )(GLsizei n, const GLuint *textures); void ( APIENTRY * qglDepthFunc )(GLenum func); void ( APIENTRY * qglDepthMask )(GLboolean flag); void ( APIENTRY * qglDepthRange )(GLclampd zNear, GLclampd zFar); void ( APIENTRY * qglDisable )(GLenum cap); void ( APIENTRY * qglDisableClientState )(GLenum array); void ( APIENTRY * qglDrawArrays )(GLenum mode, GLint first, GLsizei count); void ( APIENTRY * qglDrawBuffer )(GLenum mode); void ( APIENTRY * qglDrawElements )(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); void ( APIENTRY * qglDrawRangeElements )(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); void ( APIENTRY * qglDrawPixels )(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); void ( APIENTRY * qglEdgeFlag )(GLboolean flag); void ( APIENTRY * qglEdgeFlagPointer )(GLsizei stride, const GLvoid *pointer); void ( APIENTRY * qglEdgeFlagv )(const GLboolean *flag); void ( APIENTRY * qglEnable )(GLenum cap); void ( APIENTRY * qglEnableClientState )(GLenum array); void ( APIENTRY * qglEnd )(void); void ( APIENTRY * qglEndList )(void); void ( APIENTRY * qglEvalCoord1d )(GLdouble u); void ( APIENTRY * qglEvalCoord1dv )(const GLdouble *u); void ( APIENTRY * qglEvalCoord1f )(GLfloat u); void ( APIENTRY * qglEvalCoord1fv )(const GLfloat *u); void ( APIENTRY * qglEvalCoord2d )(GLdouble u, GLdouble v); void ( APIENTRY * qglEvalCoord2dv )(const GLdouble *u); void ( APIENTRY * qglEvalCoord2f )(GLfloat u, GLfloat v); void ( APIENTRY * qglEvalCoord2fv )(const GLfloat *u); void ( APIENTRY * qglEvalMesh1 )(GLenum mode, GLint i1, GLint i2); void ( APIENTRY * qglEvalMesh2 )(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); void ( APIENTRY * qglEvalPoint1 )(GLint i); void ( APIENTRY * qglEvalPoint2 )(GLint i, GLint j); void ( APIENTRY * qglFeedbackBuffer )(GLsizei size, GLenum type, GLfloat *buffer); void ( APIENTRY * qglFinish )(void); void ( APIENTRY * qglFlush )(void); void ( APIENTRY * qglFogf )(GLenum pname, GLfloat param); void ( APIENTRY * qglFogfv )(GLenum pname, const GLfloat *params); void ( APIENTRY * qglFogi )(GLenum pname, GLint param); void ( APIENTRY * qglFogiv )(GLenum pname, const GLint *params); void ( APIENTRY * qglFrontFace )(GLenum mode); void ( APIENTRY * qglFrustum )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); GLuint ( APIENTRY * qglGenLists )(GLsizei range); void ( APIENTRY * qglGenTextures )(GLsizei n, GLuint *textures); void ( APIENTRY * qglGetBooleanv )(GLenum pname, GLboolean *params); void ( APIENTRY * qglGetClipPlane )(GLenum plane, GLdouble *equation); void ( APIENTRY * qglGetDoublev )(GLenum pname, GLdouble *params); GLenum ( APIENTRY * qglGetError )(void); void ( APIENTRY * qglGetFloatv )(GLenum pname, GLfloat *params); void ( APIENTRY * qglGetIntegerv )(GLenum pname, GLint *params); void ( APIENTRY * qglGetLightfv )(GLenum light, GLenum pname, GLfloat *params); void ( APIENTRY * qglGetLightiv )(GLenum light, GLenum pname, GLint *params); void ( APIENTRY * qglGetMapdv )(GLenum target, GLenum query, GLdouble *v); void ( APIENTRY * qglGetMapfv )(GLenum target, GLenum query, GLfloat *v); void ( APIENTRY * qglGetMapiv )(GLenum target, GLenum query, GLint *v); void ( APIENTRY * qglGetMaterialfv )(GLenum face, GLenum pname, GLfloat *params); void ( APIENTRY * qglGetMaterialiv )(GLenum face, GLenum pname, GLint *params); void ( APIENTRY * qglGetPixelMapfv )(GLenum map, GLfloat *values); void ( APIENTRY * qglGetPixelMapuiv )(GLenum map, GLuint *values); void ( APIENTRY * qglGetPixelMapusv )(GLenum map, GLushort *values); void ( APIENTRY * qglGetPointerv )(GLenum pname, GLvoid* *params); void ( APIENTRY * qglGetPolygonStipple )(GLubyte *mask); const GLubyte * ( APIENTRY * qglGetString )(GLenum name); void ( APIENTRY * qglGetTexEnvfv )(GLenum target, GLenum pname, GLfloat *params); void ( APIENTRY * qglGetTexEnviv )(GLenum target, GLenum pname, GLint *params); void ( APIENTRY * qglGetTexGendv )(GLenum coord, GLenum pname, GLdouble *params); void ( APIENTRY * qglGetTexGenfv )(GLenum coord, GLenum pname, GLfloat *params); void ( APIENTRY * qglGetTexGeniv )(GLenum coord, GLenum pname, GLint *params); void ( APIENTRY * qglGetTexImage )(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); void ( APIENTRY * qglGetTexLevelParameterfv )(GLenum target, GLint level, GLenum pname, GLfloat *params); void ( APIENTRY * qglGetTexLevelParameteriv )(GLenum target, GLint level, GLenum pname, GLint *params); void ( APIENTRY * qglGetTexParameterfv )(GLenum target, GLenum pname, GLfloat *params); void ( APIENTRY * qglGetTexParameteriv )(GLenum target, GLenum pname, GLint *params); void ( APIENTRY * qglHint )(GLenum target, GLenum mode); void ( APIENTRY * qglIndexMask )(GLuint mask); void ( APIENTRY * qglIndexPointer )(GLenum type, GLsizei stride, const GLvoid *pointer); void ( APIENTRY * qglIndexd )(GLdouble c); void ( APIENTRY * qglIndexdv )(const GLdouble *c); void ( APIENTRY * qglIndexf )(GLfloat c); void ( APIENTRY * qglIndexfv )(const GLfloat *c); void ( APIENTRY * qglIndexi )(GLint c); void ( APIENTRY * qglIndexiv )(const GLint *c); void ( APIENTRY * qglIndexs )(GLshort c); void ( APIENTRY * qglIndexsv )(const GLshort *c); void ( APIENTRY * qglIndexub )(GLubyte c); void ( APIENTRY * qglIndexubv )(const GLubyte *c); void ( APIENTRY * qglInitNames )(void); void ( APIENTRY * qglInterleavedArrays )(GLenum format, GLsizei stride, const GLvoid *pointer); GLboolean ( APIENTRY * qglIsEnabled )(GLenum cap); GLboolean ( APIENTRY * qglIsList )(GLuint list); GLboolean ( APIENTRY * qglIsTexture )(GLuint texture); void ( APIENTRY * qglLightModelf )(GLenum pname, GLfloat param); void ( APIENTRY * qglLightModelfv )(GLenum pname, const GLfloat *params); void ( APIENTRY * qglLightModeli )(GLenum pname, GLint param); void ( APIENTRY * qglLightModeliv )(GLenum pname, const GLint *params); void ( APIENTRY * qglLightf )(GLenum light, GLenum pname, GLfloat param); void ( APIENTRY * qglLightfv )(GLenum light, GLenum pname, const GLfloat *params); void ( APIENTRY * qglLighti )(GLenum light, GLenum pname, GLint param); void ( APIENTRY * qglLightiv )(GLenum light, GLenum pname, const GLint *params); void ( APIENTRY * qglLineStipple )(GLint factor, GLushort pattern); void ( APIENTRY * qglLineWidth )(GLfloat width); void ( APIENTRY * qglListBase )(GLuint base); void ( APIENTRY * qglLoadIdentity )(void); void ( APIENTRY * qglLoadMatrixd )(const GLdouble *m); void ( APIENTRY * qglLoadMatrixf )(const GLfloat *m); void ( APIENTRY * qglLoadName )(GLuint name); void ( APIENTRY * qglLogicOp )(GLenum opcode); void ( APIENTRY * qglMap1d )(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); void ( APIENTRY * qglMap1f )(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); void ( APIENTRY * qglMap2d )(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); void ( APIENTRY * qglMap2f )(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); void ( APIENTRY * qglMapGrid1d )(GLint un, GLdouble u1, GLdouble u2); void ( APIENTRY * qglMapGrid1f )(GLint un, GLfloat u1, GLfloat u2); void ( APIENTRY * qglMapGrid2d )(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); void ( APIENTRY * qglMapGrid2f )(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); void ( APIENTRY * qglMaterialf )(GLenum face, GLenum pname, GLfloat param); void ( APIENTRY * qglMaterialfv )(GLenum face, GLenum pname, const GLfloat *params); void ( APIENTRY * qglMateriali )(GLenum face, GLenum pname, GLint param); void ( APIENTRY * qglMaterialiv )(GLenum face, GLenum pname, const GLint *params); void ( APIENTRY * qglMatrixMode )(GLenum mode); void ( APIENTRY * qglMultMatrixd )(const GLdouble *m); void ( APIENTRY * qglMultMatrixf )(const GLfloat *m); void ( APIENTRY * qglNewList )(GLuint list, GLenum mode); void ( APIENTRY * qglNormal3b )(GLbyte nx, GLbyte ny, GLbyte nz); void ( APIENTRY * qglNormal3bv )(const GLbyte *v); void ( APIENTRY * qglNormal3d )(GLdouble nx, GLdouble ny, GLdouble nz); void ( APIENTRY * qglNormal3dv )(const GLdouble *v); void ( APIENTRY * qglNormal3f )(GLfloat nx, GLfloat ny, GLfloat nz); void ( APIENTRY * qglNormal3fv )(const GLfloat *v); void ( APIENTRY * qglNormal3i )(GLint nx, GLint ny, GLint nz); void ( APIENTRY * qglNormal3iv )(const GLint *v); void ( APIENTRY * qglNormal3s )(GLshort nx, GLshort ny, GLshort nz); void ( APIENTRY * qglNormal3sv )(const GLshort *v); void ( APIENTRY * qglNormalPointer )(GLenum type, GLsizei stride, const GLvoid *pointer); void ( APIENTRY * qglOrtho )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); void ( APIENTRY * qglPassThrough )(GLfloat token); void ( APIENTRY * qglPixelMapfv )(GLenum map, GLsizei mapsize, const GLfloat *values); void ( APIENTRY * qglPixelMapuiv )(GLenum map, GLsizei mapsize, const GLuint *values); void ( APIENTRY * qglPixelMapusv )(GLenum map, GLsizei mapsize, const GLushort *values); void ( APIENTRY * qglPixelStoref )(GLenum pname, GLfloat param); void ( APIENTRY * qglPixelStorei )(GLenum pname, GLint param); void ( APIENTRY * qglPixelTransferf )(GLenum pname, GLfloat param); void ( APIENTRY * qglPixelTransferi )(GLenum pname, GLint param); void ( APIENTRY * qglPixelZoom )(GLfloat xfactor, GLfloat yfactor); void ( APIENTRY * qglPointSize )(GLfloat size); void ( APIENTRY * qglPolygonMode )(GLenum face, GLenum mode); void ( APIENTRY * qglPolygonOffset )(GLfloat factor, GLfloat units); void ( APIENTRY * qglPolygonStipple )(const GLubyte *mask); void ( APIENTRY * qglPopAttrib )(void); void ( APIENTRY * qglPopClientAttrib )(void); void ( APIENTRY * qglPopMatrix )(void); void ( APIENTRY * qglPopName )(void); void ( APIENTRY * qglPrioritizeTextures )(GLsizei n, const GLuint *textures, const GLclampf *priorities); void ( APIENTRY * qglPushAttrib )(GLbitfield mask); void ( APIENTRY * qglPushClientAttrib )(GLbitfield mask); void ( APIENTRY * qglPushMatrix )(void); void ( APIENTRY * qglPushName )(GLuint name); void ( APIENTRY * qglRasterPos2d )(GLdouble x, GLdouble y); void ( APIENTRY * qglRasterPos2dv )(const GLdouble *v); void ( APIENTRY * qglRasterPos2f )(GLfloat x, GLfloat y); void ( APIENTRY * qglRasterPos2fv )(const GLfloat *v); void ( APIENTRY * qglRasterPos2i )(GLint x, GLint y); void ( APIENTRY * qglRasterPos2iv )(const GLint *v); void ( APIENTRY * qglRasterPos2s )(GLshort x, GLshort y); void ( APIENTRY * qglRasterPos2sv )(const GLshort *v); void ( APIENTRY * qglRasterPos3d )(GLdouble x, GLdouble y, GLdouble z); void ( APIENTRY * qglRasterPos3dv )(const GLdouble *v); void ( APIENTRY * qglRasterPos3f )(GLfloat x, GLfloat y, GLfloat z); void ( APIENTRY * qglRasterPos3fv )(const GLfloat *v); void ( APIENTRY * qglRasterPos3i )(GLint x, GLint y, GLint z); void ( APIENTRY * qglRasterPos3iv )(const GLint *v); void ( APIENTRY * qglRasterPos3s )(GLshort x, GLshort y, GLshort z); void ( APIENTRY * qglRasterPos3sv )(const GLshort *v); void ( APIENTRY * qglRasterPos4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w); void ( APIENTRY * qglRasterPos4dv )(const GLdouble *v); void ( APIENTRY * qglRasterPos4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w); void ( APIENTRY * qglRasterPos4fv )(const GLfloat *v); void ( APIENTRY * qglRasterPos4i )(GLint x, GLint y, GLint z, GLint w); void ( APIENTRY * qglRasterPos4iv )(const GLint *v); void ( APIENTRY * qglRasterPos4s )(GLshort x, GLshort y, GLshort z, GLshort w); void ( APIENTRY * qglRasterPos4sv )(const GLshort *v); void ( APIENTRY * qglReadBuffer )(GLenum mode); void ( APIENTRY * qglReadPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); void ( APIENTRY * qglRectd )(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); void ( APIENTRY * qglRectdv )(const GLdouble *v1, const GLdouble *v2); void ( APIENTRY * qglRectf )(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); void ( APIENTRY * qglRectfv )(const GLfloat *v1, const GLfloat *v2); void ( APIENTRY * qglRecti )(GLint x1, GLint y1, GLint x2, GLint y2); void ( APIENTRY * qglRectiv )(const GLint *v1, const GLint *v2); void ( APIENTRY * qglRects )(GLshort x1, GLshort y1, GLshort x2, GLshort y2); void ( APIENTRY * qglRectsv )(const GLshort *v1, const GLshort *v2); GLint ( APIENTRY * qglRenderMode )(GLenum mode); void ( APIENTRY * qglRotated )(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); void ( APIENTRY * qglRotatef )(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); void ( APIENTRY * qglScaled )(GLdouble x, GLdouble y, GLdouble z); void ( APIENTRY * qglScalef )(GLfloat x, GLfloat y, GLfloat z); void ( APIENTRY * qglScissor )(GLint x, GLint y, GLsizei width, GLsizei height); void ( APIENTRY * qglSelectBuffer )(GLsizei size, GLuint *buffer); void ( APIENTRY * qglShadeModel )(GLenum mode); void ( APIENTRY * qglStencilFunc )(GLenum func, GLint ref, GLuint mask); void ( APIENTRY * qglStencilMask )(GLuint mask); void ( APIENTRY * qglStencilOp )(GLenum fail, GLenum zfail, GLenum zpass); void ( APIENTRY * qglTexCoord1d )(GLdouble s); void ( APIENTRY * qglTexCoord1dv )(const GLdouble *v); void ( APIENTRY * qglTexCoord1f )(GLfloat s); void ( APIENTRY * qglTexCoord1fv )(const GLfloat *v); void ( APIENTRY * qglTexCoord1i )(GLint s); void ( APIENTRY * qglTexCoord1iv )(const GLint *v); void ( APIENTRY * qglTexCoord1s )(GLshort s); void ( APIENTRY * qglTexCoord1sv )(const GLshort *v); void ( APIENTRY * qglTexCoord2d )(GLdouble s, GLdouble t); void ( APIENTRY * qglTexCoord2dv )(const GLdouble *v); void ( APIENTRY * qglTexCoord2f )(GLfloat s, GLfloat t); void ( APIENTRY * qglTexCoord2fv )(const GLfloat *v); void ( APIENTRY * qglTexCoord2i )(GLint s, GLint t); void ( APIENTRY * qglTexCoord2iv )(const GLint *v); void ( APIENTRY * qglTexCoord2s )(GLshort s, GLshort t); void ( APIENTRY * qglTexCoord2sv )(const GLshort *v); void ( APIENTRY * qglTexCoord3d )(GLdouble s, GLdouble t, GLdouble r); void ( APIENTRY * qglTexCoord3dv )(const GLdouble *v); void ( APIENTRY * qglTexCoord3f )(GLfloat s, GLfloat t, GLfloat r); void ( APIENTRY * qglTexCoord3fv )(const GLfloat *v); void ( APIENTRY * qglTexCoord3i )(GLint s, GLint t, GLint r); void ( APIENTRY * qglTexCoord3iv )(const GLint *v); void ( APIENTRY * qglTexCoord3s )(GLshort s, GLshort t, GLshort r); void ( APIENTRY * qglTexCoord3sv )(const GLshort *v); void ( APIENTRY * qglTexCoord4d )(GLdouble s, GLdouble t, GLdouble r, GLdouble q); void ( APIENTRY * qglTexCoord4dv )(const GLdouble *v); void ( APIENTRY * qglTexCoord4f )(GLfloat s, GLfloat t, GLfloat r, GLfloat q); void ( APIENTRY * qglTexCoord4fv )(const GLfloat *v); void ( APIENTRY * qglTexCoord4i )(GLint s, GLint t, GLint r, GLint q); void ( APIENTRY * qglTexCoord4iv )(const GLint *v); void ( APIENTRY * qglTexCoord4s )(GLshort s, GLshort t, GLshort r, GLshort q); void ( APIENTRY * qglTexCoord4sv )(const GLshort *v); void ( APIENTRY * qglTexCoordPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); void ( APIENTRY * qglTexEnvf )(GLenum target, GLenum pname, GLfloat param); void ( APIENTRY * qglTexEnvfv )(GLenum target, GLenum pname, const GLfloat *params); void ( APIENTRY * qglTexEnvi )(GLenum target, GLenum pname, GLint param); void ( APIENTRY * qglTexEnviv )(GLenum target, GLenum pname, const GLint *params); void ( APIENTRY * qglTexGend )(GLenum coord, GLenum pname, GLdouble param); void ( APIENTRY * qglTexGendv )(GLenum coord, GLenum pname, const GLdouble *params); void ( APIENTRY * qglTexGenf )(GLenum coord, GLenum pname, GLfloat param); void ( APIENTRY * qglTexGenfv )(GLenum coord, GLenum pname, const GLfloat *params); void ( APIENTRY * qglTexGeni )(GLenum coord, GLenum pname, GLint param); void ( APIENTRY * qglTexGeniv )(GLenum coord, GLenum pname, const GLint *params); void ( APIENTRY * qglTexImage1D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); void ( APIENTRY * qglTexImage2D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); void ( APIENTRY * qglTexParameterf )(GLenum target, GLenum pname, GLfloat param); void ( APIENTRY * qglTexParameterfv )(GLenum target, GLenum pname, const GLfloat *params); void ( APIENTRY * qglTexParameteri )(GLenum target, GLenum pname, GLint param); void ( APIENTRY * qglTexParameteriv )(GLenum target, GLenum pname, const GLint *params); void ( APIENTRY * qglTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); void ( APIENTRY * qglTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); void ( APIENTRY * qglTranslated )(GLdouble x, GLdouble y, GLdouble z); void ( APIENTRY * qglTranslatef )(GLfloat x, GLfloat y, GLfloat z); void ( APIENTRY * qglVertex2d )(GLdouble x, GLdouble y); void ( APIENTRY * qglVertex2dv )(const GLdouble *v); void ( APIENTRY * qglVertex2f )(GLfloat x, GLfloat y); void ( APIENTRY * qglVertex2fv )(const GLfloat *v); void ( APIENTRY * qglVertex2i )(GLint x, GLint y); void ( APIENTRY * qglVertex2iv )(const GLint *v); void ( APIENTRY * qglVertex2s )(GLshort x, GLshort y); void ( APIENTRY * qglVertex2sv )(const GLshort *v); void ( APIENTRY * qglVertex3d )(GLdouble x, GLdouble y, GLdouble z); void ( APIENTRY * qglVertex3dv )(const GLdouble *v); void ( APIENTRY * qglVertex3f )(GLfloat x, GLfloat y, GLfloat z); void ( APIENTRY * qglVertex3fv )(const GLfloat *v); void ( APIENTRY * qglVertex3i )(GLint x, GLint y, GLint z); void ( APIENTRY * qglVertex3iv )(const GLint *v); void ( APIENTRY * qglVertex3s )(GLshort x, GLshort y, GLshort z); void ( APIENTRY * qglVertex3sv )(const GLshort *v); void ( APIENTRY * qglVertex4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w); void ( APIENTRY * qglVertex4dv )(const GLdouble *v); void ( APIENTRY * qglVertex4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w); void ( APIENTRY * qglVertex4fv )(const GLfloat *v); void ( APIENTRY * qglVertex4i )(GLint x, GLint y, GLint z, GLint w); void ( APIENTRY * qglVertex4iv )(const GLint *v); void ( APIENTRY * qglVertex4s )(GLshort x, GLshort y, GLshort z, GLshort w); void ( APIENTRY * qglVertex4sv )(const GLshort *v); void ( APIENTRY * qglVertexPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); void ( APIENTRY * qglViewport )(GLint x, GLint y, GLsizei width, GLsizei height); void ( APIENTRY * qglLockArraysEXT)( int, int); void ( APIENTRY * qglUnlockArraysEXT) ( void ); void ( APIENTRY * qglPointParameterfEXT)( GLenum param, GLfloat value ); void ( APIENTRY * qglPointParameterfvEXT)( GLenum param, const GLfloat *value ); void ( APIENTRY * qglColorTableEXT)( int, int, int, int, int, const void * ); void ( APIENTRY * qgl3DfxSetPaletteEXT)( GLuint * ); void ( APIENTRY * qglSelectTextureARB)( GLenum ); void ( APIENTRY * qglMTexCoord2fARB)( GLenum, GLfloat, GLfloat ); void ( APIENTRY * qglMTexCoord3fARB)( GLenum, GLfloat, GLfloat, GLfloat ); void ( APIENTRY * qglActiveTextureARB) ( GLenum ); void ( APIENTRY * qglClientActiveTextureARB) ( GLenum ); void (APIENTRY * qglMultiTexCoord3fvARB) (GLenum, GLfloat *); void * (*qwglGetProcAddress) (const char*); static void ( APIENTRY * dllAccum )(GLenum op, GLfloat value); static void ( APIENTRY * dllAlphaFunc )(GLenum func, GLclampf ref); GLboolean ( APIENTRY * dllAreTexturesResident )(GLsizei n, const GLuint *textures, GLboolean *residences); static void ( APIENTRY * dllArrayElement )(GLint i); static void ( APIENTRY * dllBegin )(GLenum mode); static void ( APIENTRY * dllBindTexture )(GLenum target, GLuint texture); static void ( APIENTRY * dllBitmap )(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); static void ( APIENTRY * dllBlendFunc )(GLenum sfactor, GLenum dfactor); static void ( APIENTRY * dllCallList )(GLuint list); static void ( APIENTRY * dllCallLists )(GLsizei n, GLenum type, const GLvoid *lists); static void ( APIENTRY * dllClear )(GLbitfield mask); static void ( APIENTRY * dllClearAccum )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); static void ( APIENTRY * dllClearColor )(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); static void ( APIENTRY * dllClearDepth )(GLclampd depth); static void ( APIENTRY * dllClearIndex )(GLfloat c); static void ( APIENTRY * dllClearStencil )(GLint s); static void ( APIENTRY * dllClipPlane )(GLenum plane, const GLdouble *equation); static void ( APIENTRY * dllColor3b )(GLbyte red, GLbyte green, GLbyte blue); static void ( APIENTRY * dllColor3bv )(const GLbyte *v); static void ( APIENTRY * dllColor3d )(GLdouble red, GLdouble green, GLdouble blue); static void ( APIENTRY * dllColor3dv )(const GLdouble *v); static void ( APIENTRY * dllColor3f )(GLfloat red, GLfloat green, GLfloat blue); static void ( APIENTRY * dllColor3fv )(const GLfloat *v); static void ( APIENTRY * dllColor3i )(GLint red, GLint green, GLint blue); static void ( APIENTRY * dllColor3iv )(const GLint *v); static void ( APIENTRY * dllColor3s )(GLshort red, GLshort green, GLshort blue); static void ( APIENTRY * dllColor3sv )(const GLshort *v); static void ( APIENTRY * dllColor3ub )(GLubyte red, GLubyte green, GLubyte blue); static void ( APIENTRY * dllColor3ubv )(const GLubyte *v); static void ( APIENTRY * dllColor3ui )(GLuint red, GLuint green, GLuint blue); static void ( APIENTRY * dllColor3uiv )(const GLuint *v); static void ( APIENTRY * dllColor3us )(GLushort red, GLushort green, GLushort blue); static void ( APIENTRY * dllColor3usv )(const GLushort *v); static void ( APIENTRY * dllColor4b )(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); static void ( APIENTRY * dllColor4bv )(const GLbyte *v); static void ( APIENTRY * dllColor4d )(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); static void ( APIENTRY * dllColor4dv )(const GLdouble *v); static void ( APIENTRY * dllColor4f )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); static void ( APIENTRY * dllColor4fv )(const GLfloat *v); static void ( APIENTRY * dllColor4i )(GLint red, GLint green, GLint blue, GLint alpha); static void ( APIENTRY * dllColor4iv )(const GLint *v); static void ( APIENTRY * dllColor4s )(GLshort red, GLshort green, GLshort blue, GLshort alpha); static void ( APIENTRY * dllColor4sv )(const GLshort *v); static void ( APIENTRY * dllColor4ub )(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); static void ( APIENTRY * dllColor4ubv )(const GLubyte *v); static void ( APIENTRY * dllColor4ui )(GLuint red, GLuint green, GLuint blue, GLuint alpha); static void ( APIENTRY * dllColor4uiv )(const GLuint *v); static void ( APIENTRY * dllColor4us )(GLushort red, GLushort green, GLushort blue, GLushort alpha); static void ( APIENTRY * dllColor4usv )(const GLushort *v); static void ( APIENTRY * dllColorMask )(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); static void ( APIENTRY * dllColorMaterial )(GLenum face, GLenum mode); static void ( APIENTRY * dllColorPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); static void ( APIENTRY * dllCopyPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); static void ( APIENTRY * dllCopyTexImage1D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); static void ( APIENTRY * dllCopyTexImage2D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); static void ( APIENTRY * dllCopyTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); static void ( APIENTRY * dllCopyTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); static void ( APIENTRY * dllCullFace )(GLenum mode); static void ( APIENTRY * dllDeleteLists )(GLuint list, GLsizei range); static void ( APIENTRY * dllDeleteTextures )(GLsizei n, const GLuint *textures); static void ( APIENTRY * dllDepthFunc )(GLenum func); static void ( APIENTRY * dllDepthMask )(GLboolean flag); static void ( APIENTRY * dllDepthRange )(GLclampd zNear, GLclampd zFar); static void ( APIENTRY * dllDisable )(GLenum cap); static void ( APIENTRY * dllDisableClientState )(GLenum array); static void ( APIENTRY * dllDrawArrays )(GLenum mode, GLint first, GLsizei count); static void ( APIENTRY * dllDrawBuffer )(GLenum mode); static void ( APIENTRY * dllDrawElements )(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); static void ( APIENTRY * dllDrawPixels )(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); static void ( APIENTRY * dllEdgeFlag )(GLboolean flag); static void ( APIENTRY * dllEdgeFlagPointer )(GLsizei stride, const GLvoid *pointer); static void ( APIENTRY * dllEdgeFlagv )(const GLboolean *flag); static void ( APIENTRY * dllEnable )(GLenum cap); static void ( APIENTRY * dllEnableClientState )(GLenum array); static void ( APIENTRY * dllEnd )(void); static void ( APIENTRY * dllEndList )(void); static void ( APIENTRY * dllEvalCoord1d )(GLdouble u); static void ( APIENTRY * dllEvalCoord1dv )(const GLdouble *u); static void ( APIENTRY * dllEvalCoord1f )(GLfloat u); static void ( APIENTRY * dllEvalCoord1fv )(const GLfloat *u); static void ( APIENTRY * dllEvalCoord2d )(GLdouble u, GLdouble v); static void ( APIENTRY * dllEvalCoord2dv )(const GLdouble *u); static void ( APIENTRY * dllEvalCoord2f )(GLfloat u, GLfloat v); static void ( APIENTRY * dllEvalCoord2fv )(const GLfloat *u); static void ( APIENTRY * dllEvalMesh1 )(GLenum mode, GLint i1, GLint i2); static void ( APIENTRY * dllEvalMesh2 )(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); static void ( APIENTRY * dllEvalPoint1 )(GLint i); static void ( APIENTRY * dllEvalPoint2 )(GLint i, GLint j); static void ( APIENTRY * dllFeedbackBuffer )(GLsizei size, GLenum type, GLfloat *buffer); static void ( APIENTRY * dllFinish )(void); static void ( APIENTRY * dllFlush )(void); static void ( APIENTRY * dllFogf )(GLenum pname, GLfloat param); static void ( APIENTRY * dllFogfv )(GLenum pname, const GLfloat *params); static void ( APIENTRY * dllFogi )(GLenum pname, GLint param); static void ( APIENTRY * dllFogiv )(GLenum pname, const GLint *params); static void ( APIENTRY * dllFrontFace )(GLenum mode); static void ( APIENTRY * dllFrustum )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); GLuint ( APIENTRY * dllGenLists )(GLsizei range); static void ( APIENTRY * dllGenTextures )(GLsizei n, GLuint *textures); static void ( APIENTRY * dllGetBooleanv )(GLenum pname, GLboolean *params); static void ( APIENTRY * dllGetClipPlane )(GLenum plane, GLdouble *equation); static void ( APIENTRY * dllGetDoublev )(GLenum pname, GLdouble *params); GLenum ( APIENTRY * dllGetError )(void); static void ( APIENTRY * dllGetFloatv )(GLenum pname, GLfloat *params); static void ( APIENTRY * dllGetIntegerv )(GLenum pname, GLint *params); static void ( APIENTRY * dllGetLightfv )(GLenum light, GLenum pname, GLfloat *params); static void ( APIENTRY * dllGetLightiv )(GLenum light, GLenum pname, GLint *params); static void ( APIENTRY * dllGetMapdv )(GLenum target, GLenum query, GLdouble *v); static void ( APIENTRY * dllGetMapfv )(GLenum target, GLenum query, GLfloat *v); static void ( APIENTRY * dllGetMapiv )(GLenum target, GLenum query, GLint *v); static void ( APIENTRY * dllGetMaterialfv )(GLenum face, GLenum pname, GLfloat *params); static void ( APIENTRY * dllGetMaterialiv )(GLenum face, GLenum pname, GLint *params); static void ( APIENTRY * dllGetPixelMapfv )(GLenum map, GLfloat *values); static void ( APIENTRY * dllGetPixelMapuiv )(GLenum map, GLuint *values); static void ( APIENTRY * dllGetPixelMapusv )(GLenum map, GLushort *values); static void ( APIENTRY * dllGetPointerv )(GLenum pname, GLvoid* *params); static void ( APIENTRY * dllGetPolygonStipple )(GLubyte *mask); const GLubyte * ( APIENTRY * dllGetString )(GLenum name); static void ( APIENTRY * dllGetTexEnvfv )(GLenum target, GLenum pname, GLfloat *params); static void ( APIENTRY * dllGetTexEnviv )(GLenum target, GLenum pname, GLint *params); static void ( APIENTRY * dllGetTexGendv )(GLenum coord, GLenum pname, GLdouble *params); static void ( APIENTRY * dllGetTexGenfv )(GLenum coord, GLenum pname, GLfloat *params); static void ( APIENTRY * dllGetTexGeniv )(GLenum coord, GLenum pname, GLint *params); static void ( APIENTRY * dllGetTexImage )(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); static void ( APIENTRY * dllGetTexLevelParameterfv )(GLenum target, GLint level, GLenum pname, GLfloat *params); static void ( APIENTRY * dllGetTexLevelParameteriv )(GLenum target, GLint level, GLenum pname, GLint *params); static void ( APIENTRY * dllGetTexParameterfv )(GLenum target, GLenum pname, GLfloat *params); static void ( APIENTRY * dllGetTexParameteriv )(GLenum target, GLenum pname, GLint *params); static void ( APIENTRY * dllHint )(GLenum target, GLenum mode); static void ( APIENTRY * dllIndexMask )(GLuint mask); static void ( APIENTRY * dllIndexPointer )(GLenum type, GLsizei stride, const GLvoid *pointer); static void ( APIENTRY * dllIndexd )(GLdouble c); static void ( APIENTRY * dllIndexdv )(const GLdouble *c); static void ( APIENTRY * dllIndexf )(GLfloat c); static void ( APIENTRY * dllIndexfv )(const GLfloat *c); static void ( APIENTRY * dllIndexi )(GLint c); static void ( APIENTRY * dllIndexiv )(const GLint *c); static void ( APIENTRY * dllIndexs )(GLshort c); static void ( APIENTRY * dllIndexsv )(const GLshort *c); static void ( APIENTRY * dllIndexub )(GLubyte c); static void ( APIENTRY * dllIndexubv )(const GLubyte *c); static void ( APIENTRY * dllInitNames )(void); static void ( APIENTRY * dllInterleavedArrays )(GLenum format, GLsizei stride, const GLvoid *pointer); GLboolean ( APIENTRY * dllIsEnabled )(GLenum cap); GLboolean ( APIENTRY * dllIsList )(GLuint list); GLboolean ( APIENTRY * dllIsTexture )(GLuint texture); static void ( APIENTRY * dllLightModelf )(GLenum pname, GLfloat param); static void ( APIENTRY * dllLightModelfv )(GLenum pname, const GLfloat *params); static void ( APIENTRY * dllLightModeli )(GLenum pname, GLint param); static void ( APIENTRY * dllLightModeliv )(GLenum pname, const GLint *params); static void ( APIENTRY * dllLightf )(GLenum light, GLenum pname, GLfloat param); static void ( APIENTRY * dllLightfv )(GLenum light, GLenum pname, const GLfloat *params); static void ( APIENTRY * dllLighti )(GLenum light, GLenum pname, GLint param); static void ( APIENTRY * dllLightiv )(GLenum light, GLenum pname, const GLint *params); static void ( APIENTRY * dllLineStipple )(GLint factor, GLushort pattern); static void ( APIENTRY * dllLineWidth )(GLfloat width); static void ( APIENTRY * dllListBase )(GLuint base); static void ( APIENTRY * dllLoadIdentity )(void); static void ( APIENTRY * dllLoadMatrixd )(const GLdouble *m); static void ( APIENTRY * dllLoadMatrixf )(const GLfloat *m); static void ( APIENTRY * dllLoadName )(GLuint name); static void ( APIENTRY * dllLogicOp )(GLenum opcode); static void ( APIENTRY * dllMap1d )(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); static void ( APIENTRY * dllMap1f )(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); static void ( APIENTRY * dllMap2d )(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); static void ( APIENTRY * dllMap2f )(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); static void ( APIENTRY * dllMapGrid1d )(GLint un, GLdouble u1, GLdouble u2); static void ( APIENTRY * dllMapGrid1f )(GLint un, GLfloat u1, GLfloat u2); static void ( APIENTRY * dllMapGrid2d )(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); static void ( APIENTRY * dllMapGrid2f )(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); static void ( APIENTRY * dllMaterialf )(GLenum face, GLenum pname, GLfloat param); static void ( APIENTRY * dllMaterialfv )(GLenum face, GLenum pname, const GLfloat *params); static void ( APIENTRY * dllMateriali )(GLenum face, GLenum pname, GLint param); static void ( APIENTRY * dllMaterialiv )(GLenum face, GLenum pname, const GLint *params); static void ( APIENTRY * dllMatrixMode )(GLenum mode); static void ( APIENTRY * dllMultMatrixd )(const GLdouble *m); static void ( APIENTRY * dllMultMatrixf )(const GLfloat *m); static void ( APIENTRY * dllNewList )(GLuint list, GLenum mode); static void ( APIENTRY * dllNormal3b )(GLbyte nx, GLbyte ny, GLbyte nz); static void ( APIENTRY * dllNormal3bv )(const GLbyte *v); static void ( APIENTRY * dllNormal3d )(GLdouble nx, GLdouble ny, GLdouble nz); static void ( APIENTRY * dllNormal3dv )(const GLdouble *v); static void ( APIENTRY * dllNormal3f )(GLfloat nx, GLfloat ny, GLfloat nz); static void ( APIENTRY * dllNormal3fv )(const GLfloat *v); static void ( APIENTRY * dllNormal3i )(GLint nx, GLint ny, GLint nz); static void ( APIENTRY * dllNormal3iv )(const GLint *v); static void ( APIENTRY * dllNormal3s )(GLshort nx, GLshort ny, GLshort nz); static void ( APIENTRY * dllNormal3sv )(const GLshort *v); static void ( APIENTRY * dllNormalPointer )(GLenum type, GLsizei stride, const GLvoid *pointer); static void ( APIENTRY * dllOrtho )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); static void ( APIENTRY * dllPassThrough )(GLfloat token); static void ( APIENTRY * dllPixelMapfv )(GLenum map, GLsizei mapsize, const GLfloat *values); static void ( APIENTRY * dllPixelMapuiv )(GLenum map, GLsizei mapsize, const GLuint *values); static void ( APIENTRY * dllPixelMapusv )(GLenum map, GLsizei mapsize, const GLushort *values); static void ( APIENTRY * dllPixelStoref )(GLenum pname, GLfloat param); static void ( APIENTRY * dllPixelStorei )(GLenum pname, GLint param); static void ( APIENTRY * dllPixelTransferf )(GLenum pname, GLfloat param); static void ( APIENTRY * dllPixelTransferi )(GLenum pname, GLint param); static void ( APIENTRY * dllPixelZoom )(GLfloat xfactor, GLfloat yfactor); static void ( APIENTRY * dllPointSize )(GLfloat size); static void ( APIENTRY * dllPolygonMode )(GLenum face, GLenum mode); static void ( APIENTRY * dllPolygonOffset )(GLfloat factor, GLfloat units); static void ( APIENTRY * dllPolygonStipple )(const GLubyte *mask); static void ( APIENTRY * dllPopAttrib )(void); static void ( APIENTRY * dllPopClientAttrib )(void); static void ( APIENTRY * dllPopMatrix )(void); static void ( APIENTRY * dllPopName )(void); static void ( APIENTRY * dllPrioritizeTextures )(GLsizei n, const GLuint *textures, const GLclampf *priorities); static void ( APIENTRY * dllPushAttrib )(GLbitfield mask); static void ( APIENTRY * dllPushClientAttrib )(GLbitfield mask); static void ( APIENTRY * dllPushMatrix )(void); static void ( APIENTRY * dllPushName )(GLuint name); static void ( APIENTRY * dllRasterPos2d )(GLdouble x, GLdouble y); static void ( APIENTRY * dllRasterPos2dv )(const GLdouble *v); static void ( APIENTRY * dllRasterPos2f )(GLfloat x, GLfloat y); static void ( APIENTRY * dllRasterPos2fv )(const GLfloat *v); static void ( APIENTRY * dllRasterPos2i )(GLint x, GLint y); static void ( APIENTRY * dllRasterPos2iv )(const GLint *v); static void ( APIENTRY * dllRasterPos2s )(GLshort x, GLshort y); static void ( APIENTRY * dllRasterPos2sv )(const GLshort *v); static void ( APIENTRY * dllRasterPos3d )(GLdouble x, GLdouble y, GLdouble z); static void ( APIENTRY * dllRasterPos3dv )(const GLdouble *v); static void ( APIENTRY * dllRasterPos3f )(GLfloat x, GLfloat y, GLfloat z); static void ( APIENTRY * dllRasterPos3fv )(const GLfloat *v); static void ( APIENTRY * dllRasterPos3i )(GLint x, GLint y, GLint z); static void ( APIENTRY * dllRasterPos3iv )(const GLint *v); static void ( APIENTRY * dllRasterPos3s )(GLshort x, GLshort y, GLshort z); static void ( APIENTRY * dllRasterPos3sv )(const GLshort *v); static void ( APIENTRY * dllRasterPos4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w); static void ( APIENTRY * dllRasterPos4dv )(const GLdouble *v); static void ( APIENTRY * dllRasterPos4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w); static void ( APIENTRY * dllRasterPos4fv )(const GLfloat *v); static void ( APIENTRY * dllRasterPos4i )(GLint x, GLint y, GLint z, GLint w); static void ( APIENTRY * dllRasterPos4iv )(const GLint *v); static void ( APIENTRY * dllRasterPos4s )(GLshort x, GLshort y, GLshort z, GLshort w); static void ( APIENTRY * dllRasterPos4sv )(const GLshort *v); static void ( APIENTRY * dllReadBuffer )(GLenum mode); static void ( APIENTRY * dllReadPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); static void ( APIENTRY * dllRectd )(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); static void ( APIENTRY * dllRectdv )(const GLdouble *v1, const GLdouble *v2); static void ( APIENTRY * dllRectf )(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); static void ( APIENTRY * dllRectfv )(const GLfloat *v1, const GLfloat *v2); static void ( APIENTRY * dllRecti )(GLint x1, GLint y1, GLint x2, GLint y2); static void ( APIENTRY * dllRectiv )(const GLint *v1, const GLint *v2); static void ( APIENTRY * dllRects )(GLshort x1, GLshort y1, GLshort x2, GLshort y2); static void ( APIENTRY * dllRectsv )(const GLshort *v1, const GLshort *v2); GLint ( APIENTRY * dllRenderMode )(GLenum mode); static void ( APIENTRY * dllRotated )(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); static void ( APIENTRY * dllRotatef )(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); static void ( APIENTRY * dllScaled )(GLdouble x, GLdouble y, GLdouble z); static void ( APIENTRY * dllScalef )(GLfloat x, GLfloat y, GLfloat z); static void ( APIENTRY * dllScissor )(GLint x, GLint y, GLsizei width, GLsizei height); static void ( APIENTRY * dllSelectBuffer )(GLsizei size, GLuint *buffer); static void ( APIENTRY * dllShadeModel )(GLenum mode); static void ( APIENTRY * dllStencilFunc )(GLenum func, GLint ref, GLuint mask); static void ( APIENTRY * dllStencilMask )(GLuint mask); static void ( APIENTRY * dllStencilOp )(GLenum fail, GLenum zfail, GLenum zpass); static void ( APIENTRY * dllTexCoord1d )(GLdouble s); static void ( APIENTRY * dllTexCoord1dv )(const GLdouble *v); static void ( APIENTRY * dllTexCoord1f )(GLfloat s); static void ( APIENTRY * dllTexCoord1fv )(const GLfloat *v); static void ( APIENTRY * dllTexCoord1i )(GLint s); static void ( APIENTRY * dllTexCoord1iv )(const GLint *v); static void ( APIENTRY * dllTexCoord1s )(GLshort s); static void ( APIENTRY * dllTexCoord1sv )(const GLshort *v); static void ( APIENTRY * dllTexCoord2d )(GLdouble s, GLdouble t); static void ( APIENTRY * dllTexCoord2dv )(const GLdouble *v); static void ( APIENTRY * dllTexCoord2f )(GLfloat s, GLfloat t); static void ( APIENTRY * dllTexCoord2fv )(const GLfloat *v); static void ( APIENTRY * dllTexCoord2i )(GLint s, GLint t); static void ( APIENTRY * dllTexCoord2iv )(const GLint *v); static void ( APIENTRY * dllTexCoord2s )(GLshort s, GLshort t); static void ( APIENTRY * dllTexCoord2sv )(const GLshort *v); static void ( APIENTRY * dllTexCoord3d )(GLdouble s, GLdouble t, GLdouble r); static void ( APIENTRY * dllTexCoord3dv )(const GLdouble *v); static void ( APIENTRY * dllTexCoord3f )(GLfloat s, GLfloat t, GLfloat r); static void ( APIENTRY * dllTexCoord3fv )(const GLfloat *v); static void ( APIENTRY * dllTexCoord3i )(GLint s, GLint t, GLint r); static void ( APIENTRY * dllTexCoord3iv )(const GLint *v); static void ( APIENTRY * dllTexCoord3s )(GLshort s, GLshort t, GLshort r); static void ( APIENTRY * dllTexCoord3sv )(const GLshort *v); static void ( APIENTRY * dllTexCoord4d )(GLdouble s, GLdouble t, GLdouble r, GLdouble q); static void ( APIENTRY * dllTexCoord4dv )(const GLdouble *v); static void ( APIENTRY * dllTexCoord4f )(GLfloat s, GLfloat t, GLfloat r, GLfloat q); static void ( APIENTRY * dllTexCoord4fv )(const GLfloat *v); static void ( APIENTRY * dllTexCoord4i )(GLint s, GLint t, GLint r, GLint q); static void ( APIENTRY * dllTexCoord4iv )(const GLint *v); static void ( APIENTRY * dllTexCoord4s )(GLshort s, GLshort t, GLshort r, GLshort q); static void ( APIENTRY * dllTexCoord4sv )(const GLshort *v); static void ( APIENTRY * dllTexCoordPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); static void ( APIENTRY * dllTexEnvf )(GLenum target, GLenum pname, GLfloat param); static void ( APIENTRY * dllTexEnvfv )(GLenum target, GLenum pname, const GLfloat *params); static void ( APIENTRY * dllTexEnvi )(GLenum target, GLenum pname, GLint param); static void ( APIENTRY * dllTexEnviv )(GLenum target, GLenum pname, const GLint *params); static void ( APIENTRY * dllTexGend )(GLenum coord, GLenum pname, GLdouble param); static void ( APIENTRY * dllTexGendv )(GLenum coord, GLenum pname, const GLdouble *params); static void ( APIENTRY * dllTexGenf )(GLenum coord, GLenum pname, GLfloat param); static void ( APIENTRY * dllTexGenfv )(GLenum coord, GLenum pname, const GLfloat *params); static void ( APIENTRY * dllTexGeni )(GLenum coord, GLenum pname, GLint param); static void ( APIENTRY * dllTexGeniv )(GLenum coord, GLenum pname, const GLint *params); static void ( APIENTRY * dllTexImage1D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); static void ( APIENTRY * dllTexImage2D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); static void ( APIENTRY * dllTexParameterf )(GLenum target, GLenum pname, GLfloat param); static void ( APIENTRY * dllTexParameterfv )(GLenum target, GLenum pname, const GLfloat *params); static void ( APIENTRY * dllTexParameteri )(GLenum target, GLenum pname, GLint param); static void ( APIENTRY * dllTexParameteriv )(GLenum target, GLenum pname, const GLint *params); static void ( APIENTRY * dllTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); static void ( APIENTRY * dllTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); static void ( APIENTRY * dllTranslated )(GLdouble x, GLdouble y, GLdouble z); static void ( APIENTRY * dllTranslatef )(GLfloat x, GLfloat y, GLfloat z); static void ( APIENTRY * dllVertex2d )(GLdouble x, GLdouble y); static void ( APIENTRY * dllVertex2dv )(const GLdouble *v); static void ( APIENTRY * dllVertex2f )(GLfloat x, GLfloat y); static void ( APIENTRY * dllVertex2fv )(const GLfloat *v); static void ( APIENTRY * dllVertex2i )(GLint x, GLint y); static void ( APIENTRY * dllVertex2iv )(const GLint *v); static void ( APIENTRY * dllVertex2s )(GLshort x, GLshort y); static void ( APIENTRY * dllVertex2sv )(const GLshort *v); static void ( APIENTRY * dllVertex3d )(GLdouble x, GLdouble y, GLdouble z); static void ( APIENTRY * dllVertex3dv )(const GLdouble *v); static void ( APIENTRY * dllVertex3f )(GLfloat x, GLfloat y, GLfloat z); static void ( APIENTRY * dllVertex3fv )(const GLfloat *v); static void ( APIENTRY * dllVertex3i )(GLint x, GLint y, GLint z); static void ( APIENTRY * dllVertex3iv )(const GLint *v); static void ( APIENTRY * dllVertex3s )(GLshort x, GLshort y, GLshort z); static void ( APIENTRY * dllVertex3sv )(const GLshort *v); static void ( APIENTRY * dllVertex4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w); static void ( APIENTRY * dllVertex4dv )(const GLdouble *v); static void ( APIENTRY * dllVertex4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w); static void ( APIENTRY * dllVertex4fv )(const GLfloat *v); static void ( APIENTRY * dllVertex4i )(GLint x, GLint y, GLint z, GLint w); static void ( APIENTRY * dllVertex4iv )(const GLint *v); static void ( APIENTRY * dllVertex4s )(GLshort x, GLshort y, GLshort z, GLshort w); static void ( APIENTRY * dllVertex4sv )(const GLshort *v); static void ( APIENTRY * dllVertexPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); static void ( APIENTRY * dllViewport )(GLint x, GLint y, GLsizei width, GLsizei height); static void APIENTRY logAccum(GLenum op, GLfloat value) { fprintf( glw_state.log_fp, "glAccum\n" ); dllAccum( op, value ); } static void APIENTRY logAlphaFunc(GLenum func, GLclampf ref) { fprintf( glw_state.log_fp, "glAlphaFunc( 0x%x, %f )\n", func, ref ); dllAlphaFunc( func, ref ); } static GLboolean APIENTRY logAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences) { fprintf( glw_state.log_fp, "glAreTexturesResident\n" ); return dllAreTexturesResident( n, textures, residences ); } static void APIENTRY logArrayElement(GLint i) { fprintf( glw_state.log_fp, "glArrayElement\n" ); dllArrayElement( i ); } static void APIENTRY logBegin(GLenum mode) { fprintf( glw_state.log_fp, "glBegin( 0x%x )\n", mode ); dllBegin( mode ); } static void APIENTRY logBindTexture(GLenum target, GLuint texture) { fprintf( glw_state.log_fp, "glBindTexture( 0x%x, %u )\n", target, texture ); dllBindTexture( target, texture ); } static void APIENTRY logBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap) { fprintf( glw_state.log_fp, "glBitmap\n" ); dllBitmap( width, height, xorig, yorig, xmove, ymove, bitmap ); } static void APIENTRY logBlendFunc(GLenum sfactor, GLenum dfactor) { fprintf( glw_state.log_fp, "glBlendFunc( 0x%x, 0x%x )\n", sfactor, dfactor ); dllBlendFunc( sfactor, dfactor ); } static void APIENTRY logCallList(GLuint list) { fprintf( glw_state.log_fp, "glCallList( %u )\n", list ); dllCallList( list ); } static void APIENTRY logCallLists(GLsizei n, GLenum type, const void *lists) { fprintf( glw_state.log_fp, "glCallLists\n" ); dllCallLists( n, type, lists ); } static void APIENTRY logClear(GLbitfield mask) { fprintf( glw_state.log_fp, "glClear\n" ); dllClear( mask ); } static void APIENTRY logClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { fprintf( glw_state.log_fp, "glClearAccum\n" ); dllClearAccum( red, green, blue, alpha ); } static void APIENTRY logClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { fprintf( glw_state.log_fp, "glClearColor\n" ); dllClearColor( red, green, blue, alpha ); } static void APIENTRY logClearDepth(GLclampd depth) { fprintf( glw_state.log_fp, "glClearDepth\n" ); dllClearDepth( depth ); } static void APIENTRY logClearIndex(GLfloat c) { fprintf( glw_state.log_fp, "glClearIndex\n" ); dllClearIndex( c ); } static void APIENTRY logClearStencil(GLint s) { fprintf( glw_state.log_fp, "glClearStencil\n" ); dllClearStencil( s ); } static void APIENTRY logClipPlane(GLenum plane, const GLdouble *equation) { fprintf( glw_state.log_fp, "glClipPlane\n" ); dllClipPlane( plane, equation ); } static void APIENTRY logColor3b(GLbyte red, GLbyte green, GLbyte blue) { fprintf( glw_state.log_fp, "glColor3b\n" ); dllColor3b( red, green, blue ); } static void APIENTRY logColor3bv(const GLbyte *v) { fprintf( glw_state.log_fp, "glColor3bv\n" ); dllColor3bv( v ); } static void APIENTRY logColor3d(GLdouble red, GLdouble green, GLdouble blue) { fprintf( glw_state.log_fp, "glColor3d\n" ); dllColor3d( red, green, blue ); } static void APIENTRY logColor3dv(const GLdouble *v) { fprintf( glw_state.log_fp, "glColor3dv\n" ); dllColor3dv( v ); } static void APIENTRY logColor3f(GLfloat red, GLfloat green, GLfloat blue) { fprintf( glw_state.log_fp, "glColor3f\n" ); dllColor3f( red, green, blue ); } static void APIENTRY logColor3fv(const GLfloat *v) { fprintf( glw_state.log_fp, "glColor3fv\n" ); dllColor3fv( v ); } static void APIENTRY logColor3i(GLint red, GLint green, GLint blue) { fprintf( glw_state.log_fp, "glColor3i\n" ); dllColor3i( red, green, blue ); } static void APIENTRY logColor3iv(const GLint *v) { fprintf( glw_state.log_fp, "glColor3iv\n" ); dllColor3iv( v ); } static void APIENTRY logColor3s(GLshort red, GLshort green, GLshort blue) { fprintf( glw_state.log_fp, "glColor3s\n" ); dllColor3s( red, green, blue ); } static void APIENTRY logColor3sv(const GLshort *v) { fprintf( glw_state.log_fp, "glColor3sv\n" ); dllColor3sv( v ); } static void APIENTRY logColor3ub(GLubyte red, GLubyte green, GLubyte blue) { fprintf( glw_state.log_fp, "glColor3ub\n" ); dllColor3ub( red, green, blue ); } static void APIENTRY logColor3ubv(const GLubyte *v) { fprintf( glw_state.log_fp, "glColor3ubv\n" ); dllColor3ubv( v ); } #define SIG( x ) fprintf( glw_state.log_fp, x "\n" ) static void APIENTRY logColor3ui(GLuint red, GLuint green, GLuint blue) { SIG( "glColor3ui" ); dllColor3ui( red, green, blue ); } static void APIENTRY logColor3uiv(const GLuint *v) { SIG( "glColor3uiv" ); dllColor3uiv( v ); } static void APIENTRY logColor3us(GLushort red, GLushort green, GLushort blue) { SIG( "glColor3us" ); dllColor3us( red, green, blue ); } static void APIENTRY logColor3usv(const GLushort *v) { SIG( "glColor3usv" ); dllColor3usv( v ); } static void APIENTRY logColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha) { SIG( "glColor4b" ); dllColor4b( red, green, blue, alpha ); } static void APIENTRY logColor4bv(const GLbyte *v) { SIG( "glColor4bv" ); dllColor4bv( v ); } static void APIENTRY logColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha) { SIG( "glColor4d" ); dllColor4d( red, green, blue, alpha ); } static void APIENTRY logColor4dv(const GLdouble *v) { SIG( "glColor4dv" ); dllColor4dv( v ); } static void APIENTRY logColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { fprintf( glw_state.log_fp, "glColor4f( %f,%f,%f,%f )\n", red, green, blue, alpha ); dllColor4f( red, green, blue, alpha ); } static void APIENTRY logColor4fv(const GLfloat *v) { fprintf( glw_state.log_fp, "glColor4fv( %f,%f,%f,%f )\n", v[0], v[1], v[2], v[3] ); dllColor4fv( v ); } static void APIENTRY logColor4i(GLint red, GLint green, GLint blue, GLint alpha) { SIG( "glColor4i" ); dllColor4i( red, green, blue, alpha ); } static void APIENTRY logColor4iv(const GLint *v) { SIG( "glColor4iv" ); dllColor4iv( v ); } static void APIENTRY logColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha) { SIG( "glColor4s" ); dllColor4s( red, green, blue, alpha ); } static void APIENTRY logColor4sv(const GLshort *v) { SIG( "glColor4sv" ); dllColor4sv( v ); } static void APIENTRY logColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) { SIG( "glColor4b" ); dllColor4b( red, green, blue, alpha ); } static void APIENTRY logColor4ubv(const GLubyte *v) { SIG( "glColor4ubv" ); dllColor4ubv( v ); } static void APIENTRY logColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha) { SIG( "glColor4ui" ); dllColor4ui( red, green, blue, alpha ); } static void APIENTRY logColor4uiv(const GLuint *v) { SIG( "glColor4uiv" ); dllColor4uiv( v ); } static void APIENTRY logColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha) { SIG( "glColor4us" ); dllColor4us( red, green, blue, alpha ); } static void APIENTRY logColor4usv(const GLushort *v) { SIG( "glColor4usv" ); dllColor4usv( v ); } static void APIENTRY logColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { SIG( "glColorMask" ); dllColorMask( red, green, blue, alpha ); } static void APIENTRY logColorMaterial(GLenum face, GLenum mode) { SIG( "glColorMaterial" ); dllColorMaterial( face, mode ); } static void APIENTRY logColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) { SIG( "glColorPointer" ); dllColorPointer( size, type, stride, pointer ); } static void APIENTRY logCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type) { SIG( "glCopyPixels" ); dllCopyPixels( x, y, width, height, type ); } static void APIENTRY logCopyTexImage1D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border) { SIG( "glCopyTexImage1D" ); dllCopyTexImage1D( target, level, internalFormat, x, y, width, border ); } static void APIENTRY logCopyTexImage2D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { SIG( "glCopyTexImage2D" ); dllCopyTexImage2D( target, level, internalFormat, x, y, width, height, border ); } static void APIENTRY logCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) { SIG( "glCopyTexSubImage1D" ); dllCopyTexSubImage1D( target, level, xoffset, x, y, width ); } static void APIENTRY logCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { SIG( "glCopyTexSubImage2D" ); dllCopyTexSubImage2D( target, level, xoffset, yoffset, x, y, width, height ); } static void APIENTRY logCullFace(GLenum mode) { SIG( "glCullFace" ); dllCullFace( mode ); } static void APIENTRY logDeleteLists(GLuint list, GLsizei range) { SIG( "glDeleteLists" ); dllDeleteLists( list, range ); } static void APIENTRY logDeleteTextures(GLsizei n, const GLuint *textures) { SIG( "glDeleteTextures" ); dllDeleteTextures( n, textures ); } static void APIENTRY logDepthFunc(GLenum func) { SIG( "glDepthFunc" ); dllDepthFunc( func ); } static void APIENTRY logDepthMask(GLboolean flag) { SIG( "glDepthMask" ); dllDepthMask( flag ); } static void APIENTRY logDepthRange(GLclampd zNear, GLclampd zFar) { SIG( "glDepthRange" ); dllDepthRange( zNear, zFar ); } static void APIENTRY logDisable(GLenum cap) { fprintf( glw_state.log_fp, "glDisable( 0x%x )\n", cap ); dllDisable( cap ); } static void APIENTRY logDisableClientState(GLenum array) { SIG( "glDisableClientState" ); dllDisableClientState( array ); } static void APIENTRY logDrawArrays(GLenum mode, GLint first, GLsizei count) { SIG( "glDrawArrays" ); dllDrawArrays( mode, first, count ); } static void APIENTRY logDrawBuffer(GLenum mode) { SIG( "glDrawBuffer" ); dllDrawBuffer( mode ); } static void APIENTRY logDrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) { SIG( "glDrawElements" ); dllDrawElements( mode, count, type, indices ); } static void APIENTRY logDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) { SIG( "glDrawPixels" ); dllDrawPixels( width, height, format, type, pixels ); } static void APIENTRY logEdgeFlag(GLboolean flag) { SIG( "glEdgeFlag" ); dllEdgeFlag( flag ); } static void APIENTRY logEdgeFlagPointer(GLsizei stride, const void *pointer) { SIG( "glEdgeFlagPointer" ); dllEdgeFlagPointer( stride, pointer ); } static void APIENTRY logEdgeFlagv(const GLboolean *flag) { SIG( "glEdgeFlagv" ); dllEdgeFlagv( flag ); } static void APIENTRY logEnable(GLenum cap) { fprintf( glw_state.log_fp, "glEnable( 0x%x )\n", cap ); dllEnable( cap ); } static void APIENTRY logEnableClientState(GLenum array) { SIG( "glEnableClientState" ); dllEnableClientState( array ); } static void APIENTRY logEnd(void) { SIG( "glEnd" ); dllEnd(); } static void APIENTRY logEndList(void) { SIG( "glEndList" ); dllEndList(); } static void APIENTRY logEvalCoord1d(GLdouble u) { SIG( "glEvalCoord1d" ); dllEvalCoord1d( u ); } static void APIENTRY logEvalCoord1dv(const GLdouble *u) { SIG( "glEvalCoord1dv" ); dllEvalCoord1dv( u ); } static void APIENTRY logEvalCoord1f(GLfloat u) { SIG( "glEvalCoord1f" ); dllEvalCoord1f( u ); } static void APIENTRY logEvalCoord1fv(const GLfloat *u) { SIG( "glEvalCoord1fv" ); dllEvalCoord1fv( u ); } static void APIENTRY logEvalCoord2d(GLdouble u, GLdouble v) { SIG( "glEvalCoord2d" ); dllEvalCoord2d( u, v ); } static void APIENTRY logEvalCoord2dv(const GLdouble *u) { SIG( "glEvalCoord2dv" ); dllEvalCoord2dv( u ); } static void APIENTRY logEvalCoord2f(GLfloat u, GLfloat v) { SIG( "glEvalCoord2f" ); dllEvalCoord2f( u, v ); } static void APIENTRY logEvalCoord2fv(const GLfloat *u) { SIG( "glEvalCoord2fv" ); dllEvalCoord2fv( u ); } static void APIENTRY logEvalMesh1(GLenum mode, GLint i1, GLint i2) { SIG( "glEvalMesh1" ); dllEvalMesh1( mode, i1, i2 ); } static void APIENTRY logEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) { SIG( "glEvalMesh2" ); dllEvalMesh2( mode, i1, i2, j1, j2 ); } static void APIENTRY logEvalPoint1(GLint i) { SIG( "glEvalPoint1" ); dllEvalPoint1( i ); } static void APIENTRY logEvalPoint2(GLint i, GLint j) { SIG( "glEvalPoint2" ); dllEvalPoint2( i, j ); } static void APIENTRY logFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer) { SIG( "glFeedbackBuffer" ); dllFeedbackBuffer( size, type, buffer ); } static void APIENTRY logFinish(void) { SIG( "glFinish" ); dllFinish(); } static void APIENTRY logFlush(void) { SIG( "glFlush" ); dllFlush(); } static void APIENTRY logFogf(GLenum pname, GLfloat param) { SIG( "glFogf" ); dllFogf( pname, param ); } static void APIENTRY logFogfv(GLenum pname, const GLfloat *params) { SIG( "glFogfv" ); dllFogfv( pname, params ); } static void APIENTRY logFogi(GLenum pname, GLint param) { SIG( "glFogi" ); dllFogi( pname, param ); } static void APIENTRY logFogiv(GLenum pname, const GLint *params) { SIG( "glFogiv" ); dllFogiv( pname, params ); } static void APIENTRY logFrontFace(GLenum mode) { SIG( "glFrontFace" ); dllFrontFace( mode ); } static void APIENTRY logFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) { SIG( "glFrustum" ); dllFrustum( left, right, bottom, top, zNear, zFar ); } static GLuint APIENTRY logGenLists(GLsizei range) { SIG( "glGenLists" ); return dllGenLists( range ); } static void APIENTRY logGenTextures(GLsizei n, GLuint *textures) { SIG( "glGenTextures" ); dllGenTextures( n, textures ); } static void APIENTRY logGetBooleanv(GLenum pname, GLboolean *params) { SIG( "glGetBooleanv" ); dllGetBooleanv( pname, params ); } static void APIENTRY logGetClipPlane(GLenum plane, GLdouble *equation) { SIG( "glGetClipPlane" ); dllGetClipPlane( plane, equation ); } static void APIENTRY logGetDoublev(GLenum pname, GLdouble *params) { SIG( "glGetDoublev" ); dllGetDoublev( pname, params ); } static GLenum APIENTRY logGetError(void) { SIG( "glGetError" ); return dllGetError(); } static void APIENTRY logGetFloatv(GLenum pname, GLfloat *params) { SIG( "glGetFloatv" ); dllGetFloatv( pname, params ); } static void APIENTRY logGetIntegerv(GLenum pname, GLint *params) { SIG( "glGetIntegerv" ); dllGetIntegerv( pname, params ); } static void APIENTRY logGetLightfv(GLenum light, GLenum pname, GLfloat *params) { SIG( "glGetLightfv" ); dllGetLightfv( light, pname, params ); } static void APIENTRY logGetLightiv(GLenum light, GLenum pname, GLint *params) { SIG( "glGetLightiv" ); dllGetLightiv( light, pname, params ); } static void APIENTRY logGetMapdv(GLenum target, GLenum query, GLdouble *v) { SIG( "glGetMapdv" ); dllGetMapdv( target, query, v ); } static void APIENTRY logGetMapfv(GLenum target, GLenum query, GLfloat *v) { SIG( "glGetMapfv" ); dllGetMapfv( target, query, v ); } static void APIENTRY logGetMapiv(GLenum target, GLenum query, GLint *v) { SIG( "glGetMapiv" ); dllGetMapiv( target, query, v ); } static void APIENTRY logGetMaterialfv(GLenum face, GLenum pname, GLfloat *params) { SIG( "glGetMaterialfv" ); dllGetMaterialfv( face, pname, params ); } static void APIENTRY logGetMaterialiv(GLenum face, GLenum pname, GLint *params) { SIG( "glGetMaterialiv" ); dllGetMaterialiv( face, pname, params ); } static void APIENTRY logGetPixelMapfv(GLenum map, GLfloat *values) { SIG( "glGetPixelMapfv" ); dllGetPixelMapfv( map, values ); } static void APIENTRY logGetPixelMapuiv(GLenum map, GLuint *values) { SIG( "glGetPixelMapuiv" ); dllGetPixelMapuiv( map, values ); } static void APIENTRY logGetPixelMapusv(GLenum map, GLushort *values) { SIG( "glGetPixelMapusv" ); dllGetPixelMapusv( map, values ); } static void APIENTRY logGetPointerv(GLenum pname, GLvoid* *params) { SIG( "glGetPointerv" ); dllGetPointerv( pname, params ); } static void APIENTRY logGetPolygonStipple(GLubyte *mask) { SIG( "glGetPolygonStipple" ); dllGetPolygonStipple( mask ); } static const GLubyte * APIENTRY logGetString(GLenum name) { SIG( "glGetString" ); return dllGetString( name ); } static void APIENTRY logGetTexEnvfv(GLenum target, GLenum pname, GLfloat *params) { SIG( "glGetTexEnvfv" ); dllGetTexEnvfv( target, pname, params ); } static void APIENTRY logGetTexEnviv(GLenum target, GLenum pname, GLint *params) { SIG( "glGetTexEnviv" ); dllGetTexEnviv( target, pname, params ); } static void APIENTRY logGetTexGendv(GLenum coord, GLenum pname, GLdouble *params) { SIG( "glGetTexGendv" ); dllGetTexGendv( coord, pname, params ); } static void APIENTRY logGetTexGenfv(GLenum coord, GLenum pname, GLfloat *params) { SIG( "glGetTexGenfv" ); dllGetTexGenfv( coord, pname, params ); } static void APIENTRY logGetTexGeniv(GLenum coord, GLenum pname, GLint *params) { SIG( "glGetTexGeniv" ); dllGetTexGeniv( coord, pname, params ); } static void APIENTRY logGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, void *pixels) { SIG( "glGetTexImage" ); dllGetTexImage( target, level, format, type, pixels ); } static void APIENTRY logGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params ) { SIG( "glGetTexLevelParameterfv" ); dllGetTexLevelParameterfv( target, level, pname, params ); } static void APIENTRY logGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) { SIG( "glGetTexLevelParameteriv" ); dllGetTexLevelParameteriv( target, level, pname, params ); } static void APIENTRY logGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params) { SIG( "glGetTexParameterfv" ); dllGetTexParameterfv( target, pname, params ); } static void APIENTRY logGetTexParameteriv(GLenum target, GLenum pname, GLint *params) { SIG( "glGetTexParameteriv" ); dllGetTexParameteriv( target, pname, params ); } static void APIENTRY logHint(GLenum target, GLenum mode) { fprintf( glw_state.log_fp, "glHint( 0x%x, 0x%x )\n", target, mode ); dllHint( target, mode ); } static void APIENTRY logIndexMask(GLuint mask) { SIG( "glIndexMask" ); dllIndexMask( mask ); } static void APIENTRY logIndexPointer(GLenum type, GLsizei stride, const void *pointer) { SIG( "glIndexPointer" ); dllIndexPointer( type, stride, pointer ); } static void APIENTRY logIndexd(GLdouble c) { SIG( "glIndexd" ); dllIndexd( c ); } static void APIENTRY logIndexdv(const GLdouble *c) { SIG( "glIndexdv" ); dllIndexdv( c ); } static void APIENTRY logIndexf(GLfloat c) { SIG( "glIndexf" ); dllIndexf( c ); } static void APIENTRY logIndexfv(const GLfloat *c) { SIG( "glIndexfv" ); dllIndexfv( c ); } static void APIENTRY logIndexi(GLint c) { SIG( "glIndexi" ); dllIndexi( c ); } static void APIENTRY logIndexiv(const GLint *c) { SIG( "glIndexiv" ); dllIndexiv( c ); } static void APIENTRY logIndexs(GLshort c) { SIG( "glIndexs" ); dllIndexs( c ); } static void APIENTRY logIndexsv(const GLshort *c) { SIG( "glIndexsv" ); dllIndexsv( c ); } static void APIENTRY logIndexub(GLubyte c) { SIG( "glIndexub" ); dllIndexub( c ); } static void APIENTRY logIndexubv(const GLubyte *c) { SIG( "glIndexubv" ); dllIndexubv( c ); } static void APIENTRY logInitNames(void) { SIG( "glInitNames" ); dllInitNames(); } static void APIENTRY logInterleavedArrays(GLenum format, GLsizei stride, const void *pointer) { SIG( "glInterleavedArrays" ); dllInterleavedArrays( format, stride, pointer ); } static GLboolean APIENTRY logIsEnabled(GLenum cap) { SIG( "glIsEnabled" ); return dllIsEnabled( cap ); } static GLboolean APIENTRY logIsList(GLuint list) { SIG( "glIsList" ); return dllIsList( list ); } static GLboolean APIENTRY logIsTexture(GLuint texture) { SIG( "glIsTexture" ); return dllIsTexture( texture ); } static void APIENTRY logLightModelf(GLenum pname, GLfloat param) { SIG( "glLightModelf" ); dllLightModelf( pname, param ); } static void APIENTRY logLightModelfv(GLenum pname, const GLfloat *params) { SIG( "glLightModelfv" ); dllLightModelfv( pname, params ); } static void APIENTRY logLightModeli(GLenum pname, GLint param) { SIG( "glLightModeli" ); dllLightModeli( pname, param ); } static void APIENTRY logLightModeliv(GLenum pname, const GLint *params) { SIG( "glLightModeliv" ); dllLightModeliv( pname, params ); } static void APIENTRY logLightf(GLenum light, GLenum pname, GLfloat param) { SIG( "glLightf" ); dllLightf( light, pname, param ); } static void APIENTRY logLightfv(GLenum light, GLenum pname, const GLfloat *params) { SIG( "glLightfv" ); dllLightfv( light, pname, params ); } static void APIENTRY logLighti(GLenum light, GLenum pname, GLint param) { SIG( "glLighti" ); dllLighti( light, pname, param ); } static void APIENTRY logLightiv(GLenum light, GLenum pname, const GLint *params) { SIG( "glLightiv" ); dllLightiv( light, pname, params ); } static void APIENTRY logLineStipple(GLint factor, GLushort pattern) { SIG( "glLineStipple" ); dllLineStipple( factor, pattern ); } static void APIENTRY logLineWidth(GLfloat width) { SIG( "glLineWidth" ); dllLineWidth( width ); } static void APIENTRY logListBase(GLuint base) { SIG( "glListBase" ); dllListBase( base ); } static void APIENTRY logLoadIdentity(void) { SIG( "glLoadIdentity" ); dllLoadIdentity(); } static void APIENTRY logLoadMatrixd(const GLdouble *m) { SIG( "glLoadMatrixd" ); dllLoadMatrixd( m ); } static void APIENTRY logLoadMatrixf(const GLfloat *m) { SIG( "glLoadMatrixf" ); dllLoadMatrixf( m ); } static void APIENTRY logLoadName(GLuint name) { SIG( "glLoadName" ); dllLoadName( name ); } static void APIENTRY logLogicOp(GLenum opcode) { SIG( "glLogicOp" ); dllLogicOp( opcode ); } static void APIENTRY logMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points) { SIG( "glMap1d" ); dllMap1d( target, u1, u2, stride, order, points ); } static void APIENTRY logMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points) { SIG( "glMap1f" ); dllMap1f( target, u1, u2, stride, order, points ); } static void APIENTRY logMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points) { SIG( "glMap2d" ); dllMap2d( target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points ); } static void APIENTRY logMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points) { SIG( "glMap2f" ); dllMap2f( target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points ); } static void APIENTRY logMapGrid1d(GLint un, GLdouble u1, GLdouble u2) { SIG( "glMapGrid1d" ); dllMapGrid1d( un, u1, u2 ); } static void APIENTRY logMapGrid1f(GLint un, GLfloat u1, GLfloat u2) { SIG( "glMapGrid1f" ); dllMapGrid1f( un, u1, u2 ); } static void APIENTRY logMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2) { SIG( "glMapGrid2d" ); dllMapGrid2d( un, u1, u2, vn, v1, v2 ); } static void APIENTRY logMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2) { SIG( "glMapGrid2f" ); dllMapGrid2f( un, u1, u2, vn, v1, v2 ); } static void APIENTRY logMaterialf(GLenum face, GLenum pname, GLfloat param) { SIG( "glMaterialf" ); dllMaterialf( face, pname, param ); } static void APIENTRY logMaterialfv(GLenum face, GLenum pname, const GLfloat *params) { SIG( "glMaterialfv" ); dllMaterialfv( face, pname, params ); } static void APIENTRY logMateriali(GLenum face, GLenum pname, GLint param) { SIG( "glMateriali" ); dllMateriali( face, pname, param ); } static void APIENTRY logMaterialiv(GLenum face, GLenum pname, const GLint *params) { SIG( "glMaterialiv" ); dllMaterialiv( face, pname, params ); } static void APIENTRY logMatrixMode(GLenum mode) { SIG( "glMatrixMode" ); dllMatrixMode( mode ); } static void APIENTRY logMultMatrixd(const GLdouble *m) { SIG( "glMultMatrixd" ); dllMultMatrixd( m ); } static void APIENTRY logMultMatrixf(const GLfloat *m) { SIG( "glMultMatrixf" ); dllMultMatrixf( m ); } static void APIENTRY logNewList(GLuint list, GLenum mode) { SIG( "glNewList" ); dllNewList( list, mode ); } static void APIENTRY logNormal3b(GLbyte nx, GLbyte ny, GLbyte nz) { SIG ("glNormal3b" ); dllNormal3b( nx, ny, nz ); } static void APIENTRY logNormal3bv(const GLbyte *v) { SIG( "glNormal3bv" ); dllNormal3bv( v ); } static void APIENTRY logNormal3d(GLdouble nx, GLdouble ny, GLdouble nz) { SIG( "glNormal3d" ); dllNormal3d( nx, ny, nz ); } static void APIENTRY logNormal3dv(const GLdouble *v) { SIG( "glNormal3dv" ); dllNormal3dv( v ); } static void APIENTRY logNormal3f(GLfloat nx, GLfloat ny, GLfloat nz) { SIG( "glNormal3f" ); dllNormal3f( nx, ny, nz ); } static void APIENTRY logNormal3fv(const GLfloat *v) { SIG( "glNormal3fv" ); dllNormal3fv( v ); } static void APIENTRY logNormal3i(GLint nx, GLint ny, GLint nz) { SIG( "glNormal3i" ); dllNormal3i( nx, ny, nz ); } static void APIENTRY logNormal3iv(const GLint *v) { SIG( "glNormal3iv" ); dllNormal3iv( v ); } static void APIENTRY logNormal3s(GLshort nx, GLshort ny, GLshort nz) { SIG( "glNormal3s" ); dllNormal3s( nx, ny, nz ); } static void APIENTRY logNormal3sv(const GLshort *v) { SIG( "glNormal3sv" ); dllNormal3sv( v ); } static void APIENTRY logNormalPointer(GLenum type, GLsizei stride, const void *pointer) { SIG( "glNormalPointer" ); dllNormalPointer( type, stride, pointer ); } static void APIENTRY logOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) { SIG( "glOrtho" ); dllOrtho( left, right, bottom, top, zNear, zFar ); } static void APIENTRY logPassThrough(GLfloat token) { SIG( "glPassThrough" ); dllPassThrough( token ); } static void APIENTRY logPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat *values) { SIG( "glPixelMapfv" ); dllPixelMapfv( map, mapsize, values ); } static void APIENTRY logPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values) { SIG( "glPixelMapuiv" ); dllPixelMapuiv( map, mapsize, values ); } static void APIENTRY logPixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values) { SIG( "glPixelMapusv" ); dllPixelMapusv( map, mapsize, values ); } static void APIENTRY logPixelStoref(GLenum pname, GLfloat param) { SIG( "glPixelStoref" ); dllPixelStoref( pname, param ); } static void APIENTRY logPixelStorei(GLenum pname, GLint param) { SIG( "glPixelStorei" ); dllPixelStorei( pname, param ); } static void APIENTRY logPixelTransferf(GLenum pname, GLfloat param) { SIG( "glPixelTransferf" ); dllPixelTransferf( pname, param ); } static void APIENTRY logPixelTransferi(GLenum pname, GLint param) { SIG( "glPixelTransferi" ); dllPixelTransferi( pname, param ); } static void APIENTRY logPixelZoom(GLfloat xfactor, GLfloat yfactor) { SIG( "glPixelZoom" ); dllPixelZoom( xfactor, yfactor ); } static void APIENTRY logPointSize(GLfloat size) { SIG( "glPointSize" ); dllPointSize( size ); } static void APIENTRY logPolygonMode(GLenum face, GLenum mode) { fprintf( glw_state.log_fp, "glPolygonMode( 0x%x, 0x%x )\n", face, mode ); dllPolygonMode( face, mode ); } static void APIENTRY logPolygonOffset(GLfloat factor, GLfloat units) { SIG( "glPolygonOffset" ); dllPolygonOffset( factor, units ); } static void APIENTRY logPolygonStipple(const GLubyte *mask ) { SIG( "glPolygonStipple" ); dllPolygonStipple( mask ); } static void APIENTRY logPopAttrib(void) { SIG( "glPopAttrib" ); dllPopAttrib(); } static void APIENTRY logPopClientAttrib(void) { SIG( "glPopClientAttrib" ); dllPopClientAttrib(); } static void APIENTRY logPopMatrix(void) { SIG( "glPopMatrix" ); dllPopMatrix(); } static void APIENTRY logPopName(void) { SIG( "glPopName" ); dllPopName(); } static void APIENTRY logPrioritizeTextures(GLsizei n, const GLuint *textures, const GLclampf *priorities) { SIG( "glPrioritizeTextures" ); dllPrioritizeTextures( n, textures, priorities ); } static void APIENTRY logPushAttrib(GLbitfield mask) { SIG( "glPushAttrib" ); dllPushAttrib( mask ); } static void APIENTRY logPushClientAttrib(GLbitfield mask) { SIG( "glPushClientAttrib" ); dllPushClientAttrib( mask ); } static void APIENTRY logPushMatrix(void) { SIG( "glPushMatrix" ); dllPushMatrix(); } static void APIENTRY logPushName(GLuint name) { SIG( "glPushName" ); dllPushName( name ); } static void APIENTRY logRasterPos2d(GLdouble x, GLdouble y) { SIG ("glRasterPot2d" ); dllRasterPos2d( x, y ); } static void APIENTRY logRasterPos2dv(const GLdouble *v) { SIG( "glRasterPos2dv" ); dllRasterPos2dv( v ); } static void APIENTRY logRasterPos2f(GLfloat x, GLfloat y) { SIG( "glRasterPos2f" ); dllRasterPos2f( x, y ); } static void APIENTRY logRasterPos2fv(const GLfloat *v) { SIG( "glRasterPos2dv" ); dllRasterPos2fv( v ); } static void APIENTRY logRasterPos2i(GLint x, GLint y) { SIG( "glRasterPos2if" ); dllRasterPos2i( x, y ); } static void APIENTRY logRasterPos2iv(const GLint *v) { SIG( "glRasterPos2iv" ); dllRasterPos2iv( v ); } static void APIENTRY logRasterPos2s(GLshort x, GLshort y) { SIG( "glRasterPos2s" ); dllRasterPos2s( x, y ); } static void APIENTRY logRasterPos2sv(const GLshort *v) { SIG( "glRasterPos2sv" ); dllRasterPos2sv( v ); } static void APIENTRY logRasterPos3d(GLdouble x, GLdouble y, GLdouble z) { SIG( "glRasterPos3d" ); dllRasterPos3d( x, y, z ); } static void APIENTRY logRasterPos3dv(const GLdouble *v) { SIG( "glRasterPos3dv" ); dllRasterPos3dv( v ); } static void APIENTRY logRasterPos3f(GLfloat x, GLfloat y, GLfloat z) { SIG( "glRasterPos3f" ); dllRasterPos3f( x, y, z ); } static void APIENTRY logRasterPos3fv(const GLfloat *v) { SIG( "glRasterPos3fv" ); dllRasterPos3fv( v ); } static void APIENTRY logRasterPos3i(GLint x, GLint y, GLint z) { SIG( "glRasterPos3i" ); dllRasterPos3i( x, y, z ); } static void APIENTRY logRasterPos3iv(const GLint *v) { SIG( "glRasterPos3iv" ); dllRasterPos3iv( v ); } static void APIENTRY logRasterPos3s(GLshort x, GLshort y, GLshort z) { SIG( "glRasterPos3s" ); dllRasterPos3s( x, y, z ); } static void APIENTRY logRasterPos3sv(const GLshort *v) { SIG( "glRasterPos3sv" ); dllRasterPos3sv( v ); } static void APIENTRY logRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w) { SIG( "glRasterPos4d" ); dllRasterPos4d( x, y, z, w ); } static void APIENTRY logRasterPos4dv(const GLdouble *v) { SIG( "glRasterPos4dv" ); dllRasterPos4dv( v ); } static void APIENTRY logRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) { SIG( "glRasterPos4f" ); dllRasterPos4f( x, y, z, w ); } static void APIENTRY logRasterPos4fv(const GLfloat *v) { SIG( "glRasterPos4fv" ); dllRasterPos4fv( v ); } static void APIENTRY logRasterPos4i(GLint x, GLint y, GLint z, GLint w) { SIG( "glRasterPos4i" ); dllRasterPos4i( x, y, z, w ); } static void APIENTRY logRasterPos4iv(const GLint *v) { SIG( "glRasterPos4iv" ); dllRasterPos4iv( v ); } static void APIENTRY logRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w) { SIG( "glRasterPos4s" ); dllRasterPos4s( x, y, z, w ); } static void APIENTRY logRasterPos4sv(const GLshort *v) { SIG( "glRasterPos4sv" ); dllRasterPos4sv( v ); } static void APIENTRY logReadBuffer(GLenum mode) { SIG( "glReadBuffer" ); dllReadBuffer( mode ); } static void APIENTRY logReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels) { SIG( "glReadPixels" ); dllReadPixels( x, y, width, height, format, type, pixels ); } static void APIENTRY logRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) { SIG( "glRectd" ); dllRectd( x1, y1, x2, y2 ); } static void APIENTRY logRectdv(const GLdouble *v1, const GLdouble *v2) { SIG( "glRectdv" ); dllRectdv( v1, v2 ); } static void APIENTRY logRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) { SIG( "glRectf" ); dllRectf( x1, y1, x2, y2 ); } static void APIENTRY logRectfv(const GLfloat *v1, const GLfloat *v2) { SIG( "glRectfv" ); dllRectfv( v1, v2 ); } static void APIENTRY logRecti(GLint x1, GLint y1, GLint x2, GLint y2) { SIG( "glRecti" ); dllRecti( x1, y1, x2, y2 ); } static void APIENTRY logRectiv(const GLint *v1, const GLint *v2) { SIG( "glRectiv" ); dllRectiv( v1, v2 ); } static void APIENTRY logRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2) { SIG( "glRects" ); dllRects( x1, y1, x2, y2 ); } static void APIENTRY logRectsv(const GLshort *v1, const GLshort *v2) { SIG( "glRectsv" ); dllRectsv( v1, v2 ); } static GLint APIENTRY logRenderMode(GLenum mode) { SIG( "glRenderMode" ); return dllRenderMode( mode ); } static void APIENTRY logRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) { SIG( "glRotated" ); dllRotated( angle, x, y, z ); } static void APIENTRY logRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { SIG( "glRotatef" ); dllRotatef( angle, x, y, z ); } static void APIENTRY logScaled(GLdouble x, GLdouble y, GLdouble z) { SIG( "glScaled" ); dllScaled( x, y, z ); } static void APIENTRY logScalef(GLfloat x, GLfloat y, GLfloat z) { SIG( "glScalef" ); dllScalef( x, y, z ); } static void APIENTRY logScissor(GLint x, GLint y, GLsizei width, GLsizei height) { SIG( "glScissor" ); dllScissor( x, y, width, height ); } static void APIENTRY logSelectBuffer(GLsizei size, GLuint *buffer) { SIG( "glSelectBuffer" ); dllSelectBuffer( size, buffer ); } static void APIENTRY logShadeModel(GLenum mode) { SIG( "glShadeModel" ); dllShadeModel( mode ); } static void APIENTRY logStencilFunc(GLenum func, GLint ref, GLuint mask) { SIG( "glStencilFunc" ); dllStencilFunc( func, ref, mask ); } static void APIENTRY logStencilMask(GLuint mask) { SIG( "glStencilMask" ); dllStencilMask( mask ); } static void APIENTRY logStencilOp(GLenum fail, GLenum zfail, GLenum zpass) { SIG( "glStencilOp" ); dllStencilOp( fail, zfail, zpass ); } static void APIENTRY logTexCoord1d(GLdouble s) { SIG( "glTexCoord1d" ); dllTexCoord1d( s ); } static void APIENTRY logTexCoord1dv(const GLdouble *v) { SIG( "glTexCoord1dv" ); dllTexCoord1dv( v ); } static void APIENTRY logTexCoord1f(GLfloat s) { SIG( "glTexCoord1f" ); dllTexCoord1f( s ); } static void APIENTRY logTexCoord1fv(const GLfloat *v) { SIG( "glTexCoord1fv" ); dllTexCoord1fv( v ); } static void APIENTRY logTexCoord1i(GLint s) { SIG( "glTexCoord1i" ); dllTexCoord1i( s ); } static void APIENTRY logTexCoord1iv(const GLint *v) { SIG( "glTexCoord1iv" ); dllTexCoord1iv( v ); } static void APIENTRY logTexCoord1s(GLshort s) { SIG( "glTexCoord1s" ); dllTexCoord1s( s ); } static void APIENTRY logTexCoord1sv(const GLshort *v) { SIG( "glTexCoord1sv" ); dllTexCoord1sv( v ); } static void APIENTRY logTexCoord2d(GLdouble s, GLdouble t) { SIG( "glTexCoord2d" ); dllTexCoord2d( s, t ); } static void APIENTRY logTexCoord2dv(const GLdouble *v) { SIG( "glTexCoord2dv" ); dllTexCoord2dv( v ); } static void APIENTRY logTexCoord2f(GLfloat s, GLfloat t) { SIG( "glTexCoord2f" ); dllTexCoord2f( s, t ); } static void APIENTRY logTexCoord2fv(const GLfloat *v) { SIG( "glTexCoord2fv" ); dllTexCoord2fv( v ); } static void APIENTRY logTexCoord2i(GLint s, GLint t) { SIG( "glTexCoord2i" ); dllTexCoord2i( s, t ); } static void APIENTRY logTexCoord2iv(const GLint *v) { SIG( "glTexCoord2iv" ); dllTexCoord2iv( v ); } static void APIENTRY logTexCoord2s(GLshort s, GLshort t) { SIG( "glTexCoord2s" ); dllTexCoord2s( s, t ); } static void APIENTRY logTexCoord2sv(const GLshort *v) { SIG( "glTexCoord2sv" ); dllTexCoord2sv( v ); } static void APIENTRY logTexCoord3d(GLdouble s, GLdouble t, GLdouble r) { SIG( "glTexCoord3d" ); dllTexCoord3d( s, t, r ); } static void APIENTRY logTexCoord3dv(const GLdouble *v) { SIG( "glTexCoord3dv" ); dllTexCoord3dv( v ); } static void APIENTRY logTexCoord3f(GLfloat s, GLfloat t, GLfloat r) { SIG( "glTexCoord3f" ); dllTexCoord3f( s, t, r ); } static void APIENTRY logTexCoord3fv(const GLfloat *v) { SIG( "glTexCoord3fv" ); dllTexCoord3fv( v ); } static void APIENTRY logTexCoord3i(GLint s, GLint t, GLint r) { SIG( "glTexCoord3i" ); dllTexCoord3i( s, t, r ); } static void APIENTRY logTexCoord3iv(const GLint *v) { SIG( "glTexCoord3iv" ); dllTexCoord3iv( v ); } static void APIENTRY logTexCoord3s(GLshort s, GLshort t, GLshort r) { SIG( "glTexCoord3s" ); dllTexCoord3s( s, t, r ); } static void APIENTRY logTexCoord3sv(const GLshort *v) { SIG( "glTexCoord3sv" ); dllTexCoord3sv( v ); } static void APIENTRY logTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q) { SIG( "glTexCoord4d" ); dllTexCoord4d( s, t, r, q ); } static void APIENTRY logTexCoord4dv(const GLdouble *v) { SIG( "glTexCoord4dv" ); dllTexCoord4dv( v ); } static void APIENTRY logTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q) { SIG( "glTexCoord4f" ); dllTexCoord4f( s, t, r, q ); } static void APIENTRY logTexCoord4fv(const GLfloat *v) { SIG( "glTexCoord4fv" ); dllTexCoord4fv( v ); } static void APIENTRY logTexCoord4i(GLint s, GLint t, GLint r, GLint q) { SIG( "glTexCoord4i" ); dllTexCoord4i( s, t, r, q ); } static void APIENTRY logTexCoord4iv(const GLint *v) { SIG( "glTexCoord4iv" ); dllTexCoord4iv( v ); } static void APIENTRY logTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q) { SIG( "glTexCoord4s" ); dllTexCoord4s( s, t, r, q ); } static void APIENTRY logTexCoord4sv(const GLshort *v) { SIG( "glTexCoord4sv" ); dllTexCoord4sv( v ); } static void APIENTRY logTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) { SIG( "glTexCoordPointer" ); dllTexCoordPointer( size, type, stride, pointer ); } static void APIENTRY logTexEnvf(GLenum target, GLenum pname, GLfloat param) { fprintf( glw_state.log_fp, "glTexEnvf( 0x%x, 0x%x, %f )\n", target, pname, param ); dllTexEnvf( target, pname, param ); } static void APIENTRY logTexEnvfv(GLenum target, GLenum pname, const GLfloat *params) { SIG( "glTexEnvfv" ); dllTexEnvfv( target, pname, params ); } static void APIENTRY logTexEnvi(GLenum target, GLenum pname, GLint param) { fprintf( glw_state.log_fp, "glTexEnvi( 0x%x, 0x%x, 0x%x )\n", target, pname, param ); dllTexEnvi( target, pname, param ); } static void APIENTRY logTexEnviv(GLenum target, GLenum pname, const GLint *params) { SIG( "glTexEnviv" ); dllTexEnviv( target, pname, params ); } static void APIENTRY logTexGend(GLenum coord, GLenum pname, GLdouble param) { SIG( "glTexGend" ); dllTexGend( coord, pname, param ); } static void APIENTRY logTexGendv(GLenum coord, GLenum pname, const GLdouble *params) { SIG( "glTexGendv" ); dllTexGendv( coord, pname, params ); } static void APIENTRY logTexGenf(GLenum coord, GLenum pname, GLfloat param) { SIG( "glTexGenf" ); dllTexGenf( coord, pname, param ); } static void APIENTRY logTexGenfv(GLenum coord, GLenum pname, const GLfloat *params) { SIG( "glTexGenfv" ); dllTexGenfv( coord, pname, params ); } static void APIENTRY logTexGeni(GLenum coord, GLenum pname, GLint param) { SIG( "glTexGeni" ); dllTexGeni( coord, pname, param ); } static void APIENTRY logTexGeniv(GLenum coord, GLenum pname, const GLint *params) { SIG( "glTexGeniv" ); dllTexGeniv( coord, pname, params ); } static void APIENTRY logTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels) { SIG( "glTexImage1D" ); dllTexImage1D( target, level, internalformat, width, border, format, type, pixels ); } static void APIENTRY logTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels) { SIG( "glTexImage2D" ); dllTexImage2D( target, level, internalformat, width, height, border, format, type, pixels ); } static void APIENTRY logTexParameterf(GLenum target, GLenum pname, GLfloat param) { fprintf( glw_state.log_fp, "glTexParameterf( 0x%x, 0x%x, %f )\n", target, pname, param ); dllTexParameterf( target, pname, param ); } static void APIENTRY logTexParameterfv(GLenum target, GLenum pname, const GLfloat *params) { SIG( "glTexParameterfv" ); dllTexParameterfv( target, pname, params ); } static void APIENTRY logTexParameteri(GLenum target, GLenum pname, GLint param) { fprintf( glw_state.log_fp, "glTexParameteri( 0x%x, 0x%x, 0x%x )\n", target, pname, param ); dllTexParameteri( target, pname, param ); } static void APIENTRY logTexParameteriv(GLenum target, GLenum pname, const GLint *params) { SIG( "glTexParameteriv" ); dllTexParameteriv( target, pname, params ); } static void APIENTRY logTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels) { SIG( "glTexSubImage1D" ); dllTexSubImage1D( target, level, xoffset, width, format, type, pixels ); } static void APIENTRY logTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) { SIG( "glTexSubImage2D" ); dllTexSubImage2D( target, level, xoffset, yoffset, width, height, format, type, pixels ); } static void APIENTRY logTranslated(GLdouble x, GLdouble y, GLdouble z) { SIG( "glTranslated" ); dllTranslated( x, y, z ); } static void APIENTRY logTranslatef(GLfloat x, GLfloat y, GLfloat z) { SIG( "glTranslatef" ); dllTranslatef( x, y, z ); } static void APIENTRY logVertex2d(GLdouble x, GLdouble y) { SIG( "glVertex2d" ); dllVertex2d( x, y ); } static void APIENTRY logVertex2dv(const GLdouble *v) { SIG( "glVertex2dv" ); dllVertex2dv( v ); } static void APIENTRY logVertex2f(GLfloat x, GLfloat y) { SIG( "glVertex2f" ); dllVertex2f( x, y ); } static void APIENTRY logVertex2fv(const GLfloat *v) { SIG( "glVertex2fv" ); dllVertex2fv( v ); } static void APIENTRY logVertex2i(GLint x, GLint y) { SIG( "glVertex2i" ); dllVertex2i( x, y ); } static void APIENTRY logVertex2iv(const GLint *v) { SIG( "glVertex2iv" ); dllVertex2iv( v ); } static void APIENTRY logVertex2s(GLshort x, GLshort y) { SIG( "glVertex2s" ); dllVertex2s( x, y ); } static void APIENTRY logVertex2sv(const GLshort *v) { SIG( "glVertex2sv" ); dllVertex2sv( v ); } static void APIENTRY logVertex3d(GLdouble x, GLdouble y, GLdouble z) { SIG( "glVertex3d" ); dllVertex3d( x, y, z ); } static void APIENTRY logVertex3dv(const GLdouble *v) { SIG( "glVertex3dv" ); dllVertex3dv( v ); } static void APIENTRY logVertex3f(GLfloat x, GLfloat y, GLfloat z) { SIG( "glVertex3f" ); dllVertex3f( x, y, z ); } static void APIENTRY logVertex3fv(const GLfloat *v) { SIG( "glVertex3fv" ); dllVertex3fv( v ); } static void APIENTRY logVertex3i(GLint x, GLint y, GLint z) { SIG( "glVertex3i" ); dllVertex3i( x, y, z ); } static void APIENTRY logVertex3iv(const GLint *v) { SIG( "glVertex3iv" ); dllVertex3iv( v ); } static void APIENTRY logVertex3s(GLshort x, GLshort y, GLshort z) { SIG( "glVertex3s" ); dllVertex3s( x, y, z ); } static void APIENTRY logVertex3sv(const GLshort *v) { SIG( "glVertex3sv" ); dllVertex3sv( v ); } static void APIENTRY logVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w) { SIG( "glVertex4d" ); dllVertex4d( x, y, z, w ); } static void APIENTRY logVertex4dv(const GLdouble *v) { SIG( "glVertex4dv" ); dllVertex4dv( v ); } static void APIENTRY logVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) { SIG( "glVertex4f" ); dllVertex4f( x, y, z, w ); } static void APIENTRY logVertex4fv(const GLfloat *v) { SIG( "glVertex4fv" ); dllVertex4fv( v ); } static void APIENTRY logVertex4i(GLint x, GLint y, GLint z, GLint w) { SIG( "glVertex4i" ); dllVertex4i( x, y, z, w ); } static void APIENTRY logVertex4iv(const GLint *v) { SIG( "glVertex4iv" ); dllVertex4iv( v ); } static void APIENTRY logVertex4s(GLshort x, GLshort y, GLshort z, GLshort w) { SIG( "glVertex4s" ); dllVertex4s( x, y, z, w ); } static void APIENTRY logVertex4sv(const GLshort *v) { SIG( "glVertex4sv" ); dllVertex4sv( v ); } static void APIENTRY logVertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) { SIG( "glVertexPointer" ); dllVertexPointer( size, type, stride, pointer ); } static void APIENTRY logViewport(GLint x, GLint y, GLsizei width, GLsizei height) { SIG( "glViewport" ); dllViewport( x, y, width, height ); } /* ** QGL_Shutdown ** ** Unloads the specified DLL then nulls out all the proc pointers. */ void QGL_Shutdown( void ) { if ( glw_state.OpenGLLib ) { dlclose ( glw_state.OpenGLLib ); glw_state.OpenGLLib = NULL; } glw_state.OpenGLLib = NULL; qglAccum = NULL; qglAlphaFunc = NULL; qglAreTexturesResident = NULL; qglArrayElement = NULL; qglBegin = NULL; qglBindTexture = NULL; qglBitmap = NULL; qglBlendFunc = NULL; qglCallList = NULL; qglCallLists = NULL; qglClear = NULL; qglClearAccum = NULL; qglClearColor = NULL; qglClearDepth = NULL; qglClearIndex = NULL; qglClearStencil = NULL; qglClipPlane = NULL; qglColor3b = NULL; qglColor3bv = NULL; qglColor3d = NULL; qglColor3dv = NULL; qglColor3f = NULL; qglColor3fv = NULL; qglColor3i = NULL; qglColor3iv = NULL; qglColor3s = NULL; qglColor3sv = NULL; qglColor3ub = NULL; qglColor3ubv = NULL; qglColor3ui = NULL; qglColor3uiv = NULL; qglColor3us = NULL; qglColor3usv = NULL; qglColor4b = NULL; qglColor4bv = NULL; qglColor4d = NULL; qglColor4dv = NULL; qglColor4f = NULL; qglColor4fv = NULL; qglColor4i = NULL; qglColor4iv = NULL; qglColor4s = NULL; qglColor4sv = NULL; qglColor4ub = NULL; qglColor4ubv = NULL; qglColor4ui = NULL; qglColor4uiv = NULL; qglColor4us = NULL; qglColor4usv = NULL; qglColorMask = NULL; qglColorMaterial = NULL; qglColorPointer = NULL; qglCopyPixels = NULL; qglCopyTexImage1D = NULL; qglCopyTexImage2D = NULL; qglCopyTexSubImage1D = NULL; qglCopyTexSubImage2D = NULL; qglCullFace = NULL; qglDeleteLists = NULL; qglDeleteTextures = NULL; qglDepthFunc = NULL; qglDepthMask = NULL; qglDepthRange = NULL; qglDisable = NULL; qglDisableClientState = NULL; qglDrawArrays = NULL; qglDrawBuffer = NULL; qglDrawElements = NULL; qglDrawRangeElements = NULL; qglDrawPixels = NULL; qglEdgeFlag = NULL; qglEdgeFlagPointer = NULL; qglEdgeFlagv = NULL; qglEnable = NULL; qglEnableClientState = NULL; qglEnd = NULL; qglEndList = NULL; qglEvalCoord1d = NULL; qglEvalCoord1dv = NULL; qglEvalCoord1f = NULL; qglEvalCoord1fv = NULL; qglEvalCoord2d = NULL; qglEvalCoord2dv = NULL; qglEvalCoord2f = NULL; qglEvalCoord2fv = NULL; qglEvalMesh1 = NULL; qglEvalMesh2 = NULL; qglEvalPoint1 = NULL; qglEvalPoint2 = NULL; qglFeedbackBuffer = NULL; qglFinish = NULL; qglFlush = NULL; qglFogf = NULL; qglFogfv = NULL; qglFogi = NULL; qglFogiv = NULL; qglFrontFace = NULL; qglFrustum = NULL; qglGenLists = NULL; qglGenTextures = NULL; qglGetBooleanv = NULL; qglGetClipPlane = NULL; qglGetDoublev = NULL; qglGetError = NULL; qglGetFloatv = NULL; qglGetIntegerv = NULL; qglGetLightfv = NULL; qglGetLightiv = NULL; qglGetMapdv = NULL; qglGetMapfv = NULL; qglGetMapiv = NULL; qglGetMaterialfv = NULL; qglGetMaterialiv = NULL; qglGetPixelMapfv = NULL; qglGetPixelMapuiv = NULL; qglGetPixelMapusv = NULL; qglGetPointerv = NULL; qglGetPolygonStipple = NULL; qglGetString = NULL; qglGetTexEnvfv = NULL; qglGetTexEnviv = NULL; qglGetTexGendv = NULL; qglGetTexGenfv = NULL; qglGetTexGeniv = NULL; qglGetTexImage = NULL; qglGetTexLevelParameterfv = NULL; qglGetTexLevelParameteriv = NULL; qglGetTexParameterfv = NULL; qglGetTexParameteriv = NULL; qglHint = NULL; qglIndexMask = NULL; qglIndexPointer = NULL; qglIndexd = NULL; qglIndexdv = NULL; qglIndexf = NULL; qglIndexfv = NULL; qglIndexi = NULL; qglIndexiv = NULL; qglIndexs = NULL; qglIndexsv = NULL; qglIndexub = NULL; qglIndexubv = NULL; qglInitNames = NULL; qglInterleavedArrays = NULL; qglIsEnabled = NULL; qglIsList = NULL; qglIsTexture = NULL; qglLightModelf = NULL; qglLightModelfv = NULL; qglLightModeli = NULL; qglLightModeliv = NULL; qglLightf = NULL; qglLightfv = NULL; qglLighti = NULL; qglLightiv = NULL; qglLineStipple = NULL; qglLineWidth = NULL; qglListBase = NULL; qglLoadIdentity = NULL; qglLoadMatrixd = NULL; qglLoadMatrixf = NULL; qglLoadName = NULL; qglLogicOp = NULL; qglMap1d = NULL; qglMap1f = NULL; qglMap2d = NULL; qglMap2f = NULL; qglMapGrid1d = NULL; qglMapGrid1f = NULL; qglMapGrid2d = NULL; qglMapGrid2f = NULL; qglMaterialf = NULL; qglMaterialfv = NULL; qglMateriali = NULL; qglMaterialiv = NULL; qglMatrixMode = NULL; qglMultMatrixd = NULL; qglMultMatrixf = NULL; qglNewList = NULL; qglNormal3b = NULL; qglNormal3bv = NULL; qglNormal3d = NULL; qglNormal3dv = NULL; qglNormal3f = NULL; qglNormal3fv = NULL; qglNormal3i = NULL; qglNormal3iv = NULL; qglNormal3s = NULL; qglNormal3sv = NULL; qglNormalPointer = NULL; qglOrtho = NULL; qglPassThrough = NULL; qglPixelMapfv = NULL; qglPixelMapuiv = NULL; qglPixelMapusv = NULL; qglPixelStoref = NULL; qglPixelStorei = NULL; qglPixelTransferf = NULL; qglPixelTransferi = NULL; qglPixelZoom = NULL; qglPointSize = NULL; qglPolygonMode = NULL; qglPolygonOffset = NULL; qglPolygonStipple = NULL; qglPopAttrib = NULL; qglPopClientAttrib = NULL; qglPopMatrix = NULL; qglPopName = NULL; qglPrioritizeTextures = NULL; qglPushAttrib = NULL; qglPushClientAttrib = NULL; qglPushMatrix = NULL; qglPushName = NULL; qglRasterPos2d = NULL; qglRasterPos2dv = NULL; qglRasterPos2f = NULL; qglRasterPos2fv = NULL; qglRasterPos2i = NULL; qglRasterPos2iv = NULL; qglRasterPos2s = NULL; qglRasterPos2sv = NULL; qglRasterPos3d = NULL; qglRasterPos3dv = NULL; qglRasterPos3f = NULL; qglRasterPos3fv = NULL; qglRasterPos3i = NULL; qglRasterPos3iv = NULL; qglRasterPos3s = NULL; qglRasterPos3sv = NULL; qglRasterPos4d = NULL; qglRasterPos4dv = NULL; qglRasterPos4f = NULL; qglRasterPos4fv = NULL; qglRasterPos4i = NULL; qglRasterPos4iv = NULL; qglRasterPos4s = NULL; qglRasterPos4sv = NULL; qglReadBuffer = NULL; qglReadPixels = NULL; qglRectd = NULL; qglRectdv = NULL; qglRectf = NULL; qglRectfv = NULL; qglRecti = NULL; qglRectiv = NULL; qglRects = NULL; qglRectsv = NULL; qglRenderMode = NULL; qglRotated = NULL; qglRotatef = NULL; qglScaled = NULL; qglScalef = NULL; qglScissor = NULL; qglSelectBuffer = NULL; qglShadeModel = NULL; qglStencilFunc = NULL; qglStencilMask = NULL; qglStencilOp = NULL; qglTexCoord1d = NULL; qglTexCoord1dv = NULL; qglTexCoord1f = NULL; qglTexCoord1fv = NULL; qglTexCoord1i = NULL; qglTexCoord1iv = NULL; qglTexCoord1s = NULL; qglTexCoord1sv = NULL; qglTexCoord2d = NULL; qglTexCoord2dv = NULL; qglTexCoord2f = NULL; qglTexCoord2fv = NULL; qglTexCoord2i = NULL; qglTexCoord2iv = NULL; qglTexCoord2s = NULL; qglTexCoord2sv = NULL; qglTexCoord3d = NULL; qglTexCoord3dv = NULL; qglTexCoord3f = NULL; qglTexCoord3fv = NULL; qglTexCoord3i = NULL; qglTexCoord3iv = NULL; qglTexCoord3s = NULL; qglTexCoord3sv = NULL; qglTexCoord4d = NULL; qglTexCoord4dv = NULL; qglTexCoord4f = NULL; qglTexCoord4fv = NULL; qglTexCoord4i = NULL; qglTexCoord4iv = NULL; qglTexCoord4s = NULL; qglTexCoord4sv = NULL; qglTexCoordPointer = NULL; qglTexEnvf = NULL; qglTexEnvfv = NULL; qglTexEnvi = NULL; qglTexEnviv = NULL; qglTexGend = NULL; qglTexGendv = NULL; qglTexGenf = NULL; qglTexGenfv = NULL; qglTexGeni = NULL; qglTexGeniv = NULL; qglTexImage1D = NULL; qglTexImage2D = NULL; qglTexParameterf = NULL; qglTexParameterfv = NULL; qglTexParameteri = NULL; qglTexParameteriv = NULL; qglTexSubImage1D = NULL; qglTexSubImage2D = NULL; qglTranslated = NULL; qglTranslatef = NULL; qglVertex2d = NULL; qglVertex2dv = NULL; qglVertex2f = NULL; qglVertex2fv = NULL; qglVertex2i = NULL; qglVertex2iv = NULL; qglVertex2s = NULL; qglVertex2sv = NULL; qglVertex3d = NULL; qglVertex3dv = NULL; qglVertex3f = NULL; qglVertex3fv = NULL; qglVertex3i = NULL; qglVertex3iv = NULL; qglVertex3s = NULL; qglVertex3sv = NULL; qglVertex4d = NULL; qglVertex4dv = NULL; qglVertex4f = NULL; qglVertex4fv = NULL; qglVertex4i = NULL; qglVertex4iv = NULL; qglVertex4s = NULL; qglVertex4sv = NULL; qglVertexPointer = NULL; qglViewport = NULL; /* qfxMesaCreateContext = NULL; qfxMesaCreateBestContext = NULL; qfxMesaDestroyContext = NULL; qfxMesaMakeCurrent = NULL; qfxMesaGetCurrentContext = NULL; qfxMesaSwapBuffers = NULL; */ qglXChooseVisual = NULL; qglXCreateContext = NULL; qglXDestroyContext = NULL; qglXMakeCurrent = NULL; qglXCopyContext = NULL; qglXSwapBuffers = NULL; } #define GPA( a ) dlsym( glw_state.OpenGLLib, a ) /* ** QGL_Init ** ** This is responsible for binding our qgl function pointers to ** the appropriate GL stuff. In Windows this means doing a ** LoadLibrary and a bunch of calls to GetProcAddress. On other ** operating systems we need to do the right thing, whatever that ** might be. ** */ qboolean QGL_Init( const char *dllname ) { // update 3Dfx gamma irrespective of underlying DLL { char envbuffer[1024]; float g; g = 2.00 * ( 0.8 - ( vid_gamma->value - 0.5 ) ) + 1.0F; Com_sprintf( envbuffer, sizeof(envbuffer), "SSTV2_GAMMA=%f", g ); putenv( envbuffer ); Com_sprintf( envbuffer, sizeof(envbuffer), "SST_GAMMA=%f", g ); putenv( envbuffer ); } if ( ( glw_state.OpenGLLib = dlopen( dllname, RTLD_LAZY | RTLD_GLOBAL ) ) == 0 ) { #if 1 // basedir deprecated. return false; #else char fn[MAX_OSPATH]; char *path; // FILE *fp; // unused // Com_Printf(PRINT_ALL, "QGL_Init: Can't load %s from /etc/ld.so.conf: %s\n", // dllname, dlerror()); // probably not useful in unix/linux // try basedir next path = Cvar_Get ("basedir", ".", CVAR_NOSET)->string; snprintf (fn, MAX_OSPATH, "%s/%s", path, dllname ); if ( ( glw_state.OpenGLLib = dlopen( fn, RTLD_LAZY ) ) == 0 ) { Com_Printf( PRINT_ALL, "%s\n", dlerror() ); return false; } #endif } gl_config.allow_cds = true; qglAccum = dllAccum = GPA( "glAccum" ); qglAlphaFunc = dllAlphaFunc = GPA( "glAlphaFunc" ); qglAreTexturesResident = dllAreTexturesResident = GPA( "glAreTexturesResident" ); qglArrayElement = dllArrayElement = GPA( "glArrayElement" ); qglBegin = dllBegin = GPA( "glBegin" ); qglBindTexture = dllBindTexture = GPA( "glBindTexture" ); qglBitmap = dllBitmap = GPA( "glBitmap" ); qglBlendFunc = dllBlendFunc = GPA( "glBlendFunc" ); qglCallList = dllCallList = GPA( "glCallList" ); qglCallLists = dllCallLists = GPA( "glCallLists" ); qglClear = dllClear = GPA( "glClear" ); qglClearAccum = dllClearAccum = GPA( "glClearAccum" ); qglClearColor = dllClearColor = GPA( "glClearColor" ); qglClearDepth = dllClearDepth = GPA( "glClearDepth" ); qglClearIndex = dllClearIndex = GPA( "glClearIndex" ); qglClearStencil = dllClearStencil = GPA( "glClearStencil" ); qglClipPlane = dllClipPlane = GPA( "glClipPlane" ); qglColor3b = dllColor3b = GPA( "glColor3b" ); qglColor3bv = dllColor3bv = GPA( "glColor3bv" ); qglColor3d = dllColor3d = GPA( "glColor3d" ); qglColor3dv = dllColor3dv = GPA( "glColor3dv" ); qglColor3f = dllColor3f = GPA( "glColor3f" ); qglColor3fv = dllColor3fv = GPA( "glColor3fv" ); qglColor3i = dllColor3i = GPA( "glColor3i" ); qglColor3iv = dllColor3iv = GPA( "glColor3iv" ); qglColor3s = dllColor3s = GPA( "glColor3s" ); qglColor3sv = dllColor3sv = GPA( "glColor3sv" ); qglColor3ub = dllColor3ub = GPA( "glColor3ub" ); qglColor3ubv = dllColor3ubv = GPA( "glColor3ubv" ); qglColor3ui = dllColor3ui = GPA( "glColor3ui" ); qglColor3uiv = dllColor3uiv = GPA( "glColor3uiv" ); qglColor3us = dllColor3us = GPA( "glColor3us" ); qglColor3usv = dllColor3usv = GPA( "glColor3usv" ); qglColor4b = dllColor4b = GPA( "glColor4b" ); qglColor4bv = dllColor4bv = GPA( "glColor4bv" ); qglColor4d = dllColor4d = GPA( "glColor4d" ); qglColor4dv = dllColor4dv = GPA( "glColor4dv" ); qglColor4f = dllColor4f = GPA( "glColor4f" ); qglColor4fv = dllColor4fv = GPA( "glColor4fv" ); qglColor4i = dllColor4i = GPA( "glColor4i" ); qglColor4iv = dllColor4iv = GPA( "glColor4iv" ); qglColor4s = dllColor4s = GPA( "glColor4s" ); qglColor4sv = dllColor4sv = GPA( "glColor4sv" ); qglColor4ub = dllColor4ub = GPA( "glColor4ub" ); qglColor4ubv = dllColor4ubv = GPA( "glColor4ubv" ); qglColor4ui = dllColor4ui = GPA( "glColor4ui" ); qglColor4uiv = dllColor4uiv = GPA( "glColor4uiv" ); qglColor4us = dllColor4us = GPA( "glColor4us" ); qglColor4usv = dllColor4usv = GPA( "glColor4usv" ); qglColorMask = dllColorMask = GPA( "glColorMask" ); qglColorMaterial = dllColorMaterial = GPA( "glColorMaterial" ); qglColorPointer = dllColorPointer = GPA( "glColorPointer" ); qglCopyPixels = dllCopyPixels = GPA( "glCopyPixels" ); qglCopyTexImage1D = dllCopyTexImage1D = GPA( "glCopyTexImage1D" ); qglCopyTexImage2D = dllCopyTexImage2D = GPA( "glCopyTexImage2D" ); qglCopyTexSubImage1D = dllCopyTexSubImage1D = GPA( "glCopyTexSubImage1D" ); qglCopyTexSubImage2D = dllCopyTexSubImage2D = GPA( "glCopyTexSubImage2D" ); qglCullFace = dllCullFace = GPA( "glCullFace" ); qglDeleteLists = dllDeleteLists = GPA( "glDeleteLists" ); qglDeleteTextures = dllDeleteTextures = GPA( "glDeleteTextures" ); qglDepthFunc = dllDepthFunc = GPA( "glDepthFunc" ); qglDepthMask = dllDepthMask = GPA( "glDepthMask" ); qglDepthRange = dllDepthRange = GPA( "glDepthRange" ); qglDisable = dllDisable = GPA( "glDisable" ); qglDisableClientState = dllDisableClientState = GPA( "glDisableClientState" ); qglDrawArrays = dllDrawArrays = GPA( "glDrawArrays" ); qglDrawBuffer = dllDrawBuffer = GPA( "glDrawBuffer" ); qglDrawElements = dllDrawElements = GPA( "glDrawElements" ); qglDrawRangeElements = GPA ("glDrawRangeElements"); qglDrawPixels = dllDrawPixels = GPA( "glDrawPixels" ); qglEdgeFlag = dllEdgeFlag = GPA( "glEdgeFlag" ); qglEdgeFlagPointer = dllEdgeFlagPointer = GPA( "glEdgeFlagPointer" ); qglEdgeFlagv = dllEdgeFlagv = GPA( "glEdgeFlagv" ); qglEnable = dllEnable = GPA( "glEnable" ); qglEnableClientState = dllEnableClientState = GPA( "glEnableClientState" ); qglEnd = dllEnd = GPA( "glEnd" ); qglEndList = dllEndList = GPA( "glEndList" ); qglEvalCoord1d = dllEvalCoord1d = GPA( "glEvalCoord1d" ); qglEvalCoord1dv = dllEvalCoord1dv = GPA( "glEvalCoord1dv" ); qglEvalCoord1f = dllEvalCoord1f = GPA( "glEvalCoord1f" ); qglEvalCoord1fv = dllEvalCoord1fv = GPA( "glEvalCoord1fv" ); qglEvalCoord2d = dllEvalCoord2d = GPA( "glEvalCoord2d" ); qglEvalCoord2dv = dllEvalCoord2dv = GPA( "glEvalCoord2dv" ); qglEvalCoord2f = dllEvalCoord2f = GPA( "glEvalCoord2f" ); qglEvalCoord2fv = dllEvalCoord2fv = GPA( "glEvalCoord2fv" ); qglEvalMesh1 = dllEvalMesh1 = GPA( "glEvalMesh1" ); qglEvalMesh2 = dllEvalMesh2 = GPA( "glEvalMesh2" ); qglEvalPoint1 = dllEvalPoint1 = GPA( "glEvalPoint1" ); qglEvalPoint2 = dllEvalPoint2 = GPA( "glEvalPoint2" ); qglFeedbackBuffer = dllFeedbackBuffer = GPA( "glFeedbackBuffer" ); qglFinish = dllFinish = GPA( "glFinish" ); qglFlush = dllFlush = GPA( "glFlush" ); qglFogf = dllFogf = GPA( "glFogf" ); qglFogfv = dllFogfv = GPA( "glFogfv" ); qglFogi = dllFogi = GPA( "glFogi" ); qglFogiv = dllFogiv = GPA( "glFogiv" ); qglFrontFace = dllFrontFace = GPA( "glFrontFace" ); qglFrustum = dllFrustum = GPA( "glFrustum" ); qglGenLists = dllGenLists = GPA( "glGenLists" ); qglGenTextures = dllGenTextures = GPA( "glGenTextures" ); qglGetBooleanv = dllGetBooleanv = GPA( "glGetBooleanv" ); qglGetClipPlane = dllGetClipPlane = GPA( "glGetClipPlane" ); qglGetDoublev = dllGetDoublev = GPA( "glGetDoublev" ); qglGetError = dllGetError = GPA( "glGetError" ); qglGetFloatv = dllGetFloatv = GPA( "glGetFloatv" ); qglGetIntegerv = dllGetIntegerv = GPA( "glGetIntegerv" ); qglGetLightfv = dllGetLightfv = GPA( "glGetLightfv" ); qglGetLightiv = dllGetLightiv = GPA( "glGetLightiv" ); qglGetMapdv = dllGetMapdv = GPA( "glGetMapdv" ); qglGetMapfv = dllGetMapfv = GPA( "glGetMapfv" ); qglGetMapiv = dllGetMapiv = GPA( "glGetMapiv" ); qglGetMaterialfv = dllGetMaterialfv = GPA( "glGetMaterialfv" ); qglGetMaterialiv = dllGetMaterialiv = GPA( "glGetMaterialiv" ); qglGetPixelMapfv = dllGetPixelMapfv = GPA( "glGetPixelMapfv" ); qglGetPixelMapuiv = dllGetPixelMapuiv = GPA( "glGetPixelMapuiv" ); qglGetPixelMapusv = dllGetPixelMapusv = GPA( "glGetPixelMapusv" ); qglGetPointerv = dllGetPointerv = GPA( "glGetPointerv" ); qglGetPolygonStipple = dllGetPolygonStipple = GPA( "glGetPolygonStipple" ); qglGetString = dllGetString = GPA( "glGetString" ); qglGetTexEnvfv = dllGetTexEnvfv = GPA( "glGetTexEnvfv" ); qglGetTexEnviv = dllGetTexEnviv = GPA( "glGetTexEnviv" ); qglGetTexGendv = dllGetTexGendv = GPA( "glGetTexGendv" ); qglGetTexGenfv = dllGetTexGenfv = GPA( "glGetTexGenfv" ); qglGetTexGeniv = dllGetTexGeniv = GPA( "glGetTexGeniv" ); qglGetTexImage = dllGetTexImage = GPA( "glGetTexImage" ); qglGetTexLevelParameterfv = dllGetTexLevelParameterfv = GPA( "glGetLevelParameterfv" ); qglGetTexLevelParameteriv = dllGetTexLevelParameteriv = GPA( "glGetLevelParameteriv" ); qglGetTexParameterfv = dllGetTexParameterfv = GPA( "glGetTexParameterfv" ); qglGetTexParameteriv = dllGetTexParameteriv = GPA( "glGetTexParameteriv" ); qglHint = dllHint = GPA( "glHint" ); qglIndexMask = dllIndexMask = GPA( "glIndexMask" ); qglIndexPointer = dllIndexPointer = GPA( "glIndexPointer" ); qglIndexd = dllIndexd = GPA( "glIndexd" ); qglIndexdv = dllIndexdv = GPA( "glIndexdv" ); qglIndexf = dllIndexf = GPA( "glIndexf" ); qglIndexfv = dllIndexfv = GPA( "glIndexfv" ); qglIndexi = dllIndexi = GPA( "glIndexi" ); qglIndexiv = dllIndexiv = GPA( "glIndexiv" ); qglIndexs = dllIndexs = GPA( "glIndexs" ); qglIndexsv = dllIndexsv = GPA( "glIndexsv" ); qglIndexub = dllIndexub = GPA( "glIndexub" ); qglIndexubv = dllIndexubv = GPA( "glIndexubv" ); qglInitNames = dllInitNames = GPA( "glInitNames" ); qglInterleavedArrays = dllInterleavedArrays = GPA( "glInterleavedArrays" ); qglIsEnabled = dllIsEnabled = GPA( "glIsEnabled" ); qglIsList = dllIsList = GPA( "glIsList" ); qglIsTexture = dllIsTexture = GPA( "glIsTexture" ); qglLightModelf = dllLightModelf = GPA( "glLightModelf" ); qglLightModelfv = dllLightModelfv = GPA( "glLightModelfv" ); qglLightModeli = dllLightModeli = GPA( "glLightModeli" ); qglLightModeliv = dllLightModeliv = GPA( "glLightModeliv" ); qglLightf = dllLightf = GPA( "glLightf" ); qglLightfv = dllLightfv = GPA( "glLightfv" ); qglLighti = dllLighti = GPA( "glLighti" ); qglLightiv = dllLightiv = GPA( "glLightiv" ); qglLineStipple = dllLineStipple = GPA( "glLineStipple" ); qglLineWidth = dllLineWidth = GPA( "glLineWidth" ); qglListBase = dllListBase = GPA( "glListBase" ); qglLoadIdentity = dllLoadIdentity = GPA( "glLoadIdentity" ); qglLoadMatrixd = dllLoadMatrixd = GPA( "glLoadMatrixd" ); qglLoadMatrixf = dllLoadMatrixf = GPA( "glLoadMatrixf" ); qglLoadName = dllLoadName = GPA( "glLoadName" ); qglLogicOp = dllLogicOp = GPA( "glLogicOp" ); qglMap1d = dllMap1d = GPA( "glMap1d" ); qglMap1f = dllMap1f = GPA( "glMap1f" ); qglMap2d = dllMap2d = GPA( "glMap2d" ); qglMap2f = dllMap2f = GPA( "glMap2f" ); qglMapGrid1d = dllMapGrid1d = GPA( "glMapGrid1d" ); qglMapGrid1f = dllMapGrid1f = GPA( "glMapGrid1f" ); qglMapGrid2d = dllMapGrid2d = GPA( "glMapGrid2d" ); qglMapGrid2f = dllMapGrid2f = GPA( "glMapGrid2f" ); qglMaterialf = dllMaterialf = GPA( "glMaterialf" ); qglMaterialfv = dllMaterialfv = GPA( "glMaterialfv" ); qglMateriali = dllMateriali = GPA( "glMateriali" ); qglMaterialiv = dllMaterialiv = GPA( "glMaterialiv" ); qglMatrixMode = dllMatrixMode = GPA( "glMatrixMode" ); qglMultMatrixd = dllMultMatrixd = GPA( "glMultMatrixd" ); qglMultMatrixf = dllMultMatrixf = GPA( "glMultMatrixf" ); qglNewList = dllNewList = GPA( "glNewList" ); qglNormal3b = dllNormal3b = GPA( "glNormal3b" ); qglNormal3bv = dllNormal3bv = GPA( "glNormal3bv" ); qglNormal3d = dllNormal3d = GPA( "glNormal3d" ); qglNormal3dv = dllNormal3dv = GPA( "glNormal3dv" ); qglNormal3f = dllNormal3f = GPA( "glNormal3f" ); qglNormal3fv = dllNormal3fv = GPA( "glNormal3fv" ); qglNormal3i = dllNormal3i = GPA( "glNormal3i" ); qglNormal3iv = dllNormal3iv = GPA( "glNormal3iv" ); qglNormal3s = dllNormal3s = GPA( "glNormal3s" ); qglNormal3sv = dllNormal3sv = GPA( "glNormal3sv" ); qglNormalPointer = dllNormalPointer = GPA( "glNormalPointer" ); qglOrtho = dllOrtho = GPA( "glOrtho" ); qglPassThrough = dllPassThrough = GPA( "glPassThrough" ); qglPixelMapfv = dllPixelMapfv = GPA( "glPixelMapfv" ); qglPixelMapuiv = dllPixelMapuiv = GPA( "glPixelMapuiv" ); qglPixelMapusv = dllPixelMapusv = GPA( "glPixelMapusv" ); qglPixelStoref = dllPixelStoref = GPA( "glPixelStoref" ); qglPixelStorei = dllPixelStorei = GPA( "glPixelStorei" ); qglPixelTransferf = dllPixelTransferf = GPA( "glPixelTransferf" ); qglPixelTransferi = dllPixelTransferi = GPA( "glPixelTransferi" ); qglPixelZoom = dllPixelZoom = GPA( "glPixelZoom" ); qglPointSize = dllPointSize = GPA( "glPointSize" ); qglPolygonMode = dllPolygonMode = GPA( "glPolygonMode" ); qglPolygonOffset = dllPolygonOffset = GPA( "glPolygonOffset" ); qglPolygonStipple = dllPolygonStipple = GPA( "glPolygonStipple" ); qglPopAttrib = dllPopAttrib = GPA( "glPopAttrib" ); qglPopClientAttrib = dllPopClientAttrib = GPA( "glPopClientAttrib" ); qglPopMatrix = dllPopMatrix = GPA( "glPopMatrix" ); qglPopName = dllPopName = GPA( "glPopName" ); qglPrioritizeTextures = dllPrioritizeTextures = GPA( "glPrioritizeTextures" ); qglPushAttrib = dllPushAttrib = GPA( "glPushAttrib" ); qglPushClientAttrib = dllPushClientAttrib = GPA( "glPushClientAttrib" ); qglPushMatrix = dllPushMatrix = GPA( "glPushMatrix" ); qglPushName = dllPushName = GPA( "glPushName" ); qglRasterPos2d = dllRasterPos2d = GPA( "glRasterPos2d" ); qglRasterPos2dv = dllRasterPos2dv = GPA( "glRasterPos2dv" ); qglRasterPos2f = dllRasterPos2f = GPA( "glRasterPos2f" ); qglRasterPos2fv = dllRasterPos2fv = GPA( "glRasterPos2fv" ); qglRasterPos2i = dllRasterPos2i = GPA( "glRasterPos2i" ); qglRasterPos2iv = dllRasterPos2iv = GPA( "glRasterPos2iv" ); qglRasterPos2s = dllRasterPos2s = GPA( "glRasterPos2s" ); qglRasterPos2sv = dllRasterPos2sv = GPA( "glRasterPos2sv" ); qglRasterPos3d = dllRasterPos3d = GPA( "glRasterPos3d" ); qglRasterPos3dv = dllRasterPos3dv = GPA( "glRasterPos3dv" ); qglRasterPos3f = dllRasterPos3f = GPA( "glRasterPos3f" ); qglRasterPos3fv = dllRasterPos3fv = GPA( "glRasterPos3fv" ); qglRasterPos3i = dllRasterPos3i = GPA( "glRasterPos3i" ); qglRasterPos3iv = dllRasterPos3iv = GPA( "glRasterPos3iv" ); qglRasterPos3s = dllRasterPos3s = GPA( "glRasterPos3s" ); qglRasterPos3sv = dllRasterPos3sv = GPA( "glRasterPos3sv" ); qglRasterPos4d = dllRasterPos4d = GPA( "glRasterPos4d" ); qglRasterPos4dv = dllRasterPos4dv = GPA( "glRasterPos4dv" ); qglRasterPos4f = dllRasterPos4f = GPA( "glRasterPos4f" ); qglRasterPos4fv = dllRasterPos4fv = GPA( "glRasterPos4fv" ); qglRasterPos4i = dllRasterPos4i = GPA( "glRasterPos4i" ); qglRasterPos4iv = dllRasterPos4iv = GPA( "glRasterPos4iv" ); qglRasterPos4s = dllRasterPos4s = GPA( "glRasterPos4s" ); qglRasterPos4sv = dllRasterPos4sv = GPA( "glRasterPos4sv" ); qglReadBuffer = dllReadBuffer = GPA( "glReadBuffer" ); qglReadPixels = dllReadPixels = GPA( "glReadPixels" ); qglRectd = dllRectd = GPA( "glRectd" ); qglRectdv = dllRectdv = GPA( "glRectdv" ); qglRectf = dllRectf = GPA( "glRectf" ); qglRectfv = dllRectfv = GPA( "glRectfv" ); qglRecti = dllRecti = GPA( "glRecti" ); qglRectiv = dllRectiv = GPA( "glRectiv" ); qglRects = dllRects = GPA( "glRects" ); qglRectsv = dllRectsv = GPA( "glRectsv" ); qglRenderMode = dllRenderMode = GPA( "glRenderMode" ); qglRotated = dllRotated = GPA( "glRotated" ); qglRotatef = dllRotatef = GPA( "glRotatef" ); qglScaled = dllScaled = GPA( "glScaled" ); qglScalef = dllScalef = GPA( "glScalef" ); qglScissor = dllScissor = GPA( "glScissor" ); qglSelectBuffer = dllSelectBuffer = GPA( "glSelectBuffer" ); qglShadeModel = dllShadeModel = GPA( "glShadeModel" ); qglStencilFunc = dllStencilFunc = GPA( "glStencilFunc" ); qglStencilMask = dllStencilMask = GPA( "glStencilMask" ); qglStencilOp = dllStencilOp = GPA( "glStencilOp" ); qglTexCoord1d = dllTexCoord1d = GPA( "glTexCoord1d" ); qglTexCoord1dv = dllTexCoord1dv = GPA( "glTexCoord1dv" ); qglTexCoord1f = dllTexCoord1f = GPA( "glTexCoord1f" ); qglTexCoord1fv = dllTexCoord1fv = GPA( "glTexCoord1fv" ); qglTexCoord1i = dllTexCoord1i = GPA( "glTexCoord1i" ); qglTexCoord1iv = dllTexCoord1iv = GPA( "glTexCoord1iv" ); qglTexCoord1s = dllTexCoord1s = GPA( "glTexCoord1s" ); qglTexCoord1sv = dllTexCoord1sv = GPA( "glTexCoord1sv" ); qglTexCoord2d = dllTexCoord2d = GPA( "glTexCoord2d" ); qglTexCoord2dv = dllTexCoord2dv = GPA( "glTexCoord2dv" ); qglTexCoord2f = dllTexCoord2f = GPA( "glTexCoord2f" ); qglTexCoord2fv = dllTexCoord2fv = GPA( "glTexCoord2fv" ); qglTexCoord2i = dllTexCoord2i = GPA( "glTexCoord2i" ); qglTexCoord2iv = dllTexCoord2iv = GPA( "glTexCoord2iv" ); qglTexCoord2s = dllTexCoord2s = GPA( "glTexCoord2s" ); qglTexCoord2sv = dllTexCoord2sv = GPA( "glTexCoord2sv" ); qglTexCoord3d = dllTexCoord3d = GPA( "glTexCoord3d" ); qglTexCoord3dv = dllTexCoord3dv = GPA( "glTexCoord3dv" ); qglTexCoord3f = dllTexCoord3f = GPA( "glTexCoord3f" ); qglTexCoord3fv = dllTexCoord3fv = GPA( "glTexCoord3fv" ); qglTexCoord3i = dllTexCoord3i = GPA( "glTexCoord3i" ); qglTexCoord3iv = dllTexCoord3iv = GPA( "glTexCoord3iv" ); qglTexCoord3s = dllTexCoord3s = GPA( "glTexCoord3s" ); qglTexCoord3sv = dllTexCoord3sv = GPA( "glTexCoord3sv" ); qglTexCoord4d = dllTexCoord4d = GPA( "glTexCoord4d" ); qglTexCoord4dv = dllTexCoord4dv = GPA( "glTexCoord4dv" ); qglTexCoord4f = dllTexCoord4f = GPA( "glTexCoord4f" ); qglTexCoord4fv = dllTexCoord4fv = GPA( "glTexCoord4fv" ); qglTexCoord4i = dllTexCoord4i = GPA( "glTexCoord4i" ); qglTexCoord4iv = dllTexCoord4iv = GPA( "glTexCoord4iv" ); qglTexCoord4s = dllTexCoord4s = GPA( "glTexCoord4s" ); qglTexCoord4sv = dllTexCoord4sv = GPA( "glTexCoord4sv" ); qglTexCoordPointer = dllTexCoordPointer = GPA( "glTexCoordPointer" ); qglTexEnvf = dllTexEnvf = GPA( "glTexEnvf" ); qglTexEnvfv = dllTexEnvfv = GPA( "glTexEnvfv" ); qglTexEnvi = dllTexEnvi = GPA( "glTexEnvi" ); qglTexEnviv = dllTexEnviv = GPA( "glTexEnviv" ); qglTexGend = dllTexGend = GPA( "glTexGend" ); qglTexGendv = dllTexGendv = GPA( "glTexGendv" ); qglTexGenf = dllTexGenf = GPA( "glTexGenf" ); qglTexGenfv = dllTexGenfv = GPA( "glTexGenfv" ); qglTexGeni = dllTexGeni = GPA( "glTexGeni" ); qglTexGeniv = dllTexGeniv = GPA( "glTexGeniv" ); qglTexImage1D = dllTexImage1D = GPA( "glTexImage1D" ); qglTexImage2D = dllTexImage2D = GPA( "glTexImage2D" ); qglTexParameterf = dllTexParameterf = GPA( "glTexParameterf" ); qglTexParameterfv = dllTexParameterfv = GPA( "glTexParameterfv" ); qglTexParameteri = dllTexParameteri = GPA( "glTexParameteri" ); qglTexParameteriv = dllTexParameteriv = GPA( "glTexParameteriv" ); qglTexSubImage1D = dllTexSubImage1D = GPA( "glTexSubImage1D" ); qglTexSubImage2D = dllTexSubImage2D = GPA( "glTexSubImage2D" ); qglTranslated = dllTranslated = GPA( "glTranslated" ); qglTranslatef = dllTranslatef = GPA( "glTranslatef" ); qglVertex2d = dllVertex2d = GPA( "glVertex2d" ); qglVertex2dv = dllVertex2dv = GPA( "glVertex2dv" ); qglVertex2f = dllVertex2f = GPA( "glVertex2f" ); qglVertex2fv = dllVertex2fv = GPA( "glVertex2fv" ); qglVertex2i = dllVertex2i = GPA( "glVertex2i" ); qglVertex2iv = dllVertex2iv = GPA( "glVertex2iv" ); qglVertex2s = dllVertex2s = GPA( "glVertex2s" ); qglVertex2sv = dllVertex2sv = GPA( "glVertex2sv" ); qglVertex3d = dllVertex3d = GPA( "glVertex3d" ); qglVertex3dv = dllVertex3dv = GPA( "glVertex3dv" ); qglVertex3f = dllVertex3f = GPA( "glVertex3f" ); qglVertex3fv = dllVertex3fv = GPA( "glVertex3fv" ); qglVertex3i = dllVertex3i = GPA( "glVertex3i" ); qglVertex3iv = dllVertex3iv = GPA( "glVertex3iv" ); qglVertex3s = dllVertex3s = GPA( "glVertex3s" ); qglVertex3sv = dllVertex3sv = GPA( "glVertex3sv" ); qglVertex4d = dllVertex4d = GPA( "glVertex4d" ); qglVertex4dv = dllVertex4dv = GPA( "glVertex4dv" ); qglVertex4f = dllVertex4f = GPA( "glVertex4f" ); qglVertex4fv = dllVertex4fv = GPA( "glVertex4fv" ); qglVertex4i = dllVertex4i = GPA( "glVertex4i" ); qglVertex4iv = dllVertex4iv = GPA( "glVertex4iv" ); qglVertex4s = dllVertex4s = GPA( "glVertex4s" ); qglVertex4sv = dllVertex4sv = GPA( "glVertex4sv" ); qglVertexPointer = dllVertexPointer = GPA( "glVertexPointer" ); qglViewport = dllViewport = GPA( "glViewport" ); /* qfxMesaCreateContext = GPA("fxMesaCreateContext"); qfxMesaCreateBestContext = GPA("fxMesaCreateBestContext"); qfxMesaDestroyContext = GPA("fxMesaDestroyContext"); qfxMesaMakeCurrent = GPA("fxMesaMakeCurrent"); qfxMesaGetCurrentContext = GPA("fxMesaGetCurrentContext"); qfxMesaSwapBuffers = GPA("fxMesaSwapBuffers"); */ qglXChooseVisual = GPA("glXChooseVisual"); qglXCreateContext = GPA("glXCreateContext"); qglXDestroyContext = GPA("glXDestroyContext"); qglXMakeCurrent = GPA("glXMakeCurrent"); qglXCopyContext = GPA("glXCopyContext"); qglXSwapBuffers = GPA("glXSwapBuffers"); qwglGetProcAddress = GPA("glXGetProcAddress"); qglLockArraysEXT = 0; qglUnlockArraysEXT = 0; qglPointParameterfEXT = 0; qglPointParameterfvEXT = 0; qglColorTableEXT = 0; qgl3DfxSetPaletteEXT = 0; qglSelectTextureARB = 0; qglMTexCoord2fARB = 0; qglActiveTextureARB = 0; qglClientActiveTextureARB = 0; qglMultiTexCoord3fvARB = 0; return true; } void GLimp_EnableLogging( qboolean enable ) { if ( enable ) { if ( !glw_state.log_fp ) { struct tm *newtime; time_t aclock; char buffer[1024]; time( &aclock ); newtime = localtime( &aclock ); asctime( newtime ); Com_sprintf( buffer, sizeof(buffer), "%s/gl.log", FS_Gamedir() ); glw_state.log_fp = fopen( buffer, "wt" ); fprintf( glw_state.log_fp, "%s\n", asctime( newtime ) ); } qglAccum = logAccum; qglAlphaFunc = logAlphaFunc; qglAreTexturesResident = logAreTexturesResident; qglArrayElement = logArrayElement; qglBegin = logBegin; qglBindTexture = logBindTexture; qglBitmap = logBitmap; qglBlendFunc = logBlendFunc; qglCallList = logCallList; qglCallLists = logCallLists; qglClear = logClear; qglClearAccum = logClearAccum; qglClearColor = logClearColor; qglClearDepth = logClearDepth; qglClearIndex = logClearIndex; qglClearStencil = logClearStencil; qglClipPlane = logClipPlane; qglColor3b = logColor3b; qglColor3bv = logColor3bv; qglColor3d = logColor3d; qglColor3dv = logColor3dv; qglColor3f = logColor3f; qglColor3fv = logColor3fv; qglColor3i = logColor3i; qglColor3iv = logColor3iv; qglColor3s = logColor3s; qglColor3sv = logColor3sv; qglColor3ub = logColor3ub; qglColor3ubv = logColor3ubv; qglColor3ui = logColor3ui; qglColor3uiv = logColor3uiv; qglColor3us = logColor3us; qglColor3usv = logColor3usv; qglColor4b = logColor4b; qglColor4bv = logColor4bv; qglColor4d = logColor4d; qglColor4dv = logColor4dv; qglColor4f = logColor4f; qglColor4fv = logColor4fv; qglColor4i = logColor4i; qglColor4iv = logColor4iv; qglColor4s = logColor4s; qglColor4sv = logColor4sv; qglColor4ub = logColor4ub; qglColor4ubv = logColor4ubv; qglColor4ui = logColor4ui; qglColor4uiv = logColor4uiv; qglColor4us = logColor4us; qglColor4usv = logColor4usv; qglColorMask = logColorMask; qglColorMaterial = logColorMaterial; qglColorPointer = logColorPointer; qglCopyPixels = logCopyPixels; qglCopyTexImage1D = logCopyTexImage1D; qglCopyTexImage2D = logCopyTexImage2D; qglCopyTexSubImage1D = logCopyTexSubImage1D; qglCopyTexSubImage2D = logCopyTexSubImage2D; qglCullFace = logCullFace; qglDeleteLists = logDeleteLists ; qglDeleteTextures = logDeleteTextures ; qglDepthFunc = logDepthFunc ; qglDepthMask = logDepthMask ; qglDepthRange = logDepthRange ; qglDisable = logDisable ; qglDisableClientState = logDisableClientState ; qglDrawArrays = logDrawArrays ; qglDrawBuffer = logDrawBuffer ; qglDrawElements = logDrawElements ; qglDrawPixels = logDrawPixels ; qglEdgeFlag = logEdgeFlag ; qglEdgeFlagPointer = logEdgeFlagPointer ; qglEdgeFlagv = logEdgeFlagv ; qglEnable = logEnable ; qglEnableClientState = logEnableClientState ; qglEnd = logEnd ; qglEndList = logEndList ; qglEvalCoord1d = logEvalCoord1d ; qglEvalCoord1dv = logEvalCoord1dv ; qglEvalCoord1f = logEvalCoord1f ; qglEvalCoord1fv = logEvalCoord1fv ; qglEvalCoord2d = logEvalCoord2d ; qglEvalCoord2dv = logEvalCoord2dv ; qglEvalCoord2f = logEvalCoord2f ; qglEvalCoord2fv = logEvalCoord2fv ; qglEvalMesh1 = logEvalMesh1 ; qglEvalMesh2 = logEvalMesh2 ; qglEvalPoint1 = logEvalPoint1 ; qglEvalPoint2 = logEvalPoint2 ; qglFeedbackBuffer = logFeedbackBuffer ; qglFinish = logFinish ; qglFlush = logFlush ; qglFogf = logFogf ; qglFogfv = logFogfv ; qglFogi = logFogi ; qglFogiv = logFogiv ; qglFrontFace = logFrontFace ; qglFrustum = logFrustum ; qglGenLists = logGenLists ; qglGenTextures = logGenTextures ; qglGetBooleanv = logGetBooleanv ; qglGetClipPlane = logGetClipPlane ; qglGetDoublev = logGetDoublev ; qglGetError = logGetError ; qglGetFloatv = logGetFloatv ; qglGetIntegerv = logGetIntegerv ; qglGetLightfv = logGetLightfv ; qglGetLightiv = logGetLightiv ; qglGetMapdv = logGetMapdv ; qglGetMapfv = logGetMapfv ; qglGetMapiv = logGetMapiv ; qglGetMaterialfv = logGetMaterialfv ; qglGetMaterialiv = logGetMaterialiv ; qglGetPixelMapfv = logGetPixelMapfv ; qglGetPixelMapuiv = logGetPixelMapuiv ; qglGetPixelMapusv = logGetPixelMapusv ; qglGetPointerv = logGetPointerv ; qglGetPolygonStipple = logGetPolygonStipple ; qglGetString = logGetString ; qglGetTexEnvfv = logGetTexEnvfv ; qglGetTexEnviv = logGetTexEnviv ; qglGetTexGendv = logGetTexGendv ; qglGetTexGenfv = logGetTexGenfv ; qglGetTexGeniv = logGetTexGeniv ; qglGetTexImage = logGetTexImage ; qglGetTexLevelParameterfv = logGetTexLevelParameterfv ; qglGetTexLevelParameteriv = logGetTexLevelParameteriv ; qglGetTexParameterfv = logGetTexParameterfv ; qglGetTexParameteriv = logGetTexParameteriv ; qglHint = logHint ; qglIndexMask = logIndexMask ; qglIndexPointer = logIndexPointer ; qglIndexd = logIndexd ; qglIndexdv = logIndexdv ; qglIndexf = logIndexf ; qglIndexfv = logIndexfv ; qglIndexi = logIndexi ; qglIndexiv = logIndexiv ; qglIndexs = logIndexs ; qglIndexsv = logIndexsv ; qglIndexub = logIndexub ; qglIndexubv = logIndexubv ; qglInitNames = logInitNames ; qglInterleavedArrays = logInterleavedArrays ; qglIsEnabled = logIsEnabled ; qglIsList = logIsList ; qglIsTexture = logIsTexture ; qglLightModelf = logLightModelf ; qglLightModelfv = logLightModelfv ; qglLightModeli = logLightModeli ; qglLightModeliv = logLightModeliv ; qglLightf = logLightf ; qglLightfv = logLightfv ; qglLighti = logLighti ; qglLightiv = logLightiv ; qglLineStipple = logLineStipple ; qglLineWidth = logLineWidth ; qglListBase = logListBase ; qglLoadIdentity = logLoadIdentity ; qglLoadMatrixd = logLoadMatrixd ; qglLoadMatrixf = logLoadMatrixf ; qglLoadName = logLoadName ; qglLogicOp = logLogicOp ; qglMap1d = logMap1d ; qglMap1f = logMap1f ; qglMap2d = logMap2d ; qglMap2f = logMap2f ; qglMapGrid1d = logMapGrid1d ; qglMapGrid1f = logMapGrid1f ; qglMapGrid2d = logMapGrid2d ; qglMapGrid2f = logMapGrid2f ; qglMaterialf = logMaterialf ; qglMaterialfv = logMaterialfv ; qglMateriali = logMateriali ; qglMaterialiv = logMaterialiv ; qglMatrixMode = logMatrixMode ; qglMultMatrixd = logMultMatrixd ; qglMultMatrixf = logMultMatrixf ; qglNewList = logNewList ; qglNormal3b = logNormal3b ; qglNormal3bv = logNormal3bv ; qglNormal3d = logNormal3d ; qglNormal3dv = logNormal3dv ; qglNormal3f = logNormal3f ; qglNormal3fv = logNormal3fv ; qglNormal3i = logNormal3i ; qglNormal3iv = logNormal3iv ; qglNormal3s = logNormal3s ; qglNormal3sv = logNormal3sv ; qglNormalPointer = logNormalPointer ; qglOrtho = logOrtho ; qglPassThrough = logPassThrough ; qglPixelMapfv = logPixelMapfv ; qglPixelMapuiv = logPixelMapuiv ; qglPixelMapusv = logPixelMapusv ; qglPixelStoref = logPixelStoref ; qglPixelStorei = logPixelStorei ; qglPixelTransferf = logPixelTransferf ; qglPixelTransferi = logPixelTransferi ; qglPixelZoom = logPixelZoom ; qglPointSize = logPointSize ; qglPolygonMode = logPolygonMode ; qglPolygonOffset = logPolygonOffset ; qglPolygonStipple = logPolygonStipple ; qglPopAttrib = logPopAttrib ; qglPopClientAttrib = logPopClientAttrib ; qglPopMatrix = logPopMatrix ; qglPopName = logPopName ; qglPrioritizeTextures = logPrioritizeTextures ; qglPushAttrib = logPushAttrib ; qglPushClientAttrib = logPushClientAttrib ; qglPushMatrix = logPushMatrix ; qglPushName = logPushName ; qglRasterPos2d = logRasterPos2d ; qglRasterPos2dv = logRasterPos2dv ; qglRasterPos2f = logRasterPos2f ; qglRasterPos2fv = logRasterPos2fv ; qglRasterPos2i = logRasterPos2i ; qglRasterPos2iv = logRasterPos2iv ; qglRasterPos2s = logRasterPos2s ; qglRasterPos2sv = logRasterPos2sv ; qglRasterPos3d = logRasterPos3d ; qglRasterPos3dv = logRasterPos3dv ; qglRasterPos3f = logRasterPos3f ; qglRasterPos3fv = logRasterPos3fv ; qglRasterPos3i = logRasterPos3i ; qglRasterPos3iv = logRasterPos3iv ; qglRasterPos3s = logRasterPos3s ; qglRasterPos3sv = logRasterPos3sv ; qglRasterPos4d = logRasterPos4d ; qglRasterPos4dv = logRasterPos4dv ; qglRasterPos4f = logRasterPos4f ; qglRasterPos4fv = logRasterPos4fv ; qglRasterPos4i = logRasterPos4i ; qglRasterPos4iv = logRasterPos4iv ; qglRasterPos4s = logRasterPos4s ; qglRasterPos4sv = logRasterPos4sv ; qglReadBuffer = logReadBuffer ; qglReadPixels = logReadPixels ; qglRectd = logRectd ; qglRectdv = logRectdv ; qglRectf = logRectf ; qglRectfv = logRectfv ; qglRecti = logRecti ; qglRectiv = logRectiv ; qglRects = logRects ; qglRectsv = logRectsv ; qglRenderMode = logRenderMode ; qglRotated = logRotated ; qglRotatef = logRotatef ; qglScaled = logScaled ; qglScalef = logScalef ; qglScissor = logScissor ; qglSelectBuffer = logSelectBuffer ; qglShadeModel = logShadeModel ; qglStencilFunc = logStencilFunc ; qglStencilMask = logStencilMask ; qglStencilOp = logStencilOp ; qglTexCoord1d = logTexCoord1d ; qglTexCoord1dv = logTexCoord1dv ; qglTexCoord1f = logTexCoord1f ; qglTexCoord1fv = logTexCoord1fv ; qglTexCoord1i = logTexCoord1i ; qglTexCoord1iv = logTexCoord1iv ; qglTexCoord1s = logTexCoord1s ; qglTexCoord1sv = logTexCoord1sv ; qglTexCoord2d = logTexCoord2d ; qglTexCoord2dv = logTexCoord2dv ; qglTexCoord2f = logTexCoord2f ; qglTexCoord2fv = logTexCoord2fv ; qglTexCoord2i = logTexCoord2i ; qglTexCoord2iv = logTexCoord2iv ; qglTexCoord2s = logTexCoord2s ; qglTexCoord2sv = logTexCoord2sv ; qglTexCoord3d = logTexCoord3d ; qglTexCoord3dv = logTexCoord3dv ; qglTexCoord3f = logTexCoord3f ; qglTexCoord3fv = logTexCoord3fv ; qglTexCoord3i = logTexCoord3i ; qglTexCoord3iv = logTexCoord3iv ; qglTexCoord3s = logTexCoord3s ; qglTexCoord3sv = logTexCoord3sv ; qglTexCoord4d = logTexCoord4d ; qglTexCoord4dv = logTexCoord4dv ; qglTexCoord4f = logTexCoord4f ; qglTexCoord4fv = logTexCoord4fv ; qglTexCoord4i = logTexCoord4i ; qglTexCoord4iv = logTexCoord4iv ; qglTexCoord4s = logTexCoord4s ; qglTexCoord4sv = logTexCoord4sv ; qglTexCoordPointer = logTexCoordPointer ; qglTexEnvf = logTexEnvf ; qglTexEnvfv = logTexEnvfv ; qglTexEnvi = logTexEnvi ; qglTexEnviv = logTexEnviv ; qglTexGend = logTexGend ; qglTexGendv = logTexGendv ; qglTexGenf = logTexGenf ; qglTexGenfv = logTexGenfv ; qglTexGeni = logTexGeni ; qglTexGeniv = logTexGeniv ; qglTexImage1D = logTexImage1D ; qglTexImage2D = logTexImage2D ; qglTexParameterf = logTexParameterf ; qglTexParameterfv = logTexParameterfv ; qglTexParameteri = logTexParameteri ; qglTexParameteriv = logTexParameteriv ; qglTexSubImage1D = logTexSubImage1D ; qglTexSubImage2D = logTexSubImage2D ; qglTranslated = logTranslated ; qglTranslatef = logTranslatef ; qglVertex2d = logVertex2d ; qglVertex2dv = logVertex2dv ; qglVertex2f = logVertex2f ; qglVertex2fv = logVertex2fv ; qglVertex2i = logVertex2i ; qglVertex2iv = logVertex2iv ; qglVertex2s = logVertex2s ; qglVertex2sv = logVertex2sv ; qglVertex3d = logVertex3d ; qglVertex3dv = logVertex3dv ; qglVertex3f = logVertex3f ; qglVertex3fv = logVertex3fv ; qglVertex3i = logVertex3i ; qglVertex3iv = logVertex3iv ; qglVertex3s = logVertex3s ; qglVertex3sv = logVertex3sv ; qglVertex4d = logVertex4d ; qglVertex4dv = logVertex4dv ; qglVertex4f = logVertex4f ; qglVertex4fv = logVertex4fv ; qglVertex4i = logVertex4i ; qglVertex4iv = logVertex4iv ; qglVertex4s = logVertex4s ; qglVertex4sv = logVertex4sv ; qglVertexPointer = logVertexPointer ; qglViewport = logViewport ; } else { qglAccum = dllAccum; qglAlphaFunc = dllAlphaFunc; qglAreTexturesResident = dllAreTexturesResident; qglArrayElement = dllArrayElement; qglBegin = dllBegin; qglBindTexture = dllBindTexture; qglBitmap = dllBitmap; qglBlendFunc = dllBlendFunc; qglCallList = dllCallList; qglCallLists = dllCallLists; qglClear = dllClear; qglClearAccum = dllClearAccum; qglClearColor = dllClearColor; qglClearDepth = dllClearDepth; qglClearIndex = dllClearIndex; qglClearStencil = dllClearStencil; qglClipPlane = dllClipPlane; qglColor3b = dllColor3b; qglColor3bv = dllColor3bv; qglColor3d = dllColor3d; qglColor3dv = dllColor3dv; qglColor3f = dllColor3f; qglColor3fv = dllColor3fv; qglColor3i = dllColor3i; qglColor3iv = dllColor3iv; qglColor3s = dllColor3s; qglColor3sv = dllColor3sv; qglColor3ub = dllColor3ub; qglColor3ubv = dllColor3ubv; qglColor3ui = dllColor3ui; qglColor3uiv = dllColor3uiv; qglColor3us = dllColor3us; qglColor3usv = dllColor3usv; qglColor4b = dllColor4b; qglColor4bv = dllColor4bv; qglColor4d = dllColor4d; qglColor4dv = dllColor4dv; qglColor4f = dllColor4f; qglColor4fv = dllColor4fv; qglColor4i = dllColor4i; qglColor4iv = dllColor4iv; qglColor4s = dllColor4s; qglColor4sv = dllColor4sv; qglColor4ub = dllColor4ub; qglColor4ubv = dllColor4ubv; qglColor4ui = dllColor4ui; qglColor4uiv = dllColor4uiv; qglColor4us = dllColor4us; qglColor4usv = dllColor4usv; qglColorMask = dllColorMask; qglColorMaterial = dllColorMaterial; qglColorPointer = dllColorPointer; qglCopyPixels = dllCopyPixels; qglCopyTexImage1D = dllCopyTexImage1D; qglCopyTexImage2D = dllCopyTexImage2D; qglCopyTexSubImage1D = dllCopyTexSubImage1D; qglCopyTexSubImage2D = dllCopyTexSubImage2D; qglCullFace = dllCullFace; qglDeleteLists = dllDeleteLists ; qglDeleteTextures = dllDeleteTextures ; qglDepthFunc = dllDepthFunc ; qglDepthMask = dllDepthMask ; qglDepthRange = dllDepthRange ; qglDisable = dllDisable ; qglDisableClientState = dllDisableClientState ; qglDrawArrays = dllDrawArrays ; qglDrawBuffer = dllDrawBuffer ; qglDrawElements = dllDrawElements ; qglDrawPixels = dllDrawPixels ; qglEdgeFlag = dllEdgeFlag ; qglEdgeFlagPointer = dllEdgeFlagPointer ; qglEdgeFlagv = dllEdgeFlagv ; qglEnable = dllEnable ; qglEnableClientState = dllEnableClientState ; qglEnd = dllEnd ; qglEndList = dllEndList ; qglEvalCoord1d = dllEvalCoord1d ; qglEvalCoord1dv = dllEvalCoord1dv ; qglEvalCoord1f = dllEvalCoord1f ; qglEvalCoord1fv = dllEvalCoord1fv ; qglEvalCoord2d = dllEvalCoord2d ; qglEvalCoord2dv = dllEvalCoord2dv ; qglEvalCoord2f = dllEvalCoord2f ; qglEvalCoord2fv = dllEvalCoord2fv ; qglEvalMesh1 = dllEvalMesh1 ; qglEvalMesh2 = dllEvalMesh2 ; qglEvalPoint1 = dllEvalPoint1 ; qglEvalPoint2 = dllEvalPoint2 ; qglFeedbackBuffer = dllFeedbackBuffer ; qglFinish = dllFinish ; qglFlush = dllFlush ; qglFogf = dllFogf ; qglFogfv = dllFogfv ; qglFogi = dllFogi ; qglFogiv = dllFogiv ; qglFrontFace = dllFrontFace ; qglFrustum = dllFrustum ; qglGenLists = dllGenLists ; qglGenTextures = dllGenTextures ; qglGetBooleanv = dllGetBooleanv ; qglGetClipPlane = dllGetClipPlane ; qglGetDoublev = dllGetDoublev ; qglGetError = dllGetError ; qglGetFloatv = dllGetFloatv ; qglGetIntegerv = dllGetIntegerv ; qglGetLightfv = dllGetLightfv ; qglGetLightiv = dllGetLightiv ; qglGetMapdv = dllGetMapdv ; qglGetMapfv = dllGetMapfv ; qglGetMapiv = dllGetMapiv ; qglGetMaterialfv = dllGetMaterialfv ; qglGetMaterialiv = dllGetMaterialiv ; qglGetPixelMapfv = dllGetPixelMapfv ; qglGetPixelMapuiv = dllGetPixelMapuiv ; qglGetPixelMapusv = dllGetPixelMapusv ; qglGetPointerv = dllGetPointerv ; qglGetPolygonStipple = dllGetPolygonStipple ; qglGetString = dllGetString ; qglGetTexEnvfv = dllGetTexEnvfv ; qglGetTexEnviv = dllGetTexEnviv ; qglGetTexGendv = dllGetTexGendv ; qglGetTexGenfv = dllGetTexGenfv ; qglGetTexGeniv = dllGetTexGeniv ; qglGetTexImage = dllGetTexImage ; qglGetTexLevelParameterfv = dllGetTexLevelParameterfv ; qglGetTexLevelParameteriv = dllGetTexLevelParameteriv ; qglGetTexParameterfv = dllGetTexParameterfv ; qglGetTexParameteriv = dllGetTexParameteriv ; qglHint = dllHint ; qglIndexMask = dllIndexMask ; qglIndexPointer = dllIndexPointer ; qglIndexd = dllIndexd ; qglIndexdv = dllIndexdv ; qglIndexf = dllIndexf ; qglIndexfv = dllIndexfv ; qglIndexi = dllIndexi ; qglIndexiv = dllIndexiv ; qglIndexs = dllIndexs ; qglIndexsv = dllIndexsv ; qglIndexub = dllIndexub ; qglIndexubv = dllIndexubv ; qglInitNames = dllInitNames ; qglInterleavedArrays = dllInterleavedArrays ; qglIsEnabled = dllIsEnabled ; qglIsList = dllIsList ; qglIsTexture = dllIsTexture ; qglLightModelf = dllLightModelf ; qglLightModelfv = dllLightModelfv ; qglLightModeli = dllLightModeli ; qglLightModeliv = dllLightModeliv ; qglLightf = dllLightf ; qglLightfv = dllLightfv ; qglLighti = dllLighti ; qglLightiv = dllLightiv ; qglLineStipple = dllLineStipple ; qglLineWidth = dllLineWidth ; qglListBase = dllListBase ; qglLoadIdentity = dllLoadIdentity ; qglLoadMatrixd = dllLoadMatrixd ; qglLoadMatrixf = dllLoadMatrixf ; qglLoadName = dllLoadName ; qglLogicOp = dllLogicOp ; qglMap1d = dllMap1d ; qglMap1f = dllMap1f ; qglMap2d = dllMap2d ; qglMap2f = dllMap2f ; qglMapGrid1d = dllMapGrid1d ; qglMapGrid1f = dllMapGrid1f ; qglMapGrid2d = dllMapGrid2d ; qglMapGrid2f = dllMapGrid2f ; qglMaterialf = dllMaterialf ; qglMaterialfv = dllMaterialfv ; qglMateriali = dllMateriali ; qglMaterialiv = dllMaterialiv ; qglMatrixMode = dllMatrixMode ; qglMultMatrixd = dllMultMatrixd ; qglMultMatrixf = dllMultMatrixf ; qglNewList = dllNewList ; qglNormal3b = dllNormal3b ; qglNormal3bv = dllNormal3bv ; qglNormal3d = dllNormal3d ; qglNormal3dv = dllNormal3dv ; qglNormal3f = dllNormal3f ; qglNormal3fv = dllNormal3fv ; qglNormal3i = dllNormal3i ; qglNormal3iv = dllNormal3iv ; qglNormal3s = dllNormal3s ; qglNormal3sv = dllNormal3sv ; qglNormalPointer = dllNormalPointer ; qglOrtho = dllOrtho ; qglPassThrough = dllPassThrough ; qglPixelMapfv = dllPixelMapfv ; qglPixelMapuiv = dllPixelMapuiv ; qglPixelMapusv = dllPixelMapusv ; qglPixelStoref = dllPixelStoref ; qglPixelStorei = dllPixelStorei ; qglPixelTransferf = dllPixelTransferf ; qglPixelTransferi = dllPixelTransferi ; qglPixelZoom = dllPixelZoom ; qglPointSize = dllPointSize ; qglPolygonMode = dllPolygonMode ; qglPolygonOffset = dllPolygonOffset ; qglPolygonStipple = dllPolygonStipple ; qglPopAttrib = dllPopAttrib ; qglPopClientAttrib = dllPopClientAttrib ; qglPopMatrix = dllPopMatrix ; qglPopName = dllPopName ; qglPrioritizeTextures = dllPrioritizeTextures ; qglPushAttrib = dllPushAttrib ; qglPushClientAttrib = dllPushClientAttrib ; qglPushMatrix = dllPushMatrix ; qglPushName = dllPushName ; qglRasterPos2d = dllRasterPos2d ; qglRasterPos2dv = dllRasterPos2dv ; qglRasterPos2f = dllRasterPos2f ; qglRasterPos2fv = dllRasterPos2fv ; qglRasterPos2i = dllRasterPos2i ; qglRasterPos2iv = dllRasterPos2iv ; qglRasterPos2s = dllRasterPos2s ; qglRasterPos2sv = dllRasterPos2sv ; qglRasterPos3d = dllRasterPos3d ; qglRasterPos3dv = dllRasterPos3dv ; qglRasterPos3f = dllRasterPos3f ; qglRasterPos3fv = dllRasterPos3fv ; qglRasterPos3i = dllRasterPos3i ; qglRasterPos3iv = dllRasterPos3iv ; qglRasterPos3s = dllRasterPos3s ; qglRasterPos3sv = dllRasterPos3sv ; qglRasterPos4d = dllRasterPos4d ; qglRasterPos4dv = dllRasterPos4dv ; qglRasterPos4f = dllRasterPos4f ; qglRasterPos4fv = dllRasterPos4fv ; qglRasterPos4i = dllRasterPos4i ; qglRasterPos4iv = dllRasterPos4iv ; qglRasterPos4s = dllRasterPos4s ; qglRasterPos4sv = dllRasterPos4sv ; qglReadBuffer = dllReadBuffer ; qglReadPixels = dllReadPixels ; qglRectd = dllRectd ; qglRectdv = dllRectdv ; qglRectf = dllRectf ; qglRectfv = dllRectfv ; qglRecti = dllRecti ; qglRectiv = dllRectiv ; qglRects = dllRects ; qglRectsv = dllRectsv ; qglRenderMode = dllRenderMode ; qglRotated = dllRotated ; qglRotatef = dllRotatef ; qglScaled = dllScaled ; qglScalef = dllScalef ; qglScissor = dllScissor ; qglSelectBuffer = dllSelectBuffer ; qglShadeModel = dllShadeModel ; qglStencilFunc = dllStencilFunc ; qglStencilMask = dllStencilMask ; qglStencilOp = dllStencilOp ; qglTexCoord1d = dllTexCoord1d ; qglTexCoord1dv = dllTexCoord1dv ; qglTexCoord1f = dllTexCoord1f ; qglTexCoord1fv = dllTexCoord1fv ; qglTexCoord1i = dllTexCoord1i ; qglTexCoord1iv = dllTexCoord1iv ; qglTexCoord1s = dllTexCoord1s ; qglTexCoord1sv = dllTexCoord1sv ; qglTexCoord2d = dllTexCoord2d ; qglTexCoord2dv = dllTexCoord2dv ; qglTexCoord2f = dllTexCoord2f ; qglTexCoord2fv = dllTexCoord2fv ; qglTexCoord2i = dllTexCoord2i ; qglTexCoord2iv = dllTexCoord2iv ; qglTexCoord2s = dllTexCoord2s ; qglTexCoord2sv = dllTexCoord2sv ; qglTexCoord3d = dllTexCoord3d ; qglTexCoord3dv = dllTexCoord3dv ; qglTexCoord3f = dllTexCoord3f ; qglTexCoord3fv = dllTexCoord3fv ; qglTexCoord3i = dllTexCoord3i ; qglTexCoord3iv = dllTexCoord3iv ; qglTexCoord3s = dllTexCoord3s ; qglTexCoord3sv = dllTexCoord3sv ; qglTexCoord4d = dllTexCoord4d ; qglTexCoord4dv = dllTexCoord4dv ; qglTexCoord4f = dllTexCoord4f ; qglTexCoord4fv = dllTexCoord4fv ; qglTexCoord4i = dllTexCoord4i ; qglTexCoord4iv = dllTexCoord4iv ; qglTexCoord4s = dllTexCoord4s ; qglTexCoord4sv = dllTexCoord4sv ; qglTexCoordPointer = dllTexCoordPointer ; qglTexEnvf = dllTexEnvf ; qglTexEnvfv = dllTexEnvfv ; qglTexEnvi = dllTexEnvi ; qglTexEnviv = dllTexEnviv ; qglTexGend = dllTexGend ; qglTexGendv = dllTexGendv ; qglTexGenf = dllTexGenf ; qglTexGenfv = dllTexGenfv ; qglTexGeni = dllTexGeni ; qglTexGeniv = dllTexGeniv ; qglTexImage1D = dllTexImage1D ; qglTexImage2D = dllTexImage2D ; qglTexParameterf = dllTexParameterf ; qglTexParameterfv = dllTexParameterfv ; qglTexParameteri = dllTexParameteri ; qglTexParameteriv = dllTexParameteriv ; qglTexSubImage1D = dllTexSubImage1D ; qglTexSubImage2D = dllTexSubImage2D ; qglTranslated = dllTranslated ; qglTranslatef = dllTranslatef ; qglVertex2d = dllVertex2d ; qglVertex2dv = dllVertex2dv ; qglVertex2f = dllVertex2f ; qglVertex2fv = dllVertex2fv ; qglVertex2i = dllVertex2i ; qglVertex2iv = dllVertex2iv ; qglVertex2s = dllVertex2s ; qglVertex2sv = dllVertex2sv ; qglVertex3d = dllVertex3d ; qglVertex3dv = dllVertex3dv ; qglVertex3f = dllVertex3f ; qglVertex3fv = dllVertex3fv ; qglVertex3i = dllVertex3i ; qglVertex3iv = dllVertex3iv ; qglVertex3s = dllVertex3s ; qglVertex3sv = dllVertex3sv ; qglVertex4d = dllVertex4d ; qglVertex4dv = dllVertex4dv ; qglVertex4f = dllVertex4f ; qglVertex4fv = dllVertex4fv ; qglVertex4i = dllVertex4i ; qglVertex4iv = dllVertex4iv ; qglVertex4s = dllVertex4s ; qglVertex4sv = dllVertex4sv ; qglVertexPointer = dllVertexPointer ; qglViewport = dllViewport ; } } void GLimp_LogNewFrame( void ) { fprintf( glw_state.log_fp, "*** R_BeginFrame ***\n" ); } alien-arena-7.66+dfsg/source/unix/q_shunix.c0000600000175000017500000002220012161402010020063 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. Copyright (C) 2010 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #if defined HAVE_MREMAP #define _GNU_SOURCE #endif #include #include #include #include #include #include #include #if defined HAVE_TIME_H # include #elif defined HAVE_SYS_TIME_H # include #endif #include "unix/glob.h" #include "qcommon/qcommon.h" /* * State of currently open Hunk. * Valid between Hunk_Begin() and Hunk_End() */ byte *hunk_base = NULL; size_t *phunk_size_store = NULL; static const size_t hunk_header_size = 32; byte *user_hunk_base = NULL ; size_t rsvd_hunk_size; size_t user_hunk_size; size_t total_hunk_used_size; void *Hunk_Begin (int maxsize) { Com_DPrintf("Hunk_Begin:0x%X:\n", maxsize ); if ( hunk_base != NULL ) Com_DPrintf("Warning: Hunk_Begin: hunk_base != NULL\n"); // reserve virtual memory space rsvd_hunk_size = (size_t)maxsize + hunk_header_size; hunk_base = mmap(0, rsvd_hunk_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0); if ( hunk_base == NULL || hunk_base == (byte *)-1) Sys_Error("unable to virtual allocate %d bytes", maxsize); total_hunk_used_size = hunk_header_size; user_hunk_size = 0; user_hunk_base = hunk_base + hunk_header_size; // store the size reserved for Hunk_Free() phunk_size_store = (size_t *)hunk_base; *phunk_size_store = rsvd_hunk_size; // the initial reserved size return user_hunk_base; } void *Hunk_Alloc (int size) { byte *user_hunk_bfr; size_t user_hunk_block_size; size_t new_user_hunk_size; if ( hunk_base == NULL ) { Sys_Error("Program Error: Hunk_Alloc: hunk_base==NULL"); } // size is sometimes odd, so increment size to even boundary to avoid // odd-aligned accesses. user_hunk_block_size = ((size_t)size + 1) & ~0x01; new_user_hunk_size = user_hunk_size + user_hunk_block_size; total_hunk_used_size += user_hunk_block_size; if ( total_hunk_used_size > rsvd_hunk_size ) Sys_Error("Program Error: Hunk_Alloc: overflow"); user_hunk_bfr = user_hunk_base + user_hunk_size; // set base of new block user_hunk_size = new_user_hunk_size; // then update user hunk size // This will dump each allocate call. Too much info for regular use. //Com_DPrintf("Hunk_Alloc:%u @ %p:\n", user_hunk_block_size, user_hunk_bfr ); return (void *)user_hunk_bfr; } #if defined HAVE_MREMAP // easy version, mremap() should be available on all Linux int Hunk_End (void) { byte *remap_base; size_t new_rsvd_hunk_size; new_rsvd_hunk_size = total_hunk_used_size; remap_base = mremap( hunk_base, rsvd_hunk_size, new_rsvd_hunk_size, 0 ); if ( remap_base != hunk_base ) { Sys_Error("Hunk_End: Could not remap virtual block (%d)", errno); } // "close" this hunk, setting reserved size for Hunk_Free rsvd_hunk_size = new_rsvd_hunk_size; *phunk_size_store = rsvd_hunk_size; Com_DPrintf("Hunk_End.1:0x%X @ %p:\n", rsvd_hunk_size, remap_base ); hunk_base = user_hunk_base = NULL; phunk_size_store = NULL; return user_hunk_size; // user buffer is user_hunk_size @ user_hunk_base } #else // portable version (we hope) int Hunk_End() { size_t sys_pagesize; size_t rsvd_pages; size_t rsvd_size; size_t used_pages; size_t used_size; size_t unmap_size; void * unmap_base; // the portable way to get pagesize, according to documentation sys_pagesize = (size_t)sysconf( _SC_PAGESIZE ); // calculate page-aligned size that was reserved rsvd_pages = (rsvd_hunk_size / sys_pagesize); if ( (rsvd_hunk_size % sys_pagesize) != 0 ) rsvd_pages += 1; rsvd_size = rsvd_pages * sys_pagesize; // calculate page-aligned size that was used used_pages = total_hunk_used_size / sys_pagesize; if ( (total_hunk_used_size % sys_pagesize) != 0 ) used_pages += 1; used_size = used_pages * sys_pagesize; // unmap the unused space if ( used_size < rsvd_size ) { unmap_size = rsvd_size - used_size; unmap_base = (void *)(hunk_base + used_size); if ( ( munmap( unmap_base, unmap_size )) != 0 ) { Com_DPrintf("Hunk_End: munmap failed [0x%X @ %p]\n", unmap_size, unmap_base ); // throwing a Sys_Error is probably too drastic // Sys_Error("Program Error: Hunk_End: munmap failed"); } else { // update size reserved for Hunk_Free rsvd_hunk_size = used_size; *phunk_size_store = rsvd_hunk_size; } } Com_DPrintf( "Hunk_End.2:0x%X @ %p:\n", rsvd_hunk_size, hunk_base ); hunk_base = user_hunk_base = NULL; phunk_size_store = NULL; return user_hunk_size; } #endif void Hunk_Free (void *base) { byte *hunk_base; size_t hunk_rsvd_size; if ( base != NULL ) { // find hunk base and retreive the hunk reserved size hunk_base = base - hunk_header_size; hunk_rsvd_size = *((size_t *)hunk_base); Com_DPrintf("Hunk_Free:0x%X @ %p:\n", hunk_rsvd_size, hunk_base ); if ( munmap( hunk_base, hunk_rsvd_size ) ) Sys_Error("Hunk_Free: munmap failed (%d)", errno); } } //=============================================================================== /* ================ Sys_Milliseconds ================ */ int curtime; // curtime set at beginning of the main loop #if defined HAVE_CLOCK_GETTIME // version with more modern system time function int Sys_Milliseconds( void ) { static qboolean first_time = true; static time_t start_secs = 0; int errorflag; struct timespec tp; long timeofday; errorflag = clock_gettime( CLOCK_REALTIME, &tp ); if ( errorflag ) { Com_Printf("Sys_Milliseconds: clock_gettime() error\n"); timeofday = 0L; // fail } else if ( first_time ) { start_secs = tp.tv_sec; timeofday = tp.tv_nsec / 1000000L; first_time = false; } else { timeofday = ( tp.tv_sec - start_secs ) * 1000L; timeofday += tp.tv_nsec / 1000000L; } return (int)timeofday; } #else // version with old time function int Sys_Milliseconds (void) { struct timeval tp; static long secbase; long timeofday; // per documentation TZ arg is obsolete, never used, should be NULL. // POSIX.1-2008 recommends clock_gettime() gettimeofday( &tp, NULL ); if (!secbase) { secbase = tp.tv_sec; return tp.tv_usec/1000; } timeofday = (tp.tv_sec - secbase)*1000 + tp.tv_usec/1000; return (int)timeofday; } #endif void Sys_Mkdir (char *path) { int result; result = mkdir( path, 0700 ); // drwx------ appears to be preferred unix/linux practice for home dirs if ( !result ) { // success Com_Printf("Created directory %s\n", path ); } else { if ( errno != EEXIST ) { Com_DPrintf("Creating directory %s failed\n", path ); } } } //============================================ static char findbase[MAX_OSPATH]; static char findpath[MAX_OSPATH]; static char findpattern[MAX_OSPATH]; static DIR *fdir; static qboolean CompareAttributes(char *path, char *name, unsigned musthave, unsigned canthave ) { struct stat st; char fn[MAX_OSPATH]; // . and .. never match if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) return false; return true; if (stat(fn, &st) == -1) return false; // shouldn't happen if ( ( st.st_mode & S_IFDIR ) && ( canthave & SFF_SUBDIR ) ) return false; if ( ( musthave & SFF_SUBDIR ) && !( st.st_mode & S_IFDIR ) ) return false; return true; } char *Sys_FindFirst (char *path, unsigned musthave, unsigned canhave) { struct dirent *d; char *p; if (fdir) Sys_Error ("Sys_BeginFind without close"); // COM_FilePath (path, findbase); strcpy(findbase, path); if ((p = strrchr(findbase, '/')) != NULL) { *p = 0; strcpy(findpattern, p + 1); } else strcpy(findpattern, "*"); if (strcmp(findpattern, "*.*") == 0) strcpy(findpattern, "*"); if ((fdir = opendir(findbase)) == NULL) return NULL; while ((d = readdir(fdir)) != NULL) { if (!*findpattern || glob_match(findpattern, d->d_name)) { // if (*findpattern) // printf("%s matched %s\n", findpattern, d->d_name); if (CompareAttributes(findbase, d->d_name, musthave, canhave)) { sprintf (findpath, "%s/%s", findbase, d->d_name); return findpath; } } } return NULL; } char *Sys_FindNext (unsigned musthave, unsigned canhave) { struct dirent *d; if (fdir == NULL) return NULL; while ((d = readdir(fdir)) != NULL) { if (!*findpattern || glob_match(findpattern, d->d_name)) { // if (*findpattern) // printf("%s matched %s\n", findpattern, d->d_name); if (CompareAttributes(findbase, d->d_name, musthave, canhave)) { sprintf (findpath, "%s/%s", findbase, d->d_name); return findpath; } } } return NULL; } void Sys_FindClose (void) { if (fdir != NULL) closedir(fdir); fdir = NULL; } //============================================ alien-arena-7.66+dfsg/source/unix/gl_glx.c0000600000175000017500000005624312161402010017517 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #if defined HAVE_UNISTD_H #include #endif #include #if defined HAVE_DLFCN_H #include #endif #include "qcommon/qcommon.h" #include "ref_gl/r_local.h" #include "client/keys.h" #include "unix/glw_unix.h" #include #include #include #include #if defined HAVE_XXF86VM #include #endif // defined HAVE_XXF86VM #if defined HAVE_XXF86DGA # if defined HAVE_X11_EXTENSIONS_XXF86DGA_H #include # else // defined HAVE_X11_EXTENSIONS_XXF86DGA_H #include # endif // defined HAVE_X11_EXTENSIONS_XXF86DGA_H #endif #include /* extern globals */ // using include files for these has some problems extern cursor_t cursor; extern qboolean mouse_available; extern qboolean mouse_is_position; extern int mouse_diff_x; extern int mouse_diff_y; extern float rs_realtime; extern viddef_t vid; void GLimp_BeginFrame( float camera_separation ); void GLimp_EndFrame( void ); qboolean GLimp_Init( void *hinstance, void *hWnd ); void GLimp_Shutdown( void ); rserr_t GLimp_SetMode( unsigned *pwidth, unsigned *pheight, int mode, qboolean fullscreen ); void GLimp_AppActivate( qboolean active ); void GLimp_EnableLogging( qboolean enable ); void GLimp_LogNewFrame( void ); //--------------------------------------------------------------------------- glwstate_t glw_state; static Display *dpy = NULL; static int scrnum; static Window win; static GLXContext ctx = NULL; static Atom wmDeleteWindow; static Atom cor_clipboard; qboolean have_stencil = false; // Stencil shadows - MrG #define KEY_MASK (KeyPressMask | KeyReleaseMask) #define MOUSE_MASK (ButtonPressMask | ButtonReleaseMask | \ PointerMotionMask | ButtonMotionMask ) #define X_MASK (KEY_MASK | MOUSE_MASK | VisibilityChangeMask | \ StructureNotifyMask | PropertyChangeMask ) /*****************************************************************************/ /* MOUSE */ /*****************************************************************************/ static cvar_t *r_fakeFullscreen; extern cvar_t *in_dgamouse; static int win_x, win_y; #if defined HAVE_XXF86VM static XF86VidModeModeInfo **vidmodes; #endif // defined HAVE_XXF86VM static qboolean vidmode_active = false; qboolean mouse_active = false; qboolean dgamouse = false; qboolean vidmode_ext = false; static Cursor CreateNullCursor(Display *display, Window root) { Pixmap cursormask; XGCValues xgc; GC gc; XColor dummycolour; Cursor cursor; cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/); xgc.function = GXclear; gc = XCreateGC(display, cursormask, GCFunction, &xgc); XFillRectangle(display, cursormask, gc, 0, 0, 1, 1); dummycolour.pixel = 0; dummycolour.red = 0; dummycolour.flags = 04; cursor = XCreatePixmapCursor(display, cursormask, cursormask, &dummycolour,&dummycolour, 0,0); XFreePixmap(display,cursormask); XFreeGC(display,gc); return cursor; } void install_grabs(void) { #if defined DEBUG_GDB_NOGRAB // for running on gdb debug. prevents "lockup". Cvar_Set( "in_dgamouse", "0" ); dgamouse = false; mouse_is_position = false; #else // defined DEBUG_GDB_NOGRAB # if !defined HAVE_XXF86DGA XGrabPointer(dpy, win, True, 0, GrabModeAsync, GrabModeAsync, win, None, CurrentTime); XWarpPointer(dpy, None, win, 0, 0, 0, 0, vid.width / 2, vid.height / 2); Cvar_Set( "in_dgamouse", "0" ); dgamouse = false; # else // !defined HAVE_XXF86DGA XGrabPointer(dpy, win, True, 0, GrabModeAsync, GrabModeAsync, win, None, CurrentTime); if (in_dgamouse->integer) { int MajorVersion, MinorVersion; if (XF86DGAQueryVersion(dpy, &MajorVersion, &MinorVersion)) { XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0); XF86DGADirectVideo(dpy, DefaultScreen(dpy), XF86DGADirectMouse); dgamouse = true; } else { // unable to query, probably not supported Com_Printf ( "Failed to detect XF86DGA Mouse\n" ); Cvar_Set( "in_dgamouse", "0" ); dgamouse = false; XWarpPointer(dpy, None, win, 0, 0, 0, 0, vid.width / 2, vid.height / 2); } } else { XWarpPointer(dpy, None, win, 0, 0, 0, 0, vid.width / 2, vid.height / 2); } # endif // !defined HAVE_XXF86DGA XGrabKeyboard(dpy, win, False, GrabModeAsync, GrabModeAsync, CurrentTime); mouse_is_position = false; mouse_diff_x = mouse_diff_y = 0; #endif // defined DEBUG_GDB_NOGRAB } void uninstall_grabs(void) { if (!dpy || !win) return; #if defined HAVE_XXF86DGA if (dgamouse) { dgamouse = false; XF86DGADirectVideo(dpy, DefaultScreen(dpy), 0); } #endif XUngrabPointer(dpy, CurrentTime); XUngrabKeyboard(dpy, CurrentTime); mouse_is_position = true; } static void IN_DeactivateMouse( void ) { if (!dpy || !win) return; if (!mouse_is_position) { uninstall_grabs(); } } static void IN_ActivateMouse( void ) { if (!dpy || !win) return; if (mouse_is_position) { install_grabs(); } } void IN_Activate(qboolean active) { if (active || vidmode_active) IN_ActivateMouse(); else IN_DeactivateMouse (); } /*****************************************************************************/ /* KEYBOARD */ /*****************************************************************************/ static int XLateKey( XKeyEvent *ev ) { int key; char buf[64]; int buflen; KeySym keysym; key = 0; buflen = XLookupString( ev, buf, sizeof buf, &keysym, 0 ); switch ( keysym ) { case XK_KP_Page_Up: key = K_KP_PGUP; break; case XK_Page_Up: key = K_PGUP; break; case XK_KP_Page_Down: key = K_KP_PGDN; break; case XK_Page_Down: key = K_PGDN; break; case XK_KP_Home: key = K_KP_HOME; break; case XK_Home: key = K_HOME; break; case XK_KP_End: key = K_KP_END; break; case XK_End: key = K_END; break; case XK_KP_Left: key = K_KP_LEFTARROW; break; case XK_Left: key = K_LEFTARROW; break; case XK_KP_Right: key = K_KP_RIGHTARROW; break; case XK_Right: key = K_RIGHTARROW; break; case XK_KP_Down: key = K_KP_DOWNARROW; break; case XK_Down: key = K_DOWNARROW; break; case XK_KP_Up: key = K_KP_UPARROW; break; case XK_Up: key = K_UPARROW; break; case XK_Escape: key = K_ESCAPE; break; case XK_KP_Enter: key = K_KP_ENTER; break; case XK_Return: key = K_ENTER; break; case XK_Tab: key = K_TAB; break; case XK_F1: key = K_F1; break; case XK_F2: key = K_F2; break; case XK_F3: key = K_F3; break; case XK_F4: key = K_F4; break; case XK_F5: key = K_F5; break; case XK_F6: key = K_F6; break; case XK_F7: key = K_F7; break; case XK_F8: key = K_F8; break; case XK_F9: key = K_F9; break; case XK_F10: key = K_F10; break; case XK_F11: key = K_F11; break; case XK_F12: key = K_F12; break; case XK_BackSpace: key = K_BACKSPACE; break; case XK_KP_Delete: key = K_KP_DEL; break; case XK_Delete: key = K_DEL; break; case XK_Pause: key = K_PAUSE; break; case XK_Shift_L: case XK_Shift_R: key = K_SHIFT; break; case XK_Execute: case XK_Control_L: case XK_Control_R: key = K_CTRL; break; case XK_Alt_L: case XK_Meta_L: case XK_Alt_R: case XK_Meta_R: key = K_ALT; break; case XK_KP_Begin: key = K_KP_5; break; case XK_Insert: key = K_INS; break; case XK_KP_Insert: key = K_KP_INS; break; case XK_KP_Multiply: key = '*'; break; case XK_KP_Add: key = K_KP_PLUS; break; case XK_KP_Subtract: key = K_KP_MINUS; break; case XK_KP_Divide: key = K_KP_SLASH; break; default: if ( buflen == 1 ) { key = *(unsigned char*)buf; if ( key >= 'A' && key <= 'Z' ) key = key - 'A' + 'a'; if ( key >= 1 && key <= 26 ) /* ctrl+alpha */ key = key + 'a' - 1; } break; } return key; } void HandleEvents( void ) { XEvent event; qboolean dowarp = false; int mwx = vid.width / 2; int mwy = vid.height / 2; int multiclicktime = 750; int mouse_button; static int last_mouse_x = 0, last_mouse_y = 0; float f_sys_msecs; unsigned u_sys_msecs; if ( !dpy ) return; // do one read of time for consistency // theory is that all pending events occurring before this point in time // should be considered occurring at this single point in time. u_sys_msecs = (unsigned)Sys_Milliseconds(); f_sys_msecs = (float)u_sys_msecs; while ( XPending( dpy ) ) { XNextEvent( dpy, &event ); // TODO: check for errors here, maybe switch ( event.type ) { case KeyPress: Key_Event( XLateKey( &event.xkey ), true, u_sys_msecs ); break; case KeyRelease: Key_Event( XLateKey( &event.xkey ), false, u_sys_msecs ); break; case MotionNotify: last_mouse_x = event.xmotion.x; last_mouse_y = event.xmotion.y; break; case ButtonPress: if ( event.xbutton.button ) { mouse_button = event.xbutton.button - 1; switch ( mouse_button ) { // index swap, buttons 2 & 3 case 1: mouse_button = 2; break; case 2: mouse_button = 1; break; } if (mouse_button < MENU_CURSOR_BUTTON_MAX) { if ( (f_sys_msecs - cursor.buttontime[mouse_button]) < multiclicktime ) cursor.buttonclicks[mouse_button] += 1; else cursor.buttonclicks[mouse_button] = 1; if ( cursor.buttonclicks[mouse_button] > 3 ) cursor.buttonclicks[mouse_button] = 3; cursor.buttontime[mouse_button] = f_sys_msecs; cursor.buttondown[mouse_button] = true; cursor.buttonused[mouse_button] = false; cursor.mouseaction = true; } switch ( event.xbutton.button ) { case 1: Key_Event( K_MOUSE1, true, u_sys_msecs ); break; case 2: Key_Event( K_MOUSE3, true, u_sys_msecs ); break; case 3: Key_Event( K_MOUSE2, true, u_sys_msecs ); break; case 4: Key_Event( K_MWHEELUP, true, u_sys_msecs ); break; case 5: Key_Event( K_MWHEELDOWN, true, u_sys_msecs ); break; case 6: Key_Event( K_MOUSE4, true, u_sys_msecs ); break; case 7: Key_Event( K_MOUSE5, true, u_sys_msecs ); break; case 8: Key_Event( K_MOUSE6, true, u_sys_msecs ); break; case 9: Key_Event( K_MOUSE7, true, u_sys_msecs ); break; case 10: Key_Event( K_MOUSE8, true, u_sys_msecs ); break; case 11: Key_Event( K_MOUSE9, true, u_sys_msecs ); break; } } break; case ButtonRelease: if ( event.xbutton.button ) { mouse_button = event.xbutton.button - 1; switch ( mouse_button ) { // index swap, buttons 2 & 3 case 1: mouse_button = 2; break; case 2: mouse_button = 1; break; } if (mouse_button < MENU_CURSOR_BUTTON_MAX) { cursor.buttondown[mouse_button] = false; cursor.buttonused[mouse_button] = false; } switch ( event.xbutton.button ) { case 1: Key_Event( K_MOUSE1, false, u_sys_msecs ); break; case 2: Key_Event( K_MOUSE3, false, u_sys_msecs ); break; case 3: Key_Event( K_MOUSE2, false, u_sys_msecs ); break; case 4: Key_Event( K_MWHEELUP, false, u_sys_msecs ); break; case 5: Key_Event( K_MWHEELDOWN, false, u_sys_msecs ); break; case 6: Key_Event( K_MOUSE4, false, u_sys_msecs ); break; case 7: Key_Event( K_MOUSE5, false, u_sys_msecs ); break; case 8: Key_Event( K_MOUSE6, false, u_sys_msecs ); break; case 9: Key_Event( K_MOUSE7, false, u_sys_msecs ); break; case 10: Key_Event( K_MOUSE8, false, u_sys_msecs ); break; case 11: Key_Event( K_MOUSE9, false, u_sys_msecs ); break; } } break; case CreateNotify: win_x = event.xcreatewindow.x; win_y = event.xcreatewindow.y; break; case ConfigureNotify: win_x = event.xconfigure.x; win_y = event.xconfigure.y; break; case ClientMessage: if ( event.xclient.data.l[0] == wmDeleteWindow ) Cbuf_ExecuteText( EXEC_NOW, "quit" ); break; } } if ( mouse_is_position ) { // allow mouse movement on menus in windowed mode mouse_diff_x = last_mouse_x; mouse_diff_y = last_mouse_y; } else { if ( dgamouse ) { // TODO: find documentation for DGA mouse, explain this mouse_diff_x += (last_mouse_x + (vidmode_active ? 0 : win_x)) * 2; mouse_diff_y += (last_mouse_y + (vidmode_active ? 0 : win_y)) * 2; } else { // add the delta from the current position to the center // to the pointer motion accumulator mouse_diff_x += ((int)last_mouse_x - mwx); mouse_diff_y += ((int)last_mouse_y - mwy); // flag to recenter pointer dowarp = (mouse_diff_x != 0 || mouse_diff_y != 0 ); } } if ( dowarp ) { /* move the pointer back to the window center */ XWarpPointer( dpy, None, win, 0, 0, 0, 0, mwx, mwy ); } } /*****************************************************************************/ qboolean GLimp_InitGL (void); // TODO: modernize signal handler static void signal_handler(int sig) { printf("Received signal %d, exiting...\n", sig); GLimp_Shutdown(); exit(0); } static void InitSig(void) { signal(SIGHUP, signal_handler); signal(SIGQUIT, signal_handler); signal(SIGILL, signal_handler); signal(SIGTRAP, signal_handler); signal(SIGIOT, signal_handler); signal(SIGBUS, signal_handler); signal(SIGFPE, signal_handler); signal(SIGSEGV, signal_handler); signal(SIGTERM, signal_handler); } /* ** GLimp_SetMode */ rserr_t GLimp_SetMode( unsigned *pwidth, unsigned *pheight, int mode, qboolean fullscreen ) { extern cvar_t *vid_xpos; // X coordinate of window position extern cvar_t *vid_ypos; // Y coordinate of window position int xpos, ypos; int width, height; int attrib[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 4, GLX_GREEN_SIZE, 4, GLX_BLUE_SIZE, 4, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 8, None }; int attrib2[] = { //no stencil buffer, original settings GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 1, None }; Window root; XVisualInfo *visinfo; XSetWindowAttributes attr; XSizeHints *sizehints; unsigned long mask; #if defined HAVE_XXF86VM int MajorVersion, MinorVersion; int actualWidth, actualHeight; int i; #endif r_fakeFullscreen = Cvar_Get( "r_fakeFullscreen", "0", CVAR_ARCHIVE); Com_Printf ( "Initializing OpenGL display\n"); if (fullscreen) Com_Printf ("...setting fullscreen mode %d:", mode ); else Com_Printf ("...setting mode %d:", mode ); if ( !VID_GetModeInfo( &width, &height, mode ) ) { Com_Printf ( " invalid mode\n" ); return rserr_invalid_mode; } Com_Printf ( " %d %d\n", width, height ); // destroy the existing window GLimp_Shutdown (); if (!(dpy = XOpenDisplay(NULL))) { fprintf(stderr, "Error couldn't open the X display\n"); return rserr_invalid_mode; } scrnum = DefaultScreen(dpy); root = RootWindow(dpy, scrnum); // Get video mode list #if defined HAVE_XXF86VM MajorVersion = MinorVersion = 0; if (!XF86VidModeQueryVersion(dpy, &MajorVersion, &MinorVersion)) { vidmode_ext = false; } else { Com_Printf ( "Using XFree86-VidModeExtension Version %d.%d\n", MajorVersion, MinorVersion); vidmode_ext = true; } #else // defined HAVE_XXF86VM vidmode_ext = false; #endif // defined HAVE_XXF86VM visinfo = qglXChooseVisual(dpy, scrnum, attrib); if (!visinfo) { fprintf(stderr, "Error couldn't get an RGB, Double-buffered, Depth visual, Stencil Buffered\n"); visinfo = qglXChooseVisual(dpy, scrnum, attrib2); if(!visinfo){ fprintf(stderr, "Error couldn't get an RGB, Double-buffered, Depth visual\n"); return rserr_invalid_mode; } } else have_stencil = true; vidmode_active = false; xpos = ypos = 0; #if defined HAVE_XXF86VM if (vidmode_ext) { int best_fit, best_dist, dist, x, y, num_vidmodes; XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes); // Are we going fullscreen? If so, let's change video mode if (fullscreen && !r_fakeFullscreen->integer) { best_dist = 9999999; best_fit = -1; for (i = 0; i < num_vidmodes; i++) { if (width > vidmodes[i]->hdisplay || height > vidmodes[i]->vdisplay) continue; x = width - vidmodes[i]->hdisplay; y = height - vidmodes[i]->vdisplay; dist = (x * x) + (y * y); if (dist < best_dist) { best_dist = dist; best_fit = i; } } if (best_fit != -1) { actualWidth = vidmodes[best_fit]->hdisplay; actualHeight = vidmodes[best_fit]->vdisplay; // change to the mode XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]); vidmode_active = true; // Move the viewport to top left XF86VidModeSetViewPort(dpy, scrnum, 0, 0); if (width != actualWidth || height != actualHeight) { xpos = vid_xpos->integer; ypos = vid_ypos->integer; Com_Printf ("Resolution %dx%d is not supported natively by the display!\n", width, height); Com_Printf ("Closest screen resolution is %dx%d. ", actualWidth, actualHeight); Com_Printf ("Use vid_xpos and vid_ypos to adjust the position of the game window (current offset is %d, %d)\n", xpos, ypos); } } else fullscreen = 0; } } #endif // defined HAVE_XXF86VM /* window attributes */ attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone); attr.event_mask = X_MASK; if (vidmode_active) { mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore | CWEventMask | CWOverrideRedirect; attr.override_redirect = True; attr.backing_store = NotUseful; attr.save_under = False; } else mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow(dpy, root, 0, 0, width, height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); sizehints = XAllocSizeHints(); if (sizehints) { sizehints->min_width = width; sizehints->min_height = height; sizehints->max_width = width; sizehints->max_height = height; sizehints->base_width = width; sizehints->base_height = vid.height; sizehints->flags = PMinSize | PMaxSize | PBaseSize; } XSetWMProperties(dpy, win, NULL, NULL, NULL, 0, sizehints, None, None); if (sizehints) XFree(sizehints); XStoreName(dpy, win, "Alien Arena"); wmDeleteWindow = XInternAtom(dpy, "WM_DELETE_WINDOW", False); XSetWMProtocols(dpy, win, &wmDeleteWindow, 1); cor_clipboard = XInternAtom(dpy, "COR_CLIPBOARD", False); XMapWindow(dpy, win); #if defined HAVE_XXF86VM if (vidmode_active) { XMoveWindow(dpy, win, xpos, ypos); XRaiseWindow(dpy, win); XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0); XFlush(dpy); // Move the viewport to top left XF86VidModeSetViewPort(dpy, scrnum, xpos, ypos); } #endif // defined HAVE_XXF86VM XFlush(dpy); ctx = qglXCreateContext(dpy, visinfo, NULL, True); qglXMakeCurrent(dpy, win, ctx); *pwidth = width; *pheight = height; // let the sound and input subsystems know about the new window VID_NewWindow (width, height); XDefineCursor(dpy, win, CreateNullCursor(dpy, win)); qglXMakeCurrent(dpy, win, ctx); RS_ScanPathForScripts(); // load all found scripts return rserr_ok; } /* ** GLimp_Shutdown ** ** This routine does all OS specific shutdown procedures for the OpenGL ** subsystem. Under OpenGL this means NULLing out the current DC and ** HGLRC, deleting the rendering context, and releasing the DC acquired ** for the window. The state structure is also nulled out. ** */ void GLimp_Shutdown( void ) { uninstall_grabs(); mouse_is_position = true; dgamouse = false; if (dpy) { if (ctx) qglXDestroyContext(dpy, ctx); if (win) XDestroyWindow(dpy, win); #if defined HAVE_XXF86VM if (vidmode_active) XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[0]); #endif // defined HAVE_XXF86VM XUngrabKeyboard(dpy, CurrentTime); XCloseDisplay(dpy); } ctx = NULL; dpy = NULL; win = 0; } /* ** GLimp_Init ** ** This routine is responsible for initializing the OS specific portions ** of OpenGL. */ qboolean GLimp_Init( void *hinstance, void *wndproc ) { InitSig(); return true; } /* ** GLimp_BeginFrame */ void GLimp_BeginFrame( float camera_seperation ) { } /* ** GLimp_EndFrame ** ** Responsible for doing a swapbuffers and possibly for other stuff ** as yet to be determined. Probably better not to make this a GLimp ** function and instead do a call to GLimp_SwapBuffers. */ void GLimp_EndFrame (void) { qglXSwapBuffers(dpy, win); // does glFlush() // rscript - MrG rs_realtime = (float)Sys_Milliseconds() * 0.0005f; } /* ** GLimp_AppActivate */ void GLimp_AppActivate( qboolean active ) { } void Fake_glColorTableEXT( GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table ) { byte temptable[256][4]; byte *intbl; int i; for (intbl = (byte *)table, i = 0; i < 256; i++) { temptable[i][2] = *intbl++; temptable[i][1] = *intbl++; temptable[i][0] = *intbl++; temptable[i][3] = 255; } qgl3DfxSetPaletteEXT((GLuint *)temptable); } /*------------------------------------------------*/ /* X11 Input Stuff */ /*------------------------------------------------*/ /* ** Sys_GetClipboardData() ** ** Returns the contents of the X clipboard; needs to ** be here instead of inside sys_unix.c because it ** needs to access the X display. */ char *Sys_GetClipboardData(void) { XEvent evt; int sent_at; Bool received; Atom prop_type; int prop_fmt; unsigned long prop_items, prop_size; unsigned char *buffer, *output = NULL; // request the contents of the clipboard XConvertSelection( dpy, XA_PRIMARY, XA_STRING, cor_clipboard, win, CurrentTime ); sent_at = Sys_Milliseconds(); // now we need to wait until either: // 1) we get a response // 2) 250ms have gone by and we got nothing do { received = XCheckTypedEvent( dpy, SelectionNotify, &evt ); } while ( !( received || Sys_Milliseconds() - sent_at > 250 ) ); // no reply received, return NULL if ( !received ) return NULL; // get information about property XGetWindowProperty( dpy , win, cor_clipboard, 0, 0, False, AnyPropertyType, &prop_type, &prop_fmt, &prop_items, &prop_size, &buffer ); XFree(buffer); // only get the text if it's actually ASCII if ( prop_fmt == 8 ) { XGetWindowProperty( dpy , win, cor_clipboard, 0, prop_size, False, AnyPropertyType, &prop_type, &prop_fmt, &prop_items, &prop_size, &buffer ); output = malloc( prop_items + 1 ); memcpy( output, buffer, prop_items ); output[prop_items] = 0; } XDeleteProperty(dpy, win, cor_clipboard); return (char*)output; } alien-arena-7.66+dfsg/source/unix/glw_unix.h0000600000175000017500000000153312161402010020074 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ typedef struct { void *OpenGLLib; // instance of OpenGL library FILE *log_fp; } glwstate_t; extern glwstate_t glw_state; alien-arena-7.66+dfsg/source/unix/sys_unix.c0000600000175000017500000001767212161402010020127 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #if defined HAVE_UNISTD_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined HAVE_DLFCN_H #include #endif #include "qcommon/qcommon.h" #include "unix/rw_unix.h" cvar_t *nostdout; unsigned sys_frame_time; uid_t saved_euid; qboolean stdin_active = true; // attachment to statically linked game library extern void *GetGameAPI ( void *import); // ======================================================================= // General routines // ======================================================================= // Added ANSI color-escape output based on/inspired by Warsow. -M void Sys_ConsoleOutput (char *string) { #if defined ANSI_COLOR static int q3ToAnsi[ 8 ] = { 30, // COLOR_BLACK 31, // COLOR_RED 32, // COLOR_GREEN 33, // COLOR_YELLOW 34, // COLOR_BLUE 36, // COLOR_CYAN 35, // COLOR_MAGENTA 0 // COLOR_WHITE }; if ( nostdout && nostdout->integer ) return; while (*string) { if (*string == '^' && string[1]) { int colornum = (string[1]-'0')&7; printf ("\033[%dm", q3ToAnsi[colornum]); string += 2; continue; } if (*string == '\n') printf ("\033[0m\n"); else if (*string == ' ') printf ("\033[0m "); else printf ("%c", *string); string++; } #else if ( nostdout == NULL || !nostdout->integer ) { fputs( string, stdout ); } #endif } #if 0 // not currently used in Unix/Linux void Sys_Printf (const char *fmt, ...) { va_list argptr; char text[1024]; unsigned char *p; va_start (argptr,fmt); vsnprintf (text,1024,fmt,argptr); va_end (argptr); if (nostdout && nostdout->value) return; for (p = (unsigned char *)text; *p; p++) { *p &= 0x7f; if ((*p > 128 || *p < 32) && *p != 10 && *p != 13 && *p != 9) printf("[%02x]", *p); else putc(*p, stdout); } } #endif void Sys_Quit (void) { fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY); CL_Shutdown (); Qcommon_Shutdown (); exit(0); } void Sys_Init(void) { } //void Sys_Error (const char *error, ...) void Sys_Error (char *error, ...) { va_list argptr; char string[1024]; // change stdin to non blocking fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY); CL_Shutdown (); Qcommon_Shutdown (); va_start (argptr,error); vsnprintf (string,1024,error,argptr); va_end (argptr); fprintf(stderr, "Error: %s\n", string); exit (1); } void Sys_Warn (char *warning, ...) { va_list argptr; char string[1024]; va_start (argptr,warning); vsnprintf (string,1024,warning,argptr); va_end (argptr); fprintf(stderr, "Warning: %s", string); } /* ============ Sys_FileTime returns -1 if not present ============ */ int Sys_FileTime (char *path) { struct stat buf; if (stat (path,&buf) == -1) return -1; return buf.st_mtime; } void floating_point_exception_handler(int whatever) { // Sys_Warn("floating point exception\n"); signal(SIGFPE, floating_point_exception_handler); } char *Sys_ConsoleInput(void) { static char text[256]; int len; fd_set fdset; struct timeval timeout; if (!stdin_active) return NULL; FD_ZERO(&fdset); FD_SET(0, &fdset); // stdin timeout.tv_sec = 0; timeout.tv_usec = 0; if (select (1, &fdset, NULL, NULL, &timeout) == -1 || !FD_ISSET(0, &fdset)) return NULL; len = read (0, text, sizeof(text)); if (len == 0) { // eof! stdin_active = false; return NULL; } if (len < 1) return NULL; text[len-1] = 0; // rip off the /n and terminate return text; } /*****************************************************************************/ static void *game_library = NULL; /* ================= Sys_UnloadGame ================= */ void Sys_UnloadGame (void) { if ( game_library != NULL ) dlclose (game_library); game_library = NULL; } /* ================= Sys_GetGameAPI Loads the game module 2010-08 : Implements a statically linked game module. Loading a game module lib is supported if it exists. To prevent problems with attempting to load an older, incompatible version, a lib will not be loaded from arena/ nor data1/ ================= */ void *Sys_GetGameAPI (void *parms) { void *(*ptrGetGameAPI) (void *) = NULL; FILE *fp; char name[MAX_OSPATH]; char *path; size_t pathlen; char *str_p; const char *gamename = "game.so"; setreuid(getuid(), getuid()); setegid(getgid()); if (game_library != NULL) Com_Error (ERR_FATAL, "Sys_GetGameAPI without Sys_UnloadingGame"); // now run through the search paths path = NULL; while (1) { path = FS_NextPath (path); if (!path) break; // Search did not turn up a game shared library pathlen = strlen( path ); // old game lib in data1 is a problem if ( !Q_strncasecmp( "data1", &path[ pathlen-5 ], 5 ) ) continue; // may want to have a game lib in arena, but disable for now if ( !Q_strncasecmp( "arena", &path[ pathlen-5 ], 5 ) ) continue; snprintf (name, MAX_OSPATH, "%s/%s", path, gamename); /* skip it if it just doesn't exist */ fp = fopen(name, "rb"); if (fp == NULL) continue; fclose(fp); game_library = dlopen (name, RTLD_NOW); if (game_library != NULL ) { Com_Printf("------- Loading %s -------\n", gamename); break; } else { Com_DPrintf ("LoadLibrary (%s):", name); path = dlerror(); str_p = strchr(path, ':'); // skip the path (already shown) if (str_p == NULL) str_p = path; else str_p++; Com_DPrintf ("%s\n", str_p); break; // file opened but did not dlopen } } if ( game_library != NULL ) { // game module from dlopen'd shared library ptrGetGameAPI = (void *)dlsym (game_library, "GetGameAPI"); } /* * No game shared library found, use statically linked game */ if ( ptrGetGameAPI == NULL ) { ptrGetGameAPI = &GetGameAPI; } if ( ptrGetGameAPI == NULL ) { // program error Sys_UnloadGame (); return NULL; } return ptrGetGameAPI (parms); } /*****************************************************************************/ void Sys_AppActivate (void) { } void HandleEvents(void); void Sys_SendKeyEvents (void) { #ifndef DEDICATED_ONLY HandleEvents(); #endif // grab frame time sys_frame_time = Sys_Milliseconds(); } /*****************************************************************************/ int main (int argc, char **argv) { int time, oldtime, newtime; // go back to real user for config loads saved_euid = geteuid(); seteuid(getuid()); Qcommon_Init(argc, argv); fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY); nostdout = Cvar_Get("nostdout", "0", 0); if (!nostdout->value) { fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY); } oldtime = Sys_Milliseconds (); while (1) { // find time spent rendering last frame do { newtime = Sys_Milliseconds (); time = newtime - oldtime; } while (time < 1); // curtime setting moved from Sys_Milliseconds() // so it consistent for entire frame curtime = newtime; Qcommon_Frame (time); oldtime = newtime; } } alien-arena-7.66+dfsg/source/unix/odesrc/0000700000175000017500000000000012207204656017363 5ustar zero79zero79alien-arena-7.66+dfsg/source/unix/odesrc/heightfield.h0000600000175000017500000001470412161402010021777 0ustar zero79zero79// dHeightfield Collider // Martijn Buijs 2006 http://home.planet.nl/~buijs512/ // Based on Terrain & Cone contrib by: // Benoit CHAPEROT 2003-2004 http://www.jstarlab.com #ifndef _DHEIGHTFIELD_H_ #define _DHEIGHTFIELD_H_ //------------------------------------------------------------------------------ #include #include "collision_kernel.h" #define HEIGHTFIELDMAXCONTACTPERCELL 10 class HeightFieldVertex; class HeightFieldEdge; class HeightFieldTriangle; // // dxHeightfieldData // // Heightfield Data structure // struct dxHeightfieldData { dReal m_fWidth; // World space heightfield dimension on X axis dReal m_fDepth; // World space heightfield dimension on Z axis dReal m_fSampleWidth; // Vertex spacing on X axis edge (== m_vWidth / (m_nWidthSamples-1)) dReal m_fSampleDepth; // Vertex spacing on Z axis edge (== m_vDepth / (m_nDepthSamples-1)) dReal m_fSampleZXAspect; // Relation of Z axis spacing to X axis spacing (== m_fSampleDepth / m_fSampleWidth) dReal m_fInvSampleWidth; // Cache of inverse Vertex count on X axis edge (== m_vWidth / (m_nWidthSamples-1)) dReal m_fInvSampleDepth; // Cache of inverse Vertex count on Z axis edge (== m_vDepth / (m_nDepthSamples-1)) dReal m_fHalfWidth; // Cache of half of m_fWidth dReal m_fHalfDepth; // Cache of half of m_fDepth dReal m_fMinHeight; // Min sample height value (scaled and offset) dReal m_fMaxHeight; // Max sample height value (scaled and offset) dReal m_fThickness; // Surface thickness (added to bottom AABB) dReal m_fScale; // Sample value multiplier dReal m_fOffset; // Vertical sample offset int m_nWidthSamples; // Vertex count on X axis edge (number of samples) int m_nDepthSamples; // Vertex count on Z axis edge (number of samples) int m_bCopyHeightData; // Do we own the sample data? int m_bWrapMode; // Heightfield wrapping mode (0=finite, 1=infinite) int m_nGetHeightMode; // GetHeight mode ( 0=callback, 1=byte, 2=short, 3=float ) const void* m_pHeightData; // Sample data array void* m_pUserData; // Callback user data dContactGeom m_contacts[HEIGHTFIELDMAXCONTACTPERCELL]; dHeightfieldGetHeight* m_pGetHeightCallback; // Callback pointer. dxHeightfieldData(); ~dxHeightfieldData(); void SetData( int nWidthSamples, int nDepthSamples, dReal fWidth, dReal fDepth, dReal fScale, dReal fOffset, dReal fThickness, int bWrapMode ); void ComputeHeightBounds(); bool IsOnHeightfield2 ( const HeightFieldVertex * const CellCorner, const dReal * const pos, const bool isABC) const; dReal GetHeight(int x, int z); dReal GetHeight(dReal x, dReal z); }; typedef int HeightFieldVertexCoords[2]; class HeightFieldVertex { public: HeightFieldVertex(){}; dVector3 vertex; HeightFieldVertexCoords coords; bool state; }; class HeightFieldEdge { public: HeightFieldEdge(){}; HeightFieldVertex *vertices[2]; }; class HeightFieldTriangle { public: HeightFieldTriangle(){}; inline void setMinMax() { maxAAAB = vertices[0]->vertex[1] > vertices[1]->vertex[1] ? vertices[0]->vertex[1] : vertices[1]->vertex[1]; maxAAAB = vertices[2]->vertex[1] > maxAAAB ? vertices[2]->vertex[1] : maxAAAB; }; HeightFieldVertex *vertices[3]; dReal planeDef[4]; dReal maxAAAB; bool isUp; bool state; }; class HeightFieldPlane { public: HeightFieldPlane(): trianglelist(0), trianglelistReservedSize(0), trianglelistCurrentSize(0) { }; ~HeightFieldPlane() { delete [] trianglelist; }; inline void setMinMax() { const size_t asize = trianglelistCurrentSize; if (asize > 0) { maxAAAB = trianglelist[0]->maxAAAB; for (size_t k = 1; asize > k; k++) { if (trianglelist[k]->maxAAAB > maxAAAB) maxAAAB = trianglelist[k]->maxAAAB; } } }; void resetTriangleListSize(const size_t newSize) { if (trianglelistReservedSize < newSize) { delete [] trianglelist; trianglelistReservedSize = newSize; trianglelist = new HeightFieldTriangle *[newSize]; } trianglelistCurrentSize = 0; } void addTriangle(HeightFieldTriangle *tri) { dIASSERT(trianglelistCurrentSize < trianglelistReservedSize); trianglelist[trianglelistCurrentSize++] = tri; } HeightFieldTriangle **trianglelist; size_t trianglelistReservedSize; size_t trianglelistCurrentSize; dReal maxAAAB; dReal planeDef[4]; }; // // dxHeightfield // // Heightfield geom structure // struct dxHeightfield : public dxGeom { dxHeightfieldData* m_p_data; dxHeightfield( dSpaceID space, dHeightfieldDataID data, int bPlaceable ); ~dxHeightfield(); void computeAABB(); int dCollideHeightfieldZone( const int minX, const int maxX, const int minZ, const int maxZ, dxGeom *o2, const int numMaxContacts, int flags, dContactGeom *contact, int skip ); enum { TEMP_PLANE_BUFFER_ELEMENT_COUNT_ALIGNMENT = 4, TEMP_HEIGHT_BUFFER_ELEMENT_COUNT_ALIGNMENT_X = 4, TEMP_HEIGHT_BUFFER_ELEMENT_COUNT_ALIGNMENT_Z = 4, TEMP_TRIANGLE_BUFFER_ELEMENT_COUNT_ALIGNMENT = 1, // Triangles are easy to reallocate and hard to predict }; static inline size_t AlignBufferSize(size_t value, size_t alignment) { dIASSERT((alignment & (alignment - 1)) == 0); return (value + (alignment - 1)) & ~(alignment - 1); } void allocateTriangleBuffer(size_t numTri); void resetTriangleBuffer(); void allocatePlaneBuffer(size_t numTri); void resetPlaneBuffer(); void allocateHeightBuffer(size_t numX, size_t numZ); void resetHeightBuffer(); void sortPlanes(const size_t numPlanes); HeightFieldPlane **tempPlaneBuffer; HeightFieldPlane *tempPlaneInstances; size_t tempPlaneBufferSize; HeightFieldTriangle *tempTriangleBuffer; size_t tempTriangleBufferSize; HeightFieldVertex **tempHeightBuffer; HeightFieldVertex *tempHeightInstances; size_t tempHeightBufferSizeX; size_t tempHeightBufferSizeZ; }; //------------------------------------------------------------------------------ #endif //_DHEIGHTFIELD_H_ alien-arena-7.66+dfsg/source/unix/odesrc/fastlsolve.c0000600000175000017500000001765612161402010021711 0ustar zero79zero79/* generated code, do not edit. */ #include "ode/matrix.h" /* solve L*X=B, with B containing 1 right hand sides. * L is an n*n lower triangular matrix with ones on the diagonal. * L is stored by rows and its leading dimension is lskip. * B is an n*1 matrix that contains the right hand sides. * B is stored by columns and its leading dimension is also lskip. * B is overwritten with X. * this processes blocks of 4*4. * if this is in the factorizer source file, n must be a multiple of 4. */ void dSolveL1 (const dReal *L, dReal *B, int n, int lskip1) { /* declare variables - Z matrix, p and q vectors, etc */ dReal Z11,Z21,Z31,Z41,p1,q1,p2,p3,p4,*ex; const dReal *ell; int lskip2,lskip3,i,j; /* compute lskip values */ lskip2 = 2*lskip1; lskip3 = 3*lskip1; /* compute all 4 x 1 blocks of X */ for (i=0; i <= n-4; i+=4) { /* compute all 4 x 1 block of X, from rows i..i+4-1 */ /* set the Z matrix to 0 */ Z11=0; Z21=0; Z31=0; Z41=0; ell = L + i*lskip1; ex = B; /* the inner loop that computes outer products and adds them to Z */ for (j=i-12; j >= 0; j -= 12) { /* load p and q values */ p1=ell[0]; q1=ex[0]; p2=ell[lskip1]; p3=ell[lskip2]; p4=ell[lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* load p and q values */ p1=ell[1]; q1=ex[1]; p2=ell[1+lskip1]; p3=ell[1+lskip2]; p4=ell[1+lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* load p and q values */ p1=ell[2]; q1=ex[2]; p2=ell[2+lskip1]; p3=ell[2+lskip2]; p4=ell[2+lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* load p and q values */ p1=ell[3]; q1=ex[3]; p2=ell[3+lskip1]; p3=ell[3+lskip2]; p4=ell[3+lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* load p and q values */ p1=ell[4]; q1=ex[4]; p2=ell[4+lskip1]; p3=ell[4+lskip2]; p4=ell[4+lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* load p and q values */ p1=ell[5]; q1=ex[5]; p2=ell[5+lskip1]; p3=ell[5+lskip2]; p4=ell[5+lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* load p and q values */ p1=ell[6]; q1=ex[6]; p2=ell[6+lskip1]; p3=ell[6+lskip2]; p4=ell[6+lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* load p and q values */ p1=ell[7]; q1=ex[7]; p2=ell[7+lskip1]; p3=ell[7+lskip2]; p4=ell[7+lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* load p and q values */ p1=ell[8]; q1=ex[8]; p2=ell[8+lskip1]; p3=ell[8+lskip2]; p4=ell[8+lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* load p and q values */ p1=ell[9]; q1=ex[9]; p2=ell[9+lskip1]; p3=ell[9+lskip2]; p4=ell[9+lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* load p and q values */ p1=ell[10]; q1=ex[10]; p2=ell[10+lskip1]; p3=ell[10+lskip2]; p4=ell[10+lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* load p and q values */ p1=ell[11]; q1=ex[11]; p2=ell[11+lskip1]; p3=ell[11+lskip2]; p4=ell[11+lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* advance pointers */ ell += 12; ex += 12; /* end of inner loop */ } /* compute left-over iterations */ j += 12; for (; j > 0; j--) { /* load p and q values */ p1=ell[0]; q1=ex[0]; p2=ell[lskip1]; p3=ell[lskip2]; p4=ell[lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* advance pointers */ ell += 1; ex += 1; } /* finish computing the X(i) block */ Z11 = ex[0] - Z11; ex[0] = Z11; p1 = ell[lskip1]; Z21 = ex[1] - Z21 - p1*Z11; ex[1] = Z21; p1 = ell[lskip2]; p2 = ell[1+lskip2]; Z31 = ex[2] - Z31 - p1*Z11 - p2*Z21; ex[2] = Z31; p1 = ell[lskip3]; p2 = ell[1+lskip3]; p3 = ell[2+lskip3]; Z41 = ex[3] - Z41 - p1*Z11 - p2*Z21 - p3*Z31; ex[3] = Z41; /* end of outer loop */ } /* compute rows at end that are not a multiple of block size */ for (; i < n; i++) { /* compute all 1 x 1 block of X, from rows i..i+1-1 */ /* set the Z matrix to 0 */ Z11=0; ell = L + i*lskip1; ex = B; /* the inner loop that computes outer products and adds them to Z */ for (j=i-12; j >= 0; j -= 12) { /* load p and q values */ p1=ell[0]; q1=ex[0]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* load p and q values */ p1=ell[1]; q1=ex[1]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* load p and q values */ p1=ell[2]; q1=ex[2]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* load p and q values */ p1=ell[3]; q1=ex[3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* load p and q values */ p1=ell[4]; q1=ex[4]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* load p and q values */ p1=ell[5]; q1=ex[5]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* load p and q values */ p1=ell[6]; q1=ex[6]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* load p and q values */ p1=ell[7]; q1=ex[7]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* load p and q values */ p1=ell[8]; q1=ex[8]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* load p and q values */ p1=ell[9]; q1=ex[9]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* load p and q values */ p1=ell[10]; q1=ex[10]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* load p and q values */ p1=ell[11]; q1=ex[11]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* advance pointers */ ell += 12; ex += 12; /* end of inner loop */ } /* compute left-over iterations */ j += 12; for (; j > 0; j--) { /* load p and q values */ p1=ell[0]; q1=ex[0]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* advance pointers */ ell += 1; ex += 1; } /* finish computing the X(i) block */ Z11 = ex[0] - Z11; ex[0] = Z11; } } alien-arena-7.66+dfsg/source/unix/odesrc/collision_sapspace.cpp0000600000175000017500000006205412161402010023731 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* * Sweep and Prune adaptation/tweaks for ODE by Aras Pranckevicius. * Additional work by David Walters * Original code: * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm * * This version does complete radix sort, not "classical" SAP. So, we * have no temporal coherence, but are able to handle any movement * velocities equally well. */ #include #include #include #include #include "collision_kernel.h" #include "collision_space_internal.h" // Reference counting helper for radix sort global data. //static void RadixSortRef(); //static void RadixSortDeref(); // -------------------------------------------------------------------------- // Radix Sort Context // -------------------------------------------------------------------------- struct RaixSortContext { public: RaixSortContext(): mCurrentSize(0), mCurrentUtilization(0), mRanksValid(false), mRanksBuffer(NULL), mPrimaryRanks(NULL) {} ~RaixSortContext() { FreeRanks(); } // OPCODE's Radix Sorting, returns a list of indices in sorted order const uint32* RadixSort( const float* input2, uint32 nb ); private: void FreeRanks(); void AllocateRanks(size_t nNewSize); void ReallocateRanksIfNecessary(size_t nNewSize); private: void SetCurrentSize(size_t nValue) { mCurrentSize = nValue; } size_t GetCurrentSize() const { return mCurrentSize; } void SetCurrentUtilization(size_t nValue) { mCurrentUtilization = nValue; } size_t GetCurrentUtilization() const { return mCurrentUtilization; } uint32 *GetRanks1() const { return mPrimaryRanks; } uint32 *GetRanks2() const { return mRanksBuffer + ((mRanksBuffer + mCurrentSize) - mPrimaryRanks); } void SwapRanks() { mPrimaryRanks = GetRanks2(); } bool AreRanksValid() const { return mRanksValid; } void InvalidateRanks() { mRanksValid = false; } void ValidateRanks() { mRanksValid = true; } private: size_t mCurrentSize; //!< Current size of the indices list size_t mCurrentUtilization; //!< Current utilization of the indices list bool mRanksValid; uint32* mRanksBuffer; //!< Two lists allocated sequentially in a single block uint32* mPrimaryRanks; }; void RaixSortContext::AllocateRanks(size_t nNewSize) { dIASSERT(GetCurrentSize() == 0); mRanksBuffer = new uint32[2 * nNewSize]; mPrimaryRanks = mRanksBuffer; SetCurrentSize(nNewSize); } void RaixSortContext::FreeRanks() { SetCurrentSize(0); delete[] mRanksBuffer; } void RaixSortContext::ReallocateRanksIfNecessary(size_t nNewSize) { size_t nCurUtilization = GetCurrentUtilization(); if (nNewSize != nCurUtilization) { size_t nCurSize = GetCurrentSize(); if ( nNewSize > nCurSize ) { // Free previously used ram FreeRanks(); // Get some fresh one AllocateRanks(nNewSize); } InvalidateRanks(); SetCurrentUtilization(nNewSize); } } // -------------------------------------------------------------------------- // SAP space code // -------------------------------------------------------------------------- struct dxSAPSpace : public dxSpace { // Constructor / Destructor dxSAPSpace( dSpaceID _space, int sortaxis ); ~dxSAPSpace(); // dxSpace virtual dxGeom* getGeom(int i); virtual void add(dxGeom* g); virtual void remove(dxGeom* g); virtual void dirty(dxGeom* g); virtual void computeAABB(); virtual void cleanGeoms(); virtual void collide( void *data, dNearCallback *callback ); virtual void collide2( void *data, dxGeom *geom, dNearCallback *callback ); private: //-------------------------------------------------------------------------- // Local Declarations //-------------------------------------------------------------------------- //! A generic couple structure struct Pair { uint32 id0; //!< First index of the pair uint32 id1; //!< Second index of the pair // Default and Value Constructor Pair() {} Pair( uint32 i0, uint32 i1 ) : id0( i0 ), id1( i1 ) {} }; //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Complete box pruning. * Returns a list of overlapping pairs of boxes, each box of the pair * belongs to the same set. * * @param count [in] number of boxes. * @param geoms [in] geoms of boxes. * @param pairs [out] array of overlapping pairs. */ void BoxPruning( int count, const dxGeom** geoms, dArray< Pair >& pairs ); //-------------------------------------------------------------------------- // Implementation Data //-------------------------------------------------------------------------- // We have two lists (arrays of pointers) to dirty and clean // geoms. Each geom knows it's index into the corresponding list // (see macros above). dArray DirtyList; // dirty geoms dArray GeomList; // clean geoms // For SAP, we ultimately separate "normal" geoms and the ones that have // infinite AABBs. No point doing SAP on infinite ones (and it doesn't handle // infinite geoms anyway). dArray TmpGeomList; // temporary for normal geoms dArray TmpInfGeomList; // temporary for geoms with infinite AABBs // Our sorting axes. (X,Z,Y is often best). Stored *2 for minor speedup // Axis indices into geom's aabb are: min=idx, max=idx+1 uint32 ax0idx; uint32 ax1idx; uint32 ax2idx; // pruning position array scratch pad // NOTE: this is float not dReal because of the OPCODE radix sorter dArray< float > poslist; RaixSortContext sortContext; }; // Creation dSpaceID dSweepAndPruneSpaceCreate( dxSpace* space, int axisorder ) { return new dxSAPSpace( space, axisorder ); } //============================================================================== #define GEOM_ENABLED(g) (((g)->gflags & GEOM_ENABLE_TEST_MASK) == GEOM_ENABLE_TEST_VALUE) // HACK: We abuse 'next' and 'tome' members of dxGeom to store indice into dirty/geom lists. #define GEOM_SET_DIRTY_IDX(g,idx) { (g)->next = (dxGeom*)(size_t)(idx); } #define GEOM_SET_GEOM_IDX(g,idx) { (g)->tome = (dxGeom**)(size_t)(idx); } #define GEOM_GET_DIRTY_IDX(g) ((int)(size_t)(g)->next) #define GEOM_GET_GEOM_IDX(g) ((int)(size_t)(g)->tome) #define GEOM_INVALID_IDX (-1) /* * A bit of repetitive work - similar to collideAABBs, but doesn't check * if AABBs intersect (because SAP returns pairs with overlapping AABBs). */ static void collideGeomsNoAABBs( dxGeom *g1, dxGeom *g2, void *data, dNearCallback *callback ) { dIASSERT( (g1->gflags & GEOM_AABB_BAD)==0 ); dIASSERT( (g2->gflags & GEOM_AABB_BAD)==0 ); // no contacts if both geoms on the same body, and the body is not 0 if (g1->body == g2->body && g1->body) return; // test if the category and collide bitfields match if ( ((g1->category_bits & g2->collide_bits) || (g2->category_bits & g1->collide_bits)) == 0) { return; } dReal *bounds1 = g1->aabb; dReal *bounds2 = g2->aabb; // check if either object is able to prove that it doesn't intersect the // AABB of the other if (g1->AABBTest (g2,bounds2) == 0) return; if (g2->AABBTest (g1,bounds1) == 0) return; // the objects might actually intersect - call the space callback function callback (data,g1,g2); }; dxSAPSpace::dxSAPSpace( dSpaceID _space, int axisorder ) : dxSpace( _space ) { type = dSweepAndPruneSpaceClass; // Init AABB to infinity aabb[0] = -dInfinity; aabb[1] = dInfinity; aabb[2] = -dInfinity; aabb[3] = dInfinity; aabb[4] = -dInfinity; aabb[5] = dInfinity; ax0idx = ( ( axisorder ) & 3 ) << 1; ax1idx = ( ( axisorder >> 2 ) & 3 ) << 1; ax2idx = ( ( axisorder >> 4 ) & 3 ) << 1; } dxSAPSpace::~dxSAPSpace() { CHECK_NOT_LOCKED(this); if ( cleanup ) { // note that destroying each geom will call remove() for ( ; DirtyList.size(); dGeomDestroy( DirtyList[ 0 ] ) ) {} for ( ; GeomList.size(); dGeomDestroy( GeomList[ 0 ] ) ) {} } else { // just unhook them for ( ; DirtyList.size(); remove( DirtyList[ 0 ] ) ) {} for ( ; GeomList.size(); remove( GeomList[ 0 ] ) ) {} } } dxGeom* dxSAPSpace::getGeom( int i ) { dUASSERT( i >= 0 && i < count, "index out of range" ); int dirtySize = DirtyList.size(); if( i < dirtySize ) return DirtyList[i]; else return GeomList[i-dirtySize]; } void dxSAPSpace::add( dxGeom* g ) { CHECK_NOT_LOCKED (this); dAASSERT(g); dUASSERT(g->parent_space == 0 && g->next == 0, "geom is already in a space"); g->gflags |= GEOM_DIRTY | GEOM_AABB_BAD; // add to dirty list GEOM_SET_DIRTY_IDX( g, DirtyList.size() ); GEOM_SET_GEOM_IDX( g, GEOM_INVALID_IDX ); DirtyList.push( g ); g->parent_space = this; this->count++; dGeomMoved(this); } void dxSAPSpace::remove( dxGeom* g ) { CHECK_NOT_LOCKED(this); dAASSERT(g); dUASSERT(g->parent_space == this,"object is not in this space"); // remove int dirtyIdx = GEOM_GET_DIRTY_IDX(g); int geomIdx = GEOM_GET_GEOM_IDX(g); // must be in one list, not in both dUASSERT( dirtyIdx==GEOM_INVALID_IDX && geomIdx>=0 && geomIdx=0 && dirtyIdxparent_space = 0; // the bounding box of this space (and that of all the parents) may have // changed as a consequence of the removal. dGeomMoved(this); } void dxSAPSpace::dirty( dxGeom* g ) { dAASSERT(g); dUASSERT(g->parent_space == this,"object is not in this space"); // check if already dirtied int dirtyIdx = GEOM_GET_DIRTY_IDX(g); if( dirtyIdx != GEOM_INVALID_IDX ) return; int geomIdx = GEOM_GET_GEOM_IDX(g); dUASSERT( geomIdx>=0 && geomIdxcleanGeoms(); } g->recomputeAABB(); g->gflags &= (~(GEOM_DIRTY|GEOM_AABB_BAD)); // remove from dirty list, add to geom list GEOM_SET_DIRTY_IDX( g, GEOM_INVALID_IDX ); GEOM_SET_GEOM_IDX( g, geomSize + i ); GeomList[geomSize+i] = g; } // clear dirty list DirtyList.setSize( 0 ); lock_count--; } void dxSAPSpace::collide( void *data, dNearCallback *callback ) { dAASSERT (callback); lock_count++; cleanGeoms(); // by now all geoms are in GeomList, and DirtyList must be empty int geom_count = GeomList.size(); dUASSERT( geom_count == count, "geom counts messed up" ); // separate all ENABLED geoms into infinite AABBs and normal AABBs TmpGeomList.setSize(0); TmpInfGeomList.setSize(0); int axis0max = ax0idx + 1; for( int i = 0; i < geom_count; ++i ) { dxGeom* g = GeomList[i]; if( !GEOM_ENABLED(g) ) // skip disabled ones continue; const dReal& amax = g->aabb[axis0max]; if( amax == dInfinity ) // HACK? probably not... TmpInfGeomList.push( g ); else TmpGeomList.push( g ); } // do SAP on normal AABBs dArray< Pair > overlapBoxes; int tmp_geom_count = TmpGeomList.size(); if ( tmp_geom_count > 0 ) { // Size the poslist (+1 for infinity end cap) poslist.setSize( tmp_geom_count + 1 ); // Generate a list of overlapping boxes BoxPruning( tmp_geom_count, (const dxGeom**)TmpGeomList.data(), overlapBoxes ); } // collide overlapping int overlapCount = overlapBoxes.size(); for( int j = 0; j < overlapCount; ++j ) { const Pair& pair = overlapBoxes[ j ]; dxGeom* g1 = TmpGeomList[ pair.id0 ]; dxGeom* g2 = TmpGeomList[ pair.id1 ]; collideGeomsNoAABBs( g1, g2, data, callback ); } int infSize = TmpInfGeomList.size(); int normSize = TmpGeomList.size(); int m, n; for ( m = 0; m < infSize; ++m ) { dxGeom* g1 = TmpInfGeomList[ m ]; // collide infinite ones for( n = m+1; n < infSize; ++n ) { dxGeom* g2 = TmpInfGeomList[n]; collideGeomsNoAABBs( g1, g2, data, callback ); } // collide infinite ones with normal ones for( n = 0; n < normSize; ++n ) { dxGeom* g2 = TmpGeomList[n]; collideGeomsNoAABBs( g1, g2, data, callback ); } } lock_count--; } void dxSAPSpace::collide2( void *data, dxGeom *geom, dNearCallback *callback ) { dAASSERT (geom && callback); // TODO: This is just a simple N^2 implementation lock_count++; cleanGeoms(); geom->recomputeAABB(); // intersect bounding boxes int geom_count = GeomList.size(); for ( int i = 0; i < geom_count; ++i ) { dxGeom* g = GeomList[i]; if ( GEOM_ENABLED(g) ) collideAABBs (g,geom,data,callback); } lock_count--; } void dxSAPSpace::BoxPruning( int count, const dxGeom** geoms, dArray< Pair >& pairs ) { // 1) Build main list using the primary axis // NOTE: uses floats instead of dReals because that's what radix sort wants for( int i = 0; i < count; ++i ) poslist[ i ] = (float)TmpGeomList[i]->aabb[ ax0idx ]; poslist[ count++ ] = FLT_MAX; // 2) Sort the list const uint32* Sorted = sortContext.RadixSort( poslist.data(), count ); // 3) Prune the list const uint32* const LastSorted = Sorted + count; const uint32* RunningAddress = Sorted; Pair IndexPair; while ( RunningAddress < LastSorted && Sorted < LastSorted ) { IndexPair.id0 = *Sorted++; // empty, this loop just advances RunningAddress while ( poslist[*RunningAddress++] < poslist[IndexPair.id0] ) {} if ( RunningAddress < LastSorted ) { const uint32* RunningAddress2 = RunningAddress; const dReal idx0ax0max = geoms[IndexPair.id0]->aabb[ax0idx+1]; const dReal idx0ax1max = geoms[IndexPair.id0]->aabb[ax1idx+1]; const dReal idx0ax2max = geoms[IndexPair.id0]->aabb[ax2idx+1]; while ( poslist[ IndexPair.id1 = *RunningAddress2++ ] <= idx0ax0max ) { const dReal* aabb0 = geoms[ IndexPair.id0 ]->aabb; const dReal* aabb1 = geoms[ IndexPair.id1 ]->aabb; // Intersection? if ( idx0ax1max >= aabb1[ax1idx] && aabb1[ax1idx+1] >= aabb0[ax1idx] ) if ( idx0ax2max >= aabb1[ax2idx] && aabb1[ax2idx+1] >= aabb0[ax2idx] ) { pairs.push( IndexPair ); } } } }; // while ( RunningAddress < LastSorted && Sorted < LastSorted ) } //============================================================================== //------------------------------------------------------------------------------ // Radix Sort //------------------------------------------------------------------------------ #define CHECK_PASS_VALIDITY(pass) \ /* Shortcut to current counters */ \ uint32* CurCount = &mHistogram[pass<<8]; \ \ /* Reset flag. The sorting pass is supposed to be performed. (default) */ \ bool PerformPass = true; \ \ /* Check pass validity */ \ \ /* If all values have the same byte, sorting is useless. */ \ /* It may happen when sorting bytes or words instead of dwords. */ \ /* This routine actually sorts words faster than dwords, and bytes */ \ /* faster than words. Standard running time (O(4*n))is reduced to O(2*n) */ \ /* for words and O(n) for bytes. Running time for floats depends on actual values... */ \ \ /* Get first byte */ \ uint8 UniqueVal = *(((uint8*)input)+pass); \ \ /* Check that byte's counter */ \ if(CurCount[UniqueVal]==nb) PerformPass=false; // WARNING ONLY SORTS IEEE FLOATING-POINT VALUES const uint32* RaixSortContext::RadixSort( const float* input2, uint32 nb ) { uint32* input = (uint32*)input2; // Resize lists if needed ReallocateRanksIfNecessary(nb); // Allocate histograms & offsets on the stack uint32 mHistogram[256*4]; uint32* mLink[256]; // Create histograms (counters). Counters for all passes are created in one run. // Pros: read input buffer once instead of four times // Cons: mHistogram is 4Kb instead of 1Kb // Floating-point values are always supposed to be signed values, so there's only one code path there. // Please note the floating point comparison needed for temporal coherence! Although the resulting asm code // is dreadful, this is surprisingly not such a performance hit - well, I suppose that's a big one on first // generation Pentiums....We can't make comparison on integer representations because, as Chris said, it just // wouldn't work with mixed positive/negative values.... { /* Clear counters/histograms */ memset(mHistogram, 0, 256*4*sizeof(uint32)); /* Prepare to count */ uint8* p = (uint8*)input; uint8* pe = &p[nb*4]; uint32* h0= &mHistogram[0]; /* Histogram for first pass (LSB) */ uint32* h1= &mHistogram[256]; /* Histogram for second pass */ uint32* h2= &mHistogram[512]; /* Histogram for third pass */ uint32* h3= &mHistogram[768]; /* Histogram for last pass (MSB) */ bool AlreadySorted = true; /* Optimism... */ if (!AreRanksValid()) { /* Prepare for temporal coherence */ float* Running = (float*)input2; float PrevVal = *Running; while(p!=pe) { /* Read input input2 in previous sorted order */ float Val = *Running++; /* Check whether already sorted or not */ if(Val>24; // Radix byte, same as above. AND is useless here (uint32). // ### cmp to be killed. Not good. Later. if(Radix<128) *mLink[Radix]++ = i; // Number is positive, same as above else *(--mLink[Radix]) = i; // Number is negative, flip the sorting order } ValidateRanks(); } else { uint32* const Ranks1 = GetRanks1(); for(uint32 i=0;i>24; // Radix byte, same as above. AND is useless here (uint32). // ### cmp to be killed. Not good. Later. if(Radix<128) *mLink[Radix]++ = Ranks1[i]; // Number is positive, same as above else *(--mLink[Radix]) = Ranks1[i]; // Number is negative, flip the sorting order } } // Swap pointers for next pass. Valid indices - the most recent ones - are in mRanks after the swap. SwapRanks(); } else { // The pass is useless, yet we still have to reverse the order of current list if all values are negative. if(UniqueVal>=128) { if (!AreRanksValid()) { uint32* const Ranks2 = GetRanks2(); // ###Possible? for(uint32 i=0;i #include #include #include #include #include "collision_kernel.h" #include "collision_std.h" #include "collision_util.h" #ifdef _MSC_VER #pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" #endif //**************************************************************************** // plane public API static void make_sure_plane_normal_has_unit_length (dxPlane *g) { dReal l = g->p[0]*g->p[0] + g->p[1]*g->p[1] + g->p[2]*g->p[2]; if (l > 0) { l = dRecipSqrt(l); g->p[0] *= l; g->p[1] *= l; g->p[2] *= l; g->p[3] *= l; } else { g->p[0] = 1; g->p[1] = 0; g->p[2] = 0; g->p[3] = 0; } } dxPlane::dxPlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d) : dxGeom (space,0) { type = dPlaneClass; p[0] = a; p[1] = b; p[2] = c; p[3] = d; make_sure_plane_normal_has_unit_length (this); } void dxPlane::computeAABB() { aabb[0] = -dInfinity; aabb[1] = dInfinity; aabb[2] = -dInfinity; aabb[3] = dInfinity; aabb[4] = -dInfinity; aabb[5] = dInfinity; // Planes that have normal vectors aligned along an axis can use a // less comprehensive (half space) bounding box. if ( p[1] == 0.0f && p[2] == 0.0f ) { // normal aligned with x-axis aabb[0] = (p[0] > 0) ? -dInfinity : -p[3]; aabb[1] = (p[0] > 0) ? p[3] : dInfinity; } else if ( p[0] == 0.0f && p[2] == 0.0f ) { // normal aligned with y-axis aabb[2] = (p[1] > 0) ? -dInfinity : -p[3]; aabb[3] = (p[1] > 0) ? p[3] : dInfinity; } else if ( p[0] == 0.0f && p[1] == 0.0f ) { // normal aligned with z-axis aabb[4] = (p[2] > 0) ? -dInfinity : -p[3]; aabb[5] = (p[2] > 0) ? p[3] : dInfinity; } } dGeomID dCreatePlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d) { return new dxPlane (space,a,b,c,d); } void dGeomPlaneSetParams (dGeomID g, dReal a, dReal b, dReal c, dReal d) { dUASSERT (g && g->type == dPlaneClass,"argument not a plane"); dxPlane *p = (dxPlane*) g; p->p[0] = a; p->p[1] = b; p->p[2] = c; p->p[3] = d; make_sure_plane_normal_has_unit_length (p); dGeomMoved (g); } void dGeomPlaneGetParams (dGeomID g, dVector4 result) { dUASSERT (g && g->type == dPlaneClass,"argument not a plane"); dxPlane *p = (dxPlane*) g; result[0] = p->p[0]; result[1] = p->p[1]; result[2] = p->p[2]; result[3] = p->p[3]; } dReal dGeomPlanePointDepth (dGeomID g, dReal x, dReal y, dReal z) { dUASSERT (g && g->type == dPlaneClass,"argument not a plane"); dxPlane *p = (dxPlane*) g; return p->p[3] - p->p[0]*x - p->p[1]*y - p->p[2]*z; } alien-arena-7.66+dfsg/source/unix/odesrc/collision_trimesh_trimesh_new.cpp0000600000175000017500000010013312161402010026200 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ // OPCODE TriMesh/TriMesh collision code // Written at 2006-10-28 by Francisco Len (http://gimpact.sourceforge.net) #ifdef _MSC_VER #pragma warning(disable:4244 4305) // for VC++, no precision loss complaints #endif #include #include #include #include #include "config.h" // New Implementation #if !dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER #if dTRIMESH_ENABLED #include "collision_util.h" #include "collision_trimesh_internal.h" #if !dTLS_ENABLED // Have collider cache instance unconditionally of OPCODE or GIMPACT selection /*extern */TrimeshCollidersCache g_ccTrimeshCollidersCache; #endif #if dTRIMESH_OPCODE #define SMALL_ELT REAL(2.5e-4) #define EXPANDED_ELT_THRESH REAL(1.0e-3) #define DISTANCE_EPSILON REAL(1.0e-8) #define VELOCITY_EPSILON REAL(1.0e-5) #define TINY_PENETRATION REAL(5.0e-6) struct LineContactSet { enum { MAX_POINTS = 8 }; dVector3 Points[MAX_POINTS]; int Count; }; // static void GetTriangleGeometryCallback(udword, VertexPointers&, udword); -- not used inline void dMakeMatrix4(const dVector3 Position, const dMatrix3 Rotation, dMatrix4 &B); //static void dInvertMatrix4( dMatrix4& B, dMatrix4& Binv ); //static int IntersectLineSegmentRay(dVector3, dVector3, dVector3, dVector3, dVector3); static void ClipConvexPolygonAgainstPlane( const dVector3, dReal, LineContactSet& ); ///returns the penetration depth static dReal MostDeepPoints( LineContactSet & points, const dVector3 plane_normal, dReal plane_dist, LineContactSet & deep_points); static bool TriTriContacts(const dVector3 tr1[3], const dVector3 tr2[3], int TriIndex1, int TriIndex2, dxGeom* g1, dxGeom* g2, int Flags, CONTACT_KEY_HASH_TABLE &hashcontactset, dContactGeom* Contacts, int Stride, int &contactcount); /* some math macros */ #define CROSS(dest,v1,v2) { dest[0]=v1[1]*v2[2]-v1[2]*v2[1]; \ dest[1]=v1[2]*v2[0]-v1[0]*v2[2]; \ dest[2]=v1[0]*v2[1]-v1[1]*v2[0]; } #define DOT(v1,v2) (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2]) #define SUB(dest,v1,v2) { dest[0]=v1[0]-v2[0]; dest[1]=v1[1]-v2[1]; dest[2]=v1[2]-v2[2]; } #define ADD(dest,v1,v2) { dest[0]=v1[0]+v2[0]; dest[1]=v1[1]+v2[1]; dest[2]=v1[2]+v2[2]; } #define MULT(dest,v,factor) { dest[0]=factor*v[0]; dest[1]=factor*v[1]; dest[2]=factor*v[2]; } #define SET(dest,src) { dest[0]=src[0]; dest[1]=src[1]; dest[2]=src[2]; } #define SMULT(p,q,s) { p[0]=q[0]*s; p[1]=q[1]*s; p[2]=q[2]*s; } #define COMBO(combo,p,t,q) { combo[0]=p[0]+t*q[0]; combo[1]=p[1]+t*q[1]; combo[2]=p[2]+t*q[2]; } #define LENGTH(x) ((dReal) 1.0f/InvSqrt(dDOT(x, x))) #define DEPTH(d, p, q, n) d = (p[0] - q[0])*n[0] + (p[1] - q[1])*n[1] + (p[2] - q[2])*n[2]; inline const dReal dMin(const dReal x, const dReal y) { return x < y ? x : y; } inline void SwapNormals(dVector3 *&pen_v, dVector3 *&col_v, dVector3* v1, dVector3* v2, dVector3 *&pen_elt, dVector3 *elt_f1, dVector3 *elt_f2, dVector3 n, dVector3 n1, dVector3 n2) { if (pen_v == v1) { pen_v = v2; pen_elt = elt_f2; col_v = v1; SET(n, n1); } else { pen_v = v1; pen_elt = elt_f1; col_v = v2; SET(n, n2); } } ///////////////////////MECHANISM FOR AVOID CONTACT REDUNDANCE/////////////////////////////// ////* Written by Francisco Len (http://gimpact.sourceforge.net) */// #define CONTACT_DIFF_EPSILON REAL(0.00001) #if defined(dDOUBLE) #define CONTACT_NORMAL_ZERO REAL(0.0000001) #else // if defined(dSINGLE) #define CONTACT_NORMAL_ZERO REAL(0.00001) #endif #define CONTACT_POS_HASH_QUOTIENT REAL(10000.0) #define dSQRT3 REAL(1.7320508075688773) void UpdateContactKey(CONTACT_KEY & key, dContactGeom * contact) { key.m_contact = contact; unsigned int hash=0; int i = 0; while (true) { dReal coord = contact->pos[i]; coord = dFloor(coord * CONTACT_POS_HASH_QUOTIENT); const int sz = sizeof(coord) / sizeof(unsigned); dIASSERT(sizeof(coord) % sizeof(unsigned) == 0); unsigned hash_v[ sz ]; memcpy(hash_v, &coord, sizeof(coord)); unsigned int hash_input = hash_v[0]; for (int i=1; i> 24)) ^ ( hash >> 28 ); hash = (( hash << 4 ) + ((hash_input >> 16) & 0xFF)) ^ ( hash >> 28 ); hash = (( hash << 4 ) + ((hash_input >> 8) & 0xFF)) ^ ( hash >> 28 ); hash = (( hash << 4 ) + (hash_input & 0xFF)) ^ ( hash >> 28 ); if (++i == 3) { break; } hash = (hash << 11) | (hash >> 21); } key.m_key = hash; } static inline unsigned int MakeContactIndex(unsigned int key) { dIASSERT(CONTACTS_HASHSIZE == 256); unsigned int index = key ^ (key >> 16); index = (index ^ (index >> 8)) & 0xFF; return index; } dContactGeom *AddContactToNode(const CONTACT_KEY * contactkey,CONTACT_KEY_HASH_NODE * node) { for(int i=0;im_keycount;i++) { if(node->m_keyarray[i].m_key == contactkey->m_key) { dContactGeom *contactfound = node->m_keyarray[i].m_contact; if (dDISTANCE(contactfound->pos, contactkey->m_contact->pos) < REAL(1.00001) /*for comp. errors*/ * dSQRT3 / CONTACT_POS_HASH_QUOTIENT /*cube diagonal*/) { return contactfound; } } } if (node->m_keycount < MAXCONTACT_X_NODE) { node->m_keyarray[node->m_keycount].m_contact = contactkey->m_contact; node->m_keyarray[node->m_keycount].m_key = contactkey->m_key; node->m_keycount++; } else { dDEBUGMSG("Trimesh-trimesh contach hash table bucket overflow - close contacts might not be culled"); } return contactkey->m_contact; } void RemoveNewContactFromNode(const CONTACT_KEY * contactkey, CONTACT_KEY_HASH_NODE * node) { dIASSERT(node->m_keycount > 0); if (node->m_keyarray[node->m_keycount - 1].m_contact == contactkey->m_contact) { node->m_keycount -= 1; } else { dIASSERT(node->m_keycount == MAXCONTACT_X_NODE); } } void RemoveArbitraryContactFromNode(const CONTACT_KEY *contactkey, CONTACT_KEY_HASH_NODE *node) { dIASSERT(node->m_keycount > 0); int keyindex, lastkeyindex = node->m_keycount - 1; // Do not check the last contact for (keyindex = 0; keyindex < lastkeyindex; keyindex++) { if (node->m_keyarray[keyindex].m_contact == contactkey->m_contact) { node->m_keyarray[keyindex] = node->m_keyarray[lastkeyindex]; break; } } dIASSERT(keyindex < lastkeyindex || node->m_keyarray[keyindex].m_contact == contactkey->m_contact); // It has been either the break from loop or last element should match node->m_keycount = lastkeyindex; } void UpdateArbitraryContactInNode(const CONTACT_KEY *contactkey, CONTACT_KEY_HASH_NODE *node, dContactGeom *pwithcontact) { dIASSERT(node->m_keycount > 0); int keyindex, lastkeyindex = node->m_keycount - 1; // Do not check the last contact for (keyindex = 0; keyindex < lastkeyindex; keyindex++) { if (node->m_keyarray[keyindex].m_contact == contactkey->m_contact) { break; } } dIASSERT(keyindex < lastkeyindex || node->m_keyarray[keyindex].m_contact == contactkey->m_contact); // It has been either the break from loop or last element should match node->m_keyarray[keyindex].m_contact = pwithcontact; } void ClearContactSet(CONTACT_KEY_HASH_TABLE &hashcontactset) { memset(&hashcontactset, 0, sizeof(CONTACT_KEY_HASH_TABLE)); } //return true if found dContactGeom *InsertContactInSet(CONTACT_KEY_HASH_TABLE &hashcontactset, const CONTACT_KEY &newkey) { unsigned int index = MakeContactIndex(newkey.m_key); return AddContactToNode(&newkey, &hashcontactset[index]); } void RemoveNewContactFromSet(CONTACT_KEY_HASH_TABLE &hashcontactset, const CONTACT_KEY &contactkey) { unsigned int index = MakeContactIndex(contactkey.m_key); RemoveNewContactFromNode(&contactkey, &hashcontactset[index]); } void RemoveArbitraryContactFromSet(CONTACT_KEY_HASH_TABLE &hashcontactset, const CONTACT_KEY &contactkey) { unsigned int index = MakeContactIndex(contactkey.m_key); RemoveArbitraryContactFromNode(&contactkey, &hashcontactset[index]); } void UpdateArbitraryContactInSet(CONTACT_KEY_HASH_TABLE &hashcontactset, const CONTACT_KEY &contactkey, dContactGeom *pwithcontact) { unsigned int index = MakeContactIndex(contactkey.m_key); UpdateArbitraryContactInNode(&contactkey, &hashcontactset[index], pwithcontact); } bool AllocNewContact( const dVector3 newpoint, dContactGeom *& out_pcontact, int Flags, CONTACT_KEY_HASH_TABLE &hashcontactset, dContactGeom* Contacts, int Stride, int &contactcount) { bool allocated_new = false; dContactGeom dLocalContact; dContactGeom * pcontact = contactcount != (Flags & NUMC_MASK) ? SAFECONTACT(Flags, Contacts, contactcount, Stride) : &dLocalContact; pcontact->pos[0] = newpoint[0]; pcontact->pos[1] = newpoint[1]; pcontact->pos[2] = newpoint[2]; pcontact->pos[3] = 1.0f; CONTACT_KEY newkey; UpdateContactKey(newkey, pcontact); dContactGeom *pcontactfound = InsertContactInSet(hashcontactset, newkey); if (pcontactfound == pcontact) { if (pcontactfound != &dLocalContact) { contactcount++; } else { RemoveNewContactFromSet(hashcontactset, newkey); pcontactfound = NULL; } allocated_new = true; } out_pcontact = pcontactfound; return allocated_new; } void FreeExistingContact(dContactGeom *pcontact, int Flags, CONTACT_KEY_HASH_TABLE &hashcontactset, dContactGeom *Contacts, int Stride, int &contactcount) { CONTACT_KEY contactKey; UpdateContactKey(contactKey, pcontact); RemoveArbitraryContactFromSet(hashcontactset, contactKey); int lastContactIndex = contactcount - 1; dContactGeom *plastContact = SAFECONTACT(Flags, Contacts, lastContactIndex, Stride); if (pcontact != plastContact) { *pcontact = *plastContact; CONTACT_KEY lastContactKey; UpdateContactKey(lastContactKey, plastContact); UpdateArbitraryContactInSet(hashcontactset, lastContactKey, pcontact); } contactcount = lastContactIndex; } dContactGeom * PushNewContact( dxGeom* g1, dxGeom* g2, int TriIndex1, int TriIndex2, const dVector3 point, dVector3 normal, dReal depth, int Flags, CONTACT_KEY_HASH_TABLE &hashcontactset, dContactGeom* Contacts, int Stride, int &contactcount) { dIASSERT(dFabs(dVector3Length((const dVector3 &)(*normal)) - REAL(1.0)) < REAL(1e-6)); // This assumption is used in the code dContactGeom * pcontact; if (!AllocNewContact(point, pcontact, Flags, hashcontactset, Contacts, Stride, contactcount)) { const dReal depthDifference = depth - pcontact->depth; if (depthDifference > CONTACT_DIFF_EPSILON) { pcontact->normal[0] = normal[0]; pcontact->normal[1] = normal[1]; pcontact->normal[2] = normal[2]; pcontact->normal[3] = REAL(1.0); // used to store length of vector sum for averaging pcontact->depth = depth; pcontact->g1 = g1; pcontact->g2 = g2; pcontact->side1 = TriIndex1; pcontact->side2 = TriIndex2; } else if (depthDifference >= -CONTACT_DIFF_EPSILON) ///average { if(pcontact->g1 == g2) { MULT(normal,normal, REAL(-1.0)); int tempInt = TriIndex1; TriIndex1 = TriIndex2; TriIndex2 = tempInt; // This should be discarded by optimizer as g1 and g2 are // not used any more but it's preferable to keep this line for // the sake of consistency in variable values. dxGeom *tempGeom = g1; g1 = g2; g2 = tempGeom; } const dReal oldLen = pcontact->normal[3]; COMBO(pcontact->normal, normal, oldLen, pcontact->normal); const dReal len = LENGTH(pcontact->normal); if (len > CONTACT_NORMAL_ZERO) { MULT(pcontact->normal, pcontact->normal, REAL(1.0) / len); pcontact->normal[3] = len; pcontact->side1 = ((dxTriMesh *)pcontact->g1)->TriMergeCallback ? ((dxTriMesh *)pcontact->g1)->TriMergeCallback((dxTriMesh *)pcontact->g1, pcontact->side1, TriIndex1) : -1; pcontact->side2 = ((dxTriMesh *)pcontact->g2)->TriMergeCallback ? ((dxTriMesh *)pcontact->g2)->TriMergeCallback((dxTriMesh *)pcontact->g2, pcontact->side2, TriIndex2) : -1; } else { FreeExistingContact(pcontact, Flags, hashcontactset, Contacts, Stride, contactcount); } } } // Contact can be not available if buffer is full else if (pcontact) { pcontact->normal[0] = normal[0]; pcontact->normal[1] = normal[1]; pcontact->normal[2] = normal[2]; pcontact->normal[3] = REAL(1.0); // used to store length of vector sum for averaging pcontact->depth = depth; pcontact->g1 = g1; pcontact->g2 = g2; pcontact->side1 = TriIndex1; pcontact->side2 = TriIndex2; } return pcontact; } //////////////////////////////////////////////////////////////////////////////////////////// int dCollideTTL(dxGeom* g1, dxGeom* g2, int Flags, dContactGeom* Contacts, int Stride) { dIASSERT (Stride >= (int)sizeof(dContactGeom)); dIASSERT (g1->type == dTriMeshClass); dIASSERT (g2->type == dTriMeshClass); dIASSERT ((Flags & NUMC_MASK) >= 1); dxTriMesh* TriMesh1 = (dxTriMesh*) g1; dxTriMesh* TriMesh2 = (dxTriMesh*) g2; //dReal * TriNormals1 = (dReal *) TriMesh1->Data->Normals; //dReal * TriNormals2 = (dReal *) TriMesh2->Data->Normals; const dVector3& TLPosition1 = *(const dVector3*) dGeomGetPosition(TriMesh1); // TLRotation1 = column-major order const dMatrix3& TLRotation1 = *(const dMatrix3*) dGeomGetRotation(TriMesh1); const dVector3& TLPosition2 = *(const dVector3*) dGeomGetPosition(TriMesh2); // TLRotation2 = column-major order const dMatrix3& TLRotation2 = *(const dMatrix3*) dGeomGetRotation(TriMesh2); const unsigned uiTLSKind = TriMesh1->getParentSpaceTLSKind(); dIASSERT(uiTLSKind == TriMesh2->getParentSpaceTLSKind()); // The colliding spaces must use matching cleanup method TrimeshCollidersCache *pccColliderCache = GetTrimeshCollidersCache(uiTLSKind); AABBTreeCollider& Collider = pccColliderCache->_AABBTreeCollider; BVTCache &ColCache = pccColliderCache->ColCache; CONTACT_KEY_HASH_TABLE &hashcontactset = pccColliderCache->_hashcontactset; ColCache.Model0 = &TriMesh1->Data->BVTree; ColCache.Model1 = &TriMesh2->Data->BVTree; ////Prepare contact list ClearContactSet(hashcontactset); // Collision query Matrix4x4 amatrix, bmatrix; BOOL IsOk = Collider.Collide(ColCache, &MakeMatrix(TLPosition1, TLRotation1, amatrix), &MakeMatrix(TLPosition2, TLRotation2, bmatrix) ); // Make "double" versions of these matrices, if appropriate dMatrix4 A, B; dMakeMatrix4(TLPosition1, TLRotation1, A); dMakeMatrix4(TLPosition2, TLRotation2, B); if (IsOk) { // Get collision status => if true, objects overlap if ( Collider.GetContactStatus() ) { // Number of colliding pairs and list of pairs int TriCount = Collider.GetNbPairs(); const Pair* CollidingPairs = Collider.GetPairs(); if (TriCount > 0) { // step through the pairs, adding contacts int id1, id2; int OutTriCount = 0; dVector3 v1[3], v2[3]; // only do these expensive inversions once /*dMatrix4 InvMatrix1, InvMatrix2; dInvertMatrix4(A, InvMatrix1); dInvertMatrix4(B, InvMatrix2);*/ for (int i = 0; i < TriCount; i++) { id1 = CollidingPairs[i].id0; id2 = CollidingPairs[i].id1; // grab the colliding triangles FetchTriangle((dxTriMesh*) g1, id1, TLPosition1, TLRotation1, v1); FetchTriangle((dxTriMesh*) g2, id2, TLPosition2, TLRotation2, v2); // Since we'll be doing matrix transformations, we need to // make sure that all vertices have four elements for (int j=0; j<3; j++) { v1[j][3] = 1.0; v2[j][3] = 1.0; } TriTriContacts(v1,v2, id1,id2, g1, g2, Flags, hashcontactset, Contacts,Stride,OutTriCount); // Continue loop even after contacts are full // as existing contacts' normals/depths might be updated // Break only if contacts are not important if ((OutTriCount | CONTACTS_UNIMPORTANT) == (Flags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { break; } } // Return the number of contacts return OutTriCount; } } } // There was some kind of failure during the Collide call or // there are no faces overlapping return 0; } /* -- not used static void GetTriangleGeometryCallback(udword triangleindex, VertexPointers& triangle, udword user_data) { dVector3 Out[3]; FetchTriangle((dxTriMesh*) user_data, (int) triangleindex, Out); for (int i = 0; i < 3; i++) triangle.Vertex[i] = (const Point*) ((dReal*) Out[i]); } */ // // // #define B11 B[0] #define B12 B[1] #define B13 B[2] #define B14 B[3] #define B21 B[4] #define B22 B[5] #define B23 B[6] #define B24 B[7] #define B31 B[8] #define B32 B[9] #define B33 B[10] #define B34 B[11] #define B41 B[12] #define B42 B[13] #define B43 B[14] #define B44 B[15] #define Binv11 Binv[0] #define Binv12 Binv[1] #define Binv13 Binv[2] #define Binv14 Binv[3] #define Binv21 Binv[4] #define Binv22 Binv[5] #define Binv23 Binv[6] #define Binv24 Binv[7] #define Binv31 Binv[8] #define Binv32 Binv[9] #define Binv33 Binv[10] #define Binv34 Binv[11] #define Binv41 Binv[12] #define Binv42 Binv[13] #define Binv43 Binv[14] #define Binv44 Binv[15] inline void dMakeMatrix4(const dVector3 Position, const dMatrix3 Rotation, dMatrix4 &B) { B11 = Rotation[0]; B21 = Rotation[1]; B31 = Rotation[2]; B41 = Position[0]; B12 = Rotation[4]; B22 = Rotation[5]; B32 = Rotation[6]; B42 = Position[1]; B13 = Rotation[8]; B23 = Rotation[9]; B33 = Rotation[10]; B43 = Position[2]; B14 = 0.0; B24 = 0.0; B34 = 0.0; B44 = 1.0; } #if 0 static void dInvertMatrix4( dMatrix4& B, dMatrix4& Binv ) { dReal det = (B11 * B22 - B12 * B21) * (B33 * B44 - B34 * B43) -(B11 * B23 - B13 * B21) * (B32 * B44 - B34 * B42) +(B11 * B24 - B14 * B21) * (B32 * B43 - B33 * B42) +(B12 * B23 - B13 * B22) * (B31 * B44 - B34 * B41) -(B12 * B24 - B14 * B22) * (B31 * B43 - B33 * B41) +(B13 * B24 - B14 * B23) * (B31 * B42 - B32 * B41); dAASSERT (det != 0.0); det = 1.0 / det; Binv11 = (dReal) (det * ((B22 * B33) - (B23 * B32))); Binv12 = (dReal) (det * ((B32 * B13) - (B33 * B12))); Binv13 = (dReal) (det * ((B12 * B23) - (B13 * B22))); Binv14 = 0.0f; Binv21 = (dReal) (det * ((B23 * B31) - (B21 * B33))); Binv22 = (dReal) (det * ((B33 * B11) - (B31 * B13))); Binv23 = (dReal) (det * ((B13 * B21) - (B11 * B23))); Binv24 = 0.0f; Binv31 = (dReal) (det * ((B21 * B32) - (B22 * B31))); Binv32 = (dReal) (det * ((B31 * B12) - (B32 * B11))); Binv33 = (dReal) (det * ((B11 * B22) - (B12 * B21))); Binv34 = 0.0f; Binv41 = (dReal) (det * (B21*(B33*B42 - B32*B43) + B22*(B31*B43 - B33*B41) + B23*(B32*B41 - B31*B42))); Binv42 = (dReal) (det * (B31*(B13*B42 - B12*B43) + B32*(B11*B43 - B13*B41) + B33*(B12*B41 - B11*B42))); Binv43 = (dReal) (det * (B41*(B13*B22 - B12*B23) + B42*(B11*B23 - B13*B21) + B43*(B12*B21 - B11*B22))); Binv44 = 1.0f; } #endif // Find the intersectiojn point between a coplanar line segement, // defined by X1 and X2, and a ray defined by X3 and direction N. // // This forumla for this calculation is: // (c x b) . (a x b) // Q = x1 + a ------------------- // | a x b | ^2 // // where a = x2 - x1 // b = x4 - x3 // c = x3 - x1 // x1 and x2 are the edges of the triangle, and x3 is CoplanarPt // and x4 is (CoplanarPt - n) #if 0 static int IntersectLineSegmentRay(dVector3 x1, dVector3 x2, dVector3 x3, dVector3 n, dVector3 out_pt) { dVector3 a, b, c, x4; ADD(x4, x3, n); // x4 = x3 + n SUB(a, x2, x1); // a = x2 - x1 SUB(b, x4, x3); SUB(c, x3, x1); dVector3 tmp1, tmp2; CROSS(tmp1, c, b); CROSS(tmp2, a, b); dReal num, denom; num = dDOT(tmp1, tmp2); denom = LENGTH( tmp2 ); dReal s; s = num /(denom*denom); for (int i=0; i<3; i++) out_pt[i] = x1[i] + a[i]*s; // Test if this intersection is "behind" x3, w.r.t. n SUB(a, x3, out_pt); if (dDOT(a, n) > 0.0) return 0; // Test if this intersection point is outside the edge limits, // if (dot( (out_pt-x1), (out_pt-x2) ) < 0) it's inside // else outside SUB(a, out_pt, x1); SUB(b, out_pt, x2); if (dDOT(a,b) < 0.0) return 1; else return 0; } #endif void PlaneClipSegment( const dVector3 s1, const dVector3 s2, const dVector3 N, dReal C, dVector3 clipped) { dReal dis1,dis2; dis1 = DOT(s1,N)-C; SUB(clipped,s2,s1); dis2 = DOT(clipped,N); MULT(clipped,clipped,-dis1/dis2); ADD(clipped,clipped,s1); clipped[3] = 1.0f; } /* ClipConvexPolygonAgainstPlane - Clip a a convex polygon, described by CONTACTS, with a plane (described by N and C distance from origin). Note: the input vertices are assumed to be in invcounterclockwise order. changed by Francisco Leon (http://gimpact.sourceforge.net) */ static void ClipConvexPolygonAgainstPlane( const dVector3 N, dReal C, LineContactSet& Contacts ) { int i, vi, prevclassif=32000, classif; /* classif 0 : back, 1 : front */ dReal d; dVector3 clipped[8]; int clippedcount =0; if(Contacts.Count==0) { return; } for(i=0;i<=Contacts.Count;i++) { vi = i%Contacts.Count; d = DOT(N,Contacts.Points[vi]) - C; ////classify point if(d>REAL(1.0e-8)) classif = 1; else classif = 0; if(classif == 0)//back { if(i>0) { if(prevclassif==1)///in front { ///add clipped point if(clippedcount<8) { PlaneClipSegment(Contacts.Points[i-1],Contacts.Points[vi], N,C,clipped[clippedcount]); clippedcount++; } } } ///add point if(clippedcount<8&&i0) { if(prevclassif==0) { ///add point if(clippedcount<8) { PlaneClipSegment(Contacts.Points[i-1],Contacts.Points[vi], N,C,clipped[clippedcount]); clippedcount++; } } } } prevclassif = classif; } if(clippedcount==0) { Contacts.Count = 0; return; } Contacts.Count = clippedcount; memcpy( Contacts.Points, clipped, clippedcount * sizeof(dVector3) ); return; } bool BuildPlane(const dVector3 s0, const dVector3 s1,const dVector3 s2, dVector3 Normal, dReal & Dist) { dVector3 e0,e1; SUB(e0,s1,s0); SUB(e1,s2,s0); CROSS(Normal,e0,e1); if (!dSafeNormalize3(Normal)) { return false; } Dist = DOT(Normal,s0); return true; } bool BuildEdgesDir(const dVector3 s0, const dVector3 s1, const dVector3 t0, const dVector3 t1, dVector3 crossdir) { dVector3 e0,e1; SUB(e0,s1,s0); SUB(e1,t1,t0); CROSS(crossdir,e0,e1); if (!dSafeNormalize3(crossdir)) { return false; } return true; } bool BuildEdgePlane( const dVector3 s0, const dVector3 s1, const dVector3 normal, dVector3 plane_normal, dReal & plane_dist) { dVector3 e0; SUB(e0,s1,s0); CROSS(plane_normal,e0,normal); if (!dSafeNormalize3(plane_normal)) { return false; } plane_dist = DOT(plane_normal,s0); return true; } /* Positive penetration Negative number: they are separated */ dReal IntervalPenetration(dReal &vmin1,dReal &vmax1, dReal &vmin2,dReal &vmax2) { if(vmax1<=vmin2) { return -(vmin2-vmax1); } else { if(vmax2<=vmin1) { return -(vmin1-vmax2); } else { if(vmax1<=vmax2) { return vmax1-vmin2; } return vmax2-vmin1; } } return 0; } void FindInterval( const dVector3 * vertices, int verticecount, dVector3 dir,dReal &vmin,dReal &vmax) { dReal dist; int i; vmin = DOT(vertices[0],dir); vmax = vmin; for(i=1;idist) vmin=dist; else if(vmaxmaxdeep) { maxdeep = dist; deep_points.Count=1; max_candidates[deep_points.Count-1] = i; } else if(dist+REAL(0.000001)>=maxdeep) { deep_points.Count++; max_candidates[deep_points.Count-1] = i; } } for(i=0;i0.0) { MULT(separating_normal,separating_normal,-1.0f); deep_points.Count = 1; SET(deep_points.Points[0],pt2); } else { deep_points.Count = 1; SET(deep_points.Points[0],pt2); } } else { vmin1 = DOT(separating_normal,tri2plane); if(vmin1<0.0) { MULT(separating_normal,separating_normal,-1.0f); deep_points.Count = 1; SET(deep_points.Points[0],pt2); } else { deep_points.Count = 1; SET(deep_points.Points[0],pt2); } } } else { MULT(separating_normal,crossdir,1.0f/vmin1); vmin1 = DOT(separating_normal,tri1plane); if(vmin1>0.0) { MULT(separating_normal,separating_normal,-1.0f); deep_points.Count = 1; SET(deep_points.Points[0],pt2); } else { deep_points.Count = 1; SET(deep_points.Points[0],pt2); } } }*/ return maxdeep; } ///SUPPORT UP TO 8 CONTACTS bool TriTriContacts(const dVector3 tr1[3], const dVector3 tr2[3], int TriIndex1, int TriIndex2, dxGeom* g1, dxGeom* g2, int Flags, CONTACT_KEY_HASH_TABLE &hashcontactset, dContactGeom* Contacts, int Stride, int &contactcount) { dVector4 normal; dReal depth; ///Test Tri Vs Tri // dContactGeom* pcontact; int ccount = 0; LineContactSet contactpoints; contactpoints.Count = 0; ///find best direction depth = FindTriangleTriangleCollision( tr1, tr2, normal, contactpoints); if(depth<0.0f) return false; ccount = 0; while (ccount #include #include #include #include #include "collision_kernel.h" #include "collision_std.h" #include "collision_util.h" #ifdef _MSC_VER #pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" #endif // flat cylinder public API dxCylinder::dxCylinder (dSpaceID space, dReal _radius, dReal _length) : dxGeom (space,1) { dAASSERT (_radius >= 0 && _length >= 0); type = dCylinderClass; radius = _radius; lz = _length; updateZeroSizedFlag(!_radius || !_length); } void dxCylinder::computeAABB() { const dMatrix3& R = final_posr->R; const dVector3& pos = final_posr->pos; dReal xrange = dFabs (R[0] * radius) + dFabs (R[1] * radius) + REAL(0.5)* dFabs (R[2] * lz); dReal yrange = dFabs (R[4] * radius) + dFabs (R[5] * radius) + REAL(0.5)* dFabs (R[6] * lz); dReal zrange = dFabs (R[8] * radius) + dFabs (R[9] * radius) + REAL(0.5)* dFabs (R[10] * lz); aabb[0] = pos[0] - xrange; aabb[1] = pos[0] + xrange; aabb[2] = pos[1] - yrange; aabb[3] = pos[1] + yrange; aabb[4] = pos[2] - zrange; aabb[5] = pos[2] + zrange; } dGeomID dCreateCylinder (dSpaceID space, dReal radius, dReal length) { return new dxCylinder (space,radius,length); } void dGeomCylinderSetParams (dGeomID cylinder, dReal radius, dReal length) { dUASSERT (cylinder && cylinder->type == dCylinderClass,"argument not a ccylinder"); dAASSERT (radius >= 0 && length >= 0); dxCylinder *c = (dxCylinder*) cylinder; c->radius = radius; c->lz = length; c->updateZeroSizedFlag(!radius || !length); dGeomMoved (cylinder); } void dGeomCylinderGetParams (dGeomID cylinder, dReal *radius, dReal *length) { dUASSERT (cylinder && cylinder->type == dCylinderClass,"argument not a ccylinder"); dxCylinder *c = (dxCylinder*) cylinder; *radius = c->radius; *length = c->lz; } alien-arena-7.66+dfsg/source/unix/odesrc/collision_trimesh_internal.h0000600000175000017500000004454612161402010025154 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ // TriMesh code by Erwin de Vries. // Modified for FreeSOLID Compatibility by Rodrigo Hernandez // Trimesh caches separation by Oleh Derevenko #ifndef _ODE_COLLISION_TRIMESH_INTERNAL_H_ #define _ODE_COLLISION_TRIMESH_INTERNAL_H_ //**************************************************************************** // dxTriMesh class #include "collision_kernel.h" #include "collision_trimesh_colliders.h" #include #if dTRIMESH_OPCODE #define BAN_OPCODE_AUTOLINK #include "Opcode.h" using namespace Opcode; #endif // dTRIMESH_OPCODE #if dTRIMESH_GIMPACT #include #endif #if dTLS_ENABLED #include "odetls.h" #endif #if dTRIMESH_OPCODE #if !dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER // New trimesh collider hash table types enum { MAXCONTACT_X_NODE = 4, CONTACTS_HASHSIZE = 256, }; struct CONTACT_KEY { dContactGeom * m_contact; unsigned int m_key; }; struct CONTACT_KEY_HASH_NODE { CONTACT_KEY m_keyarray[MAXCONTACT_X_NODE]; int m_keycount; }; struct CONTACT_KEY_HASH_TABLE { public: CONTACT_KEY_HASH_NODE &operator[](unsigned int index) { return m_storage[index]; } private: CONTACT_KEY_HASH_NODE m_storage[CONTACTS_HASHSIZE]; }; #endif // !dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER #endif // dTRIMESH_OPCODE struct TrimeshCollidersCache { TrimeshCollidersCache() { #if dTRIMESH_OPCODE InitOPCODECaches(); #endif // dTRIMESH_OPCODE } #if dTRIMESH_OPCODE void InitOPCODECaches(); // Collider caches BVTCache ColCache; #if !dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER CONTACT_KEY_HASH_TABLE _hashcontactset; #endif // Colliders /* -- not used -- also uncomment in InitOPCODECaches() PlanesCollider _PlanesCollider; -- not used */ SphereCollider _SphereCollider; OBBCollider _OBBCollider; RayCollider _RayCollider; AABBTreeCollider _AABBTreeCollider; /* -- not used -- also uncomment in InitOPCODECaches() LSSCollider _LSSCollider; */ // Trimesh caches CollisionFaces Faces; SphereCache defaultSphereCache; OBBCache defaultBoxCache; LSSCache defaultCapsuleCache; #endif // dTRIMESH_OPCODE }; #if dTLS_ENABLED inline TrimeshCollidersCache *GetTrimeshCollidersCache(unsigned uiTLSKind) { EODETLSKIND tkTLSKind = (EODETLSKIND)uiTLSKind; return COdeTls::GetTrimeshCollidersCache(tkTLSKind); } #else // dTLS_ENABLED inline TrimeshCollidersCache *GetTrimeshCollidersCache(unsigned uiTLSKind) { extern TrimeshCollidersCache g_ccTrimeshCollidersCache; return &g_ccTrimeshCollidersCache; } #endif // dTLS_ENABLED struct dxTriMeshData : public dBase { /* Array of flags for which edges and verts should be used on each triangle */ enum UseFlags { kEdge0 = 0x1, kEdge1 = 0x2, kEdge2 = 0x4, kVert0 = 0x8, kVert1 = 0x10, kVert2 = 0x20, kUseAll = 0xFF, }; /* Setup the UseFlags array */ void Preprocess(); /* For when app changes the vertices */ void UpdateData(); #if dTRIMESH_OPCODE Model BVTree; MeshInterface Mesh; dxTriMeshData(); ~dxTriMeshData(); void Build(const void* Vertices, int VertexStide, int VertexCount, const void* Indices, int IndexCount, int TriStride, const void* Normals, bool Single); /* aabb in model space */ dVector3 AABBCenter; dVector3 AABBExtents; // data for use in collision resolution const void* Normals; uint8* UseFlags; #endif // dTRIMESH_OPCODE #if dTRIMESH_GIMPACT const char* m_Vertices; int m_VertexStride; int m_VertexCount; const char* m_Indices; int m_TriangleCount; int m_TriStride; bool m_single; dxTriMeshData() { m_Vertices=NULL; m_VertexStride = 12; m_VertexCount = 0; m_Indices = 0; m_TriangleCount = 0; m_TriStride = 12; m_single = true; } void Build(const void* Vertices, int VertexStride, int VertexCount, const void* Indices, int IndexCount, int TriStride, const void* Normals, bool Single) { dIASSERT(Vertices); dIASSERT(Indices); dIASSERT(VertexStride); dIASSERT(TriStride); dIASSERT(IndexCount); m_Vertices=(const char *)Vertices; m_VertexStride = VertexStride; m_VertexCount = VertexCount; m_Indices = (const char *)Indices; m_TriangleCount = IndexCount/3; m_TriStride = TriStride; m_single = Single; } inline void GetVertex(unsigned int i, dVector3 Out) { if(m_single) { const float * fverts = (const float * )(m_Vertices + m_VertexStride*i); Out[0] = fverts[0]; Out[1] = fverts[1]; Out[2] = fverts[2]; Out[3] = 1.0f; } else { const double * dverts = (const double * )(m_Vertices + m_VertexStride*i); Out[0] = (float)dverts[0]; Out[1] = (float)dverts[1]; Out[2] = (float)dverts[2]; Out[3] = 1.0f; } } inline void GetTriIndices(unsigned int itriangle, unsigned int triindices[3]) { const unsigned int * ind = (const unsigned int * )(m_Indices + m_TriStride*itriangle); triindices[0] = ind[0]; triindices[1] = ind[1]; triindices[2] = ind[2]; } #endif // dTRIMESH_GIMPACT }; struct dxTriMesh : public dxGeom{ // Callbacks dTriCallback* Callback; dTriArrayCallback* ArrayCallback; dTriRayCallback* RayCallback; dTriTriMergeCallback* TriMergeCallback; // Data types dxTriMeshData* Data; bool doSphereTC; bool doBoxTC; bool doCapsuleTC; // Functions dxTriMesh(dSpaceID Space, dTriMeshDataID Data); ~dxTriMesh(); void ClearTCCache(); int AABBTest(dxGeom* g, dReal aabb[6]); void computeAABB(); #if dTRIMESH_OPCODE // Instance data for last transform. dMatrix4 last_trans; // Some constants // Temporal coherence struct SphereTC : public SphereCache{ dxGeom* Geom; }; dArray SphereTCCache; struct BoxTC : public OBBCache{ dxGeom* Geom; }; dArray BoxTCCache; struct CapsuleTC : public LSSCache{ dxGeom* Geom; }; dArray CapsuleTCCache; #endif // dTRIMESH_OPCODE #if dTRIMESH_GIMPACT GIM_TRIMESH m_collision_trimesh; GBUFFER_MANAGER_DATA m_buffer_managers[G_BUFFER_MANAGER__MAX]; #endif // dTRIMESH_GIMPACT }; #if 0 #include "collision_kernel.h" // Fetches a contact inline dContactGeom* SAFECONTACT(int Flags, dContactGeom* Contacts, int Index, int Stride){ dIASSERT(Index >= 0 && Index < (Flags & NUMC_MASK)); return ((dContactGeom*)(((char*)Contacts) + (Index * Stride))); } #endif #if dTRIMESH_OPCODE inline unsigned FetchTriangleCount(dxTriMesh* TriMesh) { return TriMesh->Data->Mesh.GetNbTriangles(); } inline void FetchTriangle(dxTriMesh* TriMesh, int Index, const dVector3 Position, const dMatrix3 Rotation, dVector3 Out[3]){ VertexPointers VP; ConversionArea VC; TriMesh->Data->Mesh.GetTriangle(VP, Index, VC); for (int i = 0; i < 3; i++){ dVector3 v; v[0] = VP.Vertex[i]->x; v[1] = VP.Vertex[i]->y; v[2] = VP.Vertex[i]->z; v[3] = 0; dMULTIPLY0_331(Out[i], Rotation, v); Out[i][0] += Position[0]; Out[i][1] += Position[1]; Out[i][2] += Position[2]; Out[i][3] = 0; } } inline void FetchTransformedTriangle(dxTriMesh* TriMesh, int Index, dVector3 Out[3]){ const dVector3& Position = *(const dVector3*)dGeomGetPosition(TriMesh); const dMatrix3& Rotation = *(const dMatrix3*)dGeomGetRotation(TriMesh); FetchTriangle(TriMesh, Index, Position, Rotation, Out); } inline Matrix4x4& MakeMatrix(const dVector3 Position, const dMatrix3 Rotation, Matrix4x4& Out){ Out.m[0][0] = (float) Rotation[0]; Out.m[1][0] = (float) Rotation[1]; Out.m[2][0] = (float) Rotation[2]; Out.m[0][1] = (float) Rotation[4]; Out.m[1][1] = (float) Rotation[5]; Out.m[2][1] = (float) Rotation[6]; Out.m[0][2] = (float) Rotation[8]; Out.m[1][2] = (float) Rotation[9]; Out.m[2][2] = (float) Rotation[10]; Out.m[3][0] = (float) Position[0]; Out.m[3][1] = (float) Position[1]; Out.m[3][2] = (float) Position[2]; Out.m[0][3] = 0.0f; Out.m[1][3] = 0.0f; Out.m[2][3] = 0.0f; Out.m[3][3] = 1.0f; return Out; } inline Matrix4x4& MakeMatrix(dxGeom* g, Matrix4x4& Out){ const dVector3& Position = *(const dVector3*)dGeomGetPosition(g); const dMatrix3& Rotation = *(const dMatrix3*)dGeomGetRotation(g); return MakeMatrix(Position, Rotation, Out); } #endif // dTRIMESH_OPCODE #if dTRIMESH_GIMPACT #ifdef dDOUBLE // To use GIMPACT with doubles, we need to patch a couple of the GIMPACT functions to // convert arguments to floats before sending them in /// Convert an gimpact vec3f to a ODE dVector3d: dVector3[i] = vec3f[i] #define dVECTOR3_VEC3F_COPY(b,a) { \ (b)[0] = (a)[0]; \ (b)[1] = (a)[1]; \ (b)[2] = (a)[2]; \ (b)[3] = 0; \ } inline void gim_trimesh_get_triangle_verticesODE(GIM_TRIMESH * trimesh, GUINT32 triangle_index, dVector3 v1, dVector3 v2, dVector3 v3) { vec3f src1, src2, src3; gim_trimesh_get_triangle_vertices(trimesh, triangle_index, src1, src2, src3); dVECTOR3_VEC3F_COPY(v1, src1); dVECTOR3_VEC3F_COPY(v2, src2); dVECTOR3_VEC3F_COPY(v3, src3); } // Anything calling gim_trimesh_get_triangle_vertices from within ODE // should be patched through to the dDOUBLE version above #define gim_trimesh_get_triangle_vertices gim_trimesh_get_triangle_verticesODE inline int gim_trimesh_ray_closest_collisionODE( GIM_TRIMESH *mesh, dVector3 origin, dVector3 dir, GREAL tmax, GIM_TRIANGLE_RAY_CONTACT_DATA *contact ) { vec3f dir_vec3f = { dir[ 0 ], dir[ 1 ], dir[ 2 ] }; vec3f origin_vec3f = { origin[ 0 ], origin[ 1 ], origin[ 2 ] }; return gim_trimesh_ray_closest_collision( mesh, origin_vec3f, dir_vec3f, tmax, contact ); } inline int gim_trimesh_ray_collisionODE( GIM_TRIMESH *mesh, dVector3 origin, dVector3 dir, GREAL tmax, GIM_TRIANGLE_RAY_CONTACT_DATA *contact ) { vec3f dir_vec3f = { dir[ 0 ], dir[ 1 ], dir[ 2 ] }; vec3f origin_vec3f = { origin[ 0 ], origin[ 1 ], origin[ 2 ] }; return gim_trimesh_ray_collision( mesh, origin_vec3f, dir_vec3f, tmax, contact ); } #define gim_trimesh_sphere_collisionODE( mesh, Position, Radius, contact ) { \ vec3f pos_vec3f = { Position[ 0 ], Position[ 1 ], Position[ 2 ] }; \ gim_trimesh_sphere_collision( mesh, pos_vec3f, Radius, contact ); \ } #define gim_trimesh_plane_collisionODE( mesh, plane, contact ) { \ vec4f plane_vec4f = { plane[ 0 ], plane[ 1 ], plane[ 2 ], plane[ 3 ] }; \ gim_trimesh_plane_collision( mesh, plane_vec4f, contact ); \ } #define GIM_AABB_COPY( src, dst ) { \ dst[ 0 ]= (src) -> minX; \ dst[ 1 ]= (src) -> maxX; \ dst[ 2 ]= (src) -> minY; \ dst[ 3 ]= (src) -> maxY; \ dst[ 4 ]= (src) -> minZ; \ dst[ 5 ]= (src) -> maxZ; \ } #else // With single precision, we can pass native ODE vectors directly to GIMPACT #define gim_trimesh_ray_closest_collisionODE gim_trimesh_ray_closest_collision #define gim_trimesh_ray_collisionODE gim_trimesh_ray_collision #define gim_trimesh_sphere_collisionODE gim_trimesh_sphere_collision #define gim_trimesh_plane_collisionODE gim_trimesh_plane_collision #define GIM_AABB_COPY( src, dst ) memcpy( dst, src, 6 * sizeof( GREAL ) ) #endif // dDouble inline unsigned FetchTriangleCount(dxTriMesh* TriMesh) { return gim_trimesh_get_triangle_count(&TriMesh->m_collision_trimesh); } inline void FetchTransformedTriangle(dxTriMesh* TriMesh, int Index, dVector3 Out[3]){ gim_trimesh_locks_work_data(&TriMesh->m_collision_trimesh); gim_trimesh_get_triangle_vertices(&TriMesh->m_collision_trimesh, (GUINT32)Index, Out[0], Out[1], Out[2]); gim_trimesh_unlocks_work_data(&TriMesh->m_collision_trimesh); } inline void MakeMatrix(const dVector3 Position, const dMatrix3 Rotation, mat4f m) { m[0][0] = (float) Rotation[0]; m[0][1] = (float) Rotation[1]; m[0][2] = (float) Rotation[2]; m[1][0] = (float) Rotation[4]; m[1][1] = (float) Rotation[5]; m[1][2] = (float) Rotation[6]; m[2][0] = (float) Rotation[8]; m[2][1] = (float) Rotation[9]; m[2][2] = (float) Rotation[10]; m[0][3] = (float) Position[0]; m[1][3] = (float) Position[1]; m[2][3] = (float) Position[2]; } inline void MakeMatrix(dxGeom* g, mat4f Out){ const dVector3& Position = *(const dVector3*)dGeomGetPosition(g); const dMatrix3& Rotation = *(const dMatrix3*)dGeomGetRotation(g); MakeMatrix(Position, Rotation, Out); } #endif // dTRIMESH_GIMPACT // Outputs a matrix to 3 vectors inline void Decompose(const dMatrix3 Matrix, dVector3 Right, dVector3 Up, dVector3 Direction){ Right[0] = Matrix[0 * 4 + 0]; Right[1] = Matrix[1 * 4 + 0]; Right[2] = Matrix[2 * 4 + 0]; Right[3] = REAL(0.0); Up[0] = Matrix[0 * 4 + 1]; Up[1] = Matrix[1 * 4 + 1]; Up[2] = Matrix[2 * 4 + 1]; Up[3] = REAL(0.0); Direction[0] = Matrix[0 * 4 + 2]; Direction[1] = Matrix[1 * 4 + 2]; Direction[2] = Matrix[2 * 4 + 2]; Direction[3] = REAL(0.0); } // Outputs a matrix to 3 vectors inline void Decompose(const dMatrix3 Matrix, dVector3 Vectors[3]){ Decompose(Matrix, Vectors[0], Vectors[1], Vectors[2]); } // Finds barycentric inline void GetPointFromBarycentric(const dVector3 dv[3], dReal u, dReal v, dVector3 Out){ dReal w = REAL(1.0) - u - v; Out[0] = (dv[0][0] * w) + (dv[1][0] * u) + (dv[2][0] * v); Out[1] = (dv[0][1] * w) + (dv[1][1] * u) + (dv[2][1] * v); Out[2] = (dv[0][2] * w) + (dv[1][2] * u) + (dv[2][2] * v); Out[3] = (dv[0][3] * w) + (dv[1][3] * u) + (dv[2][3] * v); } // Performs a callback inline bool Callback(dxTriMesh* TriMesh, dxGeom* Object, int TriIndex){ if (TriMesh->Callback != NULL){ return (TriMesh->Callback(TriMesh, Object, TriIndex)!=0); } else return true; } // Some utilities template const T& dcMAX(const T& x, const T& y){ return x > y ? x : y; } template const T& dcMIN(const T& x, const T& y){ return x < y ? x : y; } dReal SqrDistancePointTri( const dVector3 p, const dVector3 triOrigin, const dVector3 triEdge1, const dVector3 triEdge2, dReal* pfSParam = 0, dReal* pfTParam = 0 ); dReal SqrDistanceSegments( const dVector3 seg1Origin, const dVector3 seg1Direction, const dVector3 seg2Origin, const dVector3 seg2Direction, dReal* pfSegP0 = 0, dReal* pfSegP1 = 0 ); dReal SqrDistanceSegTri( const dVector3 segOrigin, const dVector3 segEnd, const dVector3 triOrigin, const dVector3 triEdge1, const dVector3 triEdge2, dReal* t = 0, dReal* u = 0, dReal* v = 0 ); inline void Vector3Subtract( const dVector3 left, const dVector3 right, dVector3 result ) { result[0] = left[0] - right[0]; result[1] = left[1] - right[1]; result[2] = left[2] - right[2]; result[3] = REAL(0.0); } inline void Vector3Add( const dVector3 left, const dVector3 right, dVector3 result ) { result[0] = left[0] + right[0]; result[1] = left[1] + right[1]; result[2] = left[2] + right[2]; result[3] = REAL(0.0); } inline void Vector3Negate( const dVector3 in, dVector3 out ) { out[0] = -in[0]; out[1] = -in[1]; out[2] = -in[2]; out[3] = REAL(0.0); } inline void Vector3Copy( const dVector3 in, dVector3 out ) { out[0] = in[0]; out[1] = in[1]; out[2] = in[2]; out[3] = REAL(0.0); } inline void Vector3Multiply( const dVector3 in, dReal scalar, dVector3 out ) { out[0] = in[0] * scalar; out[1] = in[1] * scalar; out[2] = in[2] * scalar; out[3] = REAL(0.0); } inline void TransformVector3( const dVector3 in, const dMatrix3 orientation, const dVector3 position, dVector3 out ) { dMULTIPLY0_331( out, orientation, in ); out[0] += position[0]; out[1] += position[1]; out[2] += position[2]; } //------------------------------------------------------------------------------ /** @brief Check for intersection between triangle and capsule. @param dist [out] Shortest distance squared between the triangle and the capsule segment (central axis). @param t [out] t value of point on segment that's the shortest distance away from the triangle, the coordinates of this point can be found by (cap.seg.end - cap.seg.start) * t, or cap.seg.ipol(t). @param u [out] Barycentric coord on triangle. @param v [out] Barycentric coord on triangle. @return True if intersection exists. The third Barycentric coord is implicit, ie. w = 1.0 - u - v The Barycentric coords give the location of the point on the triangle closest to the capsule (where the distance between the two shapes is the shortest). */ inline bool IntersectCapsuleTri( const dVector3 segOrigin, const dVector3 segEnd, const dReal radius, const dVector3 triOrigin, const dVector3 triEdge0, const dVector3 triEdge1, dReal* dist, dReal* t, dReal* u, dReal* v ) { dReal sqrDist = SqrDistanceSegTri( segOrigin, segEnd, triOrigin, triEdge0, triEdge1, t, u, v ); if ( dist ) *dist = sqrDist; return ( sqrDist <= (radius * radius) ); } #endif //_ODE_COLLISION_TRIMESH_INTERNAL_H_ alien-arena-7.66+dfsg/source/unix/odesrc/heightfield.cpp0000600000175000017500000016750512161402010022342 0ustar zero79zero79// dHeightfield Collider // Paul Cheyrou-Lagreze aka Tuan Kuranes 2006 Speed enhancements http://www.pop-3d.com // Martijn Buijs 2006 http://home.planet.nl/~buijs512/ // Based on Terrain & Cone contrib by: // Benoit CHAPEROT 2003-2004 http://www.jstarlab.com // Some code inspired by Magic Software #include #include #include #include #include #include "collision_kernel.h" #include "collision_std.h" #include "collision_util.h" #include "heightfield.h" #if dTRIMESH_ENABLED #include "collision_trimesh_colliders.h" #endif // dTRIMESH_ENABLED #define dMIN(A,B) ((A)>(B) ? (B) : (A)) #define dMAX(A,B) ((A)>(B) ? (A) : (B)) // Three-way MIN and MAX #define dMIN3(A,B,C) ( (A)<(B) ? dMIN((A),(C)) : dMIN((B),(C)) ) #define dMAX3(A,B,C) ( (A)>(B) ? dMAX((A),(C)) : dMAX((B),(C)) ) #define dOPESIGN(a, op1, op2,b) \ (a)[0] op1 op2 ((b)[0]); \ (a)[1] op1 op2 ((b)[1]); \ (a)[2] op1 op2 ((b)[2]); #define dGeomRaySetNoNormalize(myRay, MyPoint, MyVector) { \ \ dVector3Copy (MyPoint, (myRay).final_posr->pos); \ (myRay).final_posr->R[2] = (MyVector)[0]; \ (myRay).final_posr->R[6] = (MyVector)[1]; \ (myRay).final_posr->R[10] = (MyVector)[2]; \ dGeomMoved (&myRay); \ } #define dGeomPlaneSetNoNormalize(MyPlane, MyPlaneDef) { \ \ (MyPlane)->p[0] = (MyPlaneDef)[0]; \ (MyPlane)->p[1] = (MyPlaneDef)[1]; \ (MyPlane)->p[2] = (MyPlaneDef)[2]; \ (MyPlane)->p[3] = (MyPlaneDef)[3]; \ dGeomMoved (MyPlane); \ } //////// Local Build Option //////////////////////////////////////////////////// // Uncomment this #define to use the (0,0) corner of the geom as the origin, // rather than the center. This was the way the original heightfield worked, // but as it does not match the way all other geometries work, so for constancy it // was changed to work like this. // #define DHEIGHTFIELD_CORNER_ORIGIN // Uncomment this #define to add heightfield triangles edge colliding // Code is not guaranteed and I didn't find the need to add that as // colliding planes triangles and edge triangles seems enough. // #define _HEIGHTFIELDEDGECOLLIDING //////// dxHeightfieldData ///////////////////////////////////////////////////////////// // dxHeightfieldData constructor dxHeightfieldData::dxHeightfieldData() : m_fWidth( 0 ), m_fDepth( 0 ), m_fSampleWidth( 0 ), m_fSampleDepth( 0 ), m_fSampleZXAspect( 0 ), m_fInvSampleWidth( 0 ), m_fInvSampleDepth( 0 ), m_fHalfWidth( 0 ), m_fHalfDepth( 0 ), m_fMinHeight( 0 ), m_fMaxHeight( 0 ), m_fThickness( 0 ), m_fScale( 0 ), m_fOffset( 0 ), m_nWidthSamples( 0 ), m_nDepthSamples( 0 ), m_bCopyHeightData( 0 ), m_bWrapMode( 0 ), m_nGetHeightMode( 0 ), m_pHeightData( NULL ), m_pUserData( NULL ), m_pGetHeightCallback( NULL ) { memset( m_contacts, 0, sizeof( m_contacts ) ); } // build Heightfield data void dxHeightfieldData::SetData( int nWidthSamples, int nDepthSamples, dReal fWidth, dReal fDepth, dReal fScale, dReal fOffset, dReal fThickness, int bWrapMode ) { dIASSERT( fWidth > REAL( 0.0 ) ); dIASSERT( fDepth > REAL( 0.0 ) ); dIASSERT( nWidthSamples > 0 ); dIASSERT( nDepthSamples > 0 ); // x,z bounds m_fWidth = fWidth; m_fDepth = fDepth; // cache half x,z bounds m_fHalfWidth = fWidth / REAL( 2.0 ); m_fHalfDepth = fDepth / REAL( 2.0 ); // scale and offset m_fScale = fScale; m_fOffset = fOffset; // infinite min height bounds m_fThickness = fThickness; // number of vertices per side m_nWidthSamples = nWidthSamples; m_nDepthSamples = nDepthSamples; m_fSampleWidth = m_fWidth / ( m_nWidthSamples - REAL( 1.0 ) ); m_fSampleDepth = m_fDepth / ( m_nDepthSamples - REAL( 1.0 ) ); m_fSampleZXAspect = m_fSampleDepth / m_fSampleWidth; m_fInvSampleWidth = REAL( 1.0 ) / m_fSampleWidth; m_fInvSampleDepth = REAL( 1.0 ) / m_fSampleDepth; // finite or repeated terrain? m_bWrapMode = bWrapMode; } // recomputes heights bounds void dxHeightfieldData::ComputeHeightBounds() { int i; dReal h; unsigned char *data_byte; short *data_short; float *data_float; double *data_double; switch ( m_nGetHeightMode ) { // callback case 0: // change nothing, keep using default or user specified bounds return; // byte case 1: data_byte = (unsigned char*)m_pHeightData; m_fMinHeight = dInfinity; m_fMaxHeight = -dInfinity; for (i=0; i m_fMaxHeight) m_fMaxHeight = h; } break; // short case 2: data_short = (short*)m_pHeightData; m_fMinHeight = dInfinity; m_fMaxHeight = -dInfinity; for (i=0; i m_fMaxHeight) m_fMaxHeight = h; } break; // float case 3: data_float = (float*)m_pHeightData; m_fMinHeight = dInfinity; m_fMaxHeight = -dInfinity; for (i=0; i m_fMaxHeight) m_fMaxHeight = h; } break; // double case 4: data_double = (double*)m_pHeightData; m_fMinHeight = dInfinity; m_fMaxHeight = -dInfinity; for (i=0; i( data_double[i] ); if (h < m_fMinHeight) m_fMinHeight = h; if (h > m_fMaxHeight) m_fMaxHeight = h; } break; } // scale and offset m_fMinHeight *= m_fScale; m_fMaxHeight *= m_fScale; m_fMinHeight += m_fOffset; m_fMaxHeight += m_fOffset; // add thickness m_fMinHeight -= m_fThickness; } // returns whether point is over terrain Cell triangle? bool dxHeightfieldData::IsOnHeightfield2 ( const HeightFieldVertex * const CellCorner, const dReal * const pos, const bool isABC) const { // WARNING!!! // This function must be written in the way to make sure that every point on // XZ plane falls in one and only one triangle. Keep that in mind if you // intend to change the code. // Also remember about computational errors and possible mismatches in // values if they are calculated differently in different places in the code. // Currently both the implementation has been optimized and effects of // computational errors have been eliminated. dReal MaxX, MinX; dReal MaxZ, MinZ; if (isABC) { // point A MinX = CellCorner->vertex[0]; if (pos[0] < MinX) return false; MaxX = (CellCorner->coords[0] + 1) * m_fSampleWidth; if (pos[0] >= MaxX) return false; MinZ = CellCorner->vertex[2]; if (pos[2] < MinZ) return false; MaxZ = (CellCorner->coords[1] + 1) * m_fSampleDepth; if (pos[2] >= MaxZ) return false; return (MaxZ - pos[2]) > (pos[0] - MinX) * m_fSampleZXAspect; } else { // point D MaxX = CellCorner->vertex[0]; if (pos[0] >= MaxX) return false; MinX = (CellCorner->coords[0] - 1) * m_fSampleWidth; if (pos[0] < MinX) return false; MaxZ = CellCorner->vertex[2]; if (pos[2] >= MaxZ) return false; MinZ = (CellCorner->coords[1] - 1) * m_fSampleDepth; if (pos[2] < MinZ) return false; return (MaxZ - pos[2]) <= (pos[0] - MinX) * m_fSampleZXAspect; } } // returns height at given sample coordinates dReal dxHeightfieldData::GetHeight( int x, int z ) { dReal h=0; unsigned char *data_byte; short *data_short; float *data_float; double *data_double; if ( m_bWrapMode == 0 ) { // Finite if ( x < 0 ) x = 0; if ( z < 0 ) z = 0; if ( x > m_nWidthSamples - 1 ) x = m_nWidthSamples - 1; if ( z > m_nDepthSamples - 1 ) z = m_nDepthSamples - 1; } else { // Infinite x %= m_nWidthSamples - 1; z %= m_nDepthSamples - 1; if ( x < 0 ) x += m_nWidthSamples - 1; if ( z < 0 ) z += m_nDepthSamples - 1; } switch ( m_nGetHeightMode ) { // callback (dReal) case 0: h = (*m_pGetHeightCallback)(m_pUserData, x, z); break; // byte case 1: data_byte = (unsigned char*)m_pHeightData; h = data_byte[x+(z * m_nWidthSamples)]; break; // short case 2: data_short = (short*)m_pHeightData; h = data_short[x+(z * m_nWidthSamples)]; break; // float case 3: data_float = (float*)m_pHeightData; h = data_float[x+(z * m_nWidthSamples)]; break; // double case 4: data_double = (double*)m_pHeightData; h = (dReal)( data_double[x+(z * m_nWidthSamples)] ); break; } return (h * m_fScale) + m_fOffset; } // returns height at given coordinates dReal dxHeightfieldData::GetHeight( dReal x, dReal z ) { dReal dnX = dFloor( x * m_fInvSampleWidth ); dReal dnZ = dFloor( z * m_fInvSampleDepth ); dReal dx = ( x - ( dnX * m_fSampleWidth ) ) * m_fInvSampleWidth; dReal dz = ( z - ( dnZ * m_fSampleDepth ) ) * m_fInvSampleDepth; int nX = int( dnX ); int nZ = int( dnZ ); //dIASSERT( ( dx + dEpsilon >= 0.0f ) && ( dx - dEpsilon <= 1.0f ) ); //dIASSERT( ( dz + dEpsilon >= 0.0f ) && ( dz - dEpsilon <= 1.0f ) ); dReal y, y0; if ( dx + dz <= REAL( 1.0 ) ) // Use <= comparison to prefer simpler branch { y0 = GetHeight( nX, nZ ); y = y0 + ( GetHeight( nX + 1, nZ ) - y0 ) * dx + ( GetHeight( nX, nZ + 1 ) - y0 ) * dz; } else { y0 = GetHeight( nX + 1, nZ + 1 ); y = y0 + ( GetHeight( nX + 1, nZ ) - y0 ) * ( REAL(1.0) - dz ) + ( GetHeight( nX, nZ + 1 ) - y0 ) * ( REAL(1.0) - dx ); } return y; } // dxHeightfieldData destructor dxHeightfieldData::~dxHeightfieldData() { unsigned char *data_byte; short *data_short; float *data_float; double *data_double; if ( m_bCopyHeightData ) { switch ( m_nGetHeightMode ) { // callback case 0: // do nothing break; // byte case 1: dIASSERT( m_pHeightData ); data_byte = (unsigned char*)m_pHeightData; delete [] data_byte; break; // short case 2: dIASSERT( m_pHeightData ); data_short = (short*)m_pHeightData; delete [] data_short; break; // float case 3: dIASSERT( m_pHeightData ); data_float = (float*)m_pHeightData; delete [] data_float; break; // double case 4: dIASSERT( m_pHeightData ); data_double = (double*)m_pHeightData; delete [] data_double; break; } } } //////// dxHeightfield ///////////////////////////////////////////////////////////////// // dxHeightfield constructor dxHeightfield::dxHeightfield( dSpaceID space, dHeightfieldDataID data, int bPlaceable ) : dxGeom( space, bPlaceable ), tempPlaneBuffer(0), tempPlaneInstances(0), tempPlaneBufferSize(0), tempTriangleBuffer(0), tempTriangleBufferSize(0), tempHeightBuffer(0), tempHeightInstances(0), tempHeightBufferSizeX(0), tempHeightBufferSizeZ(0) { type = dHeightfieldClass; this->m_p_data = data; } // compute axis aligned bounding box void dxHeightfield::computeAABB() { const dxHeightfieldData *d = m_p_data; if ( d->m_bWrapMode == 0 ) { // Finite if ( gflags & GEOM_PLACEABLE ) { dReal dx[6], dy[6], dz[6]; // Y-axis if (d->m_fMinHeight != -dInfinity) { dy[0] = ( final_posr->R[ 1] * d->m_fMinHeight ); dy[1] = ( final_posr->R[ 5] * d->m_fMinHeight ); dy[2] = ( final_posr->R[ 9] * d->m_fMinHeight ); } else { // Multiplication is performed to obtain infinity of correct sign dy[0] = ( final_posr->R[ 1] ? final_posr->R[ 1] * -dInfinity : REAL(0.0) ); dy[1] = ( final_posr->R[ 5] ? final_posr->R[ 5] * -dInfinity : REAL(0.0) ); dy[2] = ( final_posr->R[ 9] ? final_posr->R[ 9] * -dInfinity : REAL(0.0) ); } if (d->m_fMaxHeight != dInfinity) { dy[3] = ( final_posr->R[ 1] * d->m_fMaxHeight ); dy[4] = ( final_posr->R[ 5] * d->m_fMaxHeight ); dy[5] = ( final_posr->R[ 9] * d->m_fMaxHeight ); } else { dy[3] = ( final_posr->R[ 1] ? final_posr->R[ 1] * dInfinity : REAL(0.0) ); dy[4] = ( final_posr->R[ 5] ? final_posr->R[ 5] * dInfinity : REAL(0.0) ); dy[5] = ( final_posr->R[ 9] ? final_posr->R[ 9] * dInfinity : REAL(0.0) ); } #ifdef DHEIGHTFIELD_CORNER_ORIGIN // X-axis dx[0] = 0; dx[3] = ( final_posr->R[ 0] * d->m_fWidth ); dx[1] = 0; dx[4] = ( final_posr->R[ 4] * d->m_fWidth ); dx[2] = 0; dx[5] = ( final_posr->R[ 8] * d->m_fWidth ); // Z-axis dz[0] = 0; dz[3] = ( final_posr->R[ 2] * d->m_fDepth ); dz[1] = 0; dz[4] = ( final_posr->R[ 6] * d->m_fDepth ); dz[2] = 0; dz[5] = ( final_posr->R[10] * d->m_fDepth ); #else // DHEIGHTFIELD_CORNER_ORIGIN // X-axis dx[0] = ( final_posr->R[ 0] * -d->m_fHalfWidth ); dx[1] = ( final_posr->R[ 4] * -d->m_fHalfWidth ); dx[2] = ( final_posr->R[ 8] * -d->m_fHalfWidth ); dx[3] = ( final_posr->R[ 0] * d->m_fHalfWidth ); dx[4] = ( final_posr->R[ 4] * d->m_fHalfWidth ); dx[5] = ( final_posr->R[ 8] * d->m_fHalfWidth ); // Z-axis dz[0] = ( final_posr->R[ 2] * -d->m_fHalfDepth ); dz[1] = ( final_posr->R[ 6] * -d->m_fHalfDepth ); dz[2] = ( final_posr->R[10] * -d->m_fHalfDepth ); dz[3] = ( final_posr->R[ 2] * d->m_fHalfDepth ); dz[4] = ( final_posr->R[ 6] * d->m_fHalfDepth ); dz[5] = ( final_posr->R[10] * d->m_fHalfDepth ); #endif // DHEIGHTFIELD_CORNER_ORIGIN // X extents aabb[0] = final_posr->pos[0] + dMIN3( dMIN( dx[0], dx[3] ), dMIN( dy[0], dy[3] ), dMIN( dz[0], dz[3] ) ); aabb[1] = final_posr->pos[0] + dMAX3( dMAX( dx[0], dx[3] ), dMAX( dy[0], dy[3] ), dMAX( dz[0], dz[3] ) ); // Y extents aabb[2] = final_posr->pos[1] + dMIN3( dMIN( dx[1], dx[4] ), dMIN( dy[1], dy[4] ), dMIN( dz[1], dz[4] ) ); aabb[3] = final_posr->pos[1] + dMAX3( dMAX( dx[1], dx[4] ), dMAX( dy[1], dy[4] ), dMAX( dz[1], dz[4] ) ); // Z extents aabb[4] = final_posr->pos[2] + dMIN3( dMIN( dx[2], dx[5] ), dMIN( dy[2], dy[5] ), dMIN( dz[2], dz[5] ) ); aabb[5] = final_posr->pos[2] + dMAX3( dMAX( dx[2], dx[5] ), dMAX( dy[2], dy[5] ), dMAX( dz[2], dz[5] ) ); } else { #ifdef DHEIGHTFIELD_CORNER_ORIGIN aabb[0] = 0; aabb[1] = d->m_fWidth; aabb[2] = d->m_fMinHeight; aabb[3] = d->m_fMaxHeight; aabb[4] = 0; aabb[5] = d->m_fDepth; #else // DHEIGHTFIELD_CORNER_ORIGIN aabb[0] = -d->m_fHalfWidth; aabb[1] = +d->m_fHalfWidth; aabb[2] = d->m_fMinHeight; aabb[3] = d->m_fMaxHeight; aabb[4] = -d->m_fHalfDepth; aabb[5] = +d->m_fHalfDepth; #endif // DHEIGHTFIELD_CORNER_ORIGIN } } else { // Infinite if ( gflags & GEOM_PLACEABLE ) { aabb[0] = -dInfinity; aabb[1] = +dInfinity; aabb[2] = -dInfinity; aabb[3] = +dInfinity; aabb[4] = -dInfinity; aabb[5] = +dInfinity; } else { aabb[0] = -dInfinity; aabb[1] = +dInfinity; aabb[2] = d->m_fMinHeight; aabb[3] = d->m_fMaxHeight; aabb[4] = -dInfinity; aabb[5] = +dInfinity; } } } // dxHeightfield destructor dxHeightfield::~dxHeightfield() { resetTriangleBuffer(); resetPlaneBuffer(); resetHeightBuffer(); } void dxHeightfield::allocateTriangleBuffer(size_t numTri) { size_t alignedNumTri = AlignBufferSize(numTri, TEMP_TRIANGLE_BUFFER_ELEMENT_COUNT_ALIGNMENT); tempTriangleBufferSize = alignedNumTri; tempTriangleBuffer = new HeightFieldTriangle[alignedNumTri]; } void dxHeightfield::resetTriangleBuffer() { delete[] tempTriangleBuffer; } void dxHeightfield::allocatePlaneBuffer(size_t numTri) { size_t alignedNumTri = AlignBufferSize(numTri, TEMP_PLANE_BUFFER_ELEMENT_COUNT_ALIGNMENT); tempPlaneBufferSize = alignedNumTri; tempPlaneBuffer = new HeightFieldPlane *[alignedNumTri]; tempPlaneInstances = new HeightFieldPlane[alignedNumTri]; HeightFieldPlane *ptrPlaneMatrix = tempPlaneInstances; for (size_t indexTri = 0; indexTri != alignedNumTri; indexTri++) { tempPlaneBuffer[indexTri] = ptrPlaneMatrix; ptrPlaneMatrix += 1; } } void dxHeightfield::resetPlaneBuffer() { delete[] tempPlaneInstances; delete[] tempPlaneBuffer; } void dxHeightfield::allocateHeightBuffer(size_t numX, size_t numZ) { size_t alignedNumX = AlignBufferSize(numX, TEMP_HEIGHT_BUFFER_ELEMENT_COUNT_ALIGNMENT_X); size_t alignedNumZ = AlignBufferSize(numZ, TEMP_HEIGHT_BUFFER_ELEMENT_COUNT_ALIGNMENT_Z); tempHeightBufferSizeX = alignedNumX; tempHeightBufferSizeZ = alignedNumZ; tempHeightBuffer = new HeightFieldVertex *[alignedNumX]; size_t numCells = alignedNumX * alignedNumZ; tempHeightInstances = new HeightFieldVertex [numCells]; HeightFieldVertex *ptrHeightMatrix = tempHeightInstances; for (size_t indexX = 0; indexX != alignedNumX; indexX++) { tempHeightBuffer[indexX] = ptrHeightMatrix; ptrHeightMatrix += alignedNumZ; } } void dxHeightfield::resetHeightBuffer() { delete[] tempHeightInstances; delete[] tempHeightBuffer; } //////// Heightfield data interface //////////////////////////////////////////////////// dHeightfieldDataID dGeomHeightfieldDataCreate() { return new dxHeightfieldData(); } void dGeomHeightfieldDataBuildCallback( dHeightfieldDataID d, void* pUserData, dHeightfieldGetHeight* pCallback, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap ) { dUASSERT( d, "argument not Heightfield data" ); dIASSERT( pCallback ); dIASSERT( widthSamples >= 2 ); // Ensure we're making something with at least one cell. dIASSERT( depthSamples >= 2 ); // callback d->m_nGetHeightMode = 0; d->m_pUserData = pUserData; d->m_pGetHeightCallback = pCallback; // set info d->SetData( widthSamples, depthSamples, width, depth, scale, offset, thickness, bWrap ); // default bounds d->m_fMinHeight = -dInfinity; d->m_fMaxHeight = dInfinity; } void dGeomHeightfieldDataBuildByte( dHeightfieldDataID d, const unsigned char *pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap ) { dUASSERT( d, "Argument not Heightfield data" ); dIASSERT( pHeightData ); dIASSERT( widthSamples >= 2 ); // Ensure we're making something with at least one cell. dIASSERT( depthSamples >= 2 ); // set info d->SetData( widthSamples, depthSamples, width, depth, scale, offset, thickness, bWrap ); d->m_nGetHeightMode = 1; d->m_bCopyHeightData = bCopyHeightData; if ( d->m_bCopyHeightData == 0 ) { // Data is referenced only. d->m_pHeightData = pHeightData; } else { // We own the height data, allocate storage d->m_pHeightData = new unsigned char[ d->m_nWidthSamples * d->m_nDepthSamples ]; dIASSERT( d->m_pHeightData ); // Copy data. memcpy( (void*)d->m_pHeightData, pHeightData, sizeof( unsigned char ) * d->m_nWidthSamples * d->m_nDepthSamples ); } // Find height bounds d->ComputeHeightBounds(); } void dGeomHeightfieldDataBuildShort( dHeightfieldDataID d, const short* pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap ) { dUASSERT( d, "Argument not Heightfield data" ); dIASSERT( pHeightData ); dIASSERT( widthSamples >= 2 ); // Ensure we're making something with at least one cell. dIASSERT( depthSamples >= 2 ); // set info d->SetData( widthSamples, depthSamples, width, depth, scale, offset, thickness, bWrap ); d->m_nGetHeightMode = 2; d->m_bCopyHeightData = bCopyHeightData; if ( d->m_bCopyHeightData == 0 ) { // Data is referenced only. d->m_pHeightData = pHeightData; } else { // We own the height data, allocate storage d->m_pHeightData = new short[ d->m_nWidthSamples * d->m_nDepthSamples ]; dIASSERT( d->m_pHeightData ); // Copy data. memcpy( (void*)d->m_pHeightData, pHeightData, sizeof( short ) * d->m_nWidthSamples * d->m_nDepthSamples ); } // Find height bounds d->ComputeHeightBounds(); } void dGeomHeightfieldDataBuildSingle( dHeightfieldDataID d, const float *pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap ) { dUASSERT( d, "Argument not Heightfield data" ); dIASSERT( pHeightData ); dIASSERT( widthSamples >= 2 ); // Ensure we're making something with at least one cell. dIASSERT( depthSamples >= 2 ); // set info d->SetData( widthSamples, depthSamples, width, depth, scale, offset, thickness, bWrap ); d->m_nGetHeightMode = 3; d->m_bCopyHeightData = bCopyHeightData; if ( d->m_bCopyHeightData == 0 ) { // Data is referenced only. d->m_pHeightData = pHeightData; } else { // We own the height data, allocate storage d->m_pHeightData = new float[ d->m_nWidthSamples * d->m_nDepthSamples ]; dIASSERT( d->m_pHeightData ); // Copy data. memcpy( (void*)d->m_pHeightData, pHeightData, sizeof( float ) * d->m_nWidthSamples * d->m_nDepthSamples ); } // Find height bounds d->ComputeHeightBounds(); } void dGeomHeightfieldDataBuildDouble( dHeightfieldDataID d, const double *pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap ) { dUASSERT( d, "Argument not Heightfield data" ); dIASSERT( pHeightData ); dIASSERT( widthSamples >= 2 ); // Ensure we're making something with at least one cell. dIASSERT( depthSamples >= 2 ); // set info d->SetData( widthSamples, depthSamples, width, depth, scale, offset, thickness, bWrap ); d->m_nGetHeightMode = 4; d->m_bCopyHeightData = bCopyHeightData; if ( d->m_bCopyHeightData == 0 ) { // Data is referenced only. d->m_pHeightData = pHeightData; } else { // We own the height data, allocate storage d->m_pHeightData = new double[ d->m_nWidthSamples * d->m_nDepthSamples ]; dIASSERT( d->m_pHeightData ); // Copy data. memcpy( (void*)d->m_pHeightData, pHeightData, sizeof( double ) * d->m_nWidthSamples * d->m_nDepthSamples ); } // Find height bounds d->ComputeHeightBounds(); } void dGeomHeightfieldDataSetBounds( dHeightfieldDataID d, dReal minHeight, dReal maxHeight ) { dUASSERT(d, "Argument not Heightfield data"); d->m_fMinHeight = ( minHeight * d->m_fScale ) + d->m_fOffset - d->m_fThickness; d->m_fMaxHeight = ( maxHeight * d->m_fScale ) + d->m_fOffset; } void dGeomHeightfieldDataDestroy( dHeightfieldDataID d ) { dUASSERT(d, "argument not Heightfield data"); delete d; } //////// Heightfield geom interface //////////////////////////////////////////////////// dGeomID dCreateHeightfield( dSpaceID space, dHeightfieldDataID data, int bPlaceable ) { return new dxHeightfield( space, data, bPlaceable ); } void dGeomHeightfieldSetHeightfieldData( dGeomID g, dHeightfieldDataID d ) { dxHeightfield* geom = (dxHeightfield*) g; geom->data = d; } dHeightfieldDataID dGeomHeightfieldGetHeightfieldData( dGeomID g ) { dxHeightfield* geom = (dxHeightfield*) g; return geom->m_p_data; } //////// dxHeightfield ///////////////////////////////////////////////////////////////// // Typedef for generic 'get point depth' function typedef dReal dGetDepthFn( dGeomID g, dReal x, dReal y, dReal z ); #define DMESS(A) \ dMessage(0,"Contact Plane (%d %d %d) %.5e %.5e (%.5e %.5e %.5e)(%.5e %.5e %.5e)).", \ x,z,(A), \ pContact->depth, \ dGeomSphereGetRadius(o2), \ pContact->pos[0], \ pContact->pos[1], \ pContact->pos[2], \ pContact->normal[0], \ pContact->normal[1], \ pContact->normal[2]); static inline bool DescendingTriangleSort(const HeightFieldTriangle * const A, const HeightFieldTriangle * const B) { return ((A->maxAAAB - B->maxAAAB) > dEpsilon); } static inline bool DescendingPlaneSort(const HeightFieldPlane * const A, const HeightFieldPlane * const B) { return ((A->maxAAAB - B->maxAAAB) > dEpsilon); } void dxHeightfield::sortPlanes(const size_t numPlanes) { bool has_swapped = true; do { has_swapped = false;//reset flag for (size_t i = 0; i < numPlanes - 1; i++) { //if they are in the wrong order if (DescendingPlaneSort(tempPlaneBuffer[i], tempPlaneBuffer[i + 1])) { //exchange them HeightFieldPlane * tempPlane = tempPlaneBuffer[i]; tempPlaneBuffer[i] = tempPlaneBuffer[i + 1]; tempPlaneBuffer[i + 1] = tempPlane; //we have swapped at least once, list may not be sorted yet has_swapped = true; } } } //if no swaps were made during this pass, the list has been sorted while (has_swapped); } static inline dReal DistancePointToLine(const dVector3 &_point, const dVector3 &_pt0, const dVector3 &_Edge, const dReal _Edgelength) { dVector3 v; dVector3Subtract(_point, _pt0, v); dVector3 s; dVector3Copy (_Edge, s); const dReal dot = dVector3Dot(v, _Edge) / _Edgelength; dVector3Scale(s, dot); dVector3Subtract(v, s, v); return dVector3Length(v); } int dxHeightfield::dCollideHeightfieldZone( const int minX, const int maxX, const int minZ, const int maxZ, dxGeom* o2, const int numMaxContactsPossible, int flags, dContactGeom* contact, int skip ) { dContactGeom *pContact = 0; int x, z; // check if not above or inside terrain first // while filling a heightmap partial temporary buffer const unsigned int numX = (maxX - minX) + 1; const unsigned int numZ = (maxZ - minZ) + 1; const dReal minO2Height = o2->aabb[2]; const dReal maxO2Height = o2->aabb[3]; unsigned int x_local, z_local; dReal maxY = - dInfinity; dReal minY = dInfinity; // localize and const for faster access const dReal cfSampleWidth = m_p_data->m_fSampleWidth; const dReal cfSampleDepth = m_p_data->m_fSampleDepth; { if (tempHeightBufferSizeX < numX || tempHeightBufferSizeZ < numZ) { resetHeightBuffer(); allocateHeightBuffer(numX, numZ); } dReal Xpos, Ypos; for ( x = minX, x_local = 0; x_local < numX; x++, x_local++) { Xpos = x * cfSampleWidth; // Always calculate pos via multiplication to avoid computational error accumulation during multiple additions const dReal c_Xpos = Xpos; HeightFieldVertex *HeightFieldRow = tempHeightBuffer[x_local]; for ( z = minZ, z_local = 0; z_local < numZ; z++, z_local++) { Ypos = z * cfSampleDepth; // Always calculate pos via multiplication to avoid computational error accumulation during multiple additions const dReal h = m_p_data->GetHeight(x, z); HeightFieldRow[z_local].vertex[0] = c_Xpos; HeightFieldRow[z_local].vertex[1] = h; HeightFieldRow[z_local].vertex[2] = Ypos; HeightFieldRow[z_local].coords[0] = x; HeightFieldRow[z_local].coords[1] = z; maxY = dMAX(maxY, h); minY = dMIN(minY, h); } } if (minO2Height - maxY > -dEpsilon ) { //totally above heightfield return 0; } if (minY - maxO2Height > -dEpsilon ) { // totally under heightfield pContact = CONTACT(contact, 0); pContact->pos[0] = o2->final_posr->pos[0]; pContact->pos[1] = minY; pContact->pos[2] = o2->final_posr->pos[2]; pContact->normal[0] = 0; pContact->normal[1] = - 1; pContact->normal[2] = 0; pContact->depth = minY - maxO2Height; pContact->side1 = -1; pContact->side2 = -1; return 1; } } // get All Planes that could collide against. dColliderFn *geomRayNCollider=0; dColliderFn *geomNPlaneCollider=0; dGetDepthFn *geomNDepthGetter=0; // int max_collisionContact = numMaxContactsPossible; -- not used switch (o2->type) { case dRayClass: geomRayNCollider = NULL; geomNPlaneCollider = dCollideRayPlane; geomNDepthGetter = NULL; //max_collisionContact = 1; break; case dSphereClass: geomRayNCollider = dCollideRaySphere; geomNPlaneCollider = dCollideSpherePlane; geomNDepthGetter = dGeomSpherePointDepth; //max_collisionContact = 3; break; case dBoxClass: geomRayNCollider = dCollideRayBox; geomNPlaneCollider = dCollideBoxPlane; geomNDepthGetter = dGeomBoxPointDepth; //max_collisionContact = 8; break; case dCapsuleClass: geomRayNCollider = dCollideRayCapsule; geomNPlaneCollider = dCollideCapsulePlane; geomNDepthGetter = dGeomCapsulePointDepth; // max_collisionContact = 3; break; case dCylinderClass: geomRayNCollider = dCollideRayCylinder; geomNPlaneCollider = dCollideCylinderPlane; geomNDepthGetter = NULL;// TODO: dGeomCCylinderPointDepth //max_collisionContact = 3; break; case dConvexClass: geomRayNCollider = dCollideRayConvex; geomNPlaneCollider = dCollideConvexPlane; geomNDepthGetter = NULL;// TODO: dGeomConvexPointDepth; //max_collisionContact = 3; break; #if dTRIMESH_ENABLED case dTriMeshClass: geomRayNCollider = dCollideRayTrimesh; geomNPlaneCollider = dCollideTrimeshPlane; geomNDepthGetter = NULL;// TODO: dGeomTrimeshPointDepth; //max_collisionContact = 3; break; #endif // dTRIMESH_ENABLED default: dIASSERT(0); // Shouldn't ever get here. break; } dxPlane myplane(0,0,0,0,0); dxPlane* sliding_plane = &myplane; dReal triplane[4]; int i; // check some trivial case. // Vector Up plane if (maxY - minY < dEpsilon) { // it's a single plane. triplane[0] = 0; triplane[1] = 1; triplane[2] = 0; triplane[3] = minY; dGeomPlaneSetNoNormalize (sliding_plane, triplane); // find collision and compute contact points const int numTerrainContacts = geomNPlaneCollider (o2, sliding_plane, flags, contact, skip); dIASSERT(numTerrainContacts <= numMaxContactsPossible); for (i = 0; i < numTerrainContacts; i++) { pContact = CONTACT(contact, i*skip); dOPESIGN(pContact->normal, =, -, triplane); } return numTerrainContacts; } /* -- This block is invalid as per Martijn Buijs The problem seems to be based on the erroneously assumption that if two of the four vertices of a 'grid' are at the same height, the entire grid can be represented as a single plane. It works for an axis aligned slope, but fails on all 4 grids of a 3x3 spike feature. Since the plane normal is constructed from only 3 vertices (only one of the two triangles) this often results in discontinuities at the grid edges (causing small jumps when the contact point moves from one grid to another). // unique plane { // check for very simple plane heightfield dReal minXHeightDelta = dInfinity, maxXHeightDelta = - dInfinity; dReal minZHeightDelta = dInfinity, maxZHeightDelta = - dInfinity; dReal lastXHeight = tempHeightBuffer[0][0].vertex[1]; for ( x_local = 1; x_local < numX; x_local++) { HeightFieldVertex *HeightFieldRow = tempHeightBuffer[x_local]; const dReal deltaX = HeightFieldRow[0].vertex[1] - lastXHeight; maxXHeightDelta = dMAX (maxXHeightDelta, deltaX); minXHeightDelta = dMIN (minXHeightDelta, deltaX); dReal lastZHeight = HeightFieldRow[0].vertex[1]; for ( z_local = 1; z_local < numZ; z_local++) { const dReal deltaZ = (HeightFieldRow[z_local].vertex[1] - lastZHeight); maxZHeightDelta = dMAX (maxZHeightDelta, deltaZ); minZHeightDelta = dMIN (minZHeightDelta, deltaZ); } } if (maxZHeightDelta - minZHeightDelta < dEpsilon && maxXHeightDelta - minXHeightDelta < dEpsilon ) { // it's a single plane. const dVector3 &A = tempHeightBuffer[0][0].vertex; const dVector3 &B = tempHeightBuffer[1][0].vertex; const dVector3 &C = tempHeightBuffer[0][1].vertex; // define 2 edges and a point that will define collision plane { dVector3 Edge1, Edge2; dVector3Subtract(C, A, Edge1); dVector3Subtract(B, A, Edge2); dVector3Cross(Edge1, Edge2, triplane); } // Define Plane // Normalize plane normal const dReal dinvlength = REAL(1.0) / dVector3Length(triplane); triplane[0] *= dinvlength; triplane[1] *= dinvlength; triplane[2] *= dinvlength; // get distance to origin from plane triplane[3] = dVector3Dot(triplane, A); dGeomPlaneSetNoNormalize (sliding_plane, triplane); // find collision and compute contact points const int numTerrainContacts = geomNPlaneCollider (o2, sliding_plane, flags, contact, skip); dIASSERT(numTerrainContacts <= numMaxContactsPossible); for (i = 0; i < numTerrainContacts; i++) { pContact = CONTACT(contact, i*skip); dOPESIGN(pContact->normal, =, -, triplane); } return numTerrainContacts; } } */ int numTerrainContacts = 0; dContactGeom *PlaneContact = m_p_data->m_contacts; const unsigned int numTriMax = (maxX - minX) * (maxZ - minZ) * 2; if (tempTriangleBufferSize < numTriMax) { resetTriangleBuffer(); allocateTriangleBuffer(numTriMax); } // Sorting triangle/plane resulting from heightfield zone // Perhaps that would be necessary in case of too much limited // maximum contact point... // or in complex mesh case (trimesh and convex) // need some test or insights on this before enabling this. const bool isContactNumPointsLimited = true; // (numMaxContacts < 8) // || o2->type == dConvexClass // || o2->type == dTriMeshClass // || (numMaxContacts < (int)numTriMax) // if small heightfield triangle related to O2 colliding // or no Triangle colliding at all. bool needFurtherPasses = (o2->type == dTriMeshClass); //compute Ratio between Triangle size and O2 aabb size // no FurtherPasses are needed in ray class if (o2->type != dRayClass && needFurtherPasses == false) { const dReal xratio = (o2->aabb[1] - o2->aabb[0]) * m_p_data->m_fInvSampleWidth; if (xratio > REAL(1.5)) needFurtherPasses = true; else { const dReal zratio = (o2->aabb[5] - o2->aabb[4]) * m_p_data->m_fInvSampleDepth; if (zratio > REAL(1.5)) needFurtherPasses = true; } } unsigned int numTri = 0; HeightFieldVertex *A, *B, *C, *D; /* (y is up) A--------B-...x | /| | / | | / | | / | | / | | / | | / | |/ | C--------D . . . z */ // keep only triangle that does intersect geom const unsigned int maxX_local = maxX - minX; const unsigned int maxZ_local = maxZ - minZ; for ( x_local = 0; x_local < maxX_local; x_local++) { HeightFieldVertex *HeightFieldRow = tempHeightBuffer[x_local]; HeightFieldVertex *HeightFieldNextRow = tempHeightBuffer[x_local + 1]; // First A C = &HeightFieldRow [0]; // First B D = &HeightFieldNextRow[0]; for ( z_local = 0; z_local < maxZ_local; z_local++) { A = C; B = D; C = &HeightFieldRow [z_local + 1]; D = &HeightFieldNextRow[z_local + 1]; const dReal AHeight = A->vertex[1]; const dReal BHeight = B->vertex[1]; const dReal CHeight = C->vertex[1]; const dReal DHeight = D->vertex[1]; const bool isACollide = AHeight > minO2Height; const bool isBCollide = BHeight > minO2Height; const bool isCCollide = CHeight > minO2Height; const bool isDCollide = DHeight > minO2Height; A->state = !(isACollide); B->state = !(isBCollide); C->state = !(isCCollide); D->state = !(isDCollide); if (isACollide || isBCollide || isCCollide) { HeightFieldTriangle * const CurrTriUp = &tempTriangleBuffer[numTri++]; CurrTriUp->state = false; // changing point order here implies to change it in isOnHeightField CurrTriUp->vertices[0] = A; CurrTriUp->vertices[1] = B; CurrTriUp->vertices[2] = C; if (isContactNumPointsLimited) CurrTriUp->setMinMax(); CurrTriUp->isUp = true; } if (isBCollide || isCCollide || isDCollide) { HeightFieldTriangle * const CurrTriDown = &tempTriangleBuffer[numTri++]; CurrTriDown->state = false; // changing point order here implies to change it in isOnHeightField CurrTriDown->vertices[0] = D; CurrTriDown->vertices[1] = B; CurrTriDown->vertices[2] = C; if (isContactNumPointsLimited) CurrTriDown->setMinMax(); CurrTriDown->isUp = false; } if (needFurtherPasses && (isBCollide || isCCollide) && (AHeight > CHeight && AHeight > BHeight && DHeight > CHeight && DHeight > BHeight)) { // That means Edge BC is concave, therefore // BC Edge and B and C vertices cannot collide B->state = true; C->state = true; } // should find a way to check other edges (AB, BD, CD) too for concavity } } // at least on triangle should intersect geom dIASSERT (numTri != 0); // pass1: VS triangle as Planes // Group Triangle by same plane definition // as Terrain often has many triangles using same plane definition // then collide against that list of triangles. { dVector3 Edge1, Edge2; //compute all triangles normals. for (unsigned int k = 0; k < numTri; k++) { HeightFieldTriangle * const itTriangle = &tempTriangleBuffer[k]; // define 2 edges and a point that will define collision plane dVector3Subtract(itTriangle->vertices[2]->vertex, itTriangle->vertices[0]->vertex, Edge1); dVector3Subtract(itTriangle->vertices[1]->vertex, itTriangle->vertices[0]->vertex, Edge2); // find a perpendicular vector to the triangle if (itTriangle->isUp) dVector3Cross(Edge1, Edge2, triplane); else dVector3Cross(Edge2, Edge1, triplane); // Define Plane // Normalize plane normal const dReal dinvlength = REAL(1.0) / dVector3Length(triplane); triplane[0] *= dinvlength; triplane[1] *= dinvlength; triplane[2] *= dinvlength; // get distance to origin from plane triplane[3] = dVector3Dot(triplane, itTriangle->vertices[0]->vertex); // saves normal for collision check (planes, triangles, vertices and edges.) dVector3Copy(triplane, itTriangle->planeDef); // saves distance for collision check (planes, triangles, vertices and edges.) itTriangle->planeDef[3] = triplane[3]; } // group by Triangles by Planes sharing shame plane definition if (tempPlaneBufferSize < numTri) { resetPlaneBuffer(); allocatePlaneBuffer(numTri); } unsigned int numPlanes = 0; for (unsigned int k = 0; k < numTri; k++) { HeightFieldTriangle * const tri_base = &tempTriangleBuffer[k]; if (tri_base->state == true) continue;// already tested or added to plane list. HeightFieldPlane * const currPlane = tempPlaneBuffer[numPlanes]; currPlane->resetTriangleListSize(numTri - k); currPlane->addTriangle(tri_base); // saves normal for collision check (planes, triangles, vertices and edges.) dVector3Copy(tri_base->planeDef, currPlane->planeDef); // saves distance for collision check (planes, triangles, vertices and edges.) currPlane->planeDef[3]= tri_base->planeDef[3]; const dReal normx = tri_base->planeDef[0]; const dReal normy = tri_base->planeDef[1]; const dReal normz = tri_base->planeDef[2]; const dReal dist = tri_base->planeDef[3]; for (unsigned int m = k + 1; m < numTri; m++) { HeightFieldTriangle * const tri_test = &tempTriangleBuffer[m]; if (tri_test->state == true) continue;// already tested or added to plane list. // normals and distance are the same. if ( dFabs(normy - tri_test->planeDef[1]) < dEpsilon && dFabs(dist - tri_test->planeDef[3]) < dEpsilon && dFabs(normx - tri_test->planeDef[0]) < dEpsilon && dFabs(normz - tri_test->planeDef[2]) < dEpsilon ) { currPlane->addTriangle (tri_test); tri_test->state = true; } } tri_base->state = true; if (isContactNumPointsLimited) currPlane->setMinMax(); numPlanes++; } // sort planes if (isContactNumPointsLimited) sortPlanes(numPlanes); #if !defined(NO_CONTACT_CULLING_BY_ISONHEIGHTFIELD2) /* Note by Oleh_Derevenko: It seems to be incorrect to limit contact count by some particular value since some of them (and even all of them) may be culled in following condition. However I do not see an easy way to fix this. If not that culling the flags modification should be changed here and additionally repeated after some contacts have been generated (in "if (didCollide)"). The maximum of contacts in flags would then be set to minimum of contacts remaining and HEIGHTFIELDMAXCONTACTPERCELL. */ int planeTestFlags = (flags & ~NUMC_MASK) | HEIGHTFIELDMAXCONTACTPERCELL; dIASSERT((HEIGHTFIELDMAXCONTACTPERCELL & ~NUMC_MASK) == 0); #else // if defined(NO_CONTACT_CULLING_BY_ISONHEIGHTFIELD2) int numMaxContactsPerPlane = dMIN(numMaxContactsPossible - numTerrainContacts, HEIGHTFIELDMAXCONTACTPERCELL); int planeTestFlags = (flags & ~NUMC_MASK) | numMaxContactsPerPlane; dIASSERT((HEIGHTFIELDMAXCONTACTPERCELL & ~NUMC_MASK) == 0); #endif for (unsigned int k = 0; k < numPlanes; k++) { HeightFieldPlane * const itPlane = tempPlaneBuffer[k]; //set Geom dGeomPlaneSetNoNormalize (sliding_plane, itPlane->planeDef); //dGeomPlaneSetParams (sliding_plane, triangle_Plane[0], triangle_Plane[1], triangle_Plane[2], triangle_Plane[3]); // find collision and compute contact points bool didCollide = false; const int numPlaneContacts = geomNPlaneCollider (o2, sliding_plane, planeTestFlags, PlaneContact, sizeof(dContactGeom)); const size_t planeTriListSize = itPlane->trianglelistCurrentSize; for (i = 0; i < numPlaneContacts; i++) { dContactGeom *planeCurrContact = PlaneContact + i; // Check if contact point found in plane is inside Triangle. const dVector3 &pCPos = planeCurrContact->pos; for (size_t b = 0; planeTriListSize > b; b++) { if (m_p_data->IsOnHeightfield2 (itPlane->trianglelist[b]->vertices[0], pCPos, itPlane->trianglelist[b]->isUp)) { pContact = CONTACT(contact, numTerrainContacts*skip); dVector3Copy(pCPos, pContact->pos); dOPESIGN(pContact->normal, =, -, itPlane->planeDef); pContact->depth = planeCurrContact->depth; pContact->side1 = planeCurrContact->side1; pContact->side2 = planeCurrContact->side2; numTerrainContacts++; if ( numTerrainContacts == numMaxContactsPossible ) return numTerrainContacts; didCollide = true; break; } } } if (didCollide) { #if defined(NO_CONTACT_CULLING_BY_ISONHEIGHTFIELD2) /* Note by Oleh_Derevenko: This code is not used - see another note above */ numMaxContactsPerPlane = dMIN(numMaxContactsPossible - numTerrainContacts, HEIGHTFIELDMAXCONTACTPERCELL); planeTestFlags = (flags & ~NUMC_MASK) | numMaxContactsPerPlane; dIASSERT((HEIGHTFIELDMAXCONTACTPERCELL & ~NUMC_MASK) == 0); #endif for (size_t b = 0; planeTriListSize > b; b++) { // flag Triangles Vertices as collided // to prevent any collision test of those for (i = 0; i < 3; i++) itPlane->trianglelist[b]->vertices[i]->state = true; } } else { // flag triangle as not collided so that Vertices or Edge // of that triangles will be checked. for (size_t b = 0; planeTriListSize > b; b++) { itPlane->trianglelist[b]->state = false; } } } } // pass2: VS triangle vertices if (needFurtherPasses) { dxRay tempRay(0, 1); dReal depth; bool vertexCollided; // Only one contact is necessary for ray test int rayTestFlags = (flags & ~NUMC_MASK) | 1; dIASSERT((1 & ~NUMC_MASK) == 0); // // Find Contact Penetration Depth of each vertices // for (unsigned int k = 0; k < numTri; k++) { const HeightFieldTriangle * const itTriangle = &tempTriangleBuffer[k]; if (itTriangle->state == true) continue;// plane triangle did already collide. for (size_t i = 0; i < 3; i++) { HeightFieldVertex *vertex = itTriangle->vertices[i]; if (vertex->state == true) continue;// vertice did already collide. vertexCollided = false; const dVector3 &triVertex = vertex->vertex; if ( geomNDepthGetter ) { depth = geomNDepthGetter( o2, triVertex[0], triVertex[1], triVertex[2] ); if (depth > dEpsilon) vertexCollided = true; } else { // We don't have a GetDepth function, so do a ray cast instead. // NOTE: This isn't ideal, and a GetDepth function should be // written for all geom classes. tempRay.length = (minO2Height - triVertex[1]) * REAL(1000.0); //dGeomRaySet( &tempRay, pContact->pos[0], pContact->pos[1], pContact->pos[2], // - itTriangle->Normal[0], - itTriangle->Normal[1], - itTriangle->Normal[2] ); dGeomRaySetNoNormalize(tempRay, triVertex, itTriangle->planeDef); if ( geomRayNCollider( &tempRay, o2, rayTestFlags, PlaneContact, sizeof( dContactGeom ) ) ) { depth = PlaneContact[0].depth; vertexCollided = true; } } if (vertexCollided) { pContact = CONTACT(contact, numTerrainContacts*skip); //create contact using vertices dVector3Copy (triVertex, pContact->pos); //create contact using Plane Normal dOPESIGN(pContact->normal, =, -, itTriangle->planeDef); pContact->depth = depth; pContact->side1 = -1; pContact->side2 = -1; numTerrainContacts++; if ( numTerrainContacts == numMaxContactsPossible ) return numTerrainContacts; vertex->state = true; } } } } #ifdef _HEIGHTFIELDEDGECOLLIDING // pass3: VS triangle Edges if (needFurtherPasses) { dVector3 Edge; dxRay edgeRay(0, 1); int numMaxContactsPerTri = dMIN(numMaxContactsPossible - numTerrainContacts, HEIGHTFIELDMAXCONTACTPERCELL); int triTestFlags = (flags & ~NUMC_MASK) | numMaxContactsPerTri; dIASSERT((HEIGHTFIELDMAXCONTACTPERCELL & ~NUMC_MASK) == 0); for (unsigned int k = 0; k < numTri; k++) { const HeightFieldTriangle * const itTriangle = &tempTriangleBuffer[k]; if (itTriangle->state == true) continue;// plane did already collide. for (size_t m = 0; m < 3; m++) { const size_t next = (m + 1) % 3; HeightFieldVertex *vertex0 = itTriangle->vertices[m]; HeightFieldVertex *vertex1 = itTriangle->vertices[next]; // not concave or under the AABB // nor triangle already collided against vertices if (vertex0->state == true && vertex1->state == true) continue;// plane did already collide. dVector3Subtract(vertex1->vertex, vertex0->vertex, Edge); edgeRay.length = dVector3Length (Edge); dGeomRaySetNoNormalize(edgeRay, vertex1->vertex, Edge); int prevTerrainContacts = numTerrainContacts; pContact = CONTACT(contact, prevTerrainContacts*skip); const int numCollision = geomRayNCollider(&edgeRay,o2,triTestFlags,pContact,skip); dIASSERT(numCollision <= numMaxContactsPerTri); if (numCollision) { numTerrainContacts += numCollision; do { pContact = CONTACT(contact, prevTerrainContacts*skip); //create contact using Plane Normal dOPESIGN(pContact->normal, =, -, itTriangle->planeDef); pContact->depth = DistancePointToLine(pContact->pos, vertex1->vertex, Edge, edgeRay.length); } while (++prevTerrainContacts != numTerrainContacts); if ( numTerrainContacts == numMaxContactsPossible ) return numTerrainContacts; numMaxContactsPerTri = dMIN(numMaxContactsPossible - numTerrainContacts, HEIGHTFIELDMAXCONTACTPERCELL); triTestFlags = (flags & ~NUMC_MASK) | numMaxContactsPerTri; dIASSERT((HEIGHTFIELDMAXCONTACTPERCELL & ~NUMC_MASK) == 0); } } itTriangle->vertices[0]->state = true; itTriangle->vertices[1]->state = true; itTriangle->vertices[2]->state = true; } } #endif // _HEIGHTFIELDEDGECOLLIDING return numTerrainContacts; } int dCollideHeightfield( dxGeom *o1, dxGeom *o2, int flags, dContactGeom* contact, int skip ) { dIASSERT( skip >= (int)sizeof(dContactGeom) ); dIASSERT( o1->type == dHeightfieldClass ); dIASSERT((flags & NUMC_MASK) >= 1); int i; // if ((flags & NUMC_MASK) == 0) -- An assertion check is made on entry // { flags = (flags & ~NUMC_MASK) | 1; dIASSERT((1 & ~NUMC_MASK) == 0); } int numMaxTerrainContacts = (flags & NUMC_MASK); dxHeightfield *terrain = (dxHeightfield*) o1; dVector3 posbak; dMatrix3 Rbak; dReal aabbbak[6]; int gflagsbak; dVector3 pos0,pos1; dMatrix3 R1; int numTerrainContacts = 0; int numTerrainOrigContacts = 0; //@@ Should find a way to set reComputeAABB to false in default case // aka DHEIGHTFIELD_CORNER_ORIGIN not defined and terrain not PLACEABLE // so that we can free some memory and speed up things a bit // while saving some precision loss #ifndef DHEIGHTFIELD_CORNER_ORIGIN const bool reComputeAABB = true; #else const bool reComputeAABB = ( terrain->gflags & GEOM_PLACEABLE ) ? true : false; #endif //DHEIGHTFIELD_CORNER_ORIGIN // // Transform O2 into Heightfield Space // if (reComputeAABB) { // Backup original o2 position, rotation and AABB. dVector3Copy( o2->final_posr->pos, posbak ); dMatrix3Copy( o2->final_posr->R, Rbak ); memcpy( aabbbak, o2->aabb, sizeof( dReal ) * 6 ); gflagsbak = o2->gflags; } if ( terrain->gflags & GEOM_PLACEABLE ) { // Transform o2 into heightfield space. dOP( pos0, -, o2->final_posr->pos, terrain->final_posr->pos ); dMULTIPLY1_331( pos1, terrain->final_posr->R, pos0 ); dMULTIPLY1_333( R1, terrain->final_posr->R, o2->final_posr->R ); // Update o2 with transformed position and rotation. dVector3Copy( pos1, o2->final_posr->pos ); dMatrix3Copy( R1, o2->final_posr->R ); } #ifndef DHEIGHTFIELD_CORNER_ORIGIN o2->final_posr->pos[ 0 ] += terrain->m_p_data->m_fHalfWidth; o2->final_posr->pos[ 2 ] += terrain->m_p_data->m_fHalfDepth; #endif // DHEIGHTFIELD_CORNER_ORIGIN // Rebuild AABB for O2 if (reComputeAABB) o2->computeAABB(); // // Collide // //check if inside boundaries // using O2 aabb // aabb[6] is (minx, maxx, miny, maxy, minz, maxz) const bool wrapped = terrain->m_p_data->m_bWrapMode != 0; int nMinX; int nMaxX; int nMinZ; int nMaxZ; if ( !wrapped ) { if ( o2->aabb[0] > terrain->m_p_data->m_fWidth //MinX || o2->aabb[4] > terrain->m_p_data->m_fDepth)//MinZ goto dCollideHeightfieldExit; if ( o2->aabb[1] < 0 //MaxX || o2->aabb[5] < 0) //MaxZ goto dCollideHeightfieldExit; } nMinX = int(dFloor(o2->aabb[0] * terrain->m_p_data->m_fInvSampleWidth)); nMaxX = int(dFloor(o2->aabb[1] * terrain->m_p_data->m_fInvSampleWidth)) + 1; nMinZ = int(dFloor(o2->aabb[4] * terrain->m_p_data->m_fInvSampleDepth)); nMaxZ = int(dFloor(o2->aabb[5] * terrain->m_p_data->m_fInvSampleDepth)) + 1; if ( !wrapped ) { nMinX = dMAX( nMinX, 0 ); nMaxX = dMIN( nMaxX, terrain->m_p_data->m_nWidthSamples - 1 ); nMinZ = dMAX( nMinZ, 0 ); nMaxZ = dMIN( nMaxZ, terrain->m_p_data->m_nDepthSamples - 1 ); dIASSERT ((nMinX < nMaxX) && (nMinZ < nMaxZ)) } numTerrainOrigContacts = numTerrainContacts; numTerrainContacts += terrain->dCollideHeightfieldZone( nMinX,nMaxX,nMinZ,nMaxZ,o2,numMaxTerrainContacts - numTerrainContacts, flags,CONTACT(contact,numTerrainContacts*skip),skip ); dIASSERT( numTerrainContacts <= numMaxTerrainContacts ); dContactGeom *pContact; for ( i = numTerrainOrigContacts; i != numTerrainContacts; ++i ) { pContact = CONTACT(contact,i*skip); pContact->g1 = o1; pContact->g2 = o2; // pContact->side1 = -1; -- Oleh_Derevenko: sides must not be erased here as they are set by respective colliders during ray/plane tests // pContact->side2 = -1; } //------------------------------------------------------------------------------ dCollideHeightfieldExit: if (reComputeAABB) { // Restore o2 position, rotation and AABB dVector3Copy( posbak, o2->final_posr->pos ); dMatrix3Copy( Rbak, o2->final_posr->R ); memcpy( o2->aabb, aabbbak, sizeof(dReal)*6 ); o2->gflags = gflagsbak; // // Transform Contacts to World Space // if ( terrain->gflags & GEOM_PLACEABLE ) { for ( i = 0; i < numTerrainContacts; ++i ) { pContact = CONTACT(contact,i*skip); dOPE( pos0, =, pContact->pos ); #ifndef DHEIGHTFIELD_CORNER_ORIGIN pos0[ 0 ] -= terrain->m_p_data->m_fHalfWidth; pos0[ 2 ] -= terrain->m_p_data->m_fHalfDepth; #endif // !DHEIGHTFIELD_CORNER_ORIGIN dMULTIPLY0_331( pContact->pos, terrain->final_posr->R, pos0 ); dOP( pContact->pos, +, pContact->pos, terrain->final_posr->pos ); dOPE( pos0, =, pContact->normal ); dMULTIPLY0_331( pContact->normal, terrain->final_posr->R, pos0 ); } } #ifndef DHEIGHTFIELD_CORNER_ORIGIN else { for ( i = 0; i < numTerrainContacts; ++i ) { pContact = CONTACT(contact,i*skip); pContact->pos[ 0 ] -= terrain->m_p_data->m_fHalfWidth; pContact->pos[ 2 ] -= terrain->m_p_data->m_fHalfDepth; } } #endif // !DHEIGHTFIELD_CORNER_ORIGIN } // Return contact count. return numTerrainContacts; } alien-arena-7.66+dfsg/source/unix/odesrc/util.cpp0000600000175000017500000003363112161402010021033 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include "ode/ode.h" #include "objects.h" #include "joints/joint.h" #include "util.h" #define ALLOCA dALLOCA16 //**************************************************************************** // Auto disabling void dInternalHandleAutoDisabling (dxWorld *world, dReal stepsize) { dxBody *bb; for ( bb=world->firstbody; bb; bb=(dxBody*)bb->next ) { // don't freeze objects mid-air (patch 1586738) if ( bb->firstjoint == NULL ) continue; // nothing to do unless this body is currently enabled and has // the auto-disable flag set if ( (bb->flags & (dxBodyAutoDisable|dxBodyDisabled)) != dxBodyAutoDisable ) continue; // if sampling / threshold testing is disabled, we can never sleep. if ( bb->adis.average_samples == 0 ) continue; // // see if the body is idle // #ifndef dNODEBUG // sanity check if ( bb->average_counter >= bb->adis.average_samples ) { dUASSERT( bb->average_counter < bb->adis.average_samples, "buffer overflow" ); // something is going wrong, reset the average-calculations bb->average_ready = 0; // not ready for average calculation bb->average_counter = 0; // reset the buffer index } #endif // dNODEBUG // sample the linear and angular velocity bb->average_lvel_buffer[bb->average_counter][0] = bb->lvel[0]; bb->average_lvel_buffer[bb->average_counter][1] = bb->lvel[1]; bb->average_lvel_buffer[bb->average_counter][2] = bb->lvel[2]; bb->average_avel_buffer[bb->average_counter][0] = bb->avel[0]; bb->average_avel_buffer[bb->average_counter][1] = bb->avel[1]; bb->average_avel_buffer[bb->average_counter][2] = bb->avel[2]; bb->average_counter++; // buffer ready test if ( bb->average_counter >= bb->adis.average_samples ) { bb->average_counter = 0; // fill the buffer from the beginning bb->average_ready = 1; // this body is ready now for average calculation } int idle = 0; // Assume it's in motion unless we have samples to disprove it. // enough samples? if ( bb->average_ready ) { idle = 1; // Initial assumption: IDLE // the sample buffers are filled and ready for calculation dVector3 average_lvel, average_avel; // Store first velocity samples average_lvel[0] = bb->average_lvel_buffer[0][0]; average_avel[0] = bb->average_avel_buffer[0][0]; average_lvel[1] = bb->average_lvel_buffer[0][1]; average_avel[1] = bb->average_avel_buffer[0][1]; average_lvel[2] = bb->average_lvel_buffer[0][2]; average_avel[2] = bb->average_avel_buffer[0][2]; // If we're not in "instantaneous mode" if ( bb->adis.average_samples > 1 ) { // add remaining velocities together for ( unsigned int i = 1; i < bb->adis.average_samples; ++i ) { average_lvel[0] += bb->average_lvel_buffer[i][0]; average_avel[0] += bb->average_avel_buffer[i][0]; average_lvel[1] += bb->average_lvel_buffer[i][1]; average_avel[1] += bb->average_avel_buffer[i][1]; average_lvel[2] += bb->average_lvel_buffer[i][2]; average_avel[2] += bb->average_avel_buffer[i][2]; } // make average dReal r1 = dReal( 1.0 ) / dReal( bb->adis.average_samples ); average_lvel[0] *= r1; average_avel[0] *= r1; average_lvel[1] *= r1; average_avel[1] *= r1; average_lvel[2] *= r1; average_avel[2] *= r1; } // threshold test dReal av_lspeed, av_aspeed; av_lspeed = dDOT( average_lvel, average_lvel ); if ( av_lspeed > bb->adis.linear_average_threshold ) { idle = 0; // average linear velocity is too high for idle } else { av_aspeed = dDOT( average_avel, average_avel ); if ( av_aspeed > bb->adis.angular_average_threshold ) { idle = 0; // average angular velocity is too high for idle } } } // if it's idle, accumulate steps and time. // these counters won't overflow because this code doesn't run for disabled bodies. if (idle) { bb->adis_stepsleft--; bb->adis_timeleft -= stepsize; } else { // Reset countdowns bb->adis_stepsleft = bb->adis.idle_steps; bb->adis_timeleft = bb->adis.idle_time; } // disable the body if it's idle for a long enough time if ( bb->adis_stepsleft <= 0 && bb->adis_timeleft <= 0 ) { bb->flags |= dxBodyDisabled; // set the disable flag // disabling bodies should also include resetting the velocity // should prevent jittering in big "islands" bb->lvel[0] = 0; bb->lvel[1] = 0; bb->lvel[2] = 0; bb->avel[0] = 0; bb->avel[1] = 0; bb->avel[2] = 0; } } } //**************************************************************************** // body rotation // return sin(x)/x. this has a singularity at 0 so special handling is needed // for small arguments. static inline dReal sinc (dReal x) { // if |x| < 1e-4 then use a taylor series expansion. this two term expansion // is actually accurate to one LS bit within this range if double precision // is being used - so don't worry! if (dFabs(x) < 1.0e-4) return REAL(1.0) - x*x*REAL(0.166666666666666666667); else return dSin(x)/x; } // given a body b, apply its linear and angular rotation over the time // interval h, thereby adjusting its position and orientation. void dxStepBody (dxBody *b, dReal h) { // cap the angular velocity if (b->flags & dxBodyMaxAngularSpeed) { const dReal max_ang_speed = b->max_angular_speed; const dReal aspeed = dDOT( b->avel, b->avel ); if (aspeed > max_ang_speed*max_ang_speed) { const dReal coef = max_ang_speed/dSqrt(aspeed); dOPEC(b->avel, *=, coef); } } // end of angular velocity cap int j; // handle linear velocity for (j=0; j<3; j++) b->posr.pos[j] += h * b->lvel[j]; if (b->flags & dxBodyFlagFiniteRotation) { dVector3 irv; // infitesimal rotation vector dQuaternion q; // quaternion for finite rotation if (b->flags & dxBodyFlagFiniteRotationAxis) { // split the angular velocity vector into a component along the finite // rotation axis, and a component orthogonal to it. dVector3 frv; // finite rotation vector dReal k = dDOT (b->finite_rot_axis,b->avel); frv[0] = b->finite_rot_axis[0] * k; frv[1] = b->finite_rot_axis[1] * k; frv[2] = b->finite_rot_axis[2] * k; irv[0] = b->avel[0] - frv[0]; irv[1] = b->avel[1] - frv[1]; irv[2] = b->avel[2] - frv[2]; // make a rotation quaternion q that corresponds to frv * h. // compare this with the full-finite-rotation case below. h *= REAL(0.5); dReal theta = k * h; q[0] = dCos(theta); dReal s = sinc(theta) * h; q[1] = frv[0] * s; q[2] = frv[1] * s; q[3] = frv[2] * s; } else { // make a rotation quaternion q that corresponds to w * h dReal wlen = dSqrt (b->avel[0]*b->avel[0] + b->avel[1]*b->avel[1] + b->avel[2]*b->avel[2]); h *= REAL(0.5); dReal theta = wlen * h; q[0] = dCos(theta); dReal s = sinc(theta) * h; q[1] = b->avel[0] * s; q[2] = b->avel[1] * s; q[3] = b->avel[2] * s; } // do the finite rotation dQuaternion q2; dQMultiply0 (q2,q,b->q); for (j=0; j<4; j++) b->q[j] = q2[j]; // do the infitesimal rotation if required if (b->flags & dxBodyFlagFiniteRotationAxis) { dReal dq[4]; dWtoDQ (irv,b->q,dq); for (j=0; j<4; j++) b->q[j] += h * dq[j]; } } else { // the normal way - do an infitesimal rotation dReal dq[4]; dWtoDQ (b->avel,b->q,dq); for (j=0; j<4; j++) b->q[j] += h * dq[j]; } // normalize the quaternion and convert it to a rotation matrix dNormalize4 (b->q); dQtoR (b->q,b->posr.R); // notify all attached geoms that this body has moved for (dxGeom *geom = b->geom; geom; geom = dGeomGetBodyNext (geom)) dGeomMoved (geom); // notify the user if (b->moved_callback) b->moved_callback(b); // damping if (b->flags & dxBodyLinearDamping) { const dReal lin_threshold = b->dampingp.linear_threshold; const dReal lin_speed = dDOT( b->lvel, b->lvel ); if ( lin_speed > lin_threshold) { const dReal k = 1 - b->dampingp.linear_scale; dOPEC(b->lvel, *=, k); } } if (b->flags & dxBodyAngularDamping) { const dReal ang_threshold = b->dampingp.angular_threshold; const dReal ang_speed = dDOT( b->avel, b->avel ); if ( ang_speed > ang_threshold) { const dReal k = 1 - b->dampingp.angular_scale; dOPEC(b->avel, *=, k); } } } //**************************************************************************** // island processing // this groups all joints and bodies in a world into islands. all objects // in an island are reachable by going through connected bodies and joints. // each island can be simulated separately. // note that joints that are not attached to anything will not be included // in any island, an so they do not affect the simulation. // // this function starts new island from unvisited bodies. however, it will // never start a new islands from a disabled body. thus islands of disabled // bodies will not be included in the simulation. disabled bodies are // re-enabled if they are found to be part of an active island. void dxProcessIslands (dxWorld *world, dReal stepsize, dstepper_fn_t stepper) { dxBody *b,*bb,**body; dxJoint *j,**joint; // nothing to do if no bodies if (world->nb <= 0) return; // handle auto-disabling of bodies dInternalHandleAutoDisabling (world,stepsize); // make arrays for body and joint lists (for a single island) to go into body = (dxBody**) ALLOCA (world->nb * sizeof(dxBody*)); joint = (dxJoint**) ALLOCA (world->nj * sizeof(dxJoint*)); int bcount = 0; // number of bodies in `body' int jcount = 0; // number of joints in `joint' // set all body/joint tags to 0 for (b=world->firstbody; b; b=(dxBody*)b->next) b->tag = 0; for (j=world->firstjoint; j; j=(dxJoint*)j->next) j->tag = 0; // allocate a stack of unvisited bodies in the island. the maximum size of // the stack can be the lesser of the number of bodies or joints, because // new bodies are only ever added to the stack by going through untagged // joints. all the bodies in the stack must be tagged! int stackalloc = (world->nj < world->nb) ? world->nj : world->nb; dxBody **stack = (dxBody**) ALLOCA (stackalloc * sizeof(dxBody*)); for (bb=world->firstbody; bb; bb=(dxBody*)bb->next) { // get bb = the next enabled, untagged body, and tag it if (bb->tag || (bb->flags & dxBodyDisabled)) continue; bb->tag = 1; // tag all bodies and joints starting from bb. int stacksize = 0; b = bb; body[0] = bb; bcount = 1; jcount = 0; goto quickstart; while (stacksize > 0) { b = stack[--stacksize]; // pop body off stack body[bcount++] = b; // put body on body list quickstart: // traverse and tag all body's joints, add untagged connected bodies // to stack for (dxJointNode *n=b->firstjoint; n; n=n->next) { if (!n->joint->tag && n->joint->isEnabled()) { n->joint->tag = 1; joint[jcount++] = n->joint; if (n->body && !n->body->tag) { n->body->tag = 1; stack[stacksize++] = n->body; } } } dIASSERT(stacksize <= world->nb); dIASSERT(stacksize <= world->nj); } // now do something with body and joint lists stepper (world,body,bcount,joint,jcount,stepsize); // what we've just done may have altered the body/joint tag values. // we must make sure that these tags are nonzero. // also make sure all bodies are in the enabled state. int i; for (i=0; itag = 1; body[i]->flags &= ~dxBodyDisabled; } for (i=0; itag = 1; } // if debugging, check that all objects (except for disabled bodies, // unconnected joints, and joints that are connected to disabled bodies) // were tagged. # ifndef dNODEBUG for (b=world->firstbody; b; b=(dxBody*)b->next) { if (b->flags & dxBodyDisabled) { if (b->tag) dDebug (0,"disabled body tagged"); } else { if (!b->tag) dDebug (0,"enabled body not tagged"); } } for (j=world->firstjoint; j; j=(dxJoint*)j->next) { if ( (( j->node[0].body && (j->node[0].body->flags & dxBodyDisabled)==0 ) || (j->node[1].body && (j->node[1].body->flags & dxBodyDisabled)==0) ) && j->isEnabled() ) { if (!j->tag) dDebug (0,"attached enabled joint not tagged"); } else { if (j->tag) dDebug (0,"unattached or disabled joint tagged"); } } # endif } alien-arena-7.66+dfsg/source/unix/odesrc/obstack.h0000600000175000017500000000567712161402010021162 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_OBSTACK_H_ #define _ODE_OBSTACK_H_ #include "objects.h" // each obstack Arena pointer points to a block of this many bytes #define dOBSTACK_ARENA_SIZE 16384 struct dObStack : public dBase { struct Arena { Arena *next; // next arena in linked list size_t used; // total number of bytes used in this arena, counting }; // this header Arena *first; // head of the arena linked list. 0 if no arenas yet Arena *last; // arena where blocks are currently being allocated // used for iterator Arena *current_arena; size_t current_ofs; dObStack(); ~dObStack(); void *alloc (int num_bytes); // allocate a block in the last arena, allocating a new arena if necessary. // it is a runtime error if num_bytes is larger than the arena size. void freeAll(); // free all blocks in all arenas. this does not deallocate the arenas // themselves, so future alloc()s will reuse them. void *rewind(); // rewind the obstack iterator, and return the address of the first // allocated block. return 0 if there are no allocated blocks. void *next (int num_bytes); // return the address of the next allocated block. 'num_bytes' is the size // of the previous block. this returns null if there are no more arenas. // the sequence of 'num_bytes' parameters passed to next() during a // traversal of the list must exactly match the parameters passed to alloc(). }; #endif alien-arena-7.66+dfsg/source/unix/odesrc/fastltsolve.c0000600000175000017500000001160312161402010022057 0ustar zero79zero79/* generated code, do not edit. */ #include "ode/matrix.h" /* solve L^T * x=b, with b containing 1 right hand side. * L is an n*n lower triangular matrix with ones on the diagonal. * L is stored by rows and its leading dimension is lskip. * b is an n*1 matrix that contains the right hand side. * b is overwritten with x. * this processes blocks of 4. */ void dSolveL1T (const dReal *L, dReal *B, int n, int lskip1) { /* declare variables - Z matrix, p and q vectors, etc */ dReal Z11,m11,Z21,m21,Z31,m31,Z41,m41,p1,q1,p2,p3,p4,*ex; const dReal *ell; int lskip2,lskip3,i,j; /* special handling for L and B because we're solving L1 *transpose* */ L = L + (n-1)*(lskip1+1); B = B + n-1; lskip1 = -lskip1; /* compute lskip values */ lskip2 = 2*lskip1; lskip3 = 3*lskip1; /* compute all 4 x 1 blocks of X */ for (i=0; i <= n-4; i+=4) { /* compute all 4 x 1 block of X, from rows i..i+4-1 */ /* set the Z matrix to 0 */ Z11=0; Z21=0; Z31=0; Z41=0; ell = L - i; ex = B; /* the inner loop that computes outer products and adds them to Z */ for (j=i-4; j >= 0; j -= 4) { /* load p and q values */ p1=ell[0]; q1=ex[0]; p2=ell[-1]; p3=ell[-2]; p4=ell[-3]; /* compute outer product and add it to the Z matrix */ m11 = p1 * q1; m21 = p2 * q1; m31 = p3 * q1; m41 = p4 * q1; ell += lskip1; Z11 += m11; Z21 += m21; Z31 += m31; Z41 += m41; /* load p and q values */ p1=ell[0]; q1=ex[-1]; p2=ell[-1]; p3=ell[-2]; p4=ell[-3]; /* compute outer product and add it to the Z matrix */ m11 = p1 * q1; m21 = p2 * q1; m31 = p3 * q1; m41 = p4 * q1; ell += lskip1; Z11 += m11; Z21 += m21; Z31 += m31; Z41 += m41; /* load p and q values */ p1=ell[0]; q1=ex[-2]; p2=ell[-1]; p3=ell[-2]; p4=ell[-3]; /* compute outer product and add it to the Z matrix */ m11 = p1 * q1; m21 = p2 * q1; m31 = p3 * q1; m41 = p4 * q1; ell += lskip1; Z11 += m11; Z21 += m21; Z31 += m31; Z41 += m41; /* load p and q values */ p1=ell[0]; q1=ex[-3]; p2=ell[-1]; p3=ell[-2]; p4=ell[-3]; /* compute outer product and add it to the Z matrix */ m11 = p1 * q1; m21 = p2 * q1; m31 = p3 * q1; m41 = p4 * q1; ell += lskip1; ex -= 4; Z11 += m11; Z21 += m21; Z31 += m31; Z41 += m41; /* end of inner loop */ } /* compute left-over iterations */ j += 4; for (; j > 0; j--) { /* load p and q values */ p1=ell[0]; q1=ex[0]; p2=ell[-1]; p3=ell[-2]; p4=ell[-3]; /* compute outer product and add it to the Z matrix */ m11 = p1 * q1; m21 = p2 * q1; m31 = p3 * q1; m41 = p4 * q1; ell += lskip1; ex -= 1; Z11 += m11; Z21 += m21; Z31 += m31; Z41 += m41; } /* finish computing the X(i) block */ Z11 = ex[0] - Z11; ex[0] = Z11; p1 = ell[-1]; Z21 = ex[-1] - Z21 - p1*Z11; ex[-1] = Z21; p1 = ell[-2]; p2 = ell[-2+lskip1]; Z31 = ex[-2] - Z31 - p1*Z11 - p2*Z21; ex[-2] = Z31; p1 = ell[-3]; p2 = ell[-3+lskip1]; p3 = ell[-3+lskip2]; Z41 = ex[-3] - Z41 - p1*Z11 - p2*Z21 - p3*Z31; ex[-3] = Z41; /* end of outer loop */ } /* compute rows at end that are not a multiple of block size */ for (; i < n; i++) { /* compute all 1 x 1 block of X, from rows i..i+1-1 */ /* set the Z matrix to 0 */ Z11=0; ell = L - i; ex = B; /* the inner loop that computes outer products and adds them to Z */ for (j=i-4; j >= 0; j -= 4) { /* load p and q values */ p1=ell[0]; q1=ex[0]; /* compute outer product and add it to the Z matrix */ m11 = p1 * q1; ell += lskip1; Z11 += m11; /* load p and q values */ p1=ell[0]; q1=ex[-1]; /* compute outer product and add it to the Z matrix */ m11 = p1 * q1; ell += lskip1; Z11 += m11; /* load p and q values */ p1=ell[0]; q1=ex[-2]; /* compute outer product and add it to the Z matrix */ m11 = p1 * q1; ell += lskip1; Z11 += m11; /* load p and q values */ p1=ell[0]; q1=ex[-3]; /* compute outer product and add it to the Z matrix */ m11 = p1 * q1; ell += lskip1; ex -= 4; Z11 += m11; /* end of inner loop */ } /* compute left-over iterations */ j += 4; for (; j > 0; j--) { /* load p and q values */ p1=ell[0]; q1=ex[0]; /* compute outer product and add it to the Z matrix */ m11 = p1 * q1; ell += lskip1; ex -= 1; Z11 += m11; } /* finish computing the X(i) block */ Z11 = ex[0] - Z11; ex[0] = Z11; } } alien-arena-7.66+dfsg/source/unix/odesrc/util.h0000600000175000017500000000566012161402010020501 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_UTIL_H_ #define _ODE_UTIL_H_ #include "objects.h" /* the efficient alignment. most platforms align data structures to some * number of bytes, but this is not always the most efficient alignment. * for example, many x86 compilers align to 4 bytes, but on a pentium it * is important to align doubles to 8 byte boundaries (for speed), and * the 4 floats in a SIMD register to 16 byte boundaries. many other * platforms have similar behavior. setting a larger alignment can waste * a (very) small amount of memory. NOTE: this number must be a power of * two. this is set to 16 by default. */ #ifndef EFFICIENT_ALIGNMENT #define EFFICIENT_ALIGNMENT 16 #endif /* utility */ /* round something up to be a multiple of the EFFICIENT_ALIGNMENT */ #define dEFFICIENT_SIZE(x) ((((x)-1)|(EFFICIENT_ALIGNMENT-1))+1) /* alloca aligned to the EFFICIENT_ALIGNMENT. note that this can waste * up to 15 bytes per allocation, depending on what alloca() returns. */ #define dALLOCA16(n) \ ((char*)dEFFICIENT_SIZE(((size_t)(alloca((n)+(EFFICIENT_ALIGNMENT-1)))))) void dInternalHandleAutoDisabling (dxWorld *world, dReal stepsize); void dxStepBody (dxBody *b, dReal h); typedef void (*dstepper_fn_t) (dxWorld *world, dxBody * const *body, int nb, dxJoint * const *_joint, int nj, dReal stepsize); void dxProcessIslands (dxWorld *world, dReal stepsize, dstepper_fn_t stepper); #endif alien-arena-7.66+dfsg/source/unix/odesrc/collision_trimesh_trimesh.cpp0000600000175000017500000021441512161402010025340 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ // OPCODE TriMesh/TriMesh collision code by Jeff Smith (c) 2004 #ifdef _MSC_VER #pragma warning(disable:4244 4305) // for VC++, no precision loss complaints #endif #include #include #include #include #include "config.h" // Classic Implementation #if dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER #if dTRIMESH_ENABLED #include "collision_util.h" #include "collision_trimesh_internal.h" #if !dTLS_ENABLED // Have collider cache instance unconditionally of OPCODE or GIMPACT selection /*extern */TrimeshCollidersCache g_ccTrimeshCollidersCache; #endif #if dTRIMESH_OPCODE #define SMALL_ELT REAL(2.5e-4) #define EXPANDED_ELT_THRESH REAL(1.0e-3) #define DISTANCE_EPSILON REAL(1.0e-8) #define VELOCITY_EPSILON REAL(1.0e-5) #define TINY_PENETRATION REAL(5.0e-6) struct LineContactSet { enum { MAX_POINTS = 8 }; dVector3 Points[MAX_POINTS]; int Count; }; // static void GetTriangleGeometryCallback(udword, VertexPointers&, udword); -- not used static void GenerateContact(int, dContactGeom*, int, dxTriMesh*, dxTriMesh*, int TriIndex1, int TriIndex2, const dVector3, const dVector3, dReal, int&); static int TriTriIntersectWithIsectLine(dReal V0[3],dReal V1[3],dReal V2[3], dReal U0[3],dReal U1[3],dReal U2[3],int *coplanar, dReal isectpt1[3],dReal isectpt2[3]); inline void dMakeMatrix4(const dVector3 Position, const dMatrix3 Rotation, dMatrix4 &B); static void dInvertMatrix4( dMatrix4& B, dMatrix4& Binv ); //static int IntersectLineSegmentRay(dVector3, dVector3, dVector3, dVector3, dVector3); static bool FindTriSolidIntrsection(const dVector3 Tri[3], const dVector4 Planes[6], int numSides, LineContactSet& ClippedPolygon ); static void ClipConvexPolygonAgainstPlane( const dVector3, dReal, LineContactSet& ); static bool SimpleUnclippedTest(dVector3 in_CoplanarPt, dVector3 in_v, dVector3 in_elt, dVector3 in_n, dVector3* in_col_v, dReal &out_depth); static int ExamineContactPoint(dVector3* v_col, dVector3 in_n, dVector3 in_point); static int RayTriangleIntersect(const dVector3 orig, const dVector3 dir, const dVector3 vert0, const dVector3 vert1,const dVector3 vert2, dReal *t,dReal *u,dReal *v); /* some math macros */ #define IS_ZERO(v) (!(v)[0] && !(v)[1] && !(v)[2]) #define CROSS(dest,v1,v2) { dest[0]=v1[1]*v2[2]-v1[2]*v2[1]; \ dest[1]=v1[2]*v2[0]-v1[0]*v2[2]; \ dest[2]=v1[0]*v2[1]-v1[1]*v2[0]; } #define DOT(v1,v2) (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2]) #define SUB(dest,v1,v2) { dest[0]=v1[0]-v2[0]; dest[1]=v1[1]-v2[1]; dest[2]=v1[2]-v2[2]; } #define ADD(dest,v1,v2) { dest[0]=v1[0]+v2[0]; dest[1]=v1[1]+v2[1]; dest[2]=v1[2]+v2[2]; } #define MULT(dest,v,factor) { dest[0]=factor*v[0]; dest[1]=factor*v[1]; dest[2]=factor*v[2]; } #define SET(dest,src) { dest[0]=src[0]; dest[1]=src[1]; dest[2]=src[2]; } #define SMULT(p,q,s) { p[0]=q[0]*s; p[1]=q[1]*s; p[2]=q[2]*s; } #define COMBO(combo,p,t,q) { combo[0]=p[0]+t*q[0]; combo[1]=p[1]+t*q[1]; combo[2]=p[2]+t*q[2]; } #define LENGTH(x) ((dReal) dSqrt(dDOT(x, x))) #define DEPTH(d, p, q, n) d = (p[0] - q[0])*n[0] + (p[1] - q[1])*n[1] + (p[2] - q[2])*n[2]; inline const dReal dMin(const dReal x, const dReal y) { return x < y ? x : y; } inline void SwapNormals(dVector3 *&pen_v, dVector3 *&col_v, dVector3* v1, dVector3* v2, dVector3 *&pen_elt, dVector3 *elt_f1, dVector3 *elt_f2, dVector3 n, dVector3 n1, dVector3 n2) { if (pen_v == v1) { pen_v = v2; pen_elt = elt_f2; col_v = v1; SET(n, n1); } else { pen_v = v1; pen_elt = elt_f1; col_v = v2; SET(n, n2); } } int dCollideTTL(dxGeom* g1, dxGeom* g2, int Flags, dContactGeom* Contacts, int Stride) { dIASSERT (Stride >= (int)sizeof(dContactGeom)); dIASSERT (g1->type == dTriMeshClass); dIASSERT (g2->type == dTriMeshClass); dIASSERT ((Flags & NUMC_MASK) >= 1); dxTriMesh* TriMesh1 = (dxTriMesh*) g1; dxTriMesh* TriMesh2 = (dxTriMesh*) g2; dReal * TriNormals1 = (dReal *) TriMesh1->Data->Normals; dReal * TriNormals2 = (dReal *) TriMesh2->Data->Normals; const dVector3& TLPosition1 = *(const dVector3*) dGeomGetPosition(TriMesh1); // TLRotation1 = column-major order const dMatrix3& TLRotation1 = *(const dMatrix3*) dGeomGetRotation(TriMesh1); const dVector3& TLPosition2 = *(const dVector3*) dGeomGetPosition(TriMesh2); // TLRotation2 = column-major order const dMatrix3& TLRotation2 = *(const dMatrix3*) dGeomGetRotation(TriMesh2); const unsigned uiTLSKind = TriMesh1->getParentSpaceTLSKind(); dIASSERT(uiTLSKind == TriMesh2->getParentSpaceTLSKind()); // The colliding spaces must use matching cleanup method TrimeshCollidersCache *pccColliderCache = GetTrimeshCollidersCache(uiTLSKind); AABBTreeCollider& Collider = pccColliderCache->_AABBTreeCollider; BVTCache &ColCache = pccColliderCache->ColCache; ColCache.Model0 = &TriMesh1->Data->BVTree; ColCache.Model1 = &TriMesh2->Data->BVTree; // Collision query Matrix4x4 amatrix, bmatrix; BOOL IsOk = Collider.Collide(ColCache, &MakeMatrix(TLPosition1, TLRotation1, amatrix), &MakeMatrix(TLPosition2, TLRotation2, bmatrix) ); // Make "double" versions of these matrices, if appropriate dMatrix4 A, B; dMakeMatrix4(TLPosition1, TLRotation1, A); dMakeMatrix4(TLPosition2, TLRotation2, B); if (IsOk) { // Get collision status => if true, objects overlap if ( Collider.GetContactStatus() ) { // Number of colliding pairs and list of pairs int TriCount = Collider.GetNbPairs(); const Pair* CollidingPairs = Collider.GetPairs(); if (TriCount > 0) { // step through the pairs, adding contacts int id1, id2; int OutTriCount = 0; dVector3 v1[3], v2[3], CoplanarPt; dVector3 e1, e2, e3, n1, n2, n, ContactNormal; dReal depth; dVector3 orig_pos, old_pos1, old_pos2, elt1, elt2, elt_sum; dVector3 elt_f1[3], elt_f2[3]; dReal contact_elt_length = SMALL_ELT; LineContactSet firstClippedTri, secondClippedTri; dVector3 *firstClippedElt = new dVector3[LineContactSet::MAX_POINTS]; dVector3 *secondClippedElt = new dVector3[LineContactSet::MAX_POINTS]; // only do these expensive inversions once dMatrix4 InvMatrix1, InvMatrix2; dInvertMatrix4(A, InvMatrix1); dInvertMatrix4(B, InvMatrix2); for (int i = 0; i < TriCount; i++) { id1 = CollidingPairs[i].id0; id2 = CollidingPairs[i].id1; // grab the colliding triangles FetchTriangle((dxTriMesh*) g1, id1, TLPosition1, TLRotation1, v1); FetchTriangle((dxTriMesh*) g2, id2, TLPosition2, TLRotation2, v2); // Since we'll be doing matrix transfomrations, we need to // make sure that all vertices have four elements for (int j=0; j<3; j++) { v1[j][3] = 1.0; v2[j][3] = 1.0; } int IsCoplanar = 0; dReal IsectPt1[3], IsectPt2[3]; // Sometimes OPCODE makes mistakes, so we look at the return // value for TriTriIntersectWithIsectLine. A retcode of "0" // means no intersection took place if ( TriTriIntersectWithIsectLine( v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], &IsCoplanar, IsectPt1, IsectPt2) ) { // Compute the normals of the colliding faces // if (TriNormals1 == NULL) { SUB( e1, v1[1], v1[0] ); SUB( e2, v1[2], v1[0] ); CROSS( n1, e1, e2 ); dNormalize3(n1); } else { // If we were passed normals, we need to adjust them to take into // account the objects' current rotations e1[0] = TriNormals1[id1*3]; e1[1] = TriNormals1[id1*3 + 1]; e1[2] = TriNormals1[id1*3 + 2]; e1[3] = 0.0; //dMultiply1(n1, TLRotation1, e1, 3, 3, 1); dMultiply0(n1, TLRotation1, e1, 3, 3, 1); n1[3] = 1.0; } if (TriNormals2 == NULL) { SUB( e1, v2[1], v2[0] ); SUB( e2, v2[2], v2[0] ); CROSS( n2, e1, e2); dNormalize3(n2); } else { // If we were passed normals, we need to adjust them to take into // account the objects' current rotations e2[0] = TriNormals2[id2*3]; e2[1] = TriNormals2[id2*3 + 1]; e2[2] = TriNormals2[id2*3 + 2]; e2[3] = 0.0; //dMultiply1(n2, TLRotation2, e2, 3, 3, 1); dMultiply0(n2, TLRotation2, e2, 3, 3, 1); n2[3] = 1.0; } if (IsCoplanar) { // We can reach this case if the faces are coplanar, OR // if they don't actually intersect. (OPCODE can make // mistakes) if (dFabs(dDOT(n1, n2)) > REAL(0.999)) { // If the faces are coplanar, we declare that the point of // contact is at the average location of the vertices of // both faces dVector3 ContactPt; for (int j=0; j<3; j++) { ContactPt[j] = 0.0; for (int k=0; k<3; k++) ContactPt[j] += v1[k][j] + v2[k][j]; ContactPt[j] /= 6.0; } ContactPt[3] = 1.0; // and the contact normal is the normal of face 2 // (could be face 1, because they are the same) SET(n, n2); // and the penetration depth is the co-normal // distance between any two vertices A and B, // i.e. d = DOT(n, (A-B)) DEPTH(depth, v1[1], v2[1], n); if (depth < 0) depth *= -1.0; GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, ContactPt, n, depth, OutTriCount); } } else { // Otherwise (in non-co-planar cases), we create a coplanar // point -- the middle of the line of intersection -- that // will be used for various computations down the road for (int j=0; j<3; j++) CoplanarPt[j] = ( (IsectPt1[j] + IsectPt2[j]) / REAL(2.0) ); CoplanarPt[3] = 1.0; // Find the ELT of the coplanar point // dMultiply1(orig_pos, InvMatrix1, CoplanarPt, 4, 4, 1); dMultiply1(old_pos1, ((dxTriMesh*)g1)->last_trans, orig_pos, 4, 4, 1); SUB(elt1, CoplanarPt, old_pos1); dMultiply1(orig_pos, InvMatrix2, CoplanarPt, 4, 4, 1); dMultiply1(old_pos2, ((dxTriMesh*)g2)->last_trans, orig_pos, 4, 4, 1); SUB(elt2, CoplanarPt, old_pos2); SUB(elt_sum, elt1, elt2); // net motion of the coplanar point dReal elt_sum_len = LENGTH(elt_sum); // Could be calculated on demand but there is no good place... // Calculate how much the vertices of each face moved in the // direction of the opposite face's normal // dReal total_dp1, total_dp2; total_dp1 = 0.0; total_dp2 = 0.0; for (int ii=0; ii<3; ii++) { // find the estimated linear translation (ELT) of the vertices // on face 1, wrt to the center of face 2. // un-transform this vertex by the current transform dMultiply1(orig_pos, InvMatrix1, v1[ii], 4, 4, 1 ); // re-transform this vertex by last_trans (to get its old // position) dMultiply1(old_pos1, ((dxTriMesh*)g1)->last_trans, orig_pos, 4, 4, 1); // Then subtract this position from our current one to find // the elapsed linear translation (ELT) for (int k=0; k<3; k++) { elt_f1[ii][k] = (v1[ii][k] - old_pos1[k]) - elt2[k]; } // Take the dot product of the ELT for each vertex (wrt the // center of face2) total_dp1 += dFabs( dDOT(elt_f1[ii], n2) ); } for (int ii=0; ii<3; ii++) { // find the estimated linear translation (ELT) of the vertices // on face 2, wrt to the center of face 1. dMultiply1(orig_pos, InvMatrix2, v2[ii], 4, 4, 1); dMultiply1(old_pos2, ((dxTriMesh*)g2)->last_trans, orig_pos, 4, 4, 1); for (int k=0; k<3; k++) { elt_f2[ii][k] = (v2[ii][k] - old_pos2[k]) - elt1[k]; } // Take the dot product of the ELT for each vertex (wrt the // center of face2) and add them total_dp2 += dFabs( dDOT(elt_f2[ii], n1) ); } //////// // Estimate the penetration depth. // dReal dp; BOOL badPen = true; dVector3 *pen_v; // the "penetrating vertices" dVector3 *pen_elt; // the elt_f of the penetrating face dVector3 *col_v; // the "collision vertices" (the penetrated face) SMULT(n2, n2, -1.0); // SF PATCH #1335183 depth = 0.0; if ((total_dp1 > DISTANCE_EPSILON) || (total_dp2 > DISTANCE_EPSILON)) { //////// // Find the collision normal, by finding the face // that is pointed "most" in the direction of travel // of the two triangles // if (total_dp2 > total_dp1) { pen_v = v2; pen_elt = elt_f2; col_v = v1; SET(n, n1); } else { pen_v = v1; pen_elt = elt_f1; col_v = v2; SET(n, n2); } } else { // the total_dp is very small, so let's fall back // to a different test if (LENGTH(elt2) > LENGTH(elt1)) { pen_v = v2; pen_elt = elt_f2; col_v = v1; SET(n, n1); } else { pen_v = v1; pen_elt = elt_f1; col_v = v2; SET(n, n2); } } for (int j=0; j<3; j++) { if (SimpleUnclippedTest(CoplanarPt, pen_v[j], pen_elt[j], n, col_v, depth)) { GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, pen_v[j], n, depth, OutTriCount); badPen = false; if ((OutTriCount | CONTACTS_UNIMPORTANT) == (Flags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { break; } } } if (badPen) { // try the other normal SwapNormals(pen_v, col_v, v1, v2, pen_elt, elt_f1, elt_f2, n, n1, n2); for (int j=0; j<3; j++) if (SimpleUnclippedTest(CoplanarPt, pen_v[j], pen_elt[j], n, col_v, depth)) { GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, pen_v[j], n, depth, OutTriCount); badPen = false; if ((OutTriCount | CONTACTS_UNIMPORTANT) == (Flags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { break; } } } //////////////////////////////////////// // // If we haven't found a good penetration, then we're probably straddling // the edge of one of the objects, or the penetraing face is big // enough that all of its vertices are outside the bounds of the // penetrated face. // In these cases, we do a more expensive test. We clip the penetrating // triangle with a solid defined by the penetrated triangle, and repeat // the tests above on this new polygon if (badPen) { // Switch pen_v and n back again SwapNormals(pen_v, col_v, v1, v2, pen_elt, elt_f1, elt_f2, n, n1, n2); // Find the three sides (no top or bottom) of the solid defined by // the edges of the penetrated triangle. // The dVector4 "plane" structures contain the following information: // [0]-[2]: The normal of the face, pointing INWARDS (i.e. // the inverse normal // [3]: The distance between the face and the center of the // solid, along the normal dVector4 SolidPlanes[3]; dVector3 tmp1; dVector3 sn; for (int j=0; j<3; j++) { e1[j] = col_v[1][j] - col_v[0][j]; e2[j] = col_v[0][j] - col_v[2][j]; e3[j] = col_v[2][j] - col_v[1][j]; } // side 1 CROSS(sn, e1, n); dNormalize3(sn); SMULT( SolidPlanes[0], sn, -1.0 ); ADD(tmp1, col_v[0], col_v[1]); SMULT(tmp1, tmp1, 0.5); // center of edge // distance from center to edge along normal SolidPlanes[0][3] = dDOT(tmp1, SolidPlanes[0]); // side 2 CROSS(sn, e2, n); dNormalize3(sn); SMULT( SolidPlanes[1], sn, -1.0 ); ADD(tmp1, col_v[0], col_v[2]); SMULT(tmp1, tmp1, 0.5); // center of edge // distance from center to edge along normal SolidPlanes[1][3] = dDOT(tmp1, SolidPlanes[1]); // side 3 CROSS(sn, e3, n); dNormalize3(sn); SMULT( SolidPlanes[2], sn, -1.0 ); ADD(tmp1, col_v[2], col_v[1]); SMULT(tmp1, tmp1, 0.5); // center of edge // distance from center to edge along normal SolidPlanes[2][3] = dDOT(tmp1, SolidPlanes[2]); FindTriSolidIntrsection(pen_v, SolidPlanes, 3, firstClippedTri); for (int j=0; jlast_trans, orig_pos, 4, 4, 1); for (int k=0; k<3; k++) { firstClippedElt[j][k] = (firstClippedTri.Points[j][k] - old_pos1[k]) - elt2[k]; } } else { dMultiply1(orig_pos, InvMatrix2, firstClippedTri.Points[j], 4, 4, 1); dMultiply1(old_pos2, ((dxTriMesh*)g2)->last_trans, orig_pos, 4, 4, 1); for (int k=0; k<3; k++) { firstClippedElt[j][k] = (firstClippedTri.Points[j][k] - old_pos2[k]) - elt1[k]; } } if (dp >= 0.0) { contact_elt_length = dFabs(dDOT(firstClippedElt[j], n)); depth = dp; if (depth == 0.0) depth = dMin(DISTANCE_EPSILON, contact_elt_length); if ((contact_elt_length < SMALL_ELT) && (depth < EXPANDED_ELT_THRESH)) depth = contact_elt_length; if (depth <= contact_elt_length) { // Add a contact GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, firstClippedTri.Points[j], n, depth, OutTriCount); badPen = false; if ((OutTriCount | CONTACTS_UNIMPORTANT) == (Flags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { break; } } } } } if (badPen) { // Switch pen_v and n (again!) SwapNormals(pen_v, col_v, v1, v2, pen_elt, elt_f1, elt_f2, n, n1, n2); // Find the three sides (no top or bottom) of the solid created by // the penetrated triangle. // The dVector4 "plane" structures contain the following information: // [0]-[2]: The normal of the face, pointing INWARDS (i.e. // the inverse normal // [3]: The distance between the face and the center of the // solid, along the normal dVector4 SolidPlanes[3]; dVector3 tmp1; dVector3 sn; for (int j=0; j<3; j++) { e1[j] = col_v[1][j] - col_v[0][j]; e2[j] = col_v[0][j] - col_v[2][j]; e3[j] = col_v[2][j] - col_v[1][j]; } // side 1 CROSS(sn, e1, n); dNormalize3(sn); SMULT( SolidPlanes[0], sn, -1.0 ); ADD(tmp1, col_v[0], col_v[1]); SMULT(tmp1, tmp1, 0.5); // center of edge // distance from center to edge along normal SolidPlanes[0][3] = dDOT(tmp1, SolidPlanes[0]); // side 2 CROSS(sn, e2, n); dNormalize3(sn); SMULT( SolidPlanes[1], sn, -1.0 ); ADD(tmp1, col_v[0], col_v[2]); SMULT(tmp1, tmp1, 0.5); // center of edge // distance from center to edge along normal SolidPlanes[1][3] = dDOT(tmp1, SolidPlanes[1]); // side 3 CROSS(sn, e3, n); dNormalize3(sn); SMULT( SolidPlanes[2], sn, -1.0 ); ADD(tmp1, col_v[2], col_v[1]); SMULT(tmp1, tmp1, 0.5); // center of edge // distance from center to edge along normal SolidPlanes[2][3] = dDOT(tmp1, SolidPlanes[2]); FindTriSolidIntrsection(pen_v, SolidPlanes, 3, secondClippedTri); for (int j=0; jlast_trans, orig_pos, 4, 4, 1); for (int k=0; k<3; k++) { secondClippedElt[j][k] = (secondClippedTri.Points[j][k] - old_pos1[k]) - elt2[k]; } } else { dMultiply1(orig_pos, InvMatrix2, secondClippedTri.Points[j], 4, 4, 1); dMultiply1(old_pos2, ((dxTriMesh*)g2)->last_trans, orig_pos, 4, 4, 1); for (int k=0; k<3; k++) { secondClippedElt[j][k] = (secondClippedTri.Points[j][k] - old_pos2[k]) - elt1[k]; } } if (dp >= 0.0) { contact_elt_length = dFabs(dDOT(secondClippedElt[j],n)); depth = dp; if (depth == 0.0) depth = dMin(DISTANCE_EPSILON, contact_elt_length); if ((contact_elt_length < SMALL_ELT) && (depth < EXPANDED_ELT_THRESH)) depth = contact_elt_length; if (depth <= contact_elt_length) { // Add a contact GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, secondClippedTri.Points[j], n, depth, OutTriCount); badPen = false; if ((OutTriCount | CONTACTS_UNIMPORTANT) == (Flags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { break; } } } } } ///////////////// // All conventional tests have failed at this point, so now we deal with // cases on a more "heuristic" basis // if (badPen) { // Switch pen_v and n (for the fourth time, so they're // what my original guess said they were) SwapNormals(pen_v, col_v, v1, v2, pen_elt, elt_f1, elt_f2, n, n1, n2); if (dFabs(dDOT(n1, n2)) < REAL(0.01)) { // If we reach this point, we have (close to) perpindicular // faces, either resting on each other or sliding in a // direction orthogonal to both surface normals. if (elt_sum_len < DISTANCE_EPSILON) { depth = dFabs(dDOT(n, elt_sum)); if (depth > REAL(1e-12)) { dNormalize3(n); GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, CoplanarPt, n, depth, OutTriCount); badPen = false; } else { // If the two faces are (nearly) perfectly at rest with // respect to each other, then we ignore the contact, // allowing the objects to slip a little in the hopes // that next frame, they'll give us something to work // with. badPen = false; } } else { // The faces are perpindicular, but moving significantly // This can be sliding, or an unusual edge-straddling // penetration. dVector3 cn; CROSS(cn, n1, n2); dNormalize3(cn); SET(n, cn); // The shallowest ineterpenetration of the faces // is the depth dVector3 ContactPt; dVector3 dvTmp; dReal rTmp; depth = dInfinity; for (int j=0; j<3; j++) { for (int k=0; k<3; k++) { SUB(dvTmp, col_v[k], pen_v[j]); rTmp = dDOT(dvTmp, n); if ( dFabs(rTmp) < dFabs(depth) ) { depth = rTmp; SET( ContactPt, pen_v[j] ); contact_elt_length = dFabs(dDOT(pen_elt[j], n)); } } } if (depth < 0.0) { SMULT(n, n, -1.0); depth *= -1.0; } if ((depth > 0.0) && (depth <= contact_elt_length)) { GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, ContactPt, n, depth, OutTriCount); badPen = false; } } } } if (badPen && elt_sum_len != 0.0) { // Use as the normal the direction of travel, rather than any particular // face normal // dVector3 esn; if (pen_v == v1) { SMULT(esn, elt_sum, -1.0); } else { SET(esn, elt_sum); } dNormalize3(esn); // The shallowest ineterpenetration of the faces // is the depth dVector3 ContactPt; depth = dInfinity; for (int j=0; j<3; j++) { for (int k=0; k<3; k++) { DEPTH(dp, col_v[k], pen_v[j], esn); if ( (ExamineContactPoint(col_v, esn, pen_v[j])) && ( dFabs(dp) < dFabs(depth)) ) { depth = dp; SET( ContactPt, pen_v[j] ); contact_elt_length = dFabs(dDOT(pen_elt[j], esn)); } } } if ((depth > 0.0) && (depth <= contact_elt_length)) { GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, ContactPt, esn, depth, OutTriCount); badPen = false; } } if (badPen && elt_sum_len != 0.0) { // If the direction of motion is perpindicular to both normals if ( (dFabs(dDOT(n1, elt_sum)) < REAL(0.01)) && (dFabs(dDOT(n2, elt_sum)) < REAL(0.01)) ) { dVector3 esn; if (pen_v == v1) { SMULT(esn, elt_sum, -1.0); } else { SET(esn, elt_sum); } dNormalize3(esn); // Look at the clipped points again, checking them against this // new normal for (int j=0; j= 0.0) { contact_elt_length = dFabs(dDOT(firstClippedElt[j], esn)); depth = dp; //if (depth == 0.0) //depth = dMin(DISTANCE_EPSILON, contact_elt_length); if ((contact_elt_length < SMALL_ELT) && (depth < EXPANDED_ELT_THRESH)) depth = contact_elt_length; if (depth <= contact_elt_length) { // Add a contact GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, firstClippedTri.Points[j], esn, depth, OutTriCount); badPen = false; if ((OutTriCount | CONTACTS_UNIMPORTANT) == (Flags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { break; } } } } if (badPen) { // If this test failed, try it with the second set of clipped faces for (int j=0; j= 0.0) { contact_elt_length = dFabs(dDOT(secondClippedElt[j], esn)); depth = dp; //if (depth == 0.0) //depth = dMin(DISTANCE_EPSILON, contact_elt_length); if ((contact_elt_length < SMALL_ELT) && (depth < EXPANDED_ELT_THRESH)) depth = contact_elt_length; if (depth <= contact_elt_length) { // Add a contact GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, secondClippedTri.Points[j], esn, depth, OutTriCount); badPen = false; if ((OutTriCount | CONTACTS_UNIMPORTANT) == (Flags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { break; } } } } } } } if (badPen) { // if we have very little motion, we're dealing with resting contact // and shouldn't reference the ELTs at all // if (elt_sum_len < VELOCITY_EPSILON) { // instead of a "contact_elt_length" threshhold, we'll use an // arbitrary, small one for (int j=0; j<3; j++) { DEPTH(dp, CoplanarPt, pen_v[j], n); if (dp == 0.0) dp = TINY_PENETRATION; if ( (dp > 0.0) && (dp <= SMALL_ELT)) { // Add a contact GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, pen_v[j], n, dp, OutTriCount); badPen = false; if ((OutTriCount | CONTACTS_UNIMPORTANT) == (Flags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { break; } } } if (badPen) { // try the other normal SwapNormals(pen_v, col_v, v1, v2, pen_elt, elt_f1, elt_f2, n, n1, n2); for (int j=0; j<3; j++) { DEPTH(dp, CoplanarPt, pen_v[j], n); if (dp == 0.0) dp = TINY_PENETRATION; if ( (dp > 0.0) && (dp <= SMALL_ELT)) { GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, pen_v[j], n, dp, OutTriCount); badPen = false; if ((OutTriCount | CONTACTS_UNIMPORTANT) == (Flags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { break; } } } } } } if (badPen) { // find the nearest existing contact, and replicate it's // normal and depth // dContactGeom* Contact; dVector3 pos_diff; dReal min_dist, dist; min_dist = dInfinity; depth = 0.0; for (int j=0; jpos, CoplanarPt); dist = dDOT(pos_diff, pos_diff); if (dist < min_dist) { min_dist = dist; depth = Contact->depth; SMULT(ContactNormal, Contact->normal, -1.0); } } if (depth > 0.0) { // Add a tiny contact at the coplanar point GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, CoplanarPt, ContactNormal, depth, OutTriCount); badPen = false; } } if (badPen) { // Add a tiny contact at the coplanar point if (-dDOT(elt_sum, n1) > -dDOT(elt_sum, n2)) { SET(ContactNormal, n1); } else { SET(ContactNormal, n2); } GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, CoplanarPt, ContactNormal, TINY_PENETRATION, OutTriCount); badPen = false; } } // not coplanar (main loop) } // TriTriIntersectWithIsectLine if ((OutTriCount | CONTACTS_UNIMPORTANT) == (Flags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { break; } } // Free memory delete[] firstClippedElt; delete[] secondClippedElt; // Return the number of contacts return OutTriCount; } } } // There was some kind of failure during the Collide call or // there are no faces overlapping return 0; } /* -- not used static void GetTriangleGeometryCallback(udword triangleindex, VertexPointers& triangle, udword user_data) { dVector3 Out[3]; FetchTriangle((dxTriMesh*) user_data, (int) triangleindex, Out); for (int i = 0; i < 3; i++) triangle.Vertex[i] = (const Point*) ((dReal*) Out[i]); } */ // // // #define B11 B[0] #define B12 B[1] #define B13 B[2] #define B14 B[3] #define B21 B[4] #define B22 B[5] #define B23 B[6] #define B24 B[7] #define B31 B[8] #define B32 B[9] #define B33 B[10] #define B34 B[11] #define B41 B[12] #define B42 B[13] #define B43 B[14] #define B44 B[15] #define Binv11 Binv[0] #define Binv12 Binv[1] #define Binv13 Binv[2] #define Binv14 Binv[3] #define Binv21 Binv[4] #define Binv22 Binv[5] #define Binv23 Binv[6] #define Binv24 Binv[7] #define Binv31 Binv[8] #define Binv32 Binv[9] #define Binv33 Binv[10] #define Binv34 Binv[11] #define Binv41 Binv[12] #define Binv42 Binv[13] #define Binv43 Binv[14] #define Binv44 Binv[15] inline void dMakeMatrix4(const dVector3 Position, const dMatrix3 Rotation, dMatrix4 &B) { B11 = Rotation[0]; B21 = Rotation[1]; B31 = Rotation[2]; B41 = Position[0]; B12 = Rotation[4]; B22 = Rotation[5]; B32 = Rotation[6]; B42 = Position[1]; B13 = Rotation[8]; B23 = Rotation[9]; B33 = Rotation[10]; B43 = Position[2]; B14 = 0.0; B24 = 0.0; B34 = 0.0; B44 = 1.0; } static void dInvertMatrix4( dMatrix4& B, dMatrix4& Binv ) { dReal det = (B11 * B22 - B12 * B21) * (B33 * B44 - B34 * B43) -(B11 * B23 - B13 * B21) * (B32 * B44 - B34 * B42) +(B11 * B24 - B14 * B21) * (B32 * B43 - B33 * B42) +(B12 * B23 - B13 * B22) * (B31 * B44 - B34 * B41) -(B12 * B24 - B14 * B22) * (B31 * B43 - B33 * B41) +(B13 * B24 - B14 * B23) * (B31 * B42 - B32 * B41); dAASSERT (det != 0.0); det = 1.0 / det; Binv11 = (dReal) (det * ((B22 * B33) - (B23 * B32))); Binv12 = (dReal) (det * ((B32 * B13) - (B33 * B12))); Binv13 = (dReal) (det * ((B12 * B23) - (B13 * B22))); Binv14 = 0.0f; Binv21 = (dReal) (det * ((B23 * B31) - (B21 * B33))); Binv22 = (dReal) (det * ((B33 * B11) - (B31 * B13))); Binv23 = (dReal) (det * ((B13 * B21) - (B11 * B23))); Binv24 = 0.0f; Binv31 = (dReal) (det * ((B21 * B32) - (B22 * B31))); Binv32 = (dReal) (det * ((B31 * B12) - (B32 * B11))); Binv33 = (dReal) (det * ((B11 * B22) - (B12 * B21))); Binv34 = 0.0f; Binv41 = (dReal) (det * (B21*(B33*B42 - B32*B43) + B22*(B31*B43 - B33*B41) + B23*(B32*B41 - B31*B42))); Binv42 = (dReal) (det * (B31*(B13*B42 - B12*B43) + B32*(B11*B43 - B13*B41) + B33*(B12*B41 - B11*B42))); Binv43 = (dReal) (det * (B41*(B13*B22 - B12*B23) + B42*(B11*B23 - B13*B21) + B43*(B12*B21 - B11*B22))); Binv44 = 1.0f; } ///////////////////////////////////////////////// // // Triangle/Triangle intersection utilities // // From the article "A Fast Triangle-Triangle Intersection Test", // Journal of Graphics Tools, 2(2), 1997 // // Some of this functionality is duplicated in OPCODE (see // OPC_TriTriOverlap.h) but we have replicated it here so we don't // have to mess with the internals of OPCODE, as well as so we can // further optimize some of the functions. // // This version computes the line of intersection as well (if they // are not coplanar): // int TriTriIntersectWithIsectLine(dReal V0[3],dReal V1[3],dReal V2[3], // dReal U0[3],dReal U1[3],dReal U2[3], // int *coplanar, // dReal isectpt1[3],dReal isectpt2[3]); // // parameters: vertices of triangle 1: V0,V1,V2 // vertices of triangle 2: U0,U1,U2 // // result : returns 1 if the triangles intersect, otherwise 0 // "coplanar" returns whether the tris are coplanar // isectpt1, isectpt2 are the endpoints of the line of // intersection // /* if USE_EPSILON_TEST is true then we do a check: if |dv|b) \ { \ dReal c; \ c=a; \ a=b; \ b=c; \ } #define ISECT(VV0,VV1,VV2,D0,D1,D2,isect0,isect1) \ isect0=VV0+(VV1-VV0)*D0/(D0-D1); \ isect1=VV0+(VV2-VV0)*D0/(D0-D2); #define COMPUTE_INTERVALS(VV0,VV1,VV2,D0,D1,D2,D0D1,D0D2,isect0,isect1) \ if(D0D1>0.0f) \ { \ /* here we know that D0D2<=0.0 */ \ /* that is D0, D1 are on the same side, D2 on the other or on the plane */ \ ISECT(VV2,VV0,VV1,D2,D0,D1,isect0,isect1); \ } \ else if(D0D2>0.0f) \ { \ /* here we know that d0d1<=0.0 */ \ ISECT(VV1,VV0,VV2,D1,D0,D2,isect0,isect1); \ } \ else if(D1*D2>0.0f || D0!=0.0f) \ { \ /* here we know that d0d1<=0.0 or that D0!=0.0 */ \ ISECT(VV0,VV1,VV2,D0,D1,D2,isect0,isect1); \ } \ else if(D1!=0.0f) \ { \ ISECT(VV1,VV0,VV2,D1,D0,D2,isect0,isect1); \ } \ else if(D2!=0.0f) \ { \ ISECT(VV2,VV0,VV1,D2,D0,D1,isect0,isect1); \ } \ else \ { \ /* triangles are coplanar */ \ return coplanar_tri_tri(N1,V0,V1,V2,U0,U1,U2); \ } /* this edge to edge test is based on Franlin Antonio's gem: "Faster Line Segment Intersection", in Graphics Gems III, pp. 199-202 */ #define EDGE_EDGE_TEST(V0,U0,U1) \ Bx=U0[i0]-U1[i0]; \ By=U0[i1]-U1[i1]; \ Cx=V0[i0]-U0[i0]; \ Cy=V0[i1]-U0[i1]; \ f=Ay*Bx-Ax*By; \ d=By*Cx-Bx*Cy; \ if((f>0 && d>=0 && d<=f) || (f<0 && d<=0 && d>=f)) \ { \ e=Ax*Cy-Ay*Cx; \ if(f>0) \ { \ if(e>=0 && e<=f) return 1; \ } \ else \ { \ if(e<=0 && e>=f) return 1; \ } \ } #define EDGE_AGAINST_TRI_EDGES(V0,V1,U0,U1,U2) \ { \ dReal Ax,Ay,Bx,By,Cx,Cy,e,d,f; \ Ax=V1[i0]-V0[i0]; \ Ay=V1[i1]-V0[i1]; \ /* test edge U0,U1 against V0,V1 */ \ EDGE_EDGE_TEST(V0,U0,U1); \ /* test edge U1,U2 against V0,V1 */ \ EDGE_EDGE_TEST(V0,U1,U2); \ /* test edge U2,U1 against V0,V1 */ \ EDGE_EDGE_TEST(V0,U2,U0); \ } #define POINT_IN_TRI(V0,U0,U1,U2) \ { \ dReal a,b,c,d0,d1,d2; \ /* is T1 completly inside T2? */ \ /* check if V0 is inside tri(U0,U1,U2) */ \ a=U1[i1]-U0[i1]; \ b=-(U1[i0]-U0[i0]); \ c=-a*U0[i0]-b*U0[i1]; \ d0=a*V0[i0]+b*V0[i1]+c; \ \ a=U2[i1]-U1[i1]; \ b=-(U2[i0]-U1[i0]); \ c=-a*U1[i0]-b*U1[i1]; \ d1=a*V0[i0]+b*V0[i1]+c; \ \ a=U0[i1]-U2[i1]; \ b=-(U0[i0]-U2[i0]); \ c=-a*U2[i0]-b*U2[i1]; \ d2=a*V0[i0]+b*V0[i1]+c; \ if(d0*d1>0.0) \ { \ if(d0*d2>0.0) return 1; \ } \ } int coplanar_tri_tri(dReal N[3],dReal V0[3],dReal V1[3],dReal V2[3], dReal U0[3],dReal U1[3],dReal U2[3]) { dReal A[3]; short i0,i1; /* first project onto an axis-aligned plane, that maximizes the area */ /* of the triangles, compute indices: i0,i1. */ A[0]= dFabs(N[0]); A[1]= dFabs(N[1]); A[2]= dFabs(N[2]); if(A[0]>A[1]) { if(A[0]>A[2]) { i0=1; /* A[0] is greatest */ i1=2; } else { i0=0; /* A[2] is greatest */ i1=1; } } else /* A[0]<=A[1] */ { if(A[2]>A[1]) { i0=0; /* A[2] is greatest */ i1=1; } else { i0=0; /* A[1] is greatest */ i1=2; } } /* test all edges of triangle 1 against the edges of triangle 2 */ EDGE_AGAINST_TRI_EDGES(V0,V1,U0,U1,U2); EDGE_AGAINST_TRI_EDGES(V1,V2,U0,U1,U2); EDGE_AGAINST_TRI_EDGES(V2,V0,U0,U1,U2); /* finally, test if tri1 is totally contained in tri2 or vice versa */ POINT_IN_TRI(V0,U0,U1,U2); POINT_IN_TRI(U0,V0,V1,V2); return 0; } #define NEWCOMPUTE_INTERVALS(VV0,VV1,VV2,D0,D1,D2,D0D1,D0D2,A,B,C,X0,X1) \ { \ if(D0D1>0.0f) \ { \ /* here we know that D0D2<=0.0 */ \ /* that is D0, D1 are on the same side, D2 on the other or on the plane */ \ A=VV2; B=(VV0-VV2)*D2; C=(VV1-VV2)*D2; X0=D2-D0; X1=D2-D1; \ } \ else if(D0D2>0.0f)\ { \ /* here we know that d0d1<=0.0 */ \ A=VV1; B=(VV0-VV1)*D1; C=(VV2-VV1)*D1; X0=D1-D0; X1=D1-D2; \ } \ else if(D1*D2>0.0f || D0!=0.0f) \ { \ /* here we know that d0d1<=0.0 or that D0!=0.0 */ \ A=VV0; B=(VV1-VV0)*D0; C=(VV2-VV0)*D0; X0=D0-D1; X1=D0-D2; \ } \ else if(D1!=0.0f) \ { \ A=VV1; B=(VV0-VV1)*D1; C=(VV2-VV1)*D1; X0=D1-D0; X1=D1-D2; \ } \ else if(D2!=0.0f) \ { \ A=VV2; B=(VV0-VV2)*D2; C=(VV1-VV2)*D2; X0=D2-D0; X1=D2-D1; \ } \ else \ { \ /* triangles are coplanar */ \ return coplanar_tri_tri(N1,V0,V1,V2,U0,U1,U2); \ } \ } /* sort so that a<=b */ #define SORT2(a,b,smallest) \ if(a>b) \ { \ dReal c; \ c=a; \ a=b; \ b=c; \ smallest=1; \ } \ else smallest=0; inline void isect2(dReal VTX0[3],dReal VTX1[3],dReal VTX2[3],dReal VV0,dReal VV1,dReal VV2, dReal D0,dReal D1,dReal D2,dReal *isect0,dReal *isect1,dReal isectpoint0[3],dReal isectpoint1[3]) { dReal tmp=D0/(D0-D1); dReal diff[3]; *isect0=VV0+(VV1-VV0)*tmp; SUB(diff,VTX1,VTX0); MULT(diff,diff,tmp); ADD(isectpoint0,diff,VTX0); tmp=D0/(D0-D2); *isect1=VV0+(VV2-VV0)*tmp; SUB(diff,VTX2,VTX0); MULT(diff,diff,tmp); ADD(isectpoint1,VTX0,diff); } #if 0 #define ISECT2(VTX0,VTX1,VTX2,VV0,VV1,VV2,D0,D1,D2,isect0,isect1,isectpoint0,isectpoint1) \ tmp=D0/(D0-D1); \ isect0=VV0+(VV1-VV0)*tmp; \ SUB(diff,VTX1,VTX0); \ MULT(diff,diff,tmp); \ ADD(isectpoint0,diff,VTX0); \ tmp=D0/(D0-D2); /* isect1=VV0+(VV2-VV0)*tmp; \ */ /* SUB(diff,VTX2,VTX0); \ */ /* MULT(diff,diff,tmp); \ */ /* ADD(isectpoint1,VTX0,diff); */ #endif inline int compute_intervals_isectline(dReal VERT0[3],dReal VERT1[3],dReal VERT2[3], dReal VV0,dReal VV1,dReal VV2,dReal D0,dReal D1,dReal D2, dReal D0D1,dReal D0D2,dReal *isect0,dReal *isect1, dReal isectpoint0[3],dReal isectpoint1[3]) { if(D0D1>0.0f) { /* here we know that D0D2<=0.0 */ /* that is D0, D1 are on the same side, D2 on the other or on the plane */ isect2(VERT2,VERT0,VERT1,VV2,VV0,VV1,D2,D0,D1,isect0,isect1,isectpoint0,isectpoint1); } else if(D0D2>0.0f) { /* here we know that d0d1<=0.0 */ isect2(VERT1,VERT0,VERT2,VV1,VV0,VV2,D1,D0,D2,isect0,isect1,isectpoint0,isectpoint1); } else if(D1*D2>0.0f || D0!=0.0f) { /* here we know that d0d1<=0.0 or that D0!=0.0 */ isect2(VERT0,VERT1,VERT2,VV0,VV1,VV2,D0,D1,D2,isect0,isect1,isectpoint0,isectpoint1); } else if(D1!=0.0f) { isect2(VERT1,VERT0,VERT2,VV1,VV0,VV2,D1,D0,D2,isect0,isect1,isectpoint0,isectpoint1); } else if(D2!=0.0f) { isect2(VERT2,VERT0,VERT1,VV2,VV0,VV1,D2,D0,D1,isect0,isect1,isectpoint0,isectpoint1); } else { /* triangles are coplanar */ return 1; } return 0; } #define COMPUTE_INTERVALS_ISECTLINE(VERT0,VERT1,VERT2,VV0,VV1,VV2,D0,D1,D2,D0D1,D0D2,isect0,isect1,isectpoint0,isectpoint1) \ if(D0D1>0.0f) \ { \ /* here we know that D0D2<=0.0 */ \ /* that is D0, D1 are on the same side, D2 on the other or on the plane */ \ isect2(VERT2,VERT0,VERT1,VV2,VV0,VV1,D2,D0,D1,&isect0,&isect1,isectpoint0,isectpoint1); \ } #if 0 else if(D0D2>0.0f) \ { \ /* here we know that d0d1<=0.0 */ \ isect2(VERT1,VERT0,VERT2,VV1,VV0,VV2,D1,D0,D2,&isect0,&isect1,isectpoint0,isectpoint1); \ } \ else if(D1*D2>0.0f || D0!=0.0f) \ { \ /* here we know that d0d1<=0.0 or that D0!=0.0 */ \ isect2(VERT0,VERT1,VERT2,VV0,VV1,VV2,D0,D1,D2,&isect0,&isect1,isectpoint0,isectpoint1); \ } \ else if(D1!=0.0f) \ { \ isect2(VERT1,VERT0,VERT2,VV1,VV0,VV2,D1,D0,D2,&isect0,&isect1,isectpoint0,isectpoint1); \ } \ else if(D2!=0.0f) \ { \ isect2(VERT2,VERT0,VERT1,VV2,VV0,VV1,D2,D0,D1,&isect0,&isect1,isectpoint0,isectpoint1); \ } \ else \ { \ /* triangles are coplanar */ \ coplanar=1; \ return coplanar_tri_tri(N1,V0,V1,V2,U0,U1,U2); \ } #endif static int TriTriIntersectWithIsectLine(dReal V0[3],dReal V1[3],dReal V2[3], dReal U0[3],dReal U1[3],dReal U2[3],int *coplanar, dReal isectpt1[3],dReal isectpt2[3]) { dReal E1[3],E2[3]; dReal N1[3],N2[3],d1,d2; dReal du0,du1,du2,dv0,dv1,dv2; dReal D[3]; dReal isect1[2]={0,0}, isect2[2]={0,0}; dReal isectpointA1[3],isectpointA2[3]; dReal isectpointB1[3]={0,0,0},isectpointB2[3]={0,0,0}; dReal du0du1,du0du2,dv0dv1,dv0dv2; short index; dReal vp0,vp1,vp2; dReal up0,up1,up2; dReal b,c,max; int smallest1,smallest2; /* compute plane equation of triangle(V0,V1,V2) */ SUB(E1,V1,V0); SUB(E2,V2,V0); CROSS(N1,E1,E2); // Even though all triangles might be initially valid, // a triangle may degenerate into a segment after applying // space transformation. // // Oleh_Derevenko: // I'm not quite sure if this routine will fail/assert for zero normal // (it's too large and complex to be fully analyzed). // However in such a large code block three extra float comparisons // will not have any noticeable influence on performance. if (IS_ZERO(N1)) return 0; d1=-DOT(N1,V0); /* plane equation 1: N1.X+d1=0 */ /* put U0,U1,U2 into plane equation 1 to compute signed distances to the plane*/ du0=DOT(N1,U0)+d1; du1=DOT(N1,U1)+d1; du2=DOT(N1,U2)+d1; /* coplanarity robustness check */ #if USE_EPSILON_TEST==TRUE if(dFabs(du0)0.0f && du0du2>0.0f) /* same sign on all of them + not equal 0 ? */ return 0; /* no intersection occurs */ /* compute plane of triangle (U0,U1,U2) */ SUB(E1,U1,U0); SUB(E2,U2,U0); CROSS(N2,E1,E2); // Even though all triangles might be initially valid, // a triangle may degenerate into a segment after applying // space transformation. // // Oleh_Derevenko: // I'm not quite sure if this routine will fail/assert for zero normal // (it's too large and complex to be fully analyzed). // However in such a large code block three extra float comparisons // will not have any noticeable influence on performance. if (IS_ZERO(N2)) return 0; d2=-DOT(N2,U0); /* plane equation 2: N2.X+d2=0 */ /* put V0,V1,V2 into plane equation 2 */ dv0=DOT(N2,V0)+d2; dv1=DOT(N2,V1)+d2; dv2=DOT(N2,V2)+d2; #if USE_EPSILON_TEST==TRUE if(dFabs(dv0)0.0f && dv0dv2>0.0f) /* same sign on all of them + not equal 0 ? */ return 0; /* no intersection occurs */ /* compute direction of intersection line */ CROSS(D,N1,N2); /* compute and index to the largest component of D */ max= dFabs(D[0]); index=0; b= dFabs(D[1]); c= dFabs(D[2]); if(b>max) max=b,index=1; if(c>max) max=c,index=2; /* this is the simplified projection onto L*/ vp0=V0[index]; vp1=V1[index]; vp2=V2[index]; up0=U0[index]; up1=U1[index]; up2=U2[index]; /* compute interval for triangle 1 */ *coplanar=compute_intervals_isectline(V0,V1,V2,vp0,vp1,vp2,dv0,dv1,dv2, dv0dv1,dv0dv2,&isect1[0],&isect1[1],isectpointA1,isectpointA2); if(*coplanar) return coplanar_tri_tri(N1,V0,V1,V2,U0,U1,U2); /* compute interval for triangle 2 */ compute_intervals_isectline(U0,U1,U2,up0,up1,up2,du0,du1,du2, du0du1,du0du2,&isect2[0],&isect2[1],isectpointB1,isectpointB2); SORT2(isect1[0],isect1[1],smallest1); SORT2(isect2[0],isect2[1],smallest2); if(isect1[1]isect1[1]) { if(smallest1==0) { SET(isectpt2,isectpointA2); } else { SET(isectpt2,isectpointA1); } } else { if(smallest2==0) { SET(isectpt2,isectpointB2); } else { SET(isectpt2,isectpointB1); } } } return 1; } // Find the intersectiojn point between a coplanar line segement, // defined by X1 and X2, and a ray defined by X3 and direction N. // // This forumla for this calculation is: // (c x b) . (a x b) // Q = x1 + a ------------------- // | a x b | ^2 // // where a = x2 - x1 // b = x4 - x3 // c = x3 - x1 // x1 and x2 are the edges of the triangle, and x3 is CoplanarPt // and x4 is (CoplanarPt - n) #if 0 // not used anywhere static int IntersectLineSegmentRay(dVector3 x1, dVector3 x2, dVector3 x3, dVector3 n, dVector3 out_pt) { dVector3 a, b, c, x4; ADD(x4, x3, n); // x4 = x3 + n SUB(a, x2, x1); // a = x2 - x1 SUB(b, x4, x3); SUB(c, x3, x1); dVector3 tmp1, tmp2; CROSS(tmp1, c, b); CROSS(tmp2, a, b); dReal num, denom; num = dDOT(tmp1, tmp2); denom = LENGTH( tmp2 ); dReal s; s = num /(denom*denom); for (int i=0; i<3; i++) out_pt[i] = x1[i] + a[i]*s; // Test if this intersection is "behind" x3, w.r.t. n SUB(a, x3, out_pt); if (dDOT(a, n) > 0.0) return 0; // Test if this intersection point is outside the edge limits, // if (dot( (out_pt-x1), (out_pt-x2) ) < 0) it's inside // else outside SUB(a, out_pt, x1); SUB(b, out_pt, x2); if (dDOT(a,b) < 0.0) return 1; else return 0; } #endif // FindTriSolidIntersection - Clips the input trinagle TRI with the // sides of a convex bounding solid, described by PLANES, returning // the (convex) clipped polygon in CLIPPEDPOLYGON // static bool FindTriSolidIntrsection(const dVector3 Tri[3], const dVector4 Planes[6], int numSides, LineContactSet& ClippedPolygon ) { // Set up the LineContactSet structure for (int k=0; k<3; k++) { SET(ClippedPolygon.Points[k], Tri[k]); } ClippedPolygon.Count = 3; // Clip wrt the sides for ( int i = 0; i < numSides; i++ ) ClipConvexPolygonAgainstPlane( Planes[i], Planes[i][3], ClippedPolygon ); return (ClippedPolygon.Count > 0); } // ClipConvexPolygonAgainstPlane - Clip a a convex polygon, described by // CONTACTS, with a plane (described by N and C). Note: the input // vertices are assumed to be in counterclockwise order. // // This code is taken from The Nebula Device: // http://nebuladevice.sourceforge.net/cgi-bin/twiki/view/Nebula/WebHome // and is licensed under the following license: // http://nebuladevice.sourceforge.net/doc/source/license.txt // static void ClipConvexPolygonAgainstPlane( const dVector3 N, dReal C, LineContactSet& Contacts ) { // test on which side of line are the vertices int Positive = 0, Negative = 0, PIndex = -1; int Quantity = Contacts.Count; dReal Test[8]; for ( int i = 0; i < Contacts.Count; i++ ) { // An epsilon is used here because it is possible for the dot product // and C to be exactly equal to each other (in theory), but differ // slightly because of floating point problems. Thus, add a little // to the test number to push actually equal numbers over the edge // towards the positive. This should probably be somehow a relative // tolerance, and I don't think multiplying by the constant is the best // way to do this. Test[i] = dDOT(N, Contacts.Points[i]) - C + dFabs(C)*REAL(1e-08); if (Test[i] >= REAL(0.0)) { Positive++; if (PIndex < 0) { PIndex = i; } } else Negative++; } if (Positive > 0) { if (Negative > 0) { // plane transversely intersects polygon dVector3 CV[8]; int CQuantity = 0, Cur, Prv; dReal T; if (PIndex > 0) { // first clip vertex on line Cur = PIndex; Prv = Cur - 1; T = Test[Cur] / (Test[Cur] - Test[Prv]); CV[CQuantity][0] = Contacts.Points[Cur][0] + T * (Contacts.Points[Prv][0] - Contacts.Points[Cur][0]); CV[CQuantity][1] = Contacts.Points[Cur][1] + T * (Contacts.Points[Prv][1] - Contacts.Points[Cur][1]); CV[CQuantity][2] = Contacts.Points[Cur][2] + T * (Contacts.Points[Prv][2] - Contacts.Points[Cur][2]); CV[CQuantity][3] = Contacts.Points[Cur][3] + T * (Contacts.Points[Prv][3] - Contacts.Points[Cur][3]); CQuantity++; // vertices on positive side of line while (Cur < Quantity && Test[Cur] >= REAL(0.0)) { CV[CQuantity][0] = Contacts.Points[Cur][0]; CV[CQuantity][1] = Contacts.Points[Cur][1]; CV[CQuantity][2] = Contacts.Points[Cur][2]; CV[CQuantity][3] = Contacts.Points[Cur][3]; CQuantity++; Cur++; } // last clip vertex on line if (Cur < Quantity) { Prv = Cur - 1; } else { Cur = 0; Prv = Quantity - 1; } T = Test[Cur] / (Test[Cur] - Test[Prv]); CV[CQuantity][0] = Contacts.Points[Cur][0] + T * (Contacts.Points[Prv][0] - Contacts.Points[Cur][0]); CV[CQuantity][1] = Contacts.Points[Cur][1] + T * (Contacts.Points[Prv][1] - Contacts.Points[Cur][1]); CV[CQuantity][2] = Contacts.Points[Cur][2] + T * (Contacts.Points[Prv][2] - Contacts.Points[Cur][2]); CV[CQuantity][3] = Contacts.Points[Cur][3] + T * (Contacts.Points[Prv][3] - Contacts.Points[Cur][3]); CQuantity++; } else { // iPIndex is 0 // vertices on positive side of line Cur = 0; while (Cur < Quantity && Test[Cur] >= REAL(0.0)) { CV[CQuantity][0] = Contacts.Points[Cur][0]; CV[CQuantity][1] = Contacts.Points[Cur][1]; CV[CQuantity][2] = Contacts.Points[Cur][2]; CV[CQuantity][3] = Contacts.Points[Cur][3]; CQuantity++; Cur++; } // last clip vertex on line Prv = Cur - 1; T = Test[Cur] / (Test[Cur] - Test[Prv]); CV[CQuantity][0] = Contacts.Points[Cur][0] + T * (Contacts.Points[Prv][0] - Contacts.Points[Cur][0]); CV[CQuantity][1] = Contacts.Points[Cur][1] + T * (Contacts.Points[Prv][1] - Contacts.Points[Cur][1]); CV[CQuantity][2] = Contacts.Points[Cur][2] + T * (Contacts.Points[Prv][2] - Contacts.Points[Cur][2]); CV[CQuantity][3] = Contacts.Points[Cur][3] + T * (Contacts.Points[Prv][3] - Contacts.Points[Cur][3]); CQuantity++; // skip vertices on negative side while (Cur < Quantity && Test[Cur] < REAL(0.0)) { Cur++; } // first clip vertex on line if (Cur < Quantity) { Prv = Cur - 1; T = Test[Cur] / (Test[Cur] - Test[Prv]); CV[CQuantity][0] = Contacts.Points[Cur][0] + T * (Contacts.Points[Prv][0] - Contacts.Points[Cur][0]); CV[CQuantity][1] = Contacts.Points[Cur][1] + T * (Contacts.Points[Prv][1] - Contacts.Points[Cur][1]); CV[CQuantity][2] = Contacts.Points[Cur][2] + T * (Contacts.Points[Prv][2] - Contacts.Points[Cur][2]); CV[CQuantity][3] = Contacts.Points[Cur][3] + T * (Contacts.Points[Prv][3] - Contacts.Points[Cur][3]); CQuantity++; // vertices on positive side of line while (Cur < Quantity && Test[Cur] >= REAL(0.0)) { CV[CQuantity][0] = Contacts.Points[Cur][0]; CV[CQuantity][1] = Contacts.Points[Cur][1]; CV[CQuantity][2] = Contacts.Points[Cur][2]; CV[CQuantity][3] = Contacts.Points[Cur][3]; CQuantity++; Cur++; } } else { // iCur = 0 Prv = Quantity - 1; T = Test[0] / (Test[0] - Test[Prv]); CV[CQuantity][0] = Contacts.Points[0][0] + T * (Contacts.Points[Prv][0] - Contacts.Points[0][0]); CV[CQuantity][1] = Contacts.Points[0][1] + T * (Contacts.Points[Prv][1] - Contacts.Points[0][1]); CV[CQuantity][2] = Contacts.Points[0][2] + T * (Contacts.Points[Prv][2] - Contacts.Points[0][2]); CV[CQuantity][3] = Contacts.Points[0][3] + T * (Contacts.Points[Prv][3] - Contacts.Points[0][3]); CQuantity++; } } Quantity = CQuantity; memcpy( Contacts.Points, CV, CQuantity * sizeof(dVector3) ); } // else polygon fully on positive side of plane, nothing to do Contacts.Count = Quantity; } else { Contacts.Count = 0; // This should not happen, but for safety } } // Determine if a potential collision point is // // static int ExamineContactPoint(dVector3* v_col, dVector3 in_n, dVector3 in_point) { // Cast a ray from in_point, along the collison normal. Does it intersect the // collision face. dReal t, u, v; if (!RayTriangleIntersect(in_point, in_n, v_col[0], v_col[1], v_col[2], &t, &u, &v)) return 0; else return 1; } // RayTriangleIntersect - If an intersection is found, t contains the // distance along the ray (dir) and u/v contain u/v coordinates into // the triangle. Returns 0 if no hit is found // From "Real-Time Rendering," page 305 // static int RayTriangleIntersect(const dVector3 orig, const dVector3 dir, const dVector3 vert0, const dVector3 vert1,const dVector3 vert2, dReal *t,dReal *u,dReal *v) { dReal edge1[3], edge2[3], tvec[3], pvec[3], qvec[3]; dReal det,inv_det; // find vectors for two edges sharing vert0 SUB(edge1, vert1, vert0); SUB(edge2, vert2, vert0); // begin calculating determinant - also used to calculate U parameter CROSS(pvec, dir, edge2); // if determinant is near zero, ray lies in plane of triangle det = DOT(edge1, pvec); if ((det > REAL(-0.001)) && (det < REAL(0.001))) return 0; inv_det = 1.0 / det; // calculate distance from vert0 to ray origin SUB(tvec, orig, vert0); // calculate U parameter and test bounds *u = DOT(tvec, pvec) * inv_det; if ((*u < 0.0) || (*u > 1.0)) return 0; // prepare to test V parameter CROSS(qvec, tvec, edge1); // calculate V parameter and test bounds *v = DOT(dir, qvec) * inv_det; if ((*v < 0.0) || ((*u + *v) > 1.0)) return 0; // calculate t, ray intersects triangle *t = DOT(edge2, qvec) * inv_det; return 1; } static bool SimpleUnclippedTest(dVector3 in_CoplanarPt, dVector3 in_v, dVector3 in_elt, dVector3 in_n, dVector3* in_col_v, dReal &out_depth) { dReal dp = 0.0; dReal contact_elt_length; DEPTH(dp, in_CoplanarPt, in_v, in_n); if (dp >= 0.0) { // if the penetration depth (calculated above) is more than // the contact point's ELT, then we've chosen the wrong face // and should switch faces contact_elt_length = dFabs(dDOT(in_elt, in_n)); if (dp == 0.0) dp = dMin(DISTANCE_EPSILON, contact_elt_length); if ((contact_elt_length < SMALL_ELT) && (dp < EXPANDED_ELT_THRESH)) dp = contact_elt_length; if ( (dp > 0.0) && (dp <= contact_elt_length)) { // Add a contact if ( ExamineContactPoint(in_col_v, in_n, in_v) ) { out_depth = dp; return true; } } } return false; } // Generate a "unique" contact. A unique contact has a unique // position or normal. If the potential contact has the same // position and normal as an existing contact, but a larger // penetration depth, this new depth is used instead // static void GenerateContact(int in_Flags, dContactGeom* in_Contacts, int in_Stride, dxTriMesh* in_TriMesh1, dxTriMesh* in_TriMesh2, int TriIndex1, int TriIndex2, const dVector3 in_ContactPos, const dVector3 in_Normal, dReal in_Depth, int& OutTriCount) { /* NOTE by Oleh_Derevenko: This function is called after maximal number of contacts has already been collected because it has a side effect of replacing penetration depth of existing contact with larger penetration depth of another matching normal contact. If this logic is not necessary any more, you can bail out on reach of contact number maximum immediately in dCollideTTL(). You will also need to correct conditional statements after invocations of GenerateContact() in dCollideTTL(). */ dIASSERT(in_Depth >= 0.0); //if (in_Depth < 0.0) -- the function is always called with depth >= 0 // return; do { dContactGeom* Contact; dVector3 diff; if (!(in_Flags & CONTACTS_UNIMPORTANT)) { bool duplicate = false; for (int i=0; ipos); if (dDOT(diff, diff) < dEpsilon) { // same normal? if (dFabs(dDOT(in_Normal, Contact->normal)) > (REAL(1.0)-dEpsilon)) { if (in_Depth > Contact->depth) { Contact->depth = in_Depth; SMULT( Contact->normal, in_Normal, -1.0); Contact->normal[3] = 0.0; } duplicate = true; /* NOTE by Oleh_Derevenko: There may be a case when two normals are close to each other but no duplicate while third normal is detected to be duplicate for both of them. This is the only reason I can think of, there is no "break" statement. Perhaps author considered it to be logical that the third normal would replace the depth in both of initial contacts. However, I consider it a questionable practice which should not be applied without deep understanding of underlaying physics. Even more, is this situation with close normal triplet acceptable at all? Should not be two initial contacts reduced to one (replaced with the latter)? If you know the answers for these questions, you may want to change this code. See the same statement in GenerateContact() of collision_trimesh_box.cpp */ } } } if (duplicate || OutTriCount == (in_Flags & NUMC_MASK)) { break; } } else { dIASSERT(OutTriCount < (in_Flags & NUMC_MASK)); } // Add a new contact Contact = SAFECONTACT(in_Flags, in_Contacts, OutTriCount, in_Stride); SET( Contact->pos, in_ContactPos ); Contact->pos[3] = 0.0; SMULT( Contact->normal, in_Normal, -1.0); Contact->normal[3] = 0.0; Contact->depth = in_Depth; Contact->g1 = in_TriMesh1; Contact->g2 = in_TriMesh2; Contact->side1 = TriIndex1; Contact->side2 = TriIndex2; OutTriCount++; } while (false); } #endif // dTRIMESH_OPCODE #endif // dTRIMESH_USE_OLD_TRIMESH_TRIMESH_COLLIDER #endif // dTRIMESH_ENABLED alien-arena-7.66+dfsg/source/unix/odesrc/ray.cpp0000600000175000017500000005330712161402010020653 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* standard ODE geometry primitives: public API and pairwise collision functions. the rule is that only the low level primitive collision functions should set dContactGeom::g1 and dContactGeom::g2. */ #include #include #include #include #include #include "collision_kernel.h" #include "collision_std.h" #include "collision_util.h" #ifdef _MSC_VER #pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" #endif //**************************************************************************** // ray public API dxRay::dxRay (dSpaceID space, dReal _length) : dxGeom (space,1) { type = dRayClass; length = _length; } void dxRay::computeAABB() { dVector3 e; e[0] = final_posr->pos[0] + final_posr->R[0*4+2]*length; e[1] = final_posr->pos[1] + final_posr->R[1*4+2]*length; e[2] = final_posr->pos[2] + final_posr->R[2*4+2]*length; if (final_posr->pos[0] < e[0]){ aabb[0] = final_posr->pos[0]; aabb[1] = e[0]; } else{ aabb[0] = e[0]; aabb[1] = final_posr->pos[0]; } if (final_posr->pos[1] < e[1]){ aabb[2] = final_posr->pos[1]; aabb[3] = e[1]; } else{ aabb[2] = e[1]; aabb[3] = final_posr->pos[1]; } if (final_posr->pos[2] < e[2]){ aabb[4] = final_posr->pos[2]; aabb[5] = e[2]; } else{ aabb[4] = e[2]; aabb[5] = final_posr->pos[2]; } } dGeomID dCreateRay (dSpaceID space, dReal length) { return new dxRay (space,length); } void dGeomRaySetLength (dGeomID g, dReal length) { dUASSERT (g && g->type == dRayClass,"argument not a ray"); dxRay *r = (dxRay*) g; r->length = length; dGeomMoved (g); } dReal dGeomRayGetLength (dGeomID g) { dUASSERT (g && g->type == dRayClass,"argument not a ray"); dxRay *r = (dxRay*) g; return r->length; } void dGeomRaySet (dGeomID g, dReal px, dReal py, dReal pz, dReal dx, dReal dy, dReal dz) { dUASSERT (g && g->type == dRayClass,"argument not a ray"); g->recomputePosr(); dReal* rot = g->final_posr->R; dReal* pos = g->final_posr->pos; dVector3 n; pos[0] = px; pos[1] = py; pos[2] = pz; n[0] = dx; n[1] = dy; n[2] = dz; dNormalize3(n); rot[0*4+2] = n[0]; rot[1*4+2] = n[1]; rot[2*4+2] = n[2]; dGeomMoved (g); } void dGeomRayGet (dGeomID g, dVector3 start, dVector3 dir) { dUASSERT (g && g->type == dRayClass,"argument not a ray"); g->recomputePosr(); start[0] = g->final_posr->pos[0]; start[1] = g->final_posr->pos[1]; start[2] = g->final_posr->pos[2]; dir[0] = g->final_posr->R[0*4+2]; dir[1] = g->final_posr->R[1*4+2]; dir[2] = g->final_posr->R[2*4+2]; } void dGeomRaySetParams (dxGeom *g, int FirstContact, int BackfaceCull) { dUASSERT (g && g->type == dRayClass,"argument not a ray"); if (FirstContact){ g->gflags |= RAY_FIRSTCONTACT; } else g->gflags &= ~RAY_FIRSTCONTACT; if (BackfaceCull){ g->gflags |= RAY_BACKFACECULL; } else g->gflags &= ~RAY_BACKFACECULL; } void dGeomRayGetParams (dxGeom *g, int *FirstContact, int *BackfaceCull) { dUASSERT (g && g->type == dRayClass,"argument not a ray"); (*FirstContact) = ((g->gflags & RAY_FIRSTCONTACT) != 0); (*BackfaceCull) = ((g->gflags & RAY_BACKFACECULL) != 0); } void dGeomRaySetClosestHit (dxGeom *g, int closestHit) { dUASSERT (g && g->type == dRayClass,"argument not a ray"); if (closestHit){ g->gflags |= RAY_CLOSEST_HIT; } else g->gflags &= ~RAY_CLOSEST_HIT; } int dGeomRayGetClosestHit (dxGeom *g) { dUASSERT (g && g->type == dRayClass,"argument not a ray"); return ((g->gflags & RAY_CLOSEST_HIT) != 0); } // if mode==1 then use the sphere exit contact, not the entry contact static int ray_sphere_helper (dxRay *ray, dVector3 sphere_pos, dReal radius, dContactGeom *contact, int mode) { dVector3 q; q[0] = ray->final_posr->pos[0] - sphere_pos[0]; q[1] = ray->final_posr->pos[1] - sphere_pos[1]; q[2] = ray->final_posr->pos[2] - sphere_pos[2]; dReal B = dDOT14(q,ray->final_posr->R+2); dReal C = dDOT(q,q) - radius*radius; // note: if C <= 0 then the start of the ray is inside the sphere dReal k = B*B - C; if (k < 0) return 0; k = dSqrt(k); dReal alpha; if (mode && C >= 0) { alpha = -B + k; if (alpha < 0) return 0; } else { alpha = -B - k; if (alpha < 0) { alpha = -B + k; if (alpha < 0) return 0; } } if (alpha > ray->length) return 0; contact->pos[0] = ray->final_posr->pos[0] + alpha*ray->final_posr->R[0*4+2]; contact->pos[1] = ray->final_posr->pos[1] + alpha*ray->final_posr->R[1*4+2]; contact->pos[2] = ray->final_posr->pos[2] + alpha*ray->final_posr->R[2*4+2]; dReal nsign = (C < 0 || mode) ? REAL(-1.0) : REAL(1.0); contact->normal[0] = nsign*(contact->pos[0] - sphere_pos[0]); contact->normal[1] = nsign*(contact->pos[1] - sphere_pos[1]); contact->normal[2] = nsign*(contact->pos[2] - sphere_pos[2]); dNormalize3 (contact->normal); contact->depth = alpha; return 1; } int dCollideRaySphere (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT (o1->type == dRayClass); dIASSERT (o2->type == dSphereClass); dIASSERT ((flags & NUMC_MASK) >= 1); dxRay *ray = (dxRay*) o1; dxSphere *sphere = (dxSphere*) o2; contact->g1 = ray; contact->g2 = sphere; contact->side1 = -1; contact->side2 = -1; return ray_sphere_helper (ray,sphere->final_posr->pos,sphere->radius,contact,0); } int dCollideRayBox (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT (o1->type == dRayClass); dIASSERT (o2->type == dBoxClass); dIASSERT ((flags & NUMC_MASK) >= 1); dxRay *ray = (dxRay*) o1; dxBox *box = (dxBox*) o2; contact->g1 = ray; contact->g2 = box; contact->side1 = -1; contact->side2 = -1; int i; // compute the start and delta of the ray relative to the box. // we will do all subsequent computations in this box-relative coordinate // system. we have to do a translation and rotation for each point. dVector3 tmp,s,v; tmp[0] = ray->final_posr->pos[0] - box->final_posr->pos[0]; tmp[1] = ray->final_posr->pos[1] - box->final_posr->pos[1]; tmp[2] = ray->final_posr->pos[2] - box->final_posr->pos[2]; dMULTIPLY1_331 (s,box->final_posr->R,tmp); tmp[0] = ray->final_posr->R[0*4+2]; tmp[1] = ray->final_posr->R[1*4+2]; tmp[2] = ray->final_posr->R[2*4+2]; dMULTIPLY1_331 (v,box->final_posr->R,tmp); // mirror the line so that v has all components >= 0 dVector3 sign; for (i=0; i<3; i++) { if (v[i] < 0) { s[i] = -s[i]; v[i] = -v[i]; sign[i] = 1; } else sign[i] = -1; } // compute the half-sides of the box dReal h[3]; h[0] = REAL(0.5) * box->side[0]; h[1] = REAL(0.5) * box->side[1]; h[2] = REAL(0.5) * box->side[2]; // do a few early exit tests if ((s[0] < -h[0] && v[0] <= 0) || s[0] > h[0] || (s[1] < -h[1] && v[1] <= 0) || s[1] > h[1] || (s[2] < -h[2] && v[2] <= 0) || s[2] > h[2] || (v[0] == 0 && v[1] == 0 && v[2] == 0)) { return 0; } // compute the t=[lo..hi] range for where s+v*t intersects the box dReal lo = -dInfinity; dReal hi = dInfinity; int nlo = 0, nhi = 0; for (i=0; i<3; i++) { if (v[i] != 0) { dReal k = (-h[i] - s[i])/v[i]; if (k > lo) { lo = k; nlo = i; } k = (h[i] - s[i])/v[i]; if (k < hi) { hi = k; nhi = i; } } } // check if the ray intersects if (lo > hi) return 0; dReal alpha; int n; if (lo >= 0) { alpha = lo; n = nlo; } else { alpha = hi; n = nhi; } if (alpha < 0 || alpha > ray->length) return 0; contact->pos[0] = ray->final_posr->pos[0] + alpha*ray->final_posr->R[0*4+2]; contact->pos[1] = ray->final_posr->pos[1] + alpha*ray->final_posr->R[1*4+2]; contact->pos[2] = ray->final_posr->pos[2] + alpha*ray->final_posr->R[2*4+2]; contact->normal[0] = box->final_posr->R[0*4+n] * sign[n]; contact->normal[1] = box->final_posr->R[1*4+n] * sign[n]; contact->normal[2] = box->final_posr->R[2*4+n] * sign[n]; contact->depth = alpha; return 1; } int dCollideRayCapsule (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT (o1->type == dRayClass); dIASSERT (o2->type == dCapsuleClass); dIASSERT ((flags & NUMC_MASK) >= 1); dxRay *ray = (dxRay*) o1; dxCapsule *ccyl = (dxCapsule*) o2; contact->g1 = ray; contact->g2 = ccyl; contact->side1 = -1; contact->side2 = -1; dReal lz2 = ccyl->lz * REAL(0.5); // compute some useful info dVector3 cs,q,r; dReal C,k; cs[0] = ray->final_posr->pos[0] - ccyl->final_posr->pos[0]; cs[1] = ray->final_posr->pos[1] - ccyl->final_posr->pos[1]; cs[2] = ray->final_posr->pos[2] - ccyl->final_posr->pos[2]; k = dDOT41(ccyl->final_posr->R+2,cs); // position of ray start along ccyl axis q[0] = k*ccyl->final_posr->R[0*4+2] - cs[0]; q[1] = k*ccyl->final_posr->R[1*4+2] - cs[1]; q[2] = k*ccyl->final_posr->R[2*4+2] - cs[2]; C = dDOT(q,q) - ccyl->radius*ccyl->radius; // if C < 0 then ray start position within infinite extension of cylinder // see if ray start position is inside the capped cylinder int inside_ccyl = 0; if (C < 0) { if (k < -lz2) k = -lz2; else if (k > lz2) k = lz2; r[0] = ccyl->final_posr->pos[0] + k*ccyl->final_posr->R[0*4+2]; r[1] = ccyl->final_posr->pos[1] + k*ccyl->final_posr->R[1*4+2]; r[2] = ccyl->final_posr->pos[2] + k*ccyl->final_posr->R[2*4+2]; if ((ray->final_posr->pos[0]-r[0])*(ray->final_posr->pos[0]-r[0]) + (ray->final_posr->pos[1]-r[1])*(ray->final_posr->pos[1]-r[1]) + (ray->final_posr->pos[2]-r[2])*(ray->final_posr->pos[2]-r[2]) < ccyl->radius*ccyl->radius) { inside_ccyl = 1; } } // compute ray collision with infinite cylinder, except for the case where // the ray is outside the capped cylinder but within the infinite cylinder // (it that case the ray can only hit endcaps) if (!inside_ccyl && C < 0) { // set k to cap position to check if (k < 0) k = -lz2; else k = lz2; } else { dReal uv = dDOT44(ccyl->final_posr->R+2,ray->final_posr->R+2); r[0] = uv*ccyl->final_posr->R[0*4+2] - ray->final_posr->R[0*4+2]; r[1] = uv*ccyl->final_posr->R[1*4+2] - ray->final_posr->R[1*4+2]; r[2] = uv*ccyl->final_posr->R[2*4+2] - ray->final_posr->R[2*4+2]; dReal A = dDOT(r,r); dReal B = 2*dDOT(q,r); k = B*B-4*A*C; if (k < 0) { // the ray does not intersect the infinite cylinder, but if the ray is // inside and parallel to the cylinder axis it may intersect the end // caps. set k to cap position to check. if (!inside_ccyl) return 0; if (uv < 0) k = -lz2; else k = lz2; } else { k = dSqrt(k); A = dRecip (2*A); dReal alpha = (-B-k)*A; if (alpha < 0) { alpha = (-B+k)*A; if (alpha < 0) return 0; } if (alpha > ray->length) return 0; // the ray intersects the infinite cylinder. check to see if the // intersection point is between the caps contact->pos[0] = ray->final_posr->pos[0] + alpha*ray->final_posr->R[0*4+2]; contact->pos[1] = ray->final_posr->pos[1] + alpha*ray->final_posr->R[1*4+2]; contact->pos[2] = ray->final_posr->pos[2] + alpha*ray->final_posr->R[2*4+2]; q[0] = contact->pos[0] - ccyl->final_posr->pos[0]; q[1] = contact->pos[1] - ccyl->final_posr->pos[1]; q[2] = contact->pos[2] - ccyl->final_posr->pos[2]; k = dDOT14(q,ccyl->final_posr->R+2); dReal nsign = inside_ccyl ? REAL(-1.0) : REAL(1.0); if (k >= -lz2 && k <= lz2) { contact->normal[0] = nsign * (contact->pos[0] - (ccyl->final_posr->pos[0] + k*ccyl->final_posr->R[0*4+2])); contact->normal[1] = nsign * (contact->pos[1] - (ccyl->final_posr->pos[1] + k*ccyl->final_posr->R[1*4+2])); contact->normal[2] = nsign * (contact->pos[2] - (ccyl->final_posr->pos[2] + k*ccyl->final_posr->R[2*4+2])); dNormalize3 (contact->normal); contact->depth = alpha; return 1; } // the infinite cylinder intersection point is not between the caps. // set k to cap position to check. if (k < 0) k = -lz2; else k = lz2; } } // check for ray intersection with the caps. k must indicate the cap // position to check q[0] = ccyl->final_posr->pos[0] + k*ccyl->final_posr->R[0*4+2]; q[1] = ccyl->final_posr->pos[1] + k*ccyl->final_posr->R[1*4+2]; q[2] = ccyl->final_posr->pos[2] + k*ccyl->final_posr->R[2*4+2]; return ray_sphere_helper (ray,q,ccyl->radius,contact, inside_ccyl); } int dCollideRayPlane (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT (o1->type == dRayClass); dIASSERT (o2->type == dPlaneClass); dIASSERT ((flags & NUMC_MASK) >= 1); dxRay *ray = (dxRay*) o1; dxPlane *plane = (dxPlane*) o2; dReal alpha = plane->p[3] - dDOT (plane->p,ray->final_posr->pos); // note: if alpha > 0 the starting point is below the plane dReal nsign = (alpha > 0) ? REAL(-1.0) : REAL(1.0); dReal k = dDOT14(plane->p,ray->final_posr->R+2); if (k==0) return 0; // ray parallel to plane alpha /= k; if (alpha < 0 || alpha > ray->length) return 0; contact->pos[0] = ray->final_posr->pos[0] + alpha*ray->final_posr->R[0*4+2]; contact->pos[1] = ray->final_posr->pos[1] + alpha*ray->final_posr->R[1*4+2]; contact->pos[2] = ray->final_posr->pos[2] + alpha*ray->final_posr->R[2*4+2]; contact->normal[0] = nsign*plane->p[0]; contact->normal[1] = nsign*plane->p[1]; contact->normal[2] = nsign*plane->p[2]; contact->depth = alpha; contact->g1 = ray; contact->g2 = plane; contact->side1 = -1; contact->side2 = -1; return 1; } // Ray - Cylinder collider by David Walters (June 2006) int dCollideRayCylinder( dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip ) { dIASSERT( skip >= (int)sizeof( dContactGeom ) ); dIASSERT( o1->type == dRayClass ); dIASSERT( o2->type == dCylinderClass ); dIASSERT( (flags & NUMC_MASK) >= 1 ); dxRay* ray = (dxRay*)( o1 ); dxCylinder* cyl = (dxCylinder*)( o2 ); // Fill in contact information. contact->g1 = ray; contact->g2 = cyl; contact->side1 = -1; contact->side2 = -1; const dReal half_length = cyl->lz * REAL( 0.5 ); // // Compute some useful info // dVector3 q, r; dReal d, C, k; // Vector 'r', line segment from C to R (ray start) ( r = R - C ) r[ 0 ] = ray->final_posr->pos[0] - cyl->final_posr->pos[0]; r[ 1 ] = ray->final_posr->pos[1] - cyl->final_posr->pos[1]; r[ 2 ] = ray->final_posr->pos[2] - cyl->final_posr->pos[2]; // Distance that ray start is along cyl axis ( Z-axis direction ) d = dDOT41( cyl->final_posr->R + 2, r ); // // Compute vector 'q' representing the shortest line from R to the cylinder z-axis (Cz). // // Point on axis ( in world space ): cp = ( d * Cz ) + C // // Line 'q' from R to cp: q = cp - R // q = ( d * Cz ) + C - R // q = ( d * Cz ) - ( R - C ) q[ 0 ] = ( d * cyl->final_posr->R[0*4+2] ) - r[ 0 ]; q[ 1 ] = ( d * cyl->final_posr->R[1*4+2] ) - r[ 1 ]; q[ 2 ] = ( d * cyl->final_posr->R[2*4+2] ) - r[ 2 ]; // Compute square length of 'q'. Subtract from radius squared to // get square distance 'C' between the line q and the radius. // if C < 0 then ray start position is within infinite extension of cylinder C = dDOT( q, q ) - ( cyl->radius * cyl->radius ); // Compute the projection of ray direction normal onto cylinder direction normal. dReal uv = dDOT44( cyl->final_posr->R+2, ray->final_posr->R+2 ); // // Find ray collision with infinite cylinder // // Compute vector from end of ray direction normal to projection on cylinder direction normal. r[ 0 ] = ( uv * cyl->final_posr->R[0*4+2] ) - ray->final_posr->R[0*4+2]; r[ 1 ] = ( uv * cyl->final_posr->R[1*4+2] ) - ray->final_posr->R[1*4+2]; r[ 2 ] = ( uv * cyl->final_posr->R[2*4+2] ) - ray->final_posr->R[2*4+2]; // Quadratic Formula Magic // Compute discriminant 'k': // k < 0 : No intersection // k = 0 : Tangent // k > 0 : Intersection dReal A = dDOT( r, r ); dReal B = 2 * dDOT( q, r ); k = B*B - 4*A*C; // // Collision with Flat Caps ? // // No collision with cylinder edge. ( Use epsilon here or we miss some obvious cases ) if ( k < dEpsilon && C <= 0 ) { // The ray does not intersect the edge of the infinite cylinder, // but the ray start is inside and so must run parallel to the axis. // It may yet intersect an end cap. The following cases are valid: // -ve-cap , -half centre +half , +ve-cap // <<================|-------------------|------------->>>---|================>> // | | // | d-------------------> 1. // 2. d------------------> | // 3. <------------------d | // | <-------------------d 4. // | | // <<================|-------------------|------------->>>---|===============>> // Negative if the ray and cylinder axes point in opposite directions. const dReal uvsign = ( uv < 0 ) ? REAL( -1.0 ) : REAL( 1.0 ); // Negative if the ray start is inside the cylinder const dReal internal = ( d >= -half_length && d <= +half_length ) ? REAL( -1.0 ) : REAL( 1.0 ); // Ray and Cylinder axes run in the same direction ( cases 1, 2 ) // Ray and Cylinder axes run in opposite directions ( cases 3, 4 ) if ( ( ( uv > 0 ) && ( d + ( uvsign * ray->length ) < half_length * internal ) ) || ( ( uv < 0 ) && ( d + ( uvsign * ray->length ) > half_length * internal ) ) ) { return 0; // No intersection with caps or curved surface. } // Compute depth (distance from ray to cylinder) contact->depth = ( ( -uvsign * d ) - ( internal * half_length ) ); // Compute contact point. contact->pos[0] = ray->final_posr->pos[0] + ( contact->depth * ray->final_posr->R[0*4+2] ); contact->pos[1] = ray->final_posr->pos[1] + ( contact->depth * ray->final_posr->R[1*4+2] ); contact->pos[2] = ray->final_posr->pos[2] + ( contact->depth * ray->final_posr->R[2*4+2] ); // Compute reflected contact normal. contact->normal[0] = uvsign * ( cyl->final_posr->R[0*4+2] ); contact->normal[1] = uvsign * ( cyl->final_posr->R[1*4+2] ); contact->normal[2] = uvsign * ( cyl->final_posr->R[2*4+2] ); // Contact! return 1; } // // Collision with Curved Edge ? // if ( k > 0 ) { // Finish off quadratic formula to get intersection co-efficient k = dSqrt( k ); A = dRecip( 2 * A ); // Compute distance along line to contact point. dReal alpha = ( -B - k ) * A; if ( alpha < 0 ) { // Flip in the other direction. alpha = ( -B + k ) * A; } // Intersection point is within ray length? if ( alpha >= 0 && alpha <= ray->length ) { // The ray intersects the infinite cylinder! // Compute contact point. contact->pos[0] = ray->final_posr->pos[0] + ( alpha * ray->final_posr->R[0*4+2] ); contact->pos[1] = ray->final_posr->pos[1] + ( alpha * ray->final_posr->R[1*4+2] ); contact->pos[2] = ray->final_posr->pos[2] + ( alpha * ray->final_posr->R[2*4+2] ); // q is the vector from the cylinder centre to the contact point. q[0] = contact->pos[0] - cyl->final_posr->pos[0]; q[1] = contact->pos[1] - cyl->final_posr->pos[1]; q[2] = contact->pos[2] - cyl->final_posr->pos[2]; // Compute the distance along the cylinder axis of this contact point. d = dDOT14( q, cyl->final_posr->R+2 ); // Check to see if the intersection point is between the flat end caps if ( d >= -half_length && d <= +half_length ) { // Flip the normal if the start point is inside the cylinder. const dReal nsign = ( C < 0 ) ? REAL( -1.0 ) : REAL( 1.0 ); // Compute contact normal. contact->normal[0] = nsign * (contact->pos[0] - (cyl->final_posr->pos[0] + d*cyl->final_posr->R[0*4+2])); contact->normal[1] = nsign * (contact->pos[1] - (cyl->final_posr->pos[1] + d*cyl->final_posr->R[1*4+2])); contact->normal[2] = nsign * (contact->pos[2] - (cyl->final_posr->pos[2] + d*cyl->final_posr->R[2*4+2])); dNormalize3( contact->normal ); // Store depth. contact->depth = alpha; // Contact! return 1; } } } // No contact with anything. return 0; } alien-arena-7.66+dfsg/source/unix/odesrc/rotation.cpp0000600000175000017500000002062512161402010021714 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* quaternions have the format: (s,vx,vy,vz) where (vx,vy,vz) is the "rotation axis" and s is the "rotation angle". */ #include #include #define _R(i,j) R[(i)*4+(j)] #define SET_3x3_IDENTITY \ _R(0,0) = REAL(1.0); \ _R(0,1) = REAL(0.0); \ _R(0,2) = REAL(0.0); \ _R(0,3) = REAL(0.0); \ _R(1,0) = REAL(0.0); \ _R(1,1) = REAL(1.0); \ _R(1,2) = REAL(0.0); \ _R(1,3) = REAL(0.0); \ _R(2,0) = REAL(0.0); \ _R(2,1) = REAL(0.0); \ _R(2,2) = REAL(1.0); \ _R(2,3) = REAL(0.0); void dRSetIdentity (dMatrix3 R) { dAASSERT (R); SET_3x3_IDENTITY; } void dRFromAxisAndAngle (dMatrix3 R, dReal ax, dReal ay, dReal az, dReal angle) { dAASSERT (R); dQuaternion q; dQFromAxisAndAngle (q,ax,ay,az,angle); dQtoR (q,R); } void dRFromEulerAngles (dMatrix3 R, dReal phi, dReal theta, dReal psi) { dReal sphi,cphi,stheta,ctheta,spsi,cpsi; dAASSERT (R); sphi = dSin(phi); cphi = dCos(phi); stheta = dSin(theta); ctheta = dCos(theta); spsi = dSin(psi); cpsi = dCos(psi); _R(0,0) = cpsi*ctheta; _R(0,1) = spsi*ctheta; _R(0,2) =-stheta; _R(0,3) = REAL(0.0); _R(1,0) = cpsi*stheta*sphi - spsi*cphi; _R(1,1) = spsi*stheta*sphi + cpsi*cphi; _R(1,2) = ctheta*sphi; _R(1,3) = REAL(0.0); _R(2,0) = cpsi*stheta*cphi + spsi*sphi; _R(2,1) = spsi*stheta*cphi - cpsi*sphi; _R(2,2) = ctheta*cphi; _R(2,3) = REAL(0.0); } void dRFrom2Axes (dMatrix3 R, dReal ax, dReal ay, dReal az, dReal bx, dReal by, dReal bz) { dReal l,k; dAASSERT (R); l = dSqrt (ax*ax + ay*ay + az*az); if (l <= REAL(0.0)) { dDEBUGMSG ("zero length vector"); return; } l = dRecip(l); ax *= l; ay *= l; az *= l; k = ax*bx + ay*by + az*bz; bx -= k*ax; by -= k*ay; bz -= k*az; l = dSqrt (bx*bx + by*by + bz*bz); if (l <= REAL(0.0)) { dDEBUGMSG ("zero length vector"); return; } l = dRecip(l); bx *= l; by *= l; bz *= l; _R(0,0) = ax; _R(1,0) = ay; _R(2,0) = az; _R(0,1) = bx; _R(1,1) = by; _R(2,1) = bz; _R(0,2) = - by*az + ay*bz; _R(1,2) = - bz*ax + az*bx; _R(2,2) = - bx*ay + ax*by; _R(0,3) = REAL(0.0); _R(1,3) = REAL(0.0); _R(2,3) = REAL(0.0); } void dRFromZAxis (dMatrix3 R, dReal ax, dReal ay, dReal az) { dVector3 n,p,q; n[0] = ax; n[1] = ay; n[2] = az; dNormalize3 (n); dPlaneSpace (n,p,q); _R(0,0) = p[0]; _R(1,0) = p[1]; _R(2,0) = p[2]; _R(0,1) = q[0]; _R(1,1) = q[1]; _R(2,1) = q[2]; _R(0,2) = n[0]; _R(1,2) = n[1]; _R(2,2) = n[2]; _R(0,3) = REAL(0.0); _R(1,3) = REAL(0.0); _R(2,3) = REAL(0.0); } void dQSetIdentity (dQuaternion q) { dAASSERT (q); q[0] = 1; q[1] = 0; q[2] = 0; q[3] = 0; } void dQFromAxisAndAngle (dQuaternion q, dReal ax, dReal ay, dReal az, dReal angle) { dAASSERT (q); dReal l = ax*ax + ay*ay + az*az; if (l > REAL(0.0)) { angle *= REAL(0.5); q[0] = dCos (angle); l = dSin(angle) * dRecipSqrt(l); q[1] = ax*l; q[2] = ay*l; q[3] = az*l; } else { q[0] = 1; q[1] = 0; q[2] = 0; q[3] = 0; } } void dQMultiply0 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc) { dAASSERT (qa && qb && qc); qa[0] = qb[0]*qc[0] - qb[1]*qc[1] - qb[2]*qc[2] - qb[3]*qc[3]; qa[1] = qb[0]*qc[1] + qb[1]*qc[0] + qb[2]*qc[3] - qb[3]*qc[2]; qa[2] = qb[0]*qc[2] + qb[2]*qc[0] + qb[3]*qc[1] - qb[1]*qc[3]; qa[3] = qb[0]*qc[3] + qb[3]*qc[0] + qb[1]*qc[2] - qb[2]*qc[1]; } void dQMultiply1 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc) { dAASSERT (qa && qb && qc); qa[0] = qb[0]*qc[0] + qb[1]*qc[1] + qb[2]*qc[2] + qb[3]*qc[3]; qa[1] = qb[0]*qc[1] - qb[1]*qc[0] - qb[2]*qc[3] + qb[3]*qc[2]; qa[2] = qb[0]*qc[2] - qb[2]*qc[0] - qb[3]*qc[1] + qb[1]*qc[3]; qa[3] = qb[0]*qc[3] - qb[3]*qc[0] - qb[1]*qc[2] + qb[2]*qc[1]; } void dQMultiply2 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc) { dAASSERT (qa && qb && qc); qa[0] = qb[0]*qc[0] + qb[1]*qc[1] + qb[2]*qc[2] + qb[3]*qc[3]; qa[1] = -qb[0]*qc[1] + qb[1]*qc[0] - qb[2]*qc[3] + qb[3]*qc[2]; qa[2] = -qb[0]*qc[2] + qb[2]*qc[0] - qb[3]*qc[1] + qb[1]*qc[3]; qa[3] = -qb[0]*qc[3] + qb[3]*qc[0] - qb[1]*qc[2] + qb[2]*qc[1]; } void dQMultiply3 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc) { dAASSERT (qa && qb && qc); qa[0] = qb[0]*qc[0] - qb[1]*qc[1] - qb[2]*qc[2] - qb[3]*qc[3]; qa[1] = -qb[0]*qc[1] - qb[1]*qc[0] + qb[2]*qc[3] - qb[3]*qc[2]; qa[2] = -qb[0]*qc[2] - qb[2]*qc[0] + qb[3]*qc[1] - qb[1]*qc[3]; qa[3] = -qb[0]*qc[3] - qb[3]*qc[0] + qb[1]*qc[2] - qb[2]*qc[1]; } // dRfromQ(), dQfromR() and dDQfromW() are derived from equations in "An Introduction // to Physically Based Modeling: Rigid Body Simulation - 1: Unconstrained // Rigid Body Dynamics" by David Baraff, Robotics Institute, Carnegie Mellon // University, 1997. void dRfromQ (dMatrix3 R, const dQuaternion q) { dAASSERT (q && R); // q = (s,vx,vy,vz) dReal qq1 = 2*q[1]*q[1]; dReal qq2 = 2*q[2]*q[2]; dReal qq3 = 2*q[3]*q[3]; _R(0,0) = 1 - qq2 - qq3; _R(0,1) = 2*(q[1]*q[2] - q[0]*q[3]); _R(0,2) = 2*(q[1]*q[3] + q[0]*q[2]); _R(0,3) = REAL(0.0); _R(1,0) = 2*(q[1]*q[2] + q[0]*q[3]); _R(1,1) = 1 - qq1 - qq3; _R(1,2) = 2*(q[2]*q[3] - q[0]*q[1]); _R(1,3) = REAL(0.0); _R(2,0) = 2*(q[1]*q[3] - q[0]*q[2]); _R(2,1) = 2*(q[2]*q[3] + q[0]*q[1]); _R(2,2) = 1 - qq1 - qq2; _R(2,3) = REAL(0.0); } void dQfromR (dQuaternion q, const dMatrix3 R) { dAASSERT (q && R); dReal tr,s; tr = _R(0,0) + _R(1,1) + _R(2,2); if (tr >= 0) { s = dSqrt (tr + 1); q[0] = REAL(0.5) * s; s = REAL(0.5) * dRecip(s); q[1] = (_R(2,1) - _R(1,2)) * s; q[2] = (_R(0,2) - _R(2,0)) * s; q[3] = (_R(1,0) - _R(0,1)) * s; } else { // find the largest diagonal element and jump to the appropriate case if (_R(1,1) > _R(0,0)) { if (_R(2,2) > _R(1,1)) goto case_2; goto case_1; } if (_R(2,2) > _R(0,0)) goto case_2; goto case_0; case_0: s = dSqrt((_R(0,0) - (_R(1,1) + _R(2,2))) + 1); q[1] = REAL(0.5) * s; s = REAL(0.5) * dRecip(s); q[2] = (_R(0,1) + _R(1,0)) * s; q[3] = (_R(2,0) + _R(0,2)) * s; q[0] = (_R(2,1) - _R(1,2)) * s; return; case_1: s = dSqrt((_R(1,1) - (_R(2,2) + _R(0,0))) + 1); q[2] = REAL(0.5) * s; s = REAL(0.5) * dRecip(s); q[3] = (_R(1,2) + _R(2,1)) * s; q[1] = (_R(0,1) + _R(1,0)) * s; q[0] = (_R(0,2) - _R(2,0)) * s; return; case_2: s = dSqrt((_R(2,2) - (_R(0,0) + _R(1,1))) + 1); q[3] = REAL(0.5) * s; s = REAL(0.5) * dRecip(s); q[1] = (_R(2,0) + _R(0,2)) * s; q[2] = (_R(1,2) + _R(2,1)) * s; q[0] = (_R(1,0) - _R(0,1)) * s; return; } } void dDQfromW (dReal dq[4], const dVector3 w, const dQuaternion q) { dAASSERT (w && q && dq); dq[0] = REAL(0.5)*(- w[0]*q[1] - w[1]*q[2] - w[2]*q[3]); dq[1] = REAL(0.5)*( w[0]*q[0] + w[1]*q[3] - w[2]*q[2]); dq[2] = REAL(0.5)*(- w[0]*q[3] + w[1]*q[0] + w[2]*q[1]); dq[3] = REAL(0.5)*( w[0]*q[2] - w[1]*q[1] + w[2]*q[0]); } alien-arena-7.66+dfsg/source/unix/odesrc/stepfast.cpp0000600000175000017500000007556312161402010021721 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * Fast iterative solver, David Whittaker. Email: david@csworkbench.com * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ // This is the StepFast code by David Whittaker. This code is faster, but // sometimes less stable than, the original "big matrix" code. // Refer to the user's manual for more information. // Note that this source file duplicates a lot of stuff from step.cpp, // eventually we should move the common code to a third file. #include "objects.h" #include "joints/joint.h" #include #include "config.h" #include #include #include #include #include #include #include #include "lcp.h" #include "step.h" #include "util.h" // misc defines #define ALLOCA dALLOCA16 #define RANDOM_JOINT_ORDER //#define FAST_FACTOR //use a factorization approximation to the LCP solver (fast, theoretically less accurate) #define SLOW_LCP //use the old LCP solver //#define NO_ISLANDS //does not perform island creation code (3~4% of simulation time), body disabling doesn't work //#define TIMING static int autoEnableDepth = 2; void dWorldSetAutoEnableDepthSF1 (dxWorld *world, int autodepth) { if (autodepth > 0) autoEnableDepth = autodepth; else autoEnableDepth = 0; } int dWorldGetAutoEnableDepthSF1 (dxWorld *world) { return autoEnableDepth; } //little bit of math.... the _sym_ functions assume the return matrix will be symmetric static void Multiply2_sym_p8p (dReal * A, dReal * B, dReal * C, int p, int Askip) { int i, j; dReal sum, *aa, *ad, *bb, *cc; dIASSERT (p > 0 && A && B && C); bb = B; for (i = 0; i < p; i++) { //aa is going accross the matrix, ad down aa = ad = A; cc = C; for (j = i; j < p; j++) { sum = bb[0] * cc[0]; sum += bb[1] * cc[1]; sum += bb[2] * cc[2]; sum += bb[4] * cc[4]; sum += bb[5] * cc[5]; sum += bb[6] * cc[6]; *(aa++) = *ad = sum; ad += Askip; cc += 8; } bb += 8; A += Askip + 1; C += 8; } } static void MultiplyAdd2_sym_p8p (dReal * A, dReal * B, dReal * C, int p, int Askip) { int i, j; dReal sum, *aa, *ad, *bb, *cc; dIASSERT (p > 0 && A && B && C); bb = B; for (i = 0; i < p; i++) { //aa is going accross the matrix, ad down aa = ad = A; cc = C; for (j = i; j < p; j++) { sum = bb[0] * cc[0]; sum += bb[1] * cc[1]; sum += bb[2] * cc[2]; sum += bb[4] * cc[4]; sum += bb[5] * cc[5]; sum += bb[6] * cc[6]; *(aa++) += sum; *ad += sum; ad += Askip; cc += 8; } bb += 8; A += Askip + 1; C += 8; } } // this assumes the 4th and 8th rows of B are zero. static void Multiply0_p81 (dReal * A, dReal * B, dReal * C, int p) { int i; dIASSERT (p > 0 && A && B && C); dReal sum; for (i = p; i; i--) { sum = B[0] * C[0]; sum += B[1] * C[1]; sum += B[2] * C[2]; sum += B[4] * C[4]; sum += B[5] * C[5]; sum += B[6] * C[6]; *(A++) = sum; B += 8; } } // this assumes the 4th and 8th rows of B are zero. static void MultiplyAdd0_p81 (dReal * A, dReal * B, dReal * C, int p) { int i; dIASSERT (p > 0 && A && B && C); dReal sum; for (i = p; i; i--) { sum = B[0] * C[0]; sum += B[1] * C[1]; sum += B[2] * C[2]; sum += B[4] * C[4]; sum += B[5] * C[5]; sum += B[6] * C[6]; *(A++) += sum; B += 8; } } // this assumes the 4th and 8th rows of B are zero. static void Multiply1_8q1 (dReal * A, dReal * B, dReal * C, int q) { int k; dReal sum; dIASSERT (q > 0 && A && B && C); sum = 0; for (k = 0; k < q; k++) sum += B[k * 8] * C[k]; A[0] = sum; sum = 0; for (k = 0; k < q; k++) sum += B[1 + k * 8] * C[k]; A[1] = sum; sum = 0; for (k = 0; k < q; k++) sum += B[2 + k * 8] * C[k]; A[2] = sum; sum = 0; for (k = 0; k < q; k++) sum += B[4 + k * 8] * C[k]; A[4] = sum; sum = 0; for (k = 0; k < q; k++) sum += B[5 + k * 8] * C[k]; A[5] = sum; sum = 0; for (k = 0; k < q; k++) sum += B[6 + k * 8] * C[k]; A[6] = sum; } //**************************************************************************** // body rotation // return sin(x)/x. this has a singularity at 0 so special handling is needed // for small arguments. static inline dReal sinc (dReal x) { // if |x| < 1e-4 then use a taylor series expansion. this two term expansion // is actually accurate to one LS bit within this range if double precision // is being used - so don't worry! if (dFabs (x) < 1.0e-4) return REAL (1.0) - x * x * REAL (0.166666666666666666667); else return dSin (x) / x; } #if 0 // this is just dxStepBody() // given a body b, apply its linear and angular rotation over the time // interval h, thereby adjusting its position and orientation. static inline void moveAndRotateBody (dxBody * b, dReal h) { int j; // handle linear velocity for (j = 0; j < 3; j++) b->posr.pos[j] += h * b->lvel[j]; if (b->flags & dxBodyFlagFiniteRotation) { dVector3 irv; // infitesimal rotation vector dQuaternion q; // quaternion for finite rotation if (b->flags & dxBodyFlagFiniteRotationAxis) { // split the angular velocity vector into a component along the finite // rotation axis, and a component orthogonal to it. dVector3 frv, irv; // finite rotation vector dReal k = dDOT (b->finite_rot_axis, b->avel); frv[0] = b->finite_rot_axis[0] * k; frv[1] = b->finite_rot_axis[1] * k; frv[2] = b->finite_rot_axis[2] * k; irv[0] = b->avel[0] - frv[0]; irv[1] = b->avel[1] - frv[1]; irv[2] = b->avel[2] - frv[2]; // make a rotation quaternion q that corresponds to frv * h. // compare this with the full-finite-rotation case below. h *= REAL (0.5); dReal theta = k * h; q[0] = dCos (theta); dReal s = sinc (theta) * h; q[1] = frv[0] * s; q[2] = frv[1] * s; q[3] = frv[2] * s; } else { // make a rotation quaternion q that corresponds to w * h dReal wlen = dSqrt (b->avel[0] * b->avel[0] + b->avel[1] * b->avel[1] + b->avel[2] * b->avel[2]); h *= REAL (0.5); dReal theta = wlen * h; q[0] = dCos (theta); dReal s = sinc (theta) * h; q[1] = b->avel[0] * s; q[2] = b->avel[1] * s; q[3] = b->avel[2] * s; } // do the finite rotation dQuaternion q2; dQMultiply0 (q2, q, b->q); for (j = 0; j < 4; j++) b->q[j] = q2[j]; // do the infitesimal rotation if required if (b->flags & dxBodyFlagFiniteRotationAxis) { dReal dq[4]; dWtoDQ (irv, b->q, dq); for (j = 0; j < 4; j++) b->q[j] += h * dq[j]; } } else { // the normal way - do an infitesimal rotation dReal dq[4]; dWtoDQ (b->avel, b->q, dq); for (j = 0; j < 4; j++) b->q[j] += h * dq[j]; } // normalize the quaternion and convert it to a rotation matrix dNormalize4 (b->q); dQtoR (b->q, b->posr.R); // notify all attached geoms that this body has moved for (dxGeom * geom = b->geom; geom; geom = dGeomGetBodyNext (geom)) dGeomMoved (geom); } #endif //**************************************************************************** //This is an implementation of the iterated/relaxation algorithm. //Here is a quick overview of the algorithm per Sergi Valverde's posts to the //mailing list: // // for i=0..N-1 do // for c = 0..C-1 do // Solve constraint c-th // Apply forces to constraint bodies // next // next // Integrate bodies void dInternalStepFast (dxWorld * world, dxBody * body[2], dReal * GI[2], dReal * GinvI[2], dxJoint * joint, dxJoint::Info1 info, dxJoint::Info2 Jinfo, dReal stepsize) { int i, j, k; # ifdef TIMING dTimerNow ("constraint preprocessing"); # endif dReal stepsize1 = dRecip (stepsize); int m = info.m; // nothing to do if no constraints. if (m <= 0) return; int nub = 0; if (info.nub == info.m) nub = m; // compute A = J*invM*J'. first compute JinvM = J*invM. this has the same // format as J so we just go through the constraints in J multiplying by // the appropriate scalars and matrices. # ifdef TIMING dTimerNow ("compute A"); # endif dReal JinvM[2 * 6 * 8]; //dSetZero (JinvM, 2 * m * 8); dReal *Jsrc = Jinfo.J1l; dReal *Jdst = JinvM; if (body[0]) { for (j = m - 1; j >= 0; j--) { for (k = 0; k < 3; k++) Jdst[k] = Jsrc[k] * body[0]->invMass; dMULTIPLY0_133 (Jdst + 4, Jsrc + 4, GinvI[0]); Jsrc += 8; Jdst += 8; } } if (body[1]) { Jsrc = Jinfo.J2l; Jdst = JinvM + 8 * m; for (j = m - 1; j >= 0; j--) { for (k = 0; k < 3; k++) Jdst[k] = Jsrc[k] * body[1]->invMass; dMULTIPLY0_133 (Jdst + 4, Jsrc + 4, GinvI[1]); Jsrc += 8; Jdst += 8; } } // now compute A = JinvM * J'. int mskip = dPAD (m); dReal A[6 * 8]; //dSetZero (A, 6 * 8); if (body[0]) { Multiply2_sym_p8p (A, JinvM, Jinfo.J1l, m, mskip); if (body[1]) MultiplyAdd2_sym_p8p (A, JinvM + 8 * m, Jinfo.J2l, m, mskip); } else { if (body[1]) Multiply2_sym_p8p (A, JinvM + 8 * m, Jinfo.J2l, m, mskip); } // add cfm to the diagonal of A for (i = 0; i < m; i++) A[i * mskip + i] += Jinfo.cfm[i] * stepsize1; // compute the right hand side `rhs' # ifdef TIMING dTimerNow ("compute rhs"); # endif dReal tmp1[16]; //dSetZero (tmp1, 16); // put v/h + invM*fe into tmp1 for (i = 0; i < 2; i++) { if (!body[i]) continue; for (j = 0; j < 3; j++) tmp1[i * 8 + j] = body[i]->facc[j] * body[i]->invMass + body[i]->lvel[j] * stepsize1; dMULTIPLY0_331 (tmp1 + i * 8 + 4, GinvI[i], body[i]->tacc); for (j = 0; j < 3; j++) tmp1[i * 8 + 4 + j] += body[i]->avel[j] * stepsize1; } // put J*tmp1 into rhs dReal rhs[6]; //dSetZero (rhs, 6); if (body[0]) { Multiply0_p81 (rhs, Jinfo.J1l, tmp1, m); if (body[1]) MultiplyAdd0_p81 (rhs, Jinfo.J2l, tmp1 + 8, m); } else { if (body[1]) Multiply0_p81 (rhs, Jinfo.J2l, tmp1 + 8, m); } // complete rhs for (i = 0; i < m; i++) rhs[i] = Jinfo.c[i] * stepsize1 - rhs[i]; #ifdef SLOW_LCP // solve the LCP problem and get lambda. // this will destroy A but that's okay # ifdef TIMING dTimerNow ("solving LCP problem"); # endif dReal *lambda = (dReal *) ALLOCA (m * sizeof (dReal)); dReal *residual = (dReal *) ALLOCA (m * sizeof (dReal)); dReal lo[6], hi[6]; memcpy (lo, Jinfo.lo, m * sizeof (dReal)); memcpy (hi, Jinfo.hi, m * sizeof (dReal)); dSolveLCP (m, A, lambda, rhs, residual, nub, lo, hi, Jinfo.findex); #endif // LCP Solver replacement: // This algorithm goes like this: // Do a straightforward LDLT factorization of the matrix A, solving for // A*x = rhs // For each x[i] that is outside of the bounds of lo[i] and hi[i], // clamp x[i] into that range. // Substitute into A the now known x's // subtract the residual away from the rhs. // Remove row and column i from L, updating the factorization // place the known x's at the end of the array, keeping up with location in p // Repeat until all constraints have been clamped or all are within bounds // // This is probably only faster in the single joint case where only one repeat is // the norm. #ifdef FAST_FACTOR // factorize A (L*D*L'=A) # ifdef TIMING dTimerNow ("factorize A"); # endif dReal d[6]; dReal L[6 * 8]; memcpy (L, A, m * mskip * sizeof (dReal)); dFactorLDLT (L, d, m, mskip); // compute lambda # ifdef TIMING dTimerNow ("compute lambda"); # endif int left = m; //constraints left to solve. int remove[6]; dReal lambda[6]; dReal x[6]; int p[6]; for (i = 0; i < 6; i++) p[i] = i; while (true) { memcpy (x, rhs, left * sizeof (dReal)); dSolveLDLT (L, d, x, left, mskip); int fixed = 0; for (i = 0; i < left; i++) { j = p[i]; remove[i] = false; // This isn't the exact same use of findex as dSolveLCP.... since x[findex] // may change after I've already clamped x[i], but it should be close if (Jinfo.findex[j] > -1) { dReal f = fabs (Jinfo.hi[j] * x[p[Jinfo.findex[j]]]); if (x[i] > f) x[i] = f; else if (x[i] < -f) x[i] = -f; else continue; } else { if (x[i] > Jinfo.hi[j]) x[i] = Jinfo.hi[j]; else if (x[i] < Jinfo.lo[j]) x[i] = Jinfo.lo[j]; else continue; } remove[i] = true; fixed++; } if (fixed == 0 || fixed == left) //no change or all constraints solved break; for (i = 0; i < left; i++) //sub in to right hand side. if (remove[i]) for (j = 0; j < left; j++) if (!remove[j]) rhs[j] -= A[j * mskip + i] * x[i]; for (int r = left - 1; r >= 0; r--) //eliminate row/col for fixed variables { if (remove[r]) { //dRemoveLDLT adapted for use without row pointers. if (r == left - 1) { left--; continue; // deleting last row/col is easy } else if (r == 0) { dReal a[6]; for (i = 0; i < left; i++) a[i] = -A[i * mskip]; a[0] += REAL (1.0); dLDLTAddTL (L, d, a, left, mskip); } else { dReal t[6]; dReal a[6]; for (i = 0; i < r; i++) t[i] = L[r * mskip + i] / d[i]; for (i = 0; i < left - r; i++) a[i] = dDot (L + (r + i) * mskip, t, r) - A[(r + i) * mskip + r]; a[0] += REAL (1.0); dLDLTAddTL (L + r * mskip + r, d + r, a, left - r, mskip); } dRemoveRowCol (L, left, mskip, r); //end dRemoveLDLT left--; if (r < (left - 1)) { dReal tx = x[r]; memmove (d + r, d + r + 1, (left - r) * sizeof (dReal)); memmove (rhs + r, rhs + r + 1, (left - r) * sizeof (dReal)); //x will get written over by rhs anyway, no need to move it around //just store the fixed value we just discovered in it. x[left] = tx; for (i = 0; i < m; i++) if (p[i] > r && p[i] <= left) p[i]--; p[r] = left; } } } } for (i = 0; i < m; i++) lambda[i] = x[p[i]]; # endif // compute the constraint force `cforce' # ifdef TIMING dTimerNow ("compute constraint force"); #endif // compute cforce = J'*lambda dJointFeedback *fb = joint->feedback; dReal cforce[16]; //dSetZero (cforce, 16); if (fb) { // the user has requested feedback on the amount of force that this // joint is applying to the bodies. we use a slightly slower // computation that splits out the force components and puts them // in the feedback structure. dReal data1[8], data2[8]; if (body[0]) { Multiply1_8q1 (data1, Jinfo.J1l, lambda, m); dReal *cf1 = cforce; cf1[0] = (fb->f1[0] = data1[0]); cf1[1] = (fb->f1[1] = data1[1]); cf1[2] = (fb->f1[2] = data1[2]); cf1[4] = (fb->t1[0] = data1[4]); cf1[5] = (fb->t1[1] = data1[5]); cf1[6] = (fb->t1[2] = data1[6]); } if (body[1]) { Multiply1_8q1 (data2, Jinfo.J2l, lambda, m); dReal *cf2 = cforce + 8; cf2[0] = (fb->f2[0] = data2[0]); cf2[1] = (fb->f2[1] = data2[1]); cf2[2] = (fb->f2[2] = data2[2]); cf2[4] = (fb->t2[0] = data2[4]); cf2[5] = (fb->t2[1] = data2[5]); cf2[6] = (fb->t2[2] = data2[6]); } } else { // no feedback is required, let's compute cforce the faster way if (body[0]) Multiply1_8q1 (cforce, Jinfo.J1l, lambda, m); if (body[1]) Multiply1_8q1 (cforce + 8, Jinfo.J2l, lambda, m); } for (i = 0; i < 2; i++) { if (!body[i]) continue; for (j = 0; j < 3; j++) { body[i]->facc[j] += cforce[i * 8 + j]; body[i]->tacc[j] += cforce[i * 8 + 4 + j]; } } } void dInternalStepIslandFast (dxWorld * world, dxBody * const *bodies, int nb, dxJoint * const *_joints, int nj, dReal stepsize, int maxiterations) { # ifdef TIMING dTimerNow ("preprocessing"); # endif dxBody *bodyPair[2], *body; dReal *GIPair[2], *GinvIPair[2]; dxJoint *joint; int iter, b, j, i; dReal ministep = stepsize / maxiterations; // make a local copy of the joint array, because we might want to modify it. // (the "dxJoint *const*" declaration says we're allowed to modify the joints // but not the joint array, because the caller might need it unchanged). dxJoint **joints = (dxJoint **) ALLOCA (nj * sizeof (dxJoint *)); memcpy (joints, _joints, nj * sizeof (dxJoint *)); // get m = total constraint dimension, nub = number of unbounded variables. // create constraint offset array and number-of-rows array for all joints. // the constraints are re-ordered as follows: the purely unbounded // constraints, the mixed unbounded + LCP constraints, and last the purely // LCP constraints. this assists the LCP solver to put all unbounded // variables at the start for a quick factorization. // // joints with m=0 are inactive and are removed from the joints array // entirely, so that the code that follows does not consider them. // also number all active joints in the joint list (set their tag values). // inactive joints receive a tag value of -1. int m = 0; dxJoint::Info1 * info = (dxJoint::Info1 *) ALLOCA (nj * sizeof (dxJoint::Info1)); int *ofs = (int *) ALLOCA (nj * sizeof (int)); for (i = 0, j = 0; j < nj; j++) { // i=dest, j=src joints[j]->getInfo1 (info + i); dIASSERT (info[i].m >= 0 && info[i].m <= 6 && info[i].nub >= 0 && info[i].nub <= info[i].m); if (info[i].m > 0) { joints[i] = joints[j]; joints[i]->tag = i; i++; } else { joints[j]->tag = -1; } } nj = i; // the purely unbounded constraints for (i = 0; i < nj; i++) { ofs[i] = m; m += info[i].m; } dReal *c = NULL; dReal *cfm = NULL; dReal *lo = NULL; dReal *hi = NULL; int *findex = NULL; dReal *J = NULL; dxJoint::Info2 * Jinfo = NULL; if (m) { // create a constraint equation right hand side vector `c', a constraint // force mixing vector `cfm', and LCP low and high bound vectors, and an // 'findex' vector. c = (dReal *) ALLOCA (m * sizeof (dReal)); cfm = (dReal *) ALLOCA (m * sizeof (dReal)); lo = (dReal *) ALLOCA (m * sizeof (dReal)); hi = (dReal *) ALLOCA (m * sizeof (dReal)); findex = (int *) ALLOCA (m * sizeof (int)); dSetZero (c, m); dSetValue (cfm, m, world->global_cfm); dSetValue (lo, m, -dInfinity); dSetValue (hi, m, dInfinity); for (i = 0; i < m; i++) findex[i] = -1; // get jacobian data from constraints. a (2*m)x8 matrix will be created // to store the two jacobian blocks from each constraint. it has this // format: // // l l l 0 a a a 0 \ . // l l l 0 a a a 0 }-- jacobian body 1 block for joint 0 (3 rows) // l l l 0 a a a 0 / // l l l 0 a a a 0 \ . // l l l 0 a a a 0 }-- jacobian body 2 block for joint 0 (3 rows) // l l l 0 a a a 0 / // l l l 0 a a a 0 }--- jacobian body 1 block for joint 1 (1 row) // l l l 0 a a a 0 }--- jacobian body 2 block for joint 1 (1 row) // etc... // // (lll) = linear jacobian data // (aaa) = angular jacobian data // # ifdef TIMING dTimerNow ("create J"); # endif J = (dReal *) ALLOCA (2 * m * 8 * sizeof (dReal)); dSetZero (J, 2 * m * 8); Jinfo = (dxJoint::Info2 *) ALLOCA (nj * sizeof (dxJoint::Info2)); for (i = 0; i < nj; i++) { Jinfo[i].rowskip = 8; Jinfo[i].fps = dRecip (stepsize); Jinfo[i].erp = world->global_erp; Jinfo[i].J1l = J + 2 * 8 * ofs[i]; Jinfo[i].J1a = Jinfo[i].J1l + 4; Jinfo[i].J2l = Jinfo[i].J1l + 8 * info[i].m; Jinfo[i].J2a = Jinfo[i].J2l + 4; Jinfo[i].c = c + ofs[i]; Jinfo[i].cfm = cfm + ofs[i]; Jinfo[i].lo = lo + ofs[i]; Jinfo[i].hi = hi + ofs[i]; Jinfo[i].findex = findex + ofs[i]; //joints[i]->getInfo2 (Jinfo+i); } } dReal *saveFacc = (dReal *) ALLOCA (nb * 4 * sizeof (dReal)); dReal *saveTacc = (dReal *) ALLOCA (nb * 4 * sizeof (dReal)); dReal *globalI = (dReal *) ALLOCA (nb * 12 * sizeof (dReal)); dReal *globalInvI = (dReal *) ALLOCA (nb * 12 * sizeof (dReal)); for (b = 0; b < nb; b++) { for (i = 0; i < 4; i++) { saveFacc[b * 4 + i] = bodies[b]->facc[i]; saveTacc[b * 4 + i] = bodies[b]->tacc[i]; } bodies[b]->tag = b; } for (iter = 0; iter < maxiterations; iter++) { # ifdef TIMING dTimerNow ("applying inertia and gravity"); # endif dReal tmp[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; for (b = 0; b < nb; b++) { body = bodies[b]; // for all bodies, compute the inertia tensor and its inverse in the global // frame, and compute the rotational force and add it to the torque // accumulator. I and invI are vertically stacked 3x4 matrices, one per body. // @@@ check computation of rotational force. // compute inertia tensor in global frame dMULTIPLY2_333 (tmp, body->mass.I, body->posr.R); dMULTIPLY0_333 (globalI + b * 12, body->posr.R, tmp); // compute inverse inertia tensor in global frame dMULTIPLY2_333 (tmp, body->invI, body->posr.R); dMULTIPLY0_333 (globalInvI + b * 12, body->posr.R, tmp); for (i = 0; i < 4; i++) body->tacc[i] = saveTacc[b * 4 + i]; if (body->flags & dxBodyGyroscopic) { // DanielKO: this doesn't look right/efficient, but anyways... // compute rotational force dMULTIPLY0_331 (tmp, globalI + b * 12, body->avel); dCROSS (body->tacc, -=, body->avel, tmp); } // add the gravity force to all bodies if ((body->flags & dxBodyNoGravity) == 0) { body->facc[0] = saveFacc[b * 4 + 0] + body->mass.mass * world->gravity[0]; body->facc[1] = saveFacc[b * 4 + 1] + body->mass.mass * world->gravity[1]; body->facc[2] = saveFacc[b * 4 + 2] + body->mass.mass * world->gravity[2]; body->facc[3] = 0; } else { body->facc[0] = saveFacc[b * 4 + 0]; body->facc[1] = saveFacc[b * 4 + 1]; body->facc[2] = saveFacc[b * 4 + 2]; body->facc[3] = 0; } } #ifdef RANDOM_JOINT_ORDER #ifdef TIMING dTimerNow ("randomizing joint order"); #endif //randomize the order of the joints by looping through the array //and swapping the current joint pointer with a random one before it. for (j = 0; j < nj; j++) { joint = joints[j]; dxJoint::Info1 i1 = info[j]; dxJoint::Info2 i2 = Jinfo[j]; const int r = dRandInt(j+1); dIASSERT (r < nj); joints[j] = joints[r]; info[j] = info[r]; Jinfo[j] = Jinfo[r]; joints[r] = joint; info[r] = i1; Jinfo[r] = i2; } #endif //now iterate through the random ordered joint array we created. for (j = 0; j < nj; j++) { #ifdef TIMING dTimerNow ("setting up joint"); #endif joint = joints[j]; bodyPair[0] = joint->node[0].body; bodyPair[1] = joint->node[1].body; if (bodyPair[0] && (bodyPair[0]->flags & dxBodyDisabled)) bodyPair[0] = 0; if (bodyPair[1] && (bodyPair[1]->flags & dxBodyDisabled)) bodyPair[1] = 0; //if this joint is not connected to any enabled bodies, skip it. if (!bodyPair[0] && !bodyPair[1]) continue; if (bodyPair[0]) { GIPair[0] = globalI + bodyPair[0]->tag * 12; GinvIPair[0] = globalInvI + bodyPair[0]->tag * 12; } if (bodyPair[1]) { GIPair[1] = globalI + bodyPair[1]->tag * 12; GinvIPair[1] = globalInvI + bodyPair[1]->tag * 12; } joints[j]->getInfo2 (Jinfo + j); //dInternalStepIslandFast is an exact copy of the old routine with one //modification: the calculated forces are added back to the facc and tacc //vectors instead of applying them to the bodies and moving them. if (info[j].m > 0) { dInternalStepFast (world, bodyPair, GIPair, GinvIPair, joint, info[j], Jinfo[j], ministep); } } // } # ifdef TIMING dTimerNow ("moving bodies"); # endif //Now we can simulate all the free floating bodies, and move them. for (b = 0; b < nb; b++) { body = bodies[b]; for (i = 0; i < 4; i++) { body->facc[i] *= ministep; body->tacc[i] *= ministep; } //apply torque dMULTIPLYADD0_331 (body->avel, globalInvI + b * 12, body->tacc); //apply force for (i = 0; i < 3; i++) body->lvel[i] += body->invMass * body->facc[i]; //move It! dxStepBody (body, ministep); } } for (b = 0; b < nb; b++) for (j = 0; j < 4; j++) bodies[b]->facc[j] = bodies[b]->tacc[j] = 0; } #ifdef NO_ISLANDS // Since the iterative algorithm doesn't care about islands of bodies, this is a // faster algorithm that just sends it all the joints and bodies in one array. // It's downfall is it's inability to handle disabled bodies as well as the old one. static void processIslandsFast (dxWorld * world, dReal stepsize, int maxiterations) { // nothing to do if no bodies if (world->nb <= 0) return; dInternalHandleAutoDisabling (world,stepsize); # ifdef TIMING dTimerStart ("creating joint and body arrays"); # endif dxBody **bodies, *body; dxJoint **joints, *joint; joints = (dxJoint **) ALLOCA (world->nj * sizeof (dxJoint *)); bodies = (dxBody **) ALLOCA (world->nb * sizeof (dxBody *)); int nj = 0; for (joint = world->firstjoint; joint; joint = (dxJoint *) joint->next) joints[nj++] = joint; int nb = 0; for (body = world->firstbody; body; body = (dxBody *) body->next) bodies[nb++] = body; dInternalStepIslandFast (world, bodies, nb, joints, nj, stepsize, maxiterations); # ifdef TIMING dTimerEnd (); dTimerReport (stdout, 1); # endif } #else //**************************************************************************** // island processing // this groups all joints and bodies in a world into islands. all objects // in an island are reachable by going through connected bodies and joints. // each island can be simulated separately. // note that joints that are not attached to anything will not be included // in any island, an so they do not affect the simulation. // // this function starts new island from unvisited bodies. however, it will // never start a new islands from a disabled body. thus islands of disabled // bodies will not be included in the simulation. disabled bodies are // re-enabled if they are found to be part of an active island. static void processIslandsFast (dxWorld * world, dReal stepsize, int maxiterations) { #ifdef TIMING dTimerStart ("Island Setup"); #endif dxBody *b, *bb, **body; dxJoint *j, **joint; // nothing to do if no bodies if (world->nb <= 0) return; dInternalHandleAutoDisabling (world,stepsize); // make arrays for body and joint lists (for a single island) to go into body = (dxBody **) ALLOCA (world->nb * sizeof (dxBody *)); joint = (dxJoint **) ALLOCA (world->nj * sizeof (dxJoint *)); int bcount = 0; // number of bodies in `body' int jcount = 0; // number of joints in `joint' int tbcount = 0; int tjcount = 0; // set all body/joint tags to 0 for (b = world->firstbody; b; b = (dxBody *) b->next) b->tag = 0; for (j = world->firstjoint; j; j = (dxJoint *) j->next) j->tag = 0; // allocate a stack of unvisited bodies in the island. the maximum size of // the stack can be the lesser of the number of bodies or joints, because // new bodies are only ever added to the stack by going through untagged // joints. all the bodies in the stack must be tagged! int stackalloc = (world->nj < world->nb) ? world->nj : world->nb; dxBody **stack = (dxBody **) ALLOCA (stackalloc * sizeof (dxBody *)); int *autostack = (int *) ALLOCA (stackalloc * sizeof (int)); for (bb = world->firstbody; bb; bb = (dxBody *) bb->next) { #ifdef TIMING dTimerNow ("Island Processing"); #endif // get bb = the next enabled, untagged body, and tag it if (bb->tag || (bb->flags & dxBodyDisabled)) continue; bb->tag = 1; // tag all bodies and joints starting from bb. int stacksize = 0; int autoDepth = autoEnableDepth; b = bb; body[0] = bb; bcount = 1; jcount = 0; goto quickstart; while (stacksize > 0) { b = stack[--stacksize]; // pop body off stack autoDepth = autostack[stacksize]; body[bcount++] = b; // put body on body list quickstart: // traverse and tag all body's joints, add untagged connected bodies // to stack for (dxJointNode * n = b->firstjoint; n; n = n->next) { if (!n->joint->tag) { int thisDepth = autoEnableDepth; n->joint->tag = 1; joint[jcount++] = n->joint; if (n->body && !n->body->tag) { if (n->body->flags & dxBodyDisabled) thisDepth = autoDepth - 1; if (thisDepth < 0) continue; n->body->flags &= ~dxBodyDisabled; n->body->tag = 1; autostack[stacksize] = thisDepth; stack[stacksize++] = n->body; } } } dIASSERT (stacksize <= world->nb); dIASSERT (stacksize <= world->nj); } // now do something with body and joint lists dInternalStepIslandFast (world, body, bcount, joint, jcount, stepsize, maxiterations); // what we've just done may have altered the body/joint tag values. // we must make sure that these tags are nonzero. // also make sure all bodies are in the enabled state. int i; for (i = 0; i < bcount; i++) { body[i]->tag = 1; body[i]->flags &= ~dxBodyDisabled; } for (i = 0; i < jcount; i++) joint[i]->tag = 1; tbcount += bcount; tjcount += jcount; } #ifdef TIMING dMessage(0, "Total joints processed: %i, bodies: %i", tjcount, tbcount); #endif // if debugging, check that all objects (except for disabled bodies, // unconnected joints, and joints that are connected to disabled bodies) // were tagged. # ifndef dNODEBUG for (b = world->firstbody; b; b = (dxBody *) b->next) { if (b->flags & dxBodyDisabled) { if (b->tag) dDebug (0, "disabled body tagged"); } else { if (!b->tag) dDebug (0, "enabled body not tagged"); } } for (j = world->firstjoint; j; j = (dxJoint *) j->next) { if ((j->node[0].body && (j->node[0].body->flags & dxBodyDisabled) == 0) || (j->node[1].body && (j->node[1].body->flags & dxBodyDisabled) == 0)) { if (!j->tag) dDebug (0, "attached enabled joint not tagged"); } else { if (j->tag) dDebug (0, "unattached or disabled joint tagged"); } } # endif # ifdef TIMING dTimerEnd (); dTimerReport (stdout, 1); # endif } #endif void dWorldStepFast1 (dWorldID w, dReal stepsize, int maxiterations) { dUASSERT (w, "bad world argument"); dUASSERT (stepsize > 0, "stepsize must be > 0"); processIslandsFast (w, stepsize, maxiterations); } alien-arena-7.66+dfsg/source/unix/odesrc/array.h0000600000175000017500000001267412161402010020645 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* this comes from the `reuse' library. copy any changes back to the source. * * Variable sized array template. The array is always stored in a contiguous * chunk. The array can be resized. A size increase will cause more memory * to be allocated, and may result in relocation of the array memory. * A size decrease has no effect on the memory allocation. * * Array elements with constructors or destructors are not supported! * But if you must have such elements, here's what to know/do: * - Bitwise copy is used when copying whole arrays. * - When copying individual items (via push(), insert() etc) the `=' * (equals) operator is used. Thus you should define this operator to do * a bitwise copy. You should probably also define the copy constructor. */ #ifndef _ODE_ARRAY_H_ #define _ODE_ARRAY_H_ #include #include "config.h" // this base class has no constructors or destructor, for your convenience. class dArrayBase { protected: int _size; // number of elements in `data' int _anum; // allocated number of elements in `data' void *_data; // array data void _freeAll (int sizeofT); void _setSize (int newsize, int sizeofT); // set the array size to `newsize', allocating more memory if necessary. // if newsize>_anum and is a power of two then this is guaranteed to // set _size and _anum to newsize. public: // not: dArrayBase () { _size=0; _anum=0; _data=0; } int size() const { return _size; } int allocatedSize() const { return _anum; } void * operator new (size_t size); void operator delete (void *ptr, size_t size); void constructor() { _size=0; _anum=0; _data=0; } // if this structure is allocated with malloc() instead of new, you can // call this to set it up. void constructLocalArray (int __anum); // this helper function allows non-reallocating arrays to be constructed // on the stack (or in the heap if necessary). this is something of a // kludge and should be used with extreme care. this function acts like // a constructor - it is called on uninitialized memory that will hold the // Array structure and the data. __anum is the number of elements that // are allocated. the memory MUST be allocated with size: // sizeof(ArrayBase) + __anum*sizeof(T) // arrays allocated this way will never try to reallocate or free the // memory - that's your job. }; template class dArray : public dArrayBase { public: void equals (const dArray &x) { setSize (x.size()); memcpy (_data,x._data,x._size * sizeof(T)); } dArray () { constructor(); } dArray (const dArray &x) { constructor(); equals (x); } ~dArray () { _freeAll(sizeof(T)); } void setSize (int newsize) { _setSize (newsize,sizeof(T)); } T *data() const { return (T*) _data; } T & operator[] (int i) const { return ((T*)_data)[i]; } void operator = (const dArray &x) { equals (x); } void push (const T item) { if (_size < _anum) _size++; else _setSize (_size+1,sizeof(T)); memcpy (&(((T*)_data)[_size-1]), &item, sizeof(T)); } void swap (dArray &x) { int tmp1; void *tmp2; tmp1=_size; _size=x._size; x._size=tmp1; tmp1=_anum; _anum=x._anum; x._anum=tmp1; tmp2=_data; _data=x._data; x._data=tmp2; } // insert the item at the position `i'. if i<0 then add the item to the // start, if i >= size then add the item to the end of the array. void insert (int i, const T item) { if (_size < _anum) _size++; else _setSize (_size+1,sizeof(T)); if (i >= (_size-1)) i = _size-1; // add to end else { if (i < 0) i=0; // add to start int n = _size-1-i; if (n>0) memmove (((T*)_data) + i+1, ((T*)_data) + i, n*sizeof(T)); } ((T*)_data)[i] = item; } void remove (int i) { if (i >= 0 && i < _size) { // passing this test guarantees size>0 int n = _size-1-i; if (n>0) memmove (((T*)_data) + i, ((T*)_data) + i+1, n*sizeof(T)); _size--; } } }; #endif alien-arena-7.66+dfsg/source/unix/odesrc/collision_trimesh_box.cpp0000600000175000017500000012210012161402010024442 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /************************************************************************* * * * Triangle-box collider by Alen Ladavac and Vedran Klanac. * * Ported to ODE by Oskari Nyman. * * * *************************************************************************/ #include #include #include #include #include "collision_util.h" #include "collision_trimesh_internal.h" #if dTRIMESH_ENABLED static void GenerateContact(int in_Flags, dContactGeom* in_Contacts, int in_Stride, dxGeom* in_g1, dxGeom* in_g2, int TriIndex, const dVector3 in_ContactPos, const dVector3 in_Normal, dReal in_Depth, int& OutTriCount); // largest number, double or float #if defined(dSINGLE) #define MAXVALUE FLT_MAX #else #define MAXVALUE DBL_MAX #endif // dVector3 // r=a-b #define SUBTRACT(a,b,r) do{ \ (r)[0]=(a)[0] - (b)[0]; \ (r)[1]=(a)[1] - (b)[1]; \ (r)[2]=(a)[2] - (b)[2]; }while(0) // dVector3 // a=b #define SET(a,b) do{ \ (a)[0]=(b)[0]; \ (a)[1]=(b)[1]; \ (a)[2]=(b)[2]; }while(0) // dMatrix3 // a=b #define SETM(a,b) do{ \ (a)[0]=(b)[0]; \ (a)[1]=(b)[1]; \ (a)[2]=(b)[2]; \ (a)[3]=(b)[3]; \ (a)[4]=(b)[4]; \ (a)[5]=(b)[5]; \ (a)[6]=(b)[6]; \ (a)[7]=(b)[7]; \ (a)[8]=(b)[8]; \ (a)[9]=(b)[9]; \ (a)[10]=(b)[10]; \ (a)[11]=(b)[11]; }while(0) // dVector3 // r=a+b #define ADD(a,b,r) do{ \ (r)[0]=(a)[0] + (b)[0]; \ (r)[1]=(a)[1] + (b)[1]; \ (r)[2]=(a)[2] + (b)[2]; }while(0) // dMatrix3, int, dVector3 // v=column a from m #define GETCOL(m,a,v) do{ \ (v)[0]=(m)[(a)+0]; \ (v)[1]=(m)[(a)+4]; \ (v)[2]=(m)[(a)+8]; }while(0) // dVector4, dVector3 // distance between plane p and point v #define POINTDISTANCE(p,v) \ ( p[0]*v[0] + p[1]*v[1] + p[2]*v[2] + p[3] ) // dVector4, dVector3, dReal // construct plane from normal and d #define CONSTRUCTPLANE(plane,normal,d) do{ \ plane[0]=normal[0];\ plane[1]=normal[1];\ plane[2]=normal[2];\ plane[3]=d; }while(0) // dVector3 // length of vector a #define LENGTHOF(a) \ dSqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]) struct sTrimeshBoxColliderData { sTrimeshBoxColliderData(): m_iBestAxis(0), m_iExitAxis(0), m_ctContacts(0) {} void SetupInitialContext(dxTriMesh *TriMesh, dxGeom *BoxGeom, int Flags, dContactGeom* Contacts, int Stride); int TestCollisionForSingleTriangle(int ctContacts0, int Triint, dVector3 dv[3], bool &bOutFinishSearching); bool _cldTestNormal(dReal fp0, dReal fR, dVector3 vNormal, int iAxis); bool _cldTestFace(dReal fp0, dReal fp1, dReal fp2, dReal fR, dReal fD, dVector3 vNormal, int iAxis); bool _cldTestEdge(dReal fp0, dReal fp1, dReal fR, dReal fD, dVector3 vNormal, int iAxis); bool _cldTestSeparatingAxes(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2); void _cldClipping(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, int TriIndex); void _cldTestOneTriangle(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, int TriIndex); // box data dMatrix3 m_mHullBoxRot; dVector3 m_vHullBoxPos; dVector3 m_vBoxHalfSize; // mesh data dVector3 m_vHullDstPos; // global collider data dVector3 m_vBestNormal; dReal m_fBestDepth; int m_iBestAxis; int m_iExitAxis; dVector3 m_vE0, m_vE1, m_vE2, m_vN; // global info for contact creation int m_iFlags; dContactGeom *m_ContactGeoms; int m_iStride; dxGeom *m_Geom1; dxGeom *m_Geom2; int m_ctContacts; }; // Test normal of mesh face as separating axis for intersection bool sTrimeshBoxColliderData::_cldTestNormal(dReal fp0, dReal fR, dVector3 vNormal, int iAxis) { // calculate overlapping interval of box and triangle dReal fDepth = fR+fp0; // if we do not overlap if ( fDepth<0 ) { // do nothing return false; } // calculate normal's length dReal fLength = LENGTHOF(vNormal); // if long enough if ( fLength > 0.0f ) { dReal fOneOverLength = 1.0f/fLength; // normalize depth fDepth = fDepth*fOneOverLength; // get minimum depth if (fDepth < m_fBestDepth) { m_vBestNormal[0] = -vNormal[0]*fOneOverLength; m_vBestNormal[1] = -vNormal[1]*fOneOverLength; m_vBestNormal[2] = -vNormal[2]*fOneOverLength; m_iBestAxis = iAxis; //dAASSERT(fDepth>=0); m_fBestDepth = fDepth; } } return true; } // Test box axis as separating axis bool sTrimeshBoxColliderData::_cldTestFace(dReal fp0, dReal fp1, dReal fp2, dReal fR, dReal fD, dVector3 vNormal, int iAxis) { dReal fMin, fMax; // find min of triangle interval if ( fp0 < fp1 ) { if ( fp0 < fp2 ) { fMin = fp0; } else { fMin = fp2; } } else { if( fp1 < fp2 ) { fMin = fp1; } else { fMin = fp2; } } // find max of triangle interval if ( fp0 > fp1 ) { if ( fp0 > fp2 ) { fMax = fp0; } else { fMax = fp2; } } else { if( fp1 > fp2 ) { fMax = fp1; } else { fMax = fp2; } } // calculate minimum and maximum depth dReal fDepthMin = fR - fMin; dReal fDepthMax = fMax + fR; // if we dont't have overlapping interval if ( fDepthMin < 0 || fDepthMax < 0 ) { // do nothing return false; } dReal fDepth = 0; // if greater depth is on negative side if ( fDepthMin > fDepthMax ) { // use smaller depth (one from positive side) fDepth = fDepthMax; // flip normal direction vNormal[0] = -vNormal[0]; vNormal[1] = -vNormal[1]; vNormal[2] = -vNormal[2]; fD = -fD; // if greater depth is on positive side } else { // use smaller depth (one from negative side) fDepth = fDepthMin; } // if lower depth than best found so far if (fDepth < m_fBestDepth) { // remember current axis as best axis m_vBestNormal[0] = vNormal[0]; m_vBestNormal[1] = vNormal[1]; m_vBestNormal[2] = vNormal[2]; m_iBestAxis = iAxis; //dAASSERT(fDepth>=0); m_fBestDepth = fDepth; } return true; } // Test cross products of box axis and triangle edges as separating axis bool sTrimeshBoxColliderData::_cldTestEdge(dReal fp0, dReal fp1, dReal fR, dReal fD, dVector3 vNormal, int iAxis) { dReal fMin, fMax; // ===== Begin Patch by Francisco Leon, 2006/10/28 ===== // Fixed Null Normal. This prevents boxes passing // through trimeshes at certain contact angles fMin = vNormal[0] * vNormal[0] + vNormal[1] * vNormal[1] + vNormal[2] * vNormal[2]; if ( fMin <= dEpsilon ) /// THIS NORMAL WOULD BE DANGEROUS return true; // ===== Ending Patch by Francisco Leon ===== // calculate min and max interval values if ( fp0 < fp1 ) { fMin = fp0; fMax = fp1; } else { fMin = fp1; fMax = fp0; } // check if we overlapp dReal fDepthMin = fR - fMin; dReal fDepthMax = fMax + fR; // if we don't overlapp if ( fDepthMin < 0 || fDepthMax < 0 ) { // do nothing return false; } dReal fDepth; // if greater depth is on negative side if ( fDepthMin > fDepthMax ) { // use smaller depth (one from positive side) fDepth = fDepthMax; // flip normal direction vNormal[0] = -vNormal[0]; vNormal[1] = -vNormal[1]; vNormal[2] = -vNormal[2]; fD = -fD; // if greater depth is on positive side } else { // use smaller depth (one from negative side) fDepth = fDepthMin; } // calculate normal's length dReal fLength = LENGTHOF(vNormal); // if long enough if ( fLength > 0.0f ) { // normalize depth dReal fOneOverLength = 1.0f/fLength; fDepth = fDepth*fOneOverLength; fD*=fOneOverLength; // if lower depth than best found so far (favor face over edges) if (fDepth*1.5f < m_fBestDepth) { // remember current axis as best axis m_vBestNormal[0] = vNormal[0]*fOneOverLength; m_vBestNormal[1] = vNormal[1]*fOneOverLength; m_vBestNormal[2] = vNormal[2]*fOneOverLength; m_iBestAxis = iAxis; //dAASSERT(fDepth>=0); m_fBestDepth = fDepth; } } return true; } // clip polygon with plane and generate new polygon points static void _cldClipPolyToPlane( dVector3 avArrayIn[], int ctIn, dVector3 avArrayOut[], int &ctOut, const dVector4 &plPlane ) { // start with no output points ctOut = 0; int i0 = ctIn-1; // for each edge in input polygon for (int i1=0; i1= 0 ) { // emit point avArrayOut[ctOut][0] = avArrayIn[i0][0]; avArrayOut[ctOut][1] = avArrayIn[i0][1]; avArrayOut[ctOut][2] = avArrayIn[i0][2]; ctOut++; } // if points are on different sides if( (fDistance0 > 0 && fDistance1 < 0) || ( fDistance0 < 0 && fDistance1 > 0) ) { // find intersection point of edge and plane dVector3 vIntersectionPoint; vIntersectionPoint[0]= avArrayIn[i0][0] - (avArrayIn[i0][0]-avArrayIn[i1][0])*fDistance0/(fDistance0-fDistance1); vIntersectionPoint[1]= avArrayIn[i0][1] - (avArrayIn[i0][1]-avArrayIn[i1][1])*fDistance0/(fDistance0-fDistance1); vIntersectionPoint[2]= avArrayIn[i0][2] - (avArrayIn[i0][2]-avArrayIn[i1][2])*fDistance0/(fDistance0-fDistance1); // emit intersection point avArrayOut[ctOut][0] = vIntersectionPoint[0]; avArrayOut[ctOut][1] = vIntersectionPoint[1]; avArrayOut[ctOut][2] = vIntersectionPoint[2]; ctOut++; } } } bool sTrimeshBoxColliderData::_cldTestSeparatingAxes(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2) { // reset best axis m_iBestAxis = 0; m_iExitAxis = -1; m_fBestDepth = MAXVALUE; // calculate edges SUBTRACT(v1,v0,m_vE0); SUBTRACT(v2,v0,m_vE1); SUBTRACT(m_vE1,m_vE0,m_vE2); // calculate poly normal dCROSS(m_vN,=,m_vE0,m_vE1); // calculate length of face normal dReal fNLen = LENGTHOF(m_vN); // Even though all triangles might be initially valid, // a triangle may degenerate into a segment after applying // space transformation. if (!fNLen) { return false; } // extract box axes as vectors dVector3 vA0,vA1,vA2; GETCOL(m_mHullBoxRot,0,vA0); GETCOL(m_mHullBoxRot,1,vA1); GETCOL(m_mHullBoxRot,2,vA2); // box halfsizes dReal fa0 = m_vBoxHalfSize[0]; dReal fa1 = m_vBoxHalfSize[1]; dReal fa2 = m_vBoxHalfSize[2]; // calculate relative position between box and triangle dVector3 vD; SUBTRACT(v0,m_vHullBoxPos,vD); dVector3 vL; dReal fp0, fp1, fp2, fR, fD; // Test separating axes for intersection // ************************************************ // Axis 1 - Triangle Normal SET(vL,m_vN); fp0 = dDOT(vL,vD); fp1 = fp0; fp2 = fp0; fR=fa0*dFabs( dDOT(m_vN,vA0) ) + fa1 * dFabs( dDOT(m_vN,vA1) ) + fa2 * dFabs( dDOT(m_vN,vA2) ); if (!_cldTestNormal(fp0, fR, vL, 1)) { m_iExitAxis=1; return false; } // ************************************************ // Test Faces // ************************************************ // Axis 2 - Box X-Axis SET(vL,vA0); fD = dDOT(vL,m_vN)/fNLen; fp0 = dDOT(vL,vD); fp1 = fp0 + dDOT(vA0,m_vE0); fp2 = fp0 + dDOT(vA0,m_vE1); fR = fa0; if (!_cldTestFace(fp0, fp1, fp2, fR, fD, vL, 2)) { m_iExitAxis=2; return false; } // ************************************************ // ************************************************ // Axis 3 - Box Y-Axis SET(vL,vA1); fD = dDOT(vL,m_vN)/fNLen; fp0 = dDOT(vL,vD); fp1 = fp0 + dDOT(vA1,m_vE0); fp2 = fp0 + dDOT(vA1,m_vE1); fR = fa1; if (!_cldTestFace(fp0, fp1, fp2, fR, fD, vL, 3)) { m_iExitAxis=3; return false; } // ************************************************ // ************************************************ // Axis 4 - Box Z-Axis SET(vL,vA2); fD = dDOT(vL,m_vN)/fNLen; fp0 = dDOT(vL,vD); fp1 = fp0 + dDOT(vA2,m_vE0); fp2 = fp0 + dDOT(vA2,m_vE1); fR = fa2; if (!_cldTestFace(fp0, fp1, fp2, fR, fD, vL, 4)) { m_iExitAxis=4; return false; } // ************************************************ // Test Edges // ************************************************ // Axis 5 - Box X-Axis cross Edge0 dCROSS(vL,=,vA0,m_vE0); fD = dDOT(vL,m_vN)/fNLen; fp0 = dDOT(vL,vD); fp1 = fp0; fp2 = fp0 + dDOT(vA0,m_vN); fR = fa1 * dFabs(dDOT(vA2,m_vE0)) + fa2 * dFabs(dDOT(vA1,m_vE0)); if (!_cldTestEdge(fp1, fp2, fR, fD, vL, 5)) { m_iExitAxis=5; return false; } // ************************************************ // ************************************************ // Axis 6 - Box X-Axis cross Edge1 dCROSS(vL,=,vA0,m_vE1); fD = dDOT(vL,m_vN)/fNLen; fp0 = dDOT(vL,vD); fp1 = fp0 - dDOT(vA0,m_vN); fp2 = fp0; fR = fa1 * dFabs(dDOT(vA2,m_vE1)) + fa2 * dFabs(dDOT(vA1,m_vE1)); if (!_cldTestEdge(fp0, fp1, fR, fD, vL, 6)) { m_iExitAxis=6; return false; } // ************************************************ // ************************************************ // Axis 7 - Box X-Axis cross Edge2 dCROSS(vL,=,vA0,m_vE2); fD = dDOT(vL,m_vN)/fNLen; fp0 = dDOT(vL,vD); fp1 = fp0 - dDOT(vA0,m_vN); fp2 = fp0 - dDOT(vA0,m_vN); fR = fa1 * dFabs(dDOT(vA2,m_vE2)) + fa2 * dFabs(dDOT(vA1,m_vE2)); if (!_cldTestEdge(fp0, fp1, fR, fD, vL, 7)) { m_iExitAxis=7; return false; } // ************************************************ // ************************************************ // Axis 8 - Box Y-Axis cross Edge0 dCROSS(vL,=,vA1,m_vE0); fD = dDOT(vL,m_vN)/fNLen; fp0 = dDOT(vL,vD); fp1 = fp0; fp2 = fp0 + dDOT(vA1,m_vN); fR = fa0 * dFabs(dDOT(vA2,m_vE0)) + fa2 * dFabs(dDOT(vA0,m_vE0)); if (!_cldTestEdge(fp0, fp2, fR, fD, vL, 8)) { m_iExitAxis=8; return false; } // ************************************************ // ************************************************ // Axis 9 - Box Y-Axis cross Edge1 dCROSS(vL,=,vA1,m_vE1); fD = dDOT(vL,m_vN)/fNLen; fp0 = dDOT(vL,vD); fp1 = fp0 - dDOT(vA1,m_vN); fp2 = fp0; fR = fa0 * dFabs(dDOT(vA2,m_vE1)) + fa2 * dFabs(dDOT(vA0,m_vE1)); if (!_cldTestEdge(fp0, fp1, fR, fD, vL, 9)) { m_iExitAxis=9; return false; } // ************************************************ // ************************************************ // Axis 10 - Box Y-Axis cross Edge2 dCROSS(vL,=,vA1,m_vE2); fD = dDOT(vL,m_vN)/fNLen; fp0 = dDOT(vL,vD); fp1 = fp0 - dDOT(vA1,m_vN); fp2 = fp0 - dDOT(vA1,m_vN); fR = fa0 * dFabs(dDOT(vA2,m_vE2)) + fa2 * dFabs(dDOT(vA0,m_vE2)); if (!_cldTestEdge(fp0, fp1, fR, fD, vL, 10)) { m_iExitAxis=10; return false; } // ************************************************ // ************************************************ // Axis 11 - Box Z-Axis cross Edge0 dCROSS(vL,=,vA2,m_vE0); fD = dDOT(vL,m_vN)/fNLen; fp0 = dDOT(vL,vD); fp1 = fp0; fp2 = fp0 + dDOT(vA2,m_vN); fR = fa0 * dFabs(dDOT(vA1,m_vE0)) + fa1 * dFabs(dDOT(vA0,m_vE0)); if (!_cldTestEdge(fp0, fp2, fR, fD, vL, 11)) { m_iExitAxis=11; return false; } // ************************************************ // ************************************************ // Axis 12 - Box Z-Axis cross Edge1 dCROSS(vL,=,vA2,m_vE1); fD = dDOT(vL,m_vN)/fNLen; fp0 = dDOT(vL,vD); fp1 = fp0 - dDOT(vA2,m_vN); fp2 = fp0; fR = fa0 * dFabs(dDOT(vA1,m_vE1)) + fa1 * dFabs(dDOT(vA0,m_vE1)); if (!_cldTestEdge(fp0, fp1, fR, fD, vL, 12)) { m_iExitAxis=12; return false; } // ************************************************ // ************************************************ // Axis 13 - Box Z-Axis cross Edge2 dCROSS(vL,=,vA2,m_vE2); fD = dDOT(vL,m_vN)/fNLen; fp0 = dDOT(vL,vD); fp1 = fp0 - dDOT(vA2,m_vN); fp2 = fp0 - dDOT(vA2,m_vN); fR = fa0 * dFabs(dDOT(vA1,m_vE2)) + fa1 * dFabs(dDOT(vA0,m_vE2)); if (!_cldTestEdge(fp0, fp1, fR, fD, vL, 13)) { m_iExitAxis=13; return false; } // ************************************************ return true; } // find two closest points on two lines static bool _cldClosestPointOnTwoLines( dVector3 vPoint1, dVector3 vLenVec1, dVector3 vPoint2, dVector3 vLenVec2, dReal &fvalue1, dReal &fvalue2) { // calculate denominator dVector3 vp; SUBTRACT(vPoint2,vPoint1,vp); dReal fuaub = dDOT(vLenVec1,vLenVec2); dReal fq1 = dDOT(vLenVec1,vp); dReal fq2 = -dDOT(vLenVec2,vp); dReal fd = 1.0f - fuaub * fuaub; // if denominator is positive if (fd > 0.0f) { // calculate points of closest approach fd = 1.0f/fd; fvalue1 = (fq1 + fuaub*fq2)*fd; fvalue2 = (fuaub*fq1 + fq2)*fd; return true; // otherwise } else { // lines are parallel fvalue1 = 0.0f; fvalue2 = 0.0f; return false; } } // clip and generate contacts void sTrimeshBoxColliderData::_cldClipping(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, int TriIndex) { dIASSERT( !(m_iFlags & CONTACTS_UNIMPORTANT) || m_ctContacts < (m_iFlags & NUMC_MASK) ); // Do not call the function if there is no room to store results // if we have edge/edge intersection if (m_iBestAxis > 4 ) { dVector3 vub,vPb,vPa; SET(vPa,m_vHullBoxPos); // calculate point on box edge for( int i=0; i<3; i++) { dVector3 vRotCol; GETCOL(m_mHullBoxRot,i,vRotCol); dReal fSign = dDOT(m_vBestNormal,vRotCol) > 0 ? 1.0f : -1.0f; vPa[0] += fSign * m_vBoxHalfSize[i] * vRotCol[0]; vPa[1] += fSign * m_vBoxHalfSize[i] * vRotCol[1]; vPa[2] += fSign * m_vBoxHalfSize[i] * vRotCol[2]; } int iEdge = (m_iBestAxis-5)%3; // decide which edge is on triangle if ( iEdge == 0 ) { SET(vPb,v0); SET(vub,m_vE0); } else if ( iEdge == 1) { SET(vPb,v2); SET(vub,m_vE1); } else { SET(vPb,v1); SET(vub,m_vE2); } // setup direction parameter for face edge dNormalize3(vub); dReal fParam1, fParam2; // setup direction parameter for box edge dVector3 vua; int col=(m_iBestAxis-5)/3; GETCOL(m_mHullBoxRot,col,vua); // find two closest points on both edges _cldClosestPointOnTwoLines( vPa, vua, vPb, vub, fParam1, fParam2 ); vPa[0] += vua[0]*fParam1; vPa[1] += vua[1]*fParam1; vPa[2] += vua[2]*fParam1; vPb[0] += vub[0]*fParam2; vPb[1] += vub[1]*fParam2; vPb[2] += vub[2]*fParam2; // calculate collision point dVector3 vPntTmp; ADD(vPa,vPb,vPntTmp); vPntTmp[0]*=0.5f; vPntTmp[1]*=0.5f; vPntTmp[2]*=0.5f; // generate contact point between two closest points #if 0 //#ifdef ORIG -- if to use conditional define, GenerateContact must be moved into #else dContactGeom* Contact = SAFECONTACT(m_iFlags, m_ContactGeoms, m_ctContacts, m_iStride); Contact->depth = m_fBestDepth; SET(Contact->normal,m_vBestNormal); SET(Contact->pos,vPntTmp); Contact->g1 = Geom1; Contact->g2 = Geom2; Contact->side1 = TriIndex; Contact->side2 = -1; m_ctContacts++; #endif GenerateContact(m_iFlags, m_ContactGeoms, m_iStride, m_Geom1, m_Geom2, TriIndex, vPntTmp, m_vBestNormal, m_fBestDepth, m_ctContacts); // if triangle is the referent face then clip box to triangle face } else if (m_iBestAxis == 1) { dVector3 vNormal2; vNormal2[0]=-m_vBestNormal[0]; vNormal2[1]=-m_vBestNormal[1]; vNormal2[2]=-m_vBestNormal[2]; // vNr is normal in box frame, pointing from triangle to box dMatrix3 mTransposed; mTransposed[0*4+0]=m_mHullBoxRot[0*4+0]; mTransposed[0*4+1]=m_mHullBoxRot[1*4+0]; mTransposed[0*4+2]=m_mHullBoxRot[2*4+0]; mTransposed[1*4+0]=m_mHullBoxRot[0*4+1]; mTransposed[1*4+1]=m_mHullBoxRot[1*4+1]; mTransposed[1*4+2]=m_mHullBoxRot[2*4+1]; mTransposed[2*4+0]=m_mHullBoxRot[0*4+2]; mTransposed[2*4+1]=m_mHullBoxRot[1*4+2]; mTransposed[2*4+2]=m_mHullBoxRot[2*4+2]; dVector3 vNr; vNr[0]=mTransposed[0*4+0]*vNormal2[0]+ mTransposed[0*4+1]*vNormal2[1]+ mTransposed[0*4+2]*vNormal2[2]; vNr[1]=mTransposed[1*4+0]*vNormal2[0]+ mTransposed[1*4+1]*vNormal2[1]+ mTransposed[1*4+2]*vNormal2[2]; vNr[2]=mTransposed[2*4+0]*vNormal2[0]+ mTransposed[2*4+1]*vNormal2[1]+ mTransposed[2*4+2]*vNormal2[2]; dVector3 vAbsNormal; vAbsNormal[0] = dFabs( vNr[0] ); vAbsNormal[1] = dFabs( vNr[1] ); vAbsNormal[2] = dFabs( vNr[2] ); // get closest face from box int iB0, iB1, iB2; if (vAbsNormal[1] > vAbsNormal[0]) { if (vAbsNormal[1] > vAbsNormal[2]) { iB1 = 0; iB0 = 1; iB2 = 2; } else { iB1 = 0; iB2 = 1; iB0 = 2; } } else { if (vAbsNormal[0] > vAbsNormal[2]) { iB0 = 0; iB1 = 1; iB2 = 2; } else { iB1 = 0; iB2 = 1; iB0 = 2; } } // Here find center of box face we are going to project dVector3 vCenter; dVector3 vRotCol; GETCOL(m_mHullBoxRot,iB0,vRotCol); if (vNr[iB0] > 0) { vCenter[0] = m_vHullBoxPos[0] - v0[0] - m_vBoxHalfSize[iB0] * vRotCol[0]; vCenter[1] = m_vHullBoxPos[1] - v0[1] - m_vBoxHalfSize[iB0] * vRotCol[1]; vCenter[2] = m_vHullBoxPos[2] - v0[2] - m_vBoxHalfSize[iB0] * vRotCol[2]; } else { vCenter[0] = m_vHullBoxPos[0] - v0[0] + m_vBoxHalfSize[iB0] * vRotCol[0]; vCenter[1] = m_vHullBoxPos[1] - v0[1] + m_vBoxHalfSize[iB0] * vRotCol[1]; vCenter[2] = m_vHullBoxPos[2] - v0[2] + m_vBoxHalfSize[iB0] * vRotCol[2]; } // Here find 4 corner points of box dVector3 avPoints[4]; dVector3 vRotCol2; GETCOL(m_mHullBoxRot,iB1,vRotCol); GETCOL(m_mHullBoxRot,iB2,vRotCol2); for(int x=0;x<3;x++) { avPoints[0][x] = vCenter[x] + (m_vBoxHalfSize[iB1] * vRotCol[x]) - (m_vBoxHalfSize[iB2] * vRotCol2[x]); avPoints[1][x] = vCenter[x] - (m_vBoxHalfSize[iB1] * vRotCol[x]) - (m_vBoxHalfSize[iB2] * vRotCol2[x]); avPoints[2][x] = vCenter[x] - (m_vBoxHalfSize[iB1] * vRotCol[x]) + (m_vBoxHalfSize[iB2] * vRotCol2[x]); avPoints[3][x] = vCenter[x] + (m_vBoxHalfSize[iB1] * vRotCol[x]) + (m_vBoxHalfSize[iB2] * vRotCol2[x]); } // clip Box face with 4 planes of triangle (1 face plane, 3 egde planes) dVector3 avTempArray1[9]; dVector3 avTempArray2[9]; dVector4 plPlane; int iTempCnt1=0; int iTempCnt2=0; // zeroify vectors - necessary? for(int i=0; i<9; i++) { avTempArray1[i][0]=0; avTempArray1[i][1]=0; avTempArray1[i][2]=0; avTempArray2[i][0]=0; avTempArray2[i][1]=0; avTempArray2[i][2]=0; } // Normal plane dVector3 vTemp; vTemp[0]=-m_vN[0]; vTemp[1]=-m_vN[1]; vTemp[2]=-m_vN[2]; dNormalize3(vTemp); CONSTRUCTPLANE(plPlane,vTemp,0); _cldClipPolyToPlane( avPoints, 4, avTempArray1, iTempCnt1, plPlane ); // Plane p0 dVector3 vTemp2; SUBTRACT(v1,v0,vTemp2); dCROSS(vTemp,=,m_vN,vTemp2); dNormalize3(vTemp); CONSTRUCTPLANE(plPlane,vTemp,0); _cldClipPolyToPlane( avTempArray1, iTempCnt1, avTempArray2, iTempCnt2, plPlane ); // Plane p1 SUBTRACT(v2,v1,vTemp2); dCROSS(vTemp,=,m_vN,vTemp2); dNormalize3(vTemp); SUBTRACT(v0,v2,vTemp2); CONSTRUCTPLANE(plPlane,vTemp,dDOT(vTemp2,vTemp)); _cldClipPolyToPlane( avTempArray2, iTempCnt2, avTempArray1, iTempCnt1, plPlane ); // Plane p2 SUBTRACT(v0,v2,vTemp2); dCROSS(vTemp,=,m_vN,vTemp2); dNormalize3(vTemp); CONSTRUCTPLANE(plPlane,vTemp,0); _cldClipPolyToPlane( avTempArray1, iTempCnt1, avTempArray2, iTempCnt2, plPlane ); // END of clipping polygons // for each generated contact point for ( int i=0; i 0) { fTempDepth = 0; } dVector3 vPntTmp; ADD(avTempArray2[i],v0,vPntTmp); #if 0 //#ifdef ORIG -- if to use conditional define, GenerateContact must be moved into #else dContactGeom* Contact = SAFECONTACT(m_iFlags, m_ContactGeoms, m_ctContacts, m_iStride); Contact->depth = -fTempDepth; SET(Contact->normal,m_vBestNormal); SET(Contact->pos,vPntTmp); Contact->g1 = Geom1; Contact->g2 = Geom2; Contact->side1 = TriIndex; Contact->side2 = -1; m_ctContacts++; #endif GenerateContact(m_iFlags, m_ContactGeoms, m_iStride, m_Geom1, m_Geom2, TriIndex, vPntTmp, m_vBestNormal, -fTempDepth, m_ctContacts); if ((m_ctContacts | CONTACTS_UNIMPORTANT) == (m_iFlags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { break; } } //dAASSERT(m_ctContacts>0); // if box face is the referent face, then clip triangle on box face } else { // 2 <= if iBestAxis <= 4 // get normal of box face dVector3 vNormal2; SET(vNormal2,m_vBestNormal); // get indices of box axes in correct order int iA0,iA1,iA2; iA0 = m_iBestAxis-2; if ( iA0 == 0 ) { iA1 = 1; iA2 = 2; } else if ( iA0 == 1 ) { iA1 = 0; iA2 = 2; } else { iA1 = 0; iA2 = 1; } dVector3 avPoints[3]; // calculate triangle vertices in box frame SUBTRACT(v0,m_vHullBoxPos,avPoints[0]); SUBTRACT(v1,m_vHullBoxPos,avPoints[1]); SUBTRACT(v2,m_vHullBoxPos,avPoints[2]); // CLIP Polygons // define temp data for clipping dVector3 avTempArray1[9]; dVector3 avTempArray2[9]; int iTempCnt1, iTempCnt2; // zeroify vectors - necessary? for(int i=0; i<9; i++) { avTempArray1[i][0]=0; avTempArray1[i][1]=0; avTempArray1[i][2]=0; avTempArray2[i][0]=0; avTempArray2[i][1]=0; avTempArray2[i][2]=0; } // clip triangle with 5 box planes (1 face plane, 4 edge planes) dVector4 plPlane; // Normal plane dVector3 vTemp; vTemp[0]=-vNormal2[0]; vTemp[1]=-vNormal2[1]; vTemp[2]=-vNormal2[2]; CONSTRUCTPLANE(plPlane,vTemp,m_vBoxHalfSize[iA0]); _cldClipPolyToPlane( avPoints, 3, avTempArray1, iTempCnt1, plPlane ); // Plane p0 GETCOL(m_mHullBoxRot,iA1,vTemp); CONSTRUCTPLANE(plPlane,vTemp,m_vBoxHalfSize[iA1]); _cldClipPolyToPlane( avTempArray1, iTempCnt1, avTempArray2, iTempCnt2, plPlane ); // Plane p1 GETCOL(m_mHullBoxRot,iA1,vTemp); vTemp[0]=-vTemp[0]; vTemp[1]=-vTemp[1]; vTemp[2]=-vTemp[2]; CONSTRUCTPLANE(plPlane,vTemp,m_vBoxHalfSize[iA1]); _cldClipPolyToPlane( avTempArray2, iTempCnt2, avTempArray1, iTempCnt1, plPlane ); // Plane p2 GETCOL(m_mHullBoxRot,iA2,vTemp); CONSTRUCTPLANE(plPlane,vTemp,m_vBoxHalfSize[iA2]); _cldClipPolyToPlane( avTempArray1, iTempCnt1, avTempArray2, iTempCnt2, plPlane ); // Plane p3 GETCOL(m_mHullBoxRot,iA2,vTemp); vTemp[0]=-vTemp[0]; vTemp[1]=-vTemp[1]; vTemp[2]=-vTemp[2]; CONSTRUCTPLANE(plPlane,vTemp,m_vBoxHalfSize[iA2]); _cldClipPolyToPlane( avTempArray2, iTempCnt2, avTempArray1, iTempCnt1, plPlane ); // for each generated contact point for ( int i=0; i 0) { fTempDepth = 0; } // generate contact data dVector3 vPntTmp; ADD(avTempArray1[i],m_vHullBoxPos,vPntTmp); #if 0 //#ifdef ORIG -- if to use conditional define, GenerateContact must be moved into #else dContactGeom* Contact = SAFECONTACT(m_iFlags, m_ContactGeoms, m_ctContacts, m_iStride); Contact->depth = -fTempDepth; SET(Contact->normal,m_vBestNormal); SET(Contact->pos,vPntTmp); Contact->g1 = Geom1; Contact->g2 = Geom2; Contact->side1 = TriIndex; Contact->side2 = -1; m_ctContacts++; #endif GenerateContact(m_iFlags, m_ContactGeoms, m_iStride, m_Geom1, m_Geom2, TriIndex, vPntTmp, m_vBestNormal, -fTempDepth, m_ctContacts); if ((m_ctContacts | CONTACTS_UNIMPORTANT) == (m_iFlags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { break; } } //dAASSERT(m_ctContacts>0); } } // test one mesh triangle on intersection with given box void sTrimeshBoxColliderData::_cldTestOneTriangle(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, int TriIndex)//, void *pvUser) { // do intersection test and find best separating axis if(!_cldTestSeparatingAxes(v0, v1, v2)) { // if not found do nothing return; } // if best separation axis is not found if (m_iBestAxis == 0) { // this should not happen (we should already exit in that case) //dMessage (0, "best separation axis not found"); // do nothing return; } _cldClipping(v0, v1, v2, TriIndex); } void sTrimeshBoxColliderData::SetupInitialContext(dxTriMesh *TriMesh, dxGeom *BoxGeom, int Flags, dContactGeom* Contacts, int Stride) { // get source hull position, orientation and half size const dMatrix3& mRotBox=*(const dMatrix3*)dGeomGetRotation(BoxGeom); const dVector3& vPosBox=*(const dVector3*)dGeomGetPosition(BoxGeom); // to global SETM(m_mHullBoxRot,mRotBox); SET(m_vHullBoxPos,vPosBox); dGeomBoxGetLengths(BoxGeom, m_vBoxHalfSize); m_vBoxHalfSize[0] *= 0.5f; m_vBoxHalfSize[1] *= 0.5f; m_vBoxHalfSize[2] *= 0.5f; // get destination hull position and orientation const dVector3& vPosMesh=*(const dVector3*)dGeomGetPosition(TriMesh); // to global SET(m_vHullDstPos,vPosMesh); // global info for contact creation m_ctContacts = 0; m_iStride=Stride; m_iFlags=Flags; m_ContactGeoms=Contacts; m_Geom1=TriMesh; m_Geom2=BoxGeom; // reset stuff m_fBestDepth = MAXVALUE; m_vBestNormal[0]=0; m_vBestNormal[1]=0; m_vBestNormal[2]=0; } int sTrimeshBoxColliderData::TestCollisionForSingleTriangle(int ctContacts0, int Triint, dVector3 dv[3], bool &bOutFinishSearching) { // test this triangle _cldTestOneTriangle(dv[0],dv[1],dv[2],Triint); // fill-in tri index for generated contacts for (; ctContacts0 < m_ctContacts; ctContacts0++) { dContactGeom* pContact = SAFECONTACT(m_iFlags, m_ContactGeoms, ctContacts0, m_iStride); pContact->side1 = Triint; pContact->side2 = -1; } /* NOTE by Oleh_Derevenko: The function continues checking triangles after maximal number of contacts is reached because it selects maximal penetration depths. See also comments in GenerateContact() */ bOutFinishSearching = ((m_ctContacts | CONTACTS_UNIMPORTANT) == (m_iFlags & (NUMC_MASK | CONTACTS_UNIMPORTANT))); return ctContacts0; } // OPCODE version of box to mesh collider #if dTRIMESH_OPCODE static void dQueryBTLPotentialCollisionTriangles(OBBCollider &Collider, const sTrimeshBoxColliderData &cData, dxTriMesh *TriMesh, dxGeom *BoxGeom, OBBCache &BoxCache) { // get source hull position, orientation and half size const dMatrix3& mRotBox=*(const dMatrix3*)dGeomGetRotation(BoxGeom); const dVector3& vPosBox=*(const dVector3*)dGeomGetPosition(BoxGeom); // Make OBB OBB Box; Box.mCenter.x = vPosBox[0]; Box.mCenter.y = vPosBox[1]; Box.mCenter.z = vPosBox[2]; // It is a potential issue to explicitly cast to float // if custom width floating point type is introduced in OPCODE. // It is necessary to make a typedef and cast to it // (e.g. typedef float opc_float;) // However I'm not sure in what header it should be added. Box.mExtents.x = /*(float)*/cData.m_vBoxHalfSize[0]; Box.mExtents.y = /*(float)*/cData.m_vBoxHalfSize[1]; Box.mExtents.z = /*(float)*/cData.m_vBoxHalfSize[2]; Box.mRot.m[0][0] = /*(float)*/mRotBox[0]; Box.mRot.m[1][0] = /*(float)*/mRotBox[1]; Box.mRot.m[2][0] = /*(float)*/mRotBox[2]; Box.mRot.m[0][1] = /*(float)*/mRotBox[4]; Box.mRot.m[1][1] = /*(float)*/mRotBox[5]; Box.mRot.m[2][1] = /*(float)*/mRotBox[6]; Box.mRot.m[0][2] = /*(float)*/mRotBox[8]; Box.mRot.m[1][2] = /*(float)*/mRotBox[9]; Box.mRot.m[2][2] = /*(float)*/mRotBox[10]; Matrix4x4 amatrix; Matrix4x4 BoxMatrix = MakeMatrix(vPosBox, mRotBox, amatrix); Matrix4x4 InvBoxMatrix; InvertPRMatrix(InvBoxMatrix, BoxMatrix); // get destination hull position and orientation const dMatrix3& mRotMesh=*(const dMatrix3*)dGeomGetRotation(TriMesh); const dVector3& vPosMesh=*(const dVector3*)dGeomGetPosition(TriMesh); // TC results if (TriMesh->doBoxTC) { dxTriMesh::BoxTC* BoxTC = 0; for (int i = 0; i < TriMesh->BoxTCCache.size(); i++){ if (TriMesh->BoxTCCache[i].Geom == BoxGeom){ BoxTC = &TriMesh->BoxTCCache[i]; break; } } if (!BoxTC){ TriMesh->BoxTCCache.push(dxTriMesh::BoxTC()); BoxTC = &TriMesh->BoxTCCache[TriMesh->BoxTCCache.size() - 1]; BoxTC->Geom = BoxGeom; BoxTC->FatCoeff = 1.1f; // Pierre recommends this, instead of 1.0 } // Intersect Collider.SetTemporalCoherence(true); Collider.Collide(*BoxTC, Box, TriMesh->Data->BVTree, null, &MakeMatrix(vPosMesh, mRotMesh, amatrix)); } else { Collider.SetTemporalCoherence(false); Collider.Collide(BoxCache, Box, TriMesh->Data->BVTree, null, &MakeMatrix(vPosMesh, mRotMesh, amatrix)); } } int dCollideBTL(dxGeom* g1, dxGeom* BoxGeom, int Flags, dContactGeom* Contacts, int Stride){ dIASSERT (Stride >= (int)sizeof(dContactGeom)); dIASSERT (g1->type == dTriMeshClass); dIASSERT (BoxGeom->type == dBoxClass); dIASSERT ((Flags & NUMC_MASK) >= 1); dxTriMesh* TriMesh = (dxTriMesh*)g1; sTrimeshBoxColliderData cData; cData.SetupInitialContext(TriMesh, BoxGeom, Flags, Contacts, Stride); const unsigned uiTLSKind = TriMesh->getParentSpaceTLSKind(); dIASSERT(uiTLSKind == BoxGeom->getParentSpaceTLSKind()); // The colliding spaces must use matching cleanup method TrimeshCollidersCache *pccColliderCache = GetTrimeshCollidersCache(uiTLSKind); OBBCollider& Collider = pccColliderCache->_OBBCollider; dQueryBTLPotentialCollisionTriangles(Collider, cData, TriMesh, BoxGeom, pccColliderCache->defaultBoxCache); if (!Collider.GetContactStatus()) { // no collision occurred return 0; } // Retrieve data int TriCount = Collider.GetNbTouchedPrimitives(); const int* Triangles = (const int*)Collider.GetTouchedPrimitives(); if (TriCount != 0){ if (TriMesh->ArrayCallback != null){ TriMesh->ArrayCallback(TriMesh, BoxGeom, Triangles, TriCount); } // get destination hull position and orientation const dMatrix3& mRotMesh=*(const dMatrix3*)dGeomGetRotation(TriMesh); const dVector3& vPosMesh=*(const dVector3*)dGeomGetPosition(TriMesh); int ctContacts0 = 0; // loop through all intersecting triangles for (int i = 0; i < TriCount; i++){ const int Triint = Triangles[i]; if (!Callback(TriMesh, BoxGeom, Triint)) continue; dVector3 dv[3]; FetchTriangle(TriMesh, Triint, vPosMesh, mRotMesh, dv); bool bFinishSearching; ctContacts0 = cData.TestCollisionForSingleTriangle(ctContacts0, Triint, dv, bFinishSearching); if (bFinishSearching) { break; } } } return cData.m_ctContacts; } #endif // GIMPACT version of box to mesh collider #if dTRIMESH_GIMPACT int dCollideBTL(dxGeom* g1, dxGeom* BoxGeom, int Flags, dContactGeom* Contacts, int Stride) { dIASSERT (Stride >= (int)sizeof(dContactGeom)); dIASSERT (g1->type == dTriMeshClass); dIASSERT (BoxGeom->type == dBoxClass); dIASSERT ((Flags & NUMC_MASK) >= 1); dxTriMesh* TriMesh = (dxTriMesh*)g1; g1 -> recomputeAABB(); BoxGeom -> recomputeAABB(); sTrimeshBoxColliderData cData; cData.SetupInitialContext(TriMesh, BoxGeom, Flags, Contacts, Stride); //*****at first , collide box aabb******// GIM_TRIMESH * ptrimesh = &TriMesh->m_collision_trimesh; aabb3f test_aabb; test_aabb.minX = BoxGeom->aabb[0]; test_aabb.maxX = BoxGeom->aabb[1]; test_aabb.minY = BoxGeom->aabb[2]; test_aabb.maxY = BoxGeom->aabb[3]; test_aabb.minZ = BoxGeom->aabb[4]; test_aabb.maxZ = BoxGeom->aabb[5]; GDYNAMIC_ARRAY collision_result; GIM_CREATE_BOXQUERY_LIST(collision_result); gim_aabbset_box_collision(&test_aabb, &ptrimesh->m_aabbset , &collision_result); if(collision_result.m_size==0) { GIM_DYNARRAY_DESTROY(collision_result); return 0; } //*****Set globals for box collision******// //collide triangles GUINT32 * boxesresult = GIM_DYNARRAY_POINTER(GUINT32,collision_result); gim_trimesh_locks_work_data(ptrimesh); int ctContacts0 = 0; for(unsigned int i=0;ipos[j]; if (dDOT(diff, diff) < dEpsilon) { // same normal? if (dFabs(dDOT(in_Normal, Contact->normal)) > (REAL(1.0)-dEpsilon)) { if (in_Depth > Contact->depth) Contact->depth = in_Depth; duplicate = true; /* NOTE by Oleh_Derevenko: There may be a case when two normals are close to each other but not duplicate while third normal is detected to be duplicate for both of them. This is the only reason I can think of, there is no "break" statement. Perhaps author considered it to be logical that the third normal would replace the depth in both of initial contacts. However, I consider it a questionable practice which should not be applied without deep understanding of underlaying physics. Even more, is this situation with close normal triplet acceptable at all? Should not be two initial contacts reduced to one (replaced with the latter)? If you know the answers for these questions, you may want to change this code. See the same statement in GenerateContact() of collision_trimesh_trimesh.cpp */ } } } if (duplicate || OutTriCount == (in_Flags & NUMC_MASK)) { break; } } else { dIASSERT(OutTriCount < (in_Flags & NUMC_MASK)); } // Add a new contact Contact = SAFECONTACT(in_Flags, in_Contacts, OutTriCount, in_Stride); Contact->pos[0] = in_ContactPos[0]; Contact->pos[1] = in_ContactPos[1]; Contact->pos[2] = in_ContactPos[2]; Contact->pos[3] = 0.0; Contact->normal[0] = in_Normal[0]; Contact->normal[1] = in_Normal[1]; Contact->normal[2] = in_Normal[2]; Contact->normal[3] = 0.0; Contact->depth = in_Depth; Contact->g1 = in_g1; Contact->g2 = in_g2; Contact->side1 = TriIndex; Contact->side2 = -1; OutTriCount++; } while (false); } #endif // dTRIMESH_ENABLED alien-arena-7.66+dfsg/source/unix/odesrc/export-dif.cpp0000600000175000017500000004231612161402010022137 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* * Export a DIF (Dynamics Interchange Format) file. */ // @@@ TODO: // * export all spaces, and geoms in spaces, not just ones attached to bodies // (separate export function?) // * say the space each geom is in, so reader can construct space heirarchy // * limot --> separate out into limits and motors? // * make sure ODE-specific parameters divided out #include "ode/ode.h" #include "objects.h" #include "joints/joints.h" #include "collision_kernel.h" //*************************************************************************** // utility struct PrintingContext { FILE *file; // file to write to int precision; // digits of precision to print int indent; // number of levels of indent void printIndent(); void printReal (dReal x); void print (const char *name, int x); void print (const char *name, dReal x); void print (const char *name, const dReal *x, int n=3); void print (const char *name, const char *x=0); void printNonzero (const char *name, dReal x); void printNonzero (const char *name, const dReal x[3]); }; void PrintingContext::printIndent() { for (int i=0; i= 0) { c.printIndent(); fprintf (c.file,"limit%d = {\n",num); } else { c.print ("limit = {"); } c.indent++; c.print ("low_stop",limot.lostop); c.print ("high_stop",limot.histop); c.printNonzero ("bounce",limot.bounce); c.print ("ODE = {"); c.indent++; c.printNonzero ("stop_erp",limot.stop_erp); c.printNonzero ("stop_cfm",limot.stop_cfm); c.indent--; c.print ("},"); c.indent--; c.print ("},"); if (num >= 0) { c.printIndent(); fprintf (c.file,"motor%d = {\n",num); } else { c.print ("motor = {"); } c.indent++; c.printNonzero ("vel",limot.vel); c.printNonzero ("fmax",limot.fmax); c.print ("ODE = {"); c.indent++; c.printNonzero ("fudge_factor",limot.fudge_factor); c.printNonzero ("normal_cfm",limot.normal_cfm); c.indent--; c.print ("},"); c.indent--; c.print ("},"); } static const char *getJointName (dxJoint *j) { switch (j->type()) { case dJointTypeBall: return "ball"; case dJointTypeHinge: return "hinge"; case dJointTypeSlider: return "slider"; case dJointTypeContact: return "contact"; case dJointTypeUniversal: return "universal"; case dJointTypeHinge2: return "ODE_hinge2"; case dJointTypeFixed: return "fixed"; case dJointTypeNull: return "null"; case dJointTypeAMotor: return "ODE_angular_motor"; case dJointTypeLMotor: return "ODE_linear_motor"; case dJointTypePR: return "PR"; case dJointTypePU: return "PU"; case dJointTypePiston: return "piston"; default: return "unknown"; } } static void printBall (PrintingContext &c, dxJoint *j) { dxJointBall *b = (dxJointBall*) j; c.print ("anchor1",b->anchor1); c.print ("anchor2",b->anchor2); } static void printHinge (PrintingContext &c, dxJoint *j) { dxJointHinge *h = (dxJointHinge*) j; c.print ("anchor1",h->anchor1); c.print ("anchor2",h->anchor2); c.print ("axis1",h->axis1); c.print ("axis2",h->axis2); c.print ("qrel",h->qrel,4); printLimot (c,h->limot,-1); } static void printSlider (PrintingContext &c, dxJoint *j) { dxJointSlider *s = (dxJointSlider*) j; c.print ("axis1",s->axis1); c.print ("qrel",s->qrel,4); c.print ("offset",s->offset); printLimot (c,s->limot,-1); } static void printContact (PrintingContext &c, dxJoint *j) { dxJointContact *ct = (dxJointContact*) j; int mode = ct->contact.surface.mode; c.print ("pos",ct->contact.geom.pos); c.print ("normal",ct->contact.geom.normal); c.print ("depth",ct->contact.geom.depth); //@@@ may want to write the geoms g1 and g2 that are involved, for debugging. // to do this we must have written out all geoms in all spaces, not just // geoms that are attached to bodies. c.print ("mu",ct->contact.surface.mu); if (mode & dContactMu2) c.print ("mu2",ct->contact.surface.mu2); if (mode & dContactBounce) c.print ("bounce",ct->contact.surface.bounce); if (mode & dContactBounce) c.print ("bounce_vel",ct->contact.surface.bounce_vel); if (mode & dContactSoftERP) c.print ("soft_ERP",ct->contact.surface.soft_erp); if (mode & dContactSoftCFM) c.print ("soft_CFM",ct->contact.surface.soft_cfm); if (mode & dContactMotion1) c.print ("motion1",ct->contact.surface.motion1); if (mode & dContactMotion2) c.print ("motion2",ct->contact.surface.motion2); if (mode & dContactSlip1) c.print ("slip1",ct->contact.surface.slip1); if (mode & dContactSlip2) c.print ("slip2",ct->contact.surface.slip2); int fa = 0; // friction approximation code if (mode & dContactApprox1_1) fa |= 1; if (mode & dContactApprox1_2) fa |= 2; if (fa) c.print ("friction_approximation",fa); if (mode & dContactFDir1) c.print ("fdir1",ct->contact.fdir1); } static void printUniversal (PrintingContext &c, dxJoint *j) { dxJointUniversal *u = (dxJointUniversal*) j; c.print ("anchor1",u->anchor1); c.print ("anchor2",u->anchor2); c.print ("axis1",u->axis1); c.print ("axis2",u->axis2); c.print ("qrel1",u->qrel1,4); c.print ("qrel2",u->qrel2,4); printLimot (c,u->limot1,1); printLimot (c,u->limot2,2); } static void printHinge2 (PrintingContext &c, dxJoint *j) { dxJointHinge2 *h = (dxJointHinge2*) j; c.print ("anchor1",h->anchor1); c.print ("anchor2",h->anchor2); c.print ("axis1",h->axis1); c.print ("axis2",h->axis2); c.print ("v1",h->v1); //@@@ much better to write out 'qrel' here, if it's available c.print ("v2",h->v2); c.print ("susp_erp",h->susp_erp); c.print ("susp_cfm",h->susp_cfm); printLimot (c,h->limot1,1); printLimot (c,h->limot2,2); } static void printPR (PrintingContext &c, dxJoint *j) { dxJointPR *pr = (dxJointPR*) j; c.print ("anchor2",pr->anchor2); c.print ("axisR1",pr->axisR1); c.print ("axisR2",pr->axisR2); c.print ("axisP1",pr->axisP1); c.print ("qrel",pr->qrel,4); c.print ("offset",pr->offset); printLimot (c,pr->limotP,1); printLimot (c,pr->limotR,2); } static void printPU (PrintingContext &c, dxJoint *j) { dxJointPU *pu = (dxJointPU*) j; c.print ("anchor1",pu->anchor1); c.print ("anchor2",pu->anchor2); c.print ("axis1",pu->axis1); c.print ("axis2",pu->axis2); c.print ("axisP",pu->axisP1); c.print ("qrel1",pu->qrel1,4); c.print ("qrel2",pu->qrel2,4); printLimot (c,pu->limot1,1); printLimot (c,pu->limot2,2); printLimot (c,pu->limotP,3); } static void printPiston (PrintingContext &c, dxJoint *j) { dxJointPiston *rap = (dxJointPiston*) j; c.print ("anchor1",rap->anchor1); c.print ("anchor2",rap->anchor2); c.print ("axis1",rap->axis1); c.print ("axis2",rap->axis2); c.print ("qrel",rap->qrel,4); printLimot (c,rap->limotP,1); printLimot (c, rap->limotR, 2); } static void printFixed (PrintingContext &c, dxJoint *j) { dxJointFixed *f = (dxJointFixed*) j; c.print ("qrel",f->qrel); c.print ("offset",f->offset); } static void printLMotor (PrintingContext &c, dxJoint *j) { dxJointLMotor *a = (dxJointLMotor*) j; c.print("num", a->num); c.printIndent(); fprintf (c.file,"rel = {%d,%d,%d},\n",a->rel[0],a->rel[1],a->rel[2]); c.print ("axis1",a->axis[0]); c.print ("axis2",a->axis[1]); c.print ("axis3",a->axis[2]); for (int i=0; i<3; i++) printLimot (c,a->limot[i],i+1); } static void printAMotor (PrintingContext &c, dxJoint *j) { dxJointAMotor *a = (dxJointAMotor*) j; c.print ("num",a->num); c.print ("mode",a->mode); c.printIndent(); fprintf (c.file,"rel = {%d,%d,%d},\n",a->rel[0],a->rel[1],a->rel[2]); c.print ("axis1",a->axis[0]); c.print ("axis2",a->axis[1]); c.print ("axis3",a->axis[2]); for (int i=0; i<3; i++) printLimot (c,a->limot[i],i+1); c.print ("angle1",a->angle[0]); c.print ("angle2",a->angle[1]); c.print ("angle3",a->angle[2]); } //*************************************************************************** // geometry static void printGeom (PrintingContext &c, dxGeom *g); static void printSphere (PrintingContext &c, dxGeom *g) { c.print ("type","sphere"); c.print ("radius",dGeomSphereGetRadius (g)); } static void printBox (PrintingContext &c, dxGeom *g) { dVector3 sides; dGeomBoxGetLengths (g,sides); c.print ("type","box"); c.print ("sides",sides); } static void printCapsule (PrintingContext &c, dxGeom *g) { dReal radius,length; dGeomCapsuleGetParams (g,&radius,&length); c.print ("type","capsule"); c.print ("radius",radius); c.print ("length",length); } static void printCylinder (PrintingContext &c, dxGeom *g) { dReal radius,length; dGeomCylinderGetParams (g,&radius,&length); c.print ("type","cylinder"); c.print ("radius",radius); c.print ("length",length); } static void printPlane (PrintingContext &c, dxGeom *g) { dVector4 e; dGeomPlaneGetParams (g,e); c.print ("type","plane"); c.print ("normal",e); c.print ("d",e[3]); } static void printRay (PrintingContext &c, dxGeom *g) { dReal length = dGeomRayGetLength (g); c.print ("type","ray"); c.print ("length",length); } static void printConvex (PrintingContext &c, dxGeom *g) { c.print ("type","convex"); ///@todo Print information about convex hull } static void printGeomTransform (PrintingContext &c, dxGeom *g) { dxGeom *g2 = dGeomTransformGetGeom (g); const dReal *pos = dGeomGetPosition (g2); dQuaternion q; dGeomGetQuaternion (g2,q); c.print ("type","transform"); c.print ("pos",pos); c.print ("q",q,4); c.print ("geometry = {"); c.indent++; printGeom (c,g2); c.indent--; c.print ("}"); } static void printTriMesh (PrintingContext &c, dxGeom *g) { c.print ("type","trimesh"); //@@@ i don't think that the trimesh accessor functions are really // sufficient to read out all the triangle data, and anyway we // should have a method of not duplicating trimesh data that is // shared. } static void printHeightfieldClass (PrintingContext &c, dxGeom *g) { c.print ("type","heightfield"); ///@todo Print information about heightfield } static void printGeom (PrintingContext &c, dxGeom *g) { unsigned long category = dGeomGetCategoryBits (g); if (category != (unsigned long)(~0)) { c.printIndent(); fprintf (c.file,"category_bits = %lu\n",category); } unsigned long collide = dGeomGetCollideBits (g); if (collide != (unsigned long)(~0)) { c.printIndent(); fprintf (c.file,"collide_bits = %lu\n",collide); } if (!dGeomIsEnabled (g)) { c.print ("disabled",1); } switch (g->type) { case dSphereClass: printSphere (c,g); break; case dBoxClass: printBox (c,g); break; case dCapsuleClass: printCapsule (c,g); break; case dCylinderClass: printCylinder (c,g); break; case dPlaneClass: printPlane (c,g); break; case dRayClass: printRay (c,g); break; case dConvexClass: printConvex (c,g); break; case dGeomTransformClass: printGeomTransform (c,g); break; case dTriMeshClass: printTriMesh (c,g); break; case dHeightfieldClass: printHeightfieldClass (c,g); break; } } //*************************************************************************** // world void dWorldExportDIF (dWorldID w, FILE *file, const char *prefix) { PrintingContext c; c.file = file; #if defined(dSINGLE) c.precision = 7; #else c.precision = 15; #endif c.indent = 1; fprintf (file,"-- Dynamics Interchange Format v0.1\n\n%sworld = dynamics.world {\n",prefix); c.print ("gravity",w->gravity); c.print ("ODE = {"); c.indent++; c.print ("ERP",w->global_erp); c.print ("CFM",w->global_cfm); c.print ("auto_disable = {"); c.indent++; c.print ("linear_threshold",w->adis.linear_average_threshold); c.print ("angular_threshold",w->adis.angular_average_threshold); c.print ("average_samples",(int)w->adis.average_samples); c.print ("idle_time",w->adis.idle_time); c.print ("idle_steps",w->adis.idle_steps); fprintf (file,"\t\t},\n\t},\n}\n"); c.indent -= 3; // bodies int num = 0; fprintf (file,"%sbody = {}\n",prefix); for (dxBody *b=w->firstbody; b; b=(dxBody*)b->next) { b->tag = num; fprintf (file,"%sbody[%d] = dynamics.body {\n\tworld = %sworld,\n",prefix,num,prefix); c.indent++; c.print ("pos",b->posr.pos); c.print ("q",b->q,4); c.print ("lvel",b->lvel); c.print ("avel",b->avel); c.print ("mass",b->mass.mass); fprintf (file,"\tI = {{"); for (int i=0; i<3; i++) { for (int j=0; j<3; j++) { c.printReal (b->mass.I[i*4+j]); if (j < 2) fputc (',',file); } if (i < 2) fprintf (file,"},{"); } fprintf (file,"}},\n"); c.printNonzero ("com",b->mass.c); c.print ("ODE = {"); c.indent++; if (b->flags & dxBodyFlagFiniteRotation) c.print ("finite_rotation",1); if (b->flags & dxBodyDisabled) c.print ("disabled",1); if (b->flags & dxBodyNoGravity) c.print ("no_gravity",1); if (b->flags & dxBodyAutoDisable) { c.print ("auto_disable = {"); c.indent++; c.print ("linear_threshold",b->adis.linear_average_threshold); c.print ("angular_threshold",b->adis.angular_average_threshold); c.print ("average_samples",(int)b->adis.average_samples); c.print ("idle_time",b->adis.idle_time); c.print ("idle_steps",b->adis.idle_steps); c.print ("time_left",b->adis_timeleft); c.print ("steps_left",b->adis_stepsleft); c.indent--; c.print ("},"); } c.printNonzero ("facc",b->facc); c.printNonzero ("tacc",b->tacc); if (b->flags & dxBodyFlagFiniteRotationAxis) { c.print ("finite_rotation_axis",b->finite_rot_axis); } c.indent--; c.print ("},"); if (b->geom) { c.print ("geometry = {"); c.indent++; for (dxGeom *g=b->geom; g; g=g->body_next) { c.print ("{"); c.indent++; printGeom (c,g); c.indent--; c.print ("},"); } c.indent--; c.print ("},"); } c.indent--; c.print ("}"); num++; } // joints num = 0; fprintf (file,"%sjoint = {}\n",prefix); for (dxJoint *j=w->firstjoint; j; j=(dxJoint*)j->next) { c.indent++; const char *name = getJointName (j); fprintf (file, "%sjoint[%d] = dynamics.%s_joint {\n" "\tworld = %sworld,\n" "\tbody = {" ,prefix,num,name,prefix); if ( j->node[0].body ) fprintf (file,"%sbody[%d]",prefix,j->node[0].body->tag); if ( j->node[1].body ) fprintf (file,",%sbody[%d]",prefix,j->node[1].body->tag); fprintf (file,"}\n"); switch (j->type()) { case dJointTypeBall: printBall (c,j); break; case dJointTypeHinge: printHinge (c,j); break; case dJointTypeSlider: printSlider (c,j); break; case dJointTypeContact: printContact (c,j); break; case dJointTypeUniversal: printUniversal (c,j); break; case dJointTypeHinge2: printHinge2 (c,j); break; case dJointTypeFixed: printFixed (c,j); break; case dJointTypeAMotor: printAMotor (c,j); break; case dJointTypeLMotor: printLMotor (c,j); break; case dJointTypePR: printPR (c,j); break; case dJointTypePU: printPU (c,j); break; case dJointTypePiston: printPiston (c,j); break; default: c.print("unknown joint"); } c.indent--; c.print ("}"); num++; } } alien-arena-7.66+dfsg/source/unix/odesrc/collision_kernel.cpp0000600000175000017500000007024512161402010023413 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* core collision functions and data structures, plus part of the public API for geometry objects */ #include #include #include #include #include #include "config.h" #include "collision_kernel.h" #include "collision_util.h" #include "collision_std.h" #include "collision_transform.h" #include "collision_trimesh_internal.h" #include "odeou.h" #ifdef _MSC_VER #pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" #endif //**************************************************************************** // helper functions for dCollide()ing a space with another geom // this struct records the parameters passed to dCollideSpaceGeom() #if dATOMICS_ENABLED static volatile atomicptr s_cachedPosR = 0; // dxPosR * #endif // dATOMICS_ENABLED static inline dxPosR* dAllocPosr() { dxPosR *retPosR; #if dATOMICS_ENABLED retPosR = (dxPosR *)AtomicExchangePointer(&s_cachedPosR, NULL); if (!retPosR) #endif { retPosR = (dxPosR*) dAlloc (sizeof(dxPosR)); } return retPosR; } static inline void dFreePosr(dxPosR *oldPosR) { #if dATOMICS_ENABLED if (!AtomicCompareExchangePointer(&s_cachedPosR, NULL, (atomicptr)oldPosR)) #endif { dFree(oldPosR, sizeof(dxPosR)); } } /*extern */void dClearPosrCache(void) { #if dATOMICS_ENABLED // No threads should be accessing ODE at this time already, // hence variable may be read directly. dxPosR *existingPosR = (dxPosR *)s_cachedPosR; if (existingPosR) { dFree(existingPosR, sizeof(dxPosR)); s_cachedPosR = 0; } #endif } struct SpaceGeomColliderData { int flags; // space left in contacts array dContactGeom *contact; int skip; }; static void space_geom_collider (void *data, dxGeom *o1, dxGeom *o2) { SpaceGeomColliderData *d = (SpaceGeomColliderData*) data; if (d->flags & NUMC_MASK) { int n = dCollide (o1,o2,d->flags,d->contact,d->skip); d->contact = CONTACT (d->contact,d->skip*n); d->flags -= n; } } static int dCollideSpaceGeom (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { SpaceGeomColliderData data; data.flags = flags; data.contact = contact; data.skip = skip; dSpaceCollide2 (o1,o2,&data,&space_geom_collider); return (flags & NUMC_MASK) - (data.flags & NUMC_MASK); } //**************************************************************************** // dispatcher for the N^2 collider functions // function pointers and modes for n^2 class collider functions struct dColliderEntry { dColliderFn *fn; // collider function, 0 = no function available int reverse; // 1 = reverse o1 and o2 }; static dColliderEntry colliders[dGeomNumClasses][dGeomNumClasses]; static int colliders_initialized = 0; // setCollider() will refuse to write over a collider entry once it has // been written. static void setCollider (int i, int j, dColliderFn *fn) { if (colliders[i][j].fn == 0) { colliders[i][j].fn = fn; colliders[i][j].reverse = 0; } if (colliders[j][i].fn == 0) { colliders[j][i].fn = fn; colliders[j][i].reverse = 1; } } static void setAllColliders (int i, dColliderFn *fn) { for (int j=0; j Convex Collision setCollider (dConvexClass,dPlaneClass,&dCollideConvexPlane); setCollider (dSphereClass,dConvexClass,&dCollideSphereConvex); setCollider (dConvexClass,dBoxClass,&dCollideConvexBox); setCollider (dConvexClass,dCapsuleClass,&dCollideConvexCapsule); setCollider (dConvexClass,dConvexClass,&dCollideConvexConvex); setCollider (dRayClass,dConvexClass,&dCollideRayConvex); //<-- Convex Collision //--> dHeightfield Collision setCollider (dHeightfieldClass,dRayClass,&dCollideHeightfield); setCollider (dHeightfieldClass,dSphereClass,&dCollideHeightfield); setCollider (dHeightfieldClass,dBoxClass,&dCollideHeightfield); setCollider (dHeightfieldClass,dCapsuleClass,&dCollideHeightfield); setCollider (dHeightfieldClass,dCylinderClass,&dCollideHeightfield); setCollider (dHeightfieldClass,dConvexClass,&dCollideHeightfield); #if dTRIMESH_ENABLED setCollider (dHeightfieldClass,dTriMeshClass,&dCollideHeightfield); #endif //<-- dHeightfield Collision setAllColliders (dGeomTransformClass,&dCollideTransform); } /*extern */void dFinitColliders() { colliders_initialized = 0; } void dSetColliderOverride (int i, int j, dColliderFn *fn) { dIASSERT( colliders_initialized ); dAASSERT( i < dGeomNumClasses ); dAASSERT( j < dGeomNumClasses ); colliders[i][j].fn = fn; colliders[i][j].reverse = 0; colliders[j][i].fn = fn; colliders[j][i].reverse = 1; } /* * NOTE! * If it is necessary to add special processing mode without contact generation * use NULL contact parameter value as indicator, not zero in flags. */ int dCollide (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dAASSERT(o1 && o2 && contact); dUASSERT(colliders_initialized,"Please call ODE initialization (dInitODE() or similar) before using the library"); dUASSERT(o1->type >= 0 && o1->type < dGeomNumClasses,"bad o1 class number"); dUASSERT(o2->type >= 0 && o2->type < dGeomNumClasses,"bad o2 class number"); // Even though comparison for greater or equal to one is used in all the // other places, here it is more logical to check for greater than zero // because function does not require any specific number of contact slots - // it must be just a positive. dUASSERT((flags & NUMC_MASK) > 0, "no contacts requested"); // Extra precaution for zero contact count in parameters if ((flags & NUMC_MASK) == 0) return 0; // no contacts if both geoms are the same if (o1 == o2) return 0; // no contacts if both geoms on the same body, and the body is not 0 if (o1->body == o2->body && o1->body) return 0; o1->recomputePosr(); o2->recomputePosr(); dColliderEntry *ce = &colliders[o1->type][o2->type]; int count = 0; if (ce->fn) { if (ce->reverse) { count = (*ce->fn) (o2,o1,flags,contact,skip); for (int i=0; inormal[0] = -c->normal[0]; c->normal[1] = -c->normal[1]; c->normal[2] = -c->normal[2]; dxGeom *tmp = c->g1; c->g1 = c->g2; c->g2 = tmp; int tmpint = c->side1; c->side1 = c->side2; c->side2 = tmpint; } } else { count = (*ce->fn) (o1,o2,flags,contact,skip); } } return count; } //**************************************************************************** // dxGeom dxGeom::dxGeom (dSpaceID _space, int is_placeable) { // setup body vars. invalid type of -1 must be changed by the constructor. type = -1; gflags = GEOM_DIRTY | GEOM_AABB_BAD | GEOM_ENABLED; if (is_placeable) gflags |= GEOM_PLACEABLE; data = 0; body = 0; body_next = 0; if (is_placeable) { final_posr = dAllocPosr(); dSetZero (final_posr->pos,4); dRSetIdentity (final_posr->R); } else { final_posr = 0; } offset_posr = 0; // setup space vars next = 0; tome = 0; parent_space = 0; dSetZero (aabb,6); category_bits = ~0; collide_bits = ~0; // put this geom in a space if required if (_space) dSpaceAdd (_space,this); } dxGeom::~dxGeom() { if (parent_space) dSpaceRemove (parent_space,this); if ((gflags & GEOM_PLACEABLE) && (!body || (body && offset_posr))) dFreePosr(final_posr); if (offset_posr) dFreePosr(offset_posr); bodyRemove(); } unsigned dxGeom::getParentSpaceTLSKind() const { return parent_space ? parent_space->tls_kind : dSPACE_TLS_KIND_INIT_VALUE; } int dxGeom::AABBTest (dxGeom *o, dReal aabb[6]) { return 1; } void dxGeom::bodyRemove() { if (body) { // delete this geom from body list dxGeom **last = &body->geom, *g = body->geom; while (g) { if (g == this) { *last = g->body_next; break; } last = &g->body_next; g = g->body_next; } body = 0; body_next = 0; } } inline void myswap(dReal& a, dReal& b) { dReal t=b; b=a; a=t; } inline void matrixInvert(const dMatrix3& inMat, dMatrix3& outMat) { memcpy(outMat, inMat, sizeof(dMatrix3)); // swap _12 and _21 myswap(outMat[0 + 4*1], outMat[1 + 4*0]); // swap _31 and _13 myswap(outMat[2 + 4*0], outMat[0 + 4*2]); // swap _23 and _32 myswap(outMat[1 + 4*2], outMat[2 + 4*1]); } void getBodyPosr(const dxPosR& offset_posr, const dxPosR& final_posr, dxPosR& body_posr) { dMatrix3 inv_offset; matrixInvert(offset_posr.R, inv_offset); dMULTIPLY0_333(body_posr.R, final_posr.R, inv_offset); dVector3 world_offset; dMULTIPLY0_331(world_offset, body_posr.R, offset_posr.pos); body_posr.pos[0] = final_posr.pos[0] - world_offset[0]; body_posr.pos[1] = final_posr.pos[1] - world_offset[1]; body_posr.pos[2] = final_posr.pos[2] - world_offset[2]; } void getWorldOffsetPosr(const dxPosR& body_posr, const dxPosR& world_posr, dxPosR& offset_posr) { dMatrix3 inv_body; matrixInvert(body_posr.R, inv_body); dMULTIPLY0_333(offset_posr.R, inv_body, world_posr.R); dVector3 world_offset; world_offset[0] = world_posr.pos[0] - body_posr.pos[0]; world_offset[1] = world_posr.pos[1] - body_posr.pos[1]; world_offset[2] = world_posr.pos[2] - body_posr.pos[2]; dMULTIPLY0_331(offset_posr.pos, inv_body, world_offset); } void dxGeom::computePosr() { // should only be recalced if we need to - ie offset from a body dIASSERT(offset_posr); dIASSERT(body); dMULTIPLY0_331 (final_posr->pos,body->posr.R,offset_posr->pos); final_posr->pos[0] += body->posr.pos[0]; final_posr->pos[1] += body->posr.pos[1]; final_posr->pos[2] += body->posr.pos[2]; dMULTIPLY0_333 (final_posr->R,body->posr.R,offset_posr->R); } //**************************************************************************** // misc dxGeom *dGeomGetBodyNext (dxGeom *geom) { return geom->body_next; } //**************************************************************************** // public API for geometry objects #define CHECK_NOT_LOCKED(space) \ dUASSERT (!(space && space->lock_count), \ "invalid operation for geom in locked space"); void dGeomDestroy (dxGeom *g) { dAASSERT (g); delete g; } void dGeomSetData (dxGeom *g, void *data) { dAASSERT (g); g->data = data; } void *dGeomGetData (dxGeom *g) { dAASSERT (g); return g->data; } void dGeomSetBody (dxGeom *g, dxBody *b) { dAASSERT (g); dUASSERT (b == NULL || (g->gflags & GEOM_PLACEABLE),"geom must be placeable"); CHECK_NOT_LOCKED (g->parent_space); if (b) { if (!g->body) dFreePosr(g->final_posr); if (g->body != b) { if (g->offset_posr) { dFreePosr(g->offset_posr); g->offset_posr = 0; } g->final_posr = &b->posr; g->bodyRemove(); g->bodyAdd (b); } dGeomMoved (g); } else { if (g->body) { if (g->offset_posr) { // if we're offset, we already have our own final position, make sure its updated g->recomputePosr(); dFreePosr(g->offset_posr); g->offset_posr = 0; } else { g->final_posr = dAllocPosr(); memcpy (g->final_posr->pos,g->body->posr.pos,sizeof(dVector3)); memcpy (g->final_posr->R,g->body->posr.R,sizeof(dMatrix3)); } g->bodyRemove(); } // dGeomMoved() should not be called if the body is being set to 0, as the // new position of the geom is set to the old position of the body, so the // effective position of the geom remains unchanged. } } dBodyID dGeomGetBody (dxGeom *g) { dAASSERT (g); return g->body; } void dGeomSetPosition (dxGeom *g, dReal x, dReal y, dReal z) { dAASSERT (g); dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); CHECK_NOT_LOCKED (g->parent_space); if (g->offset_posr) { // move body such that body+offset = position dVector3 world_offset; dMULTIPLY0_331(world_offset, g->body->posr.R, g->offset_posr->pos); dBodySetPosition(g->body, x - world_offset[0], y - world_offset[1], z - world_offset[2]); } else if (g->body) { // this will call dGeomMoved (g), so we don't have to dBodySetPosition (g->body,x,y,z); } else { g->final_posr->pos[0] = x; g->final_posr->pos[1] = y; g->final_posr->pos[2] = z; dGeomMoved (g); } } void dGeomSetRotation (dxGeom *g, const dMatrix3 R) { dAASSERT (g && R); dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); CHECK_NOT_LOCKED (g->parent_space); if (g->offset_posr) { g->recomputePosr(); // move body such that body+offset = rotation dxPosR new_final_posr; dxPosR new_body_posr; memcpy(new_final_posr.pos, g->final_posr->pos, sizeof(dVector3)); memcpy(new_final_posr.R, R, sizeof(dMatrix3)); getBodyPosr(*g->offset_posr, new_final_posr, new_body_posr); dBodySetRotation(g->body, new_body_posr.R); dBodySetPosition(g->body, new_body_posr.pos[0], new_body_posr.pos[1], new_body_posr.pos[2]); } else if (g->body) { // this will call dGeomMoved (g), so we don't have to dBodySetRotation (g->body,R); } else { memcpy (g->final_posr->R,R,sizeof(dMatrix3)); dGeomMoved (g); } } void dGeomSetQuaternion (dxGeom *g, const dQuaternion quat) { dAASSERT (g && quat); dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); CHECK_NOT_LOCKED (g->parent_space); if (g->offset_posr) { g->recomputePosr(); // move body such that body+offset = rotation dxPosR new_final_posr; dxPosR new_body_posr; dQtoR (quat, new_final_posr.R); memcpy(new_final_posr.pos, g->final_posr->pos, sizeof(dVector3)); getBodyPosr(*g->offset_posr, new_final_posr, new_body_posr); dBodySetRotation(g->body, new_body_posr.R); dBodySetPosition(g->body, new_body_posr.pos[0], new_body_posr.pos[1], new_body_posr.pos[2]); } if (g->body) { // this will call dGeomMoved (g), so we don't have to dBodySetQuaternion (g->body,quat); } else { dQtoR (quat, g->final_posr->R); dGeomMoved (g); } } const dReal * dGeomGetPosition (dxGeom *g) { dAASSERT (g); dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); g->recomputePosr(); return g->final_posr->pos; } void dGeomCopyPosition(dxGeom *g, dVector3 pos) { dAASSERT (g); dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); g->recomputePosr(); const dReal* src = g->final_posr->pos; pos[0] = src[0]; pos[1] = src[1]; pos[2] = src[2]; } const dReal * dGeomGetRotation (dxGeom *g) { dAASSERT (g); dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); g->recomputePosr(); return g->final_posr->R; } void dGeomCopyRotation(dxGeom *g, dMatrix3 R) { dAASSERT (g); dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); g->recomputePosr(); const dReal* src = g->final_posr->R; R[0] = src[0]; R[1] = src[1]; R[2] = src[2]; R[4] = src[4]; R[5] = src[5]; R[6] = src[6]; R[8] = src[8]; R[9] = src[9]; R[10] = src[10]; } void dGeomGetQuaternion (dxGeom *g, dQuaternion quat) { dAASSERT (g); dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); if (g->body && !g->offset_posr) { const dReal * body_quat = dBodyGetQuaternion (g->body); quat[0] = body_quat[0]; quat[1] = body_quat[1]; quat[2] = body_quat[2]; quat[3] = body_quat[3]; } else { g->recomputePosr(); dRtoQ (g->final_posr->R, quat); } } void dGeomGetAABB (dxGeom *g, dReal aabb[6]) { dAASSERT (g); dAASSERT (aabb); g->recomputeAABB(); memcpy (aabb,g->aabb,6 * sizeof(dReal)); } int dGeomIsSpace (dxGeom *g) { dAASSERT (g); return IS_SPACE(g); } dSpaceID dGeomGetSpace (dxGeom *g) { dAASSERT (g); return g->parent_space; } int dGeomGetClass (dxGeom *g) { dAASSERT (g); return g->type; } void dGeomSetCategoryBits (dxGeom *g, unsigned long bits) { dAASSERT (g); CHECK_NOT_LOCKED (g->parent_space); g->category_bits = bits; } void dGeomSetCollideBits (dxGeom *g, unsigned long bits) { dAASSERT (g); CHECK_NOT_LOCKED (g->parent_space); g->collide_bits = bits; } unsigned long dGeomGetCategoryBits (dxGeom *g) { dAASSERT (g); return g->category_bits; } unsigned long dGeomGetCollideBits (dxGeom *g) { dAASSERT (g); return g->collide_bits; } void dGeomEnable (dxGeom *g) { dAASSERT (g); g->gflags |= GEOM_ENABLED; } void dGeomDisable (dxGeom *g) { dAASSERT (g); g->gflags &= ~GEOM_ENABLED; } int dGeomIsEnabled (dxGeom *g) { dAASSERT (g); return (g->gflags & GEOM_ENABLED) != 0; } //**************************************************************************** // C interface that lets the user make new classes. this interface is a lot // more cumbersome than C++ subclassing, which is what is used internally // in ODE. this API is mainly to support legacy code. static int num_user_classes = 0; static dGeomClass user_classes [dMaxUserClasses]; struct dxUserGeom : public dxGeom { void *user_data; dxUserGeom (int class_num); ~dxUserGeom(); void computeAABB(); int AABBTest (dxGeom *o, dReal aabb[6]); }; dxUserGeom::dxUserGeom (int class_num) : dxGeom (0,1) { type = class_num; int size = user_classes[type-dFirstUserClass].bytes; user_data = dAlloc (size); memset (user_data,0,size); } dxUserGeom::~dxUserGeom() { dGeomClass *c = &user_classes[type-dFirstUserClass]; if (c->dtor) c->dtor (this); dFree (user_data,c->bytes); } void dxUserGeom::computeAABB() { user_classes[type-dFirstUserClass].aabb (this,aabb); } int dxUserGeom::AABBTest (dxGeom *o, dReal aabb[6]) { dGeomClass *c = &user_classes[type-dFirstUserClass]; if (c->aabb_test) return c->aabb_test (this,o,aabb); else return 1; } static int dCollideUserGeomWithGeom (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { // this generic collider function is called the first time that a user class // tries to collide against something. it will find out the correct collider // function and then set the colliders array so that the correct function is // called directly the next time around. int t1 = o1->type; // note that o1 is a user geom int t2 = o2->type; // o2 *may* be a user geom // find the collider function to use. if o1 does not know how to collide with // o2, then o2 might know how to collide with o1 (provided that it is a user // geom). dColliderFn *fn = user_classes[t1-dFirstUserClass].collider (t2); int reverse = 0; if (!fn && t2 >= dFirstUserClass && t2 <= dLastUserClass) { fn = user_classes[t2-dFirstUserClass].collider (t1); reverse = 1; } // set the colliders array so that the correct function is called directly // the next time around. note that fn can be 0 here if no collider was found, // which means that dCollide() will always return 0 for this case. colliders[t1][t2].fn = fn; colliders[t1][t2].reverse = reverse; colliders[t2][t1].fn = fn; colliders[t2][t1].reverse = !reverse; // now call the collider function indirectly through dCollide(), so that // contact reversing is properly handled. return dCollide (o1,o2,flags,contact,skip); } int dCreateGeomClass (const dGeomClass *c) { dUASSERT(c && c->bytes >= 0 && c->collider && c->aabb,"bad geom class"); if (num_user_classes >= dMaxUserClasses) { dDebug (0,"too many user classes, you must increase the limit and " "recompile ODE"); } user_classes[num_user_classes] = *c; int class_number = num_user_classes + dFirstUserClass; setAllColliders (class_number,&dCollideUserGeomWithGeom); num_user_classes++; return class_number; } /*extern */void dFinitUserClasses() { num_user_classes = 0; } void * dGeomGetClassData (dxGeom *g) { dUASSERT (g && g->type >= dFirstUserClass && g->type <= dLastUserClass,"not a custom class"); dxUserGeom *user = (dxUserGeom*) g; return user->user_data; } dGeomID dCreateGeom (int classnum) { dUASSERT (classnum >= dFirstUserClass && classnum <= dLastUserClass,"not a custom class"); return new dxUserGeom (classnum); } /* ************************************************************************ */ /* geom offset from body */ void dGeomCreateOffset (dxGeom *g) { dAASSERT (g); dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); dUASSERT (g->body, "geom must be on a body"); if (g->offset_posr) { return; // already created } dIASSERT (g->final_posr == &g->body->posr); g->final_posr = dAllocPosr(); g->offset_posr = dAllocPosr(); dSetZero (g->offset_posr->pos,4); dRSetIdentity (g->offset_posr->R); g->gflags |= GEOM_POSR_BAD; } void dGeomSetOffsetPosition (dxGeom *g, dReal x, dReal y, dReal z) { dAASSERT (g); dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); dUASSERT (g->body, "geom must be on a body"); CHECK_NOT_LOCKED (g->parent_space); if (!g->offset_posr) { dGeomCreateOffset(g); } g->offset_posr->pos[0] = x; g->offset_posr->pos[1] = y; g->offset_posr->pos[2] = z; dGeomMoved (g); } void dGeomSetOffsetRotation (dxGeom *g, const dMatrix3 R) { dAASSERT (g && R); dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); dUASSERT (g->body, "geom must be on a body"); CHECK_NOT_LOCKED (g->parent_space); if (!g->offset_posr) { dGeomCreateOffset (g); } memcpy (g->offset_posr->R,R,sizeof(dMatrix3)); dGeomMoved (g); } void dGeomSetOffsetQuaternion (dxGeom *g, const dQuaternion quat) { dAASSERT (g && quat); dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); dUASSERT (g->body, "geom must be on a body"); CHECK_NOT_LOCKED (g->parent_space); if (!g->offset_posr) { dGeomCreateOffset (g); } dQtoR (quat, g->offset_posr->R); dGeomMoved (g); } void dGeomSetOffsetWorldPosition (dxGeom *g, dReal x, dReal y, dReal z) { dAASSERT (g); dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); dUASSERT (g->body, "geom must be on a body"); CHECK_NOT_LOCKED (g->parent_space); if (!g->offset_posr) { dGeomCreateOffset(g); } dBodyGetPosRelPoint(g->body, x, y, z, g->offset_posr->pos); dGeomMoved (g); } void dGeomSetOffsetWorldRotation (dxGeom *g, const dMatrix3 R) { dAASSERT (g && R); dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); dUASSERT (g->body, "geom must be on a body"); CHECK_NOT_LOCKED (g->parent_space); if (!g->offset_posr) { dGeomCreateOffset (g); } g->recomputePosr(); dxPosR new_final_posr; memcpy(new_final_posr.pos, g->final_posr->pos, sizeof(dVector3)); memcpy(new_final_posr.R, R, sizeof(dMatrix3)); getWorldOffsetPosr(g->body->posr, new_final_posr, *g->offset_posr); dGeomMoved (g); } void dGeomSetOffsetWorldQuaternion (dxGeom *g, const dQuaternion quat) { dAASSERT (g && quat); dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); dUASSERT (g->body, "geom must be on a body"); CHECK_NOT_LOCKED (g->parent_space); if (!g->offset_posr) { dGeomCreateOffset (g); } g->recomputePosr(); dxPosR new_final_posr; memcpy(new_final_posr.pos, g->final_posr->pos, sizeof(dVector3)); dQtoR (quat, new_final_posr.R); getWorldOffsetPosr(g->body->posr, new_final_posr, *g->offset_posr); dGeomMoved (g); } void dGeomClearOffset(dxGeom *g) { dAASSERT (g); dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); if (g->offset_posr) { dIASSERT(g->body); // no longer need an offset posr dFreePosr(g->offset_posr); g->offset_posr = 0; // the geom will now share the position of the body dFreePosr(g->final_posr); g->final_posr = &g->body->posr; // geom has moved g->gflags &= ~GEOM_POSR_BAD; dGeomMoved (g); } } int dGeomIsOffset(dxGeom *g) { dAASSERT (g); return ((0 != g->offset_posr) ? 1 : 0); } static const dVector3 OFFSET_POSITION_ZERO = { 0.0f, 0.0f, 0.0f, 0.0f }; const dReal * dGeomGetOffsetPosition (dxGeom *g) { dAASSERT (g); if (g->offset_posr) { return g->offset_posr->pos; } return OFFSET_POSITION_ZERO; } void dGeomCopyOffsetPosition (dxGeom *g, dVector3 pos) { dAASSERT (g); if (g->offset_posr) { const dReal* src = g->offset_posr->pos; pos[0] = src[0]; pos[1] = src[1]; pos[2] = src[2]; } else { pos[0] = 0; pos[1] = 0; pos[2] = 0; } } static const dMatrix3 OFFSET_ROTATION_ZERO = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, }; const dReal * dGeomGetOffsetRotation (dxGeom *g) { dAASSERT (g); if (g->offset_posr) { return g->offset_posr->R; } return OFFSET_ROTATION_ZERO; } void dGeomCopyOffsetRotation (dxGeom *g, dMatrix3 R) { dAASSERT (g); if (g->offset_posr) { const dReal* src = g->final_posr->R; R[0] = src[0]; R[1] = src[1]; R[2] = src[2]; R[4] = src[4]; R[5] = src[5]; R[6] = src[6]; R[8] = src[8]; R[9] = src[9]; R[10] = src[10]; } else { R[0] = OFFSET_ROTATION_ZERO[0]; R[1] = OFFSET_ROTATION_ZERO[1]; R[2] = OFFSET_ROTATION_ZERO[2]; R[4] = OFFSET_ROTATION_ZERO[4]; R[5] = OFFSET_ROTATION_ZERO[5]; R[6] = OFFSET_ROTATION_ZERO[6]; R[8] = OFFSET_ROTATION_ZERO[8]; R[9] = OFFSET_ROTATION_ZERO[9]; R[10] = OFFSET_ROTATION_ZERO[10]; } } void dGeomGetOffsetQuaternion (dxGeom *g, dQuaternion result) { dAASSERT (g); if (g->offset_posr) { dRtoQ (g->offset_posr->R, result); } else { dSetZero (result,4); result[0] = 1; } } alien-arena-7.66+dfsg/source/unix/odesrc/joints/0000700000175000017500000000000012207204656020671 5ustar zero79zero79alien-arena-7.66+dfsg/source/unix/odesrc/joints/joint.h0000600000175000017500000001515212161402010022152 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_JOINT_H_ #define _ODE_JOINT_H_ #include "../objects.h" #include #include "../obstack.h" // joint flags enum { // if this flag is set, the joint was allocated in a joint group dJOINT_INGROUP = 1, // if this flag is set, the joint was attached with arguments (0,body). // our convention is to treat all attaches as (body,0), i.e. so node[0].body // is always nonzero, so this flag records the fact that the arguments were // swapped. dJOINT_REVERSE = 2, // if this flag is set, the joint can not have just one body attached to it, // it must have either zero or two bodies attached. dJOINT_TWOBODIES = 4, dJOINT_DISABLED = 8 }; // there are two of these nodes in the joint, one for each connection to a // body. these are node of a linked list kept by each body of it's connecting // joints. but note that the body pointer in each node points to the body that // makes use of the *other* node, not this node. this trick makes it a bit // easier to traverse the body/joint graph. struct dxJointNode { dxJoint *joint; // pointer to enclosing dxJoint object dxBody *body; // *other* body this joint is connected to dxJointNode *next; // next node in body's list of connected joints }; struct dxJoint : public dObject { // naming convention: the "first" body this is connected to is node[0].body, // and the "second" body is node[1].body. if this joint is only connected // to one body then the second body is 0. // info returned by getInfo1 function. the constraint dimension is m (<=6). // i.e. that is the total number of rows in the jacobian. `nub' is the // number of unbounded variables (which have lo,hi = -/+ infinity). struct Info1 { int m, nub; }; // info returned by getInfo2 function struct Info2 { // integrator parameters: frames per second (1/stepsize), default error // reduction parameter (0..1). dReal fps, erp; // for the first and second body, pointers to two (linear and angular) // n*3 jacobian sub matrices, stored by rows. these matrices will have // been initialized to 0 on entry. if the second body is zero then the // J2xx pointers may be 0. dReal *J1l, *J1a, *J2l, *J2a; // elements to jump from one row to the next in J's int rowskip; // right hand sides of the equation J*v = c + cfm * lambda. cfm is the // "constraint force mixing" vector. c is set to zero on entry, cfm is // set to a constant value (typically very small or zero) value on entry. dReal *c, *cfm; // lo and hi limits for variables (set to -/+ infinity on entry). dReal *lo, *hi; // findex vector for variables. see the LCP solver interface for a // description of what this does. this is set to -1 on entry. // note that the returned indexes are relative to the first index of // the constraint. int *findex; }; unsigned flags; // dJOINT_xxx flags dxJointNode node[2]; // connections to bodies. node[1].body can be 0 dJointFeedback *feedback; // optional feedback structure dReal lambda[6]; // lambda generated by last step dxJoint( dxWorld *w ); virtual ~dxJoint(); virtual void getInfo1( Info1* info ) = 0; virtual void getInfo2( Info2* info ) = 0; virtual dJointType type() const = 0; virtual size_t size() const = 0; /// Set values which are relative with respect to bodies. /// Each dxJoint should redefine it if needed. virtual void setRelativeValues() {}; // Test if this joint should be used in the simulation step // (has the enabled flag set, and is attached to at least one dynamic body) bool isEnabled() const; }; // joint group. NOTE: any joints in the group that have their world destroyed // will have their world pointer set to 0. struct dxJointGroup : public dBase { int num; // number of joints on the stack dObStack stack; // a stack of (possibly differently sized) dxJoint }; // objects. // common limit and motor information for a single joint axis of movement struct dxJointLimitMotor { dReal vel, fmax; // powered joint: velocity, max force dReal lostop, histop; // joint limits, relative to initial position dReal fudge_factor; // when powering away from joint limits dReal normal_cfm; // cfm to use when not at a stop dReal stop_erp, stop_cfm; // erp and cfm for when at joint limit dReal bounce; // restitution factor // variables used between getInfo1() and getInfo2() int limit; // 0=free, 1=at lo limit, 2=at hi limit dReal limit_err; // if at limit, amount over limit void init( dxWorld * ); void set( int num, dReal value ); dReal get( int num ); int testRotationalLimit( dReal angle ); int addLimot( dxJoint *joint, dxJoint::Info2 *info, int row, const dVector3 ax1, int rotational ); }; #endif // Local Variables: // mode:c++ // c-basic-offset:4 // End: alien-arena-7.66+dfsg/source/unix/odesrc/joints/universal.cpp0000600000175000017500000005643012161402010023376 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include "universal.h" #include "joint_internal.h" //**************************************************************************** // universal // I just realized that the universal joint is equivalent to a hinge 2 joint with // perfectly stiff suspension. By comparing the hinge 2 implementation to // the universal implementation, you may be able to improve this // implementation (or, less likely, the hinge2 implementation). dxJointUniversal::dxJointUniversal( dxWorld *w ) : dxJoint( w ) { dSetZero( anchor1, 4 ); dSetZero( anchor2, 4 ); dSetZero( axis1, 4 ); axis1[0] = 1; dSetZero( axis2, 4 ); axis2[1] = 1; dSetZero( qrel1, 4 ); dSetZero( qrel2, 4 ); limot1.init( world ); limot2.init( world ); } void dxJointUniversal::getAxes( dVector3 ax1, dVector3 ax2 ) { // This says "ax1 = joint->node[0].body->posr.R * joint->axis1" dMULTIPLY0_331( ax1, node[0].body->posr.R, axis1 ); if ( node[1].body ) { dMULTIPLY0_331( ax2, node[1].body->posr.R, axis2 ); } else { ax2[0] = axis2[0]; ax2[1] = axis2[1]; ax2[2] = axis2[2]; } } void dxJointUniversal::getAngles( dReal *angle1, dReal *angle2 ) { if ( node[0].body ) { // length 1 joint axis in global coordinates, from each body dVector3 ax1, ax2; dMatrix3 R; dQuaternion qcross, qq, qrel; getAxes( ax1, ax2 ); // It should be possible to get both angles without explicitly // constructing the rotation matrix of the cross. Basically, // orientation of the cross about axis1 comes from body 2, // about axis 2 comes from body 1, and the perpendicular // axis can come from the two bodies somehow. (We don't really // want to assume it's 90 degrees, because in general the // constraints won't be perfectly satisfied, or even very well // satisfied.) // // However, we'd need a version of getHingeAngleFromRElativeQuat() // that CAN handle when its relative quat is rotated along a direction // other than the given axis. What I have here works, // although it's probably much slower than need be. dRFrom2Axes( R, ax1[0], ax1[1], ax1[2], ax2[0], ax2[1], ax2[2] ); dRtoQ( R, qcross ); // This code is essentialy the same as getHingeAngle(), see the comments // there for details. // get qrel = relative rotation between node[0] and the cross dQMultiply1( qq, node[0].body->q, qcross ); dQMultiply2( qrel, qq, qrel1 ); *angle1 = getHingeAngleFromRelativeQuat( qrel, axis1 ); // This is equivalent to // dRFrom2Axes(R, ax2[0], ax2[1], ax2[2], ax1[0], ax1[1], ax1[2]); // You see that the R is constructed from the same 2 axis as for angle1 // but the first and second axis are swapped. // So we can take the first R and rapply a rotation to it. // The rotation is around the axis between the 2 axes (ax1 and ax2). // We do a rotation of 180deg. dQuaternion qcross2; // Find the vector between ax1 and ax2 (i.e. in the middle) // We need to turn around this vector by 180deg // The 2 axes should be normalize so to find the vector between the 2. // Add and devide by 2 then normalize or simply normalize // ax2 // ^ // | // | /// *------------> ax1 // We want the vector a 45deg // // N.B. We don't need to normalize the ax1 and ax2 since there are // normalized when we set them. // We set the quaternion q = [cos(theta), dir*sin(theta)] = [w, x, y, Z] qrel[0] = 0; // equivalent to cos(Pi/2) qrel[1] = ax1[0] + ax2[0]; // equivalent to x*sin(Pi/2); since sin(Pi/2) = 1 qrel[2] = ax1[1] + ax2[1]; qrel[3] = ax1[2] + ax2[2]; dReal l = dRecip( sqrt( qrel[1] * qrel[1] + qrel[2] * qrel[2] + qrel[3] * qrel[3] ) ); qrel[1] *= l; qrel[2] *= l; qrel[3] *= l; dQMultiply0( qcross2, qrel, qcross ); if ( node[1].body ) { dQMultiply1( qq, node[1].body->q, qcross2 ); dQMultiply2( qrel, qq, qrel2 ); } else { // pretend joint->node[1].body->q is the identity dQMultiply2( qrel, qcross2, qrel2 ); } *angle2 = - getHingeAngleFromRelativeQuat( qrel, axis2 ); } else { *angle1 = 0; *angle2 = 0; } } dReal dxJointUniversal::getAngle1() { if ( node[0].body ) { // length 1 joint axis in global coordinates, from each body dVector3 ax1, ax2; dMatrix3 R; dQuaternion qcross, qq, qrel; getAxes( ax1, ax2 ); // It should be possible to get both angles without explicitly // constructing the rotation matrix of the cross. Basically, // orientation of the cross about axis1 comes from body 2, // about axis 2 comes from body 1, and the perpendicular // axis can come from the two bodies somehow. (We don't really // want to assume it's 90 degrees, because in general the // constraints won't be perfectly satisfied, or even very well // satisfied.) // // However, we'd need a version of getHingeAngleFromRElativeQuat() // that CAN handle when its relative quat is rotated along a direction // other than the given axis. What I have here works, // although it's probably much slower than need be. dRFrom2Axes( R, ax1[0], ax1[1], ax1[2], ax2[0], ax2[1], ax2[2] ); dRtoQ( R, qcross ); // This code is essential the same as getHingeAngle(), see the comments // there for details. // get qrel = relative rotation between node[0] and the cross dQMultiply1( qq, node[0].body->q, qcross ); dQMultiply2( qrel, qq, qrel1 ); return getHingeAngleFromRelativeQuat( qrel, axis1 ); } return 0; } dReal dxJointUniversal::getAngle2() { if ( node[0].body ) { // length 1 joint axis in global coordinates, from each body dVector3 ax1, ax2; dMatrix3 R; dQuaternion qcross, qq, qrel; getAxes( ax1, ax2 ); // It should be possible to get both angles without explicitly // constructing the rotation matrix of the cross. Basically, // orientation of the cross about axis1 comes from body 2, // about axis 2 comes from body 1, and the perpendicular // axis can come from the two bodies somehow. (We don't really // want to assume it's 90 degrees, because in general the // constraints won't be perfectly satisfied, or even very well // satisfied.) // // However, we'd need a version of getHingeAngleFromRElativeQuat() // that CAN handle when its relative quat is rotated along a direction // other than the given axis. What I have here works, // although it's probably much slower than need be. dRFrom2Axes( R, ax2[0], ax2[1], ax2[2], ax1[0], ax1[1], ax1[2] ); dRtoQ( R, qcross ); if ( node[1].body ) { dQMultiply1( qq, node[1].body->q, qcross ); dQMultiply2( qrel, qq, qrel2 ); } else { // pretend joint->node[1].body->q is the identity dQMultiply2( qrel, qcross, qrel2 ); } return - getHingeAngleFromRelativeQuat( qrel, axis2 ); } return 0; } void dxJointUniversal::getInfo1( dxJoint::Info1 *info ) { info->nub = 4; info->m = 4; bool limiting1 = ( limot1.lostop >= -M_PI || limot1.histop <= M_PI ) && limot1.lostop <= limot1.histop; bool limiting2 = ( limot2.lostop >= -M_PI || limot2.histop <= M_PI ) && limot2.lostop <= limot2.histop; // We need to call testRotationLimit() even if we're motored, since it // records the result. limot1.limit = 0; limot2.limit = 0; if ( limiting1 || limiting2 ) { dReal angle1, angle2; getAngles( &angle1, &angle2 ); if ( limiting1 ) limot1.testRotationalLimit( angle1 ); if ( limiting2 ) limot2.testRotationalLimit( angle2 ); } if ( limot1.limit || limot1.fmax > 0 ) info->m++; if ( limot2.limit || limot2.fmax > 0 ) info->m++; } void dxJointUniversal::getInfo2( dxJoint::Info2 *info ) { // set the three ball-and-socket rows setBall( this, info, anchor1, anchor2 ); // set the universal joint row. the angular velocity about an axis // perpendicular to both joint axes should be equal. thus the constraint // equation is // p*w1 - p*w2 = 0 // where p is a vector normal to both joint axes, and w1 and w2 // are the angular velocity vectors of the two bodies. // length 1 joint axis in global coordinates, from each body dVector3 ax1, ax2; dVector3 ax2_temp; // length 1 vector perpendicular to ax1 and ax2. Neither body can rotate // about this. dVector3 p; dReal k; // Since axis1 and axis2 may not be perpendicular // we find a axis2_tmp which is really perpendicular to axis1 // and in the plane of axis1 and axis2 getAxes( ax1, ax2 ); k = dDOT( ax1, ax2 ); ax2_temp[0] = ax2[0] - k * ax1[0]; ax2_temp[1] = ax2[1] - k * ax1[1]; ax2_temp[2] = ax2[2] - k * ax1[2]; dCROSS( p, = , ax1, ax2_temp ); dNormalize3( p ); int s3 = 3 * info->rowskip; info->J1a[s3+0] = p[0]; info->J1a[s3+1] = p[1]; info->J1a[s3+2] = p[2]; if ( node[1].body ) { info->J2a[s3+0] = -p[0]; info->J2a[s3+1] = -p[1]; info->J2a[s3+2] = -p[2]; } // compute the right hand side of the constraint equation. set relative // body velocities along p to bring the axes back to perpendicular. // If ax1, ax2 are unit length joint axes as computed from body1 and // body2, we need to rotate both bodies along the axis p. If theta // is the angle between ax1 and ax2, we need an angular velocity // along p to cover the angle erp * (theta - Pi/2) in one step: // // |angular_velocity| = angle/time = erp*(theta - Pi/2) / stepsize // = (erp*fps) * (theta - Pi/2) // // if theta is close to Pi/2, // theta - Pi/2 ~= cos(theta), so // |angular_velocity| ~= (erp*fps) * (ax1 dot ax2) info->c[3] = info->fps * info->erp * - k; // if the first angle is powered, or has joint limits, add in the stuff int row = 4 + limot1.addLimot( this, info, 4, ax1, 1 ); // if the second angle is powered, or has joint limits, add in more stuff limot2.addLimot( this, info, row, ax2, 1 ); } void dxJointUniversal::computeInitialRelativeRotations() { if ( node[0].body ) { dVector3 ax1, ax2; dMatrix3 R; dQuaternion qcross; getAxes( ax1, ax2 ); // Axis 1. dRFrom2Axes( R, ax1[0], ax1[1], ax1[2], ax2[0], ax2[1], ax2[2] ); dRtoQ( R, qcross ); dQMultiply1( qrel1, node[0].body->q, qcross ); // Axis 2. dRFrom2Axes( R, ax2[0], ax2[1], ax2[2], ax1[0], ax1[1], ax1[2] ); dRtoQ( R, qcross ); if ( node[1].body ) { dQMultiply1( qrel2, node[1].body->q, qcross ); } else { // set joint->qrel to qcross for ( int i = 0; i < 4; i++ ) qrel2[i] = qcross[i]; } } } void dJointSetUniversalAnchor( dJointID j, dReal x, dReal y, dReal z ) { dxJointUniversal* joint = ( dxJointUniversal* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Universal ); setAnchors( joint, x, y, z, joint->anchor1, joint->anchor2 ); joint->computeInitialRelativeRotations(); } void dJointSetUniversalAxis1( dJointID j, dReal x, dReal y, dReal z ) { dxJointUniversal* joint = ( dxJointUniversal* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Universal ); if ( joint->flags & dJOINT_REVERSE ) setAxes( joint, x, y, z, NULL, joint->axis2 ); else setAxes( joint, x, y, z, joint->axis1, NULL ); joint->computeInitialRelativeRotations(); } void dJointSetUniversalAxis1Offset( dJointID j, dReal x, dReal y, dReal z, dReal offset1, dReal offset2 ) { dxJointUniversal* joint = ( dxJointUniversal* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Universal ); if ( joint->flags & dJOINT_REVERSE ) { setAxes( joint, x, y, z, NULL, joint->axis2 ); offset1 = -offset1; offset2 = -offset2; } else setAxes( joint, x, y, z, joint->axis1, NULL ); joint->computeInitialRelativeRotations(); dVector3 ax2; getAxis2( joint, ax2, joint->axis2 ); { dVector3 ax1; joint->getAxes(ax1, ax2); } dQuaternion qAngle; dQFromAxisAndAngle(qAngle, x, y, z, offset1); dMatrix3 R; dRFrom2Axes( R, x, y, z, ax2[0], ax2[1], ax2[2] ); dQuaternion qcross; dRtoQ( R, qcross ); dQuaternion qOffset; dQMultiply0(qOffset, qAngle, qcross); dQMultiply1( joint->qrel1, joint->node[0].body->q, qOffset ); // Calculating the second offset dQFromAxisAndAngle(qAngle, ax2[0], ax2[1], ax2[2], offset2); dRFrom2Axes( R, ax2[0], ax2[1], ax2[2], x, y, z ); dRtoQ( R, qcross ); dQMultiply1(qOffset, qAngle, qcross); if ( joint->node[1].body ) { dQMultiply1( joint->qrel2, joint->node[1].body->q, qOffset ); } else { joint->qrel2[0] = qcross[0]; joint->qrel2[1] = qcross[1]; joint->qrel2[2] = qcross[2]; joint->qrel2[3] = qcross[3]; } } void dJointSetUniversalAxis2( dJointID j, dReal x, dReal y, dReal z ) { dxJointUniversal* joint = ( dxJointUniversal* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Universal ); if ( joint->flags & dJOINT_REVERSE ) setAxes( joint, x, y, z, joint->axis1, NULL ); else setAxes( joint, x, y, z, NULL, joint->axis2 ); joint->computeInitialRelativeRotations(); } void dJointSetUniversalAxis2Offset( dJointID j, dReal x, dReal y, dReal z, dReal offset1, dReal offset2 ) { dxJointUniversal* joint = ( dxJointUniversal* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Universal ); if ( joint->flags & dJOINT_REVERSE ) { setAxes( joint, x, y, z, joint->axis1, NULL ); offset1 = -offset2; offset2 = -offset1; } else setAxes( joint, x, y, z, NULL, joint->axis2 ); joint->computeInitialRelativeRotations(); // It is easier to retreive the 2 axes here since // when there is only one body B2 (the axes switch position) // Doing this way eliminate the need to write the code differently // for both case. dVector3 ax1, ax2; joint->getAxes(ax1, ax2 ); dQuaternion qAngle; dQFromAxisAndAngle(qAngle, ax1[0], ax1[1], ax1[2], offset1); dMatrix3 R; dRFrom2Axes( R, ax1[0], ax1[1], ax1[2], ax2[0], ax2[1], ax2[2]); dQuaternion qcross; dRtoQ( R, qcross ); dQuaternion qOffset; dQMultiply0(qOffset, qAngle, qcross); dQMultiply1( joint->qrel1, joint->node[0].body->q, qOffset ); // Calculating the second offset dQFromAxisAndAngle(qAngle, ax2[0], ax2[1], ax2[2], offset2); dRFrom2Axes( R, ax2[0], ax2[1], ax2[2], ax1[0], ax1[1], ax1[2]); dRtoQ( R, qcross ); dQMultiply1(qOffset, qAngle, qcross); if ( joint->node[1].body ) { dQMultiply1( joint->qrel2, joint->node[1].body->q, qOffset ); } else { joint->qrel2[0] = qcross[0]; joint->qrel2[1] = qcross[1]; joint->qrel2[2] = qcross[2]; joint->qrel2[3] = qcross[3]; } } void dJointGetUniversalAnchor( dJointID j, dVector3 result ) { dxJointUniversal* joint = ( dxJointUniversal* )j; dUASSERT( joint, "bad joint argument" ); dUASSERT( result, "bad result argument" ); checktype( joint, Universal ); if ( joint->flags & dJOINT_REVERSE ) getAnchor2( joint, result, joint->anchor2 ); else getAnchor( joint, result, joint->anchor1 ); } void dJointGetUniversalAnchor2( dJointID j, dVector3 result ) { dxJointUniversal* joint = ( dxJointUniversal* )j; dUASSERT( joint, "bad joint argument" ); dUASSERT( result, "bad result argument" ); checktype( joint, Universal ); if ( joint->flags & dJOINT_REVERSE ) getAnchor( joint, result, joint->anchor1 ); else getAnchor2( joint, result, joint->anchor2 ); } void dJointGetUniversalAxis1( dJointID j, dVector3 result ) { dxJointUniversal* joint = ( dxJointUniversal* )j; dUASSERT( joint, "bad joint argument" ); dUASSERT( result, "bad result argument" ); checktype( joint, Universal ); if ( joint->flags & dJOINT_REVERSE ) getAxis2( joint, result, joint->axis2 ); else getAxis( joint, result, joint->axis1 ); } void dJointGetUniversalAxis2( dJointID j, dVector3 result ) { dxJointUniversal* joint = ( dxJointUniversal* )j; dUASSERT( joint, "bad joint argument" ); dUASSERT( result, "bad result argument" ); checktype( joint, Universal ); if ( joint->flags & dJOINT_REVERSE ) getAxis( joint, result, joint->axis1 ); else getAxis2( joint, result, joint->axis2 ); } void dJointSetUniversalParam( dJointID j, int parameter, dReal value ) { dxJointUniversal* joint = ( dxJointUniversal* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Universal ); if (( parameter & 0xff00 ) == 0x100 ) { joint->limot2.set( parameter & 0xff, value ); } else { joint->limot1.set( parameter, value ); } } dReal dJointGetUniversalParam( dJointID j, int parameter ) { dxJointUniversal* joint = ( dxJointUniversal* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Universal ); if (( parameter & 0xff00 ) == 0x100 ) { return joint->limot2.get( parameter & 0xff ); } else { return joint->limot1.get( parameter ); } } void dJointGetUniversalAngles( dJointID j, dReal *angle1, dReal *angle2 ) { dxJointUniversal* joint = ( dxJointUniversal* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Universal ); if ( joint->flags & dJOINT_REVERSE ) { joint->getAngles( angle2, angle1 ); *angle2 = -(*angle2); } else { joint->getAngles( angle1, angle2 ); } } dReal dJointGetUniversalAngle1( dJointID j ) { dxJointUniversal* joint = ( dxJointUniversal* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Universal ); if ( joint->flags & dJOINT_REVERSE ) return joint->getAngle2(); else return joint->getAngle1(); } dReal dJointGetUniversalAngle2( dJointID j ) { dxJointUniversal* joint = ( dxJointUniversal* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Universal ); if ( joint->flags & dJOINT_REVERSE ) return -joint->getAngle1(); else return joint->getAngle2(); } dReal dJointGetUniversalAngle1Rate( dJointID j ) { dxJointUniversal* joint = ( dxJointUniversal* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Universal ); if ( joint->node[0].body ) { dVector3 axis; if ( joint->flags & dJOINT_REVERSE ) getAxis2( joint, axis, joint->axis2 ); else getAxis( joint, axis, joint->axis1 ); dReal rate = dDOT( axis, joint->node[0].body->avel ); if ( joint->node[1].body ) rate -= dDOT( axis, joint->node[1].body->avel ); return rate; } return 0; } dReal dJointGetUniversalAngle2Rate( dJointID j ) { dxJointUniversal* joint = ( dxJointUniversal* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Universal ); if ( joint->node[0].body ) { dVector3 axis; if ( joint->flags & dJOINT_REVERSE ) getAxis( joint, axis, joint->axis1 ); else getAxis2( joint, axis, joint->axis2 ); dReal rate = dDOT( axis, joint->node[0].body->avel ); if ( joint->node[1].body ) rate -= dDOT( axis, joint->node[1].body->avel ); return rate; } return 0; } void dJointAddUniversalTorques( dJointID j, dReal torque1, dReal torque2 ) { dxJointUniversal* joint = ( dxJointUniversal* )j; dVector3 axis1, axis2; dAASSERT( joint ); checktype( joint, Universal ); if ( joint->flags & dJOINT_REVERSE ) { dReal temp = torque1; torque1 = - torque2; torque2 = - temp; } getAxis( joint, axis1, joint->axis1 ); getAxis2( joint, axis2, joint->axis2 ); axis1[0] = axis1[0] * torque1 + axis2[0] * torque2; axis1[1] = axis1[1] * torque1 + axis2[1] * torque2; axis1[2] = axis1[2] * torque1 + axis2[2] * torque2; if ( joint->node[0].body != 0 ) dBodyAddTorque( joint->node[0].body, axis1[0], axis1[1], axis1[2] ); if ( joint->node[1].body != 0 ) dBodyAddTorque( joint->node[1].body, -axis1[0], -axis1[1], -axis1[2] ); } dJointType dxJointUniversal::type() const { return dJointTypeUniversal; } size_t dxJointUniversal::size() const { return sizeof( *this ); } void dxJointUniversal::setRelativeValues() { dVector3 anchor; dJointGetUniversalAnchor(this, anchor); setAnchors( this, anchor[0], anchor[1], anchor[2], anchor1, anchor2 ); dVector3 ax1,ax2; dJointGetUniversalAxis1(this, ax1); dJointGetUniversalAxis2(this, ax2); if ( flags & dJOINT_REVERSE ) { setAxes( this, ax1[0],ax1[1],ax1[2], NULL, axis2 ); setAxes( this, ax2[0],ax2[1],ax2[2], axis1, NULL ); } else { setAxes( this, ax1[0],ax1[1],ax1[2], axis1, NULL ); setAxes( this, ax2[0],ax2[1],ax2[2], NULL, axis2 ); } computeInitialRelativeRotations(); } alien-arena-7.66+dfsg/source/unix/odesrc/joints/pr.cpp0000600000175000017500000004415512161402010022010 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include "pr.h" #include "joint_internal.h" //**************************************************************************** // Prismatic and Rotoide dxJointPR::dxJointPR( dxWorld *w ) : dxJoint( w ) { // Default Position // Z^ // | Body 1 P R Body2 // |+---------+ _ _ +-----------+ // || |----|----(_)--------+ | // |+---------+ - +-----------+ // | // X.-----------------------------------------> Y // N.B. X is comming out of the page dSetZero( anchor2, 4 ); dSetZero( axisR1, 4 ); axisR1[0] = 1; dSetZero( axisR2, 4 ); axisR2[0] = 1; dSetZero( axisP1, 4 ); axisP1[1] = 1; dSetZero( qrel, 4 ); dSetZero( offset, 4 ); limotR.init( world ); limotP.init( world ); } dReal dJointGetPRPosition( dJointID j ) { dxJointPR* joint = ( dxJointPR* ) j; dUASSERT( joint, "bad joint argument" ); checktype( joint, PR ); dVector3 q; // get the offset in global coordinates dMULTIPLY0_331( q, joint->node[0].body->posr.R, joint->offset ); if ( joint->node[1].body ) { dVector3 anchor2; // get the anchor2 in global coordinates dMULTIPLY0_331( anchor2, joint->node[1].body->posr.R, joint->anchor2 ); q[0] = (( joint->node[0].body->posr.pos[0] + q[0] ) - ( joint->node[1].body->posr.pos[0] + anchor2[0] ) ); q[1] = (( joint->node[0].body->posr.pos[1] + q[1] ) - ( joint->node[1].body->posr.pos[1] + anchor2[1] ) ); q[2] = (( joint->node[0].body->posr.pos[2] + q[2] ) - ( joint->node[1].body->posr.pos[2] + anchor2[2] ) ); } else { //N.B. When there is no body 2 the joint->anchor2 is already in // global coordinates q[0] = (( joint->node[0].body->posr.pos[0] + q[0] ) - ( joint->anchor2[0] ) ); q[1] = (( joint->node[0].body->posr.pos[1] + q[1] ) - ( joint->anchor2[1] ) ); q[2] = (( joint->node[0].body->posr.pos[2] + q[2] ) - ( joint->anchor2[2] ) ); if ( joint->flags & dJOINT_REVERSE ) { q[0] = -q[0]; q[1] = -q[1]; q[2] = -q[2]; } } dVector3 axP; // get prismatic axis in global coordinates dMULTIPLY0_331( axP, joint->node[0].body->posr.R, joint->axisP1 ); return dDOT( axP, q ); } dReal dJointGetPRPositionRate( dJointID j ) { dxJointPR* joint = ( dxJointPR* ) j; dUASSERT( joint, "bad joint argument" ); checktype( joint, PR ); // get axis1 in global coordinates dVector3 ax1; dMULTIPLY0_331( ax1, joint->node[0].body->posr.R, joint->axisP1 ); if ( joint->node[1].body ) { dVector3 lv2; dBodyGetRelPointVel( joint->node[1].body, joint->anchor2[0], joint->anchor2[1], joint->anchor2[2], lv2 ); return dDOT( ax1, joint->node[0].body->lvel ) - dDOT( ax1, lv2 ); } else { dReal rate = dDOT( ax1, joint->node[0].body->lvel ); return ( (joint->flags & dJOINT_REVERSE) ? -rate : rate); } } dReal dJointGetPRAngle( dJointID j ) { dxJointPR* joint = ( dxJointPR* )j; dAASSERT( joint ); checktype( joint, PR ); if ( joint->node[0].body ) { dReal ang = getHingeAngle( joint->node[0].body, joint->node[1].body, joint->axisR1, joint->qrel ); if ( joint->flags & dJOINT_REVERSE ) return -ang; else return ang; } else return 0; } dReal dJointGetPRAngleRate( dJointID j ) { dxJointPR* joint = ( dxJointPR* )j; dAASSERT( joint ); checktype( joint, PR ); if ( joint->node[0].body ) { dVector3 axis; dMULTIPLY0_331( axis, joint->node[0].body->posr.R, joint->axisR1 ); dReal rate = dDOT( axis, joint->node[0].body->avel ); if ( joint->node[1].body ) rate -= dDOT( axis, joint->node[1].body->avel ); if ( joint->flags & dJOINT_REVERSE ) rate = -rate; return rate; } else return 0; } void dxJointPR::getInfo1( dxJoint::Info1 *info ) { info->nub = 4; info->m = 4; // see if we're at a joint limit. limotP.limit = 0; if (( limotP.lostop > -dInfinity || limotP.histop < dInfinity ) && limotP.lostop <= limotP.histop ) { // measure joint position dReal pos = dJointGetPRPosition( this ); limotP.testRotationalLimit( pos ); // N.B. The function is ill named } // powered needs an extra constraint row if ( limotP.limit || limotP.fmax > 0 ) info->m++; // see if we're at a joint limit. limotR.limit = 0; if (( limotR.lostop >= -M_PI || limotR.histop <= M_PI ) && limotR.lostop <= limotR.histop ) { dReal angle = getHingeAngle( node[0].body, node[1].body, axisR1, qrel ); limotR.testRotationalLimit( angle ); } // powered morit or at limits needs an extra constraint row if ( limotR.limit || limotR.fmax > 0 ) info->m++; } void dxJointPR::getInfo2( dxJoint::Info2 *info ) { int s = info->rowskip; int s2 = 2 * s; int s3 = 3 * s; //int s4= 4*s; dReal k = info->fps * info->erp; dVector3 q; // plane space of axP and after that axR // pull out pos and R for both bodies. also get the `connection' // vector pos2-pos1. dReal *pos1, *pos2 = 0, *R1, *R2 = 0; pos1 = node[0].body->posr.pos; R1 = node[0].body->posr.R; if ( node[1].body ) { pos2 = node[1].body->posr.pos; R2 = node[1].body->posr.R; } else { // pos2 = 0; // N.B. We can do that to be safe but it is no necessary // R2 = 0; // N.B. We can do that to be safe but it is no necessary } dVector3 axP; // Axis of the prismatic joint in global frame dMULTIPLY0_331( axP, R1, axisP1 ); // distance between the body1 and the anchor2 in global frame // Calculated in the same way as the offset dVector3 wanchor2 = {0,0,0}, dist; if ( node[1].body ) { // Calculate anchor2 in world coordinate dMULTIPLY0_331( wanchor2, R2, anchor2 ); dist[0] = wanchor2[0] + pos2[0] - pos1[0]; dist[1] = wanchor2[1] + pos2[1] - pos1[1]; dist[2] = wanchor2[2] + pos2[2] - pos1[2]; } else { if (flags & dJOINT_REVERSE ) { dist[0] = pos1[0] - anchor2[0]; // Invert the value dist[1] = pos1[1] - anchor2[1]; dist[2] = pos1[2] - anchor2[2]; } else { dist[0] = anchor2[0] - pos1[0]; dist[1] = anchor2[1] - pos1[1]; dist[2] = anchor2[2] - pos1[2]; } } // ====================================================================== // Work on the Rotoide part (i.e. row 0, 1 and maybe 4 if rotoide powered // Set the two rotoide rows. The rotoide axis should be the only unconstrained // rotational axis, the angular velocity of the two bodies perpendicular to // the rotoide axis should be equal. Thus the constraint equations are // p*w1 - p*w2 = 0 // q*w1 - q*w2 = 0 // where p and q are unit vectors normal to the rotoide axis, and w1 and w2 // are the angular velocity vectors of the two bodies. dVector3 ax1; dMULTIPLY0_331( ax1, node[0].body->posr.R, axisR1 ); dCROSS( q , = , ax1, axP ); info->J1a[0] = axP[0]; info->J1a[1] = axP[1]; info->J1a[2] = axP[2]; info->J1a[s+0] = q[0]; info->J1a[s+1] = q[1]; info->J1a[s+2] = q[2]; if ( node[1].body ) { info->J2a[0] = -axP[0]; info->J2a[1] = -axP[1]; info->J2a[2] = -axP[2]; info->J2a[s+0] = -q[0]; info->J2a[s+1] = -q[1]; info->J2a[s+2] = -q[2]; } // Compute the right hand side of the constraint equation set. Relative // body velocities along p and q to bring the rotoide back into alignment. // ax1,ax2 are the unit length rotoide axes of body1 and body2 in world frame. // We need to rotate both bodies along the axis u = (ax1 x ax2). // if `theta' is the angle between ax1 and ax2, we need an angular velocity // along u to cover angle erp*theta in one step : // |angular_velocity| = angle/time = erp*theta / stepsize // = (erp*fps) * theta // angular_velocity = |angular_velocity| * (ax1 x ax2) / |ax1 x ax2| // = (erp*fps) * theta * (ax1 x ax2) / sin(theta) // ...as ax1 and ax2 are unit length. if theta is smallish, // theta ~= sin(theta), so // angular_velocity = (erp*fps) * (ax1 x ax2) // ax1 x ax2 is in the plane space of ax1, so we project the angular // velocity to p and q to find the right hand side. dVector3 ax2; if ( node[1].body ) { dMULTIPLY0_331( ax2, R2, axisR2 ); } else { ax2[0] = axisR2[0]; ax2[1] = axisR2[1]; ax2[2] = axisR2[2]; } dVector3 b; dCROSS( b, = , ax1, ax2 ); info->c[0] = k * dDOT( b, axP ); info->c[1] = k * dDOT( b, q ); // ========================== // Work on the Prismatic part (i.e row 2,3 and 4 if only the prismatic is powered // or 5 if rotoide and prismatic powered // two rows. we want: vel2 = vel1 + w1 x c ... but this would // result in three equations, so we project along the planespace vectors // so that sliding along the prismatic axis is disregarded. for symmetry we // also substitute (w1+w2)/2 for w1, as w1 is supposed to equal w2. // p1 + R1 dist' = p2 + R2 anchor2' ## OLD ## p1 + R1 anchor1' = p2 + R2 dist' // v1 + w1 x R1 dist' + v_p = v2 + w2 x R2 anchor2'## OLD v1 + w1 x R1 anchor1' = v2 + w2 x R2 dist' + v_p // v_p is speed of prismatic joint (i.e. elongation rate) // Since the constraints are perpendicular to v_p we have: // p dot v_p = 0 and q dot v_p = 0 // ax1 dot ( v1 + w1 x dist = v2 + w2 x anchor2 ) // q dot ( v1 + w1 x dist = v2 + w2 x anchor2 ) // == // ax1 . v1 + ax1 . w1 x dist = ax1 . v2 + ax1 . w2 x anchor2 ## OLD ## ax1 . v1 + ax1 . w1 x anchor1 = ax1 . v2 + ax1 . w2 x dist // since a . (b x c) = - b . (a x c) = - (a x c) . b // and a x b = - b x a // ax1 . v1 - ax1 x dist . w1 - ax1 . v2 - (- ax1 x anchor2 . w2) = 0 // ax1 . v1 + dist x ax1 . w1 - ax1 . v2 - anchor2 x ax1 . w2 = 0 // Coeff for 1er line of: J1l => ax1, J2l => -ax1 // Coeff for 2er line of: J1l => q, J2l => -q // Coeff for 1er line of: J1a => dist x ax1, J2a => - anchor2 x ax1 // Coeff for 2er line of: J1a => dist x q, J2a => - anchor2 x q dCROSS(( info->J1a ) + s2, = , dist, ax1 ); dCROSS(( info->J1a ) + s3, = , dist, q ); info->J1l[s2+0] = ax1[0]; info->J1l[s2+1] = ax1[1]; info->J1l[s2+2] = ax1[2]; info->J1l[s3+0] = q[0]; info->J1l[s3+1] = q[1]; info->J1l[s3+2] = q[2]; if ( node[1].body ) { // ax2 x anchor2 instead of anchor2 x ax2 since we want the negative value dCROSS(( info->J2a ) + s2, = , ax2, wanchor2 ); // since ax1 == ax2 // The cross product is in reverse order since we want the negative value dCROSS(( info->J2a ) + s3, = , q, wanchor2 ); info->J2l[s2+0] = -ax1[0]; info->J2l[s2+1] = -ax1[1]; info->J2l[s2+2] = -ax1[2]; info->J2l[s3+0] = -q[0]; info->J2l[s3+1] = -q[1]; info->J2l[s3+2] = -q[2]; } // We want to make correction for motion not in the line of the axisP // We calculate the displacement w.r.t. the anchor pt. // // compute the elements 2 and 3 of right hand side. // we want to align the offset point (in body 2's frame) with the center of body 1. // The position should be the same when we are not along the prismatic axis dVector3 err; dMULTIPLY0_331( err, R1, offset ); err[0] = dist[0] - err[0]; err[1] = dist[1] - err[1]; err[2] = dist[2] - err[2]; info->c[2] = k * dDOT( ax1, err ); info->c[3] = k * dDOT( q, err ); int row = 4; if ( node[1].body || !(flags & dJOINT_REVERSE) ) { row += limotP.addLimot ( this, info, 4, axP, 0 ); } else { dVector3 rAxP; rAxP[0] = -axP[0]; rAxP[1] = -axP[1]; rAxP[2] = -axP[2]; row += limotP.addLimot ( this, info, 4, rAxP, 0 ); } limotR.addLimot ( this, info, row, ax1, 1 ); } // compute initial relative rotation body1 -> body2, or env -> body1 void dxJointPR::computeInitialRelativeRotation() { if ( node[0].body ) { if ( node[1].body ) { dQMultiply1( qrel, node[0].body->q, node[1].body->q ); } else { // set joint->qrel to the transpose of the first body q qrel[0] = node[0].body->q[0]; for ( int i = 1; i < 4; i++ ) qrel[i] = -node[0].body->q[i]; // WARNING do we need the - in -joint->node[0].body->q[i]; or not } } } void dJointSetPRAnchor( dJointID j, dReal x, dReal y, dReal z ) { dxJointPR* joint = ( dxJointPR* ) j; dUASSERT( joint, "bad joint argument" ); checktype( joint, PR ); setAnchors( joint, x, y, z, joint->offset, joint->anchor2 ); } void dJointSetPRAxis1( dJointID j, dReal x, dReal y, dReal z ) { dxJointPR* joint = ( dxJointPR* ) j; dUASSERT( joint, "bad joint argument" ); checktype( joint, PR ); setAxes( joint, x, y, z, joint->axisP1, 0 ); joint->computeInitialRelativeRotation(); } void dJointSetPRAxis2( dJointID j, dReal x, dReal y, dReal z ) { dxJointPR* joint = ( dxJointPR* ) j; dUASSERT( joint, "bad joint argument" ); checktype( joint, PR ); setAxes( joint, x, y, z, joint->axisR1, joint->axisR2 ); joint->computeInitialRelativeRotation(); } void dJointSetPRParam( dJointID j, int parameter, dReal value ) { dxJointPR* joint = ( dxJointPR* ) j; dUASSERT( joint, "bad joint argument" ); checktype( joint, PR ); if (( parameter & 0xff00 ) == 0x100 ) { joint->limotR.set( parameter & 0xff, value ); // Take only lower part of the } // parameter alue else { joint->limotP.set( parameter, value ); } } void dJointGetPRAnchor( dJointID j, dVector3 result ) { dxJointPR* joint = ( dxJointPR* ) j; dUASSERT( joint, "bad joint argument" ); dUASSERT( result, "bad result argument" ); checktype( joint, PR ); if ( joint->node[1].body ) getAnchor2( joint, result, joint->anchor2 ); else { result[0] = joint->anchor2[0]; result[1] = joint->anchor2[1]; result[2] = joint->anchor2[2]; } } void dJointGetPRAxis1( dJointID j, dVector3 result ) { dxJointPR* joint = ( dxJointPR* ) j; dUASSERT( joint, "bad joint argument" ); dUASSERT( result, "bad result argument" ); checktype( joint, PR ); getAxis( joint, result, joint->axisP1 ); } void dJointGetPRAxis2( dJointID j, dVector3 result ) { dxJointPR* joint = ( dxJointPR* ) j; dUASSERT( joint, "bad joint argument" ); dUASSERT( result, "bad result argument" ); checktype( joint, PR ); getAxis( joint, result, joint->axisR1 ); } dReal dJointGetPRParam( dJointID j, int parameter ) { dxJointPR* joint = ( dxJointPR* ) j; dUASSERT( joint, "bad joint argument" ); checktype( joint, PR ); if (( parameter & 0xff00 ) == 0x100 ) { return joint->limotR.get( parameter & 0xff ); } else { return joint->limotP.get( parameter ); } } void dJointAddPRTorque( dJointID j, dReal torque ) { dxJointPR* joint = ( dxJointPR* ) j; dVector3 axis; dAASSERT( joint ); checktype( joint, PR ); if ( joint->flags & dJOINT_REVERSE ) torque = -torque; getAxis( joint, axis, joint->axisR1 ); axis[0] *= torque; axis[1] *= torque; axis[2] *= torque; if ( joint->node[0].body != 0 ) dBodyAddTorque( joint->node[0].body, axis[0], axis[1], axis[2] ); if ( joint->node[1].body != 0 ) dBodyAddTorque( joint->node[1].body, -axis[0], -axis[1], -axis[2] ); } dJointType dxJointPR::type() const { return dJointTypePR; } size_t dxJointPR::size() const { return sizeof( *this ); } void dxJointPR::setRelativeValues() { dVector3 anchor; dJointGetPRAnchor(this, anchor); setAnchors( this, anchor[0], anchor[1], anchor[2], offset, anchor2 ); dVector3 axis; dJointGetPRAxis1(this, axis); setAxes( this, axis[0], axis[1], axis[2], axisP1, 0 ); dJointGetPRAxis2(this, axis); setAxes( this, axis[0], axis[1], axis[2], axisR1, axisR2 ); computeInitialRelativeRotation(); } alien-arena-7.66+dfsg/source/unix/odesrc/joints/fixed.cpp0000600000175000017500000001260212161402010022456 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include "fixed.h" #include "joint_internal.h" //**************************************************************************** // fixed joint dxJointFixed::dxJointFixed ( dxWorld *w ) : dxJoint ( w ) { dSetZero ( offset, 4 ); dSetZero ( qrel, 4 ); erp = world->global_erp; cfm = world->global_cfm; } void dxJointFixed::getInfo1 ( dxJoint::Info1 *info ) { info->m = 6; info->nub = 6; } void dxJointFixed::getInfo2 ( dxJoint::Info2 *info ) { int s = info->rowskip; // Three rows for orientation setFixedOrientation ( this, info, qrel, 3 ); // Three rows for position. // set jacobian info->J1l[0] = 1; info->J1l[s+1] = 1; info->J1l[2*s+2] = 1; info->erp = erp; info->cfm[0] = cfm; info->cfm[1] = cfm; info->cfm[2] = cfm; dVector3 ofs; dMULTIPLY0_331 ( ofs, node[0].body->posr.R, offset ); if ( node[1].body ) { dCROSSMAT ( info->J1a, ofs, s, + , - ); info->J2l[0] = -1; info->J2l[s+1] = -1; info->J2l[2*s+2] = -1; } // set right hand side for the first three rows (linear) dReal k = info->fps * info->erp; if ( node[1].body ) { for ( int j = 0; j < 3; j++ ) info->c[j] = k * ( node[1].body->posr.pos[j] - node[0].body->posr.pos[j] + ofs[j] ); } else { for ( int j = 0; j < 3; j++ ) info->c[j] = k * ( offset[j] - node[0].body->posr.pos[j] ); } } void dJointSetFixed ( dJointID j ) { dxJointFixed* joint = ( dxJointFixed* ) j; dUASSERT ( joint, "bad joint argument" ); checktype ( joint, Fixed ); int i; // This code is taken from dJointSetSliderAxis(), we should really put the // common code in its own function. // compute the offset between the bodies if ( joint->node[0].body ) { if ( joint->node[1].body ) { dReal ofs[4]; for ( i = 0; i < 4; i++ ) ofs[i] = joint->node[0].body->posr.pos[i] - joint->node[1].body->posr.pos[i]; dMULTIPLY1_331 ( joint->offset, joint->node[0].body->posr.R, ofs ); } else { joint->offset[0] = joint->node[0].body->posr.pos[0]; joint->offset[1] = joint->node[0].body->posr.pos[1]; joint->offset[2] = joint->node[0].body->posr.pos[2]; } } joint->computeInitialRelativeRotation(); } void dxJointFixed::set ( int num, dReal value ) { switch ( num ) { case dParamCFM: cfm = value; break; case dParamERP: erp = value; break; } } dReal dxJointFixed::get ( int num ) { switch ( num ) { case dParamCFM: return cfm; case dParamERP: return erp; default: return 0; } } void dJointSetFixedParam ( dJointID j, int parameter, dReal value ) { dxJointFixed* joint = ( dxJointFixed* ) j; dUASSERT ( joint, "bad joint argument" ); checktype ( joint, Fixed ); joint->set ( parameter, value ); } dReal dJointGetFixedParam ( dJointID j, int parameter ) { dxJointFixed* joint = ( dxJointFixed* ) j; dUASSERT ( joint, "bad joint argument" ); checktype ( joint, Fixed ); return joint->get ( parameter ); } dJointType dxJointFixed::type() const { return dJointTypeFixed; } size_t dxJointFixed::size() const { return sizeof ( *this ); } void dxJointFixed::computeInitialRelativeRotation() { if (node[0].body ) { if (node[1].body ) { dQMultiply1 (qrel, node[0].body->q, node[1].body->q ); } else { // set qrel to the transpose of the first body q qrel[0] = node[0].body->q[0]; qrel[1] = -node[0].body->q[1]; qrel[2] = -node[0].body->q[2]; qrel[3] = -node[0].body->q[3]; } } } alien-arena-7.66+dfsg/source/unix/odesrc/joints/plane2d.cpp0000600000175000017500000001224012161402010022702 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include "plane2d.h" #include "joint_internal.h" //**************************************************************************** // Plane2D /* This code is part of the Plane2D ODE joint by psero@gmx.de Wed Apr 23 18:53:43 CEST 2003 */ # define VoXYZ(v1, o1, x, y, z) \ ( \ (v1)[0] o1 (x), \ (v1)[1] o1 (y), \ (v1)[2] o1 (z) \ ) static const dReal Midentity[3][3] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1, } }; dxJointPlane2D::dxJointPlane2D( dxWorld *w ) : dxJoint( w ) { motor_x.init( world ); motor_y.init( world ); motor_angle.init( world ); } void dxJointPlane2D::getInfo1( dxJoint::Info1 *info ) { info->nub = 3; info->m = 3; if ( motor_x.fmax > 0 ) row_motor_x = info->m ++; if ( motor_y.fmax > 0 ) row_motor_y = info->m ++; if ( motor_angle.fmax > 0 ) row_motor_angle = info->m ++; } void dxJointPlane2D::getInfo2( dxJoint::Info2 *info ) { int r0 = 0, r1 = info->rowskip, r2 = 2 * r1; dReal eps = info->fps * info->erp; /* v = v1, w = omega1 (v2, omega2 not important (== static environment)) constraint equations: xz = 0 wx = 0 wy = 0 <=> ( 0 0 1 ) (vx) ( 0 0 0 ) (wx) ( 0 ) ( 0 0 0 ) (vy) + ( 1 0 0 ) (wy) = ( 0 ) ( 0 0 0 ) (vz) ( 0 1 0 ) (wz) ( 0 ) J1/J1l Omega1/J1a */ // fill in linear and angular coeff. for left hand side: VoXYZ( &info->J1l[r0], = , 0, 0, 1 ); VoXYZ( &info->J1l[r1], = , 0, 0, 0 ); VoXYZ( &info->J1l[r2], = , 0, 0, 0 ); VoXYZ( &info->J1a[r0], = , 0, 0, 0 ); VoXYZ( &info->J1a[r1], = , 1, 0, 0 ); VoXYZ( &info->J1a[r2], = , 0, 1, 0 ); // error correction (against drift): // a) linear vz, so that z (== pos[2]) == 0 info->c[0] = eps * -node[0].body->posr.pos[2]; # if 0 // b) angular correction? -> left to application !!! dReal *body_z_axis = &node[0].body->R[8]; info->c[1] = eps * + atan2( body_z_axis[1], body_z_axis[2] ); // wx error info->c[2] = eps * -atan2( body_z_axis[0], body_z_axis[2] ); // wy error # endif // if the slider is powered, or has joint limits, add in the extra row: if ( row_motor_x > 0 ) motor_x.addLimot( this, info, row_motor_x, Midentity[0], 0 ); if ( row_motor_y > 0 ) motor_y.addLimot( this, info, row_motor_y, Midentity[1], 0 ); if ( row_motor_angle > 0 ) motor_angle.addLimot( this, info, row_motor_angle, Midentity[2], 1 ); } dJointType dxJointPlane2D::type() const { return dJointTypePlane2D; }; size_t dxJointPlane2D::size() const { return sizeof( *this ); } void dJointSetPlane2DXParam( dxJoint *joint, int parameter, dReal value ) { dUASSERT( joint, "bad joint argument" ); checktype( joint, Plane2D ); dxJointPlane2D* joint2d = ( dxJointPlane2D* )( joint ); joint2d->motor_x.set( parameter, value ); } void dJointSetPlane2DYParam( dxJoint *joint, int parameter, dReal value ) { dUASSERT( joint, "bad joint argument" ); checktype( joint, Plane2D ); dxJointPlane2D* joint2d = ( dxJointPlane2D* )( joint ); joint2d->motor_y.set( parameter, value ); } void dJointSetPlane2DAngleParam( dxJoint *joint, int parameter, dReal value ) { dUASSERT( joint, "bad joint argument" ); checktype( joint, Plane2D ); dxJointPlane2D* joint2d = ( dxJointPlane2D* )( joint ); joint2d->motor_angle.set( parameter, value ); } alien-arena-7.66+dfsg/source/unix/odesrc/joints/slider.h0000600000175000017500000000457412161402010022317 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_JOINT_SLIDER_H_ #define _ODE_JOINT_SLIDER_H_ #include "joint.h" // slider. if body2 is 0 then qrel is the absolute rotation of body1 and // offset is the position of body1 center along axis1. struct dxJointSlider : public dxJoint { dVector3 axis1; // axis w.r.t first body dQuaternion qrel; // initial relative rotation body1 -> body2 dVector3 offset; // point relative to body2 that should be // aligned with body1 center along axis1 dxJointLimitMotor limot; // limit and motor information dxJointSlider ( dxWorld *w ); virtual void getInfo1 ( Info1* info ); virtual void getInfo2 ( Info2* info ); virtual dJointType type() const; virtual size_t size() const; virtual void setRelativeValues(); void computeInitialRelativeRotation(); void computeOffset(); }; #endif alien-arena-7.66+dfsg/source/unix/odesrc/joints/joint_internal.h0000600000175000017500000000547712161402010024057 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_JOINT_NTERNAL_H_ #define _ODE_JOINT_INTERNAL_H_ #include "config.h" #include #include #include #include #define checktype(j,t) dUASSERT(j->type() == dJointType##t, \ "joint type is not " #t) void setBall( dxJoint *joint, dxJoint::Info2 *info, dVector3 anchor1, dVector3 anchor2 ); void setBall2( dxJoint *joint, dxJoint::Info2 *info, dVector3 anchor1, dVector3 anchor2, dVector3 axis, dReal erp1 ); void setAnchors( dxJoint *j, dReal x, dReal y, dReal z, dVector3 anchor1, dVector3 anchor2 ); void getAnchor( dxJoint *j, dVector3 result, dVector3 anchor1 ); void getAnchor2( dxJoint *j, dVector3 result, dVector3 anchor2 ); void setAxes( dxJoint *j, dReal x, dReal y, dReal z, dVector3 axis1, dVector3 axis2 ); void getAxis( dxJoint *j, dVector3 result, dVector3 axis1 ); void getAxis2( dxJoint *j, dVector3 result, dVector3 axis2 ); dReal getHingeAngle( dxBody *body1, dxBody *body2, dVector3 axis, dQuaternion q_initial ); dReal getHingeAngleFromRelativeQuat( dQuaternion qrel, dVector3 axis ); void setFixedOrientation( dxJoint *joint, dxJoint::Info2 *info, dQuaternion qrel, int start_row ); #endif alien-arena-7.66+dfsg/source/unix/odesrc/joints/pu.h0000600000175000017500000000735512161402010021461 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_JOINT_PU_H_ #define _ODE_JOINT_PU_H_ #include "universal.h" /** * Component of a Prismatic -- Universal joint. * The axisP must be perpendicular to axis1. * The second axis of the universal joint is perpendicular to axis1. * * Since the PU joint is derived from the Universal joint. Some variable * are reused. * * anchor1: Vector from body1 to the anchor point * This vector is calculated when the body are attached or * when the anchor point is set. It is like the offset of the Slider * joint. Since their is a prismatic between the anchor and the body1 * the distance might change as the simulation goes on. * anchor2: Vector from body2 to the anchor point. *
 *                                                 Body 2
 *                                                 +-------------+
 *                                                 |      x      |
 *                                                 +------------\+
 *          Prismatic articulation                   ..     ..
 *                                |                ..     ..
 *          Body 1                v             ..      ..
 *          +--------------+    --|        __..      ..  anchor2
 * <--------|      x       | .....|.......(__)     ..
 * axisP    +--------------+    --|         ^     <
 *                 |----------------------->|
 *                     anchor1              |--- Universal articulation
 *                                               axis1 going out of the plane
 *                                               axis2 is perpendicular to axis1
 *                                               (i.e. 2 rotoides)
 * 
*/ struct dxJointPU : public dxJointUniversal { /// @brief Axis for the prismatic articulation w.r.t first body. /// @note This is considered as axis2 from the parameter view dVector3 axisP1; dxJointLimitMotor limotP; ///< limit and motor information for the prismatic articulation. dxJointPU( dxWorld *w ); virtual void getInfo1( Info1* info ); virtual void getInfo2( Info2* info ); virtual dJointType type() const; virtual size_t size() const; virtual void setRelativeValues(); }; #endif alien-arena-7.66+dfsg/source/unix/odesrc/joints/joints.h0000600000175000017500000000363412161402010022337 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_JOINTS_H_ #define _ODE_JOINTS_H_ #include #include "joint.h" #include "ball.h" #include "hinge.h" #include "slider.h" #include "contact.h" #include "universal.h" #include "hinge2.h" #include "fixed.h" #include "null.h" #include "amotor.h" #include "lmotor.h" #include "plane2d.h" #include "pu.h" #include "pr.h" #include "piston.h" #endif alien-arena-7.66+dfsg/source/unix/odesrc/joints/ball.cpp0000600000175000017500000001105612161402010022273 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include "ball.h" #include "joint_internal.h" //**************************************************************************** // ball and socket dxJointBall::dxJointBall( dxWorld *w ) : dxJoint( w ) { dSetZero( anchor1, 4 ); dSetZero( anchor2, 4 ); erp = world->global_erp; cfm = world->global_cfm; } void dxJointBall::getInfo1( dxJoint::Info1 *info ) { info->m = 3; info->nub = 3; } void dxJointBall::getInfo2( dxJoint::Info2 *info ) { info->erp = erp; info->cfm[0] = cfm; info->cfm[1] = cfm; info->cfm[2] = cfm; setBall( this, info, anchor1, anchor2 ); } void dJointSetBallAnchor( dJointID j, dReal x, dReal y, dReal z ) { dxJointBall* joint = ( dxJointBall* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Ball ); setAnchors( joint, x, y, z, joint->anchor1, joint->anchor2 ); } void dJointSetBallAnchor2( dJointID j, dReal x, dReal y, dReal z ) { dxJointBall* joint = ( dxJointBall* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Ball ); joint->anchor2[0] = x; joint->anchor2[1] = y; joint->anchor2[2] = z; joint->anchor2[3] = 0; } void dJointGetBallAnchor( dJointID j, dVector3 result ) { dxJointBall* joint = ( dxJointBall* )j; dUASSERT( joint, "bad joint argument" ); dUASSERT( result, "bad result argument" ); checktype( joint, Ball ); if ( joint->flags & dJOINT_REVERSE ) getAnchor2( joint, result, joint->anchor2 ); else getAnchor( joint, result, joint->anchor1 ); } void dJointGetBallAnchor2( dJointID j, dVector3 result ) { dxJointBall* joint = ( dxJointBall* )j; dUASSERT( joint, "bad joint argument" ); dUASSERT( result, "bad result argument" ); checktype( joint, Ball ); if ( joint->flags & dJOINT_REVERSE ) getAnchor( joint, result, joint->anchor1 ); else getAnchor2( joint, result, joint->anchor2 ); } void dxJointBall::set( int num, dReal value ) { switch ( num ) { case dParamCFM: cfm = value; break; case dParamERP: erp = value; break; } } dReal dxJointBall::get( int num ) { switch ( num ) { case dParamCFM: return cfm; case dParamERP: return erp; default: return 0; } } void dJointSetBallParam( dJointID j, int parameter, dReal value ) { dxJointBall* joint = ( dxJointBall* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Ball ); joint->set( parameter, value ); } dReal dJointGetBallParam( dJointID j, int parameter ) { dxJointBall* joint = ( dxJointBall* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Ball ); return joint->get( parameter ); } dJointType dxJointBall::type() const { return dJointTypeBall; } size_t dxJointBall::size() const { return sizeof( *this ); } void dxJointBall::setRelativeValues() { dVector3 anchor; dJointGetBallAnchor(this, anchor); setAnchors( this, anchor[0], anchor[1], anchor[2], anchor1, anchor2 ); } alien-arena-7.66+dfsg/source/unix/odesrc/joints/hinge2.h0000600000175000017500000000515412161402010022204 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_JOINT_HINGE2_H_ #define _ODE_JOINT_HINGE2_H_ #include "joint.h" // hinge 2 struct dxJointHinge2 : public dxJoint { dVector3 anchor1; // anchor w.r.t first body dVector3 anchor2; // anchor w.r.t second body dVector3 axis1; // axis 1 w.r.t first body dVector3 axis2; // axis 2 w.r.t second body dReal c0, s0; // cos,sin of desired angle between axis 1,2 dVector3 v1, v2; // angle ref vectors embedded in first body dxJointLimitMotor limot1; // limit+motor info for axis 1 dxJointLimitMotor limot2; // limit+motor info for axis 2 dReal susp_erp, susp_cfm; // suspension parameters (erp,cfm) dReal measureAngle() const; void makeV1andV2(); void getAxisInfo(dVector3 ax1, dVector3 ax2, dVector3 axis, dReal &sin_angle, dReal &cos_Angle) const; dxJointHinge2( dxWorld *w ); virtual void getInfo1( Info1* info ); virtual void getInfo2( Info2* info ); virtual dJointType type() const; virtual size_t size() const; virtual void setRelativeValues(); }; #endif alien-arena-7.66+dfsg/source/unix/odesrc/joints/hinge.h0000600000175000017500000000441512161402010022121 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_JOINT_HINGE_H_ #define _ODE_JOINT_HINGE_H_ #include "joint.h" // hinge struct dxJointHinge : public dxJoint { dVector3 anchor1; // anchor w.r.t first body dVector3 anchor2; // anchor w.r.t second body dVector3 axis1; // axis w.r.t first body dVector3 axis2; // axis w.r.t second body dQuaternion qrel; // initial relative rotation body1 -> body2 dxJointLimitMotor limot; // limit and motor information dxJointHinge( dxWorld *w ); virtual void getInfo1( Info1* info ); virtual void getInfo2( Info2* info ); virtual dJointType type() const; virtual size_t size() const; virtual void setRelativeValues(); void computeInitialRelativeRotation(); }; #endif alien-arena-7.66+dfsg/source/unix/odesrc/joints/slider.cpp0000600000175000017500000002735712161402010022656 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include "slider.h" #include "joint_internal.h" //**************************************************************************** // slider dxJointSlider::dxJointSlider ( dxWorld *w ) : dxJoint ( w ) { dSetZero ( axis1, 4 ); axis1[0] = 1; dSetZero ( qrel, 4 ); dSetZero ( offset, 4 ); limot.init ( world ); } dReal dJointGetSliderPosition ( dJointID j ) { dxJointSlider* joint = ( dxJointSlider* ) j; dUASSERT ( joint, "bad joint argument" ); checktype ( joint, Slider ); // get axis1 in global coordinates dVector3 ax1, q; dMULTIPLY0_331 ( ax1, joint->node[0].body->posr.R, joint->axis1 ); if ( joint->node[1].body ) { // get body2 + offset point in global coordinates dMULTIPLY0_331 ( q, joint->node[1].body->posr.R, joint->offset ); for ( int i = 0; i < 3; i++ ) q[i] = joint->node[0].body->posr.pos[i] - q[i] - joint->node[1].body->posr.pos[i]; } else { q[0] = joint->node[0].body->posr.pos[0] - joint->offset[0]; q[1] = joint->node[0].body->posr.pos[1] - joint->offset[1]; q[2] = joint->node[0].body->posr.pos[2] - joint->offset[2]; if ( joint->flags & dJOINT_REVERSE ) { // N.B. it could have been simplier to only inverse the sign of // the dDot result but this case is exceptional and doing // the check for all case can decrease the performance. ax1[0] = -ax1[0]; ax1[1] = -ax1[1]; ax1[2] = -ax1[2]; } } return dDOT ( ax1, q ); } dReal dJointGetSliderPositionRate ( dJointID j ) { dxJointSlider* joint = ( dxJointSlider* ) j; dUASSERT ( joint, "bad joint argument" ); checktype ( joint, Slider ); // get axis1 in global coordinates dVector3 ax1; dMULTIPLY0_331 ( ax1, joint->node[0].body->posr.R, joint->axis1 ); if ( joint->node[1].body ) { return dDOT ( ax1, joint->node[0].body->lvel ) - dDOT ( ax1, joint->node[1].body->lvel ); } else { dReal rate = dDOT ( ax1, joint->node[0].body->lvel ); if ( joint->flags & dJOINT_REVERSE ) rate = - rate; return rate; } } void dxJointSlider::getInfo1 ( dxJoint::Info1 *info ) { info->nub = 5; // see if joint is powered if ( limot.fmax > 0 ) info->m = 6; // powered slider needs an extra constraint row else info->m = 5; // see if we're at a joint limit. limot.limit = 0; if ( ( limot.lostop > -dInfinity || limot.histop < dInfinity ) && limot.lostop <= limot.histop ) { // measure joint position dReal pos = dJointGetSliderPosition ( this ); if ( pos <= limot.lostop ) { limot.limit = 1; limot.limit_err = pos - limot.lostop; info->m = 6; } else if ( pos >= limot.histop ) { limot.limit = 2; limot.limit_err = pos - limot.histop; info->m = 6; } } } void dxJointSlider::getInfo2 ( dxJoint::Info2 *info ) { int i, s = info->rowskip; int s3 = 3 * s, s4 = 4 * s; // pull out pos and R for both bodies. also get the `connection' // vector pos2-pos1. dReal *pos1, *pos2, *R1, *R2; dVector3 c; pos1 = node[0].body->posr.pos; R1 = node[0].body->posr.R; if ( node[1].body ) { pos2 = node[1].body->posr.pos; R2 = node[1].body->posr.R; for ( i = 0; i < 3; i++ ) c[i] = pos2[i] - pos1[i]; } else { pos2 = 0; R2 = 0; } // 3 rows to make body rotations equal setFixedOrientation ( this, info, qrel, 0 ); // remaining two rows. we want: vel2 = vel1 + w1 x c ... but this would // result in three equations, so we project along the planespace vectors // so that sliding along the slider axis is disregarded. for symmetry we // also substitute (w1+w2)/2 for w1, as w1 is supposed to equal w2. dVector3 ax1; // joint axis in global coordinates (unit length) dVector3 p, q; // plane space of ax1 dMULTIPLY0_331 ( ax1, R1, axis1 ); dPlaneSpace ( ax1, p, q ); if ( node[1].body ) { dVector3 tmp; dCROSS ( tmp, = REAL ( 0.5 ) * , c, p ); for ( i = 0; i < 3; i++ ) info->J1a[s3+i] = tmp[i]; for ( i = 0; i < 3; i++ ) info->J2a[s3+i] = tmp[i]; dCROSS ( tmp, = REAL ( 0.5 ) * , c, q ); for ( i = 0; i < 3; i++ ) info->J1a[s4+i] = tmp[i]; for ( i = 0; i < 3; i++ ) info->J2a[s4+i] = tmp[i]; for ( i = 0; i < 3; i++ ) info->J2l[s3+i] = -p[i]; for ( i = 0; i < 3; i++ ) info->J2l[s4+i] = -q[i]; } for ( i = 0; i < 3; i++ ) info->J1l[s3+i] = p[i]; for ( i = 0; i < 3; i++ ) info->J1l[s4+i] = q[i]; // compute last two elements of right hand side. we want to align the offset // point (in body 2's frame) with the center of body 1. dReal k = info->fps * info->erp; if ( node[1].body ) { dVector3 ofs; // offset point in global coordinates dMULTIPLY0_331 ( ofs, R2, offset ); for ( i = 0; i < 3; i++ ) c[i] += ofs[i]; info->c[3] = k * dDOT ( p, c ); info->c[4] = k * dDOT ( q, c ); } else { dVector3 ofs; // offset point in global coordinates for ( i = 0; i < 3; i++ ) ofs[i] = offset[i] - pos1[i]; info->c[3] = k * dDOT ( p, ofs ); info->c[4] = k * dDOT ( q, ofs ); if ( flags & dJOINT_REVERSE ) for ( i = 0; i < 3; ++i ) ax1[i] = -ax1[i]; } // if the slider is powered, or has joint limits, add in the extra row limot.addLimot ( this, info, 5, ax1, 0 ); } void dJointSetSliderAxis ( dJointID j, dReal x, dReal y, dReal z ) { dxJointSlider* joint = ( dxJointSlider* ) j; dUASSERT ( joint, "bad joint argument" ); checktype ( joint, Slider ); setAxes ( joint, x, y, z, joint->axis1, 0 ); joint->computeOffset(); joint->computeInitialRelativeRotation(); } void dJointSetSliderAxisDelta ( dJointID j, dReal x, dReal y, dReal z, dReal dx, dReal dy, dReal dz ) { dxJointSlider* joint = ( dxJointSlider* ) j; dUASSERT ( joint, "bad joint argument" ); checktype ( joint, Slider ); setAxes ( joint, x, y, z, joint->axis1, 0 ); joint->computeOffset(); // compute initial relative rotation body1 -> body2, or env -> body1 // also compute center of body1 w.r.t body 2 if ( !(joint->node[1].body) ) { joint->offset[0] += dx; joint->offset[1] += dy; joint->offset[2] += dz; } joint->computeInitialRelativeRotation(); } void dJointGetSliderAxis ( dJointID j, dVector3 result ) { dxJointSlider* joint = ( dxJointSlider* ) j; dUASSERT ( joint, "bad joint argument" ); dUASSERT ( result, "bad result argument" ); checktype ( joint, Slider ); getAxis ( joint, result, joint->axis1 ); } void dJointSetSliderParam ( dJointID j, int parameter, dReal value ) { dxJointSlider* joint = ( dxJointSlider* ) j; dUASSERT ( joint, "bad joint argument" ); checktype ( joint, Slider ); joint->limot.set ( parameter, value ); } dReal dJointGetSliderParam ( dJointID j, int parameter ) { dxJointSlider* joint = ( dxJointSlider* ) j; dUASSERT ( joint, "bad joint argument" ); checktype ( joint, Slider ); return joint->limot.get ( parameter ); } void dJointAddSliderForce ( dJointID j, dReal force ) { dxJointSlider* joint = ( dxJointSlider* ) j; dVector3 axis; dUASSERT ( joint, "bad joint argument" ); checktype ( joint, Slider ); if ( joint->flags & dJOINT_REVERSE ) force -= force; getAxis ( joint, axis, joint->axis1 ); axis[0] *= force; axis[1] *= force; axis[2] *= force; if ( joint->node[0].body != 0 ) dBodyAddForce ( joint->node[0].body, axis[0], axis[1], axis[2] ); if ( joint->node[1].body != 0 ) dBodyAddForce ( joint->node[1].body, -axis[0], -axis[1], -axis[2] ); if ( joint->node[0].body != 0 && joint->node[1].body != 0 ) { // linear torque decoupling: // we have to compensate the torque, that this slider force may generate // if body centers are not aligned along the slider axis dVector3 ltd; // Linear Torque Decoupling vector (a torque) dVector3 c; c[0] = REAL ( 0.5 ) * ( joint->node[1].body->posr.pos[0] - joint->node[0].body->posr.pos[0] ); c[1] = REAL ( 0.5 ) * ( joint->node[1].body->posr.pos[1] - joint->node[0].body->posr.pos[1] ); c[2] = REAL ( 0.5 ) * ( joint->node[1].body->posr.pos[2] - joint->node[0].body->posr.pos[2] ); dCROSS ( ltd, = , c, axis ); dBodyAddTorque ( joint->node[0].body, ltd[0], ltd[1], ltd[2] ); dBodyAddTorque ( joint->node[1].body, ltd[0], ltd[1], ltd[2] ); } } dJointType dxJointSlider::type() const { return dJointTypeSlider; } size_t dxJointSlider::size() const { return sizeof ( *this ); } void dxJointSlider::setRelativeValues() { computeOffset(); computeInitialRelativeRotation(); } /// Compute initial relative rotation body1 -> body2, or env -> body1 void dxJointSlider::computeInitialRelativeRotation() { if ( node[0].body ) { // compute initial relative rotation body1 -> body2, or env -> body1 // also compute center of body1 w.r.t body 2 if ( node[1].body ) { dQMultiply1 ( qrel, node[0].body->q, node[1].body->q ); } else { // set qrel to the transpose of the first body's q qrel[0] = node[0].body->q[0]; qrel[1] = -node[0].body->q[1]; qrel[2] = -node[0].body->q[2]; qrel[3] = -node[0].body->q[3]; } } } /// Compute center of body1 w.r.t body 2 void dxJointSlider::computeOffset() { if ( node[1].body ) { dVector3 c; c[0] = node[0].body->posr.pos[0] - node[1].body->posr.pos[0]; c[1] = node[0].body->posr.pos[1] - node[1].body->posr.pos[1]; c[2] = node[0].body->posr.pos[2] - node[1].body->posr.pos[2]; dMULTIPLY1_331 ( offset, node[1].body->posr.R, c ); } else if ( node[0].body ) { offset[0] = node[0].body->posr.pos[0]; offset[1] = node[0].body->posr.pos[1]; offset[2] = node[0].body->posr.pos[2]; } } alien-arena-7.66+dfsg/source/unix/odesrc/joints/contact.cpp0000600000175000017500000002034212161402010023012 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include "contact.h" #include "joint_internal.h" //**************************************************************************** // contact dxJointContact::dxJointContact( dxWorld *w ) : dxJoint( w ) { } void dxJointContact::getInfo1( dxJoint::Info1 *info ) { // make sure mu's >= 0, then calculate number of constraint rows and number // of unbounded rows. int m = 1, nub = 0; if ( contact.surface.mu < 0 ) contact.surface.mu = 0; if ( contact.surface.mode & dContactMu2 ) { if ( contact.surface.mu > 0 ) m++; if ( contact.surface.mu2 < 0 ) contact.surface.mu2 = 0; if ( contact.surface.mu2 > 0 ) m++; if ( contact.surface.mu == dInfinity ) nub ++; if ( contact.surface.mu2 == dInfinity ) nub ++; } else { if ( contact.surface.mu > 0 ) m += 2; if ( contact.surface.mu == dInfinity ) nub += 2; } the_m = m; info->m = m; info->nub = nub; } void dxJointContact::getInfo2( dxJoint::Info2 *info ) { int s = info->rowskip; int s2 = 2 * s; // get normal, with sign adjusted for body1/body2 polarity dVector3 normal; if ( flags & dJOINT_REVERSE ) { normal[0] = - contact.geom.normal[0]; normal[1] = - contact.geom.normal[1]; normal[2] = - contact.geom.normal[2]; } else { normal[0] = contact.geom.normal[0]; normal[1] = contact.geom.normal[1]; normal[2] = contact.geom.normal[2]; } normal[3] = 0; // @@@ hmmm // c1,c2 = contact points with respect to body PORs dVector3 c1, c2 = {0,0,0}; c1[0] = contact.geom.pos[0] - node[0].body->posr.pos[0]; c1[1] = contact.geom.pos[1] - node[0].body->posr.pos[1]; c1[2] = contact.geom.pos[2] - node[0].body->posr.pos[2]; // set jacobian for normal info->J1l[0] = normal[0]; info->J1l[1] = normal[1]; info->J1l[2] = normal[2]; dCROSS( info->J1a, = , c1, normal ); if ( node[1].body ) { c2[0] = contact.geom.pos[0] - node[1].body->posr.pos[0]; c2[1] = contact.geom.pos[1] - node[1].body->posr.pos[1]; c2[2] = contact.geom.pos[2] - node[1].body->posr.pos[2]; info->J2l[0] = -normal[0]; info->J2l[1] = -normal[1]; info->J2l[2] = -normal[2]; dCROSS( info->J2a, = -, c2, normal ); } // set right hand side and cfm value for normal dReal erp = info->erp; if ( contact.surface.mode & dContactSoftERP ) erp = contact.surface.soft_erp; dReal k = info->fps * erp; dReal depth = contact.geom.depth - world->contactp.min_depth; if ( depth < 0 ) depth = 0; if ( contact.surface.mode & dContactSoftCFM ) info->cfm[0] = contact.surface.soft_cfm; dReal motionN = 0; if ( contact.surface.mode & dContactMotionN ) motionN = contact.surface.motionN; const dReal pushout = k * depth + motionN; info->c[0] = pushout; // note: this cap should not limit bounce velocity const dReal maxvel = world->contactp.max_vel; if ( info->c[0] > maxvel ) info->c[0] = maxvel; // deal with bounce if ( contact.surface.mode & dContactBounce ) { // calculate outgoing velocity (-ve for incoming contact) dReal outgoing = dDOT( info->J1l, node[0].body->lvel ) + dDOT( info->J1a, node[0].body->avel ); if ( node[1].body ) { outgoing += dDOT( info->J2l, node[1].body->lvel ) + dDOT( info->J2a, node[1].body->avel ); } outgoing -= motionN; // only apply bounce if the outgoing velocity is greater than the // threshold, and if the resulting c[0] exceeds what we already have. if ( contact.surface.bounce_vel >= 0 && ( -outgoing ) > contact.surface.bounce_vel ) { dReal newc = - contact.surface.bounce * outgoing + motionN; if ( newc > info->c[0] ) info->c[0] = newc; } } // set LCP limits for normal info->lo[0] = 0; info->hi[0] = dInfinity; // now do jacobian for tangential forces dVector3 t1, t2; // two vectors tangential to normal // first friction direction if ( the_m >= 2 ) { if ( contact.surface.mode & dContactFDir1 ) // use fdir1 ? { t1[0] = contact.fdir1[0]; t1[1] = contact.fdir1[1]; t1[2] = contact.fdir1[2]; dCROSS( t2, = , normal, t1 ); } else { dPlaneSpace( normal, t1, t2 ); } info->J1l[s+0] = t1[0]; info->J1l[s+1] = t1[1]; info->J1l[s+2] = t1[2]; dCROSS( info->J1a + s, = , c1, t1 ); if ( node[1].body ) { info->J2l[s+0] = -t1[0]; info->J2l[s+1] = -t1[1]; info->J2l[s+2] = -t1[2]; dCROSS( info->J2a + s, = -, c2, t1 ); } // set right hand side if ( contact.surface.mode & dContactMotion1 ) { info->c[1] = contact.surface.motion1; } // set LCP bounds and friction index. this depends on the approximation // mode info->lo[1] = -contact.surface.mu; info->hi[1] = contact.surface.mu; if ( contact.surface.mode & dContactApprox1_1 ) info->findex[1] = 0; // set slip (constraint force mixing) if ( contact.surface.mode & dContactSlip1 ) info->cfm[1] = contact.surface.slip1; } // second friction direction if ( the_m >= 3 ) { info->J1l[s2+0] = t2[0]; info->J1l[s2+1] = t2[1]; info->J1l[s2+2] = t2[2]; dCROSS( info->J1a + s2, = , c1, t2 ); if ( node[1].body ) { info->J2l[s2+0] = -t2[0]; info->J2l[s2+1] = -t2[1]; info->J2l[s2+2] = -t2[2]; dCROSS( info->J2a + s2, = -, c2, t2 ); } // set right hand side if ( contact.surface.mode & dContactMotion2 ) { info->c[2] = contact.surface.motion2; } // set LCP bounds and friction index. this depends on the approximation // mode if ( contact.surface.mode & dContactMu2 ) { info->lo[2] = -contact.surface.mu2; info->hi[2] = contact.surface.mu2; } else { info->lo[2] = -contact.surface.mu; info->hi[2] = contact.surface.mu; } if ( contact.surface.mode & dContactApprox1_2 ) info->findex[2] = 0; // set slip (constraint force mixing) if ( contact.surface.mode & dContactSlip2 ) info->cfm[2] = contact.surface.slip2; } } dJointType dxJointContact::type() const { return dJointTypeContact; } size_t dxJointContact::size() const { return sizeof( *this ); } alien-arena-7.66+dfsg/source/unix/odesrc/joints/pr.h0000600000175000017500000000736512161402010021457 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_JOINT_PR_H_ #define _ODE_JOINT_PR_H_ #include "joint.h" /** * The axisP must be perpendicular to axis2 *
 *                                        +-------------+
 *                                        |      x      |
 *                                        +------------\+
 * Prismatic articulation                   ..     ..
 *                       |                ..     ..
 *                      \/              ..      ..
 * +--------------+    --|        __..      ..  anchor2
 * |      x       | .....|.......(__)     ..
 * +--------------+    --|         ^     <
 *        |----------------------->|
 *            Offset               |--- Rotoide articulation
 * 
*/ struct dxJointPR : public dxJoint { /// @brief Position of the rotoide articulation w.r.t second body. /// @note Position of body 2 in world frame + anchor2 in world frame give /// the position of the rotoide articulation dVector3 anchor2; /// axis of the rotoide articulation w.r.t first body. /// @note This is considered as axis1 from the parameter view. dVector3 axisR1; /// axis of the rotoide articulation w.r.t second body. /// @note This is considered also as axis1 from the parameter view dVector3 axisR2; /// axis for the prismatic articulation w.r.t first body. /// @note This is considered as axis2 in from the parameter view dVector3 axisP1; dQuaternion qrel; ///< initial relative rotation body1 -> body2. /// @brief vector between the body1 and the rotoide articulation. /// /// Going from the first to the second in the frame of body1. /// That should be aligned with body1 center along axisP. /// This is calculated when the axis are set. dVector3 offset; dxJointLimitMotor limotR; ///< limit and motor information for the rotoide articulation. dxJointLimitMotor limotP; ///< limit and motor information for the prismatic articulation. void computeInitialRelativeRotation(); dxJointPR( dxWorld *w ); virtual void getInfo1( Info1* info ); virtual void getInfo2( Info2* info ); virtual dJointType type() const; virtual size_t size() const; virtual void setRelativeValues(); }; #endif alien-arena-7.66+dfsg/source/unix/odesrc/joints/joint.cpp0000600000175000017500000005661612161402010022517 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* design note: the general principle for giving a joint the option of connecting to the static environment (i.e. the absolute frame) is to check the second body (joint->node[1].body), and if it is zero then behave as if its body transform is the identity. */ #include #include #include #include #include "joint.h" #include "joint_internal.h" extern void addObjectToList( dObject *obj, dObject **first ); dxJoint::dxJoint( dxWorld *w ) : dObject( w ) { //printf("constructing %p\n", this); dIASSERT( w ); flags = 0; node[0].joint = this; node[0].body = 0; node[0].next = 0; node[1].joint = this; node[1].body = 0; node[1].next = 0; dSetZero( lambda, 6 ); addObjectToList( this, ( dObject ** ) &w->firstjoint ); w->nj++; feedback = 0; } dxJoint::~dxJoint() { } bool dxJoint::isEnabled() const { return ( (flags & dJOINT_DISABLED) == 0 && (node[0].body->invMass > 0 || (node[1].body && node[1].body->invMass > 0)) ); } //**************************************************************************** // externs // extern "C" void dBodyAddTorque (dBodyID, dReal fx, dReal fy, dReal fz); // extern "C" void dBodyAddForce (dBodyID, dReal fx, dReal fy, dReal fz); //**************************************************************************** // utility // set three "ball-and-socket" rows in the constraint equation, and the // corresponding right hand side. void setBall( dxJoint *joint, dxJoint::Info2 *info, dVector3 anchor1, dVector3 anchor2 ) { // anchor points in global coordinates with respect to body PORs. dVector3 a1, a2; int s = info->rowskip; // set jacobian info->J1l[0] = 1; info->J1l[s+1] = 1; info->J1l[2*s+2] = 1; dMULTIPLY0_331( a1, joint->node[0].body->posr.R, anchor1 ); dCROSSMAT( info->J1a, a1, s, -, + ); if ( joint->node[1].body ) { info->J2l[0] = -1; info->J2l[s+1] = -1; info->J2l[2*s+2] = -1; dMULTIPLY0_331( a2, joint->node[1].body->posr.R, anchor2 ); dCROSSMAT( info->J2a, a2, s, + , - ); } // set right hand side dReal k = info->fps * info->erp; if ( joint->node[1].body ) { for ( int j = 0; j < 3; j++ ) { info->c[j] = k * ( a2[j] + joint->node[1].body->posr.pos[j] - a1[j] - joint->node[0].body->posr.pos[j] ); } } else { for ( int j = 0; j < 3; j++ ) { info->c[j] = k * ( anchor2[j] - a1[j] - joint->node[0].body->posr.pos[j] ); } } } // this is like setBall(), except that `axis' is a unit length vector // (in global coordinates) that should be used for the first jacobian // position row (the other two row vectors will be derived from this). // `erp1' is the erp value to use along the axis. void setBall2( dxJoint *joint, dxJoint::Info2 *info, dVector3 anchor1, dVector3 anchor2, dVector3 axis, dReal erp1 ) { // anchor points in global coordinates with respect to body PORs. dVector3 a1, a2; int i, s = info->rowskip; // get vectors normal to the axis. in setBall() axis,q1,q2 is [1 0 0], // [0 1 0] and [0 0 1], which makes everything much easier. dVector3 q1, q2; dPlaneSpace( axis, q1, q2 ); // set jacobian for ( i = 0; i < 3; i++ ) info->J1l[i] = axis[i]; for ( i = 0; i < 3; i++ ) info->J1l[s+i] = q1[i]; for ( i = 0; i < 3; i++ ) info->J1l[2*s+i] = q2[i]; dMULTIPLY0_331( a1, joint->node[0].body->posr.R, anchor1 ); dCROSS( info->J1a, = , a1, axis ); dCROSS( info->J1a + s, = , a1, q1 ); dCROSS( info->J1a + 2*s, = , a1, q2 ); if ( joint->node[1].body ) { for ( i = 0; i < 3; i++ ) info->J2l[i] = -axis[i]; for ( i = 0; i < 3; i++ ) info->J2l[s+i] = -q1[i]; for ( i = 0; i < 3; i++ ) info->J2l[2*s+i] = -q2[i]; dMULTIPLY0_331( a2, joint->node[1].body->posr.R, anchor2 ); dCROSS( info->J2a, = -, a2, axis ); dCROSS( info->J2a + s, = -, a2, q1 ); dCROSS( info->J2a + 2*s, = -, a2, q2 ); } // set right hand side - measure error along (axis,q1,q2) dReal k1 = info->fps * erp1; dReal k = info->fps * info->erp; for ( i = 0; i < 3; i++ ) a1[i] += joint->node[0].body->posr.pos[i]; if ( joint->node[1].body ) { for ( i = 0; i < 3; i++ ) a2[i] += joint->node[1].body->posr.pos[i]; info->c[0] = k1 * ( dDOT( axis, a2 ) - dDOT( axis, a1 ) ); info->c[1] = k * ( dDOT( q1, a2 ) - dDOT( q1, a1 ) ); info->c[2] = k * ( dDOT( q2, a2 ) - dDOT( q2, a1 ) ); } else { info->c[0] = k1 * ( dDOT( axis, anchor2 ) - dDOT( axis, a1 ) ); info->c[1] = k * ( dDOT( q1, anchor2 ) - dDOT( q1, a1 ) ); info->c[2] = k * ( dDOT( q2, anchor2 ) - dDOT( q2, a1 ) ); } } // set three orientation rows in the constraint equation, and the // corresponding right hand side. void setFixedOrientation( dxJoint *joint, dxJoint::Info2 *info, dQuaternion qrel, int start_row ) { int s = info->rowskip; int start_index = start_row * s; // 3 rows to make body rotations equal info->J1a[start_index] = 1; info->J1a[start_index + s + 1] = 1; info->J1a[start_index + s*2+2] = 1; if ( joint->node[1].body ) { info->J2a[start_index] = -1; info->J2a[start_index + s+1] = -1; info->J2a[start_index + s*2+2] = -1; } // compute the right hand side. the first three elements will result in // relative angular velocity of the two bodies - this is set to bring them // back into alignment. the correcting angular velocity is // |angular_velocity| = angle/time = erp*theta / stepsize // = (erp*fps) * theta // angular_velocity = |angular_velocity| * u // = (erp*fps) * theta * u // where rotation along unit length axis u by theta brings body 2's frame // to qrel with respect to body 1's frame. using a small angle approximation // for sin(), this gives // angular_velocity = (erp*fps) * 2 * v // where the quaternion of the relative rotation between the two bodies is // q = [cos(theta/2) sin(theta/2)*u] = [s v] // get qerr = relative rotation (rotation error) between two bodies dQuaternion qerr, e; if ( joint->node[1].body ) { dQuaternion qq; dQMultiply1( qq, joint->node[0].body->q, joint->node[1].body->q ); dQMultiply2( qerr, qq, qrel ); } else { dQMultiply3( qerr, joint->node[0].body->q, qrel ); } if ( qerr[0] < 0 ) { qerr[1] = -qerr[1]; // adjust sign of qerr to make theta small qerr[2] = -qerr[2]; qerr[3] = -qerr[3]; } dMULTIPLY0_331( e, joint->node[0].body->posr.R, qerr + 1 ); // @@@ bad SIMD padding! dReal k = info->fps * info->erp; info->c[start_row] = 2 * k * e[0]; info->c[start_row+1] = 2 * k * e[1]; info->c[start_row+2] = 2 * k * e[2]; } // compute anchor points relative to bodies void setAnchors( dxJoint *j, dReal x, dReal y, dReal z, dVector3 anchor1, dVector3 anchor2 ) { if ( j->node[0].body ) { dReal q[4]; q[0] = x - j->node[0].body->posr.pos[0]; q[1] = y - j->node[0].body->posr.pos[1]; q[2] = z - j->node[0].body->posr.pos[2]; q[3] = 0; dMULTIPLY1_331( anchor1, j->node[0].body->posr.R, q ); if ( j->node[1].body ) { q[0] = x - j->node[1].body->posr.pos[0]; q[1] = y - j->node[1].body->posr.pos[1]; q[2] = z - j->node[1].body->posr.pos[2]; q[3] = 0; dMULTIPLY1_331( anchor2, j->node[1].body->posr.R, q ); } else { anchor2[0] = x; anchor2[1] = y; anchor2[2] = z; } } anchor1[3] = 0; anchor2[3] = 0; } // compute axes relative to bodies. either axis1 or axis2 can be 0. void setAxes( dxJoint *j, dReal x, dReal y, dReal z, dVector3 axis1, dVector3 axis2 ) { if ( j->node[0].body ) { dReal q[4]; q[0] = x; q[1] = y; q[2] = z; q[3] = 0; dNormalize3( q ); if ( axis1 ) { dMULTIPLY1_331( axis1, j->node[0].body->posr.R, q ); axis1[3] = 0; } if ( axis2 ) { if ( j->node[1].body ) { dMULTIPLY1_331( axis2, j->node[1].body->posr.R, q ); } else { axis2[0] = x; axis2[1] = y; axis2[2] = z; } axis2[3] = 0; } } } void getAnchor( dxJoint *j, dVector3 result, dVector3 anchor1 ) { if ( j->node[0].body ) { dMULTIPLY0_331( result, j->node[0].body->posr.R, anchor1 ); result[0] += j->node[0].body->posr.pos[0]; result[1] += j->node[0].body->posr.pos[1]; result[2] += j->node[0].body->posr.pos[2]; } } void getAnchor2( dxJoint *j, dVector3 result, dVector3 anchor2 ) { if ( j->node[1].body ) { dMULTIPLY0_331( result, j->node[1].body->posr.R, anchor2 ); result[0] += j->node[1].body->posr.pos[0]; result[1] += j->node[1].body->posr.pos[1]; result[2] += j->node[1].body->posr.pos[2]; } else { result[0] = anchor2[0]; result[1] = anchor2[1]; result[2] = anchor2[2]; } } void getAxis( dxJoint *j, dVector3 result, dVector3 axis1 ) { if ( j->node[0].body ) { dMULTIPLY0_331( result, j->node[0].body->posr.R, axis1 ); } } void getAxis2( dxJoint *j, dVector3 result, dVector3 axis2 ) { if ( j->node[1].body ) { dMULTIPLY0_331( result, j->node[1].body->posr.R, axis2 ); } else { result[0] = axis2[0]; result[1] = axis2[1]; result[2] = axis2[2]; } } dReal getHingeAngleFromRelativeQuat( dQuaternion qrel, dVector3 axis ) { // the angle between the two bodies is extracted from the quaternion that // represents the relative rotation between them. recall that a quaternion // q is: // [s,v] = [ cos(theta/2) , sin(theta/2) * u ] // where s is a scalar and v is a 3-vector. u is a unit length axis and // theta is a rotation along that axis. we can get theta/2 by: // theta/2 = atan2 ( sin(theta/2) , cos(theta/2) ) // but we can't get sin(theta/2) directly, only its absolute value, i.e.: // |v| = |sin(theta/2)| * |u| // = |sin(theta/2)| // using this value will have a strange effect. recall that there are two // quaternion representations of a given rotation, q and -q. typically as // a body rotates along the axis it will go through a complete cycle using // one representation and then the next cycle will use the other // representation. this corresponds to u pointing in the direction of the // hinge axis and then in the opposite direction. the result is that theta // will appear to go "backwards" every other cycle. here is a fix: if u // points "away" from the direction of the hinge (motor) axis (i.e. more // than 90 degrees) then use -q instead of q. this represents the same // rotation, but results in the cos(theta/2) value being sign inverted. // extract the angle from the quaternion. cost2 = cos(theta/2), // sint2 = |sin(theta/2)| dReal cost2 = qrel[0]; dReal sint2 = dSqrt( qrel[1] * qrel[1] + qrel[2] * qrel[2] + qrel[3] * qrel[3] ); dReal theta = ( dDOT( qrel + 1, axis ) >= 0 ) ? // @@@ padding assumptions ( 2 * dAtan2( sint2, cost2 ) ) : // if u points in direction of axis ( 2 * dAtan2( sint2, -cost2 ) ); // if u points in opposite direction // the angle we get will be between 0..2*pi, but we want to return angles // between -pi..pi if ( theta > M_PI ) theta -= ( dReal )( 2 * M_PI ); // the angle we've just extracted has the wrong sign theta = -theta; return theta; } // given two bodies (body1,body2), the hinge axis that they are connected by // w.r.t. body1 (axis), and the initial relative orientation between them // (q_initial), return the relative rotation angle. the initial relative // orientation corresponds to an angle of zero. if body2 is 0 then measure the // angle between body1 and the static frame. // // this will not return the correct angle if the bodies rotate along any axis // other than the given hinge axis. dReal getHingeAngle( dxBody *body1, dxBody *body2, dVector3 axis, dQuaternion q_initial ) { // get qrel = relative rotation between the two bodies dQuaternion qrel; if ( body2 ) { dQuaternion qq; dQMultiply1( qq, body1->q, body2->q ); dQMultiply2( qrel, qq, q_initial ); } else { // pretend body2->q is the identity dQMultiply3( qrel, body1->q, q_initial ); } return getHingeAngleFromRelativeQuat( qrel, axis ); } //**************************************************************************** // dxJointLimitMotor void dxJointLimitMotor::init( dxWorld *world ) { vel = 0; fmax = 0; lostop = -dInfinity; histop = dInfinity; fudge_factor = 1; normal_cfm = world->global_cfm; stop_erp = world->global_erp; stop_cfm = world->global_cfm; bounce = 0; limit = 0; limit_err = 0; } void dxJointLimitMotor::set( int num, dReal value ) { switch ( num ) { case dParamLoStop: lostop = value; break; case dParamHiStop: histop = value; break; case dParamVel: vel = value; break; case dParamFMax: if ( value >= 0 ) fmax = value; break; case dParamFudgeFactor: if ( value >= 0 && value <= 1 ) fudge_factor = value; break; case dParamBounce: bounce = value; break; case dParamCFM: normal_cfm = value; break; case dParamStopERP: stop_erp = value; break; case dParamStopCFM: stop_cfm = value; break; } } dReal dxJointLimitMotor::get( int num ) { switch ( num ) { case dParamLoStop: return lostop; case dParamHiStop: return histop; case dParamVel: return vel; case dParamFMax: return fmax; case dParamFudgeFactor: return fudge_factor; case dParamBounce: return bounce; case dParamCFM: return normal_cfm; case dParamStopERP: return stop_erp; case dParamStopCFM: return stop_cfm; default: return 0; } } int dxJointLimitMotor::testRotationalLimit( dReal angle ) { if ( angle <= lostop ) { limit = 1; limit_err = angle - lostop; return 1; } else if ( angle >= histop ) { limit = 2; limit_err = angle - histop; return 1; } else { limit = 0; return 0; } } int dxJointLimitMotor::addLimot( dxJoint *joint, dxJoint::Info2 *info, int row, const dVector3 ax1, int rotational ) { int srow = row * info->rowskip; // if the joint is powered, or has joint limits, add in the extra row int powered = fmax > 0; if ( powered || limit ) { dReal *J1 = rotational ? info->J1a : info->J1l; dReal *J2 = rotational ? info->J2a : info->J2l; J1[srow+0] = ax1[0]; J1[srow+1] = ax1[1]; J1[srow+2] = ax1[2]; if ( joint->node[1].body ) { J2[srow+0] = -ax1[0]; J2[srow+1] = -ax1[1]; J2[srow+2] = -ax1[2]; } // linear limot torque decoupling step: // // if this is a linear limot (e.g. from a slider), we have to be careful // that the linear constraint forces (+/- ax1) applied to the two bodies // do not create a torque couple. in other words, the points that the // constraint force is applied at must lie along the same ax1 axis. // a torque couple will result in powered or limited slider-jointed free // bodies from gaining angular momentum. // the solution used here is to apply the constraint forces at the point // halfway between the body centers. there is no penalty (other than an // extra tiny bit of computation) in doing this adjustment. note that we // only need to do this if the constraint connects two bodies. dVector3 ltd = {0,0,0}; // Linear Torque Decoupling vector (a torque) if ( !rotational && joint->node[1].body ) { dVector3 c; c[0] = REAL( 0.5 ) * ( joint->node[1].body->posr.pos[0] - joint->node[0].body->posr.pos[0] ); c[1] = REAL( 0.5 ) * ( joint->node[1].body->posr.pos[1] - joint->node[0].body->posr.pos[1] ); c[2] = REAL( 0.5 ) * ( joint->node[1].body->posr.pos[2] - joint->node[0].body->posr.pos[2] ); dCROSS( ltd, = , c, ax1 ); info->J1a[srow+0] = ltd[0]; info->J1a[srow+1] = ltd[1]; info->J1a[srow+2] = ltd[2]; info->J2a[srow+0] = ltd[0]; info->J2a[srow+1] = ltd[1]; info->J2a[srow+2] = ltd[2]; } // if we're limited low and high simultaneously, the joint motor is // ineffective if ( limit && ( lostop == histop ) ) powered = 0; if ( powered ) { info->cfm[row] = normal_cfm; if ( ! limit ) { info->c[row] = vel; info->lo[row] = -fmax; info->hi[row] = fmax; } else { // the joint is at a limit, AND is being powered. if the joint is // being powered into the limit then we apply the maximum motor force // in that direction, because the motor is working against the // immovable limit. if the joint is being powered away from the limit // then we have problems because actually we need *two* lcp // constraints to handle this case. so we fake it and apply some // fraction of the maximum force. the fraction to use can be set as // a fudge factor. dReal fm = fmax; if (( vel > 0 ) || ( vel == 0 && limit == 2 ) ) fm = -fm; // if we're powering away from the limit, apply the fudge factor if (( limit == 1 && vel > 0 ) || ( limit == 2 && vel < 0 ) ) fm *= fudge_factor; if ( rotational ) { dBodyAddTorque( joint->node[0].body, -fm*ax1[0], -fm*ax1[1], -fm*ax1[2] ); if ( joint->node[1].body ) dBodyAddTorque( joint->node[1].body, fm*ax1[0], fm*ax1[1], fm*ax1[2] ); } else { dBodyAddForce( joint->node[0].body, -fm*ax1[0], -fm*ax1[1], -fm*ax1[2] ); if ( joint->node[1].body ) { dBodyAddForce( joint->node[1].body, fm*ax1[0], fm*ax1[1], fm*ax1[2] ); // linear limot torque decoupling step: refer to above discussion dBodyAddTorque( joint->node[0].body, -fm*ltd[0], -fm*ltd[1], -fm*ltd[2] ); dBodyAddTorque( joint->node[1].body, -fm*ltd[0], -fm*ltd[1], -fm*ltd[2] ); } } } } if ( limit ) { dReal k = info->fps * stop_erp; info->c[row] = -k * limit_err; info->cfm[row] = stop_cfm; if ( lostop == histop ) { // limited low and high simultaneously info->lo[row] = -dInfinity; info->hi[row] = dInfinity; } else { if ( limit == 1 ) { // low limit info->lo[row] = 0; info->hi[row] = dInfinity; } else { // high limit info->lo[row] = -dInfinity; info->hi[row] = 0; } // deal with bounce if ( bounce > 0 ) { // calculate joint velocity dReal vel; if ( rotational ) { vel = dDOT( joint->node[0].body->avel, ax1 ); if ( joint->node[1].body ) vel -= dDOT( joint->node[1].body->avel, ax1 ); } else { vel = dDOT( joint->node[0].body->lvel, ax1 ); if ( joint->node[1].body ) vel -= dDOT( joint->node[1].body->lvel, ax1 ); } // only apply bounce if the velocity is incoming, and if the // resulting c[] exceeds what we already have. if ( limit == 1 ) { // low limit if ( vel < 0 ) { dReal newc = -bounce * vel; if ( newc > info->c[row] ) info->c[row] = newc; } } else { // high limit - all those computations are reversed if ( vel > 0 ) { dReal newc = -bounce * vel; if ( newc < info->c[row] ) info->c[row] = newc; } } } } } return 1; } else return 0; } // Local Variables: // mode:c++ // c-basic-offset:4 // End: alien-arena-7.66+dfsg/source/unix/odesrc/joints/amotor.h0000600000175000017500000000503612161402010022330 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_JOINT_AMOTOR_H_ #define _ODE_JOINT_AMOTOR_H_ #include "joint.h" // angular motor struct dxJointAMotor : public dxJoint { int num; // number of axes (0..3) int mode; // a dAMotorXXX constant int rel[3]; // what the axes are relative to (global,b1,b2) dVector3 axis[3]; // three axes dxJointLimitMotor limot[3]; // limit+motor info for axes dReal angle[3]; // user-supplied angles for axes // these vectors are used for calculating euler angles dVector3 reference1; // original axis[2], relative to body 1 dVector3 reference2; // original axis[0], relative to body 2 void computeGlobalAxes( dVector3 ax[3] ); void computeEulerAngles( dVector3 ax[3] ); void setEulerReferenceVectors(); dxJointAMotor( dxWorld *w ); virtual void getInfo1( Info1* info ); virtual void getInfo2( Info2* info ); virtual dJointType type() const; virtual size_t size() const; }; #endif alien-arena-7.66+dfsg/source/unix/odesrc/joints/fixed.h0000600000175000017500000000431312161402010022123 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_JOINT_FIXED_H_ #define _ODE_JOINT_FIXED_H_ #include "joint.h" // fixed struct dxJointFixed : public dxJoint { dQuaternion qrel; // initial relative rotation body1 -> body2 dVector3 offset; // relative offset between the bodies dReal erp; // error reduction parameter dReal cfm; // constraint force mix-in void set ( int num, dReal value ); dReal get ( int num ); dxJointFixed ( dxWorld *w ); virtual void getInfo1 ( Info1* info ); virtual void getInfo2 ( Info2* info ); virtual dJointType type() const; virtual size_t size() const; void computeInitialRelativeRotation(); }; #endif alien-arena-7.66+dfsg/source/unix/odesrc/joints/piston.cpp0000600000175000017500000005461412161402010022704 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include "piston.h" #include "joint_internal.h" //**************************************************************************** // Piston // dxJointPiston::dxJointPiston ( dxWorld *w ) : dxJoint ( w ) { dSetZero ( axis1, 4 ); dSetZero ( axis2, 4 ); axis1[0] = 1; axis2[0] = 1; dSetZero ( qrel, 4 ); dSetZero ( anchor1, 4 ); dSetZero ( anchor2, 4 ); limotP.init ( world ); limotR.init ( world ); } dReal dJointGetPistonPosition ( dJointID j ) { dxJointPiston* joint = ( dxJointPiston* ) j; dUASSERT ( joint, "bad joint argument" ); checktype ( joint, Piston ); if ( joint->node[0].body ) { dVector3 q; // get the anchor (or offset) in global coordinates dMULTIPLY0_331 ( q, joint->node[0].body->posr.R, joint->anchor1 ); if ( joint->node[1].body ) { dVector3 anchor2; // get the anchor2 in global coordinates dMULTIPLY0_331 ( anchor2, joint->node[1].body->posr.R, joint->anchor2 ); q[0] = ( ( joint->node[0].body->posr.pos[0] + q[0] ) - ( joint->node[1].body->posr.pos[0] + anchor2[0] ) ); q[1] = ( ( joint->node[0].body->posr.pos[1] + q[1] ) - ( joint->node[1].body->posr.pos[1] + anchor2[1] ) ); q[2] = ( ( joint->node[0].body->posr.pos[2] + q[2] ) - ( joint->node[1].body->posr.pos[2] + anchor2[2] ) ); } else { // N.B. When there is no body 2 the joint->anchor2 is already in // global coordinates q[0] = ( ( joint->node[0].body->posr.pos[0] + q[0] ) - ( joint->anchor2[0] ) ); q[1] = ( ( joint->node[0].body->posr.pos[1] + q[1] ) - ( joint->anchor2[1] ) ); q[2] = ( ( joint->node[0].body->posr.pos[2] + q[2] ) - ( joint->anchor2[2] ) ); if ( joint->flags & dJOINT_REVERSE ) { q[0] = -q[0]; q[1] = -q[1]; q[2] = -q[2]; } } // get axis in global coordinates dVector3 ax; dMULTIPLY0_331 ( ax, joint->node[0].body->posr.R, joint->axis1 ); return dDOT ( ax, q ); } dDEBUGMSG ( "The function always return 0 since no body are attached" ); return 0; } dReal dJointGetPistonPositionRate ( dJointID j ) { dxJointPiston* joint = ( dxJointPiston* ) j; dUASSERT ( joint, "bad joint argument" ); checktype ( joint, Piston ); // get axis in global coordinates dVector3 ax; dMULTIPLY0_331 ( ax, joint->node[0].body->posr.R, joint->axis1 ); // The linear velocity created by the rotation can be discarded since // the rotation is along the prismatic axis and this rotation don't create // linear velocity in the direction of the prismatic axis. if ( joint->node[1].body ) { return ( dDOT ( ax, joint->node[0].body->lvel ) - dDOT ( ax, joint->node[1].body->lvel ) ); } else { dReal rate = dDOT ( ax, joint->node[0].body->lvel ); return ( (joint->flags & dJOINT_REVERSE) ? -rate : rate); } } dReal dJointGetPistonAngle ( dJointID j ) { dxJointPiston* joint = ( dxJointPiston * ) j; dAASSERT ( joint ); checktype ( joint, Piston ); if ( joint->node[0].body ) { dReal ang = getHingeAngle ( joint->node[0].body, joint->node[1].body, joint->axis1, joint->qrel ); if ( joint->flags & dJOINT_REVERSE ) return -ang; else return ang; } else return 0; } dReal dJointGetPistonAngleRate ( dJointID j ) { dxJointPiston* joint = ( dxJointPiston* ) j; dAASSERT ( joint ); checktype ( joint, Piston ); if ( joint->node[0].body ) { dVector3 axis; dMULTIPLY0_331 ( axis, joint->node[0].body->posr.R, joint->axis1 ); dReal rate = dDOT ( axis, joint->node[0].body->avel ); if ( joint->node[1].body ) rate -= dDOT ( axis, joint->node[1].body->avel ); if ( joint->flags & dJOINT_REVERSE ) rate = - rate; return rate; } else return 0; } void dxJointPiston::getInfo1 ( dxJoint::Info1 *info ) { info->nub = 4; // Number of unbound variables // The only bound variable is one linear displacement info->m = 4; // Default number of constraint row // see if we're at a joint limit. limotP.limit = 0; if ( ( limotP.lostop > -dInfinity || limotP.histop < dInfinity ) && limotP.lostop <= limotP.histop ) { // measure joint position dReal pos = dJointGetPistonPosition ( this ); limotP.testRotationalLimit ( pos ); // N.B. The fucntion is ill named } // powered Piston or at limits needs an extra constraint row if ( limotP.limit || limotP.fmax > 0 ) info->m++; // see if we're at a joint limit. limotR.limit = 0; if ( ( limotR.lostop > -dInfinity || limotR.histop < dInfinity ) && limotR.lostop <= limotR.histop ) { // measure joint position dReal angle = getHingeAngle ( node[0].body, node[1].body, axis1, qrel ); limotR.testRotationalLimit ( angle ); } // powered Piston or at limits needs an extra constraint row if ( limotR.limit || limotR.fmax > 0 ) info->m++; } void dxJointPiston::getInfo2 ( dxJoint::Info2 *info ) { const int s0 = 0; const int s1 = info->rowskip; const int s2 = 2 * s1, s3 = 3 * s1 /*, s4=4*s1*/; const dReal k = info->fps * info->erp; // Pull out pos and R for both bodies. also get the `connection' // vector pos2-pos1. dReal *pos1, *pos2, *R1, *R2=0; dVector3 dist; // Current position of body_1 w.r.t "anchor" // 2 bodies anchor is center of body 2 // 1 bodies anchor is origin dVector3 lanchor2= { 0,0,0 }; pos1 = node[0].body->posr.pos; R1 = node[0].body->posr.R; if ( node[1].body ) { pos2 = node[1].body->posr.pos; R2 = node[1].body->posr.R; dMULTIPLY0_331 ( lanchor2, R2, anchor2 ); dist[0] = lanchor2[0] + pos2[0] - pos1[0]; dist[1] = lanchor2[1] + pos2[1] - pos1[1]; dist[2] = lanchor2[2] + pos2[2] - pos1[2]; } else { // pos2 = 0; // N.B. We can do that to be safe but it is no necessary // R2 = 0; // N.B. We can do that to be safe but it is no necessary if (flags & dJOINT_REVERSE ) { dist[0] = pos1[0] - anchor2[0]; // Invert the value dist[1] = pos1[1] - anchor2[1]; dist[2] = pos1[2] - anchor2[2]; } else { dist[0] = anchor2[0] - pos1[0]; dist[1] = anchor2[1] - pos1[1]; dist[2] = anchor2[2] - pos1[2]; } } // ====================================================================== // Work on the angular part (i.e. row 0, 1) // Set the two orientation rows. The rotoide axis should be the only // unconstrained rotational axis, the angular velocity of the two bodies // perpendicular to the rotoide axis should be equal. // Thus the constraint equations are: // p*w1 - p*w2 = 0 // q*w1 - q*w2 = 0 // where p and q are unit vectors normal to the rotoide axis, and w1 and w2 // are the angular velocity vectors of the two bodies. // Since the rotoide axis is the same as the prismatic axis. // // // Also, compute the right hand side (RHS) of the rotation constraint equation set. // The first 2 element will result in the relative angular velocity of the two // bodies along axis p and q. This is set to bring the rotoide back into alignment. // if `theta' is the angle between ax1 and ax2, we need an angular velocity // along u to cover angle erp*theta in one step : // |angular_velocity| = angle/time = erp*theta / stepsize // = (erp*fps) * theta // angular_velocity = |angular_velocity| * u // = (erp*fps) * theta * u // where rotation along unit length axis u by theta brings body 2's frame // // if theta is smallish, sin(theta) ~= theta and cos(theta) ~= 1 // where the quaternion of the relative rotation between the two bodies is // quat = [cos(theta/2) sin(theta/2)*u] // quat = [1 theta/2*u] // => q[0] ~= 1 // 2 * q[1+i] = theta * u[i] // // Since there is no constraint along the rotoide axis // only along p and q that we want the same angular velocity and need to reduce // the error dVector3 ax1, p, q; dMULTIPLY0_331 ( ax1, node[0].body->posr.R, axis1 ); // Find the 2 axis perpendicular to the rotoide axis. dPlaneSpace ( ax1, p, q ); // LHS dOPE ( ( info->J1a ) + s0, = , p ); dOPE ( ( info->J1a ) + s1, = , q ); dVector3 b; if ( node[1].body ) { // LHS // info->J2a[s0+i] = -p[i] dOPE ( ( info->J2a ) + s0, = -, p ); dOPE ( ( info->J2a ) + s1, = -, q ); // Some math for the RHS dVector3 ax2; dMULTIPLY0_331 ( ax2, R2, axis2 ); dCROSS ( b, = , ax1, ax2 ); } else { // Some math for the RHS dCROSS ( b, = , ax1, axis2 ); } // RHS info->c[0] = k * dDOT ( p, b ); info->c[1] = k * dDOT ( q, b ); // ====================================================================== // Work on the linear part (i.e row 2,3) // p2 + R2 anchor2' = p1 + R1 dist' // v2 + w2 R2 anchor2' + R2 d(anchor2')/dt = v1 + w1 R1 dist' + R1 d(dist')/dt // v2 + w2 x anchor2 = v1 + w1 x dist + v_p // v_p is speed of prismatic joint (i.e. elongation rate) // Since the constraints are perpendicular to v_p we have: // p . v_p = 0 and q . v_p = 0 // Along p and q we have (since sliding along the prismatic axis is disregarded): // u . ( v2 + w2 x anchor2 = v1 + w1 x dist + v_p) ( where u is p or q ) // Simplify // u . v2 + u. w2 x anchor2 = u . v1 + u . w1 x dist // or // u . v1 - u . v2 + u . w1 x dist - u2 . w2 x anchor2 = 0 // using the fact that (a x b = - b x a) // u . v1 - u . v2 - u . dist x w1 + u . anchor2 x w2 = 0 // With the help of the triple product: // i.e. a . b x c = b . c x a = c . a x b or a . b x c = a x b . c // Ref: http://mathworld.wolfram.com/ScalarTripleProduct.html // u . v1 - u . v2 - u x dist . w1 + u x anchor2 . w2 = 0 // u . v1 - u . v2 + dist x u . w1 - u x anchor2 . w2 = 0 // // Coeff for 1er line of: J1l => p, J2l => -p // Coeff for 2er line of: J1l => q, J2l => -q // Coeff for 1er line of: J1a => dist x p, J2a => p x anchor2 // Coeff for 2er line of: J1a => dist x q, J2a => q x anchor2 dCROSS ( ( info->J1a ) + s2, = , dist, p ); dCROSS ( ( info->J1a ) + s3, = , dist, q ); dOPE ( ( info->J1l ) + s2, = , p ); dOPE ( ( info->J1l ) + s3, = , q ); if ( node[1].body ) { // q x anchor2 instead of anchor2 x q since we want the negative value dCROSS ( ( info->J2a ) + s2, = , p, lanchor2 ); // The cross product is in reverse order since we want the negative value dCROSS ( ( info->J2a ) + s3, = , q, lanchor2 ); // info->J2l[s2+i] = -p[i]; dOPE ( ( info->J2l ) + s2, = -, p ); dOPE ( ( info->J2l ) + s3, = -, q ); } // We want to make correction for motion not in the line of the axis // We calculate the displacement w.r.t. the "anchor" pt. // i.e. Find the difference between the current position and the initial // position along the constrained axies (i.e. axis p and q). // The bodies can move w.r.t each other only along the prismatic axis // // Compute the RHS of rows 2 and 3 dVector3 err; dMULTIPLY0_331 ( err, R1, anchor1 ); dOPE2 ( err, = , dist, -, err ); info->c[2] = k * dDOT ( p, err ); info->c[3] = k * dDOT ( q, err ); int row = 4; if ( node[1].body ) { row += limotP.addLimot ( this, info, 4, ax1, 0 ); } else if (flags & dJOINT_REVERSE ) { dVector3 rAx1; rAx1[0] = -ax1[0]; rAx1[1] = -ax1[1]; rAx1[2] = -ax1[2]; row += limotP.addLimot ( this, info, 4, rAx1, 0 ); } else row += limotP.addLimot ( this, info, 4, ax1, 0 ); limotR.addLimot ( this, info, row, ax1, 1 ); } void dJointSetPistonAnchor ( dJointID j, dReal x, dReal y, dReal z ) { dxJointPiston* joint = ( dxJointPiston* ) j; dUASSERT ( joint, "bad joint argument" ); checktype ( joint, Piston ); setAnchors ( joint, x, y, z, joint->anchor1, joint->anchor2 ); joint->computeInitialRelativeRotation(); } void dJointSetPistonAnchorOffset (dJointID j, dReal x, dReal y, dReal z, dReal dx, dReal dy, dReal dz) { dxJointPiston* joint = (dxJointPiston*) j; dUASSERT (joint,"bad joint argument"); checktype ( joint, Piston ); if (joint->flags & dJOINT_REVERSE) { dx = -dx; dy = -dy; dz = -dz; } if (joint->node[0].body) { joint->node[0].body->posr.pos[0] -= dx; joint->node[0].body->posr.pos[1] -= dy; joint->node[0].body->posr.pos[2] -= dz; } setAnchors (joint,x ,y, z, joint->anchor1, joint->anchor2); if (joint->node[0].body) { joint->node[0].body->posr.pos[0] += dx; joint->node[0].body->posr.pos[1] += dy; joint->node[0].body->posr.pos[2] += dz; } joint->computeInitialRelativeRotation(); } void dJointGetPistonAnchor ( dJointID j, dVector3 result ) { dxJointPiston* joint = ( dxJointPiston* ) j; dUASSERT ( joint, "bad joint argument" ); dUASSERT ( result, "bad result argument" ); checktype ( joint, Piston ); if ( joint->flags & dJOINT_REVERSE ) getAnchor2 ( joint, result, joint->anchor2 ); else getAnchor ( joint, result, joint->anchor1 ); } void dJointGetPistonAnchor2 ( dJointID j, dVector3 result ) { dxJointPiston* joint = ( dxJointPiston* ) j; dUASSERT ( joint, "bad joint argument" ); dUASSERT ( result, "bad result argument" ); checktype ( joint, Piston ); if ( joint->flags & dJOINT_REVERSE ) getAnchor ( joint, result, joint->anchor1 ); else getAnchor2 ( joint, result, joint->anchor2 ); } void dJointSetPistonAxis ( dJointID j, dReal x, dReal y, dReal z ) { dxJointPiston* joint = ( dxJointPiston* ) j; dUASSERT ( joint, "bad joint argument" ); checktype ( joint, Piston ); setAxes ( joint, x, y, z, joint->axis1, joint->axis2 ); joint->computeInitialRelativeRotation(); } void dJointSetPistonAxisDelta ( dJointID j, dReal x, dReal y, dReal z, dReal dx, dReal dy, dReal dz ) { dxJointPiston* joint = ( dxJointPiston* ) j; dUASSERT ( joint, "bad joint argument" ); checktype ( joint, Piston ); setAxes ( joint, x, y, z, joint->axis1, joint->axis2 ); joint->computeInitialRelativeRotation(); dVector3 c = {0,0,0}; if ( joint->node[1].body ) { c[0] = ( joint->node[0].body->posr.pos[0] - joint->node[1].body->posr.pos[0] - dx ); c[1] = ( joint->node[0].body->posr.pos[1] - joint->node[1].body->posr.pos[1] - dy ); c[2] = ( joint->node[0].body->posr.pos[2] - joint->node[1].body->posr.pos[2] - dz ); } else if ( joint->node[0].body ) { c[0] = joint->node[0].body->posr.pos[0] - dx; c[1] = joint->node[0].body->posr.pos[1] - dy; c[2] = joint->node[0].body->posr.pos[2] - dz; } // Convert into frame of body 1 dMULTIPLY1_331 ( joint->anchor1, joint->node[0].body->posr.R, c ); } void dJointGetPistonAxis ( dJointID j, dVector3 result ) { dxJointPiston* joint = ( dxJointPiston* ) j; dUASSERT ( joint, "bad joint argument" ); dUASSERT ( result, "bad result argument" ); checktype ( joint, Piston ); getAxis ( joint, result, joint->axis1 ); } void dJointSetPistonParam ( dJointID j, int parameter, dReal value ) { dxJointPiston* joint = ( dxJointPiston* ) j; dUASSERT ( joint, "bad joint argument" ); checktype ( joint, Piston ); if ( ( parameter & 0xff00 ) == 0x100 ) { joint->limotR.set ( parameter & 0xff, value ); } else { joint->limotP.set ( parameter, value ); } } dReal dJointGetPistonParam ( dJointID j, int parameter ) { dxJointPiston* joint = ( dxJointPiston* ) j; dUASSERT ( joint, "bad joint argument" ); checktype ( joint, Piston ); if ( ( parameter & 0xff00 ) == 0x100 ) { return joint->limotR.get ( parameter & 0xff ); } else { return joint->limotP.get ( parameter ); } } void dJointAddPistonForce ( dJointID j, dReal force ) { dxJointPiston* joint = ( dxJointPiston* ) j; dUASSERT ( joint, "bad joint argument" ); checktype ( joint, Piston ); if ( joint->flags & dJOINT_REVERSE ) force -= force; dVector3 axis; getAxis ( joint, axis, joint->axis1 ); // axis[i] *= force dOPEC ( axis, *= , force ); if ( joint->node[0].body != 0 ) dBodyAddForce ( joint->node[0].body, axis[0], axis[1], axis[2] ); if ( joint->node[1].body != 0 ) dBodyAddForce ( joint->node[1].body, -axis[0], -axis[1], -axis[2] ); if ( joint->node[0].body != 0 && joint->node[1].body != 0 ) { // Case where we don't need ltd since center of mass of both bodies // pass by the anchor point '*' when travelling along the prismatic axis. // Body_2 // Body_1 ----- // --- |-- | | // | |---------------*-------------| | ---> prismatic axis // --- |-- | | // ----- // Body_2 // Case where we need ltd // Body_1 // --- // | |--------- // --- | // | |-- // -----*----- ---> prismatic axis // |-- | // | // | // | ----- // | | | // -------| | // | | // ----- // Body_2 // // In real life force apply at the '*' point // But in ODE the force are applied on the center of mass of Body_1 and Body_2 // So we have to add torques on both bodies to compensate for that when there // is an offset between the anchor point and the center of mass of both bodies. // // We need to add to each body T = r x F // Where r is the distance between the cm and '*' dVector3 ltd; // Linear Torque Decoupling vector (a torque) dVector3 c; // Distance of the body w.r.t the anchor // N.B. The distance along the prismatic axis might not // not be included in this variable since it won't add // anything to the ltd. // Calculate the distance of the body w.r.t the anchor // The anchor1 of body1 can be used since: // Real anchor = Position of body 1 + anchor + d* axis1 = anchor in world frame // d is the position of the prismatic joint (i.e. elongation) // Since axis1 x axis1 == 0 // We can do the following. dMULTIPLY0_331 ( c, joint->node[0].body->posr.R, joint->anchor1 ); dCROSS ( ltd, = , c, axis ); dBodyAddTorque ( joint->node[0].body, ltd[0], ltd[1], ltd[2] ); dMULTIPLY0_331 ( c, joint->node[1].body->posr.R, joint->anchor2 ); dCROSS ( ltd, = , c, axis ); dBodyAddTorque ( joint->node[1].body, ltd[0], ltd[1], ltd[2] ); } } dJointType dxJointPiston::type() const { return dJointTypePiston; } size_t dxJointPiston::size() const { return sizeof ( *this ); } void dxJointPiston::setRelativeValues() { dVector3 vec; dJointGetPistonAnchor(this, vec); setAnchors( this, vec[0], vec[1], vec[2], anchor1, anchor2 ); dJointGetPistonAxis(this, vec); setAxes( this, vec[0], vec[1], vec[2], axis1, axis2 ); computeInitialRelativeRotation(); } void dxJointPiston::computeInitialRelativeRotation() { if ( node[0].body ) { if ( node[1].body ) { dQMultiply1 ( qrel, node[0].body->q, node[1].body->q ); } else { // set joint->qrel to the transpose of the first body q qrel[0] = node[0].body->q[0]; for ( int i = 1; i < 4; i++ ) qrel[i] = -node[0].body->q[i]; // WARNING do we need the - in -joint->node[0].body->q[i]; or not } } } alien-arena-7.66+dfsg/source/unix/odesrc/joints/lmotor.h0000600000175000017500000000375412161402010022350 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_JOINT_LMOTOR_H_ #define _ODE_JOINT_LMOTOR_H_ #include "joint.h" struct dxJointLMotor : public dxJoint { int num; int rel[3]; dVector3 axis[3]; dxJointLimitMotor limot[3]; void computeGlobalAxes( dVector3 ax[3] ); dxJointLMotor( dxWorld *w ); virtual void getInfo1( Info1* info ); virtual void getInfo2( Info2* info ); virtual dJointType type() const; virtual size_t size() const; }; #endif alien-arena-7.66+dfsg/source/unix/odesrc/joints/null.cpp0000600000175000017500000000411112161402010022325 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include "null.h" #include "joint_internal.h" //**************************************************************************** // null joint dxJointNull::dxJointNull( dxWorld *w ) : dxJoint( w ) { } void dxJointNull::getInfo1( dxJoint::Info1 *info ) { info->m = 0; info->nub = 0; } void dxJointNull::getInfo2( dxJoint::Info2 *info ) { dDebug( 0, "this should never get called" ); } dJointType dxJointNull::type() const { return dJointTypeNull; } size_t dxJointNull::size() const { return sizeof( *this ); } alien-arena-7.66+dfsg/source/unix/odesrc/joints/null.h0000600000175000017500000000360212161402010021776 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_JOINT_NULL_H_ #define _ODE_JOINT_NULL_H_ #include "joint.h" // null joint, for testing only struct dxJointNull : public dxJoint { dxJointNull( dxWorld *w ); virtual void getInfo1( Info1* info ); virtual void getInfo2( Info2* info ); virtual dJointType type() const; virtual size_t size() const; }; #endif alien-arena-7.66+dfsg/source/unix/odesrc/joints/pu.cpp0000600000175000017500000006406712161402010022017 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include "pu.h" #include "joint_internal.h" //**************************************************************************** // Prismatic and Universal dxJointPU::dxJointPU( dxWorld *w ) : dxJointUniversal( w ) { // Default Position // Y ^ Axis2 // ^ | // / | ^ Axis1 // Z^ / | / // | / Body 2 | / Body 1 // | / +---------+ | / +-----------+ // | / / /| | / / /| // | / / / + _/ - / / + // | / / /-/--------(_)----|--- /-----------/-------> AxisP // | / +---------+ / - +-----------+ / // | / | |/ | |/ // | / +---------+ +-----------+ // |/ // .-----------------------------------------> X // |-----------------> // Anchor2 <--------------| // Anchor1 // // Setting member variables which are w.r.t body2 dSetZero( axis1, 4 ); axis1[1] = 1; // Setting member variables which are w.r.t body2 dSetZero( anchor2, 4 ); dSetZero( axis2, 4 ); axis2[2] = 1; dSetZero( axisP1, 4 ); axisP1[0] = 1; dSetZero( qrel1, 4 ); dSetZero( qrel2, 4 ); limotP.init( world ); limot1.init( world ); limot2.init( world ); } dReal dJointGetPUPosition( dJointID j ) { dxJointPU* joint = ( dxJointPU* ) j; dUASSERT( joint, "bad joint argument" ); checktype( joint, PU ); dVector3 q; // get the offset in global coordinates dMULTIPLY0_331( q, joint->node[0].body->posr.R, joint->anchor1 ); if ( joint->node[1].body ) { dVector3 anchor2; // get the anchor2 in global coordinates dMULTIPLY0_331( anchor2, joint->node[1].body->posr.R, joint->anchor2 ); q[0] = (( joint->node[0].body->posr.pos[0] + q[0] ) - ( joint->node[1].body->posr.pos[0] + anchor2[0] ) ); q[1] = (( joint->node[0].body->posr.pos[1] + q[1] ) - ( joint->node[1].body->posr.pos[1] + anchor2[1] ) ); q[2] = (( joint->node[0].body->posr.pos[2] + q[2] ) - ( joint->node[1].body->posr.pos[2] + anchor2[2] ) ); } else { //N.B. When there is no body 2 the joint->anchor2 is already in // global coordinates q[0] = (( joint->node[0].body->posr.pos[0] + q[0] ) - ( joint->anchor2[0] ) ); q[1] = (( joint->node[0].body->posr.pos[1] + q[1] ) - ( joint->anchor2[1] ) ); q[2] = (( joint->node[0].body->posr.pos[2] + q[2] ) - ( joint->anchor2[2] ) ); if ( joint->flags & dJOINT_REVERSE ) { q[0] = -q[0]; q[1] = -q[1]; q[2] = -q[2]; } } dVector3 axP; // get prismatic axis in global coordinates dMULTIPLY0_331( axP, joint->node[0].body->posr.R, joint->axisP1 ); return dDOT( axP, q ); } dReal dJointGetPUPositionRate( dJointID j ) { dxJointPU* joint = ( dxJointPU* ) j; dUASSERT( joint, "bad joint argument" ); checktype( joint, PU ); if ( joint->node[0].body ) { // We want to find the rate of change of the prismatic part of the joint // We can find it by looking at the speed difference between body1 and the // anchor point. // r will be used to find the distance between body1 and the anchor point dVector3 r; dVector3 anchor2 = {0,0,0}; if ( joint->node[1].body ) { // Find joint->anchor2 in global coordinates dMULTIPLY0_331( anchor2, joint->node[1].body->posr.R, joint->anchor2 ); r[0] = ( joint->node[0].body->posr.pos[0] - ( anchor2[0] + joint->node[1].body->posr.pos[0] ) ); r[1] = ( joint->node[0].body->posr.pos[1] - ( anchor2[1] + joint->node[1].body->posr.pos[1] ) ); r[2] = ( joint->node[0].body->posr.pos[2] - ( anchor2[2] + joint->node[1].body->posr.pos[2] ) ); } else { //N.B. When there is no body 2 the joint->anchor2 is already in // global coordinates // r = joint->node[0].body->posr.pos - joint->anchor2; dOP( r, -, joint->node[0].body->posr.pos, joint->anchor2 ); } // The body1 can have velocity coming from the rotation of // the rotoide axis. We need to remove this. // N.B. We do vel = r X w instead of vel = w x r to have vel negative // since we want to remove it from the linear velocity of the body dVector3 lvel1; dCROSS( lvel1, = , r, joint->node[0].body->avel ); // lvel1 += joint->node[0].body->lvel; dOPE( lvel1, += , joint->node[0].body->lvel ); // Since we want rate of change along the prismatic axis // get axisP1 in global coordinates and get the component // along this axis only dVector3 axP1; dMULTIPLY0_331( axP1, joint->node[0].body->posr.R, joint->axisP1 ); if ( joint->node[1].body ) { // Find the contribution of the angular rotation to the linear speed // N.B. We do vel = r X w instead of vel = w x r to have vel negative // since we want to remove it from the linear velocity of the body dVector3 lvel2; dCROSS( lvel2, = , anchor2, joint->node[1].body->avel ); // lvel1 -= lvel2 + joint->node[1].body->lvel; dOPE2( lvel1, -= , lvel2, + , joint->node[1].body->lvel ); return dDOT( axP1, lvel1 ); } else { dReal rate = dDOT( axP1, lvel1 ); return ( (joint->flags & dJOINT_REVERSE) ? -rate : rate); } } return 0.0; } void dxJointPU::getInfo1( dxJoint::Info1 *info ) { info->m = 3; info->nub = 3; // powered needs an extra constraint row // see if we're at a joint limit. limotP.limit = 0; if (( limotP.lostop > -dInfinity || limotP.histop < dInfinity ) && limotP.lostop <= limotP.histop ) { // measure joint position dReal pos = dJointGetPUPosition( this ); limotP.testRotationalLimit( pos ); // N.B. The function is ill named } if ( limotP.limit || limotP.fmax > 0 ) info->m++; bool limiting1 = ( limot1.lostop >= -M_PI || limot1.histop <= M_PI ) && limot1.lostop <= limot1.histop; bool limiting2 = ( limot2.lostop >= -M_PI || limot2.histop <= M_PI ) && limot2.lostop <= limot2.histop; // We need to call testRotationLimit() even if we're motored, since it // records the result. limot1.limit = 0; limot2.limit = 0; if ( limiting1 || limiting2 ) { dReal angle1, angle2; getAngles( &angle1, &angle2 ); if ( limiting1 ) limot1.testRotationalLimit( angle1 ); if ( limiting2 ) limot2.testRotationalLimit( angle2 ); } if ( limot1.limit || limot1.fmax > 0 ) info->m++; if ( limot2.limit || limot2.fmax > 0 ) info->m++; } void dxJointPU::getInfo2( dxJoint::Info2 *info ) { const int s0 = 0; const int s1 = info->rowskip; const int s2 = 2 * s1; const dReal k = info->fps * info->erp; // pull out pos and R for both bodies. also get the `connection' // vector pos2-pos1. dReal *pos1, *pos2 = 0, *R1, *R2 = 0; pos1 = node[0].body->posr.pos; R1 = node[0].body->posr.R; if ( node[1].body ) { pos2 = node[1].body->posr.pos; R2 = node[1].body->posr.R; } dVector3 axP; // Axis of the prismatic joint in global frame dMULTIPLY0_331( axP, R1, axisP1 ); // distance between the body1 and the anchor2 in global frame // Calculated in the same way as the offset dVector3 dist; dVector3 wanchor2 = {0,0,0}; if ( node[1].body ) { dMULTIPLY0_331( wanchor2, R2, anchor2 ); dist[0] = wanchor2[0] + pos2[0] - pos1[0]; dist[1] = wanchor2[1] + pos2[1] - pos1[1]; dist[2] = wanchor2[2] + pos2[2] - pos1[2]; } else { if (flags & dJOINT_REVERSE ) { // Invert the sign of dist dist[0] = pos1[0] - anchor2[0]; dist[1] = pos1[1] - anchor2[1]; dist[2] = pos1[2] - anchor2[2]; } else { dist[0] = anchor2[0] - pos1[0]; dist[1] = anchor2[1] - pos1[1]; dist[2] = anchor2[2] - pos1[2]; } } dVector3 q; // Temporary axis vector // Will be used at 2 places with 2 different meaning // ====================================================================== // Work on the angular part (i.e. row 0) // // The axis perpendicular to both axis1 and axis2 should be the only unconstrained // rotational axis, the angular velocity of the two bodies perpendicular to // the rotoide axes should be equal. Thus the constraint equations are // p*w1 - p*w2 = 0 // where p is a unit vector perpendicular to both axis1 and axis2 // and w1 and w2 are the angular velocity vectors of the two bodies. dVector3 ax1, ax2; getAxes( ax1, ax2 ); dReal val = dDOT( ax1, ax2 ); q[0] = ax2[0] - val * ax1[0]; q[1] = ax2[1] - val * ax1[1]; q[2] = ax2[2] - val * ax1[2]; dVector3 p; dCROSS( p, = , ax1, q ); dNormalize3( p ); // info->J1a[s0+i] = p[i]; dOPE(( info->J1a ) + s0, = , p ); if ( node[1].body ) { // info->J2a[s0+i] = -p[i]; dOPE(( info->J2a ) + s0, = -, p ); } // compute the right hand side of the constraint equation. Set relative // body velocities along p to bring the axes back to perpendicular. // If ax1, ax2 are unit length joint axes as computed from body1 and // body2, we need to rotate both bodies along the axis p. If theta // is the angle between ax1 and ax2, we need an angular velocity // along p to cover the angle erp * (theta - Pi/2) in one step: // // |angular_velocity| = angle/time = erp*(theta - Pi/2) / stepsize // = (erp*fps) * (theta - Pi/2) // // if theta is close to Pi/2, // theta - Pi/2 ~= cos(theta), so // |angular_velocity| ~= (erp*fps) * (ax1 dot ax2) info->c[0] = k * - val; // ========================================================================== // Work on the linear part (i.e rows 1 and 2) // // We want: vel2 = vel1 + w1 x c ... but this would // result in three equations, so we project along the planespace vectors // so that sliding along the axisP is disregarded. // // p1 + R1 dist' = p2 + R2 anchor2' // v1 + w1 x R1 dist' + v_p = v2 + w2 x R2 anchor2' // v_p is speed of prismatic joint (i.e. elongation rate) // Since the constraints are perpendicular to v_p we have: // e1 dot v_p = 0 and e2 dot v_p = 0 // e1 dot ( v1 + w1 x dist = v2 + w2 x anchor2 ) // e2 dot ( v1 + w1 x dist = v2 + w2 x anchor2 ) // == // e1 . v1 + e1 . w1 x dist = e1 . v2 + e1 . w2 x anchor2 // since a . (b x c) = - b . (a x c) = - (a x c) . b // and a x b = - b x a // e1 . v1 - e1 x dist . w1 - e1 . v2 - (- e1 x anchor2 . w2) = 0 // e1 . v1 + dist x e1 . w1 - e1 . v2 - anchor2 x e1 . w2 = 0 // Coeff for 1er line of: J1l => e1, J2l => -e1 // Coeff for 2er line of: J1l => e2, J2l => -ax2 // Coeff for 1er line of: J1a => dist x e1, J2a => - anchor2 x e1 // Coeff for 2er line of: J1a => dist x e2, J2a => - anchor2 x e2 // e1 and e2 are perpendicular to axP // so e1 = ax1 and e2 = ax1 x axP // N.B. ax2 is not always perpendicular to axP since it is attached to body 2 dCROSS( q , = , ax1, axP ); dMULTIPLY0_331( axP, R1, axisP1 ); dCROSS(( info->J1a ) + s1, = , dist, ax1 ); dCROSS(( info->J1a ) + s2, = , dist, q ); // info->J1l[s1+i] = ax[i]; dOPE(( info->J1l ) + s1, = , ax1 ); // info->J1l[s2+i] = q[i]; dOPE(( info->J1l ) + s2, = , q ); if ( node[1].body ) { // Calculate anchor2 in world coordinate // q x anchor2 instead of anchor2 x q since we want the negative value dCROSS(( info->J2a ) + s1, = , ax1, wanchor2 ); // The cross product is in reverse order since we want the negative value dCROSS(( info->J2a ) + s2, = , q, wanchor2 ); // info->J2l[s1+i] = -ax1[i]; dOPE(( info->J2l ) + s1, = -, ax1 ); // info->J2l[s2+i] = -ax1[i]; dOPE(( info->J2l ) + s2, = -, q ); } // We want to make correction for motion not in the line of the axisP // We calculate the displacement w.r.t. the anchor pt. // // compute the elements 1 and 2 of right hand side. // We want to align the offset point (in body 2's frame) with the center of body 1. // The position should be the same when we are not along the prismatic axis dVector3 err; dMULTIPLY0_331( err, R1, anchor1 ); // err[i] = dist[i] - err[i]; dOPE2( err, = , dist, -, err ); info->c[1] = k * dDOT( ax1, err ); info->c[2] = k * dDOT( q, err ); int row = 3 + limot1.addLimot( this, info, 3, ax1, 1 ); if ( node[1].body || !(flags & dJOINT_REVERSE) ) limotP.addLimot( this, info, row, axP, 0 ); else { axP[0] = -axP[0]; axP[1] = -axP[1]; axP[2] = -axP[2]; limotP.addLimot ( this, info, row, axP, 0 ); } } void dJointSetPUAnchor( dJointID j, dReal x, dReal y, dReal z ) { dxJointPU* joint = ( dxJointPU* ) j; dUASSERT( joint, "bad joint argument" ); checktype( joint, PU ); setAnchors( joint, x, y, z, joint->anchor1, joint->anchor2 ); joint->computeInitialRelativeRotations(); } /** * This function initialize the anchor and the relative position of each body * as if body2 was at its current position + [dx,dy,dy]. * Ex: *
 * dReal offset = 1;
 * dVector3 dir;
 * dJointGetPUAxis3(jId, dir);
 * dJointSetPUAnchor(jId, 0, 0, 0);
 * // If you request the position you will have: dJointGetPUPosition(jId) == 0
 * dJointSetPUAnchorDelta(jId, 0, 0, 0, dir[X]*offset, dir[Y]*offset, dir[Z]*offset);
 * // If you request the position you will have: dJointGetPUPosition(jId) == -offset
 * 
* @param j The PU joint for which the anchor point will be set * @param x The X position of the anchor point in world frame * @param y The Y position of the anchor point in world frame * @param z The Z position of the anchor point in world frame * @param dx A delta to be added to the X position as if the anchor was set * when body1 was at current_position[X] + dx * @param dx A delta to be added to the Y position as if the anchor was set * when body1 was at current_position[Y] + dy * @param dx A delta to be added to the Z position as if the anchor was set * when body1 was at current_position[Z] + dz * @note Should have the same meaning as dJointSetSliderAxisDelta */ void dJointSetPUAnchorDelta( dJointID j, dReal x, dReal y, dReal z, dReal dx, dReal dy, dReal dz ) { dxJointPU* joint = ( dxJointPU* ) j; dUASSERT( joint, "bad joint argument" ); checktype( joint, PU ); if ( joint->node[0].body ) { joint->node[0].body->posr.pos[0] += dx; joint->node[0].body->posr.pos[1] += dy; joint->node[0].body->posr.pos[2] += dz; } setAnchors( joint, x, y, z, joint->anchor1, joint->anchor2 ); if ( joint->node[0].body ) { joint->node[0].body->posr.pos[0] -= dx; joint->node[0].body->posr.pos[1] -= dy; joint->node[0].body->posr.pos[2] -= dz; } joint->computeInitialRelativeRotations(); } /** * \brief This function initialize the anchor and the relative position of each body * such that dJointGetPUPosition will return the dot product of axis and [dx,dy,dy]. * * The body 1 is moved to [-dx, -dy, -dx] then the anchor is set. This will be the * position 0 for the prismatic part of the joint. Then the body 1 is moved to its * original position. * * Ex: *
 * dReal offset = 1;
 * dVector3 dir;
 * dJointGetPUAxis3(jId, dir);
 * dJointSetPUAnchor(jId, 0, 0, 0);
 * // If you request the position you will have: dJointGetPUPosition(jId) == 0
 * dJointSetPUAnchorDelta(jId, 0, 0, 0, dir[X]*offset, dir[Y]*offset, dir[Z]*offset);
 * // If you request the position you will have: dJointGetPUPosition(jId) == offset
 * 
* @param j The PU joint for which the anchor point will be set * @param x The X position of the anchor point in world frame * @param y The Y position of the anchor point in world frame * @param z The Z position of the anchor point in world frame * @param dx A delta to be added to the X position as if the anchor was set * when body1 was at current_position[X] + dx * @param dx A delta to be added to the Y position as if the anchor was set * when body1 was at current_position[Y] + dy * @param dx A delta to be added to the Z position as if the anchor was set * when body1 was at current_position[Z] + dz * @note Should have the same meaning as dJointSetSliderAxisDelta */ void dJointSetPUAnchorOffset( dJointID j, dReal x, dReal y, dReal z, dReal dx, dReal dy, dReal dz ) { dxJointPU* joint = ( dxJointPU* ) j; dUASSERT( joint, "bad joint argument" ); checktype( joint, PU ); if (joint->flags & dJOINT_REVERSE) { dx = -dx; dy = -dy; dz = -dz; } if ( joint->node[0].body ) { joint->node[0].body->posr.pos[0] -= dx; joint->node[0].body->posr.pos[1] -= dy; joint->node[0].body->posr.pos[2] -= dz; } setAnchors( joint, x, y, z, joint->anchor1, joint->anchor2 ); if ( joint->node[0].body ) { joint->node[0].body->posr.pos[0] += dx; joint->node[0].body->posr.pos[1] += dy; joint->node[0].body->posr.pos[2] += dz; } joint->computeInitialRelativeRotations(); } void dJointSetPUAxis1( dJointID j, dReal x, dReal y, dReal z ) { dxJointPU* joint = ( dxJointPU* ) j; dUASSERT( joint, "bad joint argument" ); checktype( joint, PU ); if ( joint->flags & dJOINT_REVERSE ) setAxes( joint, x, y, z, NULL, joint->axis2 ); else setAxes( joint, x, y, z, joint->axis1, NULL ); joint->computeInitialRelativeRotations(); } void dJointSetPUAxis2( dJointID j, dReal x, dReal y, dReal z ) { dxJointPU* joint = ( dxJointPU* ) j; dUASSERT( joint, "bad joint argument" ); checktype( joint, PU ); if ( joint->flags & dJOINT_REVERSE ) setAxes( joint, x, y, z, joint->axis1, NULL ); else setAxes( joint, x, y, z, NULL, joint->axis2 ); joint->computeInitialRelativeRotations(); } void dJointSetPUAxisP( dJointID id, dReal x, dReal y, dReal z ) { dJointSetPUAxis3( id, x, y, z ); } void dJointSetPUAxis3( dJointID j, dReal x, dReal y, dReal z ) { dxJointPU* joint = ( dxJointPU* ) j; dUASSERT( joint, "bad joint argument" ); checktype( joint, PU ); setAxes( joint, x, y, z, joint->axisP1, 0 ); joint->computeInitialRelativeRotations(); } void dJointGetPUAngles( dJointID j, dReal *angle1, dReal *angle2 ) { dxJointUniversal* joint = ( dxJointUniversal* ) j; dUASSERT( joint, "bad joint argument" ); checktype( joint, PU ); if ( joint->flags & dJOINT_REVERSE ) joint->getAngles( angle2, angle1 ); else joint->getAngles( angle1, angle2 ); } dReal dJointGetPUAngle1( dJointID j ) { dxJointUniversal* joint = ( dxJointUniversal* ) j; dUASSERT( joint, "bad joint argument" ); checktype( joint, PU ); if ( joint->flags & dJOINT_REVERSE ) return joint->getAngle2(); else return joint->getAngle1(); } dReal dJointGetPUAngle2( dJointID j ) { dxJointUniversal* joint = ( dxJointUniversal* ) j; dUASSERT( joint, "bad joint argument" ); checktype( joint, PU ); if ( joint->flags & dJOINT_REVERSE ) return joint->getAngle1(); else return joint->getAngle2(); } dReal dJointGetPUAngle1Rate( dJointID j ) { dxJointPU* joint = ( dxJointPU* ) j; dUASSERT( joint, "bad joint argument" ); checktype( joint, PU ); if ( joint->node[0].body ) { dVector3 axis; if ( joint->flags & dJOINT_REVERSE ) getAxis2( joint, axis, joint->axis2 ); else getAxis( joint, axis, joint->axis1 ); dReal rate = dDOT( axis, joint->node[0].body->avel ); if ( joint->node[1].body ) rate -= dDOT( axis, joint->node[1].body->avel ); return rate; } return 0; } dReal dJointGetPUAngle2Rate( dJointID j ) { dxJointPU* joint = ( dxJointPU* ) j; dUASSERT( joint, "bad joint argument" ); checktype( joint, PU ); if ( joint->node[0].body ) { dVector3 axis; if ( joint->flags & dJOINT_REVERSE ) getAxis( joint, axis, joint->axis1 ); else getAxis2( joint, axis, joint->axis2 ); dReal rate = dDOT( axis, joint->node[0].body->avel ); if ( joint->node[1].body ) rate -= dDOT( axis, joint->node[1].body->avel ); return rate; } return 0; } void dJointSetPUParam( dJointID j, int parameter, dReal value ) { dxJointPU* joint = ( dxJointPU* ) j; dUASSERT( joint, "bad joint argument" ); checktype( joint, PU ); switch ( parameter & 0xff00 ) { case dParamGroup1: joint->limot1.set( parameter, value ); break; case dParamGroup2: joint->limot2.set( parameter & 0xff, value ); break; case dParamGroup3: joint->limotP.set( parameter & 0xff, value ); break; } } void dJointGetPUAnchor( dJointID j, dVector3 result ) { dxJointPU* joint = ( dxJointPU* ) j; dUASSERT( joint, "bad joint argument" ); dUASSERT( result, "bad result argument" ); checktype( joint, PU ); if ( joint->node[1].body ) getAnchor2( joint, result, joint->anchor2 ); else { // result[i] = joint->anchor2[i]; dOPE( result, = , joint->anchor2 ); } } void dJointGetPUAxis1( dJointID j, dVector3 result ) { dxJointPU* joint = ( dxJointPU* ) j; dUASSERT( joint, "bad joint argument" ); dUASSERT( result, "bad result argument" ); checktype( joint, PU ); if ( joint->flags & dJOINT_REVERSE ) getAxis2( joint, result, joint->axis2 ); else getAxis( joint, result, joint->axis1 ); } void dJointGetPUAxis2( dJointID j, dVector3 result ) { dxJointPU* joint = ( dxJointPU* ) j; dUASSERT( joint, "bad joint argument" ); dUASSERT( result, "bad result argument" ); checktype( joint, PU ); if ( joint->flags & dJOINT_REVERSE ) getAxis( joint, result, joint->axis1 ); else getAxis2( joint, result, joint->axis2 ); } /** * @brief Get the prismatic axis * @ingroup joints * * @note This function was added for convenience it is the same as * dJointGetPUAxis3 */ void dJointGetPUAxisP( dJointID id, dVector3 result ) { dJointGetPUAxis3( id, result ); } void dJointGetPUAxis3( dJointID j, dVector3 result ) { dxJointPU* joint = ( dxJointPU* ) j; dUASSERT( joint, "bad joint argument" ); dUASSERT( result, "bad result argument" ); checktype( joint, PU ); getAxis( joint, result, joint->axisP1 ); } dReal dJointGetPUParam( dJointID j, int parameter ) { dxJointPU* joint = ( dxJointPU* ) j; dUASSERT( joint, "bad joint argument" ); checktype( joint, PU ); switch ( parameter & 0xff00 ) { case dParamGroup1: return joint->limot1.get( parameter ); break; case dParamGroup2: return joint->limot2.get( parameter & 0xff ); break; case dParamGroup3: return joint->limotP.get( parameter & 0xff ); break; } return 0; } dJointType dxJointPU::type() const { return dJointTypePU; } size_t dxJointPU::size() const { return sizeof( *this ); } void dxJointPU::setRelativeValues() { dVector3 anchor; dJointGetPUAnchor(this, anchor); setAnchors( this, anchor[0], anchor[1], anchor[2], anchor1, anchor2 ); dVector3 ax1, ax2, ax3; dJointGetPUAxis1(this, ax1); dJointGetPUAxis2(this, ax2); dJointGetPUAxis3(this, ax3); if ( flags & dJOINT_REVERSE ) { setAxes( this, ax1[0], ax1[1], ax1[2], NULL, axis2 ); setAxes( this, ax2[0], ax2[1], ax2[2], axis1, NULL ); } else { setAxes( this, ax1[0], ax1[1], ax1[2], axis1, NULL ); setAxes( this, ax2[0], ax2[1], ax2[2], NULL, axis2 ); } setAxes( this, ax3[0], ax3[1], ax3[2], NULL, axisP1 ); computeInitialRelativeRotations(); } alien-arena-7.66+dfsg/source/unix/odesrc/joints/hinge2.cpp0000600000175000017500000003310612161402010022535 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include "hinge2.h" #include "joint_internal.h" //**************************************************************************** // hinge 2. note that this joint must be attached to two bodies for it to work dReal dxJointHinge2::measureAngle() const { dVector3 a1, a2; dMULTIPLY0_331( a1, node[1].body->posr.R, axis2 ); dMULTIPLY1_331( a2, node[0].body->posr.R, a1 ); dReal x = dDOT( v1, a2 ); dReal y = dDOT( v2, a2 ); return -dAtan2( y, x ); } dxJointHinge2::dxJointHinge2( dxWorld *w ) : dxJoint( w ) { dSetZero( anchor1, 4 ); dSetZero( anchor2, 4 ); dSetZero( axis1, 4 ); axis1[0] = 1; dSetZero( axis2, 4 ); axis2[1] = 1; c0 = 0; s0 = 0; dSetZero( v1, 4 ); v1[0] = 1; dSetZero( v2, 4 ); v2[1] = 1; limot1.init( world ); limot2.init( world ); susp_erp = world->global_erp; susp_cfm = world->global_cfm; flags |= dJOINT_TWOBODIES; } void dxJointHinge2::getInfo1( dxJoint::Info1 *info ) { info->m = 4; info->nub = 4; // see if we're powered or at a joint limit for axis 1 limot1.limit = 0; if (( limot1.lostop >= -M_PI || limot1.histop <= M_PI ) && limot1.lostop <= limot1.histop ) { dReal angle = measureAngle(); limot1.testRotationalLimit( angle ); } if ( limot1.limit || limot1.fmax > 0 ) info->m++; // see if we're powering axis 2 (we currently never limit this axis) limot2.limit = 0; if ( limot2.fmax > 0 ) info->m++; } //////////////////////////////////////////////////////////////////////////////// /// Function that computes ax1,ax2 = axis 1 and 2 in global coordinates (they are /// relative to body 1 and 2 initially) and then computes the constrained /// rotational axis as the cross product of ax1 and ax2. /// the sin and cos of the angle between axis 1 and 2 is computed, this comes /// from dot and cross product rules. /// /// @param ax1 Will contain the joint axis1 in world frame /// @param ax2 Will contain the joint axis2 in world frame /// @param axis Will contain the cross product of ax1 x ax2 /// @param sin_angle /// @param cos_angle //////////////////////////////////////////////////////////////////////////////// void dxJointHinge2::getAxisInfo(dVector3 ax1, dVector3 ax2, dVector3 axCross, dReal &sin_angle, dReal &cos_angle) const { dMULTIPLY0_331 (ax1, node[0].body->posr.R, axis1); dMULTIPLY0_331 (ax2, node[1].body->posr.R, axis2); dCROSS (axCross,=,ax1,ax2); sin_angle = dSqrt (axCross[0]*axCross[0] + axCross[1]*axCross[1] + axCross[2]*axCross[2]); cos_angle = dDOT (ax1,ax2); } void dxJointHinge2::getInfo2( dxJoint::Info2 *info ) { // get information we need to set the hinge row dReal s, c; dVector3 q; const dxJointHinge2 *joint = this; dVector3 ax1, ax2; joint->getAxisInfo( ax1, ax2, q, s, c ); dNormalize3( q ); // @@@ quicker: divide q by s ? // set the three ball-and-socket rows (aligned to the suspension axis ax1) setBall2( this, info, anchor1, anchor2, ax1, susp_erp ); // set the hinge row int s3 = 3 * info->rowskip; info->J1a[s3+0] = q[0]; info->J1a[s3+1] = q[1]; info->J1a[s3+2] = q[2]; if ( joint->node[1].body ) { info->J2a[s3+0] = -q[0]; info->J2a[s3+1] = -q[1]; info->J2a[s3+2] = -q[2]; } // compute the right hand side for the constrained rotational DOF. // axis 1 and axis 2 are separated by an angle `theta'. the desired // separation angle is theta0. sin(theta0) and cos(theta0) are recorded // in the joint structure. the correcting angular velocity is: // |angular_velocity| = angle/time = erp*(theta0-theta) / stepsize // = (erp*fps) * (theta0-theta) // (theta0-theta) can be computed using the following small-angle-difference // approximation: // theta0-theta ~= tan(theta0-theta) // = sin(theta0-theta)/cos(theta0-theta) // = (c*s0 - s*c0) / (c*c0 + s*s0) // = c*s0 - s*c0 assuming c*c0 + s*s0 ~= 1 // where c = cos(theta), s = sin(theta) // c0 = cos(theta0), s0 = sin(theta0) dReal k = info->fps * info->erp; info->c[3] = k * ( c0 * s - joint->s0 * c ); // if the axis1 hinge is powered, or has joint limits, add in more stuff int row = 4 + limot1.addLimot( this, info, 4, ax1, 1 ); // if the axis2 hinge is powered, add in more stuff limot2.addLimot( this, info, row, ax2, 1 ); // set parameter for the suspension info->cfm[0] = susp_cfm; } // compute vectors v1 and v2 (embedded in body1), used to measure angle // between body 1 and body 2 void dxJointHinge2::makeV1andV2() { if ( node[0].body ) { // get axis 1 and 2 in global coords dVector3 ax1, ax2, v; dMULTIPLY0_331( ax1, node[0].body->posr.R, axis1 ); dMULTIPLY0_331( ax2, node[1].body->posr.R, axis2 ); // don't do anything if the axis1 or axis2 vectors are zero or the same if (( ax1[0] == 0 && ax1[1] == 0 && ax1[2] == 0 ) || ( ax2[0] == 0 && ax2[1] == 0 && ax2[2] == 0 ) || ( ax1[0] == ax2[0] && ax1[1] == ax2[1] && ax1[2] == ax2[2] ) ) return; // modify axis 2 so it's perpendicular to axis 1 dReal k = dDOT( ax1, ax2 ); for ( int i = 0; i < 3; i++ ) ax2[i] -= k * ax1[i]; dNormalize3( ax2 ); // make v1 = modified axis2, v2 = axis1 x (modified axis2) dCROSS( v, = , ax1, ax2 ); dMULTIPLY1_331( v1, node[0].body->posr.R, ax2 ); dMULTIPLY1_331( v2, node[0].body->posr.R, v ); } } void dJointSetHinge2Anchor( dJointID j, dReal x, dReal y, dReal z ) { dxJointHinge2* joint = ( dxJointHinge2* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Hinge2 ); setAnchors( joint, x, y, z, joint->anchor1, joint->anchor2 ); joint->makeV1andV2(); } void dJointSetHinge2Axis1( dJointID j, dReal x, dReal y, dReal z ) { dxJointHinge2* joint = ( dxJointHinge2* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Hinge2 ); if ( joint->node[0].body ) { setAxes(joint, x, y, z, joint->axis1, NULL); // compute the sin and cos of the angle between axis 1 and axis 2 dVector3 ax1, ax2, ax; joint->getAxisInfo( ax1, ax2, ax, joint->s0, joint->c0 ); } joint->makeV1andV2(); } void dJointSetHinge2Axis2( dJointID j, dReal x, dReal y, dReal z ) { dxJointHinge2* joint = ( dxJointHinge2* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Hinge2 ); if ( joint->node[1].body ) { setAxes(joint, x, y, z, NULL, joint->axis2); // compute the sin and cos of the angle between axis 1 and axis 2 dVector3 ax1, ax2, ax;; joint->getAxisInfo( ax1, ax2, ax, joint->s0, joint->c0 ); } joint->makeV1andV2(); } void dJointSetHinge2Param( dJointID j, int parameter, dReal value ) { dxJointHinge2* joint = ( dxJointHinge2* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Hinge2 ); if (( parameter & 0xff00 ) == 0x100 ) { joint->limot2.set( parameter & 0xff, value ); } else { if ( parameter == dParamSuspensionERP ) joint->susp_erp = value; else if ( parameter == dParamSuspensionCFM ) joint->susp_cfm = value; else joint->limot1.set( parameter, value ); } } void dJointGetHinge2Anchor( dJointID j, dVector3 result ) { dxJointHinge2* joint = ( dxJointHinge2* )j; dUASSERT( joint, "bad joint argument" ); dUASSERT( result, "bad result argument" ); checktype( joint, Hinge2 ); if ( joint->flags & dJOINT_REVERSE ) getAnchor2( joint, result, joint->anchor2 ); else getAnchor( joint, result, joint->anchor1 ); } void dJointGetHinge2Anchor2( dJointID j, dVector3 result ) { dxJointHinge2* joint = ( dxJointHinge2* )j; dUASSERT( joint, "bad joint argument" ); dUASSERT( result, "bad result argument" ); checktype( joint, Hinge2 ); if ( joint->flags & dJOINT_REVERSE ) getAnchor( joint, result, joint->anchor1 ); else getAnchor2( joint, result, joint->anchor2 ); } void dJointGetHinge2Axis1( dJointID j, dVector3 result ) { dxJointHinge2* joint = ( dxJointHinge2* )j; dUASSERT( joint, "bad joint argument" ); dUASSERT( result, "bad result argument" ); checktype( joint, Hinge2 ); if ( joint->node[0].body ) { dMULTIPLY0_331( result, joint->node[0].body->posr.R, joint->axis1 ); } } void dJointGetHinge2Axis2( dJointID j, dVector3 result ) { dxJointHinge2* joint = ( dxJointHinge2* )j; dUASSERT( joint, "bad joint argument" ); dUASSERT( result, "bad result argument" ); checktype( joint, Hinge2 ); if ( joint->node[1].body ) { dMULTIPLY0_331( result, joint->node[1].body->posr.R, joint->axis2 ); } } dReal dJointGetHinge2Param( dJointID j, int parameter ) { dxJointHinge2* joint = ( dxJointHinge2* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Hinge2 ); if (( parameter & 0xff00 ) == 0x100 ) { return joint->limot2.get( parameter & 0xff ); } else { if ( parameter == dParamSuspensionERP ) return joint->susp_erp; else if ( parameter == dParamSuspensionCFM ) return joint->susp_cfm; else return joint->limot1.get( parameter ); } } dReal dJointGetHinge2Angle1( dJointID j ) { dxJointHinge2* joint = ( dxJointHinge2* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Hinge2 ); if ( joint->node[0].body ) return joint->measureAngle(); else return 0; } dReal dJointGetHinge2Angle1Rate( dJointID j ) { dxJointHinge2* joint = ( dxJointHinge2* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Hinge2 ); if ( joint->node[0].body ) { dVector3 axis; dMULTIPLY0_331( axis, joint->node[0].body->posr.R, joint->axis1 ); dReal rate = dDOT( axis, joint->node[0].body->avel ); if ( joint->node[1].body ) rate -= dDOT( axis, joint->node[1].body->avel ); return rate; } else return 0; } dReal dJointGetHinge2Angle2Rate( dJointID j ) { dxJointHinge2* joint = ( dxJointHinge2* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Hinge2 ); if ( joint->node[0].body && joint->node[1].body ) { dVector3 axis; dMULTIPLY0_331( axis, joint->node[1].body->posr.R, joint->axis2 ); dReal rate = dDOT( axis, joint->node[0].body->avel ); if ( joint->node[1].body ) rate -= dDOT( axis, joint->node[1].body->avel ); return rate; } else return 0; } void dJointAddHinge2Torques( dJointID j, dReal torque1, dReal torque2 ) { dxJointHinge2* joint = ( dxJointHinge2* )j; dVector3 axis1, axis2; dUASSERT( joint, "bad joint argument" ); checktype( joint, Hinge2 ); if ( joint->node[0].body && joint->node[1].body ) { dMULTIPLY0_331( axis1, joint->node[0].body->posr.R, joint->axis1 ); dMULTIPLY0_331( axis2, joint->node[1].body->posr.R, joint->axis2 ); axis1[0] = axis1[0] * torque1 + axis2[0] * torque2; axis1[1] = axis1[1] * torque1 + axis2[1] * torque2; axis1[2] = axis1[2] * torque1 + axis2[2] * torque2; dBodyAddTorque( joint->node[0].body, axis1[0], axis1[1], axis1[2] ); dBodyAddTorque( joint->node[1].body, -axis1[0], -axis1[1], -axis1[2] ); } } dJointType dxJointHinge2::type() const { return dJointTypeHinge2; } size_t dxJointHinge2::size() const { return sizeof( *this ); } void dxJointHinge2::setRelativeValues() { dVector3 anchor; dJointGetHinge2Anchor(this, anchor); setAnchors( this, anchor[0], anchor[1], anchor[2], anchor1, anchor2 ); dVector3 axis; if ( node[0].body ) { dJointGetHinge2Axis1(this, axis); setAxes( this, axis[0],axis[1],axis[2], axis1, NULL ); } if ( node[0].body ) { dJointGetHinge2Axis2(this, axis); setAxes( this, axis[0],axis[1],axis[2], NULL, axis2 ); } dVector3 ax1, ax2; getAxisInfo( ax1, ax2, axis, s0, c0 ); makeV1andV2(); } alien-arena-7.66+dfsg/source/unix/odesrc/joints/ball.h0000600000175000017500000000424112161402010021736 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_JOINT_BALL_H_ #define _ODE_JOINT_BALL_H_ #include "joint.h" // ball and socket struct dxJointBall : public dxJoint { dVector3 anchor1; // anchor w.r.t first body dVector3 anchor2; // anchor w.r.t second body dReal erp; // error reduction dReal cfm; // constraint force mix in void set( int num, dReal value ); dReal get( int num ); dxJointBall( dxWorld *w ); virtual void getInfo1( Info1* info ); virtual void getInfo2( Info2* info ); virtual dJointType type() const; virtual size_t size() const; virtual void setRelativeValues(); }; #endif alien-arena-7.66+dfsg/source/unix/odesrc/joints/piston.h0000600000175000017500000001214712161402010022344 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_JOINT_PISTON_H_ #define _ODE_JOINT_PISTON_H_ #include "joint.h" //////////////////////////////////////////////////////////////////////////////// /// Component of a Piston joint ///
///                              |- Anchor point
///      Body_1                  |                       Body_2
///      +---------------+       V                       +------------------+
///     /               /|                             /                  /|
///    /               / +       |--      ______      /                  / +
///   /      x        /./........x.......(_____()..../         x        /.......> axis
///  +---------------+ /         |--                +------------------+ /
///  |               |/                             |                  |/
///  +---------------+                              +------------------+
///          |                                                 |
///          |                                                 |
///          |------------------> <----------------------------|
///              anchor1                  anchor2
///
///
/// 
/// /// When the prismatic joint as been elongated (i.e. dJointGetPistonPosition) /// return a value > 0 ///
///                                   |- Anchor point
///      Body_1                       |                       Body_2
///      +---------------+            V                       +------------------+
///     /               /|                                  /                  /|
///    /               / +            |--      ______      /                  / +
///   /      x        /./........_____x.......(_____()..../         x        /.......> axis
///  +---------------+ /              |--                +------------------+ /
///  |               |/                                  |                  |/
///  +---------------+                                   +------------------+
///          |                                                      |
///          |                                                      |
///          |------------------>      <----------------------------|
///              anchor1         |----|         anchor2
///                                ^
///                                |-- This is what dJointGetPistonPosition will
///                                    return
/// 
//////////////////////////////////////////////////////////////////////////////// struct dxJointPiston : public dxJoint { dVector3 axis1; ///< Axis of the prismatic and rotoide w.r.t first body dVector3 axis2; ///< Axis of the prismatic and rotoide w.r.t second body dQuaternion qrel; ///< Initial relative rotation body1 -> body2 /// Anchor w.r.t first body. /// This is the same as the offset for the Slider joint /// @note To find the position of the anchor when the body 1 has moved /// you must add the position of the prismatic joint /// i.e anchor = R1 * anchor1 + dJointGetPistonPosition() * (R1 * axis1) dVector3 anchor1; dVector3 anchor2; //< anchor w.r.t second body /// limit and motor information for the prismatic /// part of the joint dxJointLimitMotor limotP; /// limit and motor information for the rotoide /// part of the joint dxJointLimitMotor limotR; dxJointPiston( dxWorld *w ); virtual void getInfo1( Info1* info ); virtual void getInfo2( Info2* info ); virtual dJointType type() const; virtual size_t size() const; virtual void setRelativeValues(); void computeInitialRelativeRotation(); }; #endif alien-arena-7.66+dfsg/source/unix/odesrc/joints/hinge.cpp0000600000175000017500000002730012161402010022452 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include "hinge.h" #include "joint_internal.h" //**************************************************************************** // hinge dxJointHinge::dxJointHinge( dxWorld *w ) : dxJoint( w ) { dSetZero( anchor1, 4 ); dSetZero( anchor2, 4 ); dSetZero( axis1, 4 ); axis1[0] = 1; dSetZero( axis2, 4 ); axis2[0] = 1; dSetZero( qrel, 4 ); limot.init( world ); } void dxJointHinge::getInfo1( dxJoint::Info1 *info ) { info->nub = 5; // see if joint is powered if ( limot.fmax > 0 ) info->m = 6; // powered hinge needs an extra constraint row else info->m = 5; // see if we're at a joint limit. if (( limot.lostop >= -M_PI || limot.histop <= M_PI ) && limot.lostop <= limot.histop ) { dReal angle = getHingeAngle( node[0].body, node[1].body, axis1, qrel ); if ( limot.testRotationalLimit( angle ) ) info->m = 6; } } void dxJointHinge::getInfo2( dxJoint::Info2 *info ) { // set the three ball-and-socket rows setBall( this, info, anchor1, anchor2 ); // set the two hinge rows. the hinge axis should be the only unconstrained // rotational axis, the angular velocity of the two bodies perpendicular to // the hinge axis should be equal. thus the constraint equations are // p*w1 - p*w2 = 0 // q*w1 - q*w2 = 0 // where p and q are unit vectors normal to the hinge axis, and w1 and w2 // are the angular velocity vectors of the two bodies. dVector3 ax1; // length 1 joint axis in global coordinates, from 1st body dVector3 p, q; // plane space vectors for ax1 dMULTIPLY0_331( ax1, node[0].body->posr.R, axis1 ); dPlaneSpace( ax1, p, q ); int s3 = 3 * info->rowskip; int s4 = 4 * info->rowskip; info->J1a[s3+0] = p[0]; info->J1a[s3+1] = p[1]; info->J1a[s3+2] = p[2]; info->J1a[s4+0] = q[0]; info->J1a[s4+1] = q[1]; info->J1a[s4+2] = q[2]; if ( node[1].body ) { info->J2a[s3+0] = -p[0]; info->J2a[s3+1] = -p[1]; info->J2a[s3+2] = -p[2]; info->J2a[s4+0] = -q[0]; info->J2a[s4+1] = -q[1]; info->J2a[s4+2] = -q[2]; } // compute the right hand side of the constraint equation. set relative // body velocities along p and q to bring the hinge back into alignment. // if ax1,ax2 are the unit length hinge axes as computed from body1 and // body2, we need to rotate both bodies along the axis u = (ax1 x ax2). // if `theta' is the angle between ax1 and ax2, we need an angular velocity // along u to cover angle erp*theta in one step : // |angular_velocity| = angle/time = erp*theta / stepsize // = (erp*fps) * theta // angular_velocity = |angular_velocity| * (ax1 x ax2) / |ax1 x ax2| // = (erp*fps) * theta * (ax1 x ax2) / sin(theta) // ...as ax1 and ax2 are unit length. if theta is smallish, // theta ~= sin(theta), so // angular_velocity = (erp*fps) * (ax1 x ax2) // ax1 x ax2 is in the plane space of ax1, so we project the angular // velocity to p and q to find the right hand side. dVector3 ax2, b; if ( node[1].body ) { dMULTIPLY0_331( ax2, node[1].body->posr.R, axis2 ); } else { ax2[0] = axis2[0]; ax2[1] = axis2[1]; ax2[2] = axis2[2]; } dCROSS( b, = , ax1, ax2 ); dReal k = info->fps * info->erp; info->c[3] = k * dDOT( b, p ); info->c[4] = k * dDOT( b, q ); // if the hinge is powered, or has joint limits, add in the stuff limot.addLimot( this, info, 5, ax1, 1 ); } void dJointSetHingeAnchor( dJointID j, dReal x, dReal y, dReal z ) { dxJointHinge* joint = ( dxJointHinge* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Hinge ); setAnchors( joint, x, y, z, joint->anchor1, joint->anchor2 ); joint->computeInitialRelativeRotation(); } void dJointSetHingeAnchorDelta( dJointID j, dReal x, dReal y, dReal z, dReal dx, dReal dy, dReal dz ) { dxJointHinge* joint = ( dxJointHinge* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Hinge ); if ( joint->node[0].body ) { dReal q[4]; q[0] = x - joint->node[0].body->posr.pos[0]; q[1] = y - joint->node[0].body->posr.pos[1]; q[2] = z - joint->node[0].body->posr.pos[2]; q[3] = 0; dMULTIPLY1_331( joint->anchor1, joint->node[0].body->posr.R, q ); if ( joint->node[1].body ) { q[0] = x - joint->node[1].body->posr.pos[0]; q[1] = y - joint->node[1].body->posr.pos[1]; q[2] = z - joint->node[1].body->posr.pos[2]; q[3] = 0; dMULTIPLY1_331( joint->anchor2, joint->node[1].body->posr.R, q ); } else { // Move the relative displacement between the passive body and the // anchor in the same direction as the passive body has just moved joint->anchor2[0] = x + dx; joint->anchor2[1] = y + dy; joint->anchor2[2] = z + dz; } } joint->anchor1[3] = 0; joint->anchor2[3] = 0; joint->computeInitialRelativeRotation(); } void dJointSetHingeAxis( dJointID j, dReal x, dReal y, dReal z ) { dxJointHinge* joint = ( dxJointHinge* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Hinge ); setAxes( joint, x, y, z, joint->axis1, joint->axis2 ); joint->computeInitialRelativeRotation(); } void dJointSetHingeAxisOffset( dJointID j, dReal x, dReal y, dReal z, dReal dangle ) { dxJointHinge* joint = ( dxJointHinge* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Hinge ); setAxes( joint, x, y, z, joint->axis1, joint->axis2 ); joint->computeInitialRelativeRotation(); if ( joint->flags & dJOINT_REVERSE ) dangle = -dangle; dQuaternion qAngle, qOffset; dQFromAxisAndAngle(qAngle, x, y, z, dangle); dQMultiply3(qOffset, qAngle, joint->qrel); joint->qrel[0] = qOffset[0]; joint->qrel[1] = qOffset[1]; joint->qrel[2] = qOffset[2]; joint->qrel[3] = qOffset[3]; } void dJointGetHingeAnchor( dJointID j, dVector3 result ) { dxJointHinge* joint = ( dxJointHinge* )j; dUASSERT( joint, "bad joint argument" ); dUASSERT( result, "bad result argument" ); checktype( joint, Hinge ); if ( joint->flags & dJOINT_REVERSE ) getAnchor2( joint, result, joint->anchor2 ); else getAnchor( joint, result, joint->anchor1 ); } void dJointGetHingeAnchor2( dJointID j, dVector3 result ) { dxJointHinge* joint = ( dxJointHinge* )j; dUASSERT( joint, "bad joint argument" ); dUASSERT( result, "bad result argument" ); checktype( joint, Hinge ); if ( joint->flags & dJOINT_REVERSE ) getAnchor( joint, result, joint->anchor1 ); else getAnchor2( joint, result, joint->anchor2 ); } void dJointGetHingeAxis( dJointID j, dVector3 result ) { dxJointHinge* joint = ( dxJointHinge* )j; dUASSERT( joint, "bad joint argument" ); dUASSERT( result, "bad result argument" ); checktype( joint, Hinge ); getAxis( joint, result, joint->axis1 ); } void dJointSetHingeParam( dJointID j, int parameter, dReal value ) { dxJointHinge* joint = ( dxJointHinge* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Hinge ); joint->limot.set( parameter, value ); } dReal dJointGetHingeParam( dJointID j, int parameter ) { dxJointHinge* joint = ( dxJointHinge* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Hinge ); return joint->limot.get( parameter ); } dReal dJointGetHingeAngle( dJointID j ) { dxJointHinge* joint = ( dxJointHinge* )j; dAASSERT( joint ); checktype( joint, Hinge ); if ( joint->node[0].body ) { dReal ang = getHingeAngle( joint->node[0].body, joint->node[1].body, joint->axis1, joint->qrel ); if ( joint->flags & dJOINT_REVERSE ) return -ang; else return ang; } else return 0; } dReal dJointGetHingeAngleRate( dJointID j ) { dxJointHinge* joint = ( dxJointHinge* )j; dAASSERT( joint ); checktype( joint, Hinge ); if ( joint->node[0].body ) { dVector3 axis; dMULTIPLY0_331( axis, joint->node[0].body->posr.R, joint->axis1 ); dReal rate = dDOT( axis, joint->node[0].body->avel ); if ( joint->node[1].body ) rate -= dDOT( axis, joint->node[1].body->avel ); if ( joint->flags & dJOINT_REVERSE ) rate = - rate; return rate; } else return 0; } void dJointAddHingeTorque( dJointID j, dReal torque ) { dxJointHinge* joint = ( dxJointHinge* )j; dVector3 axis; dAASSERT( joint ); checktype( joint, Hinge ); if ( joint->flags & dJOINT_REVERSE ) torque = -torque; getAxis( joint, axis, joint->axis1 ); axis[0] *= torque; axis[1] *= torque; axis[2] *= torque; if ( joint->node[0].body != 0 ) dBodyAddTorque( joint->node[0].body, axis[0], axis[1], axis[2] ); if ( joint->node[1].body != 0 ) dBodyAddTorque( joint->node[1].body, -axis[0], -axis[1], -axis[2] ); } dJointType dxJointHinge::type() const { return dJointTypeHinge; } size_t dxJointHinge::size() const { return sizeof( *this ); } void dxJointHinge::setRelativeValues() { dVector3 vec; dJointGetHingeAnchor(this, vec); setAnchors( this, vec[0], vec[1], vec[2], anchor1, anchor2 ); dJointGetHingeAxis(this, vec); setAxes( this, vec[0], vec[1], vec[2], axis1, axis2 ); computeInitialRelativeRotation(); } /// Compute initial relative rotation body1 -> body2, or env -> body1 void dxJointHinge::computeInitialRelativeRotation() { if ( node[0].body ) { if ( node[1].body ) { dQMultiply1( qrel, node[0].body->q, node[1].body->q ); } else { // set qrel to the transpose of the first body q qrel[0] = node[0].body->q[0]; qrel[1] = -node[0].body->q[1]; qrel[2] = -node[0].body->q[2]; qrel[3] = -node[0].body->q[3]; } } } alien-arena-7.66+dfsg/source/unix/odesrc/joints/contact.h0000600000175000017500000000370712161402010022465 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_JOINT_CONTACT_H_ #define _ODE_JOINT_CONTACT_H_ #include "joint.h" // contact struct dxJointContact : public dxJoint { int the_m; // number of rows computed by getInfo1 dContact contact; dxJointContact( dxWorld* w ); virtual void getInfo1( Info1* info ); virtual void getInfo2( Info2* info ); virtual dJointType type() const; virtual size_t size() const; }; #endif alien-arena-7.66+dfsg/source/unix/odesrc/joints/plane2d.h0000600000175000017500000000415412161402010022354 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_JOINT_PLANE2D_H_ #define _ODE_JOINT_PLANE2D_H_ #include "joint.h" // 2d joint, constrains to z == 0 struct dxJointPlane2D : public dxJoint { int row_motor_x; int row_motor_y; int row_motor_angle; dxJointLimitMotor motor_x; dxJointLimitMotor motor_y; dxJointLimitMotor motor_angle; dxJointPlane2D( dxWorld *w ); virtual void getInfo1( Info1* info ); virtual void getInfo2( Info2* info ); virtual dJointType type() const; virtual size_t size() const; }; #endif alien-arena-7.66+dfsg/source/unix/odesrc/joints/lmotor.cpp0000600000175000017500000001270212161402010022674 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include "lmotor.h" #include "joint_internal.h" //**************************************************************************** // lmotor joint dxJointLMotor::dxJointLMotor( dxWorld *w ) : dxJoint( w ) { int i; num = 0; for ( i = 0;i < 3;i++ ) { dSetZero( axis[i], 4 ); limot[i].init( world ); } } void dxJointLMotor::computeGlobalAxes( dVector3 ax[3] ) { for ( int i = 0; i < num; i++ ) { if ( rel[i] == 1 ) { dMULTIPLY0_331( ax[i], node[0].body->posr.R, axis[i] ); } else if ( rel[i] == 2 ) { if ( node[1].body ) // jds: don't assert, just ignore { dMULTIPLY0_331( ax[i], node[1].body->posr.R, axis[i] ); } } else { ax[i][0] = axis[i][0]; ax[i][1] = axis[i][1]; ax[i][2] = axis[i][2]; } } } void dxJointLMotor::getInfo1( dxJoint::Info1 *info ) { info->m = 0; info->nub = 0; for ( int i = 0; i < num; i++ ) { if ( limot[i].fmax > 0 ) { info->m++; } } } void dxJointLMotor::getInfo2( dxJoint::Info2 *info ) { int row = 0; dVector3 ax[3]; computeGlobalAxes( ax ); for ( int i = 0;i < num;i++ ) { row += limot[i].addLimot( this, info, row, ax[i], 0 ); } } void dJointSetLMotorAxis( dJointID j, int anum, int rel, dReal x, dReal y, dReal z ) { dxJointLMotor* joint = ( dxJointLMotor* )j; //for now we are ignoring rel! dAASSERT( joint && anum >= 0 && anum <= 2 && rel >= 0 && rel <= 2 ); checktype( joint, LMotor ); if ( anum < 0 ) anum = 0; if ( anum > 2 ) anum = 2; if ( !joint->node[1].body && rel == 2 ) rel = 1; //ref 1 joint->rel[anum] = rel; dVector3 r; r[0] = x; r[1] = y; r[2] = z; r[3] = 0; if ( rel > 0 ) { if ( rel == 1 ) { dMULTIPLY1_331( joint->axis[anum], joint->node[0].body->posr.R, r ); } else { //second body has to exists thanks to ref 1 line dMULTIPLY1_331( joint->axis[anum], joint->node[1].body->posr.R, r ); } } else { joint->axis[anum][0] = r[0]; joint->axis[anum][1] = r[1]; joint->axis[anum][2] = r[2]; } dNormalize3( joint->axis[anum] ); } void dJointSetLMotorNumAxes( dJointID j, int num ) { dxJointLMotor* joint = ( dxJointLMotor* )j; dAASSERT( joint && num >= 0 && num <= 3 ); checktype( joint, LMotor ); if ( num < 0 ) num = 0; if ( num > 3 ) num = 3; joint->num = num; } void dJointSetLMotorParam( dJointID j, int parameter, dReal value ) { dxJointLMotor* joint = ( dxJointLMotor* )j; dAASSERT( joint ); checktype( joint, LMotor ); int anum = parameter >> 8; if ( anum < 0 ) anum = 0; if ( anum > 2 ) anum = 2; parameter &= 0xff; joint->limot[anum].set( parameter, value ); } int dJointGetLMotorNumAxes( dJointID j ) { dxJointLMotor* joint = ( dxJointLMotor* )j; dAASSERT( joint ); checktype( joint, LMotor ); return joint->num; } void dJointGetLMotorAxis( dJointID j, int anum, dVector3 result ) { dxJointLMotor* joint = ( dxJointLMotor* )j; dAASSERT( joint && anum >= 0 && anum < 3 ); checktype( joint, LMotor ); if ( anum < 0 ) anum = 0; if ( anum > 2 ) anum = 2; result[0] = joint->axis[anum][0]; result[1] = joint->axis[anum][1]; result[2] = joint->axis[anum][2]; } dReal dJointGetLMotorParam( dJointID j, int parameter ) { dxJointLMotor* joint = ( dxJointLMotor* )j; dAASSERT( joint ); checktype( joint, LMotor ); int anum = parameter >> 8; if ( anum < 0 ) anum = 0; if ( anum > 2 ) anum = 2; parameter &= 0xff; return joint->limot[anum].get( parameter ); } dJointType dxJointLMotor::type() const { return dJointTypeLMotor; } size_t dxJointLMotor::size() const { return sizeof( *this ); } alien-arena-7.66+dfsg/source/unix/odesrc/joints/universal.h0000600000175000017500000000514712161402010023042 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_JOINT_UNIVERSAL_H_ #define _ODE_JOINT_UNIVERSAL_H_ #include "joint.h" // universal struct dxJointUniversal : public dxJoint { dVector3 anchor1; // anchor w.r.t first body dVector3 anchor2; // anchor w.r.t second body dVector3 axis1; // axis w.r.t first body dVector3 axis2; // axis w.r.t second body dQuaternion qrel1; // initial relative rotation body1 -> virtual cross piece dQuaternion qrel2; // initial relative rotation virtual cross piece -> body2 dxJointLimitMotor limot1; // limit and motor information for axis1 dxJointLimitMotor limot2; // limit and motor information for axis2 void getAxes( dVector3 ax1, dVector3 ax2 ); void getAngles( dReal *angle1, dReal *angle2 ); dReal getAngle1(); dReal getAngle2(); void computeInitialRelativeRotations(); dxJointUniversal( dxWorld *w ); virtual void getInfo1( Info1* info ); virtual void getInfo2( Info2* info ); virtual dJointType type() const; virtual size_t size() const; virtual void setRelativeValues(); }; #endif alien-arena-7.66+dfsg/source/unix/odesrc/joints/amotor.cpp0000600000175000017500000003515212161402010022665 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include "amotor.h" #include "joint_internal.h" //**************************************************************************** // angular motor dxJointAMotor::dxJointAMotor( dxWorld *w ) : dxJoint( w ) { int i; num = 0; mode = dAMotorUser; for ( i = 0; i < 3; i++ ) { rel[i] = 0; dSetZero( axis[i], 4 ); limot[i].init( world ); angle[i] = 0; } dSetZero( reference1, 4 ); dSetZero( reference2, 4 ); } // compute the 3 axes in global coordinates void dxJointAMotor::computeGlobalAxes( dVector3 ax[3] ) { if ( mode == dAMotorEuler ) { // special handling for euler mode dMULTIPLY0_331( ax[0], node[0].body->posr.R, axis[0] ); if ( node[1].body ) { dMULTIPLY0_331( ax[2], node[1].body->posr.R, axis[2] ); } else { ax[2][0] = axis[2][0]; ax[2][1] = axis[2][1]; ax[2][2] = axis[2][2]; } dCROSS( ax[1], = , ax[2], ax[0] ); dNormalize3( ax[1] ); } else { for ( int i = 0; i < num; i++ ) { if ( rel[i] == 1 ) { // relative to b1 dMULTIPLY0_331( ax[i], node[0].body->posr.R, axis[i] ); } else if ( rel[i] == 2 ) { // relative to b2 if ( node[1].body ) // jds: don't assert, just ignore { dMULTIPLY0_331( ax[i], node[1].body->posr.R, axis[i] ); } } else { // global - just copy it ax[i][0] = axis[i][0]; ax[i][1] = axis[i][1]; ax[i][2] = axis[i][2]; } } } } void dxJointAMotor::computeEulerAngles( dVector3 ax[3] ) { // assumptions: // global axes already calculated --> ax // axis[0] is relative to body 1 --> global ax[0] // axis[2] is relative to body 2 --> global ax[2] // ax[1] = ax[2] x ax[0] // original ax[0] and ax[2] are perpendicular // reference1 is perpendicular to ax[0] (in body 1 frame) // reference2 is perpendicular to ax[2] (in body 2 frame) // all ax[] and reference vectors are unit length // calculate references in global frame dVector3 ref1, ref2; dMULTIPLY0_331( ref1, node[0].body->posr.R, reference1 ); if ( node[1].body ) { dMULTIPLY0_331( ref2, node[1].body->posr.R, reference2 ); } else { ref2[0] = reference2[0]; ref2[1] = reference2[1]; ref2[2] = reference2[2]; } // get q perpendicular to both ax[0] and ref1, get first euler angle dVector3 q; dCROSS( q, = , ax[0], ref1 ); angle[0] = -dAtan2( dDOT( ax[2], q ), dDOT( ax[2], ref1 ) ); // get q perpendicular to both ax[0] and ax[1], get second euler angle dCROSS( q, = , ax[0], ax[1] ); angle[1] = -dAtan2( dDOT( ax[2], ax[0] ), dDOT( ax[2], q ) ); // get q perpendicular to both ax[1] and ax[2], get third euler angle dCROSS( q, = , ax[1], ax[2] ); angle[2] = -dAtan2( dDOT( ref2, ax[1] ), dDOT( ref2, q ) ); } // set the reference vectors as follows: // * reference1 = current axis[2] relative to body 1 // * reference2 = current axis[0] relative to body 2 // this assumes that: // * axis[0] is relative to body 1 // * axis[2] is relative to body 2 void dxJointAMotor::setEulerReferenceVectors() { if ( node[0].body && node[1].body ) { dVector3 r; // axis[2] and axis[0] in global coordinates dMULTIPLY0_331( r, node[1].body->posr.R, axis[2] ); dMULTIPLY1_331( reference1, node[0].body->posr.R, r ); dMULTIPLY0_331( r, node[0].body->posr.R, axis[0] ); dMULTIPLY1_331( reference2, node[1].body->posr.R, r ); } else // jds { // else if (j->node[0].body) { // dMULTIPLY1_331 (j->reference1,j->node[0].body->posr.R,j->axis[2]); // dMULTIPLY0_331 (j->reference2,j->node[0].body->posr.R,j->axis[0]); // We want to handle angular motors attached to passive geoms dVector3 r; // axis[2] and axis[0] in global coordinates r[0] = axis[2][0]; r[1] = axis[2][1]; r[2] = axis[2][2]; r[3] = axis[2][3]; dMULTIPLY1_331( reference1, node[0].body->posr.R, r ); dMULTIPLY0_331( r, node[0].body->posr.R, axis[0] ); reference2[0] += r[0]; reference2[1] += r[1]; reference2[2] += r[2]; reference2[3] += r[3]; } } void dxJointAMotor::getInfo1( dxJoint::Info1 *info ) { info->m = 0; info->nub = 0; // compute the axes and angles, if in euler mode if ( mode == dAMotorEuler ) { dVector3 ax[3]; computeGlobalAxes( ax ); computeEulerAngles( ax ); } // see if we're powered or at a joint limit for each axis for ( int i = 0; i < num; i++ ) { if ( limot[i].testRotationalLimit( angle[i] ) || limot[i].fmax > 0 ) { info->m++; } } } void dxJointAMotor::getInfo2( dxJoint::Info2 *info ) { int i; // compute the axes (if not global) dVector3 ax[3]; computeGlobalAxes( ax ); // in euler angle mode we do not actually constrain the angular velocity // along the axes axis[0] and axis[2] (although we do use axis[1]) : // // to get constrain w2-w1 along ...not // ------ --------------------- ------ // d(angle[0])/dt = 0 ax[1] x ax[2] ax[0] // d(angle[1])/dt = 0 ax[1] // d(angle[2])/dt = 0 ax[0] x ax[1] ax[2] // // constraining w2-w1 along an axis 'a' means that a'*(w2-w1)=0. // to prove the result for angle[0], write the expression for angle[0] from // GetInfo1 then take the derivative. to prove this for angle[2] it is // easier to take the euler rate expression for d(angle[2])/dt with respect // to the components of w and set that to 0. dVector3 *axptr[3]; axptr[0] = &ax[0]; axptr[1] = &ax[1]; axptr[2] = &ax[2]; dVector3 ax0_cross_ax1; dVector3 ax1_cross_ax2; if ( mode == dAMotorEuler ) { dCROSS( ax0_cross_ax1, = , ax[0], ax[1] ); axptr[2] = &ax0_cross_ax1; dCROSS( ax1_cross_ax2, = , ax[1], ax[2] ); axptr[0] = &ax1_cross_ax2; } int row = 0; for ( i = 0; i < num; i++ ) { row += limot[i].addLimot( this, info, row, *( axptr[i] ), 1 ); } } void dJointSetAMotorNumAxes( dJointID j, int num ) { dxJointAMotor* joint = ( dxJointAMotor* )j; dAASSERT( joint && num >= 0 && num <= 3 ); checktype( joint, AMotor ); if ( joint->mode == dAMotorEuler ) { joint->num = 3; } else { if ( num < 0 ) num = 0; if ( num > 3 ) num = 3; joint->num = num; } } void dJointSetAMotorAxis( dJointID j, int anum, int rel, dReal x, dReal y, dReal z ) { dxJointAMotor* joint = ( dxJointAMotor* )j; dAASSERT( joint && anum >= 0 && anum <= 2 && rel >= 0 && rel <= 2 ); checktype( joint, AMotor ); dUASSERT( !( !joint->node[1].body && ( joint->flags & dJOINT_REVERSE ) && rel == 1 ), "no first body, can't set axis rel=1" ); dUASSERT( !( !joint->node[1].body && !( joint->flags & dJOINT_REVERSE ) && rel == 2 ), "no second body, can't set axis rel=2" ); if ( anum < 0 ) anum = 0; if ( anum > 2 ) anum = 2; // adjust rel to match the internal body order if ( !joint->node[1].body && rel == 2 ) rel = 1; joint->rel[anum] = rel; // x,y,z is always in global coordinates regardless of rel, so we may have // to convert it to be relative to a body dVector3 r; r[0] = x; r[1] = y; r[2] = z; r[3] = 0; if ( rel > 0 ) { if ( rel == 1 ) { dMULTIPLY1_331( joint->axis[anum], joint->node[0].body->posr.R, r ); } else { // don't assert; handle the case of attachment to a bodiless geom if ( joint->node[1].body ) // jds { dMULTIPLY1_331( joint->axis[anum], joint->node[1].body->posr.R, r ); } else { joint->axis[anum][0] = r[0]; joint->axis[anum][1] = r[1]; joint->axis[anum][2] = r[2]; joint->axis[anum][3] = r[3]; } } } else { joint->axis[anum][0] = r[0]; joint->axis[anum][1] = r[1]; joint->axis[anum][2] = r[2]; } dNormalize3( joint->axis[anum] ); if ( joint->mode == dAMotorEuler ) joint->setEulerReferenceVectors(); } void dJointSetAMotorAngle( dJointID j, int anum, dReal angle ) { dxJointAMotor* joint = ( dxJointAMotor* )j; dAASSERT( joint && anum >= 0 && anum < 3 ); checktype( joint, AMotor ); if ( joint->mode == dAMotorUser ) { if ( anum < 0 ) anum = 0; if ( anum > 3 ) anum = 3; joint->angle[anum] = angle; } } void dJointSetAMotorParam( dJointID j, int parameter, dReal value ) { dxJointAMotor* joint = ( dxJointAMotor* )j; dAASSERT( joint ); checktype( joint, AMotor ); int anum = parameter >> 8; if ( anum < 0 ) anum = 0; if ( anum > 2 ) anum = 2; parameter &= 0xff; joint->limot[anum].set( parameter, value ); } void dJointSetAMotorMode( dJointID j, int mode ) { dxJointAMotor* joint = ( dxJointAMotor* )j; dAASSERT( joint ); checktype( joint, AMotor ); joint->mode = mode; if ( joint->mode == dAMotorEuler ) { joint->num = 3; joint->setEulerReferenceVectors(); } } int dJointGetAMotorNumAxes( dJointID j ) { dxJointAMotor* joint = ( dxJointAMotor* )j; dAASSERT( joint ); checktype( joint, AMotor ); return joint->num; } void dJointGetAMotorAxis( dJointID j, int anum, dVector3 result ) { dxJointAMotor* joint = ( dxJointAMotor* )j; dAASSERT( joint && anum >= 0 && anum < 3 ); checktype( joint, AMotor ); if ( anum < 0 ) anum = 0; if ( anum > 2 ) anum = 2; if ( joint->rel[anum] > 0 ) { if ( joint->rel[anum] == 1 ) { dMULTIPLY0_331( result, joint->node[0].body->posr.R, joint->axis[anum] ); } else { if ( joint->node[1].body ) // jds { dMULTIPLY0_331( result, joint->node[1].body->posr.R, joint->axis[anum] ); } else { result[0] = joint->axis[anum][0]; result[1] = joint->axis[anum][1]; result[2] = joint->axis[anum][2]; result[3] = joint->axis[anum][3]; } } } else { result[0] = joint->axis[anum][0]; result[1] = joint->axis[anum][1]; result[2] = joint->axis[anum][2]; } } int dJointGetAMotorAxisRel( dJointID j, int anum ) { dxJointAMotor* joint = ( dxJointAMotor* )j; dAASSERT( joint && anum >= 0 && anum < 3 ); checktype( joint, AMotor ); if ( anum < 0 ) anum = 0; if ( anum > 2 ) anum = 2; return joint->rel[anum]; } dReal dJointGetAMotorAngle( dJointID j, int anum ) { dxJointAMotor* joint = ( dxJointAMotor* )j; dAASSERT( joint && anum >= 0 && anum < 3 ); checktype( joint, AMotor ); if ( anum < 0 ) anum = 0; if ( anum > 3 ) anum = 3; return joint->angle[anum]; } dReal dJointGetAMotorAngleRate( dJointID j, int anum ) { //dxJointAMotor* joint = (dxJointAMotor*)j; // @@@ dDebug( 0, "not yet implemented" ); return 0; } dReal dJointGetAMotorParam( dJointID j, int parameter ) { dxJointAMotor* joint = ( dxJointAMotor* )j; dAASSERT( joint ); checktype( joint, AMotor ); int anum = parameter >> 8; if ( anum < 0 ) anum = 0; if ( anum > 2 ) anum = 2; parameter &= 0xff; return joint->limot[anum].get( parameter ); } int dJointGetAMotorMode( dJointID j ) { dxJointAMotor* joint = ( dxJointAMotor* )j; dAASSERT( joint ); checktype( joint, AMotor ); return joint->mode; } void dJointAddAMotorTorques( dJointID j, dReal torque1, dReal torque2, dReal torque3 ) { dxJointAMotor* joint = ( dxJointAMotor* )j; dVector3 axes[3]; dAASSERT( joint ); checktype( joint, AMotor ); if ( joint->num == 0 ) return; dUASSERT(( joint->flags & dJOINT_REVERSE ) == 0, "dJointAddAMotorTorques not yet implemented for reverse AMotor joints" ); joint->computeGlobalAxes( axes ); axes[0][0] *= torque1; axes[0][1] *= torque1; axes[0][2] *= torque1; if ( joint->num >= 2 ) { axes[0][0] += axes[1][0] * torque2; axes[0][1] += axes[1][1] * torque2; axes[0][2] += axes[1][2] * torque2; if ( joint->num >= 3 ) { axes[0][0] += axes[2][0] * torque3; axes[0][1] += axes[2][1] * torque3; axes[0][2] += axes[2][2] * torque3; } } if ( joint->node[0].body != 0 ) dBodyAddTorque( joint->node[0].body, axes[0][0], axes[0][1], axes[0][2] ); if ( joint->node[1].body != 0 ) dBodyAddTorque( joint->node[1].body, -axes[0][0], -axes[0][1], -axes[0][2] ); } dJointType dxJointAMotor::type() const { return dJointTypeAMotor; } size_t dxJointAMotor::size() const { return sizeof( *this ); } alien-arena-7.66+dfsg/source/unix/odesrc/mass.cpp0000600000175000017500000003360412161402010021021 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include #include "config.h" #include #include #include // Local dependencies #include "collision_kernel.h" #if dTRIMESH_ENABLED #include "collision_trimesh_internal.h" #endif // dTRIMESH_ENABLED #define SQR(x) ((x)*(x)) //!< Returns x square #define CUBE(x) ((x)*(x)*(x)) //!< Returns x cube #define _I(i,j) I[(i)*4+(j)] // return 1 if ok, 0 if bad int dMassCheck (const dMass *m) { int i; if (m->mass <= 0) { dDEBUGMSG ("mass must be > 0"); return 0; } if (!dIsPositiveDefinite (m->I,3)) { dDEBUGMSG ("inertia must be positive definite"); return 0; } // verify that the center of mass position is consistent with the mass // and inertia matrix. this is done by checking that the inertia around // the center of mass is also positive definite. from the comment in // dMassTranslate(), if the body is translated so that its center of mass // is at the point of reference, then the new inertia is: // I + mass*crossmat(c)^2 // note that requiring this to be positive definite is exactly equivalent // to requiring that the spatial inertia matrix // [ mass*eye(3,3) M*crossmat(c)^T ] // [ M*crossmat(c) I ] // is positive definite, given that I is PD and mass>0. see the theorem // about partitioned PD matrices for proof. dMatrix3 I2,chat; dSetZero (chat,12); dCROSSMAT (chat,m->c,4,+,-); dMULTIPLY0_333 (I2,chat,chat); for (i=0; i<3; i++) I2[i] = m->I[i] + m->mass*I2[i]; for (i=4; i<7; i++) I2[i] = m->I[i] + m->mass*I2[i]; for (i=8; i<11; i++) I2[i] = m->I[i] + m->mass*I2[i]; if (!dIsPositiveDefinite (I2,3)) { dDEBUGMSG ("center of mass inconsistent with mass parameters"); return 0; } return 1; } void dMassSetZero (dMass *m) { dAASSERT (m); m->mass = REAL(0.0); dSetZero (m->c,sizeof(m->c) / sizeof(dReal)); dSetZero (m->I,sizeof(m->I) / sizeof(dReal)); } void dMassSetParameters (dMass *m, dReal themass, dReal cgx, dReal cgy, dReal cgz, dReal I11, dReal I22, dReal I33, dReal I12, dReal I13, dReal I23) { dAASSERT (m); dMassSetZero (m); m->mass = themass; m->c[0] = cgx; m->c[1] = cgy; m->c[2] = cgz; m->_I(0,0) = I11; m->_I(1,1) = I22; m->_I(2,2) = I33; m->_I(0,1) = I12; m->_I(0,2) = I13; m->_I(1,2) = I23; m->_I(1,0) = I12; m->_I(2,0) = I13; m->_I(2,1) = I23; dMassCheck (m); } void dMassSetSphere (dMass *m, dReal density, dReal radius) { dMassSetSphereTotal (m, (dReal) ((REAL(4.0)/REAL(3.0)) * M_PI * radius*radius*radius * density), radius); } void dMassSetSphereTotal (dMass *m, dReal total_mass, dReal radius) { dAASSERT (m); dMassSetZero (m); m->mass = total_mass; dReal II = REAL(0.4) * total_mass * radius*radius; m->_I(0,0) = II; m->_I(1,1) = II; m->_I(2,2) = II; # ifndef dNODEBUG dMassCheck (m); # endif } void dMassSetCapsule (dMass *m, dReal density, int direction, dReal radius, dReal length) { dReal M1,M2,Ia,Ib; dAASSERT (m); dUASSERT (direction >= 1 && direction <= 3,"bad direction number"); dMassSetZero (m); M1 = (dReal) (M_PI*radius*radius*length*density); // cylinder mass M2 = (dReal) ((REAL(4.0)/REAL(3.0))*M_PI*radius*radius*radius*density); // total cap mass m->mass = M1+M2; Ia = M1*(REAL(0.25)*radius*radius + (REAL(1.0)/REAL(12.0))*length*length) + M2*(REAL(0.4)*radius*radius + REAL(0.375)*radius*length + REAL(0.25)*length*length); Ib = (M1*REAL(0.5) + M2*REAL(0.4))*radius*radius; m->_I(0,0) = Ia; m->_I(1,1) = Ia; m->_I(2,2) = Ia; m->_I(direction-1,direction-1) = Ib; # ifndef dNODEBUG dMassCheck (m); # endif } void dMassSetCapsuleTotal (dMass *m, dReal total_mass, int direction, dReal a, dReal b) { dMassSetCapsule (m, 1.0, direction, a, b); dMassAdjust (m, total_mass); } void dMassSetCylinder (dMass *m, dReal density, int direction, dReal radius, dReal length) { dMassSetCylinderTotal (m, (dReal) (M_PI*radius*radius*length*density), direction, radius, length); } void dMassSetCylinderTotal (dMass *m, dReal total_mass, int direction, dReal radius, dReal length) { dReal r2,I; dAASSERT (m); dUASSERT (direction >= 1 && direction <= 3,"bad direction number"); dMassSetZero (m); r2 = radius*radius; m->mass = total_mass; I = total_mass*(REAL(0.25)*r2 + (REAL(1.0)/REAL(12.0))*length*length); m->_I(0,0) = I; m->_I(1,1) = I; m->_I(2,2) = I; m->_I(direction-1,direction-1) = total_mass*REAL(0.5)*r2; # ifndef dNODEBUG dMassCheck (m); # endif } void dMassSetBox (dMass *m, dReal density, dReal lx, dReal ly, dReal lz) { dMassSetBoxTotal (m, lx*ly*lz*density, lx, ly, lz); } void dMassSetBoxTotal (dMass *m, dReal total_mass, dReal lx, dReal ly, dReal lz) { dAASSERT (m); dMassSetZero (m); m->mass = total_mass; m->_I(0,0) = total_mass/REAL(12.0) * (ly*ly + lz*lz); m->_I(1,1) = total_mass/REAL(12.0) * (lx*lx + lz*lz); m->_I(2,2) = total_mass/REAL(12.0) * (lx*lx + ly*ly); # ifndef dNODEBUG dMassCheck (m); # endif } /* * dMassSetTrimesh, implementation by Gero Mueller. * Based on Brian Mirtich, "Fast and Accurate Computation of * Polyhedral Mass Properties," journal of graphics tools, volume 1, * number 2, 1996. */ void dMassSetTrimesh( dMass *m, dReal density, dGeomID g ) { dAASSERT (m); dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); dMassSetZero (m); #if dTRIMESH_ENABLED dxTriMesh *TriMesh = (dxTriMesh *)g; unsigned int triangles = FetchTriangleCount( TriMesh ); dReal nx, ny, nz; unsigned int i, A, B, C; // face integrals dReal Fa, Fb, Fc, Faa, Fbb, Fcc, Faaa, Fbbb, Fccc, Faab, Fbbc, Fcca; // projection integrals dReal P1, Pa, Pb, Paa, Pab, Pbb, Paaa, Paab, Pabb, Pbbb; dReal T0 = 0; dReal T1[3] = {0., 0., 0.}; dReal T2[3] = {0., 0., 0.}; dReal TP[3] = {0., 0., 0.}; for( i = 0; i < triangles; i++ ) { dVector3 v[3]; FetchTransformedTriangle( TriMesh, i, v); dVector3 n, a, b; dOP( a, -, v[1], v[0] ); dOP( b, -, v[2], v[0] ); dCROSS( n, =, b, a ); nx = fabs(n[0]); ny = fabs(n[1]); nz = fabs(n[2]); if( nx > ny && nx > nz ) C = 0; else C = (ny > nz) ? 1 : 2; // Even though all triangles might be initially valid, // a triangle may degenerate into a segment after applying // space transformation. if (n[C] != REAL(0.0)) { A = (C + 1) % 3; B = (A + 1) % 3; // calculate face integrals { dReal w; dReal k1, k2, k3, k4; //compProjectionIntegrals(f); { dReal a0=0, a1=0, da; dReal b0=0, b1=0, db; dReal a0_2, a0_3, a0_4, b0_2, b0_3, b0_4; dReal a1_2, a1_3, b1_2, b1_3; dReal C1, Ca, Caa, Caaa, Cb, Cbb, Cbbb; dReal Cab, Kab, Caab, Kaab, Cabb, Kabb; P1 = Pa = Pb = Paa = Pab = Pbb = Paaa = Paab = Pabb = Pbbb = 0.0; for( int j = 0; j < 3; j++) { switch(j) { case 0: a0 = v[0][A]; b0 = v[0][B]; a1 = v[1][A]; b1 = v[1][B]; break; case 1: a0 = v[1][A]; b0 = v[1][B]; a1 = v[2][A]; b1 = v[2][B]; break; case 2: a0 = v[2][A]; b0 = v[2][B]; a1 = v[0][A]; b1 = v[0][B]; break; } da = a1 - a0; db = b1 - b0; a0_2 = a0 * a0; a0_3 = a0_2 * a0; a0_4 = a0_3 * a0; b0_2 = b0 * b0; b0_3 = b0_2 * b0; b0_4 = b0_3 * b0; a1_2 = a1 * a1; a1_3 = a1_2 * a1; b1_2 = b1 * b1; b1_3 = b1_2 * b1; C1 = a1 + a0; Ca = a1*C1 + a0_2; Caa = a1*Ca + a0_3; Caaa = a1*Caa + a0_4; Cb = b1*(b1 + b0) + b0_2; Cbb = b1*Cb + b0_3; Cbbb = b1*Cbb + b0_4; Cab = 3*a1_2 + 2*a1*a0 + a0_2; Kab = a1_2 + 2*a1*a0 + 3*a0_2; Caab = a0*Cab + 4*a1_3; Kaab = a1*Kab + 4*a0_3; Cabb = 4*b1_3 + 3*b1_2*b0 + 2*b1*b0_2 + b0_3; Kabb = b1_3 + 2*b1_2*b0 + 3*b1*b0_2 + 4*b0_3; P1 += db*C1; Pa += db*Ca; Paa += db*Caa; Paaa += db*Caaa; Pb += da*Cb; Pbb += da*Cbb; Pbbb += da*Cbbb; Pab += db*(b1*Cab + b0*Kab); Paab += db*(b1*Caab + b0*Kaab); Pabb += da*(a1*Cabb + a0*Kabb); } P1 /= 2.0; Pa /= 6.0; Paa /= 12.0; Paaa /= 20.0; Pb /= -6.0; Pbb /= -12.0; Pbbb /= -20.0; Pab /= 24.0; Paab /= 60.0; Pabb /= -60.0; } w = - dDOT(n, v[0]); k1 = 1 / n[C]; k2 = k1 * k1; k3 = k2 * k1; k4 = k3 * k1; Fa = k1 * Pa; Fb = k1 * Pb; Fc = -k2 * (n[A]*Pa + n[B]*Pb + w*P1); Faa = k1 * Paa; Fbb = k1 * Pbb; Fcc = k3 * (SQR(n[A])*Paa + 2*n[A]*n[B]*Pab + SQR(n[B])*Pbb + w*(2*(n[A]*Pa + n[B]*Pb) + w*P1)); Faaa = k1 * Paaa; Fbbb = k1 * Pbbb; Fccc = -k4 * (CUBE(n[A])*Paaa + 3*SQR(n[A])*n[B]*Paab + 3*n[A]*SQR(n[B])*Pabb + CUBE(n[B])*Pbbb + 3*w*(SQR(n[A])*Paa + 2*n[A]*n[B]*Pab + SQR(n[B])*Pbb) + w*w*(3*(n[A]*Pa + n[B]*Pb) + w*P1)); Faab = k1 * Paab; Fbbc = -k2 * (n[A]*Pabb + n[B]*Pbbb + w*Pbb); Fcca = k3 * (SQR(n[A])*Paaa + 2*n[A]*n[B]*Paab + SQR(n[B])*Pabb + w*(2*(n[A]*Paa + n[B]*Pab) + w*Pa)); } T0 += n[0] * ((A == 0) ? Fa : ((B == 0) ? Fb : Fc)); T1[A] += n[A] * Faa; T1[B] += n[B] * Fbb; T1[C] += n[C] * Fcc; T2[A] += n[A] * Faaa; T2[B] += n[B] * Fbbb; T2[C] += n[C] * Fccc; TP[A] += n[A] * Faab; TP[B] += n[B] * Fbbc; TP[C] += n[C] * Fcca; } } T1[0] /= 2; T1[1] /= 2; T1[2] /= 2; T2[0] /= 3; T2[1] /= 3; T2[2] /= 3; TP[0] /= 2; TP[1] /= 2; TP[2] /= 2; m->mass = density * T0; m->_I(0,0) = density * (T2[1] + T2[2]); m->_I(1,1) = density * (T2[2] + T2[0]); m->_I(2,2) = density * (T2[0] + T2[1]); m->_I(0,1) = - density * TP[0]; m->_I(1,0) = - density * TP[0]; m->_I(2,1) = - density * TP[1]; m->_I(1,2) = - density * TP[1]; m->_I(2,0) = - density * TP[2]; m->_I(0,2) = - density * TP[2]; // Added to address SF bug 1729095 dMassTranslate( m, T1[0] / T0, T1[1] / T0, T1[2] / T0 ); # ifndef dNODEBUG dMassCheck (m); # endif #endif // dTRIMESH_ENABLED } void dMassSetTrimeshTotal( dMass *m, dReal total_mass, dGeomID g) { dAASSERT( m ); dUASSERT( g && g->type == dTriMeshClass, "argument not a trimesh" ); dMassSetTrimesh( m, 1.0, g ); dMassAdjust( m, total_mass ); } void dMassAdjust (dMass *m, dReal newmass) { dAASSERT (m); dReal scale = newmass / m->mass; m->mass = newmass; for (int i=0; i<3; i++) for (int j=0; j<3; j++) m->_I(i,j) *= scale; # ifndef dNODEBUG dMassCheck (m); # endif } void dMassTranslate (dMass *m, dReal x, dReal y, dReal z) { // if the body is translated by `a' relative to its point of reference, // the new inertia about the point of reference is: // // I + mass*(crossmat(c)^2 - crossmat(c+a)^2) // // where c is the existing center of mass and I is the old inertia. int i,j; dMatrix3 ahat,chat,t1,t2; dReal a[3]; dAASSERT (m); // adjust inertia matrix dSetZero (chat,12); dCROSSMAT (chat,m->c,4,+,-); a[0] = x + m->c[0]; a[1] = y + m->c[1]; a[2] = z + m->c[2]; dSetZero (ahat,12); dCROSSMAT (ahat,a,4,+,-); dMULTIPLY0_333 (t1,ahat,ahat); dMULTIPLY0_333 (t2,chat,chat); for (i=0; i<3; i++) for (j=0; j<3; j++) m->_I(i,j) += m->mass * (t2[i*4+j]-t1[i*4+j]); // ensure perfect symmetry m->_I(1,0) = m->_I(0,1); m->_I(2,0) = m->_I(0,2); m->_I(2,1) = m->_I(1,2); // adjust center of mass m->c[0] += x; m->c[1] += y; m->c[2] += z; # ifndef dNODEBUG dMassCheck (m); # endif } void dMassRotate (dMass *m, const dMatrix3 R) { // if the body is rotated by `R' relative to its point of reference, // the new inertia about the point of reference is: // // R * I * R' // // where I is the old inertia. dMatrix3 t1; dReal t2[3]; dAASSERT (m); // rotate inertia matrix dMULTIPLY2_333 (t1,m->I,R); dMULTIPLY0_333 (m->I,R,t1); // ensure perfect symmetry m->_I(1,0) = m->_I(0,1); m->_I(2,0) = m->_I(0,2); m->_I(2,1) = m->_I(1,2); // rotate center of mass dMULTIPLY0_331 (t2,R,m->c); m->c[0] = t2[0]; m->c[1] = t2[1]; m->c[2] = t2[2]; # ifndef dNODEBUG dMassCheck (m); # endif } void dMassAdd (dMass *a, const dMass *b) { int i; dAASSERT (a && b); dReal denom = dRecip (a->mass + b->mass); for (i=0; i<3; i++) a->c[i] = (a->c[i]*a->mass + b->c[i]*b->mass)*denom; a->mass += b->mass; for (i=0; i<12; i++) a->I[i] += b->I[i]; } // Backwards compatible API void dMassSetCappedCylinder(dMass *a, dReal b, int c, dReal d, dReal e) { dMassSetCapsule(a,b,c,d,e); } void dMassSetCappedCylinderTotal(dMass *a, dReal b, int c, dReal d, dReal e) { dMassSetCapsuleTotal(a,b,c,d,e); } alien-arena-7.66+dfsg/source/unix/odesrc/collision_kernel.h0000600000175000017500000002202412161402010023050 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* internal data structures and functions for collision detection. */ #ifndef _ODE_COLLISION_KERNEL_H_ #define _ODE_COLLISION_KERNEL_H_ #include #include #include #include "config.h" #include "objects.h" #include "odetls.h" //**************************************************************************** // constants and macros // mask for the number-of-contacts field in the dCollide() flags parameter #define NUMC_MASK (0xffff) #define IS_SPACE(geom) \ ((geom)->type >= dFirstSpaceClass && (geom)->type <= dLastSpaceClass) //**************************************************************************** // geometry object base class // geom flags. // // GEOM_DIRTY means that the space data structures for this geom are // potentially not up to date. NOTE THAT all space parents of a dirty geom // are themselves dirty. this is an invariant that must be enforced. // // GEOM_AABB_BAD means that the cached AABB for this geom is not up to date. // note that GEOM_DIRTY does not imply GEOM_AABB_BAD, as the geom might // recalculate its own AABB but does not know how to update the space data // structures for the space it is in. but GEOM_AABB_BAD implies GEOM_DIRTY. // the valid combinations are: // 0 // GEOM_DIRTY // GEOM_DIRTY|GEOM_AABB_BAD // GEOM_DIRTY|GEOM_AABB_BAD|GEOM_POSR_BAD enum { GEOM_DIRTY = 1, // geom is 'dirty', i.e. position unknown GEOM_POSR_BAD = 2, // geom's final posr is not valid GEOM_AABB_BAD = 4, // geom's AABB is not valid GEOM_PLACEABLE = 8, // geom is placeable GEOM_ENABLED = 16, // geom is enabled GEOM_ZERO_SIZED = 32, // geom is zero sized GEOM_ENABLE_TEST_MASK = GEOM_ENABLED | GEOM_ZERO_SIZED, GEOM_ENABLE_TEST_VALUE = GEOM_ENABLED, // Ray specific RAY_FIRSTCONTACT = 0x10000, RAY_BACKFACECULL = 0x20000, RAY_CLOSEST_HIT = 0x40000 }; // geometry object base class. pos and R will either point to a separately // allocated buffer (if body is 0 - pos points to the dxPosR object) or to // the pos and R of the body (if body nonzero). // a dGeomID is a pointer to this object. struct dxGeom : public dBase { int type; // geom type number, set by subclass constructor int gflags; // flags used by geom and space void *data; // user-defined data pointer dBodyID body; // dynamics body associated with this object (if any) dxGeom *body_next; // next geom in body's linked list of associated geoms dxPosR *final_posr; // final position of the geom in world coordinates dxPosR *offset_posr; // offset from body in local coordinates // information used by spaces dxGeom *next; // next geom in linked list of geoms dxGeom **tome; // linked list backpointer dxSpace *parent_space;// the space this geom is contained in, 0 if none dReal aabb[6]; // cached AABB for this space unsigned long category_bits,collide_bits; dxGeom (dSpaceID _space, int is_placeable); virtual ~dxGeom(); // Set or clear GEOM_ZERO_SIZED flag void updateZeroSizedFlag(bool is_zero_sized) { gflags = is_zero_sized ? (gflags | GEOM_ZERO_SIZED) : (gflags & ~GEOM_ZERO_SIZED); } // Get parent space TLS kind unsigned getParentSpaceTLSKind() const; // calculate our new final position from our offset and body void computePosr(); // recalculate our new final position if needed void recomputePosr() { if (gflags & GEOM_POSR_BAD) { computePosr(); gflags &= ~GEOM_POSR_BAD; } } virtual void computeAABB()=0; // compute the AABB for this object and put it in aabb. this function // always performs a fresh computation, it does not inspect the // GEOM_AABB_BAD flag. virtual int AABBTest (dxGeom *o, dReal aabb[6]); // test whether the given AABB object intersects with this object, return // 1=yes, 0=no. this is used as an early-exit test in the space collision // functions. the default implementation returns 1, which is the correct // behavior if no more detailed implementation can be provided. // utility functions // compute the AABB only if it is not current. this function manipulates // the GEOM_AABB_BAD flag. void recomputeAABB() { if (gflags & GEOM_AABB_BAD) { // our aabb functions assume final_posr is up to date recomputePosr(); computeAABB(); gflags &= ~GEOM_AABB_BAD; } } // add and remove this geom from a linked list maintained by a space. void spaceAdd (dxGeom **first_ptr) { next = *first_ptr; tome = first_ptr; if (*first_ptr) (*first_ptr)->tome = &next; *first_ptr = this; } void spaceRemove() { if (next) next->tome = tome; *tome = next; } // add and remove this geom from a linked list maintained by a body. void bodyAdd (dxBody *b) { body = b; body_next = b->geom; b->geom = this; } void bodyRemove(); }; //**************************************************************************** // the base space class // // the contained geoms are divided into two kinds: clean and dirty. // the clean geoms have not moved since they were put in the list, // and their AABBs are valid. the dirty geoms have changed position, and // their AABBs are may not be valid. the two types are distinguished by the // GEOM_DIRTY flag. all dirty geoms come *before* all clean geoms in the list. #if dTLS_ENABLED #define dSPACE_TLS_KIND_INIT_VALUE OTK__DEFAULT #define dSPACE_TLS_KIND_MANUAL_VALUE OTK_MANUALCLEANUP #else #define dSPACE_TLS_KIND_INIT_VALUE 0 #define dSPACE_TLS_KIND_MANUAL_VALUE 0 #endif struct dxSpace : public dxGeom { int count; // number of geoms in this space dxGeom *first; // first geom in list int cleanup; // cleanup mode, 1=destroy geoms on exit int sublevel; // space sublevel (used in dSpaceCollide2). NOT TRACKED AUTOMATICALLY!!! unsigned tls_kind; // space TLS kind to be used for global caches retrieval // cached state for getGeom() int current_index; // only valid if current_geom != 0 dxGeom *current_geom; // if 0 then there is no information // locking stuff. the space is locked when it is currently traversing its // internal data structures, e.g. in collide() and collide2(). operations // that modify the contents of the space are not permitted when the space // is locked. int lock_count; dxSpace (dSpaceID _space); ~dxSpace(); void computeAABB(); void setCleanup (int mode) { cleanup = (mode != 0); } int getCleanup() const { return cleanup; } void setSublevel(int value) { sublevel = value; } int getSublevel() const { return sublevel; } void setManulCleanup(int value) { tls_kind = (value ? dSPACE_TLS_KIND_MANUAL_VALUE : dSPACE_TLS_KIND_INIT_VALUE); } int getManualCleanup() const { return (tls_kind == dSPACE_TLS_KIND_MANUAL_VALUE) ? 1 : 0; } int query (dxGeom *geom) const { dAASSERT(geom); return (geom->parent_space == this); } int getNumGeoms() const { return count; } virtual dxGeom *getGeom (int i); virtual void add (dxGeom *); virtual void remove (dxGeom *); virtual void dirty (dxGeom *); virtual void cleanGeoms()=0; // turn all dirty geoms into clean geoms by computing their AABBs and any // other space data structures that are required. this should clear the // GEOM_DIRTY and GEOM_AABB_BAD flags of all geoms. virtual void collide (void *data, dNearCallback *callback)=0; virtual void collide2 (void *data, dxGeom *geom, dNearCallback *callback)=0; }; //**************************************************************************** // Initialization and finalization functions void dInitColliders(); void dFinitColliders(); void dClearPosrCache(void); void dFinitUserClasses(); #endif alien-arena-7.66+dfsg/source/unix/odesrc/collision_trimesh_opcode.cpp0000600000175000017500000005547612161402010025150 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ // TriMesh code by Erwin de Vries. #include #include #include #include #include "collision_util.h" #include "collision_trimesh_internal.h" #if dTRIMESH_ENABLED #if dTRIMESH_OPCODE void TrimeshCollidersCache::InitOPCODECaches() { _RayCollider.SetDestination(&Faces); /* -- not used _PlanesCollider.SetTemporalCoherence(true); */ _SphereCollider.SetTemporalCoherence(true); _SphereCollider.SetPrimitiveTests(false); _OBBCollider.SetTemporalCoherence(true); // no first-contact test (i.e. return full contact info) _AABBTreeCollider.SetFirstContact( false ); // temporal coherence only works with "first contact" tests _AABBTreeCollider.SetTemporalCoherence(false); // Perform full BV-BV tests (true) or SAT-lite tests (false) _AABBTreeCollider.SetFullBoxBoxTest( true ); // Perform full Primitive-BV tests (true) or SAT-lite tests (false) _AABBTreeCollider.SetFullPrimBoxTest( true ); const char* msg; if ((msg =_AABBTreeCollider.ValidateSettings())) dDebug (d_ERR_UASSERT, msg, " (%s:%d)", __FILE__,__LINE__); /* -- not used _LSSCollider.SetTemporalCoherence(false); _LSSCollider.SetPrimitiveTests(false); _LSSCollider.SetFirstContact(false); */ } // Trimesh data dxTriMeshData::dxTriMeshData() : UseFlags( NULL ) { #if !dTRIMESH_ENABLED dUASSERT(false, "dTRIMESH_ENABLED is not defined. Trimesh geoms will not work"); #endif } dxTriMeshData::~dxTriMeshData() { if ( UseFlags ) delete [] UseFlags; } void dxTriMeshData::Build(const void* Vertices, int VertexStide, int VertexCount, const void* Indices, int IndexCount, int TriStride, const void* in_Normals, bool Single) { #if dTRIMESH_ENABLED Mesh.SetNbTriangles(IndexCount / 3); Mesh.SetNbVertices(VertexCount); Mesh.SetPointers((IndexedTriangle*)Indices, (Point*)Vertices); Mesh.SetStrides(TriStride, VertexStide); Mesh.SetSingle(Single); // Build tree BuildSettings Settings; // recommended in Opcode User Manual //Settings.mRules = SPLIT_COMPLETE | SPLIT_SPLATTERPOINTS | SPLIT_GEOMCENTER; // used in ODE, why? //Settings.mRules = SPLIT_BEST_AXIS; // best compromise? Settings.mRules = SPLIT_BEST_AXIS | SPLIT_SPLATTER_POINTS | SPLIT_GEOM_CENTER; OPCODECREATE TreeBuilder; TreeBuilder.mIMesh = &Mesh; TreeBuilder.mSettings = Settings; TreeBuilder.mNoLeaf = true; TreeBuilder.mQuantized = false; TreeBuilder.mKeepOriginal = false; TreeBuilder.mCanRemap = false; BVTree.Build(TreeBuilder); // compute model space AABB dVector3 AABBMax, AABBMin; AABBMax[0] = AABBMax[1] = AABBMax[2] = (dReal) -dInfinity; AABBMin[0] = AABBMin[1] = AABBMin[2] = (dReal) dInfinity; if( Single ) { const char* verts = (const char*)Vertices; for( int i = 0; i < VertexCount; ++i ) { const float* v = (const float*)verts; if( v[0] > AABBMax[0] ) AABBMax[0] = v[0]; if( v[1] > AABBMax[1] ) AABBMax[1] = v[1]; if( v[2] > AABBMax[2] ) AABBMax[2] = v[2]; if( v[0] < AABBMin[0] ) AABBMin[0] = v[0]; if( v[1] < AABBMin[1] ) AABBMin[1] = v[1]; if( v[2] < AABBMin[2] ) AABBMin[2] = v[2]; verts += VertexStide; } } else { const char* verts = (const char*)Vertices; for( int i = 0; i < VertexCount; ++i ) { const double* v = (const double*)verts; if( v[0] > AABBMax[0] ) AABBMax[0] = (dReal) v[0]; if( v[1] > AABBMax[1] ) AABBMax[1] = (dReal) v[1]; if( v[2] > AABBMax[2] ) AABBMax[2] = (dReal) v[2]; if( v[0] < AABBMin[0] ) AABBMin[0] = (dReal) v[0]; if( v[1] < AABBMin[1] ) AABBMin[1] = (dReal) v[1]; if( v[2] < AABBMin[2] ) AABBMin[2] = (dReal) v[2]; verts += VertexStide; } } AABBCenter[0] = (AABBMin[0] + AABBMax[0]) * REAL(0.5); AABBCenter[1] = (AABBMin[1] + AABBMax[1]) * REAL(0.5); AABBCenter[2] = (AABBMin[2] + AABBMax[2]) * REAL(0.5); AABBExtents[0] = AABBMax[0] - AABBCenter[0]; AABBExtents[1] = AABBMax[1] - AABBCenter[1]; AABBExtents[2] = AABBMax[2] - AABBCenter[2]; // user data (not used by OPCODE) Normals = (dReal *) in_Normals; UseFlags = 0; #endif // dTRIMESH_ENABLED } struct EdgeRecord { int VertIdx1; // Index into vertex array for this edges vertices int VertIdx2; int TriIdx; // Index into triangle array for triangle this edge belongs to uint8 EdgeFlags; uint8 Vert1Flags; uint8 Vert2Flags; bool Concave; }; // Edge comparison function for qsort static int EdgeCompare(const void* edge1, const void* edge2) { EdgeRecord* e1 = (EdgeRecord*)edge1; EdgeRecord* e2 = (EdgeRecord*)edge2; if (e1->VertIdx1 == e2->VertIdx1) return e1->VertIdx2 - e2->VertIdx2; else return e1->VertIdx1 - e2->VertIdx1; } void SetupEdge(EdgeRecord* edge, int edgeIdx, int triIdx, const dTriIndex* vertIdxs) { if (edgeIdx == 0) { edge->EdgeFlags = dxTriMeshData::kEdge0; edge->Vert1Flags = dxTriMeshData::kVert0; edge->Vert2Flags = dxTriMeshData::kVert1; edge->VertIdx1 = vertIdxs[0]; edge->VertIdx2 = vertIdxs[1]; } else if (edgeIdx == 1) { edge->EdgeFlags = dxTriMeshData::kEdge1; edge->Vert1Flags = dxTriMeshData::kVert1; edge->Vert2Flags = dxTriMeshData::kVert2; edge->VertIdx1 = vertIdxs[1]; edge->VertIdx2 = vertIdxs[2]; } else if (edgeIdx == 2) { edge->EdgeFlags = dxTriMeshData::kEdge2; edge->Vert1Flags = dxTriMeshData::kVert2; edge->Vert2Flags = dxTriMeshData::kVert0; edge->VertIdx1 = vertIdxs[2]; edge->VertIdx2 = vertIdxs[0]; } // Make sure vert index 1 is less than index 2 (for easier sorting) if (edge->VertIdx1 > edge->VertIdx2) { unsigned int tempIdx = edge->VertIdx1; edge->VertIdx1 = edge->VertIdx2; edge->VertIdx2 = tempIdx; uint8 tempFlags = edge->Vert1Flags; edge->Vert1Flags = edge->Vert2Flags; edge->Vert2Flags = tempFlags; } edge->TriIdx = triIdx; edge->Concave = false; } #if dTRIMESH_ENABLED // Get the vertex opposite this edge in the triangle inline Point GetOppositeVert(EdgeRecord* edge, const Point* vertices[]) { if ((edge->Vert1Flags == dxTriMeshData::kVert0 && edge->Vert2Flags == dxTriMeshData::kVert1) || (edge->Vert1Flags == dxTriMeshData::kVert1 && edge->Vert2Flags == dxTriMeshData::kVert0)) { return *vertices[2]; } else if ((edge->Vert1Flags == dxTriMeshData::kVert1 && edge->Vert2Flags == dxTriMeshData::kVert2) || (edge->Vert1Flags == dxTriMeshData::kVert2 && edge->Vert2Flags == dxTriMeshData::kVert1)) { return *vertices[0]; } else return *vertices[1]; } #endif // dTRIMESH_ENABLED void dxTriMeshData::Preprocess() { #if dTRIMESH_ENABLED // If this mesh has already been preprocessed, exit if (UseFlags) return; udword numTris = Mesh.GetNbTriangles(); udword numEdges = numTris * 3; UseFlags = new uint8[numTris]; memset(UseFlags, 0, sizeof(uint8) * numTris); EdgeRecord* records = new EdgeRecord[numEdges]; // Make a list of every edge in the mesh const IndexedTriangle* tris = Mesh.GetTris(); for (unsigned int i = 0; i < numTris; i++) { SetupEdge(&records[i*3], 0, i, tris->mVRef); SetupEdge(&records[i*3+1], 1, i, tris->mVRef); SetupEdge(&records[i*3+2], 2, i, tris->mVRef); tris = (const IndexedTriangle*)(((uint8*)tris) + Mesh.GetTriStride()); } // Sort the edges, so the ones sharing the same verts are beside each other qsort(records, numEdges, sizeof(EdgeRecord), EdgeCompare); // Go through the sorted list of edges and flag all the edges and vertices that we need to use for (unsigned int i = 0; i < numEdges; i++) { EdgeRecord* rec1 = &records[i]; EdgeRecord* rec2 = 0; if (i < numEdges - 1) rec2 = &records[i+1]; if (rec2 && rec1->VertIdx1 == rec2->VertIdx1 && rec1->VertIdx2 == rec2->VertIdx2) { VertexPointers vp; ConversionArea vc; Mesh.GetTriangle(vp, rec1->TriIdx, vc); // Get the normal of the first triangle Point triNorm = (*vp.Vertex[2] - *vp.Vertex[1]) ^ (*vp.Vertex[0] - *vp.Vertex[1]); triNorm.Normalize(); // Get the vert opposite this edge in the first triangle Point oppositeVert1 = GetOppositeVert(rec1, vp.Vertex); // Get the vert opposite this edge in the second triangle Mesh.GetTriangle(vp, rec2->TriIdx, vc); Point oppositeVert2 = GetOppositeVert(rec2, vp.Vertex); float dot = triNorm.Dot((oppositeVert2 - oppositeVert1).Normalize()); // We let the dot threshold for concavity get slightly negative to allow for rounding errors static const float kConcaveThresh = -0.000001f; // This is a concave edge, leave it for the next pass if (dot >= kConcaveThresh) rec1->Concave = true; // If this is a convex edge, mark its vertices and edge as used else UseFlags[rec1->TriIdx] |= rec1->Vert1Flags | rec1->Vert2Flags | rec1->EdgeFlags; // Skip the second edge i++; } // This is a boundary edge else { UseFlags[rec1->TriIdx] |= rec1->Vert1Flags | rec1->Vert2Flags | rec1->EdgeFlags; } } // Go through the list once more, and take any edge we marked as concave and // clear it's vertices flags in any triangles they're used in for (unsigned int i = 0; i < numEdges; i++) { EdgeRecord& er = records[i]; if (er.Concave) { for (unsigned int j = 0; j < numEdges; j++) { EdgeRecord& curER = records[j]; if (curER.VertIdx1 == er.VertIdx1 || curER.VertIdx1 == er.VertIdx2) UseFlags[curER.TriIdx] &= ~curER.Vert1Flags; if (curER.VertIdx2 == er.VertIdx1 || curER.VertIdx2 == er.VertIdx2) UseFlags[curER.TriIdx] &= ~curER.Vert2Flags; } } } delete [] records; #endif // dTRIMESH_ENABLED } dTriMeshDataID dGeomTriMeshDataCreate(){ return new dxTriMeshData(); } void dGeomTriMeshDataDestroy(dTriMeshDataID g){ delete g; } void dGeomTriMeshSetLastTransform( dxGeom* g, dMatrix4 last_trans ) { dAASSERT(g) dUASSERT(g->type == dTriMeshClass, "geom not trimesh"); for (int i=0; i<16; i++) (((dxTriMesh*)g)->last_trans)[ i ] = last_trans[ i ]; return; } dReal* dGeomTriMeshGetLastTransform( dxGeom* g ) { dAASSERT(g) dUASSERT(g->type == dTriMeshClass, "geom not trimesh"); return (dReal*)(((dxTriMesh*)g)->last_trans); } void dGeomTriMeshDataSet(dTriMeshDataID g, int data_id, void* in_data) { dUASSERT(g, "argument not trimesh data"); switch (data_id) { case TRIMESH_FACE_NORMALS: g->Normals = (dReal *) in_data; break; default: dUASSERT(data_id, "invalid data type"); break; } return; } void* dGeomTriMeshDataGet(dTriMeshDataID g, int data_id) { dUASSERT(g, "argument not trimesh data"); switch (data_id) { case TRIMESH_FACE_NORMALS: return (void *) g->Normals; break; default: dUASSERT(data_id, "invalid data type"); break; } return NULL; } void dGeomTriMeshDataBuildSingle1(dTriMeshDataID g, const void* Vertices, int VertexStride, int VertexCount, const void* Indices, int IndexCount, int TriStride, const void* Normals) { dUASSERT(g, "argument not trimesh data"); g->Build(Vertices, VertexStride, VertexCount, Indices, IndexCount, TriStride, Normals, true); } void dGeomTriMeshDataBuildSingle(dTriMeshDataID g, const void* Vertices, int VertexStride, int VertexCount, const void* Indices, int IndexCount, int TriStride) { dGeomTriMeshDataBuildSingle1(g, Vertices, VertexStride, VertexCount, Indices, IndexCount, TriStride, (void*)NULL); } void dGeomTriMeshDataBuildDouble1(dTriMeshDataID g, const void* Vertices, int VertexStride, int VertexCount, const void* Indices, int IndexCount, int TriStride, const void* Normals) { dUASSERT(g, "argument not trimesh data"); g->Build(Vertices, VertexStride, VertexCount, Indices, IndexCount, TriStride, Normals, false); } void dGeomTriMeshDataBuildDouble(dTriMeshDataID g, const void* Vertices, int VertexStride, int VertexCount, const void* Indices, int IndexCount, int TriStride) { dGeomTriMeshDataBuildDouble1(g, Vertices, VertexStride, VertexCount, Indices, IndexCount, TriStride, NULL); } void dGeomTriMeshDataBuildSimple1(dTriMeshDataID g, const dReal* Vertices, int VertexCount, const dTriIndex* Indices, int IndexCount, const int* Normals){ #ifdef dSINGLE dGeomTriMeshDataBuildSingle1(g, Vertices, 4 * sizeof(dReal), VertexCount, Indices, IndexCount, 3 * sizeof(dTriIndex), Normals); #else dGeomTriMeshDataBuildDouble1(g, Vertices, 4 * sizeof(dReal), VertexCount, Indices, IndexCount, 3 * sizeof(dTriIndex), Normals); #endif } void dGeomTriMeshDataBuildSimple(dTriMeshDataID g, const dReal* Vertices, int VertexCount, const dTriIndex* Indices, int IndexCount) { dGeomTriMeshDataBuildSimple1(g, Vertices, VertexCount, Indices, IndexCount, (const int*)NULL); } void dGeomTriMeshDataPreprocess(dTriMeshDataID g) { dUASSERT(g, "argument not trimesh data"); g->Preprocess(); } void dGeomTriMeshDataGetBuffer(dTriMeshDataID g, unsigned char** buf, int* bufLen) { dUASSERT(g, "argument not trimesh data"); #if dTRIMESH_ENABLED *buf = g->UseFlags; *bufLen = g->Mesh.GetNbTriangles(); #endif // dTRIMESH_ENABLED } void dGeomTriMeshDataSetBuffer(dTriMeshDataID g, unsigned char* buf) { dUASSERT(g, "argument not trimesh data"); g->UseFlags = buf; } dxTriMesh::dxTriMesh(dSpaceID Space, dTriMeshDataID Data) : dxGeom(Space, 1) { type = dTriMeshClass; Callback = NULL; ArrayCallback = NULL; RayCallback = NULL; TriMergeCallback = NULL; // Not initialized in dCreateTriMesh this->Data = Data; /* TC has speed/space 'issues' that don't make it a clear win by default on spheres/boxes. */ this->doSphereTC = false; this->doBoxTC = false; this->doCapsuleTC = false; for (int i=0; i<16; i++) last_trans[i] = REAL( 0.0 ); } dxTriMesh::~dxTriMesh(){ // } // Cleanup for allocations when shutting down ODE /*extern */void opcode_collider_cleanup() { #if !dTLS_ENABLED #if dTRIMESH_ENABLED // Clear TC caches TrimeshCollidersCache *pccColliderCache = GetTrimeshCollidersCache(0); pccColliderCache->Faces.Empty(); pccColliderCache->defaultSphereCache.TouchedPrimitives.Empty(); pccColliderCache->defaultBoxCache.TouchedPrimitives.Empty(); pccColliderCache->defaultCapsuleCache.TouchedPrimitives.Empty(); #endif // dTRIMESH_ENABLED #endif // dTLS_ENABLED } void dxTriMesh::ClearTCCache() { #if dTRIMESH_ENABLED /* dxTriMesh::ClearTCCache uses dArray's setSize(0) to clear the caches - but the destructor isn't called when doing this, so we would leak. So, call the previous caches' containers' destructors by hand first. */ int i, n; n = SphereTCCache.size(); for( i = 0; i < n; ++i ) { SphereTCCache[i].~SphereTC(); } SphereTCCache.setSize(0); n = BoxTCCache.size(); for( i = 0; i < n; ++i ) { BoxTCCache[i].~BoxTC(); } BoxTCCache.setSize(0); n = CapsuleTCCache.size(); for( i = 0; i < n; ++i ) { CapsuleTCCache[i].~CapsuleTC(); } CapsuleTCCache.setSize(0); #endif // dTRIMESH_ENABLED } int dxTriMesh::AABBTest(dxGeom* g, dReal aabb[6]){ return 1; } void dxTriMesh::computeAABB() { const dxTriMeshData* d = Data; dVector3 c; const dMatrix3& R = final_posr->R; const dVector3& pos = final_posr->pos; dMULTIPLY0_331( c, R, d->AABBCenter ); dReal xrange = dFabs(R[0] * Data->AABBExtents[0]) + dFabs(R[1] * Data->AABBExtents[1]) + dFabs(R[2] * Data->AABBExtents[2]); dReal yrange = dFabs(R[4] * Data->AABBExtents[0]) + dFabs(R[5] * Data->AABBExtents[1]) + dFabs(R[6] * Data->AABBExtents[2]); dReal zrange = dFabs(R[8] * Data->AABBExtents[0]) + dFabs(R[9] * Data->AABBExtents[1]) + dFabs(R[10] * Data->AABBExtents[2]); aabb[0] = c[0] + pos[0] - xrange; aabb[1] = c[0] + pos[0] + xrange; aabb[2] = c[1] + pos[1] - yrange; aabb[3] = c[1] + pos[1] + yrange; aabb[4] = c[2] + pos[2] - zrange; aabb[5] = c[2] + pos[2] + zrange; } void dxTriMeshData::UpdateData() { #if dTRIMESH_ENABLED BVTree.Refit(); #endif // dTRIMESH_ENABLED } dGeomID dCreateTriMesh(dSpaceID space, dTriMeshDataID Data, dTriCallback* Callback, dTriArrayCallback* ArrayCallback, dTriRayCallback* RayCallback) { dxTriMesh* Geom = new dxTriMesh(space, Data); Geom->Callback = Callback; Geom->ArrayCallback = ArrayCallback; Geom->RayCallback = RayCallback; return Geom; } void dGeomTriMeshSetCallback(dGeomID g, dTriCallback* Callback) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); ((dxTriMesh*)g)->Callback = Callback; } dTriCallback* dGeomTriMeshGetCallback(dGeomID g) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); return ((dxTriMesh*)g)->Callback; } void dGeomTriMeshSetArrayCallback(dGeomID g, dTriArrayCallback* ArrayCallback) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); ((dxTriMesh*)g)->ArrayCallback = ArrayCallback; } dTriArrayCallback* dGeomTriMeshGetArrayCallback(dGeomID g) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); return ((dxTriMesh*)g)->ArrayCallback; } void dGeomTriMeshSetRayCallback(dGeomID g, dTriRayCallback* Callback) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); ((dxTriMesh*)g)->RayCallback = Callback; } dTriRayCallback* dGeomTriMeshGetRayCallback(dGeomID g) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); return ((dxTriMesh*)g)->RayCallback; } void dGeomTriMeshSetTriMergeCallback(dGeomID g, dTriTriMergeCallback* Callback) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); ((dxTriMesh*)g)->TriMergeCallback = Callback; } dTriTriMergeCallback* dGeomTriMeshGetTriMergeCallback(dGeomID g) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); return ((dxTriMesh*)g)->TriMergeCallback; } void dGeomTriMeshSetData(dGeomID g, dTriMeshDataID Data) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); ((dxTriMesh*)g)->Data = Data; // I changed my data -- I know nothing about my own AABB anymore. ((dxTriMesh*)g)->gflags |= (GEOM_DIRTY|GEOM_AABB_BAD); } dTriMeshDataID dGeomTriMeshGetData(dGeomID g) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); return ((dxTriMesh*)g)->Data; } void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); switch (geomClass) { case dSphereClass: ((dxTriMesh*)g)->doSphereTC = (1 == enable); break; case dBoxClass: ((dxTriMesh*)g)->doBoxTC = (1 == enable); break; case dCapsuleClass: ((dxTriMesh*)g)->doCapsuleTC = (1 == enable); break; } } int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); switch (geomClass) { case dSphereClass: if (((dxTriMesh*)g)->doSphereTC) return 1; break; case dBoxClass: if (((dxTriMesh*)g)->doBoxTC) return 1; break; case dCapsuleClass: if (((dxTriMesh*)g)->doCapsuleTC) return 1; break; } return 0; } void dGeomTriMeshClearTCCache(dGeomID g){ dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); dxTriMesh* Geom = (dxTriMesh*)g; Geom->ClearTCCache(); } /* * returns the TriMeshDataID */ dTriMeshDataID dGeomTriMeshGetTriMeshDataID(dGeomID g) { dxTriMesh* Geom = (dxTriMesh*) g; return Geom->Data; } // Getting data void dGeomTriMeshGetTriangle(dGeomID g, int Index, dVector3* v0, dVector3* v1, dVector3* v2){ dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); dxTriMesh* Geom = (dxTriMesh*)g; const dVector3& Position = *(const dVector3*)dGeomGetPosition(g); const dMatrix3& Rotation = *(const dMatrix3*)dGeomGetRotation(g); dVector3 v[3]; FetchTriangle(Geom, Index, Position, Rotation, v); if (v0){ (*v0)[0] = v[0][0]; (*v0)[1] = v[0][1]; (*v0)[2] = v[0][2]; (*v0)[3] = v[0][3]; } if (v1){ (*v1)[0] = v[1][0]; (*v1)[1] = v[1][1]; (*v1)[2] = v[1][2]; (*v1)[3] = v[1][3]; } if (v2){ (*v2)[0] = v[2][0]; (*v2)[1] = v[2][1]; (*v2)[2] = v[2][2]; (*v2)[3] = v[2][3]; } } void dGeomTriMeshGetPoint(dGeomID g, int Index, dReal u, dReal v, dVector3 Out){ dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); dxTriMesh* Geom = (dxTriMesh*)g; const dVector3& Position = *(const dVector3*)dGeomGetPosition(g); const dMatrix3& Rotation = *(const dMatrix3*)dGeomGetRotation(g); dVector3 dv[3]; FetchTriangle(Geom, Index, Position, Rotation, dv); GetPointFromBarycentric(dv, u, v, Out); } int dGeomTriMeshGetTriangleCount (dGeomID g) { dxTriMesh* Geom = (dxTriMesh*)g; return FetchTriangleCount(Geom); } void dGeomTriMeshDataUpdate(dTriMeshDataID g) { dUASSERT(g, "argument not trimesh data"); g->UpdateData(); } #endif // dTRIMESH_OPCODE #endif // dTRIMESH_ENABLED alien-arena-7.66+dfsg/source/unix/odesrc/collision_space_internal.h0000600000175000017500000000647312161402010024571 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* stuff common to all spaces */ #ifndef _ODE_COLLISION_SPACE_INTERNAL_H_ #define _ODE_COLLISION_SPACE_INTERNAL_H_ #define ALLOCA(x) dALLOCA16(x) #define CHECK_NOT_LOCKED(space) \ dUASSERT ((space)==0 || (space)->lock_count==0, \ "invalid operation for locked space"); // collide two geoms together. for the hash table space, this is // called if the two AABBs inhabit the same hash table cells. // this only calls the callback function if the AABBs actually // intersect. if a geom has an AABB test function, that is called to // provide a further refinement of the intersection. // // NOTE: this assumes that the geom AABBs are valid on entry // and that both geoms are enabled. static void collideAABBs (dxGeom *g1, dxGeom *g2, void *data, dNearCallback *callback) { dIASSERT((g1->gflags & GEOM_AABB_BAD)==0); dIASSERT((g2->gflags & GEOM_AABB_BAD)==0); // no contacts if both geoms on the same body, and the body is not 0 if (g1->body == g2->body && g1->body) return; // test if the category and collide bitfields match if ( ((g1->category_bits & g2->collide_bits) || (g2->category_bits & g1->collide_bits)) == 0) { return; } // if the bounding boxes are disjoint then don't do anything dReal *bounds1 = g1->aabb; dReal *bounds2 = g2->aabb; if (bounds1[0] > bounds2[1] || bounds1[1] < bounds2[0] || bounds1[2] > bounds2[3] || bounds1[3] < bounds2[2] || bounds1[4] > bounds2[5] || bounds1[5] < bounds2[4]) { return; } // check if either object is able to prove that it doesn't intersect the // AABB of the other if (g1->AABBTest (g2,bounds2) == 0) return; if (g2->AABBTest (g1,bounds1) == 0) return; // the objects might actually intersect - call the space callback function callback (data,g1,g2); } #endif alien-arena-7.66+dfsg/source/unix/odesrc/collision_transform.cpp0000600000175000017500000001574012161402010024145 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* geom transform */ #include #include #include #include #include "collision_transform.h" #include "collision_util.h" #ifdef _MSC_VER #pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" #endif //**************************************************************************** // dxGeomTransform class struct dxGeomTransform : public dxGeom { dxGeom *obj; // object that is being transformed int cleanup; // 1 to destroy obj when destroyed int infomode; // 1 to put Tx geom in dContactGeom g1 // cached final object transform (body tx + relative tx). this is set by // computeAABB(), and it is valid while the AABB is valid. dxPosR transform_posr; dxGeomTransform (dSpaceID space); ~dxGeomTransform(); void computeAABB(); void computeFinalTx(); }; /* void RunMe() { printf("sizeof body = %i\n", sizeof(dxBody)); printf("sizeof geom = %i\n", sizeof(dxGeom)); printf("sizeof geomtransform = %i\n", sizeof(dxGeomTransform)); printf("sizeof posr = %i\n", sizeof(dxPosR)); } */ dxGeomTransform::dxGeomTransform (dSpaceID space) : dxGeom (space,1) { type = dGeomTransformClass; obj = 0; cleanup = 0; infomode = 0; dSetZero (transform_posr.pos,4); dRSetIdentity (transform_posr.R); } dxGeomTransform::~dxGeomTransform() { if (obj && cleanup) delete obj; } void dxGeomTransform::computeAABB() { if (!obj) { dSetZero (aabb,6); return; } // backup the relative pos and R pointers of the encapsulated geom object dxPosR* posr_bak = obj->final_posr; // compute temporary pos and R for the encapsulated geom object computeFinalTx(); obj->final_posr = &transform_posr; // compute the AABB obj->computeAABB(); memcpy (aabb,obj->aabb,6*sizeof(dReal)); // restore the pos and R obj->final_posr = posr_bak; } // utility function for dCollideTransform() : compute final pos and R // for the encapsulated geom object void dxGeomTransform::computeFinalTx() { dMULTIPLY0_331 (transform_posr.pos,final_posr->R,obj->final_posr->pos); transform_posr.pos[0] += final_posr->pos[0]; transform_posr.pos[1] += final_posr->pos[1]; transform_posr.pos[2] += final_posr->pos[2]; dMULTIPLY0_333 (transform_posr.R,final_posr->R,obj->final_posr->R); } //**************************************************************************** // collider function: // this collides a transformed geom with another geom. the other geom can // also be a transformed geom, but this case is not handled specially. int dCollideTransform (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT (o1->type == dGeomTransformClass); dxGeomTransform *tr = (dxGeomTransform*) o1; if (!tr->obj) return 0; dUASSERT (tr->obj->parent_space==0, "GeomTransform encapsulated object must not be in a space"); dUASSERT (tr->obj->body==0, "GeomTransform encapsulated object must not be attached " "to a body"); // backup the relative pos and R pointers of the encapsulated geom object, // and the body pointer dxPosR *posr_bak = tr->obj->final_posr; dxBody *bodybak = tr->obj->body; // compute temporary pos and R for the encapsulated geom object. // note that final_pos and final_R are valid if no GEOM_AABB_BAD flag, // because computeFinalTx() will have already been called in // dxGeomTransform::computeAABB() if (tr->gflags & GEOM_AABB_BAD) tr->computeFinalTx(); tr->obj->final_posr = &tr->transform_posr; tr->obj->body = o1->body; // do the collision int n = dCollide (tr->obj,o2,flags,contact,skip); // if required, adjust the 'g1' values in the generated contacts so that // thay indicated the GeomTransform object instead of the encapsulated // object. if (tr->infomode) { for (int i=0; ig1 = o1; } } // restore the pos, R and body tr->obj->final_posr = posr_bak; tr->obj->body = bodybak; return n; } //**************************************************************************** // public API dGeomID dCreateGeomTransform (dSpaceID space) { return new dxGeomTransform (space); } void dGeomTransformSetGeom (dGeomID g, dGeomID obj) { dUASSERT (g && g->type == dGeomTransformClass, "argument not a geom transform"); dxGeomTransform *tr = (dxGeomTransform*) g; if (tr->obj && tr->cleanup) delete tr->obj; tr->obj = obj; } dGeomID dGeomTransformGetGeom (dGeomID g) { dUASSERT (g && g->type == dGeomTransformClass, "argument not a geom transform"); dxGeomTransform *tr = (dxGeomTransform*) g; return tr->obj; } void dGeomTransformSetCleanup (dGeomID g, int mode) { dUASSERT (g && g->type == dGeomTransformClass, "argument not a geom transform"); dxGeomTransform *tr = (dxGeomTransform*) g; tr->cleanup = mode; } int dGeomTransformGetCleanup (dGeomID g) { dUASSERT (g && g->type == dGeomTransformClass, "argument not a geom transform"); dxGeomTransform *tr = (dxGeomTransform*) g; return tr->cleanup; } void dGeomTransformSetInfo (dGeomID g, int mode) { dUASSERT (g && g->type == dGeomTransformClass, "argument not a geom transform"); dxGeomTransform *tr = (dxGeomTransform*) g; tr->infomode = mode; } int dGeomTransformGetInfo (dGeomID g) { dUASSERT (g && g->type == dGeomTransformClass, "argument not a geom transform"); dxGeomTransform *tr = (dxGeomTransform*) g; return tr->infomode; } alien-arena-7.66+dfsg/source/unix/odesrc/obstack.cpp0000600000175000017500000001111212161402010021472 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include #include #include #include "obstack.h" #include "util.h" /* * Alien Arena 7.51 addition * (This was done by injecting header files and a typedef into * config.h in configure.ac. Seemed more drastic for a defined type * that only occurs in this file than doing the following.) */ #if defined HAVE_STDINT_H # include #endif #if defined HAVE_UINTPTR_T typedef uintptr_t intP; #else typedef unsigned int intP; #endif /* end of Alien Arena 7.51 addition */ //**************************************************************************** // macros and constants #define ROUND_UP_OFFSET_TO_EFFICIENT_SIZE(arena,ofs) \ ofs = (size_t) (dEFFICIENT_SIZE( ((intP)(arena)) + ofs ) - ((intP)(arena)) ); #define MAX_ALLOC_SIZE \ ((size_t)(dOBSTACK_ARENA_SIZE - sizeof (Arena) - EFFICIENT_ALIGNMENT + 1)) //**************************************************************************** // dObStack dObStack::dObStack() { first = 0; last = 0; current_arena = 0; current_ofs = 0; } dObStack::~dObStack() { // free all arenas Arena *a,*nexta; a = first; while (a) { nexta = a->next; dFree (a,dOBSTACK_ARENA_SIZE); a = nexta; } } void *dObStack::alloc (int num_bytes) { if ((size_t)num_bytes > MAX_ALLOC_SIZE) dDebug (0,"num_bytes too large"); // allocate or move to a new arena if necessary if (!first) { // allocate the first arena if necessary first = last = (Arena *) dAlloc (dOBSTACK_ARENA_SIZE); first->next = 0; first->used = sizeof (Arena); ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (first,first->used); } else { // we already have one or more arenas, see if a new arena must be used if ((last->used + num_bytes) > dOBSTACK_ARENA_SIZE) { if (!last->next) { last->next = (Arena *) dAlloc (dOBSTACK_ARENA_SIZE); last->next->next = 0; } last = last->next; last->used = sizeof (Arena); ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (last,last->used); } } // allocate an area in the arena char *c = ((char*) last) + last->used; last->used += num_bytes; ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (last,last->used); return c; } void dObStack::freeAll() { last = first; if (first) { first->used = sizeof(Arena); ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (first,first->used); } } void *dObStack::rewind() { current_arena = first; current_ofs = sizeof (Arena); if (current_arena) { ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (current_arena,current_ofs) return ((char*) current_arena) + current_ofs; } else return 0; } void *dObStack::next (int num_bytes) { // this functions like alloc, except that no new storage is ever allocated if (!current_arena) return 0; current_ofs += num_bytes; ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (current_arena,current_ofs); if (current_ofs >= current_arena->used) { current_arena = current_arena->next; if (!current_arena) return 0; current_ofs = sizeof (Arena); ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (current_arena,current_ofs); } return ((char*) current_arena) + current_ofs; } alien-arena-7.66+dfsg/source/unix/odesrc/lcp.cpp0000600000175000017500000015012412161402010020631 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* THE ALGORITHM ------------- solve A*x = b+w, with x and w subject to certain LCP conditions. each x(i),w(i) must lie on one of the three line segments in the following diagram. each line segment corresponds to one index set : w(i) /|\ | : | | : | |i in N : w>0 | |state[i]=0 : | | : | | : i in C w=0 + +-----------------------+ | : | | : | w<0 | : |i in N | : |state[i]=1 | : | | : | +-------|-----------|-----------|----------> x(i) lo 0 hi the Dantzig algorithm proceeds as follows: for i=1:n * if (x(i),w(i)) is not on the line, push x(i) and w(i) positive or negative towards the line. as this is done, the other (x(j),w(j)) for j= 0. this makes the algorithm a bit simpler, because the starting point for x(i),w(i) is always on the dotted line x=0 and x will only ever increase in one direction, so it can only hit two out of the three line segments. NOTES ----- this is an implementation of "lcp_dantzig2_ldlt.m" and "lcp_dantzig_lohi.m". the implementation is split into an LCP problem object (dLCP) and an LCP driver function. most optimization occurs in the dLCP object. a naive implementation of the algorithm requires either a lot of data motion or a lot of permutation-array lookup, because we are constantly re-ordering rows and columns. to avoid this and make a more optimized algorithm, a non-trivial data structure is used to represent the matrix A (this is implemented in the fast version of the dLCP object). during execution of this algorithm, some indexes in A are clamped (set C), some are non-clamped (set N), and some are "don't care" (where x=0). A,x,b,w (and other problem vectors) are permuted such that the clamped indexes are first, the unclamped indexes are next, and the don't-care indexes are last. this permutation is recorded in the array `p'. initially p = 0..n-1, and as the rows and columns of A,x,b,w are swapped, the corresponding elements of p are swapped. because the C and N elements are grouped together in the rows of A, we can do lots of work with a fast dot product function. if A,x,etc were not permuted and we only had a permutation array, then those dot products would be much slower as we would have a permutation array lookup in some inner loops. A is accessed through an array of row pointers, so that element (i,j) of the permuted matrix is A[i][j]. this makes row swapping fast. for column swapping we still have to actually move the data. during execution of this algorithm we maintain an L*D*L' factorization of the clamped submatrix of A (call it `AC') which is the top left nC*nC submatrix of A. there are two ways we could arrange the rows/columns in AC. (1) AC is always permuted such that L*D*L' = AC. this causes a problem when a row/column is removed from C, because then all the rows/columns of A between the deleted index and the end of C need to be rotated downward. this results in a lot of data motion and slows things down. (2) L*D*L' is actually a factorization of a *permutation* of AC (which is itself a permutation of the underlying A). this is what we do - the permutation is recorded in the vector C. call this permutation A[C,C]. when a row/column is removed from C, all we have to do is swap two rows/columns and manipulate C. */ #include #include "config.h" #include "lcp.h" #include #include #include "mat.h" // for testing #include // for testing #include "util.h" //*************************************************************************** // code generation parameters // LCP debugging (mosty for fast dLCP) - this slows things down a lot //#define DEBUG_LCP //#define dLCP_SLOW // use slow dLCP object #define dLCP_FAST // use fast dLCP object // option 1 : matrix row pointers (less data copying) #define ROWPTRS #define ATYPE dReal ** #define AROW(i) (A[i]) // option 2 : no matrix row pointers (slightly faster inner loops) //#define NOROWPTRS //#define ATYPE dReal * //#define AROW(i) (A+(i)*nskip) // use protected, non-stack memory allocation system #ifdef dUSE_MALLOC_FOR_ALLOCA extern unsigned int dMemoryFlag; #define ALLOCA(t,v,s) t* v = (t*) malloc(s) #define UNALLOCA(t) free(t) #else #define ALLOCA(t,v,s) t* v =(t*)dALLOCA16(s) #define UNALLOCA(t) /* nothing */ #endif #define NUB_OPTIMIZATIONS //*************************************************************************** // swap row/column i1 with i2 in the n*n matrix A. the leading dimension of // A is nskip. this only references and swaps the lower triangle. // if `do_fast_row_swaps' is nonzero and row pointers are being used, then // rows will be swapped by exchanging row pointers. otherwise the data will // be copied. static void swapRowsAndCols (ATYPE A, int n, int i1, int i2, int nskip, int do_fast_row_swaps) { int i; dAASSERT (A && n > 0 && i1 >= 0 && i2 >= 0 && i1 < n && i2 < n && nskip >= n && i1 < i2); # ifdef ROWPTRS for (i=i1+1; i 0) { memcpy (tmprow,A+i1*nskip,i1*sizeof(dReal)); memcpy (A+i1*nskip,A+i2*nskip,i1*sizeof(dReal)); memcpy (A+i2*nskip,tmprow,i1*sizeof(dReal)); } for (i=i1+1; i0 && i1 >=0 && i2 >= 0 && i1 < n && i2 < n && nskip >= n && i1 <= i2); if (i1==i2) return; swapRowsAndCols (A,n,i1,i2,nskip,do_fast_row_swaps); #ifdef dUSE_MALLOC_FOR_ALLOCA if (dMemoryFlag == d_MEMORY_OUT_OF_MEMORY) return; #endif tmp = x[i1]; x[i1] = x[i2]; x[i2] = tmp; tmp = b[i1]; b[i1] = b[i2]; b[i2] = tmp; tmp = w[i1]; w[i1] = w[i2]; w[i2] = tmp; tmp = lo[i1]; lo[i1] = lo[i2]; lo[i2] = tmp; tmp = hi[i1]; hi[i1] = hi[i2]; hi[i2] = tmp; tmpi = p[i1]; p[i1] = p[i2]; p[i2] = tmpi; tmpi = state[i1]; state[i1] = state[i2]; state[i2] = tmpi; if (findex) { tmpi = findex[i1]; findex[i1] = findex[i2]; findex[i2] = tmpi; } } // for debugging - check that L,d is the factorization of A[C,C]. // A[C,C] has size nC*nC and leading dimension nskip. // L has size nC*nC and leading dimension nskip. // d has size nC. #ifdef DEBUG_LCP static void checkFactorization (ATYPE A, dReal *_L, dReal *_d, int nC, int *C, int nskip) { int i,j; if (nC==0) return; // get A1=A, copy the lower triangle to the upper triangle, get A2=A[C,C] dMatrix A1 (nC,nC); for (i=0; i 1e-8) dDebug (0,"L*D*L' check, maximum difference = %.6e\n",diff); } #endif // for debugging #ifdef DEBUG_LCP static void checkPermutations (int i, int n, int nC, int nN, int *p, int *C) { int j,k; dIASSERT (nC>=0 && nN>=0 && (nC+nN)==i && i < n); for (k=0; k= 0 && p[k] < i); for (k=i; k C,N; // index sets int last_i_for_solve1; // last i value given to solve1 dLCP (int _n, int _nub, dReal *_Adata, dReal *_x, dReal *_b, dReal *_w, dReal *_lo, dReal *_hi, dReal *_L, dReal *_d, dReal *_Dell, dReal *_ell, dReal *_tmp, int *_state, int *_findex, int *_p, int *_C, dReal **Arows); // the constructor is given an initial problem description (A,x,b,w) and // space for other working data (which the caller may allocate on the stack). // some of this data is specific to the fast dLCP implementation. // the matrices A and L have size n*n, vectors have size n*1. // A represents a symmetric matrix but only the lower triangle is valid. // `nub' is the number of unbounded indexes at the start. all the indexes // 0..nub-1 will be put into C. ~dLCP(); int getNub() { return nub; } // return the value of `nub'. the constructor may want to change it, // so the caller should find out its new value. // transfer functions: transfer index i to the given set (C or N). indexes // less than `nub' can never be given. A,x,b,w,etc may be permuted by these // functions, the caller must be robust to this. void transfer_i_to_C (int i); // this assumes C and N span 1:i-1. this also assumes that solve1() has // been recently called for the same i without any other transfer // functions in between (thereby allowing some data reuse for the fast // implementation). void transfer_i_to_N (int i); // this assumes C and N span 1:i-1. void transfer_i_from_N_to_C (int i); void transfer_i_from_C_to_N (int i); int numC(); int numN(); // return the number of indexes in set C/N int indexC (int i); int indexN (int i); // return index i in set C/N. // accessor and arithmetic functions. Aij translates as A(i,j), etc. // make sure that only the lower triangle of A is ever referenced. dReal Aii (int i); dReal AiC_times_qC (int i, dReal *q); dReal AiN_times_qN (int i, dReal *q); // for all Nj void pN_equals_ANC_times_qC (dReal *p, dReal *q); // for all Nj void pN_plusequals_ANi (dReal *p, int i, int sign=1); // for all Nj. sign = +1,-1. assumes i > maximum index in N. void pC_plusequals_s_times_qC (dReal *p, dReal s, dReal *q); void pN_plusequals_s_times_qN (dReal *p, dReal s, dReal *q); // for all Nj void solve1 (dReal *a, int i, int dir=1, int only_transfer=0); // get a(C) = - dir * A(C,C) \ A(C,i). dir must be +/- 1. // the fast version of this function computes some data that is needed by // transfer_i_to_C(). if only_transfer is nonzero then this function // *only* computes that data, it does not set a(C). void unpermute(); // call this at the end of the LCP function. if the x/w values have been // permuted then this will unscramble them. }; dLCP::dLCP (int _n, int _nub, dReal *_Adata, dReal *_x, dReal *_b, dReal *_w, dReal *_lo, dReal *_hi, dReal *_L, dReal *_d, dReal *_Dell, dReal *_ell, dReal *_tmp, int *_state, int *_findex, int *_p, int *_C, dReal **Arows) { dUASSERT (_findex==0,"slow dLCP object does not support findex array"); n = _n; nub = _nub; Adata = _Adata; A = 0; x = _x; b = _b; w = _w; lo = _lo; hi = _hi; nskip = dPAD(n); dSetZero (x,n); last_i_for_solve1 = -1; int i,j; C.setSize (n); N.setSize (n); for (i=0; i0, put all indexes 0..nub-1 into C and solve for x if (nub > 0) { for (i=0; i= i) dDebug (0,"N assumption violated"); if (sign > 0) { for (k=0; k 0) { for (ii=0; ii nub if (nub < n) { for (k=0; k<100; k++) { int i1,i2; do { i1 = dRandInt(n-nub)+nub; i2 = dRandInt(n-nub)+nub; } while (i1 > i2); //printf ("--> %d %d\n",i1,i2); swapProblem (A,x,b,w,lo,hi,p,state,findex,n,i1,i2,nskip,0); } } */ // permute the problem so that *all* the unbounded variables are at the // start, i.e. look for unbounded variables not included in `nub'. we can // potentially push up `nub' this way and get a bigger initial factorization. // note that when we swap rows/cols here we must not just swap row pointers, // as the initial factorization relies on the data being all in one chunk. // variables that have findex >= 0 are *not* considered to be unbounded even // if lo=-inf and hi=inf - this is because these limits may change during the // solution process. for (k=nub; k= 0) continue; if (lo[k]==-dInfinity && hi[k]==dInfinity) { swapProblem (A,x,b,w,lo,hi,p,state,findex,n,nub,k,nskip,0); nub++; } } // if there are unbounded variables at the start, factorize A up to that // point and solve for x. this puts all indexes 0..nub-1 into C. if (nub > 0) { for (k=0; k nub such that all findex variables are at the end if (findex) { int num_at_end = 0; for (k=n-1; k >= nub; k--) { if (findex[k] >= 0) { swapProblem (A,x,b,w,lo,hi,p,state,findex,n,k,n-1-num_at_end,nskip,1); num_at_end++; } } } // print info about indexes /* for (k=0; k 0) { // ell,Dell were computed by solve1(). note, ell = D \ L1solve (L,A(i,C)) for (j=0; j 0) { dReal *aptr = AROW(i); # ifdef NUB_OPTIMIZATIONS // if nub>0, initial part of aptr unpermuted for (j=0; j 0) { for (int i=0; i 0) { dReal *aptr = AROW(i); # ifdef NUB_OPTIMIZATIONS // if nub>0, initial part of aptr[] is guaranteed unpermuted for (j=0; j 0) { for (j=0; j0 && A && x && b && w && nub == 0); int i,k; int nskip = dPAD(n); ALLOCA (dReal,L,n*nskip*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (L == NULL) { dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,d,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (d == NULL) { UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,delta_x,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (delta_x == NULL) { UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,delta_w,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (delta_w == NULL) { UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,Dell,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (Dell == NULL) { UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,ell,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (ell == NULL) { UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,tmp,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (tmp == NULL) { UNALLOCA(ell); UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal*,Arows,n*sizeof(dReal*)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (Arows == NULL) { UNALLOCA(tmp); UNALLOCA(ell); UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (int,p,n*sizeof(int)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (p == NULL) { UNALLOCA(Arows); UNALLOCA(tmp); UNALLOCA(ell); UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (int,C,n*sizeof(int)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (C == NULL) { UNALLOCA(p); UNALLOCA(Arows); UNALLOCA(tmp); UNALLOCA(ell); UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (int,dummy,n*sizeof(int)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (dummy == NULL) { UNALLOCA(C); UNALLOCA(p); UNALLOCA(Arows); UNALLOCA(tmp); UNALLOCA(ell); UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif dLCP lcp (n,0,A,x,b,w,tmp,tmp,L,d,Dell,ell,tmp,dummy,dummy,p,C,Arows); nub = lcp.getNub(); for (i=0; i= 0) { lcp.transfer_i_to_N (i); } else { for (;;) { // compute: delta_x(C) = -A(C,C)\A(C,i) dSetZero (delta_x,n); lcp.solve1 (delta_x,i); #ifdef dUSE_MALLOC_FOR_ALLOCA if (dMemoryFlag == d_MEMORY_OUT_OF_MEMORY) { UNALLOCA(dummy); UNALLOCA(C); UNALLOCA(p); UNALLOCA(Arows); UNALLOCA(tmp); UNALLOCA(ell); UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); return; } #endif delta_x[i] = 1; // compute: delta_w = A*delta_x dSetZero (delta_w,n); lcp.pN_equals_ANC_times_qC (delta_w,delta_x); lcp.pN_plusequals_ANi (delta_w,i); delta_w[i] = lcp.AiC_times_qC (i,delta_x) + lcp.Aii(i); // find index to switch int si = i; // si = switch index int si_in_N = 0; // set to 1 if si in N dReal s = -w[i]/delta_w[i]; if (s <= 0) { dMessage (d_ERR_LCP, "LCP internal error, s <= 0 (s=%.4e)",s); if (i < (n-1)) { dSetZero (x+i,n-i); dSetZero (w+i,n-i); } goto done; } for (k=0; k < lcp.numN(); k++) { if (delta_w[lcp.indexN(k)] < 0) { dReal s2 = -w[lcp.indexN(k)] / delta_w[lcp.indexN(k)]; if (s2 < s) { s = s2; si = lcp.indexN(k); si_in_N = 1; } } } for (k=0; k < lcp.numC(); k++) { if (delta_x[lcp.indexC(k)] < 0) { dReal s2 = -x[lcp.indexC(k)] / delta_x[lcp.indexC(k)]; if (s2 < s) { s = s2; si = lcp.indexC(k); si_in_N = 0; } } } // apply x = x + s * delta_x lcp.pC_plusequals_s_times_qC (x,s,delta_x); x[i] += s; lcp.pN_plusequals_s_times_qN (w,s,delta_w); w[i] += s * delta_w[i]; // switch indexes between sets if necessary if (si==i) { w[i] = 0; lcp.transfer_i_to_C (i); break; } if (si_in_N) { w[si] = 0; lcp.transfer_i_from_N_to_C (si); } else { x[si] = 0; lcp.transfer_i_from_C_to_N (si); } } } } done: lcp.unpermute(); UNALLOCA (L); UNALLOCA (d); UNALLOCA (delta_x); UNALLOCA (delta_w); UNALLOCA (Dell); UNALLOCA (ell); UNALLOCA (tmp); UNALLOCA (Arows); UNALLOCA (p); UNALLOCA (C); UNALLOCA (dummy); } //*************************************************************************** // an optimized Dantzig LCP driver routine for the lo-hi LCP problem. void dSolveLCP (int n, dReal *A, dReal *x, dReal *b, dReal *w, int nub, dReal *lo, dReal *hi, int *findex) { dAASSERT (n>0 && A && x && b && w && lo && hi && nub >= 0 && nub <= n); int i,k,hit_first_friction_index = 0; int nskip = dPAD(n); // if all the variables are unbounded then we can just factor, solve, // and return if (nub >= n) { dFactorLDLT (A,w,n,nskip); // use w for d dSolveLDLT (A,w,b,n,nskip); memcpy (x,b,n*sizeof(dReal)); dSetZero (w,n); return; } # ifndef dNODEBUG // check restrictions on lo and hi for (k=0; k= 0); # endif ALLOCA (dReal,L,n*nskip*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (L == NULL) { dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,d,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (d == NULL) { UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,delta_x,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (delta_x == NULL) { UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,delta_w,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (delta_w == NULL) { UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,Dell,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (Dell == NULL) { UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,ell,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (ell == NULL) { UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal*,Arows,n*sizeof(dReal*)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (Arows == NULL) { UNALLOCA(ell); UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (int,p,n*sizeof(int)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (p == NULL) { UNALLOCA(Arows); UNALLOCA(ell); UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (int,C,n*sizeof(int)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (C == NULL) { UNALLOCA(p); UNALLOCA(Arows); UNALLOCA(ell); UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif int dir; dReal dirf; // for i in N, state[i] is 0 if x(i)==lo(i) or 1 if x(i)==hi(i) ALLOCA (int,state,n*sizeof(int)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (state == NULL) { UNALLOCA(C); UNALLOCA(p); UNALLOCA(Arows); UNALLOCA(ell); UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif // create LCP object. note that tmp is set to delta_w to save space, this // optimization relies on knowledge of how tmp is used, so be careful! dLCP *lcp=new dLCP(n,nub,A,x,b,w,lo,hi,L,d,Dell,ell,delta_w,state,findex,p,C,Arows); nub = lcp->getNub(); // loop over all indexes nub..n-1. for index i, if x(i),w(i) satisfy the // LCP conditions then i is added to the appropriate index set. otherwise // x(i),w(i) is driven either +ve or -ve to force it to the valid region. // as we drive x(i), x(C) is also adjusted to keep w(C) at zero. // while driving x(i) we maintain the LCP conditions on the other variables // 0..i-1. we do this by watching out for other x(i),w(i) values going // outside the valid region, and then switching them between index sets // when that happens. for (i=nub; i= 0) { // un-permute x into delta_w, which is not being used at the moment for (k=0; kAiC_times_qC (i,x) + lcp->AiN_times_qN (i,x) - b[i]; // if lo=hi=0 (which can happen for tangential friction when normals are // 0) then the index will be assigned to set N with some state. however, // set C's line has zero size, so the index will always remain in set N. // with the "normal" switching logic, if w changed sign then the index // would have to switch to set C and then back to set N with an inverted // state. this is pointless, and also computationally expensive. to // prevent this from happening, we use the rule that indexes with lo=hi=0 // will never be checked for set changes. this means that the state for // these indexes may be incorrect, but that doesn't matter. // see if x(i),w(i) is in a valid region if (lo[i]==0 && w[i] >= 0) { lcp->transfer_i_to_N (i); state[i] = 0; } else if (hi[i]==0 && w[i] <= 0) { lcp->transfer_i_to_N (i); state[i] = 1; } else if (w[i]==0) { // this is a degenerate case. by the time we get to this test we know // that lo != 0, which means that lo < 0 as lo is not allowed to be +ve, // and similarly that hi > 0. this means that the line segment // corresponding to set C is at least finite in extent, and we are on it. // NOTE: we must call lcp->solve1() before lcp->transfer_i_to_C() lcp->solve1 (delta_x,i,0,1); #ifdef dUSE_MALLOC_FOR_ALLOCA if (dMemoryFlag == d_MEMORY_OUT_OF_MEMORY) { UNALLOCA(state); UNALLOCA(C); UNALLOCA(p); UNALLOCA(Arows); UNALLOCA(ell); UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); return; } #endif lcp->transfer_i_to_C (i); } else { // we must push x(i) and w(i) for (;;) { // find direction to push on x(i) if (w[i] <= 0) { dir = 1; dirf = REAL(1.0); } else { dir = -1; dirf = REAL(-1.0); } // compute: delta_x(C) = -dir*A(C,C)\A(C,i) lcp->solve1 (delta_x,i,dir); #ifdef dUSE_MALLOC_FOR_ALLOCA if (dMemoryFlag == d_MEMORY_OUT_OF_MEMORY) { UNALLOCA(state); UNALLOCA(C); UNALLOCA(p); UNALLOCA(Arows); UNALLOCA(ell); UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); return; } #endif // note that delta_x[i] = dirf, but we wont bother to set it // compute: delta_w = A*delta_x ... note we only care about // delta_w(N) and delta_w(i), the rest is ignored lcp->pN_equals_ANC_times_qC (delta_w,delta_x); lcp->pN_plusequals_ANi (delta_w,i,dir); delta_w[i] = lcp->AiC_times_qC (i,delta_x) + lcp->Aii(i)*dirf; // find largest step we can take (size=s), either to drive x(i),w(i) // to the valid LCP region or to drive an already-valid variable // outside the valid region. int cmd = 1; // index switching command int si = 0; // si = index to switch if cmd>3 dReal s = -w[i]/delta_w[i]; if (dir > 0) { if (hi[i] < dInfinity) { dReal s2 = (hi[i]-x[i])/dirf; // step to x(i)=hi(i) if (s2 < s) { s = s2; cmd = 3; } } } else { if (lo[i] > -dInfinity) { dReal s2 = (lo[i]-x[i])/dirf; // step to x(i)=lo(i) if (s2 < s) { s = s2; cmd = 2; } } } for (k=0; k < lcp->numN(); k++) { if ((state[lcp->indexN(k)]==0 && delta_w[lcp->indexN(k)] < 0) || (state[lcp->indexN(k)]!=0 && delta_w[lcp->indexN(k)] > 0)) { // don't bother checking if lo=hi=0 if (lo[lcp->indexN(k)] == 0 && hi[lcp->indexN(k)] == 0) continue; dReal s2 = -w[lcp->indexN(k)] / delta_w[lcp->indexN(k)]; if (s2 < s) { s = s2; cmd = 4; si = lcp->indexN(k); } } } for (k=nub; k < lcp->numC(); k++) { if (delta_x[lcp->indexC(k)] < 0 && lo[lcp->indexC(k)] > -dInfinity) { dReal s2 = (lo[lcp->indexC(k)]-x[lcp->indexC(k)]) / delta_x[lcp->indexC(k)]; if (s2 < s) { s = s2; cmd = 5; si = lcp->indexC(k); } } if (delta_x[lcp->indexC(k)] > 0 && hi[lcp->indexC(k)] < dInfinity) { dReal s2 = (hi[lcp->indexC(k)]-x[lcp->indexC(k)]) / delta_x[lcp->indexC(k)]; if (s2 < s) { s = s2; cmd = 6; si = lcp->indexC(k); } } } //static char* cmdstring[8] = {0,"->C","->NL","->NH","N->C", // "C->NL","C->NH"}; //printf ("cmd=%d (%s), si=%d\n",cmd,cmdstring[cmd],(cmd>3) ? si : i); // if s <= 0 then we've got a problem. if we just keep going then // we're going to get stuck in an infinite loop. instead, just cross // our fingers and exit with the current solution. if (s <= 0) { dMessage (d_ERR_LCP, "LCP internal error, s <= 0 (s=%.4e)",s); if (i < (n-1)) { dSetZero (x+i,n-i); dSetZero (w+i,n-i); } goto done; } // apply x = x + s * delta_x lcp->pC_plusequals_s_times_qC (x,s,delta_x); x[i] += s * dirf; // apply w = w + s * delta_w lcp->pN_plusequals_s_times_qN (w,s,delta_w); w[i] += s * delta_w[i]; // switch indexes between sets if necessary switch (cmd) { case 1: // done w[i] = 0; lcp->transfer_i_to_C (i); break; case 2: // done x[i] = lo[i]; state[i] = 0; lcp->transfer_i_to_N (i); break; case 3: // done x[i] = hi[i]; state[i] = 1; lcp->transfer_i_to_N (i); break; case 4: // keep going w[si] = 0; lcp->transfer_i_from_N_to_C (si); break; case 5: // keep going x[si] = lo[si]; state[si] = 0; lcp->transfer_i_from_C_to_N (si); break; case 6: // keep going x[si] = hi[si]; state[si] = 1; lcp->transfer_i_from_C_to_N (si); break; } if (cmd <= 3) break; } } } done: lcp->unpermute(); delete lcp; UNALLOCA (L); UNALLOCA (d); UNALLOCA (delta_x); UNALLOCA (delta_w); UNALLOCA (Dell); UNALLOCA (ell); UNALLOCA (Arows); UNALLOCA (p); UNALLOCA (C); UNALLOCA (state); } //*************************************************************************** // accuracy and timing test extern "C" ODE_API void dTestSolveLCP() { int n = 100; int i,nskip = dPAD(n); #ifdef dDOUBLE const dReal tol = REAL(1e-9); #endif #ifdef dSINGLE const dReal tol = REAL(1e-4); #endif printf ("dTestSolveLCP()\n"); ALLOCA (dReal,A,n*nskip*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (A == NULL) { dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,x,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (x == NULL) { UNALLOCA (A); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,b,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (b == NULL) { UNALLOCA (x); UNALLOCA (A); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,w,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (w == NULL) { UNALLOCA (b); UNALLOCA (x); UNALLOCA (A); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,lo,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (lo == NULL) { UNALLOCA (w); UNALLOCA (b); UNALLOCA (x); UNALLOCA (A); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,hi,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (hi == NULL) { UNALLOCA (lo); UNALLOCA (w); UNALLOCA (b); UNALLOCA (x); UNALLOCA (A); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,A2,n*nskip*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (A2 == NULL) { UNALLOCA (hi); UNALLOCA (lo); UNALLOCA (w); UNALLOCA (b); UNALLOCA (x); UNALLOCA (A); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,b2,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (b2 == NULL) { UNALLOCA (A2); UNALLOCA (hi); UNALLOCA (lo); UNALLOCA (w); UNALLOCA (b); UNALLOCA (x); UNALLOCA (A); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,lo2,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (lo2 == NULL) { UNALLOCA (b2); UNALLOCA (A2); UNALLOCA (hi); UNALLOCA (lo); UNALLOCA (w); UNALLOCA (b); UNALLOCA (x); UNALLOCA (A); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,hi2,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (hi2 == NULL) { UNALLOCA (lo2); UNALLOCA (b2); UNALLOCA (A2); UNALLOCA (hi); UNALLOCA (lo); UNALLOCA (w); UNALLOCA (b); UNALLOCA (x); UNALLOCA (A); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,tmp1,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (tmp1 == NULL) { UNALLOCA (hi2); UNALLOCA (lo2); UNALLOCA (b2); UNALLOCA (A2); UNALLOCA (hi); UNALLOCA (lo); UNALLOCA (w); UNALLOCA (b); UNALLOCA (x); UNALLOCA (A); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,tmp2,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (tmp2 == NULL) { UNALLOCA (tmp1); UNALLOCA (hi2); UNALLOCA (lo2); UNALLOCA (b2); UNALLOCA (A2); UNALLOCA (hi); UNALLOCA (lo); UNALLOCA (w); UNALLOCA (b); UNALLOCA (x); UNALLOCA (A); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif double total_time = 0; for (int count=0; count < 1000; count++) { // form (A,b) = a random positive definite LCP problem dMakeRandomMatrix (A2,n,n,1.0); dMultiply2 (A,A2,A2,n,n,n); dMakeRandomMatrix (x,n,1,1.0); dMultiply0 (b,A,x,n,n,1); for (i=0; i tol ? "FAILED" : "passed"); if (diff > tol) dDebug (0,"A*x = b+w, maximum difference = %.6e",diff); int n1=0,n2=0,n3=0; for (i=0; i= 0) { n1++; // ok } else if (x[i]==hi[i] && w[i] <= 0) { n2++; // ok } else if (x[i] >= lo[i] && x[i] <= hi[i] && w[i] == 0) { n3++; // ok } else { dDebug (0,"FAILED: i=%d x=%.4e w=%.4e lo=%.4e hi=%.4e",i, x[i],w[i],lo[i],hi[i]); } } // pacifier printf ("passed: NL=%3d NH=%3d C=%3d ",n1,n2,n3); printf ("time=%10.3f ms avg=%10.4f\n",time * 1000.0,average); } UNALLOCA (A); UNALLOCA (x); UNALLOCA (b); UNALLOCA (w); UNALLOCA (lo); UNALLOCA (hi); UNALLOCA (A2); UNALLOCA (b2); UNALLOCA (lo2); UNALLOCA (hi2); UNALLOCA (tmp1); UNALLOCA (tmp2); } alien-arena-7.66+dfsg/source/unix/odesrc/testing.h0000600000175000017500000000542612161402010021201 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* stuff used for testing */ #ifndef _ODE_TESTING_H_ #define _ODE_TESTING_H_ #include #include "array.h" // compare a sequence of named matrices/vectors, i.e. to make sure that two // different pieces of code are giving the same results. class dMatrixComparison { struct dMatInfo; dArray mat; int afterfirst,index; public: dMatrixComparison(); ~dMatrixComparison(); dReal nextMatrix (dReal *A, int n, int m, int lower_tri, const char *name, ...); // add a new n*m matrix A to the sequence. the name of the matrix is given // by the printf-style arguments (name,...). if this is the first sequence // then this object will simply record the matrices and return 0. // if this the second or subsequent sequence then this object will compare // the matrices with the first sequence, and report any differences. // the matrix error will be returned. if `lower_tri' is 1 then only the // lower triangle of the matrix (including the diagonal) will be compared // (the matrix must be square). void end(); // end a sequence. void reset(); // restarts the object, so the next sequence will be the first sequence. void dump(); // print out info about all the matrices in the sequence }; #endif alien-arena-7.66+dfsg/source/unix/odesrc/collision_trimesh_plane.cpp0000600000175000017500000001506512161402010024764 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ // TriMesh - Plane collider by David Walters, July 2006 #include #include #include #include #include "config.h" #if dTRIMESH_ENABLED #include "collision_util.h" #include "collision_std.h" #include "collision_trimesh_internal.h" #if dTRIMESH_OPCODE int dCollideTrimeshPlane( dxGeom *o1, dxGeom *o2, int flags, dContactGeom* contacts, int skip ) { dIASSERT( skip >= (int)sizeof( dContactGeom ) ); dIASSERT( o1->type == dTriMeshClass ); dIASSERT( o2->type == dPlaneClass ); dIASSERT ((flags & NUMC_MASK) >= 1); // Alias pointers to the plane and trimesh dxTriMesh* trimesh = (dxTriMesh*)( o1 ); dxPlane* plane = (dxPlane*)( o2 ); int contact_count = 0; // Cache the maximum contact count. const int contact_max = ( flags & NUMC_MASK ); // Cache trimesh position and rotation. const dVector3& trimesh_pos = *(const dVector3*)dGeomGetPosition( trimesh ); const dMatrix3& trimesh_R = *(const dMatrix3*)dGeomGetRotation( trimesh ); // // For all triangles. // // Cache the triangle count. const int tri_count = trimesh->Data->Mesh.GetNbTriangles(); VertexPointers VP; ConversionArea VC; dReal alpha; dVector3 vertex; #if !defined(dSINGLE) || 1 dVector3 int_vertex; // Intermediate vertex for double precision mode. #endif // dSINGLE // For each triangle for ( int t = 0; t < tri_count; ++t ) { // Get triangle, which should also use callback. trimesh->Data->Mesh.GetTriangle( VP, t, VC); // For each vertex. for ( int v = 0; v < 3; ++v ) { // // Get Vertex // #if defined(dSINGLE) && 0 // Always assign via intermediate array as otherwise it is an incapsulation violation dMULTIPLY0_331( vertex, trimesh_R, (float*)( VP.Vertex[ v ] ) ); #else // dDOUBLE || 1 // OPCODE data is in single precision format. int_vertex[ 0 ] = VP.Vertex[ v ]->x; int_vertex[ 1 ] = VP.Vertex[ v ]->y; int_vertex[ 2 ] = VP.Vertex[ v ]->z; dMULTIPLY0_331( vertex, trimesh_R, int_vertex ); #endif // dSINGLE/dDOUBLE vertex[ 0 ] += trimesh_pos[ 0 ]; vertex[ 1 ] += trimesh_pos[ 1 ]; vertex[ 2 ] += trimesh_pos[ 2 ]; // // Collision? // // If alpha < 0 then point is if front of plane. i.e. no contact // If alpha = 0 then the point is on the plane alpha = plane->p[ 3 ] - dDOT( plane->p, vertex ); // If alpha > 0 the point is behind the plane. CONTACT! if ( alpha > 0 ) { // Alias the contact dContactGeom* contact = SAFECONTACT( flags, contacts, contact_count, skip ); contact->pos[ 0 ] = vertex[ 0 ]; contact->pos[ 1 ] = vertex[ 1 ]; contact->pos[ 2 ] = vertex[ 2 ]; contact->normal[ 0 ] = plane->p[ 0 ]; contact->normal[ 1 ] = plane->p[ 1 ]; contact->normal[ 2 ] = plane->p[ 2 ]; contact->depth = alpha; contact->g1 = trimesh; contact->g2 = plane; contact->side1 = t; contact->side2 = -1; ++contact_count; // All contact slots are full? if ( contact_count >= contact_max ) return contact_count; // <=== STOP HERE } } } // Return contact count. return contact_count; } #endif // dTRIMESH_OPCODE #if dTRIMESH_GIMPACT int dCollideTrimeshPlane( dxGeom *o1, dxGeom *o2, int flags, dContactGeom* contacts, int skip ) { dIASSERT( skip >= (int)sizeof( dContactGeom ) ); dIASSERT( o1->type == dTriMeshClass ); dIASSERT( o2->type == dPlaneClass ); dIASSERT ((flags & NUMC_MASK) >= 1); // Alias pointers to the plane and trimesh dxTriMesh* trimesh = (dxTriMesh*)( o1 ); dVector4 plane; dGeomPlaneGetParams(o2, plane); o1 -> recomputeAABB(); o2 -> recomputeAABB(); //Find collision GDYNAMIC_ARRAY collision_result; GIM_CREATE_TRIMESHPLANE_CONTACTS(collision_result); gim_trimesh_plane_collisionODE(&trimesh->m_collision_trimesh,plane,&collision_result); if(collision_result.m_size == 0 ) { GIM_DYNARRAY_DESTROY(collision_result); return 0; } unsigned int contactcount = collision_result.m_size; unsigned int contactmax = (unsigned int)(flags & NUMC_MASK); if (contactcount > contactmax) { contactcount = contactmax; } dContactGeom* pcontact; vec4f * planecontact_results = GIM_DYNARRAY_POINTER(vec4f,collision_result); for(unsigned int i = 0; i < contactcount; i++ ) { pcontact = SAFECONTACT(flags, contacts, i, skip); pcontact->pos[0] = (*planecontact_results)[0]; pcontact->pos[1] = (*planecontact_results)[1]; pcontact->pos[2] = (*planecontact_results)[2]; pcontact->pos[3] = REAL(1.0); pcontact->normal[0] = plane[0]; pcontact->normal[1] = plane[1]; pcontact->normal[2] = plane[2]; pcontact->normal[3] = 0; pcontact->depth = (*planecontact_results)[3]; pcontact->g1 = o1; // trimesh geom pcontact->g2 = o2; // plane geom pcontact->side1 = -1; // note: don't have the triangle index, but OPCODE *does* do this properly pcontact->side2 = -1; planecontact_results++; } GIM_DYNARRAY_DESTROY(collision_result); return (int)contactcount; } #endif // dTRIMESH_GIMPACT #endif // dTRIMESH_ENABLED alien-arena-7.66+dfsg/source/unix/odesrc/memory.cpp0000600000175000017500000000523412161402010021364 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include #include "config.h" #include #include static dAllocFunction *allocfn = 0; static dReallocFunction *reallocfn = 0; static dFreeFunction *freefn = 0; #ifdef __MINGW32__ /* this is a guard against AC_FUNC_MALLOC and AC_FUNC_REALLOC which break cross compilation, no issues in native MSYS. */ #undef malloc #undef realloc #endif void dSetAllocHandler (dAllocFunction *fn) { allocfn = fn; } void dSetReallocHandler (dReallocFunction *fn) { reallocfn = fn; } void dSetFreeHandler (dFreeFunction *fn) { freefn = fn; } dAllocFunction *dGetAllocHandler() { return allocfn; } dReallocFunction *dGetReallocHandler() { return reallocfn; } dFreeFunction *dGetFreeHandler() { return freefn; } void * dAlloc (size_t size) { if (allocfn) return allocfn (size); else return malloc (size); } void * dRealloc (void *ptr, size_t oldsize, size_t newsize) { if (reallocfn) return reallocfn (ptr,oldsize,newsize); else return realloc (ptr,newsize); } void dFree (void *ptr, size_t size) { if (!ptr) return; if (freefn) freefn (ptr,size); else free (ptr); } alien-arena-7.66+dfsg/source/unix/odesrc/misc.cpp0000600000175000017500000001052112161402010021002 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include #include "config.h" #include #include //**************************************************************************** // random numbers static unsigned long seed = 0; unsigned long dRand() { seed = (1664525L*seed + 1013904223L) & 0xffffffff; return seed; } unsigned long dRandGetSeed() { return seed; } void dRandSetSeed (unsigned long s) { seed = s; } int dTestRand() { unsigned long oldseed = seed; int ret = 1; seed = 0; if (dRand() != 0x3c6ef35f || dRand() != 0x47502932 || dRand() != 0xd1ccf6e9 || dRand() != 0xaaf95334 || dRand() != 0x6252e503) ret = 0; seed = oldseed; return ret; } // adam's all-int straightforward(?) dRandInt (0..n-1) int dRandInt (int n) { // seems good; xor-fold and modulus const unsigned long un = n; unsigned long r = dRand(); // note: probably more aggressive than it needs to be -- might be // able to get away without one or two of the innermost branches. if (un <= 0x00010000UL) { r ^= (r >> 16); if (un <= 0x00000100UL) { r ^= (r >> 8); if (un <= 0x00000010UL) { r ^= (r >> 4); if (un <= 0x00000004UL) { r ^= (r >> 2); if (un <= 0x00000002UL) { r ^= (r >> 1); } } } } } return (int) (r % un); } dReal dRandReal() { return ((dReal) dRand()) / ((dReal) 0xffffffff); } //**************************************************************************** // matrix utility stuff void dPrintMatrix (const dReal *A, int n, int m, char *fmt, FILE *f) { int i,j; int skip = dPAD(m); for (i=0; i max) max = diff; } } return max; } dReal dMaxDifferenceLowerTriangle (const dReal *A, const dReal *B, int n) { int i,j; int skip = dPAD(n); dReal diff,max; max = 0; for (i=0; i max) max = diff; } } return max; } alien-arena-7.66+dfsg/source/unix/odesrc/fastldlt.c0000600000175000017500000002141712161402010021332 0ustar zero79zero79/* generated code, do not edit. */ #include "ode/matrix.h" /* solve L*X=B, with B containing 1 right hand sides. * L is an n*n lower triangular matrix with ones on the diagonal. * L is stored by rows and its leading dimension is lskip. * B is an n*1 matrix that contains the right hand sides. * B is stored by columns and its leading dimension is also lskip. * B is overwritten with X. * this processes blocks of 2*2. * if this is in the factorizer source file, n must be a multiple of 2. */ static void dSolveL1_1 (const dReal *L, dReal *B, int n, int lskip1) { /* declare variables - Z matrix, p and q vectors, etc */ dReal Z11,m11,Z21,m21,p1,q1,p2,*ex; const dReal *ell; int i,j; /* compute all 2 x 1 blocks of X */ for (i=0; i < n; i+=2) { /* compute all 2 x 1 block of X, from rows i..i+2-1 */ /* set the Z matrix to 0 */ Z11=0; Z21=0; ell = L + i*lskip1; ex = B; /* the inner loop that computes outer products and adds them to Z */ for (j=i-2; j >= 0; j -= 2) { /* compute outer product and add it to the Z matrix */ p1=ell[0]; q1=ex[0]; m11 = p1 * q1; p2=ell[lskip1]; m21 = p2 * q1; Z11 += m11; Z21 += m21; /* compute outer product and add it to the Z matrix */ p1=ell[1]; q1=ex[1]; m11 = p1 * q1; p2=ell[1+lskip1]; m21 = p2 * q1; /* advance pointers */ ell += 2; ex += 2; Z11 += m11; Z21 += m21; /* end of inner loop */ } /* compute left-over iterations */ j += 2; for (; j > 0; j--) { /* compute outer product and add it to the Z matrix */ p1=ell[0]; q1=ex[0]; m11 = p1 * q1; p2=ell[lskip1]; m21 = p2 * q1; /* advance pointers */ ell += 1; ex += 1; Z11 += m11; Z21 += m21; } /* finish computing the X(i) block */ Z11 = ex[0] - Z11; ex[0] = Z11; p1 = ell[lskip1]; Z21 = ex[1] - Z21 - p1*Z11; ex[1] = Z21; /* end of outer loop */ } } /* solve L*X=B, with B containing 2 right hand sides. * L is an n*n lower triangular matrix with ones on the diagonal. * L is stored by rows and its leading dimension is lskip. * B is an n*2 matrix that contains the right hand sides. * B is stored by columns and its leading dimension is also lskip. * B is overwritten with X. * this processes blocks of 2*2. * if this is in the factorizer source file, n must be a multiple of 2. */ static void dSolveL1_2 (const dReal *L, dReal *B, int n, int lskip1) { /* declare variables - Z matrix, p and q vectors, etc */ dReal Z11,m11,Z12,m12,Z21,m21,Z22,m22,p1,q1,p2,q2,*ex; const dReal *ell; int i,j; /* compute all 2 x 2 blocks of X */ for (i=0; i < n; i+=2) { /* compute all 2 x 2 block of X, from rows i..i+2-1 */ /* set the Z matrix to 0 */ Z11=0; Z12=0; Z21=0; Z22=0; ell = L + i*lskip1; ex = B; /* the inner loop that computes outer products and adds them to Z */ for (j=i-2; j >= 0; j -= 2) { /* compute outer product and add it to the Z matrix */ p1=ell[0]; q1=ex[0]; m11 = p1 * q1; q2=ex[lskip1]; m12 = p1 * q2; p2=ell[lskip1]; m21 = p2 * q1; m22 = p2 * q2; Z11 += m11; Z12 += m12; Z21 += m21; Z22 += m22; /* compute outer product and add it to the Z matrix */ p1=ell[1]; q1=ex[1]; m11 = p1 * q1; q2=ex[1+lskip1]; m12 = p1 * q2; p2=ell[1+lskip1]; m21 = p2 * q1; m22 = p2 * q2; /* advance pointers */ ell += 2; ex += 2; Z11 += m11; Z12 += m12; Z21 += m21; Z22 += m22; /* end of inner loop */ } /* compute left-over iterations */ j += 2; for (; j > 0; j--) { /* compute outer product and add it to the Z matrix */ p1=ell[0]; q1=ex[0]; m11 = p1 * q1; q2=ex[lskip1]; m12 = p1 * q2; p2=ell[lskip1]; m21 = p2 * q1; m22 = p2 * q2; /* advance pointers */ ell += 1; ex += 1; Z11 += m11; Z12 += m12; Z21 += m21; Z22 += m22; } /* finish computing the X(i) block */ Z11 = ex[0] - Z11; ex[0] = Z11; Z12 = ex[lskip1] - Z12; ex[lskip1] = Z12; p1 = ell[lskip1]; Z21 = ex[1] - Z21 - p1*Z11; ex[1] = Z21; Z22 = ex[1+lskip1] - Z22 - p1*Z12; ex[1+lskip1] = Z22; /* end of outer loop */ } } void dFactorLDLT (dReal *A, dReal *d, int n, int nskip1) { int i,j; dReal sum,*ell,*dee,dd,p1,p2,q1,q2,Z11,m11,Z21,m21,Z22,m22; if (n < 1) return; for (i=0; i<=n-2; i += 2) { /* solve L*(D*l)=a, l is scaled elements in 2 x i block at A(i,0) */ dSolveL1_2 (A,A+i*nskip1,i,nskip1); /* scale the elements in a 2 x i block at A(i,0), and also */ /* compute Z = the outer product matrix that we'll need. */ Z11 = 0; Z21 = 0; Z22 = 0; ell = A+i*nskip1; dee = d; for (j=i-6; j >= 0; j -= 6) { p1 = ell[0]; p2 = ell[nskip1]; dd = dee[0]; q1 = p1*dd; q2 = p2*dd; ell[0] = q1; ell[nskip1] = q2; m11 = p1*q1; m21 = p2*q1; m22 = p2*q2; Z11 += m11; Z21 += m21; Z22 += m22; p1 = ell[1]; p2 = ell[1+nskip1]; dd = dee[1]; q1 = p1*dd; q2 = p2*dd; ell[1] = q1; ell[1+nskip1] = q2; m11 = p1*q1; m21 = p2*q1; m22 = p2*q2; Z11 += m11; Z21 += m21; Z22 += m22; p1 = ell[2]; p2 = ell[2+nskip1]; dd = dee[2]; q1 = p1*dd; q2 = p2*dd; ell[2] = q1; ell[2+nskip1] = q2; m11 = p1*q1; m21 = p2*q1; m22 = p2*q2; Z11 += m11; Z21 += m21; Z22 += m22; p1 = ell[3]; p2 = ell[3+nskip1]; dd = dee[3]; q1 = p1*dd; q2 = p2*dd; ell[3] = q1; ell[3+nskip1] = q2; m11 = p1*q1; m21 = p2*q1; m22 = p2*q2; Z11 += m11; Z21 += m21; Z22 += m22; p1 = ell[4]; p2 = ell[4+nskip1]; dd = dee[4]; q1 = p1*dd; q2 = p2*dd; ell[4] = q1; ell[4+nskip1] = q2; m11 = p1*q1; m21 = p2*q1; m22 = p2*q2; Z11 += m11; Z21 += m21; Z22 += m22; p1 = ell[5]; p2 = ell[5+nskip1]; dd = dee[5]; q1 = p1*dd; q2 = p2*dd; ell[5] = q1; ell[5+nskip1] = q2; m11 = p1*q1; m21 = p2*q1; m22 = p2*q2; Z11 += m11; Z21 += m21; Z22 += m22; ell += 6; dee += 6; } /* compute left-over iterations */ j += 6; for (; j > 0; j--) { p1 = ell[0]; p2 = ell[nskip1]; dd = dee[0]; q1 = p1*dd; q2 = p2*dd; ell[0] = q1; ell[nskip1] = q2; m11 = p1*q1; m21 = p2*q1; m22 = p2*q2; Z11 += m11; Z21 += m21; Z22 += m22; ell++; dee++; } /* solve for diagonal 2 x 2 block at A(i,i) */ Z11 = ell[0] - Z11; Z21 = ell[nskip1] - Z21; Z22 = ell[1+nskip1] - Z22; dee = d + i; /* factorize 2 x 2 block Z,dee */ /* factorize row 1 */ dee[0] = dRecip(Z11); /* factorize row 2 */ sum = 0; q1 = Z21; q2 = q1 * dee[0]; Z21 = q2; sum += q1*q2; dee[1] = dRecip(Z22 - sum); /* done factorizing 2 x 2 block */ ell[nskip1] = Z21; } /* compute the (less than 2) rows at the bottom */ switch (n-i) { case 0: break; case 1: dSolveL1_1 (A,A+i*nskip1,i,nskip1); /* scale the elements in a 1 x i block at A(i,0), and also */ /* compute Z = the outer product matrix that we'll need. */ Z11 = 0; ell = A+i*nskip1; dee = d; for (j=i-6; j >= 0; j -= 6) { p1 = ell[0]; dd = dee[0]; q1 = p1*dd; ell[0] = q1; m11 = p1*q1; Z11 += m11; p1 = ell[1]; dd = dee[1]; q1 = p1*dd; ell[1] = q1; m11 = p1*q1; Z11 += m11; p1 = ell[2]; dd = dee[2]; q1 = p1*dd; ell[2] = q1; m11 = p1*q1; Z11 += m11; p1 = ell[3]; dd = dee[3]; q1 = p1*dd; ell[3] = q1; m11 = p1*q1; Z11 += m11; p1 = ell[4]; dd = dee[4]; q1 = p1*dd; ell[4] = q1; m11 = p1*q1; Z11 += m11; p1 = ell[5]; dd = dee[5]; q1 = p1*dd; ell[5] = q1; m11 = p1*q1; Z11 += m11; ell += 6; dee += 6; } /* compute left-over iterations */ j += 6; for (; j > 0; j--) { p1 = ell[0]; dd = dee[0]; q1 = p1*dd; ell[0] = q1; m11 = p1*q1; Z11 += m11; ell++; dee++; } /* solve for diagonal 1 x 1 block at A(i,i) */ Z11 = ell[0] - Z11; dee = d + i; /* factorize 1 x 1 block Z,dee */ /* factorize row 1 */ dee[0] = dRecip(Z11); /* done factorizing 1 x 1 block */ break; default: *((char*)0)=0; /* this should never happen! */ } } alien-arena-7.66+dfsg/source/unix/odesrc/collision_trimesh_sphere.cpp0000600000175000017500000004123312161402010025147 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ // TriMesh code by Erwin de Vries. #include #include #include #include #include "collision_util.h" #if dTRIMESH_ENABLED #include "collision_trimesh_internal.h" #if dTRIMESH_OPCODE #define MERGECONTACTS //#define MERGECONTACTNORMALS // Ripped from Opcode 1.1. static bool GetContactData(const dVector3& Center, dReal Radius, const dVector3 Origin, const dVector3 Edge0, const dVector3 Edge1, dReal& Dist, dReal& u, dReal& v){ // now onto the bulk of the collision... dVector3 Diff; Diff[0] = Origin[0] - Center[0]; Diff[1] = Origin[1] - Center[1]; Diff[2] = Origin[2] - Center[2]; Diff[3] = Origin[3] - Center[3]; dReal A00 = dDOT(Edge0, Edge0); dReal A01 = dDOT(Edge0, Edge1); dReal A11 = dDOT(Edge1, Edge1); dReal B0 = dDOT(Diff, Edge0); dReal B1 = dDOT(Diff, Edge1); dReal C = dDOT(Diff, Diff); dReal Det = dFabs(A00 * A11 - A01 * A01); u = A01 * B1 - A11 * B0; v = A01 * B0 - A00 * B1; dReal DistSq; if (u + v <= Det){ if(u < REAL(0.0)){ if(v < REAL(0.0)){ // region 4 if(B0 < REAL(0.0)){ v = REAL(0.0); if (-B0 >= A00){ u = REAL(1.0); DistSq = A00 + REAL(2.0) * B0 + C; } else{ u = -B0 / A00; DistSq = B0 * u + C; } } else{ u = REAL(0.0); if(B1 >= REAL(0.0)){ v = REAL(0.0); DistSq = C; } else if(-B1 >= A11){ v = REAL(1.0); DistSq = A11 + REAL(2.0) * B1 + C; } else{ v = -B1 / A11; DistSq = B1 * v + C; } } } else{ // region 3 u = REAL(0.0); if(B1 >= REAL(0.0)){ v = REAL(0.0); DistSq = C; } else if(-B1 >= A11){ v = REAL(1.0); DistSq = A11 + REAL(2.0) * B1 + C; } else{ v = -B1 / A11; DistSq = B1 * v + C; } } } else if(v < REAL(0.0)){ // region 5 v = REAL(0.0); if (B0 >= REAL(0.0)){ u = REAL(0.0); DistSq = C; } else if (-B0 >= A00){ u = REAL(1.0); DistSq = A00 + REAL(2.0) * B0 + C; } else{ u = -B0 / A00; DistSq = B0 * u + C; } } else{ // region 0 // minimum at interior point if (Det == REAL(0.0)){ u = REAL(0.0); v = REAL(0.0); DistSq = FLT_MAX; } else{ dReal InvDet = REAL(1.0) / Det; u *= InvDet; v *= InvDet; DistSq = u * (A00 * u + A01 * v + REAL(2.0) * B0) + v * (A01 * u + A11 * v + REAL(2.0) * B1) + C; } } } else{ dReal Tmp0, Tmp1, Numer, Denom; if(u < REAL(0.0)){ // region 2 Tmp0 = A01 + B0; Tmp1 = A11 + B1; if (Tmp1 > Tmp0){ Numer = Tmp1 - Tmp0; Denom = A00 - REAL(2.0) * A01 + A11; if (Numer >= Denom){ u = REAL(1.0); v = REAL(0.0); DistSq = A00 + REAL(2.0) * B0 + C; } else{ u = Numer / Denom; v = REAL(1.0) - u; DistSq = u * (A00 * u + A01 * v + REAL(2.0) * B0) + v * (A01 * u + A11 * v + REAL(2.0) * B1) + C; } } else{ u = REAL(0.0); if(Tmp1 <= REAL(0.0)){ v = REAL(1.0); DistSq = A11 + REAL(2.0) * B1 + C; } else if(B1 >= REAL(0.0)){ v = REAL(0.0); DistSq = C; } else{ v = -B1 / A11; DistSq = B1 * v + C; } } } else if(v < REAL(0.0)){ // region 6 Tmp0 = A01 + B1; Tmp1 = A00 + B0; if (Tmp1 > Tmp0){ Numer = Tmp1 - Tmp0; Denom = A00 - REAL(2.0) * A01 + A11; if (Numer >= Denom){ v = REAL(1.0); u = REAL(0.0); DistSq = A11 + REAL(2.0) * B1 + C; } else{ v = Numer / Denom; u = REAL(1.0) - v; DistSq = u * (A00 * u + A01 * v + REAL(2.0) * B0) + v * (A01 * u + A11 * v + REAL(2.0) * B1) + C; } } else{ v = REAL(0.0); if (Tmp1 <= REAL(0.0)){ u = REAL(1.0); DistSq = A00 + REAL(2.0) * B0 + C; } else if(B0 >= REAL(0.0)){ u = REAL(0.0); DistSq = C; } else{ u = -B0 / A00; DistSq = B0 * u + C; } } } else{ // region 1 Numer = A11 + B1 - A01 - B0; if (Numer <= REAL(0.0)){ u = REAL(0.0); v = REAL(1.0); DistSq = A11 + REAL(2.0) * B1 + C; } else{ Denom = A00 - REAL(2.0) * A01 + A11; if (Numer >= Denom){ u = REAL(1.0); v = REAL(0.0); DistSq = A00 + REAL(2.0) * B0 + C; } else{ u = Numer / Denom; v = REAL(1.0) - u; DistSq = u * (A00 * u + A01 * v + REAL(2.0) * B0) + v * (A01 * u + A11 * v + REAL(2.0) * B1) + C; } } } } Dist = dSqrt(dFabs(DistSq)); if (Dist <= Radius){ Dist = Radius - Dist; return true; } else return false; } int dCollideSTL(dxGeom* g1, dxGeom* SphereGeom, int Flags, dContactGeom* Contacts, int Stride){ dIASSERT (Stride >= (int)sizeof(dContactGeom)); dIASSERT (g1->type == dTriMeshClass); dIASSERT (SphereGeom->type == dSphereClass); dIASSERT ((Flags & NUMC_MASK) >= 1); dxTriMesh* TriMesh = (dxTriMesh*)g1; // Init const dVector3& TLPosition = *(const dVector3*)dGeomGetPosition(TriMesh); const dMatrix3& TLRotation = *(const dMatrix3*)dGeomGetRotation(TriMesh); const unsigned uiTLSKind = TriMesh->getParentSpaceTLSKind(); dIASSERT(uiTLSKind == SphereGeom->getParentSpaceTLSKind()); // The colliding spaces must use matching cleanup method TrimeshCollidersCache *pccColliderCache = GetTrimeshCollidersCache(uiTLSKind); SphereCollider& Collider = pccColliderCache->_SphereCollider; const dVector3& Position = *(const dVector3*)dGeomGetPosition(SphereGeom); dReal Radius = dGeomSphereGetRadius(SphereGeom); // Sphere Sphere Sphere; Sphere.mCenter.x = Position[0]; Sphere.mCenter.y = Position[1]; Sphere.mCenter.z = Position[2]; Sphere.mRadius = Radius; Matrix4x4 amatrix; // TC results if (TriMesh->doSphereTC) { dxTriMesh::SphereTC* sphereTC = 0; for (int i = 0; i < TriMesh->SphereTCCache.size(); i++){ if (TriMesh->SphereTCCache[i].Geom == SphereGeom){ sphereTC = &TriMesh->SphereTCCache[i]; break; } } if (!sphereTC){ TriMesh->SphereTCCache.push(dxTriMesh::SphereTC()); sphereTC = &TriMesh->SphereTCCache[TriMesh->SphereTCCache.size() - 1]; sphereTC->Geom = SphereGeom; } // Intersect Collider.SetTemporalCoherence(true); Collider.Collide(*sphereTC, Sphere, TriMesh->Data->BVTree, null, &MakeMatrix(TLPosition, TLRotation, amatrix)); } else { Collider.SetTemporalCoherence(false); Collider.Collide(pccColliderCache->defaultSphereCache, Sphere, TriMesh->Data->BVTree, null, &MakeMatrix(TLPosition, TLRotation, amatrix)); } if (! Collider.GetContactStatus()) { // no collision occurred return 0; } // get results int TriCount = Collider.GetNbTouchedPrimitives(); const int* Triangles = (const int*)Collider.GetTouchedPrimitives(); if (TriCount != 0){ if (TriMesh->ArrayCallback != null){ TriMesh->ArrayCallback(TriMesh, SphereGeom, Triangles, TriCount); } int OutTriCount = 0; for (int i = 0; i < TriCount; i++){ if (OutTriCount == (Flags & NUMC_MASK)){ break; } const int TriIndex = Triangles[i]; dVector3 dv[3]; if (!Callback(TriMesh, SphereGeom, TriIndex)) continue; FetchTriangle(TriMesh, TriIndex, TLPosition, TLRotation, dv); dVector3& v0 = dv[0]; dVector3& v1 = dv[1]; dVector3& v2 = dv[2]; dVector3 vu; vu[0] = v1[0] - v0[0]; vu[1] = v1[1] - v0[1]; vu[2] = v1[2] - v0[2]; vu[3] = REAL(0.0); dVector3 vv; vv[0] = v2[0] - v0[0]; vv[1] = v2[1] - v0[1]; vv[2] = v2[2] - v0[2]; vv[3] = REAL(0.0); // Get plane coefficients dVector4 Plane; dCROSS(Plane, =, vu, vv); // Even though all triangles might be initially valid, // a triangle may degenerate into a segment after applying // space transformation. if (!dSafeNormalize3(Plane)) { continue; } /* If the center of the sphere is within the positive halfspace of the * triangle's plane, allow a contact to be generated. * If the center of the sphere made it into the positive halfspace of a * back-facing triangle, then the physics update and/or velocity needs * to be adjusted (penetration has occured anyway). */ dReal side = dDOT(Plane,Position) - dDOT(Plane, v0); if(side < REAL(0.0)) { continue; } dReal Depth; dReal u, v; if (!GetContactData(Position, Radius, v0, vu, vv, Depth, u, v)){ continue; // Sphere doesn't hit triangle } if (Depth < REAL(0.0)){ continue; // Negative depth does not produce a contact } dVector3 ContactPos; dReal w = REAL(1.0) - u - v; ContactPos[0] = (v0[0] * w) + (v1[0] * u) + (v2[0] * v); ContactPos[1] = (v0[1] * w) + (v1[1] * u) + (v2[1] * v); ContactPos[2] = (v0[2] * w) + (v1[2] * u) + (v2[2] * v); // Depth returned from GetContactData is depth along // contact point - sphere center direction // we'll project it to contact normal dVector3 dir; dir[0] = Position[0]-ContactPos[0]; dir[1] = Position[1]-ContactPos[1]; dir[2] = Position[2]-ContactPos[2]; dReal dirProj = dDOT(dir, Plane) / dSqrt(dDOT(dir, dir)); // Since Depth already had a requirement to be non-negative, // negative direction projections should not be allowed as well, // as otherwise the multiplication will result in negative contact depth. if (dirProj < REAL(0.0)){ continue; // Zero contact depth could be ignored } dContactGeom* Contact = SAFECONTACT(Flags, Contacts, OutTriCount, Stride); Contact->pos[0] = ContactPos[0]; Contact->pos[1] = ContactPos[1]; Contact->pos[2] = ContactPos[2]; Contact->pos[3] = REAL(0.0); // Using normal as plane (reversed) Contact->normal[0] = -Plane[0]; Contact->normal[1] = -Plane[1]; Contact->normal[2] = -Plane[2]; Contact->normal[3] = REAL(0.0); Contact->depth = Depth * dirProj; //Contact->depth = Radius - side; // (mg) penetration depth is distance along normal not shortest distance #if !defined MERGECONTACTS // Merge all contacts into 1 Contact->g1 = TriMesh; Contact->g2 = SphereGeom; Contact->side2 = -1; #endif // Otherwise assigned later Contact->side1 = TriIndex; OutTriCount++; } #if defined MERGECONTACTS // Merge all contacts into 1 if (OutTriCount > 0){ dContactGeom* Contact = SAFECONTACT(Flags, Contacts, 0, Stride); Contact->g1 = TriMesh; Contact->g2 = SphereGeom; Contact->side2 = -1; if (OutTriCount > 1 && !(Flags & CONTACTS_UNIMPORTANT)){ dVector3 pos; pos[0] = Contact->pos[0]; pos[1] = Contact->pos[1]; pos[2] = Contact->pos[2]; dVector3 normal; normal[0] = Contact->normal[0] * Contact->depth; normal[1] = Contact->normal[1] * Contact->depth; normal[2] = Contact->normal[2] * Contact->depth; int TriIndex = Contact->side1; for (int i = 1; i < OutTriCount; i++){ dContactGeom* TempContact = SAFECONTACT(Flags, Contacts, i, Stride); pos[0] += TempContact->pos[0]; pos[1] += TempContact->pos[1]; pos[2] += TempContact->pos[2]; normal[0] += TempContact->normal[0] * TempContact->depth; normal[1] += TempContact->normal[1] * TempContact->depth; normal[2] += TempContact->normal[2] * TempContact->depth; TriIndex = (TriMesh->TriMergeCallback) ? TriMesh->TriMergeCallback(TriMesh, TriIndex, TempContact->side1) : -1; } Contact->side1 = TriIndex; Contact->pos[0] = pos[0] / OutTriCount; Contact->pos[1] = pos[1] / OutTriCount; Contact->pos[2] = pos[2] / OutTriCount; // Remember to divide in square space. Contact->depth = dSqrt(dDOT(normal, normal) / OutTriCount); if (Contact->depth > dEpsilon) { // otherwise the normal is too small dVector3Copy(normal, Contact->normal); dNormalize3(Contact->normal); } // otherwise original Contact's normal would be used and it should be already normalized } return 1; } else return 0; #elif defined MERGECONTACTNORMALS // Merge all normals, and distribute between all contacts if (OutTriCount != 0){ if (OutTriCount != 1 && !(Flags & CONTACTS_UNIMPORTANT)){ dVector3 Normal; dContactGeom* FirstContact = SAFECONTACT(Flags, Contacts, 0, Stride); Normal[0] = FirstContact->normal[0] * FirstContact->depth; Normal[1] = FirstContact->normal[1] * FirstContact->depth; Normal[2] = FirstContact->normal[2] * FirstContact->depth; Normal[3] = FirstContact->normal[3] * FirstContact->depth; for (int i = 1; i < OutTriCount; i++){ dContactGeom* Contact = SAFECONTACT(Flags, Contacts, i, Stride); Normal[0] += Contact->normal[0] * Contact->depth; Normal[1] += Contact->normal[1] * Contact->depth; Normal[2] += Contact->normal[2] * Contact->depth; Normal[3] += Contact->normal[3] * Contact->depth; } dNormalize3(Normal); for (int i = 0; i < OutTriCount; i++){ dContactGeom* Contact = SAFECONTACT(Flags, Contacts, i, Stride); Contact->normal[0] = Normal[0]; Contact->normal[1] = Normal[1]; Contact->normal[2] = Normal[2]; Contact->normal[3] = Normal[3]; } } return OutTriCount; } else return 0; #else // none of MERGECONTACTS and MERGECONTACTNORMALS // Just return return OutTriCount; #endif // MERGECONTACTS } else return 0; } #endif // dTRIMESH_OPCODE #if dTRIMESH_GIMPACT int dCollideSTL(dxGeom* g1, dxGeom* SphereGeom, int Flags, dContactGeom* Contacts, int Stride) { dIASSERT (Stride >= (int)sizeof(dContactGeom)); dIASSERT (g1->type == dTriMeshClass); dIASSERT (SphereGeom->type == dSphereClass); dIASSERT ((Flags & NUMC_MASK) >= 1); dxTriMesh* TriMesh = (dxTriMesh*)g1; dVector3& Position = *(dVector3*)dGeomGetPosition(SphereGeom); dReal Radius = dGeomSphereGetRadius(SphereGeom); //Create contact list GDYNAMIC_ARRAY trimeshcontacts; GIM_CREATE_CONTACT_LIST(trimeshcontacts); g1 -> recomputeAABB(); SphereGeom -> recomputeAABB(); //Collide trimeshes gim_trimesh_sphere_collisionODE(&TriMesh->m_collision_trimesh,Position,Radius,&trimeshcontacts); if(trimeshcontacts.m_size == 0) { GIM_DYNARRAY_DESTROY(trimeshcontacts); return 0; } GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts); unsigned contactcount = trimeshcontacts.m_size; unsigned maxcontacts = (unsigned)(Flags & NUMC_MASK); if (contactcount > maxcontacts) { contactcount = maxcontacts; } dContactGeom* pcontact; unsigned i; for (i=0;ipos[0] = ptrimeshcontacts->m_point[0]; pcontact->pos[1] = ptrimeshcontacts->m_point[1]; pcontact->pos[2] = ptrimeshcontacts->m_point[2]; pcontact->pos[3] = REAL(1.0); pcontact->normal[0] = ptrimeshcontacts->m_normal[0]; pcontact->normal[1] = ptrimeshcontacts->m_normal[1]; pcontact->normal[2] = ptrimeshcontacts->m_normal[2]; pcontact->normal[3] = 0; pcontact->depth = ptrimeshcontacts->m_depth; pcontact->g1 = g1; pcontact->g2 = SphereGeom; pcontact->side1 = ptrimeshcontacts->m_feature1; pcontact->side2 = -1; ptrimeshcontacts++; } GIM_DYNARRAY_DESTROY(trimeshcontacts); return (int)contactcount; } #endif // dTRIMESH_GIMPACT #endif // dTRIMESH_ENABLED alien-arena-7.66+dfsg/source/unix/odesrc/collision_space.cpp0000600000175000017500000005403512161402010023225 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* spaces */ #include #include #include #include #include "util.h" #include "collision_kernel.h" #include "collision_space_internal.h" #ifdef _MSC_VER #pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" #endif //**************************************************************************** // make the geom dirty by setting the GEOM_DIRTY and GEOM_BAD_AABB flags // and moving it to the front of the space's list. all the parents of a // dirty geom also become dirty. void dGeomMoved (dxGeom *geom) { dAASSERT (geom); // if geom is offset, mark it as needing a calculate if (geom->offset_posr) { geom->gflags |= GEOM_POSR_BAD; } // from the bottom of the space heirarchy up, process all clean geoms // turning them into dirty geoms. dxSpace *parent = geom->parent_space; while (parent && (geom->gflags & GEOM_DIRTY)==0) { CHECK_NOT_LOCKED (parent); geom->gflags |= GEOM_DIRTY | GEOM_AABB_BAD; parent->dirty (geom); geom = parent; parent = parent->parent_space; } // all the remaining dirty geoms must have their AABB_BAD flags set, to // ensure that their AABBs get recomputed while (geom) { geom->gflags |= GEOM_DIRTY | GEOM_AABB_BAD; CHECK_NOT_LOCKED (geom->parent_space); geom = geom->parent_space; } } #define GEOM_ENABLED(g) (((g)->gflags & GEOM_ENABLE_TEST_MASK) == GEOM_ENABLE_TEST_VALUE) //**************************************************************************** // dxSpace dxSpace::dxSpace (dSpaceID _space) : dxGeom (_space,0) { count = 0; first = 0; cleanup = 1; sublevel = 0; tls_kind = dSPACE_TLS_KIND_INIT_VALUE; current_index = 0; current_geom = 0; lock_count = 0; } dxSpace::~dxSpace() { CHECK_NOT_LOCKED (this); if (cleanup) { // note that destroying each geom will call remove() dxGeom *g,*n; for (g = first; g; g=n) { n = g->next; dGeomDestroy (g); } } else { dxGeom *g,*n; for (g = first; g; g=n) { n = g->next; remove (g); } } } void dxSpace::computeAABB() { if (first) { int i; dReal a[6]; a[0] = dInfinity; a[1] = -dInfinity; a[2] = dInfinity; a[3] = -dInfinity; a[4] = dInfinity; a[5] = -dInfinity; for (dxGeom *g=first; g; g=g->next) { g->recomputeAABB(); for (i=0; i<6; i += 2) if (g->aabb[i] < a[i]) a[i] = g->aabb[i]; for (i=1; i<6; i += 2) if (g->aabb[i] > a[i]) a[i] = g->aabb[i]; } memcpy(aabb,a,6*sizeof(dReal)); } else { dSetZero (aabb,6); } } // the dirty geoms are numbered 0..k, the clean geoms are numbered k+1..count-1 dxGeom *dxSpace::getGeom (int i) { dUASSERT (i >= 0 && i < count,"index out of range"); if (current_geom && current_index == i-1) { current_geom = current_geom->next; current_index = i; return current_geom; } else { dxGeom *g=first; for (int j=0; jnext; else return 0; } current_geom = g; current_index = i; return g; } } void dxSpace::add (dxGeom *geom) { CHECK_NOT_LOCKED (this); dAASSERT (geom); dUASSERT (geom->parent_space == 0 && geom->next == 0, "geom is already in a space"); // add geom->parent_space = this; geom->spaceAdd (&first); count++; // enumerator has been invalidated current_geom = 0; // new geoms are added to the front of the list and are always // considered to be dirty. as a consequence, this space and all its // parents are dirty too. geom->gflags |= GEOM_DIRTY | GEOM_AABB_BAD; dGeomMoved (this); } void dxSpace::remove (dxGeom *geom) { CHECK_NOT_LOCKED (this); dAASSERT (geom); dUASSERT (geom->parent_space == this,"object is not in this space"); // remove geom->spaceRemove(); count--; // safeguard geom->next = 0; geom->tome = 0; geom->parent_space = 0; // enumerator has been invalidated current_geom = 0; // the bounding box of this space (and that of all the parents) may have // changed as a consequence of the removal. dGeomMoved (this); } void dxSpace::dirty (dxGeom *geom) { geom->spaceRemove(); geom->spaceAdd (&first); } //**************************************************************************** // simple space - reports all n^2 object intersections struct dxSimpleSpace : public dxSpace { dxSimpleSpace (dSpaceID _space); void cleanGeoms(); void collide (void *data, dNearCallback *callback); void collide2 (void *data, dxGeom *geom, dNearCallback *callback); }; dxSimpleSpace::dxSimpleSpace (dSpaceID _space) : dxSpace (_space) { type = dSimpleSpaceClass; } void dxSimpleSpace::cleanGeoms() { // compute the AABBs of all dirty geoms, and clear the dirty flags lock_count++; for (dxGeom *g=first; g && (g->gflags & GEOM_DIRTY); g=g->next) { if (IS_SPACE(g)) { ((dxSpace*)g)->cleanGeoms(); } g->recomputeAABB(); g->gflags &= (~(GEOM_DIRTY|GEOM_AABB_BAD)); } lock_count--; } void dxSimpleSpace::collide (void *data, dNearCallback *callback) { dAASSERT (callback); lock_count++; cleanGeoms(); // intersect all bounding boxes for (dxGeom *g1=first; g1; g1=g1->next) { if (GEOM_ENABLED(g1)){ for (dxGeom *g2=g1->next; g2; g2=g2->next) { if (GEOM_ENABLED(g2)){ collideAABBs (g1,g2,data,callback); } } } } lock_count--; } void dxSimpleSpace::collide2 (void *data, dxGeom *geom, dNearCallback *callback) { dAASSERT (geom && callback); lock_count++; cleanGeoms(); geom->recomputeAABB(); // intersect bounding boxes for (dxGeom *g=first; g; g=g->next) { if (GEOM_ENABLED(g)){ collideAABBs (g,geom,data,callback); } } lock_count--; } //**************************************************************************** // utility stuff for hash table space // kind of silly, but oh well... #ifndef MAXINT #define MAXINT ((int)((((unsigned int)(-1)) << 1) >> 1)) #endif // prime[i] is the largest prime smaller than 2^i #define NUM_PRIMES 31 static const long int prime[NUM_PRIMES] = {1L,2L,3L,7L,13L,31L,61L,127L,251L,509L, 1021L,2039L,4093L,8191L,16381L,32749L,65521L,131071L,262139L, 524287L,1048573L,2097143L,4194301L,8388593L,16777213L,33554393L, 67108859L,134217689L,268435399L,536870909L,1073741789L}; // an axis aligned bounding box in the hash table struct dxAABB { dxAABB *next; // next in the list of all AABBs int level; // the level this is stored in (cell size = 2^level) int dbounds[6]; // AABB bounds, discretized to cell size dxGeom *geom; // corresponding geometry object (AABB stored here) int index; // index of this AABB, starting from 0 }; // a hash table node that represents an AABB that intersects a particular cell // at a particular level struct Node { Node *next; // next node in hash table collision list, 0 if none int x,y,z; // cell position in space, discretized to cell size dxAABB *aabb; // axis aligned bounding box that intersects this cell }; // return the `level' of an AABB. the AABB will be put into cells at this // level - the cell size will be 2^level. the level is chosen to be the // smallest value such that the AABB occupies no more than 8 cells, regardless // of its placement. this means that: // size/2 < q <= size // where q is the maximum AABB dimension. static int findLevel (dReal bounds[6]) { if (bounds[0] <= -dInfinity || bounds[1] >= dInfinity || bounds[2] <= -dInfinity || bounds[3] >= dInfinity || bounds[4] <= -dInfinity || bounds[5] >= dInfinity) { return MAXINT; } // compute q dReal q,q2; q = bounds[1] - bounds[0]; // x bounds q2 = bounds[3] - bounds[2]; // y bounds if (q2 > q) q = q2; q2 = bounds[5] - bounds[4]; // z bounds if (q2 > q) q = q2; // find level such that 0.5 * 2^level < q <= 2^level int level; frexp (q,&level); // q = (0.5 .. 1.0) * 2^level (definition of frexp) return level; } // find a virtual memory address for a cell at the given level and x,y,z // position. // @@@ currently this is not very sophisticated, e.g. the scaling // factors could be better designed to avoid collisions, and they should // probably depend on the hash table physical size. static unsigned long getVirtualAddress (int level, int x, int y, int z) { return level*1000 + x*100 + y*10 + z; } //**************************************************************************** // hash space struct dxHashSpace : public dxSpace { int global_minlevel; // smallest hash table level to put AABBs in int global_maxlevel; // objects that need a level larger than this will be // put in a "big objects" list instead of a hash table dxHashSpace (dSpaceID _space); void setLevels (int minlevel, int maxlevel); void getLevels (int *minlevel, int *maxlevel); void cleanGeoms(); void collide (void *data, dNearCallback *callback); void collide2 (void *data, dxGeom *geom, dNearCallback *callback); }; dxHashSpace::dxHashSpace (dSpaceID _space) : dxSpace (_space) { type = dHashSpaceClass; global_minlevel = -3; global_maxlevel = 10; } void dxHashSpace::setLevels (int minlevel, int maxlevel) { dAASSERT (minlevel <= maxlevel); global_minlevel = minlevel; global_maxlevel = maxlevel; } void dxHashSpace::getLevels (int *minlevel, int *maxlevel) { if (minlevel) *minlevel = global_minlevel; if (maxlevel) *maxlevel = global_maxlevel; } void dxHashSpace::cleanGeoms() { // compute the AABBs of all dirty geoms, and clear the dirty flags lock_count++; for (dxGeom *g=first; g && (g->gflags & GEOM_DIRTY); g=g->next) { if (IS_SPACE(g)) { ((dxSpace*)g)->cleanGeoms(); } g->recomputeAABB(); g->gflags &= (~(GEOM_DIRTY|GEOM_AABB_BAD)); } lock_count--; } void dxHashSpace::collide (void *data, dNearCallback *callback) { dAASSERT(this && callback); dxGeom *geom; dxAABB *aabb; int i,maxlevel; // 0 or 1 geoms can't collide with anything if (count < 2) return; lock_count++; cleanGeoms(); // create a list of auxiliary information for all geom axis aligned bounding // boxes. set the level for all AABBs. put AABBs larger than the space's // global_maxlevel in the big_boxes list, check everything else against // that list at the end. for AABBs that are not too big, record the maximum // level that we need. int n = 0; // number of AABBs in main list dxAABB *first_aabb = 0; // list of AABBs in hash table dxAABB *big_boxes = 0; // list of AABBs too big for hash table maxlevel = global_minlevel - 1; for (geom = first; geom; geom=geom->next) { if (!GEOM_ENABLED(geom)){ continue; } dxAABB *aabb = (dxAABB*) ALLOCA (sizeof(dxAABB)); aabb->geom = geom; // compute level, but prevent cells from getting too small int level = findLevel (geom->aabb); if (level < global_minlevel) level = global_minlevel; if (level <= global_maxlevel) { // aabb goes in main list aabb->next = first_aabb; first_aabb = aabb; aabb->level = level; if (level > maxlevel) maxlevel = level; // cellsize = 2^level dReal cellsize = (dReal) ldexp (1.0,level); // discretize AABB position to cell size for (i=0; i < 6; i++) aabb->dbounds[i] = (int) floor (geom->aabb[i]/cellsize); // set AABB index aabb->index = n; n++; } else { // aabb is too big, put it in the big_boxes list. we don't care about // setting level, dbounds, index, or the maxlevel aabb->next = big_boxes; big_boxes = aabb; } } // for `n' objects, an n*n array of bits is used to record if those objects // have been intersection-tested against each other yet. this array can // grow large with high n, but oh well... int tested_rowsize = (n+7) >> 3; // number of bytes needed for n bits unsigned char *tested = (unsigned char *) ALLOCA (n * tested_rowsize); memset (tested,0,n * tested_rowsize); // create a hash table to store all AABBs. each AABB may take up to 8 cells. // we use chaining to resolve collisions, but we use a relatively large table // to reduce the chance of collisions. // compute hash table size sz to be a prime > 8*n for (i=0; i= (8*n)) break; } if (i >= NUM_PRIMES) i = NUM_PRIMES-1; // probably pointless int sz = prime[i]; // allocate and initialize hash table node pointers Node **table = (Node **) ALLOCA (sizeof(Node*) * sz); for (i=0; inext) { int *dbounds = aabb->dbounds; for (int xi = dbounds[0]; xi <= dbounds[1]; xi++) { for (int yi = dbounds[2]; yi <= dbounds[3]; yi++) { for (int zi = dbounds[4]; zi <= dbounds[5]; zi++) { // get the hash index unsigned long hi = getVirtualAddress (aabb->level,xi,yi,zi) % sz; // add a new node to the hash table Node *node = (Node*) ALLOCA (sizeof (Node)); node->x = xi; node->y = yi; node->z = zi; node->aabb = aabb; node->next = table[hi]; table[hi] = node; } } } } // now that all AABBs are loaded into the hash table, we do the actual // collision detection. for all AABBs, check for other AABBs in the // same cells for collisions, and then check for other AABBs in all // intersecting higher level cells. int db[6]; // discrete bounds at current level for (aabb=first_aabb; aabb; aabb=aabb->next) { // we are searching for collisions with aabb for (i=0; i<6; i++) db[i] = aabb->dbounds[i]; for (int level = aabb->level; level <= maxlevel; level++) { for (int xi = db[0]; xi <= db[1]; xi++) { for (int yi = db[2]; yi <= db[3]; yi++) { for (int zi = db[4]; zi <= db[5]; zi++) { // get the hash index unsigned long hi = getVirtualAddress (level,xi,yi,zi) % sz; // search all nodes at this index Node *node; for (node = table[hi]; node; node=node->next) { // node points to an AABB that may intersect aabb if (node->aabb == aabb) continue; if (node->aabb->level == level && node->x == xi && node->y == yi && node->z == zi) { // see if aabb and node->aabb have already been tested // against each other unsigned char mask; if (aabb->index <= node->aabb->index) { i = (aabb->index * tested_rowsize)+(node->aabb->index >> 3); mask = 1 << (node->aabb->index & 7); } else { i = (node->aabb->index * tested_rowsize)+(aabb->index >> 3); mask = 1 << (aabb->index & 7); } dIASSERT (i >= 0 && i < (tested_rowsize*n)); if ((tested[i] & mask)==0) { collideAABBs (aabb->geom,node->aabb->geom,data,callback); } tested[i] |= mask; } } } } } // get the discrete bounds for the next level up for (i=0; i<6; i++) db[i] >>= 1; } } // every AABB in the normal list must now be intersected against every // AABB in the big_boxes list. so let's hope there are not too many objects // in the big_boxes list. for (aabb=first_aabb; aabb; aabb=aabb->next) { for (dxAABB *aabb2=big_boxes; aabb2; aabb2=aabb2->next) { collideAABBs (aabb->geom,aabb2->geom,data,callback); } } // intersected all AABBs in the big_boxes list together for (aabb=big_boxes; aabb; aabb=aabb->next) { for (dxAABB *aabb2=aabb->next; aabb2; aabb2=aabb2->next) { collideAABBs (aabb->geom,aabb2->geom,data,callback); } } lock_count--; } void dxHashSpace::collide2 (void *data, dxGeom *geom, dNearCallback *callback) { dAASSERT (geom && callback); // this could take advantage of the hash structure to avoid // O(n2) complexity, but it does not yet. lock_count++; cleanGeoms(); geom->recomputeAABB(); // intersect bounding boxes for (dxGeom *g=first; g; g=g->next) { if (GEOM_ENABLED(g)) collideAABBs (g,geom,data,callback); } lock_count--; } //**************************************************************************** // space functions dxSpace *dSimpleSpaceCreate (dxSpace *space) { return new dxSimpleSpace (space); } dxSpace *dHashSpaceCreate (dxSpace *space) { return new dxHashSpace (space); } void dHashSpaceSetLevels (dxSpace *space, int minlevel, int maxlevel) { dAASSERT (space); dUASSERT (minlevel <= maxlevel,"must have minlevel <= maxlevel"); dUASSERT (space->type == dHashSpaceClass,"argument must be a hash space"); dxHashSpace *hspace = (dxHashSpace*) space; hspace->setLevels (minlevel,maxlevel); } void dHashSpaceGetLevels (dxSpace *space, int *minlevel, int *maxlevel) { dAASSERT (space); dUASSERT (space->type == dHashSpaceClass,"argument must be a hash space"); dxHashSpace *hspace = (dxHashSpace*) space; hspace->getLevels (minlevel,maxlevel); } void dSpaceDestroy (dxSpace *space) { dAASSERT (space); dUASSERT (dGeomIsSpace(space),"argument not a space"); dGeomDestroy (space); } void dSpaceSetCleanup (dxSpace *space, int mode) { dAASSERT (space); dUASSERT (dGeomIsSpace(space),"argument not a space"); space->setCleanup (mode); } int dSpaceGetCleanup (dxSpace *space) { dAASSERT (space); dUASSERT (dGeomIsSpace(space),"argument not a space"); return space->getCleanup(); } void dSpaceSetSublevel (dSpaceID space, int sublevel) { dAASSERT (space); dUASSERT (dGeomIsSpace(space),"argument not a space"); space->setSublevel (sublevel); } int dSpaceGetSublevel (dSpaceID space) { dAASSERT (space); dUASSERT (dGeomIsSpace(space),"argument not a space"); return space->getSublevel(); } void dSpaceSetManualCleanup (dSpaceID space, int mode) { dAASSERT (space); dUASSERT (dGeomIsSpace(space),"argument not a space"); space->setManulCleanup(mode); } int dSpaceGetManualCleanup (dSpaceID space) { dAASSERT (space); dUASSERT (dGeomIsSpace(space),"argument not a space"); return space->getManualCleanup(); } void dSpaceAdd (dxSpace *space, dxGeom *g) { dAASSERT (space); dUASSERT (dGeomIsSpace(space),"argument not a space"); CHECK_NOT_LOCKED (space); space->add (g); } void dSpaceRemove (dxSpace *space, dxGeom *g) { dAASSERT (space); dUASSERT (dGeomIsSpace(space),"argument not a space"); CHECK_NOT_LOCKED (space); space->remove (g); } int dSpaceQuery (dxSpace *space, dxGeom *g) { dAASSERT (space); dUASSERT (dGeomIsSpace(space),"argument not a space"); return space->query (g); } void dSpaceClean (dxSpace *space){ dAASSERT (space); dUASSERT (dGeomIsSpace(space),"argument not a space"); space->cleanGeoms(); } int dSpaceGetNumGeoms (dxSpace *space) { dAASSERT (space); dUASSERT (dGeomIsSpace(space),"argument not a space"); return space->getNumGeoms(); } dGeomID dSpaceGetGeom (dxSpace *space, int i) { dAASSERT (space); dUASSERT (dGeomIsSpace(space),"argument not a space"); return space->getGeom (i); } int dSpaceGetClass (dxSpace *space) { dAASSERT (space); dUASSERT (dGeomIsSpace(space),"argument not a space"); return space->type; } void dSpaceCollide (dxSpace *space, void *data, dNearCallback *callback) { dAASSERT (space && callback); dUASSERT (dGeomIsSpace(space),"argument not a space"); space->collide (data,callback); } struct DataCallback { void *data; dNearCallback *callback; }; // Invokes the callback with arguments swapped static void swap_callback(void *data, dxGeom *g1, dxGeom *g2) { DataCallback *dc = (DataCallback*)data; dc->callback(dc->data, g2, g1); } void dSpaceCollide2 (dxGeom *g1, dxGeom *g2, void *data, dNearCallback *callback) { dAASSERT (g1 && g2 && callback); dxSpace *s1,*s2; // see if either geom is a space if (IS_SPACE(g1)) s1 = (dxSpace*) g1; else s1 = 0; if (IS_SPACE(g2)) s2 = (dxSpace*) g2; else s2 = 0; if (s1 && s2) { int l1 = s1->getSublevel(); int l2 = s2->getSublevel(); if (l1 != l2) { if (l1 > l2) { s2 = 0; } else { s1 = 0; } } } // handle the four space/geom cases if (s1) { if (s2) { // g1 and g2 are spaces. if (s1==s2) { // collide a space with itself --> interior collision s1->collide (data,callback); } else { // iterate through the space that has the fewest geoms, calling // collide2 in the other space for each one. if (s1->count < s2->count) { DataCallback dc = {data, callback}; for (dxGeom *g = s1->first; g; g=g->next) { s2->collide2 (&dc,g,swap_callback); } } else { for (dxGeom *g = s2->first; g; g=g->next) { s1->collide2 (data,g,callback); } } } } else { // g1 is a space, g2 is a geom s1->collide2 (data,g2,callback); } } else { if (s2) { // g1 is a geom, g2 is a space DataCallback dc = {data, callback}; s2->collide2 (&dc,g1,swap_callback); } else { // g1 and g2 are geoms // make sure they have valid AABBs g1->recomputeAABB(); g2->recomputeAABB(); collideAABBs(g1,g2, data, callback); } } } alien-arena-7.66+dfsg/source/unix/odesrc/odeinit.cpp0000600000175000017500000002405412161402010021510 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* ODE initialization/finalization code */ #include #include #include #include "config.h" #include "collision_kernel.h" #include "collision_trimesh_internal.h" #include "odetls.h" #include "odeou.h" //**************************************************************************** // Initialization tracking variables static unsigned int g_uiODEInitCounter = 0; static unsigned int g_uiODEInitModes = 0; enum EODEINITMODE { OIM__MIN, OIM_AUTOTLSCLEANUP = OIM__MIN, OIM_MANUALTLSCLEANUP, OIM__MAX, }; #if dTLS_ENABLED static const EODETLSKIND g_atkTLSKindsByInitMode[OIM__MAX] = { OTK_AUTOCLEANUP, // OIM_AUTOTLSCLEANUP, OTK_MANUALCLEANUP, // OIM_MANUALTLSCLEANUP, }; #endif // #if dTLS_ENABLED static inline bool IsODEModeInitialized(EODEINITMODE imInitMode) { return (g_uiODEInitModes & (1U << imInitMode)) != 0; } static inline void SetODEModeInitialized(EODEINITMODE imInitMode) { g_uiODEInitModes |= (1U << imInitMode); } static inline void ResetODEModeInitialized(EODEINITMODE imInitMode) { g_uiODEInitModes &= ~(1U << imInitMode); } static inline bool IsODEAnyModeInitialized() { return g_uiODEInitModes != 0; } enum { TLD_INTERNAL_COLLISIONDATA_ALLOCATED = 0x00000001, }; static bool AllocateThreadBasicDataIfNecessary(EODEINITMODE imInitMode) { bool bResult = false; do { #if dTLS_ENABLED EODETLSKIND tkTlsKind = g_atkTLSKindsByInitMode[imInitMode]; const unsigned uDataAllocationFlags = COdeTls::GetDataAllocationFlags(tkTlsKind); // If no flags are set it may mean that TLS slot is not allocated yet if (uDataAllocationFlags == 0) { // Assign zero flags to make sure that TLS slot has been allocated if (!COdeTls::AssignDataAllocationFlags(tkTlsKind, 0)) { break; } } #endif // #if dTLS_ENABLED bResult = true; } while (false); return bResult; } static void FreeThreadBasicDataOnFailureIfNecessary(EODEINITMODE imInitMode) { #if dTLS_ENABLED if (imInitMode == OIM_MANUALTLSCLEANUP) { EODETLSKIND tkTlsKind = g_atkTLSKindsByInitMode[imInitMode]; const unsigned uDataAllocationFlags = COdeTls::GetDataAllocationFlags(tkTlsKind); if (uDataAllocationFlags == 0) { // So far, only free TLS slot, if no subsystems have data allocated COdeTls::CleanupForThread(); } } #endif // #if dTLS_ENABLED } #if dTLS_ENABLED static bool AllocateThreadCollisionData(EODETLSKIND tkTlsKind) { bool bResult = false; do { dIASSERT(!(COdeTls::GetDataAllocationFlags(tkTlsKind) & TLD_INTERNAL_COLLISIONDATA_ALLOCATED)); #if dTRIMESH_ENABLED TrimeshCollidersCache *pccColliderCache = new TrimeshCollidersCache(); if (!COdeTls::AssignTrimeshCollidersCache(tkTlsKind, pccColliderCache)) { delete pccColliderCache; break; } #endif // dTRIMESH_ENABLED COdeTls::SignalDataAllocationFlags(tkTlsKind, TLD_INTERNAL_COLLISIONDATA_ALLOCATED); bResult = true; } while (false); return bResult; } #endif // dTLS_ENABLED static bool AllocateThreadCollisionDataIfNecessary(EODEINITMODE imInitMode, bool &bOutDataAllocated) { bool bResult = false; bOutDataAllocated = false; do { #if dTLS_ENABLED EODETLSKIND tkTlsKind = g_atkTLSKindsByInitMode[imInitMode]; const unsigned uDataAllocationFlags = COdeTls::GetDataAllocationFlags(tkTlsKind); if ((uDataAllocationFlags & TLD_INTERNAL_COLLISIONDATA_ALLOCATED) == 0) { if (!AllocateThreadCollisionData(tkTlsKind)) { break; } bOutDataAllocated = true; } #endif // #if dTLS_ENABLED bResult = true; } while (false); return bResult; } static void FreeThreadCollisionData(EODEINITMODE imInitMode) { #if dTLS_ENABLED EODETLSKIND tkTlsKind = g_atkTLSKindsByInitMode[imInitMode]; COdeTls::DestroyTrimeshCollidersCache(tkTlsKind); COdeTls::DropDataAllocationFlags(tkTlsKind, TLD_INTERNAL_COLLISIONDATA_ALLOCATED); #endif // dTLS_ENABLED } static bool InitODEForMode(EODEINITMODE imInitMode) { bool bResult = false; #if dOU_ENABLED bool bOUCustomizationsDone = false; #endif #if dATOMICS_ENABLED bool bAtomicsInitialized = false; #endif #if dTLS_ENABLED EODETLSKIND tkTLSKindToInit = g_atkTLSKindsByInitMode[imInitMode]; bool bTlsInitialized = false; #endif do { bool bAnyModeAlreadyInitialized = IsODEAnyModeInitialized(); if (!bAnyModeAlreadyInitialized) { #if dOU_ENABLED if (!COdeOu::DoOUCustomizations()) { break; } bOUCustomizationsDone = true; #endif #if dATOMICS_ENABLED if (!COdeOu::InitializeAtomics()) { break; } bAtomicsInitialized = true; #endif } #if dTLS_ENABLED if (!COdeTls::Initialize(tkTLSKindToInit)) { break; } bTlsInitialized = true; #endif if (!bAnyModeAlreadyInitialized) { #if dTRIMESH_ENABLED && dTRIMESH_OPCODE if (!Opcode::InitOpcode()) { break; } #endif #if dTRIMESH_ENABLED && dTRIMESH_GIMPACT gimpact_init(); #endif dInitColliders(); } bResult = true; } while (false); if (!bResult) { #if dTLS_ENABLED if (bTlsInitialized) { COdeTls::Finalize(tkTLSKindToInit); } #endif #if dATOMICS_ENABLED if (bAtomicsInitialized) { COdeOu::FinalizeAtomics(); } #endif #if dOU_ENABLED if (bOUCustomizationsDone) { COdeOu::UndoOUCustomizations(); } #endif } return bResult; } static bool AllocateODEDataForThreadForMode(EODEINITMODE imInitMode, unsigned int uiAllocateFlags) { bool bResult = false; bool bCollisionDataAllocated = false; do { if (!AllocateThreadBasicDataIfNecessary(imInitMode)) { break; } if (uiAllocateFlags & dAllocateFlagCollisionData) { if (!AllocateThreadCollisionDataIfNecessary(imInitMode, bCollisionDataAllocated)) { break; } } bResult = true; } while (false); if (!bResult) { if (bCollisionDataAllocated) { FreeThreadCollisionData(imInitMode); } FreeThreadBasicDataOnFailureIfNecessary(imInitMode); } return bResult; } static void CloseODEForMode(EODEINITMODE imInitMode) { bool bAnyModeStillInitialized = IsODEAnyModeInitialized(); if (!bAnyModeStillInitialized) { dClearPosrCache(); dFinitUserClasses(); dFinitColliders(); #if dTRIMESH_ENABLED && dTRIMESH_GIMPACT gimpact_terminate(); #endif #if dTRIMESH_ENABLED && dTRIMESH_OPCODE extern void opcode_collider_cleanup(); // Free up static allocations in opcode opcode_collider_cleanup(); Opcode::CloseOpcode(); #endif } #if dTLS_ENABLED EODETLSKIND tkTLSKindToFinalize = g_atkTLSKindsByInitMode[imInitMode]; COdeTls::Finalize(tkTLSKindToFinalize); #endif if (!bAnyModeStillInitialized) { #if dATOMICS_ENABLED COdeOu::FinalizeAtomics(); #endif #if dOU_ENABLED COdeOu::UndoOUCustomizations(); #endif } } //**************************************************************************** // initialization and shutdown routines - allocate and initialize data, // cleanup before exiting void dInitODE() { int bInitResult = dInitODE2(0); dIASSERT(bInitResult); dVARIABLEUSED(bInitResult); int ibAllocResult = dAllocateODEDataForThread(dAllocateMaskAll); dIASSERT(ibAllocResult); dVARIABLEUSED(ibAllocResult); } int dInitODE2(unsigned int uiInitFlags/*=0*/) { bool bResult = false; do { EODEINITMODE imInitMode = (uiInitFlags & dInitFlagManualThreadCleanup) ? OIM_MANUALTLSCLEANUP : OIM_AUTOTLSCLEANUP; if (!IsODEModeInitialized(imInitMode)) { if (!InitODEForMode(imInitMode)) { break; } SetODEModeInitialized(imInitMode); } ++g_uiODEInitCounter; bResult = true; } while (false); return bResult; } int dAllocateODEDataForThread(unsigned int uiAllocateFlags) { dIASSERT(g_uiODEInitCounter != 0); // Call dInitODE2 first bool bAnyFailure = false; for (unsigned uiCurrentMode = OIM__MIN; uiCurrentMode != OIM__MAX; ++uiCurrentMode) { if (IsODEModeInitialized((EODEINITMODE)uiCurrentMode)) { if (!AllocateODEDataForThreadForMode((EODEINITMODE)uiCurrentMode, uiAllocateFlags)) { bAnyFailure = true; break; } } } bool bResult = !bAnyFailure; return bResult; } void dCleanupODEAllDataForThread() { dIASSERT(g_uiODEInitCounter != 0); // Call dInitODE2 first or delay dCloseODE until all threads exit #if dTLS_ENABLED COdeTls::CleanupForThread(); #endif } void dCloseODE() { dIASSERT(g_uiODEInitCounter != 0); // dCloseODE must not be called without dInitODE2 or if dInitODE2 fails unsigned int uiCurrentMode = (--g_uiODEInitCounter == 0) ? OIM__MIN : OIM__MAX; for (; uiCurrentMode != OIM__MAX; ++uiCurrentMode) { if (IsODEModeInitialized((EODEINITMODE)uiCurrentMode)) { // Must be called before CloseODEForMode() ResetODEModeInitialized((EODEINITMODE)uiCurrentMode); // Must be called after ResetODEModeInitialized() CloseODEForMode((EODEINITMODE)uiCurrentMode); } } } alien-arena-7.66+dfsg/source/unix/odesrc/collision_trimesh_ray.cpp0000600000175000017500000001600112161402010024447 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ // TriMesh code by Erwin de Vries. #include #include #include #include #include "config.h" #if dTRIMESH_ENABLED #include "collision_util.h" #include "collision_trimesh_internal.h" #if dTRIMESH_OPCODE int dCollideRTL(dxGeom* g1, dxGeom* RayGeom, int Flags, dContactGeom* Contacts, int Stride){ dIASSERT (Stride >= (int)sizeof(dContactGeom)); dIASSERT (g1->type == dTriMeshClass); dIASSERT (RayGeom->type == dRayClass); dIASSERT ((Flags & NUMC_MASK) >= 1); dxTriMesh* TriMesh = (dxTriMesh*)g1; const dVector3& TLPosition = *(const dVector3*)dGeomGetPosition(TriMesh); const dMatrix3& TLRotation = *(const dMatrix3*)dGeomGetRotation(TriMesh); const unsigned uiTLSKind = TriMesh->getParentSpaceTLSKind(); dIASSERT(uiTLSKind == RayGeom->getParentSpaceTLSKind()); // The colliding spaces must use matching cleanup method TrimeshCollidersCache *pccColliderCache = GetTrimeshCollidersCache(uiTLSKind); RayCollider& Collider = pccColliderCache->_RayCollider; dReal Length = dGeomRayGetLength(RayGeom); int FirstContact, BackfaceCull; dGeomRayGetParams(RayGeom, &FirstContact, &BackfaceCull); int ClosestHit = dGeomRayGetClosestHit(RayGeom); Collider.SetFirstContact(FirstContact != 0); Collider.SetClosestHit(ClosestHit != 0); Collider.SetCulling(BackfaceCull != 0); Collider.SetMaxDist(Length); dVector3 Origin, Direction; dGeomRayGet(RayGeom, Origin, Direction); /* Make Ray */ Ray WorldRay; WorldRay.mOrig.x = Origin[0]; WorldRay.mOrig.y = Origin[1]; WorldRay.mOrig.z = Origin[2]; WorldRay.mDir.x = Direction[0]; WorldRay.mDir.y = Direction[1]; WorldRay.mDir.z = Direction[2]; /* Intersect */ Matrix4x4 amatrix; int TriCount = 0; if (Collider.Collide(WorldRay, TriMesh->Data->BVTree, &MakeMatrix(TLPosition, TLRotation, amatrix))) { TriCount = pccColliderCache->Faces.GetNbFaces(); } if (TriCount == 0) { return 0; } const CollisionFace* Faces = pccColliderCache->Faces.GetFaces(); int OutTriCount = 0; for (int i = 0; i < TriCount; i++) { if (TriMesh->RayCallback == null || TriMesh->RayCallback(TriMesh, RayGeom, Faces[i].mFaceID, Faces[i].mU, Faces[i].mV)) { const int& TriIndex = Faces[i].mFaceID; if (!Callback(TriMesh, RayGeom, TriIndex)) { continue; } dContactGeom* Contact = SAFECONTACT(Flags, Contacts, OutTriCount, Stride); dVector3 dv[3]; FetchTriangle(TriMesh, TriIndex, TLPosition, TLRotation, dv); dVector3 vu; vu[0] = dv[1][0] - dv[0][0]; vu[1] = dv[1][1] - dv[0][1]; vu[2] = dv[1][2] - dv[0][2]; vu[3] = REAL(0.0); dVector3 vv; vv[0] = dv[2][0] - dv[0][0]; vv[1] = dv[2][1] - dv[0][1]; vv[2] = dv[2][2] - dv[0][2]; vv[3] = REAL(0.0); dCROSS(Contact->normal, =, vv, vu); // Reversed // Even though all triangles might be initially valid, // a triangle may degenerate into a segment after applying // space transformation. if (dSafeNormalize3(Contact->normal)) { // No sense to save on single type conversion in algorithm of this size. // If there would be a custom typedef for distance type it could be used // instead of dReal. However using float directly is the loss of abstraction // and possible loss of precision in future. /*float*/ dReal T = Faces[i].mDistance; Contact->pos[0] = Origin[0] + (Direction[0] * T); Contact->pos[1] = Origin[1] + (Direction[1] * T); Contact->pos[2] = Origin[2] + (Direction[2] * T); Contact->pos[3] = REAL(0.0); Contact->depth = T; Contact->g1 = TriMesh; Contact->g2 = RayGeom; Contact->side1 = TriIndex; Contact->side2 = -1; OutTriCount++; // Putting "break" at the end of loop prevents unnecessary checks on first pass and "continue" if (OutTriCount >= (Flags & NUMC_MASK)) { break; } } } } return OutTriCount; } #endif // dTRIMESH_OPCODE #if dTRIMESH_GIMPACT int dCollideRTL(dxGeom* g1, dxGeom* RayGeom, int Flags, dContactGeom* Contacts, int Stride) { dIASSERT (Stride >= (int)sizeof(dContactGeom)); dIASSERT (g1->type == dTriMeshClass); dIASSERT (RayGeom->type == dRayClass); dIASSERT ((Flags & NUMC_MASK) >= 1); dxTriMesh* TriMesh = (dxTriMesh*)g1; dReal Length = dGeomRayGetLength(RayGeom); int FirstContact, BackfaceCull; dGeomRayGetParams(RayGeom, &FirstContact, &BackfaceCull); int ClosestHit = dGeomRayGetClosestHit(RayGeom); dVector3 Origin, Direction; dGeomRayGet(RayGeom, Origin, Direction); char intersect=0; GIM_TRIANGLE_RAY_CONTACT_DATA contact_data; if(ClosestHit) { intersect = gim_trimesh_ray_closest_collisionODE(&TriMesh->m_collision_trimesh,Origin,Direction,Length,&contact_data); } else { intersect = gim_trimesh_ray_collisionODE(&TriMesh->m_collision_trimesh,Origin,Direction,Length,&contact_data); } if(intersect == 0) { return 0; } if(!TriMesh->RayCallback || TriMesh->RayCallback(TriMesh, RayGeom, contact_data.m_face_id, contact_data.u , contact_data.v)) { dContactGeom* Contact = &( Contacts[ 0 ] ); VEC_COPY(Contact->pos,contact_data.m_point); VEC_COPY(Contact->normal,contact_data.m_normal); Contact->depth = contact_data.tparam; Contact->g1 = TriMesh; Contact->g2 = RayGeom; Contact->side1 = contact_data.m_face_id; Contact->side2 = -1; return 1; } return 0; } #endif // dTRIMESH_GIMPACT #endif // dTRIMESH_ENABLED alien-arena-7.66+dfsg/source/unix/odesrc/odetls.h0000600000175000017500000001041112161402010021004 0ustar zero79zero79/************************************************************************* * * * Thread local storage access stub for Open Dynamics Engine, * * Copyright (C) 2008 Oleh Derevenko. All rights reserved. * * Email: odar@eleks.com (change all "a" to "e") * * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* ODE Thread Local Storage access stub interface. */ #ifndef _ODE_ODETLS_H_ #define _ODE_ODETLS_H_ #include "odeou.h" #if dTLS_ENABLED struct TrimeshCollidersCache; enum EODETLSKIND { OTK__MIN, OTK_AUTOCLEANUP = OTK__MIN, OTK_MANUALCLEANUP, OTK__MAX, OTK__DEFAULT = OTK_AUTOCLEANUP, }; enum EODETLSITEM { OTI_DATA_ALLOCATION_FLAGS, OTI_TRIMESH_TRIMESH_COLLIDER_CACHE, OTI__MAX, }; class COdeTls { public: static bool Initialize(EODETLSKIND tkTLSKind); static void Finalize(EODETLSKIND tkTLSKind); static void CleanupForThread(); public: static unsigned GetDataAllocationFlags(EODETLSKIND tkTLSKind) { // Must be a safe call as it is used to test if TLS slot is allocated at all return (unsigned)(size_t)CThreadLocalStorage::GetStorageValue(m_ahtkStorageKeys[tkTLSKind], OTI_DATA_ALLOCATION_FLAGS); } static void SignalDataAllocationFlags(EODETLSKIND tkTLSKind, unsigned uFlagsMask) { unsigned uCurrentFlags = (unsigned)(size_t)CThreadLocalStorage::UnsafeGetStorageValue(m_ahtkStorageKeys[tkTLSKind], OTI_DATA_ALLOCATION_FLAGS); CThreadLocalStorage::UnsafeSetStorageValue(m_ahtkStorageKeys[tkTLSKind], OTI_DATA_ALLOCATION_FLAGS, (tlsvaluetype)(size_t)(uCurrentFlags | uFlagsMask)); } static void DropDataAllocationFlags(EODETLSKIND tkTLSKind, unsigned uFlagsMask) { unsigned uCurrentFlags = (unsigned)(size_t)CThreadLocalStorage::UnsafeGetStorageValue(m_ahtkStorageKeys[tkTLSKind], OTI_DATA_ALLOCATION_FLAGS); CThreadLocalStorage::UnsafeSetStorageValue(m_ahtkStorageKeys[tkTLSKind], OTI_DATA_ALLOCATION_FLAGS, (tlsvaluetype)(size_t)(uCurrentFlags & ~uFlagsMask)); } static TrimeshCollidersCache *GetTrimeshCollidersCache(EODETLSKIND tkTLSKind) { return (TrimeshCollidersCache *)CThreadLocalStorage::UnsafeGetStorageValue(m_ahtkStorageKeys[tkTLSKind], OTI_TRIMESH_TRIMESH_COLLIDER_CACHE); } public: static bool AssignDataAllocationFlags(EODETLSKIND tkTLSKind, unsigned uInitializationFlags); static bool AssignTrimeshCollidersCache(EODETLSKIND tkTLSKind, TrimeshCollidersCache *pccInstance); static void DestroyTrimeshCollidersCache(EODETLSKIND tkTLSKind); private: static void FreeTrimeshCollidersCache(TrimeshCollidersCache *pccCacheInstance); private: static void _OU_CONVENTION_CALLBACK FreeTrimeshCollidersCache_Callback(tlsvaluetype vValueData); private: static HTLSKEY m_ahtkStorageKeys[OTK__MAX]; }; #endif // dTLS_ENABLED #endif // _ODE_ODETLS_H_ alien-arena-7.66+dfsg/source/unix/odesrc/odemath.cpp0000600000175000017500000001236012161402010021473 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include #include // get some math functions under windows #ifdef WIN32 #include #ifndef CYGWIN // added by andy for cygwin #undef copysign #define copysign(a,b) ((dReal)_copysign(a,b)) #endif // added by andy for cygwin #endif #undef dSafeNormalize3 #undef dSafeNormalize4 #undef dNormalize3 #undef dNormalize4 // this may be called for vectors `a' with extremely small magnitude, for // example the result of a cross product on two nearly perpendicular vectors. // we must be robust to these small vectors. to prevent numerical error, // first find the component a[i] with the largest magnitude and then scale // all the components by 1/a[i]. then we can compute the length of `a' and // scale the components by 1/l. this has been verified to work with vectors // containing the smallest representable numbers. int _dSafeNormalize3 (dVector3 a) { dAASSERT (a); int idx; dReal aa[3], l; aa[0] = dFabs(a[0]); aa[1] = dFabs(a[1]); aa[2] = dFabs(a[2]); if (aa[1] > aa[0]) { if (aa[2] > aa[1]) { // aa[2] is largest idx = 2; } else { // aa[1] is largest idx = 1; } } else { if (aa[2] > aa[0]) {// aa[2] is largest idx = 2; } else { // aa[0] might be the largest if (aa[0] <= 0) { // aa[0] might is largest a[0] = 1; // if all a's are zero, this is where we'll end up. a[1] = 0; // return a default unit length vector. a[2] = 0; return 0; } else { idx = 0; } } } a[0] /= aa[idx]; a[1] /= aa[idx]; a[2] /= aa[idx]; l = dRecipSqrt (a[0]*a[0] + a[1]*a[1] + a[2]*a[2]); a[0] *= l; a[1] *= l; a[2] *= l; return 1; } /* OLD VERSION */ /* void dNormalize3 (dVector3 a) { dIASSERT (a); dReal l = dDOT(a,a); if (l > 0) { l = dRecipSqrt(l); a[0] *= l; a[1] *= l; a[2] *= l; } else { a[0] = 1; a[1] = 0; a[2] = 0; } } */ int dSafeNormalize3 (dVector3 a) { return _dSafeNormalize3(a); } void dNormalize3(dVector3 a) { _dNormalize3(a); } int _dSafeNormalize4 (dVector4 a) { dAASSERT (a); dReal l = dDOT(a,a)+a[3]*a[3]; if (l > 0) { l = dRecipSqrt(l); a[0] *= l; a[1] *= l; a[2] *= l; a[3] *= l; return 1; } else { a[0] = 1; a[1] = 0; a[2] = 0; a[3] = 0; return 0; } } int dSafeNormalize4 (dVector4 a) { return _dSafeNormalize4(a); } void dNormalize4(dVector4 a) { _dNormalize4(a); } void dPlaneSpace (const dVector3 n, dVector3 p, dVector3 q) { dAASSERT (n && p && q); if (dFabs(n[2]) > M_SQRT1_2) { // choose p in y-z plane dReal a = n[1]*n[1] + n[2]*n[2]; dReal k = dRecipSqrt (a); p[0] = 0; p[1] = -n[2]*k; p[2] = n[1]*k; // set q = n x p q[0] = a*k; q[1] = -n[0]*p[2]; q[2] = n[0]*p[1]; } else { // choose p in x-y plane dReal a = n[0]*n[0] + n[1]*n[1]; dReal k = dRecipSqrt (a); p[0] = -n[1]*k; p[1] = n[0]*k; p[2] = 0; // set q = n x p q[0] = -n[2]*p[1]; q[1] = n[2]*p[0]; q[2] = a*k; } } /* * This takes what is supposed to be a rotation matrix, * and make sure it is correct. * Note: this operates on rows, not columns, because for rotations * both ways give equivalent results. */ void dOrthogonalizeR(dMatrix3 m) { dReal n0 = dLENGTHSQUARED(m); if (n0 != 1) dSafeNormalize3(m); // project row[0] on row[1], should be zero dReal proj = dDOT(m, m+4); if (proj != 0) { // Gram-Schmidt step on row[1] m[4] -= proj * m[0]; m[5] -= proj * m[1]; m[6] -= proj * m[2]; } dReal n1 = dLENGTHSQUARED(m+4); if (n1 != 1) dSafeNormalize3(m+4); /* just overwrite row[2], this makes sure the matrix is not a reflection */ dCROSS(m+8, =, m, m+4); m[3] = m[4+3] = m[8+3] = 0; } alien-arena-7.66+dfsg/source/unix/odesrc/collision_transform.h0000600000175000017500000000346012161402010023606 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* geom transform */ #ifndef _ODE_COLLISION_TRANSFORM_H_ #define _ODE_COLLISION_TRANSFORM_H_ #include #include "collision_kernel.h" int dCollideTransform (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); #endif alien-arena-7.66+dfsg/source/unix/odesrc/convex.cpp0000600000175000017500000014266312161402010021366 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* Code for Convex Collision Detection By Rodrigo Hernandez */ #include #include #include #include #include #include "collision_kernel.h" #include "collision_std.h" #include "collision_util.h" #ifdef _MSC_VER #pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" #endif #if 1 #define dMIN(A,B) ((A)>(B) ? (B) : (A)) #define dMAX(A,B) ((A)>(B) ? (A) : (B)) #else #define dMIN(A,B) std::min(A,B) #define dMAX(A,B) std::max(A,B) #endif //**************************************************************************** // Convex public API dxConvex::dxConvex (dSpaceID space, dReal *_planes, unsigned int _planecount, dReal *_points, unsigned int _pointcount, unsigned int *_polygons) : dxGeom (space,1) { dAASSERT (_planes != NULL); dAASSERT (_points != NULL); dAASSERT (_polygons != NULL); //fprintf(stdout,"dxConvex Constructor planes %X\n",_planes); type = dConvexClass; planes = _planes; planecount = _planecount; // we need points as well points = _points; pointcount = _pointcount; polygons=_polygons; edges = NULL; FillEdges(); #ifndef dNODEBUG // Check for properly build polygons by calculating the determinant // of the 3x3 matrix composed of the first 3 points in the polygon. unsigned int *points_in_poly=polygons; unsigned int *index=polygons+1; for(unsigned int i=0;i 2 ); if(( points[(index[0]*3)+0]*points[(index[1]*3)+1]*points[(index[2]*3)+2] + points[(index[0]*3)+1]*points[(index[1]*3)+2]*points[(index[2]*3)+0] + points[(index[0]*3)+2]*points[(index[1]*3)+0]*points[(index[2]*3)+1] - points[(index[0]*3)+2]*points[(index[1]*3)+1]*points[(index[2]*3)+0] - points[(index[0]*3)+1]*points[(index[1]*3)+0]*points[(index[2]*3)+2] - points[(index[0]*3)+0]*points[(index[1]*3)+2]*points[(index[2]*3)+1])<0) { fprintf(stdout,"WARNING: Polygon %d is not defined counterclockwise\n",i); } points_in_poly+=(*points_in_poly+1); index=points_in_poly+1; if(planes[(i*4)+3]<0) fprintf(stdout,"WARNING: Plane %d does not contain the origin\n",i); } #endif //CreateTree(); } void dxConvex::computeAABB() { // this can, and should be optimized dVector3 point; dMULTIPLY0_331 (point,final_posr->R,points); aabb[0] = point[0]+final_posr->pos[0]; aabb[1] = point[0]+final_posr->pos[0]; aabb[2] = point[1]+final_posr->pos[1]; aabb[3] = point[1]+final_posr->pos[1]; aabb[4] = point[2]+final_posr->pos[2]; aabb[5] = point[2]+final_posr->pos[2]; for(unsigned int i=3;i<(pointcount*3);i+=3) { dMULTIPLY0_331 (point,final_posr->R,&points[i]); aabb[0] = dMIN(aabb[0],point[0]+final_posr->pos[0]); aabb[1] = dMAX(aabb[1],point[0]+final_posr->pos[0]); aabb[2] = dMIN(aabb[2],point[1]+final_posr->pos[1]); aabb[3] = dMAX(aabb[3],point[1]+final_posr->pos[1]); aabb[4] = dMIN(aabb[4],point[2]+final_posr->pos[2]); aabb[5] = dMAX(aabb[5],point[2]+final_posr->pos[2]); } } /*! \brief Populates the edges set, should be called only once whenever the polygon array gets updated */ void dxConvex::FillEdges() { unsigned int *points_in_poly=polygons; unsigned int *index=polygons+1; if (edges!=NULL) delete[] edges; edgecount = 0; edge e; bool isinset; for(unsigned int i=0;i Arcs,std::vector Polygons) { #if 0 dVector3 ea,eb,e; dVector3Copy(points+((edges.begin()+Arcs[0].edge)first*3),ea); dMULTIPLY0_331(e1b,cvx1.final_posr->R,cvx1.points+(i->second*3)); dVector3Copy(points[edges[Arcs[0].edge] #endif return NULL; } void dxConvex::CreateTree() { std::vector A; A.reserve(edgecount); for(unsigned int i=0;iGetFacesSharedByEdge(i,A[i].normals); A[i].edge = i; } std::vector S; S.reserve(pointcount); for(unsigned int i=0;iGetFacesSharedByVertex(i,S[i].normals); S[i].vertex=i; } this->tree = CreateNode(A,S); } void dxConvex::GetFacesSharedByVertex(int i, std::vector f) { } void dxConvex::GetFacesSharedByEdge(int i, int* f) { } void dxConvex::GetFaceNormal(int i, dVector3 normal) { } #endif dGeomID dCreateConvex (dSpaceID space,dReal *_planes,unsigned int _planecount, dReal *_points, unsigned int _pointcount, unsigned int *_polygons) { //fprintf(stdout,"dxConvex dCreateConvex\n"); return new dxConvex(space,_planes, _planecount, _points, _pointcount, _polygons); } void dGeomSetConvex (dGeomID g,dReal *_planes,unsigned int _planecount, dReal *_points, unsigned int _pointcount, unsigned int *_polygons) { //fprintf(stdout,"dxConvex dGeomSetConvex\n"); dUASSERT (g && g->type == dConvexClass,"argument not a convex shape"); dxConvex *s = (dxConvex*) g; s->planes = _planes; s->planecount = _planecount; s->points = _points; s->pointcount = _pointcount; s->polygons=_polygons; } //**************************************************************************** // Helper Inlines // /*! \brief Returns Whether or not the segment ab intersects plane p \param a origin of the segment \param b segment destination \param p plane to test for intersection \param t returns the time "t" in the segment ray that gives us the intersecting point \param q returns the intersection point \return true if there is an intersection, otherwise false. */ bool IntersectSegmentPlane(dVector3 a, dVector3 b, dVector4 p, dReal &t, dVector3 q) { // Compute the t value for the directed line ab intersecting the plane dVector3 ab; ab[0]= b[0] - a[0]; ab[1]= b[1] - a[1]; ab[2]= b[2] - a[2]; t = (p[3] - dDOT(p,a)) / dDOT(p,ab); // If t in [0..1] compute and return intersection point if (t >= 0.0 && t <= 1.0) { q[0] = a[0] + t * ab[0]; q[1] = a[1] + t * ab[1]; q[2] = a[2] + t * ab[2]; return true; } // Else no intersection return false; } /*! \brief Returns the Closest Point in Ray 1 to Ray 2 \param Origin1 The origin of Ray 1 \param Direction1 The direction of Ray 1 \param Origin1 The origin of Ray 2 \param Direction1 The direction of Ray 3 \param t the time "t" in Ray 1 that gives us the closest point (closest_point=Origin1+(Direction1*t). \return true if there is a closest point, false if the rays are paralell. */ inline bool ClosestPointInRay(const dVector3 Origin1, const dVector3 Direction1, const dVector3 Origin2, const dVector3 Direction2, dReal& t) { dVector3 w = {Origin1[0]-Origin2[0], Origin1[1]-Origin2[1], Origin1[2]-Origin2[2]}; dReal a = dDOT(Direction1 , Direction1); dReal b = dDOT(Direction1 , Direction2); dReal c = dDOT(Direction2 , Direction2); dReal d = dDOT(Direction1 , w); dReal e = dDOT(Direction2 , w); dReal denominator = (a*c)-(b*b); if(denominator==0.0f) { return false; } t = ((a*e)-(b*d))/denominator; return true; } /*! \brief Clamp n to lie within the range [min, max] */ inline float Clamp(float n, float min, float max) { if (n < min) return min; if (n > max) return max; return n; } /*! \brief Returns the Closest Points from Segment 1 to Segment 2 \param p1 start of segment 1 \param q1 end of segment 1 \param p2 start of segment 2 \param q2 end of segment 2 \param t the time "t" in Ray 1 that gives us the closest point (closest_point=Origin1+(Direction1*t). \return true if there is a closest point, false if the rays are paralell. \note Adapted from Christer Ericson's Real Time Collision Detection Book. */ inline float ClosestPointBetweenSegments(dVector3& p1, dVector3& q1, dVector3& p2, dVector3& q2, dVector3& c1, dVector3& c2) { // s & t were originaly part of the output args, but since // we don't really need them, we'll just declare them in here float s; float t; dVector3 d1 = {q1[0] - p1[0], q1[1] - p1[1], q1[2] - p1[2]}; dVector3 d2 = {q2[0] - p2[0], q2[1] - p2[1], q2[2] - p2[2]}; dVector3 r = {p1[0] - p2[0], p1[1] - p2[1], p1[2] - p2[2]}; float a = dDOT(d1, d1); float e = dDOT(d2, d2); float f = dDOT(d2, r); // Check if either or both segments degenerate into points if (a <= dEpsilon && e <= dEpsilon) { // Both segments degenerate into points s = t = 0.0f; dVector3Copy(p1,c1); dVector3Copy(p2,c2); return (c1[0] - c2[0])*(c1[0] - c2[0])+ (c1[1] - c2[1])*(c1[1] - c2[1])+ (c1[2] - c2[2])*(c1[2] - c2[2]); } if (a <= dEpsilon) { // First segment degenerates into a point s = 0.0f; t = f / e; // s = 0 => t = (b*s + f) / e = f / e t = Clamp(t, 0.0f, 1.0f); } else { float c = dDOT(d1, r); if (e <= dEpsilon) { // Second segment degenerates into a point t = 0.0f; s = Clamp(-c / a, 0.0f, 1.0f); // t = 0 => s = (b*t - c) / a = -c / a } else { // The general non degenerate case starts here float b = dDOT(d1, d2); float denom = a*e-b*b; // Always nonnegative // If segments not parallel, compute closest point on L1 to L2, and // clamp to segment S1. Else pick arbitrary s (here 0) if (denom != 0.0f) { s = Clamp((b*f - c*e) / denom, 0.0f, 1.0f); } else s = 0.0f; #if 0 // Compute point on L2 closest to S1(s) using // t = Dot((P1+D1*s)-P2,D2) / Dot(D2,D2) = (b*s + f) / e t = (b*s + f) / e; // If t in [0,1] done. Else clamp t, recompute s for the new value // of t using s = Dot((P2+D2*t)-P1,D1) / Dot(D1,D1)= (t*b - c) / a // and clamp s to [0, 1] if (t < 0.0f) { t = 0.0f; s = Clamp(-c / a, 0.0f, 1.0f); } else if (t > 1.0f) { t = 1.0f; s = Clamp((b - c) / a, 0.0f, 1.0f); } #else float tnom = b*s + f; if (tnom < 0.0f) { t = 0.0f; s = Clamp(-c / a, 0.0f, 1.0f); } else if (tnom > e) { t = 1.0f; s = Clamp((b - c) / a, 0.0f, 1.0f); } else { t = tnom / e; } #endif } } c1[0] = p1[0] + d1[0] * s; c1[1] = p1[1] + d1[1] * s; c1[2] = p1[2] + d1[2] * s; c2[0] = p2[0] + d2[0] * t; c2[1] = p2[1] + d2[1] * t; c2[2] = p2[2] + d2[2] * t; return (c1[0] - c2[0])*(c1[0] - c2[0])+ (c1[1] - c2[1])*(c1[1] - c2[1])+ (c1[2] - c2[2])*(c1[2] - c2[2]); } #if 0 float tnom = b*s + f; if (tnom < 0.0f) { t = 0.0f; s = Clamp(-c / a, 0.0f, 1.0f); } else if (tnom > e) { t = 1.0f; s = Clamp((b - c) / a, 0.0f, 1.0f); } else { t = tnom / e; } #endif /*! \brief Returns the Ray on which 2 planes intersect if they do. \param p1 Plane 1 \param p2 Plane 2 \param p Contains the origin of the ray upon returning if planes intersect \param d Contains the direction of the ray upon returning if planes intersect \return true if the planes intersect, false if paralell. */ inline bool IntersectPlanes(const dVector4 p1, const dVector4 p2, dVector3 p, dVector3 d) { // Compute direction of intersection line dCROSS(d,=,p1,p2); // If d is (near) zero, the planes are parallel (and separated) // or coincident, so they're not considered intersecting dReal denom = dDOT(d, d); if (denom < dEpsilon) return false; dVector3 n; n[0]=p1[3]*p2[0] - p2[3]*p1[0]; n[1]=p1[3]*p2[1] - p2[3]*p1[1]; n[2]=p1[3]*p2[2] - p2[3]*p1[2]; // Compute point on intersection line dCROSS(p,=,n,d); p[0]/=denom; p[1]/=denom; p[2]/=denom; return true; } #if 0 /*! \brief Finds out if a point lies inside a convex \param p Point to test \param convex a pointer to convex to test against \return true if the point lies inside the convex, false if not. */ inline bool IsPointInConvex(dVector3 p, dxConvex *convex) { dVector3 lp,tmp; // move point into convex space to avoid plane local to world calculations tmp[0] = p[0] - convex->final_posr->pos[0]; tmp[1] = p[1] - convex->final_posr->pos[1]; tmp[2] = p[2] - convex->final_posr->pos[2]; dMULTIPLY1_331 (lp,convex->final_posr->R,tmp); for(unsigned int i=0;iplanecount;++i) { if(( ((convex->planes+(i*4))[0]*lp[0])+ ((convex->planes+(i*4))[1]*lp[1])+ ((convex->planes+(i*4))[2]*lp[2])+ -(convex->planes+(i*4))[3] )>0) { return false; } } return true; } #endif /*! \brief Finds out if a point lies inside a 2D polygon \param p Point to test \param polygon a pointer to the start of the convex polygon index buffer \param out the closest point in the polygon if the point is not inside \return true if the point lies inside of the polygon, false if not. */ inline bool IsPointInPolygon(dVector3 p, unsigned int *polygon, dxConvex *convex, dVector3 out) { // p is the point we want to check, // polygon is a pointer to the polygon we // are checking against, remember it goes // number of vertices then that many indexes // out returns the closest point on the border of the // polygon if the point is not inside it. size_t pointcount=polygon[0]; dVector3 a; dVector3 b; dVector3 c; dVector3 ab; dVector3 ac; dVector3 ap; dVector3 bp; dReal d1; dReal d2; dReal d3; dReal d4; dReal vc; polygon++; // skip past pointcount for(size_t i=0;ifinal_posr->R,&convex->points[(polygon[i]*3)]); a[0]=convex->final_posr->pos[0]+a[0]; a[1]=convex->final_posr->pos[1]+a[1]; a[2]=convex->final_posr->pos[2]+a[2]; dMULTIPLY0_331 (b,convex->final_posr->R, &convex->points[(polygon[(i+1)%pointcount]*3)]); b[0]=convex->final_posr->pos[0]+b[0]; b[1]=convex->final_posr->pos[1]+b[1]; b[2]=convex->final_posr->pos[2]+b[2]; dMULTIPLY0_331 (c,convex->final_posr->R, &convex->points[(polygon[(i+2)%pointcount]*3)]); c[0]=convex->final_posr->pos[0]+c[0]; c[1]=convex->final_posr->pos[1]+c[1]; c[2]=convex->final_posr->pos[2]+c[2]; ab[0] = b[0] - a[0]; ab[1] = b[1] - a[1]; ab[2] = b[2] - a[2]; ac[0] = c[0] - a[0]; ac[1] = c[1] - a[1]; ac[2] = c[2] - a[2]; ap[0] = p[0] - a[0]; ap[1] = p[1] - a[1]; ap[2] = p[2] - a[2]; d1 = dDOT(ab,ap); d2 = dDOT(ac,ap); if (d1 <= 0.0 && d2 <= 0.0) { out[0]=a[0]; out[1]=a[1]; out[2]=a[2]; return false; } bp[0] = p[0] - b[0]; bp[1] = p[1] - b[1]; bp[2] = p[2] - b[2]; d3 = dDOT(ab,bp); d4 = dDOT(ac,bp); if (d3 >= 0.0f && d4 <= d3) { out[0]=b[0]; out[1]=b[1]; out[2]=b[2]; return false; } vc = d1*d4 - d3*d2; if (vc < 0.0 && d1 > 0.0 && d3 < 0.0) { dReal v = d1 / (d1 - d3); out[0] = a[0] + (ab[0]*v); out[1] = a[1] + (ab[1]*v); out[2] = a[2] + (ab[2]*v); return false; } } return true; } int dCollideConvexPlane (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT (o1->type == dConvexClass); dIASSERT (o2->type == dPlaneClass); dIASSERT ((flags & NUMC_MASK) >= 1); dxConvex *Convex = (dxConvex*) o1; dxPlane *Plane = (dxPlane*) o2; unsigned int contacts=0; unsigned int maxc = flags & NUMC_MASK; dVector3 v2; #define LTEQ_ZERO 0x10000000 #define GTEQ_ZERO 0x20000000 #define BOTH_SIGNS (LTEQ_ZERO | GTEQ_ZERO) dIASSERT((BOTH_SIGNS & NUMC_MASK) == 0); // used in conditional operator later unsigned int totalsign = 0; for(unsigned int i=0;ipointcount;++i) { dMULTIPLY0_331 (v2,Convex->final_posr->R,&Convex->points[(i*3)]); dVector3Add(Convex->final_posr->pos, v2, v2); unsigned int distance2sign = GTEQ_ZERO; dReal distance2 = dVector3Dot(Plane->p, v2) - Plane->p[3]; // Ax + By + Cz - D if((distance2 <= REAL(0.0))) { distance2sign = distance2 != REAL(0.0) ? LTEQ_ZERO : BOTH_SIGNS; if (contacts != maxc) { dContactGeom *target = SAFECONTACT(flags, contact, contacts, skip); dVector3Copy(Plane->p, target->normal); dVector3Copy(v2, target->pos); target->depth = -distance2; target->g1 = Convex; target->g2 = Plane; target->side1 = -1; // TODO: set plane index? target->side2 = -1; contacts++; } } // Take new sign into account totalsign |= distance2sign; // Check if contacts are full and both signs have been already found if ((contacts ^ maxc | totalsign) == BOTH_SIGNS) // harder to comprehend but requires one register less { break; // Nothing can be changed any more } } if (totalsign == BOTH_SIGNS) return contacts; return 0; #undef BOTH_SIGNS #undef GTEQ_ZERO #undef LTEQ_ZERO } int dCollideSphereConvex (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT (o1->type == dSphereClass); dIASSERT (o2->type == dConvexClass); dIASSERT ((flags & NUMC_MASK) >= 1); dxSphere *Sphere = (dxSphere*) o1; dxConvex *Convex = (dxConvex*) o2; dReal dist,closestdist=dInfinity; dVector4 plane; // dVector3 contactpoint; dVector3 offsetpos,out,temp; unsigned int *pPoly=Convex->polygons; int closestplane=-1; bool sphereinside=true; /* Do a good old sphere vs plane check first, if a collision is found then check if the contact point is within the polygon */ // offset the sphere final_posr->position into the convex space offsetpos[0]=Sphere->final_posr->pos[0]-Convex->final_posr->pos[0]; offsetpos[1]=Sphere->final_posr->pos[1]-Convex->final_posr->pos[1]; offsetpos[2]=Sphere->final_posr->pos[2]-Convex->final_posr->pos[2]; for(unsigned int i=0;iplanecount;++i) { // apply rotation to the plane dMULTIPLY0_331(plane,Convex->final_posr->R,&Convex->planes[(i*4)]); plane[3]=(&Convex->planes[(i*4)])[3]; // Get the distance from the sphere origin to the plane dist = dVector3Dot(plane, offsetpos) - plane[3]; // Ax + By + Cz - D if(dist>0) { // if we get here, we know the center of the sphere is // outside of the convex hull. if(distradius) { // if we get here we know the sphere surface penetrates // the plane if(IsPointInPolygon(Sphere->final_posr->pos,pPoly,Convex,out)) { // finally if we get here we know that the // sphere is directly touching the inside of the polyhedron contact->normal[0] = plane[0]; contact->normal[1] = plane[1]; contact->normal[2] = plane[2]; contact->pos[0] = Sphere->final_posr->pos[0]+ (-contact->normal[0]*Sphere->radius); contact->pos[1] = Sphere->final_posr->pos[1]+ (-contact->normal[1]*Sphere->radius); contact->pos[2] = Sphere->final_posr->pos[2]+ (-contact->normal[2]*Sphere->radius); contact->depth = Sphere->radius-dist; contact->g1 = Sphere; contact->g2 = Convex; contact->side1 = -1; contact->side2 = -1; // TODO: set plane index? return 1; } else { // the sphere may not be directly touching // the polyhedron, but it may be touching // a point or an edge, if the distance between // the closest point on the poly (out) and the // center of the sphere is less than the sphere // radius we have a hit. temp[0] = (Sphere->final_posr->pos[0]-out[0]); temp[1] = (Sphere->final_posr->pos[1]-out[1]); temp[2] = (Sphere->final_posr->pos[2]-out[2]); dist=(temp[0]*temp[0])+(temp[1]*temp[1])+(temp[2]*temp[2]); // avoid the sqrt unless really necesary if(dist<(Sphere->radius*Sphere->radius)) { // We got an indirect hit dist=dSqrt(dist); contact->normal[0] = temp[0]/dist; contact->normal[1] = temp[1]/dist; contact->normal[2] = temp[2]/dist; contact->pos[0] = Sphere->final_posr->pos[0]+ (-contact->normal[0]*Sphere->radius); contact->pos[1] = Sphere->final_posr->pos[1]+ (-contact->normal[1]*Sphere->radius); contact->pos[2] = Sphere->final_posr->pos[2]+ (-contact->normal[2]*Sphere->radius); contact->depth = Sphere->radius-dist; contact->g1 = Sphere; contact->g2 = Convex; contact->side1 = -1; contact->side2 = -1; // TODO: set plane index? return 1; } } } sphereinside=false; } if(sphereinside) { if(closestdist>dFabs(dist)) { closestdist=dFabs(dist); closestplane=i; } } pPoly+=pPoly[0]+1; } if(sphereinside) { // if the center of the sphere is inside // the Convex, we need to pop it out dMULTIPLY0_331(contact->normal, Convex->final_posr->R, &Convex->planes[(closestplane*4)]); contact->pos[0] = Sphere->final_posr->pos[0]; contact->pos[1] = Sphere->final_posr->pos[1]; contact->pos[2] = Sphere->final_posr->pos[2]; contact->depth = closestdist+Sphere->radius; contact->g1 = Sphere; contact->g2 = Convex; contact->side1 = -1; contact->side2 = -1; // TODO: set plane index? return 1; } return 0; } int dCollideConvexBox (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT (o1->type == dConvexClass); dIASSERT (o2->type == dBoxClass); dIASSERT ((flags & NUMC_MASK) >= 1); //dxConvex *Convex = (dxConvex*) o1; //dxBox *Box = (dxBox*) o2; return 0; } int dCollideConvexCapsule (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT (o1->type == dConvexClass); dIASSERT (o2->type == dCapsuleClass); dIASSERT ((flags & NUMC_MASK) >= 1); //dxConvex *Convex = (dxConvex*) o1; //dxCapsule *Capsule = (dxCapsule*) o2; return 0; } inline void ComputeInterval(dxConvex& cvx,dVector4 axis,dReal& min,dReal& max) { /* TODO: Use Support points here */ dVector3 point; dReal value; //fprintf(stdout,"Compute Interval Axis %f,%f,%f\n",axis[0],axis[1],axis[2]); dMULTIPLY0_331(point,cvx.final_posr->R,cvx.points); //fprintf(stdout,"initial point %f,%f,%f\n",point[0],point[1],point[2]); point[0]+=cvx.final_posr->pos[0]; point[1]+=cvx.final_posr->pos[1]; point[2]+=cvx.final_posr->pos[2]; max = min = dDOT(point,axis)-axis[3];//(*) for (unsigned int i = 1; i < cvx.pointcount; ++i) { dMULTIPLY0_331(point,cvx.final_posr->R,cvx.points+(i*3)); point[0]+=cvx.final_posr->pos[0]; point[1]+=cvx.final_posr->pos[1]; point[2]+=cvx.final_posr->pos[2]; value=dDOT(point,axis)-axis[3];//(*) if(valuemax) { max=value; } } // *: usually using the distance part of the plane (axis) is // not necesary, however, here we need it here in order to know // which face to pick when there are 2 parallel sides. } bool CheckEdgeIntersection(dxConvex& cvx1,dxConvex& cvx2, int flags,int& curc, dContactGeom *contact, int skip) { int maxc = flags & NUMC_MASK; dIASSERT(maxc != 0); dVector3 e1,e2,q; dVector4 plane,depthplane; dReal t; for(unsigned int i = 0;iR,cvx1.points+(cvx1.edges[i].first*3)); // translate e1[0]+=cvx1.final_posr->pos[0]; e1[1]+=cvx1.final_posr->pos[1]; e1[2]+=cvx1.final_posr->pos[2]; // Rotate dMULTIPLY0_331(e2,cvx1.final_posr->R,cvx1.points+(cvx1.edges[i].second*3)); // translate e2[0]+=cvx1.final_posr->pos[0]; e2[1]+=cvx1.final_posr->pos[1]; e2[2]+=cvx1.final_posr->pos[2]; unsigned int* pPoly=cvx2.polygons; for(size_t j=0;jR,cvx2.planes+(j*4)); dNormalize3(plane); // Translate plane[3]= (cvx2.planes[(j*4)+3])+ ((plane[0] * cvx2.final_posr->pos[0]) + (plane[1] * cvx2.final_posr->pos[1]) + (plane[2] * cvx2.final_posr->pos[2])); dContactGeom *target = SAFECONTACT(flags, contact, curc, skip); target->g1=&cvx1; // g1 is the one pushed target->g2=&cvx2; if(IntersectSegmentPlane(e1,e2,plane,t,target->pos)) { if(IsPointInPolygon(target->pos,pPoly,&cvx2,q)) { target->depth = dInfinity; for(size_t k=0;kR,cvx2.planes+(k*4)); dNormalize3(depthplane); // Translate depthplane[3]= (cvx2.planes[(k*4)+3])+ ((plane[0] * cvx2.final_posr->pos[0]) + (plane[1] * cvx2.final_posr->pos[1]) + (plane[2] * cvx2.final_posr->pos[2])); dReal depth = (dVector3Dot(depthplane, target->pos) - depthplane[3]); // Ax + By + Cz - D if((fabs(depth)depth))&&((depth<-dEpsilon)||(depth>dEpsilon))) { target->depth=depth; dVector3Copy(depthplane,target->normal); } } ++curc; if(curc==maxc) return true; } } pPoly+=pPoly[0]+1; } } return false; } /* Helper struct */ struct ConvexConvexSATOutput { dReal min_depth; int depth_type; dVector3 dist; // distance from center to center, from cvx1 to cvx2 dVector3 e1a,e1b,e2a,e2b; // e1a to e1b = edge in cvx1,e2a to e2b = edge in cvx2. }; /*! \brief Does an axis separation test using cvx1 planes on cvx1 and cvx2, returns true for a collision false for no collision \param cvx1 [IN] First Convex object, its planes are used to do the tests \param cvx2 [IN] Second Convex object \param min_depth [IN/OUT] Used to input as well as output the minimum depth so far, must be set to a huge value such as dInfinity for initialization. \param g1 [OUT] Pointer to the convex which should be used in the returned contact as g1 \param g2 [OUT] Pointer to the convex which should be used in the returned contact as g2 */ inline bool CheckSATConvexFaces(dxConvex& cvx1, dxConvex& cvx2, ConvexConvexSATOutput& ccso) { dReal min,max,min1,max1,min2,max2,depth; dVector4 plane; for(unsigned int i=0;iR,cvx1.planes+(i*4)); dNormalize3(plane); // Translate plane[3]= (cvx1.planes[(i*4)+3])+ ((plane[0] * cvx1.final_posr->pos[0]) + (plane[1] * cvx1.final_posr->pos[1]) + (plane[2] * cvx1.final_posr->pos[2])); ComputeInterval(cvx1,plane,min1,max1); ComputeInterval(cvx2,plane,min2,max2); if(max2R,cvx1.points+(cvx1.edges[i].first*3)); dMULTIPLY0_331(e1b,cvx1.final_posr->R,cvx1.points+(cvx1.edges[i].second*3)); e1[0]=e1b[0]-e1a[0]; e1[1]=e1b[1]-e1a[1]; e1[2]=e1b[2]-e1a[2]; for(unsigned int j = 0;jR,cvx2.points+(cvx2.edges[j].first*3)); dMULTIPLY0_331 (e2b,cvx2.final_posr->R,cvx2.points+(cvx2.edges[j].second*3)); e2[0]=e2b[0]-e2a[0]; e2[1]=e2b[1]-e2a[1]; e2[2]=e2b[2]-e2a[2]; dCROSS(plane,=,e1,e2); if(dDOT(plane,plane)pos[0]; ccso.e1a[1]+=cvx1.final_posr->pos[1]; ccso.e1a[2]+=cvx1.final_posr->pos[2]; ccso.e1b[0]+=cvx1.final_posr->pos[0]; ccso.e1b[1]+=cvx1.final_posr->pos[1]; ccso.e1b[2]+=cvx1.final_posr->pos[2]; dVector3Copy(e2a,ccso.e2a); dVector3Copy(e2b,ccso.e2b); ccso.e2a[0]+=cvx2.final_posr->pos[0]; ccso.e2a[1]+=cvx2.final_posr->pos[1]; ccso.e2a[2]+=cvx2.final_posr->pos[2]; ccso.e2b[0]+=cvx2.final_posr->pos[0]; ccso.e2b[1]+=cvx2.final_posr->pos[1]; ccso.e2b[2]+=cvx2.final_posr->pos[2]; } } } return true; } #if 0 /*! \brief Returns the index of the plane/side of the incident convex (ccso.g2) which is closer to the reference convex (ccso.g1) side This function just looks for the incident face that is facing the reference face and is the closest to being parallel to it, which sometimes is. */ inline unsigned int GetIncidentSide(ConvexConvexSATOutput& ccso) { dVector3 nis; // (N)ormal in (I)ncident convex (S)pace dReal SavedDot; dReal Dot; unsigned int incident_side=0; // Rotate the plane normal into incident convex space // (things like this should be done all over this file, // will look into that) dMULTIPLY1_331(nis,ccso.g2->final_posr->R,ccso.plane); SavedDot = dDOT(nis,ccso.g2->planes); for(unsigned int i=1;iplanecount;++i) { Dot = dDOT(nis,ccso.g2->planes+(i*4)); if(Dot>SavedDot) { SavedDot=Dot; incident_side=i; } } return incident_side; } #endif inline unsigned int GetSupportSide(dVector3& dir,dxConvex& cvx) { dVector3 dics,tmp; // Direction in convex space dReal SavedDot; dReal Dot; unsigned int side=0; dVector3Copy(dir,tmp); dNormalize3(tmp); dMULTIPLY1_331(dics,cvx.final_posr->R,tmp); SavedDot = dDOT(dics,cvx.planes); for(unsigned int i=1;iSavedDot) { SavedDot=Dot; side=i; } } return side; } /*! \brief Does an axis separation test between the 2 convex shapes using faces and edges */ int TestConvexIntersection(dxConvex& cvx1,dxConvex& cvx2, int flags, dContactGeom *contact, int skip) { ConvexConvexSATOutput ccso; ccso.min_depth=dInfinity; // Min not min at all ccso.depth_type=0; // no type // precompute distance vector ccso.dist[0] = cvx2.final_posr->pos[0]-cvx1.final_posr->pos[0]; ccso.dist[1] = cvx2.final_posr->pos[1]-cvx1.final_posr->pos[1]; ccso.dist[2] = cvx2.final_posr->pos[2]-cvx1.final_posr->pos[2]; int maxc = flags & NUMC_MASK; dIASSERT(maxc != 0); dVector3 i1,i2,r1,r2; // edges of incident and reference faces respectively int contacts=0; if(!CheckSATConvexFaces(cvx1,cvx2,ccso)) { return 0; } else if(!CheckSATConvexFaces(cvx2,cvx1,ccso)) { return 0; } else if(!CheckSATConvexEdges(cvx1,cvx2,ccso)) { return 0; } // If we get here, there was a collision if(ccso.depth_type==1) // face-face { // cvx1 MUST always be in contact->g1 and cvx2 in contact->g2 // This was learned the hard way :( unsigned int incident_side; unsigned int* pIncidentPoly; unsigned int* pIncidentPoints; unsigned int reference_side; unsigned int* pReferencePoly; unsigned int* pReferencePoints; dVector4 plane,rplane,iplane; dVector3 tmp; dVector3 dist,p; dReal t,d,d1,d2; bool outside,out; dVector3Copy(ccso.dist,dist); reference_side = GetSupportSide(dist,cvx1); dist[0]=-dist[0]; dist[1]=-dist[1]; dist[2]=-dist[2]; incident_side = GetSupportSide(dist,cvx2); pReferencePoly = cvx1.polygons; pIncidentPoly = cvx2.polygons; // Get Reference plane (We may not have to apply transforms Optimization Oportunity) // Rotate dMULTIPLY0_331(rplane,cvx1.final_posr->R,cvx1.planes+(reference_side*4)); dNormalize3(rplane); // Translate rplane[3]= (cvx1.planes[(reference_side*4)+3])+ ((rplane[0] * cvx1.final_posr->pos[0]) + (rplane[1] * cvx1.final_posr->pos[1]) + (rplane[2] * cvx1.final_posr->pos[2])); // flip rplane[0]=-rplane[0]; rplane[1]=-rplane[1]; rplane[2]=-rplane[2]; rplane[3]=-rplane[3]; for(unsigned int i=0;iR,&cvx2.points[(pIncidentPoints[0]*3)]); dVector3Add(i2,cvx2.final_posr->pos,i2); // Get the same point in the reference convex space dVector3Copy(i2,r2); dVector3Subtract(r2,cvx1.final_posr->pos,r2); dVector3Copy(r2,tmp); dMULTIPLY1_331(r2,cvx1.final_posr->R,tmp); for(unsigned int i=0;iR,&cvx2.points[(pIncidentPoints[(i+1)%pIncidentPoly[0]]*3)]); dVector3Add(i2,cvx2.final_posr->pos,i2); // Get the same point in the reference convex space dVector3Copy(i2,r2); dVector3Subtract(r2,cvx1.final_posr->pos,r2); dVector3Copy(r2,tmp); dMULTIPLY1_331(r2,cvx1.final_posr->R,tmp); outside=false; for(unsigned int j=0;j0) { out = true; break; }; } if(!out) { #if 0 // Use t to move p into global space p[0] = i1[0]+((i2[0]-i1[0])*t); p[1] = i1[1]+((i2[1]-i1[1])*t); p[2] = i1[2]+((i2[2]-i1[2])*t); #else // Apply reference convex transformations to p // The commented out piece of code is likelly to // produce less operations than this one, but // this way we know we are getting the right data dMULTIPLY0_331(tmp,cvx1.final_posr->R,p); dVector3Add(tmp,cvx1.final_posr->pos,p); #endif // get p's distance to reference plane d = p[0]*rplane[0]+ p[1]*rplane[1]+ p[2]*rplane[2]- rplane[3]; if(d>0) { dVector3Copy(p,SAFECONTACT(flags, contact, contacts, skip)->pos); dVector3Copy(rplane,SAFECONTACT(flags, contact, contacts, skip)->normal); SAFECONTACT(flags, contact, contacts, skip)->g1=&cvx1; SAFECONTACT(flags, contact, contacts, skip)->g2=&cvx2; SAFECONTACT(flags, contact, contacts, skip)->depth=d; ++contacts; if (contacts==maxc) return contacts; } } } if(d1>0) { outside=true; } } if(outside) continue; d = i1[0]*rplane[0]+ i1[1]*rplane[1]+ i1[2]*rplane[2]- rplane[3]; if(d>0) { dVector3Copy(i1,SAFECONTACT(flags, contact, contacts, skip)->pos); dVector3Copy(rplane,SAFECONTACT(flags, contact, contacts, skip)->normal); SAFECONTACT(flags, contact, contacts, skip)->g1=&cvx1; SAFECONTACT(flags, contact, contacts, skip)->g2=&cvx2; SAFECONTACT(flags, contact, contacts, skip)->depth=d; ++contacts; if (contacts==maxc) return contacts; } } // IF we get here, we got the easiest contacts to calculate, // but there is still space in the contacts array for more. // So, project the Reference's face points onto the Incident face // plane and test them for inclusion in the reference plane as well. // We already have computed intersections so, skip those. /* Get Incident plane, we need it for projection */ /* Rotate */ dMULTIPLY0_331(iplane,cvx2.final_posr->R,cvx2.planes+(incident_side*4)); dNormalize3(iplane); /* Translate */ iplane[3]= (cvx2.planes[(incident_side*4)+3]) + ((iplane[0] * cvx2.final_posr->pos[0]) + (iplane[1] * cvx2.final_posr->pos[1]) + (iplane[2] * cvx2.final_posr->pos[2])); // get reference face for(unsigned int i=0;iR,&cvx1.points[(pReferencePoints[i]*3)]); dVector3Add(cvx1.final_posr->pos,i1,i1); // Project onto Incident face plane t = -(i1[0]*iplane[0]+ i1[1]*iplane[1]+ i1[2]*iplane[2]- iplane[3]); i1[0]+=iplane[0]*t; i1[1]+=iplane[1]*t; i1[2]+=iplane[2]*t; // Get the same point in the incident convex space dVector3Copy(i1,r1); dVector3Subtract(r1,cvx2.final_posr->pos,r1); dVector3Copy(r1,tmp); dMULTIPLY1_331(r1,cvx2.final_posr->R,tmp); // Check if it is outside the incident convex out = false; for(unsigned int j=0;j=0){out = true;break;}; } if(!out) { // check that the point is not a duplicate outside = false; for(int j=0;jpos[0]==i1[0])&& (SAFECONTACT(flags, contact, j, skip)->pos[1]==i1[1])&& (SAFECONTACT(flags, contact, j, skip)->pos[2]==i1[2])) { outside=true; } } if(!outside) { d = i1[0]*rplane[0]+ i1[1]*rplane[1]+ i1[2]*rplane[2]- rplane[3]; if(d>0) { dVector3Copy(i1,SAFECONTACT(flags, contact, contacts, skip)->pos); dVector3Copy(rplane,SAFECONTACT(flags, contact, contacts, skip)->normal); SAFECONTACT(flags, contact, contacts, skip)->g1=&cvx1; SAFECONTACT(flags, contact, contacts, skip)->g2=&cvx2; SAFECONTACT(flags, contact, contacts, skip)->depth=d; ++contacts; if (contacts==maxc) return contacts; } } } } } else if(ccso.depth_type==2) // edge-edge { dVector3 c1,c2; //float s,t; SAFECONTACT(flags, contact, contacts, skip)->depth = dSqrt(ClosestPointBetweenSegments(ccso.e1a,ccso.e1b,ccso.e2a,ccso.e2b,c1,c2)); SAFECONTACT(flags, contact, contacts, skip)->g1=&cvx1; SAFECONTACT(flags, contact, contacts, skip)->g2=&cvx2; dVector3Copy(c1,SAFECONTACT(flags, contact, contacts, skip)->pos); SAFECONTACT(flags, contact, contacts, skip)->normal[0] = c2[0]-c1[0]; SAFECONTACT(flags, contact, contacts, skip)->normal[1] = c2[1]-c1[1]; SAFECONTACT(flags, contact, contacts, skip)->normal[2] = c2[2]-c1[2]; dNormalize3(SAFECONTACT(flags, contact, contacts, skip)->normal); contacts++; } return contacts; } int dCollideConvexConvex (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT (o1->type == dConvexClass); dIASSERT (o2->type == dConvexClass); dIASSERT ((flags & NUMC_MASK) >= 1); dxConvex *Convex1 = (dxConvex*) o1; dxConvex *Convex2 = (dxConvex*) o2; return TestConvexIntersection(*Convex1,*Convex2,flags, contact,skip); } #if 0 int dCollideRayConvex (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT( o1->type == dRayClass ); dIASSERT( o2->type == dConvexClass ); dIASSERT ((flags & NUMC_MASK) >= 1); dxRay* ray = (dxRay*) o1; dxConvex* convex = (dxConvex*) o2; dVector3 origin,destination,contactpoint,out; dReal depth; dVector4 plane; unsigned int *pPoly=convex->polygons; // Calculate ray origin and destination destination[0]=0; destination[1]=0; destination[2]= ray->length; // -- Rotate -- dMULTIPLY0_331(destination,ray->final_posr->R,destination); origin[0]=ray->final_posr->pos[0]; origin[1]=ray->final_posr->pos[1]; origin[2]=ray->final_posr->pos[2]; destination[0]+=origin[0]; destination[1]+=origin[1]; destination[2]+=origin[2]; for(int i=0;iplanecount;++i) { // Rotate dMULTIPLY0_331(plane,convex->final_posr->R,convex->planes+(i*4)); // Translate plane[3]= (convex->planes[(i*4)+3])+ ((plane[0] * convex->final_posr->pos[0]) + (plane[1] * convex->final_posr->pos[1]) + (plane[2] * convex->final_posr->pos[2])); if(IntersectSegmentPlane(origin, destination, plane, depth, contactpoint)) { if(IsPointInPolygon(contactpoint,pPoly,convex,out)) { contact->pos[0]=contactpoint[0]; contact->pos[1]=contactpoint[1]; contact->pos[2]=contactpoint[2]; contact->normal[0]=plane[0]; contact->normal[1]=plane[1]; contact->normal[2]=plane[2]; contact->depth=depth; contact->g1 = ray; contact->g2 = convex; contact->side1 = -1; contact->side2 = -1; // TODO: set plane index? return 1; } } pPoly+=pPoly[0]+1; } return 0; } #else // Ray - Convex collider by David Walters, June 2006 int dCollideRayConvex( dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip ) { dIASSERT( skip >= (int)sizeof(dContactGeom) ); dIASSERT( o1->type == dRayClass ); dIASSERT( o2->type == dConvexClass ); dIASSERT ((flags & NUMC_MASK) >= 1); dxRay* ray = (dxRay*) o1; dxConvex* convex = (dxConvex*) o2; contact->g1 = ray; contact->g2 = convex; contact->side1 = -1; contact->side2 = -1; // TODO: set plane index? dReal alpha, beta, nsign; int flag; // // Compute some useful info // flag = 0; // Assume start point is behind all planes. for ( unsigned int i = 0; i < convex->planecount; ++i ) { // Alias this plane. dReal* plane = convex->planes + ( i * 4 ); // If alpha >= 0 then start point is outside of plane. alpha = dDOT( plane, ray->final_posr->pos ) - plane[3]; // If any alpha is positive, then // the ray start is _outside_ of the hull if ( alpha >= 0 ) { flag = 1; break; } } // If the ray starts inside the convex hull, then everything is flipped. nsign = ( flag ) ? REAL( 1.0 ) : REAL( -1.0 ); // // Find closest contact point // // Assume no contacts. contact->depth = dInfinity; for ( unsigned int i = 0; i < convex->planecount; ++i ) { // Alias this plane. dReal* plane = convex->planes + ( i * 4 ); // If alpha >= 0 then point is outside of plane. alpha = nsign * ( dDOT( plane, ray->final_posr->pos ) - plane[3] ); // Compute [ plane-normal DOT ray-normal ], (/flip) beta = dDOT13( plane, ray->final_posr->R+2 ) * nsign; // Ray is pointing at the plane? ( beta < 0 ) // Ray start to plane is within maximum ray length? // Ray start to plane is closer than the current best distance? if ( beta < -dEpsilon && alpha >= 0 && alpha <= ray->length && alpha < contact->depth ) { // Compute contact point on convex hull surface. contact->pos[0] = ray->final_posr->pos[0] + alpha * ray->final_posr->R[0*4+2]; contact->pos[1] = ray->final_posr->pos[1] + alpha * ray->final_posr->R[1*4+2]; contact->pos[2] = ray->final_posr->pos[2] + alpha * ray->final_posr->R[2*4+2]; flag = 0; // For all _other_ planes. for ( unsigned int j = 0; j < convex->planecount; ++j ) { if ( i == j ) continue; // Skip self. // Alias this plane. dReal* planej = convex->planes + ( j * 4 ); // If beta >= 0 then start is outside of plane. beta = dDOT( planej, contact->pos ) - plane[3]; // If any beta is positive, then the contact point // is not on the surface of the convex hull - it's just // intersecting some part of its infinite extent. if ( beta > dEpsilon ) { flag = 1; break; } } // Contact point isn't outside hull's surface? then it's a good contact! if ( flag == 0 ) { // Store the contact normal, possibly flipped. contact->normal[0] = nsign * plane[0]; contact->normal[1] = nsign * plane[1]; contact->normal[2] = nsign * plane[2]; // Store depth contact->depth = alpha; if ((flags & CONTACTS_UNIMPORTANT) && contact->depth <= ray->length ) { // Break on any contact if contacts are not important break; } } } } // Contact? return ( contact->depth <= ray->length ); } #endif //<-- Convex Collision alien-arena-7.66+dfsg/source/unix/odesrc/collision_util.cpp0000600000175000017500000004516312161402010023111 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* some useful collision utility stuff. this includes some API utility functions that are defined in the public header files. */ #include #include #include #include "collision_util.h" //**************************************************************************** int dCollideSpheres (dVector3 p1, dReal r1, dVector3 p2, dReal r2, dContactGeom *c) { // printf ("d=%.2f (%.2f %.2f %.2f) (%.2f %.2f %.2f) r1=%.2f r2=%.2f\n", // d,p1[0],p1[1],p1[2],p2[0],p2[1],p2[2],r1,r2); dReal d = dDISTANCE (p1,p2); if (d > (r1 + r2)) return 0; if (d <= 0) { c->pos[0] = p1[0]; c->pos[1] = p1[1]; c->pos[2] = p1[2]; c->normal[0] = 1; c->normal[1] = 0; c->normal[2] = 0; c->depth = r1 + r2; } else { dReal d1 = dRecip (d); c->normal[0] = (p1[0]-p2[0])*d1; c->normal[1] = (p1[1]-p2[1])*d1; c->normal[2] = (p1[2]-p2[2])*d1; dReal k = REAL(0.5) * (r2 - r1 - d); c->pos[0] = p1[0] + c->normal[0]*k; c->pos[1] = p1[1] + c->normal[1]*k; c->pos[2] = p1[2] + c->normal[2]*k; c->depth = r1 + r2 - d; } return 1; } void dLineClosestApproach (const dVector3 pa, const dVector3 ua, const dVector3 pb, const dVector3 ub, dReal *alpha, dReal *beta) { dVector3 p; p[0] = pb[0] - pa[0]; p[1] = pb[1] - pa[1]; p[2] = pb[2] - pa[2]; dReal uaub = dDOT(ua,ub); dReal q1 = dDOT(ua,p); dReal q2 = -dDOT(ub,p); dReal d = 1-uaub*uaub; if (d <= REAL(0.0001)) { // @@@ this needs to be made more robust *alpha = 0; *beta = 0; } else { d = dRecip(d); *alpha = (q1 + uaub*q2)*d; *beta = (uaub*q1 + q2)*d; } } // given two line segments A and B with endpoints a1-a2 and b1-b2, return the // points on A and B that are closest to each other (in cp1 and cp2). // in the case of parallel lines where there are multiple solutions, a // solution involving the endpoint of at least one line will be returned. // this will work correctly for zero length lines, e.g. if a1==a2 and/or // b1==b2. // // the algorithm works by applying the voronoi clipping rule to the features // of the line segments. the three features of each line segment are the two // endpoints and the line between them. the voronoi clipping rule states that, // for feature X on line A and feature Y on line B, the closest points PA and // PB between X and Y are globally the closest points if PA is in V(Y) and // PB is in V(X), where V(X) is the voronoi region of X. void dClosestLineSegmentPoints (const dVector3 a1, const dVector3 a2, const dVector3 b1, const dVector3 b2, dVector3 cp1, dVector3 cp2) { dVector3 a1a2,b1b2,a1b1,a1b2,a2b1,a2b2,n; dReal la,lb,k,da1,da2,da3,da4,db1,db2,db3,db4,det; #define SET2(a,b) a[0]=b[0]; a[1]=b[1]; a[2]=b[2]; #define SET3(a,b,op,c) a[0]=b[0] op c[0]; a[1]=b[1] op c[1]; a[2]=b[2] op c[2]; // check vertex-vertex features SET3 (a1a2,a2,-,a1); SET3 (b1b2,b2,-,b1); SET3 (a1b1,b1,-,a1); da1 = dDOT(a1a2,a1b1); db1 = dDOT(b1b2,a1b1); if (da1 <= 0 && db1 >= 0) { SET2 (cp1,a1); SET2 (cp2,b1); return; } SET3 (a1b2,b2,-,a1); da2 = dDOT(a1a2,a1b2); db2 = dDOT(b1b2,a1b2); if (da2 <= 0 && db2 <= 0) { SET2 (cp1,a1); SET2 (cp2,b2); return; } SET3 (a2b1,b1,-,a2); da3 = dDOT(a1a2,a2b1); db3 = dDOT(b1b2,a2b1); if (da3 >= 0 && db3 >= 0) { SET2 (cp1,a2); SET2 (cp2,b1); return; } SET3 (a2b2,b2,-,a2); da4 = dDOT(a1a2,a2b2); db4 = dDOT(b1b2,a2b2); if (da4 >= 0 && db4 <= 0) { SET2 (cp1,a2); SET2 (cp2,b2); return; } // check edge-vertex features. // if one or both of the lines has zero length, we will never get to here, // so we do not have to worry about the following divisions by zero. la = dDOT(a1a2,a1a2); if (da1 >= 0 && da3 <= 0) { k = da1 / la; SET3 (n,a1b1,-,k*a1a2); if (dDOT(b1b2,n) >= 0) { SET3 (cp1,a1,+,k*a1a2); SET2 (cp2,b1); return; } } if (da2 >= 0 && da4 <= 0) { k = da2 / la; SET3 (n,a1b2,-,k*a1a2); if (dDOT(b1b2,n) <= 0) { SET3 (cp1,a1,+,k*a1a2); SET2 (cp2,b2); return; } } lb = dDOT(b1b2,b1b2); if (db1 <= 0 && db2 >= 0) { k = -db1 / lb; SET3 (n,-a1b1,-,k*b1b2); if (dDOT(a1a2,n) >= 0) { SET2 (cp1,a1); SET3 (cp2,b1,+,k*b1b2); return; } } if (db3 <= 0 && db4 >= 0) { k = -db3 / lb; SET3 (n,-a2b1,-,k*b1b2); if (dDOT(a1a2,n) <= 0) { SET2 (cp1,a2); SET3 (cp2,b1,+,k*b1b2); return; } } // it must be edge-edge k = dDOT(a1a2,b1b2); det = la*lb - k*k; if (det <= 0) { // this should never happen, but just in case... SET2(cp1,a1); SET2(cp2,b1); return; } det = dRecip (det); dReal alpha = (lb*da1 - k*db1) * det; dReal beta = ( k*da1 - la*db1) * det; SET3 (cp1,a1,+,alpha*a1a2); SET3 (cp2,b1,+,beta*b1b2); # undef SET2 # undef SET3 } // a simple root finding algorithm is used to find the value of 't' that // satisfies: // d|D(t)|^2/dt = 0 // where: // |D(t)| = |p(t)-b(t)| // where p(t) is a point on the line parameterized by t: // p(t) = p1 + t*(p2-p1) // and b(t) is that same point clipped to the boundary of the box. in box- // relative coordinates d|D(t)|^2/dt is the sum of three x,y,z components // each of which looks like this: // // t_lo / // ______/ -->t // / t_hi // / // // t_lo and t_hi are the t values where the line passes through the planes // corresponding to the sides of the box. the algorithm computes d|D(t)|^2/dt // in a piecewise fashion from t=0 to t=1, stopping at the point where // d|D(t)|^2/dt crosses from negative to positive. void dClosestLineBoxPoints (const dVector3 p1, const dVector3 p2, const dVector3 c, const dMatrix3 R, const dVector3 side, dVector3 lret, dVector3 bret) { int i; // compute the start and delta of the line p1-p2 relative to the box. // we will do all subsequent computations in this box-relative coordinate // system. we have to do a translation and rotation for each point. dVector3 tmp,s,v; tmp[0] = p1[0] - c[0]; tmp[1] = p1[1] - c[1]; tmp[2] = p1[2] - c[2]; dMULTIPLY1_331 (s,R,tmp); tmp[0] = p2[0] - p1[0]; tmp[1] = p2[1] - p1[1]; tmp[2] = p2[2] - p1[2]; dMULTIPLY1_331 (v,R,tmp); // mirror the line so that v has all components >= 0 dVector3 sign; for (i=0; i<3; i++) { if (v[i] < 0) { s[i] = -s[i]; v[i] = -v[i]; sign[i] = -1; } else sign[i] = 1; } // compute v^2 dVector3 v2; v2[0] = v[0]*v[0]; v2[1] = v[1]*v[1]; v2[2] = v[2]*v[2]; // compute the half-sides of the box dReal h[3]; h[0] = REAL(0.5) * side[0]; h[1] = REAL(0.5) * side[1]; h[2] = REAL(0.5) * side[2]; // region is -1,0,+1 depending on which side of the box planes each // coordinate is on. tanchor is the next t value at which there is a // transition, or the last one if there are no more. int region[3]; dReal tanchor[3]; // Denormals are a problem, because we divide by v[i], and then // multiply that by 0. Alas, infinity times 0 is infinity (!) // We also use v2[i], which is v[i] squared. Here's how the epsilons // are chosen: // float epsilon = 1.175494e-038 (smallest non-denormal number) // double epsilon = 2.225074e-308 (smallest non-denormal number) // For single precision, choose an epsilon such that v[i] squared is // not a denormal; this is for performance. // For double precision, choose an epsilon such that v[i] is not a // denormal; this is for correctness. (Jon Watte on mailinglist) #if defined( dSINGLE ) const dReal tanchor_eps = REAL(1e-19); #else const dReal tanchor_eps = REAL(1e-307); #endif // find the region and tanchor values for p1 for (i=0; i<3; i++) { if (v[i] > tanchor_eps) { if (s[i] < -h[i]) { region[i] = -1; tanchor[i] = (-h[i]-s[i])/v[i]; } else { region[i] = (s[i] > h[i]); tanchor[i] = (h[i]-s[i])/v[i]; } } else { region[i] = 0; tanchor[i] = 2; // this will never be a valid tanchor } } // compute d|d|^2/dt for t=0. if it's >= 0 then p1 is the closest point dReal t=0; dReal dd2dt = 0; for (i=0; i<3; i++) dd2dt -= (region[i] ? v2[i] : 0) * tanchor[i]; if (dd2dt >= 0) goto got_answer; do { // find the point on the line that is at the next clip plane boundary dReal next_t = 1; for (i=0; i<3; i++) { if (tanchor[i] > t && tanchor[i] < 1 && tanchor[i] < next_t) next_t = tanchor[i]; } // compute d|d|^2/dt for the next t dReal next_dd2dt = 0; for (i=0; i<3; i++) { next_dd2dt += (region[i] ? v2[i] : 0) * (next_t - tanchor[i]); } // if the sign of d|d|^2/dt has changed, solution = the crossover point if (next_dd2dt >= 0) { dReal m = (next_dd2dt-dd2dt)/(next_t - t); t -= dd2dt/m; goto got_answer; } // advance to the next anchor point / region for (i=0; i<3; i++) { if (tanchor[i] == next_t) { tanchor[i] = (h[i]-s[i])/v[i]; region[i]++; } } t = next_t; dd2dt = next_dd2dt; } while (t < 1); t = 1; got_answer: // compute closest point on the line for (i=0; i<3; i++) lret[i] = p1[i] + t*tmp[i]; // note: tmp=p2-p1 // compute closest point on the box for (i=0; i<3; i++) { tmp[i] = sign[i] * (s[i] + t*v[i]); if (tmp[i] < -h[i]) tmp[i] = -h[i]; else if (tmp[i] > h[i]) tmp[i] = h[i]; } dMULTIPLY0_331 (s,R,tmp); for (i=0; i<3; i++) bret[i] = s[i] + c[i]; } // given boxes (p1,R1,side1) and (p1,R1,side1), return 1 if they intersect // or 0 if not. int dBoxTouchesBox (const dVector3 p1, const dMatrix3 R1, const dVector3 side1, const dVector3 p2, const dMatrix3 R2, const dVector3 side2) { // two boxes are disjoint if (and only if) there is a separating axis // perpendicular to a face from one box or perpendicular to an edge from // either box. the following tests are derived from: // "OBB Tree: A Hierarchical Structure for Rapid Interference Detection", // S.Gottschalk, M.C.Lin, D.Manocha., Proc of ACM Siggraph 1996. // Rij is R1'*R2, i.e. the relative rotation between R1 and R2. // Qij is abs(Rij) dVector3 p,pp; dReal A1,A2,A3,B1,B2,B3,R11,R12,R13,R21,R22,R23,R31,R32,R33, Q11,Q12,Q13,Q21,Q22,Q23,Q31,Q32,Q33; // get vector from centers of box 1 to box 2, relative to box 1 p[0] = p2[0] - p1[0]; p[1] = p2[1] - p1[1]; p[2] = p2[2] - p1[2]; dMULTIPLY1_331 (pp,R1,p); // get pp = p relative to body 1 // get side lengths / 2 A1 = side1[0]*REAL(0.5); A2 = side1[1]*REAL(0.5); A3 = side1[2]*REAL(0.5); B1 = side2[0]*REAL(0.5); B2 = side2[1]*REAL(0.5); B3 = side2[2]*REAL(0.5); // for the following tests, excluding computation of Rij, in the worst case, // 15 compares, 60 adds, 81 multiplies, and 24 absolutes. // notation: R1=[u1 u2 u3], R2=[v1 v2 v3] // separating axis = u1,u2,u3 R11 = dDOT44(R1+0,R2+0); R12 = dDOT44(R1+0,R2+1); R13 = dDOT44(R1+0,R2+2); Q11 = dFabs(R11); Q12 = dFabs(R12); Q13 = dFabs(R13); if (dFabs(pp[0]) > (A1 + B1*Q11 + B2*Q12 + B3*Q13)) return 0; R21 = dDOT44(R1+1,R2+0); R22 = dDOT44(R1+1,R2+1); R23 = dDOT44(R1+1,R2+2); Q21 = dFabs(R21); Q22 = dFabs(R22); Q23 = dFabs(R23); if (dFabs(pp[1]) > (A2 + B1*Q21 + B2*Q22 + B3*Q23)) return 0; R31 = dDOT44(R1+2,R2+0); R32 = dDOT44(R1+2,R2+1); R33 = dDOT44(R1+2,R2+2); Q31 = dFabs(R31); Q32 = dFabs(R32); Q33 = dFabs(R33); if (dFabs(pp[2]) > (A3 + B1*Q31 + B2*Q32 + B3*Q33)) return 0; // separating axis = v1,v2,v3 if (dFabs(dDOT41(R2+0,p)) > (A1*Q11 + A2*Q21 + A3*Q31 + B1)) return 0; if (dFabs(dDOT41(R2+1,p)) > (A1*Q12 + A2*Q22 + A3*Q32 + B2)) return 0; if (dFabs(dDOT41(R2+2,p)) > (A1*Q13 + A2*Q23 + A3*Q33 + B3)) return 0; // separating axis = u1 x (v1,v2,v3) if (dFabs(pp[2]*R21-pp[1]*R31) > A2*Q31 + A3*Q21 + B2*Q13 + B3*Q12) return 0; if (dFabs(pp[2]*R22-pp[1]*R32) > A2*Q32 + A3*Q22 + B1*Q13 + B3*Q11) return 0; if (dFabs(pp[2]*R23-pp[1]*R33) > A2*Q33 + A3*Q23 + B1*Q12 + B2*Q11) return 0; // separating axis = u2 x (v1,v2,v3) if (dFabs(pp[0]*R31-pp[2]*R11) > A1*Q31 + A3*Q11 + B2*Q23 + B3*Q22) return 0; if (dFabs(pp[0]*R32-pp[2]*R12) > A1*Q32 + A3*Q12 + B1*Q23 + B3*Q21) return 0; if (dFabs(pp[0]*R33-pp[2]*R13) > A1*Q33 + A3*Q13 + B1*Q22 + B2*Q21) return 0; // separating axis = u3 x (v1,v2,v3) if (dFabs(pp[1]*R11-pp[0]*R21) > A1*Q21 + A2*Q11 + B2*Q33 + B3*Q32) return 0; if (dFabs(pp[1]*R12-pp[0]*R22) > A1*Q22 + A2*Q12 + B1*Q33 + B3*Q31) return 0; if (dFabs(pp[1]*R13-pp[0]*R23) > A1*Q23 + A2*Q13 + B1*Q32 + B2*Q31) return 0; return 1; } //**************************************************************************** // other utility functions void dInfiniteAABB (dxGeom *geom, dReal aabb[6]) { aabb[0] = -dInfinity; aabb[1] = dInfinity; aabb[2] = -dInfinity; aabb[3] = dInfinity; aabb[4] = -dInfinity; aabb[5] = dInfinity; } //**************************************************************************** // Helpers for Croteam's collider - by Nguyen Binh int dClipEdgeToPlane( dVector3 &vEpnt0, dVector3 &vEpnt1, const dVector4& plPlane) { // calculate distance of edge points to plane dReal fDistance0 = dPointPlaneDistance( vEpnt0 ,plPlane ); dReal fDistance1 = dPointPlaneDistance( vEpnt1 ,plPlane ); // if both points are behind the plane if ( fDistance0 < 0 && fDistance1 < 0 ) { // do nothing return 0; // if both points in front of the plane } else if ( fDistance0 > 0 && fDistance1 > 0 ) { // accept them return 1; // if we have edge/plane intersection } else if ((fDistance0 > 0 && fDistance1 < 0) || ( fDistance0 < 0 && fDistance1 > 0)) { // find intersection point of edge and plane dVector3 vIntersectionPoint; vIntersectionPoint[0]= vEpnt0[0]-(vEpnt0[0]-vEpnt1[0])*fDistance0/(fDistance0-fDistance1); vIntersectionPoint[1]= vEpnt0[1]-(vEpnt0[1]-vEpnt1[1])*fDistance0/(fDistance0-fDistance1); vIntersectionPoint[2]= vEpnt0[2]-(vEpnt0[2]-vEpnt1[2])*fDistance0/(fDistance0-fDistance1); // clamp correct edge to intersection point if ( fDistance0 < 0 ) { dVector3Copy(vIntersectionPoint,vEpnt0); } else { dVector3Copy(vIntersectionPoint,vEpnt1); } return 1; } return 1; } // clip polygon with plane and generate new polygon points void dClipPolyToPlane( const dVector3 avArrayIn[], const int ctIn, dVector3 avArrayOut[], int &ctOut, const dVector4 &plPlane ) { // start with no output points ctOut = 0; int i0 = ctIn-1; // for each edge in input polygon for (int i1=0; i1= 0 ) { // emit point avArrayOut[ctOut][0] = avArrayIn[i0][0]; avArrayOut[ctOut][1] = avArrayIn[i0][1]; avArrayOut[ctOut][2] = avArrayIn[i0][2]; ctOut++; } // if points are on different sides if( (fDistance0 > 0 && fDistance1 < 0) || ( fDistance0 < 0 && fDistance1 > 0) ) { // find intersection point of edge and plane dVector3 vIntersectionPoint; vIntersectionPoint[0]= avArrayIn[i0][0] - (avArrayIn[i0][0]-avArrayIn[i1][0])*fDistance0/(fDistance0-fDistance1); vIntersectionPoint[1]= avArrayIn[i0][1] - (avArrayIn[i0][1]-avArrayIn[i1][1])*fDistance0/(fDistance0-fDistance1); vIntersectionPoint[2]= avArrayIn[i0][2] - (avArrayIn[i0][2]-avArrayIn[i1][2])*fDistance0/(fDistance0-fDistance1); // emit intersection point avArrayOut[ctOut][0] = vIntersectionPoint[0]; avArrayOut[ctOut][1] = vIntersectionPoint[1]; avArrayOut[ctOut][2] = vIntersectionPoint[2]; ctOut++; } } } void dClipPolyToCircle(const dVector3 avArrayIn[], const int ctIn, dVector3 avArrayOut[], int &ctOut, const dVector4 &plPlane ,dReal fRadius) { // start with no output points ctOut = 0; int i0 = ctIn-1; // for each edge in input polygon for (int i1=0; i1= 0 ) { // emit point if (dVector3Length2(avArrayIn[i0]) <= fRadius*fRadius) { avArrayOut[ctOut][0] = avArrayIn[i0][0]; avArrayOut[ctOut][1] = avArrayIn[i0][1]; avArrayOut[ctOut][2] = avArrayIn[i0][2]; ctOut++; } } // if points are on different sides if( (fDistance0 > 0 && fDistance1 < 0) || ( fDistance0 < 0 && fDistance1 > 0) ) { // find intersection point of edge and plane dVector3 vIntersectionPoint; vIntersectionPoint[0]= avArrayIn[i0][0] - (avArrayIn[i0][0]-avArrayIn[i1][0])*fDistance0/(fDistance0-fDistance1); vIntersectionPoint[1]= avArrayIn[i0][1] - (avArrayIn[i0][1]-avArrayIn[i1][1])*fDistance0/(fDistance0-fDistance1); vIntersectionPoint[2]= avArrayIn[i0][2] - (avArrayIn[i0][2]-avArrayIn[i1][2])*fDistance0/(fDistance0-fDistance1); // emit intersection point if (dVector3Length2(avArrayIn[i0]) <= fRadius*fRadius) { avArrayOut[ctOut][0] = vIntersectionPoint[0]; avArrayOut[ctOut][1] = vIntersectionPoint[1]; avArrayOut[ctOut][2] = vIntersectionPoint[2]; ctOut++; } } } } alien-arena-7.66+dfsg/source/unix/odesrc/collision_trimesh_disabled.cpp0000600000175000017500000001337612161402010025437 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include #include #include "config.h" #if !dTRIMESH_ENABLED #include "collision_util.h" #include "collision_trimesh_internal.h" dxTriMesh::dxTriMesh(dSpaceID Space, dTriMeshDataID Data) : dxGeom(Space, 1) { type = dTriMeshClass; } dxTriMesh::~dxTriMesh(){} int dxTriMesh::AABBTest(dxGeom* g, dReal aabb[6]) { return 0; } void dxTriMesh::computeAABB() { dSetZero (aabb,6); } static dMatrix4 identity = { REAL( 0.0 ), REAL( 0.0 ), REAL( 0.0 ), REAL( 0.0 ), REAL( 0.0 ), REAL( 0.0 ), REAL( 0.0 ), REAL( 0.0 ), REAL( 0.0 ), REAL( 0.0 ), REAL( 0.0 ), REAL( 0.0 ), REAL( 0.0 ), REAL( 0.0 ), REAL( 0.0 ), REAL( 0.0 ) }; // Stub functions for trimesh calls dTriMeshDataID dGeomTriMeshDataCreate(void) { return 0; } void dGeomTriMeshDataDestroy(dTriMeshDataID g) {} void dGeomTriMeshDataSet(dTriMeshDataID g, int data_id, void* in_data) {} void* dGeomTriMeshDataGet(dTriMeshDataID g, int data_id) { return 0; } ODE_API void dGeomTriMeshSetLastTransform( dGeomID g, dMatrix4 last_trans ) {} ODE_API dReal* dGeomTriMeshGetLastTransform( dGeomID g ) { return identity; } dGeomID dCreateTriMesh(dSpaceID space, dTriMeshDataID Data, dTriCallback* Callback, dTriArrayCallback* ArrayCallback, dTriRayCallback* RayCallback) { dxTriMesh* Geom = new dxTriMesh(space, Data); Geom->Callback = Callback; Geom->ArrayCallback = ArrayCallback; Geom->RayCallback = RayCallback; return Geom; } void dGeomTriMeshSetData(dGeomID g, dTriMeshDataID Data) {} dTriMeshDataID dGeomTriMeshGetData(dGeomID g) { return 0; } void dGeomTriMeshDataBuildSingle(dTriMeshDataID g, const void* Vertices, int VertexStride, int VertexCount, const void* Indices, int IndexCount, int TriStride) { } void dGeomTriMeshDataBuildSingle1(dTriMeshDataID g, const void* Vertices, int VertexStride, int VertexCount, const void* Indices, int IndexCount, int TriStride, const void* Normals) { } void dGeomTriMeshDataBuildDouble(dTriMeshDataID g, const void* Vertices, int VertexStride, int VertexCount, const void* Indices, int IndexCount, int TriStride) { } void dGeomTriMeshDataBuildDouble1(dTriMeshDataID g, const void* Vertices, int VertexStride, int VertexCount, const void* Indices, int IndexCount, int TriStride, const void* Normals) { } void dGeomTriMeshDataBuildSimple(dTriMeshDataID g, const dReal* Vertices, int VertexCount, const dTriIndex* Indices, int IndexCount) { } void dGeomTriMeshDataBuildSimple1(dTriMeshDataID g, const dReal* Vertices, int VertexCount, const dTriIndex* Indices, int IndexCount, const int* Normals) { } void dGeomTriMeshDataPreprocess(dTriMeshDataID g) { } void dGeomTriMeshDataGetBuffer(dTriMeshDataID g, unsigned char** buf, int* bufLen) { *buf = NULL; *bufLen=0; } void dGeomTriMeshDataSetBuffer(dTriMeshDataID g, unsigned char* buf) {} void dGeomTriMeshSetCallback(dGeomID g, dTriCallback* Callback) { } dTriCallback* dGeomTriMeshGetCallback(dGeomID g) { return 0; } void dGeomTriMeshSetArrayCallback(dGeomID g, dTriArrayCallback* ArrayCallback) { } dTriArrayCallback* dGeomTriMeshGetArrayCallback(dGeomID g) { return 0; } void dGeomTriMeshSetRayCallback(dGeomID g, dTriRayCallback* Callback) { } dTriRayCallback* dGeomTriMeshGetRayCallback(dGeomID g) { return 0; } void dGeomTriMeshSetTriMergeCallback(dGeomID g, dTriTriMergeCallback* Callback) { } dTriTriMergeCallback* dGeomTriMeshGetTriMergeCallback(dGeomID g) { return 0; } void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable) {} int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass) { return 0; } void dGeomTriMeshClearTCCache(dGeomID g) {} dTriMeshDataID dGeomTriMeshGetTriMeshDataID(dGeomID g) { return 0; } int dGeomTriMeshGetTriangleCount (dGeomID g) { return 0; } void dGeomTriMeshDataUpdate(dTriMeshDataID g) {} #endif // !dTRIMESH_ENABLED alien-arena-7.66+dfsg/source/unix/odesrc/mat.cpp0000600000175000017500000001326012161402010020633 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include #include "config.h" #include #include #include #include #include "mat.h" dMatrix::dMatrix() { n = 0; m = 0; data = 0; } dMatrix::dMatrix (int rows, int cols) { if (rows < 1 || cols < 1) dDebug (0,"bad matrix size"); n = rows; m = cols; data = (dReal*) dAlloc (n*m*sizeof(dReal)); dSetZero (data,n*m); } dMatrix::dMatrix (const dMatrix &a) { n = a.n; m = a.m; data = (dReal*) dAlloc (n*m*sizeof(dReal)); memcpy (data,a.data,n*m*sizeof(dReal)); } dMatrix::dMatrix (int rows, int cols, dReal *_data, int rowskip, int colskip) { if (rows < 1 || cols < 1) dDebug (0,"bad matrix size"); n = rows; m = cols; data = (dReal*) dAlloc (n*m*sizeof(dReal)); for (int i=0; i= n || j < 0 || j >= m) dDebug (0,"bad matrix (i,j)"); return data [i*m+j]; } void dMatrix::operator= (const dMatrix &a) { if (data) dFree (data,n*m*sizeof(dReal)); n = a.n; m = a.m; if (n > 0 && m > 0) { data = (dReal*) dAlloc (n*m*sizeof(dReal)); memcpy (data,a.data,n*m*sizeof(dReal)); } else data = 0; } void dMatrix::operator= (dReal a) { for (int i=0; i= n || q[i] < 0 || q[i] >= m) dDebug (0,"Matrix select, bad index arrays"); r.data[i*nq+j] = data[p[i]*m+q[j]]; } } return r; } dMatrix dMatrix::operator + (const dMatrix &a) { if (n != a.n || m != a.m) dDebug (0,"matrix +, mismatched sizes"); dMatrix r (n,m); for (int i=0; i max) max = diff; } } return max; } alien-arena-7.66+dfsg/source/unix/odesrc/collision_cylinder_plane.cpp0000600000175000017500000001762212161402010025123 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* * Cylinder-Plane collider by Christoph Beyer ( boernerb@web.de ) * * This testing basically comes down to testing the intersection * of the cylinder caps (discs) with the plane. * */ #include #include #include #include #include #include "collision_kernel.h" // for dxGeom #include "collision_util.h" int dCollideCylinderPlane(dxGeom *Cylinder, dxGeom *Plane, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT (Cylinder->type == dCylinderClass); dIASSERT (Plane->type == dPlaneClass); dIASSERT ((flags & NUMC_MASK) >= 1); int GeomCount = 0; // count of used contactgeoms #ifdef dSINGLE const dReal toleranz = REAL(0.0001); #endif #ifdef dDOUBLE const dReal toleranz = REAL(0.0000001); #endif // Get the properties of the cylinder (length+radius) dReal radius, length; dGeomCylinderGetParams(Cylinder, &radius, &length); dVector3 &cylpos = Cylinder->final_posr->pos; // and the plane dVector4 planevec; dGeomPlaneGetParams(Plane, planevec); dVector3 PlaneNormal = {planevec[0],planevec[1],planevec[2]}; //dVector3 PlanePos = {planevec[0] * planevec[3],planevec[1] * planevec[3],planevec[2] * planevec[3]}; dVector3 G1Pos1, G1Pos2, vDir1; vDir1[0] = Cylinder->final_posr->R[2]; vDir1[1] = Cylinder->final_posr->R[6]; vDir1[2] = Cylinder->final_posr->R[10]; dReal s; s = length * REAL(0.5); G1Pos2[0] = vDir1[0] * s + cylpos[0]; G1Pos2[1] = vDir1[1] * s + cylpos[1]; G1Pos2[2] = vDir1[2] * s + cylpos[2]; G1Pos1[0] = vDir1[0] * -s + cylpos[0]; G1Pos1[1] = vDir1[1] * -s + cylpos[1]; G1Pos1[2] = vDir1[2] * -s + cylpos[2]; dVector3 C; // parallel-check s = vDir1[0] * PlaneNormal[0] + vDir1[1] * PlaneNormal[1] + vDir1[2] * PlaneNormal[2]; if(s < 0) s += REAL(1.0); // is ca. 0, if vDir1 and PlaneNormal are parallel else s -= REAL(1.0); // is ca. 0, if vDir1 and PlaneNormal are parallel if(s < toleranz && s > (-toleranz)) { // discs are parallel to the plane // 1.compute if, and where contacts are dVector3 P; s = planevec[3] - dVector3Dot(planevec, G1Pos1); dReal t; t = planevec[3] - dVector3Dot(planevec, G1Pos2); if(s >= t) // s == t does never happen, { if(s >= 0) { // 1. Disc dVector3Copy(G1Pos1, P); } else return GeomCount; // no contacts } else { if(t >= 0) { // 2. Disc dVector3Copy(G1Pos2, P); } else return GeomCount; // no contacts } // 2. generate a coordinate-system on the disc dVector3 V1, V2; if(vDir1[0] < toleranz && vDir1[0] > (-toleranz)) { // not x-axis V1[0] = vDir1[0] + REAL(1.0); // random value V1[1] = vDir1[1]; V1[2] = vDir1[2]; } else { // maybe x-axis V1[0] = vDir1[0]; V1[1] = vDir1[1] + REAL(1.0); // random value V1[2] = vDir1[2]; } // V1 is now another direction than vDir1 // Cross-product dVector3Cross(V1, vDir1, V2); // make unit V2 t = dVector3Length(V2); t = radius / t; dVector3Scale(V2, t); // cross again dVector3Cross(V2, vDir1, V1); // |V2| is 'radius' and vDir1 unit, so |V1| is 'radius' // V1 = first axis // V2 = second axis // 3. generate contactpoints // Potential contact 1 dVector3Add(P, V1, contact->pos); contact->depth = planevec[3] - dVector3Dot(planevec, contact->pos); if(contact->depth > 0) { dVector3Copy(PlaneNormal, contact->normal); contact->g1 = Cylinder; contact->g2 = Plane; contact->side1 = -1; contact->side2 = -1; GeomCount++; if( GeomCount >= (flags & NUMC_MASK)) return GeomCount; // enough contactgeoms contact = (dContactGeom *)((char *)contact + skip); } // Potential contact 2 dVector3Subtract(P, V1, contact->pos); contact->depth = planevec[3] - dVector3Dot(planevec, contact->pos); if(contact->depth > 0) { dVector3Copy(PlaneNormal, contact->normal); contact->g1 = Cylinder; contact->g2 = Plane; contact->side1 = -1; contact->side2 = -1; GeomCount++; if( GeomCount >= (flags & NUMC_MASK)) return GeomCount; // enough contactgeoms contact = (dContactGeom *)((char *)contact + skip); } // Potential contact 3 dVector3Add(P, V2, contact->pos); contact->depth = planevec[3] - dVector3Dot(planevec, contact->pos); if(contact->depth > 0) { dVector3Copy(PlaneNormal, contact->normal); contact->g1 = Cylinder; contact->g2 = Plane; contact->side1 = -1; contact->side2 = -1; GeomCount++; if( GeomCount >= (flags & NUMC_MASK)) return GeomCount; // enough contactgeoms contact = (dContactGeom *)((char *)contact + skip); } // Potential contact 4 dVector3Subtract(P, V2, contact->pos); contact->depth = planevec[3] - dVector3Dot(planevec, contact->pos); if(contact->depth > 0) { dVector3Copy(PlaneNormal, contact->normal); contact->g1 = Cylinder; contact->g2 = Plane; contact->side1 = -1; contact->side2 = -1; GeomCount++; if( GeomCount >= (flags & NUMC_MASK)) return GeomCount; // enough contactgeoms contact = (dContactGeom *)((char *)contact + skip); } } else { dReal t = dVector3Dot(PlaneNormal, vDir1); C[0] = vDir1[0] * t - PlaneNormal[0]; C[1] = vDir1[1] * t - PlaneNormal[1]; C[2] = vDir1[2] * t - PlaneNormal[2]; s = dVector3Length(C); // move C onto the circle s = radius / s; dVector3Scale(C, s); // deepest point of disc 1 dVector3Add(C, G1Pos1, contact->pos); // depth of the deepest point contact->depth = planevec[3] - dVector3Dot(planevec, contact->pos); if(contact->depth >= 0) { dVector3Copy(PlaneNormal, contact->normal); contact->g1 = Cylinder; contact->g2 = Plane; contact->side1 = -1; contact->side2 = -1; GeomCount++; if( GeomCount >= (flags & NUMC_MASK)) return GeomCount; // enough contactgeoms contact = (dContactGeom *)((char *)contact + skip); } // C is still computed // deepest point of disc 2 dVector3Add(C, G1Pos2, contact->pos); // depth of the deepest point contact->depth = planevec[3] - planevec[0] * contact->pos[0] - planevec[1] * contact->pos[1] - planevec[2] * contact->pos[2]; if(contact->depth >= 0) { dVector3Copy(PlaneNormal, contact->normal); contact->g1 = Cylinder; contact->g2 = Plane; contact->side1 = -1; contact->side2 = -1; GeomCount++; if( GeomCount >= (flags & NUMC_MASK)) return GeomCount; // enough contactgeoms contact = (dContactGeom *)((char *)contact + skip); } } return GeomCount; } alien-arena-7.66+dfsg/source/unix/odesrc/quickstep.h0000600000175000017500000000337712161402010021537 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_QUICK_STEP_H_ #define _ODE_QUICK_STEP_H_ #include void dxQuickStepper (dxWorld *world, dxBody * const *body, int nb, dxJoint * const *_joint, int nj, dReal stepsize); #endif alien-arena-7.66+dfsg/source/unix/odesrc/collision_cylinder_sphere.cpp0000600000175000017500000002263712161402010025314 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /******************************************************************* * * * cylinder-sphere collider by Christoph Beyer (boernerb@web.de) * * * * In Cylinder/Sphere-collisions, there are three possibilies: * * 1. collision with the cylinder's nappe * * 2. collision with one of the cylinder's disc * * 3. collision with one of the disc's border * * * * This collider computes two distances (s, t) and based on them, * * it decides, which collision we have. * * This collider always generates 1 (or 0, if we have no collison) * * contacts. * * It is able to "separate" cylinder and sphere in all * * configurations, but it never pays attention to velocity. * * So, in extrem situations, "tunneling-effect" is possible. * * * *******************************************************************/ #include #include #include #include #include #include "collision_kernel.h" // for dxGeom #include "collision_util.h" int dCollideCylinderSphere(dxGeom* Cylinder, dxGeom* Sphere, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT (Cylinder->type == dCylinderClass); dIASSERT (Sphere->type == dSphereClass); dIASSERT ((flags & NUMC_MASK) >= 1); //unsigned char* pContactData = (unsigned char*)contact; int GeomCount = 0; // count of used contacts #ifdef dSINGLE const dReal toleranz = REAL(0.0001); #endif #ifdef dDOUBLE const dReal toleranz = REAL(0.0000001); #endif // get the data from the geoms dReal radius, length; dGeomCylinderGetParams(Cylinder, &radius, &length); dVector3 &cylpos = Cylinder->final_posr->pos; //const dReal* pfRot1 = dGeomGetRotation(Cylinder); dReal radius2; radius2 = dGeomSphereGetRadius(Sphere); const dReal* SpherePos = dGeomGetPosition(Sphere); // G1Pos1 is the middle of the first disc // G1Pos2 is the middle of the second disc // vDir1 is the unit direction of the cylinderaxis dVector3 G1Pos1, G1Pos2, vDir1; vDir1[0] = Cylinder->final_posr->R[2]; vDir1[1] = Cylinder->final_posr->R[6]; vDir1[2] = Cylinder->final_posr->R[10]; dReal s; s = length * REAL(0.5); // just a precomputed factor G1Pos2[0] = vDir1[0] * s + cylpos[0]; G1Pos2[1] = vDir1[1] * s + cylpos[1]; G1Pos2[2] = vDir1[2] * s + cylpos[2]; G1Pos1[0] = vDir1[0] * -s + cylpos[0]; G1Pos1[1] = vDir1[1] * -s + cylpos[1]; G1Pos1[2] = vDir1[2] * -s + cylpos[2]; dVector3 C; dReal t; // Step 1: compute the two distances 's' and 't' // 's' is the distance from the first disc (in vDir1-/Zylinderaxis-direction), the disc with G1Pos1 in the middle s = (SpherePos[0] - G1Pos1[0]) * vDir1[0] - (G1Pos1[1] - SpherePos[1]) * vDir1[1] - (G1Pos1[2] - SpherePos[2]) * vDir1[2]; if(s < (-radius2) || s > (length + radius2) ) { // Sphere is too far away from the discs // no collision return 0; } // C is the direction from Sphere-middle to the cylinder-axis (vDir1); C is orthogonal to the cylinder-axis C[0] = s * vDir1[0] + G1Pos1[0] - SpherePos[0]; C[1] = s * vDir1[1] + G1Pos1[1] - SpherePos[1]; C[2] = s * vDir1[2] + G1Pos1[2] - SpherePos[2]; // t is the distance from the Sphere-middle to the cylinder-axis! t = dVector3Length(C); if(t > (radius + radius2) ) { // Sphere is too far away from the cylinder axis! // no collision return 0; } // decide which kind of collision we have: if(t > radius && (s < 0 || s > length) ) { // 3. collision if(s <= 0) { contact->depth = radius2 - dSqrt( (s) * (s) + (t - radius) * (t - radius) ); if(contact->depth < 0) { // no collision! return 0; } contact->pos[0] = C[0] / t * -radius + G1Pos1[0]; contact->pos[1] = C[1] / t * -radius + G1Pos1[1]; contact->pos[2] = C[2] / t * -radius + G1Pos1[2]; contact->normal[0] = (contact->pos[0] - SpherePos[0]) / (radius2 - contact->depth); contact->normal[1] = (contact->pos[1] - SpherePos[1]) / (radius2 - contact->depth); contact->normal[2] = (contact->pos[2] - SpherePos[2]) / (radius2 - contact->depth); contact->g1 = Cylinder; contact->g2 = Sphere; contact->side1 = -1; contact->side2 = -1; GeomCount++; return GeomCount; } else { // now s is bigger than length here! contact->depth = radius2 - dSqrt( (s - length) * (s - length) + (t - radius) * (t - radius) ); if(contact->depth < 0) { // no collision! return 0; } contact->pos[0] = C[0] / t * -radius + G1Pos2[0]; contact->pos[1] = C[1] / t * -radius + G1Pos2[1]; contact->pos[2] = C[2] / t * -radius + G1Pos2[2]; contact->normal[0] = (contact->pos[0] - SpherePos[0]) / (radius2 - contact->depth); contact->normal[1] = (contact->pos[1] - SpherePos[1]) / (radius2 - contact->depth); contact->normal[2] = (contact->pos[2] - SpherePos[2]) / (radius2 - contact->depth); contact->g1 = Cylinder; contact->g2 = Sphere; contact->side1 = -1; contact->side2 = -1; GeomCount++; return GeomCount; } } else if( (radius - t) <= s && (radius - t) <= (length - s) ) { // 1. collsision if(t > (radius2 + toleranz)) { // cylinder-axis is outside the sphere contact->depth = (radius2 + radius) - t; if(contact->depth < 0) { // should never happen, but just for safeness return 0; } else { C[0] /= t; C[1] /= t; C[2] /= t; contact->pos[0] = C[0] * radius2 + SpherePos[0]; contact->pos[1] = C[1] * radius2 + SpherePos[1]; contact->pos[2] = C[2] * radius2 + SpherePos[2]; contact->normal[0] = C[0]; contact->normal[1] = C[1]; contact->normal[2] = C[2]; contact->g1 = Cylinder; contact->g2 = Sphere; contact->side1 = -1; contact->side2 = -1; GeomCount++; return GeomCount; } } else { // cylinder-axis is outside of the sphere contact->depth = (radius2 + radius) - t; if(contact->depth < 0) { // should never happen, but just for safeness return 0; } else { contact->pos[0] = C[0] + SpherePos[0]; contact->pos[1] = C[1] + SpherePos[1]; contact->pos[2] = C[2] + SpherePos[2]; contact->normal[0] = C[0] / t; contact->normal[1] = C[1] / t; contact->normal[2] = C[2] / t; contact->g1 = Cylinder; contact->g2 = Sphere; contact->side1 = -1; contact->side2 = -1; GeomCount++; return GeomCount; } } } else { // 2. collision if(s <= (length * REAL(0.5)) ) { // collsision with the first disc contact->depth = s + radius2; if(contact->depth < 0) { // should never happen, but just for safeness return 0; } contact->pos[0] = radius2 * vDir1[0] + SpherePos[0]; contact->pos[1] = radius2 * vDir1[1] + SpherePos[1]; contact->pos[2] = radius2 * vDir1[2] + SpherePos[2]; contact->normal[0] = vDir1[0]; contact->normal[1] = vDir1[1]; contact->normal[2] = vDir1[2]; contact->g1 = Cylinder; contact->g2 = Sphere; contact->side1 = -1; contact->side2 = -1; GeomCount++; return GeomCount; } else { // collsision with the second disc contact->depth = (radius2 + length - s); if(contact->depth < 0) { // should never happen, but just for safeness return 0; } contact->pos[0] = radius2 * -vDir1[0] + SpherePos[0]; contact->pos[1] = radius2 * -vDir1[1] + SpherePos[1]; contact->pos[2] = radius2 * -vDir1[2] + SpherePos[2]; contact->normal[0] = -vDir1[0]; contact->normal[1] = -vDir1[1]; contact->normal[2] = -vDir1[2]; contact->g1 = Cylinder; contact->g2 = Sphere; contact->side1 = -1; contact->side2 = -1; GeomCount++; return GeomCount; } } return GeomCount; } alien-arena-7.66+dfsg/source/unix/odesrc/array.cpp0000600000175000017500000000522312161402010021170 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include #include "config.h" #include #include #include "array.h" static inline int roundUpToPowerOfTwo (int x) { int i = 1; while (i < x) i <<= 1; return i; } void dArrayBase::_freeAll (int sizeofT) { if (_data) { if (_data == this+1) return; // if constructLocalArray() was called dFree (_data,_anum * sizeofT); } } void dArrayBase::_setSize (int newsize, int sizeofT) { if (newsize < 0) return; if (newsize > _anum) { if (_data == this+1) { // this is a no-no, because constructLocalArray() was called dDebug (0,"setSize() out of space in LOCAL array"); } int newanum = roundUpToPowerOfTwo (newsize); if (_data) _data = dRealloc (_data, _anum*sizeofT, newanum*sizeofT); else _data = dAlloc (newanum*sizeofT); _anum = newanum; } _size = newsize; } void * dArrayBase::operator new (size_t size) { return dAlloc (size); } void dArrayBase::operator delete (void *ptr, size_t size) { dFree (ptr,size); } void dArrayBase::constructLocalArray (int __anum) { _size = 0; _anum = __anum; _data = this+1; } alien-arena-7.66+dfsg/source/unix/odesrc/fastdot.c0000600000175000017500000000067512161402010021164 0ustar zero79zero79/* generated code, do not edit. */ #include "ode/matrix.h" dReal dDot (const dReal *a, const dReal *b, int n) { dReal p0,q0,m0,p1,q1,m1,sum; sum = 0; n -= 2; while (n >= 0) { p0 = a[0]; q0 = b[0]; m0 = p0 * q0; p1 = a[1]; q1 = b[1]; m1 = p1 * q1; sum += m0; sum += m1; a += 2; b += 2; n -= 2; } n += 2; while (n > 0) { sum += (*a) * (*b); a++; b++; n--; } return sum; } alien-arena-7.66+dfsg/source/unix/odesrc/step.cpp0000600000175000017500000010011612161402010021022 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include "objects.h" #include "joints/joint.h" #include #include "config.h" #include #include #include #include #include #include "lcp.h" #include "util.h" //**************************************************************************** // misc defines #define FAST_FACTOR //#define TIMING // memory allocation system #ifdef dUSE_MALLOC_FOR_ALLOCA unsigned int dMemoryFlag; #define REPORT_OUT_OF_MEMORY fprintf(stderr, "Insufficient memory to complete rigid body simulation. Results will not be accurate.\n") #define CHECK(p) \ if (!p) { \ dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; \ return; \ } #define ALLOCA(t,v,s) \ Auto v(malloc(s)); \ CHECK(v) #else // use alloca() #define ALLOCA(t,v,s) \ Auto v( dALLOCA16(s) ); #endif /* This template should work almost like std::auto_ptr */ template struct Auto { T *p; Auto(void * q) : p(reinterpret_cast(q)) { } ~Auto() { #ifdef dUSE_MALLOC_FOR_ALLOCA free(p); #endif } operator T*() { return p; } T& operator[] (int i) { return p[i]; } private: // intentionally undefined, don't use this template Auto& operator=(const Auto&) const; }; //**************************************************************************** // debugging - comparison of various vectors and matrices produced by the // slow and fast versions of the stepper. //#define COMPARE_METHODS #ifdef COMPARE_METHODS #include "testing.h" dMatrixComparison comparator; #endif // undef to use the fast decomposition #define DIRECT_CHOLESKY #undef REPORT_ERROR //**************************************************************************** // special matrix multipliers // this assumes the 4th and 8th rows of B and C are zero. static void Multiply2_p8r (dReal *A, dReal *B, dReal *C, int p, int r, int Askip) { int i,j; dReal sum,*bb,*cc; dIASSERT (p>0 && r>0 && A && B && C); bb = B; for (i=p; i; i--) { cc = C; for (j=r; j; j--) { sum = bb[0]*cc[0]; sum += bb[1]*cc[1]; sum += bb[2]*cc[2]; sum += bb[4]*cc[4]; sum += bb[5]*cc[5]; sum += bb[6]*cc[6]; *(A++) = sum; cc += 8; } A += Askip - r; bb += 8; } } // this assumes the 4th and 8th rows of B and C are zero. static void MultiplyAdd2_p8r (dReal *A, dReal *B, dReal *C, int p, int r, int Askip) { int i,j; dReal sum,*bb,*cc; dIASSERT (p>0 && r>0 && A && B && C); bb = B; for (i=p; i; i--) { cc = C; for (j=r; j; j--) { sum = bb[0]*cc[0]; sum += bb[1]*cc[1]; sum += bb[2]*cc[2]; sum += bb[4]*cc[4]; sum += bb[5]*cc[5]; sum += bb[6]*cc[6]; *(A++) += sum; cc += 8; } A += Askip - r; bb += 8; } } // this assumes the 4th and 8th rows of B are zero. static void Multiply0_p81 (dReal *A, dReal *B, dReal *C, int p) { int i; dIASSERT (p>0 && A && B && C); dReal sum; for (i=p; i; i--) { sum = B[0]*C[0]; sum += B[1]*C[1]; sum += B[2]*C[2]; sum += B[4]*C[4]; sum += B[5]*C[5]; sum += B[6]*C[6]; *(A++) = sum; B += 8; } } // this assumes the 4th and 8th rows of B are zero. static void MultiplyAdd0_p81 (dReal *A, dReal *B, dReal *C, int p) { int i; dIASSERT (p>0 && A && B && C); dReal sum; for (i=p; i; i--) { sum = B[0]*C[0]; sum += B[1]*C[1]; sum += B[2]*C[2]; sum += B[4]*C[4]; sum += B[5]*C[5]; sum += B[6]*C[6]; *(A++) += sum; B += 8; } } // this assumes the 4th and 8th rows of B are zero. static void MultiplyAdd1_8q1 (dReal *A, dReal *B, dReal *C, int q) { int k; dReal sum; dIASSERT (q>0 && A && B && C); sum = 0; for (k=0; k0 && A && B && C); sum = 0; for (k=0; ktag = i; // make a local copy of the joint array, because we might want to modify it. // (the "dxJoint *const*" declaration says we're allowed to modify the joints // but not the joint array, because the caller might need it unchanged). ALLOCA(dxJoint*,joint,nj*sizeof(dxJoint*)); memcpy (joint,_joint,nj * sizeof(dxJoint*)); // for all bodies, compute the inertia tensor and its inverse in the global // frame, and compute the rotational force and add it to the torque // accumulator. // @@@ check computation of rotational force. ALLOCA(dReal,I,3*nb*4*sizeof(dReal)); ALLOCA(dReal,invI,3*nb*4*sizeof(dReal)); //dSetZero (I,3*nb*4); //dSetZero (invI,3*nb*4); for (i=0; imass.I,body[i]->posr.R); dMULTIPLY0_333 (I+i*12,body[i]->posr.R,tmp); // compute inverse inertia tensor in global frame dMULTIPLY2_333 (tmp,body[i]->invI,body[i]->posr.R); dMULTIPLY0_333 (invI+i*12,body[i]->posr.R,tmp); // compute rotational force dMULTIPLY0_331 (tmp,I+i*12,body[i]->avel); dCROSS (body[i]->tacc,-=,body[i]->avel,tmp); } // add the gravity force to all bodies for (i=0; iflags & dxBodyNoGravity)==0) { body[i]->facc[0] += body[i]->mass.mass * world->gravity[0]; body[i]->facc[1] += body[i]->mass.mass * world->gravity[1]; body[i]->facc[2] += body[i]->mass.mass * world->gravity[2]; } } // get m = total constraint dimension, nub = number of unbounded variables. // create constraint offset array and number-of-rows array for all joints. // the constraints are re-ordered as follows: the purely unbounded // constraints, the mixed unbounded + LCP constraints, and last the purely // LCP constraints. // // joints with m=0 are inactive and are removed from the joints array // entirely, so that the code that follows does not consider them. int m = 0; ALLOCA(dxJoint::Info1,info,nj*sizeof(dxJoint::Info1)); ALLOCA(int,ofs,nj*sizeof(int)); for (i=0, j=0; jgetInfo1 (info+i); dIASSERT (info[i].m >= 0 && info[i].m <= 6 && info[i].nub >= 0 && info[i].nub <= info[i].m); if (info[i].m > 0) { joint[i] = joint[j]; i++; } } nj = i; // the purely unbounded constraints for (i=0; i 0 && info[i].nub < info[i].m) { ofs[i] = m; m += info[i].m; } // the purely LCP constraints for (i=0; iinvMass; MM[nskip+1] = body[i]->invMass; MM[2*nskip+2] = body[i]->invMass; MM += 3*nskip+3; for (j=0; j<3; j++) for (k=0; k<3; k++) { MM[j*nskip+k] = invI[i*12+j*4+k]; } } // assemble some body vectors: fe = external forces, v = velocities ALLOCA(dReal,fe,n6*sizeof(dReal)); ALLOCA(dReal,v,n6*sizeof(dReal)); //dSetZero (fe,n6); //dSetZero (v,n6); for (i=0; ifacc[j]; for (j=0; j<3; j++) fe[i*6+3+j] = body[i]->tacc[j]; for (j=0; j<3; j++) v[i*6+j] = body[i]->lvel[j]; for (j=0; j<3; j++) v[i*6+3+j] = body[i]->avel[j]; } // this will be set to the velocity update ALLOCA(dReal,vnew,n6*sizeof(dReal)); dSetZero (vnew,n6); // if there are constraints, compute cforce if (m > 0) { // create a constraint equation right hand side vector `c', a constraint // force mixing vector `cfm', and LCP low and high bound vectors, and an // 'findex' vector. ALLOCA(dReal,c,m*sizeof(dReal)); ALLOCA(dReal,cfm,m*sizeof(dReal)); ALLOCA(dReal,lo,m*sizeof(dReal)); ALLOCA(dReal,hi,m*sizeof(dReal)); ALLOCA(int,findex,m*sizeof(int)); dSetZero (c,m); dSetValue (cfm,m,world->global_cfm); dSetValue (lo,m,-dInfinity); dSetValue (hi,m, dInfinity); for (i=0; iglobal_erp; for (i=0; inode[0].body->tag; Jinfo.J1a = Jinfo.J1l + 3; if (joint[i]->node[1].body) { Jinfo.J2l = J + nskip*ofs[i] + 6*joint[i]->node[1].body->tag; Jinfo.J2a = Jinfo.J2l + 3; } else { Jinfo.J2l = 0; Jinfo.J2a = 0; } Jinfo.c = c + ofs[i]; Jinfo.cfm = cfm + ofs[i]; Jinfo.lo = lo + ofs[i]; Jinfo.hi = hi + ofs[i]; Jinfo.findex = findex + ofs[i]; joint[i]->getInfo2 (&Jinfo); // adjust returned findex values for global index numbering for (j=0; j= 0) findex[ofs[i] + j] += ofs[i]; } } // compute A = J*invM*J' # ifdef TIMING dTimerNow ("compute A"); # endif ALLOCA(dReal,JinvM,m*nskip*sizeof(dReal)); //dSetZero (JinvM,m*nskip); dMultiply0 (JinvM,J,invM,m,n6,n6); int mskip = dPAD(m); ALLOCA(dReal,A,m*mskip*sizeof(dReal)); //dSetZero (A,m*mskip); dMultiply2 (A,JinvM,J,m,n6,m); // add cfm to the diagonal of A for (i=0; ilvel[j] = vnew[i*6+j]; for (j=0; j<3; j++) body[i]->avel[j] = vnew[i*6+3+j]; } // update the position and orientation from the new linear/angular velocity // (over the given timestep) #ifdef TIMING dTimerNow ("update position"); #endif for (i=0; ifacc[0] = 0; body[i]->facc[1] = 0; body[i]->facc[2] = 0; body[i]->facc[3] = 0; body[i]->tacc[0] = 0; body[i]->tacc[1] = 0; body[i]->tacc[2] = 0; body[i]->tacc[3] = 0; } #ifdef TIMING dTimerEnd(); if (m > 0) dTimerReport (stdout,1); #endif } //**************************************************************************** // an optimized version of dInternalStepIsland1() void dInternalStepIsland_x2 (dxWorld *world, dxBody * const *body, int nb, dxJoint * const *_joint, int nj, dReal stepsize) { int i,j,k; #ifdef TIMING dTimerStart("preprocessing"); #endif dReal stepsize1 = dRecip(stepsize); // number all bodies in the body list - set their tag values for (i=0; itag = i; // make a local copy of the joint array, because we might want to modify it. // (the "dxJoint *const*" declaration says we're allowed to modify the joints // but not the joint array, because the caller might need it unchanged). ALLOCA(dxJoint*,joint,nj*sizeof(dxJoint*)); memcpy (joint,_joint,nj * sizeof(dxJoint*)); // for all bodies, compute the inertia tensor and its inverse in the global // frame, and compute the rotational force and add it to the torque // accumulator. invI are vertically stacked 3x4 matrices, one per body. // @@@ check computation of rotational force. ALLOCA(dReal,invI,3*nb*4*sizeof(dReal)); //dSetZero (I,3*nb*4); //dSetZero (invI,3*nb*4); for (i=0; iinvI,body[i]->posr.R); dMULTIPLY0_333 (invI+i*12,body[i]->posr.R,tmp); if (body[i]->flags & dxBodyGyroscopic) { dMatrix3 I; // compute inertia tensor in global frame dMULTIPLY2_333 (tmp,body[i]->mass.I,body[i]->posr.R); dMULTIPLY0_333 (I,body[i]->posr.R,tmp); // compute rotational force dMULTIPLY0_331 (tmp,I,body[i]->avel); dCROSS (body[i]->tacc,-=,body[i]->avel,tmp); } } // add the gravity force to all bodies for (i=0; iflags & dxBodyNoGravity)==0) { body[i]->facc[0] += body[i]->mass.mass * world->gravity[0]; body[i]->facc[1] += body[i]->mass.mass * world->gravity[1]; body[i]->facc[2] += body[i]->mass.mass * world->gravity[2]; } } // get m = total constraint dimension, nub = number of unbounded variables. // create constraint offset array and number-of-rows array for all joints. // the constraints are re-ordered as follows: the purely unbounded // constraints, the mixed unbounded + LCP constraints, and last the purely // LCP constraints. this assists the LCP solver to put all unbounded // variables at the start for a quick factorization. // // joints with m=0 are inactive and are removed from the joints array // entirely, so that the code that follows does not consider them. // also number all active joints in the joint list (set their tag values). // inactive joints receive a tag value of -1. int m = 0; ALLOCA(dxJoint::Info1,info,nj*sizeof(dxJoint::Info1)); ALLOCA(int,ofs,nj*sizeof(int)); for (i=0, j=0; jgetInfo1 (info+i); dIASSERT (info[i].m >= 0 && info[i].m <= 6 && info[i].nub >= 0 && info[i].nub <= info[i].m); if (info[i].m > 0) { joint[i] = joint[j]; joint[i]->tag = i; i++; } else { joint[j]->tag = -1; } } nj = i; // the purely unbounded constraints for (i=0; i 0 && info[i].nub < info[i].m) { ofs[i] = m; m += info[i].m; } // the purely LCP constraints for (i=0; i 0) { // create a constraint equation right hand side vector `c', a constraint // force mixing vector `cfm', and LCP low and high bound vectors, and an // 'findex' vector. ALLOCA(dReal,c,m*sizeof(dReal)); ALLOCA(dReal,cfm,m*sizeof(dReal)); ALLOCA(dReal,lo,m*sizeof(dReal)); ALLOCA(dReal,hi,m*sizeof(dReal)); ALLOCA(int,findex,m*sizeof(int)); dSetZero (c,m); dSetValue (cfm,m,world->global_cfm); dSetValue (lo,m,-dInfinity); dSetValue (hi,m, dInfinity); for (i=0; iglobal_erp; for (i=0; igetInfo2 (&Jinfo); // adjust returned findex values for global index numbering for (j=0; j= 0) findex[ofs[i] + j] += ofs[i]; } } // compute A = J*invM*J'. first compute JinvM = J*invM. this has the same // format as J so we just go through the constraints in J multiplying by // the appropriate scalars and matrices. # ifdef TIMING dTimerNow ("compute A"); # endif ALLOCA(dReal,JinvM,2*m*8*sizeof(dReal)); dSetZero (JinvM,2*m*8); for (i=0; inode[0].body->tag; dReal body_invMass = body[b]->invMass; dReal *body_invI = invI + b*12; dReal *Jsrc = J + 2*8*ofs[i]; dReal *Jdst = JinvM + 2*8*ofs[i]; for (j=info[i].m-1; j>=0; j--) { for (k=0; k<3; k++) Jdst[k] = Jsrc[k] * body_invMass; dMULTIPLY0_133 (Jdst+4,Jsrc+4,body_invI); Jsrc += 8; Jdst += 8; } if (joint[i]->node[1].body) { b = joint[i]->node[1].body->tag; body_invMass = body[b]->invMass; body_invI = invI + b*12; for (j=info[i].m-1; j>=0; j--) { for (k=0; k<3; k++) Jdst[k] = Jsrc[k] * body_invMass; dMULTIPLY0_133 (Jdst+4,Jsrc+4,body_invI); Jsrc += 8; Jdst += 8; } } } // now compute A = JinvM * J'. A's rows and columns are grouped by joint, // i.e. in the same way as the rows of J. block (i,j) of A is only nonzero // if joints i and j have at least one body in common. this fact suggests // the algorithm used to fill A: // // for b = all bodies // n = number of joints attached to body b // for i = 1..n // for j = i+1..n // ii = actual joint number for i // jj = actual joint number for j // // (ii,jj) will be set to all pairs of joints around body b // compute blockwise: A(ii,jj) += JinvM(ii) * J(jj)' // // this algorithm catches all pairs of joints that have at least one body // in common. it does not compute the diagonal blocks of A however - // another similar algorithm does that. int mskip = dPAD(m); ALLOCA(dReal,A,m*mskip*sizeof(dReal)); dSetZero (A,m*mskip); for (i=0; ifirstjoint; n1; n1=n1->next) { for (dxJointNode *n2=n1->next; n2; n2=n2->next) { // get joint numbers and ensure ofs[j1] >= ofs[j2] int j1 = n1->joint->tag; int j2 = n2->joint->tag; if (ofs[j1] < ofs[j2]) { int tmp = j1; j1 = j2; j2 = tmp; } // if either joint was tagged as -1 then it is an inactive (m=0) // joint that should not be considered if (j1==-1 || j2==-1) continue; // determine if body i is the 1st or 2nd body of joints j1 and j2 int jb1 = (joint[j1]->node[1].body == body[i]); int jb2 = (joint[j2]->node[1].body == body[i]); // jb1/jb2 must be 0 for joints with only one body dIASSERT(joint[j1]->node[1].body || jb1==0); dIASSERT(joint[j2]->node[1].body || jb2==0); // set block of A MultiplyAdd2_p8r (A + ofs[j1]*mskip + ofs[j2], JinvM + 2*8*ofs[j1] + jb1*8*info[j1].m, J + 2*8*ofs[j2] + jb2*8*info[j2].m, info[j1].m,info[j2].m, mskip); } } } // compute diagonal blocks of A for (i=0; inode[1].body) { MultiplyAdd2_p8r (A + ofs[i]*(mskip+1), JinvM + 2*8*ofs[i] + 8*info[i].m, J + 2*8*ofs[i] + 8*info[i].m, info[i].m,info[i].m, mskip); } } // add cfm to the diagonal of A for (i=0; iinvMass; dReal *body_invI = invI + i*12; for (j=0; j<3; j++) tmp1[i*8+j] = body[i]->facc[j] * body_invMass + body[i]->lvel[j] * stepsize1; dMULTIPLY0_331 (tmp1 + i*8 + 4,body_invI,body[i]->tacc); for (j=0; j<3; j++) tmp1[i*8+4+j] += body[i]->avel[j] * stepsize1; } // put J*tmp1 into rhs ALLOCA(dReal,rhs,m*sizeof(dReal)); //dSetZero (rhs,m); for (i=0; inode[0].body->tag, info[i].m); if (joint[i]->node[1].body) { MultiplyAdd0_p81 (rhs+ofs[i],JJ + 8*info[i].m, tmp1 + 8*joint[i]->node[1].body->tag, info[i].m); } } // complete rhs for (i=0; inode[0].body; dxBody* b2 = joint[i]->node[1].body; dJointFeedback *fb = joint[i]->feedback; if (fb) { // the user has requested feedback on the amount of force that this // joint is applying to the bodies. we use a slightly slower // computation that splits out the force components and puts them // in the feedback structure. dReal data[8]; Multiply1_8q1 (data, JJ, lambda+ofs[i], info[i].m); dReal *cf1 = cforce + 8*b1->tag; cf1[0] += (fb->f1[0] = data[0]); cf1[1] += (fb->f1[1] = data[1]); cf1[2] += (fb->f1[2] = data[2]); cf1[4] += (fb->t1[0] = data[4]); cf1[5] += (fb->t1[1] = data[5]); cf1[6] += (fb->t1[2] = data[6]); if (b2){ Multiply1_8q1 (data, JJ + 8*info[i].m, lambda+ofs[i], info[i].m); dReal *cf2 = cforce + 8*b2->tag; cf2[0] += (fb->f2[0] = data[0]); cf2[1] += (fb->f2[1] = data[1]); cf2[2] += (fb->f2[2] = data[2]); cf2[4] += (fb->t2[0] = data[4]); cf2[5] += (fb->t2[1] = data[5]); cf2[6] += (fb->t2[2] = data[6]); } } else { // no feedback is required, let's compute cforce the faster way MultiplyAdd1_8q1 (cforce + 8*b1->tag,JJ, lambda+ofs[i], info[i].m); if (b2) { MultiplyAdd1_8q1 (cforce + 8*b2->tag, JJ + 8*info[i].m, lambda+ofs[i], info[i].m); } } } } // compute the velocity update #ifdef TIMING dTimerNow ("compute velocity update"); #endif // add fe to cforce for (i=0; ifacc[j]; for (j=0; j<3; j++) cforce[i*8+4+j] += body[i]->tacc[j]; } // multiply cforce by stepsize for (i=0; i < nb*8; i++) cforce[i] *= stepsize; // add invM * cforce to the body velocity for (i=0; iinvMass; dReal *body_invI = invI + i*12; for (j=0; j<3; j++) body[i]->lvel[j] += body_invMass * cforce[i*8+j]; dMULTIPLYADD0_331 (body[i]->avel,body_invI,cforce+i*8+4); } // update the position and orientation from the new linear/angular velocity // (over the given timestep) # ifdef TIMING dTimerNow ("update position"); # endif for (i=0; ilvel[j]; for (j=0; j<3; j++) tmp_vnew[i*6+3+j] = body[i]->avel[j]; } comparator.nextMatrix (tmp_vnew,nb*6,1,0,"vnew"); #endif #ifdef TIMING dTimerNow ("tidy up"); #endif // zero all force accumulators for (i=0; ifacc[0] = 0; body[i]->facc[1] = 0; body[i]->facc[2] = 0; body[i]->facc[3] = 0; body[i]->tacc[0] = 0; body[i]->tacc[1] = 0; body[i]->tacc[2] = 0; body[i]->tacc[3] = 0; } #ifdef TIMING dTimerEnd(); if (m > 0) dTimerReport (stdout,1); #endif } //**************************************************************************** void dInternalStepIsland (dxWorld *world, dxBody * const *body, int nb, dxJoint * const *joint, int nj, dReal stepsize) { #ifdef dUSE_MALLOC_FOR_ALLOCA dMemoryFlag = d_MEMORY_OK; #endif #ifndef COMPARE_METHODS dInternalStepIsland_x2 (world,body,nb,joint,nj,stepsize); #ifdef dUSE_MALLOC_FOR_ALLOCA if (dMemoryFlag == d_MEMORY_OUT_OF_MEMORY) { REPORT_OUT_OF_MEMORY; return; } #endif #endif #ifdef COMPARE_METHODS int i; // save body state ALLOCA(dxBody,state,nb*sizeof(dxBody)); for (i=0; i #include #include #include #include "collision_kernel.h" #include "collision_space_internal.h" #define AXIS0 0 #define AXIS1 1 #define UP 2 //#define DRAWBLOCKS const int SPLITAXIS = 2; const int SPLITS = SPLITAXIS * SPLITAXIS; #define GEOM_ENABLED(g) (((g)->gflags & GEOM_ENABLE_TEST_MASK) == GEOM_ENABLE_TEST_VALUE) class Block{ public: dReal MinX, MaxX; dReal MinZ, MaxZ; dGeomID First; int GeomCount; Block* Parent; Block* Children; void Create(const dVector3 Center, const dVector3 Extents, Block* Parent, int Depth, Block*& Blocks); void Collide(void* UserData, dNearCallback* Callback); void Collide(dGeomID g1, dGeomID g2, void* UserData, dNearCallback* Callback); void CollideLocal(dGeomID g2, void* UserData, dNearCallback* Callback); void AddObject(dGeomID Object); void DelObject(dGeomID Object); void Traverse(dGeomID Object); bool Inside(const dReal* AABB); Block* GetBlock(const dReal* AABB); Block* GetBlockChild(const dReal* AABB); }; #ifdef DRAWBLOCKS #include "..\..\Include\drawstuff\\drawstuff.h" static void DrawBlock(Block* Block){ dVector3 v[8]; v[0][AXIS0] = Block->MinX; v[0][UP] = REAL(-1.0); v[0][AXIS1] = Block->MinZ; v[1][AXIS0] = Block->MinX; v[1][UP] = REAL(-1.0); v[1][AXIS1] = Block->MaxZ; v[2][AXIS0] = Block->MaxX; v[2][UP] = REAL(-1.0); v[2][AXIS1] = Block->MinZ; v[3][AXIS0] = Block->MaxX; v[3][UP] = REAL(-1.0); v[3][AXIS1] = Block->MaxZ; v[4][AXIS0] = Block->MinX; v[4][UP] = REAL(1.0); v[4][AXIS1] = Block->MinZ; v[5][AXIS0] = Block->MinX; v[5][UP] = REAL(1.0); v[5][AXIS1] = Block->MaxZ; v[6][AXIS0] = Block->MaxX; v[6][UP] = REAL(1.0); v[6][AXIS1] = Block->MinZ; v[7][AXIS0] = Block->MaxX; v[7][UP] = REAL(1.0); v[7][AXIS1] = Block->MaxZ; // Bottom dsDrawLine(v[0], v[1]); dsDrawLine(v[1], v[3]); dsDrawLine(v[3], v[2]); dsDrawLine(v[2], v[0]); // Top dsDrawLine(v[4], v[5]); dsDrawLine(v[5], v[7]); dsDrawLine(v[7], v[6]); dsDrawLine(v[6], v[4]); // Sides dsDrawLine(v[0], v[4]); dsDrawLine(v[1], v[5]); dsDrawLine(v[2], v[6]); dsDrawLine(v[3], v[7]); } #endif //DRAWBLOCKS void Block::Create(const dVector3 Center, const dVector3 Extents, Block* Parent, int Depth, Block*& Blocks){ GeomCount = 0; First = 0; MinX = Center[AXIS0] - Extents[AXIS0]; MaxX = Center[AXIS0] + Extents[AXIS0]; MinZ = Center[AXIS1] - Extents[AXIS1]; MaxZ = Center[AXIS1] + Extents[AXIS1]; this->Parent = Parent; if (Depth > 0){ Children = Blocks; Blocks += SPLITS; dVector3 ChildExtents; ChildExtents[AXIS0] = Extents[AXIS0] / SPLITAXIS; ChildExtents[AXIS1] = Extents[AXIS1] / SPLITAXIS; ChildExtents[UP] = Extents[UP]; for (int i = 0; i < SPLITAXIS; i++){ for (int j = 0; j < SPLITAXIS; j++){ int Index = i * SPLITAXIS + j; dVector3 ChildCenter; ChildCenter[AXIS0] = Center[AXIS0] - Extents[AXIS0] + ChildExtents[AXIS0] + i * (ChildExtents[AXIS0] * 2); ChildCenter[AXIS1] = Center[AXIS1] - Extents[AXIS1] + ChildExtents[AXIS1] + j * (ChildExtents[AXIS1] * 2); ChildCenter[UP] = Center[UP]; Children[Index].Create(ChildCenter, ChildExtents, this, Depth - 1, Blocks); } } } else Children = 0; } void Block::Collide(void* UserData, dNearCallback* Callback){ #ifdef DRAWBLOCKS DrawBlock(this); #endif // Collide the local list dxGeom* g = First; while (g){ if (GEOM_ENABLED(g)){ Collide(g, g->next, UserData, Callback); } g = g->next; } // Recurse for children if (Children){ for (int i = 0; i < SPLITS; i++){ if (Children[i].GeomCount <= 1){ // Early out continue; } Children[i].Collide(UserData, Callback); } } } // Note: g2 is assumed to be in this Block void Block::Collide(dxGeom* g1, dxGeom* g2, void* UserData, dNearCallback* Callback){ #ifdef DRAWBLOCKS DrawBlock(this); #endif // Collide against local list while (g2){ if (GEOM_ENABLED(g2)){ collideAABBs (g1, g2, UserData, Callback); } g2 = g2->next; } // Collide against children if (Children){ for (int i = 0; i < SPLITS; i++){ // Early out for empty blocks if (Children[i].GeomCount == 0){ continue; } // Does the geom's AABB collide with the block? // Dont do AABB tests for single geom blocks. if (Children[i].GeomCount == 1 && Children[i].First){ // } else if (true){ if (g1->aabb[AXIS0 * 2 + 0] > Children[i].MaxX || g1->aabb[AXIS0 * 2 + 1] < Children[i].MinX || g1->aabb[AXIS1 * 2 + 0] > Children[i].MaxZ || g1->aabb[AXIS1 * 2 + 1] < Children[i].MinZ) continue; } Children[i].Collide(g1, Children[i].First, UserData, Callback); } } } void Block::CollideLocal(dxGeom* g2, void* UserData, dNearCallback* Callback){ // Collide against local list dxGeom* g1 = First; while (g1){ if (GEOM_ENABLED(g1)){ collideAABBs (g1, g2, UserData, Callback); } g1 = g1->next; } } void Block::AddObject(dGeomID Object){ // Add the geom Object->next = First; First = Object; Object->tome = (dxGeom**)this; // Now traverse upwards to tell that we have a geom Block* Block = this; do{ Block->GeomCount++; Block = Block->Parent; } while (Block); } void Block::DelObject(dGeomID Object){ // Del the geom dxGeom* g = First; dxGeom* Last = 0; while (g){ if (g == Object){ if (Last){ Last->next = g->next; } else First = g->next; break; } Last = g; g = g->next; } Object->tome = 0; // Now traverse upwards to tell that we have lost a geom Block* Block = this; do{ Block->GeomCount--; Block = Block->Parent; } while (Block); } void Block::Traverse(dGeomID Object){ Block* NewBlock = GetBlock(Object->aabb); if (NewBlock != this){ // Remove the geom from the old block and add it to the new block. // This could be more optimal, but the loss should be very small. DelObject(Object); NewBlock->AddObject(Object); } } bool Block::Inside(const dReal* AABB){ return AABB[AXIS0 * 2 + 0] >= MinX && AABB[AXIS0 * 2 + 1] <= MaxX && AABB[AXIS1 * 2 + 0] >= MinZ && AABB[AXIS1 * 2 + 1] <= MaxZ; } Block* Block::GetBlock(const dReal* AABB){ if (Inside(AABB)){ return GetBlockChild(AABB); // Child or this will have a good block } else if (Parent){ return Parent->GetBlock(AABB); // Parent has a good block } else return this; // We are at the root, so we have little choice } Block* Block::GetBlockChild(const dReal* AABB){ if (Children){ for (int i = 0; i < SPLITS; i++){ if (Children[i].Inside(AABB)){ return Children[i].GetBlockChild(AABB); // Child will have good block } } } return this; // This is the best block } //**************************************************************************** // quadtree space struct dxQuadTreeSpace : public dxSpace{ Block* Blocks; // Blocks[0] is the root dArray DirtyList; dxQuadTreeSpace(dSpaceID _space, const dVector3 Center, const dVector3 Extents, int Depth); ~dxQuadTreeSpace(); dxGeom* getGeom(int i); void add(dxGeom* g); void remove(dxGeom* g); void dirty(dxGeom* g); void computeAABB(); void cleanGeoms(); void collide(void* UserData, dNearCallback* Callback); void collide2(void* UserData, dxGeom* g1, dNearCallback* Callback); // Temp data Block* CurrentBlock; // Only used while enumerating int* CurrentChild; // Only used while enumerating int CurrentLevel; // Only used while enumerating dxGeom* CurrentObject; // Only used while enumerating int CurrentIndex; }; dxQuadTreeSpace::dxQuadTreeSpace(dSpaceID _space, const dVector3 Center, const dVector3 Extents, int Depth) : dxSpace(_space){ type = dQuadTreeSpaceClass; int BlockCount = 0; // TODO: should be just BlockCount = (4^(n+1) - 1)/3 for (int i = 0; i <= Depth; i++){ BlockCount += (int)pow((dReal)SPLITS, i); } Blocks = (Block*)dAlloc(BlockCount * sizeof(Block)); Block* Blocks = this->Blocks + 1; // This pointer gets modified! this->Blocks[0].Create(Center, Extents, 0, Depth, Blocks); CurrentBlock = 0; CurrentChild = (int*)dAlloc((Depth + 1) * sizeof(int)); CurrentLevel = 0; CurrentObject = 0; CurrentIndex = -1; // Init AABB. We initialize to infinity because it is not illegal for an object to be outside of the tree. Its simply inserted in the root block aabb[0] = -dInfinity; aabb[1] = dInfinity; aabb[2] = -dInfinity; aabb[3] = dInfinity; aabb[4] = -dInfinity; aabb[5] = dInfinity; } dxQuadTreeSpace::~dxQuadTreeSpace(){ int Depth = 0; Block* Current = &Blocks[0]; while (Current){ Depth++; Current = Current->Children; } int BlockCount = 0; for (int i = 0; i < Depth; i++){ BlockCount += (int)pow((dReal)SPLITS, i); } dFree(Blocks, BlockCount * sizeof(Block)); dFree(CurrentChild, (Depth + 1) * sizeof(int)); } dxGeom* dxQuadTreeSpace::getGeom(int Index){ dUASSERT(Index >= 0 && Index < count, "index out of range"); //@@@ dDebug (0,"dxQuadTreeSpace::getGeom() not yet implemented"); return 0; // This doesnt work /*if (CurrentIndex == Index){ // Loop through all objects in the local list CHILDRECURSE: if (CurrentObject){ dGeomID g = CurrentObject; CurrentObject = CurrentObject->next; CurrentIndex++; #ifdef DRAWBLOCKS DrawBlock(CurrentBlock); #endif //DRAWBLOCKS return g; } else{ // Now lets loop through our children. Starting at index 0. if (CurrentBlock->Children){ CurrentChild[CurrentLevel] = 0; PARENTRECURSE: for (int& i = CurrentChild[CurrentLevel]; i < SPLITS; i++){ if (CurrentBlock->Children[i].GeomCount == 0){ continue; } CurrentBlock = &CurrentBlock->Children[i]; CurrentObject = CurrentBlock->First; i++; CurrentLevel++; goto CHILDRECURSE; } } } // Now lets go back to the parent so it can continue processing its other children. if (CurrentBlock->Parent){ CurrentBlock = CurrentBlock->Parent; CurrentLevel--; goto PARENTRECURSE; } } else{ CurrentBlock = &Blocks[0]; CurrentLevel = 0; CurrentObject = CurrentObject; CurrentIndex = 0; // Other states are already set CurrentObject = CurrentBlock->First; } if (current_geom && current_index == Index - 1){ //current_geom = current_geom->next; // next current_index = Index; return current_geom; } else for (int i = 0; i < Index; i++){ // this will be verrrrrrry slow getGeom(i); }*/ return 0; } void dxQuadTreeSpace::add(dxGeom* g){ CHECK_NOT_LOCKED (this); dAASSERT(g); dUASSERT(g->parent_space == 0 && g->next == 0, "geom is already in a space"); g->gflags |= GEOM_DIRTY | GEOM_AABB_BAD; DirtyList.push(g); // add g->parent_space = this; Blocks[0].GetBlock(g->aabb)->AddObject(g); // Add to best block count++; // enumerator has been invalidated current_geom = 0; dGeomMoved(this); } void dxQuadTreeSpace::remove(dxGeom* g){ CHECK_NOT_LOCKED(this); dAASSERT(g); dUASSERT(g->parent_space == this,"object is not in this space"); // remove ((Block*)g->tome)->DelObject(g); count--; for (int i = 0; i < DirtyList.size(); i++){ if (DirtyList[i] == g){ DirtyList.remove(i); // (mg) there can be multiple instances of a dirty object on stack be sure to remove ALL and not just first, for this we decrement i --i; } } // safeguard g->next = 0; g->tome = 0; g->parent_space = 0; // enumerator has been invalidated current_geom = 0; // the bounding box of this space (and that of all the parents) may have // changed as a consequence of the removal. dGeomMoved(this); } void dxQuadTreeSpace::dirty(dxGeom* g){ DirtyList.push(g); } void dxQuadTreeSpace::computeAABB(){ // } void dxQuadTreeSpace::cleanGeoms(){ // compute the AABBs of all dirty geoms, and clear the dirty flags lock_count++; for (int i = 0; i < DirtyList.size(); i++){ dxGeom* g = DirtyList[i]; if (IS_SPACE(g)){ ((dxSpace*)g)->cleanGeoms(); } g->recomputeAABB(); g->gflags &= (~(GEOM_DIRTY|GEOM_AABB_BAD)); ((Block*)g->tome)->Traverse(g); } DirtyList.setSize(0); lock_count--; } void dxQuadTreeSpace::collide(void* UserData, dNearCallback* Callback){ dAASSERT(Callback); lock_count++; cleanGeoms(); Blocks[0].Collide(UserData, Callback); lock_count--; } struct DataCallback { void *data; dNearCallback *callback; }; // Invokes the callback with arguments swapped static void swap_callback(void *data, dxGeom *g1, dxGeom *g2) { DataCallback *dc = (DataCallback*)data; dc->callback(dc->data, g2, g1); } void dxQuadTreeSpace::collide2(void* UserData, dxGeom* g2, dNearCallback* Callback){ dAASSERT(g2 && Callback); lock_count++; cleanGeoms(); g2->recomputeAABB(); if (g2->parent_space == this){ // The block the geom is in Block* CurrentBlock = (Block*)g2->tome; // Collide against block and its children DataCallback dc = {UserData, Callback}; CurrentBlock->Collide(g2, CurrentBlock->First, &dc, swap_callback); // Collide against parents while ((CurrentBlock = CurrentBlock->Parent)) CurrentBlock->CollideLocal(g2, UserData, Callback); } else { DataCallback dc = {UserData, Callback}; Blocks[0].Collide(g2, Blocks[0].First, &dc, swap_callback); } lock_count--; } dSpaceID dQuadTreeSpaceCreate(dxSpace* space, const dVector3 Center, const dVector3 Extents, int Depth){ return new dxQuadTreeSpace(space, Center, Extents, Depth); } alien-arena-7.66+dfsg/source/unix/odesrc/objects.h0000600000175000017500000001462212161402010021153 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ // object, body, and world structs. #ifndef _ODE_OBJECT_H_ #define _ODE_OBJECT_H_ #include #include #include #include "array.h" // some body flags enum { dxBodyFlagFiniteRotation = 1, // use finite rotations dxBodyFlagFiniteRotationAxis = 2, // use finite rotations only along axis dxBodyDisabled = 4, // body is disabled dxBodyNoGravity = 8, // body is not influenced by gravity dxBodyAutoDisable = 16, // enable auto-disable on body dxBodyLinearDamping = 32, // use linear damping dxBodyAngularDamping = 64, // use angular damping dxBodyMaxAngularSpeed = 128,// use maximum angular speed dxBodyGyroscopic = 256,// use gyroscopic term }; // base class that does correct object allocation / deallocation struct dBase { void *operator new (size_t size) { return dAlloc (size); } void *operator new (size_t size, void *p) { return p; } void operator delete (void *ptr, size_t size) { dFree (ptr,size); } void *operator new[] (size_t size) { return dAlloc (size); } void operator delete[] (void *ptr, size_t size) { dFree (ptr,size); } }; // base class for bodies and joints struct dObject : public dBase { dxWorld *world; // world this object is in dObject *next; // next object of this type in list dObject **tome; // pointer to previous object's next ptr int tag; // used by dynamics algorithms void *userdata; // user settable data dObject(dxWorld *w); virtual ~dObject() { } }; // auto disable parameters struct dxAutoDisable { dReal idle_time; // time the body needs to be idle to auto-disable it int idle_steps; // steps the body needs to be idle to auto-disable it dReal linear_average_threshold; // linear (squared) average velocity threshold dReal angular_average_threshold; // angular (squared) average velocity threshold unsigned int average_samples; // size of the average_lvel and average_avel buffers }; // damping parameters struct dxDampingParameters { dReal linear_scale; // multiply the linear velocity by (1 - scale) dReal angular_scale; // multiply the angular velocity by (1 - scale) dReal linear_threshold; // linear (squared) average speed threshold dReal angular_threshold; // angular (squared) average speed threshold }; // quick-step parameters struct dxQuickStepParameters { int num_iterations; // number of SOR iterations to perform dReal w; // the SOR over-relaxation parameter }; // contact generation parameters struct dxContactParameters { dReal max_vel; // maximum correcting velocity dReal min_depth; // thickness of 'surface layer' }; // position vector and rotation matrix for geometry objects that are not // connected to bodies. struct dxPosR { dVector3 pos; dMatrix3 R; }; struct dxBody : public dObject { dxJointNode *firstjoint; // list of attached joints unsigned flags; // some dxBodyFlagXXX flags dGeomID geom; // first collision geom associated with body dMass mass; // mass parameters about POR dMatrix3 invI; // inverse of mass.I dReal invMass; // 1 / mass.mass dxPosR posr; // position and orientation of point of reference dQuaternion q; // orientation quaternion dVector3 lvel,avel; // linear and angular velocity of POR dVector3 facc,tacc; // force and torque accumulators dVector3 finite_rot_axis; // finite rotation axis, unit length or 0=none // auto-disable information dxAutoDisable adis; // auto-disable parameters dReal adis_timeleft; // time left to be idle int adis_stepsleft; // steps left to be idle dVector3* average_lvel_buffer; // buffer for the linear average velocity calculation dVector3* average_avel_buffer; // buffer for the angular average velocity calculation unsigned int average_counter; // counter/index to fill the average-buffers int average_ready; // indicates ( with = 1 ), if the Body's buffers are ready for average-calculations void (*moved_callback)(dxBody*); // let the user know the body moved dxDampingParameters dampingp; // damping parameters, depends on flags dReal max_angular_speed; // limit the angular velocity to this magnitude dxBody(dxWorld *w); }; struct dxWorld : public dBase { dxBody *firstbody; // body linked list dxJoint *firstjoint; // joint linked list int nb,nj; // number of bodies and joints in lists dVector3 gravity; // gravity vector (m/s/s) dReal global_erp; // global error reduction parameter dReal global_cfm; // global costraint force mixing parameter dxAutoDisable adis; // auto-disable parameters int body_flags; // flags for new bodies dxQuickStepParameters qs; dxContactParameters contactp; dxDampingParameters dampingp; // damping parameters dReal max_angular_speed; // limit the angular velocity to this magnitude }; #endif alien-arena-7.66+dfsg/source/unix/odesrc/box.cpp0000600000175000017500000006472412161402010020655 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* standard ODE geometry primitives: public API and pairwise collision functions. the rule is that only the low level primitive collision functions should set dContactGeom::g1 and dContactGeom::g2. */ #include #include #include #include #include #include "collision_kernel.h" #include "collision_std.h" #include "collision_util.h" #ifdef _MSC_VER #pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" #endif //**************************************************************************** // box public API dxBox::dxBox (dSpaceID space, dReal lx, dReal ly, dReal lz) : dxGeom (space,1) { dAASSERT (lx >= 0 && ly >= 0 && lz >= 0); type = dBoxClass; side[0] = lx; side[1] = ly; side[2] = lz; updateZeroSizedFlag(!lx || !ly || !lz); } void dxBox::computeAABB() { const dMatrix3& R = final_posr->R; const dVector3& pos = final_posr->pos; dReal xrange = REAL(0.5) * (dFabs (R[0] * side[0]) + dFabs (R[1] * side[1]) + dFabs (R[2] * side[2])); dReal yrange = REAL(0.5) * (dFabs (R[4] * side[0]) + dFabs (R[5] * side[1]) + dFabs (R[6] * side[2])); dReal zrange = REAL(0.5) * (dFabs (R[8] * side[0]) + dFabs (R[9] * side[1]) + dFabs (R[10] * side[2])); aabb[0] = pos[0] - xrange; aabb[1] = pos[0] + xrange; aabb[2] = pos[1] - yrange; aabb[3] = pos[1] + yrange; aabb[4] = pos[2] - zrange; aabb[5] = pos[2] + zrange; } dGeomID dCreateBox (dSpaceID space, dReal lx, dReal ly, dReal lz) { return new dxBox (space,lx,ly,lz); } void dGeomBoxSetLengths (dGeomID g, dReal lx, dReal ly, dReal lz) { dUASSERT (g && g->type == dBoxClass,"argument not a box"); dAASSERT (lx >= 0 && ly >= 0 && lz >= 0); dxBox *b = (dxBox*) g; b->side[0] = lx; b->side[1] = ly; b->side[2] = lz; b->updateZeroSizedFlag(!lx || !ly || !lz); dGeomMoved (g); } void dGeomBoxGetLengths (dGeomID g, dVector3 result) { dUASSERT (g && g->type == dBoxClass,"argument not a box"); dxBox *b = (dxBox*) g; result[0] = b->side[0]; result[1] = b->side[1]; result[2] = b->side[2]; } dReal dGeomBoxPointDepth (dGeomID g, dReal x, dReal y, dReal z) { dUASSERT (g && g->type == dBoxClass,"argument not a box"); g->recomputePosr(); dxBox *b = (dxBox*) g; // Set p = (x,y,z) relative to box center // // This will be (0,0,0) if the point is at (side[0]/2,side[1]/2,side[2]/2) dVector3 p,q; p[0] = x - b->final_posr->pos[0]; p[1] = y - b->final_posr->pos[1]; p[2] = z - b->final_posr->pos[2]; // Rotate p into box's coordinate frame, so we can // treat the OBB as an AABB dMULTIPLY1_331 (q,b->final_posr->R,p); // Record distance from point to each successive box side, and see // if the point is inside all six sides dReal dist[6]; int i; bool inside = true; for (i=0; i < 3; i++) { dReal side = b->side[i] * REAL(0.5); dist[i ] = side - q[i]; dist[i+3] = side + q[i]; if ((dist[i] < 0) || (dist[i+3] < 0)) { inside = false; } } // If point is inside the box, the depth is the smallest positive distance // to any side if (inside) { dReal smallest_dist = (dReal) (unsigned) -1; for (i=0; i < 6; i++) { if (dist[i] < smallest_dist) smallest_dist = dist[i]; } return smallest_dist; } // Otherwise, if point is outside the box, the depth is the largest // distance to any side. This is an approximation to the 'proper' // solution (the proper solution may be larger in some cases). dReal largest_dist = 0; for (i=0; i < 6; i++) { if (dist[i] > largest_dist) largest_dist = dist[i]; } return -largest_dist; } //**************************************************************************** // box-box collision utility // find all the intersection points between the 2D rectangle with vertices // at (+/-h[0],+/-h[1]) and the 2D quadrilateral with vertices (p[0],p[1]), // (p[2],p[3]),(p[4],p[5]),(p[6],p[7]). // // the intersection points are returned as x,y pairs in the 'ret' array. // the number of intersection points is returned by the function (this will // be in the range 0 to 8). static int intersectRectQuad (dReal h[2], dReal p[8], dReal ret[16]) { // q (and r) contain nq (and nr) coordinate points for the current (and // chopped) polygons int nq=4,nr; dReal buffer[16]; dReal *q = p; dReal *r = ret; for (int dir=0; dir <= 1; dir++) { // direction notation: xy[0] = x axis, xy[1] = y axis for (int sign=-1; sign <= 1; sign += 2) { // chop q along the line xy[dir] = sign*h[dir] dReal *pq = q; dReal *pr = r; nr = 0; for (int i=nq; i > 0; i--) { // go through all points in q and all lines between adjacent points if (sign*pq[dir] < h[dir]) { // this point is inside the chopping line pr[0] = pq[0]; pr[1] = pq[1]; pr += 2; nr++; if (nr & 8) { q = r; goto done; } } dReal *nextq = (i > 1) ? pq+2 : q; if ((sign*pq[dir] < h[dir]) ^ (sign*nextq[dir] < h[dir])) { // this line crosses the chopping line pr[1-dir] = pq[1-dir] + (nextq[1-dir]-pq[1-dir]) / (nextq[dir]-pq[dir]) * (sign*h[dir]-pq[dir]); pr[dir] = sign*h[dir]; pr += 2; nr++; if (nr & 8) { q = r; goto done; } } pq += 2; } q = r; r = (q==ret) ? buffer : ret; nq = nr; } } done: if (q != ret) memcpy (ret,q,nr*2*sizeof(dReal)); return nr; } // given n points in the plane (array p, of size 2*n), generate m points that // best represent the whole set. the definition of 'best' here is not // predetermined - the idea is to select points that give good box-box // collision detection behavior. the chosen point indexes are returned in the // array iret (of size m). 'i0' is always the first entry in the array. // n must be in the range [1..8]. m must be in the range [1..n]. i0 must be // in the range [0..n-1]. void cullPoints (int n, dReal p[], int m, int i0, int iret[]) { // compute the centroid of the polygon in cx,cy int i,j; dReal a,cx,cy,q; if (n==1) { cx = p[0]; cy = p[1]; } else if (n==2) { cx = REAL(0.5)*(p[0] + p[2]); cy = REAL(0.5)*(p[1] + p[3]); } else { a = 0; cx = 0; cy = 0; for (i=0; i<(n-1); i++) { q = p[i*2]*p[i*2+3] - p[i*2+2]*p[i*2+1]; a += q; cx += q*(p[i*2]+p[i*2+2]); cy += q*(p[i*2+1]+p[i*2+3]); } q = p[n*2-2]*p[1] - p[0]*p[n*2-1]; a = dRecip(REAL(3.0)*(a+q)); cx = a*(cx + q*(p[n*2-2]+p[0])); cy = a*(cy + q*(p[n*2-1]+p[1])); } // compute the angle of each point w.r.t. the centroid dReal A[8]; for (i=0; i M_PI) a -= (dReal)(2*M_PI); dReal maxdiff=1e9,diff; #ifndef dNODEBUG *iret = i0; // iret is not allowed to keep this value #endif for (i=0; i M_PI) diff = (dReal) (2*M_PI - diff); if (diff < maxdiff) { maxdiff = diff; *iret = i; } } } #ifndef dNODEBUG dIASSERT (*iret != i0); // ensure iret got set #endif avail[*iret] = 0; iret++; } } // given two boxes (p1,R1,side1) and (p2,R2,side2), collide them together and // generate contact points. this returns 0 if there is no contact otherwise // it returns the number of contacts generated. // `normal' returns the contact normal. // `depth' returns the maximum penetration depth along that normal. // `return_code' returns a number indicating the type of contact that was // detected: // 1,2,3 = box 2 intersects with a face of box 1 // 4,5,6 = box 1 intersects with a face of box 2 // 7..15 = edge-edge contact // `maxc' is the maximum number of contacts allowed to be generated, i.e. // the size of the `contact' array. // `contact' and `skip' are the contact array information provided to the // collision functions. this function only fills in the position and depth // fields. int dBoxBox (const dVector3 p1, const dMatrix3 R1, const dVector3 side1, const dVector3 p2, const dMatrix3 R2, const dVector3 side2, dVector3 normal, dReal *depth, int *return_code, int flags, dContactGeom *contact, int skip) { const dReal fudge_factor = REAL(1.05); dVector3 p,pp,normalC={0,0,0}; const dReal *normalR = 0; dReal A[3],B[3],R11,R12,R13,R21,R22,R23,R31,R32,R33, Q11,Q12,Q13,Q21,Q22,Q23,Q31,Q32,Q33,s,s2,l,expr1_val; int i,j,invert_normal,code; // get vector from centers of box 1 to box 2, relative to box 1 p[0] = p2[0] - p1[0]; p[1] = p2[1] - p1[1]; p[2] = p2[2] - p1[2]; dMULTIPLY1_331 (pp,R1,p); // get pp = p relative to body 1 // get side lengths / 2 A[0] = side1[0]*REAL(0.5); A[1] = side1[1]*REAL(0.5); A[2] = side1[2]*REAL(0.5); B[0] = side2[0]*REAL(0.5); B[1] = side2[1]*REAL(0.5); B[2] = side2[2]*REAL(0.5); // Rij is R1'*R2, i.e. the relative rotation between R1 and R2 R11 = dDOT44(R1+0,R2+0); R12 = dDOT44(R1+0,R2+1); R13 = dDOT44(R1+0,R2+2); R21 = dDOT44(R1+1,R2+0); R22 = dDOT44(R1+1,R2+1); R23 = dDOT44(R1+1,R2+2); R31 = dDOT44(R1+2,R2+0); R32 = dDOT44(R1+2,R2+1); R33 = dDOT44(R1+2,R2+2); Q11 = dFabs(R11); Q12 = dFabs(R12); Q13 = dFabs(R13); Q21 = dFabs(R21); Q22 = dFabs(R22); Q23 = dFabs(R23); Q31 = dFabs(R31); Q32 = dFabs(R32); Q33 = dFabs(R33); // for all 15 possible separating axes: // * see if the axis separates the boxes. if so, return 0. // * find the depth of the penetration along the separating axis (s2) // * if this is the largest depth so far, record it. // the normal vector will be set to the separating axis with the smallest // depth. note: normalR is set to point to a column of R1 or R2 if that is // the smallest depth normal so far. otherwise normalR is 0 and normalC is // set to a vector relative to body 1. invert_normal is 1 if the sign of // the normal should be flipped. do { #define TST(expr1,expr2,norm,cc) \ expr1_val = (expr1); /* Avoid duplicate evaluation of expr1 */ \ s2 = dFabs(expr1_val) - (expr2); \ if (s2 > 0) return 0; \ if (s2 > s) { \ s = s2; \ normalR = norm; \ invert_normal = ((expr1_val) < 0); \ code = (cc); \ if (flags & CONTACTS_UNIMPORTANT) break; \ } s = -dInfinity; invert_normal = 0; code = 0; // separating axis = u1,u2,u3 TST (pp[0],(A[0] + B[0]*Q11 + B[1]*Q12 + B[2]*Q13),R1+0,1); TST (pp[1],(A[1] + B[0]*Q21 + B[1]*Q22 + B[2]*Q23),R1+1,2); TST (pp[2],(A[2] + B[0]*Q31 + B[1]*Q32 + B[2]*Q33),R1+2,3); // separating axis = v1,v2,v3 TST (dDOT41(R2+0,p),(A[0]*Q11 + A[1]*Q21 + A[2]*Q31 + B[0]),R2+0,4); TST (dDOT41(R2+1,p),(A[0]*Q12 + A[1]*Q22 + A[2]*Q32 + B[1]),R2+1,5); TST (dDOT41(R2+2,p),(A[0]*Q13 + A[1]*Q23 + A[2]*Q33 + B[2]),R2+2,6); // note: cross product axes need to be scaled when s is computed. // normal (n1,n2,n3) is relative to box 1. #undef TST #define TST(expr1,expr2,n1,n2,n3,cc) \ expr1_val = (expr1); /* Avoid duplicate evaluation of expr1 */ \ s2 = dFabs(expr1_val) - (expr2); \ if (s2 > 0) return 0; \ l = dSqrt ((n1)*(n1) + (n2)*(n2) + (n3)*(n3)); \ if (l > 0) { \ s2 /= l; \ if (s2*fudge_factor > s) { \ s = s2; \ normalR = 0; \ normalC[0] = (n1)/l; normalC[1] = (n2)/l; normalC[2] = (n3)/l; \ invert_normal = ((expr1_val) < 0); \ code = (cc); \ if (flags & CONTACTS_UNIMPORTANT) break; \ } \ } // We only need to check 3 edges per box // since parallel edges are equivalent. // separating axis = u1 x (v1,v2,v3) TST(pp[2]*R21-pp[1]*R31,(A[1]*Q31+A[2]*Q21+B[1]*Q13+B[2]*Q12),0,-R31,R21,7); TST(pp[2]*R22-pp[1]*R32,(A[1]*Q32+A[2]*Q22+B[0]*Q13+B[2]*Q11),0,-R32,R22,8); TST(pp[2]*R23-pp[1]*R33,(A[1]*Q33+A[2]*Q23+B[0]*Q12+B[1]*Q11),0,-R33,R23,9); // separating axis = u2 x (v1,v2,v3) TST(pp[0]*R31-pp[2]*R11,(A[0]*Q31+A[2]*Q11+B[1]*Q23+B[2]*Q22),R31,0,-R11,10); TST(pp[0]*R32-pp[2]*R12,(A[0]*Q32+A[2]*Q12+B[0]*Q23+B[2]*Q21),R32,0,-R12,11); TST(pp[0]*R33-pp[2]*R13,(A[0]*Q33+A[2]*Q13+B[0]*Q22+B[1]*Q21),R33,0,-R13,12); // separating axis = u3 x (v1,v2,v3) TST(pp[1]*R11-pp[0]*R21,(A[0]*Q21+A[1]*Q11+B[1]*Q33+B[2]*Q32),-R21,R11,0,13); TST(pp[1]*R12-pp[0]*R22,(A[0]*Q22+A[1]*Q12+B[0]*Q33+B[2]*Q31),-R22,R12,0,14); TST(pp[1]*R13-pp[0]*R23,(A[0]*Q23+A[1]*Q13+B[0]*Q32+B[1]*Q31),-R23,R13,0,15); #undef TST } while (0); if (!code) return 0; // if we get to this point, the boxes interpenetrate. compute the normal // in global coordinates. if (normalR) { normal[0] = normalR[0]; normal[1] = normalR[4]; normal[2] = normalR[8]; } else { dMULTIPLY0_331 (normal,R1,normalC); } if (invert_normal) { normal[0] = -normal[0]; normal[1] = -normal[1]; normal[2] = -normal[2]; } *depth = -s; // compute contact point(s) if (code > 6) { // An edge from box 1 touches an edge from box 2. // find a point pa on the intersecting edge of box 1 dVector3 pa; dReal sign; // Copy p1 into pa for (i=0; i<3; i++) pa[i] = p1[i]; // why no memcpy? // Get world position of p2 into pa for (j=0; j<3; j++) { sign = (dDOT14(normal,R1+j) > 0) ? REAL(1.0) : REAL(-1.0); for (i=0; i<3; i++) pa[i] += sign * A[j] * R1[i*4+j]; } // find a point pb on the intersecting edge of box 2 dVector3 pb; // Copy p2 into pb for (i=0; i<3; i++) pb[i] = p2[i]; // why no memcpy? // Get world position of p2 into pb for (j=0; j<3; j++) { sign = (dDOT14(normal,R2+j) > 0) ? REAL(-1.0) : REAL(1.0); for (i=0; i<3; i++) pb[i] += sign * B[j] * R2[i*4+j]; } dReal alpha,beta; dVector3 ua,ub; // Get direction of first edge for (i=0; i<3; i++) ua[i] = R1[((code)-7)/3 + i*4]; // Get direction of second edge for (i=0; i<3; i++) ub[i] = R2[((code)-7)%3 + i*4]; // Get closest points between edges (one at each) dLineClosestApproach (pa,ua,pb,ub,&alpha,&beta); for (i=0; i<3; i++) pa[i] += ua[i]*alpha; for (i=0; i<3; i++) pb[i] += ub[i]*beta; // Set the contact point as halfway between the 2 closest points for (i=0; i<3; i++) contact[0].pos[i] = REAL(0.5)*(pa[i]+pb[i]); contact[0].depth = *depth; *return_code = code; return 1; } // okay, we have a face-something intersection (because the separating // axis is perpendicular to a face). define face 'a' to be the reference // face (i.e. the normal vector is perpendicular to this) and face 'b' to be // the incident face (the closest face of the other box). // Note: Unmodified parameter values are being used here const dReal *Ra,*Rb,*pa,*pb,*Sa,*Sb; if (code <= 3) { // One of the faces of box 1 is the reference face Ra = R1; // Rotation of 'a' Rb = R2; // Rotation of 'b' pa = p1; // Center (location) of 'a' pb = p2; // Center (location) of 'b' Sa = A; // Side Lenght of 'a' Sb = B; // Side Lenght of 'b' } else { // One of the faces of box 2 is the reference face Ra = R2; // Rotation of 'a' Rb = R1; // Rotation of 'b' pa = p2; // Center (location) of 'a' pb = p1; // Center (location) of 'b' Sa = B; // Side Lenght of 'a' Sb = A; // Side Lenght of 'b' } // nr = normal vector of reference face dotted with axes of incident box. // anr = absolute values of nr. /* The normal is flipped if necessary so it always points outward from box 'a', box 'b' is thus always the incident box */ dVector3 normal2,nr,anr; if (code <= 3) { normal2[0] = normal[0]; normal2[1] = normal[1]; normal2[2] = normal[2]; } else { normal2[0] = -normal[0]; normal2[1] = -normal[1]; normal2[2] = -normal[2]; } // Rotate normal2 in incident box opposite direction dMULTIPLY1_331 (nr,Rb,normal2); anr[0] = dFabs (nr[0]); anr[1] = dFabs (nr[1]); anr[2] = dFabs (nr[2]); // find the largest compontent of anr: this corresponds to the normal // for the incident face. the other axis numbers of the incident face // are stored in a1,a2. int lanr,a1,a2; if (anr[1] > anr[0]) { if (anr[1] > anr[2]) { a1 = 0; lanr = 1; a2 = 2; } else { a1 = 0; a2 = 1; lanr = 2; } } else { if (anr[0] > anr[2]) { lanr = 0; a1 = 1; a2 = 2; } else { a1 = 0; a2 = 1; lanr = 2; } } // compute center point of incident face, in reference-face coordinates dVector3 center; if (nr[lanr] < 0) { for (i=0; i<3; i++) center[i] = pb[i] - pa[i] + Sb[lanr] * Rb[i*4+lanr]; } else { for (i=0; i<3; i++) center[i] = pb[i] - pa[i] - Sb[lanr] * Rb[i*4+lanr]; } // find the normal and non-normal axis numbers of the reference box int codeN,code1,code2; if (code <= 3) codeN = code-1; else codeN = code-4; if (codeN==0) { code1 = 1; code2 = 2; } else if (codeN==1) { code1 = 0; code2 = 2; } else { code1 = 0; code2 = 1; } // find the four corners of the incident face, in reference-face coordinates dReal quad[8]; // 2D coordinate of incident face (x,y pairs) dReal c1,c2,m11,m12,m21,m22; c1 = dDOT14 (center,Ra+code1); c2 = dDOT14 (center,Ra+code2); // optimize this? - we have already computed this data above, but it is not // stored in an easy-to-index format. for now it's quicker just to recompute // the four dot products. m11 = dDOT44 (Ra+code1,Rb+a1); m12 = dDOT44 (Ra+code1,Rb+a2); m21 = dDOT44 (Ra+code2,Rb+a1); m22 = dDOT44 (Ra+code2,Rb+a2); { dReal k1 = m11*Sb[a1]; dReal k2 = m21*Sb[a1]; dReal k3 = m12*Sb[a2]; dReal k4 = m22*Sb[a2]; quad[0] = c1 - k1 - k3; quad[1] = c2 - k2 - k4; quad[2] = c1 - k1 + k3; quad[3] = c2 - k2 + k4; quad[4] = c1 + k1 + k3; quad[5] = c2 + k2 + k4; quad[6] = c1 + k1 - k3; quad[7] = c2 + k2 - k4; } // find the size of the reference face dReal rect[2]; rect[0] = Sa[code1]; rect[1] = Sa[code2]; // intersect the incident and reference faces dReal ret[16]; int n = intersectRectQuad (rect,quad,ret); if (n < 1) return 0; // this should never happen // convert the intersection points into reference-face coordinates, // and compute the contact position and depth for each point. only keep // those points that have a positive (penetrating) depth. delete points in // the 'ret' array as necessary so that 'point' and 'ret' correspond. dReal point[3*8]; // penetrating contact points dReal dep[8]; // depths for those points dReal det1 = dRecip(m11*m22 - m12*m21); m11 *= det1; m12 *= det1; m21 *= det1; m22 *= det1; int cnum = 0; // number of penetrating contact points found for (j=0; j < n; j++) { dReal k1 = m22*(ret[j*2]-c1) - m12*(ret[j*2+1]-c2); dReal k2 = -m21*(ret[j*2]-c1) + m11*(ret[j*2+1]-c2); for (i=0; i<3; i++) point[cnum*3+i] = center[i] + k1*Rb[i*4+a1] + k2*Rb[i*4+a2]; dep[cnum] = Sa[codeN] - dDOT(normal2,point+cnum*3); if (dep[cnum] >= 0) { ret[cnum*2] = ret[j*2]; ret[cnum*2+1] = ret[j*2+1]; cnum++; if ((cnum | CONTACTS_UNIMPORTANT) == (flags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { break; } } } if (cnum < 1) { return 0; // this should not happen, yet does at times (demo_plane2d single precision). } // we can't generate more contacts than we actually have int maxc = flags & NUMC_MASK; if (maxc > cnum) maxc = cnum; if (maxc < 1) maxc = 1; // Even though max count must not be zero this check is kept for backward compatibility as this is a public function if (cnum <= maxc) { // we have less contacts than we need, so we use them all for (j=0; j < cnum; j++) { dContactGeom *con = CONTACT(contact,skip*j); for (i=0; i<3; i++) con->pos[i] = point[j*3+i] + pa[i]; con->depth = dep[j]; } } else { dIASSERT(!(flags & CONTACTS_UNIMPORTANT)); // cnum should be generated not greater than maxc so that "then" clause is executed // we have more contacts than are wanted, some of them must be culled. // find the deepest point, it is always the first contact. int i1 = 0; dReal maxdepth = dep[0]; for (i=1; i maxdepth) { maxdepth = dep[i]; i1 = i; } } int iret[8]; cullPoints (cnum,ret,maxc,i1,iret); for (j=0; j < maxc; j++) { dContactGeom *con = CONTACT(contact,skip*j); for (i=0; i<3; i++) con->pos[i] = point[iret[j]*3+i] + pa[i]; con->depth = dep[iret[j]]; } cnum = maxc; } *return_code = code; return cnum; } int dCollideBoxBox (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT (o1->type == dBoxClass); dIASSERT (o2->type == dBoxClass); dIASSERT ((flags & NUMC_MASK) >= 1); dVector3 normal; dReal depth; int code; dxBox *b1 = (dxBox*) o1; dxBox *b2 = (dxBox*) o2; int num = dBoxBox (o1->final_posr->pos,o1->final_posr->R,b1->side, o2->final_posr->pos,o2->final_posr->R,b2->side, normal,&depth,&code,flags,contact,skip); for (int i=0; inormal[0] = -normal[0]; currContact->normal[1] = -normal[1]; currContact->normal[2] = -normal[2]; currContact->g1 = o1; currContact->g2 = o2; currContact->side1 = -1; currContact->side2 = -1; } return num; } int dCollideBoxPlane (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT (o1->type == dBoxClass); dIASSERT (o2->type == dPlaneClass); dIASSERT ((flags & NUMC_MASK) >= 1); dxBox *box = (dxBox*) o1; dxPlane *plane = (dxPlane*) o2; contact->g1 = o1; contact->g2 = o2; contact->side1 = -1; contact->side2 = -1; int ret = 0; //@@@ problem: using 4-vector (plane->p) as 3-vector (normal). const dReal *R = o1->final_posr->R; // rotation of box const dReal *n = plane->p; // normal vector // project sides lengths along normal vector, get absolute values dReal Q1 = dDOT14(n,R+0); dReal Q2 = dDOT14(n,R+1); dReal Q3 = dDOT14(n,R+2); dReal A1 = box->side[0] * Q1; dReal A2 = box->side[1] * Q2; dReal A3 = box->side[2] * Q3; dReal B1 = dFabs(A1); dReal B2 = dFabs(A2); dReal B3 = dFabs(A3); // early exit test dReal depth = plane->p[3] + REAL(0.5)*(B1+B2+B3) - dDOT(n,o1->final_posr->pos); if (depth < 0) return 0; // find number of contacts requested int maxc = flags & NUMC_MASK; // if (maxc < 1) maxc = 1; // an assertion is made on entry if (maxc > 3) maxc = 3; // not more than 3 contacts per box allowed // find deepest point dVector3 p; p[0] = o1->final_posr->pos[0]; p[1] = o1->final_posr->pos[1]; p[2] = o1->final_posr->pos[2]; #define FOO(i,op) \ p[0] op REAL(0.5)*box->side[i] * R[0+i]; \ p[1] op REAL(0.5)*box->side[i] * R[4+i]; \ p[2] op REAL(0.5)*box->side[i] * R[8+i]; #define BAR(i,iinc) if (A ## iinc > 0) { FOO(i,-=) } else { FOO(i,+=) } BAR(0,1); BAR(1,2); BAR(2,3); #undef FOO #undef BAR // the deepest point is the first contact point contact->pos[0] = p[0]; contact->pos[1] = p[1]; contact->pos[2] = p[2]; contact->normal[0] = n[0]; contact->normal[1] = n[1]; contact->normal[2] = n[2]; contact->depth = depth; ret = 1; // ret is number of contact points found so far if (maxc == 1) goto done; // get the second and third contact points by starting from `p' and going // along the two sides with the smallest projected length. #define FOO(i,j,op) \ CONTACT(contact,i*skip)->pos[0] = p[0] op box->side[j] * R[0+j]; \ CONTACT(contact,i*skip)->pos[1] = p[1] op box->side[j] * R[4+j]; \ CONTACT(contact,i*skip)->pos[2] = p[2] op box->side[j] * R[8+j]; #define BAR(ctact,side,sideinc) \ depth -= B ## sideinc; \ if (depth < 0) goto done; \ if (A ## sideinc > 0) { FOO(ctact,side,+); } else { FOO(ctact,side,-); } \ CONTACT(contact,ctact*skip)->depth = depth; \ ret++; CONTACT(contact,skip)->normal[0] = n[0]; CONTACT(contact,skip)->normal[1] = n[1]; CONTACT(contact,skip)->normal[2] = n[2]; if (maxc == 3) { CONTACT(contact,2*skip)->normal[0] = n[0]; CONTACT(contact,2*skip)->normal[1] = n[1]; CONTACT(contact,2*skip)->normal[2] = n[2]; } if (B1 < B2) { if (B3 < B1) goto use_side_3; else { BAR(1,0,1); // use side 1 if (maxc == 2) goto done; if (B2 < B3) goto contact2_2; else goto contact2_3; } } else { if (B3 < B2) { use_side_3: // use side 3 BAR(1,2,3); if (maxc == 2) goto done; if (B1 < B2) goto contact2_1; else goto contact2_2; } else { BAR(1,1,2); // use side 2 if (maxc == 2) goto done; if (B1 < B3) goto contact2_1; else goto contact2_3; } } contact2_1: BAR(2,0,1); goto done; contact2_2: BAR(2,1,2); goto done; contact2_3: BAR(2,2,3); goto done; #undef FOO #undef BAR done: for (int i=0; ig1 = o1; currContact->g2 = o2; currContact->side1 = -1; currContact->side2 = -1; } return ret; } alien-arena-7.66+dfsg/source/unix/odesrc/collision_trimesh_colliders.h0000600000175000017500000000522312161402010025305 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_COLLISION_TRIMESH_COLLIDERS_H_ #define _ODE_COLLISION_TRIMESH_COLLIDERS_H_ int dCollideCylinderTrimesh(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideTrimeshPlane(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideSTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideBTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideRTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideTTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideCCTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); PURE_INLINE int dCollideRayTrimesh( dxGeom *ray, dxGeom *trimesh, int flags, dContactGeom *contact, int skip ) { // Swapped case, for code that needs it (heightfield initially) // The other ray-geom colliders take geoms in a swapped order to the // dCollideRTL function which is annoying when using function pointers. return dCollideRTL( trimesh, ray, flags, contact, skip ); } #endif // _ODE_COLLISION_TRIMESH_COLLIDERS_H_ alien-arena-7.66+dfsg/source/unix/odesrc/ode.cpp0000600000175000017500000013221112161402010020617 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifdef _MSC_VER #pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" #endif // this source file is mostly concerned with the data structures, not the // numerics. #include "objects.h" #include #include "joints/joints.h" #include #include #include "step.h" #include "quickstep.h" #include "util.h" #include #include // misc defines #define ALLOCA dALLOCA16 //**************************************************************************** // utility dObject::dObject(dxWorld *w) { world = w; next = 0; tome = 0; userdata = 0; tag = 0; } // add an object `obj' to the list who's head pointer is pointed to by `first'. void addObjectToList (dObject *obj, dObject **first) { obj->next = *first; obj->tome = first; if (*first) (*first)->tome = &obj->next; (*first) = obj; } // remove the object from the linked list static inline void removeObjectFromList (dObject *obj) { if (obj->next) obj->next->tome = obj->tome; *(obj->tome) = obj->next; // safeguard obj->next = 0; obj->tome = 0; } // remove the joint from neighbour lists of all connected bodies static void removeJointReferencesFromAttachedBodies (dxJoint *j) { for (int i=0; i<2; i++) { dxBody *body = j->node[i].body; if (body) { dxJointNode *n = body->firstjoint; dxJointNode *last = 0; while (n) { if (n->joint == j) { if (last) last->next = n->next; else body->firstjoint = n->next; break; } last = n; n = n->next; } } } j->node[0].body = 0; j->node[0].next = 0; j->node[1].body = 0; j->node[1].next = 0; } //**************************************************************************** // debugging // see if an object list loops on itself (if so, it's bad). static int listHasLoops (dObject *first) { if (first==0 || first->next==0) return 0; dObject *a=first,*b=first->next; int skip=0; while (b) { if (a==b) return 1; b = b->next; if (skip) a = a->next; skip ^= 1; } return 0; } // check the validity of the world data structures static int g_world_check_tag_generator = 0; static inline int generateWorldCheckTag() { // Atomicity is not necessary here return ++g_world_check_tag_generator; } static void checkWorld (dxWorld *w) { dxBody *b; dxJoint *j; // check there are no loops if (listHasLoops (w->firstbody)) dDebug (0,"body list has loops"); if (listHasLoops (w->firstjoint)) dDebug (0,"joint list has loops"); // check lists are well formed (check `tome' pointers) for (b=w->firstbody; b; b=(dxBody*)b->next) { if (b->next && b->next->tome != &b->next) dDebug (0,"bad tome pointer in body list"); } for (j=w->firstjoint; j; j=(dxJoint*)j->next) { if (j->next && j->next->tome != &j->next) dDebug (0,"bad tome pointer in joint list"); } // check counts int n = 0; for (b=w->firstbody; b; b=(dxBody*)b->next) n++; if (w->nb != n) dDebug (0,"body count incorrect"); n = 0; for (j=w->firstjoint; j; j=(dxJoint*)j->next) n++; if (w->nj != n) dDebug (0,"joint count incorrect"); // set all tag values to a known value int count = generateWorldCheckTag(); for (b=w->firstbody; b; b=(dxBody*)b->next) b->tag = count; for (j=w->firstjoint; j; j=(dxJoint*)j->next) j->tag = count; // check all body/joint world pointers are ok for (b=w->firstbody; b; b=(dxBody*)b->next) if (b->world != w) dDebug (0,"bad world pointer in body list"); for (j=w->firstjoint; j; j=(dxJoint*)j->next) if (j->world != w) dDebug (0,"bad world pointer in joint list"); /* // check for half-connected joints - actually now these are valid for (j=w->firstjoint; j; j=(dxJoint*)j->next) { if (j->node[0].body || j->node[1].body) { if (!(j->node[0].body && j->node[1].body)) dDebug (0,"half connected joint found"); } } */ // check that every joint node appears in the joint lists of both bodies it // attaches for (j=w->firstjoint; j; j=(dxJoint*)j->next) { for (int i=0; i<2; i++) { if (j->node[i].body) { int ok = 0; for (dxJointNode *n=j->node[i].body->firstjoint; n; n=n->next) { if (n->joint == j) ok = 1; } if (ok==0) dDebug (0,"joint not in joint list of attached body"); } } } // check all body joint lists (correct body ptrs) for (b=w->firstbody; b; b=(dxBody*)b->next) { for (dxJointNode *n=b->firstjoint; n; n=n->next) { if (&n->joint->node[0] == n) { if (n->joint->node[1].body != b) dDebug (0,"bad body pointer in joint node of body list (1)"); } else { if (n->joint->node[0].body != b) dDebug (0,"bad body pointer in joint node of body list (2)"); } if (n->joint->tag != count) dDebug (0,"bad joint node pointer in body"); } } // check all body pointers in joints, check they are distinct for (j=w->firstjoint; j; j=(dxJoint*)j->next) { if (j->node[0].body && (j->node[0].body == j->node[1].body)) dDebug (0,"non-distinct body pointers in joint"); if ((j->node[0].body && j->node[0].body->tag != count) || (j->node[1].body && j->node[1].body->tag != count)) dDebug (0,"bad body pointer in joint"); } } void dWorldCheck (dxWorld *w) { checkWorld (w); } //**************************************************************************** // body dxBody::dxBody(dxWorld *w) : dObject(w) { } dxWorld* dBodyGetWorld (dxBody * b) { dAASSERT (b); return b->world; } dxBody *dBodyCreate (dxWorld *w) { dAASSERT (w); dxBody *b = new dxBody(w); b->firstjoint = 0; b->flags = 0; b->geom = 0; b->average_lvel_buffer = 0; b->average_avel_buffer = 0; dMassSetParameters (&b->mass,1,0,0,0,1,1,1,0,0,0); dSetZero (b->invI,4*3); b->invI[0] = 1; b->invI[5] = 1; b->invI[10] = 1; b->invMass = 1; dSetZero (b->posr.pos,4); dSetZero (b->q,4); b->q[0] = 1; dRSetIdentity (b->posr.R); dSetZero (b->lvel,4); dSetZero (b->avel,4); dSetZero (b->facc,4); dSetZero (b->tacc,4); dSetZero (b->finite_rot_axis,4); addObjectToList (b,(dObject **) &w->firstbody); w->nb++; // set auto-disable parameters b->average_avel_buffer = b->average_lvel_buffer = 0; // no buffer at beginning dBodySetAutoDisableDefaults (b); // must do this after adding to world b->adis_stepsleft = b->adis.idle_steps; b->adis_timeleft = b->adis.idle_time; b->average_counter = 0; b->average_ready = 0; // average buffer not filled on the beginning dBodySetAutoDisableAverageSamplesCount(b, b->adis.average_samples); b->moved_callback = 0; dBodySetDampingDefaults(b); // must do this after adding to world b->flags |= w->body_flags & dxBodyMaxAngularSpeed; b->max_angular_speed = w->max_angular_speed; b->flags |= dxBodyGyroscopic; return b; } void dBodyDestroy (dxBody *b) { dAASSERT (b); // all geoms that link to this body must be notified that the body is about // to disappear. note that the call to dGeomSetBody(geom,0) will result in // dGeomGetBodyNext() returning 0 for the body, so we must get the next body // before setting the body to 0. dxGeom *next_geom = 0; for (dxGeom *geom = b->geom; geom; geom = next_geom) { next_geom = dGeomGetBodyNext (geom); dGeomSetBody (geom,0); } // detach all neighbouring joints, then delete this body. dxJointNode *n = b->firstjoint; while (n) { // sneaky trick to speed up removal of joint references (black magic) n->joint->node[(n == n->joint->node)].body = 0; dxJointNode *next = n->next; n->next = 0; removeJointReferencesFromAttachedBodies (n->joint); n = next; } removeObjectFromList (b); b->world->nb--; // delete the average buffers if(b->average_lvel_buffer) { delete[] (b->average_lvel_buffer); b->average_lvel_buffer = 0; } if(b->average_avel_buffer) { delete[] (b->average_avel_buffer); b->average_avel_buffer = 0; } delete b; } void dBodySetData (dBodyID b, void *data) { dAASSERT (b); b->userdata = data; } void *dBodyGetData (dBodyID b) { dAASSERT (b); return b->userdata; } void dBodySetPosition (dBodyID b, dReal x, dReal y, dReal z) { dAASSERT (b); b->posr.pos[0] = x; b->posr.pos[1] = y; b->posr.pos[2] = z; // notify all attached geoms that this body has moved for (dxGeom *geom = b->geom; geom; geom = dGeomGetBodyNext (geom)) dGeomMoved (geom); } void dBodySetRotation (dBodyID b, const dMatrix3 R) { dAASSERT (b && R); memcpy(b->posr.R, R, sizeof(dMatrix3)); dOrthogonalizeR(b->posr.R); dRtoQ (R, b->q); dNormalize4 (b->q); // notify all attached geoms that this body has moved for (dxGeom *geom = b->geom; geom; geom = dGeomGetBodyNext (geom)) dGeomMoved (geom); } void dBodySetQuaternion (dBodyID b, const dQuaternion q) { dAASSERT (b && q); b->q[0] = q[0]; b->q[1] = q[1]; b->q[2] = q[2]; b->q[3] = q[3]; dNormalize4 (b->q); dQtoR (b->q,b->posr.R); // notify all attached geoms that this body has moved for (dxGeom *geom = b->geom; geom; geom = dGeomGetBodyNext (geom)) dGeomMoved (geom); } void dBodySetLinearVel (dBodyID b, dReal x, dReal y, dReal z) { dAASSERT (b); b->lvel[0] = x; b->lvel[1] = y; b->lvel[2] = z; } void dBodySetAngularVel (dBodyID b, dReal x, dReal y, dReal z) { dAASSERT (b); b->avel[0] = x; b->avel[1] = y; b->avel[2] = z; } const dReal * dBodyGetPosition (dBodyID b) { dAASSERT (b); return b->posr.pos; } void dBodyCopyPosition (dBodyID b, dVector3 pos) { dAASSERT (b); dReal* src = b->posr.pos; pos[0] = src[0]; pos[1] = src[1]; pos[2] = src[2]; } const dReal * dBodyGetRotation (dBodyID b) { dAASSERT (b); return b->posr.R; } void dBodyCopyRotation (dBodyID b, dMatrix3 R) { dAASSERT (b); const dReal* src = b->posr.R; R[0] = src[0]; R[1] = src[1]; R[2] = src[2]; R[3] = src[3]; R[4] = src[4]; R[5] = src[5]; R[6] = src[6]; R[7] = src[7]; R[8] = src[8]; R[9] = src[9]; R[10] = src[10]; R[11] = src[11]; } const dReal * dBodyGetQuaternion (dBodyID b) { dAASSERT (b); return b->q; } void dBodyCopyQuaternion (dBodyID b, dQuaternion quat) { dAASSERT (b); dReal* src = b->q; quat[0] = src[0]; quat[1] = src[1]; quat[2] = src[2]; quat[3] = src[3]; } const dReal * dBodyGetLinearVel (dBodyID b) { dAASSERT (b); return b->lvel; } const dReal * dBodyGetAngularVel (dBodyID b) { dAASSERT (b); return b->avel; } void dBodySetMass (dBodyID b, const dMass *mass) { dAASSERT (b && mass ); dIASSERT(dMassCheck(mass)); // The centre of mass must be at the origin. // Use dMassTranslate( mass, -mass->c[0], -mass->c[1], -mass->c[2] ) to correct it. dUASSERT( fabs( mass->c[0] ) <= dEpsilon && fabs( mass->c[1] ) <= dEpsilon && fabs( mass->c[2] ) <= dEpsilon, "The centre of mass must be at the origin." ) memcpy (&b->mass,mass,sizeof(dMass)); if (dInvertPDMatrix (b->mass.I,b->invI,3)==0) { dDEBUGMSG ("inertia must be positive definite!"); dRSetIdentity (b->invI); } b->invMass = dRecip(b->mass.mass); } void dBodyGetMass (dBodyID b, dMass *mass) { dAASSERT (b && mass); memcpy (mass,&b->mass,sizeof(dMass)); } void dBodyAddForce (dBodyID b, dReal fx, dReal fy, dReal fz) { dAASSERT (b); b->facc[0] += fx; b->facc[1] += fy; b->facc[2] += fz; } void dBodyAddTorque (dBodyID b, dReal fx, dReal fy, dReal fz) { dAASSERT (b); b->tacc[0] += fx; b->tacc[1] += fy; b->tacc[2] += fz; } void dBodyAddRelForce (dBodyID b, dReal fx, dReal fy, dReal fz) { dAASSERT (b); dVector3 t1,t2; t1[0] = fx; t1[1] = fy; t1[2] = fz; t1[3] = 0; dMULTIPLY0_331 (t2,b->posr.R,t1); b->facc[0] += t2[0]; b->facc[1] += t2[1]; b->facc[2] += t2[2]; } void dBodyAddRelTorque (dBodyID b, dReal fx, dReal fy, dReal fz) { dAASSERT (b); dVector3 t1,t2; t1[0] = fx; t1[1] = fy; t1[2] = fz; t1[3] = 0; dMULTIPLY0_331 (t2,b->posr.R,t1); b->tacc[0] += t2[0]; b->tacc[1] += t2[1]; b->tacc[2] += t2[2]; } void dBodyAddForceAtPos (dBodyID b, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz) { dAASSERT (b); b->facc[0] += fx; b->facc[1] += fy; b->facc[2] += fz; dVector3 f,q; f[0] = fx; f[1] = fy; f[2] = fz; q[0] = px - b->posr.pos[0]; q[1] = py - b->posr.pos[1]; q[2] = pz - b->posr.pos[2]; dCROSS (b->tacc,+=,q,f); } void dBodyAddForceAtRelPos (dBodyID b, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz) { dAASSERT (b); dVector3 prel,f,p; f[0] = fx; f[1] = fy; f[2] = fz; f[3] = 0; prel[0] = px; prel[1] = py; prel[2] = pz; prel[3] = 0; dMULTIPLY0_331 (p,b->posr.R,prel); b->facc[0] += f[0]; b->facc[1] += f[1]; b->facc[2] += f[2]; dCROSS (b->tacc,+=,p,f); } void dBodyAddRelForceAtPos (dBodyID b, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz) { dAASSERT (b); dVector3 frel,f; frel[0] = fx; frel[1] = fy; frel[2] = fz; frel[3] = 0; dMULTIPLY0_331 (f,b->posr.R,frel); b->facc[0] += f[0]; b->facc[1] += f[1]; b->facc[2] += f[2]; dVector3 q; q[0] = px - b->posr.pos[0]; q[1] = py - b->posr.pos[1]; q[2] = pz - b->posr.pos[2]; dCROSS (b->tacc,+=,q,f); } void dBodyAddRelForceAtRelPos (dBodyID b, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz) { dAASSERT (b); dVector3 frel,prel,f,p; frel[0] = fx; frel[1] = fy; frel[2] = fz; frel[3] = 0; prel[0] = px; prel[1] = py; prel[2] = pz; prel[3] = 0; dMULTIPLY0_331 (f,b->posr.R,frel); dMULTIPLY0_331 (p,b->posr.R,prel); b->facc[0] += f[0]; b->facc[1] += f[1]; b->facc[2] += f[2]; dCROSS (b->tacc,+=,p,f); } const dReal * dBodyGetForce (dBodyID b) { dAASSERT (b); return b->facc; } const dReal * dBodyGetTorque (dBodyID b) { dAASSERT (b); return b->tacc; } void dBodySetForce (dBodyID b, dReal x, dReal y, dReal z) { dAASSERT (b); b->facc[0] = x; b->facc[1] = y; b->facc[2] = z; } void dBodySetTorque (dBodyID b, dReal x, dReal y, dReal z) { dAASSERT (b); b->tacc[0] = x; b->tacc[1] = y; b->tacc[2] = z; } void dBodyGetRelPointPos (dBodyID b, dReal px, dReal py, dReal pz, dVector3 result) { dAASSERT (b); dVector3 prel,p; prel[0] = px; prel[1] = py; prel[2] = pz; prel[3] = 0; dMULTIPLY0_331 (p,b->posr.R,prel); result[0] = p[0] + b->posr.pos[0]; result[1] = p[1] + b->posr.pos[1]; result[2] = p[2] + b->posr.pos[2]; } void dBodyGetRelPointVel (dBodyID b, dReal px, dReal py, dReal pz, dVector3 result) { dAASSERT (b); dVector3 prel,p; prel[0] = px; prel[1] = py; prel[2] = pz; prel[3] = 0; dMULTIPLY0_331 (p,b->posr.R,prel); result[0] = b->lvel[0]; result[1] = b->lvel[1]; result[2] = b->lvel[2]; dCROSS (result,+=,b->avel,p); } void dBodyGetPointVel (dBodyID b, dReal px, dReal py, dReal pz, dVector3 result) { dAASSERT (b); dVector3 p; p[0] = px - b->posr.pos[0]; p[1] = py - b->posr.pos[1]; p[2] = pz - b->posr.pos[2]; p[3] = 0; result[0] = b->lvel[0]; result[1] = b->lvel[1]; result[2] = b->lvel[2]; dCROSS (result,+=,b->avel,p); } void dBodyGetPosRelPoint (dBodyID b, dReal px, dReal py, dReal pz, dVector3 result) { dAASSERT (b); dVector3 prel; prel[0] = px - b->posr.pos[0]; prel[1] = py - b->posr.pos[1]; prel[2] = pz - b->posr.pos[2]; prel[3] = 0; dMULTIPLY1_331 (result,b->posr.R,prel); } void dBodyVectorToWorld (dBodyID b, dReal px, dReal py, dReal pz, dVector3 result) { dAASSERT (b); dVector3 p; p[0] = px; p[1] = py; p[2] = pz; p[3] = 0; dMULTIPLY0_331 (result,b->posr.R,p); } void dBodyVectorFromWorld (dBodyID b, dReal px, dReal py, dReal pz, dVector3 result) { dAASSERT (b); dVector3 p; p[0] = px; p[1] = py; p[2] = pz; p[3] = 0; dMULTIPLY1_331 (result,b->posr.R,p); } void dBodySetFiniteRotationMode (dBodyID b, int mode) { dAASSERT (b); b->flags &= ~(dxBodyFlagFiniteRotation | dxBodyFlagFiniteRotationAxis); if (mode) { b->flags |= dxBodyFlagFiniteRotation; if (b->finite_rot_axis[0] != 0 || b->finite_rot_axis[1] != 0 || b->finite_rot_axis[2] != 0) { b->flags |= dxBodyFlagFiniteRotationAxis; } } } void dBodySetFiniteRotationAxis (dBodyID b, dReal x, dReal y, dReal z) { dAASSERT (b); b->finite_rot_axis[0] = x; b->finite_rot_axis[1] = y; b->finite_rot_axis[2] = z; if (x != 0 || y != 0 || z != 0) { dNormalize3 (b->finite_rot_axis); b->flags |= dxBodyFlagFiniteRotationAxis; } else { b->flags &= ~dxBodyFlagFiniteRotationAxis; } } int dBodyGetFiniteRotationMode (dBodyID b) { dAASSERT (b); return ((b->flags & dxBodyFlagFiniteRotation) != 0); } void dBodyGetFiniteRotationAxis (dBodyID b, dVector3 result) { dAASSERT (b); result[0] = b->finite_rot_axis[0]; result[1] = b->finite_rot_axis[1]; result[2] = b->finite_rot_axis[2]; } int dBodyGetNumJoints (dBodyID b) { dAASSERT (b); int count=0; for (dxJointNode *n=b->firstjoint; n; n=n->next, count++); return count; } dJointID dBodyGetJoint (dBodyID b, int index) { dAASSERT (b); int i=0; for (dxJointNode *n=b->firstjoint; n; n=n->next, i++) { if (i == index) return n->joint; } return 0; } void dBodySetDynamic (dBodyID b) { dAASSERT (b); dBodySetMass(b,&b->mass); } void dBodySetKinematic (dBodyID b) { dAASSERT (b); dSetZero (b->invI,4*3); b->invMass = 0; } int dBodyIsKinematic (dBodyID b) { dAASSERT (b); return b->invMass == 0; } void dBodyEnable (dBodyID b) { dAASSERT (b); b->flags &= ~dxBodyDisabled; b->adis_stepsleft = b->adis.idle_steps; b->adis_timeleft = b->adis.idle_time; // no code for average-processing needed here } void dBodyDisable (dBodyID b) { dAASSERT (b); b->flags |= dxBodyDisabled; } int dBodyIsEnabled (dBodyID b) { dAASSERT (b); return ((b->flags & dxBodyDisabled) == 0); } void dBodySetGravityMode (dBodyID b, int mode) { dAASSERT (b); if (mode) b->flags &= ~dxBodyNoGravity; else b->flags |= dxBodyNoGravity; } int dBodyGetGravityMode (dBodyID b) { dAASSERT (b); return ((b->flags & dxBodyNoGravity) == 0); } // body auto-disable functions dReal dBodyGetAutoDisableLinearThreshold (dBodyID b) { dAASSERT(b); return dSqrt (b->adis.linear_average_threshold); } void dBodySetAutoDisableLinearThreshold (dBodyID b, dReal linear_average_threshold) { dAASSERT(b); b->adis.linear_average_threshold = linear_average_threshold * linear_average_threshold; } dReal dBodyGetAutoDisableAngularThreshold (dBodyID b) { dAASSERT(b); return dSqrt (b->adis.angular_average_threshold); } void dBodySetAutoDisableAngularThreshold (dBodyID b, dReal angular_average_threshold) { dAASSERT(b); b->adis.angular_average_threshold = angular_average_threshold * angular_average_threshold; } int dBodyGetAutoDisableAverageSamplesCount (dBodyID b) { dAASSERT(b); return b->adis.average_samples; } void dBodySetAutoDisableAverageSamplesCount (dBodyID b, unsigned int average_samples_count) { dAASSERT(b); b->adis.average_samples = average_samples_count; // update the average buffers if(b->average_lvel_buffer) { delete[] b->average_lvel_buffer; b->average_lvel_buffer = 0; } if(b->average_avel_buffer) { delete[] b->average_avel_buffer; b->average_avel_buffer = 0; } if(b->adis.average_samples > 0) { b->average_lvel_buffer = new dVector3[b->adis.average_samples]; b->average_avel_buffer = new dVector3[b->adis.average_samples]; } else { b->average_lvel_buffer = 0; b->average_avel_buffer = 0; } // new buffer is empty b->average_counter = 0; b->average_ready = 0; } int dBodyGetAutoDisableSteps (dBodyID b) { dAASSERT(b); return b->adis.idle_steps; } void dBodySetAutoDisableSteps (dBodyID b, int steps) { dAASSERT(b); b->adis.idle_steps = steps; } dReal dBodyGetAutoDisableTime (dBodyID b) { dAASSERT(b); return b->adis.idle_time; } void dBodySetAutoDisableTime (dBodyID b, dReal time) { dAASSERT(b); b->adis.idle_time = time; } int dBodyGetAutoDisableFlag (dBodyID b) { dAASSERT(b); return ((b->flags & dxBodyAutoDisable) != 0); } void dBodySetAutoDisableFlag (dBodyID b, int do_auto_disable) { dAASSERT(b); if (!do_auto_disable) { b->flags &= ~dxBodyAutoDisable; // (mg) we should also reset the IsDisabled state to correspond to the DoDisabling flag b->flags &= ~dxBodyDisabled; b->adis.idle_steps = dWorldGetAutoDisableSteps(b->world); b->adis.idle_time = dWorldGetAutoDisableTime(b->world); // resetting the average calculations too dBodySetAutoDisableAverageSamplesCount(b, dWorldGetAutoDisableAverageSamplesCount(b->world) ); } else { b->flags |= dxBodyAutoDisable; } } void dBodySetAutoDisableDefaults (dBodyID b) { dAASSERT(b); dWorldID w = b->world; dAASSERT(w); b->adis = w->adis; dBodySetAutoDisableFlag (b, w->body_flags & dxBodyAutoDisable); } // body damping functions dReal dBodyGetLinearDamping(dBodyID b) { dAASSERT(b); return b->dampingp.linear_scale; } void dBodySetLinearDamping(dBodyID b, dReal scale) { dAASSERT(b); if (scale) b->flags |= dxBodyLinearDamping; else b->flags &= ~dxBodyLinearDamping; b->dampingp.linear_scale = scale; } dReal dBodyGetAngularDamping(dBodyID b) { dAASSERT(b); return b->dampingp.angular_scale; } void dBodySetAngularDamping(dBodyID b, dReal scale) { dAASSERT(b); if (scale) b->flags |= dxBodyAngularDamping; else b->flags &= ~dxBodyAngularDamping; b->dampingp.angular_scale = scale; } void dBodySetDamping(dBodyID b, dReal linear_scale, dReal angular_scale) { dAASSERT(b); dBodySetLinearDamping(b, linear_scale); dBodySetAngularDamping(b, angular_scale); } dReal dBodyGetLinearDampingThreshold(dBodyID b) { dAASSERT(b); return dSqrt(b->dampingp.linear_threshold); } void dBodySetLinearDampingThreshold(dBodyID b, dReal threshold) { dAASSERT(b); b->dampingp.linear_threshold = threshold*threshold; } dReal dBodyGetAngularDampingThreshold(dBodyID b) { dAASSERT(b); return dSqrt(b->dampingp.angular_threshold); } void dBodySetAngularDampingThreshold(dBodyID b, dReal threshold) { dAASSERT(b); b->dampingp.angular_threshold = threshold*threshold; } void dBodySetDampingDefaults(dBodyID b) { dAASSERT(b); dWorldID w = b->world; dAASSERT(w); b->dampingp = w->dampingp; const unsigned mask = dxBodyLinearDamping | dxBodyAngularDamping; b->flags &= ~mask; // zero them b->flags |= w->body_flags & mask; } dReal dBodyGetMaxAngularSpeed(dBodyID b) { dAASSERT(b); return b->max_angular_speed; } void dBodySetMaxAngularSpeed(dBodyID b, dReal max_speed) { dAASSERT(b); if (max_speed < dInfinity) b->flags |= dxBodyMaxAngularSpeed; else b->flags &= ~dxBodyMaxAngularSpeed; b->max_angular_speed = max_speed; } void dBodySetMovedCallback(dBodyID b, void (*callback)(dBodyID)) { dAASSERT(b); b->moved_callback = callback; } dGeomID dBodyGetFirstGeom(dBodyID b) { dAASSERT(b); return b->geom; } dGeomID dBodyGetNextGeom(dGeomID geom) { dAASSERT(geom); return dGeomGetBodyNext(geom); } int dBodyGetGyroscopicMode(dBodyID b) { dAASSERT(b); return b->flags & dxBodyGyroscopic; } void dBodySetGyroscopicMode(dBodyID b, int enabled) { dAASSERT(b); if (enabled) b->flags |= dxBodyGyroscopic; else b->flags &= ~dxBodyGyroscopic; } //**************************************************************************** // joints template dxJoint* createJoint(dWorldID w, dJointGroupID group) { dxJoint *j; if (group) { j = (dxJoint*) group->stack.alloc(sizeof(T)); group->num++; } else j = (dxJoint*) dAlloc(sizeof(T)); new(j) T(w); if (group) j->flags |= dJOINT_INGROUP; return j; } dxJoint * dJointCreateBall (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint(w,group); } dxJoint * dJointCreateHinge (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint(w,group); } dxJoint * dJointCreateSlider (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint(w,group); } dxJoint * dJointCreateContact (dWorldID w, dJointGroupID group, const dContact *c) { dAASSERT (w && c); dxJointContact *j = (dxJointContact *) createJoint (w,group); j->contact = *c; return j; } dxJoint * dJointCreateHinge2 (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint (w,group); } dxJoint * dJointCreateUniversal (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint (w,group); } dxJoint * dJointCreatePR (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint (w,group); } dxJoint * dJointCreatePU (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint (w,group); } dxJoint * dJointCreatePiston (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint (w,group); } dxJoint * dJointCreateFixed (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint (w,group); } dxJoint * dJointCreateNull (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint (w,group); } dxJoint * dJointCreateAMotor (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint (w,group); } dxJoint * dJointCreateLMotor (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint (w,group); } dxJoint * dJointCreatePlane2D (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint (w,group); } void dJointDestroy (dxJoint *j) { dAASSERT (j); size_t sz = j->size(); if (j->flags & dJOINT_INGROUP) return; removeJointReferencesFromAttachedBodies (j); removeObjectFromList (j); j->world->nj--; j->~dxJoint(); dFree (j, sz); } dJointGroupID dJointGroupCreate (int max_size) { // not any more ... dUASSERT (max_size > 0,"max size must be > 0"); dxJointGroup *group = new dxJointGroup; group->num = 0; return group; } void dJointGroupDestroy (dJointGroupID group) { dAASSERT (group); dJointGroupEmpty (group); delete group; } void dJointGroupEmpty (dJointGroupID group) { // the joints in this group are detached starting from the most recently // added (at the top of the stack). this helps ensure that the various // linked lists are not traversed too much, as the joints will hopefully // be at the start of those lists. // if any group joints have their world pointer set to 0, their world was // previously destroyed. no special handling is required for these joints. dAASSERT (group); int i; dxJoint **jlist = (dxJoint**) ALLOCA (group->num * sizeof(dxJoint*)); dxJoint *j = (dxJoint*) group->stack.rewind(); for (i=0; i < group->num; i++) { jlist[i] = j; j = (dxJoint*) (group->stack.next (j->size())); } for (i=group->num-1; i >= 0; i--) { if (jlist[i]->world) { removeJointReferencesFromAttachedBodies (jlist[i]); removeObjectFromList (jlist[i]); jlist[i]->world->nj--; jlist[i]->~dxJoint(); } } group->num = 0; group->stack.freeAll(); } int dJointGetNumBodies(dxJoint *joint) { // check arguments dUASSERT (joint,"bad joint argument"); if ( !joint->node[0].body ) return 0; else if ( !joint->node[1].body ) return 1; else return 2; } void dJointAttach (dxJoint *joint, dxBody *body1, dxBody *body2) { // check arguments dUASSERT (joint,"bad joint argument"); dUASSERT (body1 == 0 || body1 != body2,"can't have body1==body2"); dxWorld *world = joint->world; dUASSERT ( (!body1 || body1->world == world) && (!body2 || body2->world == world), "joint and bodies must be in same world"); // check if the joint can not be attached to just one body dUASSERT (!((joint->flags & dJOINT_TWOBODIES) && ((body1 != 0) ^ (body2 != 0))), "joint can not be attached to just one body"); // remove any existing body attachments if (joint->node[0].body || joint->node[1].body) { removeJointReferencesFromAttachedBodies (joint); } // if a body is zero, make sure that it is body2, so 0 --> node[1].body if (body1==0) { body1 = body2; body2 = 0; joint->flags |= dJOINT_REVERSE; } else { joint->flags &= (~dJOINT_REVERSE); } // attach to new bodies joint->node[0].body = body1; joint->node[1].body = body2; if (body1) { joint->node[1].next = body1->firstjoint; body1->firstjoint = &joint->node[1]; } else joint->node[1].next = 0; if (body2) { joint->node[0].next = body2->firstjoint; body2->firstjoint = &joint->node[0]; } else { joint->node[0].next = 0; } // Since the bodies are now set. // Calculate the values depending on the bodies. // Only need to calculate relative value if a body exist if (body1 || body2) joint->setRelativeValues(); } void dJointEnable (dxJoint *joint) { dAASSERT (joint); joint->flags &= ~dJOINT_DISABLED; } void dJointDisable (dxJoint *joint) { dAASSERT (joint); joint->flags |= dJOINT_DISABLED; } int dJointIsEnabled (dxJoint *joint) { dAASSERT (joint); return (joint->flags & dJOINT_DISABLED) == 0; } void dJointSetData (dxJoint *joint, void *data) { dAASSERT (joint); joint->userdata = data; } void *dJointGetData (dxJoint *joint) { dAASSERT (joint); return joint->userdata; } dJointType dJointGetType (dxJoint *joint) { dAASSERT (joint); return joint->type(); } dBodyID dJointGetBody (dxJoint *joint, int index) { dAASSERT (joint); if (index == 0 || index == 1) { if (joint->flags & dJOINT_REVERSE) return joint->node[1-index].body; else return joint->node[index].body; } else return 0; } void dJointSetFeedback (dxJoint *joint, dJointFeedback *f) { dAASSERT (joint); joint->feedback = f; } dJointFeedback *dJointGetFeedback (dxJoint *joint) { dAASSERT (joint); return joint->feedback; } dJointID dConnectingJoint (dBodyID in_b1, dBodyID in_b2) { dAASSERT (in_b1 || in_b2); dBodyID b1, b2; if (in_b1 == 0) { b1 = in_b2; b2 = in_b1; } else { b1 = in_b1; b2 = in_b2; } // look through b1's neighbour list for b2 for (dxJointNode *n=b1->firstjoint; n; n=n->next) { if (n->body == b2) return n->joint; } return 0; } int dConnectingJointList (dBodyID in_b1, dBodyID in_b2, dJointID* out_list) { dAASSERT (in_b1 || in_b2); dBodyID b1, b2; if (in_b1 == 0) { b1 = in_b2; b2 = in_b1; } else { b1 = in_b1; b2 = in_b2; } // look through b1's neighbour list for b2 int numConnectingJoints = 0; for (dxJointNode *n=b1->firstjoint; n; n=n->next) { if (n->body == b2) out_list[numConnectingJoints++] = n->joint; } return numConnectingJoints; } int dAreConnected (dBodyID b1, dBodyID b2) { dAASSERT (b1 && b2); // look through b1's neighbour list for b2 for (dxJointNode *n=b1->firstjoint; n; n=n->next) { if (n->body == b2) return 1; } return 0; } int dAreConnectedExcluding (dBodyID b1, dBodyID b2, int joint_type) { dAASSERT (b1 && b2); // look through b1's neighbour list for b2 for (dxJointNode *n=b1->firstjoint; n; n=n->next) { if (dJointGetType (n->joint) != joint_type && n->body == b2) return 1; } return 0; } //**************************************************************************** // world dxWorld * dWorldCreate() { dxWorld *w = new dxWorld; w->firstbody = 0; w->firstjoint = 0; w->nb = 0; w->nj = 0; dSetZero (w->gravity,4); w->global_erp = REAL(0.2); #if defined(dSINGLE) w->global_cfm = 1e-5f; #elif defined(dDOUBLE) w->global_cfm = 1e-10; #else #error dSINGLE or dDOUBLE must be defined #endif w->body_flags = 0; // everything disabled w->adis.idle_steps = 10; w->adis.idle_time = 0; w->adis.average_samples = 1; // Default is 1 sample => Instantaneous velocity w->adis.angular_average_threshold = REAL(0.01)*REAL(0.01); // (magnitude squared) w->adis.linear_average_threshold = REAL(0.01)*REAL(0.01); // (magnitude squared) w->qs.num_iterations = 20; w->qs.w = REAL(1.3); w->contactp.max_vel = dInfinity; w->contactp.min_depth = 0; w->dampingp.linear_scale = 0; w->dampingp.angular_scale = 0; w->dampingp.linear_threshold = REAL(0.01) * REAL(0.01); w->dampingp.angular_threshold = REAL(0.01) * REAL(0.01); w->max_angular_speed = dInfinity; return w; } void dWorldDestroy (dxWorld *w) { // delete all bodies and joints dAASSERT (w); dxBody *nextb, *b = w->firstbody; while (b) { nextb = (dxBody*) b->next; // TODO: remove those 2 ifs if(b->average_lvel_buffer) { delete[] (b->average_lvel_buffer); b->average_lvel_buffer = 0; } if(b->average_avel_buffer) { delete[] (b->average_avel_buffer); b->average_avel_buffer = 0; } dBodyDestroy(b); // calling here dBodyDestroy for correct destroying! (i.e. the average buffers) b = nextb; } dxJoint *nextj, *j = w->firstjoint; while (j) { nextj = (dxJoint*)j->next; if (j->flags & dJOINT_INGROUP) { // the joint is part of a group, so "deactivate" it instead j->world = 0; j->node[0].body = 0; j->node[0].next = 0; j->node[1].body = 0; j->node[1].next = 0; dMessage (0,"warning: destroying world containing grouped joints"); } else { size_t sz = j->size(); j->~dxJoint(); dFree (j,sz); } j = nextj; } delete w; } void dWorldSetGravity (dWorldID w, dReal x, dReal y, dReal z) { dAASSERT (w); w->gravity[0] = x; w->gravity[1] = y; w->gravity[2] = z; } void dWorldGetGravity (dWorldID w, dVector3 g) { dAASSERT (w); g[0] = w->gravity[0]; g[1] = w->gravity[1]; g[2] = w->gravity[2]; } void dWorldSetERP (dWorldID w, dReal erp) { dAASSERT (w); w->global_erp = erp; } dReal dWorldGetERP (dWorldID w) { dAASSERT (w); return w->global_erp; } void dWorldSetCFM (dWorldID w, dReal cfm) { dAASSERT (w); w->global_cfm = cfm; } dReal dWorldGetCFM (dWorldID w) { dAASSERT (w); return w->global_cfm; } void dWorldStep (dWorldID w, dReal stepsize) { dUASSERT (w,"bad world argument"); dUASSERT (stepsize > 0,"stepsize must be > 0"); dxProcessIslands (w,stepsize,&dInternalStepIsland); } void dWorldQuickStep (dWorldID w, dReal stepsize) { dUASSERT (w,"bad world argument"); dUASSERT (stepsize > 0,"stepsize must be > 0"); dxProcessIslands (w,stepsize,&dxQuickStepper); } void dWorldImpulseToForce (dWorldID w, dReal stepsize, dReal ix, dReal iy, dReal iz, dVector3 force) { dAASSERT (w); stepsize = dRecip(stepsize); force[0] = stepsize * ix; force[1] = stepsize * iy; force[2] = stepsize * iz; // @@@ force[3] = 0; } // world auto-disable functions dReal dWorldGetAutoDisableLinearThreshold (dWorldID w) { dAASSERT(w); return dSqrt (w->adis.linear_average_threshold); } void dWorldSetAutoDisableLinearThreshold (dWorldID w, dReal linear_average_threshold) { dAASSERT(w); w->adis.linear_average_threshold = linear_average_threshold * linear_average_threshold; } dReal dWorldGetAutoDisableAngularThreshold (dWorldID w) { dAASSERT(w); return dSqrt (w->adis.angular_average_threshold); } void dWorldSetAutoDisableAngularThreshold (dWorldID w, dReal angular_average_threshold) { dAASSERT(w); w->adis.angular_average_threshold = angular_average_threshold * angular_average_threshold; } int dWorldGetAutoDisableAverageSamplesCount (dWorldID w) { dAASSERT(w); return w->adis.average_samples; } void dWorldSetAutoDisableAverageSamplesCount (dWorldID w, unsigned int average_samples_count) { dAASSERT(w); w->adis.average_samples = average_samples_count; } int dWorldGetAutoDisableSteps (dWorldID w) { dAASSERT(w); return w->adis.idle_steps; } void dWorldSetAutoDisableSteps (dWorldID w, int steps) { dAASSERT(w); w->adis.idle_steps = steps; } dReal dWorldGetAutoDisableTime (dWorldID w) { dAASSERT(w); return w->adis.idle_time; } void dWorldSetAutoDisableTime (dWorldID w, dReal time) { dAASSERT(w); w->adis.idle_time = time; } int dWorldGetAutoDisableFlag (dWorldID w) { dAASSERT(w); return w->body_flags & dxBodyAutoDisable; } void dWorldSetAutoDisableFlag (dWorldID w, int do_auto_disable) { dAASSERT(w); if (do_auto_disable) w->body_flags |= dxBodyAutoDisable; else w->body_flags &= ~dxBodyAutoDisable; } // world damping functions dReal dWorldGetLinearDampingThreshold(dWorldID w) { dAASSERT(w); return dSqrt(w->dampingp.linear_threshold); } void dWorldSetLinearDampingThreshold(dWorldID w, dReal threshold) { dAASSERT(w); w->dampingp.linear_threshold = threshold*threshold; } dReal dWorldGetAngularDampingThreshold(dWorldID w) { dAASSERT(w); return dSqrt(w->dampingp.angular_threshold); } void dWorldSetAngularDampingThreshold(dWorldID w, dReal threshold) { dAASSERT(w); w->dampingp.angular_threshold = threshold*threshold; } dReal dWorldGetLinearDamping(dWorldID w) { dAASSERT(w); return w->dampingp.linear_scale; } void dWorldSetLinearDamping(dWorldID w, dReal scale) { dAASSERT(w); if (scale) w->body_flags |= dxBodyLinearDamping; else w->body_flags &= ~dxBodyLinearDamping; w->dampingp.linear_scale = scale; } dReal dWorldGetAngularDamping(dWorldID w) { dAASSERT(w); return w->dampingp.angular_scale; } void dWorldSetAngularDamping(dWorldID w, dReal scale) { dAASSERT(w); if (scale) w->body_flags |= dxBodyAngularDamping; else w->body_flags &= ~dxBodyAngularDamping; w->dampingp.angular_scale = scale; } void dWorldSetDamping(dWorldID w, dReal linear_scale, dReal angular_scale) { dAASSERT(w); dWorldSetLinearDamping(w, linear_scale); dWorldSetAngularDamping(w, angular_scale); } dReal dWorldGetMaxAngularSpeed(dWorldID w) { dAASSERT(w); return w->max_angular_speed; } void dWorldSetMaxAngularSpeed(dWorldID w, dReal max_speed) { dAASSERT(w); if (max_speed < dInfinity) w->body_flags |= dxBodyMaxAngularSpeed; else w->body_flags &= ~dxBodyMaxAngularSpeed; w->max_angular_speed = max_speed; } void dWorldSetQuickStepNumIterations (dWorldID w, int num) { dAASSERT(w); w->qs.num_iterations = num; } int dWorldGetQuickStepNumIterations (dWorldID w) { dAASSERT(w); return w->qs.num_iterations; } void dWorldSetQuickStepW (dWorldID w, dReal param) { dAASSERT(w); w->qs.w = param; } dReal dWorldGetQuickStepW (dWorldID w) { dAASSERT(w); return w->qs.w; } void dWorldSetContactMaxCorrectingVel (dWorldID w, dReal vel) { dAASSERT(w); w->contactp.max_vel = vel; } dReal dWorldGetContactMaxCorrectingVel (dWorldID w) { dAASSERT(w); return w->contactp.max_vel; } void dWorldSetContactSurfaceLayer (dWorldID w, dReal depth) { dAASSERT(w); w->contactp.min_depth = depth; } dReal dWorldGetContactSurfaceLayer (dWorldID w) { dAASSERT(w); return w->contactp.min_depth; } //**************************************************************************** // testing #define NUM 100 #define DO(x) extern "C" void dTestDataStructures() { int i; DO(printf ("testDynamicsStuff()\n")); dBodyID body [NUM]; int nb = 0; dJointID joint [NUM]; int nj = 0; for (i=0; i 0.5) { DO(printf ("creating body\n")); body[nb] = dBodyCreate (w); DO(printf ("\t--> %p\n",body[nb])); nb++; checkWorld (w); DO(printf ("%d BODIES, %d JOINTS\n",nb,nj)); } if (nj < NUM && nb > 2 && dRandReal() > 0.5) { dBodyID b1 = body [dRand() % nb]; dBodyID b2 = body [dRand() % nb]; if (b1 != b2) { DO(printf ("creating joint, attaching to %p,%p\n",b1,b2)); joint[nj] = dJointCreateBall (w,0); DO(printf ("\t-->%p\n",joint[nj])); checkWorld (w); dJointAttach (joint[nj],b1,b2); nj++; checkWorld (w); DO(printf ("%d BODIES, %d JOINTS\n",nb,nj)); } } if (nj > 0 && nb > 2 && dRandReal() > 0.5) { dBodyID b1 = body [dRand() % nb]; dBodyID b2 = body [dRand() % nb]; if (b1 != b2) { int k = dRand() % nj; DO(printf ("reattaching joint %p\n",joint[k])); dJointAttach (joint[k],b1,b2); checkWorld (w); DO(printf ("%d BODIES, %d JOINTS\n",nb,nj)); } } if (nb > 0 && dRandReal() > 0.5) { int k = dRand() % nb; DO(printf ("destroying body %p\n",body[k])); dBodyDestroy (body[k]); checkWorld (w); for (; k < (NUM-1); k++) body[k] = body[k+1]; nb--; DO(printf ("%d BODIES, %d JOINTS\n",nb,nj)); } if (nj > 0 && dRandReal() > 0.5) { int k = dRand() % nj; DO(printf ("destroying joint %p\n",joint[k])); dJointDestroy (joint[k]); checkWorld (w); for (; k < (NUM-1); k++) joint[k] = joint[k+1]; nj--; DO(printf ("%d BODIES, %d JOINTS\n",nb,nj)); } } /* printf ("creating world\n"); dWorldID w = dWorldCreate(); checkWorld (w); printf ("creating body\n"); dBodyID b1 = dBodyCreate (w); checkWorld (w); printf ("creating body\n"); dBodyID b2 = dBodyCreate (w); checkWorld (w); printf ("creating joint\n"); dJointID j = dJointCreateBall (w); checkWorld (w); printf ("attaching joint\n"); dJointAttach (j,b1,b2); checkWorld (w); printf ("destroying joint\n"); dJointDestroy (j); checkWorld (w); printf ("destroying body\n"); dBodyDestroy (b1); checkWorld (w); printf ("destroying body\n"); dBodyDestroy (b2); checkWorld (w); printf ("destroying world\n"); dWorldDestroy (w); */ } //**************************************************************************** // configuration #if 1 #define REGISTER_EXTENSION( __a ) #__a " " #else #define REGISTER_EXTENSION( __a ) "__a " #endif static const char ode_configuration[] = "ODE " // EXTENSION LIST BEGIN //********************************** #ifdef dNODEBUG REGISTER_EXTENSION( ODE_EXT_no_debug ) #endif // dNODEBUG #ifdef dUSE_MALLOC_FOR_ALLOCA REGISTER_EXTENSION( ODE_EXT_malloc_not_alloca ) #endif #if dTRIMESH_ENABLED REGISTER_EXTENSION( ODE_EXT_trimesh ) // tri-mesh extensions #if dTRIMESH_OPCODE REGISTER_EXTENSION( ODE_EXT_opcode ) // opcode extensions #if dTRIMESH_16BIT_INDICES REGISTER_EXTENSION( ODE_OPC_16bit_indices ) #endif #if !dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER REGISTER_EXTENSION( ODE_OPC_new_collider ) #endif #endif // dTRIMESH_OPCODE #if dTRIMESH_GIMPACT REGISTER_EXTENSION( ODE_EXT_gimpact ) // gimpact extensions #endif #endif // dTRIMESH_ENABLED #if dTLS_ENABLED REGISTER_EXTENSION( ODE_EXT_mt_collisions ) #endif // dTLS_ENABLED //********************************** // EXTENSION LIST END // These tokens are mutually exclusive, and always present #ifdef dSINGLE "ODE_single_precision" #else "ODE_double_precision" #endif // dDOUBLE ; // END const char* dGetConfiguration (void) { return ode_configuration; } // Helper to check for a feature of ODE int dCheckConfiguration( const char* extension ) { const char *start; char *where, *terminator; /* Feature names should not have spaces. */ where = (char*)strchr(extension, ' '); if ( where || *extension == '\0') return 1; const char* config = dGetConfiguration(); const size_t ext_length = strlen(extension); /* It takes a bit of care to be fool-proof. Don't be fooled by sub-strings, etc. */ start = config; for ( ; ; ) { where = (char*)strstr((const char *) start, extension); if (!where) break; terminator = where + ext_length; if ( (where == start || *(where - 1) == ' ') && (*terminator == ' ' || *terminator == '\0') ) { return 1; } start = terminator; } return 0; } // Local Variables: // c-basic-offset:4 // End: alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/0000700000175000017500000000000012207204656020334 5ustar zero79zero79alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Stdafx.h0000600000175000017500000000207212161402010021720 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #if !defined(AFX_STDAFX_H__EFB95044_1D31_11D5_8B0F_0050BAC83302__INCLUDED_) #define AFX_STDAFX_H__EFB95044_1D31_11D5_8B0F_0050BAC83302__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // Insert your headers here #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #include "Opcode.h" //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_STDAFX_H__EFB95044_1D31_11D5_8B0F_0050BAC83302__INCLUDED_) alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_SphereAABBOverlap.h0000600000175000017500000000436412161402010024363 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Sphere-AABB overlap test, based on Jim Arvo's code. * \param center [in] box center * \param extents [in] box extents * \return TRUE on overlap */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL SphereCollider::SphereAABBOverlap(const Point& center, const Point& extents) { // Stats mNbVolumeBVTests++; float d = 0.0f; //find the square of the distance //from the sphere to the box #ifdef OLDIES for(udword i=0;i<3;i++) { float tmp = mCenter[i] - center[i]; float s = tmp + extents[i]; if(s<0.0f) d += s*s; else { s = tmp - extents[i]; if(s>0.0f) d += s*s; } } #endif //#ifdef NEW_TEST // float tmp = mCenter.x - center.x; // float s = tmp + extents.x; float tmp,s; tmp = mCenter.x - center.x; s = tmp + extents.x; if(s<0.0f) { d += s*s; if(d>mRadius2) return FALSE; } else { s = tmp - extents.x; if(s>0.0f) { d += s*s; if(d>mRadius2) return FALSE; } } tmp = mCenter.y - center.y; s = tmp + extents.y; if(s<0.0f) { d += s*s; if(d>mRadius2) return FALSE; } else { s = tmp - extents.y; if(s>0.0f) { d += s*s; if(d>mRadius2) return FALSE; } } tmp = mCenter.z - center.z; s = tmp + extents.z; if(s<0.0f) { d += s*s; if(d>mRadius2) return FALSE; } else { s = tmp - extents.z; if(s>0.0f) { d += s*s; if(d>mRadius2) return FALSE; } } //#endif #ifdef OLDIES // Point Min = center - extents; // Point Max = center + extents; float d = 0.0f; //find the square of the distance //from the sphere to the box for(udword i=0;i<3;i++) { float Min = center[i] - extents[i]; // if(mCenter[i]Max[i]) if(mCenter[i]>Max) { float s = mCenter[i] - Max; d += s*s; } } } #endif return d <= mRadius2; } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_AABBTree.cpp0000600000175000017500000005373412161402010023043 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for a versatile AABB tree. * \file OPC_AABBTree.cpp * \author Pierre Terdiman * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains a generic AABB tree node. * * \class AABBTreeNode * \author Pierre Terdiman * \version 1.3 * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains a generic AABB tree. * This is a vanilla AABB tree, without any particular optimization. It contains anonymous references to * user-provided primitives, which can theoretically be anything - triangles, boxes, etc. Each primitive * is surrounded by an AABB, regardless of the primitive's nature. When the primitive is a triangle, the * resulting tree can be converted into an optimized tree. If the primitive is a box, the resulting tree * can be used for culling - VFC or occlusion -, assuming you cull on a mesh-by-mesh basis (modern way). * * \class AABBTree * \author Pierre Terdiman * \version 1.3 * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace Opcode; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// AABBTreeNode::AABBTreeNode() : mPos (null), #ifndef OPC_NO_NEG_VANILLA_TREE mNeg (null), #endif mNodePrimitives (null), mNbPrimitives (0) { #ifdef OPC_USE_TREE_COHERENCE mBitmask = 0; #endif } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Destructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// AABBTreeNode::~AABBTreeNode() { // Opcode 1.3: const AABBTreeNode* Pos = GetPos(); #ifndef OPC_NO_NEG_VANILLA_TREE const AABBTreeNode* Neg = GetNeg(); if(!(mPos&1)) DELETESINGLE(Pos); if(!(mNeg&1)) DELETESINGLE(Neg); #else if(!(mPos&1)) DELETEARRAY(Pos); #endif mNodePrimitives = null; // This was just a shortcut to the global list => no release mNbPrimitives = 0; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Splits the node along a given axis. * The list of indices is reorganized according to the split values. * \param axis [in] splitting axis index * \param builder [in] the tree builder * \return the number of primitives assigned to the first child * \warning this method reorganizes the internal list of primitives */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// udword AABBTreeNode::Split(udword axis, AABBTreeBuilder* builder) { // Get node split value float SplitValue = builder->GetSplittingValue(mNodePrimitives, mNbPrimitives, mBV, axis); udword NbPos = 0; // Loop through all node-related primitives. Their indices range from mNodePrimitives[0] to mNodePrimitives[mNbPrimitives-1]. // Those indices map the global list in the tree builder. for(udword i=0;iGetSplittingValue(Index, axis); // Reorganize the list of indices in this order: positive - negative. if(PrimitiveValue > SplitValue) { // Swap entries udword Tmp = mNodePrimitives[i]; mNodePrimitives[i] = mNodePrimitives[NbPos]; mNodePrimitives[NbPos] = Tmp; // Count primitives assigned to positive space NbPos++; } } return NbPos; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Subdivides the node. * * N * / \ * / \ * N/2 N/2 * / \ / \ * N/4 N/4 N/4 N/4 * (etc) * * A well-balanced tree should have a O(log n) depth. * A degenerate tree would have a O(n) depth. * Note a perfectly-balanced tree is not well-suited to collision detection anyway. * * \param builder [in] the tree builder * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool AABBTreeNode::Subdivide(AABBTreeBuilder* builder) { // Checkings if(!builder) return false; // Stop subdividing if we reach a leaf node. This is always performed here, // else we could end in trouble if user overrides this. if(mNbPrimitives==1) return true; // Let the user validate the subdivision if(!builder->ValidateSubdivision(mNodePrimitives, mNbPrimitives, mBV)) return true; bool ValidSplit = true; // Optimism... udword NbPos; if(builder->mSettings.mRules & SPLIT_LARGEST_AXIS) { // Find the largest axis to split along Point Extents; mBV.GetExtents(Extents); // Box extents udword Axis = Extents.LargestAxis(); // Index of largest axis // Split along the axis NbPos = Split(Axis, builder); // Check split validity if(!NbPos || NbPos==mNbPrimitives) ValidSplit = false; } else if(builder->mSettings.mRules & SPLIT_SPLATTER_POINTS) { // Compute the means Point Means(0.0f, 0.0f, 0.0f); for(udword i=0;iGetSplittingValue(Index, 0); Means.y+=builder->GetSplittingValue(Index, 1); Means.z+=builder->GetSplittingValue(Index, 2); } Means/=float(mNbPrimitives); // Compute variances Point Vars(0.0f, 0.0f, 0.0f); for(udword i=0;iGetSplittingValue(Index, 0); float Cy = builder->GetSplittingValue(Index, 1); float Cz = builder->GetSplittingValue(Index, 2); Vars.x += (Cx - Means.x)*(Cx - Means.x); Vars.y += (Cy - Means.y)*(Cy - Means.y); Vars.z += (Cz - Means.z)*(Cz - Means.z); } Vars/=float(mNbPrimitives-1); // Choose axis with greatest variance udword Axis = Vars.LargestAxis(); // Split along the axis NbPos = Split(Axis, builder); // Check split validity if(!NbPos || NbPos==mNbPrimitives) ValidSplit = false; } else if(builder->mSettings.mRules & SPLIT_BALANCED) { // Test 3 axis, take the best float Results[3]; NbPos = Split(0, builder); Results[0] = float(NbPos)/float(mNbPrimitives); NbPos = Split(1, builder); Results[1] = float(NbPos)/float(mNbPrimitives); NbPos = Split(2, builder); Results[2] = float(NbPos)/float(mNbPrimitives); Results[0]-=0.5f; Results[0]*=Results[0]; Results[1]-=0.5f; Results[1]*=Results[1]; Results[2]-=0.5f; Results[2]*=Results[2]; udword Min=0; if(Results[1]mSettings.mRules & SPLIT_BEST_AXIS) { // Test largest, then middle, then smallest axis... // Sort axis Point Extents; mBV.GetExtents(Extents); // Box extents udword SortedAxis[] = { 0, 1, 2 }; float* Keys = (float*)&Extents.x; for(udword j=0;j<3;j++) { for(udword i=0;i<2;i++) { if(Keys[SortedAxis[i]]mSettings.mRules & SPLIT_FIFTY) { // Don't even bother splitting (mainly a performance test) NbPos = mNbPrimitives>>1; } else return false; // Unknown splitting rules // Check the subdivision has been successful if(!ValidSplit) { // Here, all boxes lie in the same sub-space. Two strategies: // - if the tree *must* be complete, make an arbitrary 50-50 split // - else stop subdividing // if(builder->mSettings.mRules&SPLIT_COMPLETE) if(builder->mSettings.mLimit==1) { builder->IncreaseNbInvalidSplits(); NbPos = mNbPrimitives>>1; } else return true; } // Now create children and assign their pointers. if(builder->mNodeBase) { // We use a pre-allocated linear pool for complete trees [Opcode 1.3] AABBTreeNode* Pool = (AABBTreeNode*)builder->mNodeBase; udword Count = builder->GetCount() - 1; // Count begins to 1... // Set last bit to tell it shouldn't be freed ### pretty ugly, find a better way. Maybe one bit in mNbPrimitives ASSERT(!(udword(&Pool[Count+0])&1)); ASSERT(!(udword(&Pool[Count+1])&1)); mPos = size_t(&Pool[Count+0])|1; #ifndef OPC_NO_NEG_VANILLA_TREE mNeg = size_t(&Pool[Count+1])|1; #endif } else { // Non-complete trees and/or Opcode 1.2 allocate nodes on-the-fly #ifndef OPC_NO_NEG_VANILLA_TREE mPos = (size_t)new AABBTreeNode; CHECKALLOC(mPos); mNeg = (size_t)new AABBTreeNode; CHECKALLOC(mNeg); #else AABBTreeNode* PosNeg = new AABBTreeNode[2]; CHECKALLOC(PosNeg); mPos = (size_t)PosNeg; #endif } // Update stats builder->IncreaseCount(2); // Assign children AABBTreeNode* Pos = (AABBTreeNode*)GetPos(); AABBTreeNode* Neg = (AABBTreeNode*)GetNeg(); Pos->mNodePrimitives = &mNodePrimitives[0]; Pos->mNbPrimitives = NbPos; Neg->mNodePrimitives = &mNodePrimitives[NbPos]; Neg->mNbPrimitives = mNbPrimitives - NbPos; return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive hierarchy building in a top-down fashion. * \param builder [in] the tree builder */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void AABBTreeNode::_BuildHierarchy(AABBTreeBuilder* builder) { // 1) Compute the global box for current node. The box is stored in mBV. builder->ComputeGlobalBox(mNodePrimitives, mNbPrimitives, mBV); // 2) Subdivide current node Subdivide(builder); // 3) Recurse AABBTreeNode* Pos = (AABBTreeNode*)GetPos(); AABBTreeNode* Neg = (AABBTreeNode*)GetNeg(); if(Pos) Pos->_BuildHierarchy(builder); if(Neg) Neg->_BuildHierarchy(builder); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Refits the tree (top-down). * \param builder [in] the tree builder */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void AABBTreeNode::_Refit(AABBTreeBuilder* builder) { // 1) Recompute the new global box for current node builder->ComputeGlobalBox(mNodePrimitives, mNbPrimitives, mBV); // 2) Recurse AABBTreeNode* Pos = (AABBTreeNode*)GetPos(); AABBTreeNode* Neg = (AABBTreeNode*)GetNeg(); if(Pos) Pos->_Refit(builder); if(Neg) Neg->_Refit(builder); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// AABBTree::AABBTree() : mIndices(null), mPool(null), mTotalNbNodes(0) { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Destructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// AABBTree::~AABBTree() { Release(); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Releases the tree. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void AABBTree::Release() { DELETEARRAY(mPool); DELETEARRAY(mIndices); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Builds a generic AABB tree from a tree builder. * \param builder [in] the tree builder * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool AABBTree::Build(AABBTreeBuilder* builder) { // Checkings if(!builder || !builder->mNbPrimitives) return false; // Release previous tree Release(); // Init stats builder->SetCount(1); builder->SetNbInvalidSplits(0); // Initialize indices. This list will be modified during build. mIndices = new dTriIndex[builder->mNbPrimitives]; CHECKALLOC(mIndices); // Identity permutation for(udword i=0;imNbPrimitives;i++) mIndices[i] = i; // Setup initial node. Here we have a complete permutation of the app's primitives. mNodePrimitives = mIndices; mNbPrimitives = builder->mNbPrimitives; // Use a linear array for complete trees (since we can predict the final number of nodes) [Opcode 1.3] // if(builder->mRules&SPLIT_COMPLETE) if(builder->mSettings.mLimit==1) { // Allocate a pool of nodes mPool = new AABBTreeNode[builder->mNbPrimitives*2 - 1]; builder->mNodeBase = mPool; // ### ugly ! } // Build the hierarchy _BuildHierarchy(builder); // Get back total number of nodes mTotalNbNodes = builder->GetCount(); // For complete trees, check the correct number of nodes has been created [Opcode 1.3] if(mPool) ASSERT(mTotalNbNodes==builder->mNbPrimitives*2 - 1); return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the depth of the tree. * A well-balanced tree should have a log(n) depth. A degenerate tree O(n) depth. * \return depth of the tree */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// udword AABBTree::ComputeDepth() const { return Walk(null, null); // Use the walking code without callback } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Walks the tree, calling the user back for each node. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// udword AABBTree::Walk(WalkingCallback callback, void* user_data) const { // Call it without callback to compute max depth udword MaxDepth = 0; udword CurrentDepth = 0; struct Local { static void _Walk(const AABBTreeNode* current_node, udword& max_depth, udword& current_depth, WalkingCallback callback, void* user_data) { // Checkings if(!current_node) return; // Entering a new node => increase depth current_depth++; // Keep track of max depth if(current_depth>max_depth) max_depth = current_depth; // Callback if(callback && !(callback)(current_node, current_depth, user_data)) return; // Recurse if(current_node->GetPos()) { _Walk(current_node->GetPos(), max_depth, current_depth, callback, user_data); current_depth--; } if(current_node->GetNeg()) { _Walk(current_node->GetNeg(), max_depth, current_depth, callback, user_data); current_depth--; } } }; Local::_Walk(this, MaxDepth, CurrentDepth, callback, user_data); return MaxDepth; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Refits the tree in a top-down way. * \param builder [in] the tree builder */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool AABBTree::Refit(AABBTreeBuilder* builder) { if(!builder) return false; _Refit(builder); return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Refits the tree in a bottom-up way. * \param builder [in] the tree builder */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool AABBTree::Refit2(AABBTreeBuilder* builder) { // Checkings if(!builder) return false; ASSERT(mPool); // Bottom-up update Point Min,Max; Point Min_,Max_; udword Index = mTotalNbNodes; while(Index--) { AABBTreeNode& Current = mPool[Index]; if(Current.IsLeaf()) { builder->ComputeGlobalBox(Current.GetPrimitives(), Current.GetNbPrimitives(), *(AABB*)Current.GetAABB()); } else { Current.GetPos()->GetAABB()->GetMin(Min); Current.GetPos()->GetAABB()->GetMax(Max); Current.GetNeg()->GetAABB()->GetMin(Min_); Current.GetNeg()->GetAABB()->GetMax(Max_); Min.Min(Min_); Max.Max(Max_); ((AABB*)Current.GetAABB())->SetMinMax(Min, Max); } } return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the number of bytes used by the tree. * \return number of bytes used */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// udword AABBTree::GetUsedBytes() const { udword TotalSize = mTotalNbNodes*GetNodeSize(); if(mIndices) TotalSize+=mNbPrimitives*sizeof(udword); return TotalSize; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks the tree is a complete tree or not. * A complete tree is made of 2*N-1 nodes, where N is the number of primitives in the tree. * \return true for complete trees */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool AABBTree::IsComplete() const { return (GetNbNodes()==GetNbPrimitives()*2-1); } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_LSSCollider.cpp0000600000175000017500000006427212161402010023654 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for an LSS collider. * \file OPC_LSSCollider.cpp * \author Pierre Terdiman * \date December, 28, 2002 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains a lss-vs-tree collider. * * \class LSSCollider * \author Pierre Terdiman * \version 1.3 * \date December, 28, 2002 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace Opcode; #include "OPC_LSSAABBOverlap.h" #include "OPC_LSSTriOverlap.h" #define SET_CONTACT(prim_index, flag) \ /* Set contact status */ \ mFlags |= flag; \ mTouchedPrimitives->Add(udword(prim_index)); //! LSS-triangle overlap test #define LSS_PRIM(prim_index, flag) \ /* Request vertices from the app */ \ VertexPointers VP; ConversionArea VC; mIMesh->GetTriangle(VP, prim_index, VC); \ \ /* Perform LSS-tri overlap test */ \ if(LSSTriOverlap(*VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2])) \ { \ SET_CONTACT(prim_index, flag) \ } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// LSSCollider::LSSCollider() { // mCenter.Zero(); // mRadius2 = 0.0f; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Destructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// LSSCollider::~LSSCollider() { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Generic collision query for generic OPCODE models. After the call, access the results: * - with GetContactStatus() * - with GetNbTouchedPrimitives() * - with GetTouchedPrimitives() * * \param cache [in/out] an lss cache * \param lss [in] collision lss in local space * \param model [in] Opcode model to collide with * \param worldl [in] lss world matrix, or null * \param worldm [in] model's world matrix, or null * \return true if success * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool LSSCollider::Collide(LSSCache& cache, const LSS& lss, const Model& model, const Matrix4x4* worldl, const Matrix4x4* worldm) { // Checkings if(!Setup(&model)) return false; // Init collision query if(InitQuery(cache, lss, worldl, worldm)) return true; if(!model.HasLeafNodes()) { if(model.IsQuantized()) { const AABBQuantizedNoLeafTree* Tree = (const AABBQuantizedNoLeafTree*)model.GetTree(); // Setup dequantization coeffs mCenterCoeff = Tree->mCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); else _Collide(Tree->GetNodes()); } else { const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); else _Collide(Tree->GetNodes()); } } else { if(model.IsQuantized()) { const AABBQuantizedTree* Tree = (const AABBQuantizedTree*)model.GetTree(); // Setup dequantization coeffs mCenterCoeff = Tree->mCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); else _Collide(Tree->GetNodes()); } else { const AABBCollisionTree* Tree = (const AABBCollisionTree*)model.GetTree(); // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); else _Collide(Tree->GetNodes()); } } return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Initializes a collision query : * - reset stats & contact status * - setup matrices * - check temporal coherence * * \param cache [in/out] an lss cache * \param lss [in] lss in local space * \param worldl [in] lss world matrix, or null * \param worldm [in] model's world matrix, or null * \return TRUE if we can return immediately * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// BOOL LSSCollider::InitQuery(LSSCache& cache, const LSS& lss, const Matrix4x4* worldl, const Matrix4x4* worldm) { // 1) Call the base method VolumeCollider::InitQuery(); // 2) Compute LSS in model space: // - Precompute R^2 mRadius2 = lss.mRadius * lss.mRadius; // - Compute segment mSeg.mP0 = lss.mP0; mSeg.mP1 = lss.mP1; // -> to world space if(worldl) { mSeg.mP0 *= *worldl; mSeg.mP1 *= *worldl; } // -> to model space if(worldm) { // Invert model matrix Matrix4x4 InvWorldM; InvertPRMatrix(InvWorldM, *worldm); mSeg.mP0 *= InvWorldM; mSeg.mP1 *= InvWorldM; } // 3) Setup destination pointer mTouchedPrimitives = &cache.TouchedPrimitives; // 4) Special case: 1-triangle meshes [Opcode 1.3] if(mCurrentModel && mCurrentModel->HasSingleNode()) { if(!SkipPrimitiveTests()) { // We simply perform the BV-Prim overlap test each time. We assume single triangle has index 0. mTouchedPrimitives->Reset(); // Perform overlap test between the unique triangle and the LSS (and set contact status if needed) LSS_PRIM(udword(0), OPC_CONTACT) // Return immediately regardless of status return TRUE; } } // 5) Check temporal coherence : if(TemporalCoherenceEnabled()) { // Here we use temporal coherence // => check results from previous frame before performing the collision query if(FirstContactEnabled()) { // We're only interested in the first contact found => test the unique previously touched face if(mTouchedPrimitives->GetNbEntries()) { // Get index of previously touched face = the first entry in the array udword PreviouslyTouchedFace = mTouchedPrimitives->GetEntry(0); // Then reset the array: // - if the overlap test below is successful, the index we'll get added back anyway // - if it isn't, then the array should be reset anyway for the normal query mTouchedPrimitives->Reset(); // Perform overlap test between the cached triangle and the LSS (and set contact status if needed) LSS_PRIM(PreviouslyTouchedFace, OPC_TEMPORAL_CONTACT) // Return immediately if possible if(GetContactStatus()) return TRUE; } // else no face has been touched during previous query // => we'll have to perform a normal query } else { // We're interested in all contacts =>test the new real LSS N(ew) against the previous fat LSS P(revious): // ### rewrite this LSS Test(mSeg, lss.mRadius); // in model space LSS Previous(cache.Previous, sqrtf(cache.Previous.mRadius)); // if(cache.Previous.Contains(Test)) if(IsCacheValid(cache) && Previous.Contains(Test)) { // - if N is included in P, return previous list // => we simply leave the list (mTouchedFaces) unchanged // Set contact status if needed if(mTouchedPrimitives->GetNbEntries()) mFlags |= OPC_TEMPORAL_CONTACT; // In any case we don't need to do a query return TRUE; } else { // - else do the query using a fat N // Reset cache since we'll about to perform a real query mTouchedPrimitives->Reset(); // Make a fat sphere so that coherence will work for subsequent frames mRadius2 *= cache.FatCoeff; // mRadius2 = (lss.mRadius * cache.FatCoeff)*(lss.mRadius * cache.FatCoeff); // Update cache with query data (signature for cached faces) cache.Previous.mP0 = mSeg.mP0; cache.Previous.mP1 = mSeg.mP1; cache.Previous.mRadius = mRadius2; } } } else { // Here we don't use temporal coherence => do a normal query mTouchedPrimitives->Reset(); } return FALSE; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Collision query for vanilla AABB trees. * \param cache [in/out] an lss cache * \param lss [in] collision lss in world space * \param tree [in] AABB tree * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool LSSCollider::Collide(LSSCache& cache, const LSS& lss, const AABBTree* tree) { // This is typically called for a scene tree, full of -AABBs-, not full of triangles. // So we don't really have "primitives" to deal with. Hence it doesn't work with // "FirstContact" + "TemporalCoherence". ASSERT( !(FirstContactEnabled() && TemporalCoherenceEnabled()) ); // Checkings if(!tree) return false; // Init collision query if(InitQuery(cache, lss)) return true; // Perform collision query _Collide(tree); return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks the LSS completely contains the box. In which case we can end the query sooner. * \param bc [in] box center * \param be [in] box extents * \return true if the LSS contains the whole box */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL LSSCollider::LSSContainsBox(const Point& bc, const Point& be) { // Not implemented return FALSE; } #define TEST_BOX_IN_LSS(center, extents) \ if(LSSContainsBox(center, extents)) \ { \ /* Set contact status */ \ mFlags |= OPC_CONTACT; \ _Dump(node); \ return; \ } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for normal AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void LSSCollider::_Collide(const AABBCollisionNode* node) { // Perform LSS-AABB overlap test if(!LSSAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; TEST_BOX_IN_LSS(node->mAABB.mCenter, node->mAABB.mExtents) if(node->IsLeaf()) { LSS_PRIM(node->GetPrimitive(), OPC_CONTACT) } else { _Collide(node->GetPos()); if(ContactFound()) return; _Collide(node->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for normal AABB trees, without primitive tests. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void LSSCollider::_CollideNoPrimitiveTest(const AABBCollisionNode* node) { // Perform LSS-AABB overlap test if(!LSSAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; TEST_BOX_IN_LSS(node->mAABB.mCenter, node->mAABB.mExtents) if(node->IsLeaf()) { SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) } else { _CollideNoPrimitiveTest(node->GetPos()); if(ContactFound()) return; _CollideNoPrimitiveTest(node->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for quantized AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void LSSCollider::_Collide(const AABBQuantizedNode* node) { // Dequantize box const QuantizedAABB& Box = node->mAABB; const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); // Perform LSS-AABB overlap test if(!LSSAABBOverlap(Center, Extents)) return; TEST_BOX_IN_LSS(Center, Extents) if(node->IsLeaf()) { LSS_PRIM(node->GetPrimitive(), OPC_CONTACT) } else { _Collide(node->GetPos()); if(ContactFound()) return; _Collide(node->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for quantized AABB trees, without primitive tests. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void LSSCollider::_CollideNoPrimitiveTest(const AABBQuantizedNode* node) { // Dequantize box const QuantizedAABB& Box = node->mAABB; const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); // Perform LSS-AABB overlap test if(!LSSAABBOverlap(Center, Extents)) return; TEST_BOX_IN_LSS(Center, Extents) if(node->IsLeaf()) { SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) } else { _CollideNoPrimitiveTest(node->GetPos()); if(ContactFound()) return; _CollideNoPrimitiveTest(node->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for no-leaf AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void LSSCollider::_Collide(const AABBNoLeafNode* node) { // Perform LSS-AABB overlap test if(!LSSAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; TEST_BOX_IN_LSS(node->mAABB.mCenter, node->mAABB.mExtents) if(node->HasPosLeaf()) { LSS_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } else _Collide(node->GetPos()); if(ContactFound()) return; if(node->HasNegLeaf()) { LSS_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } else _Collide(node->GetNeg()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for no-leaf AABB trees, without primitive tests. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void LSSCollider::_CollideNoPrimitiveTest(const AABBNoLeafNode* node) { // Perform LSS-AABB overlap test if(!LSSAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; TEST_BOX_IN_LSS(node->mAABB.mCenter, node->mAABB.mExtents) if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } else _CollideNoPrimitiveTest(node->GetPos()); if(ContactFound()) return; if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } else _CollideNoPrimitiveTest(node->GetNeg()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for quantized no-leaf AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void LSSCollider::_Collide(const AABBQuantizedNoLeafNode* node) { // Dequantize box const QuantizedAABB& Box = node->mAABB; const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); // Perform LSS-AABB overlap test if(!LSSAABBOverlap(Center, Extents)) return; TEST_BOX_IN_LSS(Center, Extents) if(node->HasPosLeaf()) { LSS_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } else _Collide(node->GetPos()); if(ContactFound()) return; if(node->HasNegLeaf()) { LSS_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } else _Collide(node->GetNeg()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for quantized no-leaf AABB trees, without primitive tests. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void LSSCollider::_CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node) { // Dequantize box const QuantizedAABB& Box = node->mAABB; const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); // Perform LSS-AABB overlap test if(!LSSAABBOverlap(Center, Extents)) return; TEST_BOX_IN_LSS(Center, Extents) if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } else _CollideNoPrimitiveTest(node->GetPos()); if(ContactFound()) return; if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } else _CollideNoPrimitiveTest(node->GetNeg()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for vanilla AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void LSSCollider::_Collide(const AABBTreeNode* node) { // Perform LSS-AABB overlap test Point Center, Extents; node->GetAABB()->GetCenter(Center); node->GetAABB()->GetExtents(Extents); if(!LSSAABBOverlap(Center, Extents)) return; if(node->IsLeaf() || LSSContainsBox(Center, Extents)) { mFlags |= OPC_CONTACT; mTouchedPrimitives->Add(node->GetPrimitives(), node->GetNbPrimitives()); } else { _Collide(node->GetPos()); _Collide(node->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// HybridLSSCollider::HybridLSSCollider() { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Destructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// HybridLSSCollider::~HybridLSSCollider() { } bool HybridLSSCollider::Collide(LSSCache& cache, const LSS& lss, const HybridModel& model, const Matrix4x4* worldl, const Matrix4x4* worldm) { // We don't want primitive tests here! mFlags |= OPC_NO_PRIMITIVE_TESTS; // Checkings if(!Setup(&model)) return false; // Init collision query if(InitQuery(cache, lss, worldl, worldm)) return true; // Special case for 1-leaf trees if(mCurrentModel && mCurrentModel->HasSingleNode()) { // Here we're supposed to perform a normal query, except our tree has a single node, i.e. just a few triangles udword Nb = mIMesh->GetNbTriangles(); // Loop through all triangles for(udword i=0;imCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes()); } else { const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes()); } } else { if(model.IsQuantized()) { const AABBQuantizedTree* Tree = (const AABBQuantizedTree*)model.GetTree(); // Setup dequantization coeffs mCenterCoeff = Tree->mCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes()); } else { const AABBCollisionTree* Tree = (const AABBCollisionTree*)model.GetTree(); // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes()); } } // We only have a list of boxes so far if(GetContactStatus()) { // Reset contact status, since it currently only reflects collisions with leaf boxes Collider::InitQuery(); // Change dest container so that we can use built-in overlap tests and get collided primitives cache.TouchedPrimitives.Reset(); mTouchedPrimitives = &cache.TouchedPrimitives; // Read touched leaf boxes udword Nb = mTouchedBoxes.GetNbEntries(); const udword* Touched = mTouchedBoxes.GetEntries(); const LeafTriangles* LT = model.GetLeafTriangles(); const udword* Indices = model.GetIndices(); // Loop through touched leaves while(Nb--) { const LeafTriangles& CurrentLeaf = LT[*Touched++]; // Each leaf box has a set of triangles udword NbTris = CurrentLeaf.GetNbTriangles(); if(Indices) { const udword* T = &Indices[CurrentLeaf.GetTriangleIndex()]; // Loop through triangles and test each of them while(NbTris--) { udword TriangleIndex = *T++; LSS_PRIM(TriangleIndex, OPC_CONTACT) } } else { udword BaseIndex = CurrentLeaf.GetTriangleIndex(); // Loop through triangles and test each of them while(NbTris--) { udword TriangleIndex = BaseIndex++; LSS_PRIM(TriangleIndex, OPC_CONTACT) } } } } return true; } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_RayCollider.cpp0000600000175000017500000007114712161402010023745 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for a ray collider. * \file OPC_RayCollider.cpp * \author Pierre Terdiman * \date June, 2, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains a ray-vs-tree collider. * This class performs a stabbing query on an AABB tree, i.e. does a ray-mesh collision. * * HIGHER DISTANCE BOUND: * * If P0 and P1 are two 3D points, let's define: * - d = distance between P0 and P1 * - Origin = P0 * - Direction = (P1 - P0) / d = normalized direction vector * - A parameter t such as a point P on the line (P0,P1) is P = Origin + t * Direction * - t = 0 --> P = P0 * - t = d --> P = P1 * * Then we can define a general "ray" as: * * struct Ray * { * Point Origin; * Point Direction; * }; * * But it actually maps three different things: * - a segment, when 0 <= t <= d * - a half-line, when 0 <= t < +infinity, or -infinity < t <= d * - a line, when -infinity < t < +infinity * * In Opcode, we support segment queries, which yield half-line queries by setting d = +infinity. * We don't support line-queries. If you need them, shift the origin along the ray by an appropriate margin. * * In short, the lower bound is always 0, and you can setup the higher bound "d" with RayCollider::SetMaxDist(). * * Query |segment |half-line |line * --------|-------------------|---------------|---------------- * Usages |-shadow feelers |-raytracing |- * |-sweep tests |-in/out tests | * * FIRST CONTACT: * * - You can setup "first contact" mode or "all contacts" mode with RayCollider::SetFirstContact(). * - In "first contact" mode we return as soon as the ray hits one face. If can be useful e.g. for shadow feelers, where * you want to know whether the path to the light is free or not (a boolean answer is enough). * - In "all contacts" mode we return all faces hit by the ray. * * TEMPORAL COHERENCE: * * - You can enable or disable temporal coherence with RayCollider::SetTemporalCoherence(). * - It currently only works in "first contact" mode. * - If temporal coherence is enabled, the previously hit triangle is cached during the first query. Then, next queries * start by colliding the ray against the cached triangle. If they still collide, we return immediately. * * CLOSEST HIT: * * - You can enable or disable "closest hit" with RayCollider::SetClosestHit(). * - It currently only works in "all contacts" mode. * - If closest hit is enabled, faces are sorted by distance on-the-fly and the closest one only is reported. * * BACKFACE CULLING: * * - You can enable or disable backface culling with RayCollider::SetCulling(). * - If culling is enabled, ray will not hit back faces (only front faces). * * * * \class RayCollider * \author Pierre Terdiman * \version 1.3 * \date June, 2, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * This class describes a face hit by a ray or segment. * This is a particular class dedicated to stabbing queries. * * \class CollisionFace * \author Pierre Terdiman * \version 1.3 * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * This class is a dedicated collection of CollisionFace. * * \class CollisionFaces * \author Pierre Terdiman * \version 1.3 * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace Opcode; #include "OPC_RayAABBOverlap.h" #include "OPC_RayTriOverlap.h" #define SET_CONTACT(prim_index, flag) \ mNbIntersections++; \ /* Set contact status */ \ mFlags |= flag; \ /* In any case the contact has been found and recorded in mStabbedFace */ \ mStabbedFace.mFaceID = prim_index; #ifdef OPC_RAYHIT_CALLBACK #define HANDLE_CONTACT(prim_index, flag) \ SET_CONTACT(prim_index, flag) \ \ if(mHitCallback) (mHitCallback)(mStabbedFace, mUserData); #define UPDATE_CACHE \ if(cache && GetContactStatus()) \ { \ *cache = mStabbedFace.mFaceID; \ } #else #define HANDLE_CONTACT(prim_index, flag) \ SET_CONTACT(prim_index, flag) \ \ /* Now we can also record it in mStabbedFaces if available */ \ if(mStabbedFaces) \ { \ /* If we want all faces or if that's the first one we hit */ \ if(!mClosestHit || !mStabbedFaces->GetNbFaces()) \ { \ mStabbedFaces->AddFace(mStabbedFace); \ } \ else \ { \ /* We only keep closest hit */ \ CollisionFace* Current = const_cast(mStabbedFaces->GetFaces()); \ if(Current && mStabbedFace.mDistancemDistance) \ { \ *Current = mStabbedFace; \ } \ } \ } #define UPDATE_CACHE \ if(cache && GetContactStatus() && mStabbedFaces) \ { \ const CollisionFace* Current = mStabbedFaces->GetFaces(); \ if(Current) *cache = Current->mFaceID; \ else *cache = INVALID_ID; \ } #endif #define SEGMENT_PRIM(prim_index, flag) \ /* Request vertices from the app */ \ VertexPointers VP; ConversionArea VC; mIMesh->GetTriangle(VP, prim_index, VC); \ \ /* Perform ray-tri overlap test and return */ \ if(RayTriOverlap(*VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2])) \ { \ /* Intersection point is valid if dist < segment's length */ \ /* We know dist>0 so we can use integers */ \ if(IR(mStabbedFace.mDistance)GetTriangle(VP, prim_index, VC); \ \ /* Perform ray-tri overlap test and return */ \ if(RayTriOverlap(*VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2])) \ { \ HANDLE_CONTACT(prim_index, flag) \ } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// RayCollider::RayCollider() : #ifdef OPC_RAYHIT_CALLBACK mHitCallback (null), mUserData (0), #else mStabbedFaces (null), mClosestHit (false), #endif mNbRayBVTests (0), mNbRayPrimTests (0), mNbIntersections (0), mMaxDist (MAX_FLOAT), mCulling (true) { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Destructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// RayCollider::~RayCollider() { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Validates current settings. You should call this method after all the settings and callbacks have been defined. * \return null if everything is ok, else a string describing the problem */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const char* RayCollider::ValidateSettings() { if(mMaxDist<0.0f) return "Higher distance bound must be positive!"; if(TemporalCoherenceEnabled() && !FirstContactEnabled()) return "Temporal coherence only works with ""First contact"" mode!"; #ifndef OPC_RAYHIT_CALLBACK if(mClosestHit && FirstContactEnabled()) return "Closest hit doesn't work with ""First contact"" mode!"; if(TemporalCoherenceEnabled() && mClosestHit) return "Temporal coherence can't guarantee to report closest hit!"; #endif if(SkipPrimitiveTests()) return "SkipPrimitiveTests not possible for RayCollider ! (not implemented)"; return null; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Generic stabbing query for generic OPCODE models. After the call, access the results: * - with GetContactStatus() * - in the user-provided destination array * * \param world_ray [in] stabbing ray in world space * \param model [in] Opcode model to collide with * \param world [in] model's world matrix, or null * \param cache [in] a possibly cached face index, or null * \return true if success * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool RayCollider::Collide(const Ray& world_ray, const Model& model, const Matrix4x4* world, udword* cache) { // Checkings if(!Setup(&model)) return false; // Init collision query if(InitQuery(world_ray, world, cache)) return true; if(!model.HasLeafNodes()) { if(model.IsQuantized()) { const AABBQuantizedNoLeafTree* Tree = (const AABBQuantizedNoLeafTree*)model.GetTree(); // Setup dequantization coeffs mCenterCoeff = Tree->mCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform stabbing query if(IR(mMaxDist)!=IEEE_MAX_FLOAT) _SegmentStab(Tree->GetNodes()); else _RayStab(Tree->GetNodes()); } else { const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); // Perform stabbing query if(IR(mMaxDist)!=IEEE_MAX_FLOAT) _SegmentStab(Tree->GetNodes()); else _RayStab(Tree->GetNodes()); } } else { if(model.IsQuantized()) { const AABBQuantizedTree* Tree = (const AABBQuantizedTree*)model.GetTree(); // Setup dequantization coeffs mCenterCoeff = Tree->mCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform stabbing query if(IR(mMaxDist)!=IEEE_MAX_FLOAT) _SegmentStab(Tree->GetNodes()); else _RayStab(Tree->GetNodes()); } else { const AABBCollisionTree* Tree = (const AABBCollisionTree*)model.GetTree(); // Perform stabbing query if(IR(mMaxDist)!=IEEE_MAX_FLOAT) _SegmentStab(Tree->GetNodes()); else _RayStab(Tree->GetNodes()); } } // Update cache if needed UPDATE_CACHE return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Initializes a stabbing query : * - reset stats & contact status * - compute ray in local space * - check temporal coherence * * \param world_ray [in] stabbing ray in world space * \param world [in] object's world matrix, or null * \param face_id [in] index of previously stabbed triangle * \return TRUE if we can return immediately * \warning SCALE NOT SUPPORTED. The matrix must contain rotation & translation parts only. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// BOOL RayCollider::InitQuery(const Ray& world_ray, const Matrix4x4* world, udword* face_id) { // Reset stats & contact status Collider::InitQuery(); mNbRayBVTests = 0; mNbRayPrimTests = 0; mNbIntersections = 0; #ifndef OPC_RAYHIT_CALLBACK if(mStabbedFaces) mStabbedFaces->Reset(); #endif // Compute ray in local space // The (Origin/Dir) form is needed for the ray-triangle test anyway (even for segment tests) if(world) { Matrix3x3 InvWorld = *world; mDir = InvWorld * world_ray.mDir; Matrix4x4 World; InvertPRMatrix(World, *world); mOrigin = world_ray.mOrig * World; } else { mDir = world_ray.mDir; mOrigin = world_ray.mOrig; } // 4) Special case: 1-triangle meshes [Opcode 1.3] if(mCurrentModel && mCurrentModel->HasSingleNode()) { // We simply perform the BV-Prim overlap test each time. We assume single triangle has index 0. if(!SkipPrimitiveTests()) { // Perform overlap test between the unique triangle and the ray (and set contact status if needed) SEGMENT_PRIM(udword(0), OPC_CONTACT) // Return immediately regardless of status return TRUE; } } // Check temporal coherence : // Test previously colliding primitives first if(TemporalCoherenceEnabled() && FirstContactEnabled() && face_id && *face_id!=INVALID_ID) { #ifdef OLD_CODE #ifndef OPC_RAYHIT_CALLBACK if(!mClosestHit) #endif { // Request vertices from the app VertexPointers VP; ConversionArea VC; mIMesh->GetTriangle(VP, *face_id, VC); // Perform ray-cached tri overlap test if(RayTriOverlap(*VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2])) { // Intersection point is valid if: // - distance is positive (else it can just be a face behind the orig point) // - distance is smaller than a given max distance (useful for shadow feelers) // if(mStabbedFace.mDistance>0.0f && mStabbedFace.mDistanceAddFace(mStabbedFace); #endif return TRUE; } } } #else // New code // We handle both Segment/ray queries with the same segment code, and a possible infinite limit SEGMENT_PRIM(*face_id, OPC_TEMPORAL_CONTACT) // Return immediately if possible if(GetContactStatus()) return TRUE; #endif } // Precompute data (moved after temporal coherence since only needed for ray-AABB) if(IR(mMaxDist)!=IEEE_MAX_FLOAT) { // For Segment-AABB overlap mData = 0.5f * mDir * mMaxDist; mData2 = mOrigin + mData; // Precompute mFDir; mFDir.x = fabsf(mData.x); mFDir.y = fabsf(mData.y); mFDir.z = fabsf(mData.z); } else { // For Ray-AABB overlap // udword x = SIR(mDir.x)-1; // udword y = SIR(mDir.y)-1; // udword z = SIR(mDir.z)-1; // mData.x = FR(x); // mData.y = FR(y); // mData.z = FR(z); // Precompute mFDir; mFDir.x = fabsf(mDir.x); mFDir.y = fabsf(mDir.y); mFDir.z = fabsf(mDir.z); } return FALSE; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Stabbing query for vanilla AABB trees. * \param world_ray [in] stabbing ray in world space * \param tree [in] AABB tree * \param box_indices [out] indices of stabbed boxes * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool RayCollider::Collide(const Ray& world_ray, const AABBTree* tree, Container& box_indices) { // ### bad design here // This is typically called for a scene tree, full of -AABBs-, not full of triangles. // So we don't really have "primitives" to deal with. Hence it doesn't work with // "FirstContact" + "TemporalCoherence". ASSERT( !(FirstContactEnabled() && TemporalCoherenceEnabled()) ); // Checkings if(!tree) return false; // Init collision query // Basically this is only called to initialize precomputed data if(InitQuery(world_ray)) return true; // Perform stabbing query if(IR(mMaxDist)!=IEEE_MAX_FLOAT) _SegmentStab(tree, box_indices); else _RayStab(tree, box_indices); return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive stabbing query for normal AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void RayCollider::_SegmentStab(const AABBCollisionNode* node) { // Perform Segment-AABB overlap test if(!SegmentAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; if(node->IsLeaf()) { SEGMENT_PRIM(node->GetPrimitive(), OPC_CONTACT) } else { _SegmentStab(node->GetPos()); if(ContactFound()) return; _SegmentStab(node->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive stabbing query for quantized AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void RayCollider::_SegmentStab(const AABBQuantizedNode* node) { // Dequantize box const QuantizedAABB& Box = node->mAABB; const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); // Perform Segment-AABB overlap test if(!SegmentAABBOverlap(Center, Extents)) return; if(node->IsLeaf()) { SEGMENT_PRIM(node->GetPrimitive(), OPC_CONTACT) } else { _SegmentStab(node->GetPos()); if(ContactFound()) return; _SegmentStab(node->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive stabbing query for no-leaf AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void RayCollider::_SegmentStab(const AABBNoLeafNode* node) { // Perform Segment-AABB overlap test if(!SegmentAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; if(node->HasPosLeaf()) { SEGMENT_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } else _SegmentStab(node->GetPos()); if(ContactFound()) return; if(node->HasNegLeaf()) { SEGMENT_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } else _SegmentStab(node->GetNeg()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive stabbing query for quantized no-leaf AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void RayCollider::_SegmentStab(const AABBQuantizedNoLeafNode* node) { // Dequantize box const QuantizedAABB& Box = node->mAABB; const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); // Perform Segment-AABB overlap test if(!SegmentAABBOverlap(Center, Extents)) return; if(node->HasPosLeaf()) { SEGMENT_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } else _SegmentStab(node->GetPos()); if(ContactFound()) return; if(node->HasNegLeaf()) { SEGMENT_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } else _SegmentStab(node->GetNeg()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive stabbing query for vanilla AABB trees. * \param node [in] current collision node * \param box_indices [out] indices of stabbed boxes */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void RayCollider::_SegmentStab(const AABBTreeNode* node, Container& box_indices) { // Test the box against the segment Point Center, Extents; node->GetAABB()->GetCenter(Center); node->GetAABB()->GetExtents(Extents); if(!SegmentAABBOverlap(Center, Extents)) return; if(node->IsLeaf()) { box_indices.Add(node->GetPrimitives(), node->GetNbPrimitives()); } else { _SegmentStab(node->GetPos(), box_indices); _SegmentStab(node->GetNeg(), box_indices); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive stabbing query for normal AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void RayCollider::_RayStab(const AABBCollisionNode* node) { // Perform Ray-AABB overlap test if(!RayAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; if(node->IsLeaf()) { RAY_PRIM(node->GetPrimitive(), OPC_CONTACT) } else { _RayStab(node->GetPos()); if(ContactFound()) return; _RayStab(node->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive stabbing query for quantized AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void RayCollider::_RayStab(const AABBQuantizedNode* node) { // Dequantize box const QuantizedAABB& Box = node->mAABB; const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); // Perform Ray-AABB overlap test if(!RayAABBOverlap(Center, Extents)) return; if(node->IsLeaf()) { RAY_PRIM(node->GetPrimitive(), OPC_CONTACT) } else { _RayStab(node->GetPos()); if(ContactFound()) return; _RayStab(node->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive stabbing query for no-leaf AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void RayCollider::_RayStab(const AABBNoLeafNode* node) { // Perform Ray-AABB overlap test if(!RayAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; if(node->HasPosLeaf()) { RAY_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } else _RayStab(node->GetPos()); if(ContactFound()) return; if(node->HasNegLeaf()) { RAY_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } else _RayStab(node->GetNeg()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive stabbing query for quantized no-leaf AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void RayCollider::_RayStab(const AABBQuantizedNoLeafNode* node) { // Dequantize box const QuantizedAABB& Box = node->mAABB; const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); // Perform Ray-AABB overlap test if(!RayAABBOverlap(Center, Extents)) return; if(node->HasPosLeaf()) { RAY_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } else _RayStab(node->GetPos()); if(ContactFound()) return; if(node->HasNegLeaf()) { RAY_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } else _RayStab(node->GetNeg()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive stabbing query for vanilla AABB trees. * \param node [in] current collision node * \param box_indices [out] indices of stabbed boxes */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void RayCollider::_RayStab(const AABBTreeNode* node, Container& box_indices) { // Test the box against the ray Point Center, Extents; node->GetAABB()->GetCenter(Center); node->GetAABB()->GetExtents(Extents); if(!RayAABBOverlap(Center, Extents)) return; if(node->IsLeaf()) { mFlags |= OPC_CONTACT; box_indices.Add(node->GetPrimitives(), node->GetNbPrimitives()); } else { _RayStab(node->GetPos(), box_indices); _RayStab(node->GetNeg(), box_indices); } } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_LSSTriOverlap.h0000600000175000017500000005130212161402010023641 0ustar zero79zero79// Following code from Magic-Software (http://www.magic-software.com/) // A bit modified for Opcode static const float gs_fTolerance = 1e-05f; static float OPC_PointTriangleSqrDist(const Point& point, const Point& p0, const Point& p1, const Point& p2) { // Hook Point TriEdge0 = p1 - p0; Point TriEdge1 = p2 - p0; Point kDiff = p0 - point; float fA00 = TriEdge0.SquareMagnitude(); float fA01 = TriEdge0 | TriEdge1; float fA11 = TriEdge1.SquareMagnitude(); float fB0 = kDiff | TriEdge0; float fB1 = kDiff | TriEdge1; float fC = kDiff.SquareMagnitude(); float fDet = fabsf(fA00*fA11 - fA01*fA01); float fS = fA01*fB1-fA11*fB0; float fT = fA01*fB0-fA00*fB1; float fSqrDist; if(fS + fT <= fDet) { if(fS < 0.0f) { if(fT < 0.0f) // region 4 { if(fB0 < 0.0f) { if(-fB0 >= fA00) fSqrDist = fA00+2.0f*fB0+fC; else fSqrDist = fB0*(-fB0/fA00)+fC; } else { if(fB1 >= 0.0f) fSqrDist = fC; else if(-fB1 >= fA11) fSqrDist = fA11+2.0f*fB1+fC; else fSqrDist = fB1*(-fB1/fA11)+fC; } } else // region 3 { if(fB1 >= 0.0f) fSqrDist = fC; else if(-fB1 >= fA11) fSqrDist = fA11+2.0f*fB1+fC; else fSqrDist = fB1*(-fB1/fA11)+fC; } } else if(fT < 0.0f) // region 5 { if(fB0 >= 0.0f) fSqrDist = fC; else if(-fB0 >= fA00) fSqrDist = fA00+2.0f*fB0+fC; else fSqrDist = fB0*(-fB0/fA00)+fC; } else // region 0 { // minimum at interior point if(fDet==0.0f) { fSqrDist = MAX_FLOAT; } else { float fInvDet = 1.0f/fDet; fS *= fInvDet; fT *= fInvDet; fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; } } } else { float fTmp0, fTmp1, fNumer, fDenom; if(fS < 0.0f) // region 2 { fTmp0 = fA01 + fB0; fTmp1 = fA11 + fB1; if(fTmp1 > fTmp0) { fNumer = fTmp1 - fTmp0; fDenom = fA00-2.0f*fA01+fA11; if(fNumer >= fDenom) { fSqrDist = fA00+2.0f*fB0+fC; } else { fS = fNumer/fDenom; fT = 1.0f - fS; fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; } } else { if(fTmp1 <= 0.0f) fSqrDist = fA11+2.0f*fB1+fC; else if(fB1 >= 0.0f) fSqrDist = fC; else fSqrDist = fB1*(-fB1/fA11)+fC; } } else if(fT < 0.0f) // region 6 { fTmp0 = fA01 + fB1; fTmp1 = fA00 + fB0; if(fTmp1 > fTmp0) { fNumer = fTmp1 - fTmp0; fDenom = fA00-2.0f*fA01+fA11; if(fNumer >= fDenom) { fSqrDist = fA11+2.0f*fB1+fC; } else { fT = fNumer/fDenom; fS = 1.0f - fT; fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; } } else { if(fTmp1 <= 0.0f) fSqrDist = fA00+2.0f*fB0+fC; else if(fB0 >= 0.0f) fSqrDist = fC; else fSqrDist = fB0*(-fB0/fA00)+fC; } } else // region 1 { fNumer = fA11 + fB1 - fA01 - fB0; if(fNumer <= 0.0f) { fSqrDist = fA11+2.0f*fB1+fC; } else { fDenom = fA00-2.0f*fA01+fA11; if(fNumer >= fDenom) { fSqrDist = fA00+2.0f*fB0+fC; } else { fS = fNumer/fDenom; fT = 1.0f - fS; fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; } } } } return fabsf(fSqrDist); } static float OPC_SegmentSegmentSqrDist(const Segment& rkSeg0, const Segment& rkSeg1) { // Hook Point rkSeg0Direction = rkSeg0.ComputeDirection(); Point rkSeg1Direction = rkSeg1.ComputeDirection(); Point kDiff = rkSeg0.mP0 - rkSeg1.mP0; float fA00 = rkSeg0Direction.SquareMagnitude(); float fA01 = -rkSeg0Direction.Dot(rkSeg1Direction); float fA11 = rkSeg1Direction.SquareMagnitude(); float fB0 = kDiff.Dot(rkSeg0Direction); float fC = kDiff.SquareMagnitude(); float fDet = fabsf(fA00*fA11-fA01*fA01); float fB1, fS, fT, fSqrDist, fTmp; if(fDet>=gs_fTolerance) { // line segments are not parallel fB1 = -kDiff.Dot(rkSeg1Direction); fS = fA01*fB1-fA11*fB0; fT = fA01*fB0-fA00*fB1; if(fS >= 0.0f) { if(fS <= fDet) { if(fT >= 0.0f) { if(fT <= fDet) // region 0 (interior) { // minimum at two interior points of 3D lines float fInvDet = 1.0f/fDet; fS *= fInvDet; fT *= fInvDet; fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; } else // region 3 (side) { fTmp = fA01+fB0; if(fTmp>=0.0f) fSqrDist = fA11+2.0f*fB1+fC; else if(-fTmp>=fA00) fSqrDist = fA00+fA11+fC+2.0f*(fB1+fTmp); else fSqrDist = fTmp*(-fTmp/fA00)+fA11+2.0f*fB1+fC; } } else // region 7 (side) { if(fB0>=0.0f) fSqrDist = fC; else if(-fB0>=fA00) fSqrDist = fA00+2.0f*fB0+fC; else fSqrDist = fB0*(-fB0/fA00)+fC; } } else { if ( fT >= 0.0 ) { if ( fT <= fDet ) // region 1 (side) { fTmp = fA01+fB1; if(fTmp>=0.0f) fSqrDist = fA00+2.0f*fB0+fC; else if(-fTmp>=fA11) fSqrDist = fA00+fA11+fC+2.0f*(fB0+fTmp); else fSqrDist = fTmp*(-fTmp/fA11)+fA00+2.0f*fB0+fC; } else // region 2 (corner) { fTmp = fA01+fB0; if ( -fTmp <= fA00 ) { if(fTmp>=0.0f) fSqrDist = fA11+2.0f*fB1+fC; else fSqrDist = fTmp*(-fTmp/fA00)+fA11+2.0f*fB1+fC; } else { fTmp = fA01+fB1; if(fTmp>=0.0f) fSqrDist = fA00+2.0f*fB0+fC; else if(-fTmp>=fA11) fSqrDist = fA00+fA11+fC+2.0f*(fB0+fTmp); else fSqrDist = fTmp*(-fTmp/fA11)+fA00+2.0f*fB0+fC; } } } else // region 8 (corner) { if ( -fB0 < fA00 ) { if(fB0>=0.0f) fSqrDist = fC; else fSqrDist = fB0*(-fB0/fA00)+fC; } else { fTmp = fA01+fB1; if(fTmp>=0.0f) fSqrDist = fA00+2.0f*fB0+fC; else if(-fTmp>=fA11) fSqrDist = fA00+fA11+fC+2.0f*(fB0+fTmp); else fSqrDist = fTmp*(-fTmp/fA11)+fA00+2.0f*fB0+fC; } } } } else { if ( fT >= 0.0f ) { if ( fT <= fDet ) // region 5 (side) { if(fB1>=0.0f) fSqrDist = fC; else if(-fB1>=fA11) fSqrDist = fA11+2.0f*fB1+fC; else fSqrDist = fB1*(-fB1/fA11)+fC; } else // region 4 (corner) { fTmp = fA01+fB0; if ( fTmp < 0.0f ) { if(-fTmp>=fA00) fSqrDist = fA00+fA11+fC+2.0f*(fB1+fTmp); else fSqrDist = fTmp*(-fTmp/fA00)+fA11+2.0f*fB1+fC; } else { if(fB1>=0.0f) fSqrDist = fC; else if(-fB1>=fA11) fSqrDist = fA11+2.0f*fB1+fC; else fSqrDist = fB1*(-fB1/fA11)+fC; } } } else // region 6 (corner) { if ( fB0 < 0.0f ) { if(-fB0>=fA00) fSqrDist = fA00+2.0f*fB0+fC; else fSqrDist = fB0*(-fB0/fA00)+fC; } else { if(fB1>=0.0f) fSqrDist = fC; else if(-fB1>=fA11) fSqrDist = fA11+2.0f*fB1+fC; else fSqrDist = fB1*(-fB1/fA11)+fC; } } } } else { // line segments are parallel if ( fA01 > 0.0f ) { // direction vectors form an obtuse angle if ( fB0 >= 0.0f ) { fSqrDist = fC; } else if ( -fB0 <= fA00 ) { fSqrDist = fB0*(-fB0/fA00)+fC; } else { fB1 = -kDiff.Dot(rkSeg1Direction); fTmp = fA00+fB0; if ( -fTmp >= fA01 ) { fSqrDist = fA00+fA11+fC+2.0f*(fA01+fB0+fB1); } else { fT = -fTmp/fA01; fSqrDist = fA00+2.0f*fB0+fC+fT*(fA11*fT+2.0f*(fA01+fB1)); } } } else { // direction vectors form an acute angle if ( -fB0 >= fA00 ) { fSqrDist = fA00+2.0f*fB0+fC; } else if ( fB0 <= 0.0f ) { fSqrDist = fB0*(-fB0/fA00)+fC; } else { fB1 = -kDiff.Dot(rkSeg1Direction); if ( fB0 >= -fA01 ) { fSqrDist = fA11+2.0f*fB1+fC; } else { fT = -fB0/fA01; fSqrDist = fC+fT*(2.0f*fB1+fA11*fT); } } } } return fabsf(fSqrDist); } inline_ float OPC_SegmentRaySqrDist(const Segment& rkSeg0, const Ray& rkSeg1) { return OPC_SegmentSegmentSqrDist(rkSeg0, Segment(rkSeg1.mOrig, rkSeg1.mOrig + rkSeg1.mDir)); } static float OPC_SegmentTriangleSqrDist(const Segment& segment, const Point& p0, const Point& p1, const Point& p2) { // Hook const Point TriEdge0 = p1 - p0; const Point TriEdge1 = p2 - p0; const Point& rkSegOrigin = segment.GetOrigin(); Point rkSegDirection = segment.ComputeDirection(); Point kDiff = p0 - rkSegOrigin; float fA00 = rkSegDirection.SquareMagnitude(); float fA01 = -rkSegDirection.Dot(TriEdge0); float fA02 = -rkSegDirection.Dot(TriEdge1); float fA11 = TriEdge0.SquareMagnitude(); float fA12 = TriEdge0.Dot(TriEdge1); float fA22 = TriEdge1.Dot(TriEdge1); float fB0 = -kDiff.Dot(rkSegDirection); float fB1 = kDiff.Dot(TriEdge0); float fB2 = kDiff.Dot(TriEdge1); float fCof00 = fA11*fA22-fA12*fA12; float fCof01 = fA02*fA12-fA01*fA22; float fCof02 = fA01*fA12-fA02*fA11; float fDet = fA00*fCof00+fA01*fCof01+fA02*fCof02; Ray kTriSeg; Point kPt; float fSqrDist, fSqrDist0; if(fabsf(fDet)>=gs_fTolerance) { float fCof11 = fA00*fA22-fA02*fA02; float fCof12 = fA02*fA01-fA00*fA12; float fCof22 = fA00*fA11-fA01*fA01; float fInvDet = 1.0f/fDet; float fRhs0 = -fB0*fInvDet; float fRhs1 = -fB1*fInvDet; float fRhs2 = -fB2*fInvDet; float fR = fCof00*fRhs0+fCof01*fRhs1+fCof02*fRhs2; float fS = fCof01*fRhs0+fCof11*fRhs1+fCof12*fRhs2; float fT = fCof02*fRhs0+fCof12*fRhs1+fCof22*fRhs2; if ( fR < 0.0f ) { if ( fS+fT <= 1.0f ) { if ( fS < 0.0f ) { if ( fT < 0.0f ) // region 4m { // min on face s=0 or t=0 or r=0 kTriSeg.mOrig = p0; kTriSeg.mDir = TriEdge1; fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); kTriSeg.mOrig = p0; kTriSeg.mDir = TriEdge0; fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); if(fSqrDist0 1 { if ( fS+fT <= 1.0f ) { if ( fS < 0.0f ) { if ( fT < 0.0f ) // region 4p { // min on face s=0 or t=0 or r=1 kTriSeg.mOrig = p0; kTriSeg.mDir = TriEdge1; fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); kTriSeg.mOrig = p0; kTriSeg.mDir = TriEdge0; fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); if(fSqrDist0Add(udword(prim_index)); //! AABB-triangle test #define AABB_PRIM(prim_index, flag) \ /* Request vertices from the app */ \ VertexPointers VP; ConversionArea VC; mIMesh->GetTriangle(VP, prim_index, VC); \ mLeafVerts[0] = *VP.Vertex[0]; \ mLeafVerts[1] = *VP.Vertex[1]; \ mLeafVerts[2] = *VP.Vertex[2]; \ /* Perform triangle-box overlap test */ \ if(TriBoxOverlap()) \ { \ SET_CONTACT(prim_index, flag) \ } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// AABBCollider::AABBCollider() { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Destructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// AABBCollider::~AABBCollider() { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Generic collision query for generic OPCODE models. After the call, access the results: * - with GetContactStatus() * - with GetNbTouchedPrimitives() * - with GetTouchedPrimitives() * * \param cache [in/out] a box cache * \param box [in] collision AABB in world space * \param model [in] Opcode model to collide with * \return true if success * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool AABBCollider::Collide(AABBCache& cache, const CollisionAABB& box, const Model& model) { // Checkings if(!Setup(&model)) return false; // Init collision query if(InitQuery(cache, box)) return true; if(!model.HasLeafNodes()) { if(model.IsQuantized()) { const AABBQuantizedNoLeafTree* Tree = (const AABBQuantizedNoLeafTree*)model.GetTree(); // Setup dequantization coeffs mCenterCoeff = Tree->mCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); else _Collide(Tree->GetNodes()); } else { const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); else _Collide(Tree->GetNodes()); } } else { if(model.IsQuantized()) { const AABBQuantizedTree* Tree = (const AABBQuantizedTree*)model.GetTree(); // Setup dequantization coeffs mCenterCoeff = Tree->mCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); else _Collide(Tree->GetNodes()); } else { const AABBCollisionTree* Tree = (const AABBCollisionTree*)model.GetTree(); // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); else _Collide(Tree->GetNodes()); } } return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Initializes a collision query : * - reset stats & contact status * - check temporal coherence * * \param cache [in/out] a box cache * \param box [in] AABB in world space * \return TRUE if we can return immediately */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// BOOL AABBCollider::InitQuery(AABBCache& cache, const CollisionAABB& box) { // 1) Call the base method VolumeCollider::InitQuery(); // 2) Keep track of the query box mBox = box; // 3) Setup destination pointer mTouchedPrimitives = &cache.TouchedPrimitives; // 4) Special case: 1-triangle meshes [Opcode 1.3] if(mCurrentModel && mCurrentModel->HasSingleNode()) { if(!SkipPrimitiveTests()) { // We simply perform the BV-Prim overlap test each time. We assume single triangle has index 0. mTouchedPrimitives->Reset(); // Perform overlap test between the unique triangle and the box (and set contact status if needed) AABB_PRIM(udword(0), OPC_CONTACT) // Return immediately regardless of status return TRUE; } } // 5) Check temporal coherence : if(TemporalCoherenceEnabled()) { // Here we use temporal coherence // => check results from previous frame before performing the collision query if(FirstContactEnabled()) { // We're only interested in the first contact found => test the unique previously touched face if(mTouchedPrimitives->GetNbEntries()) { // Get index of previously touched face = the first entry in the array udword PreviouslyTouchedFace = mTouchedPrimitives->GetEntry(0); // Then reset the array: // - if the overlap test below is successful, the index we'll get added back anyway // - if it isn't, then the array should be reset anyway for the normal query mTouchedPrimitives->Reset(); // Perform overlap test between the cached triangle and the box (and set contact status if needed) AABB_PRIM(PreviouslyTouchedFace, OPC_TEMPORAL_CONTACT) // Return immediately if possible if(GetContactStatus()) return TRUE; } // else no face has been touched during previous query // => we'll have to perform a normal query } else { // We're interested in all contacts =>test the new real box N(ew) against the previous fat box P(revious): if(IsCacheValid(cache) && mBox.IsInside(cache.FatBox)) { // - if N is included in P, return previous list // => we simply leave the list (mTouchedFaces) unchanged // Set contact status if needed if(mTouchedPrimitives->GetNbEntries()) mFlags |= OPC_TEMPORAL_CONTACT; // In any case we don't need to do a query return TRUE; } else { // - else do the query using a fat N // Reset cache since we'll about to perform a real query mTouchedPrimitives->Reset(); // Make a fat box so that coherence will work for subsequent frames mBox.mExtents *= cache.FatCoeff; // Update cache with query data (signature for cached faces) cache.FatBox = mBox; } } } else { // Here we don't use temporal coherence => do a normal query mTouchedPrimitives->Reset(); } // 5) Precompute min & max bounds if needed mMin = box.mCenter - box.mExtents; mMax = box.mCenter + box.mExtents; return FALSE; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Collision query for vanilla AABB trees. * \param cache [in/out] a box cache * \param box [in] collision AABB in world space * \param tree [in] AABB tree * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool AABBCollider::Collide(AABBCache& cache, const CollisionAABB& box, const AABBTree* tree) { // This is typically called for a scene tree, full of -AABBs-, not full of triangles. // So we don't really have "primitives" to deal with. Hence it doesn't work with // "FirstContact" + "TemporalCoherence". ASSERT( !(FirstContactEnabled() && TemporalCoherenceEnabled()) ); // Checkings if(!tree) return false; // Init collision query if(InitQuery(cache, box)) return true; // Perform collision query _Collide(tree); return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks the AABB completely contains the box. In which case we can end the query sooner. * \param bc [in] box center * \param be [in] box extents * \return true if the AABB contains the whole box */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL AABBCollider::AABBContainsBox(const Point& bc, const Point& be) { if(mMin.x > bc.x - be.x) return FALSE; if(mMin.y > bc.y - be.y) return FALSE; if(mMin.z > bc.z - be.z) return FALSE; if(mMax.x < bc.x + be.x) return FALSE; if(mMax.y < bc.y + be.y) return FALSE; if(mMax.z < bc.z + be.z) return FALSE; return TRUE; } #define TEST_BOX_IN_AABB(center, extents) \ if(AABBContainsBox(center, extents)) \ { \ /* Set contact status */ \ mFlags |= OPC_CONTACT; \ _Dump(node); \ return; \ } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for normal AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void AABBCollider::_Collide(const AABBCollisionNode* node) { // Perform AABB-AABB overlap test if(!AABBAABBOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; TEST_BOX_IN_AABB(node->mAABB.mCenter, node->mAABB.mExtents) if(node->IsLeaf()) { AABB_PRIM(node->GetPrimitive(), OPC_CONTACT) } else { _Collide(node->GetPos()); if(ContactFound()) return; _Collide(node->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for normal AABB trees, without primitive tests. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void AABBCollider::_CollideNoPrimitiveTest(const AABBCollisionNode* node) { // Perform AABB-AABB overlap test if(!AABBAABBOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; TEST_BOX_IN_AABB(node->mAABB.mCenter, node->mAABB.mExtents) if(node->IsLeaf()) { SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) } else { _CollideNoPrimitiveTest(node->GetPos()); if(ContactFound()) return; _CollideNoPrimitiveTest(node->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for quantized AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void AABBCollider::_Collide(const AABBQuantizedNode* node) { // Dequantize box const QuantizedAABB& Box = node->mAABB; const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); // Perform AABB-AABB overlap test if(!AABBAABBOverlap(Extents, Center)) return; TEST_BOX_IN_AABB(Center, Extents) if(node->IsLeaf()) { AABB_PRIM(node->GetPrimitive(), OPC_CONTACT) } else { _Collide(node->GetPos()); if(ContactFound()) return; _Collide(node->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for quantized AABB trees, without primitive tests. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void AABBCollider::_CollideNoPrimitiveTest(const AABBQuantizedNode* node) { // Dequantize box const QuantizedAABB& Box = node->mAABB; const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); // Perform AABB-AABB overlap test if(!AABBAABBOverlap(Extents, Center)) return; TEST_BOX_IN_AABB(Center, Extents) if(node->IsLeaf()) { SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) } else { _CollideNoPrimitiveTest(node->GetPos()); if(ContactFound()) return; _CollideNoPrimitiveTest(node->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for no-leaf AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void AABBCollider::_Collide(const AABBNoLeafNode* node) { // Perform AABB-AABB overlap test if(!AABBAABBOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; TEST_BOX_IN_AABB(node->mAABB.mCenter, node->mAABB.mExtents) if(node->HasPosLeaf()) { AABB_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } else _Collide(node->GetPos()); if(ContactFound()) return; if(node->HasNegLeaf()) { AABB_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } else _Collide(node->GetNeg()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for no-leaf AABB trees, without primitive tests. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void AABBCollider::_CollideNoPrimitiveTest(const AABBNoLeafNode* node) { // Perform AABB-AABB overlap test if(!AABBAABBOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; TEST_BOX_IN_AABB(node->mAABB.mCenter, node->mAABB.mExtents) if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } else _CollideNoPrimitiveTest(node->GetPos()); if(ContactFound()) return; if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } else _CollideNoPrimitiveTest(node->GetNeg()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for quantized no-leaf AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void AABBCollider::_Collide(const AABBQuantizedNoLeafNode* node) { // Dequantize box const QuantizedAABB& Box = node->mAABB; const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); // Perform AABB-AABB overlap test if(!AABBAABBOverlap(Extents, Center)) return; TEST_BOX_IN_AABB(Center, Extents) if(node->HasPosLeaf()) { AABB_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } else _Collide(node->GetPos()); if(ContactFound()) return; if(node->HasNegLeaf()) { AABB_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } else _Collide(node->GetNeg()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for quantized no-leaf AABB trees, without primitive tests. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void AABBCollider::_CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node) { // Dequantize box const QuantizedAABB& Box = node->mAABB; const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); // Perform AABB-AABB overlap test if(!AABBAABBOverlap(Extents, Center)) return; TEST_BOX_IN_AABB(Center, Extents) if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } else _CollideNoPrimitiveTest(node->GetPos()); if(ContactFound()) return; if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } else _CollideNoPrimitiveTest(node->GetNeg()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for vanilla AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void AABBCollider::_Collide(const AABBTreeNode* node) { // Perform AABB-AABB overlap test Point Center, Extents; node->GetAABB()->GetCenter(Center); node->GetAABB()->GetExtents(Extents); if(!AABBAABBOverlap(Center, Extents)) return; if(node->IsLeaf() || AABBContainsBox(Center, Extents)) { mFlags |= OPC_CONTACT; mTouchedPrimitives->Add(node->GetPrimitives(), node->GetNbPrimitives()); } else { _Collide(node->GetPos()); _Collide(node->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// HybridAABBCollider::HybridAABBCollider() { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Destructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// HybridAABBCollider::~HybridAABBCollider() { } bool HybridAABBCollider::Collide(AABBCache& cache, const CollisionAABB& box, const HybridModel& model) { // We don't want primitive tests here! mFlags |= OPC_NO_PRIMITIVE_TESTS; // Checkings if(!Setup(&model)) return false; // Init collision query if(InitQuery(cache, box)) return true; // Special case for 1-leaf trees if(mCurrentModel && mCurrentModel->HasSingleNode()) { // Here we're supposed to perform a normal query, except our tree has a single node, i.e. just a few triangles udword Nb = mIMesh->GetNbTriangles(); // Loop through all triangles for(udword i=0;imCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes()); } else { const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes()); } } else { if(model.IsQuantized()) { const AABBQuantizedTree* Tree = (const AABBQuantizedTree*)model.GetTree(); // Setup dequantization coeffs mCenterCoeff = Tree->mCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes()); } else { const AABBCollisionTree* Tree = (const AABBCollisionTree*)model.GetTree(); // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes()); } } // We only have a list of boxes so far if(GetContactStatus()) { // Reset contact status, since it currently only reflects collisions with leaf boxes Collider::InitQuery(); // Change dest container so that we can use built-in overlap tests and get collided primitives cache.TouchedPrimitives.Reset(); mTouchedPrimitives = &cache.TouchedPrimitives; // Read touched leaf boxes udword Nb = mTouchedBoxes.GetNbEntries(); const udword* Touched = mTouchedBoxes.GetEntries(); const LeafTriangles* LT = model.GetLeafTriangles(); const udword* Indices = model.GetIndices(); // Loop through touched leaves while(Nb--) { const LeafTriangles& CurrentLeaf = LT[*Touched++]; // Each leaf box has a set of triangles udword NbTris = CurrentLeaf.GetNbTriangles(); if(Indices) { const udword* T = &Indices[CurrentLeaf.GetTriangleIndex()]; // Loop through triangles and test each of them while(NbTris--) { udword TriangleIndex = *T++; AABB_PRIM(TriangleIndex, OPC_CONTACT) } } else { udword BaseIndex = CurrentLeaf.GetTriangleIndex(); // Loop through triangles and test each of them while(NbTris--) { udword TriangleIndex = BaseIndex++; AABB_PRIM(TriangleIndex, OPC_CONTACT) } } } } return true; } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_TreeBuilders.cpp0000600000175000017500000002732612161402010024125 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for tree builders. * \file OPC_TreeBuilders.cpp * \author Pierre Terdiman * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * A builder for AABB-trees of vertices. * * \class AABBTreeOfVerticesBuilder * \author Pierre Terdiman * \version 1.3 * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * A builder for AABB-trees of AABBs. * * \class AABBTreeOfAABBsBuilder * \author Pierre Terdiman * \version 1.3 * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * A builder for AABB-trees of triangles. * * \class AABBTreeOfTrianglesBuilder * \author Pierre Terdiman * \version 1.3 * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace Opcode; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the AABB of a set of primitives. * \param primitives [in] list of indices of primitives * \param nb_prims [in] number of indices * \param global_box [out] global AABB enclosing the set of input primitives * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool AABBTreeOfAABBsBuilder::ComputeGlobalBox(const dTriIndex* primitives, udword nb_prims, AABB& global_box) const { // Checkings if(!primitives || !nb_prims) return false; // Initialize global box global_box = mAABBArray[primitives[0]]; // Loop through boxes for(udword i=1;iGetTriangle(VP, *primitives++, VC); // Update global box Min.Min(*VP.Vertex[0]).Min(*VP.Vertex[1]).Min(*VP.Vertex[2]); Max.Max(*VP.Vertex[0]).Max(*VP.Vertex[1]).Max(*VP.Vertex[2]); } global_box.SetMinMax(Min, Max); return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the splitting value along a given axis for a given primitive. * \param index [in] index of the primitive to split * \param axis [in] axis index (0,1,2) * \return splitting value */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// float AABBTreeOfTrianglesBuilder::GetSplittingValue(udword index, udword axis) const { /* // Compute center of triangle Point Center; mTriList[index].Center(mVerts, Center); // Return value return Center[axis];*/ // Compute correct component from center of triangle // return (mVerts[mTriList[index].mVRef[0]][axis] // +mVerts[mTriList[index].mVRef[1]][axis] // +mVerts[mTriList[index].mVRef[2]][axis])*INV3; VertexPointers VP; ConversionArea VC; mIMesh->GetTriangle(VP, index, VC); // Compute correct component from center of triangle return ((*VP.Vertex[0])[axis] +(*VP.Vertex[1])[axis] +(*VP.Vertex[2])[axis])*INV3; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the splitting value along a given axis for a given node. * \param primitives [in] list of indices of primitives * \param nb_prims [in] number of indices * \param global_box [in] global AABB enclosing the set of input primitives * \param axis [in] axis index (0,1,2) * \return splitting value */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// float AABBTreeOfTrianglesBuilder::GetSplittingValue(const dTriIndex* primitives, udword nb_prims, const AABB& global_box, udword axis) const { if(mSettings.mRules&SPLIT_GEOM_CENTER) { // Loop through triangles float SplitValue = 0.0f; VertexPointers VP; ConversionArea VC; for(udword i=0;iGetTriangle(VP, primitives[i], VC); // Update split value SplitValue += (*VP.Vertex[0])[axis]; SplitValue += (*VP.Vertex[1])[axis]; SplitValue += (*VP.Vertex[2])[axis]; } return SplitValue / float(nb_prims*3); } else return AABBTreeBuilder::GetSplittingValue(primitives, nb_prims, global_box, axis); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the AABB of a set of primitives. * \param primitives [in] list of indices of primitives * \param nb_prims [in] number of indices * \param global_box [out] global AABB enclosing the set of input primitives * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool AABBTreeOfVerticesBuilder::ComputeGlobalBox(const dTriIndex* primitives, udword nb_prims, AABB& global_box) const { // Checkings if(!primitives || !nb_prims) return false; // Initialize global box global_box.SetEmpty(); // Loop through vertices for(udword i=0;i>2; } inline_ const CollisionFace* GetFaces() const { return (const CollisionFace*)GetEntries(); } inline_ void Reset() { Container::Reset(); } inline_ void AddFace(const CollisionFace& face) { Add(face.mFaceID).Add(face.mDistance).Add(face.mU).Add(face.mV); } }; #ifdef OPC_RAYHIT_CALLBACK /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * User-callback, called by OPCODE to record a hit. * \param hit [in] current hit * \param user_data [in] user-defined data from SetCallback() */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// typedef void (*HitCallback) (const CollisionFace& hit, void* user_data); #endif class OPCODE_API RayCollider : public Collider { public: // Constructor / Destructor RayCollider(); virtual ~RayCollider(); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Generic stabbing query for generic OPCODE models. After the call, access the results: * - with GetContactStatus() * - in the user-provided destination array * * \param world_ray [in] stabbing ray in world space * \param model [in] Opcode model to collide with * \param world [in] model's world matrix, or null * \param cache [in] a possibly cached face index, or null * \return true if success * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool Collide(const Ray& world_ray, const Model& model, const Matrix4x4* world=null, udword* cache=null); // bool Collide(const Ray& world_ray, const AABBTree* tree, Container& box_indices); // Settings #ifndef OPC_RAYHIT_CALLBACK /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Settings: enable or disable "closest hit" mode. * \param flag [in] true to report closest hit only * \see SetCulling(bool flag) * \see SetMaxDist(float max_dist) * \see SetDestination(StabbedFaces* sf) */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void SetClosestHit(bool flag) { mClosestHit = flag; } #endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Settings: enable or disable backface culling. * \param flag [in] true to enable backface culling * \see SetClosestHit(bool flag) * \see SetMaxDist(float max_dist) * \see SetDestination(StabbedFaces* sf) */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void SetCulling(bool flag) { mCulling = flag; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Settings: sets the higher distance bound. * \param max_dist [in] higher distance bound. Default = maximal value, for ray queries (else segment) * \see SetClosestHit(bool flag) * \see SetCulling(bool flag) * \see SetDestination(StabbedFaces* sf) */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void SetMaxDist(float max_dist=MAX_FLOAT) { mMaxDist = max_dist; } #ifdef OPC_RAYHIT_CALLBACK inline_ void SetHitCallback(HitCallback cb) { mHitCallback = cb; } inline_ void SetUserData(void* user_data) { mUserData = user_data; } #else /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Settings: sets the destination array for stabbed faces. * \param cf [in] destination array, filled during queries * \see SetClosestHit(bool flag) * \see SetCulling(bool flag) * \see SetMaxDist(float max_dist) */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void SetDestination(CollisionFaces* cf) { mStabbedFaces = cf; } #endif // Stats /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Stats: gets the number of Ray-BV overlap tests after a collision query. * \see GetNbRayPrimTests() * \see GetNbIntersections() * \return the number of Ray-BV tests performed during last query */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ udword GetNbRayBVTests() const { return mNbRayBVTests; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Stats: gets the number of Ray-Triangle overlap tests after a collision query. * \see GetNbRayBVTests() * \see GetNbIntersections() * \return the number of Ray-Triangle tests performed during last query */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ udword GetNbRayPrimTests() const { return mNbRayPrimTests; } // In-out test /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Stats: gets the number of intersection found after a collision query. Can be used for in/out tests. * \see GetNbRayBVTests() * \see GetNbRayPrimTests() * \return the number of valid intersections during last query */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ udword GetNbIntersections() const { return mNbIntersections; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Validates current settings. You should call this method after all the settings and callbacks have been defined for a collider. * \return null if everything is ok, else a string describing the problem */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// override(Collider) const char* ValidateSettings(); protected: // Ray in local space Point mOrigin; //!< Ray origin Point mDir; //!< Ray direction (normalized) Point mFDir; //!< fabsf(mDir) Point mData, mData2; // Stabbed faces CollisionFace mStabbedFace; //!< Current stabbed face #ifdef OPC_RAYHIT_CALLBACK HitCallback mHitCallback; //!< Callback used to record a hit void* mUserData; //!< User-defined data #else CollisionFaces* mStabbedFaces; //!< List of stabbed faces bool mClosestHit; //!< Report closest hit only #endif // Stats udword mNbRayBVTests; //!< Number of Ray-BV tests udword mNbRayPrimTests; //!< Number of Ray-Primitive tests // In-out test udword mNbIntersections; //!< Number of valid intersections // Dequantization coeffs Point mCenterCoeff; Point mExtentsCoeff; // Settings float mMaxDist; //!< Valid segment on the ray bool mCulling; //!< Stab culled faces or not // Internal methods void _SegmentStab(const AABBCollisionNode* node); void _SegmentStab(const AABBNoLeafNode* node); void _SegmentStab(const AABBQuantizedNode* node); void _SegmentStab(const AABBQuantizedNoLeafNode* node); void _SegmentStab(const AABBTreeNode* node, Container& box_indices); void _RayStab(const AABBCollisionNode* node); void _RayStab(const AABBNoLeafNode* node); void _RayStab(const AABBQuantizedNode* node); void _RayStab(const AABBQuantizedNoLeafNode* node); void _RayStab(const AABBTreeNode* node, Container& box_indices); // Overlap tests inline_ BOOL RayAABBOverlap(const Point& center, const Point& extents); inline_ BOOL SegmentAABBOverlap(const Point& center, const Point& extents); inline_ BOOL RayTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2); // Init methods BOOL InitQuery(const Ray& world_ray, const Matrix4x4* world=null, udword* face_id=null); }; #endif // __OPC_RAYCOLLIDER_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_SphereCollider.h0000600000175000017500000001130112161402010024067 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for a sphere collider. * \file OPC_SphereCollider.h * \author Pierre Terdiman * \date June, 2, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __OPC_SPHERECOLLIDER_H__ #define __OPC_SPHERECOLLIDER_H__ struct OPCODE_API SphereCache : VolumeCache { SphereCache() : Center(0.0f,0.0f,0.0f), FatRadius2(0.0f), FatCoeff(1.1f) {} ~SphereCache() {} // Cached faces signature Point Center; //!< Sphere used when performing the query resulting in cached faces float FatRadius2; //!< Sphere used when performing the query resulting in cached faces // User settings float FatCoeff; //!< mRadius2 multiplier used to create a fat sphere }; class OPCODE_API SphereCollider : public VolumeCollider { public: // Constructor / Destructor SphereCollider(); virtual ~SphereCollider(); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Generic collision query for generic OPCODE models. After the call, access the results: * - with GetContactStatus() * - with GetNbTouchedPrimitives() * - with GetTouchedPrimitives() * * \param cache [in/out] a sphere cache * \param sphere [in] collision sphere in local space * \param model [in] Opcode model to collide with * \param worlds [in] sphere's world matrix, or null * \param worldm [in] model's world matrix, or null * \return true if success * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool Collide(SphereCache& cache, const Sphere& sphere, const Model& model, const Matrix4x4* worlds=null, const Matrix4x4* worldm=null); // bool Collide(SphereCache& cache, const Sphere& sphere, const AABBTree* tree); protected: // Sphere in model space Point mCenter; //!< Sphere center float mRadius2; //!< Sphere radius squared // Internal methods void _Collide(const AABBCollisionNode* node); void _Collide(const AABBNoLeafNode* node); void _Collide(const AABBQuantizedNode* node); void _Collide(const AABBQuantizedNoLeafNode* node); void _Collide(const AABBTreeNode* node); void _CollideNoPrimitiveTest(const AABBCollisionNode* node); void _CollideNoPrimitiveTest(const AABBNoLeafNode* node); void _CollideNoPrimitiveTest(const AABBQuantizedNode* node); void _CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node); // Overlap tests inline_ BOOL SphereContainsBox(const Point& bc, const Point& be); inline_ BOOL SphereAABBOverlap(const Point& center, const Point& extents); BOOL SphereTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2); // Init methods BOOL InitQuery(SphereCache& cache, const Sphere& sphere, const Matrix4x4* worlds=null, const Matrix4x4* worldm=null); }; class OPCODE_API HybridSphereCollider : public SphereCollider { public: // Constructor / Destructor HybridSphereCollider(); virtual ~HybridSphereCollider(); bool Collide(SphereCache& cache, const Sphere& sphere, const HybridModel& model, const Matrix4x4* worlds=null, const Matrix4x4* worldm=null); protected: Container mTouchedBoxes; }; #endif // __OPC_SPHERECOLLIDER_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_TreeCollider.cpp0000600000175000017500000011336112161402010024104 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for a tree collider. * \file OPC_TreeCollider.cpp * \author Pierre Terdiman * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains an AABB tree collider. * This class performs a collision test between two AABB trees. * * \class AABBTreeCollider * \author Pierre Terdiman * \version 1.3 * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace Opcode; #include "OPC_BoxBoxOverlap.h" #include "OPC_TriBoxOverlap.h" #include "OPC_TriTriOverlap.h" /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// AABBTreeCollider::AABBTreeCollider() : mIMesh0 (null), mIMesh1 (null), mNbBVBVTests (0), mNbPrimPrimTests (0), mNbBVPrimTests (0), mFullBoxBoxTest (true), mFullPrimBoxTest (true) { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Destructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// AABBTreeCollider::~AABBTreeCollider() { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Validates current settings. You should call this method after all the settings and callbacks have been defined. * \return null if everything is ok, else a string describing the problem */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const char* AABBTreeCollider::ValidateSettings() { if(TemporalCoherenceEnabled() && !FirstContactEnabled()) return "Temporal coherence only works with ""First contact"" mode!"; return null; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Generic collision query for generic OPCODE models. After the call, access the results with: * - GetContactStatus() * - GetNbPairs() * - GetPairs() * * \param cache [in] collision cache for model pointers and a colliding pair of primitives * \param world0 [in] world matrix for first object * \param world1 [in] world matrix for second object * \return true if success * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool AABBTreeCollider::Collide(BVTCache& cache, const Matrix4x4* world0, const Matrix4x4* world1) { // Checkings if(!cache.Model0 || !cache.Model1) return false; if(cache.Model0->HasLeafNodes()!=cache.Model1->HasLeafNodes()) return false; if(cache.Model0->IsQuantized()!=cache.Model1->IsQuantized()) return false; /* Rules: - perform hull test - when hulls collide, disable hull test - if meshes overlap, reset countdown - if countdown reaches 0, enable hull test */ #ifdef __MESHMERIZER_H__ // Handle hulls if(cache.HullTest) { if(cache.Model0->GetHull() && cache.Model1->GetHull()) { struct Local { static Point* SVCallback(const Point& sv, udword& previndex, udword user_data) { CollisionHull* Hull = (CollisionHull*)user_data; previndex = Hull->ComputeSupportingVertex(sv, previndex); return (Point*)&Hull->GetVerts()[previndex]; } }; bool Collide; if(0) { static GJKEngine GJK; -- not thread safe, store in ThreadLocalData static bool GJKInitDone=false; -- not thread safe, to be removed if(!GJKInitDone) { GJK.Enable(GJK_BACKUP_PROCEDURE); GJK.Enable(GJK_DEGENERATE); GJK.Enable(GJK_HILLCLIMBING); GJKInitDone = true; } GJK.SetCallbackObj0(Local::SVCallback); GJK.SetCallbackObj1(Local::SVCallback); GJK.SetUserData0(udword(cache.Model0->GetHull())); GJK.SetUserData1(udword(cache.Model1->GetHull())); Collide = GJK.Collide(*world0, *world1, &cache.SepVector); } else { static SVEngine SVE; -- not thread safe, store in ThreadLocalData SVE.SetCallbackObj0(Local::SVCallback); SVE.SetCallbackObj1(Local::SVCallback); SVE.SetUserData0(udword(cache.Model0->GetHull())); SVE.SetUserData1(udword(cache.Model1->GetHull())); Collide = SVE.Collide(*world0, *world1, &cache.SepVector); } if(!Collide) { // Reset stats & contact status mFlags &= ~OPC_CONTACT; mNbBVBVTests = 0; mNbPrimPrimTests = 0; mNbBVPrimTests = 0; mPairs.Reset(); return true; } } } // Here, hulls collide cache.HullTest = false; #endif // __MESHMERIZER_H__ // Checkings if(!Setup(cache.Model0->GetMeshInterface(), cache.Model1->GetMeshInterface())) return false; // Simple double-dispatch bool Status; if(!cache.Model0->HasLeafNodes()) { if(cache.Model0->IsQuantized()) { const AABBQuantizedNoLeafTree* T0 = (const AABBQuantizedNoLeafTree*)cache.Model0->GetTree(); const AABBQuantizedNoLeafTree* T1 = (const AABBQuantizedNoLeafTree*)cache.Model1->GetTree(); Status = Collide(T0, T1, world0, world1, &cache); } else { const AABBNoLeafTree* T0 = (const AABBNoLeafTree*)cache.Model0->GetTree(); const AABBNoLeafTree* T1 = (const AABBNoLeafTree*)cache.Model1->GetTree(); Status = Collide(T0, T1, world0, world1, &cache); } } else { if(cache.Model0->IsQuantized()) { const AABBQuantizedTree* T0 = (const AABBQuantizedTree*)cache.Model0->GetTree(); const AABBQuantizedTree* T1 = (const AABBQuantizedTree*)cache.Model1->GetTree(); Status = Collide(T0, T1, world0, world1, &cache); } else { const AABBCollisionTree* T0 = (const AABBCollisionTree*)cache.Model0->GetTree(); const AABBCollisionTree* T1 = (const AABBCollisionTree*)cache.Model1->GetTree(); Status = Collide(T0, T1, world0, world1, &cache); } } #ifdef __MESHMERIZER_H__ if(Status) { // Reset counter as long as overlap occurs if(GetContactStatus()) cache.ResetCountDown(); // Enable hull test again when counter reaches zero cache.CountDown--; if(!cache.CountDown) { cache.ResetCountDown(); cache.HullTest = true; } } #endif return Status; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Initializes a collision query : * - reset stats & contact status * - setup matrices * * \param world0 [in] world matrix for first object * \param world1 [in] world matrix for second object * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void AABBTreeCollider::InitQuery(const Matrix4x4* world0, const Matrix4x4* world1) { // Reset stats & contact status Collider::InitQuery(); mNbBVBVTests = 0; mNbPrimPrimTests = 0; mNbBVPrimTests = 0; mPairs.Reset(); // Setup matrices Matrix4x4 InvWorld0, InvWorld1; if(world0) InvertPRMatrix(InvWorld0, *world0); else InvWorld0.Identity(); if(world1) InvertPRMatrix(InvWorld1, *world1); else InvWorld1.Identity(); Matrix4x4 World0to1 = world0 ? (*world0 * InvWorld1) : InvWorld1; Matrix4x4 World1to0 = world1 ? (*world1 * InvWorld0) : InvWorld0; mR0to1 = World0to1; World0to1.GetTrans(mT0to1); mR1to0 = World1to0; World1to0.GetTrans(mT1to0); // Precompute absolute 1-to-0 rotation matrix for(udword i=0;i<3;i++) { for(udword j=0;j<3;j++) { // Epsilon value prevents floating-point inaccuracies (strategy borrowed from RAPID) mAR.m[i][j] = 1e-6f + fabsf(mR1to0.m[i][j]); } } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Takes advantage of temporal coherence. * \param cache [in] cache for a pair of previously colliding primitives * \return true if we can return immediately * \warning only works for "First Contact" mode */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool AABBTreeCollider::CheckTemporalCoherence(Pair* cache) { // Checkings if(!cache) return false; // Test previously colliding primitives first if(TemporalCoherenceEnabled() && FirstContactEnabled()) { PrimTest(cache->id0, cache->id1); if(GetContactStatus()) return true; } return false; } #define UPDATE_CACHE \ if(cache && GetContactStatus()) \ { \ cache->id0 = mPairs.GetEntry(0); \ cache->id1 = mPairs.GetEntry(1); \ } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Collision query for normal AABB trees. * \param tree0 [in] AABB tree from first object * \param tree1 [in] AABB tree from second object * \param world0 [in] world matrix for first object * \param world1 [in] world matrix for second object * \param cache [in/out] cache for a pair of previously colliding primitives * \return true if success * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool AABBTreeCollider::Collide(const AABBCollisionTree* tree0, const AABBCollisionTree* tree1, const Matrix4x4* world0, const Matrix4x4* world1, Pair* cache) { // Init collision query InitQuery(world0, world1); // Check previous state if(CheckTemporalCoherence(cache)) return true; // Perform collision query _Collide(tree0->GetNodes(), tree1->GetNodes()); UPDATE_CACHE return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Collision query for no-leaf AABB trees. * \param tree0 [in] AABB tree from first object * \param tree1 [in] AABB tree from second object * \param world0 [in] world matrix for first object * \param world1 [in] world matrix for second object * \param cache [in/out] cache for a pair of previously colliding primitives * \return true if success * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool AABBTreeCollider::Collide(const AABBNoLeafTree* tree0, const AABBNoLeafTree* tree1, const Matrix4x4* world0, const Matrix4x4* world1, Pair* cache) { // Init collision query InitQuery(world0, world1); // Check previous state if(CheckTemporalCoherence(cache)) return true; // Perform collision query _Collide(tree0->GetNodes(), tree1->GetNodes()); UPDATE_CACHE return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Collision query for quantized AABB trees. * \param tree0 [in] AABB tree from first object * \param tree1 [in] AABB tree from second object * \param world0 [in] world matrix for first object * \param world1 [in] world matrix for second object * \param cache [in/out] cache for a pair of previously colliding primitives * \return true if success * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool AABBTreeCollider::Collide(const AABBQuantizedTree* tree0, const AABBQuantizedTree* tree1, const Matrix4x4* world0, const Matrix4x4* world1, Pair* cache) { // Init collision query InitQuery(world0, world1); // Check previous state if(CheckTemporalCoherence(cache)) return true; // Setup dequantization coeffs mCenterCoeff0 = tree0->mCenterCoeff; mExtentsCoeff0 = tree0->mExtentsCoeff; mCenterCoeff1 = tree1->mCenterCoeff; mExtentsCoeff1 = tree1->mExtentsCoeff; // Dequantize box A const AABBQuantizedNode* N0 = tree0->GetNodes(); const Point a(float(N0->mAABB.mExtents[0]) * mExtentsCoeff0.x, float(N0->mAABB.mExtents[1]) * mExtentsCoeff0.y, float(N0->mAABB.mExtents[2]) * mExtentsCoeff0.z); const Point Pa(float(N0->mAABB.mCenter[0]) * mCenterCoeff0.x, float(N0->mAABB.mCenter[1]) * mCenterCoeff0.y, float(N0->mAABB.mCenter[2]) * mCenterCoeff0.z); // Dequantize box B const AABBQuantizedNode* N1 = tree1->GetNodes(); const Point b(float(N1->mAABB.mExtents[0]) * mExtentsCoeff1.x, float(N1->mAABB.mExtents[1]) * mExtentsCoeff1.y, float(N1->mAABB.mExtents[2]) * mExtentsCoeff1.z); const Point Pb(float(N1->mAABB.mCenter[0]) * mCenterCoeff1.x, float(N1->mAABB.mCenter[1]) * mCenterCoeff1.y, float(N1->mAABB.mCenter[2]) * mCenterCoeff1.z); // Perform collision query _Collide(N0, N1, a, Pa, b, Pb); UPDATE_CACHE return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Collision query for quantized no-leaf AABB trees. * \param tree0 [in] AABB tree from first object * \param tree1 [in] AABB tree from second object * \param world0 [in] world matrix for first object * \param world1 [in] world matrix for second object * \param cache [in/out] cache for a pair of previously colliding primitives * \return true if success * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool AABBTreeCollider::Collide(const AABBQuantizedNoLeafTree* tree0, const AABBQuantizedNoLeafTree* tree1, const Matrix4x4* world0, const Matrix4x4* world1, Pair* cache) { // Init collision query InitQuery(world0, world1); // Check previous state if(CheckTemporalCoherence(cache)) return true; // Setup dequantization coeffs mCenterCoeff0 = tree0->mCenterCoeff; mExtentsCoeff0 = tree0->mExtentsCoeff; mCenterCoeff1 = tree1->mCenterCoeff; mExtentsCoeff1 = tree1->mExtentsCoeff; // Perform collision query _Collide(tree0->GetNodes(), tree1->GetNodes()); UPDATE_CACHE return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Standard trees /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // The normal AABB tree can use 2 different descent rules (with different performances) //#define ORIGINAL_CODE //!< UNC-like descent rules #define ALTERNATIVE_CODE //!< Alternative descent rules #ifdef ORIGINAL_CODE /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for normal AABB trees. * \param b0 [in] collision node from first tree * \param b1 [in] collision node from second tree */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void AABBTreeCollider::_Collide(const AABBCollisionNode* b0, const AABBCollisionNode* b1) { // Perform BV-BV overlap test if(!BoxBoxOverlap(b0->mAABB.mExtents, b0->mAABB.mCenter, b1->mAABB.mExtents, b1->mAABB.mCenter)) return; if(b0->IsLeaf() && b1->IsLeaf()) { PrimTest(b0->GetPrimitive(), b1->GetPrimitive()); return; } if(b1->IsLeaf() || (!b0->IsLeaf() && (b0->GetSize() > b1->GetSize()))) { _Collide(b0->GetNeg(), b1); if(ContactFound()) return; _Collide(b0->GetPos(), b1); } else { _Collide(b0, b1->GetNeg()); if(ContactFound()) return; _Collide(b0, b1->GetPos()); } } #endif #ifdef ALTERNATIVE_CODE /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for normal AABB trees. * \param b0 [in] collision node from first tree * \param b1 [in] collision node from second tree */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void AABBTreeCollider::_Collide(const AABBCollisionNode* b0, const AABBCollisionNode* b1) { // Perform BV-BV overlap test if(!BoxBoxOverlap(b0->mAABB.mExtents, b0->mAABB.mCenter, b1->mAABB.mExtents, b1->mAABB.mCenter)) { return; } if(b0->IsLeaf()) { if(b1->IsLeaf()) { PrimTest(b0->GetPrimitive(), b1->GetPrimitive()); } else { _Collide(b0, b1->GetNeg()); if(ContactFound()) return; _Collide(b0, b1->GetPos()); } } else if(b1->IsLeaf()) { _Collide(b0->GetNeg(), b1); if(ContactFound()) return; _Collide(b0->GetPos(), b1); } else { _Collide(b0->GetNeg(), b1->GetNeg()); if(ContactFound()) return; _Collide(b0->GetNeg(), b1->GetPos()); if(ContactFound()) return; _Collide(b0->GetPos(), b1->GetNeg()); if(ContactFound()) return; _Collide(b0->GetPos(), b1->GetPos()); } } #endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // No-leaf trees /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Leaf-leaf test for two primitive indices. * \param id0 [in] index from first leaf-triangle * \param id1 [in] index from second leaf-triangle */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void AABBTreeCollider::PrimTest(udword id0, udword id1) { // Request vertices from the app VertexPointers VP0; VertexPointers VP1; ConversionArea VC0; ConversionArea VC1; mIMesh0->GetTriangle(VP0, id0, VC0); mIMesh1->GetTriangle(VP1, id1, VC1); // Transform from space 1 to space 0 Point u0,u1,u2; TransformPoint(u0, *VP1.Vertex[0], mR1to0, mT1to0); TransformPoint(u1, *VP1.Vertex[1], mR1to0, mT1to0); TransformPoint(u2, *VP1.Vertex[2], mR1to0, mT1to0); // Perform triangle-triangle overlap test if(TriTriOverlap(*VP0.Vertex[0], *VP0.Vertex[1], *VP0.Vertex[2], u0, u1, u2)) { // Keep track of colliding pairs mPairs.Add(id0).Add(id1); // Set contact status mFlags |= OPC_CONTACT; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Leaf-leaf test for a previously fetched triangle from tree A (in B's space) and a new leaf from B. * \param id1 [in] leaf-triangle index from tree B */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void AABBTreeCollider::PrimTestTriIndex(udword id1) { // Request vertices from the app VertexPointers VP; ConversionArea VC; mIMesh1->GetTriangle(VP, id1, VC); // Perform triangle-triangle overlap test if(TriTriOverlap(mLeafVerts[0], mLeafVerts[1], mLeafVerts[2], *VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2])) { // Keep track of colliding pairs mPairs.Add(mLeafIndex).Add(id1); // Set contact status mFlags |= OPC_CONTACT; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Leaf-leaf test for a previously fetched triangle from tree B (in A's space) and a new leaf from A. * \param id0 [in] leaf-triangle index from tree A */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void AABBTreeCollider::PrimTestIndexTri(udword id0) { // Request vertices from the app VertexPointers VP; ConversionArea VC; mIMesh0->GetTriangle(VP, id0, VC); // Perform triangle-triangle overlap test if(TriTriOverlap(mLeafVerts[0], mLeafVerts[1], mLeafVerts[2], *VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2])) { // Keep track of colliding pairs mPairs.Add(id0).Add(mLeafIndex); // Set contact status mFlags |= OPC_CONTACT; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision of a leaf node from A and a branch from B. * \param b [in] collision node from second tree */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void AABBTreeCollider::_CollideTriBox(const AABBNoLeafNode* b) { // Perform triangle-box overlap test if(!TriBoxOverlap(b->mAABB.mCenter, b->mAABB.mExtents)) return; // Keep same triangle, deal with first child if(b->HasPosLeaf()) PrimTestTriIndex(b->GetPosPrimitive()); else _CollideTriBox(b->GetPos()); if(ContactFound()) return; // Keep same triangle, deal with second child if(b->HasNegLeaf()) PrimTestTriIndex(b->GetNegPrimitive()); else _CollideTriBox(b->GetNeg()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision of a leaf node from B and a branch from A. * \param b [in] collision node from first tree */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void AABBTreeCollider::_CollideBoxTri(const AABBNoLeafNode* b) { // Perform triangle-box overlap test if(!TriBoxOverlap(b->mAABB.mCenter, b->mAABB.mExtents)) return; // Keep same triangle, deal with first child if(b->HasPosLeaf()) PrimTestIndexTri(b->GetPosPrimitive()); else _CollideBoxTri(b->GetPos()); if(ContactFound()) return; // Keep same triangle, deal with second child if(b->HasNegLeaf()) PrimTestIndexTri(b->GetNegPrimitive()); else _CollideBoxTri(b->GetNeg()); } //! Request triangle vertices from the app and transform them #define FETCH_LEAF(prim_index, imesh, rot, trans) \ mLeafIndex = prim_index; \ /* Request vertices from the app */ \ VertexPointers VP; ConversionArea VC; imesh->GetTriangle(VP, prim_index, VC); \ /* Transform them in a common space */ \ TransformPoint(mLeafVerts[0], *VP.Vertex[0], rot, trans); \ TransformPoint(mLeafVerts[1], *VP.Vertex[1], rot, trans); \ TransformPoint(mLeafVerts[2], *VP.Vertex[2], rot, trans); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for no-leaf AABB trees. * \param a [in] collision node from first tree * \param b [in] collision node from second tree */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void AABBTreeCollider::_Collide(const AABBNoLeafNode* a, const AABBNoLeafNode* b) { // Perform BV-BV overlap test if(!BoxBoxOverlap(a->mAABB.mExtents, a->mAABB.mCenter, b->mAABB.mExtents, b->mAABB.mCenter)) return; // Catch leaf status BOOL BHasPosLeaf = b->HasPosLeaf(); BOOL BHasNegLeaf = b->HasNegLeaf(); if(a->HasPosLeaf()) { FETCH_LEAF(a->GetPosPrimitive(), mIMesh0, mR0to1, mT0to1) if(BHasPosLeaf) PrimTestTriIndex(b->GetPosPrimitive()); else _CollideTriBox(b->GetPos()); if(ContactFound()) return; if(BHasNegLeaf) PrimTestTriIndex(b->GetNegPrimitive()); else _CollideTriBox(b->GetNeg()); } else { if(BHasPosLeaf) { FETCH_LEAF(b->GetPosPrimitive(), mIMesh1, mR1to0, mT1to0) _CollideBoxTri(a->GetPos()); } else _Collide(a->GetPos(), b->GetPos()); if(ContactFound()) return; if(BHasNegLeaf) { FETCH_LEAF(b->GetNegPrimitive(), mIMesh1, mR1to0, mT1to0) _CollideBoxTri(a->GetPos()); } else _Collide(a->GetPos(), b->GetNeg()); } if(ContactFound()) return; if(a->HasNegLeaf()) { FETCH_LEAF(a->GetNegPrimitive(), mIMesh0, mR0to1, mT0to1) if(BHasPosLeaf) PrimTestTriIndex(b->GetPosPrimitive()); else _CollideTriBox(b->GetPos()); if(ContactFound()) return; if(BHasNegLeaf) PrimTestTriIndex(b->GetNegPrimitive()); else _CollideTriBox(b->GetNeg()); } else { if(BHasPosLeaf) { // ### That leaf has possibly already been fetched FETCH_LEAF(b->GetPosPrimitive(), mIMesh1, mR1to0, mT1to0) _CollideBoxTri(a->GetNeg()); } else _Collide(a->GetNeg(), b->GetPos()); if(ContactFound()) return; if(BHasNegLeaf) { // ### That leaf has possibly already been fetched FETCH_LEAF(b->GetNegPrimitive(), mIMesh1, mR1to0, mT1to0) _CollideBoxTri(a->GetNeg()); } else _Collide(a->GetNeg(), b->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Quantized trees /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for quantized AABB trees. * \param b0 [in] collision node from first tree * \param b1 [in] collision node from second tree * \param a [in] extent from box A * \param Pa [in] center from box A * \param b [in] extent from box B * \param Pb [in] center from box B */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void AABBTreeCollider::_Collide(const AABBQuantizedNode* b0, const AABBQuantizedNode* b1, const Point& a, const Point& Pa, const Point& b, const Point& Pb) { // Perform BV-BV overlap test if(!BoxBoxOverlap(a, Pa, b, Pb)) return; if(b0->IsLeaf() && b1->IsLeaf()) { PrimTest(b0->GetPrimitive(), b1->GetPrimitive()); return; } if(b1->IsLeaf() || (!b0->IsLeaf() && (b0->GetSize() > b1->GetSize()))) { // Dequantize box const QuantizedAABB* Box = &b0->GetNeg()->mAABB; const Point negPa(float(Box->mCenter[0]) * mCenterCoeff0.x, float(Box->mCenter[1]) * mCenterCoeff0.y, float(Box->mCenter[2]) * mCenterCoeff0.z); const Point nega(float(Box->mExtents[0]) * mExtentsCoeff0.x, float(Box->mExtents[1]) * mExtentsCoeff0.y, float(Box->mExtents[2]) * mExtentsCoeff0.z); _Collide(b0->GetNeg(), b1, nega, negPa, b, Pb); if(ContactFound()) return; // Dequantize box Box = &b0->GetPos()->mAABB; const Point posPa(float(Box->mCenter[0]) * mCenterCoeff0.x, float(Box->mCenter[1]) * mCenterCoeff0.y, float(Box->mCenter[2]) * mCenterCoeff0.z); const Point posa(float(Box->mExtents[0]) * mExtentsCoeff0.x, float(Box->mExtents[1]) * mExtentsCoeff0.y, float(Box->mExtents[2]) * mExtentsCoeff0.z); _Collide(b0->GetPos(), b1, posa, posPa, b, Pb); } else { // Dequantize box const QuantizedAABB* Box = &b1->GetNeg()->mAABB; const Point negPb(float(Box->mCenter[0]) * mCenterCoeff1.x, float(Box->mCenter[1]) * mCenterCoeff1.y, float(Box->mCenter[2]) * mCenterCoeff1.z); const Point negb(float(Box->mExtents[0]) * mExtentsCoeff1.x, float(Box->mExtents[1]) * mExtentsCoeff1.y, float(Box->mExtents[2]) * mExtentsCoeff1.z); _Collide(b0, b1->GetNeg(), a, Pa, negb, negPb); if(ContactFound()) return; // Dequantize box Box = &b1->GetPos()->mAABB; const Point posPb(float(Box->mCenter[0]) * mCenterCoeff1.x, float(Box->mCenter[1]) * mCenterCoeff1.y, float(Box->mCenter[2]) * mCenterCoeff1.z); const Point posb(float(Box->mExtents[0]) * mExtentsCoeff1.x, float(Box->mExtents[1]) * mExtentsCoeff1.y, float(Box->mExtents[2]) * mExtentsCoeff1.z); _Collide(b0, b1->GetPos(), a, Pa, posb, posPb); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Quantized no-leaf trees /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision of a leaf node from A and a quantized branch from B. * \param leaf [in] leaf triangle from first tree * \param b [in] collision node from second tree */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void AABBTreeCollider::_CollideTriBox(const AABBQuantizedNoLeafNode* b) { // Dequantize box const QuantizedAABB* bb = &b->mAABB; const Point Pb(float(bb->mCenter[0]) * mCenterCoeff1.x, float(bb->mCenter[1]) * mCenterCoeff1.y, float(bb->mCenter[2]) * mCenterCoeff1.z); const Point eb(float(bb->mExtents[0]) * mExtentsCoeff1.x, float(bb->mExtents[1]) * mExtentsCoeff1.y, float(bb->mExtents[2]) * mExtentsCoeff1.z); // Perform triangle-box overlap test if(!TriBoxOverlap(Pb, eb)) return; if(b->HasPosLeaf()) PrimTestTriIndex(b->GetPosPrimitive()); else _CollideTriBox(b->GetPos()); if(ContactFound()) return; if(b->HasNegLeaf()) PrimTestTriIndex(b->GetNegPrimitive()); else _CollideTriBox(b->GetNeg()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision of a leaf node from B and a quantized branch from A. * \param b [in] collision node from first tree * \param leaf [in] leaf triangle from second tree */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void AABBTreeCollider::_CollideBoxTri(const AABBQuantizedNoLeafNode* b) { // Dequantize box const QuantizedAABB* bb = &b->mAABB; const Point Pa(float(bb->mCenter[0]) * mCenterCoeff0.x, float(bb->mCenter[1]) * mCenterCoeff0.y, float(bb->mCenter[2]) * mCenterCoeff0.z); const Point ea(float(bb->mExtents[0]) * mExtentsCoeff0.x, float(bb->mExtents[1]) * mExtentsCoeff0.y, float(bb->mExtents[2]) * mExtentsCoeff0.z); // Perform triangle-box overlap test if(!TriBoxOverlap(Pa, ea)) return; if(b->HasPosLeaf()) PrimTestIndexTri(b->GetPosPrimitive()); else _CollideBoxTri(b->GetPos()); if(ContactFound()) return; if(b->HasNegLeaf()) PrimTestIndexTri(b->GetNegPrimitive()); else _CollideBoxTri(b->GetNeg()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for quantized no-leaf AABB trees. * \param a [in] collision node from first tree * \param b [in] collision node from second tree */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void AABBTreeCollider::_Collide(const AABBQuantizedNoLeafNode* a, const AABBQuantizedNoLeafNode* b) { // Dequantize box A const QuantizedAABB* ab = &a->mAABB; const Point Pa(float(ab->mCenter[0]) * mCenterCoeff0.x, float(ab->mCenter[1]) * mCenterCoeff0.y, float(ab->mCenter[2]) * mCenterCoeff0.z); const Point ea(float(ab->mExtents[0]) * mExtentsCoeff0.x, float(ab->mExtents[1]) * mExtentsCoeff0.y, float(ab->mExtents[2]) * mExtentsCoeff0.z); // Dequantize box B const QuantizedAABB* bb = &b->mAABB; const Point Pb(float(bb->mCenter[0]) * mCenterCoeff1.x, float(bb->mCenter[1]) * mCenterCoeff1.y, float(bb->mCenter[2]) * mCenterCoeff1.z); const Point eb(float(bb->mExtents[0]) * mExtentsCoeff1.x, float(bb->mExtents[1]) * mExtentsCoeff1.y, float(bb->mExtents[2]) * mExtentsCoeff1.z); // Perform BV-BV overlap test if(!BoxBoxOverlap(ea, Pa, eb, Pb)) return; // Catch leaf status BOOL BHasPosLeaf = b->HasPosLeaf(); BOOL BHasNegLeaf = b->HasNegLeaf(); if(a->HasPosLeaf()) { FETCH_LEAF(a->GetPosPrimitive(), mIMesh0, mR0to1, mT0to1) if(BHasPosLeaf) PrimTestTriIndex(b->GetPosPrimitive()); else _CollideTriBox(b->GetPos()); if(ContactFound()) return; if(BHasNegLeaf) PrimTestTriIndex(b->GetNegPrimitive()); else _CollideTriBox(b->GetNeg()); } else { if(BHasPosLeaf) { FETCH_LEAF(b->GetPosPrimitive(), mIMesh1, mR1to0, mT1to0) _CollideBoxTri(a->GetPos()); } else _Collide(a->GetPos(), b->GetPos()); if(ContactFound()) return; if(BHasNegLeaf) { FETCH_LEAF(b->GetNegPrimitive(), mIMesh1, mR1to0, mT1to0) _CollideBoxTri(a->GetPos()); } else _Collide(a->GetPos(), b->GetNeg()); } if(ContactFound()) return; if(a->HasNegLeaf()) { FETCH_LEAF(a->GetNegPrimitive(), mIMesh0, mR0to1, mT0to1) if(BHasPosLeaf) PrimTestTriIndex(b->GetPosPrimitive()); else _CollideTriBox(b->GetPos()); if(ContactFound()) return; if(BHasNegLeaf) PrimTestTriIndex(b->GetNegPrimitive()); else _CollideTriBox(b->GetNeg()); } else { if(BHasPosLeaf) { // ### That leaf has possibly already been fetched FETCH_LEAF(b->GetPosPrimitive(), mIMesh1, mR1to0, mT1to0) _CollideBoxTri(a->GetNeg()); } else _Collide(a->GetNeg(), b->GetPos()); if(ContactFound()) return; if(BHasNegLeaf) { // ### That leaf has possibly already been fetched FETCH_LEAF(b->GetNegPrimitive(), mIMesh1, mR1to0, mT1to0) _CollideBoxTri(a->GetNeg()); } else _Collide(a->GetNeg(), b->GetNeg()); } } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_LSSAABBOverlap.h0000600000175000017500000003757012161402010023603 0ustar zero79zero79 // Following code from Magic-Software (http://www.magic-software.com/) // A bit modified for Opcode inline_ float OPC_PointAABBSqrDist(const Point& point, const Point& center, const Point& extents) { // Compute coordinates of point in box coordinate system Point Closest = point - center; float SqrDistance = 0.0f; if(Closest.x < -extents.x) { float Delta = Closest.x + extents.x; SqrDistance += Delta*Delta; } else if(Closest.x > extents.x) { float Delta = Closest.x - extents.x; SqrDistance += Delta*Delta; } if(Closest.y < -extents.y) { float Delta = Closest.y + extents.y; SqrDistance += Delta*Delta; } else if(Closest.y > extents.y) { float Delta = Closest.y - extents.y; SqrDistance += Delta*Delta; } if(Closest.z < -extents.z) { float Delta = Closest.z + extents.z; SqrDistance += Delta*Delta; } else if(Closest.z > extents.z) { float Delta = Closest.z - extents.z; SqrDistance += Delta*Delta; } return SqrDistance; } static void Face(int i0, int i1, int i2, Point& rkPnt, const Point& rkDir, const Point& extents, const Point& rkPmE, float* pfLParam, float& rfSqrDistance) { Point kPpE; float fLSqr, fInv, fTmp, fParam, fT, fDelta; kPpE[i1] = rkPnt[i1] + extents[i1]; kPpE[i2] = rkPnt[i2] + extents[i2]; if(rkDir[i0]*kPpE[i1] >= rkDir[i1]*rkPmE[i0]) { if(rkDir[i0]*kPpE[i2] >= rkDir[i2]*rkPmE[i0]) { // v[i1] >= -e[i1], v[i2] >= -e[i2] (distance = 0) if(pfLParam) { rkPnt[i0] = extents[i0]; fInv = 1.0f/rkDir[i0]; rkPnt[i1] -= rkDir[i1]*rkPmE[i0]*fInv; rkPnt[i2] -= rkDir[i2]*rkPmE[i0]*fInv; *pfLParam = -rkPmE[i0]*fInv; } } else { // v[i1] >= -e[i1], v[i2] < -e[i2] fLSqr = rkDir[i0]*rkDir[i0] + rkDir[i2]*rkDir[i2]; fTmp = fLSqr*kPpE[i1] - rkDir[i1]*(rkDir[i0]*rkPmE[i0] + rkDir[i2]*kPpE[i2]); if(fTmp <= 2.0f*fLSqr*extents[i1]) { fT = fTmp/fLSqr; fLSqr += rkDir[i1]*rkDir[i1]; fTmp = kPpE[i1] - fT; fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*fTmp + rkDir[i2]*kPpE[i2]; fParam = -fDelta/fLSqr; rfSqrDistance += rkPmE[i0]*rkPmE[i0] + fTmp*fTmp + kPpE[i2]*kPpE[i2] + fDelta*fParam; if(pfLParam) { *pfLParam = fParam; rkPnt[i0] = extents[i0]; rkPnt[i1] = fT - extents[i1]; rkPnt[i2] = -extents[i2]; } } else { fLSqr += rkDir[i1]*rkDir[i1]; fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*rkPmE[i1] + rkDir[i2]*kPpE[i2]; fParam = -fDelta/fLSqr; rfSqrDistance += rkPmE[i0]*rkPmE[i0] + rkPmE[i1]*rkPmE[i1] + kPpE[i2]*kPpE[i2] + fDelta*fParam; if(pfLParam) { *pfLParam = fParam; rkPnt[i0] = extents[i0]; rkPnt[i1] = extents[i1]; rkPnt[i2] = -extents[i2]; } } } } else { if ( rkDir[i0]*kPpE[i2] >= rkDir[i2]*rkPmE[i0] ) { // v[i1] < -e[i1], v[i2] >= -e[i2] fLSqr = rkDir[i0]*rkDir[i0] + rkDir[i1]*rkDir[i1]; fTmp = fLSqr*kPpE[i2] - rkDir[i2]*(rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1]); if(fTmp <= 2.0f*fLSqr*extents[i2]) { fT = fTmp/fLSqr; fLSqr += rkDir[i2]*rkDir[i2]; fTmp = kPpE[i2] - fT; fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1] + rkDir[i2]*fTmp; fParam = -fDelta/fLSqr; rfSqrDistance += rkPmE[i0]*rkPmE[i0] + kPpE[i1]*kPpE[i1] + fTmp*fTmp + fDelta*fParam; if(pfLParam) { *pfLParam = fParam; rkPnt[i0] = extents[i0]; rkPnt[i1] = -extents[i1]; rkPnt[i2] = fT - extents[i2]; } } else { fLSqr += rkDir[i2]*rkDir[i2]; fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1] + rkDir[i2]*rkPmE[i2]; fParam = -fDelta/fLSqr; rfSqrDistance += rkPmE[i0]*rkPmE[i0] + kPpE[i1]*kPpE[i1] + rkPmE[i2]*rkPmE[i2] + fDelta*fParam; if(pfLParam) { *pfLParam = fParam; rkPnt[i0] = extents[i0]; rkPnt[i1] = -extents[i1]; rkPnt[i2] = extents[i2]; } } } else { // v[i1] < -e[i1], v[i2] < -e[i2] fLSqr = rkDir[i0]*rkDir[i0]+rkDir[i2]*rkDir[i2]; fTmp = fLSqr*kPpE[i1] - rkDir[i1]*(rkDir[i0]*rkPmE[i0] + rkDir[i2]*kPpE[i2]); if(fTmp >= 0.0f) { // v[i1]-edge is closest if ( fTmp <= 2.0f*fLSqr*extents[i1] ) { fT = fTmp/fLSqr; fLSqr += rkDir[i1]*rkDir[i1]; fTmp = kPpE[i1] - fT; fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*fTmp + rkDir[i2]*kPpE[i2]; fParam = -fDelta/fLSqr; rfSqrDistance += rkPmE[i0]*rkPmE[i0] + fTmp*fTmp + kPpE[i2]*kPpE[i2] + fDelta*fParam; if(pfLParam) { *pfLParam = fParam; rkPnt[i0] = extents[i0]; rkPnt[i1] = fT - extents[i1]; rkPnt[i2] = -extents[i2]; } } else { fLSqr += rkDir[i1]*rkDir[i1]; fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*rkPmE[i1] + rkDir[i2]*kPpE[i2]; fParam = -fDelta/fLSqr; rfSqrDistance += rkPmE[i0]*rkPmE[i0] + rkPmE[i1]*rkPmE[i1] + kPpE[i2]*kPpE[i2] + fDelta*fParam; if(pfLParam) { *pfLParam = fParam; rkPnt[i0] = extents[i0]; rkPnt[i1] = extents[i1]; rkPnt[i2] = -extents[i2]; } } return; } fLSqr = rkDir[i0]*rkDir[i0] + rkDir[i1]*rkDir[i1]; fTmp = fLSqr*kPpE[i2] - rkDir[i2]*(rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1]); if(fTmp >= 0.0f) { // v[i2]-edge is closest if(fTmp <= 2.0f*fLSqr*extents[i2]) { fT = fTmp/fLSqr; fLSqr += rkDir[i2]*rkDir[i2]; fTmp = kPpE[i2] - fT; fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1] + rkDir[i2]*fTmp; fParam = -fDelta/fLSqr; rfSqrDistance += rkPmE[i0]*rkPmE[i0] + kPpE[i1]*kPpE[i1] + fTmp*fTmp + fDelta*fParam; if(pfLParam) { *pfLParam = fParam; rkPnt[i0] = extents[i0]; rkPnt[i1] = -extents[i1]; rkPnt[i2] = fT - extents[i2]; } } else { fLSqr += rkDir[i2]*rkDir[i2]; fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1] + rkDir[i2]*rkPmE[i2]; fParam = -fDelta/fLSqr; rfSqrDistance += rkPmE[i0]*rkPmE[i0] + kPpE[i1]*kPpE[i1] + rkPmE[i2]*rkPmE[i2] + fDelta*fParam; if(pfLParam) { *pfLParam = fParam; rkPnt[i0] = extents[i0]; rkPnt[i1] = -extents[i1]; rkPnt[i2] = extents[i2]; } } return; } // (v[i1],v[i2])-corner is closest fLSqr += rkDir[i2]*rkDir[i2]; fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1] + rkDir[i2]*kPpE[i2]; fParam = -fDelta/fLSqr; rfSqrDistance += rkPmE[i0]*rkPmE[i0] + kPpE[i1]*kPpE[i1] + kPpE[i2]*kPpE[i2] + fDelta*fParam; if(pfLParam) { *pfLParam = fParam; rkPnt[i0] = extents[i0]; rkPnt[i1] = -extents[i1]; rkPnt[i2] = -extents[i2]; } } } } static void CaseNoZeros(Point& rkPnt, const Point& rkDir, const Point& extents, float* pfLParam, float& rfSqrDistance) { Point kPmE(rkPnt.x - extents.x, rkPnt.y - extents.y, rkPnt.z - extents.z); float fProdDxPy, fProdDyPx, fProdDzPx, fProdDxPz, fProdDzPy, fProdDyPz; fProdDxPy = rkDir.x*kPmE.y; fProdDyPx = rkDir.y*kPmE.x; if(fProdDyPx >= fProdDxPy) { fProdDzPx = rkDir.z*kPmE.x; fProdDxPz = rkDir.x*kPmE.z; if(fProdDzPx >= fProdDxPz) { // line intersects x = e0 Face(0, 1, 2, rkPnt, rkDir, extents, kPmE, pfLParam, rfSqrDistance); } else { // line intersects z = e2 Face(2, 0, 1, rkPnt, rkDir, extents, kPmE, pfLParam, rfSqrDistance); } } else { fProdDzPy = rkDir.z*kPmE.y; fProdDyPz = rkDir.y*kPmE.z; if(fProdDzPy >= fProdDyPz) { // line intersects y = e1 Face(1, 2, 0, rkPnt, rkDir, extents, kPmE, pfLParam, rfSqrDistance); } else { // line intersects z = e2 Face(2, 0, 1, rkPnt, rkDir, extents, kPmE, pfLParam, rfSqrDistance); } } } static void Case0(int i0, int i1, int i2, Point& rkPnt, const Point& rkDir, const Point& extents, float* pfLParam, float& rfSqrDistance) { float fPmE0 = rkPnt[i0] - extents[i0]; float fPmE1 = rkPnt[i1] - extents[i1]; float fProd0 = rkDir[i1]*fPmE0; float fProd1 = rkDir[i0]*fPmE1; float fDelta, fInvLSqr, fInv; if(fProd0 >= fProd1) { // line intersects P[i0] = e[i0] rkPnt[i0] = extents[i0]; float fPpE1 = rkPnt[i1] + extents[i1]; fDelta = fProd0 - rkDir[i0]*fPpE1; if(fDelta >= 0.0f) { fInvLSqr = 1.0f/(rkDir[i0]*rkDir[i0] + rkDir[i1]*rkDir[i1]); rfSqrDistance += fDelta*fDelta*fInvLSqr; if(pfLParam) { rkPnt[i1] = -extents[i1]; *pfLParam = -(rkDir[i0]*fPmE0+rkDir[i1]*fPpE1)*fInvLSqr; } } else { if(pfLParam) { fInv = 1.0f/rkDir[i0]; rkPnt[i1] -= fProd0*fInv; *pfLParam = -fPmE0*fInv; } } } else { // line intersects P[i1] = e[i1] rkPnt[i1] = extents[i1]; float fPpE0 = rkPnt[i0] + extents[i0]; fDelta = fProd1 - rkDir[i1]*fPpE0; if(fDelta >= 0.0f) { fInvLSqr = 1.0f/(rkDir[i0]*rkDir[i0] + rkDir[i1]*rkDir[i1]); rfSqrDistance += fDelta*fDelta*fInvLSqr; if(pfLParam) { rkPnt[i0] = -extents[i0]; *pfLParam = -(rkDir[i0]*fPpE0+rkDir[i1]*fPmE1)*fInvLSqr; } } else { if(pfLParam) { fInv = 1.0f/rkDir[i1]; rkPnt[i0] -= fProd1*fInv; *pfLParam = -fPmE1*fInv; } } } if(rkPnt[i2] < -extents[i2]) { fDelta = rkPnt[i2] + extents[i2]; rfSqrDistance += fDelta*fDelta; rkPnt[i2] = -extents[i2]; } else if ( rkPnt[i2] > extents[i2] ) { fDelta = rkPnt[i2] - extents[i2]; rfSqrDistance += fDelta*fDelta; rkPnt[i2] = extents[i2]; } } static void Case00(int i0, int i1, int i2, Point& rkPnt, const Point& rkDir, const Point& extents, float* pfLParam, float& rfSqrDistance) { float fDelta; if(pfLParam) *pfLParam = (extents[i0] - rkPnt[i0])/rkDir[i0]; rkPnt[i0] = extents[i0]; if(rkPnt[i1] < -extents[i1]) { fDelta = rkPnt[i1] + extents[i1]; rfSqrDistance += fDelta*fDelta; rkPnt[i1] = -extents[i1]; } else if(rkPnt[i1] > extents[i1]) { fDelta = rkPnt[i1] - extents[i1]; rfSqrDistance += fDelta*fDelta; rkPnt[i1] = extents[i1]; } if(rkPnt[i2] < -extents[i2]) { fDelta = rkPnt[i2] + extents[i2]; rfSqrDistance += fDelta*fDelta; rkPnt[i1] = -extents[i2]; } else if(rkPnt[i2] > extents[i2]) { fDelta = rkPnt[i2] - extents[i2]; rfSqrDistance += fDelta*fDelta; rkPnt[i2] = extents[i2]; } } static void Case000(Point& rkPnt, const Point& extents, float& rfSqrDistance) { float fDelta; if(rkPnt.x < -extents.x) { fDelta = rkPnt.x + extents.x; rfSqrDistance += fDelta*fDelta; rkPnt.x = -extents.x; } else if(rkPnt.x > extents.x) { fDelta = rkPnt.x - extents.x; rfSqrDistance += fDelta*fDelta; rkPnt.x = extents.x; } if(rkPnt.y < -extents.y) { fDelta = rkPnt.y + extents.y; rfSqrDistance += fDelta*fDelta; rkPnt.y = -extents.y; } else if(rkPnt.y > extents.y) { fDelta = rkPnt.y - extents.y; rfSqrDistance += fDelta*fDelta; rkPnt.y = extents.y; } if(rkPnt.z < -extents.z) { fDelta = rkPnt.z + extents.z; rfSqrDistance += fDelta*fDelta; rkPnt.z = -extents.z; } else if(rkPnt.z > extents.z) { fDelta = rkPnt.z - extents.z; rfSqrDistance += fDelta*fDelta; rkPnt.z = extents.z; } } static float SqrDistance(const Ray& rkLine, const Point& center, const Point& extents, float* pfLParam) { // compute coordinates of line in box coordinate system Point kDiff = rkLine.mOrig - center; Point kPnt = kDiff; Point kDir = rkLine.mDir; // Apply reflections so that direction vector has nonnegative components. bool bReflect[3]; for(int i=0;i<3;i++) { if(kDir[i]<0.0f) { kPnt[i] = -kPnt[i]; kDir[i] = -kDir[i]; bReflect[i] = true; } else { bReflect[i] = false; } } float fSqrDistance = 0.0f; if(kDir.x>0.0f) { if(kDir.y>0.0f) { if(kDir.z>0.0f) CaseNoZeros(kPnt, kDir, extents, pfLParam, fSqrDistance); // (+,+,+) else Case0(0, 1, 2, kPnt, kDir, extents, pfLParam, fSqrDistance); // (+,+,0) } else { if(kDir.z>0.0f) Case0(0, 2, 1, kPnt, kDir, extents, pfLParam, fSqrDistance); // (+,0,+) else Case00(0, 1, 2, kPnt, kDir, extents, pfLParam, fSqrDistance); // (+,0,0) } } else { if(kDir.y>0.0f) { if(kDir.z>0.0f) Case0(1, 2, 0, kPnt, kDir, extents, pfLParam, fSqrDistance); // (0,+,+) else Case00(1, 0, 2, kPnt, kDir, extents, pfLParam, fSqrDistance); // (0,+,0) } else { if(kDir.z>0.0f) Case00(2, 0, 1, kPnt, kDir, extents, pfLParam, fSqrDistance); // (0,0,+) else { Case000(kPnt, extents, fSqrDistance); // (0,0,0) if(pfLParam) *pfLParam = 0.0f; } } } return fSqrDistance; } inline_ float OPC_SegmentOBBSqrDist(const Segment& segment, const Point& c0, const Point& e0) { float fLP; float fSqrDistance = SqrDistance(Ray(segment.GetOrigin(), segment.ComputeDirection()), c0, e0, &fLP); if(fLP>=0.0f) { if(fLP<=1.0f) return fSqrDistance; else return OPC_PointAABBSqrDist(segment.mP1, c0, e0); } else return OPC_PointAABBSqrDist(segment.mP0, c0, e0); } inline_ BOOL LSSCollider::LSSAABBOverlap(const Point& center, const Point& extents) { // Stats mNbVolumeBVTests++; float s2 = OPC_SegmentOBBSqrDist(mSeg, center, extents); if(s2Refit(mIMesh); // Old code kept for reference : refit the source tree then rebuild ! // if(!mSource) return false; // // Ouch... // mSource->Refit(&mTB); // // Ouch... // return mTree->Build(mSource); } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_IceHook.h0000600000175000017500000000274512161402010022520 0ustar zero79zero79 // Should be included by Opcode.h if needed #define ICE_DONT_CHECK_COMPILER_OPTIONS // From Windows... typedef int BOOL; #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif #include #include #include #include #include #include #ifndef ASSERT #define ASSERT(exp) {} #endif #define ICE_COMPILE_TIME_ASSERT(exp) extern char ICE_Dummy[ (exp) ? 1 : -1 ] #define Log {} #define SetIceError(a,b) false #define EC_OUTOFMEMORY "Out of memory" #include "Ice/IcePreprocessor.h" #undef ICECORE_API #define ICECORE_API OPCODE_API #include "Ice/IceTypes.h" #include "Ice/IceFPU.h" #include "Ice/IceMemoryMacros.h" namespace IceCore { #include "Ice/IceUtils.h" #include "Ice/IceContainer.h" #include "Ice/IcePairs.h" #include "Ice/IceRevisitedRadix.h" #include "Ice/IceRandom.h" } using namespace IceCore; #define ICEMATHS_API OPCODE_API namespace IceMaths { #include "Ice/IceAxes.h" #include "Ice/IcePoint.h" #include "Ice/IceHPoint.h" #include "Ice/IceMatrix3x3.h" #include "Ice/IceMatrix4x4.h" #include "Ice/IcePlane.h" #include "Ice/IceRay.h" #include "Ice/IceIndexedTriangle.h" #include "Ice/IceTriangle.h" #include "Ice/IceTriList.h" #include "Ice/IceAABB.h" #include "Ice/IceOBB.h" #include "Ice/IceBoundingSphere.h" #include "Ice/IceSegment.h" #include "Ice/IceLSS.h" } using namespace IceMaths; alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_Collider.h0000600000175000017500000002423512161402010022732 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains base collider class. * \file OPC_Collider.h * \author Pierre Terdiman * \date June, 2, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __OPC_COLLIDER_H__ #define __OPC_COLLIDER_H__ enum CollisionFlag { OPC_FIRST_CONTACT = (1<<0), //!< Report all contacts (false) or only first one (true) OPC_TEMPORAL_COHERENCE = (1<<1), //!< Use temporal coherence or not OPC_CONTACT = (1<<2), //!< Final contact status after a collision query OPC_TEMPORAL_HIT = (1<<3), //!< There has been an early exit due to temporal coherence OPC_NO_PRIMITIVE_TESTS = (1<<4), //!< Keep or discard primitive-bv tests in leaf nodes (volume-mesh queries) OPC_CONTACT_FOUND = OPC_FIRST_CONTACT | OPC_CONTACT, OPC_TEMPORAL_CONTACT = OPC_TEMPORAL_HIT | OPC_CONTACT, OPC_FORCE_DWORD = 0x7fffffff }; class OPCODE_API Collider { public: // Constructor / Destructor Collider(); virtual ~Collider(); // Collision report /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the last collision status after a collision query. * \return true if a collision occured */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL GetContactStatus() const { return mFlags & OPC_CONTACT; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the "first contact" mode. * \return true if "first contact" mode is on */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL FirstContactEnabled() const { return mFlags & OPC_FIRST_CONTACT; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the temporal coherence mode. * \return true if temporal coherence is on */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL TemporalCoherenceEnabled() const { return mFlags & OPC_TEMPORAL_COHERENCE; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks a first contact has already been found. * \return true if a first contact has been found and we can stop a query */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL ContactFound() const { return (mFlags&OPC_CONTACT_FOUND)==OPC_CONTACT_FOUND; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks there's been an early exit due to temporal coherence; * \return true if a temporal hit has occured */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL TemporalHit() const { return mFlags & OPC_TEMPORAL_HIT; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks primitive tests are enabled; * \return true if primitive tests must be skipped */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL SkipPrimitiveTests() const { return mFlags & OPC_NO_PRIMITIVE_TESTS; } // Settings /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Reports all contacts (false) or first contact only (true) * \param flag [in] true for first contact, false for all contacts * \see SetTemporalCoherence(bool flag) * \see ValidateSettings() */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void SetFirstContact(bool flag) { if(flag) mFlags |= OPC_FIRST_CONTACT; else mFlags &= ~OPC_FIRST_CONTACT; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Enable/disable temporal coherence. * \param flag [in] true to enable temporal coherence, false to discard it * \see SetFirstContact(bool flag) * \see ValidateSettings() */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void SetTemporalCoherence(bool flag) { if(flag) mFlags |= OPC_TEMPORAL_COHERENCE; else mFlags &= ~OPC_TEMPORAL_COHERENCE; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Enable/disable primitive tests. * \param flag [in] true to enable primitive tests, false to discard them */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void SetPrimitiveTests(bool flag) { if(!flag) mFlags |= OPC_NO_PRIMITIVE_TESTS; else mFlags &= ~OPC_NO_PRIMITIVE_TESTS; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Validates current settings. You should call this method after all the settings / callbacks have been defined for a collider. * \return null if everything is ok, else a string describing the problem */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// virtual const char* ValidateSettings() = 0; protected: udword mFlags; //!< Bit flags const BaseModel* mCurrentModel; //!< Current model for collision query (owner of touched faces) // User mesh interface const MeshInterface* mIMesh; //!< User-defined mesh interface // Internal methods /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Setups current collision model * \param model [in] current collision model * \return TRUE if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL Setup(const BaseModel* model) { // Keep track of current model mCurrentModel = model; if(!mCurrentModel) return FALSE; mIMesh = model->GetMeshInterface(); return mIMesh!=null; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Initializes a query */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// virtual inline_ void InitQuery() { mFlags &= ~OPC_TEMPORAL_CONTACT; } }; #endif // __OPC_COLLIDER_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_AABBCollider.h0000600000175000017500000001052712161402010023337 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for an AABB collider. * \file OPC_AABBCollider.h * \author Pierre Terdiman * \date January, 1st, 2002 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __OPC_AABBCOLLIDER_H__ #define __OPC_AABBCOLLIDER_H__ struct OPCODE_API AABBCache : VolumeCache { AABBCache() : FatCoeff(1.1f) { FatBox.mCenter.Zero(); FatBox.mExtents.Zero(); } // Cached faces signature CollisionAABB FatBox; //!< Box used when performing the query resulting in cached faces // User settings float FatCoeff; //!< mRadius2 multiplier used to create a fat sphere }; class OPCODE_API AABBCollider : public VolumeCollider { public: // Constructor / Destructor AABBCollider(); virtual ~AABBCollider(); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Generic collision query for generic OPCODE models. After the call, access the results: * - with GetContactStatus() * - with GetNbTouchedPrimitives() * - with GetTouchedPrimitives() * * \param cache [in/out] a box cache * \param box [in] collision AABB in world space * \param model [in] Opcode model to collide with * \return true if success * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool Collide(AABBCache& cache, const CollisionAABB& box, const Model& model); // bool Collide(AABBCache& cache, const CollisionAABB& box, const AABBTree* tree); protected: CollisionAABB mBox; //!< Query box in (center, extents) form Point mMin; //!< Query box min point Point mMax; //!< Query box max point // Leaf description Point mLeafVerts[3]; //!< Triangle vertices // Internal methods void _Collide(const AABBCollisionNode* node); void _Collide(const AABBNoLeafNode* node); void _Collide(const AABBQuantizedNode* node); void _Collide(const AABBQuantizedNoLeafNode* node); void _Collide(const AABBTreeNode* node); void _CollideNoPrimitiveTest(const AABBCollisionNode* node); void _CollideNoPrimitiveTest(const AABBNoLeafNode* node); void _CollideNoPrimitiveTest(const AABBQuantizedNode* node); void _CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node); // Overlap tests inline_ BOOL AABBContainsBox(const Point& bc, const Point& be); inline_ BOOL AABBAABBOverlap(const Point& b, const Point& Pb); inline_ BOOL TriBoxOverlap(); // Init methods BOOL InitQuery(AABBCache& cache, const CollisionAABB& box); }; class OPCODE_API HybridAABBCollider : public AABBCollider { public: // Constructor / Destructor HybridAABBCollider(); virtual ~HybridAABBCollider(); bool Collide(AABBCache& cache, const CollisionAABB& box, const HybridModel& model); protected: Container mTouchedBoxes; }; #endif // __OPC_AABBCOLLIDER_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_Settings.h0000600000175000017500000000433612161402010022775 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains compilation flags. * \file OPC_Settings.h * \author Pierre Terdiman * \date May, 12, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __OPC_SETTINGS_H__ #define __OPC_SETTINGS_H__ //! Use CPU comparisons (comment that line to use standard FPU compares) #define OPC_CPU_COMPARE //! Use FCOMI / FCMOV on Pentium-Pro based processors (comment that line to use plain C++) #define OPC_USE_FCOMI //! Use epsilon value in tri-tri overlap test #define OPC_TRITRI_EPSILON_TEST //! Use tree-coherence or not [not implemented yet] // #define OPC_USE_TREE_COHERENCE //! Use callbacks or direct pointers. Using callbacks might be a bit slower (but probably not much) // #define OPC_USE_CALLBACKS //! Support triangle and vertex strides or not. Using strides might be a bit slower (but probably not much) #define OPC_USE_STRIDE //! Discard negative pointer in vanilla trees #define OPC_NO_NEG_VANILLA_TREE //! Use a callback in the ray collider //#define OPC_RAYHIT_CALLBACK // NB: no compilation flag to enable/disable stats since they're actually needed in the box/box overlap test #endif //__OPC_SETTINGS_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_PlanesAABBOverlap.h0000600000175000017500000000500012161402010024343 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Planes-AABB overlap test. * - original code by Ville Miettinen, from Umbra/dPVS (released on the GD-Algorithms mailing list) * - almost used "as-is", I even left the comments (hence the frustum-related notes) * * \param center [in] box center * \param extents [in] box extents * \param out_clip_mask [out] bitmask for active planes * \param in_clip_mask [in] bitmask for active planes * \return TRUE if boxes overlap planes */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL PlanesCollider::PlanesAABBOverlap(const Point& center, const Point& extents, udword& out_clip_mask, udword in_clip_mask) { // Stats mNbVolumeBVTests++; const Plane* p = mPlanes; // Evaluate through all active frustum planes. We determine the relation // between the AABB and a plane by using the concept of "near" and "far" // vertices originally described by Zhang (and later by Mller). Our // variant here uses 3 fabs ops, 6 muls, 7 adds and two floating point // comparisons per plane. The routine early-exits if the AABB is found // to be outside any of the planes. The loop also constructs a new output // clip mask. Most FPUs have a native single-cycle fabsf() operation. udword Mask = 1; // current mask index (1,2,4,8,..) udword TmpOutClipMask = 0; // initialize output clip mask into empty. while(Mask<=in_clip_mask) // keep looping while we have active planes left... { if(in_clip_mask & Mask) // if clip plane is active, process it.. { float NP = extents.x*fabsf(p->n.x) + extents.y*fabsf(p->n.y) + extents.z*fabsf(p->n.z); // ### fabsf could be precomputed float MP = center.x*p->n.x + center.y*p->n.y + center.z*p->n.z + p->d; if(NP < MP) // near vertex behind the clip plane... return FALSE; // .. so there is no intersection.. if((-NP) < MP) // near and far vertices on different sides of plane.. TmpOutClipMask |= Mask; // .. so update the clip mask... } Mask+=Mask; // mk = (1<Add(udword(prim_index)); //! Sphere-triangle overlap test #define SPHERE_PRIM(prim_index, flag) \ /* Request vertices from the app */ \ VertexPointers VP; ConversionArea VC; mIMesh->GetTriangle(VP, prim_index, VC); \ \ /* Perform sphere-tri overlap test */ \ if(SphereTriOverlap(*VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2])) \ { \ SET_CONTACT(prim_index, flag) \ } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// SphereCollider::SphereCollider() { mCenter.Zero(); mRadius2 = 0.0f; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Destructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// SphereCollider::~SphereCollider() { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Generic collision query for generic OPCODE models. After the call, access the results: * - with GetContactStatus() * - with GetNbTouchedPrimitives() * - with GetTouchedPrimitives() * * \param cache [in/out] a sphere cache * \param sphere [in] collision sphere in local space * \param model [in] Opcode model to collide with * \param worlds [in] sphere's world matrix, or null * \param worldm [in] model's world matrix, or null * \return true if success * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool SphereCollider::Collide(SphereCache& cache, const Sphere& sphere, const Model& model, const Matrix4x4* worlds, const Matrix4x4* worldm) { // Checkings if(!Setup(&model)) return false; // Init collision query if(InitQuery(cache, sphere, worlds, worldm)) return true; // Special case for 1-leaf trees if(mCurrentModel && mCurrentModel->HasSingleNode()) { // Here we're supposed to perform a normal query, except our tree has a single node, i.e. just a few triangles udword Nb = mIMesh->GetNbTriangles(); // Loop through all triangles for(udword i=0;imCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); else _Collide(Tree->GetNodes()); } else { const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); else _Collide(Tree->GetNodes()); } } else { if(model.IsQuantized()) { const AABBQuantizedTree* Tree = (const AABBQuantizedTree*)model.GetTree(); // Setup dequantization coeffs mCenterCoeff = Tree->mCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); else _Collide(Tree->GetNodes()); } else { const AABBCollisionTree* Tree = (const AABBCollisionTree*)model.GetTree(); // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); else _Collide(Tree->GetNodes()); } } return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Initializes a collision query : * - reset stats & contact status * - setup matrices * - check temporal coherence * * \param cache [in/out] a sphere cache * \param sphere [in] sphere in local space * \param worlds [in] sphere's world matrix, or null * \param worldm [in] model's world matrix, or null * \return TRUE if we can return immediately * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// BOOL SphereCollider::InitQuery(SphereCache& cache, const Sphere& sphere, const Matrix4x4* worlds, const Matrix4x4* worldm) { // 1) Call the base method VolumeCollider::InitQuery(); // 2) Compute sphere in model space: // - Precompute R^2 mRadius2 = sphere.mRadius * sphere.mRadius; // - Compute center position mCenter = sphere.mCenter; // -> to world space if(worlds) mCenter *= *worlds; // -> to model space if(worldm) { // Invert model matrix Matrix4x4 InvWorldM; InvertPRMatrix(InvWorldM, *worldm); mCenter *= InvWorldM; } // 3) Setup destination pointer mTouchedPrimitives = &cache.TouchedPrimitives; // 4) Special case: 1-triangle meshes [Opcode 1.3] if(mCurrentModel && mCurrentModel->HasSingleNode()) { if(!SkipPrimitiveTests()) { // We simply perform the BV-Prim overlap test each time. We assume single triangle has index 0. mTouchedPrimitives->Reset(); // Perform overlap test between the unique triangle and the sphere (and set contact status if needed) SPHERE_PRIM(udword(0), OPC_CONTACT) // Return immediately regardless of status return TRUE; } } // 5) Check temporal coherence : if(TemporalCoherenceEnabled()) { // Here we use temporal coherence // => check results from previous frame before performing the collision query if(FirstContactEnabled()) { // We're only interested in the first contact found => test the unique previously touched face if(mTouchedPrimitives->GetNbEntries()) { // Get index of previously touched face = the first entry in the array udword PreviouslyTouchedFace = mTouchedPrimitives->GetEntry(0); // Then reset the array: // - if the overlap test below is successful, the index we'll get added back anyway // - if it isn't, then the array should be reset anyway for the normal query mTouchedPrimitives->Reset(); // Perform overlap test between the cached triangle and the sphere (and set contact status if needed) SPHERE_PRIM(PreviouslyTouchedFace, OPC_TEMPORAL_CONTACT) // Return immediately if possible if(GetContactStatus()) return TRUE; } // else no face has been touched during previous query // => we'll have to perform a normal query } else { // We're interested in all contacts =>test the new real sphere N(ew) against the previous fat sphere P(revious): float r = sqrtf(cache.FatRadius2) - sphere.mRadius; if(IsCacheValid(cache) && cache.Center.SquareDistance(mCenter) < r*r) { // - if N is included in P, return previous list // => we simply leave the list (mTouchedFaces) unchanged // Set contact status if needed if(mTouchedPrimitives->GetNbEntries()) mFlags |= OPC_TEMPORAL_CONTACT; // In any case we don't need to do a query return TRUE; } else { // - else do the query using a fat N // Reset cache since we'll about to perform a real query mTouchedPrimitives->Reset(); // Make a fat sphere so that coherence will work for subsequent frames mRadius2 *= cache.FatCoeff; // mRadius2 = (sphere.mRadius * cache.FatCoeff)*(sphere.mRadius * cache.FatCoeff); // Update cache with query data (signature for cached faces) cache.Center = mCenter; cache.FatRadius2 = mRadius2; } } } else { // Here we don't use temporal coherence => do a normal query mTouchedPrimitives->Reset(); } return FALSE; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Collision query for vanilla AABB trees. * \param cache [in/out] a sphere cache * \param sphere [in] collision sphere in world space * \param tree [in] AABB tree * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool SphereCollider::Collide(SphereCache& cache, const Sphere& sphere, const AABBTree* tree) { // This is typically called for a scene tree, full of -AABBs-, not full of triangles. // So we don't really have "primitives" to deal with. Hence it doesn't work with // "FirstContact" + "TemporalCoherence". ASSERT( !(FirstContactEnabled() && TemporalCoherenceEnabled()) ); // Checkings if(!tree) return false; // Init collision query if(InitQuery(cache, sphere)) return true; // Perform collision query _Collide(tree); return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks the sphere completely contains the box. In which case we can end the query sooner. * \param bc [in] box center * \param be [in] box extents * \return true if the sphere contains the whole box */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL SphereCollider::SphereContainsBox(const Point& bc, const Point& be) { // I assume if all 8 box vertices are inside the sphere, so does the whole box. // Sounds ok but maybe there's a better way? Point p; p.x=bc.x+be.x; p.y=bc.y+be.y; p.z=bc.z+be.z; if(mCenter.SquareDistance(p)>=mRadius2) return FALSE; p.x=bc.x-be.x; if(mCenter.SquareDistance(p)>=mRadius2) return FALSE; p.x=bc.x+be.x; p.y=bc.y-be.y; if(mCenter.SquareDistance(p)>=mRadius2) return FALSE; p.x=bc.x-be.x; if(mCenter.SquareDistance(p)>=mRadius2) return FALSE; p.x=bc.x+be.x; p.y=bc.y+be.y; p.z=bc.z-be.z; if(mCenter.SquareDistance(p)>=mRadius2) return FALSE; p.x=bc.x-be.x; if(mCenter.SquareDistance(p)>=mRadius2) return FALSE; p.x=bc.x+be.x; p.y=bc.y-be.y; if(mCenter.SquareDistance(p)>=mRadius2) return FALSE; p.x=bc.x-be.x; if(mCenter.SquareDistance(p)>=mRadius2) return FALSE; return TRUE; } #define TEST_BOX_IN_SPHERE(center, extents) \ if(SphereContainsBox(center, extents)) \ { \ /* Set contact status */ \ mFlags |= OPC_CONTACT; \ _Dump(node); \ return; \ } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for normal AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void SphereCollider::_Collide(const AABBCollisionNode* node) { // Perform Sphere-AABB overlap test if(!SphereAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; TEST_BOX_IN_SPHERE(node->mAABB.mCenter, node->mAABB.mExtents) if(node->IsLeaf()) { SPHERE_PRIM(node->GetPrimitive(), OPC_CONTACT) } else { _Collide(node->GetPos()); if(ContactFound()) return; _Collide(node->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for normal AABB trees, without primitive tests. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void SphereCollider::_CollideNoPrimitiveTest(const AABBCollisionNode* node) { // Perform Sphere-AABB overlap test if(!SphereAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; TEST_BOX_IN_SPHERE(node->mAABB.mCenter, node->mAABB.mExtents) if(node->IsLeaf()) { SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) } else { _CollideNoPrimitiveTest(node->GetPos()); if(ContactFound()) return; _CollideNoPrimitiveTest(node->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for quantized AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void SphereCollider::_Collide(const AABBQuantizedNode* node) { // Dequantize box const QuantizedAABB& Box = node->mAABB; const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); // Perform Sphere-AABB overlap test if(!SphereAABBOverlap(Center, Extents)) return; TEST_BOX_IN_SPHERE(Center, Extents) if(node->IsLeaf()) { SPHERE_PRIM(node->GetPrimitive(), OPC_CONTACT) } else { _Collide(node->GetPos()); if(ContactFound()) return; _Collide(node->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for quantized AABB trees, without primitive tests. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void SphereCollider::_CollideNoPrimitiveTest(const AABBQuantizedNode* node) { // Dequantize box const QuantizedAABB& Box = node->mAABB; const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); // Perform Sphere-AABB overlap test if(!SphereAABBOverlap(Center, Extents)) return; TEST_BOX_IN_SPHERE(Center, Extents) if(node->IsLeaf()) { SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) } else { _CollideNoPrimitiveTest(node->GetPos()); if(ContactFound()) return; _CollideNoPrimitiveTest(node->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for no-leaf AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void SphereCollider::_Collide(const AABBNoLeafNode* node) { // Perform Sphere-AABB overlap test if(!SphereAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; TEST_BOX_IN_SPHERE(node->mAABB.mCenter, node->mAABB.mExtents) if(node->HasPosLeaf()) { SPHERE_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } else _Collide(node->GetPos()); if(ContactFound()) return; if(node->HasNegLeaf()) { SPHERE_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } else _Collide(node->GetNeg()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for no-leaf AABB trees, without primitive tests. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void SphereCollider::_CollideNoPrimitiveTest(const AABBNoLeafNode* node) { // Perform Sphere-AABB overlap test if(!SphereAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; TEST_BOX_IN_SPHERE(node->mAABB.mCenter, node->mAABB.mExtents) if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } else _CollideNoPrimitiveTest(node->GetPos()); if(ContactFound()) return; if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } else _CollideNoPrimitiveTest(node->GetNeg()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for quantized no-leaf AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void SphereCollider::_Collide(const AABBQuantizedNoLeafNode* node) { // Dequantize box const QuantizedAABB& Box = node->mAABB; const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); // Perform Sphere-AABB overlap test if(!SphereAABBOverlap(Center, Extents)) return; TEST_BOX_IN_SPHERE(Center, Extents) if(node->HasPosLeaf()) { SPHERE_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } else _Collide(node->GetPos()); if(ContactFound()) return; if(node->HasNegLeaf()) { SPHERE_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } else _Collide(node->GetNeg()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for quantized no-leaf AABB trees, without primitive tests. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void SphereCollider::_CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node) { // Dequantize box const QuantizedAABB& Box = node->mAABB; const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); // Perform Sphere-AABB overlap test if(!SphereAABBOverlap(Center, Extents)) return; TEST_BOX_IN_SPHERE(Center, Extents) if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } else _CollideNoPrimitiveTest(node->GetPos()); if(ContactFound()) return; if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } else _CollideNoPrimitiveTest(node->GetNeg()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for vanilla AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void SphereCollider::_Collide(const AABBTreeNode* node) { // Perform Sphere-AABB overlap test Point Center, Extents; node->GetAABB()->GetCenter(Center); node->GetAABB()->GetExtents(Extents); if(!SphereAABBOverlap(Center, Extents)) return; if(node->IsLeaf() || SphereContainsBox(Center, Extents)) { mFlags |= OPC_CONTACT; mTouchedPrimitives->Add(node->GetPrimitives(), node->GetNbPrimitives()); } else { _Collide(node->GetPos()); _Collide(node->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// HybridSphereCollider::HybridSphereCollider() { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Destructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// HybridSphereCollider::~HybridSphereCollider() { } bool HybridSphereCollider::Collide(SphereCache& cache, const Sphere& sphere, const HybridModel& model, const Matrix4x4* worlds, const Matrix4x4* worldm) { // We don't want primitive tests here! mFlags |= OPC_NO_PRIMITIVE_TESTS; // Checkings if(!Setup(&model)) return false; // Init collision query if(InitQuery(cache, sphere, worlds, worldm)) return true; // Special case for 1-leaf trees if(mCurrentModel && mCurrentModel->HasSingleNode()) { // Here we're supposed to perform a normal query, except our tree has a single node, i.e. just a few triangles udword Nb = mIMesh->GetNbTriangles(); // Loop through all triangles for(udword i=0;imCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes()); } else { const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes()); } } else { if(model.IsQuantized()) { const AABBQuantizedTree* Tree = (const AABBQuantizedTree*)model.GetTree(); // Setup dequantization coeffs mCenterCoeff = Tree->mCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes()); } else { const AABBCollisionTree* Tree = (const AABBCollisionTree*)model.GetTree(); // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes()); } } // We only have a list of boxes so far if(GetContactStatus()) { // Reset contact status, since it currently only reflects collisions with leaf boxes Collider::InitQuery(); // Change dest container so that we can use built-in overlap tests and get collided primitives cache.TouchedPrimitives.Reset(); mTouchedPrimitives = &cache.TouchedPrimitives; // Read touched leaf boxes udword Nb = mTouchedBoxes.GetNbEntries(); const udword* Touched = mTouchedBoxes.GetEntries(); const LeafTriangles* LT = model.GetLeafTriangles(); const udword* Indices = model.GetIndices(); // Loop through touched leaves while(Nb--) { const LeafTriangles& CurrentLeaf = LT[*Touched++]; // Each leaf box has a set of triangles udword NbTris = CurrentLeaf.GetNbTriangles(); if(Indices) { const udword* T = &Indices[CurrentLeaf.GetTriangleIndex()]; // Loop through triangles and test each of them while(NbTris--) { udword TriangleIndex = *T++; SPHERE_PRIM(TriangleIndex, OPC_CONTACT) } } else { udword BaseIndex = CurrentLeaf.GetTriangleIndex(); // Loop through triangles and test each of them while(NbTris--) { udword TriangleIndex = BaseIndex++; SPHERE_PRIM(TriangleIndex, OPC_CONTACT) } } } } return true; } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_LSSCollider.h0000600000175000017500000001106712161402010023313 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for an LSS collider. * \file OPC_LSSCollider.h * \author Pierre Terdiman * \date December, 28, 2002 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __OPC_LSSCOLLIDER_H__ #define __OPC_LSSCOLLIDER_H__ struct OPCODE_API LSSCache : VolumeCache { LSSCache() { Previous.mP0 = Point(0.0f, 0.0f, 0.0f); Previous.mP1 = Point(0.0f, 0.0f, 0.0f); Previous.mRadius = 0.0f; FatCoeff = 1.1f; } // Cached faces signature LSS Previous; //!< LSS used when performing the query resulting in cached faces // User settings float FatCoeff; //!< mRadius2 multiplier used to create a fat LSS }; class OPCODE_API LSSCollider : public VolumeCollider { public: // Constructor / Destructor LSSCollider(); virtual ~LSSCollider(); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Generic collision query for generic OPCODE models. After the call, access the results: * - with GetContactStatus() * - with GetNbTouchedPrimitives() * - with GetTouchedPrimitives() * * \param cache [in/out] an lss cache * \param lss [in] collision lss in local space * \param model [in] Opcode model to collide with * \param worldl [in] lss world matrix, or null * \param worldm [in] model's world matrix, or null * \return true if success * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool Collide(LSSCache& cache, const LSS& lss, const Model& model, const Matrix4x4* worldl=null, const Matrix4x4* worldm=null); // bool Collide(LSSCache& cache, const LSS& lss, const AABBTree* tree); protected: // LSS in model space Segment mSeg; //!< Segment float mRadius2; //!< LSS radius squared // Internal methods void _Collide(const AABBCollisionNode* node); void _Collide(const AABBNoLeafNode* node); void _Collide(const AABBQuantizedNode* node); void _Collide(const AABBQuantizedNoLeafNode* node); void _Collide(const AABBTreeNode* node); void _CollideNoPrimitiveTest(const AABBCollisionNode* node); void _CollideNoPrimitiveTest(const AABBNoLeafNode* node); void _CollideNoPrimitiveTest(const AABBQuantizedNode* node); void _CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node); // Overlap tests inline_ BOOL LSSContainsBox(const Point& bc, const Point& be); inline_ BOOL LSSAABBOverlap(const Point& center, const Point& extents); inline_ BOOL LSSTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2); // Init methods BOOL InitQuery(LSSCache& cache, const LSS& lss, const Matrix4x4* worldl=null, const Matrix4x4* worldm=null); }; class OPCODE_API HybridLSSCollider : public LSSCollider { public: // Constructor / Destructor HybridLSSCollider(); virtual ~HybridLSSCollider(); bool Collide(LSSCache& cache, const LSS& lss, const HybridModel& model, const Matrix4x4* worldl=null, const Matrix4x4* worldm=null); protected: Container mTouchedBoxes; }; #endif // __OPC_LSSCOLLIDER_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_OBBCollider.cpp0000600000175000017500000007056712161402010023621 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for an OBB collider. * \file OPC_OBBCollider.cpp * \author Pierre Terdiman * \date January, 1st, 2002 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains an OBB-vs-tree collider. * * \class OBBCollider * \author Pierre Terdiman * \version 1.3 * \date January, 1st, 2002 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace Opcode; #include "OPC_BoxBoxOverlap.h" #include "OPC_TriBoxOverlap.h" #define SET_CONTACT(prim_index, flag) \ /* Set contact status */ \ mFlags |= flag; \ mTouchedPrimitives->Add(udword(prim_index)); //! OBB-triangle test #define OBB_PRIM(prim_index, flag) \ /* Request vertices from the app */ \ VertexPointers VP; ConversionArea VC; mIMesh->GetTriangle(VP, prim_index, VC); \ /* Transform them in a common space */ \ TransformPoint(mLeafVerts[0], *VP.Vertex[0], mRModelToBox, mTModelToBox); \ TransformPoint(mLeafVerts[1], *VP.Vertex[1], mRModelToBox, mTModelToBox); \ TransformPoint(mLeafVerts[2], *VP.Vertex[2], mRModelToBox, mTModelToBox); \ /* Perform triangle-box overlap test */ \ if(TriBoxOverlap()) \ { \ SET_CONTACT(prim_index, flag) \ } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// OBBCollider::OBBCollider() : mFullBoxBoxTest(true) { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Destructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// OBBCollider::~OBBCollider() { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Validates current settings. You should call this method after all the settings and callbacks have been defined. * \return null if everything is ok, else a string describing the problem */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const char* OBBCollider::ValidateSettings() { if(TemporalCoherenceEnabled() && !FirstContactEnabled()) return "Temporal coherence only works with ""First contact"" mode!"; return VolumeCollider::ValidateSettings(); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Generic collision query for generic OPCODE models. After the call, access the results: * - with GetContactStatus() * - with GetNbTouchedPrimitives() * - with GetTouchedPrimitives() * * \param cache [in/out] a box cache * \param box [in] collision OBB in local space * \param model [in] Opcode model to collide with * \param worldb [in] OBB's world matrix, or null * \param worldm [in] model's world matrix, or null * \return true if success * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool OBBCollider::Collide(OBBCache& cache, const OBB& box, const Model& model, const Matrix4x4* worldb, const Matrix4x4* worldm) { // Checkings if(!Setup(&model)) return false; // Init collision query if(InitQuery(cache, box, worldb, worldm)) return true; if(!model.HasLeafNodes()) { if(model.IsQuantized()) { const AABBQuantizedNoLeafTree* Tree = (const AABBQuantizedNoLeafTree*)model.GetTree(); // Setup dequantization coeffs mCenterCoeff = Tree->mCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); else _Collide(Tree->GetNodes()); } else { const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); else _Collide(Tree->GetNodes()); } } else { if(model.IsQuantized()) { const AABBQuantizedTree* Tree = (const AABBQuantizedTree*)model.GetTree(); // Setup dequantization coeffs mCenterCoeff = Tree->mCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); else _Collide(Tree->GetNodes()); } else { const AABBCollisionTree* Tree = (const AABBCollisionTree*)model.GetTree(); // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); else _Collide(Tree->GetNodes()); } } return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Initializes a collision query : * - reset stats & contact status * - setup matrices * - check temporal coherence * * \param cache [in/out] a box cache * \param box [in] obb in local space * \param worldb [in] obb's world matrix, or null * \param worldm [in] model's world matrix, or null * \return TRUE if we can return immediately * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// BOOL OBBCollider::InitQuery(OBBCache& cache, const OBB& box, const Matrix4x4* worldb, const Matrix4x4* worldm) { // 1) Call the base method VolumeCollider::InitQuery(); // 2) Compute obb in world space mBoxExtents = box.mExtents; Matrix4x4 WorldB; if(worldb) { WorldB = Matrix4x4( box.mRot * Matrix3x3(*worldb) ); WorldB.SetTrans(box.mCenter * *worldb); } else { WorldB = box.mRot; WorldB.SetTrans(box.mCenter); } // Setup matrices Matrix4x4 InvWorldB; InvertPRMatrix(InvWorldB, WorldB); if(worldm) { Matrix4x4 InvWorldM; InvertPRMatrix(InvWorldM, *worldm); Matrix4x4 WorldBtoM = WorldB * InvWorldM; Matrix4x4 WorldMtoB = *worldm * InvWorldB; mRModelToBox = WorldMtoB; WorldMtoB.GetTrans(mTModelToBox); mRBoxToModel = WorldBtoM; WorldBtoM.GetTrans(mTBoxToModel); } else { mRModelToBox = InvWorldB; InvWorldB.GetTrans(mTModelToBox); mRBoxToModel = WorldB; WorldB.GetTrans(mTBoxToModel); } // 3) Setup destination pointer mTouchedPrimitives = &cache.TouchedPrimitives; // 4) Special case: 1-triangle meshes [Opcode 1.3] if(mCurrentModel && mCurrentModel->HasSingleNode()) { if(!SkipPrimitiveTests()) { // We simply perform the BV-Prim overlap test each time. We assume single triangle has index 0. mTouchedPrimitives->Reset(); // Perform overlap test between the unique triangle and the box (and set contact status if needed) OBB_PRIM(udword(0), OPC_CONTACT) // Return immediately regardless of status return TRUE; } } // 5) Check temporal coherence: if(TemporalCoherenceEnabled()) { // Here we use temporal coherence // => check results from previous frame before performing the collision query if(FirstContactEnabled()) { // We're only interested in the first contact found => test the unique previously touched face if(mTouchedPrimitives->GetNbEntries()) { // Get index of previously touched face = the first entry in the array udword PreviouslyTouchedFace = mTouchedPrimitives->GetEntry(0); // Then reset the array: // - if the overlap test below is successful, the index we'll get added back anyway // - if it isn't, then the array should be reset anyway for the normal query mTouchedPrimitives->Reset(); // Perform overlap test between the cached triangle and the box (and set contact status if needed) OBB_PRIM(PreviouslyTouchedFace, OPC_TEMPORAL_CONTACT) // Return immediately if possible if(GetContactStatus()) return TRUE; } // else no face has been touched during previous query // => we'll have to perform a normal query } else { // ### rewrite this OBB TestBox(mTBoxToModel, mBoxExtents, mRBoxToModel); // We're interested in all contacts =>test the new real box N(ew) against the previous fat box P(revious): if(IsCacheValid(cache) && TestBox.IsInside(cache.FatBox)) { // - if N is included in P, return previous list // => we simply leave the list (mTouchedFaces) unchanged // Set contact status if needed if(mTouchedPrimitives->GetNbEntries()) mFlags |= OPC_TEMPORAL_CONTACT; // In any case we don't need to do a query return TRUE; } else { // - else do the query using a fat N // Reset cache since we'll about to perform a real query mTouchedPrimitives->Reset(); // Make a fat box so that coherence will work for subsequent frames TestBox.mExtents *= cache.FatCoeff; mBoxExtents *= cache.FatCoeff; // Update cache with query data (signature for cached faces) cache.FatBox = TestBox; } } } else { // Here we don't use temporal coherence => do a normal query mTouchedPrimitives->Reset(); } // Now we can precompute box-box data // Precompute absolute box-to-model rotation matrix for(udword i=0;i<3;i++) { for(udword j=0;j<3;j++) { // Epsilon value prevents floating-point inaccuracies (strategy borrowed from RAPID) mAR.m[i][j] = 1e-6f + fabsf(mRBoxToModel.m[i][j]); } } // Precompute bounds for box-in-box test mB0 = mBoxExtents - mTModelToBox; mB1 = - mBoxExtents - mTModelToBox; // Precompute box-box data - Courtesy of Erwin de Vries mBBx1 = mBoxExtents.x*mAR.m[0][0] + mBoxExtents.y*mAR.m[1][0] + mBoxExtents.z*mAR.m[2][0]; mBBy1 = mBoxExtents.x*mAR.m[0][1] + mBoxExtents.y*mAR.m[1][1] + mBoxExtents.z*mAR.m[2][1]; mBBz1 = mBoxExtents.x*mAR.m[0][2] + mBoxExtents.y*mAR.m[1][2] + mBoxExtents.z*mAR.m[2][2]; mBB_1 = mBoxExtents.y*mAR.m[2][0] + mBoxExtents.z*mAR.m[1][0]; mBB_2 = mBoxExtents.x*mAR.m[2][0] + mBoxExtents.z*mAR.m[0][0]; mBB_3 = mBoxExtents.x*mAR.m[1][0] + mBoxExtents.y*mAR.m[0][0]; mBB_4 = mBoxExtents.y*mAR.m[2][1] + mBoxExtents.z*mAR.m[1][1]; mBB_5 = mBoxExtents.x*mAR.m[2][1] + mBoxExtents.z*mAR.m[0][1]; mBB_6 = mBoxExtents.x*mAR.m[1][1] + mBoxExtents.y*mAR.m[0][1]; mBB_7 = mBoxExtents.y*mAR.m[2][2] + mBoxExtents.z*mAR.m[1][2]; mBB_8 = mBoxExtents.x*mAR.m[2][2] + mBoxExtents.z*mAR.m[0][2]; mBB_9 = mBoxExtents.x*mAR.m[1][2] + mBoxExtents.y*mAR.m[0][2]; return FALSE; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks the OBB completely contains the box. In which case we can end the query sooner. * \param bc [in] box center * \param be [in] box extents * \return true if the OBB contains the whole box */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL OBBCollider::OBBContainsBox(const Point& bc, const Point& be) { // I assume if all 8 box vertices are inside the OBB, so does the whole box. // Sounds ok but maybe there's a better way? /* #define TEST_PT(a,b,c) \ p.x=a; p.y=b; p.z=c; p+=bc; \ f = p.x * mRModelToBox.m[0][0] + p.y * mRModelToBox.m[1][0] + p.z * mRModelToBox.m[2][0]; if(f>mB0.x || fmB0.y || fmB0.z || f NCx-NEx) return FALSE; float NCy = bc.x * mRModelToBox.m[0][1] + bc.y * mRModelToBox.m[1][1] + bc.z * mRModelToBox.m[2][1]; float NEy = fabsf(mRModelToBox.m[0][1] * be.x) + fabsf(mRModelToBox.m[1][1] * be.y) + fabsf(mRModelToBox.m[2][1] * be.z); if(mB0.y < NCy+NEy) return FALSE; if(mB1.y > NCy-NEy) return FALSE; float NCz = bc.x * mRModelToBox.m[0][2] + bc.y * mRModelToBox.m[1][2] + bc.z * mRModelToBox.m[2][2]; float NEz = fabsf(mRModelToBox.m[0][2] * be.x) + fabsf(mRModelToBox.m[1][2] * be.y) + fabsf(mRModelToBox.m[2][2] * be.z); if(mB0.z < NCz+NEz) return FALSE; if(mB1.z > NCz-NEz) return FALSE; return TRUE; } #define TEST_BOX_IN_OBB(center, extents) \ if(OBBContainsBox(center, extents)) \ { \ /* Set contact status */ \ mFlags |= OPC_CONTACT; \ _Dump(node); \ return; \ } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for normal AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void OBBCollider::_Collide(const AABBCollisionNode* node) { // Perform OBB-AABB overlap test if(!BoxBoxOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; TEST_BOX_IN_OBB(node->mAABB.mCenter, node->mAABB.mExtents) if(node->IsLeaf()) { OBB_PRIM(node->GetPrimitive(), OPC_CONTACT) } else { _Collide(node->GetPos()); if(ContactFound()) return; _Collide(node->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for normal AABB trees, without primitive tests. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void OBBCollider::_CollideNoPrimitiveTest(const AABBCollisionNode* node) { // Perform OBB-AABB overlap test if(!BoxBoxOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; TEST_BOX_IN_OBB(node->mAABB.mCenter, node->mAABB.mExtents) if(node->IsLeaf()) { SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) } else { _CollideNoPrimitiveTest(node->GetPos()); if(ContactFound()) return; _CollideNoPrimitiveTest(node->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for quantized AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void OBBCollider::_Collide(const AABBQuantizedNode* node) { // Dequantize box const QuantizedAABB& Box = node->mAABB; const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); // Perform OBB-AABB overlap test if(!BoxBoxOverlap(Extents, Center)) return; TEST_BOX_IN_OBB(Center, Extents) if(node->IsLeaf()) { OBB_PRIM(node->GetPrimitive(), OPC_CONTACT) } else { _Collide(node->GetPos()); if(ContactFound()) return; _Collide(node->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for quantized AABB trees, without primitive tests. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void OBBCollider::_CollideNoPrimitiveTest(const AABBQuantizedNode* node) { // Dequantize box const QuantizedAABB& Box = node->mAABB; const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); // Perform OBB-AABB overlap test if(!BoxBoxOverlap(Extents, Center)) return; TEST_BOX_IN_OBB(Center, Extents) if(node->IsLeaf()) { SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) } else { _CollideNoPrimitiveTest(node->GetPos()); if(ContactFound()) return; _CollideNoPrimitiveTest(node->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for no-leaf AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void OBBCollider::_Collide(const AABBNoLeafNode* node) { // Perform OBB-AABB overlap test if(!BoxBoxOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; TEST_BOX_IN_OBB(node->mAABB.mCenter, node->mAABB.mExtents) if(node->HasPosLeaf()) { OBB_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } else _Collide(node->GetPos()); if(ContactFound()) return; if(node->HasNegLeaf()) { OBB_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } else _Collide(node->GetNeg()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for no-leaf AABB trees, without primitive tests. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void OBBCollider::_CollideNoPrimitiveTest(const AABBNoLeafNode* node) { // Perform OBB-AABB overlap test if(!BoxBoxOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; TEST_BOX_IN_OBB(node->mAABB.mCenter, node->mAABB.mExtents) if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } else _CollideNoPrimitiveTest(node->GetPos()); if(ContactFound()) return; if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } else _CollideNoPrimitiveTest(node->GetNeg()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for quantized no-leaf AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void OBBCollider::_Collide(const AABBQuantizedNoLeafNode* node) { // Dequantize box const QuantizedAABB& Box = node->mAABB; const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); // Perform OBB-AABB overlap test if(!BoxBoxOverlap(Extents, Center)) return; TEST_BOX_IN_OBB(Center, Extents) if(node->HasPosLeaf()) { OBB_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } else _Collide(node->GetPos()); if(ContactFound()) return; if(node->HasNegLeaf()) { OBB_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } else _Collide(node->GetNeg()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for quantized no-leaf AABB trees, without primitive tests. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void OBBCollider::_CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node) { // Dequantize box const QuantizedAABB& Box = node->mAABB; const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); // Perform OBB-AABB overlap test if(!BoxBoxOverlap(Extents, Center)) return; TEST_BOX_IN_OBB(Center, Extents) if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } else _CollideNoPrimitiveTest(node->GetPos()); if(ContactFound()) return; if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } else _CollideNoPrimitiveTest(node->GetNeg()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// HybridOBBCollider::HybridOBBCollider() { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Destructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// HybridOBBCollider::~HybridOBBCollider() { } bool HybridOBBCollider::Collide(OBBCache& cache, const OBB& box, const HybridModel& model, const Matrix4x4* worldb, const Matrix4x4* worldm) { // We don't want primitive tests here! mFlags |= OPC_NO_PRIMITIVE_TESTS; // Checkings if(!Setup(&model)) return false; // Init collision query if(InitQuery(cache, box, worldb, worldm)) return true; // Special case for 1-leaf trees if(mCurrentModel && mCurrentModel->HasSingleNode()) { // Here we're supposed to perform a normal query, except our tree has a single node, i.e. just a few triangles udword Nb = mIMesh->GetNbTriangles(); // Loop through all triangles for(udword i=0;imCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes()); } else { const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes()); } } else { if(model.IsQuantized()) { const AABBQuantizedTree* Tree = (const AABBQuantizedTree*)model.GetTree(); // Setup dequantization coeffs mCenterCoeff = Tree->mCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes()); } else { const AABBCollisionTree* Tree = (const AABBCollisionTree*)model.GetTree(); // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes()); } } // We only have a list of boxes so far if(GetContactStatus()) { // Reset contact status, since it currently only reflects collisions with leaf boxes Collider::InitQuery(); // Change dest container so that we can use built-in overlap tests and get collided primitives cache.TouchedPrimitives.Reset(); mTouchedPrimitives = &cache.TouchedPrimitives; // Read touched leaf boxes udword Nb = mTouchedBoxes.GetNbEntries(); const udword* Touched = mTouchedBoxes.GetEntries(); const LeafTriangles* LT = model.GetLeafTriangles(); const udword* Indices = model.GetIndices(); // Loop through touched leaves while(Nb--) { const LeafTriangles& CurrentLeaf = LT[*Touched++]; // Each leaf box has a set of triangles udword NbTris = CurrentLeaf.GetNbTriangles(); if(Indices) { const udword* T = &Indices[CurrentLeaf.GetTriangleIndex()]; // Loop through triangles and test each of them while(NbTris--) { udword TriangleIndex = *T++; OBB_PRIM(TriangleIndex, OPC_CONTACT) } } else { udword BaseIndex = CurrentLeaf.GetTriangleIndex(); // Loop through triangles and test each of them while(NbTris--) { udword TriangleIndex = BaseIndex++; OBB_PRIM(TriangleIndex, OPC_CONTACT) } } } } return true; } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_TreeCollider.h0000600000175000017500000003217412161402010023553 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for a tree collider. * \file OPC_TreeCollider.h * \author Pierre Terdiman * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __OPC_TREECOLLIDER_H__ #define __OPC_TREECOLLIDER_H__ //! This structure holds cached information used by the algorithm. //! Two model pointers and two colliding primitives are cached. Model pointers are assigned //! to their respective meshes, and the pair of colliding primitives is used for temporal //! coherence. That is, in case temporal coherence is enabled, those two primitives are //! tested for overlap before everything else. If they still collide, we're done before //! even entering the recursive collision code. struct OPCODE_API BVTCache : Pair { //! Constructor inline_ BVTCache() { ResetCache(); ResetCountDown(); } void ResetCache() { Model0 = null; Model1 = null; id0 = 0; id1 = 1; #ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE ! HullTest = true; SepVector.pid = 0; SepVector.qid = 0; SepVector.SV = Point(1.0f, 0.0f, 0.0f); #endif // __MESHMERIZER_H__ } #ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE ! inline_ void ResetCountDown() { CountDown = 50; } #else void ResetCountDown(){}; #endif // __MESHMERIZER_H__ const Model* Model0; //!< Model for first object const Model* Model1; //!< Model for second object #ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE ! SVCache SepVector; udword CountDown; bool HullTest; #endif // __MESHMERIZER_H__ }; class OPCODE_API AABBTreeCollider : public Collider { public: // Constructor / Destructor AABBTreeCollider(); virtual ~AABBTreeCollider(); // Generic collision query /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Generic collision query for generic OPCODE models. After the call, access the results with: * - GetContactStatus() * - GetNbPairs() * - GetPairs() * * \param cache [in] collision cache for model pointers and a colliding pair of primitives * \param world0 [in] world matrix for first object, or null * \param world1 [in] world matrix for second object, or null * \return true if success * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool Collide(BVTCache& cache, const Matrix4x4* world0=null, const Matrix4x4* world1=null); // Collision queries bool Collide(const AABBCollisionTree* tree0, const AABBCollisionTree* tree1, const Matrix4x4* world0=null, const Matrix4x4* world1=null, Pair* cache=null); bool Collide(const AABBNoLeafTree* tree0, const AABBNoLeafTree* tree1, const Matrix4x4* world0=null, const Matrix4x4* world1=null, Pair* cache=null); bool Collide(const AABBQuantizedTree* tree0, const AABBQuantizedTree* tree1, const Matrix4x4* world0=null, const Matrix4x4* world1=null, Pair* cache=null); bool Collide(const AABBQuantizedNoLeafTree* tree0, const AABBQuantizedNoLeafTree* tree1, const Matrix4x4* world0=null, const Matrix4x4* world1=null, Pair* cache=null); // Settings /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Settings: selects between full box-box tests or "SAT-lite" tests (where Class III axes are discarded) * \param flag [in] true for full tests, false for coarse tests * \see SetFullPrimBoxTest(bool flag) */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void SetFullBoxBoxTest(bool flag) { mFullBoxBoxTest = flag; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Settings: selects between full triangle-box tests or "SAT-lite" tests (where Class III axes are discarded) * \param flag [in] true for full tests, false for coarse tests * \see SetFullBoxBoxTest(bool flag) */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void SetFullPrimBoxTest(bool flag) { mFullPrimBoxTest = flag; } // Stats /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Stats: gets the number of BV-BV overlap tests after a collision query. * \see GetNbPrimPrimTests() * \see GetNbBVPrimTests() * \return the number of BV-BV tests performed during last query */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ udword GetNbBVBVTests() const { return mNbBVBVTests; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Stats: gets the number of Triangle-Triangle overlap tests after a collision query. * \see GetNbBVBVTests() * \see GetNbBVPrimTests() * \return the number of Triangle-Triangle tests performed during last query */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ udword GetNbPrimPrimTests() const { return mNbPrimPrimTests; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Stats: gets the number of BV-Triangle overlap tests after a collision query. * \see GetNbBVBVTests() * \see GetNbPrimPrimTests() * \return the number of BV-Triangle tests performed during last query */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ udword GetNbBVPrimTests() const { return mNbBVPrimTests; } // Data access /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the number of contacts after a collision query. * \see GetContactStatus() * \see GetPairs() * \return the number of contacts / colliding pairs. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ udword GetNbPairs() const { return mPairs.GetNbEntries()>>1; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the pairs of colliding triangles after a collision query. * \see GetContactStatus() * \see GetNbPairs() * \return the list of colliding pairs (triangle indices) */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ const Pair* GetPairs() const { return (const Pair*)mPairs.GetEntries(); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Validates current settings. You should call this method after all the settings and callbacks have been defined for a collider. * \return null if everything is ok, else a string describing the problem */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// override(Collider) const char* ValidateSettings(); protected: // Colliding pairs Container mPairs; //!< Pairs of colliding primitives // User mesh interfaces const MeshInterface* mIMesh0; //!< User-defined mesh interface for object0 const MeshInterface* mIMesh1; //!< User-defined mesh interface for object1 // Stats udword mNbBVBVTests; //!< Number of BV-BV tests udword mNbPrimPrimTests; //!< Number of Primitive-Primitive tests udword mNbBVPrimTests; //!< Number of BV-Primitive tests // Precomputed data Matrix3x3 mAR; //!< Absolute rotation matrix Matrix3x3 mR0to1; //!< Rotation from object0 to object1 Matrix3x3 mR1to0; //!< Rotation from object1 to object0 Point mT0to1; //!< Translation from object0 to object1 Point mT1to0; //!< Translation from object1 to object0 // Dequantization coeffs Point mCenterCoeff0; Point mExtentsCoeff0; Point mCenterCoeff1; Point mExtentsCoeff1; // Leaf description Point mLeafVerts[3]; //!< Triangle vertices udword mLeafIndex; //!< Triangle index // Settings bool mFullBoxBoxTest; //!< Perform full BV-BV tests (true) or SAT-lite tests (false) bool mFullPrimBoxTest; //!< Perform full Primitive-BV tests (true) or SAT-lite tests (false) // Internal methods // Standard AABB trees void _Collide(const AABBCollisionNode* b0, const AABBCollisionNode* b1); // Quantized AABB trees void _Collide(const AABBQuantizedNode* b0, const AABBQuantizedNode* b1, const Point& a, const Point& Pa, const Point& b, const Point& Pb); // No-leaf AABB trees void _CollideTriBox(const AABBNoLeafNode* b); void _CollideBoxTri(const AABBNoLeafNode* b); void _Collide(const AABBNoLeafNode* a, const AABBNoLeafNode* b); // Quantized no-leaf AABB trees void _CollideTriBox(const AABBQuantizedNoLeafNode* b); void _CollideBoxTri(const AABBQuantizedNoLeafNode* b); void _Collide(const AABBQuantizedNoLeafNode* a, const AABBQuantizedNoLeafNode* b); // Overlap tests void PrimTest(udword id0, udword id1); inline_ void PrimTestTriIndex(udword id1); inline_ void PrimTestIndexTri(udword id0); inline_ BOOL BoxBoxOverlap(const Point& ea, const Point& ca, const Point& eb, const Point& cb); inline_ BOOL TriBoxOverlap(const Point& center, const Point& extents); inline_ BOOL TriTriOverlap(const Point& V0, const Point& V1, const Point& V2, const Point& U0, const Point& U1, const Point& U2); // Init methods void InitQuery(const Matrix4x4* world0=null, const Matrix4x4* world1=null); bool CheckTemporalCoherence(Pair* cache); inline_ BOOL Setup(const MeshInterface* mi0, const MeshInterface* mi1) { mIMesh0 = mi0; mIMesh1 = mi1; if(!mIMesh0 || !mIMesh1) return FALSE; return TRUE; } }; #endif // __OPC_TREECOLLIDER_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_MeshInterface.h0000600000175000017500000002563512161402010023717 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains a mesh interface. * \file OPC_MeshInterface.h * \author Pierre Terdiman * \date November, 27, 2002 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __OPC_MESHINTERFACE_H__ #define __OPC_MESHINTERFACE_H__ struct VertexPointers { const Point* Vertex[3]; bool BackfaceCulling(const Point& source) { const Point& p0 = *Vertex[0]; const Point& p1 = *Vertex[1]; const Point& p2 = *Vertex[2]; // Compute normal direction Point Normal = (p2 - p1)^(p0 - p1); // Backface culling return (Normal | (source - p0)) >= 0.0f; } }; typedef Point ConversionArea[3]; #ifdef OPC_USE_CALLBACKS /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * User-callback, called by OPCODE to request vertices from the app. * \param triangle_index [in] face index for which the system is requesting the vertices * \param triangle [out] triangle's vertices (must be provided by the user) * \param user_data [in] user-defined data from SetCallback() */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// typedef void (*RequestCallback) (udword triangle_index, VertexPointers& triangle, void* user_data); #endif class OPCODE_API MeshInterface { public: // Constructor / Destructor MeshInterface(); ~MeshInterface(); // Common settings inline_ udword GetNbTriangles() const { return mNbTris; } inline_ udword GetNbVertices() const { return mNbVerts; } inline_ void SetNbTriangles(udword nb) { mNbTris = nb; } inline_ void SetNbVertices(udword nb) { mNbVerts = nb; } #ifdef OPC_USE_CALLBACKS // Callback settings /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Callback control: setups object callback. Must provide triangle-vertices for a given triangle index. * \param callback [in] user-defined callback * \param user_data [in] user-defined data * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool SetCallback(RequestCallback callback, void* user_data); inline_ void* GetUserData() const { return mUserData; } inline_ RequestCallback GetCallback() const { return mObjCallback; } #else // Pointers settings /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Pointers control: setups object pointers. Must provide access to faces and vertices for a given object. * \param tris [in] pointer to triangles * \param verts [in] pointer to vertices * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool SetPointers(const IndexedTriangle* tris, const Point* verts); inline_ const IndexedTriangle* GetTris() const { return mTris; } inline_ const Point* GetVerts() const { return mVerts; } #ifdef OPC_USE_STRIDE // Strides settings /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Strides control * \param tri_stride [in] size of a triangle in bytes. The first sizeof(IndexedTriangle) bytes are used to get vertex indices. * \param vertex_stride [in] size of a vertex in bytes. The first sizeof(Point) bytes are used to get vertex position. * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool SetStrides(udword tri_stride=sizeof(IndexedTriangle), udword vertex_stride=sizeof(Point)); inline_ udword GetTriStride() const { return mTriStride; } inline_ udword GetVertexStride() const { return mVertexStride; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Single/Double control * \param value [in] Indicates if mesh data is provided as array of \c single values. If \c false, data is expected to contain \c double elements. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void SetSingle(bool value) { mFetchTriangle = (value ? &MeshInterface::FetchTriangleFromSingles : &MeshInterface::FetchTriangleFromDoubles); } #endif #endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Fetches a triangle given a triangle index. * \param vp [out] required triangle's vertex pointers * \param index [in] triangle index * \param vc [in,out] storage required for data conversion (pass local variable with same scope as \a vp, as \a vp may point to this memory on return) */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void GetTriangle(VertexPointers& vp, udword index, ConversionArea vc) const { #ifdef OPC_USE_CALLBACKS (mObjCallback)(index, vp, mUserData); #else #ifdef OPC_USE_STRIDE // Since there was conditional statement "if (Single)" which was unpredictable for compiler // and required both branches to be always generated what made inlining a questionable // benefit, I consider it better to introduce a forced call // but get rig of branching and dead code injection. ((*this).*mFetchTriangle)(vp, index, vc); #else const IndexedTriangle* T = &mTris[index]; vp.Vertex[0] = &mVerts[T->mVRef[0]]; vp.Vertex[1] = &mVerts[T->mVRef[1]]; vp.Vertex[2] = &mVerts[T->mVRef[2]]; #endif #endif } private: #ifndef OPC_USE_CALLBACKS #ifdef OPC_USE_STRIDE void FetchTriangleFromSingles(VertexPointers& vp, udword index, ConversionArea vc) const; void FetchTriangleFromDoubles(VertexPointers& vp, udword index, ConversionArea vc) const; #endif #endif public: /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Remaps client's mesh according to a permutation. * \param nb_indices [in] number of indices in the permutation (will be checked against number of triangles) * \param permutation [in] list of triangle indices * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool RemapClient(udword nb_indices, const dTriIndex* permutation) const; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks the mesh interface is valid, i.e. things have been setup correctly. * \return true if valid */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool IsValid() const; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks the mesh itself is valid. * Currently we only look for degenerate faces. * \return number of degenerate faces */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// udword CheckTopology() const; private: udword mNbTris; //!< Number of triangles in the input model udword mNbVerts; //!< Number of vertices in the input model #ifdef OPC_USE_CALLBACKS // User callback void* mUserData; //!< User-defined data sent to callback RequestCallback mObjCallback; //!< Object callback #else // User pointers #ifdef OPC_USE_STRIDE udword mTriStride; //!< Possible triangle stride in bytes [Opcode 1.3] udword mVertexStride; //!< Possible vertex stride in bytes [Opcode 1.3] typedef void (MeshInterface:: *TriangleFetchProc)(VertexPointers& vp, udword index, ConversionArea vc) const; TriangleFetchProc mFetchTriangle; #endif const IndexedTriangle* mTris; //!< Array of indexed triangles const Point* mVerts; //!< Array of vertices #endif }; #endif //__OPC_MESHINTERFACE_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_BaseModel.h0000600000175000017500000002445412161402010023033 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains base model interface. * \file OPC_BaseModel.h * \author Pierre Terdiman * \date May, 18, 2003 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __OPC_BASEMODEL_H__ #define __OPC_BASEMODEL_H__ //! Model creation structure struct OPCODE_API OPCODECREATE { //! Constructor OPCODECREATE(); MeshInterface* mIMesh; //!< Mesh interface (access to triangles & vertices) (*) BuildSettings mSettings; //!< Builder's settings bool mNoLeaf; //!< true => discard leaf nodes (else use a normal tree) bool mQuantized; //!< true => quantize the tree (else use a normal tree) #ifdef __MESHMERIZER_H__ bool mCollisionHull; //!< true => use convex hull + GJK #endif // __MESHMERIZER_H__ bool mKeepOriginal; //!< true => keep a copy of the original tree (debug purpose) bool mCanRemap; //!< true => allows OPCODE to reorganize client arrays // (*) This pointer is saved internally and used by OPCODE until collision structures are released, // so beware of the object's lifetime. }; enum ModelFlag { OPC_QUANTIZED = (1<<0), //!< Compressed/uncompressed tree OPC_NO_LEAF = (1<<1), //!< Leaf/NoLeaf tree OPC_SINGLE_NODE = (1<<2) //!< Special case for 1-node models }; class OPCODE_API BaseModel { public: // Constructor/Destructor BaseModel(); virtual ~BaseModel(); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Builds a collision model. * \param create [in] model creation structure * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// virtual bool Build(const OPCODECREATE& create) = 0; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the number of bytes used by the tree. * \return amount of bytes used */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// virtual udword GetUsedBytes() const = 0; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Refits the collision model. This can be used to handle dynamic meshes. Usage is: * 1. modify your mesh vertices (keep the topology constant!) * 2. refit the tree (call this method) * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// virtual bool Refit(); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the source tree. * \return generic tree */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ const AABBTree* GetSourceTree() const { return mSource; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the tree. * \return the collision tree */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ const AABBOptimizedTree* GetTree() const { return mTree; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the tree. * \return the collision tree */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ AABBOptimizedTree* GetTree() { return mTree; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the number of nodes in the tree. * Should be 2*N-1 for normal trees and N-1 for optimized ones. * \return number of nodes */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ udword GetNbNodes() const { return mTree->GetNbNodes(); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks whether the tree has leaf nodes or not. * \return true if the tree has leaf nodes (normal tree), else false (optimized tree) */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL HasLeafNodes() const { return !(mModelCode & OPC_NO_LEAF); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks whether the tree is quantized or not. * \return true if the tree is quantized */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL IsQuantized() const { return mModelCode & OPC_QUANTIZED; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks whether the model has a single node or not. This special case must be handled separately. * \return true if the model has only 1 node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL HasSingleNode() const { return mModelCode & OPC_SINGLE_NODE; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the model's code. * \return model's code */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ udword GetModelCode() const { return mModelCode; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the mesh interface. * \return mesh interface */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ const MeshInterface* GetMeshInterface() const { return mIMesh; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Sets the mesh interface. * \param imesh [in] mesh interface */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void SetMeshInterface(const MeshInterface* imesh) { mIMesh = imesh; } protected: const MeshInterface* mIMesh; //!< User-defined mesh interface udword mModelCode; //!< Model code = combination of ModelFlag(s) AABBTree* mSource; //!< Original source tree AABBOptimizedTree* mTree; //!< Optimized tree owned by the model // Internal methods void ReleaseBase(); bool CreateTree(bool no_leaf, bool quantized); }; #endif //__OPC_BASEMODEL_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_TreeBuilders.h0000600000175000017500000002136412161402010023566 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for tree builders. * \file OPC_TreeBuilders.h * \author Pierre Terdiman * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __OPC_TREEBUILDERS_H__ #define __OPC_TREEBUILDERS_H__ //! Tree splitting rules enum SplittingRules { // Primitive split SPLIT_LARGEST_AXIS = (1<<0), //!< Split along the largest axis SPLIT_SPLATTER_POINTS = (1<<1), //!< Splatter primitive centers (QuickCD-style) SPLIT_BEST_AXIS = (1<<2), //!< Try largest axis, then second, then last SPLIT_BALANCED = (1<<3), //!< Try to keep a well-balanced tree SPLIT_FIFTY = (1<<4), //!< Arbitrary 50-50 split // Node split SPLIT_GEOM_CENTER = (1<<5), //!< Split at geometric center (else split in the middle) // SPLIT_FORCE_DWORD = 0x7fffffff }; //! Simple wrapper around build-related settings [Opcode 1.3] struct OPCODE_API BuildSettings { inline_ BuildSettings() : mLimit(1), mRules(SPLIT_FORCE_DWORD) {} udword mLimit; //!< Limit number of primitives / node. If limit is 1, build a complete tree (2*N-1 nodes) udword mRules; //!< Building/Splitting rules (a combination of SplittingRules flags) }; class OPCODE_API AABBTreeBuilder { public: //! Constructor AABBTreeBuilder() : mNbPrimitives(0), mNodeBase(null), mCount(0), mNbInvalidSplits(0) {} //! Destructor virtual ~AABBTreeBuilder() {} /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the AABB of a set of primitives. * \param primitives [in] list of indices of primitives * \param nb_prims [in] number of indices * \param global_box [out] global AABB enclosing the set of input primitives * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// virtual bool ComputeGlobalBox(const dTriIndex* primitives, udword nb_prims, AABB& global_box) const = 0; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the splitting value along a given axis for a given primitive. * \param index [in] index of the primitive to split * \param axis [in] axis index (0,1,2) * \return splitting value */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// virtual float GetSplittingValue(udword index, udword axis) const = 0; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the splitting value along a given axis for a given node. * \param primitives [in] list of indices of primitives * \param nb_prims [in] number of indices * \param global_box [in] global AABB enclosing the set of input primitives * \param axis [in] axis index (0,1,2) * \return splitting value */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// virtual float GetSplittingValue(const dTriIndex* primitives, udword nb_prims, const AABB& global_box, udword axis) const { // Default split value = middle of the axis (using only the box) return global_box.GetCenter(axis); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Validates node subdivision. This is called each time a node is considered for subdivision, during tree building. * \param primitives [in] list of indices of primitives * \param nb_prims [in] number of indices * \param global_box [in] global AABB enclosing the set of input primitives * \return TRUE if the node should be subdivised */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// virtual BOOL ValidateSubdivision(const dTriIndex* primitives, udword nb_prims, const AABB& global_box) { // Check the user-defined limit if(nb_prims<=mSettings.mLimit) return FALSE; return TRUE; } BuildSettings mSettings; //!< Splitting rules & split limit [Opcode 1.3] udword mNbPrimitives; //!< Total number of primitives. void* mNodeBase; //!< Address of node pool [Opcode 1.3] // Stats inline_ void SetCount(udword nb) { mCount=nb; } inline_ void IncreaseCount(udword nb) { mCount+=nb; } inline_ udword GetCount() const { return mCount; } inline_ void SetNbInvalidSplits(udword nb) { mNbInvalidSplits=nb; } inline_ void IncreaseNbInvalidSplits() { mNbInvalidSplits++; } inline_ udword GetNbInvalidSplits() const { return mNbInvalidSplits; } private: udword mCount; //!< Stats: number of nodes created udword mNbInvalidSplits; //!< Stats: number of invalid splits }; class OPCODE_API AABBTreeOfVerticesBuilder : public AABBTreeBuilder { public: //! Constructor AABBTreeOfVerticesBuilder() : mVertexArray(null) {} //! Destructor virtual ~AABBTreeOfVerticesBuilder() {} override(AABBTreeBuilder) bool ComputeGlobalBox(const dTriIndex* primitives, udword nb_prims, AABB& global_box) const; override(AABBTreeBuilder) float GetSplittingValue(udword index, udword axis) const; override(AABBTreeBuilder) float GetSplittingValue(const dTriIndex* primitives, udword nb_prims, const AABB& global_box, udword axis) const; const Point* mVertexArray; //!< Shortcut to an app-controlled array of vertices. }; class OPCODE_API AABBTreeOfAABBsBuilder : public AABBTreeBuilder { public: //! Constructor AABBTreeOfAABBsBuilder() : mAABBArray(null) {} //! Destructor virtual ~AABBTreeOfAABBsBuilder() {} override(AABBTreeBuilder) bool ComputeGlobalBox(const dTriIndex* primitives, udword nb_prims, AABB& global_box) const; override(AABBTreeBuilder) float GetSplittingValue(udword index, udword axis) const; const AABB* mAABBArray; //!< Shortcut to an app-controlled array of AABBs. }; class OPCODE_API AABBTreeOfTrianglesBuilder : public AABBTreeBuilder { public: //! Constructor AABBTreeOfTrianglesBuilder() : mIMesh(null) {} //! Destructor virtual ~AABBTreeOfTrianglesBuilder() {} override(AABBTreeBuilder) bool ComputeGlobalBox(const dTriIndex* primitives, udword nb_prims, AABB& global_box) const; override(AABBTreeBuilder) float GetSplittingValue(udword index, udword axis) const; override(AABBTreeBuilder) float GetSplittingValue(const dTriIndex* primitives, udword nb_prims, const AABB& global_box, udword axis) const; const MeshInterface* mIMesh; //!< Shortcut to an app-controlled mesh interface }; #endif // __OPC_TREEBUILDERS_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_VolumeCollider.cpp0000600000175000017500000001114312161402010024447 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains base volume collider class. * \file OPC_VolumeCollider.cpp * \author Pierre Terdiman * \date June, 2, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains the abstract class for volume colliders. * * \class VolumeCollider * \author Pierre Terdiman * \version 1.3 * \date June, 2, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace Opcode; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// VolumeCollider::VolumeCollider() : mTouchedPrimitives (null), mNbVolumeBVTests (0), mNbVolumePrimTests (0) { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Destructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// VolumeCollider::~VolumeCollider() { mTouchedPrimitives = null; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Validates current settings. You should call this method after all the settings / callbacks have been defined for a collider. * \return null if everything is ok, else a string describing the problem */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const char* VolumeCollider::ValidateSettings() { return null; } // Pretty dumb way to dump - to do better - one day... #define IMPLEMENT_NOLEAFDUMP(type) \ void VolumeCollider::_Dump(const type* node) \ { \ if(node->HasPosLeaf()) mTouchedPrimitives->Add(udword(node->GetPosPrimitive())); \ else _Dump(node->GetPos()); \ \ if(ContactFound()) return; \ \ if(node->HasNegLeaf()) mTouchedPrimitives->Add(udword(node->GetNegPrimitive())); \ else _Dump(node->GetNeg()); \ } #define IMPLEMENT_LEAFDUMP(type) \ void VolumeCollider::_Dump(const type* node) \ { \ if(node->IsLeaf()) \ { \ mTouchedPrimitives->Add(udword(node->GetPrimitive())); \ } \ else \ { \ _Dump(node->GetPos()); \ \ if(ContactFound()) return; \ \ _Dump(node->GetNeg()); \ } \ } IMPLEMENT_NOLEAFDUMP(AABBNoLeafNode) IMPLEMENT_NOLEAFDUMP(AABBQuantizedNoLeafNode) IMPLEMENT_LEAFDUMP(AABBCollisionNode) IMPLEMENT_LEAFDUMP(AABBQuantizedNode) alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_Common.h0000600000175000017500000001113612161402010022421 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains common classes & defs used in OPCODE. * \file OPC_Common.h * \author Pierre Terdiman * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __OPC_COMMON_H__ #define __OPC_COMMON_H__ // [GOTTFRIED]: Just a small change for readability. #ifdef OPC_CPU_COMPARE #define GREATER(x, y) AIR(x) > IR(y) #else #define GREATER(x, y) fabsf(x) > (y) #endif class OPCODE_API CollisionAABB { public: //! Constructor inline_ CollisionAABB() {} //! Constructor inline_ CollisionAABB(const AABB& b) { b.GetCenter(mCenter); b.GetExtents(mExtents); } //! Destructor inline_ ~CollisionAABB() {} //! Get min point of the box inline_ void GetMin(Point& min) const { min = mCenter - mExtents; } //! Get max point of the box inline_ void GetMax(Point& max) const { max = mCenter + mExtents; } //! Get component of the box's min point along a given axis inline_ float GetMin(udword axis) const { return mCenter[axis] - mExtents[axis]; } //! Get component of the box's max point along a given axis inline_ float GetMax(udword axis) const { return mCenter[axis] + mExtents[axis]; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Setups an AABB from min & max vectors. * \param min [in] the min point * \param max [in] the max point */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void SetMinMax(const Point& min, const Point& max) { mCenter = (max + min)*0.5f; mExtents = (max - min)*0.5f; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks a box is inside another box. * \param box [in] the other box * \return true if current box is inside input box */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL IsInside(const CollisionAABB& box) const { if(box.GetMin(0)>GetMin(0)) return FALSE; if(box.GetMin(1)>GetMin(1)) return FALSE; if(box.GetMin(2)>GetMin(2)) return FALSE; if(box.GetMax(0)max) max=x1; \ if(x2max) max=x2; //! TO BE DOCUMENTED inline_ BOOL planeBoxOverlap(const Point& normal, const float d, const Point& maxbox) { Point vmin, vmax; for(udword q=0;q<=2;q++) { if(normal[q]>0.0f) { vmin[q]=-maxbox[q]; vmax[q]=maxbox[q]; } else { vmin[q]=maxbox[q]; vmax[q]=-maxbox[q]; } } if((normal|vmin)+d>0.0f) return FALSE; if((normal|vmax)+d>=0.0f) return TRUE; return FALSE; } //! TO BE DOCUMENTED #define AXISTEST_X01(a, b, fa, fb) \ min = a*v0.y - b*v0.z; \ max = a*v2.y - b*v2.z; \ if(min>max) {const float tmp=max; max=min; min=tmp; } \ rad = fa * extents.y + fb * extents.z; \ if(min>rad || max<-rad) return FALSE; //! TO BE DOCUMENTED #define AXISTEST_X2(a, b, fa, fb) \ min = a*v0.y - b*v0.z; \ max = a*v1.y - b*v1.z; \ if(min>max) {const float tmp=max; max=min; min=tmp; } \ rad = fa * extents.y + fb * extents.z; \ if(min>rad || max<-rad) return FALSE; //! TO BE DOCUMENTED #define AXISTEST_Y02(a, b, fa, fb) \ min = b*v0.z - a*v0.x; \ max = b*v2.z - a*v2.x; \ if(min>max) {const float tmp=max; max=min; min=tmp; } \ rad = fa * extents.x + fb * extents.z; \ if(min>rad || max<-rad) return FALSE; //! TO BE DOCUMENTED #define AXISTEST_Y1(a, b, fa, fb) \ min = b*v0.z - a*v0.x; \ max = b*v1.z - a*v1.x; \ if(min>max) {const float tmp=max; max=min; min=tmp; } \ rad = fa * extents.x + fb * extents.z; \ if(min>rad || max<-rad) return FALSE; //! TO BE DOCUMENTED #define AXISTEST_Z12(a, b, fa, fb) \ min = a*v1.x - b*v1.y; \ max = a*v2.x - b*v2.y; \ if(min>max) {const float tmp=max; max=min; min=tmp; } \ rad = fa * extents.x + fb * extents.y; \ if(min>rad || max<-rad) return FALSE; //! TO BE DOCUMENTED #define AXISTEST_Z0(a, b, fa, fb) \ min = a*v0.x - b*v0.y; \ max = a*v1.x - b*v1.y; \ if(min>max) {const float tmp=max; max=min; min=tmp; } \ rad = fa * extents.x + fb * extents.y; \ if(min>rad || max<-rad) return FALSE; // compute triangle edges // - edges lazy evaluated to take advantage of early exits // - fabs precomputed (half less work, possible since extents are always >0) // - customized macros to take advantage of the null component // - axis vector discarded, possibly saves useless movs #define IMPLEMENT_CLASS3_TESTS \ float rad; \ float min, max; \ \ const float fey0 = fabsf(e0.y); \ const float fez0 = fabsf(e0.z); \ AXISTEST_X01(e0.z, e0.y, fez0, fey0); \ const float fex0 = fabsf(e0.x); \ AXISTEST_Y02(e0.z, e0.x, fez0, fex0); \ AXISTEST_Z12(e0.y, e0.x, fey0, fex0); \ \ const float fey1 = fabsf(e1.y); \ const float fez1 = fabsf(e1.z); \ AXISTEST_X01(e1.z, e1.y, fez1, fey1); \ const float fex1 = fabsf(e1.x); \ AXISTEST_Y02(e1.z, e1.x, fez1, fex1); \ AXISTEST_Z0(e1.y, e1.x, fey1, fex1); \ \ const Point e2 = mLeafVerts[0] - mLeafVerts[2]; \ const float fey2 = fabsf(e2.y); \ const float fez2 = fabsf(e2.z); \ AXISTEST_X2(e2.z, e2.y, fez2, fey2); \ const float fex2 = fabsf(e2.x); \ AXISTEST_Y1(e2.z, e2.x, fez2, fex2); \ AXISTEST_Z12(e2.y, e2.x, fey2, fex2); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Triangle-Box overlap test using the separating axis theorem. * This is the code from Tomas Mller, a bit optimized: * - with some more lazy evaluation (faster path on PC) * - with a tiny bit of assembly * - with "SAT-lite" applied if needed * - and perhaps with some more minor modifs... * * \param center [in] box center * \param extents [in] box extents * \return true if triangle & box overlap */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL AABBTreeCollider::TriBoxOverlap(const Point& center, const Point& extents) { // Stats mNbBVPrimTests++; // use separating axis theorem to test overlap between triangle and box // need to test for overlap in these directions: // 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle // we do not even need to test these) // 2) normal of the triangle // 3) crossproduct(edge from tri, {x,y,z}-directin) // this gives 3x3=9 more tests // move everything so that the boxcenter is in (0,0,0) Point v0, v1, v2; v0.x = mLeafVerts[0].x - center.x; v1.x = mLeafVerts[1].x - center.x; v2.x = mLeafVerts[2].x - center.x; // First, test overlap in the {x,y,z}-directions #ifdef OPC_USE_FCOMI // find min, max of the triangle in x-direction, and test for overlap in X if(FCMin3(v0.x, v1.x, v2.x)>extents.x) return FALSE; if(FCMax3(v0.x, v1.x, v2.x)<-extents.x) return FALSE; // same for Y v0.y = mLeafVerts[0].y - center.y; v1.y = mLeafVerts[1].y - center.y; v2.y = mLeafVerts[2].y - center.y; if(FCMin3(v0.y, v1.y, v2.y)>extents.y) return FALSE; if(FCMax3(v0.y, v1.y, v2.y)<-extents.y) return FALSE; // same for Z v0.z = mLeafVerts[0].z - center.z; v1.z = mLeafVerts[1].z - center.z; v2.z = mLeafVerts[2].z - center.z; if(FCMin3(v0.z, v1.z, v2.z)>extents.z) return FALSE; if(FCMax3(v0.z, v1.z, v2.z)<-extents.z) return FALSE; #else float min,max; // Find min, max of the triangle in x-direction, and test for overlap in X FINDMINMAX(v0.x, v1.x, v2.x, min, max); if(min>extents.x || max<-extents.x) return FALSE; // Same for Y v0.y = mLeafVerts[0].y - center.y; v1.y = mLeafVerts[1].y - center.y; v2.y = mLeafVerts[2].y - center.y; FINDMINMAX(v0.y, v1.y, v2.y, min, max); if(min>extents.y || max<-extents.y) return FALSE; // Same for Z v0.z = mLeafVerts[0].z - center.z; v1.z = mLeafVerts[1].z - center.z; v2.z = mLeafVerts[2].z - center.z; FINDMINMAX(v0.z, v1.z, v2.z, min, max); if(min>extents.z || max<-extents.z) return FALSE; #endif // 2) Test if the box intersects the plane of the triangle // compute plane equation of triangle: normal*x+d=0 // ### could be precomputed since we use the same leaf triangle several times const Point e0 = v1 - v0; const Point e1 = v2 - v1; const Point normal = e0 ^ e1; const float d = -normal|v0; if(!planeBoxOverlap(normal, d, extents)) return FALSE; // 3) "Class III" tests if(mFullPrimBoxTest) { IMPLEMENT_CLASS3_TESTS } return TRUE; } //! A dedicated version where the box is constant inline_ BOOL OBBCollider::TriBoxOverlap() { // Stats mNbVolumePrimTests++; // Hook const Point& extents = mBoxExtents; const Point& v0 = mLeafVerts[0]; const Point& v1 = mLeafVerts[1]; const Point& v2 = mLeafVerts[2]; // use separating axis theorem to test overlap between triangle and box // need to test for overlap in these directions: // 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle // we do not even need to test these) // 2) normal of the triangle // 3) crossproduct(edge from tri, {x,y,z}-directin) // this gives 3x3=9 more tests // Box center is already in (0,0,0) // First, test overlap in the {x,y,z}-directions #ifdef OPC_USE_FCOMI // find min, max of the triangle in x-direction, and test for overlap in X if(FCMin3(v0.x, v1.x, v2.x)>mBoxExtents.x) return FALSE; if(FCMax3(v0.x, v1.x, v2.x)<-mBoxExtents.x) return FALSE; if(FCMin3(v0.y, v1.y, v2.y)>mBoxExtents.y) return FALSE; if(FCMax3(v0.y, v1.y, v2.y)<-mBoxExtents.y) return FALSE; if(FCMin3(v0.z, v1.z, v2.z)>mBoxExtents.z) return FALSE; if(FCMax3(v0.z, v1.z, v2.z)<-mBoxExtents.z) return FALSE; #else float min,max; // Find min, max of the triangle in x-direction, and test for overlap in X FINDMINMAX(v0.x, v1.x, v2.x, min, max); if(min>mBoxExtents.x || max<-mBoxExtents.x) return FALSE; FINDMINMAX(v0.y, v1.y, v2.y, min, max); if(min>mBoxExtents.y || max<-mBoxExtents.y) return FALSE; FINDMINMAX(v0.z, v1.z, v2.z, min, max); if(min>mBoxExtents.z || max<-mBoxExtents.z) return FALSE; #endif // 2) Test if the box intersects the plane of the triangle // compute plane equation of triangle: normal*x+d=0 // ### could be precomputed since we use the same leaf triangle several times const Point e0 = v1 - v0; const Point e1 = v2 - v1; const Point normal = e0 ^ e1; const float d = -normal|v0; if(!planeBoxOverlap(normal, d, mBoxExtents)) return FALSE; // 3) "Class III" tests - here we always do full tests since the box is a primitive (not a BV) { IMPLEMENT_CLASS3_TESTS } return TRUE; } //! ...and another one, jeez inline_ BOOL AABBCollider::TriBoxOverlap() { // Stats mNbVolumePrimTests++; // Hook const Point& center = mBox.mCenter; const Point& extents = mBox.mExtents; // use separating axis theorem to test overlap between triangle and box // need to test for overlap in these directions: // 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle // we do not even need to test these) // 2) normal of the triangle // 3) crossproduct(edge from tri, {x,y,z}-directin) // this gives 3x3=9 more tests // move everything so that the boxcenter is in (0,0,0) Point v0, v1, v2; v0.x = mLeafVerts[0].x - center.x; v1.x = mLeafVerts[1].x - center.x; v2.x = mLeafVerts[2].x - center.x; // First, test overlap in the {x,y,z}-directions #ifdef OPC_USE_FCOMI // find min, max of the triangle in x-direction, and test for overlap in X if(FCMin3(v0.x, v1.x, v2.x)>extents.x) return FALSE; if(FCMax3(v0.x, v1.x, v2.x)<-extents.x) return FALSE; // same for Y v0.y = mLeafVerts[0].y - center.y; v1.y = mLeafVerts[1].y - center.y; v2.y = mLeafVerts[2].y - center.y; if(FCMin3(v0.y, v1.y, v2.y)>extents.y) return FALSE; if(FCMax3(v0.y, v1.y, v2.y)<-extents.y) return FALSE; // same for Z v0.z = mLeafVerts[0].z - center.z; v1.z = mLeafVerts[1].z - center.z; v2.z = mLeafVerts[2].z - center.z; if(FCMin3(v0.z, v1.z, v2.z)>extents.z) return FALSE; if(FCMax3(v0.z, v1.z, v2.z)<-extents.z) return FALSE; #else float min,max; // Find min, max of the triangle in x-direction, and test for overlap in X FINDMINMAX(v0.x, v1.x, v2.x, min, max); if(min>extents.x || max<-extents.x) return FALSE; // Same for Y v0.y = mLeafVerts[0].y - center.y; v1.y = mLeafVerts[1].y - center.y; v2.y = mLeafVerts[2].y - center.y; FINDMINMAX(v0.y, v1.y, v2.y, min, max); if(min>extents.y || max<-extents.y) return FALSE; // Same for Z v0.z = mLeafVerts[0].z - center.z; v1.z = mLeafVerts[1].z - center.z; v2.z = mLeafVerts[2].z - center.z; FINDMINMAX(v0.z, v1.z, v2.z, min, max); if(min>extents.z || max<-extents.z) return FALSE; #endif // 2) Test if the box intersects the plane of the triangle // compute plane equation of triangle: normal*x+d=0 // ### could be precomputed since we use the same leaf triangle several times const Point e0 = v1 - v0; const Point e1 = v2 - v1; const Point normal = e0 ^ e1; const float d = -normal|v0; if(!planeBoxOverlap(normal, d, extents)) return FALSE; // 3) "Class III" tests - here we always do full tests since the box is a primitive (not a BV) { IMPLEMENT_CLASS3_TESTS } return TRUE; } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_MeshInterface.cpp0000600000175000017500000003463412161402010024251 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains a mesh interface. * \file OPC_MeshInterface.cpp * \author Pierre Terdiman * \date November, 27, 2002 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * This structure holds 3 vertex-pointers. It's mainly used by collision callbacks so that the app doesn't have * to return 3 vertices to OPCODE (36 bytes) but only 3 pointers (12 bytes). It seems better but I never profiled * the alternative. * * \class VertexPointers * \author Pierre Terdiman * \version 1.3 * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * This class is an interface between us and user-defined meshes. Meshes can be defined in a lot of ways, and here we * try to support most of them. * * Basically you have two options: * - callbacks, if OPC_USE_CALLBACKS is defined in OPC_Settings.h. * - else pointers. * * If using pointers, you can also use strides or not. Strides are used when OPC_USE_STRIDE is defined. * * * CALLBACKS: * * Using callbacks is the most generic way to feed OPCODE with your meshes. Indeed, you just have to give * access to three vertices at the end of the day. It's up to you to fetch them from your database, using * whatever method you want. Hence your meshes can lie in system memory or AGP, be indexed or not, use 16 * or 32-bits indices, you can decompress them on-the-fly if needed, etc. On the other hand, a callback is * called each time OPCODE needs access to a particular triangle, so there might be a slight overhead. * * To make things clear: geometry & topology are NOT stored in the collision system, * in order to save some ram. So, when the system needs them to perform accurate intersection * tests, you're requested to provide the triangle-vertices corresponding to a given face index. * * Ex: * * \code * static void ColCallback(udword triangle_index, VertexPointers& triangle, udword user_data) * { * // Get back Mesh0 or Mesh1 (you also can use 2 different callbacks) * Mesh* MyMesh = (Mesh*)user_data; * // Get correct triangle in the app-controlled database * const Triangle* Tri = MyMesh->GetTriangle(triangle_index); * // Setup pointers to vertices for the collision system * triangle.Vertex[0] = MyMesh->GetVertex(Tri->mVRef[0]); * triangle.Vertex[1] = MyMesh->GetVertex(Tri->mVRef[1]); * triangle.Vertex[2] = MyMesh->GetVertex(Tri->mVRef[2]); * } * * // Setup callbacks * MeshInterface0->SetCallback(ColCallback, udword(Mesh0)); * MeshInterface1->SetCallback(ColCallback, udword(Mesh1)); * \endcode * * Of course, you should make this callback as fast as possible. And you're also not supposed * to modify the geometry *after* the collision trees have been built. The alternative was to * store the geometry & topology in the collision system as well (as in RAPID) but we have found * this approach to waste a lot of ram in many cases. * * * POINTERS: * * If you're internally using the following canonical structures: * - a vertex made of three 32-bits floating point values * - a triangle made of three 32-bits integer vertex references * ...then you may want to use pointers instead of callbacks. This is the same, except OPCODE will directly * use provided pointers to access the topology and geometry, without using a callback. It might be faster, * but probably not as safe. Pointers have been introduced in OPCODE 1.2. * * Ex: * * \code * // Setup pointers * MeshInterface0->SetPointers(Mesh0->GetFaces(), Mesh0->GetVerts()); * MeshInterface1->SetPointers(Mesh1->GetFaces(), Mesh1->GetVerts()); * \endcode * * * STRIDES: * * If your vertices are D3D-like entities interleaving a position, a normal and/or texture coordinates * (i.e. if your vertices are FVFs), you might want to use a vertex stride to skip extra data OPCODE * doesn't need. Using a stride shouldn't be notably slower than not using it, but it might increase * cache misses. Please also note that you *shouldn't* read from AGP or video-memory buffers ! * * * In any case, compilation flags are here to select callbacks/pointers/strides at compile time, so * choose what's best for your application. All of this has been wrapped into this MeshInterface. * * \class MeshInterface * \author Pierre Terdiman * \version 1.3 * \date November, 27, 2002 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace Opcode; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// MeshInterface::MeshInterface() : mNbTris (0), mNbVerts (0), #ifdef OPC_USE_CALLBACKS mUserData (null), mObjCallback (null) #else #ifdef OPC_USE_STRIDE mTriStride (sizeof(IndexedTriangle)), mVertexStride (sizeof(Point)), mFetchTriangle (&MeshInterface::FetchTriangleFromSingles), #endif mTris (null), mVerts (null) #endif { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Destructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// MeshInterface::~MeshInterface() { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks the mesh interface is valid, i.e. things have been setup correctly. * \return true if valid */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool MeshInterface::IsValid() const { if(!mNbTris || !mNbVerts) return false; #ifdef OPC_USE_CALLBACKS if(!mObjCallback) return false; #else if(!mTris || !mVerts) return false; #endif return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks the mesh itself is valid. * Currently we only look for degenerate faces. * \return number of degenerate faces */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// udword MeshInterface::CheckTopology() const { // Check topology. If the model contains degenerate faces, collision report can be wrong in some cases. // e.g. it happens with the standard MAX teapot. So clean your meshes first... If you don't have a mesh cleaner // you can try this: www.codercorner.com/Consolidation.zip udword NbDegenerate = 0; VertexPointers VP; ConversionArea VC; // Using callbacks, we don't have access to vertex indices. Nevertheless we still can check for // redundant vertex pointers, which cover all possibilities (callbacks/pointers/strides). for(udword i=0;imVRef[0] * mVertexStride); vp.Vertex[1] = (const Point*)(((ubyte*)mVerts) + T->mVRef[1] * mVertexStride); vp.Vertex[2] = (const Point*)(((ubyte*)mVerts) + T->mVRef[2] * mVertexStride); } void MeshInterface::FetchTriangleFromDoubles(VertexPointers& vp, udword index, ConversionArea vc) const { const IndexedTriangle* T = (const IndexedTriangle*)(((ubyte*)mTris) + index * mTriStride); for (int i = 0; i < 3; i++){ const double* v = (const double*)(((ubyte*)mVerts) + T->mVRef[i] * mVertexStride); vc[i].x = (float)v[0]; vc[i].y = (float)v[1]; vc[i].z = (float)v[2]; vp.Vertex[i] = &vc[i]; } } #endif #endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Remaps client's mesh according to a permutation. * \param nb_indices [in] number of indices in the permutation (will be checked against number of triangles) * \param permutation [in] list of triangle indices * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool MeshInterface::RemapClient(udword nb_indices, const dTriIndex* permutation) const { // Checkings if(!nb_indices || !permutation) return false; if(nb_indices!=mNbTris) return false; #ifdef OPC_USE_CALLBACKS // We can't really do that using callbacks return false; #else IndexedTriangle* Tmp = new IndexedTriangle[mNbTris]; CHECKALLOC(Tmp); #ifdef OPC_USE_STRIDE udword Stride = mTriStride; #else udword Stride = sizeof(IndexedTriangle); #endif for(udword i=0;i>4; } inline_ void SetData(udword nb, udword index) { ASSERT(nb>0 && nb<=16); nb--; Data = (index<<4)|(nb&15); } }; class OPCODE_API HybridModel : public BaseModel { public: // Constructor/Destructor HybridModel(); virtual ~HybridModel(); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Builds a collision model. * \param create [in] model creation structure * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// override(BaseModel) bool Build(const OPCODECREATE& create); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the number of bytes used by the tree. * \return amount of bytes used */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// override(BaseModel) udword GetUsedBytes() const; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Refits the collision model. This can be used to handle dynamic meshes. Usage is: * 1. modify your mesh vertices (keep the topology constant!) * 2. refit the tree (call this method) * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// override(BaseModel) bool Refit(); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets array of triangles. * \return array of triangles */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ const LeafTriangles* GetLeafTriangles() const { return mTriangles; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets array of indices. * \return array of indices */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ const udword* GetIndices() const { return mIndices; } private: udword mNbLeaves; //!< Number of leaf nodes in the model LeafTriangles* mTriangles; //!< Array of mNbLeaves leaf descriptors udword mNbPrimitives; //!< Number of primitives in the model udword* mIndices; //!< Array of primitive indices // Internal methods void Release(); }; #endif // __OPC_HYBRIDMODEL_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_Collider.cpp0000600000175000017500000000541512161402010023264 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains base collider class. * \file OPC_Collider.cpp * \author Pierre Terdiman * \date June, 2, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains the abstract class for colliders. * * \class Collider * \author Pierre Terdiman * \version 1.3 * \date June, 2, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace Opcode; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Collider::Collider() : mFlags (0), mCurrentModel (null), mIMesh (null) { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Destructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Collider::~Collider() { } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_Picking.h0000600000175000017500000000405412161402010022556 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code to perform "picking". * \file OPC_Picking.h * \author Pierre Terdiman * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __OPC_PICKING_H__ #define __OPC_PICKING_H__ #ifdef OPC_RAYHIT_CALLBACK enum CullMode { CULLMODE_NONE = 0, CULLMODE_CW = 1, CULLMODE_CCW = 2 }; typedef CullMode (*CullModeCallback)(udword triangle_index, void* user_data); OPCODE_API bool SetupAllHits (RayCollider& collider, CollisionFaces& contacts); OPCODE_API bool SetupClosestHit (RayCollider& collider, CollisionFace& closest_contact); OPCODE_API bool SetupShadowFeeler (RayCollider& collider); OPCODE_API bool SetupInOutTest (RayCollider& collider); OPCODE_API bool Picking( CollisionFace& picked_face, const Ray& world_ray, const Model& model, const Matrix4x4* world, float min_dist, float max_dist, const Point& view_point, CullModeCallback callback, void* user_data); #endif #endif //__OPC_PICKING_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_SphereTriOverlap.h0000600000175000017500000001053512161402010024431 0ustar zero79zero79 // This is collision detection. If you do another distance test for collision *response*, // if might be useful to simply *skip* the test below completely, and report a collision. // - if sphere-triangle overlap, result is ok // - if they don't, we'll discard them during collision response with a similar test anyway // Overall this approach should run faster. // Original code by David Eberly in Magic. BOOL SphereCollider::SphereTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2) { // Stats mNbVolumePrimTests++; // Early exit if one of the vertices is inside the sphere Point kDiff = vert2 - mCenter; float fC = kDiff.SquareMagnitude(); if(fC <= mRadius2) return TRUE; kDiff = vert1 - mCenter; fC = kDiff.SquareMagnitude(); if(fC <= mRadius2) return TRUE; kDiff = vert0 - mCenter; fC = kDiff.SquareMagnitude(); if(fC <= mRadius2) return TRUE; // Else do the full distance test Point TriEdge0 = vert1 - vert0; Point TriEdge1 = vert2 - vert0; //Point kDiff = vert0 - mCenter; float fA00 = TriEdge0.SquareMagnitude(); float fA01 = TriEdge0 | TriEdge1; float fA11 = TriEdge1.SquareMagnitude(); float fB0 = kDiff | TriEdge0; float fB1 = kDiff | TriEdge1; //float fC = kDiff.SquareMagnitude(); float fDet = fabsf(fA00*fA11 - fA01*fA01); float u = fA01*fB1-fA11*fB0; float v = fA01*fB0-fA00*fB1; float SqrDist; if(u + v <= fDet) { if(u < 0.0f) { if(v < 0.0f) // region 4 { if(fB0 < 0.0f) { // v = 0.0f; if(-fB0>=fA00) { /*u = 1.0f;*/ SqrDist = fA00+2.0f*fB0+fC; } else { u = -fB0/fA00; SqrDist = fB0*u+fC; } } else { // u = 0.0f; if(fB1>=0.0f) { /*v = 0.0f;*/ SqrDist = fC; } else if(-fB1>=fA11) { /*v = 1.0f;*/ SqrDist = fA11+2.0f*fB1+fC; } else { v = -fB1/fA11; SqrDist = fB1*v+fC; } } } else // region 3 { // u = 0.0f; if(fB1>=0.0f) { /*v = 0.0f;*/ SqrDist = fC; } else if(-fB1>=fA11) { /*v = 1.0f;*/ SqrDist = fA11+2.0f*fB1+fC; } else { v = -fB1/fA11; SqrDist = fB1*v+fC; } } } else if(v < 0.0f) // region 5 { // v = 0.0f; if(fB0>=0.0f) { /*u = 0.0f;*/ SqrDist = fC; } else if(-fB0>=fA00) { /*u = 1.0f;*/ SqrDist = fA00+2.0f*fB0+fC; } else { u = -fB0/fA00; SqrDist = fB0*u+fC; } } else // region 0 { // minimum at interior point if(fDet==0.0f) { // u = 0.0f; // v = 0.0f; SqrDist = MAX_FLOAT; } else { float fInvDet = 1.0f/fDet; u *= fInvDet; v *= fInvDet; SqrDist = u*(fA00*u+fA01*v+2.0f*fB0) + v*(fA01*u+fA11*v+2.0f*fB1)+fC; } } } else { float fTmp0, fTmp1, fNumer, fDenom; if(u < 0.0f) // region 2 { fTmp0 = fA01 + fB0; fTmp1 = fA11 + fB1; if(fTmp1 > fTmp0) { fNumer = fTmp1 - fTmp0; fDenom = fA00-2.0f*fA01+fA11; if(fNumer >= fDenom) { // u = 1.0f; // v = 0.0f; SqrDist = fA00+2.0f*fB0+fC; } else { u = fNumer/fDenom; v = 1.0f - u; SqrDist = u*(fA00*u+fA01*v+2.0f*fB0) + v*(fA01*u+fA11*v+2.0f*fB1)+fC; } } else { // u = 0.0f; if(fTmp1 <= 0.0f) { /*v = 1.0f;*/ SqrDist = fA11+2.0f*fB1+fC; } else if(fB1 >= 0.0f) { /*v = 0.0f;*/ SqrDist = fC; } else { v = -fB1/fA11; SqrDist = fB1*v+fC; } } } else if(v < 0.0f) // region 6 { fTmp0 = fA01 + fB1; fTmp1 = fA00 + fB0; if(fTmp1 > fTmp0) { fNumer = fTmp1 - fTmp0; fDenom = fA00-2.0f*fA01+fA11; if(fNumer >= fDenom) { // v = 1.0f; // u = 0.0f; SqrDist = fA11+2.0f*fB1+fC; } else { v = fNumer/fDenom; u = 1.0f - v; SqrDist = u*(fA00*u+fA01*v+2.0f*fB0) + v*(fA01*u+fA11*v+2.0f*fB1)+fC; } } else { // v = 0.0f; if(fTmp1 <= 0.0f) { /*u = 1.0f;*/ SqrDist = fA00+2.0f*fB0+fC; } else if(fB0 >= 0.0f) { /*u = 0.0f;*/ SqrDist = fC; } else { u = -fB0/fA00; SqrDist = fB0*u+fC; } } } else // region 1 { fNumer = fA11 + fB1 - fA01 - fB0; if(fNumer <= 0.0f) { // u = 0.0f; // v = 1.0f; SqrDist = fA11+2.0f*fB1+fC; } else { fDenom = fA00-2.0f*fA01+fA11; if(fNumer >= fDenom) { // u = 1.0f; // v = 0.0f; SqrDist = fA00+2.0f*fB0+fC; } else { u = fNumer/fDenom; v = 1.0f - u; SqrDist = u*(fA00*u+fA01*v+2.0f*fB0) + v*(fA01*u+fA11*v+2.0f*fB1)+fC; } } } } return fabsf(SqrDist) < mRadius2; } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_OptimizedTree.cpp0000600000175000017500000007757312161402010024331 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for optimized trees. Implements 4 trees: * - normal * - no leaf * - quantized * - no leaf / quantized * * \file OPC_OptimizedTree.cpp * \author Pierre Terdiman * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * A standard AABB tree. * * \class AABBCollisionTree * \author Pierre Terdiman * \version 1.3 * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * A no-leaf AABB tree. * * \class AABBNoLeafTree * \author Pierre Terdiman * \version 1.3 * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * A quantized AABB tree. * * \class AABBQuantizedTree * \author Pierre Terdiman * \version 1.3 * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * A quantized no-leaf AABB tree. * * \class AABBQuantizedNoLeafTree * \author Pierre Terdiman * \version 1.3 * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace Opcode; //! Compilation flag: //! - true to fix quantized boxes (i.e. make sure they enclose the original ones) //! - false to see the effects of quantization errors (faster, but wrong results in some cases) static const bool gFixQuantized = true; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Builds an implicit tree from a standard one. An implicit tree is a complete tree (2*N-1 nodes) whose negative * box pointers and primitive pointers have been made implicit, hence packing 3 pointers in one. * * Layout for implicit trees: * Node: * - box * - data (32-bits value) * * if data's LSB = 1 => remaining bits are a primitive pointer * else remaining bits are a P-node pointer, and N = P + 1 * * \relates AABBCollisionNode * \fn _BuildCollisionTree(AABBCollisionNode* linear, const udword box_id, udword& current_id, const AABBTreeNode* current_node) * \param linear [in] base address of destination nodes * \param box_id [in] index of destination node * \param current_id [in] current running index * \param current_node [in] current node from input tree */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static void _BuildCollisionTree(AABBCollisionNode* linear, const udword box_id, udword& current_id, const AABBTreeNode* current_node) { // Current node from input tree is "current_node". Must be flattened into "linear[boxid]". // Store the AABB current_node->GetAABB()->GetCenter(linear[box_id].mAABB.mCenter); current_node->GetAABB()->GetExtents(linear[box_id].mAABB.mExtents); // Store remaining info if(current_node->IsLeaf()) { // The input tree must be complete => i.e. one primitive/leaf ASSERT(current_node->GetNbPrimitives()==1); // Get the primitive index from the input tree udword PrimitiveIndex = current_node->GetPrimitives()[0]; // Setup box data as the primitive index, marked as leaf linear[box_id].mData = (PrimitiveIndex<<1)|1; } else { // To make the negative one implicit, we must store P and N in successive order udword PosID = current_id++; // Get a new id for positive child udword NegID = current_id++; // Get a new id for negative child // Setup box data as the forthcoming new P pointer linear[box_id].mData = (size_t)&linear[PosID]; // Make sure it's not marked as leaf ASSERT(!(linear[box_id].mData&1)); // Recurse with new IDs _BuildCollisionTree(linear, PosID, current_id, current_node->GetPos()); _BuildCollisionTree(linear, NegID, current_id, current_node->GetNeg()); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Builds a "no-leaf" tree from a standard one. This is a tree whose leaf nodes have been removed. * * Layout for no-leaf trees: * * Node: * - box * - P pointer => a node (LSB=0) or a primitive (LSB=1) * - N pointer => a node (LSB=0) or a primitive (LSB=1) * * \relates AABBNoLeafNode * \fn _BuildNoLeafTree(AABBNoLeafNode* linear, const udword box_id, udword& current_id, const AABBTreeNode* current_node) * \param linear [in] base address of destination nodes * \param box_id [in] index of destination node * \param current_id [in] current running index * \param current_node [in] current node from input tree */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static void _BuildNoLeafTree(AABBNoLeafNode* linear, const udword box_id, udword& current_id, const AABBTreeNode* current_node) { const AABBTreeNode* P = current_node->GetPos(); const AABBTreeNode* N = current_node->GetNeg(); // Leaf nodes here?! ASSERT(P); ASSERT(N); // Internal node => keep the box current_node->GetAABB()->GetCenter(linear[box_id].mAABB.mCenter); current_node->GetAABB()->GetExtents(linear[box_id].mAABB.mExtents); if(P->IsLeaf()) { // The input tree must be complete => i.e. one primitive/leaf ASSERT(P->GetNbPrimitives()==1); // Get the primitive index from the input tree udword PrimitiveIndex = P->GetPrimitives()[0]; // Setup prev box data as the primitive index, marked as leaf linear[box_id].mPosData = (PrimitiveIndex<<1)|1; } else { // Get a new id for positive child udword PosID = current_id++; // Setup box data linear[box_id].mPosData = (size_t)&linear[PosID]; // Make sure it's not marked as leaf ASSERT(!(linear[box_id].mPosData&1)); // Recurse _BuildNoLeafTree(linear, PosID, current_id, P); } if(N->IsLeaf()) { // The input tree must be complete => i.e. one primitive/leaf ASSERT(N->GetNbPrimitives()==1); // Get the primitive index from the input tree udword PrimitiveIndex = N->GetPrimitives()[0]; // Setup prev box data as the primitive index, marked as leaf linear[box_id].mNegData = (PrimitiveIndex<<1)|1; } else { // Get a new id for negative child udword NegID = current_id++; // Setup box data linear[box_id].mNegData = (size_t)&linear[NegID]; // Make sure it's not marked as leaf ASSERT(!(linear[box_id].mNegData&1)); // Recurse _BuildNoLeafTree(linear, NegID, current_id, N); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// AABBCollisionTree::AABBCollisionTree() : mNodes(null) { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Destructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// AABBCollisionTree::~AABBCollisionTree() { DELETEARRAY(mNodes); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Builds the collision tree from a generic AABB tree. * \param tree [in] generic AABB tree * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool AABBCollisionTree::Build(AABBTree* tree) { // Checkings if(!tree) return false; // Check the input tree is complete udword NbTriangles = tree->GetNbPrimitives(); udword NbNodes = tree->GetNbNodes(); if(NbNodes!=NbTriangles*2-1) return false; // Get nodes if(mNbNodes!=NbNodes) // Same number of nodes => keep moving { mNbNodes = NbNodes; DELETEARRAY(mNodes); mNodes = new AABBCollisionNode[mNbNodes]; CHECKALLOC(mNodes); } // Build the tree udword CurID = 1; _BuildCollisionTree(mNodes, 0, CurID, tree); ASSERT(CurID==mNbNodes); return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Refits the collision tree after vertices have been modified. * \param mesh_interface [in] mesh interface for current model * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool AABBCollisionTree::Refit(const MeshInterface* mesh_interface) { ASSERT(!"Not implemented since AABBCollisionTrees have twice as more nodes to refit as AABBNoLeafTrees!"); return false; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Walks the tree and call the user back for each node. * \param callback [in] walking callback * \param user_data [in] callback's user data * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool AABBCollisionTree::Walk(GenericWalkingCallback callback, void* user_data) const { if(!callback) return false; struct Local { static void _Walk(const AABBCollisionNode* current_node, GenericWalkingCallback callback, void* user_data) { if(!current_node || !(callback)(current_node, user_data)) return; if(!current_node->IsLeaf()) { _Walk(current_node->GetPos(), callback, user_data); _Walk(current_node->GetNeg(), callback, user_data); } } }; Local::_Walk(mNodes, callback, user_data); return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// AABBNoLeafTree::AABBNoLeafTree() : mNodes(null) { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Destructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// AABBNoLeafTree::~AABBNoLeafTree() { DELETEARRAY(mNodes); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Builds the collision tree from a generic AABB tree. * \param tree [in] generic AABB tree * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool AABBNoLeafTree::Build(AABBTree* tree) { // Checkings if(!tree) return false; // Check the input tree is complete udword NbTriangles = tree->GetNbPrimitives(); udword NbNodes = tree->GetNbNodes(); if(NbNodes!=NbTriangles*2-1) return false; // Get nodes if(mNbNodes!=NbTriangles-1) // Same number of nodes => keep moving { mNbNodes = NbTriangles-1; DELETEARRAY(mNodes); mNodes = new AABBNoLeafNode[mNbNodes]; CHECKALLOC(mNodes); } // Build the tree udword CurID = 1; _BuildNoLeafTree(mNodes, 0, CurID, tree); ASSERT(CurID==mNbNodes); return true; } inline_ void ComputeMinMax(Point& min, Point& max, const VertexPointers& vp) { // Compute triangle's AABB = a leaf box #ifdef OPC_USE_FCOMI // a 15% speedup on my machine, not much min.x = FCMin3(vp.Vertex[0]->x, vp.Vertex[1]->x, vp.Vertex[2]->x); max.x = FCMax3(vp.Vertex[0]->x, vp.Vertex[1]->x, vp.Vertex[2]->x); min.y = FCMin3(vp.Vertex[0]->y, vp.Vertex[1]->y, vp.Vertex[2]->y); max.y = FCMax3(vp.Vertex[0]->y, vp.Vertex[1]->y, vp.Vertex[2]->y); min.z = FCMin3(vp.Vertex[0]->z, vp.Vertex[1]->z, vp.Vertex[2]->z); max.z = FCMax3(vp.Vertex[0]->z, vp.Vertex[1]->z, vp.Vertex[2]->z); #else min = *vp.Vertex[0]; max = *vp.Vertex[0]; min.Min(*vp.Vertex[1]); max.Max(*vp.Vertex[1]); min.Min(*vp.Vertex[2]); max.Max(*vp.Vertex[2]); #endif } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Refits the collision tree after vertices have been modified. * \param mesh_interface [in] mesh interface for current model * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool AABBNoLeafTree::Refit(const MeshInterface* mesh_interface) { // Checkings if(!mesh_interface) return false; // Bottom-up update VertexPointers VP; ConversionArea VC; Point Min,Max; Point Min_,Max_; udword Index = mNbNodes; while(Index--) { AABBNoLeafNode& Current = mNodes[Index]; if(Current.HasPosLeaf()) { mesh_interface->GetTriangle(VP, Current.GetPosPrimitive(), VC); ComputeMinMax(Min, Max, VP); } else { const CollisionAABB& CurrentBox = Current.GetPos()->mAABB; CurrentBox.GetMin(Min); CurrentBox.GetMax(Max); } if(Current.HasNegLeaf()) { mesh_interface->GetTriangle(VP, Current.GetNegPrimitive(), VC); ComputeMinMax(Min_, Max_, VP); } else { const CollisionAABB& CurrentBox = Current.GetNeg()->mAABB; CurrentBox.GetMin(Min_); CurrentBox.GetMax(Max_); } #ifdef OPC_USE_FCOMI Min.x = FCMin2(Min.x, Min_.x); Max.x = FCMax2(Max.x, Max_.x); Min.y = FCMin2(Min.y, Min_.y); Max.y = FCMax2(Max.y, Max_.y); Min.z = FCMin2(Min.z, Min_.z); Max.z = FCMax2(Max.z, Max_.z); #else Min.Min(Min_); Max.Max(Max_); #endif Current.mAABB.SetMinMax(Min, Max); } return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Walks the tree and call the user back for each node. * \param callback [in] walking callback * \param user_data [in] callback's user data * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool AABBNoLeafTree::Walk(GenericWalkingCallback callback, void* user_data) const { if(!callback) return false; struct Local { static void _Walk(const AABBNoLeafNode* current_node, GenericWalkingCallback callback, void* user_data) { if(!current_node || !(callback)(current_node, user_data)) return; if(!current_node->HasPosLeaf()) _Walk(current_node->GetPos(), callback, user_data); if(!current_node->HasNegLeaf()) _Walk(current_node->GetNeg(), callback, user_data); } }; Local::_Walk(mNodes, callback, user_data); return true; } // Quantization notes: // - We could use the highest bits of mData to store some more quantized bits. Dequantization code // would be slightly more complex, but number of overlap tests would be reduced (and anyhow those // bits are currently wasted). Of course it's not possible if we move to 16 bits mData. // - Something like "16 bits floats" could be tested, to bypass the int-to-float conversion. // - A dedicated BV-BV test could be used, dequantizing while testing for overlap. (i.e. it's some // lazy-dequantization which may save some work in case of early exits). At the very least some // muls could be saved by precomputing several more matrices. But maybe not worth the pain. // - Do we need to dequantize anyway? Not doing the extents-related muls only implies the box has // been scaled, for example. // - The deeper we move into the hierarchy, the smaller the extents should be. May not need a fixed // number of quantization bits. Even better, could probably be best delta-encoded. // Find max values. Some people asked why I wasn't simply using the first node. Well, I can't. // I'm not looking for (min, max) values like in a standard AABB, I'm looking for the extremal // centers/extents in order to quantize them. The first node would only give a single center and // a single extents. While extents would be the biggest, the center wouldn't. #define FIND_MAX_VALUES \ /* Get max values */ \ Point CMax(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); \ Point EMax(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); \ for(udword i=0;iCMax.x) CMax.x = fabsf(Nodes[i].mAABB.mCenter.x); \ if(fabsf(Nodes[i].mAABB.mCenter.y)>CMax.y) CMax.y = fabsf(Nodes[i].mAABB.mCenter.y); \ if(fabsf(Nodes[i].mAABB.mCenter.z)>CMax.z) CMax.z = fabsf(Nodes[i].mAABB.mCenter.z); \ if(fabsf(Nodes[i].mAABB.mExtents.x)>EMax.x) EMax.x = fabsf(Nodes[i].mAABB.mExtents.x); \ if(fabsf(Nodes[i].mAABB.mExtents.y)>EMax.y) EMax.y = fabsf(Nodes[i].mAABB.mExtents.y); \ if(fabsf(Nodes[i].mAABB.mExtents.z)>EMax.z) EMax.z = fabsf(Nodes[i].mAABB.mExtents.z); \ } #define INIT_QUANTIZATION \ udword nbc=15; /* Keep one bit for sign */ \ udword nbe=15; /* Keep one bit for fix */ \ if(!gFixQuantized) nbe++; \ \ /* Compute quantization coeffs */ \ Point CQuantCoeff, EQuantCoeff; \ CQuantCoeff.x = CMax.x!=0.0f ? float((1<Min[j]) mNodes[i].mAABB.mExtents[j]++; \ else FixMe=false; \ /* Prevent wrapping */ \ if(!mNodes[i].mAABB.mExtents[j]) \ { \ mNodes[i].mAABB.mExtents[j]=0xffff; \ FixMe=false; \ } \ }while(FixMe); \ } \ } #define REMAP_DATA(member) \ /* Fix data */ \ Data = Nodes[i].member; \ if(!(Data&1)) \ { \ /* Compute box number */ \ size_t Nb = (Data - size_t(Nodes))/Nodes[i].GetNodeSize(); \ Data = (size_t) &mNodes[Nb]; \ } \ /* ...remapped */ \ mNodes[i].member = Data; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// AABBQuantizedTree::AABBQuantizedTree() : mNodes(null) { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Destructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// AABBQuantizedTree::~AABBQuantizedTree() { DELETEARRAY(mNodes); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Builds the collision tree from a generic AABB tree. * \param tree [in] generic AABB tree * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool AABBQuantizedTree::Build(AABBTree* tree) { // Checkings if(!tree) return false; // Check the input tree is complete udword NbTriangles = tree->GetNbPrimitives(); udword NbNodes = tree->GetNbNodes(); if(NbNodes!=NbTriangles*2-1) return false; // Get nodes mNbNodes = NbNodes; DELETEARRAY(mNodes); AABBCollisionNode* Nodes = new AABBCollisionNode[mNbNodes]; CHECKALLOC(Nodes); // Build the tree udword CurID = 1; _BuildCollisionTree(Nodes, 0, CurID, tree); // Quantize { mNodes = new AABBQuantizedNode[mNbNodes]; CHECKALLOC(mNodes); // Get max values FIND_MAX_VALUES // Quantization INIT_QUANTIZATION // Quantize size_t Data; for(udword i=0;iIsLeaf()) { _Walk(current_node->GetPos(), callback, user_data); _Walk(current_node->GetNeg(), callback, user_data); } } }; Local::_Walk(mNodes, callback, user_data); return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// AABBQuantizedNoLeafTree::AABBQuantizedNoLeafTree() : mNodes(null) { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Destructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// AABBQuantizedNoLeafTree::~AABBQuantizedNoLeafTree() { DELETEARRAY(mNodes); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Builds the collision tree from a generic AABB tree. * \param tree [in] generic AABB tree * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool AABBQuantizedNoLeafTree::Build(AABBTree* tree) { // Checkings if(!tree) return false; // Check the input tree is complete udword NbTriangles = tree->GetNbPrimitives(); udword NbNodes = tree->GetNbNodes(); if(NbNodes!=NbTriangles*2-1) return false; // Get nodes mNbNodes = NbTriangles-1; DELETEARRAY(mNodes); AABBNoLeafNode* Nodes = new AABBNoLeafNode[mNbNodes]; CHECKALLOC(Nodes); // Build the tree udword CurID = 1; _BuildNoLeafTree(Nodes, 0, CurID, tree); ASSERT(CurID==mNbNodes); // Quantize { mNodes = new AABBQuantizedNoLeafNode[mNbNodes]; CHECKALLOC(mNodes); // Get max values FIND_MAX_VALUES // Quantization INIT_QUANTIZATION // Quantize size_t Data; for(udword i=0;iHasPosLeaf()) _Walk(current_node->GetPos(), callback, user_data); if(!current_node->HasNegLeaf()) _Walk(current_node->GetNeg(), callback, user_data); } }; Local::_Walk(mNodes, callback, user_data); return true; } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_RayTriOverlap.h0000600000175000017500000000657012161402010023742 0ustar zero79zero79#define LOCAL_EPSILON 0.000001f /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes a ray-triangle intersection test. * Original code from Tomas Mller's "Fast Minimum Storage Ray-Triangle Intersection". * It's been optimized a bit with integer code, and modified to return a non-intersection if distance from * ray origin to triangle is negative. * * \param vert0 [in] triangle vertex * \param vert1 [in] triangle vertex * \param vert2 [in] triangle vertex * \return true on overlap. mStabbedFace is filled with relevant info. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL RayCollider::RayTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2) { // Stats mNbRayPrimTests++; // Find vectors for two edges sharing vert0 Point edge1 = vert1 - vert0; Point edge2 = vert2 - vert0; // Begin calculating determinant - also used to calculate U parameter Point pvec = mDir^edge2; // If determinant is near zero, ray lies in plane of triangle float det = edge1|pvec; if(mCulling) { if(det 0. So we can use integer cmp. // Calculate distance from vert0 to ray origin Point tvec = mOrigin - vert0; // Calculate U parameter and test bounds mStabbedFace.mU = tvec|pvec; // if(IR(u)&0x80000000 || u>det) return FALSE; if(IS_NEGATIVE_FLOAT(mStabbedFace.mU) || IR(mStabbedFace.mU)>IR(det)) return FALSE; // Prepare to test V parameter Point qvec = tvec^edge1; // Calculate V parameter and test bounds mStabbedFace.mV = mDir|qvec; if(IS_NEGATIVE_FLOAT(mStabbedFace.mV) || mStabbedFace.mU+mStabbedFace.mV>det) return FALSE; // Calculate t, scale parameters, ray intersects triangle mStabbedFace.mDistance = edge2|qvec; // Det > 0 so we can early exit here // Intersection point is valid if distance is positive (else it can just be a face behind the orig point) if(IS_NEGATIVE_FLOAT(mStabbedFace.mDistance)) return FALSE; // Else go on float OneOverDet = 1.0f / det; mStabbedFace.mDistance *= OneOverDet; mStabbedFace.mU *= OneOverDet; mStabbedFace.mV *= OneOverDet; } else { // the non-culling branch if(det>-LOCAL_EPSILON && det1.0f) return FALSE; if(IS_NEGATIVE_FLOAT(mStabbedFace.mU) || IR(mStabbedFace.mU)>IEEE_1_0) return FALSE; // prepare to test V parameter Point qvec = tvec^edge1; // Calculate V parameter and test bounds mStabbedFace.mV = (mDir|qvec) * OneOverDet; if(IS_NEGATIVE_FLOAT(mStabbedFace.mV) || mStabbedFace.mU+mStabbedFace.mV>1.0f) return FALSE; // Calculate t, ray intersects triangle mStabbedFace.mDistance = (edge2|qvec) * OneOverDet; // Intersection point is valid if distance is positive (else it can just be a face behind the orig point) if(IS_NEGATIVE_FLOAT(mStabbedFace.mDistance)) return FALSE; } return TRUE; } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Opcode.cpp0000600000175000017500000000405112161402010022232 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Main file for Opcode.dll. * \file Opcode.cpp * \author Pierre Terdiman * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* Finding a good name is difficult! Here's the draft for this lib.... Spooky, uh? VOID? Very Optimized Interference Detection ZOID? Zappy's Optimized Interference Detection CID? Custom/Clever Interference Detection AID / ACID! Accurate Interference Detection QUID? Quick Interference Detection RIDE? Realtime Interference DEtection WIDE? Wicked Interference DEtection (....) GUID! KID ! k-dop interference detection :) OPCODE! OPtimized COllision DEtection */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace Opcode; bool Opcode::InitOpcode() { //Log("// Initializing OPCODE\n\n"); // LogAPIInfo(); return true; } bool Opcode::CloseOpcode() { //Log("// Closing OPCODE\n\n"); return true; } #ifdef ICE_MAIN void ModuleAttach(HINSTANCE hinstance) { } void ModuleDetach() { } #endif alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Opcode.h0000600000175000017500000000753512161402010021711 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Main file for Opcode.dll. * \file Opcode.h * \author Pierre Terdiman * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __OPCODE_H__ #define __OPCODE_H__ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Things to help us compile on non-windows platforms #if defined(__APPLE__) || defined(__MACOSX__) #if __APPLE_CC__ < 1495 #define sqrtf sqrt #define sinf sin #define cosf cos #define acosf acos #define asinf asin #endif #endif #ifndef _MSC_VER #ifndef __int64 #define __int64 long long int #endif #ifndef __stdcall /* this is defined in MinGW and CygWin, so avoid the warning */ #define __stdcall /* */ #endif #endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Compilation messages #ifdef _MSC_VER #if defined(OPCODE_EXPORTS) // #pragma message("Compiling OPCODE") #elif !defined(OPCODE_EXPORTS) // #pragma message("Using OPCODE") /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Automatic linking #ifndef BAN_OPCODE_AUTOLINK #ifdef _DEBUG //#pragma comment(lib, "Opcode_D.lib") #else //#pragma comment(lib, "Opcode.lib") #endif #endif #endif #endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Preprocessor #ifndef ICE_NO_DLL #ifdef OPCODE_EXPORTS #define OPCODE_API// __declspec(dllexport) #else #define OPCODE_API// __declspec(dllimport) #endif #else #define OPCODE_API #endif #include "OPC_Settings.h" #include "OPC_IceHook.h" namespace Opcode { // Bulk-of-the-work #include "OPC_Common.h" #include "OPC_MeshInterface.h" // Builders #include "OPC_TreeBuilders.h" // Trees #include "OPC_AABBTree.h" #include "OPC_OptimizedTree.h" // Models #include "OPC_BaseModel.h" #include "OPC_Model.h" #include "OPC_HybridModel.h" // Colliders #include "OPC_Collider.h" #include "OPC_VolumeCollider.h" #include "OPC_TreeCollider.h" #include "OPC_RayCollider.h" #include "OPC_SphereCollider.h" #include "OPC_OBBCollider.h" #include "OPC_AABBCollider.h" #include "OPC_LSSCollider.h" #include "OPC_PlanesCollider.h" // Usages #include "OPC_Picking.h" FUNCTION OPCODE_API bool InitOpcode(); FUNCTION OPCODE_API bool CloseOpcode(); } #endif // __OPCODE_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_PlanesTriOverlap.h0000600000175000017500000000256612161402010024432 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Planes-triangle overlap test. * \param in_clip_mask [in] bitmask for active planes * \return TRUE if triangle overlap planes * \warning THIS IS A CONSERVATIVE TEST !! Some triangles will be returned as intersecting, while they're not! */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL PlanesCollider::PlanesTriOverlap(udword in_clip_mask) { // Stats mNbVolumePrimTests++; const Plane* p = mPlanes; udword Mask = 1; while(Mask<=in_clip_mask) { if(in_clip_mask & Mask) { float d0 = p->Distance(*mVP.Vertex[0]); float d1 = p->Distance(*mVP.Vertex[1]); float d2 = p->Distance(*mVP.Vertex[2]); if(d0>0.0f && d1>0.0f && d2>0.0f) return FALSE; // if(!(IR(d0)&SIGN_BITMASK) && !(IR(d1)&SIGN_BITMASK) && !(IR(d2)&SIGN_BITMASK)) return FALSE; } Mask+=Mask; p++; } /* for(udword i=0;i<6;i++) { float d0 = p[i].Distance(mLeafVerts[0]); float d1 = p[i].Distance(mLeafVerts[1]); float d2 = p[i].Distance(mLeafVerts[2]); if(d0>0.0f && d1>0.0f && d2>0.0f) return false; } */ return TRUE; } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_TriTriOverlap.h0000600000175000017500000002027312161402010023741 0ustar zero79zero79 //! if OPC_TRITRI_EPSILON_TEST is true then we do a check (if |dv|b) \ { \ const float c=a; \ a=b; \ b=c; \ } //! Edge to edge test based on Franlin Antonio's gem: "Faster Line Segment Intersection", in Graphics Gems III, pp. 199-202 #define EDGE_EDGE_TEST(V0, U0, U1) \ Bx = U0[i0] - U1[i0]; \ By = U0[i1] - U1[i1]; \ Cx = V0[i0] - U0[i0]; \ Cy = V0[i1] - U0[i1]; \ f = Ay*Bx - Ax*By; \ d = By*Cx - Bx*Cy; \ if((f>0.0f && d>=0.0f && d<=f) || (f<0.0f && d<=0.0f && d>=f)) \ { \ const float e=Ax*Cy - Ay*Cx; \ if(f>0.0f) \ { \ if(e>=0.0f && e<=f) return TRUE; \ } \ else \ { \ if(e<=0.0f && e>=f) return TRUE; \ } \ } //! TO BE DOCUMENTED #define EDGE_AGAINST_TRI_EDGES(V0, V1, U0, U1, U2) \ { \ float Bx,By,Cx,Cy,d,f; \ const float Ax = V1[i0] - V0[i0]; \ const float Ay = V1[i1] - V0[i1]; \ /* test edge U0,U1 against V0,V1 */ \ EDGE_EDGE_TEST(V0, U0, U1); \ /* test edge U1,U2 against V0,V1 */ \ EDGE_EDGE_TEST(V0, U1, U2); \ /* test edge U2,U1 against V0,V1 */ \ EDGE_EDGE_TEST(V0, U2, U0); \ } //! TO BE DOCUMENTED #define POINT_IN_TRI(V0, U0, U1, U2) \ { \ /* is T1 completly inside T2? */ \ /* check if V0 is inside tri(U0,U1,U2) */ \ float a = U1[i1] - U0[i1]; \ float b = -(U1[i0] - U0[i0]); \ float c = -a*U0[i0] - b*U0[i1]; \ float d0 = a*V0[i0] + b*V0[i1] + c; \ \ a = U2[i1] - U1[i1]; \ b = -(U2[i0] - U1[i0]); \ c = -a*U1[i0] - b*U1[i1]; \ const float d1 = a*V0[i0] + b*V0[i1] + c; \ \ a = U0[i1] - U2[i1]; \ b = -(U0[i0] - U2[i0]); \ c = -a*U2[i0] - b*U2[i1]; \ const float d2 = a*V0[i0] + b*V0[i1] + c; \ if(d0*d1>0.0f) \ { \ if(d0*d2>0.0f) return TRUE; \ } \ } //! TO BE DOCUMENTED BOOL CoplanarTriTri(const Point& n, const Point& v0, const Point& v1, const Point& v2, const Point& u0, const Point& u1, const Point& u2) { float A[3]; short i0,i1; /* first project onto an axis-aligned plane, that maximizes the area */ /* of the triangles, compute indices: i0,i1. */ A[0] = fabsf(n[0]); A[1] = fabsf(n[1]); A[2] = fabsf(n[2]); if(A[0]>A[1]) { if(A[0]>A[2]) { i0=1; /* A[0] is greatest */ i1=2; } else { i0=0; /* A[2] is greatest */ i1=1; } } else /* A[0]<=A[1] */ { if(A[2]>A[1]) { i0=0; /* A[2] is greatest */ i1=1; } else { i0=0; /* A[1] is greatest */ i1=2; } } /* test all edges of triangle 1 against the edges of triangle 2 */ EDGE_AGAINST_TRI_EDGES(v0, v1, u0, u1, u2); EDGE_AGAINST_TRI_EDGES(v1, v2, u0, u1, u2); EDGE_AGAINST_TRI_EDGES(v2, v0, u0, u1, u2); /* finally, test if tri1 is totally contained in tri2 or vice versa */ POINT_IN_TRI(v0, u0, u1, u2); POINT_IN_TRI(u0, v0, v1, v2); return FALSE; } //! TO BE DOCUMENTED #define NEWCOMPUTE_INTERVALS(VV0, VV1, VV2, D0, D1, D2, D0D1, D0D2, A, B, C, X0, X1) \ { \ if(D0D1>0.0f) \ { \ /* here we know that D0D2<=0.0 */ \ /* that is D0, D1 are on the same side, D2 on the other or on the plane */ \ A=VV2; B=(VV0 - VV2)*D2; C=(VV1 - VV2)*D2; X0=D2 - D0; X1=D2 - D1; \ } \ else if(D0D2>0.0f) \ { \ /* here we know that d0d1<=0.0 */ \ A=VV1; B=(VV0 - VV1)*D1; C=(VV2 - VV1)*D1; X0=D1 - D0; X1=D1 - D2; \ } \ else if(D1*D2>0.0f || D0!=0.0f) \ { \ /* here we know that d0d1<=0.0 or that D0!=0.0 */ \ A=VV0; B=(VV1 - VV0)*D0; C=(VV2 - VV0)*D0; X0=D0 - D1; X1=D0 - D2; \ } \ else if(D1!=0.0f) \ { \ A=VV1; B=(VV0 - VV1)*D1; C=(VV2 - VV1)*D1; X0=D1 - D0; X1=D1 - D2; \ } \ else if(D2!=0.0f) \ { \ A=VV2; B=(VV0 - VV2)*D2; C=(VV1 - VV2)*D2; X0=D2 - D0; X1=D2 - D1; \ } \ else \ { \ /* triangles are coplanar */ \ return CoplanarTriTri(N1, V0, V1, V2, U0, U1, U2); \ } \ } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Triangle/triangle intersection test routine, * by Tomas Moller, 1997. * See article "A Fast Triangle-Triangle Intersection Test", * Journal of Graphics Tools, 2(2), 1997 * * Updated June 1999: removed the divisions -- a little faster now! * Updated October 1999: added {} to CROSS and SUB macros * * int NoDivTriTriIsect(float V0[3],float V1[3],float V2[3], * float U0[3],float U1[3],float U2[3]) * * \param V0 [in] triangle 0, vertex 0 * \param V1 [in] triangle 0, vertex 1 * \param V2 [in] triangle 0, vertex 2 * \param U0 [in] triangle 1, vertex 0 * \param U1 [in] triangle 1, vertex 1 * \param U2 [in] triangle 1, vertex 2 * \return true if triangles overlap */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL AABBTreeCollider::TriTriOverlap(const Point& V0, const Point& V1, const Point& V2, const Point& U0, const Point& U1, const Point& U2) { // Stats mNbPrimPrimTests++; // Compute plane equation of triangle(V0,V1,V2) Point E1 = V1 - V0; Point E2 = V2 - V0; const Point N1 = E1 ^ E2; const float d1 =-N1 | V0; // Plane equation 1: N1.X+d1=0 // Put U0,U1,U2 into plane equation 1 to compute signed distances to the plane float du0 = (N1|U0) + d1; float du1 = (N1|U1) + d1; float du2 = (N1|U2) + d1; // Coplanarity robustness check #ifdef OPC_TRITRI_EPSILON_TEST if(fabsf(du0)0.0f && du0du2>0.0f) // same sign on all of them + not equal 0 ? return FALSE; // no intersection occurs // Compute plane of triangle (U0,U1,U2) E1 = U1 - U0; E2 = U2 - U0; const Point N2 = E1 ^ E2; const float d2=-N2 | U0; // plane equation 2: N2.X+d2=0 // put V0,V1,V2 into plane equation 2 float dv0 = (N2|V0) + d2; float dv1 = (N2|V1) + d2; float dv2 = (N2|V2) + d2; #ifdef OPC_TRITRI_EPSILON_TEST if(fabsf(dv0)0.0f && dv0dv2>0.0f) // same sign on all of them + not equal 0 ? return FALSE; // no intersection occurs // Compute direction of intersection line const Point D = N1^N2; // Compute and index to the largest component of D float max=fabsf(D[0]); short index=0; float bb=fabsf(D[1]); float cc=fabsf(D[2]); if(bb>max) max=bb,index=1; if(cc>max) max=cc,index=2; // This is the simplified projection onto L const float vp0 = V0[index]; const float vp1 = V1[index]; const float vp2 = V2[index]; const float up0 = U0[index]; const float up1 = U1[index]; const float up2 = U2[index]; // Compute interval for triangle 1 float a,b,c,x0,x1; NEWCOMPUTE_INTERVALS(vp0,vp1,vp2,dv0,dv1,dv2,dv0dv1,dv0dv2,a,b,c,x0,x1); // Compute interval for triangle 2 float d,e,f,y0,y1; NEWCOMPUTE_INTERVALS(up0,up1,up2,du0,du1,du2,du0du1,du0du2,d,e,f,y0,y1); const float xx=x0*x1; const float yy=y0*y1; const float xxyy=xx*yy; float isect1[2], isect2[2]; float tmp=a*xxyy; isect1[0]=tmp+b*x1*yy; isect1[1]=tmp+c*x0*yy; tmp=d*xxyy; isect2[0]=tmp+e*xx*y1; isect2[1]=tmp+f*xx*y0; SORT(isect1[0],isect1[1]); SORT(isect2[0],isect2[1]); if(isect1[1] extents.x + mFDir.x) return FALSE; float Dy = mData2.y - center.y; if(fabsf(Dy) > extents.y + mFDir.y) return FALSE; float Dz = mData2.z - center.z; if(fabsf(Dz) > extents.z + mFDir.z) return FALSE; float f; f = mData.y * Dz - mData.z * Dy; if(fabsf(f) > extents.y*mFDir.z + extents.z*mFDir.y) return FALSE; f = mData.z * Dx - mData.x * Dz; if(fabsf(f) > extents.x*mFDir.z + extents.z*mFDir.x) return FALSE; f = mData.x * Dy - mData.y * Dx; if(fabsf(f) > extents.x*mFDir.y + extents.y*mFDir.x) return FALSE; return TRUE; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes a ray-AABB overlap test using the separating axis theorem. Ray is cached within the class. * \param center [in] AABB center * \param extents [in] AABB extents * \return true on overlap */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL RayCollider::RayAABBOverlap(const Point& center, const Point& extents) { // Stats mNbRayBVTests++; // float Dx = mOrigin.x - center.x; if(fabsf(Dx) > extents.x && Dx*mDir.x>=0.0f) return FALSE; // float Dy = mOrigin.y - center.y; if(fabsf(Dy) > extents.y && Dy*mDir.y>=0.0f) return FALSE; // float Dz = mOrigin.z - center.z; if(fabsf(Dz) > extents.z && Dz*mDir.z>=0.0f) return FALSE; float Dx = mOrigin.x - center.x; if(GREATER(Dx, extents.x) && Dx*mDir.x>=0.0f) return FALSE; float Dy = mOrigin.y - center.y; if(GREATER(Dy, extents.y) && Dy*mDir.y>=0.0f) return FALSE; float Dz = mOrigin.z - center.z; if(GREATER(Dz, extents.z) && Dz*mDir.z>=0.0f) return FALSE; // float Dx = mOrigin.x - center.x; if(GREATER(Dx, extents.x) && ((SIR(Dx)-1)^SIR(mDir.x))>=0.0f) return FALSE; // float Dy = mOrigin.y - center.y; if(GREATER(Dy, extents.y) && ((SIR(Dy)-1)^SIR(mDir.y))>=0.0f) return FALSE; // float Dz = mOrigin.z - center.z; if(GREATER(Dz, extents.z) && ((SIR(Dz)-1)^SIR(mDir.z))>=0.0f) return FALSE; float f; f = mDir.y * Dz - mDir.z * Dy; if(fabsf(f) > extents.y*mFDir.z + extents.z*mFDir.y) return FALSE; f = mDir.z * Dx - mDir.x * Dz; if(fabsf(f) > extents.x*mFDir.z + extents.z*mFDir.x) return FALSE; f = mDir.x * Dy - mDir.y * Dx; if(fabsf(f) > extents.x*mFDir.y + extents.y*mFDir.x) return FALSE; return TRUE; } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_OptimizedTree.h0000600000175000017500000002227212161402010023760 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for optimized trees. * \file OPC_OptimizedTree.h * \author Pierre Terdiman * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __OPC_OPTIMIZEDTREE_H__ #define __OPC_OPTIMIZEDTREE_H__ //! Common interface for a node of an implicit tree #define IMPLEMENT_IMPLICIT_NODE(base_class, volume) \ public: \ /* Constructor / Destructor */ \ inline_ base_class() : mData(0) {} \ inline_ ~base_class() {} \ /* Leaf test */ \ inline_ BOOL IsLeaf() const { return (mData&1)!=0; } \ /* Data access */ \ inline_ const base_class* GetPos() const { return (base_class*)mData; } \ inline_ const base_class* GetNeg() const { return ((base_class*)mData)+1; } \ inline_ size_t GetPrimitive() const { return (mData>>1); } \ /* Stats */ \ inline_ udword GetNodeSize() const { return SIZEOFOBJECT; } \ \ volume mAABB; \ size_t mData; //! Common interface for a node of a no-leaf tree #define IMPLEMENT_NOLEAF_NODE(base_class, volume) \ public: \ /* Constructor / Destructor */ \ inline_ base_class() : mPosData(0), mNegData(0) {} \ inline_ ~base_class() {} \ /* Leaf tests */ \ inline_ BOOL HasPosLeaf() const { return (mPosData&1)!=0; } \ inline_ BOOL HasNegLeaf() const { return (mNegData&1)!=0; } \ /* Data access */ \ inline_ const base_class* GetPos() const { return (base_class*)mPosData; } \ inline_ const base_class* GetNeg() const { return (base_class*)mNegData; } \ inline_ size_t GetPosPrimitive() const { return (mPosData>>1); } \ inline_ size_t GetNegPrimitive() const { return (mNegData>>1); } \ /* Stats */ \ inline_ udword GetNodeSize() const { return SIZEOFOBJECT; } \ \ volume mAABB; \ size_t mPosData; \ size_t mNegData; class OPCODE_API AABBCollisionNode { IMPLEMENT_IMPLICIT_NODE(AABBCollisionNode, CollisionAABB) inline_ float GetVolume() const { return mAABB.mExtents.x * mAABB.mExtents.y * mAABB.mExtents.z; } inline_ float GetSize() const { return mAABB.mExtents.SquareMagnitude(); } inline_ udword GetRadius() const { udword* Bits = (udword*)&mAABB.mExtents.x; udword Max = Bits[0]; if(Bits[1]>Max) Max = Bits[1]; if(Bits[2]>Max) Max = Bits[2]; return Max; } // NB: using the square-magnitude or the true volume of the box, seems to yield better results // (assuming UNC-like informed traversal methods). I borrowed this idea from PQP. The usual "size" // otherwise, is the largest box extent. In SOLID that extent is computed on-the-fly each time it's // needed (the best approach IMHO). In RAPID the rotation matrix is permuted so that Extent[0] is // always the greatest, which saves looking for it at runtime. On the other hand, it yields matrices // whose determinant is not 1, i.e. you can't encode them anymore as unit quaternions. Not a very // good strategy. }; class OPCODE_API AABBQuantizedNode { IMPLEMENT_IMPLICIT_NODE(AABBQuantizedNode, QuantizedAABB) inline_ uword GetSize() const { const uword* Bits = mAABB.mExtents; uword Max = Bits[0]; if(Bits[1]>Max) Max = Bits[1]; if(Bits[2]>Max) Max = Bits[2]; return Max; } // NB: for quantized nodes I don't feel like computing a square-magnitude with integers all // over the place.......! }; class OPCODE_API AABBNoLeafNode { IMPLEMENT_NOLEAF_NODE(AABBNoLeafNode, CollisionAABB) }; class OPCODE_API AABBQuantizedNoLeafNode { IMPLEMENT_NOLEAF_NODE(AABBQuantizedNoLeafNode, QuantizedAABB) }; //! Common interface for a collision tree #define IMPLEMENT_COLLISION_TREE(base_class, node) \ public: \ /* Constructor / Destructor */ \ base_class(); \ virtual ~base_class(); \ /* Builds from a standard tree */ \ override(AABBOptimizedTree) bool Build(AABBTree* tree); \ /* Refits the tree */ \ override(AABBOptimizedTree) bool Refit(const MeshInterface* mesh_interface); \ /* Walks the tree */ \ override(AABBOptimizedTree) bool Walk(GenericWalkingCallback callback, void* user_data) const; \ /* Data access */ \ inline_ const node* GetNodes() const { return mNodes; } \ /* Stats */ \ override(AABBOptimizedTree) udword GetUsedBytes() const { return mNbNodes*sizeof(node); } \ private: \ node* mNodes; typedef bool (*GenericWalkingCallback) (const void* current, void* user_data); class OPCODE_API AABBOptimizedTree { public: // Constructor / Destructor AABBOptimizedTree() : mNbNodes (0) {} virtual ~AABBOptimizedTree() {} /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Builds the collision tree from a generic AABB tree. * \param tree [in] generic AABB tree * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// virtual bool Build(AABBTree* tree) = 0; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Refits the collision tree after vertices have been modified. * \param mesh_interface [in] mesh interface for current model * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// virtual bool Refit(const MeshInterface* mesh_interface) = 0; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Walks the tree and call the user back for each node. * \param callback [in] walking callback * \param user_data [in] callback's user data * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// virtual bool Walk(GenericWalkingCallback callback, void* user_data) const = 0; // Data access virtual udword GetUsedBytes() const = 0; inline_ udword GetNbNodes() const { return mNbNodes; } protected: udword mNbNodes; }; class OPCODE_API AABBCollisionTree : public AABBOptimizedTree { IMPLEMENT_COLLISION_TREE(AABBCollisionTree, AABBCollisionNode) }; class OPCODE_API AABBNoLeafTree : public AABBOptimizedTree { IMPLEMENT_COLLISION_TREE(AABBNoLeafTree, AABBNoLeafNode) }; class OPCODE_API AABBQuantizedTree : public AABBOptimizedTree { IMPLEMENT_COLLISION_TREE(AABBQuantizedTree, AABBQuantizedNode) public: Point mCenterCoeff; Point mExtentsCoeff; }; class OPCODE_API AABBQuantizedNoLeafTree : public AABBOptimizedTree { IMPLEMENT_COLLISION_TREE(AABBQuantizedNoLeafTree, AABBQuantizedNoLeafNode) public: Point mCenterCoeff; Point mExtentsCoeff; }; #endif // __OPC_OPTIMIZEDTREE_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_VolumeCollider.h0000600000175000017500000001572312161402010024124 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains base volume collider class. * \file OPC_VolumeCollider.h * \author Pierre Terdiman * \date June, 2, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __OPC_VOLUMECOLLIDER_H__ #define __OPC_VOLUMECOLLIDER_H__ struct OPCODE_API VolumeCache { VolumeCache() : Model(null) {} ~VolumeCache() {} Container TouchedPrimitives; //!< Indices of touched primitives const BaseModel* Model; //!< Owner }; class OPCODE_API VolumeCollider : public Collider { public: // Constructor / Destructor VolumeCollider(); virtual ~VolumeCollider() = 0; // Collision report /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the number of touched primitives after a collision query. * \see GetContactStatus() * \see GetTouchedPrimitives() * \return the number of touched primitives */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ udword GetNbTouchedPrimitives() const { return mTouchedPrimitives ? mTouchedPrimitives->GetNbEntries() : 0; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the list of touched primitives after a collision query. * \see GetContactStatus() * \see GetNbTouchedPrimitives() * \return the list of touched primitives (primitive indices) */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ const udword* GetTouchedPrimitives() const { return mTouchedPrimitives ? mTouchedPrimitives->GetEntries() : null; } // Stats /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Stats: gets the number of Volume-BV overlap tests after a collision query. * \see GetNbVolumePrimTests() * \return the number of Volume-BV tests performed during last query */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ udword GetNbVolumeBVTests() const { return mNbVolumeBVTests; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Stats: gets the number of Volume-Triangle overlap tests after a collision query. * \see GetNbVolumeBVTests() * \return the number of Volume-Triangle tests performed during last query */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ udword GetNbVolumePrimTests() const { return mNbVolumePrimTests; } // Settings /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Validates current settings. You should call this method after all the settings / callbacks have been defined for a collider. * \return null if everything is ok, else a string describing the problem */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// override(Collider) const char* ValidateSettings(); protected: // Touched primitives Container* mTouchedPrimitives; //!< List of touched primitives // Dequantization coeffs Point mCenterCoeff; Point mExtentsCoeff; // Stats udword mNbVolumeBVTests; //!< Number of Volume-BV tests udword mNbVolumePrimTests; //!< Number of Volume-Primitive tests // Internal methods void _Dump(const AABBCollisionNode* node); void _Dump(const AABBNoLeafNode* node); void _Dump(const AABBQuantizedNode* node); void _Dump(const AABBQuantizedNoLeafNode* node); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Initializes a query */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// override(Collider) inline_ void InitQuery() { // Reset stats & contact status mNbVolumeBVTests = 0; mNbVolumePrimTests = 0; Collider::InitQuery(); } inline_ BOOL IsCacheValid(VolumeCache& cache) { // We're going to do a volume-vs-model query. if(cache.Model!=mCurrentModel) { // Cached list was for another model so we can't keep it // Keep track of new owner and reset cache cache.Model = mCurrentModel; return FALSE; } else { // Same models, no problem return TRUE; } } }; #endif // __OPC_VOLUMECOLLIDER_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_PlanesCollider.cpp0000600000175000017500000006261212161402010024431 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for a planes collider. * \file OPC_PlanesCollider.cpp * \author Pierre Terdiman * \date January, 1st, 2002 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains a Planes-vs-tree collider. * * \class PlanesCollider * \author Pierre Terdiman * \version 1.3 * \date January, 1st, 2002 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace Opcode; #include "OPC_PlanesAABBOverlap.h" #include "OPC_PlanesTriOverlap.h" #define SET_CONTACT(prim_index, flag) \ /* Set contact status */ \ mFlags |= flag; \ mTouchedPrimitives->Add(udword(prim_index)); //! Planes-triangle test #define PLANES_PRIM(prim_index, flag) \ /* Request vertices from the app */ \ mIMesh->GetTriangle(mVP, prim_index, mVC); \ /* Perform triangle-box overlap test */ \ if(PlanesTriOverlap(clip_mask)) \ { \ SET_CONTACT(prim_index, flag) \ } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// PlanesCollider::PlanesCollider() : mNbPlanes (0), mPlanes (null) { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Destructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// PlanesCollider::~PlanesCollider() { DELETEARRAY(mPlanes); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Validates current settings. You should call this method after all the settings and callbacks have been defined. * \return null if everything is ok, else a string describing the problem */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const char* PlanesCollider::ValidateSettings() { if(TemporalCoherenceEnabled() && !FirstContactEnabled()) return "Temporal coherence only works with ""First contact"" mode!"; return VolumeCollider::ValidateSettings(); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Generic collision query for generic OPCODE models. After the call, access the results: * - with GetContactStatus() * - with GetNbTouchedPrimitives() * - with GetTouchedPrimitives() * * \param cache [in/out] a planes cache * \param planes [in] list of planes in world space * \param nb_planes [in] number of planes * \param model [in] Opcode model to collide with * \param worldm [in] model's world matrix, or null * \return true if success * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool PlanesCollider::Collide(PlanesCache& cache, const Plane* planes, udword nb_planes, const Model& model, const Matrix4x4* worldm) { // Checkings if(!Setup(&model)) return false; // Init collision query if(InitQuery(cache, planes, nb_planes, worldm)) return true; udword PlaneMask = (1<mCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); else _Collide(Tree->GetNodes(), PlaneMask); } else { const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); else _Collide(Tree->GetNodes(), PlaneMask); } } else { if(model.IsQuantized()) { const AABBQuantizedTree* Tree = (const AABBQuantizedTree*)model.GetTree(); // Setup dequantization coeffs mCenterCoeff = Tree->mCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); else _Collide(Tree->GetNodes(), PlaneMask); } else { const AABBCollisionTree* Tree = (const AABBCollisionTree*)model.GetTree(); // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); else _Collide(Tree->GetNodes(), PlaneMask); } } return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Initializes a collision query : * - reset stats & contact status * - compute planes in model space * - check temporal coherence * * \param cache [in/out] a planes cache * \param planes [in] list of planes * \param nb_planes [in] number of planes * \param worldm [in] model's world matrix, or null * \return TRUE if we can return immediately * \warning SCALE NOT SUPPORTED. The matrix must contain rotation & translation parts only. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// BOOL PlanesCollider::InitQuery(PlanesCache& cache, const Plane* planes, udword nb_planes, const Matrix4x4* worldm) { // 1) Call the base method VolumeCollider::InitQuery(); // 2) Compute planes in model space if(nb_planes>mNbPlanes) { DELETEARRAY(mPlanes); mPlanes = new Plane[nb_planes]; } mNbPlanes = nb_planes; if(worldm) { Matrix4x4 InvWorldM; InvertPRMatrix(InvWorldM, *worldm); // for(udword i=0;iHasSingleNode()) { if(!SkipPrimitiveTests()) { // We simply perform the BV-Prim overlap test each time. We assume single triangle has index 0. mTouchedPrimitives->Reset(); // Perform overlap test between the unique triangle and the planes (and set contact status if needed) udword clip_mask = (1< check results from previous frame before performing the collision query if(FirstContactEnabled()) { // We're only interested in the first contact found => test the unique previously touched face if(mTouchedPrimitives->GetNbEntries()) { // Get index of previously touched face = the first entry in the array udword PreviouslyTouchedFace = mTouchedPrimitives->GetEntry(0); // Then reset the array: // - if the overlap test below is successful, the index we'll get added back anyway // - if it isn't, then the array should be reset anyway for the normal query mTouchedPrimitives->Reset(); // Perform overlap test between the cached triangle and the planes (and set contact status if needed) udword clip_mask = (1< we'll have to perform a normal query } else mTouchedPrimitives->Reset(); } else { // Here we don't use temporal coherence => do a normal query mTouchedPrimitives->Reset(); } return FALSE; } #define TEST_CLIP_MASK \ /* If the box is completely included, so are its children. We don't need to do extra tests, we */ \ /* can immediately output a list of visible children. Those ones won't need to be clipped. */ \ if(!OutClipMask) \ { \ /* Set contact status */ \ mFlags |= OPC_CONTACT; \ _Dump(node); \ return; \ } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for normal AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void PlanesCollider::_Collide(const AABBCollisionNode* node, udword clip_mask) { // Test the box against the planes. If the box is completely culled, so are its children, hence we exit. udword OutClipMask; if(!PlanesAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents, OutClipMask, clip_mask)) return; TEST_CLIP_MASK // Else the box straddles one or several planes, so we need to recurse down the tree. if(node->IsLeaf()) { PLANES_PRIM(node->GetPrimitive(), OPC_CONTACT) } else { _Collide(node->GetPos(), OutClipMask); if(ContactFound()) return; _Collide(node->GetNeg(), OutClipMask); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for normal AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void PlanesCollider::_CollideNoPrimitiveTest(const AABBCollisionNode* node, udword clip_mask) { // Test the box against the planes. If the box is completely culled, so are its children, hence we exit. udword OutClipMask; if(!PlanesAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents, OutClipMask, clip_mask)) return; TEST_CLIP_MASK // Else the box straddles one or several planes, so we need to recurse down the tree. if(node->IsLeaf()) { SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) } else { _CollideNoPrimitiveTest(node->GetPos(), OutClipMask); if(ContactFound()) return; _CollideNoPrimitiveTest(node->GetNeg(), OutClipMask); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for quantized AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void PlanesCollider::_Collide(const AABBQuantizedNode* node, udword clip_mask) { // Dequantize box const QuantizedAABB& Box = node->mAABB; const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); // Test the box against the planes. If the box is completely culled, so are its children, hence we exit. udword OutClipMask; if(!PlanesAABBOverlap(Center, Extents, OutClipMask, clip_mask)) return; TEST_CLIP_MASK // Else the box straddles one or several planes, so we need to recurse down the tree. if(node->IsLeaf()) { PLANES_PRIM(node->GetPrimitive(), OPC_CONTACT) } else { _Collide(node->GetPos(), OutClipMask); if(ContactFound()) return; _Collide(node->GetNeg(), OutClipMask); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for quantized AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void PlanesCollider::_CollideNoPrimitiveTest(const AABBQuantizedNode* node, udword clip_mask) { // Dequantize box const QuantizedAABB& Box = node->mAABB; const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); // Test the box against the planes. If the box is completely culled, so are its children, hence we exit. udword OutClipMask; if(!PlanesAABBOverlap(Center, Extents, OutClipMask, clip_mask)) return; TEST_CLIP_MASK // Else the box straddles one or several planes, so we need to recurse down the tree. if(node->IsLeaf()) { SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) } else { _CollideNoPrimitiveTest(node->GetPos(), OutClipMask); if(ContactFound()) return; _CollideNoPrimitiveTest(node->GetNeg(), OutClipMask); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for no-leaf AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void PlanesCollider::_Collide(const AABBNoLeafNode* node, udword clip_mask) { // Test the box against the planes. If the box is completely culled, so are its children, hence we exit. udword OutClipMask; if(!PlanesAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents, OutClipMask, clip_mask)) return; TEST_CLIP_MASK // Else the box straddles one or several planes, so we need to recurse down the tree. if(node->HasPosLeaf()) { PLANES_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } else _Collide(node->GetPos(), OutClipMask); if(ContactFound()) return; if(node->HasNegLeaf()) { PLANES_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } else _Collide(node->GetNeg(), OutClipMask); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for no-leaf AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void PlanesCollider::_CollideNoPrimitiveTest(const AABBNoLeafNode* node, udword clip_mask) { // Test the box against the planes. If the box is completely culled, so are its children, hence we exit. udword OutClipMask; if(!PlanesAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents, OutClipMask, clip_mask)) return; TEST_CLIP_MASK // Else the box straddles one or several planes, so we need to recurse down the tree. if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } else _CollideNoPrimitiveTest(node->GetPos(), OutClipMask); if(ContactFound()) return; if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } else _CollideNoPrimitiveTest(node->GetNeg(), OutClipMask); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for quantized no-leaf AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void PlanesCollider::_Collide(const AABBQuantizedNoLeafNode* node, udword clip_mask) { // Dequantize box const QuantizedAABB& Box = node->mAABB; const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); // Test the box against the planes. If the box is completely culled, so are its children, hence we exit. udword OutClipMask; if(!PlanesAABBOverlap(Center, Extents, OutClipMask, clip_mask)) return; TEST_CLIP_MASK // Else the box straddles one or several planes, so we need to recurse down the tree. if(node->HasPosLeaf()) { PLANES_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } else _Collide(node->GetPos(), OutClipMask); if(ContactFound()) return; if(node->HasNegLeaf()) { PLANES_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } else _Collide(node->GetNeg(), OutClipMask); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for quantized no-leaf AABB trees. * \param node [in] current collision node */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void PlanesCollider::_CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node, udword clip_mask) { // Dequantize box const QuantizedAABB& Box = node->mAABB; const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); // Test the box against the planes. If the box is completely culled, so are its children, hence we exit. udword OutClipMask; if(!PlanesAABBOverlap(Center, Extents, OutClipMask, clip_mask)) return; TEST_CLIP_MASK // Else the box straddles one or several planes, so we need to recurse down the tree. if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } else _CollideNoPrimitiveTest(node->GetPos(), OutClipMask); if(ContactFound()) return; if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } else _CollideNoPrimitiveTest(node->GetNeg(), OutClipMask); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// HybridPlanesCollider::HybridPlanesCollider() { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Destructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// HybridPlanesCollider::~HybridPlanesCollider() { } bool HybridPlanesCollider::Collide(PlanesCache& cache, const Plane* planes, udword nb_planes, const HybridModel& model, const Matrix4x4* worldm) { // We don't want primitive tests here! mFlags |= OPC_NO_PRIMITIVE_TESTS; // Checkings if(!Setup(&model)) return false; // Init collision query if(InitQuery(cache, planes, nb_planes, worldm)) return true; // Special case for 1-leaf trees if(mCurrentModel && mCurrentModel->HasSingleNode()) { // Here we're supposed to perform a normal query, except our tree has a single node, i.e. just a few triangles udword Nb = mIMesh->GetNbTriangles(); // Loop through all triangles udword clip_mask = (1<mCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); } else { const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); } } else { if(model.IsQuantized()) { const AABBQuantizedTree* Tree = (const AABBQuantizedTree*)model.GetTree(); // Setup dequantization coeffs mCenterCoeff = Tree->mCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); } else { const AABBCollisionTree* Tree = (const AABBCollisionTree*)model.GetTree(); // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); } } // We only have a list of boxes so far if(GetContactStatus()) { // Reset contact status, since it currently only reflects collisions with leaf boxes Collider::InitQuery(); // Change dest container so that we can use built-in overlap tests and get collided primitives cache.TouchedPrimitives.Reset(); mTouchedPrimitives = &cache.TouchedPrimitives; // Read touched leaf boxes udword Nb = mTouchedBoxes.GetNbEntries(); const udword* Touched = mTouchedBoxes.GetEntries(); const LeafTriangles* LT = model.GetLeafTriangles(); const udword* Indices = model.GetIndices(); // Loop through touched leaves udword clip_mask = (1<IsValid()) return false; // Look for degenerate faces. //udword NbDegenerate = create.mIMesh->CheckTopology(); //if(NbDegenerate) Log("OPCODE WARNING: found %d degenerate faces in model! Collision might report wrong results!\n", NbDegenerate); // We continue nonetheless.... Release(); // Make sure previous tree has been discarded // 1-1) Setup mesh interface automatically SetMeshInterface(create.mIMesh); bool Status = false; AABBTree* LeafTree = null; Internal Data; // 2) Build a generic AABB Tree. mSource = new AABBTree; CHECKALLOC(mSource); // 2-1) Setup a builder. Our primitives here are triangles from input mesh, // so we use an AABBTreeOfTrianglesBuilder..... { AABBTreeOfTrianglesBuilder TB; TB.mIMesh = create.mIMesh; TB.mNbPrimitives = create.mIMesh->GetNbTriangles(); TB.mSettings = create.mSettings; TB.mSettings.mLimit = 16; // ### Hardcoded, but maybe we could let the user choose 8 / 16 / 32 ... if(!mSource->Build(&TB)) goto FreeAndExit; } // 2-2) Here's the trick : create *another* AABB tree using the leaves of the first one (which are boxes, this time) struct Local { // A callback to count leaf nodes static bool CountLeaves(const AABBTreeNode* current, udword depth, void* user_data) { if(current->IsLeaf()) { Internal* Data = (Internal*)user_data; Data->mNbLeaves++; } return true; } // A callback to setup leaf nodes in our internal structures static bool SetupLeafData(const AABBTreeNode* current, udword depth, void* user_data) { if(current->IsLeaf()) { Internal* Data = (Internal*)user_data; // Get current leaf's box Data->mLeaves[Data->mNbLeaves] = *current->GetAABB(); // Setup leaf data udword Index = udword((size_t(current->GetPrimitives()) - size_t(Data->mBase)) / sizeof(udword)); Data->mTriangles[Data->mNbLeaves].SetData(current->GetNbPrimitives(), Index); Data->mNbLeaves++; } return true; } }; // Walk the tree & count number of leaves Data.mNbLeaves = 0; mSource->Walk(Local::CountLeaves, &Data); mNbLeaves = Data.mNbLeaves; // Keep track of it // Special case for 1-leaf meshes if(mNbLeaves==1) { mModelCode |= OPC_SINGLE_NODE; Status = true; goto FreeAndExit; } // Allocate our structures Data.mLeaves = new AABB[Data.mNbLeaves]; CHECKALLOC(Data.mLeaves); mTriangles = new LeafTriangles[Data.mNbLeaves]; CHECKALLOC(mTriangles); // Walk the tree again & setup leaf data Data.mTriangles = mTriangles; Data.mBase = mSource->GetIndices(); Data.mNbLeaves = 0; // Reset for incoming walk mSource->Walk(Local::SetupLeafData, &Data); // Handle source indices { bool MustKeepIndices = true; if(create.mCanRemap) { // We try to get rid of source indices (saving more ram!) by reorganizing triangle arrays... // Remap can fail when we use callbacks => keep track of indices in that case (it still // works, only using more memory) if(create.mIMesh->RemapClient(mSource->GetNbPrimitives(), mSource->GetIndices())) { MustKeepIndices = false; } } if(MustKeepIndices) { // Keep track of source indices (from vanilla tree) mNbPrimitives = mSource->GetNbPrimitives(); mIndices = new udword[mNbPrimitives]; CopyMemory(mIndices, mSource->GetIndices(), mNbPrimitives*sizeof(udword)); } } // Now, create our optimized tree using previous leaf nodes LeafTree = new AABBTree; CHECKALLOC(LeafTree); { AABBTreeOfAABBsBuilder TB; // Now using boxes ! TB.mSettings = create.mSettings; TB.mSettings.mLimit = 1; // We now want a complete tree so that we can "optimize" it TB.mNbPrimitives = Data.mNbLeaves; TB.mAABBArray = Data.mLeaves; if(!LeafTree->Build(&TB)) goto FreeAndExit; } // 3) Create an optimized tree according to user-settings if(!CreateTree(create.mNoLeaf, create.mQuantized)) goto FreeAndExit; // 3-2) Create optimized tree if(!mTree->Build(LeafTree)) goto FreeAndExit; // Finally ok... Status = true; FreeAndExit: // Allow me this one... DELETESINGLE(LeafTree); // 3-3) Delete generic tree if needed if(!create.mKeepOriginal) DELETESINGLE(mSource); return Status; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the number of bytes used by the tree. * \return amount of bytes used */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// udword HybridModel::GetUsedBytes() const { udword UsedBytes = 0; if(mTree) UsedBytes += mTree->GetUsedBytes(); if(mIndices) UsedBytes += mNbPrimitives * sizeof(udword); // mIndices if(mTriangles) UsedBytes += mNbLeaves * sizeof(LeafTriangles); // mTriangles return UsedBytes; } inline_ void ComputeMinMax(Point& min, Point& max, const VertexPointers& vp) { // Compute triangle's AABB = a leaf box #ifdef OPC_USE_FCOMI // a 15% speedup on my machine, not much min.x = FCMin3(vp.Vertex[0]->x, vp.Vertex[1]->x, vp.Vertex[2]->x); max.x = FCMax3(vp.Vertex[0]->x, vp.Vertex[1]->x, vp.Vertex[2]->x); min.y = FCMin3(vp.Vertex[0]->y, vp.Vertex[1]->y, vp.Vertex[2]->y); max.y = FCMax3(vp.Vertex[0]->y, vp.Vertex[1]->y, vp.Vertex[2]->y); min.z = FCMin3(vp.Vertex[0]->z, vp.Vertex[1]->z, vp.Vertex[2]->z); max.z = FCMax3(vp.Vertex[0]->z, vp.Vertex[1]->z, vp.Vertex[2]->z); #else min = *vp.Vertex[0]; max = *vp.Vertex[0]; min.Min(*vp.Vertex[1]); max.Max(*vp.Vertex[1]); min.Min(*vp.Vertex[2]); max.Max(*vp.Vertex[2]); #endif } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Refits the collision model. This can be used to handle dynamic meshes. Usage is: * 1. modify your mesh vertices (keep the topology constant!) * 2. refit the tree (call this method) * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool HybridModel::Refit() { if(!mIMesh) return false; if(!mTree) return false; if(IsQuantized()) return false; if(HasLeafNodes()) return false; const LeafTriangles* LT = GetLeafTriangles(); const udword* Indices = GetIndices(); // Bottom-up update VertexPointers VP; ConversionArea VC; Point Min,Max; Point Min_,Max_; udword Index = mTree->GetNbNodes(); AABBNoLeafNode* Nodes = (AABBNoLeafNode*)((AABBNoLeafTree*)mTree)->GetNodes(); while(Index--) { AABBNoLeafNode& Current = Nodes[Index]; if(Current.HasPosLeaf()) { const LeafTriangles& CurrentLeaf = LT[Current.GetPosPrimitive()]; Min.SetPlusInfinity(); Max.SetMinusInfinity(); Point TmpMin, TmpMax; // Each leaf box has a set of triangles udword NbTris = CurrentLeaf.GetNbTriangles(); if(Indices) { const udword* T = &Indices[CurrentLeaf.GetTriangleIndex()]; // Loop through triangles and test each of them while(NbTris--) { mIMesh->GetTriangle(VP, *T++, VC); ComputeMinMax(TmpMin, TmpMax, VP); Min.Min(TmpMin); Max.Max(TmpMax); } } else { udword BaseIndex = CurrentLeaf.GetTriangleIndex(); // Loop through triangles and test each of them while(NbTris--) { mIMesh->GetTriangle(VP, BaseIndex++, VC); ComputeMinMax(TmpMin, TmpMax, VP); Min.Min(TmpMin); Max.Max(TmpMax); } } } else { const CollisionAABB& CurrentBox = Current.GetPos()->mAABB; CurrentBox.GetMin(Min); CurrentBox.GetMax(Max); } if(Current.HasNegLeaf()) { const LeafTriangles& CurrentLeaf = LT[Current.GetNegPrimitive()]; Min_.SetPlusInfinity(); Max_.SetMinusInfinity(); Point TmpMin, TmpMax; // Each leaf box has a set of triangles udword NbTris = CurrentLeaf.GetNbTriangles(); if(Indices) { const udword* T = &Indices[CurrentLeaf.GetTriangleIndex()]; // Loop through triangles and test each of them while(NbTris--) { mIMesh->GetTriangle(VP, *T++, VC); ComputeMinMax(TmpMin, TmpMax, VP); Min_.Min(TmpMin); Max_.Max(TmpMax); } } else { udword BaseIndex = CurrentLeaf.GetTriangleIndex(); // Loop through triangles and test each of them while(NbTris--) { mIMesh->GetTriangle(VP, BaseIndex++, VC); ComputeMinMax(TmpMin, TmpMax, VP); Min_.Min(TmpMin); Max_.Max(TmpMax); } } } else { const CollisionAABB& CurrentBox = Current.GetNeg()->mAABB; CurrentBox.GetMin(Min_); CurrentBox.GetMax(Max_); } #ifdef OPC_USE_FCOMI Min.x = FCMin2(Min.x, Min_.x); Max.x = FCMax2(Max.x, Max_.x); Min.y = FCMin2(Min.y, Min_.y); Max.y = FCMax2(Max.y, Max_.y); Min.z = FCMin2(Min.z, Min_.z); Max.z = FCMax2(Max.z, Max_.z); #else Min.Min(Min_); Max.Max(Max_); #endif Current.mAABB.SetMinMax(Min, Max); } return true; } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/0000700000175000017500000000000012207204656021034 5ustar zero79zero79alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceRevisitedRadix.cpp0000600000175000017500000005300212161402010025070 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains source code from the article "Radix Sort Revisited". * \file IceRevisitedRadix.cpp * \author Pierre Terdiman * \date April, 4, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Revisited Radix Sort. * This is my new radix routine: * - it uses indices and doesn't recopy the values anymore, hence wasting less ram * - it creates all the histograms in one run instead of four * - it sorts words faster than dwords and bytes faster than words * - it correctly sorts negative floating-point values by patching the offsets * - it automatically takes advantage of temporal coherence * - multiple keys support is a side effect of temporal coherence * - it may be worth recoding in asm... (mainly to use FCOMI, FCMOV, etc) [it's probably memory-bound anyway] * * History: * - 08.15.98: very first version * - 04.04.00: recoded for the radix article * - 12.xx.00: code lifting * - 09.18.01: faster CHECK_PASS_VALIDITY thanks to Mark D. Shattuck (who provided other tips, not included here) * - 10.11.01: added local ram support * - 01.20.02: bugfix! In very particular cases the last pass was skipped in the float code-path, leading to incorrect sorting...... * - 01.02.02: - "mIndices" renamed => "mRanks". That's a rank sorter after all. * - ranks are not "reset" anymore, but implicit on first calls * - 07.05.02: - offsets rewritten with one less indirection. * - 11.03.02: - "bool" replaced with RadixHint enum * * \class RadixSort * \author Pierre Terdiman * \version 1.4 * \date August, 15, 1998 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* To do: - add an offset parameter between two input values (avoid some data recopy sometimes) - unroll ? asm ? - 11 bits trick & 3 passes as Michael did - prefetch stuff the day I have a P3 - make a version with 16-bits indices ? */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace IceCore; #define INVALIDATE_RANKS mCurrentSize|=0x80000000 #define VALIDATE_RANKS mCurrentSize&=0x7fffffff #define CURRENT_SIZE (mCurrentSize&0x7fffffff) #define INVALID_RANKS (mCurrentSize&0x80000000) #define CHECK_RESIZE(n) \ if(n!=mPreviousSize) \ { \ if(n>mCurrentSize) Resize(n); \ else ResetRanks(); \ mPreviousSize = n; \ } #define CREATE_HISTOGRAMS(type, buffer) \ /* Clear counters/histograms */ \ ZeroMemory(mHistogram, 256*4*sizeof(udword)); \ \ /* Prepare to count */ \ ubyte* p = (ubyte*)input; \ ubyte* pe = &p[nb*4]; \ udword* h0= &mHistogram[0]; /* Histogram for first pass (LSB) */ \ udword* h1= &mHistogram[256]; /* Histogram for second pass */ \ udword* h2= &mHistogram[512]; /* Histogram for third pass */ \ udword* h3= &mHistogram[768]; /* Histogram for last pass (MSB) */ \ \ bool AlreadySorted = true; /* Optimism... */ \ \ if(INVALID_RANKS) \ { \ /* Prepare for temporal coherence */ \ type* Running = (type*)buffer; \ type PrevVal = *Running; \ \ while(p!=pe) \ { \ /* Read input buffer in previous sorted order */ \ type Val = *Running++; \ /* Check whether already sorted or not */ \ if(ValCurSize) Resize(nb); mCurrentSize = nb; INVALIDATE_RANKS; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Main sort routine. * This one is for integer values. After the call, mRanks contains a list of indices in sorted order, i.e. in the order you may process your data. * \param input [in] a list of integer values to sort * \param nb [in] number of values to sort, must be < 2^31 * \param hint [in] RADIX_SIGNED to handle negative values, RADIX_UNSIGNED if you know your input buffer only contains positive values * \return Self-Reference */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// RadixSort& RadixSort::Sort(const udword* input, udword nb, RadixHint hint) { // Checkings if(!input || !nb || nb&0x80000000) return *this; // Stats mTotalCalls++; // Resize lists if needed CheckResize(nb); #ifdef RADIX_LOCAL_RAM // Allocate histograms & offsets on the stack udword mHistogram[256*4]; // udword mOffset[256]; udword* mLink[256]; #endif // Create histograms (counters). Counters for all passes are created in one run. // Pros: read input buffer once instead of four times // Cons: mHistogram is 4Kb instead of 1Kb // We must take care of signed/unsigned values for temporal coherence.... I just // have 2 code paths even if just a single opcode changes. Self-modifying code, someone? if(hint==RADIX_UNSIGNED) { CREATE_HISTOGRAMS(udword, input); } else { CREATE_HISTOGRAMS(sdword, input); } // Compute #negative values involved if needed udword NbNegativeValues = 0; if(hint==RADIX_SIGNED) { // An efficient way to compute the number of negatives values we'll have to deal with is simply to sum the 128 // last values of the last histogram. Last histogram because that's the one for the Most Significant Byte, // responsible for the sign. 128 last values because the 128 first ones are related to positive numbers. udword* h3= &mHistogram[768]; for(udword i=128;i<256;i++) NbNegativeValues += h3[i]; // 768 for last histogram, 128 for negative part } // Radix sort, j is the pass number (0=LSB, 3=MSB) for(udword j=0;j<4;j++) { CHECK_PASS_VALIDITY(j); // Sometimes the fourth (negative) pass is skipped because all numbers are negative and the MSB is 0xFF (for example). This is // not a problem, numbers are correctly sorted anyway. if(PerformPass) { // Should we care about negative values? if(j!=3 || hint==RADIX_UNSIGNED) { // Here we deal with positive values only // Create offsets // mOffset[0] = 0; // for(udword i=1;i<256;i++) mOffset[i] = mOffset[i-1] + CurCount[i-1]; mLink[0] = mRanks2; for(udword i=1;i<256;i++) mLink[i] = mLink[i-1] + CurCount[i-1]; } else { // This is a special case to correctly handle negative integers. They're sorted in the right order but at the wrong place. // Create biased offsets, in order for negative numbers to be sorted as well // mOffset[0] = NbNegativeValues; // First positive number takes place after the negative ones mLink[0] = &mRanks2[NbNegativeValues]; // First positive number takes place after the negative ones // for(udword i=1;i<128;i++) mOffset[i] = mOffset[i-1] + CurCount[i-1]; // 1 to 128 for positive numbers for(udword i=1;i<128;i++) mLink[i] = mLink[i-1] + CurCount[i-1]; // 1 to 128 for positive numbers // Fixing the wrong place for negative values // mOffset[128] = 0; mLink[128] = mRanks2; // for(i=129;i<256;i++) mOffset[i] = mOffset[i-1] + CurCount[i-1]; for(udword i=129;i<256;i++) mLink[i] = mLink[i-1] + CurCount[i-1]; } // Perform Radix Sort ubyte* InputBytes = (ubyte*)input; InputBytes += j; if(INVALID_RANKS) { // for(udword i=0;i>24; // Radix byte, same as above. AND is useless here (udword). // ### cmp to be killed. Not good. Later. // if(Radix<128) mRanks2[mOffset[Radix]++] = i; // Number is positive, same as above // else mRanks2[--mOffset[Radix]] = i; // Number is negative, flip the sorting order if(Radix<128) *mLink[Radix]++ = i; // Number is positive, same as above else *(--mLink[Radix]) = i; // Number is negative, flip the sorting order } VALIDATE_RANKS; } else { for(udword i=0;i>24; // Radix byte, same as above. AND is useless here (udword). // ### cmp to be killed. Not good. Later. // if(Radix<128) mRanks2[mOffset[Radix]++] = mRanks[i]; // Number is positive, same as above // else mRanks2[--mOffset[Radix]] = mRanks[i]; // Number is negative, flip the sorting order if(Radix<128) *mLink[Radix]++ = mRanks[i]; // Number is positive, same as above else *(--mLink[Radix]) = mRanks[i]; // Number is negative, flip the sorting order } } // Swap pointers for next pass. Valid indices - the most recent ones - are in mRanks after the swap. udword* Tmp = mRanks; mRanks = mRanks2; mRanks2 = Tmp; } else { // The pass is useless, yet we still have to reverse the order of current list if all values are negative. if(UniqueVal>=128) { if(INVALID_RANKS) { // ###Possible? for(udword i=0;iRelease(); (x) = null; } //!< Safe D3D-style release #define SAFE_DESTRUCT(x) if (x) { (x)->SelfDestruct(); (x) = null; } //!< Safe ICE-style release #ifdef __ICEERROR_H__ #define CHECKALLOC(x) if(!x) return SetIceError("Out of memory.", EC_OUT_OF_MEMORY); //!< Standard alloc checking. HANDLE WITH CARE. #else #define CHECKALLOC(x) if(!x) return false; #endif //! Standard allocation cycle #define SAFE_ALLOC(ptr, type, count) DELETEARRAY(ptr); ptr = new type[count]; CHECKALLOC(ptr); #endif // __ICEMEMORYMACROS_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IcePoint.cpp0000600000175000017500000001640412161402010023240 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for 3D vectors. * \file IcePoint.cpp * \author Pierre Terdiman * \date April, 4, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 3D point. * * The name is "Point" instead of "Vector" since a vector is N-dimensional, whereas a point is an implicit "vector of dimension 3". * So the choice was between "Point" and "Vector3", the first one looked better (IMHO). * * Some people, then, use a typedef to handle both points & vectors using the same class: typedef Point Vector3; * This is bad since it opens the door to a lot of confusion while reading the code. I know it may sounds weird but check this out: * * \code * Point P0,P1 = some 3D points; * Point Delta = P1 - P0; * \endcode * * This compiles fine, although you should have written: * * \code * Point P0,P1 = some 3D points; * Vector3 Delta = P1 - P0; * \endcode * * Subtle things like this are not caught at compile-time, and when you find one in the code, you never know whether it's a mistake * from the author or something you don't get. * * One way to handle it at compile-time would be to use different classes for Point & Vector3, only overloading operator "-" for vectors. * But then, you get a lot of redundant code in thoses classes, and basically it's really a lot of useless work. * * Another way would be to use homogeneous points: w=1 for points, w=0 for vectors. That's why the HPoint class exists. Now, to store * your model's vertices and in most cases, you really want to use Points to save ram. * * \class Point * \author Pierre Terdiman * \version 1.0 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace IceMaths; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Creates a positive unit random vector. * \return Self-reference */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Point& Point::PositiveUnitRandomVector() { x = UnitRandomFloat(); y = UnitRandomFloat(); z = UnitRandomFloat(); Normalize(); return *this; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Creates a unit random vector. * \return Self-reference */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Point& Point::UnitRandomVector() { x = UnitRandomFloat() - 0.5f; y = UnitRandomFloat() - 0.5f; z = UnitRandomFloat() - 0.5f; Normalize(); return *this; } // Cast operator // WARNING: not inlined Point::operator HPoint() const { return HPoint(x, y, z, 0.0f); } Point& Point::Refract(const Point& eye, const Point& n, float refractindex, Point& refracted) { // Point EyePt = eye position // Point p = current vertex // Point n = vertex normal // Point rv = refracted vector // Eye vector - doesn't need to be normalized Point Env; Env.x = eye.x - x; Env.y = eye.y - y; Env.z = eye.z - z; float NDotE = n|Env; float NDotN = n|n; NDotE /= refractindex; // Refracted vector refracted = n*NDotE - Env*NDotN; return *this; } Point& Point::ProjectToPlane(const Plane& p) { *this-= (p.d + (*this|p.n))*p.n; return *this; } void Point::ProjectToScreen(float halfrenderwidth, float halfrenderheight, const Matrix4x4& mat, HPoint& projected) const { projected = HPoint(x, y, z, 1.0f) * mat; projected.w = 1.0f / projected.w; projected.x*=projected.w; projected.y*=projected.w; projected.z*=projected.w; projected.x *= halfrenderwidth; projected.x += halfrenderwidth; projected.y *= -halfrenderheight; projected.y += halfrenderheight; } void Point::SetNotUsed() { // We use a particular integer pattern : 0xffffffff everywhere. This is a NAN. IR(x) = 0xffffffff; IR(y) = 0xffffffff; IR(z) = 0xffffffff; } BOOL Point::IsNotUsed() const { if(IR(x)!=0xffffffff) return FALSE; if(IR(y)!=0xffffffff) return FALSE; if(IR(z)!=0xffffffff) return FALSE; return TRUE; } Point& Point::Mult(const Matrix3x3& mat, const Point& a) { x = a.x * mat.m[0][0] + a.y * mat.m[0][1] + a.z * mat.m[0][2]; y = a.x * mat.m[1][0] + a.y * mat.m[1][1] + a.z * mat.m[1][2]; z = a.x * mat.m[2][0] + a.y * mat.m[2][1] + a.z * mat.m[2][2]; return *this; } Point& Point::Mult2(const Matrix3x3& mat1, const Point& a1, const Matrix3x3& mat2, const Point& a2) { x = a1.x * mat1.m[0][0] + a1.y * mat1.m[0][1] + a1.z * mat1.m[0][2] + a2.x * mat2.m[0][0] + a2.y * mat2.m[0][1] + a2.z * mat2.m[0][2]; y = a1.x * mat1.m[1][0] + a1.y * mat1.m[1][1] + a1.z * mat1.m[1][2] + a2.x * mat2.m[1][0] + a2.y * mat2.m[1][1] + a2.z * mat2.m[1][2]; z = a1.x * mat1.m[2][0] + a1.y * mat1.m[2][1] + a1.z * mat1.m[2][2] + a2.x * mat2.m[2][0] + a2.y * mat2.m[2][1] + a2.z * mat2.m[2][2]; return *this; } Point& Point::Mac(const Matrix3x3& mat, const Point& a) { x += a.x * mat.m[0][0] + a.y * mat.m[0][1] + a.z * mat.m[0][2]; y += a.x * mat.m[1][0] + a.y * mat.m[1][1] + a.z * mat.m[1][2]; z += a.x * mat.m[2][0] + a.y * mat.m[2][1] + a.z * mat.m[2][2]; return *this; } Point& Point::TransMult(const Matrix3x3& mat, const Point& a) { x = a.x * mat.m[0][0] + a.y * mat.m[1][0] + a.z * mat.m[2][0]; y = a.x * mat.m[0][1] + a.y * mat.m[1][1] + a.z * mat.m[2][1]; z = a.x * mat.m[0][2] + a.y * mat.m[1][2] + a.z * mat.m[2][2]; return *this; } Point& Point::Transform(const Point& r, const Matrix3x3& rotpos, const Point& linpos) { x = r.x * rotpos.m[0][0] + r.y * rotpos.m[0][1] + r.z * rotpos.m[0][2] + linpos.x; y = r.x * rotpos.m[1][0] + r.y * rotpos.m[1][1] + r.z * rotpos.m[1][2] + linpos.y; z = r.x * rotpos.m[2][0] + r.y * rotpos.m[2][1] + r.z * rotpos.m[2][2] + linpos.z; return *this; } Point& Point::InvTransform(const Point& r, const Matrix3x3& rotpos, const Point& linpos) { float sx = r.x - linpos.x; float sy = r.y - linpos.y; float sz = r.z - linpos.z; x = sx * rotpos.m[0][0] + sy * rotpos.m[1][0] + sz * rotpos.m[2][0]; y = sx * rotpos.m[0][1] + sy * rotpos.m[1][1] + sz * rotpos.m[2][1]; z = sx * rotpos.m[0][2] + sy * rotpos.m[1][2] + sz * rotpos.m[2][2]; return *this; } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceFPU.h0000600000175000017500000002047012161402010022244 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains FPU related code. * \file IceFPU.h * \author Pierre Terdiman * \date April, 4, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __ICEFPU_H__ #define __ICEFPU_H__ #define SIGN_BITMASK 0x80000000 //! Integer representation of a floating-point value. #define IR(x) ((udword&)(x)) //! Signed integer representation of a floating-point value. #define SIR(x) ((sdword&)(x)) //! Absolute integer representation of a floating-point value #define AIR(x) (IR(x)&0x7fffffff) //! Floating-point representation of an integer value. #define FR(x) ((float&)(x)) //! Integer-based comparison of a floating point value. //! Don't use it blindly, it can be faster or slower than the FPU comparison, depends on the context. #define IS_NEGATIVE_FLOAT(x) (IR(x)&0x80000000) //! Fast fabs for floating-point values. It just clears the sign bit. //! Don't use it blindy, it can be faster or slower than the FPU comparison, depends on the context. inline_ float FastFabs(float x) { udword FloatBits = IR(x)&0x7fffffff; return FR(FloatBits); } //! Fast square root for floating-point values. inline_ float FastSqrt(float square) { return sqrt(square); } //! Saturates positive to zero. inline_ float fsat(float f) { udword y = (udword&)f & ~((sdword&)f >>31); return (float&)y; } //! Computes 1.0f / sqrtf(x). inline_ float frsqrt(float f) { float x = f * 0.5f; udword y = 0x5f3759df - ((udword&)f >> 1); // Iteration... (float&)y = (float&)y * ( 1.5f - ( x * (float&)y * (float&)y ) ); // Result return (float&)y; } //! Computes 1.0f / sqrtf(x). Comes from NVIDIA. inline_ float InvSqrt(const float& x) { udword tmp = (udword(IEEE_1_0 << 1) + IEEE_1_0 - *(udword*)&x) >> 1; float y = *(float*)&tmp; return y * (1.47f - 0.47f * x * y * y); } //! Computes 1.0f / sqrtf(x). Comes from Quake3. Looks like the first one I had above. //! See http://www.magic-software.com/3DGEDInvSqrt.html inline_ float RSqrt(float number) { long i; float x2, y; const float threehalfs = 1.5f; x2 = number * 0.5f; y = number; i = * (long *) &y; i = 0x5f3759df - (i >> 1); y = * (float *) &i; y = y * (threehalfs - (x2 * y * y)); return y; } //! TO BE DOCUMENTED inline_ float fsqrt(float f) { udword y = ( ( (sdword&)f - 0x3f800000 ) >> 1 ) + 0x3f800000; // Iteration...? // (float&)y = (3.0f - ((float&)y * (float&)y) / f) * (float&)y * 0.5f; // Result return (float&)y; } //! Returns the float ranged espilon value. inline_ float fepsilon(float f) { udword b = (udword&)f & 0xff800000; udword a = b | 0x00000001; (float&)a -= (float&)b; // Result return (float&)a; } //! Is the float valid ? inline_ bool IsNAN(float value) { return (IR(value)&0x7f800000) == 0x7f800000; } inline_ bool IsIndeterminate(float value) { return IR(value) == 0xffc00000; } inline_ bool IsPlusInf(float value) { return IR(value) == 0x7f800000; } inline_ bool IsMinusInf(float value) { return IR(value) == 0xff800000; } inline_ bool IsValidFloat(float value) { if(IsNAN(value)) return false; if(IsIndeterminate(value)) return false; if(IsPlusInf(value)) return false; if(IsMinusInf(value)) return false; return true; } #define CHECK_VALID_FLOAT(x) ASSERT(IsValidFloat(x)); /* //! FPU precision setting function. inline_ void SetFPU() { // This function evaluates whether the floating-point // control word is set to single precision/round to nearest/ // exceptions disabled. If these conditions don't hold, the // function changes the control word to set them and returns // TRUE, putting the old control word value in the passback // location pointed to by pwOldCW. { uword wTemp, wSave; __asm fstcw wSave if (wSave & 0x300 || // Not single mode 0x3f != (wSave & 0x3f) || // Exceptions enabled wSave & 0xC00) // Not round to nearest mode { __asm { mov ax, wSave and ax, not 300h ;; single mode or ax, 3fh ;; disable all exceptions and ax, not 0xC00 ;; round to nearest mode mov wTemp, ax fldcw wTemp } } } } */ //! This function computes the slowest possible floating-point value (you can also directly use FLT_EPSILON) inline_ float ComputeFloatEpsilon() { float f = 1.0f; ((udword&)f)^=1; return f - 1.0f; // You can check it's the same as FLT_EPSILON } inline_ bool IsFloatZero(float x, float epsilon=1e-6f) { return x*x < epsilon; } #define FCOMI_ST0 _asm _emit 0xdb _asm _emit 0xf0 #define FCOMIP_ST0 _asm _emit 0xdf _asm _emit 0xf0 #define FCMOVB_ST0 _asm _emit 0xda _asm _emit 0xc0 #define FCMOVNB_ST0 _asm _emit 0xdb _asm _emit 0xc0 #define FCOMI_ST1 _asm _emit 0xdb _asm _emit 0xf1 #define FCOMIP_ST1 _asm _emit 0xdf _asm _emit 0xf1 #define FCMOVB_ST1 _asm _emit 0xda _asm _emit 0xc1 #define FCMOVNB_ST1 _asm _emit 0xdb _asm _emit 0xc1 #define FCOMI_ST2 _asm _emit 0xdb _asm _emit 0xf2 #define FCOMIP_ST2 _asm _emit 0xdf _asm _emit 0xf2 #define FCMOVB_ST2 _asm _emit 0xda _asm _emit 0xc2 #define FCMOVNB_ST2 _asm _emit 0xdb _asm _emit 0xc2 #define FCOMI_ST3 _asm _emit 0xdb _asm _emit 0xf3 #define FCOMIP_ST3 _asm _emit 0xdf _asm _emit 0xf3 #define FCMOVB_ST3 _asm _emit 0xda _asm _emit 0xc3 #define FCMOVNB_ST3 _asm _emit 0xdb _asm _emit 0xc3 #define FCOMI_ST4 _asm _emit 0xdb _asm _emit 0xf4 #define FCOMIP_ST4 _asm _emit 0xdf _asm _emit 0xf4 #define FCMOVB_ST4 _asm _emit 0xda _asm _emit 0xc4 #define FCMOVNB_ST4 _asm _emit 0xdb _asm _emit 0xc4 #define FCOMI_ST5 _asm _emit 0xdb _asm _emit 0xf5 #define FCOMIP_ST5 _asm _emit 0xdf _asm _emit 0xf5 #define FCMOVB_ST5 _asm _emit 0xda _asm _emit 0xc5 #define FCMOVNB_ST5 _asm _emit 0xdb _asm _emit 0xc5 #define FCOMI_ST6 _asm _emit 0xdb _asm _emit 0xf6 #define FCOMIP_ST6 _asm _emit 0xdf _asm _emit 0xf6 #define FCMOVB_ST6 _asm _emit 0xda _asm _emit 0xc6 #define FCMOVNB_ST6 _asm _emit 0xdb _asm _emit 0xc6 #define FCOMI_ST7 _asm _emit 0xdb _asm _emit 0xf7 #define FCOMIP_ST7 _asm _emit 0xdf _asm _emit 0xf7 #define FCMOVB_ST7 _asm _emit 0xda _asm _emit 0xc7 #define FCMOVNB_ST7 _asm _emit 0xdb _asm _emit 0xc7 //! A global function to find MAX(a,b) using FCOMI/FCMOV inline_ float FCMax2(float a, float b) { return (a > b) ? a : b; } //! A global function to find MIN(a,b) using FCOMI/FCMOV inline_ float FCMin2(float a, float b) { return (a < b) ? a : b; } //! A global function to find MAX(a,b,c) using FCOMI/FCMOV inline_ float FCMax3(float a, float b, float c) { return (a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c); } //! A global function to find MIN(a,b,c) using FCOMI/FCMOV inline_ float FCMin3(float a, float b, float c) { return (a < b) ? ((a < c) ? a : c) : ((b < c) ? b : c); } inline_ int ConvertToSortable(float f) { int& Fi = (int&)f; int Fmask = (Fi>>31); Fi ^= Fmask; Fmask &= ~(1<<31); Fi -= Fmask; return Fi; } enum FPUMode { FPU_FLOOR = 0, FPU_CEIL = 1, FPU_BEST = 2, FPU_FORCE_DWORD = 0x7fffffff }; FUNCTION ICECORE_API FPUMode GetFPUMode(); FUNCTION ICECORE_API void SaveFPU(); FUNCTION ICECORE_API void RestoreFPU(); FUNCTION ICECORE_API void SetFPUFloorMode(); FUNCTION ICECORE_API void SetFPUCeilMode(); FUNCTION ICECORE_API void SetFPUBestMode(); FUNCTION ICECORE_API void SetFPUPrecision24(); FUNCTION ICECORE_API void SetFPUPrecision53(); FUNCTION ICECORE_API void SetFPUPrecision64(); FUNCTION ICECORE_API void SetFPURoundingChop(); FUNCTION ICECORE_API void SetFPURoundingUp(); FUNCTION ICECORE_API void SetFPURoundingDown(); FUNCTION ICECORE_API void SetFPURoundingNear(); FUNCTION ICECORE_API int intChop(const float& f); FUNCTION ICECORE_API int intFloor(const float& f); FUNCTION ICECORE_API int intCeil(const float& f); #endif // __ICEFPU_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceContainer.cpp0000600000175000017500000003323212161402010024067 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains a simple container class. * \file IceContainer.cpp * \author Pierre Terdiman * \date February, 5, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains a list of 32-bits values. * Use this class when you need to store an unknown number of values. The list is automatically * resized and can contains 32-bits entities (dwords or floats) * * \class Container * \author Pierre Terdiman * \version 1.0 * \date 08.15.98 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace IceCore; // Static members #ifdef CONTAINER_STATS udword Container::mNbContainers = 0; udword Container::mUsedRam = 0; #endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. No entries allocated there. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Container::Container() : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(2.0f) { #ifdef CONTAINER_STATS mNbContainers++; mUsedRam+=sizeof(Container); #endif } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. Also allocates a given number of entries. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Container::Container(udword size, float growth_factor) : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(growth_factor) { #ifdef CONTAINER_STATS mNbContainers++; mUsedRam+=sizeof(Container); #endif SetSize(size); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Copy constructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Container::Container(const Container& object) : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(2.0f) { #ifdef CONTAINER_STATS mNbContainers++; mUsedRam+=sizeof(Container); #endif *this = object; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Destructor. Frees everything and leaves. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Container::~Container() { Empty(); #ifdef CONTAINER_STATS mNbContainers--; mUsedRam-=GetUsedRam(); #endif } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Clears the container. All stored values are deleted, and it frees used ram. * \see Reset() * \return Self-Reference */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Container& Container::Empty() { #ifdef CONTAINER_STATS mUsedRam-=mMaxNbEntries*sizeof(udword); #endif DELETEARRAY(mEntries); mCurNbEntries = mMaxNbEntries = 0; return *this; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Resizes the container. * \param needed [in] assume the container can be added at least "needed" values * \return true if success. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool Container::Resize(udword needed) { #ifdef CONTAINER_STATS // Subtract previous amount of bytes mUsedRam-=mMaxNbEntries*sizeof(udword); #endif // Get more entries mMaxNbEntries = mMaxNbEntries ? udword(float(mMaxNbEntries)*mGrowthFactor) : 2; // Default nb Entries = 2 if(mMaxNbEntries=R2) return FALSE; p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE; p.x=Max.x; p.y=Min.y; if(mCenter.SquareDistance(p)>=R2) return FALSE; p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE; p.x=Max.x; p.y=Max.y; p.z=Min.z; if(mCenter.SquareDistance(p)>=R2) return FALSE; p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE; p.x=Max.x; p.y=Min.y; if(mCenter.SquareDistance(p)>=R2) return FALSE; p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE; return TRUE; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Tests if the sphere intersects another sphere * \param sphere [in] the other sphere * \return true if spheres overlap */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ bool Intersect(const Sphere& sphere) const { float r = mRadius + sphere.mRadius; return mCenter.SquareDistance(sphere.mCenter) <= r*r; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks the sphere is valid. * \return true if the box is valid */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL IsValid() const { // Consistency condition for spheres: Radius >= 0.0f if(mRadius < 0.0f) return FALSE; return TRUE; } public: Point mCenter; //!< Sphere center float mRadius; //!< Sphere radius }; #endif // __ICEBOUNDINGSPHERE_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceRay.h0000600000175000017500000001112012161402010022335 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for rays. * \file IceRay.h * \author Pierre Terdiman * \date April, 4, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __ICERAY_H__ #define __ICERAY_H__ class ICEMATHS_API Ray { public: //! Constructor inline_ Ray() {} //! Constructor inline_ Ray(const Point& orig, const Point& dir) : mOrig(orig), mDir(dir) {} //! Copy constructor inline_ Ray(const Ray& ray) : mOrig(ray.mOrig), mDir(ray.mDir) {} //! Destructor inline_ ~Ray() {} float SquareDistance(const Point& point, float* t=null) const; inline_ float Distance(const Point& point, float* t=null) const { return sqrtf(SquareDistance(point, t)); } Point mOrig; //!< Ray origin Point mDir; //!< Normalized direction }; inline_ void ComputeReflexionVector(Point& reflected, const Point& incoming_dir, const Point& outward_normal) { reflected = incoming_dir - outward_normal * 2.0f * (incoming_dir|outward_normal); } inline_ void ComputeReflexionVector(Point& reflected, const Point& source, const Point& impact, const Point& normal) { Point V = impact - source; reflected = V - normal * 2.0f * (V|normal); } inline_ void DecomposeVector(Point& normal_compo, Point& tangent_compo, const Point& outward_dir, const Point& outward_normal) { normal_compo = outward_normal * (outward_dir|outward_normal); tangent_compo = outward_dir - normal_compo; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Transforms a direction vector from world space to local space * \param local_dir [out] direction vector in local space * \param world_dir [in] direction vector in world space * \param world [in] world transform */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void ComputeLocalDirection(Point& local_dir, const Point& world_dir, const Matrix4x4& world) { // Get world direction back in local space // Matrix3x3 InvWorld = world; // local_dir = InvWorld * world_dir; local_dir = Matrix3x3(world) * world_dir; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Transforms a position vector from world space to local space * \param local_pt [out] position vector in local space * \param world_pt [in] position vector in world space * \param world [in] world transform */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void ComputeLocalPoint(Point& local_pt, const Point& world_pt, const Matrix4x4& world) { // Get world vertex back in local space Matrix4x4 InvWorld = world; InvWorld.Invert(); local_pt = world_pt * InvWorld; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Transforms a ray from world space to local space * \param local_ray [out] ray in local space * \param world_ray [in] ray in world space * \param world [in] world transform */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void ComputeLocalRay(Ray& local_ray, const Ray& world_ray, const Matrix4x4& world) { // Get world ray back in local space ComputeLocalDirection(local_ray.mDir, world_ray.mDir, world); ComputeLocalPoint(local_ray.mOrig, world_ray.mOrig, world); } #endif // __ICERAY_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceTriangle.h0000600000175000017500000000466412161402010023366 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains a handy triangle class. * \file IceTriangle.h * \author Pierre Terdiman * \date January, 17, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __ICETRIANGLE_H__ #define __ICETRIANGLE_H__ // Forward declarations class Moment; // Partitioning values enum PartVal { TRI_MINUS_SPACE = 0, //!< Triangle is in the negative space TRI_PLUS_SPACE = 1, //!< Triangle is in the positive space TRI_INTERSECT = 2, //!< Triangle intersects plane TRI_ON_PLANE = 3, //!< Triangle and plane are coplanar TRI_FORCEDWORD = 0x7fffffff }; // A triangle class. class ICEMATHS_API Triangle { public: //! Constructor inline_ Triangle() {} //! Constructor inline_ Triangle(const Point& p0, const Point& p1, const Point& p2) { mVerts[0]=p0; mVerts[1]=p1; mVerts[2]=p2; } //! Copy constructor inline_ Triangle(const Triangle& triangle) { mVerts[0] = triangle.mVerts[0]; mVerts[1] = triangle.mVerts[1]; mVerts[2] = triangle.mVerts[2]; } //! Destructor inline_ ~Triangle() {} //! Vertices Point mVerts[3]; // Methods void Flip(); float Area() const; float Perimeter() const; float Compacity() const; void Normal(Point& normal) const; void DenormalizedNormal(Point& normal) const; void Center(Point& center) const; inline_ Plane PlaneEquation() const { return Plane(mVerts[0], mVerts[1], mVerts[2]); } PartVal TestAgainstPlane(const Plane& plane, float epsilon) const; // float Distance(Point& cp, Point& cq, Tri& tri); void ComputeMoment(Moment& m); float MinEdgeLength() const; float MaxEdgeLength() const; void ComputePoint(float u, float v, Point& pt, udword* nearvtx=null) const; void Inflate(float fat_coeff, bool constant_border); }; #endif // __ICETRIANGLE_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceRevisitedRadix.h0000600000175000017500000000503212161402010024535 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains source code from the article "Radix Sort Revisited". * \file IceRevisitedRadix.h * \author Pierre Terdiman * \date April, 4, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __ICERADIXSORT_H__ #define __ICERADIXSORT_H__ //! Allocate histograms & offsets locally #define RADIX_LOCAL_RAM enum RadixHint { RADIX_SIGNED, //!< Input values are signed RADIX_UNSIGNED, //!< Input values are unsigned RADIX_FORCE_DWORD = 0x7fffffff }; class ICECORE_API RadixSort { public: // Constructor/Destructor RadixSort(); ~RadixSort(); // Sorting methods RadixSort& Sort(const udword* input, udword nb, RadixHint hint=RADIX_SIGNED); RadixSort& Sort(const float* input, udword nb); //! Access to results. mRanks is a list of indices in sorted order, i.e. in the order you may further process your data inline_ const udword* GetRanks() const { return mRanks; } //! mIndices2 gets trashed on calling the sort routine, but otherwise you can recycle it the way you want. inline_ udword* GetRecyclable() const { return mRanks2; } // Stats udword GetUsedRam() const; //! Returns the total number of calls to the radix sorter. inline_ udword GetNbTotalCalls() const { return mTotalCalls; } //! Returns the number of eraly exits due to temporal coherence. inline_ udword GetNbHits() const { return mNbHits; } private: #ifndef RADIX_LOCAL_RAM udword* mHistogram; //!< Counters for each byte udword* mOffset; //!< Offsets (nearly a cumulative distribution function) #endif udword mCurrentSize; //!< Current size of the indices list udword* mRanks; //!< Two lists, swapped each pass udword* mRanks2; // Stats udword mTotalCalls; //!< Total number of calls to the sort routine udword mNbHits; //!< Number of early exits due to coherence // Internal methods void CheckResize(udword nb); bool Resize(udword nb); }; #endif // __ICERADIXSORT_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceRandom.cpp0000600000175000017500000000213612161402010023364 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for random generators. * \file IceRandom.cpp * \author Pierre Terdiman * \date August, 9, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace IceCore; void IceCore:: SRand(udword seed) { srand(seed); } udword IceCore::Rand() { return rand(); } static BasicRandom gRandomGenerator(42); udword IceCore::GetRandomIndex(udword max_index) { // We don't use rand() since it's limited to RAND_MAX udword Index = gRandomGenerator.Randomize(); return Index % max_index; } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceIndexedTriangle.cpp0000600000175000017500000005730212161402010025217 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains a handy indexed triangle class. * \file IceIndexedTriangle.cpp * \author Pierre Terdiman * \date January, 17, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace IceMaths; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains an indexed triangle class. * * \class Triangle * \author Pierre Terdiman * \version 1.0 * \date 08.15.98 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Flips the winding order. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void IndexedTriangle::Flip() { Swap(mVRef[1], mVRef[2]); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the triangle area. * \param verts [in] the list of indexed vertices * \return the area */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// float IndexedTriangle::Area(const Point* verts) const { if(!verts) return 0.0f; const Point& p0 = verts[0]; const Point& p1 = verts[1]; const Point& p2 = verts[2]; return ((p0-p1)^(p0-p2)).Magnitude() * 0.5f; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the triangle perimeter. * \param verts [in] the list of indexed vertices * \return the perimeter */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// float IndexedTriangle::Perimeter(const Point* verts) const { if(!verts) return 0.0f; const Point& p0 = verts[0]; const Point& p1 = verts[1]; const Point& p2 = verts[2]; return p0.Distance(p1) + p0.Distance(p2) + p1.Distance(p2); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the triangle compacity. * \param verts [in] the list of indexed vertices * \return the compacity */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// float IndexedTriangle::Compacity(const Point* verts) const { if(!verts) return 0.0f; float P = Perimeter(verts); if(P==0.0f) return 0.0f; return (4.0f*PI*Area(verts)/(P*P)); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the triangle normal. * \param verts [in] the list of indexed vertices * \param normal [out] the computed normal */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void IndexedTriangle::Normal(const Point* verts, Point& normal) const { if(!verts) return; const Point& p0 = verts[mVRef[0]]; const Point& p1 = verts[mVRef[1]]; const Point& p2 = verts[mVRef[2]]; normal = ((p2-p1)^(p0-p1)).Normalize(); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the triangle denormalized normal. * \param verts [in] the list of indexed vertices * \param normal [out] the computed normal */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void IndexedTriangle::DenormalizedNormal(const Point* verts, Point& normal) const { if(!verts) return; const Point& p0 = verts[mVRef[0]]; const Point& p1 = verts[mVRef[1]]; const Point& p2 = verts[mVRef[2]]; normal = ((p2-p1)^(p0-p1)); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the triangle center. * \param verts [in] the list of indexed vertices * \param center [out] the computed center */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void IndexedTriangle::Center(const Point* verts, Point& center) const { if(!verts) return; const Point& p0 = verts[mVRef[0]]; const Point& p1 = verts[mVRef[1]]; const Point& p2 = verts[mVRef[2]]; center = (p0+p1+p2)*INV3; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the centered normal * \param verts [in] the list of indexed vertices * \param normal [out] the computed centered normal */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void IndexedTriangle::CenteredNormal(const Point* verts, Point& normal) const { if(!verts) return; const Point& p0 = verts[mVRef[0]]; const Point& p1 = verts[mVRef[1]]; const Point& p2 = verts[mVRef[2]]; Point Center = (p0+p1+p2)*INV3; normal = Center + ((p2-p1)^(p0-p1)).Normalize(); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes a random point within the triangle. * \param verts [in] the list of indexed vertices * \param normal [out] the computed centered normal */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void IndexedTriangle::RandomPoint(const Point* verts, Point& random) const { if(!verts) return; // Random barycentric coords float Alpha = UnitRandomFloat(); float Beta = UnitRandomFloat(); float Gamma = UnitRandomFloat(); float OneOverTotal = 1.0f / (Alpha + Beta + Gamma); Alpha *= OneOverTotal; Beta *= OneOverTotal; Gamma *= OneOverTotal; const Point& p0 = verts[mVRef[0]]; const Point& p1 = verts[mVRef[1]]; const Point& p2 = verts[mVRef[2]]; random = Alpha*p0 + Beta*p1 + Gamma*p2; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes backface culling. * \param verts [in] the list of indexed vertices * \param source [in] source point (in local space) from which culling must be computed * \return true if the triangle is visible from the source point */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool IndexedTriangle::IsVisible(const Point* verts, const Point& source) const { // Checkings if(!verts) return false; const Point& p0 = verts[mVRef[0]]; const Point& p1 = verts[mVRef[1]]; const Point& p2 = verts[mVRef[2]]; // Compute denormalized normal Point Normal = (p2 - p1)^(p0 - p1); // Backface culling return (Normal | source) >= 0.0f; // Same as: // Plane PL(verts[mVRef[0]], verts[mVRef[1]], verts[mVRef[2]]); // return PL.Distance(source) > PL.d; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes backface culling. * \param verts [in] the list of indexed vertices * \param source [in] source point (in local space) from which culling must be computed * \return true if the triangle is visible from the source point */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool IndexedTriangle::BackfaceCulling(const Point* verts, const Point& source) const { // Checkings if(!verts) return false; const Point& p0 = verts[mVRef[0]]; const Point& p1 = verts[mVRef[1]]; const Point& p2 = verts[mVRef[2]]; // Compute base // Point Base = (p0 + p1 + p2)*INV3; // Compute denormalized normal Point Normal = (p2 - p1)^(p0 - p1); // Backface culling // return (Normal | (source - Base)) >= 0.0f; return (Normal | (source - p0)) >= 0.0f; // Same as: (but a bit faster) // Plane PL(verts[mVRef[0]], verts[mVRef[1]], verts[mVRef[2]]); // return PL.Distance(source)>0.0f; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the occlusion potential of the triangle. * \param verts [in] the list of indexed vertices * \param source [in] source point (in local space) from which occlusion potential must be computed * \return the occlusion potential */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// float IndexedTriangle::ComputeOcclusionPotential(const Point* verts, const Point& view) const { if(!verts) return 0.0f; // Occlusion potential: -(A * (N|V) / d^2) // A = polygon area // N = polygon normal // V = view vector // d = distance viewpoint-center of polygon float A = Area(verts); Point N; Normal(verts, N); Point C; Center(verts, C); float d = view.Distance(C); return -(A*(N|view))/(d*d); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Replaces a vertex reference with another one. * \param oldref [in] the vertex reference to replace * \param newref [in] the new vertex reference * \return true if success, else false if the input vertex reference doesn't belong to the triangle */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool IndexedTriangle::ReplaceVertex(dTriIndex oldref, dTriIndex newref) { if(mVRef[0]==oldref) { mVRef[0] = newref; return true; } else if(mVRef[1]==oldref) { mVRef[1] = newref; return true; } else if(mVRef[2]==oldref) { mVRef[2] = newref; return true; } return false; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks whether the triangle is degenerate or not. A degenerate triangle has two common vertex references. This is a zero-area triangle. * \return true if the triangle is degenerate */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool IndexedTriangle::IsDegenerate() const { if(mVRef[0]==mVRef[1]) return true; if(mVRef[1]==mVRef[2]) return true; if(mVRef[2]==mVRef[0]) return true; return false; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks whether the input vertex reference belongs to the triangle or not. * \param ref [in] the vertex reference to look for * \return true if the triangle contains the vertex reference */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool IndexedTriangle::HasVertex(dTriIndex ref) const { if(mVRef[0]==ref) return true; if(mVRef[1]==ref) return true; if(mVRef[2]==ref) return true; return false; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks whether the input vertex reference belongs to the triangle or not. * \param ref [in] the vertex reference to look for * \param index [out] the corresponding index in the triangle * \return true if the triangle contains the vertex reference */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool IndexedTriangle::HasVertex(dTriIndex ref, dTriIndex* index) const { if(mVRef[0]==ref) { *index = 0; return true; } if(mVRef[1]==ref) { *index = 1; return true; } if(mVRef[2]==ref) { *index = 2; return true; } return false; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Finds an edge in a tri, given two vertex references. * \param vref0 [in] the edge's first vertex reference * \param vref1 [in] the edge's second vertex reference * \return the edge number between 0 and 2, or 0xff if input refs are wrong. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ubyte IndexedTriangle::FindEdge(dTriIndex vref0, dTriIndex vref1) const { if(mVRef[0]==vref0 && mVRef[1]==vref1) return 0; else if(mVRef[0]==vref1 && mVRef[1]==vref0) return 0; else if(mVRef[0]==vref0 && mVRef[2]==vref1) return 1; else if(mVRef[0]==vref1 && mVRef[2]==vref0) return 1; else if(mVRef[1]==vref0 && mVRef[2]==vref1) return 2; else if(mVRef[1]==vref1 && mVRef[2]==vref0) return 2; return 0xff; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the last reference given the first two. * \param vref0 [in] the first vertex reference * \param vref1 [in] the second vertex reference * \return the last reference, or INVALID_ID if input refs are wrong. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// dTriIndex IndexedTriangle::OppositeVertex(dTriIndex vref0, dTriIndex vref1) const { if(mVRef[0]==vref0 && mVRef[1]==vref1) return mVRef[2]; else if(mVRef[0]==vref1 && mVRef[1]==vref0) return mVRef[2]; else if(mVRef[0]==vref0 && mVRef[2]==vref1) return mVRef[1]; else if(mVRef[0]==vref1 && mVRef[2]==vref0) return mVRef[1]; else if(mVRef[1]==vref0 && mVRef[2]==vref1) return mVRef[0]; else if(mVRef[1]==vref1 && mVRef[2]==vref0) return mVRef[0]; return (dTriIndex)INVALID_ID; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the three sorted vertex references according to an edge number. * edgenb = 0 => edge 0-1, returns references 0, 1, 2 * edgenb = 1 => edge 0-2, returns references 0, 2, 1 * edgenb = 2 => edge 1-2, returns references 1, 2, 0 * * \param edgenb [in] the edge number, 0, 1 or 2 * \param vref0 [out] the returned first vertex reference * \param vref1 [out] the returned second vertex reference * \param vref2 [out] the returned third vertex reference */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void IndexedTriangle::GetVRefs(ubyte edgenb, dTriIndex& vref0, dTriIndex& vref1, dTriIndex& vref2) const { if(edgenb==0) { vref0 = mVRef[0]; vref1 = mVRef[1]; vref2 = mVRef[2]; } else if(edgenb==1) { vref0 = mVRef[0]; vref1 = mVRef[2]; vref2 = mVRef[1]; } else if(edgenb==2) { vref0 = mVRef[1]; vref1 = mVRef[2]; vref2 = mVRef[0]; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the triangle's smallest edge length. * \param verts [in] the list of indexed vertices * \return the smallest edge length */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// float IndexedTriangle::MinEdgeLength(const Point* verts) const { if(!verts) return 0.0f; float Min = MAX_FLOAT; float Length01 = verts[0].Distance(verts[1]); float Length02 = verts[0].Distance(verts[2]); float Length12 = verts[1].Distance(verts[2]); if(Length01 < Min) Min = Length01; if(Length02 < Min) Min = Length02; if(Length12 < Min) Min = Length12; return Min; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the triangle's largest edge length. * \param verts [in] the list of indexed vertices * \return the largest edge length */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// float IndexedTriangle::MaxEdgeLength(const Point* verts) const { if(!verts) return 0.0f; float Max = MIN_FLOAT; float Length01 = verts[0].Distance(verts[1]); float Length02 = verts[0].Distance(verts[2]); float Length12 = verts[1].Distance(verts[2]); if(Length01 > Max) Max = Length01; if(Length02 > Max) Max = Length02; if(Length12 > Max) Max = Length12; return Max; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes a point on the triangle according to the stabbing information. * \param verts [in] the list of indexed vertices * \param u,v [in] point's barycentric coordinates * \param pt [out] point on triangle * \param nearvtx [out] index of nearest vertex */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void IndexedTriangle::ComputePoint(const Point* verts, float u, float v, Point& pt, dTriIndex* nearvtx) const { // Checkings if(!verts) return; // Get face in local or global space const Point& p0 = verts[mVRef[0]]; const Point& p1 = verts[mVRef[1]]; const Point& p2 = verts[mVRef[2]]; // Compute point coordinates pt = (1.0f - u - v)*p0 + u*p1 + v*p2; // Compute nearest vertex if needed if(nearvtx) { // Compute distance vector Point d(p0.SquareDistance(pt), // Distance^2 from vertex 0 to point on the face p1.SquareDistance(pt), // Distance^2 from vertex 1 to point on the face p2.SquareDistance(pt)); // Distance^2 from vertex 2 to point on the face // Get smallest distance *nearvtx = mVRef[d.SmallestAxis()]; } } //************************************** // Angle between two vectors (in radians) // we use this formula // uv = |u||v| cos(u,v) // u ^ v = w // |w| = |u||v| |sin(u,v)| //************************************** float Angle(const Point& u, const Point& v) { float NormU = u.Magnitude(); // |u| float NormV = v.Magnitude(); // |v| float Product = NormU*NormV; // |u||v| if(Product==0.0f) return 0.0f; float OneOverProduct = 1.0f / Product; // Cosinus float Cosinus = (u|v) * OneOverProduct; // Sinus Point w = u^v; float NormW = w.Magnitude(); float AbsSinus = NormW * OneOverProduct; // Remove degeneracy if(AbsSinus > 1.0f) AbsSinus = 1.0f; if(AbsSinus < -1.0f) AbsSinus = -1.0f; if(Cosinus>=0.0f) return asinf(AbsSinus); else return (PI-asinf(AbsSinus)); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the angle between two triangles. * \param tri [in] the other triangle * \param verts [in] the list of indexed vertices * \return the angle in radians */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// float IndexedTriangle::Angle(const IndexedTriangle& tri, const Point* verts) const { // Checkings if(!verts) return 0.0f; // Compute face normals Point n0, n1; Normal(verts, n0); tri.Normal(verts, n1); // Compute angle float dp = n0|n1; if(dp>1.0f) return 0.0f; if(dp<-1.0f) return PI; return acosf(dp); // return ::Angle(n0,n1); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks a triangle is the same as another one. * \param tri [in] the other triangle * \return true if same triangle */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool IndexedTriangle::Equal(const IndexedTriangle& tri) const { // Test all vertex references return (HasVertex(tri.mVRef[0]) && HasVertex(tri.mVRef[1]) && HasVertex(tri.mVRef[2])); } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceRandom.h0000600000175000017500000000305112161402010023026 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for random generators. * \file IceRandom.h * \author Pierre Terdiman * \date August, 9, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __ICERANDOM_H__ #define __ICERANDOM_H__ FUNCTION ICECORE_API void SRand(udword seed); FUNCTION ICECORE_API udword Rand(); //! Returns a unit random floating-point value inline_ float UnitRandomFloat() { return float(Rand()) * ONE_OVER_RAND_MAX; } //! Returns a random index so that 0<= index < max_index ICECORE_API udword GetRandomIndex(udword max_index); class ICECORE_API BasicRandom { public: //! Constructor inline_ BasicRandom(udword seed=0) : mRnd(seed) {} //! Destructor inline_ ~BasicRandom() {} inline_ void SetSeed(udword seed) { mRnd = seed; } inline_ udword GetCurrentValue() const { return mRnd; } inline_ udword Randomize() { mRnd = mRnd * 2147001325 + 715136305; return mRnd; } private: udword mRnd; }; #endif // __ICERANDOM_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceLSS.h0000600000175000017500000000756112161402010022261 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for line-swept spheres. * \file IceLSS.h * \author Pierre Terdiman * \date April, 4, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __ICELSS_H__ #define __ICELSS_H__ class ICEMATHS_API LSS : public Segment { public: //! Constructor inline_ LSS() {} //! Constructor inline_ LSS(const Segment& seg, float radius) : Segment(seg), mRadius(radius) {} //! Destructor inline_ ~LSS() {} /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes an OBB surrounding the LSS. * \param box [out] the OBB */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void ComputeOBB(OBB& box); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Tests if a point is contained within the LSS. * \param pt [in] the point to test * \return true if inside the LSS * \warning point and LSS must be in same space */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ bool Contains(const Point& pt) const { return SquareDistance(pt) <= mRadius*mRadius; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Tests if a sphere is contained within the LSS. * \param sphere [in] the sphere to test * \return true if inside the LSS * \warning sphere and LSS must be in same space */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ bool Contains(const Sphere& sphere) { float d = mRadius - sphere.mRadius; if(d>=0.0f) return SquareDistance(sphere.mCenter) <= d*d; else return false; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Tests if an LSS is contained within the LSS. * \param lss [in] the LSS to test * \return true if inside the LSS * \warning both LSS must be in same space */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ bool Contains(const LSS& lss) { // We check the LSS contains the two spheres at the start and end of the sweep return Contains(Sphere(lss.mP0, lss.mRadius)) && Contains(Sphere(lss.mP0, lss.mRadius)); } float mRadius; //!< Sphere radius }; #endif // __ICELSS_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceTriList.h0000600000175000017500000000427312161402010023207 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for a triangle container. * \file IceTrilist.h * \author Pierre Terdiman * \date April, 4, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __ICETRILIST_H__ #define __ICETRILIST_H__ class ICEMATHS_API TriList : public Container { public: // Constructor / Destructor TriList() {} ~TriList() {} inline_ udword GetNbTriangles() const { return GetNbEntries()/9; } inline_ Triangle* GetTriangles() const { return (Triangle*)GetEntries(); } void AddTri(const Triangle& tri) { Add(tri.mVerts[0].x).Add(tri.mVerts[0].y).Add(tri.mVerts[0].z); Add(tri.mVerts[1].x).Add(tri.mVerts[1].y).Add(tri.mVerts[1].z); Add(tri.mVerts[2].x).Add(tri.mVerts[2].y).Add(tri.mVerts[2].z); } void AddTri(const Point& p0, const Point& p1, const Point& p2) { Add(p0.x).Add(p0.y).Add(p0.z); Add(p1.x).Add(p1.y).Add(p1.z); Add(p2.x).Add(p2.y).Add(p2.z); } }; class ICEMATHS_API TriangleList : public Container { public: // Constructor / Destructor TriangleList() {} ~TriangleList() {} inline_ udword GetNbTriangles() const { return GetNbEntries()/3; } inline_ IndexedTriangle* GetTriangles() const { return (IndexedTriangle*)GetEntries();} void AddTriangle(const IndexedTriangle& tri) { Add((udword)tri.mVRef[0]).Add((udword)tri.mVRef[1]).Add((udword)tri.mVRef[2]); } void AddTriangle(udword vref0, udword vref1, udword vref2) { Add(vref0).Add(vref1).Add(vref2); } }; #endif //__ICETRILIST_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceOBB.h0000600000175000017500000002300012161402010022204 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains OBB-related code. (oriented bounding box) * \file IceOBB.h * \author Pierre Terdiman * \date January, 13, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __ICEOBB_H__ #define __ICEOBB_H__ // Forward declarations class LSS; class ICEMATHS_API OBB { public: //! Constructor inline_ OBB() {} //! Constructor inline_ OBB(const Point& center, const Point& extents, const Matrix3x3& rot) : mCenter(center), mExtents(extents), mRot(rot) {} //! Destructor inline_ ~OBB() {} /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Setups an empty OBB. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void SetEmpty() { mCenter.Zero(); mExtents.Set(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); mRot.Identity(); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Tests if a point is contained within the OBB. * \param p [in] the world point to test * \return true if inside the OBB */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool ContainsPoint(const Point& p) const; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Builds an OBB from an AABB and a world transform. * \param aabb [in] the aabb * \param mat [in] the world transform */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Create(const AABB& aabb, const Matrix4x4& mat); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recomputes the OBB after an arbitrary transform by a 4x4 matrix. * \param mtx [in] the transform matrix * \param obb [out] the transformed OBB */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void Rotate(const Matrix4x4& mtx, OBB& obb) const { // The extents remain constant obb.mExtents = mExtents; // The center gets x-formed obb.mCenter = mCenter * mtx; // Combine rotations obb.mRot = mRot * Matrix3x3(mtx); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks the OBB is valid. * \return true if the box is valid */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL IsValid() const { // Consistency condition for (Center, Extents) boxes: Extents >= 0.0f if(mExtents.x < 0.0f) return FALSE; if(mExtents.y < 0.0f) return FALSE; if(mExtents.z < 0.0f) return FALSE; return TRUE; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the obb planes. * \param planes [out] 6 box planes * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool ComputePlanes(Plane* planes) const; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the obb points. * \param pts [out] 8 box points * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool ComputePoints(Point* pts) const; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes vertex normals. * \param pts [out] 8 box points * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool ComputeVertexNormals(Point* pts) const; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Returns edges. * \return 24 indices (12 edges) indexing the list returned by ComputePoints() */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const udword* GetEdges() const; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Returns local edge normals. * \return edge normals in local space */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const Point* GetLocalEdgeNormals() const; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Returns world edge normal * \param edge_index [in] 0 <= edge index < 12 * \param world_normal [out] edge normal in world space */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void ComputeWorldEdgeNormal(udword edge_index, Point& world_normal) const; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes an LSS surrounding the OBB. * \param lss [out] the LSS */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void ComputeLSS(LSS& lss) const; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks the OBB is inside another OBB. * \param box [in] the other OBB * \return TRUE if we're inside the other box */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// BOOL IsInside(const OBB& box) const; inline_ const Point& GetCenter() const { return mCenter; } inline_ const Point& GetExtents() const { return mExtents; } inline_ const Matrix3x3& GetRot() const { return mRot; } inline_ void GetRotatedExtents(Matrix3x3& extents) const { extents = mRot; extents.Scale(mExtents); } Point mCenter; //!< B for Box Point mExtents; //!< B for Bounding Matrix3x3 mRot; //!< O for Oriented // Orientation is stored in row-major format, // i.e. rows = eigen vectors of the covariance matrix }; #endif // __ICEOBB_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceMatrix4x4.h0000600000175000017500000005114512161402010023421 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for 4x4 matrices. * \file IceMatrix4x4.h * \author Pierre Terdiman * \date April, 4, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __ICEMATRIX4X4_H__ #define __ICEMATRIX4X4_H__ // Forward declarations class PRS; class PR; #define MATRIX4X4_EPSILON (1.0e-7f) class ICEMATHS_API Matrix4x4 { // void LUBackwardSubstitution( sdword *indx, float* b ); // void LUDecomposition( sdword* indx, float* d ); public: //! Empty constructor. inline_ Matrix4x4() {} //! Constructor from 16 values inline_ Matrix4x4( float m00, float m01, float m02, float m03, float m10, float m11, float m12, float m13, float m20, float m21, float m22, float m23, float m30, float m31, float m32, float m33) { m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; m[0][3] = m03; m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; m[1][3] = m13; m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; m[2][3] = m23; m[3][0] = m30; m[3][1] = m31; m[3][2] = m32; m[3][3] = m33; } //! Copy constructor inline_ Matrix4x4(const Matrix4x4& mat) { CopyMemory(m, &mat.m, 16*sizeof(float)); } //! Destructor. inline_ ~Matrix4x4() {} //! Assign values (rotation only) inline_ Matrix4x4& Set( float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22) { m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; return *this; } //! Assign values inline_ Matrix4x4& Set( float m00, float m01, float m02, float m03, float m10, float m11, float m12, float m13, float m20, float m21, float m22, float m23, float m30, float m31, float m32, float m33) { m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; m[0][3] = m03; m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; m[1][3] = m13; m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; m[2][3] = m23; m[3][0] = m30; m[3][1] = m31; m[3][2] = m32; m[3][3] = m33; return *this; } //! Copy from a Matrix4x4 inline_ void Copy(const Matrix4x4& source) { CopyMemory(m, source.m, 16*sizeof(float)); } // Row-column access //! Returns a row. inline_ void GetRow(const udword r, HPoint& p) const { p.x=m[r][0]; p.y=m[r][1]; p.z=m[r][2]; p.w=m[r][3]; } //! Returns a row. inline_ void GetRow(const udword r, Point& p) const { p.x=m[r][0]; p.y=m[r][1]; p.z=m[r][2]; } //! Returns a row. inline_ const HPoint& GetRow(const udword r) const { return *(const HPoint*)&m[r][0]; } //! Returns a row. inline_ HPoint& GetRow(const udword r) { return *(HPoint*)&m[r][0]; } //! Sets a row. inline_ void SetRow(const udword r, const HPoint& p) { m[r][0]=p.x; m[r][1]=p.y; m[r][2]=p.z; m[r][3]=p.w; } //! Sets a row. inline_ void SetRow(const udword r, const Point& p) { m[r][0]=p.x; m[r][1]=p.y; m[r][2]=p.z; m[r][3]= (r!=3) ? 0.0f : 1.0f; } //! Returns a column. inline_ void GetCol(const udword c, HPoint& p) const { p.x=m[0][c]; p.y=m[1][c]; p.z=m[2][c]; p.w=m[3][c]; } //! Returns a column. inline_ void GetCol(const udword c, Point& p) const { p.x=m[0][c]; p.y=m[1][c]; p.z=m[2][c]; } //! Sets a column. inline_ void SetCol(const udword c, const HPoint& p) { m[0][c]=p.x; m[1][c]=p.y; m[2][c]=p.z; m[3][c]=p.w; } //! Sets a column. inline_ void SetCol(const udword c, const Point& p) { m[0][c]=p.x; m[1][c]=p.y; m[2][c]=p.z; m[3][c]= (c!=3) ? 0.0f : 1.0f; } // Translation //! Returns the translation part of the matrix. inline_ const HPoint& GetTrans() const { return GetRow(3); } //! Gets the translation part of the matrix inline_ void GetTrans(Point& p) const { p.x=m[3][0]; p.y=m[3][1]; p.z=m[3][2]; } //! Sets the translation part of the matrix, from a Point. inline_ void SetTrans(const Point& p) { m[3][0]=p.x; m[3][1]=p.y; m[3][2]=p.z; } //! Sets the translation part of the matrix, from a HPoint. inline_ void SetTrans(const HPoint& p) { m[3][0]=p.x; m[3][1]=p.y; m[3][2]=p.z; m[3][3]=p.w; } //! Sets the translation part of the matrix, from floats. inline_ void SetTrans(float tx, float ty, float tz) { m[3][0]=tx; m[3][1]=ty; m[3][2]=tz; } // Scale //! Sets the scale from a Point. The point is put on the diagonal. inline_ void SetScale(const Point& p) { m[0][0]=p.x; m[1][1]=p.y; m[2][2]=p.z; } //! Sets the scale from floats. Values are put on the diagonal. inline_ void SetScale(float sx, float sy, float sz) { m[0][0]=sx; m[1][1]=sy; m[2][2]=sz; } //! Scales from a Point. Each row is multiplied by a component. void Scale(const Point& p) { m[0][0] *= p.x; m[1][0] *= p.y; m[2][0] *= p.z; m[0][1] *= p.x; m[1][1] *= p.y; m[2][1] *= p.z; m[0][2] *= p.x; m[1][2] *= p.y; m[2][2] *= p.z; } //! Scales from floats. Each row is multiplied by a value. void Scale(float sx, float sy, float sz) { m[0][0] *= sx; m[1][0] *= sy; m[2][0] *= sz; m[0][1] *= sx; m[1][1] *= sy; m[2][1] *= sz; m[0][2] *= sx; m[1][2] *= sy; m[2][2] *= sz; } /* //! Returns a row. inline_ HPoint GetRow(const udword row) const { return mRow[row]; } //! Sets a row. inline_ Matrix4x4& SetRow(const udword row, const HPoint& p) { mRow[row] = p; return *this; } //! Sets a row. Matrix4x4& SetRow(const udword row, const Point& p) { m[row][0] = p.x; m[row][1] = p.y; m[row][2] = p.z; m[row][3] = (row != 3) ? 0.0f : 1.0f; return *this; } //! Returns a column. HPoint GetCol(const udword col) const { HPoint Res; Res.x = m[0][col]; Res.y = m[1][col]; Res.z = m[2][col]; Res.w = m[3][col]; return Res; } //! Sets a column. Matrix4x4& SetCol(const udword col, const HPoint& p) { m[0][col] = p.x; m[1][col] = p.y; m[2][col] = p.z; m[3][col] = p.w; return *this; } //! Sets a column. Matrix4x4& SetCol(const udword col, const Point& p) { m[0][col] = p.x; m[1][col] = p.y; m[2][col] = p.z; m[3][col] = (col != 3) ? 0.0f : 1.0f; return *this; } */ //! Computes the trace. The trace is the sum of the 4 diagonal components. inline_ float Trace() const { return m[0][0] + m[1][1] + m[2][2] + m[3][3]; } //! Computes the trace of the upper 3x3 matrix. inline_ float Trace3x3() const { return m[0][0] + m[1][1] + m[2][2]; } //! Clears the matrix. inline_ void Zero() { ZeroMemory(&m, sizeof(m)); } //! Sets the identity matrix. inline_ void Identity() { Zero(); m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f; } //! Checks for identity inline_ bool IsIdentity() const { if(IR(m[0][0])!=IEEE_1_0) return false; if(IR(m[0][1])!=0) return false; if(IR(m[0][2])!=0) return false; if(IR(m[0][3])!=0) return false; if(IR(m[1][0])!=0) return false; if(IR(m[1][1])!=IEEE_1_0) return false; if(IR(m[1][2])!=0) return false; if(IR(m[1][3])!=0) return false; if(IR(m[2][0])!=0) return false; if(IR(m[2][1])!=0) return false; if(IR(m[2][2])!=IEEE_1_0) return false; if(IR(m[2][3])!=0) return false; if(IR(m[3][0])!=0) return false; if(IR(m[3][1])!=0) return false; if(IR(m[3][2])!=0) return false; if(IR(m[3][3])!=IEEE_1_0) return false; return true; } //! Checks matrix validity inline_ BOOL IsValid() const { for(udword j=0;j<4;j++) { for(udword i=0;i<4;i++) { if(!IsValidFloat(m[j][i])) return FALSE; } } return TRUE; } //! Sets a rotation matrix around the X axis. void RotX(float angle) { float Cos = cosf(angle), Sin = sinf(angle); Identity(); m[1][1] = m[2][2] = Cos; m[2][1] = -Sin; m[1][2] = Sin; } //! Sets a rotation matrix around the Y axis. void RotY(float angle) { float Cos = cosf(angle), Sin = sinf(angle); Identity(); m[0][0] = m[2][2] = Cos; m[2][0] = Sin; m[0][2] = -Sin; } //! Sets a rotation matrix around the Z axis. void RotZ(float angle) { float Cos = cosf(angle), Sin = sinf(angle); Identity(); m[0][0] = m[1][1] = Cos; m[1][0] = -Sin; m[0][1] = Sin; } //! Makes a rotation matrix about an arbitrary axis Matrix4x4& Rot(float angle, Point& p1, Point& p2); //! Transposes the matrix. void Transpose() { IR(m[1][0]) ^= IR(m[0][1]); IR(m[0][1]) ^= IR(m[1][0]); IR(m[1][0]) ^= IR(m[0][1]); IR(m[2][0]) ^= IR(m[0][2]); IR(m[0][2]) ^= IR(m[2][0]); IR(m[2][0]) ^= IR(m[0][2]); IR(m[3][0]) ^= IR(m[0][3]); IR(m[0][3]) ^= IR(m[3][0]); IR(m[3][0]) ^= IR(m[0][3]); IR(m[1][2]) ^= IR(m[2][1]); IR(m[2][1]) ^= IR(m[1][2]); IR(m[1][2]) ^= IR(m[2][1]); IR(m[1][3]) ^= IR(m[3][1]); IR(m[3][1]) ^= IR(m[1][3]); IR(m[1][3]) ^= IR(m[3][1]); IR(m[2][3]) ^= IR(m[3][2]); IR(m[3][2]) ^= IR(m[2][3]); IR(m[2][3]) ^= IR(m[3][2]); } //! Computes a cofactor. Used for matrix inversion. float CoFactor(udword row, udword col) const; //! Computes the determinant of the matrix. float Determinant() const; //! Inverts the matrix. Determinant must be different from zero, else matrix can't be inverted. Matrix4x4& Invert(); // Matrix& ComputeAxisMatrix(Point& axis, float angle); // Cast operators //! Casts a Matrix4x4 to a Matrix3x3. inline_ operator Matrix3x3() const { return Matrix3x3( m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2], m[2][0], m[2][1], m[2][2]); } //! Casts a Matrix4x4 to a Quat. operator Quat() const; //! Casts a Matrix4x4 to a PR. operator PR() const; // Arithmetic operators //! Operator for Matrix4x4 Plus = Matrix4x4 + Matrix4x4; inline_ Matrix4x4 operator+(const Matrix4x4& mat) const { return Matrix4x4( m[0][0]+mat.m[0][0], m[0][1]+mat.m[0][1], m[0][2]+mat.m[0][2], m[0][3]+mat.m[0][3], m[1][0]+mat.m[1][0], m[1][1]+mat.m[1][1], m[1][2]+mat.m[1][2], m[1][3]+mat.m[1][3], m[2][0]+mat.m[2][0], m[2][1]+mat.m[2][1], m[2][2]+mat.m[2][2], m[2][3]+mat.m[2][3], m[3][0]+mat.m[3][0], m[3][1]+mat.m[3][1], m[3][2]+mat.m[3][2], m[3][3]+mat.m[3][3]); } //! Operator for Matrix4x4 Minus = Matrix4x4 - Matrix4x4; inline_ Matrix4x4 operator-(const Matrix4x4& mat) const { return Matrix4x4( m[0][0]-mat.m[0][0], m[0][1]-mat.m[0][1], m[0][2]-mat.m[0][2], m[0][3]-mat.m[0][3], m[1][0]-mat.m[1][0], m[1][1]-mat.m[1][1], m[1][2]-mat.m[1][2], m[1][3]-mat.m[1][3], m[2][0]-mat.m[2][0], m[2][1]-mat.m[2][1], m[2][2]-mat.m[2][2], m[2][3]-mat.m[2][3], m[3][0]-mat.m[3][0], m[3][1]-mat.m[3][1], m[3][2]-mat.m[3][2], m[3][3]-mat.m[3][3]); } //! Operator for Matrix4x4 Mul = Matrix4x4 * Matrix4x4; inline_ Matrix4x4 operator*(const Matrix4x4& mat) const { return Matrix4x4( m[0][0]*mat.m[0][0] + m[0][1]*mat.m[1][0] + m[0][2]*mat.m[2][0] + m[0][3]*mat.m[3][0], m[0][0]*mat.m[0][1] + m[0][1]*mat.m[1][1] + m[0][2]*mat.m[2][1] + m[0][3]*mat.m[3][1], m[0][0]*mat.m[0][2] + m[0][1]*mat.m[1][2] + m[0][2]*mat.m[2][2] + m[0][3]*mat.m[3][2], m[0][0]*mat.m[0][3] + m[0][1]*mat.m[1][3] + m[0][2]*mat.m[2][3] + m[0][3]*mat.m[3][3], m[1][0]*mat.m[0][0] + m[1][1]*mat.m[1][0] + m[1][2]*mat.m[2][0] + m[1][3]*mat.m[3][0], m[1][0]*mat.m[0][1] + m[1][1]*mat.m[1][1] + m[1][2]*mat.m[2][1] + m[1][3]*mat.m[3][1], m[1][0]*mat.m[0][2] + m[1][1]*mat.m[1][2] + m[1][2]*mat.m[2][2] + m[1][3]*mat.m[3][2], m[1][0]*mat.m[0][3] + m[1][1]*mat.m[1][3] + m[1][2]*mat.m[2][3] + m[1][3]*mat.m[3][3], m[2][0]*mat.m[0][0] + m[2][1]*mat.m[1][0] + m[2][2]*mat.m[2][0] + m[2][3]*mat.m[3][0], m[2][0]*mat.m[0][1] + m[2][1]*mat.m[1][1] + m[2][2]*mat.m[2][1] + m[2][3]*mat.m[3][1], m[2][0]*mat.m[0][2] + m[2][1]*mat.m[1][2] + m[2][2]*mat.m[2][2] + m[2][3]*mat.m[3][2], m[2][0]*mat.m[0][3] + m[2][1]*mat.m[1][3] + m[2][2]*mat.m[2][3] + m[2][3]*mat.m[3][3], m[3][0]*mat.m[0][0] + m[3][1]*mat.m[1][0] + m[3][2]*mat.m[2][0] + m[3][3]*mat.m[3][0], m[3][0]*mat.m[0][1] + m[3][1]*mat.m[1][1] + m[3][2]*mat.m[2][1] + m[3][3]*mat.m[3][1], m[3][0]*mat.m[0][2] + m[3][1]*mat.m[1][2] + m[3][2]*mat.m[2][2] + m[3][3]*mat.m[3][2], m[3][0]*mat.m[0][3] + m[3][1]*mat.m[1][3] + m[3][2]*mat.m[2][3] + m[3][3]*mat.m[3][3]); } //! Operator for HPoint Mul = Matrix4x4 * HPoint; inline_ HPoint operator*(const HPoint& v) const { return HPoint(GetRow(0)|v, GetRow(1)|v, GetRow(2)|v, GetRow(3)|v); } //! Operator for Point Mul = Matrix4x4 * Point; inline_ Point operator*(const Point& v) const { return Point( m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + m[0][3], m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + m[1][3], m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + m[2][3] ); } //! Operator for Matrix4x4 Scale = Matrix4x4 * float; inline_ Matrix4x4 operator*(float s) const { return Matrix4x4( m[0][0]*s, m[0][1]*s, m[0][2]*s, m[0][3]*s, m[1][0]*s, m[1][1]*s, m[1][2]*s, m[1][3]*s, m[2][0]*s, m[2][1]*s, m[2][2]*s, m[2][3]*s, m[3][0]*s, m[3][1]*s, m[3][2]*s, m[3][3]*s); } //! Operator for Matrix4x4 Scale = float * Matrix4x4; inline_ friend Matrix4x4 operator*(float s, const Matrix4x4& mat) { return Matrix4x4( s*mat.m[0][0], s*mat.m[0][1], s*mat.m[0][2], s*mat.m[0][3], s*mat.m[1][0], s*mat.m[1][1], s*mat.m[1][2], s*mat.m[1][3], s*mat.m[2][0], s*mat.m[2][1], s*mat.m[2][2], s*mat.m[2][3], s*mat.m[3][0], s*mat.m[3][1], s*mat.m[3][2], s*mat.m[3][3]); } //! Operator for Matrix4x4 Div = Matrix4x4 / float; inline_ Matrix4x4 operator/(float s) const { if(s) s = 1.0f / s; return Matrix4x4( m[0][0]*s, m[0][1]*s, m[0][2]*s, m[0][3]*s, m[1][0]*s, m[1][1]*s, m[1][2]*s, m[1][3]*s, m[2][0]*s, m[2][1]*s, m[2][2]*s, m[2][3]*s, m[3][0]*s, m[3][1]*s, m[3][2]*s, m[3][3]*s); } //! Operator for Matrix4x4 Div = float / Matrix4x4; inline_ friend Matrix4x4 operator/(float s, const Matrix4x4& mat) { return Matrix4x4( s/mat.m[0][0], s/mat.m[0][1], s/mat.m[0][2], s/mat.m[0][3], s/mat.m[1][0], s/mat.m[1][1], s/mat.m[1][2], s/mat.m[1][3], s/mat.m[2][0], s/mat.m[2][1], s/mat.m[2][2], s/mat.m[2][3], s/mat.m[3][0], s/mat.m[3][1], s/mat.m[3][2], s/mat.m[3][3]); } //! Operator for Matrix4x4 += Matrix4x4; inline_ Matrix4x4& operator+=(const Matrix4x4& mat) { m[0][0]+=mat.m[0][0]; m[0][1]+=mat.m[0][1]; m[0][2]+=mat.m[0][2]; m[0][3]+=mat.m[0][3]; m[1][0]+=mat.m[1][0]; m[1][1]+=mat.m[1][1]; m[1][2]+=mat.m[1][2]; m[1][3]+=mat.m[1][3]; m[2][0]+=mat.m[2][0]; m[2][1]+=mat.m[2][1]; m[2][2]+=mat.m[2][2]; m[2][3]+=mat.m[2][3]; m[3][0]+=mat.m[3][0]; m[3][1]+=mat.m[3][1]; m[3][2]+=mat.m[3][2]; m[3][3]+=mat.m[3][3]; return *this; } //! Operator for Matrix4x4 -= Matrix4x4; inline_ Matrix4x4& operator-=(const Matrix4x4& mat) { m[0][0]-=mat.m[0][0]; m[0][1]-=mat.m[0][1]; m[0][2]-=mat.m[0][2]; m[0][3]-=mat.m[0][3]; m[1][0]-=mat.m[1][0]; m[1][1]-=mat.m[1][1]; m[1][2]-=mat.m[1][2]; m[1][3]-=mat.m[1][3]; m[2][0]-=mat.m[2][0]; m[2][1]-=mat.m[2][1]; m[2][2]-=mat.m[2][2]; m[2][3]-=mat.m[2][3]; m[3][0]-=mat.m[3][0]; m[3][1]-=mat.m[3][1]; m[3][2]-=mat.m[3][2]; m[3][3]-=mat.m[3][3]; return *this; } //! Operator for Matrix4x4 *= Matrix4x4; Matrix4x4& operator*=(const Matrix4x4& mat) { HPoint TempRow; GetRow(0, TempRow); m[0][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0]; m[0][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1]; m[0][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2]; m[0][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3]; GetRow(1, TempRow); m[1][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0]; m[1][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1]; m[1][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2]; m[1][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3]; GetRow(2, TempRow); m[2][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0]; m[2][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1]; m[2][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2]; m[2][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3]; GetRow(3, TempRow); m[3][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0]; m[3][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1]; m[3][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2]; m[3][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3]; return *this; } //! Operator for Matrix4x4 *= float; inline_ Matrix4x4& operator*=(float s) { m[0][0]*=s; m[0][1]*=s; m[0][2]*=s; m[0][3]*=s; m[1][0]*=s; m[1][1]*=s; m[1][2]*=s; m[1][3]*=s; m[2][0]*=s; m[2][1]*=s; m[2][2]*=s; m[2][3]*=s; m[3][0]*=s; m[3][1]*=s; m[3][2]*=s; m[3][3]*=s; return *this; } //! Operator for Matrix4x4 /= float; inline_ Matrix4x4& operator/=(float s) { if(s) s = 1.0f / s; m[0][0]*=s; m[0][1]*=s; m[0][2]*=s; m[0][3]*=s; m[1][0]*=s; m[1][1]*=s; m[1][2]*=s; m[1][3]*=s; m[2][0]*=s; m[2][1]*=s; m[2][2]*=s; m[2][3]*=s; m[3][0]*=s; m[3][1]*=s; m[3][2]*=s; m[3][3]*=s; return *this; } inline_ const HPoint& operator[](int row) const { return *(const HPoint*)&m[row][0]; } inline_ HPoint& operator[](int row) { return *(HPoint*)&m[row][0]; } public: float m[4][4]; }; //! Quickly rotates & translates a vector, using the 4x3 part of a 4x4 matrix inline_ void TransformPoint4x3(Point& dest, const Point& source, const Matrix4x4& rot) { dest.x = rot.m[3][0] + source.x * rot.m[0][0] + source.y * rot.m[1][0] + source.z * rot.m[2][0]; dest.y = rot.m[3][1] + source.x * rot.m[0][1] + source.y * rot.m[1][1] + source.z * rot.m[2][1]; dest.z = rot.m[3][2] + source.x * rot.m[0][2] + source.y * rot.m[1][2] + source.z * rot.m[2][2]; } //! Quickly rotates a vector, using the 3x3 part of a 4x4 matrix inline_ void TransformPoint3x3(Point& dest, const Point& source, const Matrix4x4& rot) { dest.x = source.x * rot.m[0][0] + source.y * rot.m[1][0] + source.z * rot.m[2][0]; dest.y = source.x * rot.m[0][1] + source.y * rot.m[1][1] + source.z * rot.m[2][1]; dest.z = source.x * rot.m[0][2] + source.y * rot.m[1][2] + source.z * rot.m[2][2]; } ICEMATHS_API void InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src); #endif // __ICEMATRIX4X4_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceSegment.cpp0000600000175000017500000000361012161402010023544 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for segments. * \file IceSegment.cpp * \author Pierre Terdiman * \date April, 4, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Segment class. * A segment is defined by S(t) = mP0 * (1 - t) + mP1 * t, with 0 <= t <= 1 * Alternatively, a segment is S(t) = Origin + t * Direction for 0 <= t <= 1. * Direction is not necessarily unit length. The end points are Origin = mP0 and Origin + Direction = mP1. * * \class Segment * \author Pierre Terdiman * \version 1.0 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace IceMaths; float Segment::SquareDistance(const Point& point, float* t) const { Point Diff = point - mP0; Point Dir = mP1 - mP0; float fT = Diff | Dir; if(fT<=0.0f) { fT = 0.0f; } else { float SqrLen= Dir.SquareMagnitude(); if(fT>=SqrLen) { fT = 1.0f; Diff -= Dir; } else { fT /= SqrLen; Diff -= fT*Dir; } } if(t) *t = fT; return Diff.SquareMagnitude(); } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceRay.cpp0000600000175000017500000000470012161402010022676 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for rays. * \file IceRay.cpp * \author Pierre Terdiman * \date April, 4, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Ray class. * A ray is a half-line P(t) = mOrig + mDir * t, with 0 <= t <= +infinity * \class Ray * \author Pierre Terdiman * \version 1.0 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* O = Origin = impact point i = normalized vector along the x axis j = normalized vector along the y axis = actually the normal vector in O D = Direction vector, norm |D| = 1 N = Projection of D on y axis, norm |N| = normal reaction T = Projection of D on x axis, norm |T| = tangential reaction R = Reflexion vector ^y | | | _ _ _| _ _ _ * * *| \ | / \ |N / | R\ | /D \ | / | \ | / _________\|/______*_______>x O T Let define theta = angle between D and N. Then cos(theta) = |N| / |D| = |N| since D is normalized. j|D = |j|*|D|*cos(theta) => |N| = j|D Then we simply have: D = N + T To compute tangential reaction : T = D - N To compute reflexion vector : R = N - T = N - (D-N) = 2*N - D */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace IceMaths; float Ray::SquareDistance(const Point& point, float* t) const { Point Diff = point - mOrig; float fT = Diff | mDir; if(fT<=0.0f) { fT = 0.0f; } else { fT /= mDir.SquareMagnitude(); Diff -= fT*mDir; } if(t) *t = fT; return Diff.SquareMagnitude(); } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceAABB.h0000600000175000017500000006076012161402010022305 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains AABB-related code. (axis-aligned bounding box) * \file IceAABB.h * \author Pierre Terdiman * \date January, 13, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __ICEAABB_H__ #define __ICEAABB_H__ // Forward declarations class Sphere; //! Declarations of type-independent methods (most of them implemented in the .cpp) #define AABB_COMMON_METHODS \ AABB& Add(const AABB& aabb); \ float MakeCube(AABB& cube) const; \ void MakeSphere(Sphere& sphere) const; \ const sbyte* ComputeOutline(const Point& local_eye, sdword& num) const; \ float ComputeBoxArea(const Point& eye, const Matrix4x4& mat, float width, float height, sdword& num) const; \ bool IsInside(const AABB& box) const; \ bool ComputePlanes(Plane* planes) const; \ bool ComputePoints(Point* pts) const; \ const Point* GetVertexNormals() const; \ const udword* GetEdges() const; \ const Point* GetEdgeNormals() const; \ inline_ BOOL ContainsPoint(const Point& p) const \ { \ if(p.x > GetMax(0) || p.x < GetMin(0)) return FALSE; \ if(p.y > GetMax(1) || p.y < GetMin(1)) return FALSE; \ if(p.z > GetMax(2) || p.z < GetMin(2)) return FALSE; \ return TRUE; \ } enum AABBType { AABB_RENDER = 0, //!< AABB used for rendering. Not visible == not rendered. AABB_UPDATE = 1, //!< AABB used for dynamic updates. Not visible == not updated. AABB_FORCE_DWORD = 0x7fffffff, }; #ifdef USE_MINMAX struct ICEMATHS_API ShadowAABB { Point mMin; Point mMax; }; class ICEMATHS_API AABB { public: //! Constructor inline_ AABB() {} //! Destructor inline_ ~AABB() {} //! Type-independent methods AABB_COMMON_METHODS; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Setups an AABB from min & max vectors. * \param min [in] the min point * \param max [in] the max point */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void SetMinMax(const Point& min, const Point& max) { mMin = min; mMax = max; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Setups an AABB from center & extents vectors. * \param c [in] the center point * \param e [in] the extents vector */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void SetCenterExtents(const Point& c, const Point& e) { mMin = c - e; mMax = c + e; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Setups an empty AABB. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void SetEmpty() { Point p(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); mMin = -p; mMax = p;} /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Setups a point AABB. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void SetPoint(const Point& pt) { mMin = mMax = pt; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the size of the AABB. The size is defined as the longest extent. * \return the size of the AABB */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// float GetSize() const { Point e; GetExtents(e); return e.Max(); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Extends the AABB. * \param p [in] the next point */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Extend(const Point& p) { if(p.x > mMax.x) mMax.x = p.x; if(p.x < mMin.x) mMin.x = p.x; if(p.y > mMax.y) mMax.y = p.y; if(p.y < mMin.y) mMin.y = p.y; if(p.z > mMax.z) mMax.z = p.z; if(p.z < mMin.z) mMin.z = p.z; } // Data access //! Get min point of the box inline_ void GetMin(Point& min) const { min = mMin; } //! Get max point of the box inline_ void GetMax(Point& max) const { max = mMax; } //! Get component of the box's min point along a given axis inline_ float GetMin(udword axis) const { return mMin[axis]; } //! Get component of the box's max point along a given axis inline_ float GetMax(udword axis) const { return mMax[axis]; } //! Get box center inline_ void GetCenter(Point& center) const { center = (mMax + mMin)*0.5f; } //! Get box extents inline_ void GetExtents(Point& extents) const { extents = (mMax - mMin)*0.5f; } //! Get component of the box's center along a given axis inline_ float GetCenter(udword axis) const { return (mMax[axis] + mMin[axis])*0.5f; } //! Get component of the box's extents along a given axis inline_ float GetExtents(udword axis) const { return (mMax[axis] - mMin[axis])*0.5f; } //! Get box diagonal inline_ void GetDiagonal(Point& diagonal) const { diagonal = mMax - mMin; } inline_ float GetWidth() const { return mMax.x - mMin.x; } inline_ float GetHeight() const { return mMax.y - mMin.y; } inline_ float GetDepth() const { return mMax.z - mMin.z; } //! Volume inline_ float GetVolume() const { return GetWidth() * GetHeight() * GetDepth(); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the intersection between two AABBs. * \param a [in] the other AABB * \return true on intersection */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL Intersect(const AABB& a) const { if(mMax.x < a.mMin.x || a.mMax.x < mMin.x || mMax.y < a.mMin.y || a.mMax.y < mMin.y || mMax.z < a.mMin.z || a.mMax.z < mMin.z) return FALSE; return TRUE; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the 1D-intersection between two AABBs, on a given axis. * \param a [in] the other AABB * \param axis [in] the axis (0, 1, 2) * \return true on intersection */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL Intersect(const AABB& a, udword axis) const { if(mMax[axis] < a.mMin[axis] || a.mMax[axis] < mMin[axis]) return FALSE; return TRUE; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recomputes the AABB after an arbitrary transform by a 4x4 matrix. * Original code by Charles Bloom on the GD-Algorithm list. (I slightly modified it) * \param mtx [in] the transform matrix * \param aabb [out] the transformed AABB [can be *this] */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void Rotate(const Matrix4x4& mtx, AABB& aabb) const { // The three edges transformed: you can efficiently transform an X-only vector // by just getting the "X" column of the matrix Point vx,vy,vz; mtx.GetRow(0, vx); vx *= (mMax.x - mMin.x); mtx.GetRow(1, vy); vy *= (mMax.y - mMin.y); mtx.GetRow(2, vz); vz *= (mMax.z - mMin.z); // Transform the min point aabb.mMin = aabb.mMax = mMin * mtx; // Take the transformed min & axes and find new extents // Using CPU code in the right place is faster... if(IS_NEGATIVE_FLOAT(vx.x)) aabb.mMin.x += vx.x; else aabb.mMax.x += vx.x; if(IS_NEGATIVE_FLOAT(vx.y)) aabb.mMin.y += vx.y; else aabb.mMax.y += vx.y; if(IS_NEGATIVE_FLOAT(vx.z)) aabb.mMin.z += vx.z; else aabb.mMax.z += vx.z; if(IS_NEGATIVE_FLOAT(vy.x)) aabb.mMin.x += vy.x; else aabb.mMax.x += vy.x; if(IS_NEGATIVE_FLOAT(vy.y)) aabb.mMin.y += vy.y; else aabb.mMax.y += vy.y; if(IS_NEGATIVE_FLOAT(vy.z)) aabb.mMin.z += vy.z; else aabb.mMax.z += vy.z; if(IS_NEGATIVE_FLOAT(vz.x)) aabb.mMin.x += vz.x; else aabb.mMax.x += vz.x; if(IS_NEGATIVE_FLOAT(vz.y)) aabb.mMin.y += vz.y; else aabb.mMax.y += vz.y; if(IS_NEGATIVE_FLOAT(vz.z)) aabb.mMin.z += vz.z; else aabb.mMax.z += vz.z; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks the AABB is valid. * \return true if the box is valid */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL IsValid() const { // Consistency condition for (Min, Max) boxes: min < max if(mMin.x > mMax.x) return FALSE; if(mMin.y > mMax.y) return FALSE; if(mMin.z > mMax.z) return FALSE; return TRUE; } //! Operator for AABB *= float. Scales the extents, keeps same center. inline_ AABB& operator*=(float s) { Point Center; GetCenter(Center); Point Extents; GetExtents(Extents); SetCenterExtents(Center, Extents * s); return *this; } //! Operator for AABB /= float. Scales the extents, keeps same center. inline_ AABB& operator/=(float s) { Point Center; GetCenter(Center); Point Extents; GetExtents(Extents); SetCenterExtents(Center, Extents / s); return *this; } //! Operator for AABB += Point. Translates the box. inline_ AABB& operator+=(const Point& trans) { mMin+=trans; mMax+=trans; return *this; } private: Point mMin; //!< Min point Point mMax; //!< Max point }; #else class ICEMATHS_API AABB { public: //! Constructor inline_ AABB() {} //! Destructor inline_ ~AABB() {} //! Type-independent methods AABB_COMMON_METHODS; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Setups an AABB from min & max vectors. * \param min [in] the min point * \param max [in] the max point */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void SetMinMax(const Point& min, const Point& max) { mCenter = (max + min)*0.5f; mExtents = (max - min)*0.5f; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Setups an AABB from center & extents vectors. * \param c [in] the center point * \param e [in] the extents vector */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void SetCenterExtents(const Point& c, const Point& e) { mCenter = c; mExtents = e; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Setups an empty AABB. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void SetEmpty() { mCenter.Zero(); mExtents.Set(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT);} /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Setups a point AABB. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void SetPoint(const Point& pt) { mCenter = pt; mExtents.Zero(); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the size of the AABB. The size is defined as the longest extent. * \return the size of the AABB */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// float GetSize() const { return mExtents.Max(); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Extends the AABB. * \param p [in] the next point */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Extend(const Point& p) { Point Max = mCenter + mExtents; Point Min = mCenter - mExtents; if(p.x > Max.x) Max.x = p.x; if(p.x < Min.x) Min.x = p.x; if(p.y > Max.y) Max.y = p.y; if(p.y < Min.y) Min.y = p.y; if(p.z > Max.z) Max.z = p.z; if(p.z < Min.z) Min.z = p.z; SetMinMax(Min, Max); } // Data access //! Get min point of the box inline_ void GetMin(Point& min) const { min = mCenter - mExtents; } //! Get max point of the box inline_ void GetMax(Point& max) const { max = mCenter + mExtents; } //! Get component of the box's min point along a given axis inline_ float GetMin(udword axis) const { return mCenter[axis] - mExtents[axis]; } //! Get component of the box's max point along a given axis inline_ float GetMax(udword axis) const { return mCenter[axis] + mExtents[axis]; } //! Get box center inline_ void GetCenter(Point& center) const { center = mCenter; } //! Get box extents inline_ void GetExtents(Point& extents) const { extents = mExtents; } //! Get component of the box's center along a given axis inline_ float GetCenter(udword axis) const { return mCenter[axis]; } //! Get component of the box's extents along a given axis inline_ float GetExtents(udword axis) const { return mExtents[axis]; } //! Get box diagonal inline_ void GetDiagonal(Point& diagonal) const { diagonal = mExtents * 2.0f; } inline_ float GetWidth() const { return mExtents.x * 2.0f; } inline_ float GetHeight() const { return mExtents.y * 2.0f; } inline_ float GetDepth() const { return mExtents.z * 2.0f; } //! Volume inline_ float GetVolume() const { return mExtents.x * mExtents.y * mExtents.z * 8.0f; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the intersection between two AABBs. * \param a [in] the other AABB * \return true on intersection */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL Intersect(const AABB& a) const { float tx = mCenter.x - a.mCenter.x; float ex = a.mExtents.x + mExtents.x; if(AIR(tx) > IR(ex)) return FALSE; float ty = mCenter.y - a.mCenter.y; float ey = a.mExtents.y + mExtents.y; if(AIR(ty) > IR(ey)) return FALSE; float tz = mCenter.z - a.mCenter.z; float ez = a.mExtents.z + mExtents.z; if(AIR(tz) > IR(ez)) return FALSE; return TRUE; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * The standard intersection method from Gamasutra. Just here to check its speed against the one above. * \param a [in] the other AABB * \return true on intersection */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ bool GomezIntersect(const AABB& a) { Point T = mCenter - a.mCenter; // Vector from A to B return ((fabsf(T.x) <= (a.mExtents.x + mExtents.x)) && (fabsf(T.y) <= (a.mExtents.y + mExtents.y)) && (fabsf(T.z) <= (a.mExtents.z + mExtents.z))); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the 1D-intersection between two AABBs, on a given axis. * \param a [in] the other AABB * \param axis [in] the axis (0, 1, 2) * \return true on intersection */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL Intersect(const AABB& a, udword axis) const { float t = mCenter[axis] - a.mCenter[axis]; float e = a.mExtents[axis] + mExtents[axis]; if(AIR(t) > IR(e)) return FALSE; return TRUE; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recomputes the AABB after an arbitrary transform by a 4x4 matrix. * \param mtx [in] the transform matrix * \param aabb [out] the transformed AABB [can be *this] */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void Rotate(const Matrix4x4& mtx, AABB& aabb) const { // Compute new center aabb.mCenter = mCenter * mtx; // Compute new extents. FPU code & CPU code have been interleaved for improved performance. Point Ex(mtx.m[0][0] * mExtents.x, mtx.m[0][1] * mExtents.x, mtx.m[0][2] * mExtents.x); IR(Ex.x)&=0x7fffffff; IR(Ex.y)&=0x7fffffff; IR(Ex.z)&=0x7fffffff; Point Ey(mtx.m[1][0] * mExtents.y, mtx.m[1][1] * mExtents.y, mtx.m[1][2] * mExtents.y); IR(Ey.x)&=0x7fffffff; IR(Ey.y)&=0x7fffffff; IR(Ey.z)&=0x7fffffff; Point Ez(mtx.m[2][0] * mExtents.z, mtx.m[2][1] * mExtents.z, mtx.m[2][2] * mExtents.z); IR(Ez.x)&=0x7fffffff; IR(Ez.y)&=0x7fffffff; IR(Ez.z)&=0x7fffffff; aabb.mExtents.x = Ex.x + Ey.x + Ez.x; aabb.mExtents.y = Ex.y + Ey.y + Ez.y; aabb.mExtents.z = Ex.z + Ey.z + Ez.z; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks the AABB is valid. * \return true if the box is valid */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL IsValid() const { // Consistency condition for (Center, Extents) boxes: Extents >= 0 if(IS_NEGATIVE_FLOAT(mExtents.x)) return FALSE; if(IS_NEGATIVE_FLOAT(mExtents.y)) return FALSE; if(IS_NEGATIVE_FLOAT(mExtents.z)) return FALSE; return TRUE; } //! Operator for AABB *= float. Scales the extents, keeps same center. inline_ AABB& operator*=(float s) { mExtents*=s; return *this; } //! Operator for AABB /= float. Scales the extents, keeps same center. inline_ AABB& operator/=(float s) { mExtents/=s; return *this; } //! Operator for AABB += Point. Translates the box. inline_ AABB& operator+=(const Point& trans) { mCenter+=trans; return *this; } private: Point mCenter; //!< AABB Center Point mExtents; //!< x, y and z extents }; #endif inline_ void ComputeMinMax(const Point& p, Point& min, Point& max) { if(p.x > max.x) max.x = p.x; if(p.x < min.x) min.x = p.x; if(p.y > max.y) max.y = p.y; if(p.y < min.y) min.y = p.y; if(p.z > max.z) max.z = p.z; if(p.z < min.z) min.z = p.z; } inline_ void ComputeAABB(AABB& aabb, const Point* list, udword nb_pts) { if(list) { Point Maxi(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); Point Mini(MAX_FLOAT, MAX_FLOAT, MAX_FLOAT); while(nb_pts--) { // _prefetch(list+1); // off by one ? ComputeMinMax(*list++, Mini, Maxi); } aabb.SetMinMax(Mini, Maxi); } } #endif // __ICEAABB_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceIndexedTriangle.h0000600000175000017500000000666612161402010024673 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains a handy indexed triangle class. * \file IceIndexedTriangle.h * \author Pierre Terdiman * \date January, 17, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include "ode/common.h" /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __ICEINDEXEDTRIANGLE_H__ #define __ICEINDEXEDTRIANGLE_H__ // Forward declarations #ifdef _MSC_VER enum CubeIndex; #else typedef int CubeIndex; #endif // An indexed triangle class. class ICEMATHS_API IndexedTriangle { public: //! Constructor inline_ IndexedTriangle() {} //! Constructor inline_ IndexedTriangle(dTriIndex r0, dTriIndex r1, dTriIndex r2) { mVRef[0]=r0; mVRef[1]=r1; mVRef[2]=r2; } //! Copy constructor inline_ IndexedTriangle(const IndexedTriangle& triangle) { mVRef[0] = triangle.mVRef[0]; mVRef[1] = triangle.mVRef[1]; mVRef[2] = triangle.mVRef[2]; } //! Destructor inline_ ~IndexedTriangle() {} //! Vertex-references dTriIndex mVRef[3]; // Methods void Flip(); float Area(const Point* verts) const; float Perimeter(const Point* verts) const; float Compacity(const Point* verts) const; void Normal(const Point* verts, Point& normal) const; void DenormalizedNormal(const Point* verts, Point& normal) const; void Center(const Point* verts, Point& center) const; void CenteredNormal(const Point* verts, Point& normal) const; void RandomPoint(const Point* verts, Point& random) const; bool IsVisible(const Point* verts, const Point& source) const; bool BackfaceCulling(const Point* verts, const Point& source) const; float ComputeOcclusionPotential(const Point* verts, const Point& view) const; bool ReplaceVertex(dTriIndex oldref, dTriIndex newref); bool IsDegenerate() const; bool HasVertex(dTriIndex ref) const; bool HasVertex(dTriIndex ref, dTriIndex* index) const; ubyte FindEdge(dTriIndex vref0, dTriIndex vref1) const; dTriIndex OppositeVertex(dTriIndex vref0, dTriIndex vref1) const; inline_ dTriIndex OppositeVertex(ubyte edgenb) const { return mVRef[2-edgenb]; } void GetVRefs(ubyte edgenb, dTriIndex& vref0, dTriIndex& vref1, dTriIndex& vref2) const; float MinEdgeLength(const Point* verts) const; float MaxEdgeLength(const Point* verts) const; void ComputePoint(const Point* verts, float u, float v, Point& pt, dTriIndex* nearvtx=null) const; float Angle(const IndexedTriangle& tri, const Point* verts) const; inline_ Plane PlaneEquation(const Point* verts) const { return Plane(verts[mVRef[0]], verts[mVRef[1]], verts[mVRef[2]]); } bool Equal(const IndexedTriangle& tri) const; CubeIndex ComputeCubeIndex(const Point* verts) const; }; #endif // __ICEINDEXEDTRIANGLE_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceTriangle.cpp0000600000175000017500000003015212161402010023710 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains a handy triangle class. * \file IceTriangle.cpp * \author Pierre Terdiman * \date January, 17, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace IceMaths; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains a triangle class. * * \class Tri * \author Pierre Terdiman * \version 1.0 * \date 08.15.98 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static sdword VPlaneSideEps(const Point& v, const Plane& plane, float epsilon) { // Compute distance from current vertex to the plane float Dist = plane.Distance(v); // Compute side: // 1 = the vertex is on the positive side of the plane // -1 = the vertex is on the negative side of the plane // 0 = the vertex is on the plane (within epsilon) return Dist > epsilon ? 1 : Dist < -epsilon ? -1 : 0; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Flips the winding order. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Triangle::Flip() { Point Tmp = mVerts[1]; mVerts[1] = mVerts[2]; mVerts[2] = Tmp; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the triangle area. * \return the area */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// float Triangle::Area() const { const Point& p0 = mVerts[0]; const Point& p1 = mVerts[1]; const Point& p2 = mVerts[2]; return ((p0 - p1)^(p0 - p2)).Magnitude() * 0.5f; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the triangle perimeter. * \return the perimeter */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// float Triangle::Perimeter() const { const Point& p0 = mVerts[0]; const Point& p1 = mVerts[1]; const Point& p2 = mVerts[2]; return p0.Distance(p1) + p0.Distance(p2) + p1.Distance(p2); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the triangle compacity. * \return the compacity */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// float Triangle::Compacity() const { float P = Perimeter(); if(P==0.0f) return 0.0f; return (4.0f*PI*Area()/(P*P)); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the triangle normal. * \param normal [out] the computed normal */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Triangle::Normal(Point& normal) const { const Point& p0 = mVerts[0]; const Point& p1 = mVerts[1]; const Point& p2 = mVerts[2]; normal = ((p0 - p1)^(p0 - p2)).Normalize(); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the triangle denormalized normal. * \param normal [out] the computed normal */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Triangle::DenormalizedNormal(Point& normal) const { const Point& p0 = mVerts[0]; const Point& p1 = mVerts[1]; const Point& p2 = mVerts[2]; normal = ((p0 - p1)^(p0 - p2)); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the triangle center. * \param center [out] the computed center */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Triangle::Center(Point& center) const { const Point& p0 = mVerts[0]; const Point& p1 = mVerts[1]; const Point& p2 = mVerts[2]; center = (p0 + p1 + p2)*INV3; } PartVal Triangle::TestAgainstPlane(const Plane& plane, float epsilon) const { bool Pos = false, Neg = false; // Loop through all vertices for(udword i=0;i<3;i++) { // Compute side: sdword Side = VPlaneSideEps(mVerts[i], plane, epsilon); if (Side < 0) Neg = true; else if (Side > 0) Pos = true; } if (!Pos && !Neg) return TRI_ON_PLANE; else if (Pos && Neg) return TRI_INTERSECT; else if (Pos && !Neg) return TRI_PLUS_SPACE; else if (!Pos && Neg) return TRI_MINUS_SPACE; // What?! return TRI_FORCEDWORD; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the triangle moment. * \param m [out] the moment */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* void Triangle::ComputeMoment(Moment& m) { // Compute the area of the triangle m.mArea = Area(); // Compute the centroid Center(m.mCentroid); // Second-order components. Handle zero-area faces. Point& p = mVerts[0]; Point& q = mVerts[1]; Point& r = mVerts[2]; if(m.mArea==0.0f) { // This triangle has zero area. The second order components would be eliminated with the usual formula, so, for the // sake of robustness we use an alternative form. These are the centroid and second-order components of the triangle's vertices. m.mCovariance.m[0][0] = (p.x*p.x + q.x*q.x + r.x*r.x); m.mCovariance.m[0][1] = (p.x*p.y + q.x*q.y + r.x*r.y); m.mCovariance.m[0][2] = (p.x*p.z + q.x*q.z + r.x*r.z); m.mCovariance.m[1][1] = (p.y*p.y + q.y*q.y + r.y*r.y); m.mCovariance.m[1][2] = (p.y*p.z + q.y*q.z + r.y*r.z); m.mCovariance.m[2][2] = (p.z*p.z + q.z*q.z + r.z*r.z); m.mCovariance.m[2][1] = m.mCovariance.m[1][2]; m.mCovariance.m[1][0] = m.mCovariance.m[0][1]; m.mCovariance.m[2][0] = m.mCovariance.m[0][2]; } else { const float OneOverTwelve = 1.0f / 12.0f; m.mCovariance.m[0][0] = m.mArea * (9.0f * m.mCentroid.x*m.mCentroid.x + p.x*p.x + q.x*q.x + r.x*r.x) * OneOverTwelve; m.mCovariance.m[0][1] = m.mArea * (9.0f * m.mCentroid.x*m.mCentroid.y + p.x*p.y + q.x*q.y + r.x*r.y) * OneOverTwelve; m.mCovariance.m[1][1] = m.mArea * (9.0f * m.mCentroid.y*m.mCentroid.y + p.y*p.y + q.y*q.y + r.y*r.y) * OneOverTwelve; m.mCovariance.m[0][2] = m.mArea * (9.0f * m.mCentroid.x*m.mCentroid.z + p.x*p.z + q.x*q.z + r.x*r.z) * OneOverTwelve; m.mCovariance.m[1][2] = m.mArea * (9.0f * m.mCentroid.y*m.mCentroid.z + p.y*p.z + q.y*q.z + r.y*r.z) * OneOverTwelve; m.mCovariance.m[2][2] = m.mArea * (9.0f * m.mCentroid.z*m.mCentroid.z + p.z*p.z + q.z*q.z + r.z*r.z) * OneOverTwelve; m.mCovariance.m[2][1] = m.mCovariance.m[1][2]; m.mCovariance.m[1][0] = m.mCovariance.m[0][1]; m.mCovariance.m[2][0] = m.mCovariance.m[0][2]; } } */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the triangle's smallest edge length. * \return the smallest edge length */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// float Triangle::MinEdgeLength() const { float Min = MAX_FLOAT; float Length01 = mVerts[0].Distance(mVerts[1]); float Length02 = mVerts[0].Distance(mVerts[2]); float Length12 = mVerts[1].Distance(mVerts[2]); if(Length01 < Min) Min = Length01; if(Length02 < Min) Min = Length02; if(Length12 < Min) Min = Length12; return Min; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the triangle's largest edge length. * \return the largest edge length */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// float Triangle::MaxEdgeLength() const { float Max = MIN_FLOAT; float Length01 = mVerts[0].Distance(mVerts[1]); float Length02 = mVerts[0].Distance(mVerts[2]); float Length12 = mVerts[1].Distance(mVerts[2]); if(Length01 > Max) Max = Length01; if(Length02 > Max) Max = Length02; if(Length12 > Max) Max = Length12; return Max; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes a point on the triangle according to the stabbing information. * \param u,v [in] point's barycentric coordinates * \param pt [out] point on triangle * \param nearvtx [out] index of nearest vertex */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Triangle::ComputePoint(float u, float v, Point& pt, udword* nearvtx) const { // Compute point coordinates pt = (1.0f - u - v)*mVerts[0] + u*mVerts[1] + v*mVerts[2]; // Compute nearest vertex if needed if(nearvtx) { // Compute distance vector Point d(mVerts[0].SquareDistance(pt), // Distance^2 from vertex 0 to point on the face mVerts[1].SquareDistance(pt), // Distance^2 from vertex 1 to point on the face mVerts[2].SquareDistance(pt)); // Distance^2 from vertex 2 to point on the face // Get smallest distance *nearvtx = d.SmallestAxis(); } } void Triangle::Inflate(float fat_coeff, bool constant_border) { // Compute triangle center Point TriangleCenter; Center(TriangleCenter); // Don't normalize? // Normalize => add a constant border, regardless of triangle size // Don't => add more to big triangles for(udword i=0;i<3;i++) { Point v = mVerts[i] - TriangleCenter; if(constant_border) v.Normalize(); mVerts[i] += v * fat_coeff; } } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceContainer.h0000600000175000017500000002317612161402010023542 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains a simple container class. * \file IceContainer.h * \author Pierre Terdiman * \date February, 5, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __ICECONTAINER_H__ #define __ICECONTAINER_H__ #define CONTAINER_STATS enum FindMode { FIND_CLAMP, FIND_WRAP, FIND_FORCE_DWORD = 0x7fffffff }; class ICECORE_API Container { public: // Constructor / Destructor Container(); Container(const Container& object); Container(udword size, float growth_factor); ~Container(); // Management /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * A O(1) method to add a value in the container. The container is automatically resized if needed. * The method is inline, not the resize. The call overhead happens on resizes only, which is not a problem since the resizing operation * costs a lot more than the call overhead... * * \param entry [in] a udword to store in the container * \see Add(float entry) * \see Empty() * \see Contains(udword entry) * \return Self-Reference */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ Container& Add(udword entry) { // Resize if needed if(mCurNbEntries==mMaxNbEntries) Resize(); // Add new entry mEntries[mCurNbEntries++] = entry; return *this; } inline_ Container& Add(const uword* entries, udword nb) { // Resize if needed if(mCurNbEntries+nb>mMaxNbEntries) Resize(nb); // Add new entry CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(uword)); mCurNbEntries+=nb; return *this; } inline_ Container& Add(const udword* entries, udword nb) { // Resize if needed if(mCurNbEntries+nb>mMaxNbEntries) Resize(nb); // Add new entry CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(udword)); mCurNbEntries+=nb; return *this; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * A O(1) method to add a value in the container. The container is automatically resized if needed. * The method is inline, not the resize. The call overhead happens on resizes only, which is not a problem since the resizing operation * costs a lot more than the call overhead... * * \param entry [in] a float to store in the container * \see Add(udword entry) * \see Empty() * \see Contains(udword entry) * \return Self-Reference */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ Container& Add(float entry) { // Resize if needed if(mCurNbEntries==mMaxNbEntries) Resize(); // Add new entry mEntries[mCurNbEntries++] = IR(entry); return *this; } inline_ Container& Add(const float* entries, udword nb) { // Resize if needed if(mCurNbEntries+nb>mMaxNbEntries) Resize(nb); // Add new entry CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(float)); mCurNbEntries+=nb; return *this; } //! Add unique [slow] inline_ Container& AddUnique(udword entry) { if(!Contains(entry)) Add(entry); return *this; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Clears the container. All stored values are deleted, and it frees used ram. * \see Reset() * \return Self-Reference */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Container& Empty(); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Resets the container. Stored values are discarded but the buffer is kept so that further calls don't need resizing again. * That's a kind of temporal coherence. * \see Empty() */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void Reset() { // Avoid the write if possible // ### CMOV if(mCurNbEntries) mCurNbEntries = 0; } // HANDLE WITH CARE inline_ void ForceSize(udword size) { mCurNbEntries = size; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Sets the initial size of the container. If it already contains something, it's discarded. * \param nb [in] Number of entries * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool SetSize(udword nb); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Refits the container and get rid of unused bytes. * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool Refit(); // Checks whether the container already contains a given value. bool Contains(udword entry, udword* location=null) const; // Deletes an entry - doesn't preserve insertion order. bool Delete(udword entry); // Deletes an entry - does preserve insertion order. bool DeleteKeepingOrder(udword entry); //! Deletes the very last entry. inline_ void DeleteLastEntry() { if(mCurNbEntries) mCurNbEntries--; } //! Deletes the entry whose index is given inline_ void DeleteIndex(udword index) { mEntries[index] = mEntries[--mCurNbEntries]; } // Helpers Container& FindNext(udword& entry, FindMode find_mode=FIND_CLAMP); Container& FindPrev(udword& entry, FindMode find_mode=FIND_CLAMP); // Data access. inline_ udword GetNbEntries() const { return mCurNbEntries; } //!< Returns the current number of entries. inline_ udword GetEntry(udword i) const { return mEntries[i]; } //!< Returns ith entry inline_ udword* GetEntries() const { return mEntries; } //!< Returns the list of entries. inline_ udword GetFirst() const { return mEntries[0]; } inline_ udword GetLast() const { return mEntries[mCurNbEntries-1]; } // Growth control inline_ float GetGrowthFactor() const { return mGrowthFactor; } //!< Returns the growth factor inline_ void SetGrowthFactor(float growth) { mGrowthFactor = growth; } //!< Sets the growth factor inline_ bool IsFull() const { return mCurNbEntries==mMaxNbEntries; } //!< Checks the container is full inline_ BOOL IsNotEmpty() const { return mCurNbEntries; } //!< Checks the container is empty //! Read-access as an array inline_ udword operator[](udword i) const { ASSERT(i>=0 && i=0 && i (b) ? (a) : (b)) //!< Returns the max value between a and b #define MAXMAX(a,b,c) ((a) > (b) ? MAX (a,c) : MAX (b,c)) //!< Returns the max value between a, b and c template inline_ const T& TMin (const T& a, const T& b) { return b < a ? b : a; } template inline_ const T& TMax (const T& a, const T& b) { return a < b ? b : a; } template inline_ void TSetMin (T& a, const T& b) { if(a>b) a = b; } template inline_ void TSetMax (T& a, const T& b) { if(a>1; } inline_ const Pair* GetPairs() const { return (const Pair*)GetEntries(); } inline_ const Pair* GetPair(udword i) const { return (const Pair*)&GetEntries()[i+i]; } inline_ BOOL HasPairs() const { return IsNotEmpty(); } inline_ void ResetPairs() { Reset(); } inline_ void DeleteLastPair() { DeleteLastEntry(); DeleteLastEntry(); } inline_ void AddPair(const Pair& p) { Add(p.id0).Add(p.id1); } inline_ void AddPair(udword id0, udword id1) { Add(id0).Add(id1); } }; #endif // __ICEPAIRS_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceUtils.h0000600000175000017500000002542612161402010022720 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains misc. useful macros & defines. * \file IceUtils.h * \author Pierre Terdiman (collected from various sources) * \date April, 4, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __ICEUTILS_H__ #define __ICEUTILS_H__ // #define START_RUNONCE { static bool __RunOnce__ = false; if(!__RunOnce__){ -- not thread safe // #define END_RUNONCE __RunOnce__ = true;}} -- not thread safe //! Reverse all the bits in a 32 bit word (from Steve Baker's Cute Code Collection) //! (each line can be done in any order. inline_ void ReverseBits(udword& n) { n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xaaaaaaaa); n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xcccccccc); n = ((n >> 4) & 0x0f0f0f0f) | ((n << 4) & 0xf0f0f0f0); n = ((n >> 8) & 0x00ff00ff) | ((n << 8) & 0xff00ff00); n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000); // Etc for larger intergers (64 bits in Java) // NOTE: the >> operation must be unsigned! (>>> in java) } //! Count the number of '1' bits in a 32 bit word (from Steve Baker's Cute Code Collection) inline_ udword CountBits(udword n) { // This relies of the fact that the count of n bits can NOT overflow // an n bit interger. EG: 1 bit count takes a 1 bit interger, 2 bit counts // 2 bit interger, 3 bit count requires only a 2 bit interger. // So we add all bit pairs, then each nible, then each byte etc... n = (n & 0x55555555) + ((n & 0xaaaaaaaa) >> 1); n = (n & 0x33333333) + ((n & 0xcccccccc) >> 2); n = (n & 0x0f0f0f0f) + ((n & 0xf0f0f0f0) >> 4); n = (n & 0x00ff00ff) + ((n & 0xff00ff00) >> 8); n = (n & 0x0000ffff) + ((n & 0xffff0000) >> 16); // Etc for larger intergers (64 bits in Java) // NOTE: the >> operation must be unsigned! (>>> in java) return n; } //! Even faster? inline_ udword CountBits2(udword bits) { bits = bits - ((bits >> 1) & 0x55555555); bits = ((bits >> 2) & 0x33333333) + (bits & 0x33333333); bits = ((bits >> 4) + bits) & 0x0F0F0F0F; return (bits * 0x01010101) >> 24; } //! Spread out bits. EG 00001111 -> 0101010101 //! 00001010 -> 0100010000 //! This is used to interleve to intergers to produce a `Morten Key' //! used in Space Filling Curves (See DrDobbs Journal, July 1999) //! Order is important. inline_ void SpreadBits(udword& n) { n = ( n & 0x0000ffff) | (( n & 0xffff0000) << 16); n = ( n & 0x000000ff) | (( n & 0x0000ff00) << 8); n = ( n & 0x000f000f) | (( n & 0x00f000f0) << 4); n = ( n & 0x03030303) | (( n & 0x0c0c0c0c) << 2); n = ( n & 0x11111111) | (( n & 0x22222222) << 1); } // Next Largest Power of 2 // Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm // that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with // the same most significant 1 as x, but all 1's below it. Adding 1 to that value yields the next // largest power of 2. For a 32-bit value: inline_ udword nlpo2(udword x) { x |= (x >> 1); x |= (x >> 2); x |= (x >> 4); x |= (x >> 8); x |= (x >> 16); return x+1; } //! Test to see if a number is an exact power of two (from Steve Baker's Cute Code Collection) inline_ bool IsPowerOfTwo(udword n) { return ((n&(n-1))==0); } //! Zero the least significant '1' bit in a word. (from Steve Baker's Cute Code Collection) inline_ void ZeroLeastSetBit(udword& n) { n&=(n-1); } //! Set the least significant N bits in a word. (from Steve Baker's Cute Code Collection) inline_ void SetLeastNBits(udword& x, udword n) { x|=~(~0<> 31; return (x^y)-y; } //!< Alternative min function inline_ sdword min_(sdword a, sdword b) { sdword delta = b-a; return a + (delta&(delta>>31)); } // Determine if one of the bytes in a 4 byte word is zero inline_ BOOL HasNullByte(udword x) { return ((x + 0xfefefeff) & (~x) & 0x80808080); } // To find the smallest 1 bit in a word EG: ~~~~~~10---0 => 0----010---0 inline_ udword LowestOneBit(udword w) { return ((w) & (~(w)+1)); } // inline_ udword LowestOneBit_(udword w) { return ((w) & (-(w))); } // Most Significant 1 Bit // Given a binary integer value x, the most significant 1 bit (highest numbered element of a bit set) // can be computed using a SWAR algorithm that recursively "folds" the upper bits into the lower bits. // This process yields a bit vector with the same most significant 1 as x, but all 1's below it. // Bitwise AND of the original value with the complement of the "folded" value shifted down by one // yields the most significant bit. For a 32-bit value: inline_ udword msb32(udword x) { x |= (x >> 1); x |= (x >> 2); x |= (x >> 4); x |= (x >> 8); x |= (x >> 16); return (x & ~(x >> 1)); } /* "Just call it repeatedly with various input values and always with the same variable as "memory". The sharpness determines the degree of filtering, where 0 completely filters out the input, and 1 does no filtering at all. I seem to recall from college that this is called an IIR (Infinite Impulse Response) filter. As opposed to the more typical FIR (Finite Impulse Response). Also, I'd say that you can make more intelligent and interesting filters than this, for example filters that remove wrong responses from the mouse because it's being moved too fast. You'd want such a filter to be applied before this one, of course." (JCAB on Flipcode) */ inline_ float FeedbackFilter(float val, float& memory, float sharpness) { ASSERT(sharpness>=0.0f && sharpness<=1.0f && "Invalid sharpness value in feedback filter"); if(sharpness<0.0f) sharpness = 0.0f; else if(sharpness>1.0f) sharpness = 1.0f; return memory = val * sharpness + memory * (1.0f - sharpness); } //! If you can guarantee that your input domain (i.e. value of x) is slightly //! limited (abs(x) must be < ((1<<31u)-32767)), then you can use the //! following code to clamp the resulting value into [-32768,+32767] range: inline_ int ClampToInt16(int x) { // ASSERT(abs(x) < (int)((1<<31u)-32767)); int delta = 32767 - x; x += (delta>>31) & delta; delta = x + 32768; x -= (delta>>31) & delta; return x; } // Generic functions template inline_ void TSwap(Type& a, Type& b) { const Type c = a; a = b; b = c; } template inline_ Type TClamp(const Type& x, const Type& lo, const Type& hi) { return ((xhi) ? hi : x); } template inline_ void TSort(Type& a, Type& b) { if(a>b) TSwap(a, b); } template inline_ void TSort(Type& a, Type& b, Type& c) { if(a>b) TSwap(a, b); if(b>c) TSwap(b, c); if(a>b) TSwap(a, b); if(b>c) TSwap(b, c); } // Prevent nasty user-manipulations (strategy borrowed from Charles Bloom) // #define PREVENT_COPY(curclass) void operator = (const curclass& object) { ASSERT(!"Bad use of operator ="); } // ... actually this is better ! #define PREVENT_COPY(cur_class) private: cur_class(const cur_class& object); cur_class& operator=(const cur_class& object); //! TO BE DOCUMENTED #define OFFSET_OF(Class, Member) (size_t)&(((Class*)0)->Member) //! TO BE DOCUMENTED #define ARRAYSIZE(p) (sizeof(p)/sizeof((p)[0])) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Returns the alignment of the input address. * \fn Alignment() * \param address [in] address to check * \return the best alignment (e.g. 1 for odd addresses, etc) */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// FUNCTION ICECORE_API udword Alignment(udword address); #define IS_ALIGNED_2(x) ((x&1)==0) #define IS_ALIGNED_4(x) ((x&3)==0) #define IS_ALIGNED_8(x) ((x&7)==0) inline_ void _prefetch(void const* ptr) { (void)*(char const volatile *)ptr; } // Compute implicit coords from an index: // The idea is to get back 2D coords from a 1D index. // For example: // // 0 1 2 ... nbu-1 // nbu nbu+1 i ... // // We have i, we're looking for the equivalent (u=2, v=1) location. // i = u + v*nbu // <=> i/nbu = u/nbu + v // Since 0 <= u < nbu, u/nbu = 0 (integer) // Hence: v = i/nbu // Then we simply put it back in the original equation to compute u = i - v*nbu inline_ void Compute2DCoords(udword& u, udword& v, udword i, udword nbu) { v = i / nbu; u = i - (v * nbu); } // In 3D: i = u + v*nbu + w*nbu*nbv // <=> i/(nbu*nbv) = u/(nbu*nbv) + v/nbv + w // u/(nbu*nbv) is null since u/nbu was null already. // v/nbv is null as well for the same reason. // Hence w = i/(nbu*nbv) // Then we're left with a 2D problem: i' = i - w*nbu*nbv = u + v*nbu inline_ void Compute3DCoords(udword& u, udword& v, udword& w, udword i, udword nbu, udword nbu_nbv) { w = i / (nbu_nbv); Compute2DCoords(u, v, i - (w * nbu_nbv), nbu); } #endif // __ICEUTILS_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceAxes.h0000600000175000017500000000264312161402010022514 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains axes definition. * \file IceAxes.h * \author Pierre Terdiman * \date January, 29, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __ICEAXES_H__ #define __ICEAXES_H__ enum PointComponent { X = 0, Y = 1, Z = 2, W = 3, FORCE_DWORD = 0x7fffffff }; enum AxisOrder { AXES_XYZ = (X)|(Y<<2)|(Z<<4), AXES_XZY = (X)|(Z<<2)|(Y<<4), AXES_YXZ = (Y)|(X<<2)|(Z<<4), AXES_YZX = (Y)|(Z<<2)|(X<<4), AXES_ZXY = (Z)|(X<<2)|(Y<<4), AXES_ZYX = (Z)|(Y<<2)|(X<<4), AXES_FORCE_DWORD = 0x7fffffff }; class ICEMATHS_API Axes { public: inline_ Axes(AxisOrder order) { mAxis0 = (order ) & 3; mAxis1 = (order>>2) & 3; mAxis2 = (order>>4) & 3; } inline_ ~Axes() {} udword mAxis0; udword mAxis1; udword mAxis2; }; #endif // __ICEAXES_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IcePoint.h0000600000175000017500000004622612161402010022712 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for 3D vectors. * \file IcePoint.h * \author Pierre Terdiman * \date April, 4, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __ICEPOINT_H__ #define __ICEPOINT_H__ // Forward declarations class HPoint; class Plane; class Matrix3x3; class Matrix4x4; #define CROSS2D(a, b) (a.x*b.y - b.x*a.y) const float EPSILON2 = 1.0e-20f; class ICEMATHS_API Point { public: //! Empty constructor inline_ Point() {} //! Constructor from a single float // inline_ Point(float val) : x(val), y(val), z(val) {} // Removed since it introduced the nasty "Point T = *Matrix4x4.GetTrans();" bug....... //! Constructor from floats inline_ Point(float xx, float yy, float zz) : x(xx), y(yy), z(zz) {} //! Constructor from array inline_ Point(const float f[3]) : x(f[X]), y(f[Y]), z(f[Z]) {} //! Copy constructor inline_ Point(const Point& p) : x(p.x), y(p.y), z(p.z) {} //! Destructor inline_ ~Point() {} //! Clears the vector inline_ Point& Zero() { x = y = z = 0.0f; return *this; } //! + infinity inline_ Point& SetPlusInfinity() { x = y = z = MAX_FLOAT; return *this; } //! - infinity inline_ Point& SetMinusInfinity() { x = y = z = MIN_FLOAT; return *this; } //! Sets positive unit random vector Point& PositiveUnitRandomVector(); //! Sets unit random vector Point& UnitRandomVector(); //! Assignment from values inline_ Point& Set(float xx, float yy, float zz) { x = xx; y = yy; z = zz; return *this; } //! Assignment from array inline_ Point& Set(const float f[3]) { x = f[X]; y = f[Y]; z = f[Z]; return *this; } //! Assignment from another point inline_ Point& Set(const Point& src) { x = src.x; y = src.y; z = src.z; return *this; } //! Adds a vector inline_ Point& Add(const Point& p) { x += p.x; y += p.y; z += p.z; return *this; } //! Adds a vector inline_ Point& Add(float xx, float yy, float zz) { x += xx; y += yy; z += zz; return *this; } //! Adds a vector inline_ Point& Add(const float f[3]) { x += f[X]; y += f[Y]; z += f[Z]; return *this; } //! Adds vectors inline_ Point& Add(const Point& p, const Point& q) { x = p.x+q.x; y = p.y+q.y; z = p.z+q.z; return *this; } //! Subtracts a vector inline_ Point& Sub(const Point& p) { x -= p.x; y -= p.y; z -= p.z; return *this; } //! Subtracts a vector inline_ Point& Sub(float xx, float yy, float zz) { x -= xx; y -= yy; z -= zz; return *this; } //! Subtracts a vector inline_ Point& Sub(const float f[3]) { x -= f[X]; y -= f[Y]; z -= f[Z]; return *this; } //! Subtracts vectors inline_ Point& Sub(const Point& p, const Point& q) { x = p.x-q.x; y = p.y-q.y; z = p.z-q.z; return *this; } //! this = -this inline_ Point& Neg() { x = -x; y = -y; z = -z; return *this; } //! this = -a inline_ Point& Neg(const Point& a) { x = -a.x; y = -a.y; z = -a.z; return *this; } //! Multiplies by a scalar inline_ Point& Mult(float s) { x *= s; y *= s; z *= s; return *this; } //! this = a * scalar inline_ Point& Mult(const Point& a, float scalar) { x = a.x * scalar; y = a.y * scalar; z = a.z * scalar; return *this; } //! this = a + b * scalar inline_ Point& Mac(const Point& a, const Point& b, float scalar) { x = a.x + b.x * scalar; y = a.y + b.y * scalar; z = a.z + b.z * scalar; return *this; } //! this = this + a * scalar inline_ Point& Mac(const Point& a, float scalar) { x += a.x * scalar; y += a.y * scalar; z += a.z * scalar; return *this; } //! this = a - b * scalar inline_ Point& Msc(const Point& a, const Point& b, float scalar) { x = a.x - b.x * scalar; y = a.y - b.y * scalar; z = a.z - b.z * scalar; return *this; } //! this = this - a * scalar inline_ Point& Msc(const Point& a, float scalar) { x -= a.x * scalar; y -= a.y * scalar; z -= a.z * scalar; return *this; } //! this = a + b * scalarb + c * scalarc inline_ Point& Mac2(const Point& a, const Point& b, float scalarb, const Point& c, float scalarc) { x = a.x + b.x * scalarb + c.x * scalarc; y = a.y + b.y * scalarb + c.y * scalarc; z = a.z + b.z * scalarb + c.z * scalarc; return *this; } //! this = a - b * scalarb - c * scalarc inline_ Point& Msc2(const Point& a, const Point& b, float scalarb, const Point& c, float scalarc) { x = a.x - b.x * scalarb - c.x * scalarc; y = a.y - b.y * scalarb - c.y * scalarc; z = a.z - b.z * scalarb - c.z * scalarc; return *this; } //! this = mat * a inline_ Point& Mult(const Matrix3x3& mat, const Point& a); //! this = mat1 * a1 + mat2 * a2 inline_ Point& Mult2(const Matrix3x3& mat1, const Point& a1, const Matrix3x3& mat2, const Point& a2); //! this = this + mat * a inline_ Point& Mac(const Matrix3x3& mat, const Point& a); //! this = transpose(mat) * a inline_ Point& TransMult(const Matrix3x3& mat, const Point& a); //! Linear interpolate between two vectors: this = a + t * (b - a) inline_ Point& Lerp(const Point& a, const Point& b, float t) { x = a.x + t * (b.x - a.x); y = a.y + t * (b.y - a.y); z = a.z + t * (b.z - a.z); return *this; } //! Hermite interpolate between p1 and p2. p0 and p3 are used for finding gradient at p1 and p2. //! this = p0 * (2t^2 - t^3 - t)/2 //! + p1 * (3t^3 - 5t^2 + 2)/2 //! + p2 * (4t^2 - 3t^3 + t)/2 //! + p3 * (t^3 - t^2)/2 inline_ Point& Herp(const Point& p0, const Point& p1, const Point& p2, const Point& p3, float t) { float t2 = t * t; float t3 = t2 * t; float kp0 = (2.0f * t2 - t3 - t) * 0.5f; float kp1 = (3.0f * t3 - 5.0f * t2 + 2.0f) * 0.5f; float kp2 = (4.0f * t2 - 3.0f * t3 + t) * 0.5f; float kp3 = (t3 - t2) * 0.5f; x = p0.x * kp0 + p1.x * kp1 + p2.x * kp2 + p3.x * kp3; y = p0.y * kp0 + p1.y * kp1 + p2.y * kp2 + p3.y * kp3; z = p0.z * kp0 + p1.z * kp1 + p2.z * kp2 + p3.z * kp3; return *this; } //! this = rotpos * r + linpos inline_ Point& Transform(const Point& r, const Matrix3x3& rotpos, const Point& linpos); //! this = trans(rotpos) * (r - linpos) inline_ Point& InvTransform(const Point& r, const Matrix3x3& rotpos, const Point& linpos); //! Returns MIN(x, y, z); inline_ float Min() const { return MIN(x, MIN(y, z)); } //! Returns MAX(x, y, z); inline_ float Max() const { return MAX(x, MAX(y, z)); } //! Sets each element to be componentwise minimum inline_ Point& Min(const Point& p) { x = MIN(x, p.x); y = MIN(y, p.y); z = MIN(z, p.z); return *this; } //! Sets each element to be componentwise maximum inline_ Point& Max(const Point& p) { x = MAX(x, p.x); y = MAX(y, p.y); z = MAX(z, p.z); return *this; } //! Clamps each element inline_ Point& Clamp(float min, float max) { if(xmax) x=max; if(ymax) y=max; if(zmax) z=max; return *this; } //! Computes square magnitude inline_ float SquareMagnitude() const { return x*x + y*y + z*z; } //! Computes magnitude inline_ float Magnitude() const { return sqrtf(x*x + y*y + z*z); } //! Computes volume inline_ float Volume() const { return x * y * z; } //! Checks the point is near zero inline_ bool ApproxZero() const { return SquareMagnitude() < EPSILON2; } //! Tests for exact zero vector inline_ BOOL IsZero() const { if(IR(x) || IR(y) || IR(z)) return FALSE; return TRUE; } //! Checks point validity inline_ BOOL IsValid() const { if(!IsValidFloat(x)) return FALSE; if(!IsValidFloat(y)) return FALSE; if(!IsValidFloat(z)) return FALSE; return TRUE; } //! Slighty moves the point void Tweak(udword coord_mask, udword tweak_mask) { if(coord_mask&1) { udword Dummy = IR(x); Dummy^=tweak_mask; x = FR(Dummy); } if(coord_mask&2) { udword Dummy = IR(y); Dummy^=tweak_mask; y = FR(Dummy); } if(coord_mask&4) { udword Dummy = IR(z); Dummy^=tweak_mask; z = FR(Dummy); } } #define TWEAKMASK 0x3fffff #define TWEAKNOTMASK ~TWEAKMASK //! Slighty moves the point out inline_ void TweakBigger() { udword Dummy = (IR(x)&TWEAKNOTMASK); if(!IS_NEGATIVE_FLOAT(x)) Dummy+=TWEAKMASK+1; x = FR(Dummy); Dummy = (IR(y)&TWEAKNOTMASK); if(!IS_NEGATIVE_FLOAT(y)) Dummy+=TWEAKMASK+1; y = FR(Dummy); Dummy = (IR(z)&TWEAKNOTMASK); if(!IS_NEGATIVE_FLOAT(z)) Dummy+=TWEAKMASK+1; z = FR(Dummy); } //! Slighty moves the point in inline_ void TweakSmaller() { udword Dummy = (IR(x)&TWEAKNOTMASK); if(IS_NEGATIVE_FLOAT(x)) Dummy+=TWEAKMASK+1; x = FR(Dummy); Dummy = (IR(y)&TWEAKNOTMASK); if(IS_NEGATIVE_FLOAT(y)) Dummy+=TWEAKMASK+1; y = FR(Dummy); Dummy = (IR(z)&TWEAKNOTMASK); if(IS_NEGATIVE_FLOAT(z)) Dummy+=TWEAKMASK+1; z = FR(Dummy); } //! Normalizes the vector inline_ Point& Normalize() { float M = x*x + y*y + z*z; if(M) { M = 1.0f / sqrtf(M); x *= M; y *= M; z *= M; } return *this; } //! Sets vector length inline_ Point& SetLength(float length) { float NewLength = length / Magnitude(); x *= NewLength; y *= NewLength; z *= NewLength; return *this; } //! Clamps vector length inline_ Point& ClampLength(float limit_length) { if(limit_length>=0.0f) // Magnitude must be positive { float CurrentSquareLength = SquareMagnitude(); if(CurrentSquareLength > limit_length * limit_length) { float Coeff = limit_length / sqrtf(CurrentSquareLength); x *= Coeff; y *= Coeff; z *= Coeff; } } return *this; } //! Computes distance to another point inline_ float Distance(const Point& b) const { return sqrtf((x - b.x)*(x - b.x) + (y - b.y)*(y - b.y) + (z - b.z)*(z - b.z)); } //! Computes square distance to another point inline_ float SquareDistance(const Point& b) const { return ((x - b.x)*(x - b.x) + (y - b.y)*(y - b.y) + (z - b.z)*(z - b.z)); } //! Dot product dp = this|a inline_ float Dot(const Point& p) const { return p.x * x + p.y * y + p.z * z; } //! Cross product this = a x b inline_ Point& Cross(const Point& a, const Point& b) { x = a.y * b.z - a.z * b.y; y = a.z * b.x - a.x * b.z; z = a.x * b.y - a.y * b.x; return *this; } //! Vector code ( bitmask = sign(z) | sign(y) | sign(x) ) inline_ udword VectorCode() const { return (IR(x)>>31) | ((IR(y)&SIGN_BITMASK)>>30) | ((IR(z)&SIGN_BITMASK)>>29); } //! Returns largest axis inline_ PointComponent LargestAxis() const { const float* Vals = &x; PointComponent m = X; if(Vals[Y] > Vals[m]) m = Y; if(Vals[Z] > Vals[m]) m = Z; return m; } //! Returns closest axis inline_ PointComponent ClosestAxis() const { const float* Vals = &x; PointComponent m = X; if(AIR(Vals[Y]) > AIR(Vals[m])) m = Y; if(AIR(Vals[Z]) > AIR(Vals[m])) m = Z; return m; } //! Returns smallest axis inline_ PointComponent SmallestAxis() const { const float* Vals = &x; PointComponent m = X; if(Vals[Y] < Vals[m]) m = Y; if(Vals[Z] < Vals[m]) m = Z; return m; } //! Refracts the point Point& Refract(const Point& eye, const Point& n, float refractindex, Point& refracted); //! Projects the point onto a plane Point& ProjectToPlane(const Plane& p); //! Projects the point onto the screen void ProjectToScreen(float halfrenderwidth, float halfrenderheight, const Matrix4x4& mat, HPoint& projected) const; //! Unfolds the point onto a plane according to edge(a,b) Point& Unfold(Plane& p, Point& a, Point& b); //! Hash function from Ville Miettinen inline_ udword GetHashValue() const { const udword* h = (const udword*)(this); udword f = (h[0]+h[1]*11-(h[2]*17)) & 0x7fffffff; // avoid problems with +-0 return (f>>22)^(f>>12)^(f); } //! Stuff magic values in the point, marking it as explicitely not used. void SetNotUsed(); //! Checks the point is marked as not used BOOL IsNotUsed() const; // Arithmetic operators //! Unary operator for Point Negate = - Point inline_ Point operator-() const { return Point(-x, -y, -z); } //! Operator for Point Plus = Point + Point. inline_ Point operator+(const Point& p) const { return Point(x + p.x, y + p.y, z + p.z); } //! Operator for Point Minus = Point - Point. inline_ Point operator-(const Point& p) const { return Point(x - p.x, y - p.y, z - p.z); } //! Operator for Point Mul = Point * Point. inline_ Point operator*(const Point& p) const { return Point(x * p.x, y * p.y, z * p.z); } //! Operator for Point Scale = Point * float. inline_ Point operator*(float s) const { return Point(x * s, y * s, z * s ); } //! Operator for Point Scale = float * Point. inline_ friend Point operator*(float s, const Point& p) { return Point(s * p.x, s * p.y, s * p.z); } //! Operator for Point Div = Point / Point. inline_ Point operator/(const Point& p) const { return Point(x / p.x, y / p.y, z / p.z); } //! Operator for Point Scale = Point / float. inline_ Point operator/(float s) const { s = 1.0f / s; return Point(x * s, y * s, z * s); } //! Operator for Point Scale = float / Point. inline_ friend Point operator/(float s, const Point& p) { return Point(s / p.x, s / p.y, s / p.z); } //! Operator for float DotProd = Point | Point. inline_ float operator|(const Point& p) const { return x*p.x + y*p.y + z*p.z; } //! Operator for Point VecProd = Point ^ Point. inline_ Point operator^(const Point& p) const { return Point( y * p.z - z * p.y, z * p.x - x * p.z, x * p.y - y * p.x ); } //! Operator for Point += Point. inline_ Point& operator+=(const Point& p) { x += p.x; y += p.y; z += p.z; return *this; } //! Operator for Point += float. inline_ Point& operator+=(float s) { x += s; y += s; z += s; return *this; } //! Operator for Point -= Point. inline_ Point& operator-=(const Point& p) { x -= p.x; y -= p.y; z -= p.z; return *this; } //! Operator for Point -= float. inline_ Point& operator-=(float s) { x -= s; y -= s; z -= s; return *this; } //! Operator for Point *= Point. inline_ Point& operator*=(const Point& p) { x *= p.x; y *= p.y; z *= p.z; return *this; } //! Operator for Point *= float. inline_ Point& operator*=(float s) { x *= s; y *= s; z *= s; return *this; } //! Operator for Point /= Point. inline_ Point& operator/=(const Point& p) { x /= p.x; y /= p.y; z /= p.z; return *this; } //! Operator for Point /= float. inline_ Point& operator/=(float s) { s = 1.0f/s; x *= s; y *= s; z *= s; return *this; } // Logical operators //! Operator for "if(Point==Point)" inline_ bool operator==(const Point& p) const { return ( (IR(x)==IR(p.x))&&(IR(y)==IR(p.y))&&(IR(z)==IR(p.z))); } //! Operator for "if(Point!=Point)" inline_ bool operator!=(const Point& p) const { return ( (IR(x)!=IR(p.x))||(IR(y)!=IR(p.y))||(IR(z)!=IR(p.z))); } // Arithmetic operators //! Operator for Point Mul = Point * Matrix3x3. inline_ Point operator*(const Matrix3x3& mat) const { class ShadowMatrix3x3{ public: float m[3][3]; }; // To allow inlining const ShadowMatrix3x3* Mat = (const ShadowMatrix3x3*)&mat; return Point( x * Mat->m[0][0] + y * Mat->m[1][0] + z * Mat->m[2][0], x * Mat->m[0][1] + y * Mat->m[1][1] + z * Mat->m[2][1], x * Mat->m[0][2] + y * Mat->m[1][2] + z * Mat->m[2][2] ); } //! Operator for Point Mul = Point * Matrix4x4. inline_ Point operator*(const Matrix4x4& mat) const { class ShadowMatrix4x4{ public: float m[4][4]; }; // To allow inlining const ShadowMatrix4x4* Mat = (const ShadowMatrix4x4*)&mat; return Point( x * Mat->m[0][0] + y * Mat->m[1][0] + z * Mat->m[2][0] + Mat->m[3][0], x * Mat->m[0][1] + y * Mat->m[1][1] + z * Mat->m[2][1] + Mat->m[3][1], x * Mat->m[0][2] + y * Mat->m[1][2] + z * Mat->m[2][2] + Mat->m[3][2]); } //! Operator for Point *= Matrix3x3. inline_ Point& operator*=(const Matrix3x3& mat) { class ShadowMatrix3x3{ public: float m[3][3]; }; // To allow inlining const ShadowMatrix3x3* Mat = (const ShadowMatrix3x3*)&mat; float xp = x * Mat->m[0][0] + y * Mat->m[1][0] + z * Mat->m[2][0]; float yp = x * Mat->m[0][1] + y * Mat->m[1][1] + z * Mat->m[2][1]; float zp = x * Mat->m[0][2] + y * Mat->m[1][2] + z * Mat->m[2][2]; x = xp; y = yp; z = zp; return *this; } //! Operator for Point *= Matrix4x4. inline_ Point& operator*=(const Matrix4x4& mat) { class ShadowMatrix4x4{ public: float m[4][4]; }; // To allow inlining const ShadowMatrix4x4* Mat = (const ShadowMatrix4x4*)&mat; float xp = x * Mat->m[0][0] + y * Mat->m[1][0] + z * Mat->m[2][0] + Mat->m[3][0]; float yp = x * Mat->m[0][1] + y * Mat->m[1][1] + z * Mat->m[2][1] + Mat->m[3][1]; float zp = x * Mat->m[0][2] + y * Mat->m[1][2] + z * Mat->m[2][2] + Mat->m[3][2]; x = xp; y = yp; z = zp; return *this; } // Cast operators //! Cast a Point to a HPoint. w is set to zero. operator HPoint() const; inline_ operator const float*() const { return &x; } inline_ operator float*() { return &x; } public: float x, y, z; }; FUNCTION ICEMATHS_API void Normalize1(Point& a); FUNCTION ICEMATHS_API void Normalize2(Point& a); #endif //__ICEPOINT_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceAABB.cpp0000600000175000017500000003760412161402010022641 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains AABB-related code. * \file IceAABB.cpp * \author Pierre Terdiman * \date January, 29, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * AABB class. * \class AABB * \author Pierre Terdiman * \version 1.0 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace IceMaths; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the sum of two AABBs. * \param aabb [in] the other AABB * \return Self-Reference */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// AABB& AABB::Add(const AABB& aabb) { // Compute new min & max values Point Min; GetMin(Min); Point Tmp; aabb.GetMin(Tmp); Min.Min(Tmp); Point Max; GetMax(Max); aabb.GetMax(Tmp); Max.Max(Tmp); // Update this SetMinMax(Min, Max); return *this; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Makes a cube from the AABB. * \param cube [out] the cube AABB * \return cube edge length */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// float AABB::MakeCube(AABB& cube) const { Point Ext; GetExtents(Ext); float Max = Ext.Max(); Point Cnt; GetCenter(Cnt); cube.SetCenterExtents(Cnt, Point(Max, Max, Max)); return Max; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Makes a sphere from the AABB. * \param sphere [out] sphere containing the AABB */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void AABB::MakeSphere(Sphere& sphere) const { GetExtents(sphere.mCenter); sphere.mRadius = sphere.mCenter.Magnitude() * 1.00001f; // To make sure sphere::Contains(*this) succeeds GetCenter(sphere.mCenter); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks a box is inside another box. * \param box [in] the other AABB * \return true if current box is inside input box */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool AABB::IsInside(const AABB& box) const { if(box.GetMin(0)>GetMin(0)) return false; if(box.GetMin(1)>GetMin(1)) return false; if(box.GetMin(2)>GetMin(2)) return false; if(box.GetMax(0) max.x) ? 2 : 0) // 2 = right + ((local_eye.y < min.y) ? 4 : 0) // 4 = bottom + ((local_eye.y > max.y) ? 8 : 0) // 8 = top + ((local_eye.z < min.z) ? 16 : 0) // 16 = front + ((local_eye.z > max.z) ? 32 : 0); // 32 = back // Look up number of vertices in outline num = (sdword)gIndexList[pos][7]; // Zero indicates invalid case if(!num) return null; return &gIndexList[pos][0]; } // calculateBoxArea: computes the screen-projected 2D area of an oriented 3D bounding box //const Point& eye, //eye point (in bbox object coordinates) //const AABB& box, //3d bbox //const Matrix4x4& mat, //free transformation for bbox //float width, float height, int& num) float AABB::ComputeBoxArea(const Point& eye, const Matrix4x4& mat, float width, float height, sdword& num) const { const sbyte* Outline = ComputeOutline(eye, num); if(!Outline) return -1.0f; // Compute box vertices Point vertexBox[8], dst[8]; ComputePoints(vertexBox); // Transform all outline corners into 2D screen space for(sdword i=0;i pt = mP0, t=1 => pt = mP1] */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void ComputePoint(Point& pt, float t) const { pt = mP0 + t * (mP1 - mP0); } float SquareDistance(const Point& point, float* t=null) const; inline_ float Distance(const Point& point, float* t=null) const { return sqrtf(SquareDistance(point, t)); } Point mP0; //!< Start of segment Point mP1; //!< End of segment }; #endif // __ICESEGMENT_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IcePlane.cpp0000600000175000017500000000376412161402010023213 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for planes. * \file IcePlane.cpp * \author Pierre Terdiman * \date April, 4, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Plane class. * \class Plane * \author Pierre Terdiman * \version 1.0 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace IceMaths; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the plane equation from 3 points. * \param p0 [in] first point * \param p1 [in] second point * \param p2 [in] third point * \return Self-reference */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Plane& Plane::Set(const Point& p0, const Point& p1, const Point& p2) { Point Edge0 = p1 - p0; Point Edge1 = p2 - p0; n = Edge0 ^ Edge1; n.Normalize(); d = -(p0 | n); return *this; } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceOBB.cpp0000600000175000017500000003035712161402010022554 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains OBB-related code. * \file IceOBB.cpp * \author Pierre Terdiman * \date January, 29, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * An Oriented Bounding Box (OBB). * \class OBB * \author Pierre Terdiman * \version 1.0 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace IceMaths; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Tests if a point is contained within the OBB. * \param p [in] the world point to test * \return true if inside the OBB */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool OBB::ContainsPoint(const Point& p) const { // Point in OBB test using lazy evaluation and early exits // Translate to box space Point RelPoint = p - mCenter; // Point * mRot maps from box space to world space // mRot * Point maps from world space to box space (what we need here) float f = mRot.m[0][0] * RelPoint.x + mRot.m[0][1] * RelPoint.y + mRot.m[0][2] * RelPoint.z; if(f >= mExtents.x || f <= -mExtents.x) return false; f = mRot.m[1][0] * RelPoint.x + mRot.m[1][1] * RelPoint.y + mRot.m[1][2] * RelPoint.z; if(f >= mExtents.y || f <= -mExtents.y) return false; f = mRot.m[2][0] * RelPoint.x + mRot.m[2][1] * RelPoint.y + mRot.m[2][2] * RelPoint.z; if(f >= mExtents.z || f <= -mExtents.z) return false; return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Builds an OBB from an AABB and a world transform. * \param aabb [in] the aabb * \param mat [in] the world transform */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void OBB::Create(const AABB& aabb, const Matrix4x4& mat) { // Note: must be coherent with Rotate() aabb.GetCenter(mCenter); aabb.GetExtents(mExtents); // Here we have the same as OBB::Rotate(mat) where the obb is (mCenter, mExtents, Identity). // So following what's done in Rotate: // - x-form the center mCenter *= mat; // - combine rotation with identity, i.e. just use given matrix mRot = mat; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the obb planes. * \param planes [out] 6 box planes * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool OBB::ComputePlanes(Plane* planes) const { // Checkings if(!planes) return false; Point Axis0 = mRot[0]; Point Axis1 = mRot[1]; Point Axis2 = mRot[2]; // Writes normals planes[0].n = Axis0; planes[1].n = -Axis0; planes[2].n = Axis1; planes[3].n = -Axis1; planes[4].n = Axis2; planes[5].n = -Axis2; // Compute a point on each plane Point p0 = mCenter + Axis0 * mExtents.x; Point p1 = mCenter - Axis0 * mExtents.x; Point p2 = mCenter + Axis1 * mExtents.y; Point p3 = mCenter - Axis1 * mExtents.y; Point p4 = mCenter + Axis2 * mExtents.z; Point p5 = mCenter - Axis2 * mExtents.z; // Compute d planes[0].d = -(planes[0].n|p0); planes[1].d = -(planes[1].n|p1); planes[2].d = -(planes[2].n|p2); planes[3].d = -(planes[3].n|p3); planes[4].d = -(planes[4].n|p4); planes[5].d = -(planes[5].n|p5); return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the obb points. * \param pts [out] 8 box points * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool OBB::ComputePoints(Point* pts) const { // Checkings if(!pts) return false; Point Axis0 = mRot[0]; Point Axis1 = mRot[1]; Point Axis2 = mRot[2]; Axis0 *= mExtents.x; Axis1 *= mExtents.y; Axis2 *= mExtents.z; // 7+------+6 0 = --- // /| /| 1 = +-- // / | / | 2 = ++- // / 4+---/--+5 3 = -+- // 3+------+2 / y z 4 = --+ // | / | / | / 5 = +-+ // |/ |/ |/ 6 = +++ // 0+------+1 *---x 7 = -++ pts[0] = mCenter - Axis0 - Axis1 - Axis2; pts[1] = mCenter + Axis0 - Axis1 - Axis2; pts[2] = mCenter + Axis0 + Axis1 - Axis2; pts[3] = mCenter - Axis0 + Axis1 - Axis2; pts[4] = mCenter - Axis0 - Axis1 + Axis2; pts[5] = mCenter + Axis0 - Axis1 + Axis2; pts[6] = mCenter + Axis0 + Axis1 + Axis2; pts[7] = mCenter - Axis0 + Axis1 + Axis2; return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes vertex normals. * \param pts [out] 8 box points * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool OBB::ComputeVertexNormals(Point* pts) const { static const float VertexNormals[] = { -INVSQRT3, -INVSQRT3, -INVSQRT3, INVSQRT3, -INVSQRT3, -INVSQRT3, INVSQRT3, INVSQRT3, -INVSQRT3, -INVSQRT3, INVSQRT3, -INVSQRT3, -INVSQRT3, -INVSQRT3, INVSQRT3, INVSQRT3, -INVSQRT3, INVSQRT3, INVSQRT3, INVSQRT3, INVSQRT3, -INVSQRT3, INVSQRT3, INVSQRT3 }; if(!pts) return false; const Point* VN = (const Point*)VertexNormals; for(udword i=0;i<8;i++) { pts[i] = VN[i] * mRot; } return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Returns edges. * \return 24 indices (12 edges) indexing the list returned by ComputePoints() */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const udword* OBB::GetEdges() const { static const udword Indices[] = { 0, 1, 1, 2, 2, 3, 3, 0, 7, 6, 6, 5, 5, 4, 4, 7, 1, 5, 6, 2, 3, 7, 4, 0 }; return Indices; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Returns local edge normals. * \return edge normals in local space */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const Point* OBB::GetLocalEdgeNormals() const { static const float EdgeNormals[] = { 0, -INVSQRT2, -INVSQRT2, // 0-1 INVSQRT2, 0, -INVSQRT2, // 1-2 0, INVSQRT2, -INVSQRT2, // 2-3 -INVSQRT2, 0, -INVSQRT2, // 3-0 0, INVSQRT2, INVSQRT2, // 7-6 INVSQRT2, 0, INVSQRT2, // 6-5 0, -INVSQRT2, INVSQRT2, // 5-4 -INVSQRT2, 0, INVSQRT2, // 4-7 INVSQRT2, -INVSQRT2, 0, // 1-5 INVSQRT2, INVSQRT2, 0, // 6-2 -INVSQRT2, INVSQRT2, 0, // 3-7 -INVSQRT2, -INVSQRT2, 0 // 4-0 }; return (const Point*)EdgeNormals; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Returns world edge normal * \param edge_index [in] 0 <= edge index < 12 * \param world_normal [out] edge normal in world space */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void OBB::ComputeWorldEdgeNormal(udword edge_index, Point& world_normal) const { ASSERT(edge_index<12); world_normal = GetLocalEdgeNormals()[edge_index] * mRot; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes an LSS surrounding the OBB. * \param lss [out] the LSS */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void OBB::ComputeLSS(LSS& lss) const { Point Axis0 = mRot[0]; Point Axis1 = mRot[1]; Point Axis2 = mRot[2]; switch(mExtents.LargestAxis()) { case 0: lss.mRadius = (mExtents.y + mExtents.z)*0.5f; lss.mP0 = mCenter + Axis0 * (mExtents.x - lss.mRadius); lss.mP1 = mCenter - Axis0 * (mExtents.x - lss.mRadius); break; case 1: lss.mRadius = (mExtents.x + mExtents.z)*0.5f; lss.mP0 = mCenter + Axis1 * (mExtents.y - lss.mRadius); lss.mP1 = mCenter - Axis1 * (mExtents.y - lss.mRadius); break; case 2: lss.mRadius = (mExtents.x + mExtents.y)*0.5f; lss.mP0 = mCenter + Axis2 * (mExtents.z - lss.mRadius); lss.mP1 = mCenter - Axis2 * (mExtents.z - lss.mRadius); break; default: {} } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks the OBB is inside another OBB. * \param box [in] the other OBB * \return TRUE if we're inside the other box */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// BOOL OBB::IsInside(const OBB& box) const { // Make a 4x4 from the box & inverse it Matrix4x4 M0Inv; { Matrix4x4 M0 = box.mRot; M0.SetTrans(box.mCenter); InvertPRMatrix(M0Inv, M0); } // With our inversed 4x4, create box1 in space of box0 OBB _1in0; Rotate(M0Inv, _1in0); // This should cancel out box0's rotation, i.e. it's now an AABB. // => Center(0,0,0), Rot(identity) // The two boxes are in the same space so now we can compare them. // Create the AABB of (box1 in space of box0) const Matrix3x3& mtx = _1in0.mRot; float f = fabsf(mtx.m[0][0] * mExtents.x) + fabsf(mtx.m[1][0] * mExtents.y) + fabsf(mtx.m[2][0] * mExtents.z) - box.mExtents.x; if(f > _1in0.mCenter.x) return FALSE; if(-f < _1in0.mCenter.x) return FALSE; f = fabsf(mtx.m[0][1] * mExtents.x) + fabsf(mtx.m[1][1] * mExtents.y) + fabsf(mtx.m[2][1] * mExtents.z) - box.mExtents.y; if(f > _1in0.mCenter.y) return FALSE; if(-f < _1in0.mCenter.y) return FALSE; f = fabsf(mtx.m[0][2] * mExtents.x) + fabsf(mtx.m[1][2] * mExtents.y) + fabsf(mtx.m[2][2] * mExtents.z) - box.mExtents.z; if(f > _1in0.mCenter.z) return FALSE; if(-f < _1in0.mCenter.z) return FALSE; return TRUE; } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceUtils.cpp0000600000175000017500000000336112161402010023245 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains misc. useful macros & defines. * \file IceUtils.cpp * \author Pierre Terdiman (collected from various sources) * \date April, 4, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace IceCore; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Returns the alignment of the input address. * \fn Alignment() * \param address [in] address to check * \return the best alignment (e.g. 1 for odd addresses, etc) */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// udword IceCore::Alignment(udword address) { // Returns 0 for null addresses if(!address) return 0; // Test all bits udword Align = 1; for(udword i=1;i<32;i++) { // Returns as soon as the alignment is broken if(address&Align) return Align; Align<<=1; } // Here all bits are null, except the highest one (else the address would be null) return Align; } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceMatrix3x3.cpp0000600000175000017500000000346312161402010023752 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for 3x3 matrices. * \file IceMatrix3x3.cpp * \author Pierre Terdiman * \date April, 4, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 3x3 matrix. * DirectX-compliant, ie row-column order, ie m[Row][Col]. * Same as: * m11 m12 m13 first row. * m21 m22 m23 second row. * m31 m32 m33 third row. * Stored in memory as m11 m12 m13 m21... * * Multiplication rules: * * [x'y'z'] = [xyz][M] * * x' = x*m11 + y*m21 + z*m31 * y' = x*m12 + y*m22 + z*m32 * z' = x*m13 + y*m23 + z*m33 * * \class Matrix3x3 * \author Pierre Terdiman * \version 1.0 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace IceMaths; // Cast operator Matrix3x3::operator Matrix4x4() const { return Matrix4x4( m[0][0], m[0][1], m[0][2], 0.0f, m[1][0], m[1][1], m[1][2], 0.0f, m[2][0], m[2][1], m[2][2], 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceMatrix4x4.cpp0000600000175000017500000001407112161402010023751 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for 4x4 matrices. * \file IceMatrix4x4.cpp * \author Pierre Terdiman * \date April, 4, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 4x4 matrix. * DirectX-compliant, ie row-column order, ie m[Row][Col]. * Same as: * m11 m12 m13 m14 first row. * m21 m22 m23 m24 second row. * m31 m32 m33 m34 third row. * m41 m42 m43 m44 fourth row. * Translation is (m41, m42, m43), (m14, m24, m34, m44) = (0, 0, 0, 1). * Stored in memory as m11 m12 m13 m14 m21... * * Multiplication rules: * * [x'y'z'1] = [xyz1][M] * * x' = x*m11 + y*m21 + z*m31 + m41 * y' = x*m12 + y*m22 + z*m32 + m42 * z' = x*m13 + y*m23 + z*m33 + m43 * 1' = 0 + 0 + 0 + m44 * * \class Matrix4x4 * \author Pierre Terdiman * \version 1.0 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace IceMaths; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Inverts a PR matrix. (which only contains a rotation and a translation) * This is faster and less subject to FPU errors than the generic inversion code. * * \relates Matrix4x4 * \fn InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src) * \param dest [out] destination matrix * \param src [in] source matrix */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ICEMATHS_API void IceMaths::InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src) { dest.m[0][0] = src.m[0][0]; dest.m[1][0] = src.m[0][1]; dest.m[2][0] = src.m[0][2]; dest.m[3][0] = -(src.m[3][0]*src.m[0][0] + src.m[3][1]*src.m[0][1] + src.m[3][2]*src.m[0][2]); dest.m[0][1] = src.m[1][0]; dest.m[1][1] = src.m[1][1]; dest.m[2][1] = src.m[1][2]; dest.m[3][1] = -(src.m[3][0]*src.m[1][0] + src.m[3][1]*src.m[1][1] + src.m[3][2]*src.m[1][2]); dest.m[0][2] = src.m[2][0]; dest.m[1][2] = src.m[2][1]; dest.m[2][2] = src.m[2][2]; dest.m[3][2] = -(src.m[3][0]*src.m[2][0] + src.m[3][1]*src.m[2][1] + src.m[3][2]*src.m[2][2]); dest.m[0][3] = 0.0f; dest.m[1][3] = 0.0f; dest.m[2][3] = 0.0f; dest.m[3][3] = 1.0f; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Compute the cofactor of the Matrix at a specified location /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// float Matrix4x4::CoFactor(udword row, udword col) const { return (( m[(row+1)&3][(col+1)&3]*m[(row+2)&3][(col+2)&3]*m[(row+3)&3][(col+3)&3] + m[(row+1)&3][(col+2)&3]*m[(row+2)&3][(col+3)&3]*m[(row+3)&3][(col+1)&3] + m[(row+1)&3][(col+3)&3]*m[(row+2)&3][(col+1)&3]*m[(row+3)&3][(col+2)&3]) - (m[(row+3)&3][(col+1)&3]*m[(row+2)&3][(col+2)&3]*m[(row+1)&3][(col+3)&3] + m[(row+3)&3][(col+2)&3]*m[(row+2)&3][(col+3)&3]*m[(row+1)&3][(col+1)&3] + m[(row+3)&3][(col+3)&3]*m[(row+2)&3][(col+1)&3]*m[(row+1)&3][(col+2)&3])) * ((row + col) & 1 ? -1.0f : +1.0f); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Compute the determinant of the Matrix /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// float Matrix4x4::Determinant() const { return m[0][0] * CoFactor(0, 0) + m[0][1] * CoFactor(0, 1) + m[0][2] * CoFactor(0, 2) + m[0][3] * CoFactor(0, 3); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Compute the inverse of the matrix /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Matrix4x4& Matrix4x4::Invert() { float Det = Determinant(); Matrix4x4 Temp; if(fabsf(Det) < MATRIX4X4_EPSILON) return *this; // The matrix is not invertible! Singular case! float IDet = 1.0f / Det; Temp.m[0][0] = CoFactor(0,0) * IDet; Temp.m[1][0] = CoFactor(0,1) * IDet; Temp.m[2][0] = CoFactor(0,2) * IDet; Temp.m[3][0] = CoFactor(0,3) * IDet; Temp.m[0][1] = CoFactor(1,0) * IDet; Temp.m[1][1] = CoFactor(1,1) * IDet; Temp.m[2][1] = CoFactor(1,2) * IDet; Temp.m[3][1] = CoFactor(1,3) * IDet; Temp.m[0][2] = CoFactor(2,0) * IDet; Temp.m[1][2] = CoFactor(2,1) * IDet; Temp.m[2][2] = CoFactor(2,2) * IDet; Temp.m[3][2] = CoFactor(2,3) * IDet; Temp.m[0][3] = CoFactor(3,0) * IDet; Temp.m[1][3] = CoFactor(3,1) * IDet; Temp.m[2][3] = CoFactor(3,2) * IDet; Temp.m[3][3] = CoFactor(3,3) * IDet; *this = Temp; return *this; } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceHPoint.h0000600000175000017500000001634612161402010023022 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for homogeneous points. * \file IceHPoint.h * \author Pierre Terdiman * \date April, 4, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __ICEHPOINT_H__ #define __ICEHPOINT_H__ class ICEMATHS_API HPoint : public Point { public: //! Empty constructor inline_ HPoint() {} //! Constructor from floats inline_ HPoint(float xx, float yy, float zz, float ww=0.0f) : Point(xx, yy, zz), w(ww) {} //! Constructor from array inline_ HPoint(const float f[4]) : Point(f), w(f[3]) {} //! Constructor from a Point inline_ HPoint(const Point& p, float ww=0.0f) : Point(p), w(ww) {} //! Destructor inline_ ~HPoint() {} //! Clear the point inline_ HPoint& Zero() { x = y = z = w = 0.0f; return *this; } //! Assignment from values inline_ HPoint& Set(float xx, float yy, float zz, float ww ) { x = xx; y = yy; z = zz; w = ww; return *this; } //! Assignment from array inline_ HPoint& Set(const float f[4]) { x = f[X]; y = f[Y]; z = f[Z]; w = f[W]; return *this; } //! Assignment from another h-point inline_ HPoint& Set(const HPoint& src) { x = src.x; y = src.y; z = src.z; w = src.w; return *this; } //! Add a vector inline_ HPoint& Add(float xx, float yy, float zz, float ww ) { x += xx; y += yy; z += zz; w += ww; return *this; } //! Add a vector inline_ HPoint& Add(const float f[4]) { x += f[X]; y += f[Y]; z += f[Z]; w += f[W]; return *this; } //! Subtract a vector inline_ HPoint& Sub(float xx, float yy, float zz, float ww ) { x -= xx; y -= yy; z -= zz; w -= ww; return *this; } //! Subtract a vector inline_ HPoint& Sub(const float f[4]) { x -= f[X]; y -= f[Y]; z -= f[Z]; w -= f[W]; return *this; } //! Multiplies by a scalar inline_ HPoint& Mul(float s) { x *= s; y *= s; z *= s; w *= s; return *this; } //! Returns MIN(x, y, z, w); float Min() const { return MIN(x, MIN(y, MIN(z, w))); } //! Returns MAX(x, y, z, w); float Max() const { return MAX(x, MAX(y, MAX(z, w))); } //! Sets each element to be componentwise minimum HPoint& Min(const HPoint& p) { x = MIN(x, p.x); y = MIN(y, p.y); z = MIN(z, p.z); w = MIN(w, p.w); return *this; } //! Sets each element to be componentwise maximum HPoint& Max(const HPoint& p) { x = MAX(x, p.x); y = MAX(y, p.y); z = MAX(z, p.z); w = MAX(w, p.w); return *this; } //! Computes square magnitude inline_ float SquareMagnitude() const { return x*x + y*y + z*z + w*w; } //! Computes magnitude inline_ float Magnitude() const { return sqrtf(x*x + y*y + z*z + w*w); } //! Normalize the vector inline_ HPoint& Normalize() { float M = Magnitude(); if(M) { M = 1.0f / M; x *= M; y *= M; z *= M; w *= M; } return *this; } // Arithmetic operators //! Operator for HPoint Negate = - HPoint; inline_ HPoint operator-() const { return HPoint(-x, -y, -z, -w); } //! Operator for HPoint Plus = HPoint + HPoint; inline_ HPoint operator+(const HPoint& p) const { return HPoint(x + p.x, y + p.y, z + p.z, w + p.w); } //! Operator for HPoint Minus = HPoint - HPoint; inline_ HPoint operator-(const HPoint& p) const { return HPoint(x - p.x, y - p.y, z - p.z, w - p.w); } //! Operator for HPoint Mul = HPoint * HPoint; inline_ HPoint operator*(const HPoint& p) const { return HPoint(x * p.x, y * p.y, z * p.z, w * p.w); } //! Operator for HPoint Scale = HPoint * float; inline_ HPoint operator*(float s) const { return HPoint(x * s, y * s, z * s, w * s); } //! Operator for HPoint Scale = float * HPoint; inline_ friend HPoint operator*(float s, const HPoint& p) { return HPoint(s * p.x, s * p.y, s * p.z, s * p.w); } //! Operator for HPoint Div = HPoint / HPoint; inline_ HPoint operator/(const HPoint& p) const { return HPoint(x / p.x, y / p.y, z / p.z, w / p.w); } //! Operator for HPoint Scale = HPoint / float; inline_ HPoint operator/(float s) const { s = 1.0f / s; return HPoint(x * s, y * s, z * s, w * s); } //! Operator for HPoint Scale = float / HPoint; inline_ friend HPoint operator/(float s, const HPoint& p) { return HPoint(s / p.x, s / p.y, s / p.z, s / p.w); } //! Operator for float DotProd = HPoint | HPoint; inline_ float operator|(const HPoint& p) const { return x*p.x + y*p.y + z*p.z + w*p.w; } // No cross-product in 4D //! Operator for HPoint += HPoint; inline_ HPoint& operator+=(const HPoint& p) { x += p.x; y += p.y; z += p.z; w += p.w; return *this; } //! Operator for HPoint += float; inline_ HPoint& operator+=(float s) { x += s; y += s; z += s; w += s; return *this; } //! Operator for HPoint -= HPoint; inline_ HPoint& operator-=(const HPoint& p) { x -= p.x; y -= p.y; z -= p.z; w -= p.w; return *this; } //! Operator for HPoint -= float; inline_ HPoint& operator-=(float s) { x -= s; y -= s; z -= s; w -= s; return *this; } //! Operator for HPoint *= HPoint; inline_ HPoint& operator*=(const HPoint& p) { x *= p.x; y *= p.y; z *= p.z; w *= p.w; return *this; } //! Operator for HPoint *= float; inline_ HPoint& operator*=(float s) { x*=s; y*=s; z*=s; w*=s; return *this; } //! Operator for HPoint /= HPoint; inline_ HPoint& operator/=(const HPoint& p) { x /= p.x; y /= p.y; z /= p.z; w /= p.w; return *this; } //! Operator for HPoint /= float; inline_ HPoint& operator/=(float s) { s = 1.0f / s; x*=s; y*=s; z*=s; w*=s; return *this; } // Arithmetic operators //! Operator for Point Mul = HPoint * Matrix3x3; Point operator*(const Matrix3x3& mat) const; //! Operator for HPoint Mul = HPoint * Matrix4x4; HPoint operator*(const Matrix4x4& mat) const; // HPoint *= Matrix3x3 doesn't exist, the matrix is first casted to a 4x4 //! Operator for HPoint *= Matrix4x4 HPoint& operator*=(const Matrix4x4& mat); // Logical operators //! Operator for "if(HPoint==HPoint)" inline_ bool operator==(const HPoint& p) const { return ( (x==p.x)&&(y==p.y)&&(z==p.z)&&(w==p.w)); } //! Operator for "if(HPoint!=HPoint)" inline_ bool operator!=(const HPoint& p) const { return ( (x!=p.x)||(y!=p.y)||(z!=p.z)||(w!=p.w)); } // Cast operators //! Cast a HPoint to a Point. w is discarded. #ifdef _MSC_VER inline_ operator Point() const { return Point(x, y, z); } // gcc complains that conversion to a base class will never use a type conversion operator #endif public: float w; }; #endif // __ICEHPOINT_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/Ice/IceMatrix3x3.h0000600000175000017500000005003312161402010023412 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for 3x3 matrices. * \file IceMatrix3x3.h * \author Pierre Terdiman * \date April, 4, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __ICEMATRIX3X3_H__ #define __ICEMATRIX3X3_H__ // Forward declarations class Quat; #define MATRIX3X3_EPSILON (1.0e-7f) class ICEMATHS_API Matrix3x3 { public: //! Empty constructor inline_ Matrix3x3() {} //! Constructor from 9 values inline_ Matrix3x3(float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22) { m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; } //! Copy constructor inline_ Matrix3x3(const Matrix3x3& mat) { CopyMemory(m, &mat.m, 9*sizeof(float)); } //! Destructor inline_ ~Matrix3x3() {} //! Assign values inline_ void Set(float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22) { m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; } //! Sets the scale from a Point. The point is put on the diagonal. inline_ void SetScale(const Point& p) { m[0][0] = p.x; m[1][1] = p.y; m[2][2] = p.z; } //! Sets the scale from floats. Values are put on the diagonal. inline_ void SetScale(float sx, float sy, float sz) { m[0][0] = sx; m[1][1] = sy; m[2][2] = sz; } //! Scales from a Point. Each row is multiplied by a component. inline_ void Scale(const Point& p) { m[0][0] *= p.x; m[0][1] *= p.x; m[0][2] *= p.x; m[1][0] *= p.y; m[1][1] *= p.y; m[1][2] *= p.y; m[2][0] *= p.z; m[2][1] *= p.z; m[2][2] *= p.z; } //! Scales from floats. Each row is multiplied by a value. inline_ void Scale(float sx, float sy, float sz) { m[0][0] *= sx; m[0][1] *= sx; m[0][2] *= sx; m[1][0] *= sy; m[1][1] *= sy; m[1][2] *= sy; m[2][0] *= sz; m[2][1] *= sz; m[2][2] *= sz; } //! Copy from a Matrix3x3 inline_ void Copy(const Matrix3x3& source) { CopyMemory(m, source.m, 9*sizeof(float)); } // Row-column access //! Returns a row. inline_ void GetRow(const udword r, Point& p) const { p.x = m[r][0]; p.y = m[r][1]; p.z = m[r][2]; } //! Returns a row. inline_ const Point& GetRow(const udword r) const { return *(const Point*)&m[r][0]; } //! Returns a row. inline_ Point& GetRow(const udword r) { return *(Point*)&m[r][0]; } //! Sets a row. inline_ void SetRow(const udword r, const Point& p) { m[r][0] = p.x; m[r][1] = p.y; m[r][2] = p.z; } //! Returns a column. inline_ void GetCol(const udword c, Point& p) const { p.x = m[0][c]; p.y = m[1][c]; p.z = m[2][c]; } //! Sets a column. inline_ void SetCol(const udword c, const Point& p) { m[0][c] = p.x; m[1][c] = p.y; m[2][c] = p.z; } //! Computes the trace. The trace is the sum of the 3 diagonal components. inline_ float Trace() const { return m[0][0] + m[1][1] + m[2][2]; } //! Clears the matrix. inline_ void Zero() { ZeroMemory(&m, sizeof(m)); } //! Sets the identity matrix. inline_ void Identity() { Zero(); m[0][0] = m[1][1] = m[2][2] = 1.0f; } //! Checks for identity inline_ bool IsIdentity() const { if(IR(m[0][0])!=IEEE_1_0) return false; if(IR(m[0][1])!=0) return false; if(IR(m[0][2])!=0) return false; if(IR(m[1][0])!=0) return false; if(IR(m[1][1])!=IEEE_1_0) return false; if(IR(m[1][2])!=0) return false; if(IR(m[2][0])!=0) return false; if(IR(m[2][1])!=0) return false; if(IR(m[2][2])!=IEEE_1_0) return false; return true; } //! Checks matrix validity inline_ BOOL IsValid() const { for(udword j=0;j<3;j++) { for(udword i=0;i<3;i++) { if(!IsValidFloat(m[j][i])) return FALSE; } } return TRUE; } //! Makes a skew-symmetric matrix (a.k.a. Star(*) Matrix) //! [ 0.0 -a.z a.y ] //! [ a.z 0.0 -a.x ] //! [ -a.y a.x 0.0 ] //! This is also called a "cross matrix" since for any vectors A and B, //! A^B = Skew(A) * B = - B * Skew(A); inline_ void SkewSymmetric(const Point& a) { m[0][0] = 0.0f; m[0][1] = -a.z; m[0][2] = a.y; m[1][0] = a.z; m[1][1] = 0.0f; m[1][2] = -a.x; m[2][0] = -a.y; m[2][1] = a.x; m[2][2] = 0.0f; } //! Negates the matrix inline_ void Neg() { m[0][0] = -m[0][0]; m[0][1] = -m[0][1]; m[0][2] = -m[0][2]; m[1][0] = -m[1][0]; m[1][1] = -m[1][1]; m[1][2] = -m[1][2]; m[2][0] = -m[2][0]; m[2][1] = -m[2][1]; m[2][2] = -m[2][2]; } //! Neg from another matrix inline_ void Neg(const Matrix3x3& mat) { m[0][0] = -mat.m[0][0]; m[0][1] = -mat.m[0][1]; m[0][2] = -mat.m[0][2]; m[1][0] = -mat.m[1][0]; m[1][1] = -mat.m[1][1]; m[1][2] = -mat.m[1][2]; m[2][0] = -mat.m[2][0]; m[2][1] = -mat.m[2][1]; m[2][2] = -mat.m[2][2]; } //! Add another matrix inline_ void Add(const Matrix3x3& mat) { m[0][0] += mat.m[0][0]; m[0][1] += mat.m[0][1]; m[0][2] += mat.m[0][2]; m[1][0] += mat.m[1][0]; m[1][1] += mat.m[1][1]; m[1][2] += mat.m[1][2]; m[2][0] += mat.m[2][0]; m[2][1] += mat.m[2][1]; m[2][2] += mat.m[2][2]; } //! Sub another matrix inline_ void Sub(const Matrix3x3& mat) { m[0][0] -= mat.m[0][0]; m[0][1] -= mat.m[0][1]; m[0][2] -= mat.m[0][2]; m[1][0] -= mat.m[1][0]; m[1][1] -= mat.m[1][1]; m[1][2] -= mat.m[1][2]; m[2][0] -= mat.m[2][0]; m[2][1] -= mat.m[2][1]; m[2][2] -= mat.m[2][2]; } //! Mac inline_ void Mac(const Matrix3x3& a, const Matrix3x3& b, float s) { m[0][0] = a.m[0][0] + b.m[0][0] * s; m[0][1] = a.m[0][1] + b.m[0][1] * s; m[0][2] = a.m[0][2] + b.m[0][2] * s; m[1][0] = a.m[1][0] + b.m[1][0] * s; m[1][1] = a.m[1][1] + b.m[1][1] * s; m[1][2] = a.m[1][2] + b.m[1][2] * s; m[2][0] = a.m[2][0] + b.m[2][0] * s; m[2][1] = a.m[2][1] + b.m[2][1] * s; m[2][2] = a.m[2][2] + b.m[2][2] * s; } //! Mac inline_ void Mac(const Matrix3x3& a, float s) { m[0][0] += a.m[0][0] * s; m[0][1] += a.m[0][1] * s; m[0][2] += a.m[0][2] * s; m[1][0] += a.m[1][0] * s; m[1][1] += a.m[1][1] * s; m[1][2] += a.m[1][2] * s; m[2][0] += a.m[2][0] * s; m[2][1] += a.m[2][1] * s; m[2][2] += a.m[2][2] * s; } //! this = A * s inline_ void Mult(const Matrix3x3& a, float s) { m[0][0] = a.m[0][0] * s; m[0][1] = a.m[0][1] * s; m[0][2] = a.m[0][2] * s; m[1][0] = a.m[1][0] * s; m[1][1] = a.m[1][1] * s; m[1][2] = a.m[1][2] * s; m[2][0] = a.m[2][0] * s; m[2][1] = a.m[2][1] * s; m[2][2] = a.m[2][2] * s; } inline_ void Add(const Matrix3x3& a, const Matrix3x3& b) { m[0][0] = a.m[0][0] + b.m[0][0]; m[0][1] = a.m[0][1] + b.m[0][1]; m[0][2] = a.m[0][2] + b.m[0][2]; m[1][0] = a.m[1][0] + b.m[1][0]; m[1][1] = a.m[1][1] + b.m[1][1]; m[1][2] = a.m[1][2] + b.m[1][2]; m[2][0] = a.m[2][0] + b.m[2][0]; m[2][1] = a.m[2][1] + b.m[2][1]; m[2][2] = a.m[2][2] + b.m[2][2]; } inline_ void Sub(const Matrix3x3& a, const Matrix3x3& b) { m[0][0] = a.m[0][0] - b.m[0][0]; m[0][1] = a.m[0][1] - b.m[0][1]; m[0][2] = a.m[0][2] - b.m[0][2]; m[1][0] = a.m[1][0] - b.m[1][0]; m[1][1] = a.m[1][1] - b.m[1][1]; m[1][2] = a.m[1][2] - b.m[1][2]; m[2][0] = a.m[2][0] - b.m[2][0]; m[2][1] = a.m[2][1] - b.m[2][1]; m[2][2] = a.m[2][2] - b.m[2][2]; } //! this = a * b inline_ void Mult(const Matrix3x3& a, const Matrix3x3& b) { m[0][0] = a.m[0][0] * b.m[0][0] + a.m[0][1] * b.m[1][0] + a.m[0][2] * b.m[2][0]; m[0][1] = a.m[0][0] * b.m[0][1] + a.m[0][1] * b.m[1][1] + a.m[0][2] * b.m[2][1]; m[0][2] = a.m[0][0] * b.m[0][2] + a.m[0][1] * b.m[1][2] + a.m[0][2] * b.m[2][2]; m[1][0] = a.m[1][0] * b.m[0][0] + a.m[1][1] * b.m[1][0] + a.m[1][2] * b.m[2][0]; m[1][1] = a.m[1][0] * b.m[0][1] + a.m[1][1] * b.m[1][1] + a.m[1][2] * b.m[2][1]; m[1][2] = a.m[1][0] * b.m[0][2] + a.m[1][1] * b.m[1][2] + a.m[1][2] * b.m[2][2]; m[2][0] = a.m[2][0] * b.m[0][0] + a.m[2][1] * b.m[1][0] + a.m[2][2] * b.m[2][0]; m[2][1] = a.m[2][0] * b.m[0][1] + a.m[2][1] * b.m[1][1] + a.m[2][2] * b.m[2][1]; m[2][2] = a.m[2][0] * b.m[0][2] + a.m[2][1] * b.m[1][2] + a.m[2][2] * b.m[2][2]; } //! this = transpose(a) * b inline_ void MultAtB(const Matrix3x3& a, const Matrix3x3& b) { m[0][0] = a.m[0][0] * b.m[0][0] + a.m[1][0] * b.m[1][0] + a.m[2][0] * b.m[2][0]; m[0][1] = a.m[0][0] * b.m[0][1] + a.m[1][0] * b.m[1][1] + a.m[2][0] * b.m[2][1]; m[0][2] = a.m[0][0] * b.m[0][2] + a.m[1][0] * b.m[1][2] + a.m[2][0] * b.m[2][2]; m[1][0] = a.m[0][1] * b.m[0][0] + a.m[1][1] * b.m[1][0] + a.m[2][1] * b.m[2][0]; m[1][1] = a.m[0][1] * b.m[0][1] + a.m[1][1] * b.m[1][1] + a.m[2][1] * b.m[2][1]; m[1][2] = a.m[0][1] * b.m[0][2] + a.m[1][1] * b.m[1][2] + a.m[2][1] * b.m[2][2]; m[2][0] = a.m[0][2] * b.m[0][0] + a.m[1][2] * b.m[1][0] + a.m[2][2] * b.m[2][0]; m[2][1] = a.m[0][2] * b.m[0][1] + a.m[1][2] * b.m[1][1] + a.m[2][2] * b.m[2][1]; m[2][2] = a.m[0][2] * b.m[0][2] + a.m[1][2] * b.m[1][2] + a.m[2][2] * b.m[2][2]; } //! this = a * transpose(b) inline_ void MultABt(const Matrix3x3& a, const Matrix3x3& b) { m[0][0] = a.m[0][0] * b.m[0][0] + a.m[0][1] * b.m[0][1] + a.m[0][2] * b.m[0][2]; m[0][1] = a.m[0][0] * b.m[1][0] + a.m[0][1] * b.m[1][1] + a.m[0][2] * b.m[1][2]; m[0][2] = a.m[0][0] * b.m[2][0] + a.m[0][1] * b.m[2][1] + a.m[0][2] * b.m[2][2]; m[1][0] = a.m[1][0] * b.m[0][0] + a.m[1][1] * b.m[0][1] + a.m[1][2] * b.m[0][2]; m[1][1] = a.m[1][0] * b.m[1][0] + a.m[1][1] * b.m[1][1] + a.m[1][2] * b.m[1][2]; m[1][2] = a.m[1][0] * b.m[2][0] + a.m[1][1] * b.m[2][1] + a.m[1][2] * b.m[2][2]; m[2][0] = a.m[2][0] * b.m[0][0] + a.m[2][1] * b.m[0][1] + a.m[2][2] * b.m[0][2]; m[2][1] = a.m[2][0] * b.m[1][0] + a.m[2][1] * b.m[1][1] + a.m[2][2] * b.m[1][2]; m[2][2] = a.m[2][0] * b.m[2][0] + a.m[2][1] * b.m[2][1] + a.m[2][2] * b.m[2][2]; } //! Makes a rotation matrix mapping vector "from" to vector "to". Matrix3x3& FromTo(const Point& from, const Point& to); //! Set a rotation matrix around the X axis. //! 1 0 0 //! RX = 0 cx sx //! 0 -sx cx void RotX(float angle); //! Set a rotation matrix around the Y axis. //! cy 0 -sy //! RY = 0 1 0 //! sy 0 cy void RotY(float angle); //! Set a rotation matrix around the Z axis. //! cz sz 0 //! RZ = -sz cz 0 //! 0 0 1 void RotZ(float angle); //! cy sx.sy -sy.cx //! RY.RX 0 cx sx //! sy -sx.cy cx.cy void RotYX(float y, float x); //! Make a rotation matrix about an arbitrary axis Matrix3x3& Rot(float angle, const Point& axis); //! Transpose the matrix. void Transpose() { IR(m[1][0]) ^= IR(m[0][1]); IR(m[0][1]) ^= IR(m[1][0]); IR(m[1][0]) ^= IR(m[0][1]); IR(m[2][0]) ^= IR(m[0][2]); IR(m[0][2]) ^= IR(m[2][0]); IR(m[2][0]) ^= IR(m[0][2]); IR(m[2][1]) ^= IR(m[1][2]); IR(m[1][2]) ^= IR(m[2][1]); IR(m[2][1]) ^= IR(m[1][2]); } //! this = Transpose(a) void Transpose(const Matrix3x3& a) { m[0][0] = a.m[0][0]; m[0][1] = a.m[1][0]; m[0][2] = a.m[2][0]; m[1][0] = a.m[0][1]; m[1][1] = a.m[1][1]; m[1][2] = a.m[2][1]; m[2][0] = a.m[0][2]; m[2][1] = a.m[1][2]; m[2][2] = a.m[2][2]; } //! Compute the determinant of the matrix. We use the rule of Sarrus. float Determinant() const { return (m[0][0]*m[1][1]*m[2][2] + m[0][1]*m[1][2]*m[2][0] + m[0][2]*m[1][0]*m[2][1]) - (m[2][0]*m[1][1]*m[0][2] + m[2][1]*m[1][2]*m[0][0] + m[2][2]*m[1][0]*m[0][1]); } /* //! Compute a cofactor. Used for matrix inversion. float CoFactor(ubyte row, ubyte column) const { static const sdword gIndex[3+2] = { 0, 1, 2, 0, 1 }; return (m[gIndex[row+1]][gIndex[column+1]]*m[gIndex[row+2]][gIndex[column+2]] - m[gIndex[row+2]][gIndex[column+1]]*m[gIndex[row+1]][gIndex[column+2]]); } */ //! Invert the matrix. Determinant must be different from zero, else matrix can't be inverted. Matrix3x3& Invert() { float Det = Determinant(); // Must be !=0 float OneOverDet = 1.0f / Det; Matrix3x3 Temp; Temp.m[0][0] = +(m[1][1] * m[2][2] - m[2][1] * m[1][2]) * OneOverDet; Temp.m[1][0] = -(m[1][0] * m[2][2] - m[2][0] * m[1][2]) * OneOverDet; Temp.m[2][0] = +(m[1][0] * m[2][1] - m[2][0] * m[1][1]) * OneOverDet; Temp.m[0][1] = -(m[0][1] * m[2][2] - m[2][1] * m[0][2]) * OneOverDet; Temp.m[1][1] = +(m[0][0] * m[2][2] - m[2][0] * m[0][2]) * OneOverDet; Temp.m[2][1] = -(m[0][0] * m[2][1] - m[2][0] * m[0][1]) * OneOverDet; Temp.m[0][2] = +(m[0][1] * m[1][2] - m[1][1] * m[0][2]) * OneOverDet; Temp.m[1][2] = -(m[0][0] * m[1][2] - m[1][0] * m[0][2]) * OneOverDet; Temp.m[2][2] = +(m[0][0] * m[1][1] - m[1][0] * m[0][1]) * OneOverDet; *this = Temp; return *this; } Matrix3x3& Normalize(); //! this = exp(a) Matrix3x3& Exp(const Matrix3x3& a); void FromQuat(const Quat &q); void FromQuatL2(const Quat &q, float l2); // Arithmetic operators //! Operator for Matrix3x3 Plus = Matrix3x3 + Matrix3x3; inline_ Matrix3x3 operator+(const Matrix3x3& mat) const { return Matrix3x3( m[0][0] + mat.m[0][0], m[0][1] + mat.m[0][1], m[0][2] + mat.m[0][2], m[1][0] + mat.m[1][0], m[1][1] + mat.m[1][1], m[1][2] + mat.m[1][2], m[2][0] + mat.m[2][0], m[2][1] + mat.m[2][1], m[2][2] + mat.m[2][2]); } //! Operator for Matrix3x3 Minus = Matrix3x3 - Matrix3x3; inline_ Matrix3x3 operator-(const Matrix3x3& mat) const { return Matrix3x3( m[0][0] - mat.m[0][0], m[0][1] - mat.m[0][1], m[0][2] - mat.m[0][2], m[1][0] - mat.m[1][0], m[1][1] - mat.m[1][1], m[1][2] - mat.m[1][2], m[2][0] - mat.m[2][0], m[2][1] - mat.m[2][1], m[2][2] - mat.m[2][2]); } //! Operator for Matrix3x3 Mul = Matrix3x3 * Matrix3x3; inline_ Matrix3x3 operator*(const Matrix3x3& mat) const { return Matrix3x3( m[0][0]*mat.m[0][0] + m[0][1]*mat.m[1][0] + m[0][2]*mat.m[2][0], m[0][0]*mat.m[0][1] + m[0][1]*mat.m[1][1] + m[0][2]*mat.m[2][1], m[0][0]*mat.m[0][2] + m[0][1]*mat.m[1][2] + m[0][2]*mat.m[2][2], m[1][0]*mat.m[0][0] + m[1][1]*mat.m[1][0] + m[1][2]*mat.m[2][0], m[1][0]*mat.m[0][1] + m[1][1]*mat.m[1][1] + m[1][2]*mat.m[2][1], m[1][0]*mat.m[0][2] + m[1][1]*mat.m[1][2] + m[1][2]*mat.m[2][2], m[2][0]*mat.m[0][0] + m[2][1]*mat.m[1][0] + m[2][2]*mat.m[2][0], m[2][0]*mat.m[0][1] + m[2][1]*mat.m[1][1] + m[2][2]*mat.m[2][1], m[2][0]*mat.m[0][2] + m[2][1]*mat.m[1][2] + m[2][2]*mat.m[2][2]); } //! Operator for Point Mul = Matrix3x3 * Point; inline_ Point operator*(const Point& v) const { return Point(GetRow(0)|v, GetRow(1)|v, GetRow(2)|v); } //! Operator for Matrix3x3 Mul = Matrix3x3 * float; inline_ Matrix3x3 operator*(float s) const { return Matrix3x3( m[0][0]*s, m[0][1]*s, m[0][2]*s, m[1][0]*s, m[1][1]*s, m[1][2]*s, m[2][0]*s, m[2][1]*s, m[2][2]*s); } //! Operator for Matrix3x3 Mul = float * Matrix3x3; inline_ friend Matrix3x3 operator*(float s, const Matrix3x3& mat) { return Matrix3x3( s*mat.m[0][0], s*mat.m[0][1], s*mat.m[0][2], s*mat.m[1][0], s*mat.m[1][1], s*mat.m[1][2], s*mat.m[2][0], s*mat.m[2][1], s*mat.m[2][2]); } //! Operator for Matrix3x3 Div = Matrix3x3 / float; inline_ Matrix3x3 operator/(float s) const { if (s) s = 1.0f / s; return Matrix3x3( m[0][0]*s, m[0][1]*s, m[0][2]*s, m[1][0]*s, m[1][1]*s, m[1][2]*s, m[2][0]*s, m[2][1]*s, m[2][2]*s); } //! Operator for Matrix3x3 Div = float / Matrix3x3; inline_ friend Matrix3x3 operator/(float s, const Matrix3x3& mat) { return Matrix3x3( s/mat.m[0][0], s/mat.m[0][1], s/mat.m[0][2], s/mat.m[1][0], s/mat.m[1][1], s/mat.m[1][2], s/mat.m[2][0], s/mat.m[2][1], s/mat.m[2][2]); } //! Operator for Matrix3x3 += Matrix3x3 inline_ Matrix3x3& operator+=(const Matrix3x3& mat) { m[0][0] += mat.m[0][0]; m[0][1] += mat.m[0][1]; m[0][2] += mat.m[0][2]; m[1][0] += mat.m[1][0]; m[1][1] += mat.m[1][1]; m[1][2] += mat.m[1][2]; m[2][0] += mat.m[2][0]; m[2][1] += mat.m[2][1]; m[2][2] += mat.m[2][2]; return *this; } //! Operator for Matrix3x3 -= Matrix3x3 inline_ Matrix3x3& operator-=(const Matrix3x3& mat) { m[0][0] -= mat.m[0][0]; m[0][1] -= mat.m[0][1]; m[0][2] -= mat.m[0][2]; m[1][0] -= mat.m[1][0]; m[1][1] -= mat.m[1][1]; m[1][2] -= mat.m[1][2]; m[2][0] -= mat.m[2][0]; m[2][1] -= mat.m[2][1]; m[2][2] -= mat.m[2][2]; return *this; } //! Operator for Matrix3x3 *= Matrix3x3 inline_ Matrix3x3& operator*=(const Matrix3x3& mat) { Point TempRow; GetRow(0, TempRow); m[0][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0]; m[0][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1]; m[0][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2]; GetRow(1, TempRow); m[1][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0]; m[1][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1]; m[1][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2]; GetRow(2, TempRow); m[2][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0]; m[2][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1]; m[2][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2]; return *this; } //! Operator for Matrix3x3 *= float inline_ Matrix3x3& operator*=(float s) { m[0][0] *= s; m[0][1] *= s; m[0][2] *= s; m[1][0] *= s; m[1][1] *= s; m[1][2] *= s; m[2][0] *= s; m[2][1] *= s; m[2][2] *= s; return *this; } //! Operator for Matrix3x3 /= float inline_ Matrix3x3& operator/=(float s) { if (s) s = 1.0f / s; m[0][0] *= s; m[0][1] *= s; m[0][2] *= s; m[1][0] *= s; m[1][1] *= s; m[1][2] *= s; m[2][0] *= s; m[2][1] *= s; m[2][2] *= s; return *this; } // Cast operators //! Cast a Matrix3x3 to a Matrix4x4. operator Matrix4x4() const; //! Cast a Matrix3x3 to a Quat. operator Quat() const; inline_ const Point& operator[](int row) const { return *(const Point*)&m[row][0]; } inline_ Point& operator[](int row) { return *(Point*)&m[row][0]; } public: float m[3][3]; }; #endif // __ICEMATRIX3X3_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_Model.h0000600000175000017500000000653712161402010022242 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for OPCODE models. * \file OPC_Model.h * \author Pierre Terdiman * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __OPC_MODEL_H__ #define __OPC_MODEL_H__ class OPCODE_API Model : public BaseModel { public: // Constructor/Destructor Model(); virtual ~Model(); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Builds a collision model. * \param create [in] model creation structure * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// override(BaseModel) bool Build(const OPCODECREATE& create); #ifdef __MESHMERIZER_H__ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the collision hull. * \return the collision hull if it exists */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ const CollisionHull* GetHull() const { return mHull; } #endif // __MESHMERIZER_H__ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the number of bytes used by the tree. * \return amount of bytes used */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// override(BaseModel) udword GetUsedBytes() const; private: #ifdef __MESHMERIZER_H__ CollisionHull* mHull; //!< Possible convex hull #endif // __MESHMERIZER_H__ // Internal methods void Release(); }; #endif //__OPC_MODEL_H__ alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_Model.cpp0000600000175000017500000002066212161402010022570 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code for OPCODE models. * \file OPC_Model.cpp * \author Pierre Terdiman * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * The main collision wrapper, for all trees. Supported trees are: * - Normal trees (2*N-1 nodes, full size) * - No-leaf trees (N-1 nodes, full size) * - Quantized trees (2*N-1 nodes, half size) * - Quantized no-leaf trees (N-1 nodes, half size) * * Usage: * * 1) Create a static mesh interface using callbacks or pointers. (see OPC_MeshInterface.cpp). * Keep it around in your app, since a pointer to this interface is saved internally and * used until you release the collision structures. * * 2) Build a Model using a creation structure: * * \code * Model Sample; * * OPCODECREATE OPCC; * OPCC.IMesh = ...; * OPCC.Rules = ...; * OPCC.NoLeaf = ...; * OPCC.Quantized = ...; * OPCC.KeepOriginal = ...; * bool Status = Sample.Build(OPCC); * \endcode * * 3) Create a tree collider and set it up: * * \code * AABBTreeCollider TC; * TC.SetFirstContact(...); * TC.SetFullBoxBoxTest(...); * TC.SetFullPrimBoxTest(...); * TC.SetTemporalCoherence(...); * \endcode * * 4) Perform a collision query * * \code * // Setup cache * static BVTCache ColCache; * ColCache.Model0 = &Model0; * ColCache.Model1 = &Model1; * * // Collision query * bool IsOk = TC.Collide(ColCache, World0, World1); * * // Get collision status => if true, objects overlap * BOOL Status = TC.GetContactStatus(); * * // Number of colliding pairs and list of pairs * udword NbPairs = TC.GetNbPairs(); * const Pair* p = TC.GetPairs() * \endcode * * 5) Stats * * \code * Model0.GetUsedBytes() = number of bytes used for this collision tree * TC.GetNbBVBVTests() = number of BV-BV overlap tests performed during last query * TC.GetNbPrimPrimTests() = number of Triangle-Triangle overlap tests performed during last query * TC.GetNbBVPrimTests() = number of Triangle-BV overlap tests performed during last query * \endcode * * \class Model * \author Pierre Terdiman * \version 1.3 * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace Opcode; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Model::Model() { #ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE ! mHull = null; #endif // __MESHMERIZER_H__ } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Destructor. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Model::~Model() { Release(); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Releases the model. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Model::Release() { ReleaseBase(); #ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE ! DELETESINGLE(mHull); #endif // __MESHMERIZER_H__ } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Builds a collision model. * \param create [in] model creation structure * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool Model::Build(const OPCODECREATE& create) { // 1) Checkings if(!create.mIMesh || !create.mIMesh->IsValid()) return false; // For this model, we only support complete trees if(create.mSettings.mLimit!=1) return SetIceError("OPCODE WARNING: supports complete trees only! Use mLimit = 1.\n", null); // Look for degenerate faces. //udword NbDegenerate = create.mIMesh->CheckTopology(); //if(NbDegenerate) Log("OPCODE WARNING: found %d degenerate faces in model! Collision might report wrong results!\n", NbDegenerate); // We continue nonetheless.... Release(); // Make sure previous tree has been discarded [Opcode 1.3, thanks Adam] // 1-1) Setup mesh interface automatically [Opcode 1.3] SetMeshInterface(create.mIMesh); // Special case for 1-triangle meshes [Opcode 1.3] udword NbTris = create.mIMesh->GetNbTriangles(); if(NbTris==1) { // We don't need to actually create a tree here, since we'll only have a single triangle to deal with anyway. // It's a waste to use a "model" for this but at least it will work. mModelCode |= OPC_SINGLE_NODE; return true; } // 2) Build a generic AABB Tree. mSource = new AABBTree; CHECKALLOC(mSource); // 2-1) Setup a builder. Our primitives here are triangles from input mesh, // so we use an AABBTreeOfTrianglesBuilder..... { AABBTreeOfTrianglesBuilder TB; TB.mIMesh = create.mIMesh; TB.mSettings = create.mSettings; TB.mNbPrimitives = NbTris; if(!mSource->Build(&TB)) return false; } // 3) Create an optimized tree according to user-settings if(!CreateTree(create.mNoLeaf, create.mQuantized)) return false; // 3-2) Create optimized tree if(!mTree->Build(mSource)) return false; // 3-3) Delete generic tree if needed if(!create.mKeepOriginal) DELETESINGLE(mSource); #ifdef __MESHMERIZER_H__ // 4) Convex hull if(create.mCollisionHull) { // Create hull mHull = new CollisionHull; CHECKALLOC(mHull); CONVEXHULLCREATE CHC; // ### doesn't work with strides CHC.NbVerts = create.mIMesh->GetNbVertices(); CHC.Vertices = create.mIMesh->GetVerts(); CHC.UnifyNormals = true; CHC.ReduceVertices = true; CHC.WordFaces = false; mHull->Compute(CHC); } #endif // __MESHMERIZER_H__ return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the number of bytes used by the tree. * \return amount of bytes used */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// udword Model::GetUsedBytes() const { if(!mTree) return 0; return mTree->GetUsedBytes(); } alien-arena-7.66+dfsg/source/unix/odesrc/OPCODE/OPC_Picking.cpp0000600000175000017500000001231012161402010023103 0ustar zero79zero79/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains code to perform "picking". * \file OPC_Picking.cpp * \author Pierre Terdiman * \date March, 20, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace Opcode; #ifdef OPC_RAYHIT_CALLBACK /* Possible RayCollider usages: - boolean query (shadow feeler) - closest hit - all hits - number of intersection (boolean) */ bool Opcode::SetupAllHits(RayCollider& collider, CollisionFaces& contacts) { struct Local { static void AllContacts(const CollisionFace& hit, void* user_data) { CollisionFaces* CF = (CollisionFaces*)user_data; CF->AddFace(hit); } }; collider.SetFirstContact(false); collider.SetHitCallback(Local::AllContacts); collider.SetUserData(&contacts); return true; } bool Opcode::SetupClosestHit(RayCollider& collider, CollisionFace& closest_contact) { struct Local { static void ClosestContact(const CollisionFace& hit, void* user_data) { CollisionFace* CF = (CollisionFace*)user_data; if(hit.mDistancemDistance) *CF = hit; } }; collider.SetFirstContact(false); collider.SetHitCallback(Local::ClosestContact); collider.SetUserData(&closest_contact); closest_contact.mDistance = MAX_FLOAT; return true; } bool Opcode::SetupShadowFeeler(RayCollider& collider) { collider.SetFirstContact(true); collider.SetHitCallback(null); return true; } bool Opcode::SetupInOutTest(RayCollider& collider) { collider.SetFirstContact(false); collider.SetHitCallback(null); // Results with collider.GetNbIntersections() return true; } bool Opcode::Picking( CollisionFace& picked_face, const Ray& world_ray, const Model& model, const Matrix4x4* world, float min_dist, float max_dist, const Point& view_point, CullModeCallback callback, void* user_data) { struct Local { struct CullData { CollisionFace* Closest; float MinLimit; CullModeCallback Callback; void* UserData; Point ViewPoint; const MeshInterface* IMesh; }; // Called for each stabbed face static void RenderCullingCallback(const CollisionFace& hit, void* user_data) { CullData* Data = (CullData*)user_data; // Discard face if we already have a closer hit if(hit.mDistance>=Data->Closest->mDistance) return; // Discard face if hit point is smaller than min limit. This mainly happens when the face is in front // of the near clip plane (or straddles it). If we keep the face nonetheless, the user can select an // object that he may not even be able to see, which is very annoying. if(hit.mDistance<=Data->MinLimit) return; // This is the index of currently stabbed triangle. udword StabbedFaceIndex = hit.mFaceID; // We may keep it or not, depending on backface culling bool KeepIt = true; // Catch *render* cull mode for this face CullMode CM = (Data->Callback)(StabbedFaceIndex, Data->UserData); if(CM!=CULLMODE_NONE) // Don't even compute culling for double-sided triangles { // Compute backface culling for current face VertexPointers VP; ConversionArea VC; Data->IMesh->GetTriangle(VP, StabbedFaceIndex, VC); if(VP.BackfaceCulling(Data->ViewPoint)) { if(CM==CULLMODE_CW) KeepIt = false; } else { if(CM==CULLMODE_CCW) KeepIt = false; } } if(KeepIt) *Data->Closest = hit; } }; RayCollider RC; RC.SetMaxDist(max_dist); RC.SetTemporalCoherence(false); RC.SetCulling(false); // We need all faces since some of them can be double-sided RC.SetFirstContact(false); RC.SetHitCallback(Local::RenderCullingCallback); picked_face.mFaceID = INVALID_ID; picked_face.mDistance = MAX_FLOAT; picked_face.mU = 0.0f; picked_face.mV = 0.0f; Local::CullData Data; Data.Closest = &picked_face; Data.MinLimit = min_dist; Data.Callback = callback; Data.UserData = user_data; Data.ViewPoint = view_point; Data.IMesh = model.GetMeshInterface(); if(world) { // Get matrices Matrix4x4 InvWorld; InvertPRMatrix(InvWorld, *world); // Compute camera position in mesh space Data.ViewPoint *= InvWorld; } RC.SetUserData(&Data); if(RC.Collide(world_ray, model, world)) { return picked_face.mFaceID!=INVALID_ID; } return false; } #endif alien-arena-7.66+dfsg/source/unix/odesrc/matrix.cpp0000600000175000017500000002214512161402010021360 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include #include #include "util.h" #include "config.h" // misc defines #define ALLOCA dALLOCA16 void dSetZero (dReal *a, int n) { dAASSERT (a && n >= 0); while (n > 0) { *(a++) = 0; n--; } } void dSetValue (dReal *a, int n, dReal value) { dAASSERT (a && n >= 0); while (n > 0) { *(a++) = value; n--; } } void dMultiply0 (dReal *A, const dReal *B, const dReal *C, int p, int q, int r) { int i,j,k,qskip,rskip,rpad; dAASSERT (A && B && C && p>0 && q>0 && r>0); qskip = dPAD(q); rskip = dPAD(r); rpad = rskip - r; dReal sum; const dReal *b,*c,*bb; bb = B; for (i=p; i; i--) { for (j=0 ; j0 && q>0 && r>0); pskip = dPAD(p); rskip = dPAD(r); for (i=0; i0 && q>0 && r>0); rpad = dPAD(r) - r; qskip = dPAD(q); bb = B; for (i=p; i; i--) { cc = C; for (j=r; j; j--) { z = 0; sum = 0; for (k=q; k; k--,z++) sum += bb[z] * cc[z]; *(A++) = sum; cc += qskip; } A += rpad; bb += qskip; } } int dFactorCholesky (dReal *A, int n) { int i,j,k,nskip; dReal sum,*a,*b,*aa,*bb,*cc,*recip; dAASSERT (n > 0 && A); nskip = dPAD (n); recip = (dReal*) ALLOCA (n * sizeof(dReal)); aa = A; for (i=0; i 0 && L && b); nskip = dPAD (n); y = (dReal*) ALLOCA (n*sizeof(dReal)); for (i=0; i= 0; i--) { sum = 0; for (k=i+1; k < n; k++) sum += L[k*nskip+i]*b[k]; b[i] = (y[i]-sum)/L[i*nskip+i]; } } int dInvertPDMatrix (const dReal *A, dReal *Ainv, int n) { int i,j,nskip; dReal *L,*x; dAASSERT (n > 0 && A && Ainv); nskip = dPAD (n); L = (dReal*) ALLOCA (nskip*n*sizeof(dReal)); memcpy (L,A,nskip*n*sizeof(dReal)); x = (dReal*) ALLOCA (n*sizeof(dReal)); if (dFactorCholesky (L,n)==0) return 0; dSetZero (Ainv,n*nskip); // make sure all padding elements set to 0 for (i=0; i 0 && A); int nskip = dPAD (n); Acopy = (dReal*) ALLOCA (nskip*n * sizeof(dReal)); memcpy (Acopy,A,nskip*n * sizeof(dReal)); return dFactorCholesky (Acopy,n); } /***** this has been replaced by a faster version void dSolveL1T (const dReal *L, dReal *b, int n, int nskip) { int i,j; dAASSERT (L && b && n >= 0 && nskip >= n); dReal sum; for (i=n-2; i>=0; i--) { sum = 0; for (j=i+1; j= 0); for (int i=0; i 0 && nskip >= n); dSolveL1 (L,b,n,nskip); dVectorScale (b,d,n); dSolveL1T (L,b,n,nskip); } void dLDLTAddTL (dReal *L, dReal *d, const dReal *a, int n, int nskip) { int j,p; dReal *W1,*W2,W11,W21,alpha1,alpha2,alphanew,gamma1,gamma2,k1,k2,Wp,ell,dee; dAASSERT (L && d && a && n > 0 && nskip >= n); if (n < 2) return; W1 = (dReal*) ALLOCA (n*sizeof(dReal)); W2 = (dReal*) ALLOCA (n*sizeof(dReal)); W1[0] = 0; W2[0] = 0; for (j=1; j j) ? _GETA(i,j) : _GETA(j,i)) void dLDLTRemove (dReal **A, const int *p, dReal *L, dReal *d, int n1, int n2, int r, int nskip) { int i; dAASSERT(A && p && L && d && n1 > 0 && n2 > 0 && r >= 0 && r < n2 && n1 >= n2 && nskip >= n1); #ifndef dNODEBUG for (i=0; i= 0 && p[i] < n1); #endif if (r==n2-1) { return; // deleting last row/col is easy } else if (r==0) { dReal *a = (dReal*) ALLOCA (n2 * sizeof(dReal)); for (i=0; i 0 && nskip >= n && r >= 0 && r < n); if (r >= n-1) return; if (r > 0) { for (i=0; i #include "collision_kernel.h" // primitive collision functions - these have the dColliderFn interface, i.e. // the same interface as dCollide(). the first and second geom arguments must // have the specified types. int dCollideSphereSphere (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideSphereBox (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideSpherePlane (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideBoxBox (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideBoxPlane (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideCapsuleSphere (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideCapsuleBox (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideCapsuleCapsule (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideCapsulePlane (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideRaySphere (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideRayBox (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideRayCapsule (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideRayPlane (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideRayCylinder (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); // Cylinder - Box/Sphere by (C) CroTeam // Ported by Nguyen Binh int dCollideCylinderBox(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideCylinderSphere(dxGeom *gCylinder, dxGeom *gSphere, int flags, dContactGeom *contact, int skip); int dCollideCylinderPlane(dxGeom *gCylinder, dxGeom *gPlane, int flags, dContactGeom *contact, int skip); //--> Convex Collision int dCollideConvexPlane (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideSphereConvex (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideConvexBox (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideConvexCapsule (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideConvexConvex (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideRayConvex (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); //<-- Convex Collision // dHeightfield int dCollideHeightfield( dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip ); //**************************************************************************** // the basic geometry objects struct dxSphere : public dxGeom { dReal radius; // sphere radius dxSphere (dSpaceID space, dReal _radius); void computeAABB(); }; struct dxBox : public dxGeom { dVector3 side; // side lengths (x,y,z) dxBox (dSpaceID space, dReal lx, dReal ly, dReal lz); void computeAABB(); }; struct dxCapsule : public dxGeom { dReal radius,lz; // radius, length along z axis dxCapsule (dSpaceID space, dReal _radius, dReal _length); void computeAABB(); }; struct dxCylinder : public dxGeom { dReal radius,lz; // radius, length along z axis dxCylinder (dSpaceID space, dReal _radius, dReal _length); void computeAABB(); }; struct dxPlane : public dxGeom { dReal p[4]; dxPlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d); void computeAABB(); }; struct dxRay : public dxGeom { dReal length; dxRay (dSpaceID space, dReal _length); void computeAABB(); }; struct dxConvex : public dxGeom { dReal *planes; /*!< An array of planes in the form: normal X, normal Y, normal Z,Distance */ dReal *points; /*!< An array of points X,Y,Z */ unsigned int *polygons; /*! An array of indices to the points of each polygon, it should be the number of vertices followed by that amount of indices to "points" in counter clockwise order*/ unsigned int planecount; /*!< Amount of planes in planes */ unsigned int pointcount;/*!< Amount of points in points */ unsigned int edgecount;/*!< Amount of edges in convex */ dReal saabb[6];/*!< Static AABB */ dxConvex(dSpaceID space, dReal *planes, unsigned int planecount, dReal *points, unsigned int pointcount, unsigned int *polygons); ~dxConvex() { if((edgecount!=0)&&(edges!=NULL)) delete[] edges; } void computeAABB(); struct edge { unsigned int first; unsigned int second; }; edge* edges; /*! \brief A Support mapping function for convex shapes \param dir [IN] direction to find the Support Point for \return the index of the support vertex. */ inline unsigned int SupportIndex(dVector3 dir) { dVector3 rdir; unsigned int index=0; dMULTIPLY1_331 (rdir,final_posr->R,dir); dReal max = dDOT(points,rdir); dReal tmp; for (unsigned int i = 1; i < pointcount; ++i) { tmp = dDOT(points+(i*3),rdir); if (tmp > max) { index=i; max = tmp; } } return index; } private: // For Internal Use Only /*! \brief Fills the edges dynamic array based on points and polygons. */ void FillEdges(); #if 0 /* What this does is the same as the Support function by doing some preprocessing for optimization. Not complete yet. */ // Based on Eberly's Game Physics Book page 307 struct Arc { // indices of polyhedron normals that form the spherical arc int normals[2]; // index of edge shared by polyhedron faces int edge; }; struct Polygon { // indices of polyhedron normals that form the spherical polygon std::vector normals; // index of extreme vertex corresponding to this polygon int vertex; }; // This is for extrem feature query and not the usual level BSP structure (that comes later) struct BSPNode { // Normal index (interior node), vertex index (leaf node) int normal; // if Dot (E,D)>=0, D gets propagated to this child BSPNode* right; // if Dot (E,D)<0, D gets propagated to this child BSPNode* left; }; void CreateTree(); BSPNode* CreateNode(std::vector Arcs,std::vector Polygons); void GetFacesSharedByVertex(int i, std::vector f); void GetFacesSharedByEdge(int i, int* f); void GetFaceNormal(int i, dVector3 normal); BSPNode* tree; #endif }; #endif alien-arena-7.66+dfsg/source/unix/odesrc/capsule.cpp0000600000175000017500000003214112161402010021505 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* standard ODE geometry primitives: public API and pairwise collision functions. the rule is that only the low level primitive collision functions should set dContactGeom::g1 and dContactGeom::g2. */ #include #include #include #include #include #include "collision_kernel.h" #include "collision_std.h" #include "collision_util.h" #ifdef _MSC_VER #pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" #endif //**************************************************************************** // capped cylinder public API dxCapsule::dxCapsule (dSpaceID space, dReal _radius, dReal _length) : dxGeom (space,1) { dAASSERT (_radius >= 0 && _length >= 0); type = dCapsuleClass; radius = _radius; lz = _length; updateZeroSizedFlag(!_radius/* || !_length -- zero length capsule is not a zero sized capsule*/); } void dxCapsule::computeAABB() { const dMatrix3& R = final_posr->R; const dVector3& pos = final_posr->pos; dReal xrange = dFabs(R[2] * lz) * REAL(0.5) + radius; dReal yrange = dFabs(R[6] * lz) * REAL(0.5) + radius; dReal zrange = dFabs(R[10] * lz) * REAL(0.5) + radius; aabb[0] = pos[0] - xrange; aabb[1] = pos[0] + xrange; aabb[2] = pos[1] - yrange; aabb[3] = pos[1] + yrange; aabb[4] = pos[2] - zrange; aabb[5] = pos[2] + zrange; } dGeomID dCreateCapsule (dSpaceID space, dReal radius, dReal length) { return new dxCapsule (space,radius,length); } void dGeomCapsuleSetParams (dGeomID g, dReal radius, dReal length) { dUASSERT (g && g->type == dCapsuleClass,"argument not a ccylinder"); dAASSERT (radius >= 0 && length >= 0); dxCapsule *c = (dxCapsule*) g; c->radius = radius; c->lz = length; c->updateZeroSizedFlag(!radius/* || !length -- zero length capsule is not a zero sized capsule*/); dGeomMoved (g); } void dGeomCapsuleGetParams (dGeomID g, dReal *radius, dReal *length) { dUASSERT (g && g->type == dCapsuleClass,"argument not a ccylinder"); dxCapsule *c = (dxCapsule*) g; *radius = c->radius; *length = c->lz; } dReal dGeomCapsulePointDepth (dGeomID g, dReal x, dReal y, dReal z) { dUASSERT (g && g->type == dCapsuleClass,"argument not a ccylinder"); g->recomputePosr(); dxCapsule *c = (dxCapsule*) g; const dReal* R = g->final_posr->R; const dReal* pos = g->final_posr->pos; dVector3 a; a[0] = x - pos[0]; a[1] = y - pos[1]; a[2] = z - pos[2]; dReal beta = dDOT14(a,R+2); dReal lz2 = c->lz*REAL(0.5); if (beta < -lz2) beta = -lz2; else if (beta > lz2) beta = lz2; a[0] = c->final_posr->pos[0] + beta*R[0*4+2]; a[1] = c->final_posr->pos[1] + beta*R[1*4+2]; a[2] = c->final_posr->pos[2] + beta*R[2*4+2]; return c->radius - dSqrt ((x-a[0])*(x-a[0]) + (y-a[1])*(y-a[1]) + (z-a[2])*(z-a[2])); } int dCollideCapsuleSphere (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT (o1->type == dCapsuleClass); dIASSERT (o2->type == dSphereClass); dIASSERT ((flags & NUMC_MASK) >= 1); dxCapsule *ccyl = (dxCapsule*) o1; dxSphere *sphere = (dxSphere*) o2; contact->g1 = o1; contact->g2 = o2; contact->side1 = -1; contact->side2 = -1; // find the point on the cylinder axis that is closest to the sphere dReal alpha = o1->final_posr->R[2] * (o2->final_posr->pos[0] - o1->final_posr->pos[0]) + o1->final_posr->R[6] * (o2->final_posr->pos[1] - o1->final_posr->pos[1]) + o1->final_posr->R[10] * (o2->final_posr->pos[2] - o1->final_posr->pos[2]); dReal lz2 = ccyl->lz * REAL(0.5); if (alpha > lz2) alpha = lz2; if (alpha < -lz2) alpha = -lz2; // collide the spheres dVector3 p; p[0] = o1->final_posr->pos[0] + alpha * o1->final_posr->R[2]; p[1] = o1->final_posr->pos[1] + alpha * o1->final_posr->R[6]; p[2] = o1->final_posr->pos[2] + alpha * o1->final_posr->R[10]; return dCollideSpheres (p,ccyl->radius,o2->final_posr->pos,sphere->radius,contact); } int dCollideCapsuleBox (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT (o1->type == dCapsuleClass); dIASSERT (o2->type == dBoxClass); dIASSERT ((flags & NUMC_MASK) >= 1); dxCapsule *cyl = (dxCapsule*) o1; dxBox *box = (dxBox*) o2; contact->g1 = o1; contact->g2 = o2; contact->side1 = -1; contact->side2 = -1; // get p1,p2 = cylinder axis endpoints, get radius dVector3 p1,p2; dReal clen = cyl->lz * REAL(0.5); p1[0] = o1->final_posr->pos[0] + clen * o1->final_posr->R[2]; p1[1] = o1->final_posr->pos[1] + clen * o1->final_posr->R[6]; p1[2] = o1->final_posr->pos[2] + clen * o1->final_posr->R[10]; p2[0] = o1->final_posr->pos[0] - clen * o1->final_posr->R[2]; p2[1] = o1->final_posr->pos[1] - clen * o1->final_posr->R[6]; p2[2] = o1->final_posr->pos[2] - clen * o1->final_posr->R[10]; dReal radius = cyl->radius; // copy out box center, rotation matrix, and side array dReal *c = o2->final_posr->pos; dReal *R = o2->final_posr->R; const dReal *side = box->side; // get the closest point between the cylinder axis and the box dVector3 pl,pb; dClosestLineBoxPoints (p1,p2,c,R,side,pl,pb); // generate contact point return dCollideSpheres (pl,radius,pb,0,contact); } int dCollideCapsuleCapsule (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT (o1->type == dCapsuleClass); dIASSERT (o2->type == dCapsuleClass); dIASSERT ((flags & NUMC_MASK) >= 1); int i; const dReal tolerance = REAL(1e-5); dxCapsule *cyl1 = (dxCapsule*) o1; dxCapsule *cyl2 = (dxCapsule*) o2; contact->g1 = o1; contact->g2 = o2; contact->side1 = -1; contact->side2 = -1; // copy out some variables, for convenience dReal lz1 = cyl1->lz * REAL(0.5); dReal lz2 = cyl2->lz * REAL(0.5); dReal *pos1 = o1->final_posr->pos; dReal *pos2 = o2->final_posr->pos; dReal axis1[3],axis2[3]; axis1[0] = o1->final_posr->R[2]; axis1[1] = o1->final_posr->R[6]; axis1[2] = o1->final_posr->R[10]; axis2[0] = o2->final_posr->R[2]; axis2[1] = o2->final_posr->R[6]; axis2[2] = o2->final_posr->R[10]; // if the cylinder axes are close to parallel, we'll try to detect up to // two contact points along the body of the cylinder. if we can't find any // points then we'll fall back to the closest-points algorithm. note that // we are not treating this special case for reasons of degeneracy, but // because we want two contact points in some situations. the closet-points // algorithm is robust in all casts, but it can return only one contact. dVector3 sphere1,sphere2; dReal a1a2 = dDOT (axis1,axis2); dReal det = REAL(1.0)-a1a2*a1a2; if (det < tolerance) { // the cylinder axes (almost) parallel, so we will generate up to two // contacts. alpha1 and alpha2 (line position parameters) are related by: // alpha2 = alpha1 + (pos1-pos2)'*axis1 (if axis1==axis2) // or alpha2 = -(alpha1 + (pos1-pos2)'*axis1) (if axis1==-axis2) // first compute where the two cylinders overlap in alpha1 space: if (a1a2 < 0) { axis2[0] = -axis2[0]; axis2[1] = -axis2[1]; axis2[2] = -axis2[2]; } dReal q[3]; for (i=0; i<3; i++) q[i] = pos1[i]-pos2[i]; dReal k = dDOT (axis1,q); dReal a1lo = -lz1; dReal a1hi = lz1; dReal a2lo = -lz2 - k; dReal a2hi = lz2 - k; dReal lo = (a1lo > a2lo) ? a1lo : a2lo; dReal hi = (a1hi < a2hi) ? a1hi : a2hi; if (lo <= hi) { int num_contacts = flags & NUMC_MASK; if (num_contacts >= 2 && lo < hi) { // generate up to two contacts. if one of those contacts is // not made, fall back on the one-contact strategy. for (i=0; i<3; i++) sphere1[i] = pos1[i] + lo*axis1[i]; for (i=0; i<3; i++) sphere2[i] = pos2[i] + (lo+k)*axis2[i]; int n1 = dCollideSpheres (sphere1,cyl1->radius, sphere2,cyl2->radius,contact); if (n1) { for (i=0; i<3; i++) sphere1[i] = pos1[i] + hi*axis1[i]; for (i=0; i<3; i++) sphere2[i] = pos2[i] + (hi+k)*axis2[i]; dContactGeom *c2 = CONTACT(contact,skip); int n2 = dCollideSpheres (sphere1,cyl1->radius, sphere2,cyl2->radius, c2); if (n2) { c2->g1 = o1; c2->g2 = o2; c2->side1 = -1; c2->side2 = -1; return 2; } } } // just one contact to generate, so put it in the middle of // the range dReal alpha1 = (lo + hi) * REAL(0.5); dReal alpha2 = alpha1 + k; for (i=0; i<3; i++) sphere1[i] = pos1[i] + alpha1*axis1[i]; for (i=0; i<3; i++) sphere2[i] = pos2[i] + alpha2*axis2[i]; return dCollideSpheres (sphere1,cyl1->radius, sphere2,cyl2->radius,contact); } } // use the closest point algorithm dVector3 a1,a2,b1,b2; a1[0] = o1->final_posr->pos[0] + axis1[0]*lz1; a1[1] = o1->final_posr->pos[1] + axis1[1]*lz1; a1[2] = o1->final_posr->pos[2] + axis1[2]*lz1; a2[0] = o1->final_posr->pos[0] - axis1[0]*lz1; a2[1] = o1->final_posr->pos[1] - axis1[1]*lz1; a2[2] = o1->final_posr->pos[2] - axis1[2]*lz1; b1[0] = o2->final_posr->pos[0] + axis2[0]*lz2; b1[1] = o2->final_posr->pos[1] + axis2[1]*lz2; b1[2] = o2->final_posr->pos[2] + axis2[2]*lz2; b2[0] = o2->final_posr->pos[0] - axis2[0]*lz2; b2[1] = o2->final_posr->pos[1] - axis2[1]*lz2; b2[2] = o2->final_posr->pos[2] - axis2[2]*lz2; dClosestLineSegmentPoints (a1,a2,b1,b2,sphere1,sphere2); return dCollideSpheres (sphere1,cyl1->radius,sphere2,cyl2->radius,contact); } int dCollideCapsulePlane (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT (o1->type == dCapsuleClass); dIASSERT (o2->type == dPlaneClass); dIASSERT ((flags & NUMC_MASK) >= 1); dxCapsule *ccyl = (dxCapsule*) o1; dxPlane *plane = (dxPlane*) o2; // collide the deepest capping sphere with the plane dReal sign = (dDOT14 (plane->p,o1->final_posr->R+2) > 0) ? REAL(-1.0) : REAL(1.0); dVector3 p; p[0] = o1->final_posr->pos[0] + o1->final_posr->R[2] * ccyl->lz * REAL(0.5) * sign; p[1] = o1->final_posr->pos[1] + o1->final_posr->R[6] * ccyl->lz * REAL(0.5) * sign; p[2] = o1->final_posr->pos[2] + o1->final_posr->R[10] * ccyl->lz * REAL(0.5) * sign; dReal k = dDOT (p,plane->p); dReal depth = plane->p[3] - k + ccyl->radius; if (depth < 0) return 0; contact->normal[0] = plane->p[0]; contact->normal[1] = plane->p[1]; contact->normal[2] = plane->p[2]; contact->pos[0] = p[0] - plane->p[0] * ccyl->radius; contact->pos[1] = p[1] - plane->p[1] * ccyl->radius; contact->pos[2] = p[2] - plane->p[2] * ccyl->radius; contact->depth = depth; int ncontacts = 1; if ((flags & NUMC_MASK) >= 2) { // collide the other capping sphere with the plane p[0] = o1->final_posr->pos[0] - o1->final_posr->R[2] * ccyl->lz * REAL(0.5) * sign; p[1] = o1->final_posr->pos[1] - o1->final_posr->R[6] * ccyl->lz * REAL(0.5) * sign; p[2] = o1->final_posr->pos[2] - o1->final_posr->R[10] * ccyl->lz * REAL(0.5) * sign; k = dDOT (p,plane->p); depth = plane->p[3] - k + ccyl->radius; if (depth >= 0) { dContactGeom *c2 = CONTACT(contact,skip); c2->normal[0] = plane->p[0]; c2->normal[1] = plane->p[1]; c2->normal[2] = plane->p[2]; c2->pos[0] = p[0] - plane->p[0] * ccyl->radius; c2->pos[1] = p[1] - plane->p[1] * ccyl->radius; c2->pos[2] = p[2] - plane->p[2] * ccyl->radius; c2->depth = depth; ncontacts = 2; } } for (int i=0; i < ncontacts; i++) { dContactGeom *currContact = CONTACT(contact,i*skip); currContact->g1 = o1; currContact->g2 = o2; currContact->side1 = -1; currContact->side2 = -1; } return ncontacts; } alien-arena-7.66+dfsg/source/unix/odesrc/collision_trimesh_ccylinder.cpp0000600000175000017500000010342612161402010025640 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* * Triangle-Capsule(Capsule) collider by Alen Ladavac * Ported to ODE by Nguyen Binh */ // NOTES from Nguyen Binh // 14 Apr : Seem to be robust // There is a problem when you use original Step and set contact friction // surface.mu = dInfinity; // More description : // When I dropped Capsule over the bunny ears, it seems to stuck // there for a while. I think the cause is when you set surface.mu = dInfinity; // the friction force is too high so it just hang the capsule there. // So the good cure for this is to set mu = around 1.5 (in my case) // For StepFast1, this become as solid as rock : StepFast1 just approximate // friction force. // NOTES from Croteam's Alen //As a side note... there are some extra contacts that can be generated //on the edge between two triangles, and if the capsule penetrates deeply into //the triangle (usually happens with large mass or low FPS), some such //contacts can in some cases push the capsule away from the edge instead of //away from the two triangles. This shows up as capsule slowing down a bit //when hitting an edge while sliding along a flat tesselated grid of //triangles. This is only if capsule is standing upwards. //Same thing can appear whenever a smooth object (e.g sphere) hits such an //edge, and it needs to be solved as a special case probably. This is a //problem we are looking forward to address soon. #include #include #include #include #include "collision_util.h" #include "collision_trimesh_internal.h" #include "util.h" #if dTRIMESH_ENABLED // OPCODE version #if dTRIMESH_OPCODE // largest number, double or float #if defined(dSINGLE) #define MAX_REAL FLT_MAX #define MIN_REAL (-FLT_MAX) #else #define MAX_REAL DBL_MAX #define MIN_REAL (-DBL_MAX) #endif // To optimize before send contacts to dynamic part #define OPTIMIZE_CONTACTS 1 // dVector3 // r=a-b #define SUBTRACT(a,b,r) \ (r)[0]=(a)[0] - (b)[0]; \ (r)[1]=(a)[1] - (b)[1]; \ (r)[2]=(a)[2] - (b)[2]; // dVector3 // a=b #define SET(a,b) \ (a)[0]=(b)[0]; \ (a)[1]=(b)[1]; \ (a)[2]=(b)[2]; // dMatrix3 // a=b #define SETM(a,b) \ (a)[0]=(b)[0]; \ (a)[1]=(b)[1]; \ (a)[2]=(b)[2]; \ (a)[3]=(b)[3]; \ (a)[4]=(b)[4]; \ (a)[5]=(b)[5]; \ (a)[6]=(b)[6]; \ (a)[7]=(b)[7]; \ (a)[8]=(b)[8]; \ (a)[9]=(b)[9]; \ (a)[10]=(b)[10]; \ (a)[11]=(b)[11]; // dVector3 // r=a+b #define ADD(a,b,r) \ (r)[0]=(a)[0] + (b)[0]; \ (r)[1]=(a)[1] + (b)[1]; \ (r)[2]=(a)[2] + (b)[2]; // dMatrix3, int, dVector3 // v=column a from m #define GETCOL(m,a,v) \ (v)[0]=(m)[(a)+0]; \ (v)[1]=(m)[(a)+4]; \ (v)[2]=(m)[(a)+8]; // dVector4, dVector3 // distance between plane p and point v #define POINTDISTANCE(p,v) \ ( p[0]*v[0] + p[1]*v[1] + p[2]*v[2] + p[3] ); \ // dVector4, dVector3, dReal // construct plane from normal and d #define CONSTRUCTPLANE(plane,normal,d) \ plane[0]=normal[0];\ plane[1]=normal[1];\ plane[2]=normal[2];\ plane[3]=d; // dVector3 // length of vector a #define LENGTHOF(a) \ dSqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);\ inline dReal _length2OfVector3(dVector3 v) { return (v[0] * v[0] + v[1] * v[1] + v[2] * v[2] ); } // Local contacts data typedef struct _sLocalContactData { dVector3 vPos; dVector3 vNormal; dReal fDepth; int triIndex; int nFlags; // 0 = filtered out, 1 = OK }sLocalContactData; struct sTrimeshCapsuleColliderData { sTrimeshCapsuleColliderData(): m_gLocalContacts(NULL), m_ctContacts(0) { memset(m_vN, 0, sizeof(dVector3)); } void SetupInitialContext(dxTriMesh *TriMesh, dxGeom *Capsule, int flags, int skip); int TestCollisionForSingleTriangle(int ctContacts0, int Triint, dVector3 dv[3], uint8 flags, bool &bOutFinishSearching); #if OPTIMIZE_CONTACTS void _OptimizeLocalContacts(); #endif int _ProcessLocalContacts(dContactGeom *contact, dxTriMesh *TriMesh, dxGeom *Capsule); static BOOL _cldClipEdgeToPlane(dVector3 &vEpnt0, dVector3 &vEpnt1, const dVector4& plPlane); BOOL _cldTestAxis(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, dVector3 vAxis, int iAxis, BOOL bNoFlip = FALSE); BOOL _cldTestSeparatingAxesOfCapsule(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, uint8 flags); void _cldTestOneTriangleVSCapsule(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, uint8 flags); sLocalContactData *m_gLocalContacts; unsigned int m_ctContacts; // capsule data // real time data dMatrix3 m_mCapsuleRotation; dVector3 m_vCapsulePosition; dVector3 m_vCapsuleAxis; // static data dReal m_vCapsuleRadius; dReal m_fCapsuleSize; // mesh data // dMatrix4 mHullDstPl; dMatrix3 m_mTriMeshRot; dVector3 m_mTriMeshPos; dVector3 m_vE0, m_vE1, m_vE2; // global collider data dVector3 m_vNormal; dReal m_fBestDepth; dReal m_fBestCenter; dReal m_fBestrt; int m_iBestAxis; dVector3 m_vN; dVector3 m_vV0; dVector3 m_vV1; dVector3 m_vV2; // ODE contact's specific unsigned int m_iFlags; int m_iStride; }; // Capsule lie on axis number 3 = (Z axis) static const int nCAPSULE_AXIS = 2; #if OPTIMIZE_CONTACTS // Use to classify contacts to be "near" in position static const dReal fSameContactPositionEpsilon = REAL(0.0001); // 1e-4 // Use to classify contacts to be "near" in normal direction static const dReal fSameContactNormalEpsilon = REAL(0.0001); // 1e-4 // If this two contact can be classified as "near" inline int _IsNearContacts(sLocalContactData& c1,sLocalContactData& c2) { int bPosNear = 0; int bSameDir = 0; dVector3 vDiff; // First check if they are "near" in position SUBTRACT(c1.vPos,c2.vPos,vDiff); if ( (dFabs(vDiff[0]) < fSameContactPositionEpsilon) &&(dFabs(vDiff[1]) < fSameContactPositionEpsilon) &&(dFabs(vDiff[2]) < fSameContactPositionEpsilon)) { bPosNear = 1; } // Second check if they are "near" in normal direction SUBTRACT(c1.vNormal,c2.vNormal,vDiff); if ( (dFabs(vDiff[0]) < fSameContactNormalEpsilon) &&(dFabs(vDiff[1]) < fSameContactNormalEpsilon) &&(dFabs(vDiff[2]) < fSameContactNormalEpsilon) ) { bSameDir = 1; } // Will be "near" if position and normal direction are "near" return (bPosNear && bSameDir); } inline int _IsBetter(sLocalContactData& c1,sLocalContactData& c2) { // The not better will be throw away // You can change the selection criteria here return (c1.fDepth > c2.fDepth); } // iterate through gLocalContacts and filtered out "near contact" void sTrimeshCapsuleColliderData::_OptimizeLocalContacts() { int nContacts = m_ctContacts; for (int i = 0; i < nContacts-1; i++) { for (int j = i+1; j < nContacts; j++) { if (_IsNearContacts(m_gLocalContacts[i],m_gLocalContacts[j])) { // If they are seem to be the samed then filtered // out the least penetrate one if (_IsBetter(m_gLocalContacts[j],m_gLocalContacts[i])) { m_gLocalContacts[i].nFlags = 0; // filtered 1st contact } else { m_gLocalContacts[j].nFlags = 0; // filtered 2nd contact } // NOTE // There is other way is to add two depth together but // it not work so well. Why??? } } } } #endif // OPTIMIZE_CONTACTS int sTrimeshCapsuleColliderData::_ProcessLocalContacts(dContactGeom *contact, dxTriMesh *TriMesh, dxGeom *Capsule) { #if OPTIMIZE_CONTACTS if (m_ctContacts > 1 && !(m_iFlags & CONTACTS_UNIMPORTANT)) { // Can be optimized... _OptimizeLocalContacts(); } #endif unsigned int iContact = 0; dContactGeom* Contact = 0; unsigned int nFinalContact = 0; for (iContact = 0; iContact < m_ctContacts; iContact ++) { // Ensure that we haven't created too many contacts if( nFinalContact >= (m_iFlags & NUMC_MASK)) { break; } if (1 == m_gLocalContacts[iContact].nFlags) { Contact = SAFECONTACT(m_iFlags, contact, nFinalContact, m_iStride); Contact->depth = m_gLocalContacts[iContact].fDepth; SET(Contact->normal,m_gLocalContacts[iContact].vNormal); SET(Contact->pos,m_gLocalContacts[iContact].vPos); Contact->g1 = TriMesh; Contact->g2 = Capsule; Contact->side1 = m_gLocalContacts[iContact].triIndex; Contact->side2 = -1; nFinalContact++; } } // debug //if (nFinalContact != m_ctContacts) //{ // printf("[Info] %d contacts generated,%d filtered.\n",m_ctContacts,m_ctContacts-nFinalContact); //} return nFinalContact; } BOOL sTrimeshCapsuleColliderData::_cldClipEdgeToPlane( dVector3 &vEpnt0, dVector3 &vEpnt1, const dVector4& plPlane) { // calculate distance of edge points to plane dReal fDistance0 = POINTDISTANCE( plPlane, vEpnt0 ); dReal fDistance1 = POINTDISTANCE( plPlane, vEpnt1 ); // if both points are behind the plane if ( fDistance0 < 0 && fDistance1 < 0 ) { // do nothing return FALSE; // if both points in front of the plane } else if ( fDistance0 > 0 && fDistance1 > 0 ) { // accept them return TRUE; // if we have edge/plane intersection } else if ((fDistance0 > 0 && fDistance1 < 0) || ( fDistance0 < 0 && fDistance1 > 0)) { // find intersection point of edge and plane dVector3 vIntersectionPoint; vIntersectionPoint[0]= vEpnt0[0]-(vEpnt0[0]-vEpnt1[0])*fDistance0/(fDistance0-fDistance1); vIntersectionPoint[1]= vEpnt0[1]-(vEpnt0[1]-vEpnt1[1])*fDistance0/(fDistance0-fDistance1); vIntersectionPoint[2]= vEpnt0[2]-(vEpnt0[2]-vEpnt1[2])*fDistance0/(fDistance0-fDistance1); // clamp correct edge to intersection point if ( fDistance0 < 0 ) { SET(vEpnt0,vIntersectionPoint); } else { SET(vEpnt1,vIntersectionPoint); } return TRUE; } return TRUE; } BOOL sTrimeshCapsuleColliderData::_cldTestAxis( const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, dVector3 vAxis, int iAxis, BOOL bNoFlip/* = FALSE*/) { // calculate length of separating axis vector dReal fL = LENGTHOF(vAxis); // if not long enough // TODO : dReal epsilon please if ( fL < REAL(1e-5) ) { // do nothing //iLastOutAxis = 0; return TRUE; } // otherwise normalize it dNormalize3(vAxis); // project capsule on vAxis dReal frc = dFabs(dDOT(m_vCapsuleAxis,vAxis))*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius) + m_vCapsuleRadius; // project triangle on vAxis dReal afv[3]; afv[0] = dDOT(m_vV0, vAxis); afv[1] = dDOT(m_vV1, vAxis); afv[2] = dDOT(m_vV2, vAxis); dReal fMin = MAX_REAL; dReal fMax = MIN_REAL; // for each vertex for(int i=0; i<3; i++) { // find minimum if (afv[i]fMax) { fMax = afv[i]; } } // find triangle's center of interval on axis dReal fCenter = (fMin+fMax)*REAL(0.5); // calculate triangles half interval dReal fTriangleRadius = (fMax-fMin)*REAL(0.5); // if they do not overlap, if (dFabs(fCenter) > ( frc + fTriangleRadius )) { // exit, we have no intersection return FALSE; } // calculate depth dReal fDepth = dFabs(fCenter) - (frc+fTriangleRadius); // if greater then best found so far if ( fDepth > m_fBestDepth ) { // remember depth m_fBestDepth = fDepth; m_fBestCenter = fCenter; m_fBestrt = fTriangleRadius; m_vNormal[0] = vAxis[0]; m_vNormal[1] = vAxis[1]; m_vNormal[2] = vAxis[2]; m_iBestAxis = iAxis; // flip normal if interval is wrong faced if (fCenter<0 && !bNoFlip) { m_vNormal[0] = -m_vNormal[0]; m_vNormal[1] = -m_vNormal[1]; m_vNormal[2] = -m_vNormal[2]; m_fBestCenter = -fCenter; } } return TRUE; } // helper for less key strokes inline void _CalculateAxis(const dVector3& v1, const dVector3& v2, const dVector3& v3, const dVector3& v4, dVector3& r) { dVector3 t1; dVector3 t2; SUBTRACT(v1,v2,t1); dCROSS(t2,=,t1,v3); dCROSS(r,=,t2,v4); } BOOL sTrimeshCapsuleColliderData::_cldTestSeparatingAxesOfCapsule( const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, uint8 flags) { // calculate caps centers in absolute space dVector3 vCp0; vCp0[0] = m_vCapsulePosition[0] + m_vCapsuleAxis[0]*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius); vCp0[1] = m_vCapsulePosition[1] + m_vCapsuleAxis[1]*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius); vCp0[2] = m_vCapsulePosition[2] + m_vCapsuleAxis[2]*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius); dVector3 vCp1; vCp1[0] = m_vCapsulePosition[0] - m_vCapsuleAxis[0]*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius); vCp1[1] = m_vCapsulePosition[1] - m_vCapsuleAxis[1]*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius); vCp1[2] = m_vCapsulePosition[2] - m_vCapsuleAxis[2]*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius); // reset best axis m_iBestAxis = 0; // reset best depth m_fBestDepth = -MAX_REAL; // reset separating axis vector dVector3 vAxis = {REAL(0.0),REAL(0.0),REAL(0.0),REAL(0.0)}; // Epsilon value for checking axis vector length const dReal fEpsilon = 1e-6f; // Translate triangle to Cc cord. SUBTRACT(v0, m_vCapsulePosition, m_vV0); SUBTRACT(v1, m_vCapsulePosition, m_vV1); SUBTRACT(v2, m_vCapsulePosition, m_vV2); // We begin to test for 19 separating axis now // I wonder does it help if we employ the method like ISA-GJK??? // Or at least we should do experiment and find what axis will // be most likely to be separating axis to check it first. // Original // axis m_vN //vAxis = -m_vN; vAxis[0] = - m_vN[0]; vAxis[1] = - m_vN[1]; vAxis[2] = - m_vN[2]; if (!_cldTestAxis(v0, v1, v2, vAxis, 1, TRUE)) { return FALSE; } if (flags & dxTriMeshData::kEdge0) { // axis CxE0 - Edge 0 dCROSS(vAxis,=,m_vCapsuleAxis,m_vE0); //vAxis = dCROSS( m_vCapsuleAxis cross vE0 ); if (_length2OfVector3( vAxis ) > fEpsilon) { if (!_cldTestAxis(v0, v1, v2, vAxis, 2)) { return FALSE; } } } if (flags & dxTriMeshData::kEdge1) { // axis CxE1 - Edge 1 dCROSS(vAxis,=,m_vCapsuleAxis,m_vE1); //vAxis = ( m_vCapsuleAxis cross m_vE1 ); if (_length2OfVector3( vAxis ) > fEpsilon) { if (!_cldTestAxis(v0, v1, v2, vAxis, 3)) { return FALSE; } } } if (flags & dxTriMeshData::kEdge2) { // axis CxE2 - Edge 2 //vAxis = ( m_vCapsuleAxis cross m_vE2 ); dCROSS(vAxis,=,m_vCapsuleAxis,m_vE2); if (_length2OfVector3( vAxis ) > fEpsilon) { if (!_cldTestAxis(v0, v1, v2, vAxis, 4)) { return FALSE; } } } if (flags & dxTriMeshData::kEdge0) { // first capsule point // axis ((Cp0-V0) x E0) x E0 _CalculateAxis(vCp0,v0,m_vE0,m_vE0,vAxis); // vAxis = ( ( vCp0-v0) cross vE0 ) cross vE0; if (_length2OfVector3( vAxis ) > fEpsilon) { if (!_cldTestAxis(v0, v1, v2, vAxis, 5)) { return FALSE; } } } if (flags & dxTriMeshData::kEdge1) { // axis ((Cp0-V1) x E1) x E1 _CalculateAxis(vCp0,v1,m_vE1,m_vE1,vAxis); //vAxis = ( ( vCp0-v1) cross vE1 ) cross vE1; if (_length2OfVector3( vAxis ) > fEpsilon) { if (!_cldTestAxis(v0, v1, v2, vAxis, 6)) { return FALSE; } } } if (flags & dxTriMeshData::kEdge2) { // axis ((Cp0-V2) x E2) x E2 _CalculateAxis(vCp0,v2,m_vE2,m_vE2,vAxis); //vAxis = ( ( vCp0-v2) cross vE2 ) cross vE2; if (_length2OfVector3( vAxis ) > fEpsilon) { if (!_cldTestAxis(v0, v1, v2, vAxis, 7)) { return FALSE; } } } if (flags & dxTriMeshData::kEdge0) { // second capsule point // axis ((Cp1-V0) x E0) x E0 _CalculateAxis(vCp1,v0,m_vE0,m_vE0,vAxis); //vAxis = ( ( vCp1-v0 ) cross vE0 ) cross vE0; if (_length2OfVector3( vAxis ) > fEpsilon) { if (!_cldTestAxis(v0, v1, v2, vAxis, 8)) { return FALSE; } } } if (flags & dxTriMeshData::kEdge1) { // axis ((Cp1-V1) x E1) x E1 _CalculateAxis(vCp1,v1,m_vE1,m_vE1,vAxis); //vAxis = ( ( vCp1-v1 ) cross vE1 ) cross vE1; if (_length2OfVector3( vAxis ) > fEpsilon) { if (!_cldTestAxis(v0, v1, v2, vAxis, 9)) { return FALSE; } } } if (flags & dxTriMeshData::kEdge2) { // axis ((Cp1-V2) x E2) x E2 _CalculateAxis(vCp1,v2,m_vE2,m_vE2,vAxis); //vAxis = ( ( vCp1-v2 ) cross vE2 ) cross vE2; if (_length2OfVector3( vAxis ) > fEpsilon) { if (!_cldTestAxis(v0, v1, v2, vAxis, 10)) { return FALSE; } } } if (flags & dxTriMeshData::kVert0) { // first vertex on triangle // axis ((V0-Cp0) x C) x C _CalculateAxis(v0,vCp0,m_vCapsuleAxis,m_vCapsuleAxis,vAxis); //vAxis = ( ( v0-vCp0 ) cross m_vCapsuleAxis ) cross m_vCapsuleAxis; if (_length2OfVector3( vAxis ) > fEpsilon) { if (!_cldTestAxis(v0, v1, v2, vAxis, 11)) { return FALSE; } } } if (flags & dxTriMeshData::kVert1) { // second vertex on triangle // axis ((V1-Cp0) x C) x C _CalculateAxis(v1,vCp0,m_vCapsuleAxis,m_vCapsuleAxis,vAxis); //vAxis = ( ( v1-vCp0 ) cross vCapsuleAxis ) cross vCapsuleAxis; if (_length2OfVector3( vAxis ) > fEpsilon) { if (!_cldTestAxis(v0, v1, v2, vAxis, 12)) { return FALSE; } } } if (flags & dxTriMeshData::kVert2) { // third vertex on triangle // axis ((V2-Cp0) x C) x C _CalculateAxis(v2,vCp0,m_vCapsuleAxis,m_vCapsuleAxis,vAxis); //vAxis = ( ( v2-vCp0 ) cross vCapsuleAxis ) cross vCapsuleAxis; if (_length2OfVector3( vAxis ) > fEpsilon) { if (!_cldTestAxis(v0, v1, v2, vAxis, 13)) { return FALSE; } } } // Test as separating axes direction vectors between each triangle // edge and each capsule's cap center if (flags & dxTriMeshData::kVert0) { // first triangle vertex and first capsule point //vAxis = v0 - vCp0; SUBTRACT(v0,vCp0,vAxis); if (_length2OfVector3( vAxis ) > fEpsilon) { if (!_cldTestAxis(v0, v1, v2, vAxis, 14)) { return FALSE; } } } if (flags & dxTriMeshData::kVert1) { // second triangle vertex and first capsule point //vAxis = v1 - vCp0; SUBTRACT(v1,vCp0,vAxis); if (_length2OfVector3( vAxis ) > fEpsilon) { if (!_cldTestAxis(v0, v1, v2, vAxis, 15)) { return FALSE; } } } if (flags & dxTriMeshData::kVert2) { // third triangle vertex and first capsule point //vAxis = v2 - vCp0; SUBTRACT(v2,vCp0,vAxis); if (_length2OfVector3( vAxis ) > fEpsilon) { if (!_cldTestAxis(v0, v1, v2, vAxis, 16)) { return FALSE; } } } if (flags & dxTriMeshData::kVert0) { // first triangle vertex and second capsule point //vAxis = v0 - vCp1; SUBTRACT(v0,vCp1,vAxis); if (_length2OfVector3( vAxis ) > fEpsilon) { if (!_cldTestAxis(v0, v1, v2, vAxis, 17)) { return FALSE; } } } if (flags & dxTriMeshData::kVert1) { // second triangle vertex and second capsule point //vAxis = v1 - vCp1; SUBTRACT(v1,vCp1,vAxis); if (_length2OfVector3( vAxis ) > fEpsilon) { if (!_cldTestAxis(v0, v1, v2, vAxis, 18)) { return FALSE; } } } if (flags & dxTriMeshData::kVert2) { // third triangle vertex and second capsule point //vAxis = v2 - vCp1; SUBTRACT(v2,vCp1,vAxis); if (_length2OfVector3( vAxis ) > fEpsilon) { if (!_cldTestAxis(v0, v1, v2, vAxis, 19)) { return FALSE; } } } return TRUE; } // test one mesh triangle on intersection with capsule void sTrimeshCapsuleColliderData::_cldTestOneTriangleVSCapsule( const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, uint8 flags) { // calculate edges SUBTRACT(v1,v0,m_vE0); SUBTRACT(v2,v1,m_vE1); SUBTRACT(v0,v2,m_vE2); dVector3 _minus_vE0; SUBTRACT(v0,v1,_minus_vE0); // calculate poly normal dCROSS(m_vN,=,m_vE1,_minus_vE0); // Even though all triangles might be initially valid, // a triangle may degenerate into a segment after applying // space transformation. if (!dSafeNormalize3(m_vN)) { return; } // create plane from triangle dReal plDistance = -dDOT(v0,m_vN); dVector4 plTrianglePlane; CONSTRUCTPLANE(plTrianglePlane,m_vN,plDistance); // calculate capsule distance to plane dReal fDistanceCapsuleCenterToPlane = POINTDISTANCE(plTrianglePlane,m_vCapsulePosition); // Capsule must be over positive side of triangle if (fDistanceCapsuleCenterToPlane < 0 /* && !bDoubleSided*/) { // if not don't generate contacts return; } dVector3 vPnt0; SET (vPnt0,v0); dVector3 vPnt1; SET (vPnt1,v1); dVector3 vPnt2; SET (vPnt2,v2); if (fDistanceCapsuleCenterToPlane < 0 ) { SET (vPnt0,v0); SET (vPnt1,v2); SET (vPnt2,v1); } // do intersection test and find best separating axis if (!_cldTestSeparatingAxesOfCapsule(vPnt0, vPnt1, vPnt2, flags)) { // if not found do nothing return; } // if best separation axis is not found if (m_iBestAxis == 0 ) { // this should not happen (we should already exit in that case) dIASSERT(FALSE); // do nothing return; } // calculate caps centers in absolute space dVector3 vCposTrans; vCposTrans[0] = m_vCapsulePosition[0] + m_vNormal[0]*m_vCapsuleRadius; vCposTrans[1] = m_vCapsulePosition[1] + m_vNormal[1]*m_vCapsuleRadius; vCposTrans[2] = m_vCapsulePosition[2] + m_vNormal[2]*m_vCapsuleRadius; dVector3 vCEdgePoint0; vCEdgePoint0[0] = vCposTrans[0] + m_vCapsuleAxis[0]*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius); vCEdgePoint0[1] = vCposTrans[1] + m_vCapsuleAxis[1]*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius); vCEdgePoint0[2] = vCposTrans[2] + m_vCapsuleAxis[2]*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius); dVector3 vCEdgePoint1; vCEdgePoint1[0] = vCposTrans[0] - m_vCapsuleAxis[0]*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius); vCEdgePoint1[1] = vCposTrans[1] - m_vCapsuleAxis[1]*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius); vCEdgePoint1[2] = vCposTrans[2] - m_vCapsuleAxis[2]*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius); // transform capsule edge points into triangle space vCEdgePoint0[0] -= vPnt0[0]; vCEdgePoint0[1] -= vPnt0[1]; vCEdgePoint0[2] -= vPnt0[2]; vCEdgePoint1[0] -= vPnt0[0]; vCEdgePoint1[1] -= vPnt0[1]; vCEdgePoint1[2] -= vPnt0[2]; dVector4 plPlane; dVector3 _minus_vN; _minus_vN[0] = -m_vN[0]; _minus_vN[1] = -m_vN[1]; _minus_vN[2] = -m_vN[2]; // triangle plane CONSTRUCTPLANE(plPlane,_minus_vN,0); //plPlane = Plane4f( -m_vN, 0); if (!_cldClipEdgeToPlane( vCEdgePoint0, vCEdgePoint1, plPlane )) { return; } // plane with edge 0 dVector3 vTemp; dCROSS(vTemp,=,m_vN,m_vE0); CONSTRUCTPLANE(plPlane, vTemp, REAL(1e-5)); if (!_cldClipEdgeToPlane( vCEdgePoint0, vCEdgePoint1, plPlane )) { return; } dCROSS(vTemp,=,m_vN,m_vE1); CONSTRUCTPLANE(plPlane, vTemp, -(dDOT(m_vE0,vTemp)-REAL(1e-5))); if (!_cldClipEdgeToPlane( vCEdgePoint0, vCEdgePoint1, plPlane )) { return; } dCROSS(vTemp,=,m_vN,m_vE2); CONSTRUCTPLANE(plPlane, vTemp, REAL(1e-5)); if (!_cldClipEdgeToPlane( vCEdgePoint0, vCEdgePoint1, plPlane )) { return; } // return capsule edge points into absolute space vCEdgePoint0[0] += vPnt0[0]; vCEdgePoint0[1] += vPnt0[1]; vCEdgePoint0[2] += vPnt0[2]; vCEdgePoint1[0] += vPnt0[0]; vCEdgePoint1[1] += vPnt0[1]; vCEdgePoint1[2] += vPnt0[2]; // calculate depths for both contact points SUBTRACT(vCEdgePoint0,m_vCapsulePosition,vTemp); dReal fDepth0 = dDOT(vTemp,m_vNormal) - (m_fBestCenter-m_fBestrt); SUBTRACT(vCEdgePoint1,m_vCapsulePosition,vTemp); dReal fDepth1 = dDOT(vTemp,m_vNormal) - (m_fBestCenter-m_fBestrt); // clamp depths to zero if (fDepth0 < 0) { fDepth0 = 0.0f; } if (fDepth1 < 0 ) { fDepth1 = 0.0f; } // Cached contacts's data // contact 0 dIASSERT(m_ctContacts < (m_iFlags & NUMC_MASK)); // Do not call function if there is no room to store result m_gLocalContacts[m_ctContacts].fDepth = fDepth0; SET(m_gLocalContacts[m_ctContacts].vNormal,m_vNormal); SET(m_gLocalContacts[m_ctContacts].vPos,vCEdgePoint0); m_gLocalContacts[m_ctContacts].nFlags = 1; m_ctContacts++; if (m_ctContacts < (m_iFlags & NUMC_MASK)) { // contact 1 m_gLocalContacts[m_ctContacts].fDepth = fDepth1; SET(m_gLocalContacts[m_ctContacts].vNormal,m_vNormal); SET(m_gLocalContacts[m_ctContacts].vPos,vCEdgePoint1); m_gLocalContacts[m_ctContacts].nFlags = 1; m_ctContacts++; } } void sTrimeshCapsuleColliderData::SetupInitialContext(dxTriMesh *TriMesh, dxGeom *Capsule, int flags, int skip) { const dMatrix3* pRot = (const dMatrix3*)dGeomGetRotation(Capsule); memcpy(m_mCapsuleRotation, pRot, sizeof(dMatrix3)); const dVector3* pDst = (const dVector3*)dGeomGetPosition(Capsule); memcpy(m_vCapsulePosition, pDst, sizeof(dVector3)); m_vCapsuleAxis[0] = m_mCapsuleRotation[0*4 + nCAPSULE_AXIS]; m_vCapsuleAxis[1] = m_mCapsuleRotation[1*4 + nCAPSULE_AXIS]; m_vCapsuleAxis[2] = m_mCapsuleRotation[2*4 + nCAPSULE_AXIS]; // Get size of Capsule dGeomCapsuleGetParams(Capsule, &m_vCapsuleRadius, &m_fCapsuleSize); m_fCapsuleSize += 2*m_vCapsuleRadius; const dMatrix3* pTriRot = (const dMatrix3*)dGeomGetRotation(TriMesh); memcpy(m_mTriMeshRot, pTriRot, sizeof(dMatrix3)); const dVector3* pTriPos = (const dVector3*)dGeomGetPosition(TriMesh); memcpy(m_mTriMeshPos, pTriPos, sizeof(dVector3)); // global info for contact creation m_iStride =skip; m_iFlags =flags; // reset contact counter m_ctContacts = 0; // reset best depth m_fBestDepth = - MAX_REAL; m_fBestCenter = 0; m_fBestrt = 0; // reset collision normal m_vNormal[0] = REAL(0.0); m_vNormal[1] = REAL(0.0); m_vNormal[2] = REAL(0.0); } int sTrimeshCapsuleColliderData::TestCollisionForSingleTriangle(int ctContacts0, int Triint, dVector3 dv[3], uint8 flags, bool &bOutFinishSearching) { // test this triangle _cldTestOneTriangleVSCapsule(dv[0],dv[1],dv[2], flags); // fill-in tri index for generated contacts for (; ctContacts0 < (int)m_ctContacts; ctContacts0++) m_gLocalContacts[ctContacts0].triIndex = Triint; // Putting "break" at the end of loop prevents unnecessary checks on first pass and "continue" bOutFinishSearching = (m_ctContacts >= (m_iFlags & NUMC_MASK)); return ctContacts0; } static void dQueryCCTLPotentialCollisionTriangles(OBBCollider &Collider, const sTrimeshCapsuleColliderData &cData, dxTriMesh *TriMesh, dxGeom *Capsule, OBBCache &BoxCache) { // It is a potential issue to explicitly cast to float // if custom width floating point type is introduced in OPCODE. // It is necessary to make a typedef and cast to it // (e.g. typedef float opc_float;) // However I'm not sure in what header it should be added. const dVector3 &vCapsulePosition = cData.m_vCapsulePosition; Point cCenter(/*(float)*/ vCapsulePosition[0], /*(float)*/ vCapsulePosition[1], /*(float)*/ vCapsulePosition[2]); Point cExtents(/*(float)*/ cData.m_vCapsuleRadius, /*(float)*/ cData.m_vCapsuleRadius,/*(float)*/ cData.m_fCapsuleSize/2); Matrix3x3 obbRot; const dMatrix3 &mCapsuleRotation = cData.m_mCapsuleRotation; obbRot[0][0] = /*(float)*/ mCapsuleRotation[0]; obbRot[1][0] = /*(float)*/ mCapsuleRotation[1]; obbRot[2][0] = /*(float)*/ mCapsuleRotation[2]; obbRot[0][1] = /*(float)*/ mCapsuleRotation[4]; obbRot[1][1] = /*(float)*/ mCapsuleRotation[5]; obbRot[2][1] = /*(float)*/ mCapsuleRotation[6]; obbRot[0][2] = /*(float)*/ mCapsuleRotation[8]; obbRot[1][2] = /*(float)*/ mCapsuleRotation[9]; obbRot[2][2] = /*(float)*/ mCapsuleRotation[10]; OBB obbCapsule(cCenter,cExtents,obbRot); Matrix4x4 CapsuleMatrix; MakeMatrix(vCapsulePosition, mCapsuleRotation, CapsuleMatrix); Matrix4x4 MeshMatrix; MakeMatrix(cData.m_mTriMeshPos, cData.m_mTriMeshRot, MeshMatrix); // TC results if (TriMesh->doBoxTC) { dxTriMesh::BoxTC* BoxTC = 0; for (int i = 0; i < TriMesh->BoxTCCache.size(); i++){ if (TriMesh->BoxTCCache[i].Geom == Capsule){ BoxTC = &TriMesh->BoxTCCache[i]; break; } } if (!BoxTC){ TriMesh->BoxTCCache.push(dxTriMesh::BoxTC()); BoxTC = &TriMesh->BoxTCCache[TriMesh->BoxTCCache.size() - 1]; BoxTC->Geom = Capsule; BoxTC->FatCoeff = 1.0f; } // Intersect Collider.SetTemporalCoherence(true); Collider.Collide(*BoxTC, obbCapsule, TriMesh->Data->BVTree, null, &MeshMatrix); } else { Collider.SetTemporalCoherence(false); Collider.Collide(BoxCache, obbCapsule, TriMesh->Data->BVTree, null,&MeshMatrix); } } // capsule - trimesh by CroTeam // Ported by Nguyem Binh int dCollideCCTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT (o1->type == dTriMeshClass); dIASSERT (o2->type == dCapsuleClass); dIASSERT ((flags & NUMC_MASK) >= 1); int nContactCount = 0; dxTriMesh *TriMesh = (dxTriMesh*)o1; dxGeom *Capsule = o2; sTrimeshCapsuleColliderData cData; cData.SetupInitialContext(TriMesh, Capsule, flags, skip); const unsigned uiTLSKind = TriMesh->getParentSpaceTLSKind(); dIASSERT(uiTLSKind == Capsule->getParentSpaceTLSKind()); // The colliding spaces must use matching cleanup method TrimeshCollidersCache *pccColliderCache = GetTrimeshCollidersCache(uiTLSKind); OBBCollider& Collider = pccColliderCache->_OBBCollider; // Will it better to use LSS here? -> confirm Pierre. dQueryCCTLPotentialCollisionTriangles(Collider, cData, TriMesh, Capsule, pccColliderCache->defaultBoxCache); if (Collider.GetContactStatus()) { // Retrieve data int TriCount = Collider.GetNbTouchedPrimitives(); if (TriCount != 0) { const int* Triangles = (const int*)Collider.GetTouchedPrimitives(); if (TriMesh->ArrayCallback != null) { TriMesh->ArrayCallback(TriMesh, Capsule, Triangles, TriCount); } // allocate buffer for local contacts on stack cData.m_gLocalContacts = (sLocalContactData*)dALLOCA16(sizeof(sLocalContactData)*(cData.m_iFlags & NUMC_MASK)); unsigned int ctContacts0 = cData.m_ctContacts; uint8* UseFlags = TriMesh->Data->UseFlags; // loop through all intersecting triangles for (int i = 0; i < TriCount; i++) { const int Triint = Triangles[i]; if (!Callback(TriMesh, Capsule, Triint)) continue; dVector3 dv[3]; FetchTriangle(TriMesh, Triint, cData.m_mTriMeshPos, cData.m_mTriMeshRot, dv); uint8 flags = UseFlags ? UseFlags[Triint] : dxTriMeshData::kUseAll; bool bFinishSearching; ctContacts0 = cData.TestCollisionForSingleTriangle(ctContacts0, Triint, dv, flags, bFinishSearching); if (bFinishSearching) { break; } } if (cData.m_ctContacts != 0) { nContactCount = cData._ProcessLocalContacts(contact, TriMesh, Capsule); } } } return nContactCount; } #endif // GIMPACT version #if dTRIMESH_GIMPACT #define nCAPSULE_AXIS 2 // capsule - trimesh By francisco leon int dCollideCCTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT (o1->type == dTriMeshClass); dIASSERT (o2->type == dCapsuleClass); dIASSERT ((flags & NUMC_MASK) >= 1); dxTriMesh* TriMesh = (dxTriMesh*)o1; dxGeom* gCylinder = o2; //Get capsule params dMatrix3 mCapsuleRotation; dVector3 vCapsulePosition; dVector3 vCapsuleAxis; dReal vCapsuleRadius; dReal fCapsuleSize; dMatrix3* pRot = (dMatrix3*) dGeomGetRotation(gCylinder); memcpy(mCapsuleRotation,pRot,sizeof(dMatrix3)); dVector3* pDst = (dVector3*)dGeomGetPosition(gCylinder); memcpy(vCapsulePosition,pDst,sizeof(dVector3)); //Axis vCapsuleAxis[0] = mCapsuleRotation[0*4 + nCAPSULE_AXIS]; vCapsuleAxis[1] = mCapsuleRotation[1*4 + nCAPSULE_AXIS]; vCapsuleAxis[2] = mCapsuleRotation[2*4 + nCAPSULE_AXIS]; // Get size of CCylinder dGeomCCylinderGetParams(gCylinder,&vCapsuleRadius,&fCapsuleSize); fCapsuleSize*=0.5f; //Set Capsule params GIM_CAPSULE_DATA capsule; capsule.m_radius = vCapsuleRadius; VEC_SCALE(capsule.m_point1,fCapsuleSize,vCapsuleAxis); VEC_SUM(capsule.m_point1,vCapsulePosition,capsule.m_point1); VEC_SCALE(capsule.m_point2,-fCapsuleSize,vCapsuleAxis); VEC_SUM(capsule.m_point2,vCapsulePosition,capsule.m_point2); //Create contact list GDYNAMIC_ARRAY trimeshcontacts; GIM_CREATE_CONTACT_LIST(trimeshcontacts); //Collide trimeshe vs capsule gim_trimesh_capsule_collision(&TriMesh->m_collision_trimesh,&capsule,&trimeshcontacts); if(trimeshcontacts.m_size == 0) { GIM_DYNARRAY_DESTROY(trimeshcontacts); return 0; } GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts); unsigned contactcount = trimeshcontacts.m_size; unsigned contactmax = (unsigned)(flags & NUMC_MASK); if (contactcount > contactmax) { contactcount = contactmax; } dContactGeom* pcontact; unsigned i; for (i=0;ipos[0] = ptrimeshcontacts->m_point[0]; pcontact->pos[1] = ptrimeshcontacts->m_point[1]; pcontact->pos[2] = ptrimeshcontacts->m_point[2]; pcontact->pos[3] = 1.0f; pcontact->normal[0] = ptrimeshcontacts->m_normal[0]; pcontact->normal[1] = ptrimeshcontacts->m_normal[1]; pcontact->normal[2] = ptrimeshcontacts->m_normal[2]; pcontact->normal[3] = 0; pcontact->depth = ptrimeshcontacts->m_depth; pcontact->g1 = TriMesh; pcontact->g2 = gCylinder; pcontact->side1 = ptrimeshcontacts->m_feature1; pcontact->side2 = -1; ptrimeshcontacts++; } GIM_DYNARRAY_DESTROY(trimeshcontacts); return (int)contactcount; } #endif #endif // dTRIMESH_ENABLED alien-arena-7.66+dfsg/source/unix/odesrc/collision_cylinder_box.cpp0000600000175000017500000006634212161402010024617 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* * Cylinder-box collider by Alen Ladavac * Ported to ODE by Nguyen Binh */ #include #include #include #include #include "collision_util.h" static const int MAX_CYLBOX_CLIP_POINTS = 16; static const int nCYLINDER_AXIS = 2; // Number of segment of cylinder base circle. // Must be divisible by 4. static const int nCYLINDER_SEGMENT = 8; #define MAX_FLOAT dInfinity // Data that passed through the collider's functions struct sCylinderBoxData { sCylinderBoxData(dxGeom *Cylinder, dxGeom *Box, int flags, dContactGeom *contact, int skip): m_gBox(Box), m_gCylinder(Cylinder), m_gContact(contact), m_iFlags(flags), m_iSkip(skip), m_nContacts(0) { } void _cldInitCylinderBox(); int _cldTestAxis( dVector3& vInputNormal, int iAxis ); int _cldTestEdgeCircleAxis( const dVector3 &vCenterPoint, const dVector3 &vVx0, const dVector3 &vVx1, int iAxis ); int _cldTestSeparatingAxes(); int _cldClipCylinderToBox(); void _cldClipBoxToCylinder(); int PerformCollisionChecking(); // cylinder parameters dMatrix3 m_mCylinderRot; dVector3 m_vCylinderPos; dVector3 m_vCylinderAxis; dReal m_fCylinderRadius; dReal m_fCylinderSize; dVector3 m_avCylinderNormals[nCYLINDER_SEGMENT]; // box parameters dMatrix3 m_mBoxRot; dVector3 m_vBoxPos; dVector3 m_vBoxHalfSize; // box vertices array : 8 vertices dVector3 m_avBoxVertices[8]; // global collider data dVector3 m_vDiff; dVector3 m_vNormal; dReal m_fBestDepth; dReal m_fBestrb; dReal m_fBestrc; int m_iBestAxis; // contact data dVector3 m_vEp0, m_vEp1; dReal m_fDepth0, m_fDepth1; // ODE stuff dGeomID m_gBox; dGeomID m_gCylinder; dContactGeom* m_gContact; int m_iFlags; int m_iSkip; int m_nContacts; }; // initialize collision data void sCylinderBoxData::_cldInitCylinderBox() { // get cylinder position, orientation const dReal* pRotCyc = dGeomGetRotation(m_gCylinder); dMatrix3Copy(pRotCyc,m_mCylinderRot); const dVector3* pPosCyc = (const dVector3*)dGeomGetPosition(m_gCylinder); dVector3Copy(*pPosCyc,m_vCylinderPos); dMat3GetCol(m_mCylinderRot,nCYLINDER_AXIS,m_vCylinderAxis); // get cylinder radius and size dGeomCylinderGetParams(m_gCylinder,&m_fCylinderRadius,&m_fCylinderSize); // get box position, orientation, size const dReal* pRotBox = dGeomGetRotation(m_gBox); dMatrix3Copy(pRotBox,m_mBoxRot); const dVector3* pPosBox = (const dVector3*)dGeomGetPosition(m_gBox); dVector3Copy(*pPosBox,m_vBoxPos); dGeomBoxGetLengths(m_gBox, m_vBoxHalfSize); m_vBoxHalfSize[0] *= REAL(0.5); m_vBoxHalfSize[1] *= REAL(0.5); m_vBoxHalfSize[2] *= REAL(0.5); // vertex 0 m_avBoxVertices[0][0] = -m_vBoxHalfSize[0]; m_avBoxVertices[0][1] = m_vBoxHalfSize[1]; m_avBoxVertices[0][2] = -m_vBoxHalfSize[2]; // vertex 1 m_avBoxVertices[1][0] = m_vBoxHalfSize[0]; m_avBoxVertices[1][1] = m_vBoxHalfSize[1]; m_avBoxVertices[1][2] = -m_vBoxHalfSize[2]; // vertex 2 m_avBoxVertices[2][0] = -m_vBoxHalfSize[0]; m_avBoxVertices[2][1] = -m_vBoxHalfSize[1]; m_avBoxVertices[2][2] = -m_vBoxHalfSize[2]; // vertex 3 m_avBoxVertices[3][0] = m_vBoxHalfSize[0]; m_avBoxVertices[3][1] = -m_vBoxHalfSize[1]; m_avBoxVertices[3][2] = -m_vBoxHalfSize[2]; // vertex 4 m_avBoxVertices[4][0] = m_vBoxHalfSize[0]; m_avBoxVertices[4][1] = m_vBoxHalfSize[1]; m_avBoxVertices[4][2] = m_vBoxHalfSize[2]; // vertex 5 m_avBoxVertices[5][0] = m_vBoxHalfSize[0]; m_avBoxVertices[5][1] = -m_vBoxHalfSize[1]; m_avBoxVertices[5][2] = m_vBoxHalfSize[2]; // vertex 6 m_avBoxVertices[6][0] = -m_vBoxHalfSize[0]; m_avBoxVertices[6][1] = -m_vBoxHalfSize[1]; m_avBoxVertices[6][2] = m_vBoxHalfSize[2]; // vertex 7 m_avBoxVertices[7][0] = -m_vBoxHalfSize[0]; m_avBoxVertices[7][1] = m_vBoxHalfSize[1]; m_avBoxVertices[7][2] = m_vBoxHalfSize[2]; // temp index int i = 0; dVector3 vTempBoxVertices[8]; // transform vertices in absolute space for(i=0; i < 8; i++) { dMultiplyMat3Vec3(m_mBoxRot,m_avBoxVertices[i], vTempBoxVertices[i]); dVector3Add(vTempBoxVertices[i], m_vBoxPos, m_avBoxVertices[i]); } // find relative position dVector3Subtract(m_vCylinderPos,m_vBoxPos,m_vDiff); m_fBestDepth = MAX_FLOAT; m_vNormal[0] = REAL(0.0); m_vNormal[1] = REAL(0.0); m_vNormal[2] = REAL(0.0); // calculate basic angle for nCYLINDER_SEGMENT-gon dReal fAngle = (dReal) (M_PI/nCYLINDER_SEGMENT); // calculate angle increment dReal fAngleIncrement = fAngle * REAL(2.0); // calculate nCYLINDER_SEGMENT-gon points for(i = 0; i < nCYLINDER_SEGMENT; i++) { m_avCylinderNormals[i][0] = -dCos(fAngle); m_avCylinderNormals[i][1] = -dSin(fAngle); m_avCylinderNormals[i][2] = 0; fAngle += fAngleIncrement; } m_fBestrb = 0; m_fBestrc = 0; m_iBestAxis = 0; m_nContacts = 0; } // test for given separating axis int sCylinderBoxData::_cldTestAxis( dVector3& vInputNormal, int iAxis ) { // check length of input normal dReal fL = dVector3Length(vInputNormal); // if not long enough if ( fL < REAL(1e-5) ) { // do nothing return 1; } // otherwise make it unit for sure dNormalize3(vInputNormal); // project box and Cylinder on mAxis dReal fdot1 = dVector3Dot(m_vCylinderAxis, vInputNormal); dReal frc; if (fdot1 > REAL(1.0)) { // assume fdot1 = 1 frc = m_fCylinderSize*REAL(0.5); } else if (fdot1 < REAL(-1.0)) { // assume fdot1 = -1 frc = m_fCylinderSize*REAL(0.5); } else { // project box and capsule on iAxis frc = dFabs( fdot1 * (m_fCylinderSize*REAL(0.5))) + m_fCylinderRadius * dSqrt(REAL(1.0)-(fdot1*fdot1)); } dVector3 vTemp1; dMat3GetCol(m_mBoxRot,0,vTemp1); dReal frb = dFabs(dVector3Dot(vTemp1,vInputNormal))*m_vBoxHalfSize[0]; dMat3GetCol(m_mBoxRot,1,vTemp1); frb += dFabs(dVector3Dot(vTemp1,vInputNormal))*m_vBoxHalfSize[1]; dMat3GetCol(m_mBoxRot,2,vTemp1); frb += dFabs(dVector3Dot(vTemp1,vInputNormal))*m_vBoxHalfSize[2]; // project their distance on separating axis dReal fd = dVector3Dot(m_vDiff,vInputNormal); // get depth dReal fDepth = frc + frb; // Calculate partial depth // if they do not overlap exit, we have no intersection if ( dFabs(fd) > fDepth ) { return 0; } // Finalyze the depth calculation fDepth -= dFabs(fd); // get maximum depth if ( fDepth < m_fBestDepth ) { m_fBestDepth = fDepth; dVector3Copy(vInputNormal,m_vNormal); m_iBestAxis = iAxis; m_fBestrb = frb; m_fBestrc = frc; // flip normal if interval is wrong faced if (fd > 0) { dVector3Inv(m_vNormal); } } return 1; } // check for separation between box edge and cylinder circle edge int sCylinderBoxData::_cldTestEdgeCircleAxis( const dVector3 &vCenterPoint, const dVector3 &vVx0, const dVector3 &vVx1, int iAxis ) { // calculate direction of edge dVector3 vDirEdge; dVector3Subtract(vVx1,vVx0,vDirEdge); dNormalize3(vDirEdge); // starting point of edge dVector3 vEStart; dVector3Copy(vVx0,vEStart);; // calculate angle cosine between cylinder axis and edge dReal fdot2 = dVector3Dot (vDirEdge,m_vCylinderAxis); // if edge is perpendicular to cylinder axis if(dFabs(fdot2) < REAL(1e-5)) { // this can't be separating axis, because edge is parallel to circle plane return 1; } // find point of intersection between edge line and circle plane dVector3 vTemp1; dVector3Subtract(vCenterPoint,vEStart,vTemp1); dReal fdot1 = dVector3Dot(vTemp1,m_vCylinderAxis); dVector3 vpnt; vpnt[0]= vEStart[0] + vDirEdge[0] * (fdot1/fdot2); vpnt[1]= vEStart[1] + vDirEdge[1] * (fdot1/fdot2); vpnt[2]= vEStart[2] + vDirEdge[2] * (fdot1/fdot2); // find tangent vector on circle with same center (vCenterPoint) that // touches point of intersection (vpnt) dVector3 vTangent; dVector3Subtract(vCenterPoint,vpnt,vTemp1); dVector3Cross(vTemp1,m_vCylinderAxis,vTangent); // find vector orthogonal both to tangent and edge direction dVector3 vAxis; dVector3Cross(vTangent,vDirEdge,vAxis); // use that vector as separating axis return _cldTestAxis( vAxis, iAxis ); } // Test separating axis for collision int sCylinderBoxData::_cldTestSeparatingAxes() { // reset best axis m_fBestDepth = MAX_FLOAT; m_iBestAxis = 0; m_fBestrb = 0; m_fBestrc = 0; m_nContacts = 0; dVector3 vAxis = {REAL(0.0),REAL(0.0),REAL(0.0),REAL(0.0)}; // Epsilon value for checking axis vector length const dReal fEpsilon = REAL(1e-6); // axis A0 dMat3GetCol(m_mBoxRot, 0 , vAxis); if (!_cldTestAxis( vAxis, 1 )) { return 0; } // axis A1 dMat3GetCol(m_mBoxRot, 1 , vAxis); if (!_cldTestAxis( vAxis, 2 )) { return 0; } // axis A2 dMat3GetCol(m_mBoxRot, 2 , vAxis); if (!_cldTestAxis( vAxis, 3 )) { return 0; } // axis C - Cylinder Axis //vAxis = vCylinderAxis; dVector3Copy(m_vCylinderAxis , vAxis); if (!_cldTestAxis( vAxis, 4 )) { return 0; } // axis CxA0 //vAxis = ( vCylinderAxis cross mthGetColM33f( mBoxRot, 0 )); dVector3CrossMat3Col(m_mBoxRot, 0 ,m_vCylinderAxis, vAxis); if(dVector3Length2( vAxis ) > fEpsilon ) { if (!_cldTestAxis( vAxis, 5 )) { return 0; } } // axis CxA1 //vAxis = ( vCylinderAxis cross mthGetColM33f( mBoxRot, 1 )); dVector3CrossMat3Col(m_mBoxRot, 1 ,m_vCylinderAxis, vAxis); if(dVector3Length2( vAxis ) > fEpsilon ) { if (!_cldTestAxis( vAxis, 6 )) { return 0; } } // axis CxA2 //vAxis = ( vCylinderAxis cross mthGetColM33f( mBoxRot, 2 )); dVector3CrossMat3Col(m_mBoxRot, 2 ,m_vCylinderAxis, vAxis); if(dVector3Length2( vAxis ) > fEpsilon ) { if (!_cldTestAxis( vAxis, 7 )) { return 0; } } int i = 0; dVector3 vTemp1; dVector3 vTemp2; // here we check box's vertices axis for(i=0; i< 8; i++) { //vAxis = ( vCylinderAxis cross (m_avBoxVertices[i] - vCylinderPos)); dVector3Subtract(m_avBoxVertices[i],m_vCylinderPos,vTemp1); dVector3Cross(m_vCylinderAxis,vTemp1,vTemp2); //vAxis = ( vCylinderAxis cross vAxis ); dVector3Cross(m_vCylinderAxis,vTemp2,vAxis); if(dVector3Length2( vAxis ) > fEpsilon ) { if (!_cldTestAxis( vAxis, 8 + i )) { return 0; } } } // ************************************ // this is defined for first 12 axes // normal of plane that contains top circle of cylinder // center of top circle of cylinder dVector3 vcc; vcc[0] = (m_vCylinderPos)[0] + m_vCylinderAxis[0]*(m_fCylinderSize*REAL(0.5)); vcc[1] = (m_vCylinderPos)[1] + m_vCylinderAxis[1]*(m_fCylinderSize*REAL(0.5)); vcc[2] = (m_vCylinderPos)[2] + m_vCylinderAxis[2]*(m_fCylinderSize*REAL(0.5)); // ************************************ if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[1], m_avBoxVertices[0], 16)) { return 0; } if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[1], m_avBoxVertices[3], 17)) { return 0; } if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[2], m_avBoxVertices[3], 18)) { return 0; } if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[2], m_avBoxVertices[0], 19)) { return 0; } if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[4], m_avBoxVertices[1], 20)) { return 0; } if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[4], m_avBoxVertices[7], 21)) { return 0; } if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[0], m_avBoxVertices[7], 22)) { return 0; } if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[5], m_avBoxVertices[3], 23)) { return 0; } if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[5], m_avBoxVertices[6], 24)) { return 0; } if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[2], m_avBoxVertices[6], 25)) { return 0; } if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[4], m_avBoxVertices[5], 26)) { return 0; } if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[6], m_avBoxVertices[7], 27)) { return 0; } // ************************************ // this is defined for second 12 axes // normal of plane that contains bottom circle of cylinder // center of bottom circle of cylinder // vcc = vCylinderPos - vCylinderAxis*(fCylinderSize*REAL(0.5)); vcc[0] = (m_vCylinderPos)[0] - m_vCylinderAxis[0]*(m_fCylinderSize*REAL(0.5)); vcc[1] = (m_vCylinderPos)[1] - m_vCylinderAxis[1]*(m_fCylinderSize*REAL(0.5)); vcc[2] = (m_vCylinderPos)[2] - m_vCylinderAxis[2]*(m_fCylinderSize*REAL(0.5)); // ************************************ if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[1], m_avBoxVertices[0], 28)) { return 0; } if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[1], m_avBoxVertices[3], 29)) { return 0; } if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[2], m_avBoxVertices[3], 30)) { return 0; } if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[2], m_avBoxVertices[0], 31)) { return 0; } if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[4], m_avBoxVertices[1], 32)) { return 0; } if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[4], m_avBoxVertices[7], 33)) { return 0; } if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[0], m_avBoxVertices[7], 34)) { return 0; } if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[5], m_avBoxVertices[3], 35)) { return 0; } if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[5], m_avBoxVertices[6], 36)) { return 0; } if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[2], m_avBoxVertices[6], 37)) { return 0; } if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[4], m_avBoxVertices[5], 38)) { return 0; } if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[6], m_avBoxVertices[7], 39)) { return 0; } return 1; } int sCylinderBoxData::_cldClipCylinderToBox() { dIASSERT(m_nContacts != (m_iFlags & NUMC_MASK)); // calculate that vector perpendicular to cylinder axis which closes lowest angle with collision normal dVector3 vN; dReal fTemp1 = dVector3Dot(m_vCylinderAxis,m_vNormal); vN[0] = m_vNormal[0] - m_vCylinderAxis[0]*fTemp1; vN[1] = m_vNormal[1] - m_vCylinderAxis[1]*fTemp1; vN[2] = m_vNormal[2] - m_vCylinderAxis[2]*fTemp1; // normalize that vector dNormalize3(vN); // translate cylinder end points by the vector dVector3 vCposTrans; vCposTrans[0] = m_vCylinderPos[0] + vN[0] * m_fCylinderRadius; vCposTrans[1] = m_vCylinderPos[1] + vN[1] * m_fCylinderRadius; vCposTrans[2] = m_vCylinderPos[2] + vN[2] * m_fCylinderRadius; m_vEp0[0] = vCposTrans[0] + m_vCylinderAxis[0]*(m_fCylinderSize*REAL(0.5)); m_vEp0[1] = vCposTrans[1] + m_vCylinderAxis[1]*(m_fCylinderSize*REAL(0.5)); m_vEp0[2] = vCposTrans[2] + m_vCylinderAxis[2]*(m_fCylinderSize*REAL(0.5)); m_vEp1[0] = vCposTrans[0] - m_vCylinderAxis[0]*(m_fCylinderSize*REAL(0.5)); m_vEp1[1] = vCposTrans[1] - m_vCylinderAxis[1]*(m_fCylinderSize*REAL(0.5)); m_vEp1[2] = vCposTrans[2] - m_vCylinderAxis[2]*(m_fCylinderSize*REAL(0.5)); // transform edge points in box space m_vEp0[0] -= m_vBoxPos[0]; m_vEp0[1] -= m_vBoxPos[1]; m_vEp0[2] -= m_vBoxPos[2]; m_vEp1[0] -= m_vBoxPos[0]; m_vEp1[1] -= m_vBoxPos[1]; m_vEp1[2] -= m_vBoxPos[2]; dVector3 vTemp1; // clip the edge to box dVector4 plPlane; // plane 0 +x dMat3GetCol(m_mBoxRot,0,vTemp1); dConstructPlane(vTemp1,m_vBoxHalfSize[0],plPlane); if(!dClipEdgeToPlane( m_vEp0, m_vEp1, plPlane )) { return 0; } // plane 1 +y dMat3GetCol(m_mBoxRot,1,vTemp1); dConstructPlane(vTemp1,m_vBoxHalfSize[1],plPlane); if(!dClipEdgeToPlane( m_vEp0, m_vEp1, plPlane )) { return 0; } // plane 2 +z dMat3GetCol(m_mBoxRot,2,vTemp1); dConstructPlane(vTemp1,m_vBoxHalfSize[2],plPlane); if(!dClipEdgeToPlane( m_vEp0, m_vEp1, plPlane )) { return 0; } // plane 3 -x dMat3GetCol(m_mBoxRot,0,vTemp1); dVector3Inv(vTemp1); dConstructPlane(vTemp1,m_vBoxHalfSize[0],plPlane); if(!dClipEdgeToPlane( m_vEp0, m_vEp1, plPlane )) { return 0; } // plane 4 -y dMat3GetCol(m_mBoxRot,1,vTemp1); dVector3Inv(vTemp1); dConstructPlane(vTemp1,m_vBoxHalfSize[1],plPlane); if(!dClipEdgeToPlane( m_vEp0, m_vEp1, plPlane )) { return 0; } // plane 5 -z dMat3GetCol(m_mBoxRot,2,vTemp1); dVector3Inv(vTemp1); dConstructPlane(vTemp1,m_vBoxHalfSize[2],plPlane); if(!dClipEdgeToPlane( m_vEp0, m_vEp1, plPlane )) { return 0; } // calculate depths for both contact points m_fDepth0 = m_fBestrb + dVector3Dot(m_vEp0, m_vNormal); m_fDepth1 = m_fBestrb + dVector3Dot(m_vEp1, m_vNormal); // clamp depths to 0 if(m_fDepth0<0) { m_fDepth0 = REAL(0.0); } if(m_fDepth1<0) { m_fDepth1 = REAL(0.0); } // back transform edge points from box to absolute space m_vEp0[0] += m_vBoxPos[0]; m_vEp0[1] += m_vBoxPos[1]; m_vEp0[2] += m_vBoxPos[2]; m_vEp1[0] += m_vBoxPos[0]; m_vEp1[1] += m_vBoxPos[1]; m_vEp1[2] += m_vBoxPos[2]; dContactGeom* Contact0 = SAFECONTACT(m_iFlags, m_gContact, m_nContacts, m_iSkip); Contact0->depth = m_fDepth0; dVector3Copy(m_vNormal,Contact0->normal); dVector3Copy(m_vEp0,Contact0->pos); Contact0->g1 = m_gCylinder; Contact0->g2 = m_gBox; Contact0->side1 = -1; Contact0->side2 = -1; dVector3Inv(Contact0->normal); m_nContacts++; if (m_nContacts != (m_iFlags & NUMC_MASK)) { dContactGeom* Contact1 = SAFECONTACT(m_iFlags, m_gContact, m_nContacts, m_iSkip); Contact1->depth = m_fDepth1; dVector3Copy(m_vNormal,Contact1->normal); dVector3Copy(m_vEp1,Contact1->pos); Contact1->g1 = m_gCylinder; Contact1->g2 = m_gBox; Contact1->side1 = -1; Contact1->side2 = -1; dVector3Inv(Contact1->normal); m_nContacts++; } return 1; } void sCylinderBoxData::_cldClipBoxToCylinder() { dIASSERT(m_nContacts != (m_iFlags & NUMC_MASK)); dVector3 vCylinderCirclePos, vCylinderCircleNormal_Rel; // check which circle from cylinder we take for clipping if ( dVector3Dot(m_vCylinderAxis, m_vNormal) > REAL(0.0) ) { // get top circle vCylinderCirclePos[0] = m_vCylinderPos[0] + m_vCylinderAxis[0]*(m_fCylinderSize*REAL(0.5)); vCylinderCirclePos[1] = m_vCylinderPos[1] + m_vCylinderAxis[1]*(m_fCylinderSize*REAL(0.5)); vCylinderCirclePos[2] = m_vCylinderPos[2] + m_vCylinderAxis[2]*(m_fCylinderSize*REAL(0.5)); vCylinderCircleNormal_Rel[0] = REAL(0.0); vCylinderCircleNormal_Rel[1] = REAL(0.0); vCylinderCircleNormal_Rel[2] = REAL(0.0); vCylinderCircleNormal_Rel[nCYLINDER_AXIS] = REAL(-1.0); } else { // get bottom circle vCylinderCirclePos[0] = m_vCylinderPos[0] - m_vCylinderAxis[0]*(m_fCylinderSize*REAL(0.5)); vCylinderCirclePos[1] = m_vCylinderPos[1] - m_vCylinderAxis[1]*(m_fCylinderSize*REAL(0.5)); vCylinderCirclePos[2] = m_vCylinderPos[2] - m_vCylinderAxis[2]*(m_fCylinderSize*REAL(0.5)); vCylinderCircleNormal_Rel[0] = REAL(0.0); vCylinderCircleNormal_Rel[1] = REAL(0.0); vCylinderCircleNormal_Rel[2] = REAL(0.0); vCylinderCircleNormal_Rel[nCYLINDER_AXIS] = REAL(1.0); } // vNr is normal in Box frame, pointing from Cylinder to Box dVector3 vNr; dMatrix3 mBoxInv; // Find a way to use quaternion dMatrix3Inv(m_mBoxRot,mBoxInv); dMultiplyMat3Vec3(mBoxInv,m_vNormal,vNr); dVector3 vAbsNormal; vAbsNormal[0] = dFabs( vNr[0] ); vAbsNormal[1] = dFabs( vNr[1] ); vAbsNormal[2] = dFabs( vNr[2] ); // find which face in box is closest to cylinder int iB0, iB1, iB2; // Different from Croteam's code if (vAbsNormal[1] > vAbsNormal[0]) { // 1 > 0 if (vAbsNormal[0]> vAbsNormal[2]) { // 0 > 2 -> 1 > 0 >2 iB0 = 1; iB1 = 0; iB2 = 2; } else { // 2 > 0-> Must compare 1 and 2 if (vAbsNormal[1] > vAbsNormal[2]) { // 1 > 2 -> 1 > 2 > 0 iB0 = 1; iB1 = 2; iB2 = 0; } else { // 2 > 1 -> 2 > 1 > 0; iB0 = 2; iB1 = 1; iB2 = 0; } } } else { // 0 > 1 if (vAbsNormal[1] > vAbsNormal[2]) { // 1 > 2 -> 0 > 1 > 2 iB0 = 0; iB1 = 1; iB2 = 2; } else { // 2 > 1 -> Must compare 0 and 2 if (vAbsNormal[0] > vAbsNormal[2]) { // 0 > 2 -> 0 > 2 > 1; iB0 = 0; iB1 = 2; iB2 = 1; } else { // 2 > 0 -> 2 > 0 > 1; iB0 = 2; iB1 = 0; iB2 = 1; } } } dVector3 vCenter; // find center of box polygon dVector3 vTemp; if (vNr[iB0] > 0) { dMat3GetCol(m_mBoxRot,iB0,vTemp); vCenter[0] = m_vBoxPos[0] - m_vBoxHalfSize[iB0]*vTemp[0]; vCenter[1] = m_vBoxPos[1] - m_vBoxHalfSize[iB0]*vTemp[1]; vCenter[2] = m_vBoxPos[2] - m_vBoxHalfSize[iB0]*vTemp[2]; } else { dMat3GetCol(m_mBoxRot,iB0,vTemp); vCenter[0] = m_vBoxPos[0] + m_vBoxHalfSize[iB0]*vTemp[0]; vCenter[1] = m_vBoxPos[1] + m_vBoxHalfSize[iB0]*vTemp[1]; vCenter[2] = m_vBoxPos[2] + m_vBoxHalfSize[iB0]*vTemp[2]; } // find the vertices of box polygon dVector3 avPoints[4]; dVector3 avTempArray1[MAX_CYLBOX_CLIP_POINTS]; dVector3 avTempArray2[MAX_CYLBOX_CLIP_POINTS]; int i=0; for(i=0; i= 0 && iTmpCounter1 <= MAX_CYLBOX_CLIP_POINTS ); dIASSERT( iTmpCounter2 >= 0 && iTmpCounter2 <= MAX_CYLBOX_CLIP_POINTS ); } // back transform clipped points to absolute space dReal ftmpdot; dReal fTempDepth; dVector3 vPoint; if (nCircleSegment % 2) { for( i=0; i REAL(0.0)) { // generate contacts dContactGeom* Contact0 = SAFECONTACT(m_iFlags, m_gContact, m_nContacts, m_iSkip); Contact0->depth = fTempDepth; dVector3Copy(m_vNormal,Contact0->normal); dVector3Copy(vPoint,Contact0->pos); Contact0->g1 = m_gCylinder; Contact0->g2 = m_gBox; Contact0->side1 = -1; Contact0->side2 = -1; dVector3Inv(Contact0->normal); m_nContacts++; if (m_nContacts == (m_iFlags & NUMC_MASK)) { break; } } } } else { for( i=0; i REAL(0.0)) { // generate contacts dContactGeom* Contact0 = SAFECONTACT(m_iFlags, m_gContact, m_nContacts, m_iSkip); Contact0->depth = fTempDepth; dVector3Copy(m_vNormal,Contact0->normal); dVector3Copy(vPoint,Contact0->pos); Contact0->g1 = m_gCylinder; Contact0->g2 = m_gBox; Contact0->side1 = -1; Contact0->side2 = -1; dVector3Inv(Contact0->normal); m_nContacts++; if (m_nContacts == (m_iFlags & NUMC_MASK)) { break; } } } } } int sCylinderBoxData::PerformCollisionChecking() { // initialize collider _cldInitCylinderBox(); // do intersection test and find best separating axis if ( !_cldTestSeparatingAxes() ) { // if not found do nothing return 0; } // if best separation axis is not found if ( m_iBestAxis == 0 ) { // this should not happen (we should already exit in that case) dIASSERT(0); // do nothing return 0; } dReal fdot = dVector3Dot(m_vNormal,m_vCylinderAxis); // choose which clipping method are we going to apply if (dFabs(fdot) < REAL(0.9) ) { // clip cylinder over box if(!_cldClipCylinderToBox()) { return 0; } } else { _cldClipBoxToCylinder(); } return m_nContacts; } // Cylinder - Box by CroTeam // Ported by Nguyen Binh int dCollideCylinderBox(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT (o1->type == dCylinderClass); dIASSERT (o2->type == dBoxClass); dIASSERT ((flags & NUMC_MASK) >= 1); sCylinderBoxData cData(o1, o2, flags, contact, skip); return cData.PerformCollisionChecking(); } alien-arena-7.66+dfsg/source/unix/odesrc/odeou.h0000600000175000017500000000521312161402010020631 0ustar zero79zero79/************************************************************************* * * * OU library interface file for Open Dynamics Engine, * * Copyright (C) 2008 Oleh Derevenko. All rights reserved. * * Email: odar@eleks.com (change all "a" to "e") * * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* ODE interface to OU library functions. */ #ifndef _ODE_ODEOU_H_ #define _ODE_ODEOU_H_ #if dOU_ENABLED #include #include #include #include #include #include #include #if dATOMICS_ENABLED #include #include #endif #if dTLS_ENABLED #include #endif using namespace _OU_NAMESPACE; class COdeOu { public: static bool DoOUCustomizations(); static void UndoOUCustomizations(); #if dATOMICS_ENABLED static bool InitializeAtomics() { return InitializeAtomicAPI(); } static void FinalizeAtomics() { FinalizeAtomicAPI(); } #endif }; #endif // dOU_ENABLED #endif // _ODE_ODEOU_H_ alien-arena-7.66+dfsg/source/unix/odesrc/error.cpp0000600000175000017500000001067212161402010021207 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include #include "config.h" #include static dMessageFunction *error_function = 0; static dMessageFunction *debug_function = 0; static dMessageFunction *message_function = 0; extern "C" void dSetErrorHandler (dMessageFunction *fn) { error_function = fn; } extern "C" void dSetDebugHandler (dMessageFunction *fn) { debug_function = fn; } extern "C" void dSetMessageHandler (dMessageFunction *fn) { message_function = fn; } extern "C" dMessageFunction *dGetErrorHandler() { return error_function; } extern "C" dMessageFunction *dGetDebugHandler() { return debug_function; } extern "C" dMessageFunction *dGetMessageHandler() { return message_function; } static void printMessage (int num, const char *msg1, const char *msg2, va_list ap) { fflush (stderr); fflush (stdout); if (num) fprintf (stderr,"\n%s %d: ",msg1,num); else fprintf (stderr,"\n%s: ",msg1); vfprintf (stderr,msg2,ap); fprintf (stderr,"\n"); fflush (stderr); } //**************************************************************************** // unix #ifndef WIN32 extern "C" void dError (int num, const char *msg, ...) { va_list ap; va_start (ap,msg); if (error_function) error_function (num,msg,ap); else printMessage (num,"ODE Error",msg,ap); exit (1); } extern "C" void dDebug (int num, const char *msg, ...) { va_list ap; va_start (ap,msg); if (debug_function) debug_function (num,msg,ap); else printMessage (num,"ODE INTERNAL ERROR",msg,ap); // *((char *)0) = 0; ... commit SEGVicide abort(); } extern "C" void dMessage (int num, const char *msg, ...) { va_list ap; va_start (ap,msg); if (message_function) message_function (num,msg,ap); else printMessage (num,"ODE Message",msg,ap); } #endif //**************************************************************************** // windows #ifdef WIN32 // isn't cygwin annoying! #ifdef CYGWIN #define _snprintf snprintf #define _vsnprintf vsnprintf #endif #include "windows.h" extern "C" void dError (int num, const char *msg, ...) { va_list ap; va_start (ap,msg); if (error_function) error_function (num,msg,ap); else { char s[1000],title[100]; _snprintf (title,sizeof(title),"ODE Error %d",num); _vsnprintf (s,sizeof(s),msg,ap); s[sizeof(s)-1] = 0; MessageBox(0,s,title,MB_OK | MB_ICONWARNING); } exit (1); } extern "C" void dDebug (int num, const char *msg, ...) { va_list ap; va_start (ap,msg); if (debug_function) debug_function (num,msg,ap); else { char s[1000],title[100]; _snprintf (title,sizeof(title),"ODE INTERNAL ERROR %d",num); _vsnprintf (s,sizeof(s),msg,ap); s[sizeof(s)-1] = 0; MessageBox(0,s,title,MB_OK | MB_ICONSTOP); } abort(); } extern "C" void dMessage (int num, const char *msg, ...) { va_list ap; va_start (ap,msg); if (message_function) message_function (num,msg,ap); else printMessage (num,"ODE Message",msg,ap); } #endif alien-arena-7.66+dfsg/source/unix/odesrc/testing.cpp0000600000175000017500000001463612161402010021537 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include #include "config.h" #include #include #include "testing.h" #ifdef dDOUBLE static const dReal tol = 1.0e-9; #else static const dReal tol = 1.0e-5f; #endif // matrix header on the stack struct dMatrixComparison::dMatInfo { int n,m; // size of matrix char name[128]; // name of the matrix dReal *data; // matrix data int size; // size of `data' }; dMatrixComparison::dMatrixComparison() { afterfirst = 0; index = 0; } dMatrixComparison::~dMatrixComparison() { reset(); } dReal dMatrixComparison::nextMatrix (dReal *A, int n, int m, int lower_tri, const char *name, ...) { if (A==0 || n < 1 || m < 1 || name==0) dDebug (0,"bad args to nextMatrix"); int num = n*dPAD(m); if (afterfirst==0) { dMatInfo *mi = (dMatInfo*) dAlloc (sizeof(dMatInfo)); mi->n = n; mi->m = m; mi->size = num * sizeof(dReal); mi->data = (dReal*) dAlloc (mi->size); memcpy (mi->data,A,mi->size); va_list ap; va_start (ap,name); vsprintf (mi->name,name,ap); if (strlen(mi->name) >= sizeof (mi->name)) dDebug (0,"name too long"); mat.push (mi); return 0; } else { if (lower_tri && n != m) dDebug (0,"dMatrixComparison, lower triangular matrix must be square"); if (index >= mat.size()) dDebug (0,"dMatrixComparison, too many matrices"); dMatInfo *mp = mat[index]; index++; dMatInfo mi; va_list ap; va_start (ap,name); vsprintf (mi.name,name,ap); if (strlen(mi.name) >= sizeof (mi.name)) dDebug (0,"name too long"); if (strcmp(mp->name,mi.name) != 0) dDebug (0,"dMatrixComparison, name mismatch (\"%s\" and \"%s\")", mp->name,mi.name); if (mp->n != n || mp->m != m) dDebug (0,"dMatrixComparison, size mismatch (%dx%d and %dx%d)", mp->n,mp->m,n,m); dReal maxdiff; if (lower_tri) { maxdiff = dMaxDifferenceLowerTriangle (A,mp->data,n); } else { maxdiff = dMaxDifference (A,mp->data,n,m); } if (maxdiff > tol) dDebug (0,"dMatrixComparison, matrix error (size=%dx%d, name=\"%s\", " "error=%.4e)",n,m,mi.name,maxdiff); return maxdiff; } } void dMatrixComparison::end() { if (mat.size() <= 0) dDebug (0,"no matrices in sequence"); afterfirst = 1; index = 0; } void dMatrixComparison::reset() { for (int i=0; idata,mat[i]->size); dFree (mat[i],sizeof(dMatInfo)); } mat.setSize (0); afterfirst = 0; index = 0; } void dMatrixComparison::dump() { for (int i=0; iname,mat[i]->n,mat[i]->m); } //**************************************************************************** // unit test #include static jmp_buf jump_buffer; static void myDebug (int num, const char *msg, va_list ap) { // printf ("(Error %d: ",num); // vprintf (msg,ap); // printf (")\n"); longjmp (jump_buffer,1); } extern "C" ODE_API void dTestMatrixComparison() { volatile int i; printf ("dTestMatrixComparison()\n"); dMessageFunction *orig_debug = dGetDebugHandler(); dMatrixComparison mc; dReal A[50*50]; // make first sequence unsigned long seed = dRandGetSeed(); for (i=1; i<49; i++) { dMakeRandomMatrix (A,i,i+1,1.0); mc.nextMatrix (A,i,i+1,0,"A%d",i); } mc.end(); //mc.dump(); // test identical sequence dSetDebugHandler (&myDebug); dRandSetSeed (seed); if (setjmp (jump_buffer)) { printf ("\tFAILED (1)\n"); } else { for (i=1; i<49; i++) { dMakeRandomMatrix (A,i,i+1,1.0); mc.nextMatrix (A,i,i+1,0,"A%d",i); } mc.end(); printf ("\tpassed (1)\n"); } dSetDebugHandler (orig_debug); // test broken sequences (with matrix error) dRandSetSeed (seed); volatile int passcount = 0; for (i=1; i<49; i++) { if (setjmp (jump_buffer)) { passcount++; } else { dSetDebugHandler (&myDebug); dMakeRandomMatrix (A,i,i+1,1.0); A[(i-1)*dPAD(i+1)+i] += REAL(0.01); mc.nextMatrix (A,i,i+1,0,"A%d",i); dSetDebugHandler (orig_debug); } } mc.end(); printf ("\t%s (2)\n",(passcount == 48) ? "passed" : "FAILED"); // test broken sequences (with name error) dRandSetSeed (seed); passcount = 0; for (i=1; i<49; i++) { if (setjmp (jump_buffer)) { passcount++; } else { dSetDebugHandler (&myDebug); dMakeRandomMatrix (A,i,i+1,1.0); mc.nextMatrix (A,i,i+1,0,"B%d",i); dSetDebugHandler (orig_debug); } } mc.end(); printf ("\t%s (3)\n",(passcount == 48) ? "passed" : "FAILED"); // test identical sequence again dSetDebugHandler (&myDebug); dRandSetSeed (seed); if (setjmp (jump_buffer)) { printf ("\tFAILED (4)\n"); } else { for (i=1; i<49; i++) { dMakeRandomMatrix (A,i,i+1,1.0); mc.nextMatrix (A,i,i+1,0,"A%d",i); } mc.end(); printf ("\tpassed (4)\n"); } dSetDebugHandler (orig_debug); } alien-arena-7.66+dfsg/source/unix/odesrc/collision_util.h0000600000175000017500000002273212161402010022553 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* some useful collision utility stuff. */ #ifndef _ODE_COLLISION_UTIL_H_ #define _ODE_COLLISION_UTIL_H_ #include #include #include #include // given a pointer `p' to a dContactGeom, return the dContactGeom at // p + skip bytes. #define CONTACT(p,skip) ((dContactGeom*) (((char*)p) + (skip))) #if 1 #include "collision_kernel.h" // Fetches a contact inline dContactGeom* SAFECONTACT(int Flags, dContactGeom* Contacts, int Index, int Stride){ dIASSERT(Index >= 0 && Index < (Flags & NUMC_MASK)); return ((dContactGeom*)(((char*)Contacts) + (Index * Stride))); } #endif // if the spheres (p1,r1) and (p2,r2) collide, set the contact `c' and // return 1, else return 0. int dCollideSpheres (dVector3 p1, dReal r1, dVector3 p2, dReal r2, dContactGeom *c); // given two lines // qa = pa + alpha* ua // qb = pb + beta * ub // where pa,pb are two points, ua,ub are two unit length vectors, and alpha, // beta go from [-inf,inf], return alpha and beta such that qa and qb are // as close as possible void dLineClosestApproach (const dVector3 pa, const dVector3 ua, const dVector3 pb, const dVector3 ub, dReal *alpha, dReal *beta); // given a line segment p1-p2 and a box (center 'c', rotation 'R', side length // vector 'side'), compute the points of closest approach between the box // and the line. return these points in 'lret' (the point on the line) and // 'bret' (the point on the box). if the line actually penetrates the box // then the solution is not unique, but only one solution will be returned. // in this case the solution points will coincide. void dClosestLineBoxPoints (const dVector3 p1, const dVector3 p2, const dVector3 c, const dMatrix3 R, const dVector3 side, dVector3 lret, dVector3 bret); // 20 Apr 2004 // Start code by Nguyen Binh int dClipEdgeToPlane(dVector3 &vEpnt0, dVector3 &vEpnt1, const dVector4& plPlane); // clip polygon with plane and generate new polygon points void dClipPolyToPlane(const dVector3 avArrayIn[], const int ctIn, dVector3 avArrayOut[], int &ctOut, const dVector4 &plPlane ); void dClipPolyToCircle(const dVector3 avArrayIn[], const int ctIn, dVector3 avArrayOut[], int &ctOut, const dVector4 &plPlane ,dReal fRadius); // Some vector math inline void dVector3Subtract(const dVector3& a,const dVector3& b,dVector3& c) { c[0] = a[0] - b[0]; c[1] = a[1] - b[1]; c[2] = a[2] - b[2]; } // Some vector math inline void dVector3Scale(dVector3& a,dReal nScale) { a[0] *= nScale ; a[1] *= nScale ; a[2] *= nScale ; } inline void dVector3Add(const dVector3& a,const dVector3& b,dVector3& c) { c[0] = a[0] + b[0]; c[1] = a[1] + b[1]; c[2] = a[2] + b[2]; } inline void dVector3Copy(const dVector3& a,dVector3& c) { c[0] = a[0]; c[1] = a[1]; c[2] = a[2]; } inline void dVector4Copy(const dVector4& a,dVector4& c) { c[0] = a[0]; c[1] = a[1]; c[2] = a[2]; c[3] = a[3]; } inline void dVector3Cross(const dVector3& a,const dVector3& b,dVector3& c) { dCROSS(c,=,a,b); } inline dReal dVector3Length(const dVector3& a) { return dSqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]); } inline dReal dVector3Dot(const dVector3& a,const dVector3& b) { return dDOT(a,b); } inline void dVector3Inv(dVector3& a) { a[0] = -a[0]; a[1] = -a[1]; a[2] = -a[2]; } inline dReal dVector3Length2(const dVector3& a) { return (a[0]*a[0]+a[1]*a[1]+a[2]*a[2]); } inline void dMat3GetCol(const dMatrix3& m,const int col, dVector3& v) { v[0] = m[col + 0]; v[1] = m[col + 4]; v[2] = m[col + 8]; } inline void dVector3CrossMat3Col(const dMatrix3& m,const int col,const dVector3& v,dVector3& r) { r[0] = v[1] * m[2*4 + col] - v[2] * m[1*4 + col]; r[1] = v[2] * m[0*4 + col] - v[0] * m[2*4 + col]; r[2] = v[0] * m[1*4 + col] - v[1] * m[0*4 + col]; } inline void dMat3ColCrossVector3(const dMatrix3& m,const int col,const dVector3& v,dVector3& r) { r[0] = v[2] * m[1*4 + col] - v[1] * m[2*4 + col]; r[1] = v[0] * m[2*4 + col] - v[2] * m[0*4 + col]; r[2] = v[1] * m[0*4 + col] - v[0] * m[1*4 + col]; } inline void dMultiplyMat3Vec3(const dMatrix3& m,const dVector3& v, dVector3& r) { dMULTIPLY0_331(r,m,v); } inline dReal dPointPlaneDistance(const dVector3& point,const dVector4& plane) { return (plane[0]*point[0] + plane[1]*point[1] + plane[2]*point[2] + plane[3]); } inline void dConstructPlane(const dVector3& normal,const dReal& distance, dVector4& plane) { plane[0] = normal[0]; plane[1] = normal[1]; plane[2] = normal[2]; plane[3] = distance; } inline void dMatrix3Copy(const dReal* source,dMatrix3& dest) { dest[0] = source[0]; dest[1] = source[1]; dest[2] = source[2]; dest[4] = source[4]; dest[5] = source[5]; dest[6] = source[6]; dest[8] = source[8]; dest[9] = source[9]; dest[10]= source[10]; } inline dReal dMatrix3Det( const dMatrix3& mat ) { dReal det; det = mat[0] * ( mat[5]*mat[10] - mat[9]*mat[6] ) - mat[1] * ( mat[4]*mat[10] - mat[8]*mat[6] ) + mat[2] * ( mat[4]*mat[9] - mat[8]*mat[5] ); return( det ); } inline void dMatrix3Inv( const dMatrix3& ma, dMatrix3& dst ) { dReal det = dMatrix3Det( ma ); if ( dFabs( det ) < REAL(0.0005) ) { dRSetIdentity( dst ); return; } dst[0] = ma[5]*ma[10] - ma[6]*ma[9] / det; dst[1] = -( ma[1]*ma[10] - ma[9]*ma[2] ) / det; dst[2] = ma[1]*ma[6] - ma[5]*ma[2] / det; dst[4] = -( ma[4]*ma[10] - ma[6]*ma[8] ) / det; dst[5] = ma[0]*ma[10] - ma[8]*ma[2] / det; dst[6] = -( ma[0]*ma[6] - ma[4]*ma[2] ) / det; dst[8] = ma[4]*ma[9] - ma[8]*ma[5] / det; dst[9] = -( ma[0]*ma[9] - ma[8]*ma[1] ) / det; dst[10] = ma[0]*ma[5] - ma[1]*ma[4] / det; } inline void dQuatTransform(const dQuaternion& quat,const dVector3& source,dVector3& dest) { // Nguyen Binh : this code seem to be the fastest. dReal x0 = source[0] * quat[0] + source[2] * quat[2] - source[1] * quat[3]; dReal x1 = source[1] * quat[0] + source[0] * quat[3] - source[2] * quat[1]; dReal x2 = source[2] * quat[0] + source[1] * quat[1] - source[0] * quat[2]; dReal x3 = source[0] * quat[1] + source[1] * quat[2] + source[2] * quat[3]; dest[0] = quat[0] * x0 + quat[1] * x3 + quat[2] * x2 - quat[3] * x1; dest[1] = quat[0] * x1 + quat[2] * x3 + quat[3] * x0 - quat[1] * x2; dest[2] = quat[0] * x2 + quat[3] * x3 + quat[1] * x1 - quat[2] * x0; /* // nVidia SDK implementation dVector3 uv, uuv; dVector3 qvec; qvec[0] = quat[1]; qvec[1] = quat[2]; qvec[2] = quat[3]; dVector3Cross(qvec,source,uv); dVector3Cross(qvec,uv,uuv); dVector3Scale(uv,REAL(2.0)*quat[0]); dVector3Scale(uuv,REAL(2.0)); dest[0] = source[0] + uv[0] + uuv[0]; dest[1] = source[1] + uv[1] + uuv[1]; dest[2] = source[2] + uv[2] + uuv[2]; */ } inline void dQuatInvTransform(const dQuaternion& quat,const dVector3& source,dVector3& dest) { dReal norm = quat[0]*quat[0] + quat[1]*quat[1] + quat[2]*quat[2] + quat[3]*quat[3]; if (norm > REAL(0.0)) { dQuaternion invQuat; invQuat[0] = quat[0] / norm; invQuat[1] = -quat[1] / norm; invQuat[2] = -quat[2] / norm; invQuat[3] = -quat[3] / norm; dQuatTransform(invQuat,source,dest); } else { // Singular -> return identity dVector3Copy(source,dest); } } inline void dGetEulerAngleFromRot(const dMatrix3& mRot,dReal& rX,dReal& rY,dReal& rZ) { rY = asin(mRot[0 * 4 + 2]); if (rY < M_PI /2) { if (rY > -M_PI /2) { rX = atan2(-mRot[1*4 + 2], mRot[2*4 + 2]); rZ = atan2(-mRot[0*4 + 1], mRot[0*4 + 0]); } else { // not unique rX = -atan2(mRot[1*4 + 0], mRot[1*4 + 1]); rZ = REAL(0.0); } } else { // not unique rX = atan2(mRot[1*4 + 0], mRot[1*4 + 1]); rZ = REAL(0.0); } } inline void dQuatInv(const dQuaternion& source, dQuaternion& dest) { dReal norm = source[0]*source[0] + source[1]*source[1] + source[2]*source[2] + source[3]*source[3]; if (norm > 0.0f) { dest[0] = source[0] / norm; dest[1] = -source[1] / norm; dest[2] = -source[2] / norm; dest[3] = -source[3] / norm; } else { // Singular -> return identity dest[0] = REAL(1.0); dest[1] = REAL(0.0); dest[2] = REAL(0.0); dest[3] = REAL(0.0); } } #endif alien-arena-7.66+dfsg/source/unix/odesrc/collision_cylinder_trimesh.cpp0000600000175000017500000010276012161402010025475 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* * Cylinder-trimesh collider by Alen Ladavac * Ported to ODE by Nguyen Binh */ #include #include #include #include #include "collision_util.h" #include "collision_trimesh_internal.h" #include "util.h" #if dTRIMESH_ENABLED #define MAX_REAL dInfinity static const int nCYLINDER_AXIS = 2; static const int nCYLINDER_CIRCLE_SEGMENTS = 8; static const int nMAX_CYLINDER_TRIANGLE_CLIP_POINTS = 12; #define OPTIMIZE_CONTACTS 1 // Local contacts data typedef struct _sLocalContactData { dVector3 vPos; dVector3 vNormal; dReal fDepth; int triIndex; int nFlags; // 0 = filtered out, 1 = OK }sLocalContactData; struct sCylinderTrimeshColliderData { sCylinderTrimeshColliderData(int flags, int skip): m_iFlags(flags), m_iSkip(skip), m_nContacts(0), m_gLocalContacts(NULL) {} #ifdef OPTIMIZE_CONTACTS void _OptimizeLocalContacts(); #endif void _InitCylinderTrimeshData(dxGeom *Cylinder, dxTriMesh *Trimesh); int _ProcessLocalContacts(dContactGeom *contact, dxGeom *Cylinder, dxTriMesh *Trimesh); bool _cldTestAxis(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, dVector3& vAxis, int iAxis, bool bNoFlip = false); bool _cldTestCircleToEdgeAxis( const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, const dVector3 &vCenterPoint, const dVector3 &vCylinderAxis1, const dVector3 &vVx0, const dVector3 &vVx1, int iAxis); bool _cldTestSeparatingAxes(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2); bool _cldClipCylinderEdgeToTriangle(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2); void _cldClipCylinderToTriangle(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2); void TestOneTriangleVsCylinder(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, const bool bDoubleSided); int TestCollisionForSingleTriangle(int ctContacts0, int Triint, dVector3 dv[3], bool &bOutFinishSearching); // cylinder data dMatrix3 m_mCylinderRot; dQuaternion m_qCylinderRot; dQuaternion m_qInvCylinderRot; dVector3 m_vCylinderPos; dVector3 m_vCylinderAxis; dReal m_fCylinderRadius; dReal m_fCylinderSize; dVector3 m_avCylinderNormals[nCYLINDER_CIRCLE_SEGMENTS]; // mesh data dQuaternion m_qTrimeshRot; dQuaternion m_qInvTrimeshRot; dMatrix3 m_mTrimeshRot; dVector3 m_vTrimeshPos; // global collider data dVector3 m_vBestPoint; dReal m_fBestDepth; dReal m_fBestCenter; dReal m_fBestrt; int m_iBestAxis; dVector3 m_vContactNormal; dVector3 m_vNormal; dVector3 m_vE0; dVector3 m_vE1; dVector3 m_vE2; // ODE stuff int m_iFlags; int m_iSkip; int m_nContacts;// = 0; sLocalContactData* m_gLocalContacts; }; #ifdef OPTIMIZE_CONTACTS // Use to classify contacts to be "near" in position static const dReal fSameContactPositionEpsilon = REAL(0.0001); // 1e-4 // Use to classify contacts to be "near" in normal direction static const dReal fSameContactNormalEpsilon = REAL(0.0001); // 1e-4 // If this two contact can be classified as "near" inline int _IsNearContacts(sLocalContactData& c1,sLocalContactData& c2) { int bPosNear = 0; int bSameDir = 0; dVector3 vDiff; // First check if they are "near" in position dVector3Subtract(c1.vPos,c2.vPos,vDiff); if ( (dFabs(vDiff[0]) < fSameContactPositionEpsilon) &&(dFabs(vDiff[1]) < fSameContactPositionEpsilon) &&(dFabs(vDiff[2]) < fSameContactPositionEpsilon)) { bPosNear = 1; } // Second check if they are "near" in normal direction dVector3Subtract(c1.vNormal,c2.vNormal,vDiff); if ( (dFabs(vDiff[0]) < fSameContactNormalEpsilon) &&(dFabs(vDiff[1]) < fSameContactNormalEpsilon) &&(dFabs(vDiff[2]) < fSameContactNormalEpsilon) ) { bSameDir = 1; } // Will be "near" if position and normal direction are "near" return (bPosNear && bSameDir); } inline int _IsBetter(sLocalContactData& c1,sLocalContactData& c2) { // The not better will be throw away // You can change the selection criteria here return (c1.fDepth > c2.fDepth); } // iterate through gLocalContacts and filtered out "near contact" void sCylinderTrimeshColliderData::_OptimizeLocalContacts() { int nContacts = m_nContacts; for (int i = 0; i < nContacts-1; i++) { for (int j = i+1; j < nContacts; j++) { if (_IsNearContacts(m_gLocalContacts[i],m_gLocalContacts[j])) { // If they are seem to be the same then filtered // out the least penetrate one if (_IsBetter(m_gLocalContacts[j],m_gLocalContacts[i])) { m_gLocalContacts[i].nFlags = 0; // filtered 1st contact } else { m_gLocalContacts[j].nFlags = 0; // filtered 2nd contact } // NOTE // There is other way is to add two depth together but // it not work so well. Why??? } } } } #endif // OPTIMIZE_CONTACTS int sCylinderTrimeshColliderData::_ProcessLocalContacts(dContactGeom *contact, dxGeom *Cylinder, dxTriMesh *Trimesh) { #ifdef OPTIMIZE_CONTACTS if (m_nContacts > 1 && !(m_iFlags & CONTACTS_UNIMPORTANT)) { // Can be optimized... _OptimizeLocalContacts(); } #endif int iContact = 0; dContactGeom* Contact = 0; int nFinalContact = 0; for (iContact = 0; iContact < m_nContacts; iContact ++) { if (1 == m_gLocalContacts[iContact].nFlags) { Contact = SAFECONTACT(m_iFlags, contact, nFinalContact, m_iSkip); Contact->depth = m_gLocalContacts[iContact].fDepth; dVector3Copy(m_gLocalContacts[iContact].vNormal,Contact->normal); dVector3Copy(m_gLocalContacts[iContact].vPos,Contact->pos); Contact->g1 = Cylinder; Contact->g2 = Trimesh; Contact->side1 = -1; Contact->side2 = m_gLocalContacts[iContact].triIndex; dVector3Inv(Contact->normal); nFinalContact++; } } // debug //if (nFinalContact != m_nContacts) //{ // printf("[Info] %d contacts generated,%d filtered.\n",m_nContacts,m_nContacts-nFinalContact); //} return nFinalContact; } bool sCylinderTrimeshColliderData::_cldTestAxis( const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, dVector3& vAxis, int iAxis, bool bNoFlip/* = false*/) { // calculate length of separating axis vector dReal fL = dVector3Length(vAxis); // if not long enough if ( fL < REAL(1e-5) ) { // do nothing return true; } // otherwise normalize it vAxis[0] /= fL; vAxis[1] /= fL; vAxis[2] /= fL; dReal fdot1 = dVector3Dot(m_vCylinderAxis,vAxis); // project capsule on vAxis dReal frc; if (dFabs(fdot1) > REAL(1.0) ) { // fdot1 = REAL(1.0); frc = dFabs(m_fCylinderSize* REAL(0.5)); } else { frc = dFabs((m_fCylinderSize* REAL(0.5)) * fdot1) + m_fCylinderRadius * dSqrt(REAL(1.0)-(fdot1*fdot1)); } dVector3 vV0; dVector3Subtract(v0,m_vCylinderPos,vV0); dVector3 vV1; dVector3Subtract(v1,m_vCylinderPos,vV1); dVector3 vV2; dVector3Subtract(v2,m_vCylinderPos,vV2); // project triangle on vAxis dReal afv[3]; afv[0] = dVector3Dot( vV0 , vAxis ); afv[1] = dVector3Dot( vV1 , vAxis ); afv[2] = dVector3Dot( vV2 , vAxis ); dReal fMin = MAX_REAL; dReal fMax = -MAX_REAL; // for each vertex for(int i = 0; i < 3; i++) { // find minimum if (afv[i]fMax) { fMax = afv[i]; } } // find capsule's center of interval on axis dReal fCenter = (fMin+fMax)* REAL(0.5); // calculate triangles halfinterval dReal fTriangleRadius = (fMax-fMin)*REAL(0.5); // if they do not overlap, if( dFabs(fCenter) > (frc+fTriangleRadius) ) { // exit, we have no intersection return false; } // calculate depth dReal fDepth = -(dFabs(fCenter) - (frc + fTriangleRadius ) ); // if greater then best found so far if ( fDepth < m_fBestDepth ) { // remember depth m_fBestDepth = fDepth; m_fBestCenter = fCenter; m_fBestrt = frc; dVector3Copy(vAxis,m_vContactNormal); m_iBestAxis = iAxis; // flip normal if interval is wrong faced if ( fCenter< REAL(0.0) && !bNoFlip) { dVector3Inv(m_vContactNormal); m_fBestCenter = -fCenter; } } return true; } // intersection test between edge and circle bool sCylinderTrimeshColliderData::_cldTestCircleToEdgeAxis( const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, const dVector3 &vCenterPoint, const dVector3 &vCylinderAxis1, const dVector3 &vVx0, const dVector3 &vVx1, int iAxis) { // calculate direction of edge dVector3 vkl; dVector3Subtract( vVx1 , vVx0 , vkl); dNormalize3(vkl); // starting point of edge dVector3 vol; dVector3Copy(vVx0,vol); // calculate angle cosine between cylinder axis and edge dReal fdot2 = dVector3Dot(vkl , vCylinderAxis1); // if edge is perpendicular to cylinder axis if(dFabs(fdot2) so save some cycles here dVector3Subtract(v0 ,v2 , m_vE2); // calculate caps centers in absolute space dVector3 vCp0; vCp0[0] = m_vCylinderPos[0] + m_vCylinderAxis[0]*(m_fCylinderSize* REAL(0.5)); vCp0[1] = m_vCylinderPos[1] + m_vCylinderAxis[1]*(m_fCylinderSize* REAL(0.5)); vCp0[2] = m_vCylinderPos[2] + m_vCylinderAxis[2]*(m_fCylinderSize* REAL(0.5)); dVector3 vCp1; vCp1[0] = m_vCylinderPos[0] - m_vCylinderAxis[0]*(m_fCylinderSize* REAL(0.5)); vCp1[1] = m_vCylinderPos[1] - m_vCylinderAxis[1]*(m_fCylinderSize* REAL(0.5)); vCp1[2] = m_vCylinderPos[2] - m_vCylinderAxis[2]*(m_fCylinderSize* REAL(0.5)); // reset best axis m_iBestAxis = 0; dVector3 vAxis; // axis m_vNormal //vAxis = -m_vNormal; vAxis[0] = -m_vNormal[0]; vAxis[1] = -m_vNormal[1]; vAxis[2] = -m_vNormal[2]; if (!_cldTestAxis(v0, v1, v2, vAxis, 1, true)) { return false; } // axis CxE0 // vAxis = ( m_vCylinderAxis cross m_vE0 ); dVector3Cross(m_vCylinderAxis, m_vE0,vAxis); if (!_cldTestAxis(v0, v1, v2, vAxis, 2)) { return false; } // axis CxE1 // vAxis = ( m_vCylinderAxis cross m_vE1 ); dVector3Cross(m_vCylinderAxis, m_vE1,vAxis); if (!_cldTestAxis(v0, v1, v2, vAxis, 3)) { return false; } // axis CxE2 // vAxis = ( m_vCylinderAxis cross m_vE2 ); dVector3Cross(m_vCylinderAxis, m_vE2,vAxis); if (!_cldTestAxis(v0, v1, v2, vAxis, 4)) { return false; } // first vertex on triangle // axis ((V0-Cp0) x C) x C //vAxis = ( ( v0-vCp0 ) cross m_vCylinderAxis ) cross m_vCylinderAxis; _CalculateAxis(v0 , vCp0 , m_vCylinderAxis , vAxis); if (!_cldTestAxis(v0, v1, v2, vAxis, 11)) { return false; } // second vertex on triangle // axis ((V1-Cp0) x C) x C // vAxis = ( ( v1-vCp0 ) cross m_vCylinderAxis ) cross m_vCylinderAxis; _CalculateAxis(v1 , vCp0 , m_vCylinderAxis , vAxis); if (!_cldTestAxis(v0, v1, v2, vAxis, 12)) { return false; } // third vertex on triangle // axis ((V2-Cp0) x C) x C //vAxis = ( ( v2-vCp0 ) cross m_vCylinderAxis ) cross m_vCylinderAxis; _CalculateAxis(v2 , vCp0 , m_vCylinderAxis , vAxis); if (!_cldTestAxis(v0, v1, v2, vAxis, 13)) { return false; } // test cylinder axis // vAxis = m_vCylinderAxis; dVector3Copy(m_vCylinderAxis , vAxis); if (!_cldTestAxis(v0, v1, v2, vAxis, 14)) { return false; } // Test top and bottom circle ring of cylinder for separation dVector3 vccATop; vccATop[0] = m_vCylinderPos[0] + m_vCylinderAxis[0]*(m_fCylinderSize * REAL(0.5)); vccATop[1] = m_vCylinderPos[1] + m_vCylinderAxis[1]*(m_fCylinderSize * REAL(0.5)); vccATop[2] = m_vCylinderPos[2] + m_vCylinderAxis[2]*(m_fCylinderSize * REAL(0.5)); dVector3 vccABottom; vccABottom[0] = m_vCylinderPos[0] - m_vCylinderAxis[0]*(m_fCylinderSize * REAL(0.5)); vccABottom[1] = m_vCylinderPos[1] - m_vCylinderAxis[1]*(m_fCylinderSize * REAL(0.5)); vccABottom[2] = m_vCylinderPos[2] - m_vCylinderAxis[2]*(m_fCylinderSize * REAL(0.5)); if (!_cldTestCircleToEdgeAxis(v0, v1, v2, vccATop, m_vCylinderAxis, v0, v1, 15)) { return false; } if (!_cldTestCircleToEdgeAxis(v0, v1, v2, vccATop, m_vCylinderAxis, v1, v2, 16)) { return false; } if (!_cldTestCircleToEdgeAxis(v0, v1, v2, vccATop, m_vCylinderAxis, v0, v2, 17)) { return false; } if (!_cldTestCircleToEdgeAxis(v0, v1, v2, vccABottom, m_vCylinderAxis, v0, v1, 18)) { return false; } if (!_cldTestCircleToEdgeAxis(v0, v1, v2, vccABottom, m_vCylinderAxis, v1, v2, 19)) { return false; } if (!_cldTestCircleToEdgeAxis(v0, v1, v2, vccABottom, m_vCylinderAxis, v0, v2, 20)) { return false; } return true; } bool sCylinderTrimeshColliderData::_cldClipCylinderEdgeToTriangle( const dVector3 &v0, const dVector3 &v1, const dVector3 &v2) { // translate cylinder dReal fTemp = dVector3Dot(m_vCylinderAxis , m_vContactNormal); dVector3 vN2; vN2[0] = m_vContactNormal[0] - m_vCylinderAxis[0]*fTemp; vN2[1] = m_vContactNormal[1] - m_vCylinderAxis[1]*fTemp; vN2[2] = m_vContactNormal[2] - m_vCylinderAxis[2]*fTemp; fTemp = dVector3Length(vN2); if (fTemp < REAL(1e-5)) { return false; } // Normalize it vN2[0] /= fTemp; vN2[1] /= fTemp; vN2[2] /= fTemp; // calculate caps centers in absolute space dVector3 vCposTrans; vCposTrans[0] = m_vCylinderPos[0] + vN2[0]*m_fCylinderRadius; vCposTrans[1] = m_vCylinderPos[1] + vN2[1]*m_fCylinderRadius; vCposTrans[2] = m_vCylinderPos[2] + vN2[2]*m_fCylinderRadius; dVector3 vCEdgePoint0; vCEdgePoint0[0] = vCposTrans[0] + m_vCylinderAxis[0] * (m_fCylinderSize* REAL(0.5)); vCEdgePoint0[1] = vCposTrans[1] + m_vCylinderAxis[1] * (m_fCylinderSize* REAL(0.5)); vCEdgePoint0[2] = vCposTrans[2] + m_vCylinderAxis[2] * (m_fCylinderSize* REAL(0.5)); dVector3 vCEdgePoint1; vCEdgePoint1[0] = vCposTrans[0] - m_vCylinderAxis[0] * (m_fCylinderSize* REAL(0.5)); vCEdgePoint1[1] = vCposTrans[1] - m_vCylinderAxis[1] * (m_fCylinderSize* REAL(0.5)); vCEdgePoint1[2] = vCposTrans[2] - m_vCylinderAxis[2] * (m_fCylinderSize* REAL(0.5)); // transform cylinder edge points into triangle space vCEdgePoint0[0] -= v0[0]; vCEdgePoint0[1] -= v0[1]; vCEdgePoint0[2] -= v0[2]; vCEdgePoint1[0] -= v0[0]; vCEdgePoint1[1] -= v0[1]; vCEdgePoint1[2] -= v0[2]; dVector4 plPlane; dVector3 vPlaneNormal; // triangle plane //plPlane = Plane4f( -m_vNormal, 0); vPlaneNormal[0] = -m_vNormal[0]; vPlaneNormal[1] = -m_vNormal[1]; vPlaneNormal[2] = -m_vNormal[2]; dConstructPlane(vPlaneNormal,REAL(0.0),plPlane); if(!dClipEdgeToPlane( vCEdgePoint0, vCEdgePoint1, plPlane )) { return false; } // plane with edge 0 //plPlane = Plane4f( ( m_vNormal cross m_vE0 ), REAL(1e-5)); dVector3Cross(m_vNormal,m_vE0,vPlaneNormal); dConstructPlane(vPlaneNormal,REAL(1e-5),plPlane); if(!dClipEdgeToPlane( vCEdgePoint0, vCEdgePoint1, plPlane )) { return false; } // plane with edge 1 //dVector3 vTemp = ( m_vNormal cross m_vE1 ); dVector3Cross(m_vNormal,m_vE1,vPlaneNormal); fTemp = dVector3Dot(m_vE0 , vPlaneNormal) - REAL(1e-5); //plPlane = Plane4f( vTemp, -(( m_vE0 dot vTemp )-REAL(1e-5))); dConstructPlane(vPlaneNormal,-fTemp,plPlane); if(!dClipEdgeToPlane( vCEdgePoint0, vCEdgePoint1, plPlane )) { return false; } // plane with edge 2 // plPlane = Plane4f( ( m_vNormal cross m_vE2 ), REAL(1e-5)); dVector3Cross(m_vNormal,m_vE2,vPlaneNormal); dConstructPlane(vPlaneNormal,REAL(1e-5),plPlane); if(!dClipEdgeToPlane( vCEdgePoint0, vCEdgePoint1, plPlane )) { return false; } // return capsule edge points into absolute space vCEdgePoint0[0] += v0[0]; vCEdgePoint0[1] += v0[1]; vCEdgePoint0[2] += v0[2]; vCEdgePoint1[0] += v0[0]; vCEdgePoint1[1] += v0[1]; vCEdgePoint1[2] += v0[2]; // calculate depths for both contact points dVector3 vTemp; dVector3Subtract(vCEdgePoint0,m_vCylinderPos, vTemp); dReal fRestDepth0 = -dVector3Dot(vTemp,m_vContactNormal) + m_fBestrt; dVector3Subtract(vCEdgePoint1,m_vCylinderPos, vTemp); dReal fRestDepth1 = -dVector3Dot(vTemp,m_vContactNormal) + m_fBestrt; dReal fDepth0 = m_fBestDepth - (fRestDepth0); dReal fDepth1 = m_fBestDepth - (fRestDepth1); // clamp depths to zero if(fDepth0 < REAL(0.0) ) { fDepth0 = REAL(0.0); } if(fDepth1= (m_iFlags & NUMC_MASK)) return true; } // Generate contact 1 { // generate contacts m_gLocalContacts[m_nContacts].fDepth = fDepth1; dVector3Copy(m_vContactNormal,m_gLocalContacts[m_nContacts].vNormal); dVector3Copy(vCEdgePoint1,m_gLocalContacts[m_nContacts].vPos); m_gLocalContacts[m_nContacts].nFlags = 1; m_nContacts++; } return true; } void sCylinderTrimeshColliderData::_cldClipCylinderToTriangle( const dVector3 &v0, const dVector3 &v1, const dVector3 &v2) { int i = 0; dVector3 avPoints[3]; dVector3 avTempArray1[nMAX_CYLINDER_TRIANGLE_CLIP_POINTS]; dVector3 avTempArray2[nMAX_CYLINDER_TRIANGLE_CLIP_POINTS]; dSetZero(&avTempArray1[0][0],nMAX_CYLINDER_TRIANGLE_CLIP_POINTS * 4); dSetZero(&avTempArray2[0][0],nMAX_CYLINDER_TRIANGLE_CLIP_POINTS * 4); // setup array of triangle vertices dVector3Copy(v0,avPoints[0]); dVector3Copy(v1,avPoints[1]); dVector3Copy(v2,avPoints[2]); dVector3 vCylinderCirclePos, vCylinderCircleNormal_Rel; dSetZero(vCylinderCircleNormal_Rel,4); // check which circle from cylinder we take for clipping if ( dVector3Dot(m_vCylinderAxis , m_vContactNormal) > REAL(0.0)) { // get top circle vCylinderCirclePos[0] = m_vCylinderPos[0] + m_vCylinderAxis[0]*(m_fCylinderSize*REAL(0.5)); vCylinderCirclePos[1] = m_vCylinderPos[1] + m_vCylinderAxis[1]*(m_fCylinderSize*REAL(0.5)); vCylinderCirclePos[2] = m_vCylinderPos[2] + m_vCylinderAxis[2]*(m_fCylinderSize*REAL(0.5)); vCylinderCircleNormal_Rel[nCYLINDER_AXIS] = REAL(-1.0); } else { // get bottom circle vCylinderCirclePos[0] = m_vCylinderPos[0] - m_vCylinderAxis[0]*(m_fCylinderSize*REAL(0.5)); vCylinderCirclePos[1] = m_vCylinderPos[1] - m_vCylinderAxis[1]*(m_fCylinderSize*REAL(0.5)); vCylinderCirclePos[2] = m_vCylinderPos[2] - m_vCylinderAxis[2]*(m_fCylinderSize*REAL(0.5)); vCylinderCircleNormal_Rel[nCYLINDER_AXIS] = REAL(1.0); } dVector3 vTemp; dQuatInv(m_qCylinderRot , m_qInvCylinderRot); // transform triangle points to space of cylinder circle for(i=0; i<3; i++) { dVector3Subtract(avPoints[i] , vCylinderCirclePos , vTemp); dQuatTransform(m_qInvCylinderRot,vTemp,avPoints[i]); } int iTmpCounter1 = 0; int iTmpCounter2 = 0; dVector4 plPlane; // plane of cylinder that contains circle for intersection //plPlane = Plane4f( vCylinderCircleNormal_Rel, 0.0f ); dConstructPlane(vCylinderCircleNormal_Rel,REAL(0.0),plPlane); dClipPolyToPlane(avPoints, 3, avTempArray1, iTmpCounter1, plPlane); // Body of base circle of Cylinder int nCircleSegment = 0; for (nCircleSegment = 0; nCircleSegment < nCYLINDER_CIRCLE_SEGMENTS; nCircleSegment++) { dConstructPlane(m_avCylinderNormals[nCircleSegment],m_fCylinderRadius,plPlane); if (0 == (nCircleSegment % 2)) { dClipPolyToPlane( avTempArray1 , iTmpCounter1 , avTempArray2, iTmpCounter2, plPlane); } else { dClipPolyToPlane( avTempArray2, iTmpCounter2, avTempArray1 , iTmpCounter1 , plPlane ); } dIASSERT( iTmpCounter1 >= 0 && iTmpCounter1 <= nMAX_CYLINDER_TRIANGLE_CLIP_POINTS ); dIASSERT( iTmpCounter2 >= 0 && iTmpCounter2 <= nMAX_CYLINDER_TRIANGLE_CLIP_POINTS ); } // back transform clipped points to absolute space dReal ftmpdot; dReal fTempDepth; dVector3 vPoint; if (nCircleSegment %2) { for( i=0; i REAL(0.0)) { m_gLocalContacts[m_nContacts].fDepth = fTempDepth; dVector3Copy(m_vContactNormal,m_gLocalContacts[m_nContacts].vNormal); dVector3Copy(vPoint,m_gLocalContacts[m_nContacts].vPos); m_gLocalContacts[m_nContacts].nFlags = 1; m_nContacts++; if(m_nContacts >= (m_iFlags & NUMC_MASK)) return;; } } } else { for( i=0; i REAL(0.0)) { m_gLocalContacts[m_nContacts].fDepth = fTempDepth; dVector3Copy(m_vContactNormal,m_gLocalContacts[m_nContacts].vNormal); dVector3Copy(vPoint,m_gLocalContacts[m_nContacts].vPos); m_gLocalContacts[m_nContacts].nFlags = 1; m_nContacts++; if(m_nContacts >= (m_iFlags & NUMC_MASK)) return;; } } } } void sCylinderTrimeshColliderData::TestOneTriangleVsCylinder( const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, const bool bDoubleSided) { // calculate triangle normal dVector3Subtract( v2 , v1 , m_vE1); dVector3 vTemp; dVector3Subtract( v0 , v1 ,vTemp); dVector3Cross(m_vE1 , vTemp , m_vNormal ); // Even though all triangles might be initially valid, // a triangle may degenerate into a segment after applying // space transformation. if (!dSafeNormalize3( m_vNormal)) { return; } // create plane from triangle //Plane4f plTrianglePlane = Plane4f( vPolyNormal, v0 ); dReal plDistance = -dVector3Dot(v0, m_vNormal); dVector4 plTrianglePlane; dConstructPlane( m_vNormal,plDistance,plTrianglePlane); // calculate sphere distance to plane dReal fDistanceCylinderCenterToPlane = dPointPlaneDistance(m_vCylinderPos , plTrianglePlane); // Sphere must be over positive side of triangle if(fDistanceCylinderCenterToPlane < 0 && !bDoubleSided) { // if not don't generate contacts return; } dVector3 vPnt0; dVector3 vPnt1; dVector3 vPnt2; if (fDistanceCylinderCenterToPlane < REAL(0.0) ) { // flip it dVector3Copy(v0 , vPnt0); dVector3Copy(v1 , vPnt2); dVector3Copy(v2 , vPnt1); } else { dVector3Copy(v0 , vPnt0); dVector3Copy(v1 , vPnt1); dVector3Copy(v2 , vPnt2); } m_fBestDepth = MAX_REAL; // do intersection test and find best separating axis if(!_cldTestSeparatingAxes(vPnt0, vPnt1, vPnt2) ) { // if not found do nothing return; } // if best separation axis is not found if ( m_iBestAxis == 0 ) { // this should not happen (we should already exit in that case) dIASSERT(false); // do nothing return; } dReal fdot = dVector3Dot( m_vContactNormal , m_vCylinderAxis ); // choose which clipping method are we going to apply if (dFabs(fdot) < REAL(0.9) ) { if (!_cldClipCylinderEdgeToTriangle(vPnt0, vPnt1, vPnt2)) { return; } } else { _cldClipCylinderToTriangle(vPnt0, vPnt1, vPnt2); } } void sCylinderTrimeshColliderData::_InitCylinderTrimeshData(dxGeom *Cylinder, dxTriMesh *Trimesh) { // get cylinder information // Rotation const dReal* pRotCyc = dGeomGetRotation(Cylinder); dMatrix3Copy(pRotCyc,m_mCylinderRot); dGeomGetQuaternion(Cylinder,m_qCylinderRot); // Position const dVector3* pPosCyc = (const dVector3*)dGeomGetPosition(Cylinder); dVector3Copy(*pPosCyc,m_vCylinderPos); // Cylinder axis dMat3GetCol(m_mCylinderRot,nCYLINDER_AXIS,m_vCylinderAxis); // get cylinder radius and size dGeomCylinderGetParams(Cylinder,&m_fCylinderRadius,&m_fCylinderSize); // get trimesh position and orientation const dReal* pRotTris = dGeomGetRotation(Trimesh); dMatrix3Copy(pRotTris,m_mTrimeshRot); dGeomGetQuaternion(Trimesh,m_qTrimeshRot); // Position const dVector3* pPosTris = (const dVector3*)dGeomGetPosition(Trimesh); dVector3Copy(*pPosTris,m_vTrimeshPos); // calculate basic angle for 8-gon dReal fAngle = (dReal) (M_PI / nCYLINDER_CIRCLE_SEGMENTS); // calculate angle increment dReal fAngleIncrement = fAngle*REAL(2.0); // calculate plane normals // axis dependant code for(int i=0; i= (m_iFlags & NUMC_MASK)); return ctContacts0; } // OPCODE version of cylinder to mesh collider #if dTRIMESH_OPCODE static void dQueryCTLPotentialCollisionTriangles(OBBCollider &Collider, sCylinderTrimeshColliderData &cData, dxGeom *Cylinder, dxTriMesh *Trimesh, OBBCache &BoxCache) { const dVector3 &vCylinderPos = cData.m_vCylinderPos; Point cCenter(vCylinderPos[0],vCylinderPos[1],vCylinderPos[2]); Point cExtents(cData.m_fCylinderRadius,cData.m_fCylinderRadius,cData.m_fCylinderRadius); cExtents[nCYLINDER_AXIS] = cData.m_fCylinderSize * REAL(0.5); Matrix3x3 obbRot; const dMatrix3 &mCylinderRot = cData.m_mCylinderRot; // It is a potential issue to explicitly cast to float // if custom width floating point type is introduced in OPCODE. // It is necessary to make a typedef and cast to it // (e.g. typedef float opc_float;) // However I'm not sure in what header it should be added. obbRot[0][0] = /*(float)*/mCylinderRot[0]; obbRot[1][0] = /*(float)*/mCylinderRot[1]; obbRot[2][0] = /*(float)*/mCylinderRot[2]; obbRot[0][1] = /*(float)*/mCylinderRot[4]; obbRot[1][1] = /*(float)*/mCylinderRot[5]; obbRot[2][1] = /*(float)*/mCylinderRot[6]; obbRot[0][2] = /*(float)*/mCylinderRot[8]; obbRot[1][2] = /*(float)*/mCylinderRot[9]; obbRot[2][2] = /*(float)*/mCylinderRot[10]; OBB obbCapsule(cCenter,cExtents,obbRot); Matrix4x4 CapsuleMatrix; MakeMatrix(vCylinderPos, mCylinderRot, CapsuleMatrix); Matrix4x4 MeshMatrix; MakeMatrix(cData.m_vTrimeshPos, cData.m_mTrimeshRot, MeshMatrix); // TC results if (Trimesh->doBoxTC) { dxTriMesh::BoxTC* BoxTC = 0; for (int i = 0; i < Trimesh->BoxTCCache.size(); i++) { if (Trimesh->BoxTCCache[i].Geom == Cylinder) { BoxTC = &Trimesh->BoxTCCache[i]; break; } } if (!BoxTC) { Trimesh->BoxTCCache.push(dxTriMesh::BoxTC()); BoxTC = &Trimesh->BoxTCCache[Trimesh->BoxTCCache.size() - 1]; BoxTC->Geom = Cylinder; BoxTC->FatCoeff = REAL(1.0); } // Intersect Collider.SetTemporalCoherence(true); Collider.Collide(*BoxTC, obbCapsule, Trimesh->Data->BVTree, null, &MeshMatrix); } else { Collider.SetTemporalCoherence(false); Collider.Collide(BoxCache, obbCapsule, Trimesh->Data->BVTree, null,&MeshMatrix); } } int dCollideCylinderTrimesh(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT( skip >= (int)sizeof( dContactGeom ) ); dIASSERT( o1->type == dCylinderClass ); dIASSERT( o2->type == dTriMeshClass ); dIASSERT ((flags & NUMC_MASK) >= 1); int nContactCount = 0; dxGeom *Cylinder = o1; dxTriMesh *Trimesh = (dxTriMesh *)o2; // Main data holder sCylinderTrimeshColliderData cData(flags, skip); cData._InitCylinderTrimeshData(Cylinder, Trimesh); const unsigned uiTLSKind = Trimesh->getParentSpaceTLSKind(); dIASSERT(uiTLSKind == Cylinder->getParentSpaceTLSKind()); // The colliding spaces must use matching cleanup method TrimeshCollidersCache *pccColliderCache = GetTrimeshCollidersCache(uiTLSKind); OBBCollider& Collider = pccColliderCache->_OBBCollider; dQueryCTLPotentialCollisionTriangles(Collider, cData, Cylinder, Trimesh, pccColliderCache->defaultBoxCache); // Retrieve data int TriCount = Collider.GetNbTouchedPrimitives(); if (TriCount != 0) { const int* Triangles = (const int*)Collider.GetTouchedPrimitives(); if (Trimesh->ArrayCallback != null) { Trimesh->ArrayCallback(Trimesh, Cylinder, Triangles, TriCount); } // allocate buffer for local contacts on stack cData.m_gLocalContacts = (sLocalContactData*)dALLOCA16(sizeof(sLocalContactData)*(cData.m_iFlags & NUMC_MASK)); int ctContacts0 = 0; // loop through all intersecting triangles for (int i = 0; i < TriCount; i++) { const int Triint = Triangles[i]; if (!Callback(Trimesh, Cylinder, Triint)) continue; dVector3 dv[3]; FetchTriangle(Trimesh, Triint, cData.m_vTrimeshPos, cData.m_mTrimeshRot, dv); bool bFinishSearching; ctContacts0 = cData.TestCollisionForSingleTriangle(ctContacts0, Triint, dv, bFinishSearching); if (bFinishSearching) { break; } } if (cData.m_nContacts != 0) { nContactCount = cData._ProcessLocalContacts(contact, Cylinder, Trimesh); } } return nContactCount; } #endif // GIMPACT version of cylinder to mesh collider #if dTRIMESH_GIMPACT int dCollideCylinderTrimesh(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT( skip >= (int)sizeof( dContactGeom ) ); dIASSERT( o1->type == dCylinderClass ); dIASSERT( o2->type == dTriMeshClass ); dIASSERT ((flags & NUMC_MASK) >= 1); int nContactCount = 0; dxGeom *Cylinder = o1; dxTriMesh *Trimesh = (dxTriMesh *)o2; // Main data holder sCylinderTrimeshColliderData cData(flags, skip); cData._InitCylinderTrimeshData(Cylinder, Trimesh); //*****at first , collide box aabb******// aabb3f test_aabb; test_aabb.minX = o1->aabb[0]; test_aabb.maxX = o1->aabb[1]; test_aabb.minY = o1->aabb[2]; test_aabb.maxY = o1->aabb[3]; test_aabb.minZ = o1->aabb[4]; test_aabb.maxZ = o1->aabb[5]; GDYNAMIC_ARRAY collision_result; GIM_CREATE_BOXQUERY_LIST(collision_result); gim_aabbset_box_collision(&test_aabb, &Trimesh->m_collision_trimesh.m_aabbset , &collision_result); if (collision_result.m_size != 0) { //*****Set globals for box collision******// int ctContacts0 = 0; cData.m_gLocalContacts = (sLocalContactData*)dALLOCA16(sizeof(sLocalContactData)*(cData.m_iFlags & NUMC_MASK)); GUINT32 * boxesresult = GIM_DYNARRAY_POINTER(GUINT32,collision_result); GIM_TRIMESH * ptrimesh = &Trimesh->m_collision_trimesh; gim_trimesh_locks_work_data(ptrimesh); for(unsigned int i=0;i #include #include #include #include #include "collision_kernel.h" #include "collision_std.h" #include "collision_util.h" #ifdef _MSC_VER #pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" #endif //**************************************************************************** // sphere public API dxSphere::dxSphere (dSpaceID space, dReal _radius) : dxGeom (space,1) { dAASSERT (_radius >= 0); type = dSphereClass; radius = _radius; updateZeroSizedFlag(!_radius); } void dxSphere::computeAABB() { aabb[0] = final_posr->pos[0] - radius; aabb[1] = final_posr->pos[0] + radius; aabb[2] = final_posr->pos[1] - radius; aabb[3] = final_posr->pos[1] + radius; aabb[4] = final_posr->pos[2] - radius; aabb[5] = final_posr->pos[2] + radius; } dGeomID dCreateSphere (dSpaceID space, dReal radius) { return new dxSphere (space,radius); } void dGeomSphereSetRadius (dGeomID g, dReal radius) { dUASSERT (g && g->type == dSphereClass,"argument not a sphere"); dAASSERT (radius >= 0); dxSphere *s = (dxSphere*) g; s->radius = radius; s->updateZeroSizedFlag(!radius); dGeomMoved (g); } dReal dGeomSphereGetRadius (dGeomID g) { dUASSERT (g && g->type == dSphereClass,"argument not a sphere"); dxSphere *s = (dxSphere*) g; return s->radius; } dReal dGeomSpherePointDepth (dGeomID g, dReal x, dReal y, dReal z) { dUASSERT (g && g->type == dSphereClass,"argument not a sphere"); g->recomputePosr(); dxSphere *s = (dxSphere*) g; dReal * pos = s->final_posr->pos; return s->radius - dSqrt ((x-pos[0])*(x-pos[0]) + (y-pos[1])*(y-pos[1]) + (z-pos[2])*(z-pos[2])); } //**************************************************************************** // pairwise collision functions for standard geom types int dCollideSphereSphere (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT (o1->type == dSphereClass); dIASSERT (o2->type == dSphereClass); dIASSERT ((flags & NUMC_MASK) >= 1); dxSphere *sphere1 = (dxSphere*) o1; dxSphere *sphere2 = (dxSphere*) o2; contact->g1 = o1; contact->g2 = o2; contact->side1 = -1; contact->side2 = -1; return dCollideSpheres (o1->final_posr->pos,sphere1->radius, o2->final_posr->pos,sphere2->radius,contact); } int dCollideSphereBox (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT (o1->type == dSphereClass); dIASSERT (o2->type == dBoxClass); dIASSERT ((flags & NUMC_MASK) >= 1); // this is easy. get the sphere center `p' relative to the box, and then clip // that to the boundary of the box (call that point `q'). if q is on the // boundary of the box and |p-q| is <= sphere radius, they touch. // if q is inside the box, the sphere is inside the box, so set a contact // normal to push the sphere to the closest box face. dVector3 l,t,p,q,r; dReal depth; int onborder = 0; dxSphere *sphere = (dxSphere*) o1; dxBox *box = (dxBox*) o2; contact->g1 = o1; contact->g2 = o2; contact->side1 = -1; contact->side2 = -1; p[0] = o1->final_posr->pos[0] - o2->final_posr->pos[0]; p[1] = o1->final_posr->pos[1] - o2->final_posr->pos[1]; p[2] = o1->final_posr->pos[2] - o2->final_posr->pos[2]; l[0] = box->side[0]*REAL(0.5); t[0] = dDOT14(p,o2->final_posr->R); if (t[0] < -l[0]) { t[0] = -l[0]; onborder = 1; } if (t[0] > l[0]) { t[0] = l[0]; onborder = 1; } l[1] = box->side[1]*REAL(0.5); t[1] = dDOT14(p,o2->final_posr->R+1); if (t[1] < -l[1]) { t[1] = -l[1]; onborder = 1; } if (t[1] > l[1]) { t[1] = l[1]; onborder = 1; } t[2] = dDOT14(p,o2->final_posr->R+2); l[2] = box->side[2]*REAL(0.5); if (t[2] < -l[2]) { t[2] = -l[2]; onborder = 1; } if (t[2] > l[2]) { t[2] = l[2]; onborder = 1; } if (!onborder) { // sphere center inside box. find closest face to `t' dReal min_distance = l[0] - dFabs(t[0]); int mini = 0; for (int i=1; i<3; i++) { dReal face_distance = l[i] - dFabs(t[i]); if (face_distance < min_distance) { min_distance = face_distance; mini = i; } } // contact position = sphere center contact->pos[0] = o1->final_posr->pos[0]; contact->pos[1] = o1->final_posr->pos[1]; contact->pos[2] = o1->final_posr->pos[2]; // contact normal points to closest face dVector3 tmp; tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[mini] = (t[mini] > 0) ? REAL(1.0) : REAL(-1.0); dMULTIPLY0_331 (contact->normal,o2->final_posr->R,tmp); // contact depth = distance to wall along normal plus radius contact->depth = min_distance + sphere->radius; return 1; } t[3] = 0; //@@@ hmmm dMULTIPLY0_331 (q,o2->final_posr->R,t); r[0] = p[0] - q[0]; r[1] = p[1] - q[1]; r[2] = p[2] - q[2]; depth = sphere->radius - dSqrt(dDOT(r,r)); if (depth < 0) return 0; contact->pos[0] = q[0] + o2->final_posr->pos[0]; contact->pos[1] = q[1] + o2->final_posr->pos[1]; contact->pos[2] = q[2] + o2->final_posr->pos[2]; contact->normal[0] = r[0]; contact->normal[1] = r[1]; contact->normal[2] = r[2]; dNormalize3 (contact->normal); contact->depth = depth; return 1; } int dCollideSpherePlane (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) { dIASSERT (skip >= (int)sizeof(dContactGeom)); dIASSERT (o1->type == dSphereClass); dIASSERT (o2->type == dPlaneClass); dIASSERT ((flags & NUMC_MASK) >= 1); dxSphere *sphere = (dxSphere*) o1; dxPlane *plane = (dxPlane*) o2; contact->g1 = o1; contact->g2 = o2; contact->side1 = -1; contact->side2 = -1; dReal k = dDOT (o1->final_posr->pos,plane->p); dReal depth = plane->p[3] - k + sphere->radius; if (depth >= 0) { contact->normal[0] = plane->p[0]; contact->normal[1] = plane->p[1]; contact->normal[2] = plane->p[2]; contact->pos[0] = o1->final_posr->pos[0] - plane->p[0] * sphere->radius; contact->pos[1] = o1->final_posr->pos[1] - plane->p[1] * sphere->radius; contact->pos[2] = o1->final_posr->pos[2] - plane->p[2] * sphere->radius; contact->depth = depth; return 1; } else return 0; } alien-arena-7.66+dfsg/source/unix/odesrc/step.h0000600000175000017500000000340012161402010020465 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #ifndef _ODE_STEP_H_ #define _ODE_STEP_H_ #include void dInternalStepIsland (dxWorld *world, dxBody * const *body, int nb, dxJoint * const *joint, int nj, dReal stepsize); #endif alien-arena-7.66+dfsg/source/unix/odesrc/quickstep.cpp0000600000175000017500000006316712161402010022075 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include "objects.h" #include "joints/joint.h" #include #include "config.h" #include #include #include #include #include #include #include "lcp.h" #include "util.h" #define ALLOCA dALLOCA16 typedef const dReal *dRealPtr; typedef dReal *dRealMutablePtr; #define dRealAllocaArray(name,n) dReal *name = (dReal*) ALLOCA ((n)*sizeof(dReal)); //*************************************************************************** // configuration // for the SOR and CG methods: // uncomment the following line to use warm starting. this definitely // help for motor-driven joints. unfortunately it appears to hurt // with high-friction contacts using the SOR method. use with care //#define WARM_STARTING 1 // for the SOR method: // uncomment the following line to determine a new constraint-solving // order for each iteration. however, the qsort per iteration is expensive, // and the optimal order is somewhat problem dependent. // @@@ try the leaf->root ordering. //#define REORDER_CONSTRAINTS 1 // for the SOR method: // uncomment the following line to randomly reorder constraint rows // during the solution. depending on the situation, this can help a lot // or hardly at all, but it doesn't seem to hurt. #define RANDOMLY_REORDER_CONSTRAINTS 1 //**************************************************************************** // special matrix multipliers // multiply block of B matrix (q x 6) with 12 dReal per row with C vektor (q) static void Multiply1_12q1 (dReal *A, dReal *B, dReal *C, int q) { int i, k; dIASSERT (q>0 && A && B && C); dReal a = 0; dReal b = 0; dReal c = 0; dReal d = 0; dReal e = 0; dReal f = 0; dReal s; for(i=0, k = 0; iinvMass; for (j=0; j<3; j++) iMJ_ptr[j] = k*J_ptr[j]; dMULTIPLY0_331 (iMJ_ptr + 3, invI + 12*b1, J_ptr + 3); if (b2 >= 0) { k = body[b2]->invMass; for (j=0; j<3; j++) iMJ_ptr[j+6] = k*J_ptr[j+6]; dMULTIPLY0_331 (iMJ_ptr + 9, invI + 12*b2, J_ptr + 9); } J_ptr += 12; iMJ_ptr += 12; } } // compute out = inv(M)*J'*in. #if 0 static void multiply_invM_JT (int m, int nb, dRealMutablePtr iMJ, int *jb, dRealMutablePtr in, dRealMutablePtr out) { int i,j; dSetZero (out,6*nb); dRealPtr iMJ_ptr = iMJ; for (i=0; i= 0) { out_ptr = out + b2*6; for (j=0; j<6; j++) out_ptr[j] += iMJ_ptr[j] * in[i]; } iMJ_ptr += 6; } } #endif // compute out = J*in. static void multiply_J (int m, dRealMutablePtr J, int *jb, dRealMutablePtr in, dRealMutablePtr out) { int i,j; dRealPtr J_ptr = J; for (i=0; i= 0) { in_ptr = in + b2*6; for (j=0; j<6; j++) sum += J_ptr[j] * in_ptr[j]; } J_ptr += 6; out[i] = sum; } } // compute out = (J*inv(M)*J' + cfm)*in. // use z as an nb*6 temporary. #if 0 static void multiply_J_invM_JT (int m, int nb, dRealMutablePtr J, dRealMutablePtr iMJ, int *jb, dRealPtr cfm, dRealMutablePtr z, dRealMutablePtr in, dRealMutablePtr out) { multiply_invM_JT (m,nb,iMJ,jb,in,z); multiply_J (m,J,jb,z,out); // add cfm for (int i=0; inum_iterations; // precompute iMJ = inv(M)*J' dRealAllocaArray (iMJ,m*12); compute_invM_JT (m,J,iMJ,jb,body,invI); dReal last_rho = 0; dRealAllocaArray (r,m); dRealAllocaArray (z,m); dRealAllocaArray (p,m); dRealAllocaArray (q,m); // precompute 1 / diagonals of A dRealAllocaArray (Ad,m); dRealPtr iMJ_ptr = iMJ; dRealPtr J_ptr = J; for (i=0; i= 0) { for (j=6; j<12; j++) sum += iMJ_ptr[j] * J_ptr[j]; } iMJ_ptr += 12; J_ptr += 12; Ad[i] = REAL(1.0) / (sum + cfm[i]); } #ifdef WARM_STARTING // compute residual r = b - A*lambda multiply_J_invM_JT (m,nb,J,iMJ,jb,cfm,fc,lambda,r); for (i=0; ifindex < 0 && i2->findex >= 0) return -1; if (i1->findex >= 0 && i2->findex < 0) return 1; if (i1->error < i2->error) return -1; if (i1->error > i2->error) return 1; return 0; } #endif static void SOR_LCP (int m, int nb, dRealMutablePtr J, int *jb, dxBody * const *body, dRealPtr invI, dRealMutablePtr lambda, dRealMutablePtr fc, dRealMutablePtr b, dRealMutablePtr lo, dRealMutablePtr hi, dRealPtr cfm, int *findex, dxQuickStepParameters *qs) { const int num_iterations = qs->num_iterations; const dReal sor_w = qs->w; // SOR over-relaxation parameter int i,j; #ifdef WARM_STARTING // for warm starting, this seems to be necessary to prevent // jerkiness in motor-driven joints. i have no idea why this works. for (i=0; i= 0) { for (j=6; j<12; j++) sum += iMJ_ptr[j] * J_ptr[j]; } iMJ_ptr += 12; J_ptr += 12; Ad[i] = sor_w / (sum + cfm[i]); } // scale J and b by Ad J_ptr = J; for (i=0; i v2) ? v1 : v2; if (max > 0) { //@@@ relative error: order[i].error = dFabs(lambda[i]-last_lambda[i])/max; order[i].error = dFabs(lambda[i]-last_lambda[i]); } else { order[i].error = dInfinity; } order[i].findex = findex[i]; order[i].index = i; } } qsort (order,m,sizeof(IndexError),&compare_index_error); //@@@ potential optimization: swap lambda and last_lambda pointers rather // than copying the data. we must make sure lambda is properly // returned to the caller memcpy (last_lambda,lambda,m*sizeof(dReal)); #endif #ifdef RANDOMLY_REORDER_CONSTRAINTS if ((iteration & 7) == 0) { for (i=1; i= 0) { hi[index] = dFabs (hicopy[index] * lambda[findex[index]]); lo[index] = -hi[index]; } int b1 = jb[index*2]; int b2 = jb[index*2+1]; dReal delta = b[index] - lambda[index]*Ad[index]; dRealMutablePtr fc_ptr = fc + 6*b1; // @@@ potential optimization: SIMD-ize this and the b2 >= 0 case delta -=fc_ptr[0] * J_ptr[0] + fc_ptr[1] * J_ptr[1] + fc_ptr[2] * J_ptr[2] + fc_ptr[3] * J_ptr[3] + fc_ptr[4] * J_ptr[4] + fc_ptr[5] * J_ptr[5]; // @@@ potential optimization: handle 1-body constraints in a separate // loop to avoid the cost of test & jump? if (b2 >= 0) { fc_ptr = fc + 6*b2; delta -=fc_ptr[0] * J_ptr[6] + fc_ptr[1] * J_ptr[7] + fc_ptr[2] * J_ptr[8] + fc_ptr[3] * J_ptr[9] + fc_ptr[4] * J_ptr[10] + fc_ptr[5] * J_ptr[11]; } // compute lambda and clamp it to [lo,hi]. // @@@ potential optimization: does SSE have clamping instructions // to save test+jump penalties here? dReal new_lambda = lambda[index] + delta; if (new_lambda < lo[index]) { delta = lo[index]-lambda[index]; lambda[index] = lo[index]; } else if (new_lambda > hi[index]) { delta = hi[index]-lambda[index]; lambda[index] = hi[index]; } else { lambda[index] = new_lambda; } //@@@ a trick that may or may not help //dReal ramp = (1-((dReal)(iteration+1)/(dReal)num_iterations)); //delta *= ramp; // update fc. // @@@ potential optimization: SIMD for this and the b2 >= 0 case fc_ptr = fc + 6*b1; fc_ptr[0] += delta * iMJ_ptr[0]; fc_ptr[1] += delta * iMJ_ptr[1]; fc_ptr[2] += delta * iMJ_ptr[2]; fc_ptr[3] += delta * iMJ_ptr[3]; fc_ptr[4] += delta * iMJ_ptr[4]; fc_ptr[5] += delta * iMJ_ptr[5]; // @@@ potential optimization: handle 1-body constraints in a separate // loop to avoid the cost of test & jump? if (b2 >= 0) { fc_ptr = fc + 6*b2; fc_ptr[0] += delta * iMJ_ptr[6]; fc_ptr[1] += delta * iMJ_ptr[7]; fc_ptr[2] += delta * iMJ_ptr[8]; fc_ptr[3] += delta * iMJ_ptr[9]; fc_ptr[4] += delta * iMJ_ptr[10]; fc_ptr[5] += delta * iMJ_ptr[11]; } } } } void dxQuickStepper (dxWorld *world, dxBody * const *body, int nb, dxJoint * const *_joint, int nj, dReal stepsize) { int i,j; IFTIMING(dTimerStart("preprocessing");) dReal stepsize1 = dRecip(stepsize); // number all bodies in the body list - set their tag values for (i=0; itag = i; // make a local copy of the joint array, because we might want to modify it. // (the "dxJoint *const*" declaration says we're allowed to modify the joints // but not the joint array, because the caller might need it unchanged). //@@@ do we really need to do this? we'll be sorting constraint rows individually, not joints dxJoint **joint = (dxJoint**) ALLOCA (nj * sizeof(dxJoint*)); memcpy (joint,_joint,nj * sizeof(dxJoint*)); // for all bodies, compute the inertia tensor and its inverse in the global // frame, and compute the rotational force and add it to the torque // accumulator. I and invI are a vertical stack of 3x4 matrices, one per body. dRealAllocaArray (invI,3*4*nb); for (i=0; iinvI,body[i]->posr.R); dMULTIPLY0_333 (invI+i*12,body[i]->posr.R,tmp); if (body[i]->flags & dxBodyGyroscopic) { dMatrix3 I; // compute inertia tensor in global frame dMULTIPLY2_333 (tmp,body[i]->mass.I,body[i]->posr.R); dMULTIPLY0_333 (I,body[i]->posr.R,tmp); // compute rotational force dMULTIPLY0_331 (tmp,I,body[i]->avel); dCROSS (body[i]->tacc,-=,body[i]->avel,tmp); } } // add the gravity force to all bodies for (i=0; iflags & dxBodyNoGravity)==0) { body[i]->facc[0] += body[i]->mass.mass * world->gravity[0]; body[i]->facc[1] += body[i]->mass.mass * world->gravity[1]; body[i]->facc[2] += body[i]->mass.mass * world->gravity[2]; } } // get joint information (m = total constraint dimension, nub = number of unbounded variables). // joints with m=0 are inactive and are removed from the joints array // entirely, so that the code that follows does not consider them. //@@@ do we really need to save all the info1's dxJoint::Info1 *info = (dxJoint::Info1*) ALLOCA (nj*sizeof(dxJoint::Info1)); for (i=0, j=0; jgetInfo1 (info+i); dIASSERT (info[i].m >= 0 && info[i].m <= 6 && info[i].nub >= 0 && info[i].nub <= info[i].m); if (info[i].m > 0) { joint[i] = joint[j]; i++; } } nj = i; // create the row offset array int m = 0; int *ofs = (int*) ALLOCA (nj*sizeof(int)); for (i=0; i 0) { // create a constraint equation right hand side vector `c', a constraint // force mixing vector `cfm', and LCP low and high bound vectors, and an // 'findex' vector. dRealAllocaArray (c,m); dRealAllocaArray (cfm,m); dRealAllocaArray (lo,m); dRealAllocaArray (hi,m); int *findex = (int*) ALLOCA (m*sizeof(int)); dSetZero (c,m); dSetValue (cfm,m,world->global_cfm); dSetValue (lo,m,-dInfinity); dSetValue (hi,m, dInfinity); for (i=0; iglobal_erp; int mfb = 0; // number of rows of Jacobian we will have to save for joint feedback for (i=0; igetInfo2 (&Jinfo); // adjust returned findex values for global index numbering for (j=0; j= 0) findex[ofs[i] + j] += ofs[i]; } if (joint[i]->feedback) mfb += info[i].m; } // we need a copy of Jacobian for joint feedbacks // because it gets destroyed by SOR solver // instead of saving all Jacobian, we can save just rows // for joints, that requested feedback (which is normaly much less) dReal *Jcopy = NULL; if (mfb > 0) { Jcopy = (dReal*) ALLOCA (mfb*12*sizeof(dReal)); mfb = 0; for (i=0; ifeedback) { memcpy(Jcopy+mfb*12, J+ofs[i]*12, info[i].m*12*sizeof(dReal)); mfb += info[i].m; } } // create an array of body numbers for each joint row int *jb_ptr = jb; for (i=0; inode[0].body) ? (joint[i]->node[0].body->tag) : -1; int b2 = (joint[i]->node[1].body) ? (joint[i]->node[1].body->tag) : -1; for (j=0; jinvMass; for (j=0; j<3; j++) tmp1[i*6+j] = body[i]->facc[j] * body_invMass + body[i]->lvel[j] * stepsize1; dMULTIPLY0_331 (tmp1 + i*6 + 3,invI + i*12,body[i]->tacc); for (j=0; j<3; j++) tmp1[i*6+3+j] += body[i]->avel[j] * stepsize1; } // put J*tmp1 into rhs dRealAllocaArray (rhs,m); multiply_J (m,J,jb,tmp1,rhs); // complete rhs for (i=0; ilambda,info[i].m * sizeof(dReal)); } #endif // solve the LCP problem and get lambda and invM*constraint_force IFTIMING (dTimerNow ("solving LCP problem");) dRealAllocaArray (cforce,nb*6); SOR_LCP (m,nb,J,jb,body,invI,lambda,cforce,rhs,lo,hi,cfm,findex,&world->qs); #ifdef WARM_STARTING // save lambda for the next iteration //@@@ note that this doesn't work for contact joints yet, as they are // recreated every iteration for (i=0; ilambda,lambda+ofs[i],info[i].m * sizeof(dReal)); } #endif // note that the SOR method overwrites rhs and J at this point, so // they should not be used again. // add stepsize * cforce to the body velocity for (i=0; ilvel[j] += stepsize * cforce[i*6+j]; for (j=0; j<3; j++) body[i]->avel[j] += stepsize * cforce[i*6+3+j]; } if (mfb > 0) { // straightforward computation of joint constraint forces: // multiply related lambdas with respective J' block for joints // where feedback was requested mfb = 0; for (i=0; ifeedback) { dJointFeedback *fb = joint[i]->feedback; dReal data[6]; Multiply1_12q1 (data, Jcopy+mfb*12, lambda+ofs[i], info[i].m); fb->f1[0] = data[0]; fb->f1[1] = data[1]; fb->f1[2] = data[2]; fb->t1[0] = data[3]; fb->t1[1] = data[4]; fb->t1[2] = data[5]; if (joint[i]->node[1].body) { Multiply1_12q1 (data, Jcopy+mfb*12+6, lambda+ofs[i], info[i].m); fb->f2[0] = data[0]; fb->f2[1] = data[1]; fb->f2[2] = data[2]; fb->t2[0] = data[3]; fb->t2[1] = data[4]; fb->t2[2] = data[5]; } mfb += info[i].m; } } } } // compute the velocity update: // add stepsize * invM * fe to the body velocity IFTIMING (dTimerNow ("compute velocity update");) for (i=0; iinvMass; for (j=0; j<3; j++) body[i]->lvel[j] += stepsize * body_invMass * body[i]->facc[j]; for (j=0; j<3; j++) body[i]->tacc[j] *= stepsize; dMULTIPLYADD0_331 (body[i]->avel,invI + i*12,body[i]->tacc); } #if 0 // check that the updated velocity obeys the constraint (this check needs unmodified J) dRealAllocaArray (vel,nb*6); for (i=0; ilvel[j]; for (j=0; j<3; j++) vel[i*6+3+j] = body[i]->avel[j]; } dRealAllocaArray (tmp,m); multiply_J (m,J,jb,vel,tmp); dReal error = 0; for (i=0; ifacc,3); dSetZero (body[i]->tacc,3); } IFTIMING (dTimerEnd();) IFTIMING (if (m > 0) dTimerReport (stdout,1);) } alien-arena-7.66+dfsg/source/unix/odesrc/collision_trimesh_distance.cpp0000600000175000017500000011241412161402010025453 0ustar zero79zero79// This file contains some code based on the code from Magic Software. // That code is available under a Free Source License Agreement // that can be found at http://www.magic-software.com/License/free.pdf #include #include #include #include "collision_trimesh_internal.h" //------------------------------------------------------------------------------ /** @brief Finds the shortest distance squared between a point and a triangle. @param pfSParam Barycentric coordinate of triangle at point closest to p (u) @param pfTParam Barycentric coordinate of triangle at point closest to p (v) @return Shortest distance squared. The third Barycentric coordinate is implicit, ie. w = 1.0 - u - v Taken from: Magic Software, Inc. http://www.magic-software.com */ dReal SqrDistancePointTri( const dVector3 p, const dVector3 triOrigin, const dVector3 triEdge0, const dVector3 triEdge1, dReal* pfSParam, dReal* pfTParam ) { dVector3 kDiff; Vector3Subtract( triOrigin, p, kDiff ); dReal fA00 = dDOT( triEdge0, triEdge0 ); dReal fA01 = dDOT( triEdge0, triEdge1 ); dReal fA11 = dDOT( triEdge1, triEdge1 ); dReal fB0 = dDOT( kDiff, triEdge0 ); dReal fB1 = dDOT( kDiff, triEdge1 ); dReal fC = dDOT( kDiff, kDiff ); dReal fDet = dReal(fabs(fA00*fA11-fA01*fA01)); dReal fS = fA01*fB1-fA11*fB0; dReal fT = fA01*fB0-fA00*fB1; dReal fSqrDist; if ( fS + fT <= fDet ) { if ( fS < REAL(0.0) ) { if ( fT < REAL(0.0) ) // region 4 { if ( fB0 < REAL(0.0) ) { fT = REAL(0.0); if ( -fB0 >= fA00 ) { fS = REAL(1.0); fSqrDist = fA00+REAL(2.0)*fB0+fC; } else { fS = -fB0/fA00; fSqrDist = fB0*fS+fC; } } else { fS = REAL(0.0); if ( fB1 >= REAL(0.0) ) { fT = REAL(0.0); fSqrDist = fC; } else if ( -fB1 >= fA11 ) { fT = REAL(1.0); fSqrDist = fA11+REAL(2.0)*fB1+fC; } else { fT = -fB1/fA11; fSqrDist = fB1*fT+fC; } } } else // region 3 { fS = REAL(0.0); if ( fB1 >= REAL(0.0) ) { fT = REAL(0.0); fSqrDist = fC; } else if ( -fB1 >= fA11 ) { fT = REAL(1.0); fSqrDist = fA11+REAL(2.0)*fB1+fC; } else { fT = -fB1/fA11; fSqrDist = fB1*fT+fC; } } } else if ( fT < REAL(0.0) ) // region 5 { fT = REAL(0.0); if ( fB0 >= REAL(0.0) ) { fS = REAL(0.0); fSqrDist = fC; } else if ( -fB0 >= fA00 ) { fS = REAL(1.0); fSqrDist = fA00+REAL(2.0)*fB0+fC; } else { fS = -fB0/fA00; fSqrDist = fB0*fS+fC; } } else // region 0 { // minimum at interior point if ( fDet == REAL(0.0) ) { fS = REAL(0.0); fT = REAL(0.0); fSqrDist = dInfinity; } else { dReal fInvDet = REAL(1.0)/fDet; fS *= fInvDet; fT *= fInvDet; fSqrDist = fS*(fA00*fS+fA01*fT+REAL(2.0)*fB0) + fT*(fA01*fS+fA11*fT+REAL(2.0)*fB1)+fC; } } } else { dReal fTmp0, fTmp1, fNumer, fDenom; if ( fS < REAL(0.0) ) // region 2 { fTmp0 = fA01 + fB0; fTmp1 = fA11 + fB1; if ( fTmp1 > fTmp0 ) { fNumer = fTmp1 - fTmp0; fDenom = fA00-REAL(2.0)*fA01+fA11; if ( fNumer >= fDenom ) { fS = REAL(1.0); fT = REAL(0.0); fSqrDist = fA00+REAL(2.0)*fB0+fC; } else { fS = fNumer/fDenom; fT = REAL(1.0) - fS; fSqrDist = fS*(fA00*fS+fA01*fT+REAL(2.0)*fB0) + fT*(fA01*fS+fA11*fT+REAL(2.0)*fB1)+fC; } } else { fS = REAL(0.0); if ( fTmp1 <= REAL(0.0) ) { fT = REAL(1.0); fSqrDist = fA11+REAL(2.0)*fB1+fC; } else if ( fB1 >= REAL(0.0) ) { fT = REAL(0.0); fSqrDist = fC; } else { fT = -fB1/fA11; fSqrDist = fB1*fT+fC; } } } else if ( fT < REAL(0.0) ) // region 6 { fTmp0 = fA01 + fB1; fTmp1 = fA00 + fB0; if ( fTmp1 > fTmp0 ) { fNumer = fTmp1 - fTmp0; fDenom = fA00-REAL(2.0)*fA01+fA11; if ( fNumer >= fDenom ) { fT = REAL(1.0); fS = REAL(0.0); fSqrDist = fA11+REAL(2.0)*fB1+fC; } else { fT = fNumer/fDenom; fS = REAL(1.0) - fT; fSqrDist = fS*(fA00*fS+fA01*fT+REAL(2.0)*fB0) + fT*(fA01*fS+fA11*fT+REAL(2.0)*fB1)+fC; } } else { fT = REAL(0.0); if ( fTmp1 <= REAL(0.0) ) { fS = REAL(1.0); fSqrDist = fA00+REAL(2.0)*fB0+fC; } else if ( fB0 >= REAL(0.0) ) { fS = REAL(0.0); fSqrDist = fC; } else { fS = -fB0/fA00; fSqrDist = fB0*fS+fC; } } } else // region 1 { fNumer = fA11 + fB1 - fA01 - fB0; if ( fNumer <= REAL(0.0) ) { fS = REAL(0.0); fT = REAL(1.0); fSqrDist = fA11+REAL(2.0)*fB1+fC; } else { fDenom = fA00-REAL(2.0)*fA01+fA11; if ( fNumer >= fDenom ) { fS = REAL(1.0); fT = REAL(0.0); fSqrDist = fA00+REAL(2.0)*fB0+fC; } else { fS = fNumer/fDenom; fT = REAL(1.0) - fS; fSqrDist = fS*(fA00*fS+fA01*fT+REAL(2.0)*fB0) + fT*(fA01*fS+fA11*fT+REAL(2.0)*fB1)+fC; } } } } if ( pfSParam ) *pfSParam = (float)fS; if ( pfTParam ) *pfTParam = (float)fT; return dReal(fabs(fSqrDist)); } //------------------------------------------------------------------------------ /** @brief Finds the shortest distance squared between two line segments. @param pfSegP0 t value for seg1 where the shortest distance between the segments exists. @param pfSegP0 t value for seg2 where the shortest distance between the segments exists. @return Shortest distance squared. Taken from: Magic Software, Inc. http://www.magic-software.com */ dReal SqrDistanceSegments( const dVector3 seg1Origin, const dVector3 seg1Direction, const dVector3 seg2Origin, const dVector3 seg2Direction, dReal* pfSegP0, dReal* pfSegP1 ) { const dReal gs_fTolerance = 1e-05f; dVector3 kDiff, kNegDiff, seg1NegDirection; Vector3Subtract( seg1Origin, seg2Origin, kDiff ); Vector3Negate( kDiff, kNegDiff ); dReal fA00 = dDOT( seg1Direction, seg1Direction ); Vector3Negate( seg1Direction, seg1NegDirection ); dReal fA01 = dDOT( seg1NegDirection, seg2Direction ); dReal fA11 = dDOT( seg2Direction, seg2Direction ); dReal fB0 = dDOT( kDiff, seg1Direction ); dReal fC = dDOT( kDiff, kDiff ); dReal fDet = dReal(fabs(fA00*fA11-fA01*fA01)); dReal fB1, fS, fT, fSqrDist, fTmp; if ( fDet >= gs_fTolerance ) { // line segments are not parallel fB1 = dDOT( kNegDiff, seg2Direction ); fS = fA01*fB1-fA11*fB0; fT = fA01*fB0-fA00*fB1; if ( fS >= REAL(0.0) ) { if ( fS <= fDet ) { if ( fT >= REAL(0.0) ) { if ( fT <= fDet ) // region 0 (interior) { // minimum at two interior points of 3D lines dReal fInvDet = REAL(1.0)/fDet; fS *= fInvDet; fT *= fInvDet; fSqrDist = fS*(fA00*fS+fA01*fT+REAL(2.0)*fB0) + fT*(fA01*fS+fA11*fT+REAL(2.0)*fB1)+fC; } else // region 3 (side) { fT = REAL(1.0); fTmp = fA01+fB0; if ( fTmp >= REAL(0.0) ) { fS = REAL(0.0); fSqrDist = fA11+REAL(2.0)*fB1+fC; } else if ( -fTmp >= fA00 ) { fS = REAL(1.0); fSqrDist = fA00+fA11+fC+REAL(2.0)*(fB1+fTmp); } else { fS = -fTmp/fA00; fSqrDist = fTmp*fS+fA11+REAL(2.0)*fB1+fC; } } } else // region 7 (side) { fT = REAL(0.0); if ( fB0 >= REAL(0.0) ) { fS = REAL(0.0); fSqrDist = fC; } else if ( -fB0 >= fA00 ) { fS = REAL(1.0); fSqrDist = fA00+REAL(2.0)*fB0+fC; } else { fS = -fB0/fA00; fSqrDist = fB0*fS+fC; } } } else { if ( fT >= REAL(0.0) ) { if ( fT <= fDet ) // region 1 (side) { fS = REAL(1.0); fTmp = fA01+fB1; if ( fTmp >= REAL(0.0) ) { fT = REAL(0.0); fSqrDist = fA00+REAL(2.0)*fB0+fC; } else if ( -fTmp >= fA11 ) { fT = REAL(1.0); fSqrDist = fA00+fA11+fC+REAL(2.0)*(fB0+fTmp); } else { fT = -fTmp/fA11; fSqrDist = fTmp*fT+fA00+REAL(2.0)*fB0+fC; } } else // region 2 (corner) { fTmp = fA01+fB0; if ( -fTmp <= fA00 ) { fT = REAL(1.0); if ( fTmp >= REAL(0.0) ) { fS = REAL(0.0); fSqrDist = fA11+REAL(2.0)*fB1+fC; } else { fS = -fTmp/fA00; fSqrDist = fTmp*fS+fA11+REAL(2.0)*fB1+fC; } } else { fS = REAL(1.0); fTmp = fA01+fB1; if ( fTmp >= REAL(0.0) ) { fT = REAL(0.0); fSqrDist = fA00+REAL(2.0)*fB0+fC; } else if ( -fTmp >= fA11 ) { fT = REAL(1.0); fSqrDist = fA00+fA11+fC+REAL(2.0)*(fB0+fTmp); } else { fT = -fTmp/fA11; fSqrDist = fTmp*fT+fA00+REAL(2.0)*fB0+fC; } } } } else // region 8 (corner) { if ( -fB0 < fA00 ) { fT = REAL(0.0); if ( fB0 >= REAL(0.0) ) { fS = REAL(0.0); fSqrDist = fC; } else { fS = -fB0/fA00; fSqrDist = fB0*fS+fC; } } else { fS = REAL(1.0); fTmp = fA01+fB1; if ( fTmp >= REAL(0.0) ) { fT = REAL(0.0); fSqrDist = fA00+REAL(2.0)*fB0+fC; } else if ( -fTmp >= fA11 ) { fT = REAL(1.0); fSqrDist = fA00+fA11+fC+REAL(2.0)*(fB0+fTmp); } else { fT = -fTmp/fA11; fSqrDist = fTmp*fT+fA00+REAL(2.0)*fB0+fC; } } } } } else { if ( fT >= REAL(0.0) ) { if ( fT <= fDet ) // region 5 (side) { fS = REAL(0.0); if ( fB1 >= REAL(0.0) ) { fT = REAL(0.0); fSqrDist = fC; } else if ( -fB1 >= fA11 ) { fT = REAL(1.0); fSqrDist = fA11+REAL(2.0)*fB1+fC; } else { fT = -fB1/fA11; fSqrDist = fB1*fT+fC; } } else // region 4 (corner) { fTmp = fA01+fB0; if ( fTmp < REAL(0.0) ) { fT = REAL(1.0); if ( -fTmp >= fA00 ) { fS = REAL(1.0); fSqrDist = fA00+fA11+fC+REAL(2.0)*(fB1+fTmp); } else { fS = -fTmp/fA00; fSqrDist = fTmp*fS+fA11+REAL(2.0)*fB1+fC; } } else { fS = REAL(0.0); if ( fB1 >= REAL(0.0) ) { fT = REAL(0.0); fSqrDist = fC; } else if ( -fB1 >= fA11 ) { fT = REAL(1.0); fSqrDist = fA11+REAL(2.0)*fB1+fC; } else { fT = -fB1/fA11; fSqrDist = fB1*fT+fC; } } } } else // region 6 (corner) { if ( fB0 < REAL(0.0) ) { fT = REAL(0.0); if ( -fB0 >= fA00 ) { fS = REAL(1.0); fSqrDist = fA00+REAL(2.0)*fB0+fC; } else { fS = -fB0/fA00; fSqrDist = fB0*fS+fC; } } else { fS = REAL(0.0); if ( fB1 >= REAL(0.0) ) { fT = REAL(0.0); fSqrDist = fC; } else if ( -fB1 >= fA11 ) { fT = REAL(1.0); fSqrDist = fA11+REAL(2.0)*fB1+fC; } else { fT = -fB1/fA11; fSqrDist = fB1*fT+fC; } } } } } else { // line segments are parallel if ( fA01 > REAL(0.0) ) { // direction vectors form an obtuse angle if ( fB0 >= REAL(0.0) ) { fS = REAL(0.0); fT = REAL(0.0); fSqrDist = fC; } else if ( -fB0 <= fA00 ) { fS = -fB0/fA00; fT = REAL(0.0); fSqrDist = fB0*fS+fC; } else { //fB1 = -kDiff % seg2.m; fB1 = dDOT( kNegDiff, seg2Direction ); fS = REAL(1.0); fTmp = fA00+fB0; if ( -fTmp >= fA01 ) { fT = REAL(1.0); fSqrDist = fA00+fA11+fC+REAL(2.0)*(fA01+fB0+fB1); } else { fT = -fTmp/fA01; fSqrDist = fA00+REAL(2.0)*fB0+fC+fT*(fA11*fT+REAL(2.0)*(fA01+fB1)); } } } else { // direction vectors form an acute angle if ( -fB0 >= fA00 ) { fS = REAL(1.0); fT = REAL(0.0); fSqrDist = fA00+REAL(2.0)*fB0+fC; } else if ( fB0 <= REAL(0.0) ) { fS = -fB0/fA00; fT = REAL(0.0); fSqrDist = fB0*fS+fC; } else { fB1 = dDOT( kNegDiff, seg2Direction ); fS = REAL(0.0); if ( fB0 >= -fA01 ) { fT = REAL(1.0); fSqrDist = fA11+REAL(2.0)*fB1+fC; } else { fT = -fB0/fA01; fSqrDist = fC+fT*(REAL(2.0)*fB1+fA11*fT); } } } } if ( pfSegP0 ) *pfSegP0 = fS; if ( pfSegP1 ) *pfSegP1 = fT; return dReal(fabs(fSqrDist)); } //------------------------------------------------------------------------------ /** @brief Finds the shortest distance squared between a line segment and a triangle. @param pfSegP t value for the line segment where the shortest distance between the segment and the triangle occurs. So the point along the segment that is the shortest distance away from the triangle can be obtained by (seg.end - seg.start) * t. @param pfTriP0 Barycentric coordinate of triangle at point closest to seg (u) @param pfTriP1 Barycentric coordinate of triangle at point closest to seg (v) @return Shortest distance squared. The third Barycentric coordinate is implicit, ie. w = 1.0 - u - v Taken from: Magic Software, Inc. http://www.magic-software.com */ dReal SqrDistanceSegTri( const dVector3 segOrigin, const dVector3 segEnd, const dVector3 triOrigin, const dVector3 triEdge0, const dVector3 triEdge1, dReal* pfSegP, dReal* pfTriP0, dReal* pfTriP1 ) { const dReal gs_fTolerance = 1e-06f; dVector3 segDirection, segNegDirection, kDiff, kNegDiff; Vector3Subtract( segEnd, segOrigin, segDirection ); Vector3Negate( segDirection, segNegDirection ); Vector3Subtract( triOrigin, segOrigin, kDiff ); Vector3Negate( kDiff, kNegDiff ); dReal fA00 = dDOT( segDirection, segDirection ); dReal fA01 = dDOT( segNegDirection, triEdge0 ); dReal fA02 = dDOT( segNegDirection, triEdge1 ); dReal fA11 = dDOT( triEdge0, triEdge0 ); dReal fA12 = dDOT( triEdge0, triEdge1 ); dReal fA22 = dDOT( triEdge1, triEdge1 ); dReal fB0 = dDOT( kNegDiff, segDirection ); dReal fB1 = dDOT( kDiff, triEdge0 ); dReal fB2 = dDOT( kDiff, triEdge1 ); dVector3 kTriSegOrigin, kTriSegDirection, kPt; dReal fSqrDist, fSqrDist0, fR, fS, fT, fR0, fS0, fT0; // Set up for a relative error test on the angle between ray direction // and triangle normal to determine parallel/nonparallel status. dVector3 kN; dCROSS( kN, =, triEdge0, triEdge1 ); dReal fNSqrLen = dDOT( kN, kN ); dReal fDot = dDOT( segDirection, kN ); bool bNotParallel = (fDot*fDot >= gs_fTolerance*fA00*fNSqrLen); if ( bNotParallel ) { dReal fCof00 = fA11*fA22-fA12*fA12; dReal fCof01 = fA02*fA12-fA01*fA22; dReal fCof02 = fA01*fA12-fA02*fA11; dReal fCof11 = fA00*fA22-fA02*fA02; dReal fCof12 = fA02*fA01-fA00*fA12; dReal fCof22 = fA00*fA11-fA01*fA01; dReal fInvDet = REAL(1.0)/(fA00*fCof00+fA01*fCof01+fA02*fCof02); dReal fRhs0 = -fB0*fInvDet; dReal fRhs1 = -fB1*fInvDet; dReal fRhs2 = -fB2*fInvDet; fR = fCof00*fRhs0+fCof01*fRhs1+fCof02*fRhs2; fS = fCof01*fRhs0+fCof11*fRhs1+fCof12*fRhs2; fT = fCof02*fRhs0+fCof12*fRhs1+fCof22*fRhs2; if ( fR < REAL(0.0) ) { if ( fS+fT <= REAL(1.0) ) { if ( fS < REAL(0.0) ) { if ( fT < REAL(0.0) ) // region 4m { // min on face s=0 or t=0 or r=0 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge1, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fT ); fS = REAL(0.0); Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge0, kTriSegDirection ); fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR0, &fS0 ); fT0 = REAL(0.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } fSqrDist0 = SqrDistancePointTri( segOrigin, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(0.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } else // region 3m { // min on face s=0 or r=0 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge1, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR,&fT ); fS = REAL(0.0); fSqrDist0 = SqrDistancePointTri( segOrigin, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(0.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } } else if ( fT < REAL(0.0) ) // region 5m { // min on face t=0 or r=0 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge0, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fS ); fT = REAL(0.0); fSqrDist0 = SqrDistancePointTri( segOrigin, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(0.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } else // region 0m { // min on face r=0 fSqrDist = SqrDistancePointTri( segOrigin, triOrigin, triEdge0, triEdge1, &fS, &fT ); fR = REAL(0.0); } } else { if ( fS < REAL(0.0) ) // region 2m { // min on face s=0 or s+t=1 or r=0 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge1, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fT ); fS = REAL(0.0); Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR0, &fT0 ); fS0 = REAL(1.0) - fT0; if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } fSqrDist0 = SqrDistancePointTri( segOrigin, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(0.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } else if ( fT < REAL(0.0) ) // region 6m { // min on face t=0 or s+t=1 or r=0 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge0, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fS ); fT = REAL(0.0); Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR0, &fT0 ); fS0 = REAL(1.0) - fT0; if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } fSqrDist0 = SqrDistancePointTri( segOrigin, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(0.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } else // region 1m { // min on face s+t=1 or r=0 Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fT ); fS = REAL(1.0) - fT; fSqrDist0 = SqrDistancePointTri( segOrigin, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(0.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } } } else if ( fR <= REAL(1.0) ) { if ( fS+fT <= REAL(1.0) ) { if ( fS < REAL(0.0) ) { if ( fT < REAL(0.0) ) // region 4 { // min on face s=0 or t=0 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge1, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fT ); fS = REAL(0.0); Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge0, kTriSegDirection ); fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR0, &fS0 ); fT0 = REAL(0.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } else // region 3 { // min on face s=0 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge1, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fT ); fS = REAL(0.0); } } else if ( fT < REAL(0.0) ) // region 5 { // min on face t=0 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge0, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fS ); fT = REAL(0.0); } else // region 0 { // global minimum is interior, done fSqrDist = REAL(0.0); } } else { if ( fS < REAL(0.0) ) // region 2 { // min on face s=0 or s+t=1 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge1, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fT ); fS = REAL(0.0); Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR0, &fT0 ); fS0 = REAL(1.0) - fT0; if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } else if ( fT < REAL(0.0) ) // region 6 { // min on face t=0 or s+t=1 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge0, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fS ); fT = REAL(0.0); Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR0, &fT0 ); fS0 = REAL(1.0) - fT0; if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } else // region 1 { // min on face s+t=1 Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fT ); fS = REAL(1.0) - fT; } } } else // fR > 1 { if ( fS+fT <= REAL(1.0) ) { if ( fS < REAL(0.0) ) { if ( fT < REAL(0.0) ) // region 4p { // min on face s=0 or t=0 or r=1 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge1, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fT ); fS = REAL(0.0); Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge0, kTriSegDirection ); fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR0, &fS0 ); fT0 = REAL(0.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } Vector3Add( segOrigin, segDirection, kPt ); fSqrDist0 = SqrDistancePointTri( kPt, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(1.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } else // region 3p { // min on face s=0 or r=1 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge1, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fT ); fS = REAL(0.0); Vector3Add( segOrigin, segDirection, kPt ); fSqrDist0 = SqrDistancePointTri( kPt, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(1.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } } else if ( fT < REAL(0.0) ) // region 5p { // min on face t=0 or r=1 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge0, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fS ); fT = REAL(0.0); Vector3Add( segOrigin, segDirection, kPt ); fSqrDist0 = SqrDistancePointTri( kPt, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(1.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } else // region 0p { // min face on r=1 Vector3Add( segOrigin, segDirection, kPt ); fSqrDist = SqrDistancePointTri( kPt, triOrigin, triEdge0, triEdge1, &fS, &fT ); fR = REAL(1.0); } } else { if ( fS < REAL(0.0) ) // region 2p { // min on face s=0 or s+t=1 or r=1 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge1, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fT ); fS = REAL(0.0); Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR0, &fT0 ); fS0 = REAL(1.0) - fT0; if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } Vector3Add( segOrigin, segDirection, kPt ); fSqrDist0 = SqrDistancePointTri( kPt, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(1.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } else if ( fT < REAL(0.0) ) // region 6p { // min on face t=0 or s+t=1 or r=1 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge0, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fS ); fT = REAL(0.0); Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR0, &fT0 ); fS0 = REAL(1.0) - fT0; if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } Vector3Add( segOrigin, segDirection, kPt ); fSqrDist0 = SqrDistancePointTri( kPt, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(1.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } else // region 1p { // min on face s+t=1 or r=1 Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fT ); fS = REAL(1.0) - fT; Vector3Add( segOrigin, segDirection, kPt ); fSqrDist0 = SqrDistancePointTri( kPt, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(1.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } } } } else { // segment and triangle are parallel Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge0, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fS ); fT = REAL(0.0); Vector3Copy( triEdge1, kTriSegDirection ); fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR0, &fT0 ); fS0 = REAL(0.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR0, &fT0 ); fS0 = REAL(1.0) - fT0; if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } fSqrDist0 = SqrDistancePointTri( segOrigin, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(0.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } Vector3Add( segOrigin, segDirection, kPt ); fSqrDist0 = SqrDistancePointTri( kPt, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(1.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } if ( pfSegP ) *pfSegP = fR; if ( pfTriP0 ) *pfTriP0 = fS; if ( pfTriP1 ) *pfTriP1 = fT; return fSqrDist; } alien-arena-7.66+dfsg/source/unix/odesrc/timer.cpp0000600000175000017500000002270412161402010021175 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* TODO ---- * gettimeofday() and the pentium time stamp counter return the real time, not the process time. fix this somehow! */ #include #include #include "config.h" #include "util.h" // misc defines #define ALLOCA dALLOCA16 //**************************************************************************** // implementation for windows based on the multimedia performance counter. #ifdef WIN32 #include "windows.h" static inline void getClockCount (unsigned long cc[2]) { LARGE_INTEGER a; QueryPerformanceCounter (&a); cc[0] = a.LowPart; cc[1] = a.HighPart; } static inline void serialize() { } static inline double loadClockCount (unsigned long cc[2]) { LARGE_INTEGER a; a.LowPart = cc[0]; a.HighPart = cc[1]; return double(a.QuadPart); } double dTimerResolution() { return 1.0/dTimerTicksPerSecond(); } double dTimerTicksPerSecond() { static int query=0; static double hz=0.0; if (!query) { LARGE_INTEGER a; QueryPerformanceFrequency (&a); hz = double(a.QuadPart); query = 1; } return hz; } #endif //**************************************************************************** // implementation based on the pentium time stamp counter. the timer functions // can be serializing or non-serializing. serializing will ensure that all // instructions have executed and data has been written back before the cpu // time stamp counter is read. the CPUID instruction is used to serialize. #if defined(PENTIUM) && !defined(WIN32) // we need to know the clock rate so that the timing function can report // accurate times. this number only needs to be set accurately if we're // doing performance tests and care about real-world time numbers - otherwise, // just ignore this. i have not worked out how to determine this number // automatically yet. #define PENTIUM_HZ (500e6) static inline void getClockCount (unsigned long cc[2]) { #ifndef X86_64_SYSTEM asm volatile ( "rdtsc\n" "movl %%eax,(%%esi)\n" "movl %%edx,4(%%esi)\n" : : "S" (cc) : "%eax","%edx","cc","memory"); #else asm volatile ( "rdtsc\n" "movl %%eax,(%%rsi)\n" "movl %%edx,4(%%rsi)\n" : : "S" (cc) : "%eax","%edx","cc","memory"); #endif } static inline void serialize() { #ifndef X86_64_SYSTEM asm volatile ( "mov $0,%%eax\n" "push %%ebx\n" "cpuid\n" "pop %%ebx\n" : : : "%eax","%ecx","%edx","cc","memory"); #else asm volatile ( "mov $0,%%rax\n" "push %%rbx\n" "cpuid\n" "pop %%rbx\n" : : : "%rax","%rcx","%rdx","cc","memory"); #endif } static inline double loadClockCount (unsigned long a[2]) { double ret; #ifndef X86_64_SYSTEM asm volatile ("fildll %1; fstpl %0" : "=m" (ret) : "m" (a[0]) : "cc","memory"); #else asm volatile ("fildll %1; fstpl %0" : "=m" (ret) : "m" (a[0]) : "cc","memory"); #endif return ret; } double dTimerResolution() { return 1.0/PENTIUM_HZ; } double dTimerTicksPerSecond() { return PENTIUM_HZ; } #endif //**************************************************************************** // otherwise, do the implementation based on gettimeofday(). #if !defined(PENTIUM) && !defined(WIN32) #ifndef macintosh #include #include static inline void getClockCount (unsigned long cc[2]) { struct timeval tv; gettimeofday (&tv,0); cc[0] = tv.tv_usec; cc[1] = tv.tv_sec; } #else // macintosh #include #include static inline void getClockCount (unsigned long cc[2]) { UnsignedWide ms; Microseconds (&ms); cc[1] = ms.lo / 1000000; cc[0] = ms.lo - ( cc[1] * 1000000 ); } #endif static inline void serialize() { } static inline double loadClockCount (unsigned long a[2]) { return a[1]*1.0e6 + a[0]; } double dTimerResolution() { unsigned long cc1[2],cc2[2]; getClockCount (cc1); do { getClockCount (cc2); } while (cc1[0]==cc2[0] && cc1[1]==cc2[1]); do { getClockCount (cc1); } while (cc1[0]==cc2[0] && cc1[1]==cc2[1]); double t1 = loadClockCount (cc1); double t2 = loadClockCount (cc2); return (t1-t2) / dTimerTicksPerSecond(); } double dTimerTicksPerSecond() { return 1000000; } #endif //**************************************************************************** // stop watches void dStopwatchReset (dStopwatch *s) { s->time = 0; s->cc[0] = 0; s->cc[1] = 0; } void dStopwatchStart (dStopwatch *s) { serialize(); getClockCount (s->cc); } void dStopwatchStop (dStopwatch *s) { unsigned long cc[2]; serialize(); getClockCount (cc); double t1 = loadClockCount (s->cc); double t2 = loadClockCount (cc); s->time += t2-t1; } double dStopwatchTime (dStopwatch *s) { return s->time / dTimerTicksPerSecond(); } //**************************************************************************** // code timers // maximum number of events to record #define MAXNUM 100 static int num = 0; // number of entries used in event array static struct { unsigned long cc[2]; // clock counts double total_t; // total clocks used in this slot. double total_p; // total percentage points used in this slot. int count; // number of times this slot has been updated. const char *description; // pointer to static string } event[MAXNUM]; // make sure all slot totals and counts reset to 0 at start static void initSlots() { static int initialized=0; if (!initialized) { for (int i=0; i (description); num = 1; serialize(); getClockCount (event[0].cc); } void dTimerNow (const char *description) { if (num < MAXNUM) { // do not serialize getClockCount (event[num].cc); event[num].description = const_cast (description); num++; } } void dTimerEnd() { if (num < MAXNUM) { serialize(); getClockCount (event[num].cc); event[num].description = "TOTAL"; num++; } } //**************************************************************************** // print report static void fprintDoubleWithPrefix (FILE *f, double a, const char *fmt) { if (a >= 0.999999) { fprintf (f,fmt,a); return; } a *= 1000.0; if (a >= 0.999999) { fprintf (f,fmt,a); fprintf (f,"m"); return; } a *= 1000.0; if (a >= 0.999999) { fprintf (f,fmt,a); fprintf (f,"u"); return; } a *= 1000.0; fprintf (f,fmt,a); fprintf (f,"n"); } void dTimerReport (FILE *fout, int average) { int i; size_t maxl; double ccunit = 1.0/dTimerTicksPerSecond(); fprintf (fout,"\nTimer Report ("); fprintDoubleWithPrefix (fout,ccunit,"%.2f "); fprintf (fout,"s resolution)\n------------\n"); if (num < 1) return; // get maximum description length maxl = 0; for (i=0; i maxl) maxl = l; } // calculate total time double t1 = loadClockCount (event[0].cc); double t2 = loadClockCount (event[num-1].cc); double total = t2 - t1; if (total <= 0) total = 1; // compute time difference for all slots except the last one. update totals double *times = (double*) ALLOCA (num * sizeof(double)); for (i=0; i < (num-1); i++) { double t1 = loadClockCount (event[i].cc); double t2 = loadClockCount (event[i+1].cc); times[i] = t2 - t1; event[i].count++; event[i].total_t += times[i]; event[i].total_p += times[i]/total * 100.0; } // print report (with optional averages) for (i=0; i class dMatrix { int n,m; // matrix dimension, n,m >= 0 dReal *data; // if nonzero, n*m elements allocated on the heap public: // constructors, destructors dMatrix(); // make default 0x0 matrix dMatrix (int rows, int cols); // construct zero matrix of given size dMatrix (const dMatrix &); // construct copy of given matrix // create copy of given data - element (i,j) is data[i*rowskip+j*colskip] dMatrix (int rows, int cols, dReal *_data, int rowskip, int colskip); ~dMatrix(); // destructor // data movement dReal & operator () (int i, int j); // reference an element void operator= (const dMatrix &); // matrix = matrix void operator= (dReal); // matrix = scalar dMatrix transpose(); // return transposed matrix // return a permuted submatrix of this matrix, made up of the rows in p // and the columns in q. p has np elements, q has nq elements. dMatrix select (int np, int *p, int nq, int *q); // operators dMatrix operator + (const dMatrix &); dMatrix operator - (const dMatrix &); dMatrix operator - (); dMatrix operator * (const dMatrix &); void operator += (const dMatrix &); void operator -= (const dMatrix &); // utility void clearUpperTriangle(); void clearLowerTriangle(); void makeRandom (dReal range); void print (char *fmt = "%10.4f ", FILE *f=stdout); dReal maxDifference (const dMatrix &); }; #endif alien-arena-7.66+dfsg/source/unix/odesrc/lcp.h0000600000175000017500000000516612161402010020303 0ustar zero79zero79/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library 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 files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* given (A,b,lo,hi), solve the LCP problem: A*x = b+w, where each x(i),w(i) satisfies one of (1) x = lo, w >= 0 (2) x = hi, w <= 0 (3) lo < x < hi, w = 0 A is a matrix of dimension n*n, everything else is a vector of size n*1. lo and hi can be +/- dInfinity as needed. the first `nub' variables are unbounded, i.e. hi and lo are assumed to be +/- dInfinity. we restrict lo(i) <= 0 and hi(i) >= 0. the original data (A,b) may be modified by this function. if the `findex' (friction index) parameter is nonzero, it points to an array of index values. in this case constraints that have findex[i] >= 0 are special. all non-special constraints are solved for, then the lo and hi values for the special constraints are set: hi[i] = abs( hi[i] * x[findex[i]] ) lo[i] = -hi[i] and the solution continues. this mechanism allows a friction approximation to be implemented. the first `nub' variables are assumed to have findex < 0. */ #ifndef _ODE_LCP_H_ #define _ODE_LCP_H_ void dSolveLCP (int n, dReal *A, dReal *x, dReal *b, dReal *w, int nub, dReal *lo, dReal *hi, int *findex); #endif alien-arena-7.66+dfsg/source/unix/rw_unix.h0000600000175000017500000000212712161402010017733 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ typedef void (*Key_Event_fp_t)(int key, qboolean down); extern void (*KBD_Update_fp)(void); extern void (*KBD_Init_fp)(Key_Event_fp_t fp); extern void (*KBD_Close_fp)(void); typedef struct in_state { // Pointers to functions back in client, set by vid_so void (*IN_CenterView_fp)(void); Key_Event_fp_t Key_Event_fp; vec_t *viewangles; int *in_strafe_state; } in_state_t; alien-arena-7.66+dfsg/source/unix/vid_so.c0000600000175000017500000001305512161402010017520 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // Main windowed and fullscreen graphics interface module. This module // is used for both the software and OpenGL rendering versions of the // Quake refresh engine. #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #if defined HAVE_DLFCN_H #include // ELF dl loader #endif #include #include #include #include "client/client.h" // Console variables that we need to access from this module cvar_t *vid_gamma; cvar_t *vid_xpos; // X coordinate of window position cvar_t *vid_ypos; // Y coordinate of window position cvar_t *vid_fullscreen; cvar_t *vid_width; cvar_t *vid_height; extern cvar_t *vid_ref; // Global variables used internally by this module viddef_t viddef; // global video state; used by other modules qboolean vid_restart = false; qboolean vid_active = false; //========================================================================== /* ============ VID_Restart_f Console command to re-start the video mode and refresh DLL. We do this simply by setting the modified flag for the vid_ref variable, which will cause the entire video mode and refresh DLL to be reset on the next frame. ============ */ void VID_Restart_f (void) { vid_restart = true; } /* ** VID_GetModeInfo */ typedef struct vidmode_s { const char *description; int width, height; int mode; } vidmode_t; vidmode_t vid_modes[] = { { "Mode 0: 640x480", 640, 480, 0 }, { "Mode 1: 800x600", 800, 600, 1 }, { "Mode 2: 960x720", 960, 720, 2 }, { "Mode 3: 1024x768", 1024, 768, 3 }, { "Mode 4: 1152x864", 1152, 864, 4 }, { "Mode 5: 1280x960", 1280, 960, 5 }, { "Mode 6: 1280x1024", 1280, 1024, 6 }, { "Mode 7: 1360x768", 1360, 768, 7 }, { "Mode 8: 1366x768", 1366, 768, 8 }, { "Mode 9: 1600x1200", 1600, 1200, 9 }, { "Mode 10: 1680x1050", 1680, 1050, 10 }, { "Mode 11: 1920x1080", 1920, 1080, 11 }, { "Mode 12: 2048x1536", 2048, 1536, 12 } }; static int s_numVidModes = ( sizeof(vid_modes) / sizeof(vid_modes[0])); qboolean VID_GetModeInfo ( int *width, int *height, int mode) { vidmode_t *vm; if ( mode < -1 ) { return false; } if ( mode >= s_numVidModes ) { return false; } if ( mode == -1 ) { *width = vid_width->value; *height = vid_height->value; return true; } vm = &vid_modes[mode]; *width = vm->width; *height = vm->height; return true; } void VID_ModeList_f(void) { int i; for ( i = 0; i < s_numVidModes; i++) { Com_Printf ( "%s\n", vid_modes[i].description ); } Com_Printf("For custom resolutions, set 'gl_mode' to -1 and use 'vid_width' / 'vid_height'\n"); } /* ** VID_NewWindow */ void VID_NewWindow ( int width, int height) { viddef.width = width; viddef.height = height; } /* ============ VID_CheckChanges This function gets called once just before drawing each frame, and it's sole purpose in life is to check to see if any of the video mode parameters have changed, and if they have to update the rendering DLL and/or video mode to match. ============ */ void VID_CheckChanges (void) { if ( vid_restart ) { S_StopAllSounds(); /* ** refresh has changed */ vid_fullscreen->modified = true; cl.refresh_prepped = false; cls.disable_screen = true; VID_Shutdown(); Com_Printf( "--------- [Loading Renderer] ---------\n" ); Swap_Init (); if ( R_Init( 0, 0 ) == -1 ) { R_Shutdown(); vid_active = false; Com_Error (ERR_FATAL, "Couldn't initialize renderer!"); } Com_Printf( "------------------------------------\n"); vid_restart = false; vid_active = true; cls.disable_screen = false; } } /* ============ VID_Init ============ */ void VID_Init (void) { /* Create the video variables so we know how to start the graphics drivers */ vid_ref = Cvar_Get ("vid_ref", "glx", CVAR_ARCHIVE); vid_xpos = Cvar_Get ("vid_xpos", "0", CVAR_ARCHIVE); vid_ypos = Cvar_Get ("vid_ypos", "0", CVAR_ARCHIVE); vid_fullscreen = Cvar_Get ("vid_fullscreen", "0", CVAR_ARCHIVE); vid_gamma = Cvar_Get( "vid_gamma", "1", CVAR_ARCHIVE ); vid_width = Cvar_Get ( "vid_width", "640", CVAR_ARCHIVE ); vid_height = Cvar_Get ( "vid_height", "480", CVAR_ARCHIVE ); /* Add some console commands that we want to handle */ Cmd_AddCommand ("vid_restart", VID_Restart_f); Cmd_AddCommand ("vid_modelist", VID_ModeList_f); #if 0 // 2010-08 Probably very obsolete. /* Disable the 3Dfx splash screen */ putenv("FX_GLIDE_NO_SPLASH=0"); #endif /* Start the graphics mode and load refresh DLL */ vid_restart = true; vid_active = false; VID_CheckChanges(); } /* ============ VID_Shutdown ============ */ void VID_Shutdown (void) { if ( vid_active ) { R_Shutdown (); vid_active = false; } } alien-arena-7.66+dfsg/source/unix/net_udp.c0000600000175000017500000003005512161402010017672 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // net_udp.c #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "qcommon/qcommon.h" /* * Notes on select() function used in Net_Sleep() * * per Linux man page and Mac OS X man page for select() * is POSIX, ,,(with ) are legacy * * For Darwin, select() can return this error, and may require the preprocessor def. * [EINVAL] ndfs is greater than FD_SETSIZE and _DARWIN_UNLIMITED_SELECT is not defined. * Error check added to Net_Sleep, to see if that is a problem. * If select() returns an error, then dedicated server will run at 100% cpu. * _DARWIN_UNLIMITED_SELECT put in config.h. TODO: determine if that is needed. */ #if defined HAVE_SYS_SELECT_H # include #else # if defined HAVE_SYS_TYPES_H # include # endif # if defined HAVE_SYS_TIME_H # include # endif #endif #if defined HAVE_UNISTD_H #include #endif #include #include #include #include #include #include #include #include int server_port; netadr_t net_local_adr; #define LOOPBACK 0x7f000001 #define MAX_LOOPBACK 4 typedef struct { byte data[MAX_MSGLEN]; int datalen; } loopmsg_t; typedef struct { loopmsg_t msgs[MAX_LOOPBACK]; int get, send; } loopback_t; loopback_t loopbacks[2]; int ip_sockets[2]; int ipx_sockets[2]; int NET_Socket (char *net_interface, int port); char *NET_ErrorString (void); //============================================================================= void NetadrToSockadr (netadr_t *a, struct sockaddr_in *s) { memset (s, 0, sizeof(*s)); if (a->type == NA_BROADCAST) { s->sin_family = AF_INET; s->sin_port = a->port; *(int *)&s->sin_addr = -1; } else if (a->type == NA_IP) { s->sin_family = AF_INET; *(int *)&s->sin_addr = *(int *)&a->ip; s->sin_port = a->port; } } void SockadrToNetadr (struct sockaddr_in *s, netadr_t *a) { *(int *)&a->ip = *(int *)&s->sin_addr; a->port = s->sin_port; a->type = NA_IP; } qboolean NET_CompareAdr (netadr_t a, netadr_t b) { if (a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3] && a.port == b.port) return true; return false; } /* =================== NET_CompareBaseAdr Compares without the port =================== */ qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b) { if (a.type != b.type) return false; if (a.type == NA_LOOPBACK) return true; if (a.type == NA_IP) { if (a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3]) return true; return false; } if (a.type == NA_IPX) { if ((memcmp(a.ipx, b.ipx, 10) == 0)) return true; return false; } return false; } char *NET_AdrToString (netadr_t a) { static char s[64]; Com_sprintf (s, sizeof(s), "%i.%i.%i.%i:%i", a.ip[0], a.ip[1], a.ip[2], a.ip[3], ntohs(a.port)); return s; } char *NET_BaseAdrToString (netadr_t a) { static char s[64]; Com_sprintf (s, sizeof(s), "%i.%i.%i.%i", a.ip[0], a.ip[1], a.ip[2], a.ip[3]); return s; } /* ============= NET_StringToAdr localhost idnewt idnewt:28000 192.246.40.70 192.246.40.70:28000 ============= */ qboolean NET_StringToSockaddr (char *s, struct sockaddr *sadr) { struct hostent *h; char *colon; char copy[128]; memset (sadr, 0, sizeof(*sadr)); ((struct sockaddr_in *)sadr)->sin_family = AF_INET; ((struct sockaddr_in *)sadr)->sin_port = 0; strcpy (copy, s); // strip off a trailing :port if present for (colon = copy ; *colon ; colon++) if (*colon == ':') { *colon = 0; ((struct sockaddr_in *)sadr)->sin_port = htons((short)atoi(colon+1)); } if (copy[0] >= '0' && copy[0] <= '9') { *(int *)&((struct sockaddr_in *)sadr)->sin_addr = inet_addr(copy); } else { if (! (h = gethostbyname(copy)) ) return 0; *(int *)&((struct sockaddr_in *)sadr)->sin_addr = *(int *)h->h_addr_list[0]; } return true; } /* ============= NET_StringToAdr localhost idnewt idnewt:28000 192.246.40.70 192.246.40.70:28000 ============= */ qboolean NET_StringToAdr (char *s, netadr_t *a) { struct sockaddr_in sadr; if (!strcmp (s, "localhost")) { memset (a, 0, sizeof(*a)); a->type = NA_LOOPBACK; return true; } if (!NET_StringToSockaddr (s, (struct sockaddr *)&sadr)) return false; SockadrToNetadr (&sadr, a); return true; } qboolean NET_IsLocalAddress (netadr_t adr) { return NET_CompareAdr (adr, net_local_adr); } /* ============================================================================= LOOPBACK BUFFERS FOR LOCAL PLAYER ============================================================================= */ qboolean NET_GetLoopPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message) { int i; loopback_t *loop; loop = &loopbacks[sock]; if (loop->send - loop->get > MAX_LOOPBACK) loop->get = loop->send - MAX_LOOPBACK; if (loop->get >= loop->send) return false; i = loop->get & (MAX_LOOPBACK-1); loop->get++; memcpy (net_message->data, loop->msgs[i].data, loop->msgs[i].datalen); net_message->cursize = loop->msgs[i].datalen; *net_from = net_local_adr; return true; } void NET_SendLoopPacket (netsrc_t sock, int length, void *data, netadr_t to) { int i; loopback_t *loop; loop = &loopbacks[sock^1]; i = loop->send & (MAX_LOOPBACK-1); loop->send++; memcpy (loop->msgs[i].data, data, length); loop->msgs[i].datalen = length; } //============================================================================= qboolean NET_GetPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message) { int ret; struct sockaddr_in from; socklen_t fromlen; int net_socket; int protocol; int err; if (NET_GetLoopPacket (sock, net_from, net_message)) return true; for (protocol = 0 ; protocol < 2 ; protocol++) { if (protocol == 0) net_socket = ip_sockets[sock]; else net_socket = ipx_sockets[sock]; if (!net_socket) continue; fromlen = sizeof(from); ret = recvfrom (net_socket, net_message->data, net_message->maxsize , 0, (struct sockaddr *)&from, &fromlen); SockadrToNetadr (&from, net_from); if (ret == -1) { err = errno; if (err == EWOULDBLOCK || err == ECONNREFUSED) continue; Com_Printf ("NET_GetPacket: %s from %s\n", NET_ErrorString(), NET_AdrToString(*net_from)); continue; } if (ret == net_message->maxsize) { Com_Printf ("Oversize packet from %s\n", NET_AdrToString (*net_from)); continue; } net_message->cursize = ret; return true; } return false; } //============================================================================= void NET_SendPacket (netsrc_t sock, int length, void *data, netadr_t to) { int ret; struct sockaddr_in addr; int net_socket = 0; if ( to.type == NA_LOOPBACK ) { NET_SendLoopPacket (sock, length, data, to); return; } if (to.type == NA_BROADCAST) { net_socket = ip_sockets[sock]; if (!net_socket) return; } else if (to.type == NA_IP) { net_socket = ip_sockets[sock]; if (!net_socket) return; } else if (to.type == NA_IPX) { net_socket = ipx_sockets[sock]; if (!net_socket) return; } else if (to.type == NA_BROADCAST_IPX) { net_socket = ipx_sockets[sock]; if (!net_socket) return; } else Com_Error (ERR_FATAL, "NET_SendPacket: bad address type"); NetadrToSockadr (&to, &addr); ret = sendto (net_socket, data, length, 0, (struct sockaddr *)&addr, sizeof(addr) ); if (ret == -1) { Com_Printf ("NET_SendPacket ERROR: %s to %s\n", NET_ErrorString(), NET_AdrToString (to)); } } /* ==================== NET_OpenIP ==================== */ void NET_OpenIP (void) { cvar_t *port, *ip; port = Cvar_Get ("port", va("%i", PORT_SERVER), CVAR_NOSET); ip = Cvar_Get ("ip", "localhost", CVAR_NOSET); server_port = (ptrdiff_t)port; if (!ip_sockets[NS_SERVER]) ip_sockets[NS_SERVER] = NET_Socket (ip->string, port->value); if (!ip_sockets[NS_CLIENT]) ip_sockets[NS_CLIENT] = NET_Socket (ip->string, PORT_ANY); } /* ==================== NET_OpenIPX ==================== */ void NET_OpenIPX (void) { } /* ==================== NET_Config A single player game will only use the loopback code ==================== */ void NET_Config (qboolean multiplayer) { int i; if (!multiplayer) { // shut down any existing sockets for (i=0 ; i<2 ; i++) { if (ip_sockets[i]) { close (ip_sockets[i]); ip_sockets[i] = 0; } if (ipx_sockets[i]) { close (ipx_sockets[i]); ipx_sockets[i] = 0; } } } else { // open sockets NET_OpenIP (); NET_OpenIPX (); } } //=================================================================== /* ==================== NET_Init ==================== */ void NET_Init (void) { } /* ==================== NET_Socket ==================== */ int NET_Socket (char *net_interface, int port) { int newsocket; struct sockaddr_in address; qboolean _true = true; int i = 1; if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { Com_Printf ("ERROR: UDP_OpenSocket: socket: %s", NET_ErrorString()); return 0; } // make it non-blocking if (ioctl (newsocket, FIONBIO, &_true) == -1) { Com_Printf ("ERROR: UDP_OpenSocket: ioctl FIONBIO:%s\n", NET_ErrorString()); return 0; } // make it broadcast capable if (setsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) == -1) { Com_Printf ("ERROR: UDP_OpenSocket: setsockopt SO_BROADCAST:%s\n", NET_ErrorString()); return 0; } if (!net_interface || !net_interface[0] || !Q_strcasecmp(net_interface, "localhost")) address.sin_addr.s_addr = INADDR_ANY; else NET_StringToSockaddr (net_interface, (struct sockaddr *)&address); if (port == PORT_ANY) address.sin_port = 0; else address.sin_port = htons((short)port); address.sin_family = AF_INET; if( bind (newsocket, (void *)&address, sizeof(address)) == -1) { Com_Printf ("ERROR: UDP_OpenSocket: bind: %s\n", NET_ErrorString()); close (newsocket); return 0; } return newsocket; } /* ==================== NET_Shutdown ==================== */ void NET_Shutdown (void) { NET_Config (false); // close sockets } /* ==================== NET_ErrorString ==================== */ char *NET_ErrorString (void) { int code; code = errno; return strerror (code); } // sleeps msec or until net socket is ready void NET_Sleep(int msec) { struct timeval timeout; fd_set fdset; extern cvar_t *dedicated; extern qboolean stdin_active; int result; if (!ip_sockets[NS_SERVER] || (dedicated && !dedicated->value)) return; // we're not a server, just run full speed FD_ZERO(&fdset); if (stdin_active) FD_SET(0, &fdset); // stdin is processed too FD_SET(ip_sockets[NS_SERVER], &fdset); // network socket timeout.tv_sec = msec/1000; timeout.tv_usec = (msec%1000)*1000; result = select(ip_sockets[NS_SERVER]+1, &fdset, NULL, NULL, &timeout); if ( result == -1 ) { Com_Printf("ERROR: Net_Sleep( msec:%i ): select() error: %s\n", msec, strerror( errno ) ); } } alien-arena-7.66+dfsg/source/unix/glob.c0000600000175000017500000000760012161402010017157 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "unix/glob.h" /* Like glob_match, but match PATTERN against any final segment of TEXT. */ static int glob_match_after_star(char *pattern, char *text) { register char *p = pattern, *t = text; register char c, c1; while ((c = *p++) == '?' || c == '*') if (c == '?' && *t++ == '\0') return 0; if (c == '\0') return 1; if (c == '\\') c1 = *p; else c1 = c; while (1) { if ((c == '[' || *t == c1) && glob_match(p - 1, t)) return 1; if (*t++ == '\0') return 0; } } #if 0 // unused /* Return nonzero if PATTERN has any special globbing chars in it. */ static int glob_pattern_p(char *pattern) { register char *p = pattern; register char c; int open = 0; while ((c = *p++) != '\0') switch (c) { case '?': case '*': return 1; case '[': /* Only accept an open brace if there is a close */ open++; /* brace to match it. Bracket expressions must be */ continue; /* complete, according to Posix.2 */ case ']': if (open) return 1; continue; case '\\': if (*p++ == '\0') return 0; } return 0; } #endif /* Match the pattern PATTERN against the string TEXT; return 1 if it matches, 0 otherwise. A match means the entire string TEXT is used up in matching. In the pattern string, `*' matches any sequence of characters, `?' matches any character, [SET] matches any character in the specified set, [!SET] matches any character not in the specified set. A set is composed of characters or ranges; a range looks like character hyphen character (as in 0-9 or A-Z). [0-9a-zA-Z_] is the set of characters allowed in C identifiers. Any other character in the pattern must be matched exactly. To suppress the special syntactic significance of any of `[]*?!-\', and match the character exactly, precede it with a `\'. */ int glob_match(char *pattern, char *text) { register char *p = pattern, *t = text; register char c; while ((c = *p++) != '\0') switch (c) { case '?': if (*t == '\0') return 0; else ++t; break; case '\\': if (*p++ != *t++) return 0; break; case '*': return glob_match_after_star(p, t); case '[': { register char c1 = *t++; int invert; if (!c1) return (0); invert = ((*p == '!') || (*p == '^')); if (invert) p++; c = *p++; while (1) { register char cstart = c, cend = c; if (c == '\\') { cstart = *p++; cend = cstart; } if (c == '\0') return 0; c = *p++; if (c == '-' && *p != ']') { cend = *p++; if (cend == '\\') cend = *p++; if (cend == '\0') return 0; c = *p++; } if (c1 >= cstart && c1 <= cend) goto match; if (c == ']') break; } if (!invert) return 0; break; match: /* Skip the rest of the [...] construct that already matched. */ while (c != ']') { if (c == '\0') return 0; c = *p++; if (c == '\0') return 0; else if (c == '\\') ++p; } if (invert) return 0; break; } default: if (c != *t++) return 0; } return *t == '\0'; } alien-arena-7.66+dfsg/source/client/0000700000175000017500000000000012207204656016377 5ustar zero79zero79alien-arena-7.66+dfsg/source/client/cl_main.c0000600000175000017500000021663712204310130020144 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. Copyright (C) 2011 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // cl_main.c -- client main loop #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "client.h" #if defined WIN32_VARIANT #include #endif #if defined UNIX_VARIANT #if defined HAVE_UNISTD_H #include #endif #include #include #include #include #include #include #include #include #endif #if defined HAVE_PUTENV && !defined HAVE__PUTENV #define _putenv putenv #endif cvar_t *freelook; cvar_t *adr0; cvar_t *adr1; cvar_t *adr2; cvar_t *adr3; cvar_t *adr4; cvar_t *adr5; cvar_t *adr6; cvar_t *adr7; cvar_t *adr8; cvar_t *cl_stereo_separation; cvar_t *cl_stereo; cvar_t *rcon_client_password; cvar_t *rcon_address; cvar_t *cl_noskins; cvar_t *cl_autoskins; cvar_t *cl_footsteps; cvar_t *cl_timeout; cvar_t *cl_predict; cvar_t *cl_maxfps; cvar_t *cl_gun; cvar_t *cl_brass; cvar_t *cl_showPlayerNames; cvar_t *cl_playtaunts; cvar_t *cl_centerprint; cvar_t *cl_precachecustom; cvar_t *cl_simpleitems; cvar_t *cl_flicker; cvar_t *cl_paindist; cvar_t *cl_explosiondist; cvar_t *cl_raindist; cvar_t *cl_add_particles; cvar_t *cl_add_lights; cvar_t *cl_add_entities; cvar_t *cl_add_blend; cvar_t *cl_shownet; cvar_t *cl_showmiss; cvar_t *cl_showclamp; cvar_t *cl_paused; cvar_t *cl_timedemo; cvar_t *cl_demoquit; cvar_t *lookspring; cvar_t *lookstrafe; cvar_t *sensitivity; cvar_t *menu_sensitivity; cvar_t *m_smoothing; cvar_t *m_pitch; cvar_t *m_yaw; cvar_t *m_forward; cvar_t *m_side; cvar_t *cl_test; // // userinfo // cvar_t *info_password; cvar_t *info_spectator; cvar_t *info_spectator_password; cvar_t *name; cvar_t *stats_password; cvar_t *pw_hashed; cvar_t *skin; cvar_t *rate; cvar_t *fov; cvar_t *msg; cvar_t *hand; cvar_t *gender; cvar_t *gender_auto; cvar_t *cl_vwep; cvar_t *cl_vehicle_huds; cvar_t *background_music; cvar_t *background_music_vol; cvar_t *scriptsloaded; //master server cvar_t *cl_master; cvar_t *cl_master2; //custom huds cvar_t *cl_hudimage1; cvar_t *cl_hudimage2; //health aura cvar_t *cl_healthaura; //blood cvar_t *cl_noblood; //beam color for disruptor cvar_t *cl_disbeamclr; cvar_t *cl_dmlights; //Stats cvar_t *cl_stats_server; //latest version of the game available cvar_t *cl_latest_game_version_url; cvar_t *cl_speedrecord; cvar_t *cl_alltimespeedrecord; client_static_t cls; client_state_t cl; centity_t cl_entities[MAX_EDICTS]; entity_state_t cl_parse_entities[MAX_PARSE_ENTITIES]; extern cvar_t *allow_download; extern cvar_t *allow_download_players; extern cvar_t *allow_download_models; extern cvar_t *allow_download_sounds; extern cvar_t *allow_download_maps; #if defined WIN32_VARIANT extern char map_music[MAX_PATH]; extern char map_music_sec[MAX_PATH]; #else extern char map_music[MAX_OSPATH]; extern char map_music_sec[MAX_OSPATH]; #endif extern void RS_FreeAllScripts(void); typedef struct _PLAYERINFO { char playername[PLAYERNAME_SIZE]; int ping; int score; } PLAYERINFO; typedef struct _SERVERINFO { char ip[32]; unsigned short port; char szHostName[256]; char szMapName[256]; int curClients; int maxClients; int starttime; int ping; PLAYERINFO players[64]; int temporary; } SERVERINFO; SERVERINFO servers[64]; static int numServers = 0; static size_t szr; // just for unused result warnings // // Fonts // FNT_auto_t CL_gameFont; static struct FNT_auto_s _CL_gameFont; FNT_auto_t CL_centerFont; static struct FNT_auto_s _CL_centerFont; FNT_auto_t CL_consoleFont; static struct FNT_auto_s _CL_consoleFont; FNT_auto_t CL_menuFont; static struct FNT_auto_s _CL_menuFont; //====================================================================== /* ==================== CL_WriteDemoMessage Dumps the current net message, prefixed by the length ==================== */ void CL_WriteDemoMessage (void) { int len, swlen; // the first eight bytes are just packet sequencing stuff len = net_message.cursize-8; swlen = LittleLong(len); if (!swlen) return; szr = fwrite (&swlen, 4, 1, cls.demofile); szr = fwrite (net_message.data+8, len, 1, cls.demofile); } /* ==================== CL_Stop_f stop recording a demo ==================== */ void CL_Stop_f (void) { int len; if (!cls.demorecording) { Com_Printf ("Not recording a demo.\n"); return; } // finish up len = -1; szr = fwrite (&len, 4, 1, cls.demofile); fclose (cls.demofile); cls.demofile = NULL; cls.demorecording = false; Com_Printf ("Stopped demo.\n"); } /* ==================== CL_Record_f record Begins recording a demo from the current position ==================== */ void CL_Record_f (void) { char name[MAX_OSPATH]; char buf_data[MAX_MSGLEN]; sizebuf_t buf; int i; int len; entity_state_t *ent; entity_state_t nullstate; if (Cmd_Argc() != 2) { Com_Printf ("record \n"); return; } if (cls.demorecording) { Com_Printf ("Already recording.\n"); return; } if (cls.state != ca_active) { Com_Printf ("You must be in a level to record.\n"); return; } // // open the demo file // Com_sprintf (name, sizeof(name), "%s/demos/%s.dm2", FS_Gamedir(), Cmd_Argv(1)); Com_Printf ("recording to %s.\n", name); FS_CreatePath (name); cls.demofile = fopen (name, "wb"); if (!cls.demofile) { Com_Printf ("ERROR: couldn't open.\n"); return; } cls.demorecording = true; // don't start saving messages until a non-delta compressed message is received cls.demowaiting = true; // // write out messages to hold the startup information // SZ_Init (&buf, (byte *)buf_data, sizeof(buf_data)); SZ_SetName ( &buf, "CL_Record_f", false ); // send the serverdata MSG_WriteByte (&buf, svc_serverdata); MSG_WriteLong (&buf, PROTOCOL_VERSION); MSG_WriteLong (&buf, 0x10000 + cl.servercount); MSG_WriteByte (&buf, 1); // demos are always attract loops MSG_WriteString (&buf, cl.gamedir); MSG_WriteShort (&buf, cl.playernum); MSG_WriteString (&buf, cl.configstrings[CS_NAME]); // configstrings for (i=0 ; i buf.maxsize) { // write it out len = LittleLong (buf.cursize); szr = fwrite (&len, 4, 1, cls.demofile); szr = fwrite (buf.data, buf.cursize, 1, cls.demofile); buf.cursize = 0; } MSG_WriteByte (&buf, svc_configstring); MSG_WriteShort (&buf, i); MSG_WriteString (&buf, cl.configstrings[i]); } } // baselines memset (&nullstate, 0, sizeof(nullstate)); for (i=0; imodelindex) continue; if (buf.cursize + 64 > buf.maxsize) { // write it out len = LittleLong (buf.cursize); szr = fwrite (&len, 4, 1, cls.demofile); szr = fwrite (buf.data, buf.cursize, 1, cls.demofile); buf.cursize = 0; } MSG_WriteByte (&buf, svc_spawnbaseline); MSG_WriteDeltaEntity (&nullstate, &cl_entities[i].baseline, &buf, true, true); } MSG_WriteByte (&buf, svc_stufftext); MSG_WriteString (&buf, "precache\n"); // write it to the demo file len = LittleLong (buf.cursize); szr = fwrite (&len, 4, 1, cls.demofile); szr = fwrite (buf.data, buf.cursize, 1, cls.demofile); // the rest of the demo file will be individual frames } //====================================================================== /* =================== Cmd_ForwardToServer adds the current command line as a clc_stringcmd to the client message. things like godmode, noclip, etc, are commands directed to the server, so when they are typed in at the console, they will need to be forwarded. =================== */ void Cmd_ForwardToServer (void) { char *cmd; cmd = Cmd_Argv(0); if (cls.state <= ca_connected || *cmd == '-' || *cmd == '+') { Com_Printf ("Unknown command \"%s\"\n", cmd); return; } MSG_WriteByte (&cls.netchan.message, clc_stringcmd); SZ_Print (&cls.netchan.message, cmd); if (Cmd_Argc() > 1) { SZ_Print (&cls.netchan.message, " "); SZ_Print (&cls.netchan.message, Cmd_Args()); } } void CL_Setenv_f( void ) { int argc = Cmd_Argc(); if ( argc > 2 ) { char buffer[1000]; int i; strcpy( buffer, Cmd_Argv(1) ); strcat( buffer, "=" ); for ( i = 2; i < argc; i++ ) { strcat( buffer, Cmd_Argv( i ) ); strcat( buffer, " " ); } _putenv( buffer ); } else if ( argc == 2 ) { char *env = getenv( Cmd_Argv(1) ); if ( env ) { Com_Printf( "%s=%s\n", Cmd_Argv(1), env ); } else { Com_Printf( "%s undefined\n", Cmd_Argv(1), env ); } } } /* ================== CL_ForwardToServer_f ================== */ void CL_ForwardToServer_f (void) { if (cls.state != ca_connected && cls.state != ca_active) { Com_Printf ("Can't \"%s\", not connected\n", Cmd_Argv(0)); return; } // don't forward the first argument if (Cmd_Argc() > 1) { MSG_WriteByte (&cls.netchan.message, clc_stringcmd); SZ_Print (&cls.netchan.message, Cmd_Args()); } } /* ================== CL_Pause_f ================== */ void CL_Pause_f (void) { // never pause in multiplayer if (Cvar_VariableValue ("maxclients") > 1 || !Com_ServerState ()) { Cvar_SetValue ("paused", 0); return; } Cvar_SetValue ("paused", !cl_paused->integer); } /* ================== CL_Quit_f ================== */ void CL_Quit_f (void) { S_StopAllSounds (); CL_Disconnect (); Com_Quit (); } /* ================ CL_Drop Called after an ERR_DROP was thrown ================ */ void CL_Drop (void) { if (cls.state == ca_uninitialized) return; if (cls.state != ca_disconnected) CL_Disconnect (); // drop loading plaque unless this is the initial game start if (cls.disable_servercount != -1) SCR_EndLoadingPlaque (); // get rid of loading plaque } /* ======================= CL_SendConnectPacket We have gotten a challenge from the server, so try and connect. ====================== */ void CL_SendConnectPacket (void) { netadr_t adr; int port; if (!NET_StringToAdr (cls.servername, &adr)) { Com_Printf ("Bad server address\n"); cls.connect_time = 0; return; } if (adr.port == 0) adr.port = BigShort (PORT_SERVER); port = Cvar_VariableValue ("qport"); userinfo_modified = false; Netchan_OutOfBandPrint (NS_CLIENT, adr, "connect %i %i %i \"%s\"\n", PROTOCOL_VERSION, port, cls.challenge, Cvar_Userinfo() ); } /* ================= CL_CheckForResend Resend a connect message if the last one has timed out ================= */ void CL_CheckForResend (void) { netadr_t adr; // if the local server is running and we aren't // then connect if (cls.state == ca_disconnected && Com_ServerState() ) { cls.state = ca_connecting; strncpy (cls.servername, "localhost", sizeof(cls.servername)-1); // we don't need a challenge on the localhost CL_SendConnectPacket (); return; // cls.connect_time = -99999; // CL_CheckForResend() will fire immediately } // resend if we haven't gotten a reply yet if (cls.state != ca_connecting) return; if (cls.realtime - cls.connect_time < 3000) return; if (!NET_StringToAdr (cls.servername, &adr)) { Com_Printf ("Bad server address\n"); cls.state = ca_disconnected; return; } if (adr.port == 0) adr.port = BigShort (PORT_SERVER); cls.connect_time = cls.realtime; // for retransmit requests Com_Printf ("Connecting to %s...\n", cls.servername); Netchan_OutOfBandPrint (NS_CLIENT, adr, "getchallenge\n"); } /* ================ CL_Connect_f ================ */ void CL_Connect_f (void) { char *server; if (Cmd_Argc() != 2) { Com_Printf ("usage: connect \n"); return; } if (Com_ServerState ()) { // if running a local server, kill it and reissue SV_Shutdown (va("Server quit\n", msg), false); } else { CL_Disconnect (); } server = Cmd_Argv (1); NET_Config (true); // allow remote CL_Disconnect (); cls.state = ca_connecting; strncpy (cls.servername, server, sizeof(cls.servername)-1); cls.connect_time = -99999; // CL_CheckForResend() will fire immediately STATS_RequestVerification(); } /* ===================== CL_Rcon_f Send the rest of the command line over as an unconnected command. ===================== */ void CL_Rcon_f (void) { char message[1024]; sizebuf_t buffer; int i; netadr_t to; if ( !(rcon_client_password->string && rcon_client_password->string[0]) && Cmd_Argc() < 3) { Com_Printf ("You must set 'rcon_password' before issuing an rcon command.\n"); return; } NET_Config (true); // allow remote SZ_Init( &buffer, (byte *) message, 1024 ); buffer.allowoverflow = true; SZ_SetName( &buffer, "RCon buffer", false ); SZ_Print (&buffer, "\xff\xff\xff\xffrcon "); if ( rcon_client_password->string && rcon_client_password->string[0] ) { SZ_Print (&buffer, "\""); SZ_Print (&buffer, rcon_client_password->string); SZ_Print (&buffer, "\" "); } for (i=1 ; i= ca_connected) to = cls.netchan.remote_address; else { if (!strlen(rcon_address->string)) { Com_Printf ("You must either be connected, or set the 'rcon_address' cvar to issue rcon commands\n"); return; } NET_StringToAdr (rcon_address->string, &to); if (to.port == 0) to.port = BigShort (PORT_SERVER); } NET_SendPacket (NS_CLIENT, strlen(message)+1, message, to); } /* ===================== CL_ClearState ===================== */ void CL_ClearState (void) { S_StopAllSounds (); CL_ClearEffects (); CL_ClearTEnts (); // wipe the entire cl structure memset (&cl, 0, sizeof(cl)); memset (cl_entities, 0, sizeof(cl_entities)); SZ_Clear (&cls.netchan.message); } /* ===================== CL_Disconnect Goes from a connected state to full screen console state Sends a disconnect message to the server This is also called on Com_Error, so it shouldn't cause any errors ===================== */ void CL_Disconnect (void) { byte final[32]; int repeat; if (cls.state == ca_disconnected) return; if (cl_timedemo && cl_timedemo->integer) { int time; time = Sys_Milliseconds () - cl.timedemo_start; if (time > 0) Com_Printf ("%i frames, %3.1f seconds: %3.1f fps\n", cl.timedemo_frames, time/1000.0, cl.timedemo_frames*1000.0 / time); cl.timedemo_start = 0; } VectorClear (cl.refdef.blend); R_SetPalette(NULL); M_ForceMenuOff (); cls.connect_time = 0; if (cls.demorecording) CL_Stop_f (); // send a disconnect message to the server final[0] = clc_stringcmd; strcpy ((char *)final+1, "disconnect"); for ( repeat = 3 ; repeat-- ;) Netchan_Transmit( &cls.netchan, (int)strlen( (char*)final ), final ); CL_ClearState (); // stop download if(cls.download){ if(cls.downloadhttp) // clean up http downloads CL_HttpDownloadCleanup(); else // or just stop legacy ones fclose(cls.download); cls.download = NULL; } cls.state = ca_disconnected; if (cl_demoquit && cl_demoquit->integer && cl_timedemo && cl_timedemo->integer) { CL_Quit_f(); } } void CL_Disconnect_f (void) { Com_Error (ERR_DROP, "Disconnected from server"); } /* ================= CL_Changing_f Just sent as a hint to the client that they should drop to full console ================= */ void CL_Changing_f (void) { //ZOID //if we are downloading, we don't change! This so we don't suddenly stop downloading a map if (cls.download) return; SCR_BeginLoadingPlaque (); cls.state = ca_connected; // not active anymore, but not disconnected Com_Printf ("\nChanging map...\n"); } /* ================= CL_Reconnect_f The server is changing levels ================= */ void CL_Reconnect_f (void) { //ZOID //if we are downloading, we don't change! This so we don't suddenly stop downloading a map if (cls.download) return; S_StopAllSounds (); if (cls.state == ca_connected) { Com_Printf ("reconnecting...\n"); cls.state = ca_connected; MSG_WriteChar (&cls.netchan.message, clc_stringcmd); MSG_WriteString (&cls.netchan.message, "new"); return; } if (*cls.servername) { if (cls.state >= ca_connected) { CL_Disconnect(); cls.connect_time = cls.realtime - 1500; } else cls.connect_time = -99999; // fire immediately cls.state = ca_connecting; Com_Printf ("reconnecting...\n"); } } /* ================= CL_ParseStatusMessage Handle a reply from a status request ================= */ void CL_ParseFullStatusMessage (void) { char *s; s = MSG_ReadString(&net_message); Com_Printf ("TESTING!!!!%s\n", s); M_AddToServerList (net_from, s); } /* =================== GetServerList Get a list of servers from the master =================== */ static void GetServerList (void) { char *requeststring; netadr_t adr; // this function may block => sound channels might not be updated // while it does so => prevent 'looping sound effect' while waiting // -JR / 20050731 / 2 S_StopAllSounds (); requeststring = va( "query" ); // send a broadcast packet Com_Printf( "querying %s...\n", cl_master->string ); if( NET_StringToAdr( cl_master->string, &adr ) ) { if( !adr.port ) adr.port = BigShort( PORT_MASTER ); Netchan_OutOfBandPrint( NS_CLIENT, adr, requeststring ); } else { Com_Printf( "Bad address: %s\n", cl_master->string); } // Query secondary server Com_Printf( "querying %s...\n", cl_master2->string ); if ( NET_StringToAdr( cl_master2->string, &adr ) ) { if ( !adr.port ) adr.port = BigShort( PORT_MASTER ); Netchan_OutOfBandPrint( NS_CLIENT, adr, requeststring ); } else { Com_Printf( "Bad address: %s\n", cl_master2->string); } // Tactical mode to do: Query third server - tactical servers will only reside on this server // Reset server list for incoming responses. numServers = 0; } /* ================= CL_ParseGetServersResponse Handle a reply from getservers message to master server ================= */ static void CL_ParseGetServersResponse() { cvar_t *noudp; cvar_t *noipx; netadr_t adr; char adrString[32]; byte addr[4]; byte port[2]; int idx; unsigned short uport; qboolean dupe; MSG_BeginReading (&net_message); MSG_ReadLong (&net_message); // skip the -1 noudp = Cvar_Get ("noudp", "0", CVAR_NOSET); if (!noudp->integer) { adr.type = NA_BROADCAST; } noipx = Cvar_Get ("noipx", "0", CVAR_NOSET); if (!noipx->integer) { adr.type = NA_BROADCAST_IPX; } if ( net_message.readcount + 8 < net_message.cursize ) net_message.readcount += 8; while( net_message.readcount +6 <= net_message.cursize ) { if (numServers == 64) break; // No room left. MSG_ReadData( &net_message, addr, 4 ); Com_sprintf( adrString, sizeof( adrString ), "%u.%u.%u.%u", addr[0], addr[1], addr[2], addr[3]); MSG_ReadData( &net_message, port, 2 ); /* network byte order (bigendian) */ /* convert to unsigned short in host byte order */ uport = (unsigned short) ((port[0] << 8) + port[1]); dupe = false; // Check that we don't have a duplicate entry. for (idx = 0; idx < numServers; idx++) { if ( !strcmp(servers[idx].ip, adrString) && servers[idx].port == uport) { Com_Printf("Already have: %s:%u\n", adrString, uport); dupe = true; break; } } if (dupe) continue; memcpy( &servers[numServers].ip, adrString, sizeof(servers[numServers].ip) ); servers[numServers].port = uport; if (!NET_StringToAdr (servers[numServers].ip, &adr)) { Com_Printf ("Bad address: %s\n", servers[numServers].ip); continue; } Com_Printf ("pinging %s:%hu...\n", servers[numServers].ip, servers[numServers].port ); /* adr.port is in network byte order (bigendian) */ adr.port = (unsigned short)BigShort( servers[numServers].port ); if (!adr.port) { adr.port = BigShort(PORT_SERVER); } Netchan_OutOfBandPrint (NS_CLIENT, adr, va("status %i", PROTOCOL_VERSION)); servers[numServers].starttime = Sys_Milliseconds(); ++numServers; } } /* ================= CL_GetPingStartTime Return ping starttime for server given its address. Returns 0 if not found. ================= */ int CL_GetPingStartTime(netadr_t adr) { int idx; char adrString[32]; unsigned short port; Com_sprintf(adrString, sizeof(adrString), "%u.%u.%u.%u", adr.ip[0], adr.ip[1], adr.ip[2], adr.ip[3]); port = (unsigned short) BigShort(adr.port); for (idx = 0; idx < numServers; idx++) { if (! strcmp(adrString, servers[idx].ip) && port == servers[idx].port) { return servers[idx].starttime; } } return 0; } /* ================= CL_PingServers_f ================= */ static void CL_ReadPackets (); void CL_PingServers_f (void) { int i; netadr_t adr; char name[32]; char *adrstring; cvar_t *noudp; cvar_t *noipx; NET_Config (true); // allow remote GetServerList(); //get list from COR master server // send a broadcast packet Com_Printf ("pinging broadcast...\n"); noudp = Cvar_Get ("noudp", "0", CVAR_NOSET); if (!noudp->integer) { adr.type = NA_BROADCAST; adr.port = BigShort(PORT_SERVER); Netchan_OutOfBandPrint (NS_CLIENT, adr, va("status %i", PROTOCOL_VERSION)); } noipx = Cvar_Get ("noipx", "0", CVAR_NOSET); if (!noipx->integer) { adr.type = NA_BROADCAST_IPX; adr.port = BigShort(PORT_SERVER); Netchan_OutOfBandPrint (NS_CLIENT, adr, va("status %i", PROTOCOL_VERSION)); } // send a packet to each address book entry for (i=0 ; i<16 ; i++) { Com_sprintf (name, sizeof(name), "adr%i", i); adrstring = Cvar_VariableString (name); if (!adrstring || !adrstring[0]) continue; Com_Printf ("pinging %s...\n", adrstring); if (!NET_StringToAdr (adrstring, &adr)) { Com_Printf ("Bad address: %s\n", adrstring); continue; } if (!adr.port) adr.port = BigShort(PORT_SERVER); Netchan_OutOfBandPrint (NS_CLIENT, adr, va("status %i", PROTOCOL_VERSION)); } // Note that all we have done thus far is // - Request server lists from the two master servers // - Sent a broadcast to the LAN looking for local servers // When CL_ReadPackets gets the responses from the master server, it will // automatically ping all the game servers. Ideally, if the net connection // is pretty good, we can get that all done in the following loop. The // game's main loop will catch any stragglers. // Read packets at 5 ms intervals 60 times. That's 300 ms. Figure maybe // 100-150 ms round trip to the master server, then another 100-150 ms // round trip to the game servers. So we should be able to grab any // servers 150 ping or less and gauge their pings to within 5 ms or so. #define PING_LOOP_TOTAL_MS 300 #define PING_LOOP_INTERVAL_MS 5 #define PING_LOOP_ITERATIONS (PING_LOOP_TOTAL_MS/PING_LOOP_INTERVAL_MS) for (i = 0; i < PING_LOOP_ITERATIONS; i++) { #if defined UNIX_VARIANT usleep (PING_LOOP_INTERVAL_MS*1000); #elif defined WIN32_VARIANT Sleep (PING_LOOP_INTERVAL_MS); #else #warning client/cl_main.c: CL_PingServers_f (): \ Do not know what sleep function to use! break; #endif CL_ReadPackets (); } // -JD restart the menu music that was stopped during this procedure S_StartMenuMusic(); } /* ================= CL_Skins_f Load or download any custom player skins and models ================= */ void CL_Skins_f (void) { int i; for (i=0 ; istring, sizeof(currLoginState.old_password)); Com_Printf("Password change successful!\n"); } else { Com_Printf("Account validated!\n"); currLoginState.validated = true; } return; } // server connection if (!strcmp(c, "client_connect")) { if (cls.state == ca_connected) { Com_Printf ("Dup connect received. Ignored.\n"); return; } Netchan_Setup (NS_CLIENT, &cls.netchan, net_from, cls.quakePort); MSG_WriteChar (&cls.netchan.message, clc_stringcmd); MSG_WriteString (&cls.netchan.message, "new"); cls.state = ca_connected; memset(cls.downloadurl, 0, sizeof(cls.downloadurl)); if(Cmd_Argc() == 2) // http download url { strncpy(cls.downloadurl, Cmd_Argv(1), sizeof(cls.downloadurl) - 1); } is_localhost = !strcmp(cls.servername, "localhost"); Netchan_OutOfBandPrint (NS_CLIENT, net_from, va("status %i", PROTOCOL_VERSION)); return; } // remote command from gui front end if (!strcmp(c, "cmd")) { if (!NET_IsLocalAddress(net_from)) { Com_Printf ("Command packet from remote host. Ignored.\n"); return; } Sys_AppActivate (); s = MSG_ReadString (&net_message); Cbuf_AddText (s); Cbuf_AddText ("\n"); return; } // print command from somewhere if (!strcmp(c, "print")) { s = MSG_ReadString (&net_message); if (s[0] == '\\') { char *playerinfo_start; if (cls.state >= ca_connected && !memcmp(&net_from, &cls.netchan.remote_address, sizeof(netadr_t))) M_UpdateConnectedServerInfo (net_from, s); if (cls.key_dest == key_menu) { M_AddToServerList (net_from, s); //add net_from so we have the addy } else { // If someone called pingservers () directly from the console, // chances are he wants to read the server list manually // anyway. playerinfo_start = strchr (s, '\n'); *playerinfo_start++ = '\0'; Info_Print (s); Com_Printf ("%s", playerinfo_start); } } else Com_Printf ("%s", s); return; } // ping from somewhere if (!strcmp(c, "ping")) { Netchan_OutOfBandPrint (NS_CLIENT, net_from, "ack"); return; } // challenge from the server we are connecting to if (!strcmp(c, "challenge")) { cls.challenge = atoi(Cmd_Argv(1)); CL_SendConnectPacket (); return; } // echo request from server if (!strcmp(c, "echo")) { Netchan_OutOfBandPrint (NS_CLIENT, net_from, "%s", Cmd_Argv(1) ); return; } if (!strcmp(c, "teamgame")) { server_is_team = atoi (Cmd_Argv(1)); return; } Com_Printf ("Unknown command.\n"); } /* ================= CL_DumpPackets A vain attempt to help bad TCP stacks that cause problems when they overflow ================= */ void CL_DumpPackets (void) { while (NET_GetPacket (NS_CLIENT, &net_from, &net_message)) { Com_Printf ("dumping a packet\n"); } } /* ================= CL_ReadPackets ================= */ int c_incoming_bytes = 0; static void CL_ReadPackets (void) { while (NET_GetPacket (NS_CLIENT, &net_from, &net_message)) { c_incoming_bytes += net_message.cursize; // // remote command packet // if (*(int *)net_message.data == -1) { CL_ConnectionlessPacket (); continue; } if (cls.state == ca_disconnected || cls.state == ca_connecting) continue; // dump it if not connected if (net_message.cursize < 8) { Com_Printf ("%s: Runt packet\n",NET_AdrToString(net_from)); continue; } // // packet from server // if (!NET_CompareAdr (net_from, cls.netchan.remote_address)) { Com_DPrintf ("%s:sequenced packet without connection\n" ,NET_AdrToString(net_from)); continue; } if (!Netchan_Process(&cls.netchan, &net_message)) continue; // wasn't accepted for some reason CL_ParseServerMessage (); } // // check timeout // if (cls.state >= ca_connected && cls.realtime - cls.netchan.last_received > cl_timeout->value*1000) { if (++cl.timeoutcount > 5) // timeoutcount saves debugger { Com_Printf ("\nServer connection timed out.\n"); CL_Disconnect (); return; } } else cl.timeoutcount = 0; } //============================================================================= /* ============== CL_FixUpGender_f ============== */ void CL_FixUpGender(void) { char *p; char sk[80]; if (gender_auto->integer) { if (gender->modified) { // was set directly, don't override the user gender->modified = false; return; } strncpy(sk, skin->string, sizeof(sk) - 2); sk[sizeof(sk) - 1] = '\0'; // in case skin->string is 79 chars or more if ((p = strchr(sk, '/')) != NULL) *p = 0; if (Q_strcasecmp(sk, "male") == 0 || Q_strcasecmp(sk, "cyborg") == 0) Cvar_Set ("gender", "male"); else if (Q_strcasecmp(sk, "female") == 0 || Q_strcasecmp(sk, "crackhor") == 0) Cvar_Set ("gender", "female"); else Cvar_Set ("gender", "none"); gender->modified = false; } } /* ============== CL_Userinfo_f ============== */ void CL_Userinfo_f (void) { Com_Printf ("User info settings:\n"); Info_Print (Cvar_Userinfo()); } /* ================= CL_Snd_Restart_f Restart the sound subsystem so it can pick up new parameters and flush all sounds ================= */ void CL_Snd_Restart_f (void) { S_Shutdown (); S_Init (); CL_RegisterSounds (); } int precache_check; // for autodownload of precache items int precache_spawncount; int precache_tex; int precache_model_skin; byte *precache_model; // used for skin checking in alias models #define PLAYER_MULT 5 // ENV_CNT is map load, ENV_CNT+1 is first env map #define ENV_CNT (CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT) #define TEXTURE_CNT (ENV_CNT+13) #define SCRIPT_CNT (TEXTURE_CNT+999) static const char *env_suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"}; void CL_RequestNextDownload (void) { unsigned map_checksum; // for detecting cheater maps char fn[MAX_OSPATH]; char map[MAX_OSPATH]; char script[MAX_OSPATH]; dmdl_t *pheader; int i, j; if (cls.state != ca_connected) return; if (!allow_download->integer && precache_check < ENV_CNT) precache_check = ENV_CNT; if (precache_check == CS_MODELS) // confirm map { precache_check = CS_MODELS+2; // 0 isn't used if (allow_download_maps->integer) if (!CL_CheckOrDownloadFile(cl.configstrings[CS_MODELS+1])) return; // started a download } redoSkins: if (precache_check >= CS_MODELS && precache_check < CS_MODELS+MAX_MODELS) { if (allow_download_models->integer) { while (precache_check < CS_MODELS+MAX_MODELS && cl.configstrings[precache_check][0]) { if (cl.configstrings[precache_check][0] == '*' || cl.configstrings[precache_check][0] == '#') { precache_check++; continue; } //do not download player models from this section else if (cl.configstrings[precache_check][0] == 'p' && cl.configstrings[precache_check][1] == 'l' && cl.configstrings[precache_check][2] == 'a' && cl.configstrings[precache_check][3] == 'y' && cl.configstrings[precache_check][4] == 'e' && cl.configstrings[precache_check][5] == 'r' && cl.configstrings[precache_check][6] == 's') { precache_check++; continue; } if (precache_model_skin == 0) { if (!CL_CheckOrDownloadFile(cl.configstrings[precache_check])) { precache_model_skin = 1; return; // started a download } precache_model_skin = 1; } // checking for skins in the model if (!precache_model) { FS_LoadFile (cl.configstrings[precache_check], (void **)&precache_model); if (!precache_model) { precache_model_skin = 0; precache_check++; continue; // couldn't load it } if (LittleLong(*(unsigned *)precache_model) != IDALIASHEADER) { // not an alias model FS_FreeFile(precache_model); precache_model = 0; precache_model_skin = 0; precache_check++; continue; } pheader = (dmdl_t *)precache_model; if (LittleLong (pheader->version) != ALIAS_VERSION) { precache_check++; precache_model_skin = 0; continue; // couldn't load it } } pheader = (dmdl_t *)precache_model; while (precache_model_skin - 1 < LittleLong(pheader->num_skins)) { if (!CL_CheckOrDownloadFile((char *)precache_model + LittleLong(pheader->ofs_skins) + (precache_model_skin - 1)*MAX_SKINNAME)) { precache_model_skin++; return; // started a download } precache_model_skin++; } if (precache_model) { FS_FreeFile(precache_model); precache_model = 0; } precache_model_skin = 0; precache_check++; } } if (precache_model) { precache_check = CS_MODELS + 2; precache_model_skin = 0; goto redoSkins; } precache_check = CS_SOUNDS; } if (precache_check >= CS_SOUNDS && precache_check < CS_SOUNDS+MAX_SOUNDS) { if (allow_download_sounds->integer) { if (precache_check == CS_SOUNDS) precache_check++; // zero is blank while (precache_check < CS_SOUNDS+MAX_SOUNDS && cl.configstrings[precache_check][0]) { if (cl.configstrings[precache_check][0] == '*') { precache_check++; continue; } Com_sprintf(fn, sizeof(fn), "sound/%s", cl.configstrings[precache_check++]); if (!CL_CheckOrDownloadFile(fn)) return; // started a download } } precache_check = CS_IMAGES; } if (precache_check >= CS_IMAGES && precache_check < CS_IMAGES+MAX_IMAGES) { if (precache_check == CS_IMAGES) precache_check++; // zero is blank while (precache_check < CS_IMAGES+MAX_IMAGES && cl.configstrings[precache_check][0]) { Com_sprintf(fn, sizeof(fn), "pics/%s.tga", cl.configstrings[precache_check++]); if (!CL_CheckOrDownloadFile(fn)) return; // started a download } precache_check = CS_PLAYERSKINS; } if (precache_check >= CS_PLAYERSKINS && precache_check < CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT) { if (allow_download_players->integer) { while (precache_check < CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT) { int i, n; char model[MAX_QPATH], skin[MAX_QPATH], *p; i = (precache_check - CS_PLAYERSKINS)/PLAYER_MULT; n = (precache_check - CS_PLAYERSKINS)%PLAYER_MULT; if (!cl.configstrings[CS_PLAYERSKINS+i][0]) { precache_check = CS_PLAYERSKINS + (i + 1) * PLAYER_MULT; continue; } if ((p = strchr(cl.configstrings[CS_PLAYERSKINS+i], '\\')) != NULL) p++; else p = cl.configstrings[CS_PLAYERSKINS+i]; strcpy(model, p); p = strchr(model, '/'); if (!p) p = strchr(model, '\\'); if (p) { *p++ = 0; strcpy(skin, p); } else *skin = 0; switch (n) { case 0: // model Com_sprintf(fn, sizeof(fn), "players/%s/tris.iqm", model); if (!CL_CheckOrDownloadFile(fn)) { precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 1; return; // started a download } n++; /*FALL THROUGH*/ case 1: // weapon model Com_sprintf(fn, sizeof(fn), "players/%s/weapon.iqm", model); if (!CL_CheckOrDownloadFile(fn)) { precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 2; return; // started a download } n++; /*FALL THROUGH*/ case 2: // weapon skin Com_sprintf(fn, sizeof(fn), "players/%s/weapon.jpg", model); if (!CL_CheckOrDownloadFile(fn)) { precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 3; return; // started a download } n++; /*FALL THROUGH*/ case 3: // skin Com_sprintf(fn, sizeof(fn), "players/%s/%s.jpg", model, skin); if (!CL_CheckOrDownloadFile(fn)) { precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 4; return; // started a download } n++; /*FALL THROUGH*/ case 4: // skin_i Com_sprintf(fn, sizeof(fn), "players/%s/%s_i.jpg", model, skin); if (!CL_CheckOrDownloadFile(fn)) { precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 5; return; // started a download } // move on to next model precache_check = CS_PLAYERSKINS + (i + 1) * PLAYER_MULT; } } } // precache phase completed precache_check = ENV_CNT; } if (precache_check == ENV_CNT) { precache_check = ENV_CNT + 1; //FIXME: support for new map specification files CM_LoadBSP (cl.configstrings[CS_MODELS+1], true, &map_checksum); if (map_checksum != atoi(cl.configstrings[CS_MAPCHECKSUM])) { Com_Error (ERR_DROP, "Local map version differs from server: %i != '%s'\n", map_checksum, cl.configstrings[CS_MAPCHECKSUM]); return; } } if (precache_check > ENV_CNT && precache_check < TEXTURE_CNT) { if (allow_download->integer && allow_download_maps->integer) { while (precache_check < TEXTURE_CNT) { int n = precache_check++ - ENV_CNT - 1; Com_sprintf(fn, sizeof(fn), "env/%s%s.tga", cl.configstrings[CS_SKY], env_suf[n/2]); if (!CL_CheckOrDownloadFile(fn)) return; // started a download } } precache_check = TEXTURE_CNT; } if (precache_check == TEXTURE_CNT) { precache_check = TEXTURE_CNT+1; precache_tex = 0; } // confirm existance of textures, download any that don't exist if (precache_check == TEXTURE_CNT+1) { // from qcommon/cmodel.c extern int numtexinfo; extern mapsurface_t map_surfaces[]; if (allow_download->integer && allow_download_maps->integer) { while (precache_tex < numtexinfo) { char fn[MAX_OSPATH]; sprintf(fn, "textures/%s.tga", map_surfaces[precache_tex++].rname); if (!CL_CheckOrDownloadFile(fn)) return; // started a download } } precache_check = SCRIPT_CNT; } //get map related scripts if (precache_check == SCRIPT_CNT) { precache_check = SCRIPT_CNT+1; if (allow_download_maps->integer) { //get fog files COM_StripExtension ( cl.configstrings[CS_MODELS+1], fn ); //remove "maps/" from string for(i = 5, j = 0; i < strlen(fn); i++, j++) { map[j] = fn[i]; } map[i-5] = 0; Com_sprintf(script, sizeof(script), "maps/scripts/%s.fog", map); if (!CL_CheckOrDownloadFile(script)) return; // started a download } } if (precache_check == SCRIPT_CNT+1) { precache_check = SCRIPT_CNT+2; if (allow_download_maps->integer) { //get mus files COM_StripExtension ( cl.configstrings[CS_MODELS+1], fn ); //remove "maps/" from string for(i = 5, j = 0; i < strlen(fn); i++, j++) map[j] = fn[i]; map[i-5] = 0; Com_sprintf(script, sizeof(script), "maps/scripts/%s.mus", map); if (!CL_CheckOrDownloadFile(script)) return; // started a download } } if (precache_check == SCRIPT_CNT+2) { precache_check = SCRIPT_CNT+3; if (allow_download_maps->integer) { //get rscript files COM_StripExtension ( cl.configstrings[CS_MODELS+1], fn ); //remove "maps/" from string for(i = 5, j = 0; i < strlen(fn); i++, j++) map[j] = fn[i]; map[i-5] = 0; Com_sprintf(script, sizeof(script), "scripts/maps/%s.rscript", map); if (!CL_CheckOrDownloadFile(script)) return; // started a download } } if (precache_check == SCRIPT_CNT+3) // try downloading lightmap { precache_check = SCRIPT_CNT+4; if (allow_download_maps->integer) { char *extension; strncpy (fn, cl.configstrings[CS_MODELS+1], MAX_OSPATH-1-strlen(".lightmap")+strlen(".bsp")); extension = strstr (fn, ".bsp"); if (extension) *extension = 0; strcat (fn, ".lightmap"); if (!CL_CheckOrDownloadFile(fn)) return; // started a download } } //ZOID CL_RegisterSounds (); CL_PrepRefresh (); MSG_WriteByte (&cls.netchan.message, clc_stringcmd); MSG_WriteString (&cls.netchan.message, va("begin %i\n", precache_spawncount) ); { netadr_t adr; if (!NET_StringToAdr (cls.servername, &adr)) { Com_Printf ("Bad address: %s\n", cls.servername); return; } // default true to avoid messing up legacy ctf servers // legacy DM servers don't send visibility lights anyway server_is_team = true; Netchan_OutOfBandPrint (NS_CLIENT, adr, "teamgame\n"); } } netadr_t *CL_GetRemoteServer (void) { static netadr_t remoteserver; if (cls.state >= ca_connected) { remoteserver = cls.netchan.remote_address; return &remoteserver; } return NULL; } /* ================= CL_Precache_f The server will send this command right before allowing the client into the server ================= */ void CL_Precache_f (void) { //Yet another hack to let old demos work //the old precache sequence if (Cmd_Argc() < 2) { unsigned map_checksum; // for detecting cheater maps //FIXME: support for new map specification files CM_LoadBSP (cl.configstrings[CS_MODELS+1], true, &map_checksum); CL_RegisterSounds (); CL_PrepRefresh (); return; } precache_check = CS_MODELS; precache_spawncount = atoi(Cmd_Argv(1)); precache_model = 0; precache_model_skin = 0; CL_RequestNextDownload(); } /* ================= CL_InitLocal ================= */ void CL_InitLocal (void) { cls.state = ca_disconnected; cls.realtime = Sys_Milliseconds (); CL_InitInput (); CL_InitHttpDownload(); CL_IRCSetup( ); adr0 = Cvar_Get( "adr0", "", CVAR_ARCHIVE ); adr1 = Cvar_Get( "adr1", "", CVAR_ARCHIVE ); adr2 = Cvar_Get( "adr2", "", CVAR_ARCHIVE ); adr3 = Cvar_Get( "adr3", "", CVAR_ARCHIVE ); adr4 = Cvar_Get( "adr4", "", CVAR_ARCHIVE ); adr5 = Cvar_Get( "adr5", "", CVAR_ARCHIVE ); adr6 = Cvar_Get( "adr6", "", CVAR_ARCHIVE ); adr7 = Cvar_Get( "adr7", "", CVAR_ARCHIVE ); adr8 = Cvar_Get( "adr8", "", CVAR_ARCHIVE ); // // register our variables // cl_stereo_separation = Cvar_Get( "cl_stereo_separation", "0.4", CVAR_ARCHIVE | CVARDOC_FLOAT ); cl_stereo = Cvar_Get( "cl_stereo", "0", CVARDOC_BOOL ); background_music = Cvar_Get("background_music", "1", CVAR_ARCHIVE | CVARDOC_BOOL); background_music_vol = Cvar_Get("background_music_vol", "0.5", CVAR_ARCHIVE | CVARDOC_FLOAT); cl_add_blend = Cvar_Get ("cl_blend", "1", CVAR_ARCHIVE | CVARDOC_BOOL); cl_add_lights = Cvar_Get ("cl_lights", "1", CVARDOC_BOOL); cl_add_particles = Cvar_Get ("cl_particles", "1", CVARDOC_BOOL); cl_add_entities = Cvar_Get ("cl_entities", "1", CVARDOC_BOOL); cl_gun = Cvar_Get ("cl_gun", "1", CVAR_ARCHIVE | CVARDOC_BOOL); cl_footsteps = Cvar_Get ("cl_footsteps", "1", CVARDOC_BOOL); cl_noskins = Cvar_Get ("cl_noskins", "0", CVAR_ARCHIVE | CVARDOC_BOOL); cl_autoskins = Cvar_Get ("cl_autoskins", "0", CVARDOC_BOOL); cl_predict = Cvar_Get ("cl_predict", "1", CVARDOC_BOOL); cl_maxfps = Cvar_Get ("cl_maxfps", "60", CVAR_ARCHIVE | CVARDOC_INT); cl_showPlayerNames = Cvar_Get ("cl_showplayernames", "0", CVAR_ARCHIVE | CVARDOC_INT); Cvar_Describe (cl_showPlayerNames, "0 means no nametags, 1 means show one nametag in the center of the screen, 2 means show a nametag over each player."); cl_healthaura = Cvar_Get ("cl_healthaura", "1", CVAR_ARCHIVE | CVARDOC_BOOL); Cvar_Describe (cl_healthaura, "show glowing effects around health pickups."); cl_noblood = Cvar_Get ("cl_noblood", "0", CVAR_ARCHIVE | CVARDOC_BOOL); cl_disbeamclr = Cvar_Get("cl_disbeamclr", "0", CVAR_ARCHIVE | CVARDOC_INT); Cvar_Describe (cl_disbeamclr, "beam color for the disruptor weapon. 0 = green, 1 = blue, 2 = red, 3 = yellow, 4 = purple."); cl_brass = Cvar_Get ("cl_brass", "1", CVAR_ARCHIVE | CVARDOC_BOOL); cl_dmlights = Cvar_Get("cl_dmlights", "1", CVAR_ARCHIVE | CVARDOC_BOOL); cl_playtaunts = Cvar_Get ("cl_playtaunts", "1", CVAR_ARCHIVE | CVARDOC_BOOL); cl_centerprint = Cvar_Get ("cl_centerprint", "1", CVAR_ARCHIVE | CVARDOC_BOOL); cl_precachecustom = Cvar_Get ("cl_precachecustom", "0", CVAR_ARCHIVE | CVARDOC_BOOL); Cvar_Describe (cl_precachecustom, "precache 3rd-party and custom player skins at the first map load."); cl_simpleitems = Cvar_Get ("cl_simpleitems", "0", CVAR_ARCHIVE | CVARDOC_BOOL); Cvar_Describe (cl_simpleitems, "show sprites instead of models for pickup items."); cl_flicker = Cvar_Get ("cl_flicker", "1", CVAR_ARCHIVE | CVARDOC_BOOL); Cvar_Describe (cl_flicker, "enable flickering world lighting."); cl_paindist = Cvar_Get ("cl_paindist", "1", CVAR_ARCHIVE); cl_explosiondist = Cvar_Get ("cl_explosiondist", "1", CVAR_ARCHIVE); cl_raindist = Cvar_Get ("cl_raindist", "1", CVAR_ARCHIVE); cl_upspeed = Cvar_Get ("cl_upspeed", "200", 0); cl_forwardspeed = Cvar_Get ("cl_forwardspeed", "200", 0); cl_sidespeed = Cvar_Get ("cl_sidespeed", "200", 0); cl_yawspeed = Cvar_Get ("cl_yawspeed", "140", 0); cl_pitchspeed = Cvar_Get ("cl_pitchspeed", "150", 0); cl_anglespeedkey = Cvar_Get ("cl_anglespeedkey", "1.5", 0); cl_run = Cvar_Get ("cl_run", "0", CVAR_ARCHIVE | CVARDOC_BOOL); freelook = Cvar_Get( "freelook", "0", CVAR_ARCHIVE | CVARDOC_BOOL); lookspring = Cvar_Get ("lookspring", "0", CVAR_ARCHIVE | CVARDOC_BOOL); lookstrafe = Cvar_Get ("lookstrafe", "0", CVAR_ARCHIVE | CVARDOC_BOOL); m_accel = Cvar_Get ("m_accel", "1", CVAR_ARCHIVE | CVARDOC_BOOL); sensitivity = Cvar_Get ("sensitivity", "3", CVAR_ARCHIVE | CVARDOC_FLOAT); menu_sensitivity = Cvar_Get("menu_sensitivity", "3", CVAR_ARCHIVE | CVARDOC_FLOAT); m_smoothing = Cvar_Get("m_smoothing", "0", CVAR_ARCHIVE | CVARDOC_BOOL); m_pitch = Cvar_Get ("m_pitch", "0.022", CVAR_ARCHIVE | CVARDOC_FLOAT); m_yaw = Cvar_Get ("m_yaw", "0.022", CVAR_ARCHIVE | CVARDOC_FLOAT); m_forward = Cvar_Get ("m_forward", "1", 0); m_side = Cvar_Get ("m_side", "1", 0); cl_shownet = Cvar_Get ("cl_shownet", "0", 0); cl_showmiss = Cvar_Get ("cl_showmiss", "0", 0); cl_showclamp = Cvar_Get ("showclamp", "0", 0); cl_timeout = Cvar_Get ("cl_timeout", "120", 0); cl_paused = Cvar_Get ("paused", "0", 0); cl_timedemo = Cvar_Get ("timedemo", "0", CVARDOC_BOOL); Cvar_Describe (cl_timedemo, "play back demos (recorded games) in benchmark mode."); cl_demoquit = Cvar_Get ("demoquit", "0", CVARDOC_BOOL); Cvar_Describe (cl_demoquit, "quit automatically after a demo has finished."); cl_speedrecord = Cvar_Get ("cl_speedrecord", "450", CVARDOC_INT); cl_alltimespeedrecord = Cvar_Get ("cl_alltimespeedrecord", "450", CVAR_ARCHIVE | CVARDOC_INT); rcon_client_password = Cvar_Get ("rcon_password", "", CVARDOC_STR); rcon_address = Cvar_Get ("rcon_address", "", CVARDOC_STR); cl_test = Cvar_Get ("cl_test", "0", CVAR_ARCHIVE); // // userinfo // info_password = Cvar_Get ("password", "", CVAR_USERINFO | CVARDOC_STR); info_spectator = Cvar_Get ("spectator", "0", CVAR_USERINFO | CVARDOC_BOOL); info_spectator_password = Cvar_Get ( "spectator_password", "", CVAR_USERINFO | CVARDOC_STR); name = Cvar_Get ("name", "unnamed", CVAR_USERINFO | CVAR_ARCHIVE | CVARDOC_STR); stats_password = Cvar_Get("stats_password", "password", CVAR_PROFILE | CVARDOC_STR); Q_strncpyz2(currLoginState.old_password, stats_password->string, sizeof(currLoginState.old_password)); currLoginState.hashed = false; pw_hashed = Cvar_Get("stats_pw_hashed", "0", CVAR_PROFILE | CVARDOC_BOOL); /* */ ValidatePlayerName( name->string, (strlen(name->string)+1) ); /* */ skin = Cvar_Get ("skin", "male/grunt", CVAR_USERINFO | CVAR_ARCHIVE | CVARDOC_STR); rate = Cvar_Get ("rate", "25000", CVAR_USERINFO | CVAR_ARCHIVE | CVARDOC_INT); // FIXME msg = Cvar_Get ("msg", "1", CVAR_USERINFO | CVAR_ARCHIVE); hand = Cvar_Get ("hand", "0", CVAR_USERINFO | CVAR_ARCHIVE); fov = Cvar_Get ("fov", "90", CVAR_USERINFO | CVAR_ARCHIVE | CVARDOC_INT); Cvar_Describe (fov, "horizontal field of view (in degrees.) Maximum 160."); gender = Cvar_Get ("gender", "male", CVAR_USERINFO | CVAR_ARCHIVE | CVARDOC_STR); gender_auto = Cvar_Get ("gender_auto", "1", CVAR_ARCHIVE); gender->modified = false; // clear this so we know when user sets it manually cl_vwep = Cvar_Get ("cl_vwep", "1", CVAR_ARCHIVE | CVARDOC_BOOL); cl_vehicle_huds = Cvar_Get ("cl_vehicle_huds", "1", CVAR_ARCHIVE | CVARDOC_BOOL); cl_master = Cvar_Get ("cl_master", "master.corservers.com", CVAR_ARCHIVE | CVARDOC_STR); cl_master2 = Cvar_Get ("cl_master2", "master2.corservers.com", CVAR_ARCHIVE | CVARDOC_STR); //custom huds cl_hudimage1 = Cvar_Get("cl_hudimage1", "pics/i_health.tga", CVAR_ARCHIVE | CVARDOC_STR); cl_hudimage2 = Cvar_Get("cl_hudimage2", "pics/i_score.tga", CVAR_ARCHIVE | CVARDOC_STR); //stats server cl_stats_server = Cvar_Get("cl_stats_server", "http://stats.planetarena.org", CVAR_ARCHIVE | CVARDOC_STR); //update checker cl_latest_game_version_url = Cvar_Get("cl_latest_game_version_server", "http://red.planetarena.org/version/crx_version", CVAR_ARCHIVE | CVARDOC_STR); //throwaway cvars Cvar_Get("g_dm_lights", "1", CVAR_ARCHIVE | CVAR_GAMEINFO | CVARDOC_BOOL); //mark this as archived even if game code doesn't run. // // register our commands // Cmd_AddCommand ("cmd", CL_ForwardToServer_f); Cmd_AddCommand ("pause", CL_Pause_f); Cmd_AddCommand ("pingservers", CL_PingServers_f); Cmd_AddCommand ("skins", CL_Skins_f); Cmd_AddCommand ("userinfo", CL_Userinfo_f); Cmd_AddCommand ("snd_restart", CL_Snd_Restart_f); Cmd_AddCommand ("changing", CL_Changing_f); Cmd_AddCommand ("disconnect", CL_Disconnect_f); Cmd_AddCommand ("record", CL_Record_f); Cmd_AddCommand ("stop", CL_Stop_f); Cmd_AddCommand ("quit", CL_Quit_f); Cmd_AddCommand ("connect", CL_Connect_f); Cmd_AddCommand ("reconnect", CL_Reconnect_f); Cmd_AddCommand ("rcon", CL_Rcon_f); Cmd_AddCommand ("setenv", CL_Setenv_f ); Cmd_AddCommand ("precache", CL_Precache_f); Cmd_AddCommand ("download", CL_Download_f); Cmd_AddCommand ("irc_connect", CL_InitIRC); Cmd_AddCommand ("irc_quit", CL_IRCInitiateShutdown); Cmd_AddCommand ("irc_say", CL_IRCSay); // // forward to server commands // // the only thing this does is allow command completion // to work -- all unknown commands are automatically // forwarded to the server. It also prevents the commands // from being ignored if they are issued in 'forced' mode. Cmd_AddCommand ("wave", NULL); Cmd_AddCommand ("inven", NULL); Cmd_AddCommand ("kill", NULL); Cmd_AddCommand ("use", NULL); Cmd_AddCommand ("drop", NULL); Cmd_AddCommand ("say", NULL); Cmd_AddCommand ("say_team", NULL); Cmd_AddCommand ("info", NULL); Cmd_AddCommand ("prog", NULL); Cmd_AddCommand ("give", NULL); Cmd_AddCommand ("god", NULL); Cmd_AddCommand ("notarget", NULL); Cmd_AddCommand ("noclip", NULL); Cmd_AddCommand ("invuse", NULL); Cmd_AddCommand ("invprevw", NULL); Cmd_AddCommand ("invnextw", NULL); Cmd_AddCommand ("invprevp", NULL); Cmd_AddCommand ("invnextp", NULL); Cmd_AddCommand ("invprev", NULL); Cmd_AddCommand ("invnext", NULL); Cmd_AddCommand ("invdrop", NULL); Cmd_AddCommand ("weapnext", NULL); Cmd_AddCommand ("weapprev", NULL); Cmd_AddCommand ("weaplast", NULL); Cmd_AddCommand ("chatbubble", NULL); Cmd_AddCommand ("players", NULL); Cmd_AddCommand ("score", NULL); Cmd_AddCommand ("vote", NULL); Cmd_AddCommand ("putaway", NULL); Cmd_AddCommand ("playerlist", NULL); Cvar_SetValue("scriptsloaded", 0); strcpy(map_music, "music/none.wav"); //register all our menu gfx (void)R_RegisterPic("m_main"); (void)R_RegisterPic("m_options"); (void)R_RegisterPic("menu_back"); (void)R_RegisterPic("m_video"); (void)R_RegisterPic("m_controls"); (void)R_RegisterPic("m_player"); (void)R_RegisterPic("m_bots"); (void)R_RegisterPic("m_startserver"); (void)R_RegisterPic("m_dmoptions"); (void)R_RegisterPic("m_mutators"); (void)R_RegisterPic("m_single"); (void)R_RegisterPic("m_quit"); (void)R_RegisterPic("m_main_mont0"); (void)R_RegisterPic("m_main_mont1"); (void)R_RegisterPic("m_main_mont2"); (void)R_RegisterPic("m_main_mont3"); (void)R_RegisterPic("m_main_mont4"); (void)R_RegisterPic("m_main_mont5"); (void)R_RegisterPic("hud_bomber"); (void)R_RegisterPic("hud_strafer"); (void)R_RegisterPic("hud_hover"); (void)R_RegisterPic("blood_ring"); remoteserver_runspeed = 300; //default } /* =============== CL_WriteConfiguration Writes key bindings and archived cvars to config.cfg =============== */ void CL_WriteConfiguration (void) { FILE *f; char path[MAX_OSPATH]; if (cls.state == ca_uninitialized) return; FS_FullWritePath( path, sizeof(path), "config.cfg"); f = fopen (path, "w"); if (!f) { Com_Printf ("Couldn't write config.cfg.\n"); return; } fprintf (f, "// generated by Alien Arena. Use autoexec.cfg for custom settings.\n"); Key_WriteBindings (f); fclose (f); Cvar_WriteVariables (path); } /* =============== CL_WriteProfile Writes profile information to profile.cfg =============== */ void CL_WriteProfile (void) { FILE *f; char path[MAX_OSPATH]; if (cls.state == ca_uninitialized) return; if(!currLoginState.hashed) return; //We don't ever want to write out non-hashed passwords, period! FS_FullWritePath( path, sizeof(path), "profile.cfg"); f = fopen (path, "w"); if (!f) { Com_Printf ("Couldn't write profile.cfg.\n"); return; } fprintf (f, "// generated by Alien Arena.\n"); fprintf (f, "set stats_password %s\n", stats_password->string); fprintf (f, "set stats_pw_hashed %i\n", pw_hashed->integer); fclose (f); } /* ================== CL_FixCvarCheats ================== */ typedef struct { char *name; char *value; cvar_t *var; } cheatvar_t; cheatvar_t cheatvars[] = { {"timescale", "1", NULL}, {"timedemo", "0", NULL}, {"r_drawworld", "1", NULL}, {"cl_testlights", "0", NULL}, {"r_fullbright", "0", NULL}, {"r_drawflat", "0", NULL}, {"paused", "0", NULL}, {"fixedtime", "0", NULL}, {"gl_lightmap", "0", NULL}, {"gl_showpolys", "0", NULL}, {NULL, NULL, NULL} }; void CL_FixCvarCheats (void) { static int numcheatvars = 0; int i; cheatvar_t *var; if ( !strcmp(cl.configstrings[CS_MAXCLIENTS], "1") || !cl.configstrings[CS_MAXCLIENTS][0] || cl.attractloop ) return; // single player or demo playback can cheat // find all the cvars if we haven't done it yet if (!numcheatvars) { while (cheatvars[numcheatvars].name) { cheatvars[numcheatvars].var = Cvar_Get (cheatvars[numcheatvars].name, cheatvars[numcheatvars].value, 0); numcheatvars++; } } // make sure they are all set to the proper values for (i=0, var = cheatvars ; iname, "timedemo" ) || !strcmp( var->name, "timescale")) ) continue; // allow these when running a .dm2 demo if ( strcmp (var->var->string, var->value) ) { Cvar_Set (var->name, var->value); } } } void CL_CheckFlagStatus( void ) { if(r_gotFlag) { //start the new music S_StartMusic(map_music_sec); } else if(r_lostFlag) { //start the original map music back up S_StartMusic(map_music); } } //============================================================================ qboolean send_packet_now = false; // instant packets. used during downloads extern float r_frametime; // TODO: move to appropriate .h extern unsigned sys_frame_time; // TODO: ditto /** * @brief Top level client-side routine for main loop. * * @param msec the time since the previous CL_Frame. */ /* * Notes on time variables: * cls.frametime : * float seconds since last render * clamped for packet processing, now unclamped for rendering * used in client-to-server move message * in CL_AddClEntities(): used in bouncing entities (brass) calculations * * r_frametime : * unclamped float seconds since last render. Used in particle rendering. * * cl.time : * critical global timer used in various places. * clamped to [cl.frame.servertime-100, cl.frame.servertime] in CL_ParseFrame() * * cls.realtime : * set to time at start of frame. Updated anywhere else? * * cl.frame.servertime: * equivalent to server frame number times 100msecs. see CL_ParseFrame() */ /* Packet Rate Limiting Cap in milliseconds * msecs=PPS :: 12=83, 13=76, 14=71, 15=66, 16=62 * Current choice is 16msec/62PPS nominal. * This matches the default cl_maxfps setting. * Which is 60, of course, but because of msec rounding, the result is 62 * This results in 6 packets per server frame, mostly. * Packet rate limiting is not invoked unless the PPS is set higher than the FPS. * Seems like a good idea not to invoke packet rate limiting unless the * cl_maxfps is set higher than the default. * * PKTRATE_EARLY is the minimum msecs for catching up when packets are delayed */ #define PKTRATE_CAP 16 #define PKTRATE_EARLY 12 void CL_Frame( int msec ) { // static int lasttimecalled = 0; // TODO: see below, obsolete logging? static int frcjitter[4] = { 0, -1, 0, 1 }; static int frcjitter_ix = 0; static int framerate_cap = 0; static int packetrate_cap = 0; static int packet_timer = 0; static int render_timer = 0; static int render_counter = 0; static int packet_delay = 0; int render_trigger; int packet_trigger; static perftest_t *speedometer = NULL; static perftest_t *accelerometer = NULL; if ( dedicated->integer ) { // crx running as dedicated server crashes without this. return; } cls.realtime = curtime; // time at start of Qcommon_Frame() cls.frametime = 0.0f; // zero here for debug purposes, set below cl.time += msec; // clamped to [cl.frame.servertime-100,cl.frame.servertime] /* local timers for decoupling frame rate from packet rate */ packet_timer += msec; render_timer += msec; if (!speedometer) { speedometer = get_perftest("speedometer"); if (speedometer) { speedometer->is_timerate = false; speedometer->cvar = Cvar_Get("cl_showspeedometer", "0", CVAR_ARCHIVE); strcpy (speedometer->format, "speed %4.0f u/s"); speedometer->scale = 1.0f;///12.3f; } } if (!accelerometer) { accelerometer = get_perftest("acceleromter"); if (accelerometer) { accelerometer->is_timerate = true; accelerometer->cvar = Cvar_Get("cl_showaccelerometer", "0", CVAR_ARCHIVE); strcpy (accelerometer->format, "accel %4.0f u/s/s"); accelerometer->scale = 1.0f; } } /* * update maximum FPS. * framerate_cap is in msecs/frame and is user specified. * Note: Quake2World sets a hard lower limit of 30. Not sure if * that is needed; to be determined if that is a good thing to do. */ if ( cl_maxfps->modified ) { if ( cl_maxfps->value < 30.0f ) { Com_Printf("Warning: cl_maxfps set to less than 30.\n"); if ( cl_maxfps->value < 1.0f ) { Cvar_ForceSet( "cl_maxfps", "1" ); } } cl_maxfps->modified = false; framerate_cap = 0; // force a recalculation } if ( framerate_cap < 1 ) { framerate_cap = (int)(ceil( 1000.0f / cl_maxfps->value )); if ( framerate_cap < 1 ) { framerate_cap = 1; } Com_DPrintf("framerate_cap set to %i msec\n", framerate_cap ); } /* * Set nominal milliseconds-per-packet for client-to-server messages. * Idea is to be timely in getting and transmitting player input without * congesting the server. * Plan is to not implement a user setting for this unless a need for that * is discovered. * If the cl_maxfps is set low, then FPS will limit PPS, and * packet rate limiting is bypassed. */ if ( cls.state == ca_connected ) { // receiving configstrings from the server, run at nominal 10PPS // avoids unnecessary load on the server if ( packetrate_cap != 100 ) Com_DPrintf("packet rate change: 10 PPS\n"); packetrate_cap = 100; } else if ( framerate_cap >= PKTRATE_CAP ) { // do not to throttle packet sending, run in sync with render if ( packetrate_cap != -1) Com_DPrintf("packetrate change: framerate\n"); packetrate_cap = -1; } else { // packet rate limiting if ( packetrate_cap != PKTRATE_CAP ) Com_DPrintf("packetrate change: %iPPS\n", 1000/PKTRATE_CAP); packetrate_cap = PKTRATE_CAP; } /* local triggers for decoupling framerate from packet rate */ render_trigger = 0; packet_trigger = 0; if ( cl_timedemo->integer == 1 ) { /* accumulate timed demo statistics, free run both packet and render */ /* setting render_trigger to 1 forces timedemo_start to be set if it * hasn't been already. It also forces cl.timedemo_frames to be * incremented. */ render_trigger = 1; packet_trigger = 1; } else { /* normal operation. */ /* Sometimes, the packetrate_cap can be "in phase" with * the frame rate affecting the average packets-per-server-frame. * A little jitter in the framerate_cap counteracts that. */ if ( render_timer >= (framerate_cap + frcjitter[frcjitter_ix]) ) { if ( ++frcjitter_ix > 3 ) frcjitter_ix = 0; render_trigger = 1; } if ( packetrate_cap == -1 ) { // flagged to run same as framerate_cap packet_trigger = render_trigger; } else if ( packet_timer >= packetrate_cap ) { // normal packet trigger packet_trigger = 1; } else if ( packet_delay > 0 ) { // packet sent in previous loop was delayed if ( packet_timer >= PKTRATE_EARLY ) { // should be ok to send a packet early /* idea is to try to maintain a steady number of * client-to-server packets per server frame. * If render is triggered, it is good to poll input and * send a packet to avoid more delay. * If adding the delay to the timer reaches the cap then * try to catch up * Otherwise, do nothing, the next loop should occur soon. */ if ( render_trigger || ((packet_timer + packet_delay) >= packetrate_cap) ) { packet_trigger = 1; } } } } if ( packet_trigger || send_packet_now || cls.download) { send_packet_now = false; // used during downloads if ( packetrate_cap > 0 && packet_timer > packetrate_cap ) { // difference between cap and timer, a delayed packet packet_delay = packet_timer - packetrate_cap; } else { packet_delay = 0; } render_counter = 0; // for counting renders since last packet /* let the mouse activate or deactivate */ IN_Frame(); /* * calculate frametime in seconds for packet procedures * cls.frametime is source for the cmd.msecs byte * in the client-to-server move message. */ cls.frametime = ((float)packet_timer) / 1000.0f; if ( cls.frametime >= 0.250f ) { /* very long delay */ /* * server checks for cmd.msecs to be <= 250 */ Com_DPrintf("CL_Frame(): cls.frametime clamped from %0.8f to 0.24999\n", cls.frametime ); cls.frametime = 0.24999f ; /* * try to throttle the video frame rate by overriding the * render trigger. */ render_trigger = false; render_timer = 0; } /* process server-to-client packets */ CL_ReadPackets(); /* execute pending commands */ Cbuf_Execute(); /* run cURL downloads */ CL_HttpDownloadThink(); /* * system dependent keyboard and mouse input event polling * accumulate keyboard and mouse events */ Sys_SendKeyEvents(); /* joystick input. may or may not be working. */ IN_Commands(); /* execute pending commands */ Cbuf_Execute(); /* * send client commands to server * these are construced from accumulated keyboard and mouse events, * which are then reset */ CL_SendCmd(); /* clear various cvars unless single player */ CL_FixCvarCheats (); /* resend a connection request if necessary */ CL_CheckForResend(); /* * predict movement for un-acked client-to-server packets * [The Quake trick that keeps players view smooth in on-line play.] */ CL_PredictMovement(); if (speedometer && speedometer->cvar->integer) { speedometer->counter = sqrt( cl.predicted_velocity[0]*cl.predicted_velocity[0]+ cl.predicted_velocity[1]*cl.predicted_velocity[1] ); if (speedometer->counter > cl_speedrecord->value) { Cvar_SetValue ("cl_speedrecord", speedometer->counter); if (speedometer->counter > cl_alltimespeedrecord->value) Cvar_SetValue ("cl_alltimespeedrecord", speedometer->counter); } } if (accelerometer && accelerometer->cvar->integer) { static float old_vel; float new_vel; new_vel = sqrt( cl.predicted_velocity[0]*cl.predicted_velocity[0]+ cl.predicted_velocity[1]*cl.predicted_velocity[1] ); accelerometer->counter += new_vel-old_vel; old_vel = new_vel; } /* retrigger packet send timer */ packet_timer = 0; } /* * refresh can occur on different frames than client-to-server messages. * when packet rate limiting is in effect */ if ( render_trigger ) { ++render_counter; // counting renders since last packet if (!packet_trigger && cl_test->integer) //return cl_test - this was causing major issues with menu mouse in windows build { /* * system dependent keyboard and mouse input event polling * accumulate keyboard and mouse events */ cls.frametime = ((float)packet_timer) / 1000.0f; Sys_SendKeyEvents(); /* * update view angles based on accumulated keyboard and mouse * events, which are *not* reset */ IN_Move(NULL); } /* * calculate cls.frametime in seconds for render procedures. * * May not need to clamp for rendering. * Only would affect things if framerate went below 4 FPS. * * Using a simple lowpass filter, to smooth out irregular timing. */ cls.frametime = (float)(render_timer) / 1000.0f; r_frametime = (r_frametime + cls.frametime + cls.frametime) / 3.0f; cls.frametime = r_frametime; // Update the display VID_CheckChanges(); if ( !cl.refresh_prepped && cls.state == ca_active ) { // re-initialize video configuration CL_PrepRefresh(); } else { // regular screen update if ( host_speeds->integer ) time_before_ref = Sys_Milliseconds(); // TODO: obsolete test? SCR_UpdateScreen(); if ( host_speeds->integer ) time_after_ref = Sys_Milliseconds(); } // check for flag and update music src if possesed or lost CL_CheckFlagStatus(); // update audio. S_Update( cl.refdef.vieworg, cl.v_forward, cl.v_right, cl.v_up ); // advance local effects for next frame CL_RunDLights(); CL_RunLightStyles(); SCR_RunConsole (); ++cls.framecount; // does not appear to be used anywhere /* developer test for observing timers */ // Com_DPrintf("rt: %i cft: %f\n", render_timer, cls.frametime ); // retrigger render timing render_timer = 0; #if 0 /* TODO: Check if this still works and/or is useful. */ if ( log_stats->value ) { if ( cls.state == ca_active ) { if ( !lasttimecalled ) { lasttimecalled = Sys_Milliseconds(); if ( log_stats_file ) fprintf( log_stats_file, "0\n" ); } else { int now = Sys_Milliseconds(); if ( log_stats_file ) fprintf( log_stats_file, "%d\n", now - lasttimecalled ); lasttimecalled = now; } } } #endif } } //============================================================================ /* ==================== CL_Init ==================== */ void CL_Init (void) { if (dedicated->integer) return; // nothing running on the client // Initialise fonts CL_gameFont = &_CL_gameFont; FNT_AutoInit( CL_gameFont , "freesans" , 0 , 65 , 8 , 48 ); CL_gameFont->faceVar = Cvar_Get( "fnt_game" , "orbitron" , CVAR_ARCHIVE ); CL_gameFont->sizeVar = Cvar_Get( "fnt_game_size" , "0" , CVAR_ARCHIVE ); FNT_AutoRegister( CL_gameFont ); CL_centerFont = &_CL_centerFont; FNT_AutoInit( CL_centerFont , "freesans" , 0 , 45 , 16 , 64 ); CL_centerFont->faceVar = CL_gameFont->faceVar; CL_centerFont->sizeVar = Cvar_Get( "fnt_center_size" , "0" , CVAR_ARCHIVE ); FNT_AutoRegister( CL_centerFont ); CL_consoleFont = &_CL_consoleFont; FNT_AutoInit( CL_consoleFont , "freesans" , 0 , 52 , 8 , 48 ); CL_consoleFont->faceVar = Cvar_Get( "fnt_console" , "freemono" , CVAR_ARCHIVE ); CL_consoleFont->sizeVar = Cvar_Get( "fnt_console_size" , "0" , CVAR_ARCHIVE ); FNT_AutoRegister( CL_consoleFont ); CL_menuFont = &_CL_menuFont; FNT_AutoInit( CL_menuFont , "freesans" , 0 , 48 , 8 , 48 ); CL_menuFont->faceVar = Cvar_Get( "fnt_menu" , "freesans" , CVAR_ARCHIVE ); CL_menuFont->sizeVar = Cvar_Get( "fnt_menu_size" , "0" , CVAR_ARCHIVE ); FNT_AutoRegister( CL_menuFont ); // all archived variables will now be loaded CON_Initialise( ); VID_Init (); S_Init (); V_Init (); net_message.data = net_message_buffer; net_message.maxsize = sizeof(net_message_buffer); M_Init (); SCR_Init (); cls.disable_screen = true; // don't draw yet CL_InitLocal (); IN_Init (); FS_ExecAutoexec (); // add commands from autoexec.cfg Cbuf_Execute (); if ( name && name->string[0] ) { ValidatePlayerName( name->string, (strlen(name->string)+1) ); } } /* =============== CL_Shutdown FIXME: this is a callback from Sys_Quit and Com_Error. It would be better to run quit through here before the final handoff to the sys code. =============== */ void CL_Shutdown(void) { static qboolean isdown = false; if (isdown) { printf ("recursive shutdown\n"); return; } isdown = true; STATS_Logout(); CL_IRCInitiateShutdown(); CL_ShutdownHttpDownload(); CL_WriteConfiguration (); CL_WriteProfile(); S_Shutdown(); IN_Shutdown (); VID_Shutdown(); CL_IRCWaitShutdown( ); NET_Shutdown(); RS_FreeAllScripts(); } alien-arena-7.66+dfsg/source/client/anorms.h0000600000175000017500000001451412161402010020035 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ {-0.525731, 0.000000, 0.850651}, {-0.442863, 0.238856, 0.864188}, {-0.295242, 0.000000, 0.955423}, {-0.309017, 0.500000, 0.809017}, {-0.162460, 0.262866, 0.951056}, {0.000000, 0.000000, 1.000000}, {0.000000, 0.850651, 0.525731}, {-0.147621, 0.716567, 0.681718}, {0.147621, 0.716567, 0.681718}, {0.000000, 0.525731, 0.850651}, {0.309017, 0.500000, 0.809017}, {0.525731, 0.000000, 0.850651}, {0.295242, 0.000000, 0.955423}, {0.442863, 0.238856, 0.864188}, {0.162460, 0.262866, 0.951056}, {-0.681718, 0.147621, 0.716567}, {-0.809017, 0.309017, 0.500000}, {-0.587785, 0.425325, 0.688191}, {-0.850651, 0.525731, 0.000000}, {-0.864188, 0.442863, 0.238856}, {-0.716567, 0.681718, 0.147621}, {-0.688191, 0.587785, 0.425325}, {-0.500000, 0.809017, 0.309017}, {-0.238856, 0.864188, 0.442863}, {-0.425325, 0.688191, 0.587785}, {-0.716567, 0.681718, -0.147621}, {-0.500000, 0.809017, -0.309017}, {-0.525731, 0.850651, 0.000000}, {0.000000, 0.850651, -0.525731}, {-0.238856, 0.864188, -0.442863}, {0.000000, 0.955423, -0.295242}, {-0.262866, 0.951056, -0.162460}, {0.000000, 1.000000, 0.000000}, {0.000000, 0.955423, 0.295242}, {-0.262866, 0.951056, 0.162460}, {0.238856, 0.864188, 0.442863}, {0.262866, 0.951056, 0.162460}, {0.500000, 0.809017, 0.309017}, {0.238856, 0.864188, -0.442863}, {0.262866, 0.951056, -0.162460}, {0.500000, 0.809017, -0.309017}, {0.850651, 0.525731, 0.000000}, {0.716567, 0.681718, 0.147621}, {0.716567, 0.681718, -0.147621}, {0.525731, 0.850651, 0.000000}, {0.425325, 0.688191, 0.587785}, {0.864188, 0.442863, 0.238856}, {0.688191, 0.587785, 0.425325}, {0.809017, 0.309017, 0.500000}, {0.681718, 0.147621, 0.716567}, {0.587785, 0.425325, 0.688191}, {0.955423, 0.295242, 0.000000}, {1.000000, 0.000000, 0.000000}, {0.951056, 0.162460, 0.262866}, {0.850651, -0.525731, 0.000000}, {0.955423, -0.295242, 0.000000}, {0.864188, -0.442863, 0.238856}, {0.951056, -0.162460, 0.262866}, {0.809017, -0.309017, 0.500000}, {0.681718, -0.147621, 0.716567}, {0.850651, 0.000000, 0.525731}, {0.864188, 0.442863, -0.238856}, {0.809017, 0.309017, -0.500000}, {0.951056, 0.162460, -0.262866}, {0.525731, 0.000000, -0.850651}, {0.681718, 0.147621, -0.716567}, {0.681718, -0.147621, -0.716567}, {0.850651, 0.000000, -0.525731}, {0.809017, -0.309017, -0.500000}, {0.864188, -0.442863, -0.238856}, {0.951056, -0.162460, -0.262866}, {0.147621, 0.716567, -0.681718}, {0.309017, 0.500000, -0.809017}, {0.425325, 0.688191, -0.587785}, {0.442863, 0.238856, -0.864188}, {0.587785, 0.425325, -0.688191}, {0.688191, 0.587785, -0.425325}, {-0.147621, 0.716567, -0.681718}, {-0.309017, 0.500000, -0.809017}, {0.000000, 0.525731, -0.850651}, {-0.525731, 0.000000, -0.850651}, {-0.442863, 0.238856, -0.864188}, {-0.295242, 0.000000, -0.955423}, {-0.162460, 0.262866, -0.951056}, {0.000000, 0.000000, -1.000000}, {0.295242, 0.000000, -0.955423}, {0.162460, 0.262866, -0.951056}, {-0.442863, -0.238856, -0.864188}, {-0.309017, -0.500000, -0.809017}, {-0.162460, -0.262866, -0.951056}, {0.000000, -0.850651, -0.525731}, {-0.147621, -0.716567, -0.681718}, {0.147621, -0.716567, -0.681718}, {0.000000, -0.525731, -0.850651}, {0.309017, -0.500000, -0.809017}, {0.442863, -0.238856, -0.864188}, {0.162460, -0.262866, -0.951056}, {0.238856, -0.864188, -0.442863}, {0.500000, -0.809017, -0.309017}, {0.425325, -0.688191, -0.587785}, {0.716567, -0.681718, -0.147621}, {0.688191, -0.587785, -0.425325}, {0.587785, -0.425325, -0.688191}, {0.000000, -0.955423, -0.295242}, {0.000000, -1.000000, 0.000000}, {0.262866, -0.951056, -0.162460}, {0.000000, -0.850651, 0.525731}, {0.000000, -0.955423, 0.295242}, {0.238856, -0.864188, 0.442863}, {0.262866, -0.951056, 0.162460}, {0.500000, -0.809017, 0.309017}, {0.716567, -0.681718, 0.147621}, {0.525731, -0.850651, 0.000000}, {-0.238856, -0.864188, -0.442863}, {-0.500000, -0.809017, -0.309017}, {-0.262866, -0.951056, -0.162460}, {-0.850651, -0.525731, 0.000000}, {-0.716567, -0.681718, -0.147621}, {-0.716567, -0.681718, 0.147621}, {-0.525731, -0.850651, 0.000000}, {-0.500000, -0.809017, 0.309017}, {-0.238856, -0.864188, 0.442863}, {-0.262866, -0.951056, 0.162460}, {-0.864188, -0.442863, 0.238856}, {-0.809017, -0.309017, 0.500000}, {-0.688191, -0.587785, 0.425325}, {-0.681718, -0.147621, 0.716567}, {-0.442863, -0.238856, 0.864188}, {-0.587785, -0.425325, 0.688191}, {-0.309017, -0.500000, 0.809017}, {-0.147621, -0.716567, 0.681718}, {-0.425325, -0.688191, 0.587785}, {-0.162460, -0.262866, 0.951056}, {0.442863, -0.238856, 0.864188}, {0.162460, -0.262866, 0.951056}, {0.309017, -0.500000, 0.809017}, {0.147621, -0.716567, 0.681718}, {0.000000, -0.525731, 0.850651}, {0.425325, -0.688191, 0.587785}, {0.587785, -0.425325, 0.688191}, {0.688191, -0.587785, 0.425325}, {-0.955423, 0.295242, 0.000000}, {-0.951056, 0.162460, 0.262866}, {-1.000000, 0.000000, 0.000000}, {-0.850651, 0.000000, 0.525731}, {-0.955423, -0.295242, 0.000000}, {-0.951056, -0.162460, 0.262866}, {-0.864188, 0.442863, -0.238856}, {-0.951056, 0.162460, -0.262866}, {-0.809017, 0.309017, -0.500000}, {-0.864188, -0.442863, -0.238856}, {-0.951056, -0.162460, -0.262866}, {-0.809017, -0.309017, -0.500000}, {-0.681718, 0.147621, -0.716567}, {-0.681718, -0.147621, -0.716567}, {-0.850651, 0.000000, -0.525731}, {-0.688191, 0.587785, -0.425325}, {-0.587785, 0.425325, -0.688191}, {-0.425325, 0.688191, -0.587785}, {-0.425325, -0.688191, -0.587785}, {-0.587785, -0.425325, -0.688191}, {-0.688191, -0.587785, -0.425325}, alien-arena-7.66+dfsg/source/client/cl_irc.c0000600000175000017500000016025512161402010017770 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. Copyright (C) 2010 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // cl_irc.c -- irc client #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "client.h" #include "qcommon/htable.h" #if defined WIN32_VARIANT # include # include typedef SOCKET irc_socket_t; #else # if defined HAVE_UNISTD_H # include # endif # include # include # include # include # include # include # include # include # include typedef int irc_socket_t; # if !defined HAVE_CLOSESOCKET # define closesocket close # endif # if !defined INVALID_SOCKET # define INVALID_SOCKET -1 # endif #endif /* IRC control cvars */ cvar_t * cl_IRC_connect_at_startup; cvar_t * cl_IRC_server; cvar_t * cl_IRC_channel; cvar_t * cl_IRC_port; cvar_t * cl_IRC_override_nickname; cvar_t * cl_IRC_nickname; cvar_t * cl_IRC_kick_rejoin; cvar_t * cl_IRC_reconnect_delay; /* * Timing controls * * In order to avoid actively waiting like crazy, there are many parts of the * IRC client code that need to sleep or wait for a timeout. However, if the * wait is too long, it makes the whole thing unreactive to e.g. the irc_say * command; if the wait is too shot, it starts using CPU time. * * The constants below control the timeouts. */ #define IRC_TIMEOUT_MS 250 #define IRC_TIMEOUT_US ( IRC_TIMEOUT_MS * 1000 ) #define IRC_TIMEOUTS_PER_SEC ( 1000 / IRC_TIMEOUT_MS) /* Ctype-like macros */ #define IS_UPPER(c) ( (c) >= 'A' && (c) <= 'Z' ) #define IS_LOWER(c) ( (c) >= 'a' && (c) <= 'z' ) #define IS_DIGIT(c) ( (c) >= '0' && (c) <= '9' ) #define IS_CNTRL(c) ( (c) >= 0 && (c) <= 31 ) #define IS_ALPHA(c) ( IS_UPPER(c) || IS_LOWER(c) ) #define IS_ALNUM(c) ( IS_ALPHA(c) || IS_DIGIT(c) ) /* IRC command status; used to determine if connection should be re-attempted or not */ #define IRC_CMD_SUCCESS 0 // Success #define IRC_CMD_FATAL 1 // Fatal error, don't bother retrying #define IRC_CMD_RETRY 2 // Recoverable error, command should be attempted again /* Constants that indicate the state of the IRC thread. */ #define IRC_THREAD_DEAD 0 // Thread is dead or hasn't been started #define IRC_THREAD_INITIALISING 1 // Thread is being initialised #define IRC_THREAD_CONNECTING 2 // Thread is attempting to connect #define IRC_THREAD_SETNICK 3 // Thread is trying to set the player's // nick #define IRC_THREAD_CONNECTED 4 // Thread established a connection to // the server and will attempt to join // the channel #define IRC_THREAD_JOINED 5 // Channel joined, ready to send or // receive messages #define IRC_THREAD_QUITTING 6 // The thread is being killed /* Function that sets the thread status when the thread dies. Since that is * system-dependent, it can't be done in the thread's main code. */ static void IRC_SetThreadDead( ); /* Status of the IRC thread */ static int IRC_ThreadStatus = IRC_THREAD_DEAD; /* Quit requested? */ static qboolean IRC_QuitRequested; /* Socket handler */ static irc_socket_t IRC_Socket; // Socket /* * The protocol parser uses a finite state machine, here are the various * states' definitions as well as a variable containing the current state * and various other variables for message building. */ #define IRC_PARSER_RECOVERY (-1) // Error recovery #define IRC_PARSER_START 0 // Start of a message #define IRC_PARSER_PFX_NOS_START 1 // Prefix start #define IRC_PARSER_PFX_NOS 2 // Prefix, server or nick name #define IRC_PARSER_PFX_USER_START 3 // Prefix, start of user name #define IRC_PARSER_PFX_USER 4 // Prefix, user name #define IRC_PARSER_PFX_HOST_START 5 // Prefix, start of host name #define IRC_PARSER_PFX_HOST 6 // Prefix, host name #define IRC_PARSER_COMMAND_START 7 // Start of command after a prefix #define IRC_PARSER_STR_COMMAND 8 // String command #define IRC_PARSER_NUM_COMMAND_2 9 // Numeric command, second character #define IRC_PARSER_NUM_COMMAND_3 10 // Numeric command, third character #define IRC_PARSER_NUM_COMMAND_4 11 // Numeric command end #define IRC_PARSER_PARAM_START 12 // Parameter start #define IRC_PARSER_MID_PARAM 13 // "Middle" parameter #define IRC_PARSER_TRAILING_PARAM 14 // Trailing parameter #define IRC_PARSER_LF 15 // End of line static int IRC_ParserState; static qboolean IRC_ParserInMessage; static qboolean IRC_ParserError; /* * According to RFC 1459, maximal message size is 512 bytes, including trailing * CRLF. */ #define IRC_MESSAGE_SIZE 512 #define IRC_SEND_BUF_SIZE IRC_MESSAGE_SIZE #define IRC_RECV_BUF_SIZE (IRC_MESSAGE_SIZE * 2) /* * IRC messages consist in: * 1) an optional prefix, which contains either a server name or a nickname, * 2) a command, which may be either a word or 3 numbers, * 3) any number of arguments. * * RFC 2812 says that there are at most 14 "middle" parameters and a trailing * parameter. However, UnrealIRCd does not respect this, and sends messages * that contain an extra parameter. While the message in question could be * ignored, it's better to avoid entering the error recovery state. * * Since we won't be handling messages in parallel, we will create a * static record and use that to store everything, as we can definitely * spare 130k of memory (note: we could have something smaller but it'd * probably be a pointless exercise). */ #define irc_string_t(len) struct { \ unsigned int length; \ char string[ len ]; \ } #define IRC_MAX_NICK_LEN 64 #define IRC_MAX_ARG_LEN 509 #define IRC_MAX_PARAMS 16 struct irc_message_t { // Prefix irc_string_t(IRC_MAX_NICK_LEN) pfx_nickOrServer; irc_string_t(IRC_MAX_NICK_LEN) pfx_user; irc_string_t(IRC_MAX_NICK_LEN) pfx_host; // Command irc_string_t(32) cmd_string; // Arguments irc_string_t(IRC_MAX_ARG_LEN) arg_values[IRC_MAX_PARAMS]; unsigned int arg_count; }; static struct irc_message_t IRC_ReceivedMessage; // Macros to access the message's various fields #define IRC_String(N) (IRC_ReceivedMessage.N.string) #define IRC_Length(N) (IRC_ReceivedMessage.N.length) /* * IRC command handlers are called when some command is received; * they are stored in hash tables. */ typedef int (*irc_handler_func_t)( ); typedef int (*ctcp_handler_func_t)( qboolean is_channel , const char * message ); struct irc_handler_t { char cmd_string[33]; void * handler; }; static hashtable_t IRC_Handlers; static hashtable_t IRC_CTCPHandlers; /* * Username, nickname, etc... */ struct irc_user_t { char nick[16]; int nicklen; int nickattempts; char username[16]; char email[100]; }; static struct irc_user_t IRC_User; /* * Events that can be displayed and flags that apply to them. */ #define IRC_EVT_SAY 0x00000000 // Standard message #define IRC_EVT_ACT 0x00000001 // /me message #define IRC_EVT_JOIN 0x00000002 // Join #define IRC_EVT_PART 0x00000003 // Part #define IRC_EVT_QUIT 0x00000004 // Quit #define IRC_EVT_KICK 0x00000005 // Kick #define IRC_EVT_NICK_CHANGE 0x00000006 // Nick change #define IRC_EVTF_SELF 0x00000100 // Event applies to current user #define IRC_EventType(evt) ( evt & 0xff ) #define IRC_EventIsSelf(evt) ( ( evt & IRC_EVTF_SELF ) == IRC_EVTF_SELF ) #define IRC_MakeEvent(type,isself) ( IRC_EVT_##type | ( (isself) ? IRC_EVTF_SELF : 0 ) ) /* * Rate limiters for various events. * * The rate limiter works on a per-event basis, it doesn't know nor care * about users. * Its threshold and increase constants (which will be scaled depending on * the timing controls) determine the amount of responses per second, while * also allowing "bursts". */ /* Rate limiter threshold - above that, no response */ #define IRC_LIMIT_THRESHOLD 3 /* Rate limiter increase per check */ #define IRC_LIMIT_INCREASE 1 #define IRC_RL_MESSAGE 0 #define IRC_RL_PING 1 #define IRC_RL_VERSION 2 static unsigned int IRC_RateLimiter[ 3 ]; /*--------------------------------------------------------------------------*/ /* FUNCTIONS THAT MANAGE IRC COMMAND HANDLERS */ /*--------------------------------------------------------------------------*/ /* * Initialises the handler tables */ static inline void IRC_InitHandlers( ) { IRC_Handlers = HT_Create( 100 , HT_FLAG_INTABLE | HT_FLAG_CASE , sizeof( struct irc_handler_t ) , HT_OffsetOfField( struct irc_handler_t , cmd_string ) , 32 ); IRC_CTCPHandlers = HT_Create( 100 , HT_FLAG_INTABLE | HT_FLAG_CASE , sizeof( struct irc_handler_t ) , HT_OffsetOfField( struct irc_handler_t , cmd_string ) , 32 ); } /* * Frees the list of handlers (used when the IRC thread dies). */ static void IRC_FreeHandlers( ) { HT_Destroy( IRC_Handlers ); HT_Destroy( IRC_CTCPHandlers ); } /* * Registers a new IRC command handler. */ static inline void IRC_AddHandler( const char * command , irc_handler_func_t handler ) { qboolean created; struct irc_handler_t * rv; rv = HT_GetItem( IRC_Handlers , command , &created ); assert( created ); rv->handler = handler; } /* * Registers a new CTCP command handler. */ static void IRC_AddCTCPHandler( const char * command , ctcp_handler_func_t handler ) { qboolean created; struct irc_handler_t * rv; rv = HT_GetItem( IRC_CTCPHandlers , command , &created ); assert( created ); rv->handler = handler; } /* * Executes the command handler for the currently stored command. If there is * no registered handler matching the command, ignore it. */ static int IRC_ExecuteHandler( ) { struct irc_handler_t * handler; handler = HT_GetItem( IRC_Handlers , IRC_String(cmd_string) , NULL ); if ( handler == NULL ) return IRC_CMD_SUCCESS; return ((irc_handler_func_t)(handler->handler))( ); } /* * Executes a CTCP command handler. */ static int IRC_ExecuteCTCPHandler( const char * command , qboolean is_channel , const char *argument ) { struct irc_handler_t * handler; handler = HT_GetItem( IRC_CTCPHandlers , command , NULL ); if ( handler == NULL ) return IRC_CMD_SUCCESS; return ((ctcp_handler_func_t)(handler->handler))( is_channel , argument ); } /*--------------------------------------------------------------------------*/ /* IRC DELAYED EXECUTION */ /*--------------------------------------------------------------------------*/ /* Structure for the delayed execution queue */ struct irc_delayed_t { irc_handler_func_t handler; // Handler to call int time_left; // "Time" left before call struct irc_delayed_t * next; // Next record }; /* Delayed execution queue head & tail */ static struct irc_delayed_t * IRC_DEQueue = NULL; /* * This function sets an IRC handler function to be executed after some time. */ static void IRC_SetTimeout( irc_handler_func_t function , int time ) { struct irc_delayed_t * qe , * find; assert( time > 0 ); // Create entry qe = (struct irc_delayed_t *) malloc( sizeof( struct irc_delayed_t ) ); qe->handler = function; qe->time_left = time * IRC_TIMEOUTS_PER_SEC; // Find insert location if ( IRC_DEQueue ) { if ( IRC_DEQueue->time_left >= time ) { qe->next = IRC_DEQueue; IRC_DEQueue = qe; } else { find = IRC_DEQueue; while ( find->next && find->next->time_left < time ) find = find->next; qe->next = find->next; find->next = qe; } } else { qe->next = NULL; IRC_DEQueue = qe; } } /* * This function dequeues an entry from the delayed execution queue. */ static qboolean IRC_DequeueDelayed( ) { struct irc_delayed_t * found; if ( ! IRC_DEQueue ) return false; found = IRC_DEQueue; IRC_DEQueue = found->next; free( found ); return true; } /* * This function deletes all remaining entries from the delayed execution * queue. */ static void IRC_FlushDEQueue( ) { while ( IRC_DequeueDelayed( ) ) { // PURPOSEDLY EMPTY } } /* * This function processes the delayed execution queue. */ static int IRC_ProcessDEQueue( ) { struct irc_delayed_t * iter; int err_code; iter = IRC_DEQueue; while ( iter ) { if ( iter->time_left == 1 ) { err_code = (iter->handler)( ); IRC_DequeueDelayed( ); if ( err_code != IRC_CMD_SUCCESS ) return err_code; iter = IRC_DEQueue; } else { iter->time_left --; iter = iter->next; } } return IRC_CMD_SUCCESS; } /*--------------------------------------------------------------------------*/ /* IRC MESSAGE PARSER */ /*--------------------------------------------------------------------------*/ /* Parser macros, 'cause I'm lazy */ #define P_SET_STATE(S) IRC_ParserState = IRC_PARSER_##S #define P_INIT_MESSAGE(S) { \ P_SET_STATE(S); \ IRC_ParserInMessage = true; \ memset( &IRC_ReceivedMessage , 0 , sizeof( struct irc_message_t ) ); \ } #if defined DEBUG_DUMP_IRC #define P_ERROR(S) { \ if ( ! IRC_ParserError ) { \ Com_Printf( "IRC PARSER ERROR (state: %d , received: %d)\n" , IRC_ParserState , next ); \ } \ P_SET_STATE(S); \ IRC_ParserError = true; \ } #else // defined DEBUG_DUMP_IRC #define P_ERROR(S) { \ P_SET_STATE(S); \ IRC_ParserError = true; \ } #endif // defined DEBUG_DUMP_IRC #define P_AUTO_ERROR { \ if ( next == '\r' ) { \ P_ERROR(LF); \ } else { \ P_ERROR(RECOVERY); \ } \ } #define P_INIT_STRING(S) { \ IRC_ReceivedMessage.S.string[0] = next; \ IRC_ReceivedMessage.S.length = 1; \ } #define P_ADD_STRING(S) { \ if ( IRC_ReceivedMessage.S.length == sizeof( IRC_ReceivedMessage.S.string ) - 1 ) { \ P_ERROR(RECOVERY); \ } else { \ IRC_ReceivedMessage.S.string[IRC_ReceivedMessage.S.length ++] = next; \ } \ } #define P_NEXT_PARAM { \ if ( ( ++ IRC_ReceivedMessage.arg_count ) == IRC_MAX_PARAMS ) { \ P_ERROR(RECOVERY); \ } \ } #define P_START_PARAM { \ if ( ( ++ IRC_ReceivedMessage.arg_count ) == IRC_MAX_PARAMS ) { \ P_ERROR(RECOVERY); \ } else \ P_INIT_STRING(arg_values[IRC_ReceivedMessage.arg_count - 1]) \ } #define P_ADD_PARAM P_ADD_STRING(arg_values[IRC_ReceivedMessage.arg_count - 1]) /* * Main parsing function that uses a FSM to parse one character at a time. * Returns true when a full message is read and no error has occured. */ static qboolean IRC_Parser( char next ) { qboolean has_msg = false; switch ( IRC_ParserState ) { /* Initial state; clear the message, then check input. ':' * indicates there is a prefix, a digit indicates a numeric * command, an upper-case letter indicates a string command. * It's also possible we received an empty line - just skip * it. Anything else is an error. */ case IRC_PARSER_START: IRC_ParserError = false; IRC_ParserInMessage = false; if ( next == ':' ) { P_INIT_MESSAGE(PFX_NOS_START); } else if ( next == '\r' ) { P_SET_STATE(LF); } else if ( IS_DIGIT( next ) ) { P_INIT_MESSAGE(NUM_COMMAND_2); P_INIT_STRING(cmd_string); } else if ( IS_UPPER( next ) ) { P_INIT_MESSAGE(STR_COMMAND); P_INIT_STRING(cmd_string); } else { P_ERROR(RECOVERY); } break; /* * Start of prefix; anything is accepted, except for '!', '@', ' ' * and control characters which all cause an error recovery. */ case IRC_PARSER_PFX_NOS_START: if ( next == '!' || next == '@' || next == ' ' || IS_CNTRL( next ) ) { P_AUTO_ERROR; } else { P_SET_STATE(PFX_NOS); P_INIT_STRING(pfx_nickOrServer); } break; /* * Prefix, server or nick name. Control characters cause an error, * ' ', '!' and '@' cause state changes. */ case IRC_PARSER_PFX_NOS: if ( next == '!' ) { P_SET_STATE(PFX_USER_START); } else if ( next == '@' ) { P_SET_STATE(PFX_HOST_START); } else if ( next == ' ' ) { P_SET_STATE(COMMAND_START); } else if IS_CNTRL( next ) { P_AUTO_ERROR; } else { P_ADD_STRING(pfx_nickOrServer); } break; /* * Start of user name; anything goes, except for '!', '@', ' ' * and control characters which cause an error. */ case IRC_PARSER_PFX_USER_START: if ( next == '!' || next == '@' || next == ' ' || IS_CNTRL( next ) ) { P_AUTO_ERROR; } else { P_SET_STATE(PFX_USER); P_INIT_STRING(pfx_user); } break; /* * User name; '@' will cause state changes, '!' , ' ' and * control characters will cause errors. */ case IRC_PARSER_PFX_USER: if ( next == '@' ) { P_SET_STATE(PFX_HOST_START); } else if ( next == '!' || next == ' ' || IS_CNTRL( next ) ) { P_AUTO_ERROR; } else { P_ADD_STRING(pfx_user); } break; /* * Start of host name; anything goes, except for '!', '@', ' ' * and control characters which cause an error. */ case IRC_PARSER_PFX_HOST_START: if ( next == '!' || next == '@' || next == ' ' || IS_CNTRL( next ) ) { P_AUTO_ERROR; } else { P_SET_STATE(PFX_HOST); P_INIT_STRING(pfx_host); } break; /* * Host name; ' ' will cause state changes, '!' and control * characters will cause errors. */ case IRC_PARSER_PFX_HOST: if ( next == ' ' ) { P_SET_STATE(COMMAND_START); } else if ( next == '!' || next == '@' || IS_CNTRL( next ) ) { P_AUTO_ERROR; } else { P_ADD_STRING(pfx_host); } break; /* * Start of command, will accept start of numeric and string * commands; anything else is an error. */ case IRC_PARSER_COMMAND_START: if ( IS_DIGIT( next ) ) { P_SET_STATE(NUM_COMMAND_2); P_INIT_STRING(cmd_string); } else if ( IS_UPPER( next ) ) { P_SET_STATE(STR_COMMAND); P_INIT_STRING(cmd_string); } else { P_AUTO_ERROR; } break; /* * String command. Uppercase letters will cause the parser * to continue on string commands, ' ' indicates a parameter * is expected, '\r' means we're done. Anything else is an * error. */ case IRC_PARSER_STR_COMMAND: if ( next == ' ' ) { P_SET_STATE(PARAM_START); } else if ( next == '\r' ) { P_SET_STATE(LF); } else if ( IS_UPPER( next ) ) { P_ADD_STRING(cmd_string); } else { P_ERROR(RECOVERY); } break; /* * Second/third digit of numeric command; anything but a digit * is an error. */ case IRC_PARSER_NUM_COMMAND_2: case IRC_PARSER_NUM_COMMAND_3: if ( IS_DIGIT( next ) ) { IRC_ParserState ++; P_ADD_STRING(cmd_string); } else { P_AUTO_ERROR; } break; /* * End of numeric command, could be a ' ' or a '\r'. */ case IRC_PARSER_NUM_COMMAND_4: if ( next == ' ' ) { P_SET_STATE(PARAM_START); } else if ( next == '\r' ) { P_SET_STATE(LF); } else { P_ERROR(RECOVERY); } break; /* * Start of parameter. ':' means it's a trailing parameter, * spaces and control characters shouldn't be here, and * anything else is a "middle" parameter. */ case IRC_PARSER_PARAM_START: if ( next == ':' ) { P_SET_STATE(TRAILING_PARAM); P_NEXT_PARAM; } else if ( next == '\r' ) { P_SET_STATE(LF); } else if ( IS_CNTRL( next ) ) { P_AUTO_ERROR; } else if ( next != ' ' ) { if ( next & 0x80 ) next = '?'; P_SET_STATE(MID_PARAM); P_START_PARAM; } break; /* * "Middle" parameter; ' ' means there's another parameter coming, * '\r' means the end of the message, control characters are not * accepted, anything else is part of the parameter. */ case IRC_PARSER_MID_PARAM: if ( next == ' ' ) { P_SET_STATE(PARAM_START); } else if ( next == '\r' ) { P_SET_STATE(LF); } else if ( IS_CNTRL( next ) ) { P_ERROR(RECOVERY); } else { if ( next & 0x80 ) next = '?'; P_ADD_PARAM; } break; /* * Trailing parameter; '\r' means the end of the command, * and anything else is just added to the string. */ case IRC_PARSER_TRAILING_PARAM: if ( next == '\r' ) { P_SET_STATE(LF); } else { if ( next & 0x80 ) { next = '?'; } P_ADD_PARAM; } break; /* * End of line, expect '\n'. If found, we may have a message * to handle (unless there were errors). Anything else is an * error. */ case IRC_PARSER_LF: if ( next == '\n' ) { has_msg = IRC_ParserInMessage; P_SET_STATE(START); } else { P_AUTO_ERROR; } break; /* * Error recovery: wait for an '\r'. */ case IRC_PARSER_RECOVERY: if ( next == '\r' ) P_SET_STATE(LF); break; } return has_msg && !IRC_ParserError; } /* * Debugging function that dumps the IRC message. */ #ifdef DEBUG_DUMP_IRC static void IRC_DumpMessage( ) { int i; Com_Printf( "----------- IRC MESSAGE RECEIVED -----------\n" ); Com_Printf( " (pfx) nick/server .... [%.3d]%s\n" , IRC_Length( pfx_nickOrServer ) , IRC_String( pfx_nickOrServer ) ); Com_Printf( " (pfx) user ........... [%.3d]%s\n" , IRC_Length( pfx_user ) , IRC_String( pfx_user ) ); Com_Printf( " (pfx) host ........... [%.3d]%s\n" , IRC_Length( pfx_host ) , IRC_String( pfx_host ) ); Com_Printf( " command string ....... [%.3d]%s\n" , IRC_Length( cmd_string ) , IRC_String( cmd_string ) ); Com_Printf( " arguments ............ %.3d\n" , IRC_ReceivedMessage.arg_count ); for ( i = 0 ; i < IRC_ReceivedMessage.arg_count ; i ++ ) { Com_Printf( " ARG %d = [%.3d]%s\n" , i + 1 , IRC_Length( arg_values[ i ] ) , IRC_String( arg_values[ i ] ) ); } } #endif // DEBUG_DUMP_IRC /*--------------------------------------------------------------------------*/ /* "SYSTEM" FUNCTIONS */ /*--------------------------------------------------------------------------*/ #if defined WIN32_VARIANT static void IRC_HandleError(void) { switch ( WSAGetLastError() ) { case 0: // No error return; case WSANOTINITIALISED : Com_Printf("Unable to initialise socket.\n"); break; case WSAEAFNOSUPPORT : Com_Printf("The specified address family is not supported.\n"); break; case WSAEADDRNOTAVAIL : Com_Printf("Specified address is not available from the local machine.\n"); break; case WSAECONNREFUSED : Com_Printf("The attempt to connect was forcefully rejected.\n"); break; case WSAEDESTADDRREQ : Com_Printf("address destination address is required.\n"); break; case WSAEFAULT : Com_Printf("The namelen argument is incorrect.\n"); break; case WSAEINVAL : Com_Printf("The socket is not already bound to an address.\n"); break; case WSAEISCONN : Com_Printf("The socket is already connected.\n"); break; case WSAEADDRINUSE : Com_Printf("The specified address is already in use.\n"); break; case WSAEMFILE : Com_Printf("No more file descriptors are available.\n"); break; case WSAENOBUFS : Com_Printf("No buffer space available. The socket cannot be created.\n"); break; case WSAEPROTONOSUPPORT : Com_Printf("The specified protocol is not supported.\n"); break; case WSAEPROTOTYPE : Com_Printf("The specified protocol is the wrong type for this socket.\n"); break; case WSAENETUNREACH : Com_Printf("The network can't be reached from this host at this time.\n"); break; case WSAENOTSOCK : Com_Printf("The descriptor is not a socket.\n"); break; case WSAETIMEDOUT : Com_Printf("Attempt timed out without establishing a connection.\n"); break; case WSAESOCKTNOSUPPORT : Com_Printf("Socket type is not supported in this address family.\n"); break; case WSAENETDOWN : Com_Printf("Network subsystem failure.\n"); break; case WSAHOST_NOT_FOUND : Com_Printf("Authoritative Answer Host not found.\n"); break; case WSATRY_AGAIN : Com_Printf("Non-Authoritative Host not found or SERVERFAIL.\n"); break; case WSANO_RECOVERY : Com_Printf("Non recoverable errors, FORMERR, REFUSED, NOTIMP.\n"); break; case WSANO_DATA : Com_Printf("Valid name, no data record of requested type.\n"); break; case WSAEINPROGRESS : Com_Printf("address blocking Windows Sockets operation is in progress.\n"); break; default : Com_Printf("Unknown connection error.\n"); break; } WSASetLastError( 0 ); } #elif defined UNIX_VARIANT static void IRC_HandleError( void ) { Com_Printf( "IRC socket connection error: %s\n" , strerror( errno ) ); } #endif #if defined MSG_NOSIGNAL # define IRC_SEND_FLAGS MSG_NOSIGNAL #else # define IRC_SEND_FLAGS 0 #endif /* * Attempt to format then send a message to the IRC server. Will return * true on success, and false if an overflow occurred or if send() failed. */ static int IRC_Send( const char * format , ... ) { char buffer[ IRC_SEND_BUF_SIZE + 1 ]; va_list args; int len , sent; // Format message va_start( args , format ); len = vsnprintf( buffer , IRC_SEND_BUF_SIZE - 1 , format , args ); va_end( args ); if ( len >= IRC_SEND_BUF_SIZE - 1 ) { // This is a bug, return w/ a fatal error Com_Printf( "...IRC: send buffer overflow (%d characters)\n" , len ); return IRC_CMD_FATAL; } // Add CRLF terminator #if defined DEBUG_DUMP_IRC Com_Printf( "SENDING IRC MESSAGE: %s\n" , buffer ); #endif buffer[ len++ ] = '\r'; buffer[ len++ ] = '\n'; // Send message sent = send(IRC_Socket, buffer , len , IRC_SEND_FLAGS ); if ( sent < len ) { IRC_HandleError( ); return IRC_CMD_RETRY; } return IRC_CMD_SUCCESS; } /* * This function is used to prevent the IRC thread from turning the CPU into * a piece of molten silicium while it waits for the server to send data. * * If data is received, SUCCESS is returned; otherwise, RETRY will be returned * on timeout and FATAL on error. */ #if defined WIN32_VARIANT # define SELECT_ARG 0 # define SELECT_CHECK ( rv == -1 && WSAGetLastError() == WSAEINTR ) #elif defined UNIX_VARIANT # define SELECT_ARG ( IRC_Socket + 1 ) # define SELECT_CHECK ( rv == -1 && errno == EINTR ) #endif static int IRC_Wait( ) { struct timeval timeout; fd_set read_set; int rv; // Wait for data to be available do { FD_ZERO( &read_set ); FD_SET( IRC_Socket, &read_set ); timeout.tv_sec = 0; timeout.tv_usec = IRC_TIMEOUT_US; rv = select( SELECT_ARG , &read_set , NULL , NULL , &timeout ); } while ( SELECT_CHECK ); // Something wrong happened if ( rv < 0 ) { IRC_HandleError( ); return IRC_CMD_FATAL; } return ( rv == 0 ) ? IRC_CMD_RETRY : IRC_CMD_SUCCESS; } /* * Wait for some seconds. */ static void IRC_Sleep( int seconds ) { int i; assert( seconds > 0 ); for ( i = 0 ; i < seconds * IRC_TIMEOUTS_PER_SEC && !IRC_QuitRequested ; i ++ ) { #if defined WIN32_VARIANT Sleep( IRC_TIMEOUT_MS ); #elif defined UNIX_VARIANT usleep( IRC_TIMEOUT_US ); #endif } } /*--------------------------------------------------------------------------*/ /* RATE LIMITS */ /*--------------------------------------------------------------------------*/ /* * Checks if some action can be effected using the rate limiter. If it can, * the rate limiter's status will be updated. */ static inline qboolean IRC_CheckEventRate( int event_type ) { if ( IRC_RateLimiter[ event_type ] >= IRC_LIMIT_THRESHOLD * IRC_TIMEOUTS_PER_SEC ) return false; IRC_RateLimiter[ event_type ] += IRC_LIMIT_INCREASE * IRC_TIMEOUTS_PER_SEC; return true; } /* * Decrease all non-zero rate limiter entries. */ static inline void IRC_UpdateRateLimiter( ) { int i; for ( i = 0 ; i < sizeof( IRC_RateLimiter ) / sizeof( unsigned int ) ; i ++ ) if ( IRC_RateLimiter[ i ] ) { IRC_RateLimiter[ i ] --; } } /* * Initialise the rate limiter. */ static inline void IRC_InitRateLimiter( ) { int i; for ( i = 0 ; i < sizeof( IRC_RateLimiter ) / sizeof( unsigned int ) ; i ++ ) IRC_RateLimiter[ i ] = 0; } /*--------------------------------------------------------------------------*/ /* DISPLAY CODE */ /*--------------------------------------------------------------------------*/ static void IRC_NeutraliseString( char * buffer , const char * source ) { while ( *source ) { char c = *source; if ( IS_CNTRL( c ) ) { *( buffer ++ ) = ' '; } else if ( c & 0x80 ) { *( buffer ++ ) = '?'; } else if ( c == Q_COLOR_ESCAPE ) { *( buffer ++ ) = Q_COLOR_ESCAPE; *( buffer ++ ) = Q_COLOR_ESCAPE; } else { *( buffer ++ ) = c; } source ++; } *buffer = 0; } static void IRC_Display( int event , const char * nick , const char *message ) { char buffer[ IRC_RECV_BUF_SIZE * 2 ]; char nick_copy[ IRC_MAX_NICK_LEN * 2 ]; char message_copy[ IRC_MAX_ARG_LEN * 2 ]; const char *fmt_string; qboolean has_nick; qboolean has_message; // If we're quitting, just skip this if ( IRC_QuitRequested ) return; // Determine message format switch ( IRC_EventType( event ) ) { case IRC_EVT_SAY: has_nick = has_message = true; if ( IRC_EventIsSelf( event ) ) { fmt_string = "^2<^7%s^2> %s"; } else if ( strstr( message , IRC_User.nick ) ) { fmt_string = "^3<^7%s^3> %s"; } else { fmt_string = "^1<^7%s^1> %s"; } break; case IRC_EVT_ACT: has_nick = has_message = true; if ( IRC_EventIsSelf( event ) ) { fmt_string = "^2* ^7%s^2 %s"; } else if ( strstr( message , IRC_User.nick ) ) { fmt_string = "^3* ^7%s^3 %s"; } else { fmt_string = "^1* ^7%s^1 %s"; } break; case IRC_EVT_JOIN: has_message = false; has_nick = !IRC_EventIsSelf( event ); if ( has_nick ) { fmt_string = "^5-> ^7%s^5 has entered the channel."; } else { fmt_string = "^2Joined IRC chat."; } break; case IRC_EVT_PART: // The AlienArena IRC client never parts, so it's // someone else. has_nick = true; has_message = ( message[0] != 0 ); if ( has_message ) { fmt_string = "^5<- ^7%s^5 has left the channel: %s."; } else { fmt_string = "^5<- ^7%s^5 has left the channel."; } break; case IRC_EVT_QUIT: has_nick = !IRC_EventIsSelf( event ); if ( has_nick ) { has_message = ( message[0] != 0 ); if ( has_message ) { fmt_string = "^5<- ^7%s^5 has quit: %s."; } else { fmt_string = "^5<- ^7%s^5 has quit."; } } else { has_message = true; fmt_string = "^2Quit IRC chat: %s."; } break; case IRC_EVT_KICK: has_nick = has_message = true; if ( IRC_EventIsSelf( event ) ) { fmt_string = "^2Kicked by ^7%s^2: %s."; } else { fmt_string = "^5<- ^7%s^5 has been kicked: %s."; } break; case IRC_EVT_NICK_CHANGE: has_nick = has_message = true; if ( IRC_EventIsSelf( event ) ) { fmt_string = "^2** ^7%s^2 is now known as ^7%s^2."; } else { fmt_string = "^5** ^7%s^5 is now known as ^7%s^5."; } break; default: has_nick = has_message = false; fmt_string = "unknown message received"; break; } // Neutralise required strings if ( has_nick ) IRC_NeutraliseString( nick_copy , nick ); if ( has_message ) IRC_NeutraliseString( message_copy , message ); // Format message if ( has_nick && has_message ) { sprintf( buffer , fmt_string , nick_copy , message_copy ); } else if ( has_nick ) { sprintf( buffer , fmt_string , nick_copy ); } else if ( has_message ) { sprintf( buffer , fmt_string , message_copy ); } else { strncpy( buffer , fmt_string , IRC_RECV_BUF_SIZE * 2 - 1 ); } buffer[ IRC_RECV_BUF_SIZE * 2 - 1 ] = 0; SCR_IRCPrintf( "^1IRC: %s", buffer ); } /*--------------------------------------------------------------------------*/ /* IRC MESSAGE HANDLERS */ /*--------------------------------------------------------------------------*/ /* * Send the user's nickname. */ static int IRC_SendNickname( ) { return IRC_Send( "NICK %s" , IRC_User.nick ); } /* * Join the channel */ static int IRC_JoinChannel( ) { return IRC_Send( "JOIN #%s" , cl_IRC_channel->string ); } /* * Handles a PING by replying with a PONG. */ static int IRCH_Ping( ) { if ( IRC_ReceivedMessage.arg_count == 1 ) return IRC_Send( "PONG :%s" , IRC_String( arg_values[ 0 ] ) ); return IRC_CMD_SUCCESS; } /* * Handles server errors */ static int IRCH_ServerError( ) { if ( IRC_ThreadStatus == IRC_THREAD_QUITTING ) { return IRC_CMD_SUCCESS; } if ( IRC_ReceivedMessage.arg_count == 1 ) { Com_Printf( "IRC: server error - %s\n" , IRC_String( arg_values[ 0 ] ) ); } else { Com_Printf( "IRC: server error\n" ); } return IRC_CMD_RETRY; } /* * Some fatal error was received, the IRC thread must die. */ static int IRCH_FatalError( ) { IRC_Display( IRC_MakeEvent(QUIT,1) , "" , "fatal error" ); IRC_Send( "QUIT :Something went wrong" ); return IRC_CMD_RETRY; } /* * Nickname error. If received while the thread is in the SETNICK state, * we might want to try again. Otherwise, we ignore the error as it should * not have been received anyway. */ #define RANDOM_NUMBER_CHAR ( '0' + rand() % 10 ) static int IRCH_NickError( ) { int i; if ( IRC_ThreadStatus == IRC_THREAD_SETNICK ) { if ( ++ IRC_User.nickattempts == 4 ) { IRC_Send( "QUIT :Could not set nickname" ); return IRC_CMD_FATAL; } if ( IRC_User.nicklen < 15 ) { IRC_User.nick[ IRC_User.nicklen ++ ] = RANDOM_NUMBER_CHAR; } else { for ( i = IRC_User.nicklen - 3 ; i < IRC_User.nicklen ; i ++ ) { IRC_User.nick[ i ] = RANDOM_NUMBER_CHAR; } } IRC_SetTimeout( IRC_SendNickname , 2 ); } else { Com_Printf( "...IRC: got spurious nickname error\n" ); } return IRC_CMD_SUCCESS; } /* * Connection established, we will be able to join a channel */ static int IRCH_Connected( ) { if ( IRC_ThreadStatus != IRC_THREAD_SETNICK ) { IRC_Display( IRC_MakeEvent(QUIT,1) , "" , "IRC client bug" ); IRC_Send( "QUIT :AlienArena IRC bug!" ); return IRC_CMD_RETRY; } IRC_ThreadStatus = IRC_THREAD_CONNECTED; IRC_SetTimeout( &IRC_JoinChannel , 1 ); return IRC_CMD_SUCCESS; } /* * Received JOIN */ static int IRCH_Joined( ) { int event; if ( IRC_ThreadStatus < IRC_THREAD_CONNECTED ) { IRC_Display( IRC_MakeEvent(QUIT,1) , "" , "IRC client bug" ); IRC_Send( "QUIT :AlienArena IRC bug!" ); return IRC_CMD_RETRY; } if ( !strcmp( IRC_String( pfx_nickOrServer ) , IRC_User.nick ) ) { IRC_ThreadStatus = IRC_THREAD_JOINED; event = IRC_MakeEvent(JOIN,1); } else { event = IRC_MakeEvent(JOIN,0); } IRC_Display( event , IRC_String( pfx_nickOrServer ) , NULL ); return IRC_CMD_SUCCESS; } /* * Received PART */ static int IRCH_Part( ) { IRC_Display( IRC_MakeEvent(PART, 0) , IRC_String( pfx_nickOrServer ) , IRC_String( arg_values[ 1 ] ) ); return IRC_CMD_SUCCESS; } /* * Received QUIT */ static int IRCH_Quit( ) { IRC_Display( IRC_MakeEvent(QUIT, 0) , IRC_String( pfx_nickOrServer ) , IRC_String( arg_values[ 0 ] ) ); return IRC_CMD_SUCCESS; } /* * Received KICK */ static int IRCH_Kick( ) { if ( !strcmp( IRC_String( arg_values[ 1 ] ) , IRC_User.nick ) ) { IRC_Display( IRC_MakeEvent(KICK, 1) , IRC_String( pfx_nickOrServer ) , IRC_String( arg_values[ 2 ] ) ); if ( cl_IRC_kick_rejoin->integer > 0 ) { IRC_ThreadStatus = IRC_THREAD_CONNECTED; IRC_SetTimeout( &IRC_JoinChannel , cl_IRC_kick_rejoin->integer ); } else { IRC_Display( IRC_MakeEvent(QUIT, 1) , "" , "kicked from channel.." ); IRC_Send( "QUIT :b&!" ); return IRC_CMD_FATAL; } } else { IRC_Display( IRC_MakeEvent(KICK, 0) , IRC_String( arg_values[ 1 ] ) , IRC_String( arg_values[ 2 ] ) ); } return IRC_CMD_SUCCESS; } /* * Received NICK * * While the AA client does not support changing the current nickname, * it is still possible to receive a NICK applying to the connected user * because of e.g. OperServ's SVSNICK command. */ static int IRCH_Nick( ) { int event; if ( IRC_ReceivedMessage.arg_count != 1 ) return IRC_CMD_SUCCESS; if ( !strcmp( IRC_String( pfx_nickOrServer ) , IRC_User.nick ) ) { strncpy( IRC_User.nick , IRC_String( arg_values[ 0 ] ) , 15 ); Com_Printf( "%s\n", IRC_User.nick ); event = IRC_MakeEvent(NICK_CHANGE, 1); } else { event = IRC_MakeEvent(NICK_CHANGE, 0); } IRC_Display( event , IRC_String( pfx_nickOrServer ) , IRC_String( arg_values[ 0 ] ) ); return IRC_CMD_SUCCESS; } /* * Handles an actual message. */ static int IRC_HandleMessage( qboolean is_channel , const char * string ) { if ( is_channel ) { IRC_Display( IRC_MakeEvent(SAY, 0) , IRC_String( pfx_nickOrServer ) , string ); return IRC_CMD_SUCCESS; } if ( IRC_CheckEventRate( IRC_RL_MESSAGE ) ) return IRC_Send( "PRIVMSG %s :Sorry, AlienArena's IRC client does not support private messages" , IRC_String( pfx_nickOrServer ) ); return IRC_CMD_SUCCESS; } /* * Splits a CTCP message into action and argument, then call * its handler (if there is one). */ static int IRC_HandleCTCP( qboolean is_channel , char * string , int string_len ) { char * end_of_action; end_of_action = strchr( string , ' ' ); if ( end_of_action == NULL ) { end_of_action = string + string_len - 1; *end_of_action = 0; } else { *( string + string_len - 1 ) = 0; *end_of_action = 0; end_of_action ++; } #if defined DEBUG_DUMP_IRC Com_Printf( "--- IRC/CTCP ---\n" ); Com_Printf( " Command: %s\n Argument(s): %s\n" , string , end_of_action ); #endif return IRC_ExecuteCTCPHandler( string , is_channel , end_of_action ); } /* * Received PRIVMSG. * * This is either an actual message (to the channel or to the user) or a * CTCP command (action, version, etc...) */ static int IRCH_PrivMsg( ) { qboolean is_channel; if ( IRC_ReceivedMessage.arg_count != 2 ) { return IRC_CMD_SUCCESS; } // Check message to channel (bail out if it isn't our channel) is_channel = IRC_String( arg_values[ 0 ] )[ 0 ] == '#'; if ( is_channel && strcmp( &( IRC_String( arg_values[ 0 ] )[ 1 ] ) , cl_IRC_channel->string ) ) return IRC_CMD_SUCCESS; if ( IRC_Length( arg_values[ 1 ] ) > 2 && IRC_String( arg_values[ 1 ] )[ 0 ] == 1 && IRC_String( arg_values[ 1 ] )[ IRC_Length( arg_values[ 1 ] ) - 1 ] == 1 ) { return IRC_HandleCTCP( is_channel , IRC_String( arg_values[ 1 ] ) + 1 , IRC_Length( arg_values[ 1 ] ) - 1 ); } return IRC_HandleMessage( is_channel , IRC_String( arg_values[ 1 ] ) ); } /* * User is banned. Leave and do not come back. */ static int IRCH_Banned( ) { IRC_Display( IRC_MakeEvent(QUIT, 1) , "" , "banned from channel.." ); IRC_Send( "QUIT :b&!" ); return IRC_CMD_FATAL; } /*--------------------------------------------------------------------------*/ /* CTCP COMMAND HANDLERS */ /*--------------------------------------------------------------------------*/ /* * Action command aka "/me" */ static int CTCP_Action( qboolean is_channel , const char * argument ) { if ( !*argument ) return IRC_CMD_SUCCESS; if ( is_channel ) { IRC_Display( IRC_MakeEvent(ACT, 0) , IRC_String( pfx_nickOrServer ) , argument ); return IRC_CMD_SUCCESS; } if ( IRC_CheckEventRate( IRC_RL_MESSAGE ) ) return IRC_Send( "PRIVMSG %s :Sorry, AlienArena's IRC client does not support private messages" , IRC_String( pfx_nickOrServer ) ); return IRC_CMD_SUCCESS; } /* * PING requests */ static int CTCP_Ping( qboolean is_channel , const char * argument ) { if ( is_channel || !IRC_CheckEventRate( IRC_RL_PING ) ) return IRC_CMD_SUCCESS; if ( *argument ) return IRC_Send( "NOTICE %s :\001PING %s\001" , IRC_String( pfx_nickOrServer ) , argument ); return IRC_Send( "NOTICE %s :\001PING\001" , IRC_String( pfx_nickOrServer ) ); } /* * VERSION requests, let's advertise AA a lil'. */ static int CTCP_Version( qboolean is_channel , const char * argument ) { if ( is_channel || !IRC_CheckEventRate( IRC_RL_VERSION ) ) return IRC_CMD_SUCCESS; return IRC_Send( "NOTICE %s :\001VERSION AlienArena IRC client - v" VERSION "\001" , IRC_String( pfx_nickOrServer ) ); } /*--------------------------------------------------------------------------*/ /* MESSAGE SENDING */ /*--------------------------------------------------------------------------*/ /* Maximal message length */ #define IRC_MAX_SEND_LEN 400 /* * The message sending queue is used to avoid having to send stuff from the * game's main thread, as it could block or cause mix-ups in the printing * function. */ struct irc_sendqueue_t { qboolean has_content; qboolean is_action; char string[IRC_MAX_SEND_LEN]; }; /* Length of the IRC send queue */ #define IRC_SENDQUEUE_SIZE 16 /* Index of the next message to process */ static int IRC_SendQueue_Process = 0; /* Index of the next message to write */ static int IRC_SendQueue_Write = 0; /* The queue */ static struct irc_sendqueue_t IRC_SendQueue[ IRC_SENDQUEUE_SIZE ]; /* * Initialise the send queue. */ static inline void IRC_InitSendQueue( ) { memset( &IRC_SendQueue , 0 , sizeof( IRC_SendQueue ) ); } /* * Writes an entry to the send queue. */ static qboolean IRC_AddSendItem( qboolean is_action , const char * string ) { if ( IRC_SendQueue[ IRC_SendQueue_Write ].has_content ) return false; strcpy( IRC_SendQueue[ IRC_SendQueue_Write ].string , string ); IRC_SendQueue[ IRC_SendQueue_Write ].is_action = is_action; IRC_SendQueue[ IRC_SendQueue_Write ].has_content = true; IRC_SendQueue_Write = ( IRC_SendQueue_Write + 1 ) % IRC_SENDQUEUE_SIZE; return true; } /* * Sends an IRC message (console command). */ void CL_IRCSay( ) { char m_sendstring[480]; qboolean send_result; if (Cmd_Argc() != 2) { Com_Printf ("usage: irc_say \n"); return; } if ( IRC_ThreadStatus != IRC_THREAD_JOINED ) { Com_Printf("IRC: Not connected\n"); return; } memset( m_sendstring , 0 , sizeof( m_sendstring ) ); strncpy( m_sendstring , Cmd_Argv(1) , 479 ); if ( m_sendstring[ 0 ] == 0 ) return; if ( ( m_sendstring[ 0 ] == '/' || m_sendstring[ 0 ] == '.' ) && !Q_strnicmp( m_sendstring + 1 , "me " , 3 ) && m_sendstring[ 4 ] != 0 ) { send_result = IRC_AddSendItem( true , m_sendstring + 4 ); } else { send_result = IRC_AddSendItem( false , m_sendstring ); } if ( !send_result ) Com_Printf( "IRC: flood detected, message not sent\n" ); } /* * Processes the next item on the send queue, if any. */ static qboolean IRC_ProcessSendQueue( ) { const char * fmt_string; int event , rv; if ( !IRC_SendQueue[ IRC_SendQueue_Process ].has_content ) return true; if ( IRC_SendQueue[ IRC_SendQueue_Process ].is_action ) { fmt_string = "PRIVMSG #%s :\001ACTION %s\001"; event = IRC_MakeEvent(ACT, 1); } else { fmt_string = "PRIVMSG #%s :%s"; event = IRC_MakeEvent(SAY, 1); } rv = IRC_Send( fmt_string , cl_IRC_channel->string , IRC_SendQueue[ IRC_SendQueue_Process ].string ); if ( rv == IRC_CMD_SUCCESS ) { IRC_Display( event , IRC_User.nick , IRC_SendQueue[ IRC_SendQueue_Process ].string ); } IRC_SendQueue[ IRC_SendQueue_Process ].has_content = false; IRC_SendQueue_Process = ( IRC_SendQueue_Process + 1 ) % IRC_SENDQUEUE_SIZE; return ( rv == IRC_CMD_SUCCESS ); } /* * Attempts to receive data from the server. If data is received, parse it * and attempt to execute a handler for each complete message. */ static int IRC_ProcessData(void) { char buffer[ IRC_RECV_BUF_SIZE ]; int i , len , err_code; len = recv( IRC_Socket, buffer, IRC_RECV_BUF_SIZE, 0 ); // Handle errors / remote disconnects if ( len <= 0 ) { if ( len < 0 ) IRC_HandleError( ); IRC_ThreadStatus = IRC_THREAD_QUITTING; return IRC_CMD_RETRY; } for ( i = 0 ; i < len ; i ++ ) { if ( IRC_Parser( buffer[ i ] ) ) { #ifdef DEBUG_DUMP_IRC IRC_DumpMessage( ); #endif // DEBUG_DUMP_IRC err_code = IRC_ExecuteHandler( ); if ( err_code != IRC_CMD_SUCCESS ) return err_code; } } return IRC_CMD_SUCCESS; } /* * Prepares the user record which is used when issuing the USER command. */ static qboolean IRC_InitialiseUser( const char * name ) { qboolean ovrnn; const char * source; int i = 0, j = 0; int replaced = 0; char c; ovrnn = cl_IRC_override_nickname->integer && strlen( cl_IRC_nickname->name ); source = ovrnn ? cl_IRC_nickname->string : name; // Strip color chars for the player's name, and remove special // characters IRC_User.nicklen = 0; IRC_User.nickattempts = 1; while ( j < 15 ) { if ( !ovrnn ) { // Only process color escape codes if the nickname // is being computed from the player source if ( i == 32 || !source[i] ) { IRC_User.nick[j ++] = 0; continue; } if ( source[i] == Q_COLOR_ESCAPE ) { i ++; if ( source[i] != Q_COLOR_ESCAPE ) { if ( source[i] ) i ++; continue; } } } c = source[i ++]; if ( j == 0 && !( IS_ALPHA( c ) || strchr( "[]\\`_^{|}" , c ) ) ) { c = '_'; replaced ++; } else if ( j > 0 && !( IS_ALNUM( c ) || strchr( "-[]\\`_^{|}" , c ) ) ) { c = '_'; replaced ++; } IRC_User.nick[j] = c; // User names are even more sensitive if ( ! ( c == '-' || c == '.' || c == '_' || IS_ALNUM( c ) ) ) c = '_'; IRC_User.username[j] = c; IRC_User.nicklen = ++j; } // If the nickname is overriden and its modified value differs, // then it is invalid if ( ovrnn && strcmp( source , IRC_User.nick ) ) return false; // Set static address strcpy( IRC_User.email, "mymail@mail.com" ); return ( IRC_User.nicklen > 0 && replaced < IRC_User.nicklen / 2 ); } /* * Establishes the IRC connection, sets the nick, etc... */ #define CHECK_SHUTDOWN { if ( IRC_QuitRequested ) return IRC_CMD_FATAL; } #define CHECK_SHUTDOWN_CLOSE { if ( IRC_QuitRequested ) { closesocket( IRC_Socket ); return IRC_CMD_FATAL; } } static int IRC_AttemptConnection( ) { struct sockaddr_in address; // socket address struct hostent * host; // host lookup char host_name[100]; // host name char name[32]; // player's name int err_code; int port; CHECK_SHUTDOWN; Com_Printf("...IRC: connecting to server\n"); // Force players to use a non-default name strcpy( name, Cvar_VariableString( "name" ) ); if (! Q_strnicmp( name , "player" , 7 ) ) { Com_Printf("...IRC: rejected due to unset player name\n"); return IRC_CMD_FATAL; } // Prepare USER record if (! IRC_InitialiseUser( name ) ) { Com_Printf("...IRC: rejected due to mostly unusable player name\n"); return IRC_CMD_FATAL; } // Find server address Q_strncpyz2( host_name, cl_IRC_server->string, sizeof(host_name) ); if ( (host=gethostbyname(host_name)) == NULL ) { Com_Printf("...IRC: unknown server\n"); return IRC_CMD_FATAL; } // Create socket CHECK_SHUTDOWN; if ( (IRC_Socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET ) { IRC_HandleError( ); return IRC_CMD_FATAL; } // Initialise socket address port = cl_IRC_port->integer; if ( port <= 0 || port >= 65536 ) { Com_Printf("IRC: invalid port number, defaulting to 6667\n"); port = 6667; } address.sin_family = AF_INET; address.sin_port = htons( port ); address.sin_addr.s_addr = *((unsigned long *) host->h_addr); // Attempt connection if ( (connect(IRC_Socket,(struct sockaddr *) &address, sizeof(address))) != 0) { closesocket(IRC_Socket); Com_Printf("...IRC connection refused.\n"); return IRC_CMD_RETRY; } // Send username and nick name CHECK_SHUTDOWN_CLOSE; err_code = IRC_Send( "USER %s %s %s :%s" , IRC_User.username , IRC_User.email , host_name , IRC_User.nick ); if ( err_code == IRC_CMD_SUCCESS ) err_code = IRC_SendNickname( ); if ( err_code != IRC_CMD_SUCCESS ) { closesocket(IRC_Socket); return err_code; } // Initialise parser and set thread state IRC_ParserState = IRC_PARSER_START; IRC_ThreadStatus = IRC_THREAD_SETNICK; CHECK_SHUTDOWN_CLOSE; Com_Printf("...Connected to IRC server\n"); return IRC_CMD_SUCCESS; } /* * Attempt to connect to the IRC server for the first time. * Only retry a few times and assume the server's dead/does not exist if * connection can't be established. */ static qboolean IRC_InitialConnect( ) { int err_code , retries = 3; int rc_delay = cl_IRC_reconnect_delay->integer; if ( rc_delay < 5 ) rc_delay = 5; err_code = IRC_CMD_SUCCESS; IRC_ThreadStatus = IRC_THREAD_CONNECTING; do { // If we're re-attempting a connection, wait a little bit, // or we might just piss the server off. if ( err_code == IRC_CMD_RETRY ) { IRC_Sleep( rc_delay ); } else if ( IRC_QuitRequested ) { return false; } err_code = IRC_AttemptConnection( ); } while ( err_code == IRC_CMD_RETRY && --retries > 0 ); return ( err_code == IRC_CMD_SUCCESS ); } /* * Attempt to reconnect to the IRC server. Only stop trying on fatal errors * or if the thread's status is set to QUITTING. */ static int IRC_Reconnect( ) { int err_code; int rc_delay = cl_IRC_reconnect_delay->integer; if ( rc_delay < 5 ) rc_delay = 5; err_code = IRC_CMD_SUCCESS; IRC_ThreadStatus = IRC_THREAD_CONNECTING; do { IRC_Sleep( ( err_code == IRC_CMD_SUCCESS ) ? ( rc_delay >> 1 ) : rc_delay ); if ( IRC_QuitRequested ) { return IRC_CMD_FATAL; } err_code = IRC_AttemptConnection( ); } while ( err_code == IRC_CMD_RETRY ); return err_code; } /* * IRC main loop. Once the initial connection has been established, either * 1) pump messages or 2) handle delayed functions. Try re-connecting if * connection is lost. */ static void IRC_MainLoop() { int err_code; // Connect to server if (! IRC_InitialConnect() ) return; do { do { // If we must quit, send the command. if ( IRC_QuitRequested && IRC_ThreadStatus != IRC_THREAD_QUITTING ) { IRC_ThreadStatus = IRC_THREAD_QUITTING; IRC_Display( IRC_MakeEvent(QUIT,1) , "" , "quit from menu" ); err_code = IRC_Send( "QUIT :AlienArena IRC %s" , VERSION ); } else { // Wait for data or 1s timeout err_code = IRC_Wait( ); if ( err_code == IRC_CMD_SUCCESS ) { // We have some data, process it err_code = IRC_ProcessData( ); } else if ( err_code == IRC_CMD_RETRY ) { // Timed out, handle timers and update rate limiter err_code = IRC_ProcessDEQueue(); IRC_UpdateRateLimiter( ); } else { // Disconnected, but reconnection should be attempted err_code = IRC_CMD_RETRY; } if ( err_code == IRC_CMD_SUCCESS && ! IRC_QuitRequested ) err_code = IRC_ProcessSendQueue( ) ? IRC_CMD_SUCCESS : IRC_CMD_RETRY; } } while ( err_code == IRC_CMD_SUCCESS ); closesocket( IRC_Socket ); // If we must quit, let's skip trying to reconnect if ( IRC_QuitRequested || err_code == IRC_CMD_FATAL ) return; // Reconnect to server do { err_code = IRC_Reconnect( ); } while ( err_code == IRC_CMD_RETRY ); } while ( err_code != IRC_CMD_FATAL ); } /* * Main function of the IRC thread: initialise command handlers, * start the main loop, and uninitialise handlers after the loop * exits. */ static void IRC_Thread( ) { // Init. send queue & rate limiter IRC_InitSendQueue( ); IRC_InitRateLimiter( ); IRC_InitHandlers( ); // Init. IRC handlers IRC_AddHandler( "PING" , &IRCH_Ping ); // Ping request IRC_AddHandler( "ERROR" , &IRCH_ServerError ); // Server error IRC_AddHandler( "JOIN" , &IRCH_Joined ); // Channel join IRC_AddHandler( "PART" , &IRCH_Part ); // Channel part IRC_AddHandler( "QUIT" , &IRCH_Quit ); // Client quit IRC_AddHandler( "PRIVMSG" , &IRCH_PrivMsg ); // Message or CTCP IRC_AddHandler( "KICK" , &IRCH_Kick ); // Kick IRC_AddHandler( "NICK" , &IRCH_Nick ); // Nick change IRC_AddHandler( "001" , &IRCH_Connected ); // Connection established IRC_AddHandler( "404" , &IRCH_Banned ); // Banned (when sending message) IRC_AddHandler( "432" , &IRCH_FatalError ); // Erroneous nick name IRC_AddHandler( "433" , &IRCH_NickError ); // Nick name in use IRC_AddHandler( "474" , &IRCH_Banned ); // Banned (when joining) // Init. CTCP handlers IRC_AddCTCPHandler( "ACTION" , &CTCP_Action ); // "/me" IRC_AddCTCPHandler( "PING" , &CTCP_Ping ); IRC_AddCTCPHandler( "VERSION" , &CTCP_Version ); // Enter loop IRC_MainLoop( ); // Clean up Com_Printf( "...IRC: disconnected from server\n" ); IRC_FlushDEQueue( ); IRC_FreeHandlers( ); IRC_SetThreadDead( ); } /* * Caution: IRC_SystemThreadProc(), IRC_StartThread() and IRC_WaitThread() * have separate "VARIANTS". * * Note different prototypes for IRC_SystemThreadProc() and completely * different IRC_StartThread()/IRC_WaitThread() implementations. */ #if defined WIN32_VARIANT /****** THREAD HANDLING - WINDOWS VARIANT ******/ static HANDLE IRC_ThreadHandle = NULL; static DWORD WINAPI IRC_SystemThreadProc( LPVOID dummy) { IRC_Thread( ); return 0; } static void IRC_StartThread() { if ( IRC_ThreadHandle == NULL ) IRC_ThreadHandle = CreateThread( NULL , 0 , IRC_SystemThreadProc , NULL , 0 , NULL ); } static void IRC_SetThreadDead( ) { IRC_ThreadStatus = IRC_THREAD_DEAD; IRC_ThreadHandle = NULL; } static void IRC_WaitThread() { if ( IRC_ThreadHandle != NULL ) { if ( IRC_ThreadStatus != IRC_THREAD_DEAD ) { WaitForSingleObject( IRC_ThreadHandle , 10000 ); CloseHandle( IRC_ThreadHandle ); } IRC_ThreadHandle = NULL; } } #elif defined UNIX_VARIANT /****** THREAD HANDLING - UNIX VARIANT ******/ static pthread_t IRC_ThreadHandle = (pthread_t) NULL; static void *IRC_SystemThreadProc(void *dummy) { IRC_Thread( ); return NULL; } static void IRC_StartThread(void) { if ( IRC_ThreadHandle == (pthread_t) NULL ) pthread_create( &IRC_ThreadHandle , NULL , IRC_SystemThreadProc , NULL ); } static void IRC_SetThreadDead( ) { IRC_ThreadStatus = IRC_THREAD_DEAD; IRC_ThreadHandle = (pthread_t) NULL; } static void IRC_WaitThread() { if ( IRC_ThreadHandle != (pthread_t) NULL ) { if ( IRC_ThreadStatus != IRC_THREAD_DEAD ) pthread_join( IRC_ThreadHandle , NULL ); IRC_ThreadHandle = (pthread_t) NULL; } } #endif void CL_IRCSetup(void) { cl_IRC_connect_at_startup = Cvar_Get( "cl_IRC_connect_at_startup" , "1" , CVAR_ARCHIVE ); cl_IRC_server = Cvar_Get( "cl_IRC_server" , "irc.planetarena.org" , CVAR_ARCHIVE ); cl_IRC_channel = Cvar_Get( "cl_IRC_channel" , "alienarena" , CVAR_ARCHIVE ); cl_IRC_port = Cvar_Get( "cl_IRC_port" , "6667" , CVAR_ARCHIVE ); cl_IRC_override_nickname = Cvar_Get( "cl_IRC_override_nickname" , "0" , CVAR_ARCHIVE ); cl_IRC_nickname = Cvar_Get( "cl_IRC_nickname" , "" , CVAR_ARCHIVE ); cl_IRC_kick_rejoin = Cvar_Get( "cl_IRC_kick_rejoin" , "0" , CVAR_ARCHIVE ); cl_IRC_reconnect_delay = Cvar_Get( "cl_IRC_reconnect_delay" , "100" , CVAR_ARCHIVE ); if ( cl_IRC_connect_at_startup->value ) CL_InitIRC( ); } void CL_InitIRC(void) { if ( IRC_ThreadStatus != IRC_THREAD_DEAD ) { Com_Printf( "...IRC thread is already running\n" ); return; } IRC_QuitRequested = false; IRC_ThreadStatus = IRC_THREAD_INITIALISING; IRC_StartThread( ); } void CL_IRCInitiateShutdown(void) { IRC_QuitRequested = true; } void CL_IRCWaitShutdown( void ) { IRC_WaitThread( ); } qboolean CL_IRCIsConnected(void) { return ( IRC_ThreadStatus == IRC_THREAD_JOINED ); } qboolean CL_IRCIsRunning(void) { return ( IRC_ThreadStatus != IRC_THREAD_DEAD ); } alien-arena-7.66+dfsg/source/client/qmenu.h0000600000175000017500000002316612204310130017665 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. Copyright (C) 2013 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __QMENU_H__ #define __QMENU_H__ // TODO: This stuff could be useful outside the menu as well. typedef enum { linkstatus_literal, linkstatus_linktarget, linkstatus_link } linkable_status_t; // NOTE: if the compiler complains that this is defined but not used, that is // GOOD! It means the optimizing compiler has detected that the code in the // ASSERTFAILLINK macro never runs, optimized that code out of the binary, // and as a result there's no code that uses this array. But we still need // the ASSERTFAILLINK macro so that invalid code will be detected as soon as // it's tested. So DON'T DELETE THIS! static const char *LINK_STATUS_NAMES[] = { "literal", "linktarget", "link" }; #define LINKABLE(type) \ struct \ { \ /*For determining whether an encapsulated variable has been linked to another, and if so, how. */ \ linkable_status_t status; \ /*Contents do not matter if status == linkstatus_link*/\ type val; \ /*points to val within another struct of this type */ \ /*Contents do not matter unless status == linkstatus_link*/\ type *ptr; \ } #define ASSERTFAILLINK(a,b)\ Com_Error (ERR_FATAL, "CANNOT CREATE LINK!\n%s (%p) type %s\n%s (%p) type %s", \ #a, &a, LINK_STATUS_NAMES[a.status], #b, &b, LINK_STATUS_NAMES[b.status]); #define _ASSERTLINK(a,b)\ {\ if (b.status == linkstatus_link)\ {\ if (a.ptr != b.ptr)\ ASSERTFAILLINK (a,b)\ }\ else if (b.status != linkstatus_linktarget || a.ptr != &(b.val))\ ASSERTFAILLINK (a,b)\ } #define ASSERTLINK(a,b)\ {\ if (a.status == linkstatus_link)\ _ASSERTLINK(a,b)\ else if (b.status == linkstatus_link)\ _ASSERTLINK(b,a)\ else\ ASSERTFAILLINK (a,b)\ } #define _LINK(a,b) \ {\ b.status = linkstatus_link;\ if (a.status == linkstatus_link)\ {\ b.ptr = a.ptr;\ }\ else\ {\ a.status = linkstatus_linktarget;\ b.ptr = &(a.val);\ }\ } #define LINK(a,b) \ {\ if (&(a) != &(b)) \ {\ if ((a).status != linkstatus_literal && (b).status != linkstatus_literal)\ ASSERTLINK ((a),(b))\ else if ((b).status == linkstatus_literal)\ _LINK((a),(b))\ else\ _LINK((b),(a))\ }\ } // The reason this macro is so odd is because you need to be able to do // CHASELINK(var) = value directly. #define CHASELINK(l) \ (*\ (\ ((l).status == linkstatus_link)?\ ( /* Macro evaluates to (*((l).ptr)) */ \ (l).ptr\ )\ :\ ( /* Macro evaluates to (*(&((l).val))) which simplifies to (l).val The compiler should figure that out and come up with something you can assign directly. */ \ &((l).val)\ )\ )\ ) #define RESETLINK(l,v) \ {\ if ((l).status != linkstatus_link) \ (l).val = v; \ } #define INCREASELINK(l,v) \ {\ if ((l).status == linkstatus_link) \ {\ if (*((l).ptr) < v) \ *((l).ptr) = v; \ else \ v = *((l).ptr); \ }\ else \ {\ (l).val = v; \ }\ } #define MAXMENUITEMS 64 typedef enum { MTYPE_SLIDER, MTYPE_VERT_SCROLLBAR, MTYPE_ACTION, MTYPE_FIELD, MTYPE_NOT_INTERACTIVE, MTYPE_SPINCONTROL, MTYPE_SUBMENU } menutype_t ; #define MTYPE_TEXT MTYPE_NOT_INTERACTIVE #define K_TAB 9 #define K_ENTER 13 #define K_ESCAPE 27 #define K_SPACE 32 //menu mouse #define RCOLUMN_OFFSET 12 #define LCOLUMN_OFFSET -12 #define LONGINPUT_SIZE 13 // times font width #define NUM_CURSOR_FRAMES 15 #define FONTSCALE 1.5 //menu mouse #define MOUSEBUTTON1 0 #define MOUSEBUTTON2 1 // normal keys should be passed as lowercased ascii #define K_BACKSPACE 127 #define K_UPARROW 128 #define K_DOWNARROW 129 #define K_LEFTARROW 130 #define K_RIGHTARROW 131 #define QMF_RIGHT_COLUMN 0x00000001 #define QMF_NUMBERSONLY 0x00000002 #define QMF_ALLOW_WRAP 0x00000004 #define QMF_STRIP_COLOR 0x00000008 #define QMF_SNUG_LEFT 0x00000010 #define QMF_ACTION_WAIT 0x00000020 #define QMF_BUTTON 0x00000040 #define QMF_SUBMENU_CAPTURE 0x00000080 typedef struct { int x, y; } menuvec2_t; typedef struct { menutype_t type; const char *name; LINKABLE(int) x, y; int visible_length; struct _tag_menuframework *parent; int localints[3]; const char *localstrings[1]; void *localptrs[1]; unsigned flags; const char *statusbar; const char *tooltip; float highlight_alpha; // action callbacks void (*callback) (void *self); // clicked on/activated void (*cursorcallback) (void *self, FNT_font_t font); // moused over // layout callbacks for each column menuvec2_t (*namesizecallback) (void *self, FNT_font_t font); // left menuvec2_t (*itemsizecallback) (void *self, FNT_font_t font); // right // rendering callbacks void (*itemdraw) (void *self, FNT_font_t font); void (*namedraw) (void *self, FNT_font_t font); void (*cursordraw) (void *self, FNT_font_t font); // Each menu item may draw different things in the left column and/or the // right column. The size of whatever gets drawn in each column is tracked // separately. LINKABLE(menuvec2_t) lsize, rsize; // only used for non-submenus with QMF_ACTION_WAIT qboolean apply_pending; } menucommon_s; typedef struct _tag_menuframework { menucommon_s generic; qboolean initialized; int x, y; LINKABLE(int) lwidth, rwidth, height; int maxwidth, maxheight; // 0 for no limit int maxlines; // for generating maxheight automatically int xscroll, yscroll; qboolean horizontal; float scroll_top, scroll_range, scrollbar_size, maxscroll; menucommon_s vertical_scrollbar; qboolean navagable; qboolean enable_highlight; float borderalpha; int nitems; void *items[64]; const char *statusbar; const char *tooltip; const char *bordertitle; const char *bordertexture; void (*cursordraw)( struct _tag_menuframework *m ); // only used at the top level of the menu tree: int num_apply_pending; struct _tag_menuitem *default_cursor_selection; // will auto-pick if not set } menuframework_s; typedef struct { menucommon_s generic; // slider only int minvalue; int maxvalue; float range; int size; // slider and list int curvalue; // list only const char **itemnames; // fields char buffer[80]; int cursor; int length; } menumultival_s; typedef menumultival_s menuslider_s; typedef menumultival_s menulist_s; typedef menumultival_s menufield_s; typedef struct _tag_menuitem { menucommon_s generic; } menuitem_s; typedef menuitem_s menuaction_s; typedef menuitem_s menutxt_s; void refreshCursorLink (void); qboolean Field_Key (int key); void _Menu_AddItem( menuframework_s *menu, menucommon_s *item ); // Hushes up the incompatible pointer compiler warnings while still preventing // a genuinely incorrect value from being used: #define Menu_AddItem(menu,item)\ _Menu_AddItem((menu), &((item)->generic)) menuframework_s *Menu_GetItemTree (menuitem_s *item); int Cursor_GetLayer (void); qboolean Cursor_SelectMenu (menuframework_s *menu); void Cursor_SelectItem (menuitem_s *item); void Menu_AdvanceCursor (int dir, qboolean allow_capture); void Menu_Center( menuframework_s *menu ); void Menu_AutoArrange( menuframework_s *menu ); void Screen_Draw (menuframework_s *menu, menuvec2_t offset); void Menu_AssignCursor (menuframework_s *menu); void Menu_DrawHighlightItem (menuitem_s *item); void Menu_DrawHighlight (void); void Menu_ActivateItem (menuitem_s *item); void Menu_ApplyItem (menuitem_s *item); void Menu_ApplyMenu (menuframework_s *menu); void Menu_SetStatusBar( menuframework_s *s, const char *string ); void Menu_SlideItem (int dir); void Menu_Draw (menuframework_s *menu, FNT_font_t font); void Menu_DrawString (int x, int y, const char *string, unsigned int cmode, unsigned int align, const float *color); void Menu_DrawBox (int x, int y, int w, int h, float alpha, const char *title, const char *prefix); int Menu_PredictSize (const char *str); // utility layout functions void Menu_MakeTable (menuframework_s *menu, int nrows, int ncolumns, size_t *celltype_size, menuframework_s *header, menuframework_s *rows, void *columns, const char **contents); #if !defined min #define min(a,b) (((a)<(b)) ? (a) : (b)) #endif #if !defined max #define max(a,b) (((a)>(b)) ? (a) : (b)) #endif #if !defined clamp #define clamp(x,low,high) (min(max(low,x),high)) #endif #define Item_GetHeight(i) \ (max(CHASELINK((i).generic.lsize).y, CHASELINK((i).generic.rsize).y)) #define Menu_GetCtrX(m) ((m).x + CHASELINK((m).lwidth)) #define Item_GetX(i) (CHASELINK((i).generic.x) + Menu_GetCtrX(*((i).generic.parent))) #define Menu_TrueHeight(m) \ ((m).maxheight!=0?min((m).maxheight,CHASELINK((m).height)):CHASELINK((m).height)) #define Menu_TrueWidth(m) \ (CHASELINK((m).lwidth) + CHASELINK((m).rwidth)) #define Menu_GetBaseY(m) ((m).y - (m).yscroll) #define Item_GetY(i) (CHASELINK((i).generic.y) + Menu_GetBaseY(*((i).generic.parent))) #define Menu_ContainsMouse(m) \ ( cursor.y > (m).y && cursor.y < (m).y+Menu_TrueHeight(m) && \ cursor.x > (m).x && cursor.x < (m).x+CHASELINK((m).rwidth)+CHASELINK((m).lwidth) \ ) #define MenuText_UpperMargin(item,height) ( (((item)->generic.parent->horizontal ? Menu_TrueHeight (*((item)->generic.parent)) : Item_GetHeight(*(item)))-height)/2) struct FNT_window_s menu_box; #endif alien-arena-7.66+dfsg/source/client/cl_input.c0000600000175000017500000004132512161402010020346 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // cl.input.c -- builds an intended movement command to send to the server #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "client.h" cvar_t *cl_nodelta; extern unsigned sys_frame_time; unsigned frame_msec; unsigned old_sys_frame_time; /* =============================================================================== KEY BUTTONS Continuous button event tracking is complicated by the fact that two different input sources (say, mouse button 1 and the control key) can both press the same button, but the button should only be released when both of the pressing key have been released. When a key event issues a button command (+forward, +attack, etc), it appends its key number as a parameter to the command so it can be matched up with the release. state bit 0 is the current state of the key state bit 1 is edge triggered on the up to down transition state bit 2 is edge triggered on the down to up transition Key_Event (int key, qboolean down, unsigned time); +mlook src time =============================================================================== */ kbutton_t in_klook; kbutton_t in_left, in_right, in_forward, in_back; kbutton_t in_lookup, in_lookdown, in_moveleft, in_moveright; kbutton_t in_strafe, in_speed, in_use, in_attack, in_attack2; kbutton_t in_up, in_down; int in_impulse; void KeyDown (kbutton_t *b) { int k; char *c; c = Cmd_Argv(1); if (c[0]) k = atoi(c); else k = -1; // typed manually at the console for continuous down if (k == b->down[0] || k == b->down[1]) return; // repeating key if (!b->down[0]) b->down[0] = k; else if (!b->down[1]) b->down[1] = k; else { Com_Printf ("Three keys down for a button!\n"); return; } if (b->state & 1) return; // still down // save timestamp c = Cmd_Argv(2); b->downtime = atoi(c); if (!b->downtime) b->downtime = sys_frame_time - 100; b->state |= 1 + 2; // down + impulse down } void KeyUp (kbutton_t *b) { int k; char *c; unsigned uptime; c = Cmd_Argv(1); if (c[0]) k = atoi(c); else { // typed manually at the console, assume for unsticking, so clear all b->down[0] = b->down[1] = 0; b->state = 4; // impulse up return; } if (b->down[0] == k) b->down[0] = 0; else if (b->down[1] == k) b->down[1] = 0; else return; // key up without coresponding down (menu pass through) if (b->down[0] || b->down[1]) return; // some other key is still holding it down if (!(b->state & 1)) return; // still up (this should not happen) // save timestamp c = Cmd_Argv(2); uptime = atoi(c); if (uptime) b->msec += uptime - b->downtime; else b->msec += 10; b->state &= ~1; // now up b->state |= 4; // impulse up } void IN_KLookDown (void) {KeyDown(&in_klook);} void IN_KLookUp (void) {KeyUp(&in_klook);} void IN_UpDown(void) {KeyDown(&in_up);} void IN_UpUp(void) {KeyUp(&in_up);} void IN_DownDown(void) {KeyDown(&in_down);} void IN_DownUp(void) {KeyUp(&in_down);} void IN_LeftDown(void) {KeyDown(&in_left);} void IN_LeftUp(void) {KeyUp(&in_left);} void IN_RightDown(void) {KeyDown(&in_right);} void IN_RightUp(void) {KeyUp(&in_right);} void IN_ForwardDown(void) {KeyDown(&in_forward);} void IN_ForwardUp(void) {KeyUp(&in_forward);} void IN_BackDown(void) {KeyDown(&in_back);} void IN_BackUp(void) {KeyUp(&in_back);} void IN_LookupDown(void) {KeyDown(&in_lookup);} void IN_LookupUp(void) {KeyUp(&in_lookup);} void IN_LookdownDown(void) {KeyDown(&in_lookdown);} void IN_LookdownUp(void) {KeyUp(&in_lookdown);} void IN_MoveleftDown(void) {KeyDown(&in_moveleft);} void IN_MoveleftUp(void) {KeyUp(&in_moveleft);} void IN_MoverightDown(void) {KeyDown(&in_moveright);} void IN_MoverightUp(void) {KeyUp(&in_moveright);} void IN_SpeedDown(void) {KeyDown(&in_speed);} void IN_SpeedUp(void) {KeyUp(&in_speed);} void IN_StrafeDown(void) {KeyDown(&in_strafe);} void IN_StrafeUp(void) {KeyUp(&in_strafe);} void IN_AttackDown(void) {KeyDown(&in_attack);} void IN_AttackUp(void) {KeyUp(&in_attack);} //alt fire void IN_Attack2Down(void) {KeyDown(&in_attack2);} void IN_Attack2Up(void) {KeyUp(&in_attack2);} void IN_UseDown (void) {KeyDown(&in_use);} void IN_UseUp (void) {KeyUp(&in_use);} void IN_Impulse (void) {in_impulse=atoi(Cmd_Argv(1));} /* =============== CL_KeyState Returns the fraction of the frame that the key was down =============== */ float CL_KeyState (kbutton_t *key) { float val; int msec; key->state &= 1; // clear impulses msec = key->msec; key->msec = 0; if (key->state) { // still down msec += sys_frame_time - key->downtime; key->downtime = sys_frame_time; } #if 0 if (msec) { Com_Printf ("%i ", msec); } #endif val = (float)msec / frame_msec; if (val < 0) val = 0; if (val > 1) val = 1; return val; } //========================================================================== cvar_t *cl_upspeed; cvar_t *cl_forwardspeed; cvar_t *cl_sidespeed; cvar_t *cl_yawspeed; cvar_t *cl_pitchspeed; cvar_t *cl_run; cvar_t *cl_anglespeedkey; /* ================ CL_AdjustAngles Moves the local angle positions ================ */ void CL_AdjustAngles (void) { float speed; float up, down; if (in_speed.state & 1) speed = cls.frametime * cl_anglespeedkey->value; else speed = cls.frametime; if (!(in_strafe.state & 1)) { cl.viewangles[YAW] -= speed*cl_yawspeed->value*CL_KeyState (&in_right); cl.viewangles[YAW] += speed*cl_yawspeed->value*CL_KeyState (&in_left); } if (in_klook.state & 1) { cl.viewangles[PITCH] -= speed*cl_pitchspeed->value * CL_KeyState (&in_forward); cl.viewangles[PITCH] += speed*cl_pitchspeed->value * CL_KeyState (&in_back); } up = CL_KeyState (&in_lookup); down = CL_KeyState(&in_lookdown); cl.viewangles[PITCH] -= speed*cl_pitchspeed->value * up; cl.viewangles[PITCH] += speed*cl_pitchspeed->value * down; } /* ================ CL_BaseMove Send the intended movement message to the server ================ */ void CL_BaseMove (usercmd_t *cmd) { CL_AdjustAngles (); memset (cmd, 0, sizeof(*cmd)); VectorCopy (cl.viewangles, cmd->angles); if (in_strafe.state & 1) { cmd->sidemove += cl_sidespeed->value * CL_KeyState (&in_right); cmd->sidemove -= cl_sidespeed->value * CL_KeyState (&in_left); } cmd->sidemove += cl_sidespeed->value * CL_KeyState (&in_moveright); cmd->sidemove -= cl_sidespeed->value * CL_KeyState (&in_moveleft); cmd->upmove += cl_upspeed->value * CL_KeyState (&in_up); cmd->upmove -= cl_upspeed->value * CL_KeyState (&in_down); if (! (in_klook.state & 1) ) { cmd->forwardmove += cl_forwardspeed->value * CL_KeyState (&in_forward); cmd->forwardmove -= cl_forwardspeed->value * CL_KeyState (&in_back); } // // adjust for speed key / running // if (!cl.tactical && ( (in_speed.state & 1) ^ cl_run->integer )) { cmd->forwardmove *= 2; cmd->sidemove *= 2; cmd->upmove *= 2; } } void CL_ClampPitch (void) { float pitch; pitch = SHORT2ANGLE(cl.frame.playerstate.pmove.delta_angles[PITCH]); if (pitch > 180) pitch -= 360; if (cl.viewangles[PITCH] + pitch < -360) cl.viewangles[PITCH] += 360; // wrapped if (cl.viewangles[PITCH] + pitch > 360) cl.viewangles[PITCH] -= 360; // wrapped if (cl.viewangles[PITCH] + pitch > 89) cl.viewangles[PITCH] = 89 - pitch; if (cl.viewangles[PITCH] + pitch < -89) cl.viewangles[PITCH] = -89 - pitch; } /* ============== CL_FinishMove ============== */ void CL_FinishMove (usercmd_t *cmd) { int ms; int i; // // figure button bits // if ( in_attack.state & 3 ) cmd->buttons |= BUTTON_ATTACK; in_attack.state &= ~2; //alt fire if ( in_attack2.state & 3 ) cmd->buttons |= BUTTON_ATTACK2; in_attack2.state &= ~2; if (in_use.state & 3) cmd->buttons |= BUTTON_USE; in_use.state &= ~2; if (anykeydown && cls.key_dest == key_game) cmd->buttons |= BUTTON_ANY; // send milliseconds of time to apply the move ms = cls.frametime * 1000; if (ms > 250) ms = 100; // time was unreasonable cmd->msec = ms; CL_ClampPitch (); for (i=0 ; i<3 ; i++) cmd->angles[i] = ANGLE2SHORT(cl.viewangles[i]); cmd->impulse = in_impulse; in_impulse = 0; } /* ================= CL_CreateCmd ================= */ usercmd_t CL_CreateCmd (void) { usercmd_t cmd; frame_msec = sys_frame_time - old_sys_frame_time; if (frame_msec < 1) frame_msec = 1; if (frame_msec > 200) frame_msec = 200; // get basic movement from keyboard CL_BaseMove (&cmd); // allow mice or other external controllers to add to the move IN_Move (&cmd); IN_JoyMove (&cmd); CL_FinishMove (&cmd); old_sys_frame_time = sys_frame_time; //cmd.impulse = cls.framecount; return cmd; } void IN_CenterView (void) { cl.viewangles[PITCH] = -SHORT2ANGLE(cl.frame.playerstate.pmove.delta_angles[PITCH]); } /* ============ CL_InitInput ============ */ void CL_InitInput (void) { Cmd_AddCommand ("centerview",IN_CenterView); Cmd_AddCommand ("+moveup",IN_UpDown); Cmd_AddCommand ("-moveup",IN_UpUp); Cmd_AddCommand ("+movedown",IN_DownDown); Cmd_AddCommand ("-movedown",IN_DownUp); Cmd_AddCommand ("+left",IN_LeftDown); Cmd_AddCommand ("-left",IN_LeftUp); Cmd_AddCommand ("+right",IN_RightDown); Cmd_AddCommand ("-right",IN_RightUp); Cmd_AddCommand ("+forward",IN_ForwardDown); Cmd_AddCommand ("-forward",IN_ForwardUp); Cmd_AddCommand ("+back",IN_BackDown); Cmd_AddCommand ("-back",IN_BackUp); Cmd_AddCommand ("+lookup", IN_LookupDown); Cmd_AddCommand ("-lookup", IN_LookupUp); Cmd_AddCommand ("+lookdown", IN_LookdownDown); Cmd_AddCommand ("-lookdown", IN_LookdownUp); Cmd_AddCommand ("+strafe", IN_StrafeDown); Cmd_AddCommand ("-strafe", IN_StrafeUp); Cmd_AddCommand ("+moveleft", IN_MoveleftDown); Cmd_AddCommand ("-moveleft", IN_MoveleftUp); Cmd_AddCommand ("+moveright", IN_MoverightDown); Cmd_AddCommand ("-moveright", IN_MoverightUp); Cmd_AddCommand ("+speed", IN_SpeedDown); Cmd_AddCommand ("-speed", IN_SpeedUp); Cmd_AddCommand ("+attack", IN_AttackDown); Cmd_AddCommand ("-attack", IN_AttackUp); Cmd_AddCommand ("+use", IN_UseDown); Cmd_AddCommand ("-use", IN_UseUp); Cmd_AddCommand ("impulse", IN_Impulse); Cmd_AddCommand ("+klook", IN_KLookDown); Cmd_AddCommand ("-klook", IN_KLookUp); //alt fire Cmd_AddCommand ("+attack2", IN_Attack2Down); Cmd_AddCommand ("-attack2", IN_Attack2Up); cl_nodelta = Cvar_Get ("cl_nodelta", "0", 0); } /* ================= CL_SendCmd ================= */ void CL_SendCmd (void) { sizebuf_t buf; byte data[128]; int i; usercmd_t *cmd, *oldcmd; usercmd_t nullcmd; int checksumIndex; // build a command even if not connected // save this command off for prediction i = cls.netchan.outgoing_sequence & (CMD_BACKUP-1); cmd = &cl.cmds[i]; cl.cmd_time[i] = cls.realtime; // for netgraph ping calculation *cmd = CL_CreateCmd (); cl.cmd = *cmd; if (cls.state == ca_disconnected || cls.state == ca_connecting) return; if ( cls.state == ca_connected) { if (cls.netchan.message.cursize || curtime - cls.netchan.last_sent > 1000 ) Netchan_Transmit (&cls.netchan, 0, data); return; } // send a userinfo update if needed if (userinfo_modified) { CL_FixUpGender(); userinfo_modified = false; MSG_WriteByte (&cls.netchan.message, clc_userinfo); MSG_WriteString (&cls.netchan.message, Cvar_Userinfo() ); } SZ_Init (&buf, data, sizeof(data)); SZ_SetName ( &buf, "CL_SendCmd", false ); // begin a client move command MSG_WriteByte (&buf, clc_move); // save the position for a checksum byte checksumIndex = buf.cursize; MSG_WriteByte (&buf, 0); // let the server know what the last frame we // got was, so the next message can be delta compressed if (cl_nodelta->value || !cl.frame.valid || cls.demowaiting) MSG_WriteLong (&buf, -1); // no compression else MSG_WriteLong (&buf, cl.frame.serverframe); // send this and the previous cmds in the message, so // if the last packet was dropped, it can be recovered i = (cls.netchan.outgoing_sequence-2) & (CMD_BACKUP-1); cmd = &cl.cmds[i]; memset (&nullcmd, 0, sizeof(nullcmd)); MSG_WriteDeltaUsercmd (&buf, &nullcmd, cmd); oldcmd = cmd; i = (cls.netchan.outgoing_sequence-1) & (CMD_BACKUP-1); cmd = &cl.cmds[i]; MSG_WriteDeltaUsercmd (&buf, oldcmd, cmd); oldcmd = cmd; i = (cls.netchan.outgoing_sequence) & (CMD_BACKUP-1); cmd = &cl.cmds[i]; MSG_WriteDeltaUsercmd (&buf, oldcmd, cmd); // calculate a checksum over the move commands buf.data[checksumIndex] = COM_BlockSequenceCRCByte( buf.data + checksumIndex + 1, buf.cursize - checksumIndex - 1, cls.netchan.outgoing_sequence); // // deliver the message // Netchan_Transmit (&cls.netchan, buf.cursize, buf.data); } #if defined WIN32_VARIANT # define OS_MENU_MOUSESCALE 0.35 #else # if defined UNIX_VARIANT # define OS_MENU_MOUSESCALE 0.1 # else # define OS_MENU_MOUSESCALE 1 # endif #endif qboolean mouse_available = false; qboolean mouse_is_position = false; qboolean mlooking = false; int mouse_diff_x = 0; int mouse_diff_y = 0; int mouse_odiff_x = 0; int mouse_odiff_y = 0; cursor_t cursor; void IN_MLookDown (void) { mlooking = true; } void IN_MLookUp (void) { mlooking = false; if (!freelook->integer && lookspring->integer) { IN_CenterView (); } } static void IN_MoveMenuMouse( int x , int y ) { cursor.oldx = cursor.x; cursor.oldy = cursor.y; // Clip cursor location to window if ( x < 0 ) { x = 0; } else if ( x > viddef.width ) { x = viddef.width; } if ( y < 0 ) { y = 0; } else if ( y > viddef.height ) { y = viddef.height; } cursor.x = x; cursor.y = y; cursor.mouseaction = cursor.mouseaction || cursor.x != cursor.oldx || cursor.y != cursor.oldy; M_Think_MouseCursor(); } extern cvar_t *fov; void IN_Move (usercmd_t *cmd) { float fmx; float fmy; float adjust; if ( ! mouse_available ) { return; } // If we have a position instead of a diff, don't go through // the normal process. Instead, update the menu's cursor // as necessary, and bail out. if ( mouse_is_position ) { if ( cls.key_dest == key_menu ) { IN_MoveMenuMouse( mouse_diff_x , mouse_diff_y ); } return; } // Apply interpolation with previous value if necessary fmx = (float) mouse_diff_x; fmy = (float) mouse_diff_y; if ( m_filter->integer ) { fmx = ( fmx + mouse_odiff_x ) * 0.5f; fmy = ( fmy + mouse_odiff_y ) * 0.5f; } if (cmd) { mouse_odiff_x = mouse_diff_x; mouse_odiff_y = mouse_diff_y; mouse_diff_x = mouse_diff_y = 0; } // No mouse in console if ( cls.key_dest == key_console ) { return; } // Compute adjustments adjust = 1.0; if ( m_smoothing->value ) { // reduce sensitivity when frames per sec is below maximum // setting by multiplying by: // current measured fps / cvar set maximum fps adjust /= cls.frametime * cl_maxfps->value; } // Update menu cursor location if ( cls.key_dest == key_menu ) { adjust *= menu_sensitivity->value * OS_MENU_MOUSESCALE; IN_MoveMenuMouse( cursor.x + fmx * adjust , cursor.y + fmy * adjust ); return; } // Game mouse adjust *= sensitivity->value * cl.refdef.fov_x/fov->value; fmx *= adjust; fmy *= adjust; // Add mouse X/Y movement to cmd if ( ( lookstrafe->integer && mlooking ) || ( in_strafe.state & 1 ) ) { if (!cmd) return; cmd->sidemove += (short)( ( m_side->value * fmx ) + 0.5f ); } else { if (cmd) cl.viewangles[ YAW ] -= m_yaw->value * fmx; else cl.predicted_angles[ YAW ] = cl.last_predicted_angles[ YAW ] - m_yaw->value * fmx; } if ( ( mlooking || freelook->integer ) && !( in_strafe.state & 1 ) ) { if (cmd) cl.viewangles[ PITCH ] += m_pitch->value * fmy; else cl.predicted_angles[ PITCH ] = cl.last_predicted_angles[ PITCH ] + m_pitch->value * fmy; } else { if (!cmd) return; cmd->forwardmove -= (short)( ( m_forward->value * fmy ) + 0.5f ); } } alien-arena-7.66+dfsg/source/client/keys.c0000600000175000017500000005356212161402010017512 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "client.h" /* key up events are sent even if in console mode */ char key_lines[32][MAXCMDLINE]; int key_linelen; int key_linepos; int shift_down=false; int anykeydown; int edit_line=0; int history_line=0; int key_waiting; char *keybindings[256]; qboolean consolekeys[256]; // if true, can't be rebound while in console qboolean menubound[256]; // if true, can't be rebound while in menu int keyshift[256]; // key to map to if shift held down in console int key_repeats[256]; // if > 1, it is autorepeating qboolean keydown[256]; typedef struct { char *name; int keynum; } keyname_t; keyname_t keynames[] = { {"TAB", K_TAB}, {"ENTER", K_ENTER}, {"ESCAPE", K_ESCAPE}, {"SPACE", K_SPACE}, {"BACKSPACE", K_BACKSPACE}, {"UPARROW", K_UPARROW}, {"DOWNARROW", K_DOWNARROW}, {"LEFTARROW", K_LEFTARROW}, {"RIGHTARROW", K_RIGHTARROW}, {"ALT", K_ALT}, {"CTRL", K_CTRL}, {"SHIFT", K_SHIFT}, {"F1", K_F1}, {"F2", K_F2}, {"F3", K_F3}, {"F4", K_F4}, {"F5", K_F5}, {"F6", K_F6}, {"F7", K_F7}, {"F8", K_F8}, {"F9", K_F9}, {"F10", K_F10}, {"F11", K_F11}, {"F12", K_F12}, {"INS", K_INS}, {"DEL", K_DEL}, {"PGDN", K_PGDN}, {"PGUP", K_PGUP}, {"HOME", K_HOME}, {"END", K_END}, {"MOUSE1", K_MOUSE1}, {"MOUSE2", K_MOUSE2}, {"MOUSE3", K_MOUSE3}, {"MOUSE4", K_MOUSE4}, {"MOUSE5", K_MOUSE5}, {"MOUSE6", K_MOUSE6}, {"MOUSE7", K_MOUSE7}, {"MOUSE8", K_MOUSE8}, {"MOUSE9", K_MOUSE9}, {"JOY1", K_JOY1}, {"JOY2", K_JOY2}, {"JOY3", K_JOY3}, {"JOY4", K_JOY4}, {"AUX1", K_AUX1}, {"AUX2", K_AUX2}, {"AUX3", K_AUX3}, {"AUX4", K_AUX4}, {"AUX5", K_AUX5}, {"AUX6", K_AUX6}, {"AUX7", K_AUX7}, {"AUX8", K_AUX8}, {"AUX9", K_AUX9}, {"AUX10", K_AUX10}, {"AUX11", K_AUX11}, {"AUX12", K_AUX12}, {"AUX13", K_AUX13}, {"AUX14", K_AUX14}, {"AUX15", K_AUX15}, {"AUX16", K_AUX16}, {"AUX17", K_AUX17}, {"AUX18", K_AUX18}, {"AUX19", K_AUX19}, {"AUX20", K_AUX20}, {"AUX21", K_AUX21}, {"AUX22", K_AUX22}, {"AUX23", K_AUX23}, {"AUX24", K_AUX24}, {"AUX25", K_AUX25}, {"AUX26", K_AUX26}, {"AUX27", K_AUX27}, {"AUX28", K_AUX28}, {"AUX29", K_AUX29}, {"AUX30", K_AUX30}, {"AUX31", K_AUX31}, {"AUX32", K_AUX32}, {"KP_HOME", K_KP_HOME }, {"KP_UPARROW", K_KP_UPARROW }, {"KP_PGUP", K_KP_PGUP }, {"KP_LEFTARROW", K_KP_LEFTARROW }, {"KP_5", K_KP_5 }, {"KP_RIGHTARROW", K_KP_RIGHTARROW }, {"KP_END", K_KP_END }, {"KP_DOWNARROW", K_KP_DOWNARROW }, {"KP_PGDN", K_KP_PGDN }, {"KP_ENTER", K_KP_ENTER }, {"KP_INS", K_KP_INS }, {"KP_DEL", K_KP_DEL }, {"KP_SLASH", K_KP_SLASH }, {"KP_MINUS", K_KP_MINUS }, {"KP_PLUS", K_KP_PLUS }, {"MWHEELUP", K_MWHEELUP }, {"MWHEELDOWN", K_MWHEELDOWN }, {"PAUSE", K_PAUSE}, {"SEMICOLON", ';'}, // because a raw semicolon seperates commands {NULL,0} }; /* ============================================================================== LINE TYPING INTO THE CONSOLE ============================================================================== */ void Key_ClearTyping (void) { key_lines[edit_line][1] = 0; // clear any typing key_linelen = key_linepos = 1; } qboolean Cmd_IsComplete(char *cmd); extern void Q_strncpyz( char *dest, const char *src, size_t size ); void CompleteCommand (void) { char *cmd, *s; s = key_lines[edit_line] + 1; if (*s == '\\' || *s == '/') s++; cmd = Cmd_CompleteCommand(s); if (cmd) { key_lines[edit_line][1] = '/'; Q_strncpyz(key_lines[edit_line] + 2, cmd, sizeof(key_lines[0])); key_linelen = key_linepos = strlen(cmd) + 2; if (Cmd_IsComplete(cmd)) { key_lines[edit_line][key_linepos] = ' '; key_linepos++; key_lines[edit_line][key_linepos] = 0; key_linelen++; } else { key_lines[edit_line][key_linepos] = 0; } return; } } /* ==================== Key_Console Interactive line editing and console scrollback ==================== */ void Key_Console (int key) { char buffer[MAXCMDLINE]; switch ( key ) { case K_KP_SLASH: key = '/'; break; case K_KP_MINUS: key = '-'; break; case K_KP_PLUS: key = '+'; break; case K_KP_HOME: key = '7'; break; case K_KP_UPARROW: key = '8'; break; case K_KP_PGUP: key = '9'; break; case K_KP_LEFTARROW: key = '4'; break; case K_KP_5: key = '5'; break; case K_KP_RIGHTARROW: key = '6'; break; case K_KP_END: key = '1'; break; case K_KP_DOWNARROW: key = '2'; break; case K_KP_PGDN: key = '3'; break; case K_KP_INS: key = '0'; break; case K_KP_DEL: key = '.'; break; } if ( ( toupper( key ) == 'V' && keydown[K_CTRL] ) || ( ( ( key == K_INS ) || ( key == K_KP_INS ) ) && keydown[K_SHIFT] ) ) { char *cbd; if ( ( cbd = Sys_GetClipboardData() ) != 0 ) { int i, l; // save the end of the line l = 1 + key_linelen - key_linepos; memcpy (buffer, key_lines[edit_line] + key_linepos, l); i = 0; while ( cbd[i] && key_linelen < MAXCMDLINE - 1 ) { // only copy printable characters if ( cbd[i] >= 32 ) { key_lines[edit_line][key_linepos ++] = cbd[i]; key_linelen ++; } i++; } // restore the end of the line memcpy (key_lines[edit_line] + key_linepos, buffer, l); free( cbd ); } return; } if ( key == K_ENTER || key == K_KP_ENTER ) { Cbuf_AddText (key_lines[edit_line]+1); Cbuf_AddText ("\n"); Com_Printf ("%s\n",key_lines[edit_line]); edit_line = (edit_line + 1) & 31; history_line = edit_line; key_lines[edit_line][0] = ']'; key_linelen = key_linepos = 1; if (cls.state == ca_disconnected) SCR_UpdateScreen (); // force an update, because the command // may take some time return; } if (key == K_TAB) { // command completion CompleteCommand (); return; } if ( key == K_DEL || key == K_KP_DEL ) { // Del key, fakes a backspace from the next character if ( key_linepos == key_linelen ) return; key_linepos ++; key = K_BACKSPACE; } if ( ( key == K_BACKSPACE ) || ( ( key == 'h' ) && ( keydown[K_CTRL] ) ) ) { if (key_linepos > 1) { // remove character at key_linepos if ( key_linelen == key_linepos ) { key_lines[edit_line][key_linelen - 1] = 0; } else { memcpy (buffer, key_lines[edit_line], key_linepos - 1); memcpy (buffer + key_linepos - 1, key_lines[edit_line] + key_linepos, key_linelen - key_linepos); buffer[key_linelen - 1] = 0; memcpy (key_lines[edit_line], buffer, MAXCMDLINE); } key_linepos--; key_linelen--; } return; } if ( ( key == K_LEFTARROW ) || ( key == K_KP_LEFTARROW ) ) { if (key_linepos > 1) { if ( keydown[K_CTRL] ) { qboolean found_char = false, printable = false; while (key_linepos > 1) { key_linepos --; printable = isalpha(key_lines[edit_line][key_linepos]); found_char = found_char || printable; if ( found_char && !printable ) { key_linepos ++; break; } } } else { key_linepos--; } } return; } if ( ( key == K_RIGHTARROW ) || ( key == K_KP_RIGHTARROW ) ) { if (key_linepos < key_linelen) { if ( keydown[K_CTRL] ) { qboolean found_char = false, printable = false; while (key_linepos < key_linelen && (! found_char || printable)) { key_linepos ++; printable = isalpha(key_lines[edit_line][key_linepos]); found_char = found_char || printable; } } else { key_linepos++; } } return; } if ( ( key == K_UPARROW ) || ( key == K_KP_UPARROW ) || ( ( key == 'p' ) && keydown[K_CTRL] ) ) { do { history_line = (history_line - 1) & 31; } while (history_line != edit_line && !key_lines[history_line][1]); if (history_line == edit_line) history_line = (edit_line+1)&31; strcpy(key_lines[edit_line], key_lines[history_line]); key_linelen = key_linepos = strlen(key_lines[edit_line]); return; } if ( ( key == K_DOWNARROW ) || ( key == K_KP_DOWNARROW ) || ( ( key == 'n' ) && keydown[K_CTRL] ) ) { if (history_line == edit_line) return; do { history_line = (history_line + 1) & 31; } while (history_line != edit_line && !key_lines[history_line][1]); if (history_line == edit_line) { key_lines[edit_line][0] = ']'; key_linelen = key_linepos = 1; } else { strcpy(key_lines[edit_line], key_lines[history_line]); key_linelen = key_linepos = strlen(key_lines[edit_line]); } return; } if (key == K_PGUP || key == K_KP_PGUP || key == K_MWHEELUP ) { CON_console.displayOffset += 64; return; } if (key == K_PGDN || key == K_KP_PGDN || key == K_MWHEELDOWN ) { if ( CON_console.displayOffset >= 64 ) { CON_console.displayOffset -= 64; } else { CON_console.displayOffset = 0; } return; } if (key == K_HOME || key == K_KP_HOME ) { if ( keydown[K_CTRL] ) CON_console.displayOffset = 0x7fffffff; else key_linepos = 1; return; } if (key == K_END || key == K_KP_END ) { if ( keydown[K_CTRL] ) CON_console.displayOffset = 0; else key_linepos = key_linelen; return; } if (key < 32 || key > 127) return; // non printable if ( keydown[K_CTRL] ) { switch ( key ) { case 'a': case 'A': key_linepos = 1; break; case 'e': case 'E': key_linepos = key_linelen; break; case 'l': case 'L': Cbuf_AddText ("clear\n"); break; case 'k': case 'K': key_linelen = key_linepos; key_lines[edit_line][key_linepos + 1] = 0; break; } return; } if (key_linelen < MAXCMDLINE-1) { if (key_linepos == key_linelen) { // end of the line, append character key_lines[edit_line][key_linepos] = key; key_lines[edit_line][key_linepos + 1] = 0; } else { // insert character memcpy (buffer, key_lines[edit_line], key_linepos); buffer[key_linepos] = key; memcpy (buffer + key_linepos + 1, key_lines[edit_line] + key_linepos, key_linelen - key_linepos); buffer[key_linelen + 1] = 0; memcpy (key_lines[edit_line], buffer, MAXCMDLINE); } key_linepos++; key_linelen++; } } //============================================================================ qboolean chat_team; qboolean chat_irc; char chat_buffer[MAXCMDLINE]; int chat_bufferlen = 0; void Key_Message (int key) { if ( key == K_ENTER || key == K_KP_ENTER ) { if (chat_team) Cbuf_AddText ("say_team \""); else if (chat_irc) Cbuf_AddText ("irc_say \""); else Cbuf_AddText ("say \""); Cbuf_AddText(chat_buffer); Cbuf_AddText("\"\n"); cls.key_dest = key_game; chat_bufferlen = 0; chat_buffer[0] = 0; return; } if (key == K_ESCAPE) { cls.key_dest = key_game; chat_bufferlen = 0; chat_buffer[0] = 0; return; } if (key < 32 || key > 127) return; // non printable if (key == K_BACKSPACE) { if (chat_bufferlen) { chat_bufferlen--; chat_buffer[chat_bufferlen] = 0; } return; } if (chat_bufferlen == sizeof(chat_buffer)-1) return; // all full chat_buffer[chat_bufferlen++] = key; chat_buffer[chat_bufferlen] = 0; } //============================================================================ /* =================== Key_StringToKeynum Returns a key number to be used to index keybindings[] by looking at the given string. Single ascii characters return themselves, while the K_* names are matched up. =================== */ int Key_StringToKeynum (char *str) { keyname_t *kn; if (!str || !str[0]) return -1; if (!str[1]) return str[0]; for (kn=keynames ; kn->name ; kn++) { if (!Q_strcasecmp(str,kn->name)) return kn->keynum; } return -1; } /* =================== Key_KeynumToString Returns a string (either a single ascii char, or a K_* name) for the given keynum. FIXME: handle quote special (general escape sequence?) =================== */ char *Key_KeynumToString (int keynum) { keyname_t *kn; static char tinystr[2]; if (keynum == -1) return ""; if (keynum > 32 && keynum < 127) { // printable ascii tinystr[0] = keynum; tinystr[1] = 0; return tinystr; } for (kn=keynames ; kn->name ; kn++) if (keynum == kn->keynum) return kn->name; return ""; } /* =================== Key_SetBinding =================== */ void Key_SetBinding (int keynum, char *binding) { char *new; int l; if (keynum == -1) return; // free old bindings if (keybindings[keynum]) { Z_Free (keybindings[keynum]); keybindings[keynum] = NULL; } // allocate memory for new binding l = strlen (binding); new = Z_Malloc (l+1); strcpy (new, binding); new[l] = 0; keybindings[keynum] = new; } /* =================== Key_Unbind_f =================== */ void Key_Unbind_f (void) { int b; if (Cmd_Argc() != 2) { Com_Printf ("unbind : remove commands from a key\n"); return; } b = Key_StringToKeynum (Cmd_Argv(1)); if (b==-1) { Com_Printf ("\"%s\" isn't a valid key\n", Cmd_Argv(1)); return; } Key_SetBinding (b, ""); } void Key_Unbindall_f (void) { int i; for (i=0 ; i<256 ; i++) if (keybindings[i]) Key_SetBinding (i, ""); } /* =================== Key_Bind_f =================== */ void Key_Bind_f (void) { int i, c, b; char cmd[1024]; c = Cmd_Argc(); if (c < 2) { Com_Printf ("bind [command] : attach a command to a key\n"); return; } b = Key_StringToKeynum (Cmd_Argv(1)); if (b==-1) { Com_Printf ("\"%s\" isn't a valid key\n", Cmd_Argv(1)); return; } if (c == 2) { if (keybindings[b]) Com_Printf ("\"%s\" = \"%s\"\n", Cmd_Argv(1), keybindings[b] ); else Com_Printf ("\"%s\" is not bound\n", Cmd_Argv(1) ); return; } // copy the rest of the command line cmd[0] = 0; // start out with a null string for (i=2 ; i< c ; i++) { strcat (cmd, Cmd_Argv(i)); if (i != (c-1)) strcat (cmd, " "); } Key_SetBinding (b, cmd); } /* ============ Key_WriteBindings Writes lines containing "bind key value" ============ */ void Key_WriteBindings (FILE *f) { int i; for (i=0 ; i<256 ; i++) if (keybindings[i] && keybindings[i][0]) fprintf (f, "bind %s \"%s\"\n", Key_KeynumToString(i), keybindings[i]); } /* ============ Key_Bindlist_f ============ */ void Key_Bindlist_f (void) { int i; for (i=0 ; i<256 ; i++) if (keybindings[i] && keybindings[i][0]) Com_Printf ("%s \"%s\"\n", Key_KeynumToString(i), keybindings[i]); } /* =================== Key_Init =================== */ void Key_Init (void) { int i; for (i=0 ; i<32 ; i++) { key_lines[i][0] = ']'; key_lines[i][1] = 0; } key_linelen = key_linepos = 1; // // init ascii characters in console mode // for (i=32 ; i<128 ; i++) consolekeys[i] = true; consolekeys[K_ENTER] = true; consolekeys[K_KP_ENTER] = true; consolekeys[K_TAB] = true; consolekeys[K_LEFTARROW] = true; consolekeys[K_KP_LEFTARROW] = true; consolekeys[K_RIGHTARROW] = true; consolekeys[K_KP_RIGHTARROW] = true; consolekeys[K_UPARROW] = true; consolekeys[K_KP_UPARROW] = true; consolekeys[K_DOWNARROW] = true; consolekeys[K_KP_DOWNARROW] = true; consolekeys[K_BACKSPACE] = true; consolekeys[K_HOME] = true; consolekeys[K_KP_HOME] = true; consolekeys[K_END] = true; consolekeys[K_KP_END] = true; consolekeys[K_PGUP] = true; consolekeys[K_KP_PGUP] = true; consolekeys[K_PGDN] = true; consolekeys[K_KP_PGDN] = true; consolekeys[K_SHIFT] = true; consolekeys[K_INS] = true; consolekeys[K_DEL] = true; consolekeys[K_KP_INS] = true; consolekeys[K_KP_DEL] = true; consolekeys[K_KP_SLASH] = true; consolekeys[K_KP_PLUS] = true; consolekeys[K_KP_MINUS] = true; consolekeys[K_KP_5] = true; consolekeys[K_MWHEELUP] = true; consolekeys[K_MWHEELDOWN] = true; consolekeys['`'] = false; consolekeys['~'] = false; for (i=0 ; i<256 ; i++) keyshift[i] = i; for (i='a' ; i<='z' ; i++) keyshift[i] = i - 'a' + 'A'; keyshift['1'] = '!'; keyshift['2'] = '@'; keyshift['3'] = '#'; keyshift['4'] = '$'; keyshift['5'] = '%'; keyshift['6'] = '^'; keyshift['7'] = '&'; keyshift['8'] = '*'; keyshift['9'] = '('; keyshift['0'] = ')'; keyshift['-'] = '_'; keyshift['='] = '+'; keyshift[','] = '<'; keyshift['.'] = '>'; keyshift['/'] = '?'; keyshift[';'] = ':'; keyshift['\''] = '"'; keyshift['['] = '{'; keyshift[']'] = '}'; keyshift['`'] = '~'; keyshift['\\'] = '|'; menubound[K_ESCAPE] = true; for (i=0 ; i<12 ; i++) menubound[K_F1+i] = true; // // register our functions // Cmd_AddCommand ("bind",Key_Bind_f); Cmd_AddCommand ("unbind",Key_Unbind_f); Cmd_AddCommand ("unbindall",Key_Unbindall_f); Cmd_AddCommand ("bindlist",Key_Bindlist_f); } /* =================== Key_Event Called by the system between frames for both key up and key down events Should NOT be called during an interrupt! =================== */ void Key_Event (int key, qboolean down, unsigned time) { char *kb; char cmd[1024]; // hack for modal presses if (key_waiting == -1) { if (down) key_waiting = key; return; } // update auto-repeat status if (down) { key_repeats[key]++; if (key != K_BACKSPACE && key != K_PAUSE && key != K_PGUP && key != K_KP_PGUP && key != K_PGDN && key != K_KP_PGDN && key_repeats[key] > 1) return; // ignore most autorepeats if (key >= 200 && !keybindings[key]) Com_Printf ("%s is not bound to a command.\n", Key_KeynumToString (key) ); } else { key_repeats[key] = 0; } if (key == K_SHIFT) shift_down = down; // console key is hardcoded, so the user can never unbind it if (key == '`' || key == '~') { if (!down) return; if (cls.key_dest == key_console && cls.state == ca_disconnected) { M_Menu_Main_f (); return; } CON_ToggleConsole( ); return; } // menu key is hardcoded, so the user can never unbind it if (key == K_ESCAPE) { if (!down) return; if (cl.frame.playerstate.stats[STAT_LAYOUTS] && cls.key_dest == key_game) { // put away help computer / inventory Cbuf_AddText ("cmd putaway\n"); return; } switch (cls.key_dest) { case key_message: Key_Message (key); break; case key_menu: M_Keydown (key); break; case key_game: case key_console: M_Menu_Main_f (); break; default: Com_Error (ERR_FATAL, "Bad cls.key_dest"); } return; } // track if any key is down for BUTTON_ANY keydown[key] = down; if (down) { if (key_repeats[key] == 1) anykeydown++; } else { anykeydown--; if (anykeydown < 0) anykeydown = 0; } // // key up events only generate commands if the game key binding is // a button command (leading + sign). These will occur even in console mode, // to keep the character from continuing an action started before a console // switch. Button commands include the kenum as a parameter, so multiple // downs can be matched with ups // if (!down) { kb = keybindings[key]; if (kb && kb[0] == '+') { Com_sprintf (cmd, sizeof(cmd), "-%s %i %i\n", kb+1, key, time); Cbuf_AddText (cmd); } if (keyshift[key] != key) { kb = keybindings[keyshift[key]]; if (kb && kb[0] == '+') { Com_sprintf (cmd, sizeof(cmd), "-%s %i %i\n", kb+1, key, time); Cbuf_AddText (cmd); } } return; } // // if not a consolekey, send to the interpreter no matter what mode is // if ( (cls.key_dest == key_menu && menubound[key]) || (cls.key_dest == key_console && !consolekeys[key]) || (cls.key_dest == key_game && ( cls.state == ca_active || !consolekeys[key] ) ) ) { kb = keybindings[key]; if (kb) { if (kb[0] == '+') { // button commands add keynum and time as a parm Com_sprintf (cmd, sizeof(cmd), "%s %i %i\n", kb, key, time); Cbuf_AddText (cmd); } else { Cbuf_AddText (kb); Cbuf_AddText ("\n"); } } return; } if (!down) return; // other systems only care about key down events if (shift_down) key = keyshift[key]; switch (cls.key_dest) { case key_message: Key_Message (key); break; case key_menu: M_Keydown (key); break; case key_game: case key_console: Key_Console (key); break; default: Com_Error (ERR_FATAL, "Bad cls.key_dest"); } } /* =================== Key_ClearStates =================== */ void Key_ClearStates (void) { int i; anykeydown = false; for (i=0 ; i<256 ; i++) { if ( keydown[i] || key_repeats[i] ) Key_Event( i, false, 0 ); keydown[i] = 0; key_repeats[i] = 0; } } /* =================== Key_GetKey =================== */ int Key_GetKey (void) { key_waiting = -1; while (key_waiting == -1) Sys_SendKeyEvents (); return key_waiting; } alien-arena-7.66+dfsg/source/client/menu.c0000600000175000017500000054507612204310130017510 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. Copyright (C) 2005-2013 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #if defined WIN32_VARIANT #include #endif #if defined UNIX_VARIANT #include #if defined HAVE_UNISTD_H #include #endif #endif #if defined WIN32_VARIANT #include #endif #include "client.h" #include "client/qmenu.h" #if !defined HAVE__STRDUP #if defined HAVE_STRDUP #define _strdup strdup #endif #endif static int m_main_cursor; extern int CL_GetPingStartTime(netadr_t adr); extern void RS_LoadScript(char *script); extern void RS_LoadSpecialScripts(void); extern void RS_ScanPathForScripts(void); extern void RS_FreeUnmarked (void); extern void SCR_DrawCenterString (void); extern cvar_t *scriptsloaded; #if defined WIN32_VARIANT extern char map_music[MAX_PATH]; #else extern char map_music[MAX_OSPATH]; #endif extern cvar_t *background_music; extern cvar_t *background_music_vol; extern cvar_t *fov; extern cvar_t *stats_password; static char *menu_in_sound = "misc/menu1.wav"; static char *menu_move_sound = "misc/menu2.wav"; static char *menu_out_sound = "misc/menu3.wav"; #define PLAYER_NAME_UNIQUE (strcmp (Cvar_VariableString ("name"), "Player") != 0) void SetCrosshairNames (char **list); void SetHudNames (char **list); void SetFontNames (char **list); void M_Menu_Main_f (void); static void M_Menu_PlayerConfig_f (void); static void M_Menu_Game_f (void); static void M_Menu_Credits_f( void ); static void M_Menu_JoinServer_f (void); static void M_Menu_AddressBook_f( void ); static void M_Menu_PlayerRanking_f( void ); static void M_Menu_Tactical_f( void ); static void M_Menu_StartServer_f (void); static void M_Menu_BotOptions_f (void); static void M_Menu_IRC_f (void); static void M_Menu_Options_f (void); static void M_Menu_Video_f (void); static void M_Menu_Keys_f (void); static void M_Menu_Quit_f (void); static void M_Menu_Credits( void ); qboolean m_entersound; // play after drawing a frame, so caching // won't disrupt the sound static size_t szr; // just for unused result warnings // common callbacks static void StrFieldCallback( void *_self ) { menufield_s *self = (menufield_s *)_self; Cvar_Set( self->generic.localstrings[0], self->buffer); } static void IntFieldCallback( void *_self ) { menufield_s *self = (menufield_s *)_self; Cvar_SetValue( self->generic.localstrings[0], atoi(self->buffer)); } static menuvec2_t PicSizeFunc (void *_self, FNT_font_t font) { menuvec2_t ret; menuitem_s *self = (menuitem_s *)_self; ret.x = ret.y = 0; // Determine if pic exists, if not return 0 size. // However, we give the benefit of the doubt if the name isn't there, and // assume it will be. if (self->generic.localstrings[0] == NULL || Draw_PicExists (self->generic.localstrings[0])) { ret.x = self->generic.localints[0]*font->size; ret.y = self->generic.localints[1]*font->size; ret.x += self->generic.localints[2]; } return ret; } // most useful if this element will always draw the same pic static void PicDrawFunc (void *_self, FNT_font_t font) { int x, y; menuitem_s *self = (menuitem_s *)_self; x = Item_GetX (*self) + self->generic.localints[2]; y = Item_GetY (*self); Draw_StretchPic (x, y, font->size*self->generic.localints[0], font->size*self->generic.localints[1], self->generic.localstrings[0]); } // for spin controls where each item is a texture path static menuvec2_t PicSpinSizeFunc (void *_self, FNT_font_t font) { menuvec2_t ret; menulist_s *self = (menulist_s *)_self; ret.x = self->generic.localints[0]*font->size; ret.y = self->generic.localints[1]*font->size; ret.x += self->generic.localints[2]; return ret; } static void PicSpinDrawFunc (void *_self, FNT_font_t font) { int x, y; menulist_s *self = (menulist_s *)_self; x = Item_GetX (*self); y = Item_GetY (*self); x += self->generic.localints[2]; if (strlen(self->itemnames[self->curvalue]) > 0) Draw_StretchPic (x, y,font->size*self->generic.localints[0], font->size*self->generic.localints[1], self->itemnames[self->curvalue]); } // name lists: list of strings terminated by 0 static const char *onoff_names[] = { "", "menu/on", 0 }; // when you want 0 to be on static const char *offon_names[] = { "menu/on", "", 0 }; static menuvec2_t IconSpinSizeFunc (void *_self, FNT_font_t font) { menuvec2_t ret; menulist_s *self = (menulist_s *)_self; ret.x = ret.y = font->size; ret.x += RCOLUMN_OFFSET; if ((self->generic.flags & QMF_RIGHT_COLUMN)) ret.x += Menu_PredictSize (self->generic.name); return ret; } static void IconSpinDrawFunc (void *_self, FNT_font_t font) { int x, y; menulist_s *self = (menulist_s *)_self; x = Item_GetX (*self)+RCOLUMN_OFFSET; y = Item_GetY (*self)+MenuText_UpperMargin (self, font->size); if ((self->generic.flags & QMF_RIGHT_COLUMN)) x += Menu_PredictSize (self->generic.name); Draw_AlphaStretchPic ( x, y, font->size, font->size, "menu/icon_border", self->generic.highlight_alpha*self->generic.highlight_alpha ); if (strlen(self->itemnames[self->curvalue]) > 0) Draw_AlphaStretchPic (x, y, font->size, font->size, self->itemnames[self->curvalue], self->generic.highlight_alpha); } #define setup_tickbox(spinctrl) \ { \ (spinctrl).generic.type = MTYPE_SPINCONTROL; \ (spinctrl).generic.itemsizecallback = IconSpinSizeFunc; \ (spinctrl).generic.itemdraw = IconSpinDrawFunc; \ (spinctrl).itemnames = onoff_names; \ (spinctrl).generic.flags |= QMF_ALLOW_WRAP; \ (spinctrl).curvalue = 0; \ } static void RadioSpinDrawFunc (void *_self, FNT_font_t font) { int x, y; menulist_s *self = (menulist_s *)_self; x = Item_GetX (*self)+RCOLUMN_OFFSET; y = Item_GetY (*self)+MenuText_UpperMargin (self, font->size); if ((self->generic.flags & QMF_RIGHT_COLUMN)) x += Menu_PredictSize (self->generic.name); Draw_AlphaStretchPic ( x, y, font->size, font->size, "menu/radio_border", self->generic.highlight_alpha*self->generic.highlight_alpha ); if (strlen(self->itemnames[self->curvalue]) > 0) Draw_AlphaStretchPic (x, y, font->size, font->size, self->itemnames[self->curvalue], self->generic.highlight_alpha); } #define setup_radiobutton(spinctrl) \ { \ (spinctrl).generic.type = MTYPE_SPINCONTROL; \ (spinctrl).generic.itemsizecallback = IconSpinSizeFunc; \ (spinctrl).generic.itemdraw = RadioSpinDrawFunc; \ (spinctrl).itemnames = onoff_names; \ (spinctrl).generic.flags |= QMF_ALLOW_WRAP; \ (spinctrl).curvalue = 0; \ } #define setup_nth_window(parent,n,window,title) \ { \ (parent).nitems = n; \ (parent).num_apply_pending = 0; \ \ (window).generic.type = MTYPE_SUBMENU; \ (window).navagable = true; \ (window).nitems = 0; \ (window).bordertitle = title; \ (window).bordertexture = "menu/m_"; \ \ Menu_AddItem (&(parent), &(window)); \ } #define setup_window(parent,window,title) setup_nth_window(parent,0,window,title) #define setup_panel(parent,panel) \ { \ (panel).generic.type = MTYPE_SUBMENU; \ (panel).generic.flags = QMF_SNUG_LEFT; \ (panel).navagable = true; \ (panel).nitems = 0; \ (panel).bordertexture = "menu/sm_"; \ Menu_AddItem (&(parent), &(panel)); \ } // if you just want to add some text to a menu and never need to refer to it // again (don't use inside a loop!) #define add_text(menu,text,itflags) \ {\ static menutxt_s it; \ it.generic.type = MTYPE_TEXT; \ it.generic.flags = (itflags); \ it.generic.name = (text); \ Menu_AddItem(&(menu), &(it)); \ } // if you just want to add an action to a menu and never need to refer to it // again (don't use inside a loop!) #define add_action(menu,itname,itcallback,itflags) \ {\ static menuaction_s it; \ it.generic.type = MTYPE_ACTION; \ it.generic.flags = (itflags)|QMF_BUTTON; \ it.generic.name = (itname); \ it.generic.callback = (itcallback); \ Menu_AddItem (&(menu), &(it)); \ } // Should be useful for most menus #define M_PushMenu_Defaults(struct) \ M_PushMenu (Screen_Draw, Default_MenuKey, &(struct)) static inline void refreshCursorButton (int button) { cursor.buttonused[button] = true; cursor.buttonclicks[button] = 0; } void refreshAllCursorButtons(void) { int i; for (i = 0; i < MENU_CURSOR_BUTTON_MAX; i++) refreshCursorButton (i); } //============================================================================= /* Screen layout routines -- responsible for tiling all the levels of menus on the screen and animating transitions between them. This uses a finite state machine to track which windows are active, "incoming" (will become active after the current animation is complete,) and "outgoing" (will no longer be active after the current animation is complete. If there are incoming or outgoing windows, user input is disabled until the transition animation is complete. Each window is a menu tree (a menuframework_s struct with submenus.) The purpose of the animation code is to determine what x-axis offset each window should be drawn at (that is, what number of pixels should be added to the x-axis of the window when it is drawn.) The x offset for each window is recalculated each frame so that the windows tile neatly alongside each other, slide across the screen, etc. The main menu is a special case, in that it will shrink into a sidebar instead of appearing partially off screen. Architecturally, this is done with a simple finite-state machine. */ // M_Interp - responsible for animating the transitions as menus are added and // removed from the screen. Actually, this function just performs an // interpolation between 0 and target, returning a number that should be used // next time for progress. you determine roughly how many pixels a menu is // going to slide, and in which direction. Your target is that number of // pixels, positive or negative depending on the direction. Call this // function repeatedly with your target, and it will return a series of pixel // offsets that can be used in your animation. int M_Interp (int progress, int target) { int increment = 0; // always positive // Determine the movement amount this frame. Make it nice and fast, // because while slow might look cool, it's also an inconvenience. if (target != progress) { static float frametime_accum = 0; // The animation speeds up as it gets further from the starting point // and slows down twice as fast as it approaches the ending point. increment = min( abs((11*target)/10-progress)/2, abs(progress) )*40; // Clamp the animation speed at a minimum so it won't freeze due to // rounding errors or take too long at either end. increment = max (increment, abs(target)/10); // Scale the animation by frame time so its speed is independent of // framerate. At very high framerates, each individual frame might be // too small a time to result in an integer amount of movement. So we // just add frames together until we do get some movement. frametime_accum += cls.frametime; increment *= frametime_accum; if (increment > 0) frametime_accum = 0; else return progress; // no movement, better luck next time. } if (target > 0) { // increasing progress += increment; progress = min (progress, target); // make sure we don't overshoot } else if (target < 0) { // decreasing progress -= increment; progress = max (progress, target); // make sure we don't overshoot } return progress; } // linear interpolation #define lerp(start,end,progress) ((start) + (double)((end)-(start))*(progress)) #define MAX_MENU_DEPTH 8 #define sidebar_width ((float)(150*viddef.width)/1024.0) // Window wrapper // (TODO: rename all mention of "layer" to "screen" or "window," haven't // decided which yet.) typedef struct { void (*draw) (menuframework_s *screen, menuvec2_t offset); const char *(*key) (menuframework_s *screen, int k); menuframework_s *screen; } menulayer_t; // An "inelastic" row of windows. They always tile side by side, and the total // width is always the sum of the contained windows. This struct is for // convenience; it's easier to animate such a group of windows as a single // unit. typedef struct { int offset; // starting x-axis pixel offset for the leftmost window int num_layers; menulayer_t layers[MAX_MENU_DEPTH]; } layergroup_t; #define layergroup_last(g) ((g).layers[(g).num_layers-1]) // add up all the widths of each window in the group static inline int layergroup_width (layergroup_t *g) { int i, ret; ret = 0; for (i = 0; i < g->num_layers; i++) ret += Menu_TrueWidth (*g->layers[i].screen); return ret; } // Add up the widths of each window in the group that cannot fit on screen, // starting with the leftmost. If the final (deepest) window is itself too // wide, it still won't be included. static inline int layergroup_excesswidth (layergroup_t *g) { int i, ret, w; ret = w = layergroup_width (g); for (i = 0; i < g->num_layers-1; i++) { if (ret < viddef.width) break; ret -= Menu_TrueWidth (*g->layers[i].screen); } return w-ret; } // Like layergroup_excesswidth, but as if the windows from the two groups were // hypothetically in the same group. static inline int layergroup_pair_excesswidth (layergroup_t *g1, layergroup_t *g2) { int i, ret, w; if (g2->num_layers == 0) return layergroup_excesswidth (g1); if (g1->num_layers == 0) return layergroup_excesswidth (g2); ret = w = layergroup_width (g1) + layergroup_width (g2); for (i = 0; i < g1->num_layers; i++) { if (ret < viddef.width) break; ret -= Menu_TrueWidth (*g1->layers[i].screen); } for (i = 0; i < g2->num_layers-1; i++) { if (ret < viddef.width) break; ret -= Menu_TrueWidth (*g2->layers[i].screen); } return w-ret; } static void layergroup_draw (layergroup_t *g) { int i; menuvec2_t offs; offs.y = 0; offs.x = g->offset; for (i = 0; i < g->num_layers; i++) { g->layers[i].draw (g->layers[i].screen, offs); offs.x += Menu_TrueWidth (*g->layers[i].screen); } } // this holds the state machine state static struct { enum { mstate_steady, // no animation, incoming & outgoing empty mstate_insert, // menus being added, possibly some outgoing menus mstate_remove // outgoing menus } state; layergroup_t active; layergroup_t outgoing; layergroup_t incoming; int animation; // current animation pixel offset } mstate; static inline void mstate_reset (void) { mstate.active.num_layers = mstate.incoming.num_layers = mstate.outgoing.num_layers = 0; mstate.state = mstate_steady; refreshCursorLink (); } #define activelayer(idx) (mstate.active.layers[(idx)]) int Cursor_GetLayer (void) { int i; menuframework_s *screen; if (cursor.menuitem == NULL) Com_Error (ERR_FATAL, "Cursor_GetLayer: unset cursor.menuitem!"); screen = Menu_GetItemTree (cursor.menuitem); for (i = 0; i < mstate.active.num_layers; i++) { if (activelayer(i).screen == screen) return i; } // We only get here if, after changing resolutions, the mouse is no longer // on screen. Com_Printf ("WARN: fake cursor.menulayer!\n"); return -1; } static int activelayer_coordidx (int xcoord) { int i; xcoord -= mstate.active.offset; if (xcoord < 0 || mstate.active.num_layers == 0) return -1; for (i = 0; i < mstate.active.num_layers; i++) { xcoord -= Menu_TrueWidth (*activelayer(i).screen); if (xcoord < 0) break; } return i; } // Figure out the starting offset for the leftmost window of the "active" // (neither incoming nor outgoing) window group. Usually just equal to the // maximum width of the sidebar, unless there are so many large windows that // they can't all fit on screen at once, in which case it may be a negative // number. static inline int Menuscreens_Animate_Active (void) { int shove_offset, ret, excess; excess = layergroup_excesswidth (&mstate.active); if (excess != 0) return -excess; ret = sidebar_width; shove_offset = viddef.width - layergroup_width (&mstate.active); if (shove_offset < ret) ret = shove_offset; return ret; } // Figure out the starting offset for the leftmost window of the active window // group, *if* the "incoming" windows were hypothetically added to the end of // the active window group. Will be used as the "target" for the incoming- // window animation. This is because when the animation is done, the incoming // windows will be added to the end of the active window group, and we want // the transition to be smooth. static inline int MenuScreens_Animate_Incoming_Target (void) { int shove_offset, ret, excess; excess = layergroup_pair_excesswidth (&mstate.active, &mstate.incoming); if (excess != 0) return -excess; ret = sidebar_width; shove_offset = viddef.width - layergroup_width (&mstate.active) - layergroup_width (&mstate.incoming); if (shove_offset < ret) ret = shove_offset; return ret; } // Figure out the starting offset for the leftmost window of the "active" // window group, *if* the outgoing windows were hypothetically added to the // end of the active window group. Will be used as the "start" for the // outgoing- window animation. This is because before the animation started, // the outgoing windows were at the end of the active window group, and we // want the transition to be smooth. static inline int MenuScreens_Animate_Outgoing_Start (void) { int shove_offset, ret, excess; excess = layergroup_pair_excesswidth (&mstate.active, &mstate.outgoing); if (excess != 0) return -excess; ret = sidebar_width; shove_offset = viddef.width - layergroup_width (&mstate.active) - layergroup_width (&mstate.outgoing); if (shove_offset < ret) ret = shove_offset; return ret; } void Menuscreens_Animate (void); // state machine state transitions void Menuscreens_Animate_Insert_To_Steady (void) { int i; for (i = 0; i < mstate.incoming.num_layers; i++) activelayer(mstate.active.num_layers++) = mstate.incoming.layers[i]; Cursor_SelectMenu (layergroup_last(mstate.active).screen); mstate.incoming.num_layers = 0; mstate.outgoing.num_layers = 0; mstate.state = mstate_steady; mstate.animation = 0; Menuscreens_Animate (); } void Menuscreens_Animate_Remove_To_Steady (void) { mstate.outgoing.num_layers = 0; mstate.state = mstate_steady; if (mstate.active.num_layers == 0) refreshCursorLink (); else Cursor_SelectMenu (layergroup_last(mstate.active).screen); mstate.animation = 0; Menuscreens_Animate (); } void M_Main_Draw (menuvec2_t offset); void CheckMainMenuMouse (void); // This is where the magic happens. (TODO: maybe separate the actual rendering // out into a different function?) void Menuscreens_Animate (void) { int shove_offset, anim_start, anim_end; menuvec2_t main_offs; main_offs.x = main_offs.y = 0; switch (mstate.state) { case mstate_steady: { if (mstate.active.num_layers != 0) { mstate.active.offset = Menuscreens_Animate_Active (); main_offs.x = mstate.active.offset-viddef.width; } M_Main_Draw (main_offs); layergroup_draw (&mstate.active); } break; case mstate_insert: { if (mstate.active.num_layers == 0) mstate.active.offset = 0; else mstate.active.offset = Menuscreens_Animate_Active (); anim_start = mstate.active.offset+viddef.width; anim_end = MenuScreens_Animate_Incoming_Target (); mstate.animation = M_Interp (mstate.animation, anim_end-anim_start); if (mstate.animation <= anim_end-anim_start) { Menuscreens_Animate_Insert_To_Steady (); return; } shove_offset = anim_start+mstate.animation; if (shove_offset < mstate.active.offset || mstate.active.num_layers == 0) mstate.active.offset = shove_offset; // If there are outgoing windows, the incoming ones "push" them back // behind the active windows and the sidebar. if (mstate.outgoing.num_layers > 0) { int outgoing_shove, outgoing_start, outgoing_end; double outgoing_fade; mstate.outgoing.offset = outgoing_start = MenuScreens_Animate_Outgoing_Start () + layergroup_width (&mstate.active); outgoing_end = Menuscreens_Animate_Active () - layergroup_width (&mstate.outgoing); outgoing_shove = shove_offset + layergroup_width (&mstate.active) - layergroup_width (&mstate.outgoing); if (outgoing_shove < mstate.outgoing.offset) mstate.outgoing.offset = outgoing_shove; layergroup_draw (&mstate.outgoing); outgoing_fade = (double)(mstate.outgoing.offset-outgoing_start)/(double)(outgoing_end-outgoing_start); // Fade out the outgoing windows Draw_Fill ( mstate.outgoing.offset, 0, layergroup_width (&mstate.outgoing), viddef.height, RGBA (0, 0, 0, sqrt(outgoing_fade)) ); // Interpolate the sidebar as well. mstate.active.offset = lerp ( MenuScreens_Animate_Outgoing_Start (), MenuScreens_Animate_Incoming_Target (), outgoing_fade ); } main_offs.x = mstate.active.offset-viddef.width; mstate.incoming.offset = shove_offset + layergroup_width (&mstate.active); M_Main_Draw (main_offs); layergroup_draw (&mstate.active); layergroup_draw (&mstate.incoming); } break; case mstate_remove: { if (mstate.active.num_layers == 0) mstate.active.offset = 0; else mstate.active.offset = Menuscreens_Animate_Active (); anim_start = MenuScreens_Animate_Outgoing_Start (); anim_end = mstate.active.offset + viddef.width; mstate.animation = M_Interp (mstate.animation, anim_end-anim_start); if (mstate.animation >= anim_end-anim_start) { Menuscreens_Animate_Remove_To_Steady (); return; } shove_offset = anim_start+mstate.animation; if (shove_offset < mstate.active.offset || mstate.active.num_layers == 0) mstate.active.offset = shove_offset; main_offs.x = mstate.active.offset-viddef.width; mstate.outgoing.offset = shove_offset + layergroup_width (&mstate.active); M_Main_Draw (main_offs); layergroup_draw (&mstate.active); layergroup_draw (&mstate.outgoing); } break; } } // These functions (Push, Force Off, and Pop) are used by the outside world to // control the state machine. void M_PushMenu ( void (*draw) (menuframework_s *screen, menuvec2_t offset), const char *(*key) (menuframework_s *screen, int k), menuframework_s *screen) { int i, insertion_point; qboolean found = false; if (Cvar_VariableValue ("maxclients") == 1 && Com_ServerState ()) Cvar_Set ("paused", "1"); screen->navagable = true; Menu_AutoArrange (screen); for (i = 0; i < mstate.active.num_layers; i++) { if (activelayer(i).screen == screen) { found = true; break; } } if (found) { insertion_point = i; mstate.state = mstate_remove; } else { mstate.incoming.num_layers++; layergroup_last(mstate.incoming).draw = draw; layergroup_last(mstate.incoming).key = key; layergroup_last(mstate.incoming).screen = screen; mstate.state = mstate_insert; insertion_point = cursor.menulayer; } for (i = insertion_point+1; i < mstate.active.num_layers; i++) mstate.outgoing.layers[mstate.outgoing.num_layers++] = activelayer(i); mstate.active.num_layers = insertion_point+1; cls.key_dest = key_menu; m_entersound = true; } void M_ForceMenuOff (void) { cls.key_dest = key_game; Key_ClearStates (); Cvar_Set ("paused", "0"); mstate_reset (); //-JD kill the music when leaving the menu of course S_StopAllSounds(); background_music = Cvar_Get ("background_music", "1", CVAR_ARCHIVE); S_StartMapMusic(); } void M_PopMenu (void) { S_StartLocalSound( menu_out_sound ); if (mstate.active.num_layers == 0) { M_ForceMenuOff (); return; } mstate.outgoing.layers[mstate.outgoing.num_layers++] = activelayer(--mstate.active.num_layers); mstate.state = mstate_remove; } const char *Default_MenuKey (menuframework_s *m, int key) { const char *sound = NULL; // this should work no matter what if (key == K_ESCAPE) { M_PopMenu(); return menu_out_sound; } // the rest of these won't work unless there's a selected menu item if (cursor.menuitem == NULL) return NULL; // offer the keypress to the field key parser, see if it wants it if (Field_Key (key)) { Menu_ActivateItem (cursor.menuitem); return NULL; } switch ( key ) { case K_MWHEELUP: case K_KP_UPARROW: case K_UPARROW: Menu_AdvanceCursor (-1, false); break; case K_TAB: Menu_AdvanceCursor (1, true); break; case K_MWHEELDOWN: case K_KP_DOWNARROW: case K_DOWNARROW: Menu_AdvanceCursor (1, false); break; case K_KP_LEFTARROW: case K_LEFTARROW: Menu_SlideItem (-1); sound = menu_move_sound; break; case K_KP_RIGHTARROW: case K_RIGHTARROW: Menu_SlideItem (1); sound = menu_move_sound; break; case K_KP_ENTER: case K_ENTER: Menu_ActivateItem (cursor.menuitem); sound = menu_move_sound; break; } return sound; } /* ======================================================================= MAIN MENU ======================================================================= */ char *main_names[] = { "m_main_game", "m_main_join", "m_main_host", "m_main_options", "m_main_quit", "m_main_credits", }; #define MAIN_ITEMS static_array_size(main_names) void (*main_open_funcs[MAIN_ITEMS])(void) = { &M_Menu_Game_f, &M_Menu_JoinServer_f, &M_Menu_StartServer_f, &M_Menu_Options_f, &M_Menu_Quit_f, &M_Menu_Credits_f }; void findMenuCoords (int *xoffset, int *ystart, int *totalheight, int *widest) { int w, h, i; float scale; scale = (float)(viddef.height)/600; *totalheight = 0; *widest = -1; for ( i = 0; i < MAIN_ITEMS; i++ ) { Draw_GetPicSize( &w, &h, main_names[i] ); if ( w*scale > *widest ) *widest = w*scale; *totalheight += ( h*scale + 24*scale); } *ystart = ( viddef.height / 2 - 20*scale ); *xoffset = ( viddef.width - *widest + 350*scale) / 2; } void M_Main_Draw (menuvec2_t offset) { int i; int ystart, xstart, xend; int xoffset; int widest = -1; int totalheight = 0; char litname[80]; float scale, hscale, hscaleoffs; float widscale; int w, h; char montagepicname[16]; char backgroundpic[16]; char *version_warning; static float mainalpha; static int montagepic = 1; scale = ((float)(viddef.height))/600.0; widscale = ((float)(viddef.width))/1024.0; findMenuCoords(&xoffset, &ystart, &totalheight, &widest); ystart = ( viddef.height / 2 - 20*scale ) + offset.y; xoffset = ( viddef.width - widest - 35*widscale) / 2 + offset.x; // When animating a transition away from the main menu, the background // slides away at double speed, disappearing and leaving just the menu // items themselves. Hence some things use offset.x*1.25. #ifdef TACTICAL Draw_StretchPic(offset.x*1.25, offset.y, viddef.width, viddef.height, "m_main_tactical"); #else Draw_StretchPic(offset.x*1.25, offset.y, viddef.width, viddef.height, "m_main"); #endif //draw the montage pics mainalpha += cls.frametime; //fade image in if(mainalpha > 4) { //switch pics at this point mainalpha = 0.1; montagepic++; if(montagepic > 5) { montagepic = 1; } } sprintf(backgroundpic, "m_main_mont%i", (montagepic==1)?5:montagepic-1); sprintf(montagepicname, "m_main_mont%i", montagepic); Draw_StretchPic (offset.x*1.25, offset.y, viddef.width, viddef.height, backgroundpic); Draw_AlphaStretchPic (offset.x*1.25, offset.y, viddef.width, viddef.height, montagepicname, mainalpha); /* check for more recent program version */ version_warning = VersionUpdateNotice(); if ( version_warning != NULL ) { extern const float light_color[4]; Menu_DrawString ( offset.x, offset.y + 5*scale, version_warning, FNT_CMODE_QUAKE_SRS, FNT_ALIGN_LEFT, light_color ); } //draw the main menu buttons for ( i = 0; i < MAIN_ITEMS; i++ ) { strcpy( litname, main_names[i] ); if (i == m_main_cursor && cursor.menulayer == -1) strcat( litname, "_sel"); Draw_GetPicSize( &w, &h, litname ); xstart = xoffset + 100*widscale + (20*i*widscale); if (xstart < 0) xstart += min(-xstart, (8-i)*20*widscale); xend = xstart+w*widscale; hscale = 1; if (xstart < 0) { if (xend < 150*widscale) xend = min (viddef.width+offset.x, 150*widscale); xstart = 0; if (xend < 50*widscale) return; } hscale = (float)(xend-xstart)/(float)(w*widscale); hscaleoffs = (float)h*scale-(float)h*hscale*scale; Draw_StretchPic( xstart, (int)(ystart + i * 32.5*scale + 13*scale + hscaleoffs), xend-xstart, h*hscale*scale, litname ); } } void CheckMainMenuMouse (void) { int ystart; int xoffset; int widest; int totalheight; int i, oldhover; float scale; static int MainMenuMouseHover; scale = (float)(viddef.height)/600; oldhover = MainMenuMouseHover; MainMenuMouseHover = 0; findMenuCoords(&xoffset, &ystart, &totalheight, &widest); i = (cursor.y - ystart - 24*scale)/(32*scale); if (i < 0 || i >= MAIN_ITEMS) { if (cursor.buttonclicks[MOUSEBUTTON1]==1) { cursor.buttonused[MOUSEBUTTON1] = true; cursor.buttonclicks[MOUSEBUTTON1] = 0; } return; } if (cursor.mouseaction) { refreshCursorLink (); m_main_cursor = i; cursor.mouseaction = false; } MainMenuMouseHover = 1 + i; if (oldhover == MainMenuMouseHover && MainMenuMouseHover-1 == m_main_cursor && !cursor.buttonused[MOUSEBUTTON1] && cursor.buttonclicks[MOUSEBUTTON1]==1) { main_open_funcs[m_main_cursor](); S_StartLocalSound( menu_move_sound ); cursor.buttonused[MOUSEBUTTON1] = true; cursor.buttonclicks[MOUSEBUTTON1] = 0; } } const char *M_Main_Key (int key) { switch (key) { case K_ESCAPE: m_entersound = true; M_PopMenu (); break; case K_KP_DOWNARROW: case K_DOWNARROW: case K_TAB: case K_MWHEELDOWN: if (++m_main_cursor >= MAIN_ITEMS) m_main_cursor = 0; break; case K_KP_UPARROW: case K_UPARROW: case K_MWHEELUP: if (--m_main_cursor < 0) m_main_cursor = MAIN_ITEMS - 1; break; case K_KP_ENTER: case K_ENTER: m_entersound = true; main_open_funcs[m_main_cursor](); break; } return NULL; } void M_Menu_Main_f (void) { S_StartMenuMusic(); cls.key_dest = key_menu; mstate_reset (); } /* ======================================================================= OPTIONS MENUS - INPUT MENU ======================================================================= */ char *bindnames[][2] = { {"+attack", "attack"}, {"+attack2", "alt attack"}, {"weapnext", "next weapon"}, {"weapprev", "previous weapon"}, {"+forward", "walk forward"}, {"+back", "backpedal"}, {"+speed", "run"}, {"+moveleft", "step left"}, {"+moveright", "step right"}, {"+moveup", "up / jump"}, {"+movedown", "down / crouch"}, {"inven", "inventory"}, {"invuse", "use item"}, {"invdrop", "drop item"}, {"invprev", "prev item"}, {"invnext", "next item"}, {"use Alien Disruptor", "alien disruptor" }, {"use Pulse Rifle", "chaingun" }, {"use Flame Thrower", "flame thrower" }, {"use Rocket Launcher", "rocket launcher" }, {"use Alien Smartgun", "alien smartgun" }, {"use Disruptor", "alien beamgun" }, {"use Alien Vaporizer", "alien vaporizer" }, {"use Violator", "the violator" }, {"score", "show scores" }, {"use grapple", "grapple hook"}, {"use sproing", "sproing"}, {"use haste", "haste"}, {"use invisibility", "invisibility"}, {"vtaunt 1", "voice taunt #1"}, {"vtaunt 2", "voice taunt #2"}, {"vtaunt 3", "voice taunt #3"}, {"vtaunt 4", "voice taunt #4"}, {"vtaunt 5", "voice taunt #5"}, {"vtaunt 0", "voice taunt auto"} }; #define num_bindable_actions static_array_size(bindnames) int keys_cursor; static int bind_grab; static menuframework_s s_keys_screen; static menuframework_s s_keys_menu; static menuaction_s s_keys_actions[num_bindable_actions]; static void M_UnbindCommand (const char *command) { int j; int l; char *b; l = strlen(command); for (j=0 ; j<256 ; j++) { b = keybindings[j]; if (!b) continue; if (!strncmp (b, command, l) ) Key_SetBinding (j, ""); } } static void M_FindKeysForCommand (const char *command, int *twokeys) { int count; int j; int l; char *b; twokeys[0] = twokeys[1] = -1; l = strlen(command); count = 0; for (j=0 ; j<256 ; j++) { b = keybindings[j]; if (!b) continue; if (!strncmp (b, command, l) ) { twokeys[count] = j; count++; if (count == 2) break; } } } static void M_KeyBindingDisplayStr (const char *command, size_t bufsize, char *buf) { int keys[2]; M_FindKeysForCommand (command, keys); if (keys[0] == -1) { Com_sprintf (buf, bufsize, "???"); } else { // Key_KeynumToString reuses the same buffer for output sometimes int len; Com_sprintf (buf, bufsize, "%s", Key_KeynumToString (keys[0])); len = strlen(buf); if (keys[1] != -1) Com_sprintf (buf+len, bufsize-len, " or %s", Key_KeynumToString (keys[1])); } } static menuvec2_t KeySizeFunc (void *_self, FNT_font_t font) { menuvec2_t ret; char buf[1024]; menuaction_s *self = ( menuaction_s * ) _self; M_KeyBindingDisplayStr (self->generic.localstrings[0], sizeof(buf), buf); ret.y = font->height; ret.x = RCOLUMN_OFFSET + Menu_PredictSize (buf); return ret; } static void DrawKeyBindingFunc( void *_self, FNT_font_t font ) { extern const float light_color[4]; char buf[1024]; menuaction_s *self = ( menuaction_s * ) _self; M_KeyBindingDisplayStr (self->generic.localstrings[0], sizeof(buf), buf); Menu_DrawString ( Item_GetX (*self) + RCOLUMN_OFFSET, Item_GetY (*self) + MenuText_UpperMargin (self, font->size), buf, FNT_CMODE_QUAKE_SRS, FNT_ALIGN_LEFT, light_color ); } static void KeyBindingFunc( void *_self ) { menuaction_s *self = ( menuaction_s * ) _self; int keys[2]; M_FindKeysForCommand( self->generic.localstrings[0], keys ); if (keys[1] != -1) M_UnbindCommand( self->generic.localstrings[0]); bind_grab = true; Menu_SetStatusBar( &s_keys_menu, "press a key or button for this action" ); } static void Keys_MenuInit( void ) { int i = 0; setup_window (s_keys_screen, s_keys_menu, "CUSTOMIZE CONTROLS"); for (i = 0; i < num_bindable_actions; i++) { s_keys_actions[i].generic.type = MTYPE_ACTION; s_keys_actions[i].generic.callback = KeyBindingFunc; s_keys_actions[i].generic.itemdraw = DrawKeyBindingFunc; s_keys_actions[i].generic.localstrings[0] = bindnames[i][0]; s_keys_actions[i].generic.name = bindnames[i][1]; s_keys_actions[i].generic.itemsizecallback = KeySizeFunc; Menu_AddItem( &s_keys_menu, &s_keys_actions[i]); } Menu_SetStatusBar( &s_keys_menu, "enter to change, backspace to clear" ); s_keys_menu.maxlines = 30; } static const char *Keys_MenuKey (menuframework_s *screen, int key) { menuaction_s *item = ( menuaction_s * ) cursor.menuitem; if ( bind_grab && !(cursor.buttonused[MOUSEBUTTON1]&&key==K_MOUSE1)) { if ( key != K_ESCAPE && key != '`' ) { char cmd[1024]; Com_sprintf (cmd, sizeof(cmd), "bind \"%s\" \"%s\"\n", Key_KeynumToString(key), item->generic.localstrings[0]); Cbuf_InsertText (cmd); } //dont let selecting with mouse buttons screw everything up refreshAllCursorButtons(); if (key==K_MOUSE1) cursor.buttonclicks[MOUSEBUTTON1] = -1; Menu_SetStatusBar (&s_keys_menu, "enter to change, backspace to clear"); bind_grab = false; Menu_AutoArrange (screen); return menu_out_sound; } switch ( key ) { case K_BACKSPACE: // delete bindings case K_DEL: // delete bindings case K_KP_DEL: M_UnbindCommand( item->generic.localstrings[0] ); return menu_out_sound; default: return Default_MenuKey (screen, key); } } void M_Menu_Keys_f (void) { Keys_MenuInit(); M_PushMenu (Screen_Draw, Keys_MenuKey, &s_keys_screen); } /* ======================================================================= OPTIONS MENUS - GENERIC CODE FOR OPTIONS WIDGETS ======================================================================= */ typedef struct { int maxchars; int min_value, max_value; // for numerical fields, otherwise ignore } fieldsize_t; typedef struct { int slider_min, slider_max; float cvar_min, cvar_max; } sliderlimit_t; typedef struct { enum { option_slider, option_textcvarslider, option_spincontrol, option_textcvarspincontrol, option_textcvarpicspincontrol, option_hudspincontrol, option_minimapspincontrol, option_numberfield } type; const char *cvarname; const char *displayname; const char *tooltip; // extra data - set the appropriate one const char **names; const sliderlimit_t *limits; const fieldsize_t *fieldsize; #define setnames(x) (const char **)(x), NULL, NULL #define setlimits(x) NULL, &(x), NULL #define setfieldsize(x) NULL, NULL, &(x) // flags - optional, defaults to no flags int flags; } option_name_t; static void SpinOptionFunc (void *_self) { menulist_s *self; const char *cvarname; self = (menulist_s *)_self; cvarname = self->generic.localstrings[0]; Cvar_SetValue( cvarname, self->curvalue ); } static menuvec2_t FontSelectorSizeFunc (void *_self, FNT_font_t unused) { menuvec2_t ret; menulist_s *self; FNT_font_t font; self = (menulist_s *)_self; font = FNT_AutoGet (*(FNT_auto_t *)self->generic.localptrs[0]); ret.y = font->height; ret.x = RCOLUMN_OFFSET + FNT_PredictSize (font, self->itemnames[self->curvalue], false); return ret; } static void FontSelectorDrawFunc (void *_self, FNT_font_t unused) { extern const float light_color[4]; menulist_s *self; FNT_font_t font; self = (menulist_s *)_self; font = FNT_AutoGet (*(FNT_auto_t *)self->generic.localptrs[0]); menu_box.x = Item_GetX (*self)+RCOLUMN_OFFSET; menu_box.y = Item_GetY (*self) + MenuText_UpperMargin (self, font->size); menu_box.height = menu_box.width = 0; FNT_BoundedPrint (font, self->itemnames[self->curvalue], FNT_CMODE_QUAKE_SRS, FNT_ALIGN_LEFT, &menu_box, light_color); } static void TextVarSpinOptionFunc (void *_self) { menulist_s *self; const char *cvarname; char *cvarval; self = (menulist_s *)_self; cvarname = self->generic.localstrings[0]; cvarval = strchr(self->itemnames[self->curvalue], '\0')+1; Cvar_Set( cvarname, cvarval); } static void UpdateDopplerEffectFunc( void *self ) { TextVarSpinOptionFunc (self); R_EndFrame(); // buffer swap needed to show text box S_UpdateDopplerFactor(); } static void SliderOptionFunc (void *_self) { menuslider_s *self; const char *cvarname; float cvarval, sliderval, valscale; const sliderlimit_t *limit; self = (menulist_s *)_self; cvarname = self->generic.localstrings[0]; limit = (const sliderlimit_t *) self->generic.localptrs[0]; sliderval = self->curvalue; valscale = (limit->cvar_max-limit->cvar_min)/ (float)(limit->slider_max-limit->slider_min); cvarval = limit->cvar_min + valscale*(sliderval-limit->slider_min); Cvar_SetValue (cvarname, cvarval); } static void NumberFieldOptionFunc (void *_self) { menufield_s *self; int num, clamped_num; const fieldsize_t *fieldsize; const char *cvarname; self = (menufield_s *)_self; cvarname = self->generic.localstrings[0]; fieldsize = (const fieldsize_t *)self->generic.localptrs[0]; num = atoi (self->buffer); clamped_num = clamp (num, fieldsize->min_value, fieldsize->max_value); if (num != clamped_num) { Com_sprintf (self->buffer, sizeof(self->buffer), "%d", clamped_num); self->cursor = strlen (self->buffer); } Cvar_SetValue (cvarname, clamped_num); } // HACKS for specific menus extern cvar_t *crosshair; #define MAX_CROSSHAIRS 256 char *crosshair_names[MAX_CROSSHAIRS]; int numcrosshairs = 0; static void HudFunc( void *item ); static void MinimapFunc( void *item ); static void UpdateBGMusicFunc( void *_self ); static float ClampCvar( float min, float max, float value ); extern cvar_t *r_minimap; extern cvar_t *r_minimap_style; #define MAX_FONTS 32 char *font_names[MAX_FONTS]; int numfonts = 0; // name and value lists: for spin-controls where the cvar value isn't simply // the integer index of whatever text is displaying in the control. We use // NULL terminators to separate display names and variable values, so that way // we can use the existing menu code. static const char *doppler_effect_items[] = { "off\0000", "normal\0001", "high\0003", "very high\0005", 0 }; int numhuds = 0; extern cvar_t *cl_hudimage1; extern cvar_t *cl_hudimage2; #define MAX_HUDS 256 char *hud_names[MAX_HUDS]; // initialize a menu item as an "option." void Option_Setup (menumultival_s *item, option_name_t *optionname) { int val, maxval; char *vartextval; int i; float cvarval, sliderval, valscale; const sliderlimit_t *limit; const fieldsize_t *fieldsize; // Do not re-allocate font/crosshair/HUD names each time the menu is // displayed - BlackIce if ( numfonts == 0 ) SetFontNames (font_names); if ( numhuds == 0 ) SetHudNames (hud_names); if ( numcrosshairs == 0 ) SetCrosshairNames (crosshair_names); // initialize item item->generic.name = optionname->displayname; item->generic.tooltip = optionname->tooltip; item->generic.localstrings[0] = optionname->cvarname; item->generic.flags = optionname->flags; item->generic.apply_pending = false; switch (optionname->type) { case option_spincontrol: item->generic.type = MTYPE_SPINCONTROL; item->itemnames = optionname->names; if (!strcmp (optionname->cvarname, "background_music")) // FIXME HACK item->generic.callback = UpdateBGMusicFunc; else item->generic.callback = SpinOptionFunc; if (item->itemnames == onoff_names) setup_tickbox (*item); if (item->itemnames == offon_names) { setup_tickbox (*item); // because setup_tickbox overwrites itemnames item->itemnames = offon_names; } break; case option_textcvarslider: item->generic.type = MTYPE_SLIDER; // TODO: use the name part in a tooltip or something item->itemnames = optionname->names; item->minvalue = 0; for (item->maxvalue = 0; item->itemnames[item->maxvalue+1]; item->maxvalue++) continue; if (item->itemnames == doppler_effect_items) // FIXME HACK item->generic.callback = UpdateDopplerEffectFunc; else item->generic.callback = TextVarSpinOptionFunc; break; case option_textcvarspincontrol: case option_textcvarpicspincontrol: item->generic.type = MTYPE_SPINCONTROL; item->itemnames = optionname->names; item->generic.callback = TextVarSpinOptionFunc; // FIXME HACK if (item->itemnames == font_names) { item->generic.itemsizecallback = FontSelectorSizeFunc; item->generic.itemdraw = FontSelectorDrawFunc; if (!strcmp (optionname->cvarname, "fnt_game")) item->generic.localptrs[0] = &CL_gameFont; else if (!strcmp (optionname->cvarname, "fnt_console")) item->generic.localptrs[0] = &CL_consoleFont; else if (!strcmp (optionname->cvarname, "fnt_menu")) item->generic.localptrs[0] = &CL_menuFont; } else if (optionname->type == option_textcvarpicspincontrol) { item->generic.itemsizecallback = PicSpinSizeFunc; item->generic.itemdraw = PicSpinDrawFunc; VectorSet (item->generic.localints, 5, 5, RCOLUMN_OFFSET); } break; case option_hudspincontrol: item->generic.type = MTYPE_SPINCONTROL; item->itemnames = optionname->names; item->generic.callback = HudFunc; break; case option_minimapspincontrol: item->generic.type = MTYPE_SPINCONTROL; item->itemnames = optionname->names; item->generic.callback = MinimapFunc; break; case option_slider: limit = optionname->limits; item->generic.type = MTYPE_SLIDER; item->minvalue = limit->slider_min; item->maxvalue = limit->slider_max; item->generic.callback = SliderOptionFunc; item->generic.localptrs[0] = limit; break; case option_numberfield: fieldsize = optionname->fieldsize; item->generic.type = MTYPE_FIELD; item->generic.flags |= QMF_NUMBERSONLY; item->generic.visible_length = fieldsize->maxchars; item->cursor = 0; memset (item->buffer, 0, sizeof(item->buffer)); item->generic.callback = NumberFieldOptionFunc; item->generic.localptrs[0] = fieldsize; break; } // initialize value switch (optionname->type) { case option_spincontrol: for (maxval = 0; item->itemnames[maxval]; maxval++) continue; maxval--; val = ClampCvar (0, maxval, Cvar_VariableValue (optionname->cvarname)); item->curvalue = val; Cvar_SetValue (optionname->cvarname, val); break; case option_hudspincontrol: case option_textcvarspincontrol: case option_textcvarpicspincontrol: case option_textcvarslider: item->curvalue = 0; vartextval = Cvar_VariableString (optionname->cvarname); for (i=0; item->itemnames[i]; i++) { char *corresponding_cvar_val = strchr(item->itemnames[i], '\0')+1; if (!Q_strcasecmp(vartextval, corresponding_cvar_val)) { item->curvalue = i; break; } } break; case option_minimapspincontrol: Cvar_SetValue("r_minimap_style", ClampCvar(0, 1, r_minimap_style->value)); Cvar_SetValue("r_minimap", ClampCvar(0, 1, r_minimap->value)); if(r_minimap_style->value == 0) item->curvalue = 2; else item->curvalue = r_minimap->value; break; case option_slider: limit = optionname->limits; cvarval = ClampCvar ( limit->cvar_min, limit->cvar_max, Cvar_VariableValue (optionname->cvarname)); Cvar_SetValue (optionname->cvarname, cvarval); valscale = (float)(limit->slider_max-limit->slider_min)/ (limit->cvar_max-limit->cvar_min); sliderval = limit->slider_min + valscale*(cvarval-limit->cvar_min); item->curvalue = sliderval; break; case option_numberfield: fieldsize = optionname->fieldsize; Com_sprintf (item->buffer, sizeof(item->buffer), "%d", (int)Cvar_VariableValue (optionname->cvarname)); item->cursor = strlen (item->buffer); break; } } // all "options" menus have roughly the same layout, so we can automate some // of the grunt work typedef struct { menuframework_s screen; menuframework_s window; menuframework_s panel; menumultival_s widgets[]; } options_menu_t; static options_menu_t *last_options_menu; static option_name_t *last_options_menu_namelist; static int last_options_menu_nitems; // Use this anywhere to reinitialize whatever options menu is currently // showing so it reflects current cvar values. void Options_Menu_Reinitialize (void) { int i; for (i = 0; i < last_options_menu_nitems; i++) Option_Setup (&last_options_menu->widgets[i], &last_options_menu_namelist[i]); } #define options_menu(menu,title) \ static struct \ { \ menuframework_s screen; \ menuframework_s window; \ menuframework_s panel; \ menumultival_s widgets[static_array_size(menu ## _option_names)]; \ } menu; \ \ setup_window (menu.screen, menu.window, title); \ setup_panel (menu.window, menu.panel); \ \ { \ \ int i; \ for (i = 0; i < static_array_size(menu ## _option_names); i++) \ { \ Option_Setup (&menu.widgets[i], &(menu ## _option_names)[i]); \ Menu_AddItem( &menu.panel, &menu.widgets[i]); \ } \ } \ last_options_menu_nitems = static_array_size(menu ## _option_names); \ last_options_menu_namelist = &(menu ## _option_names)[0]; \ last_options_menu = (options_menu_t*)&menu; /* ======================================================================= OPTIONS MENUS - DISPLAY OPTIONS MENU ======================================================================= */ static void MinimapFunc( void *item ) { menulist_s *self = (menulist_s *)item; Cvar_SetValue("r_minimap", self->curvalue != 0); if(r_minimap->integer) { Cvar_SetValue("r_minimap_style", self->curvalue % 2); } } static float ClampCvar( float min, float max, float value ) { if ( value < min ) return min; if ( value > max ) return max; return value; } qboolean fontInList (char *check, int num, char **list) { int i; for (i=0;ii ;j--) list[j] = list[j-1]; list[i] = tmp; return; } } list[len] = tmp; } static void AddFontNames( char * path , int * nfontnames , char ** list ) { char ** fontfiles; int nfonts = 0; int i; fontfiles = FS_ListFilesInFS( path , &nfonts, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM ); for (i=0;icurvalue == 0) { //none sprintf(hud1, "none"); sprintf(hud2, "none"); } if(self->curvalue == 1) { sprintf(hud1, "pics/i_health.tga"); sprintf(hud2, "pics/i_score.tga"); } if(self->curvalue > 1) { sprintf(hud1, "pics/huds/%s1", hud_names[self->curvalue]); sprintf(hud2, "pics/huds/%s2", hud_names[self->curvalue]); } //set the cvars, both of them Cvar_Set( "cl_hudimage1", hud1 ); Cvar_Set( "cl_hudimage2", hud2 ); } void SetHudNames (char **list) { char *curHud, *curHudFile; char *p; int nhuds = 0, nhudnames; char **hudfiles; int i; memset( list, 0, sizeof( char * ) * MAX_HUDS ); nhudnames = 2; list[0] = str_combine("none", "none"); list[1] = str_combine("default", "pics/i_health.tga"); //the default hud hudfiles = FS_ListFilesInFS( "pics/huds/*1.tga", &nhuds, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM ); for (i=0;icurvalue ); if ( background_music->value > 0.99f && background_music_vol->value >= 0.1f ) { S_StartMenuMusic(); } } // name lists: list of strings terminated by 0 static const char *minimap_names[] = { "off", "static", "rotating", 0 }; static const char *playerid_names[] = { "off", "centered", "over player", 0 }; static const char *color_names[] = { "^2green", "^4blue", "^1red", "^3yellow", "^6purple", 0 }; static const char *handedness_names[] = { "right", "left", "center", 0 }; sliderlimit_t mousespeed_limits = { 0, 110, 0.0f, 11.0f }; fieldsize_t fov_limits = { 3, 10, 130 }; option_name_t disp_option_names[] = { { option_spincontrol, "cl_precachecustom", "precache custom models", "Enabling this can result in slow map loading times", setnames (onoff_names) }, { option_spincontrol, "cl_showplayernames", "identify target", NULL, setnames (playerid_names) }, { option_spincontrol, "r_ragdolls", "ragdolls", NULL, setnames (onoff_names) }, { option_spincontrol, "cl_noblood", "no blood", NULL, setnames (onoff_names) }, { option_spincontrol, "cl_noskins", "force martian models", NULL, setnames (onoff_names) }, { option_textcvarspincontrol, "fnt_console", "console font", "select the font used to display the console", setnames (font_names) }, { option_textcvarspincontrol, "fnt_game", "game font", "select the font used in the game", setnames (font_names) }, { option_textcvarspincontrol, "fnt_menu", "menu font", "select the font used in the menu", setnames (font_names) }, { option_textcvarpicspincontrol, "crosshair", "crosshair", "select your crosshair", setnames (crosshair_names) }, { option_hudspincontrol, "cl_hudimage1", //multiple cvars controlled-- see HudFunc "HUD", "select your HUD style", setnames (hud_names) }, { option_spincontrol, "cl_disbeamclr", "disruptor color", "select disruptor beam color", setnames (color_names) }, { option_minimapspincontrol, NULL, //multiple cvars controlled-- see MinimapFunc "minimap", "select your minimap style", setnames (minimap_names) }, { option_spincontrol, "in_joystick", "use joystick", NULL, setnames (onoff_names) }, { option_spincontrol, "cl_drawfps", "display framerate", NULL, setnames (onoff_names) }, { option_spincontrol, "cl_drawtimer", "display timer", NULL, setnames (onoff_names) }, { option_spincontrol, "cl_simpleitems", "simple items", "Draw floating icons instead of 3D models for ingame items", setnames (onoff_names) }, { option_spincontrol, "hand", "weapon handedness", "NOTE: This does effect aim!", setnames (handedness_names) }, { option_numberfield, "fov", "FOV", "Horizontal field of view in degrees", setfieldsize (fov_limits) } }; #define num_options static_array_size(disp_option_names) menumultival_s options[num_options]; static void OptionsResetDefaultsFunc( void *unused ) { Cbuf_AddText ("exec default.cfg\n"); Cbuf_Execute(); Options_Menu_Reinitialize (); CL_Snd_Restart_f(); S_StartMenuMusic(); } static void OptionsResetSavedFunc( void *unused ) { Cbuf_AddText ("exec config.cfg\n"); Cbuf_Execute(); Options_Menu_Reinitialize (); CL_Snd_Restart_f(); S_StartMenuMusic(); } static void M_Menu_Display_f (void) { options_menu (disp, "DISPLAY"); M_PushMenu_Defaults (disp.screen); } /* ======================================================================= OPTIONS MENUS - VIDEO OPTIONS MENU ======================================================================= */ sliderlimit_t brightnesscontrast_limits = { 1, 20, 0.1f, 2.0f }; // FIXME: is this really supposed to be separate? sliderlimit_t bloom_limits = { 0, 20, 0.0f, 2.0f }; sliderlimit_t modulate_limits = { 1, 5, 1.0f, 5.0f }; fieldsize_t resolution_width_limits = { 4, 640, 2048 }; fieldsize_t resolution_height_limits = { 4, 480, 1536 }; static const char *resolution_items[] = { "[640 480 ]\0000", "[800 600 ]\0001", "[960 720 ]\0002", "[1024 768 ]\0003", "[1152 864 ]\0004", "[1280 960 ]\0005", "[1280 1024]\0006", "[1360 768 ]\0007", "[1366 768 ]\0008", "[1600 1200]\0009", "[1680 1050]\00010", "[1920 1080]\00011", "[2048 1536]\00012", "[custom ]\000-1", 0 }; static const char *overbright_items[] = { "low\0001", "medium\0002", "high\0003", 0 }; static const char *texquality_items[] = { "very low\0003", "low\0002", "medium\0001", "high\0000", 0 }; option_name_t video_option_names[] = { { option_textcvarspincontrol, "gl_mode", "video mode", NULL, setnames (resolution_items), QMF_ACTION_WAIT }, { option_numberfield, "vid_width", "custom width", "set custom horizontal screen resolution", setfieldsize (resolution_width_limits), QMF_ACTION_WAIT }, { option_numberfield, "vid_height", "custom height", "set custom vertical screen resolution", setfieldsize (resolution_height_limits), QMF_ACTION_WAIT }, { option_slider, "vid_gamma", "texture brightness", NULL, setlimits (brightnesscontrast_limits) }, { option_slider, "vid_contrast", "texture contrast", NULL, setlimits (brightnesscontrast_limits) }, { option_slider, "gl_modulate", "lightmap brightness", NULL, setlimits (modulate_limits) }, { option_spincontrol, "vid_fullscreen", "fullscreen", NULL, setnames (onoff_names), QMF_ACTION_WAIT }, { option_spincontrol, "r_bloom", "light bloom", NULL, setnames (onoff_names) }, { option_slider, "r_bloom_intensity", "bloom intensity", NULL, setlimits (bloom_limits) }, { option_textcvarslider, "r_overbrightbits", "overbright bits", NULL, setnames (overbright_items) }, { option_textcvarslider, "gl_picmip", "texture quality", NULL, setnames (texquality_items) }, { option_spincontrol, "gl_glsl_shaders", "GLSL shaders", NULL, setnames (onoff_names) }, { option_spincontrol, "cl_paindist", "pain distortion fx", "GLSL must be enabled for this to take effect", setnames (onoff_names) }, { option_spincontrol, "cl_explosiondist", "explosion distortion fx", "GLSL must be enabled for this to take effect", setnames (onoff_names) }, { option_spincontrol, "cl_raindist", "rain droplet fx", "GLSL must be enabled for this to take effect", setnames (onoff_names) }, { option_spincontrol, "gl_finish", "triple buffering", "improved framerates, but displayed frame is more out of date", setnames (offon_names), QMF_ACTION_WAIT }, { option_spincontrol, "gl_swapinterval", "vertical sync", "should be on unless framerates dip below your monitor's refresh rate", setnames (onoff_names), QMF_ACTION_WAIT } }; const char *graphical_preset_names[][3] = { // display name, cfg name, tooltip { "High Compatibility", "compatibility", "use when all other modes fail or run slowly" }, { "High Performance", "maxperformance", "fast rendering, many effects disabled" }, { "Performance", "maxperformance", "GLSL per-pixel lighting and postprocess" }, { "Quality", "quality", "GLSL per-pixel effects on all surfaces" }, { "High Quality", "maxquality", "GLSL, shadows, light shafts from sun" } }; #define num_graphical_presets static_array_size(graphical_preset_names) static menuaction_s s_graphical_presets[num_graphical_presets]; static menuframework_s *Video_MenuInit (void); static void PresetCallback (void *_self) { char cmd[MAX_STRING_CHARS]; menuaction_s *self = (menuaction_s *)_self; Com_sprintf (cmd, sizeof(cmd), "exec graphical_presets/%s.cfg", self->generic.localstrings[0]); Cmd_ExecuteString (cmd); Cbuf_Execute (); Video_MenuInit (); //TODO: alert user of the need to apply here } void VidApplyFunc (void *self) { #if defined UNIX_VARIANT extern qboolean vid_restart; #endif extern cvar_t *vid_ref; Menu_ApplyMenu (Menu_GetItemTree ((menuitem_s *)self)); RS_FreeUnmarked(); Cvar_SetValue("scriptsloaded", 0); //scripts get flushed vid_ref->modified = true; #if defined UNIX_VARIANT vid_restart = true; #endif M_ForceMenuOff(); } static menuframework_s *Video_MenuInit (void) { int i; options_menu (video, "VIDEO OPTIONS"); add_text (video.window, NULL, 0); // spacer for (i = 0; i < num_graphical_presets; i++) { s_graphical_presets[i].generic.type = MTYPE_ACTION; s_graphical_presets[i].generic.flags = QMF_BUTTON|QMF_RIGHT_COLUMN; s_graphical_presets[i].generic.callback = PresetCallback; s_graphical_presets[i].generic.name = graphical_preset_names[i][0]; s_graphical_presets[i].generic.localstrings[0] = graphical_preset_names[i][1]; s_graphical_presets[i].generic.tooltip = graphical_preset_names[i][2]; Menu_AddItem (&video.window, &s_graphical_presets[i]); } add_text (video.window, NULL, 0); // spacer add_action (video.window, "Apply", VidApplyFunc, 0); return &video.screen; } static void M_Menu_Video_f (void) { menuframework_s *screen = Video_MenuInit (); M_PushMenu_Defaults (*screen); } /* ======================================================================= OPTIONS MENUS - AUDIO OPTIONS MENU ======================================================================= */ sliderlimit_t volume_limits = { 1, 50, 0.0f, 1.0f }; option_name_t audio_option_names[] = { { option_spincontrol, "cl_playtaunts", "player taunts", NULL, setnames (onoff_names) }, { option_slider, "s_volume", "global volume", NULL, setlimits (volume_limits) }, { option_slider, "background_music_vol", "music volume", NULL, setlimits (volume_limits) }, { option_spincontrol, "background_music", "music", NULL, setnames (onoff_names) }, { option_textcvarslider, "s_doppler", "doppler effect", NULL, setnames (doppler_effect_items) }, }; static void M_Menu_Audio_f (void) { options_menu (audio, "AUDIO OPTIONS"); M_PushMenu_Defaults (audio.screen); } /* ======================================================================= OPTIONS MENUS - INPUT OPTIONS MENU ======================================================================= */ option_name_t input_option_names[] = { { option_slider, "sensitivity", "mouse speed", NULL, setlimits (mousespeed_limits) }, { option_slider, "menu_sensitivity", "menu mouse speed", NULL, setlimits (mousespeed_limits) }, { option_spincontrol, "m_accel", "mouse acceleration", NULL, setnames (onoff_names) }, { option_spincontrol, "m_smoothing", "mouse smoothing", NULL, setnames (onoff_names) }, { option_spincontrol, "cl_run", "always run", NULL, setnames (onoff_names) }, }; static void InvertMouseFunc( void *_self ) { menulist_s *self = (menulist_s *)_self; if(self->curvalue && m_pitch->value > 0) Cvar_SetValue( "m_pitch", -m_pitch->value ); else if(m_pitch->value < 0) Cvar_SetValue( "m_pitch", -m_pitch->value ); } void CustomizeControlsFunc (void *unused) { M_Menu_Keys_f (); } static void M_Menu_Input_f (void) { options_menu (input, "INPUT OPTIONS"); { static menulist_s s_options_invertmouse_box; s_options_invertmouse_box.generic.name = "invert mouse"; s_options_invertmouse_box.generic.callback = InvertMouseFunc; s_options_invertmouse_box.curvalue = m_pitch->value < 0; setup_tickbox (s_options_invertmouse_box); Menu_AddItem (&input.panel, &s_options_invertmouse_box); } add_text (input.window, NULL, 0); //spacer add_action (input.window, "Key Bindings", CustomizeControlsFunc, 0); M_PushMenu_Defaults (input.screen); } /* ======================================================================= OPTIONS MENUS - NETWORK OPTIONS MENU ======================================================================= */ option_name_t net_option_names[] = { { option_spincontrol, "allow_download", "download missing files", NULL, setnames (onoff_names) }, { option_spincontrol, "allow_download_maps", "maps", NULL, setnames (onoff_names) }, { option_spincontrol, "allow_download_players", "player models/skins", NULL, setnames (onoff_names) }, { option_spincontrol, "allow_download_models", "models", NULL, setnames (onoff_names) }, { option_spincontrol, "allow_download_sounds", "sounds", NULL, setnames (onoff_names) }, }; static void M_Menu_Net_f (void) { options_menu (net, "NETWORK OPTIONS"); M_PushMenu_Defaults (net.screen); } /* ============================================================================= OPTIONS MENUS - IRC OPTIONS MENU ============================================================================= */ char IRC_key[64]; static menuframework_s s_irc_screen; static menuframework_s s_irc_menu; static menuaction_s s_irc_join; static menulist_s s_irc_joinatstartup; static menufield_s s_irc_server; static menufield_s s_irc_channel; static menufield_s s_irc_port; static menulist_s s_irc_ovnickname; static menufield_s s_irc_nickname; static menufield_s s_irc_kickrejoin; static menufield_s s_irc_reconnectdelay; static void JoinIRCFunc( void *unused ) { if(PLAYER_NAME_UNIQUE) CL_InitIRC(); } static void QuitIRCFunc( void *unused ) { CL_IRCInitiateShutdown(); } static void ApplyIRCSettings( void * self ) { qboolean running = CL_IRCIsRunning( ); if ( running ) { CL_IRCInitiateShutdown( ); CL_IRCWaitShutdown( ); } Cvar_Set( "cl_IRC_server" , s_irc_server.buffer); Cvar_Set( "cl_IRC_channel" , s_irc_channel.buffer); Cvar_SetValue( "cl_IRC_port" , atoi( s_irc_port.buffer ) ); Cvar_SetValue( "cl_IRC_override_nickname" , s_irc_ovnickname.curvalue ); Cvar_Set( "cl_IRC_nickname" , s_irc_nickname.buffer ); Cvar_SetValue( "cl_IRC_kick_rejoin" , atoi( s_irc_kickrejoin.buffer ) ); Cvar_SetValue( "cl_IRC_reconnect_delay" , atoi( s_irc_reconnectdelay.buffer ) ); if ( running ) CL_InitIRC( ); M_PopMenu( ); } // TODO: use the options menu macros like everywhere else. static void IRC_Settings_SubMenuInit( ) { setup_tickbox (s_irc_joinatstartup); s_irc_joinatstartup.generic.name = "join at startup"; s_irc_joinatstartup.generic.localstrings[0] = "cl_IRC_connect_at_startup"; s_irc_joinatstartup.curvalue = cl_IRC_connect_at_startup->integer != 0; s_irc_joinatstartup.generic.callback = SpinOptionFunc; Menu_AddItem( &s_irc_menu, &s_irc_joinatstartup ); s_irc_server.generic.type = MTYPE_FIELD; s_irc_server.generic.name = "server"; s_irc_server.generic.tooltip = "Address or name of the IRC server"; s_irc_server.generic.visible_length = LONGINPUT_SIZE; s_irc_server.cursor = strlen( cl_IRC_server->string ); strcpy( s_irc_server.buffer, Cvar_VariableString("cl_IRC_server") ); Menu_AddItem( &s_irc_menu, &s_irc_server ); s_irc_channel.generic.type = MTYPE_FIELD; s_irc_channel.generic.name = "channel"; s_irc_channel.generic.tooltip = "Name of the channel to join"; s_irc_channel.generic.visible_length = LONGINPUT_SIZE; s_irc_channel.cursor = strlen( cl_IRC_channel->string ); strcpy( s_irc_channel.buffer, Cvar_VariableString("cl_IRC_channel") ); Menu_AddItem( &s_irc_menu, &s_irc_channel ); s_irc_port.generic.type = MTYPE_FIELD; s_irc_port.generic.name = "port"; s_irc_port.generic.tooltip = "Port to connect to on the server"; s_irc_port.generic.visible_length = 4; s_irc_port.cursor = strlen( cl_IRC_port->string ); strcpy( s_irc_port.buffer, Cvar_VariableString("cl_IRC_port") ); Menu_AddItem( &s_irc_menu, &s_irc_port ); s_irc_ovnickname.generic.name = "override nick"; s_irc_ovnickname.generic.tooltip = "Enable this to override the default, player-based nick"; setup_tickbox (s_irc_ovnickname); s_irc_ovnickname.curvalue = cl_IRC_override_nickname->value ? 1 : 0; Menu_AddItem( &s_irc_menu, &s_irc_ovnickname ); s_irc_nickname.generic.type = MTYPE_FIELD; s_irc_nickname.generic.name = "nick"; s_irc_nickname.generic.tooltip = "Nickname override to use"; s_irc_nickname.generic.visible_length = LONGINPUT_SIZE; s_irc_nickname.cursor = strlen( cl_IRC_nickname->string ); strcpy( s_irc_nickname.buffer, Cvar_VariableString("cl_IRC_nickname") ); Menu_AddItem( &s_irc_menu, &s_irc_nickname ); s_irc_kickrejoin.generic.type = MTYPE_FIELD; s_irc_kickrejoin.generic.name = "autorejoin"; s_irc_kickrejoin.generic.tooltip = "Delay before automatic rejoin after kick (0 to disable)"; s_irc_kickrejoin.generic.visible_length = 4; s_irc_kickrejoin.cursor = strlen( cl_IRC_kick_rejoin->string ); strcpy( s_irc_kickrejoin.buffer, Cvar_VariableString("cl_IRC_kick_rejoin") ); Menu_AddItem( &s_irc_menu, &s_irc_kickrejoin ); s_irc_reconnectdelay.generic.type = MTYPE_FIELD; s_irc_reconnectdelay.generic.name = "reconnect"; s_irc_reconnectdelay.generic.tooltip= "Delay between reconnection attempts (minimum 5)"; s_irc_reconnectdelay.generic.visible_length = 4; s_irc_reconnectdelay.cursor = strlen( cl_IRC_reconnect_delay->string ); strcpy( s_irc_reconnectdelay.buffer, Cvar_VariableString("cl_IRC_reconnect_delay") ); Menu_AddItem( &s_irc_menu, &s_irc_reconnectdelay ); add_action (s_irc_menu, "Apply", ApplyIRCSettings, 0); } static void M_FindIRCKey ( void ) { int count; int j; int l; char *b; int twokeys[2]; twokeys[0] = twokeys[1] = -1; l = strlen("messagemode3"); count = 0; for (j=0 ; j<256 ; j++) { b = keybindings[j]; if (!b) continue; if (!strncmp (b, "messagemode3", l) ) { twokeys[count] = j; count++; if (count == 2) break; } } //got our key Com_sprintf(IRC_key, sizeof(IRC_key), "(IRC Chat Key is %s)", Key_KeynumToString(twokeys[0])); } void IRC_MenuInit( void ) { if(!cl_IRC_connect_at_startup) cl_IRC_connect_at_startup = Cvar_Get("cl_IRC_connect_at_startup", "0", CVAR_ARCHIVE); M_FindIRCKey(); setup_window (s_irc_screen, s_irc_menu, "IRC CHAT OPTIONS"); s_irc_join.generic.type = MTYPE_ACTION; s_irc_join.generic.flags = QMF_BUTTON; s_irc_join.generic.name = "Connect Now"; s_irc_join.generic.callback = JoinIRCFunc; Menu_AddItem( &s_irc_menu, &s_irc_join ); IRC_Settings_SubMenuInit (); add_text (s_irc_menu, IRC_key, 0); Menu_AutoArrange (&s_irc_screen); } void IRC_MenuDraw (menuframework_s *dummy, menuvec2_t offset) { //warn user that they cannot join until changing default player name if(!PLAYER_NAME_UNIQUE) s_irc_menu.statusbar = "You must create your player name before joining a server!"; else if(CL_IRCIsConnected()) s_irc_menu.statusbar = "Connected to IRC server."; else if(CL_IRCIsRunning()) s_irc_menu.statusbar = "Connecting to IRC server..."; else s_irc_menu.statusbar = "Not connected to IRC server."; // Update join/quit menu entry if ( CL_IRCIsRunning( ) ) { s_irc_join.generic.name = "Disconnect Now"; s_irc_join.generic.callback = QuitIRCFunc; } else { s_irc_join.generic.name = "Connect Now"; s_irc_join.generic.callback = JoinIRCFunc; } Screen_Draw (&s_irc_screen, offset); } void M_Menu_IRC_f (void) { IRC_MenuInit(); M_PushMenu (IRC_MenuDraw, Default_MenuKey, &s_irc_screen); } /* ======================================================================= OPTIONS MENUS - TOP-LEVEL OPTIONS MENU ======================================================================= */ static menuframework_s s_options_screen; static menuframework_s s_options_menu; char *option_screen_names[] = { "Player", // whatever's first will be the default "Display", "Video", "Audio", "Input", "Network", "IRC Chat", }; #define OPTION_SCREENS static_array_size(option_screen_names) void (*option_open_funcs[OPTION_SCREENS])(void) = { &M_Menu_PlayerConfig_f, &M_Menu_Display_f, &M_Menu_Video_f, &M_Menu_Audio_f, &M_Menu_Input_f, &M_Menu_Net_f, &M_Menu_IRC_f, }; static menuframework_s s_player_config_screen; static menuaction_s s_option_screen_actions[OPTION_SCREENS]; LINKABLE(int) option_screen_height; static void OptionScreenFunc (void *_self) { menuframework_s *self = (menuframework_s *)_self; option_open_funcs[self->generic.localints[0]](); } void M_Menu_Options_f (void) { int i; setup_window (s_options_screen, s_options_menu, "OPTIONS"); for (i = 0; i < OPTION_SCREENS; i++) { s_option_screen_actions[i].generic.type = MTYPE_ACTION; s_option_screen_actions[i].generic.flags = QMF_BUTTON; s_option_screen_actions[i].generic.name = option_screen_names[i]; s_option_screen_actions[i].generic.localints[0] = i; s_option_screen_actions[i].generic.callback = OptionScreenFunc; Menu_AddItem (&s_options_menu, &s_option_screen_actions[i]); } add_text (s_options_menu, NULL, 0); //spacer add_action (s_options_menu, "Reset to Defaults", OptionsResetDefaultsFunc, 0); add_action (s_options_menu, "Restore from Saved", OptionsResetSavedFunc, 0); M_PushMenu_Defaults (s_options_screen); // select the default options screen OptionScreenFunc (&s_option_screen_actions[0]); } /* ============================================================================= END GAME MENU ============================================================================= */ static int credits_start_time; static const char **credits; //static char *creditsIndex[256]; static char *creditsBuffer; static const char *idcredits[] = { "+Alien Arena by COR Entertainment", "", "+PROGRAMMING", "John Diamond", "Jim Bower", "Emmanuel Benoit", "Max Eliaser", "Charles Hudson", "Lee Salzman", "Dave Carter", "Victor Luchits", "Jan Rafaj", "Shane Bayer", "Tony Jackson", "Stephan Stahl", "Kyle Hunter", "Andres Mejia", "", "+ART", "John Diamond", "Dennis -xEMPx- Zedlach", "Franc Cassar", "Shawn Keeth", "Enki", "", "+FONTS", "John Diamond", "The League of Moveable Type", "Brian Kent", "", "+LOGO", "Adam -servercleaner- Szalai", "Paul -GimpAlien-", "", "+LEVEL DESIGN", "John Diamond", "Dennis -xEMPx- Zedlach", "Charles Hudson", "Torben Fahrnbach", "", "+SOUND EFFECTS AND MUSIC", "Music/FX Composed and Produced by", "Paul Joyce, Whitelipper, Divinity", "Arteria Games, Wooden Productions", "and Soundrangers.com", "", "+CROSSHAIRS AND HUDS", "Astralsin", "Dangeresque", "Phenax", "Roadrage", "Forsaken", "Capt Crazy", "Torok -Intimidator- Ivan", "Stratocaster", "ChexGuy", "Crayon", "", "+LINUX PORT", "Shane Bayer", "", "+FREEBSD PORT", "Ale", "", "+GENTOO PORTAGE", "Paul Bredbury", "", "+DEBIAN PACKAGE", "Andres Mejia", "", "+LANGUAGE TRANSLATIONS", "Ken Deguisse", "", "+STORYLINE", "Sinnocent", "", "+SPECIAL THANKS", "The Alien Arena Community", "and everyone else who", "has been loyal to the", "game.", "", "", "+ALIEN ARENA - THE STORY", "", "Alien Arena : Many are called, only one will reign supreme", "", "Eternal war ravaged the vastness of infinite space.", "For as far back into the ages as the memories of the", "galaxies oldest races could reach, it had been this way.", "Planet at war with planet, conflicts ending with a", "burned cinder orbiting a dead sun and countless billions", "sent screaming into oblivion. War, endless and ", "eternal, embracing all the peoples of the cosmos.", "Scientific triumphs heralded the creation of ever more", "deadly weapons until the very fabric of the universe itself was threatened.", "", "Then came the call.", "", "Some said it was sent by an elder race, legendary beings", "of terrifying power who had existed since the", "birth of the stars and who now made their home beyond", "the fringes of known creation, others whispered", "fearfully and looked to the skies for the coming of their", "gods. Perhaps it didn't matter who had sent the", "call, for all the people of the stars could at least agree", "that the call was there.", "", "The wars were to end - or they would be ended. In a", "demonstration of power whoever had sent the call", "snuffed out the homeworld of the XXXX, the greatest", "empire of all the stars, in a heartbeat. One moment it", "was there, the next it was dust carried on the solar winds.", "All races had no choice but to heed the call.", "", "For most the call was a distant tug, a whispered warning", "that the wars were over, but for the greatest", "hero of each people it was more, it was a fire raging", "through their blood, a call to a new war, to the battle", "to end all battles. That fire burns in your blood, compelling", "you, the greatest warrior of your people, to fight", "in a distant and unknown arena, your honor and the", "future of your race at stake.", "", "Across the stars you traveled in search of this arena where", "the mightiest of the mighty would do battle,", "where you would stand face to face with your enemies", "in a duel to the death. Strange new weapons", "awaited you, weapons which you would have to master", "if you were to survive and emerge victorious from", "the complex and deadly arenas in which you were summoned to fight.", "", "The call to battle beats through your heart and soul", "like the drums of war. Will you be the one to rise", "through the ranks and conquer all others, the one who", "stands proud as the undefeated champion of the", "Alien Arena?", "", "Alien Arena (C)2007-2012 COR Entertainment, LLC", "All Rights Reserved.", 0 }; void M_Credits_MenuDraw (menuframework_s *dummy, menuvec2_t offset) { int i, y, scale; FNT_font_t font; struct FNT_window_s box; font = FNT_AutoGet( CL_menuFont ); scale = font->size / 8.0; /* ** draw the credits */ for ( i = 0, y = viddef.height - ( ( cls.realtime - credits_start_time ) / 40.0F ); credits[i]; y += 12*scale, i++ ) { if ( y <= -12*scale ) continue; box.y = offset.y + y; box.x = offset.x; box.height = 0; box.width = viddef.width; if ( credits[i][0] == '+' ) { FNT_BoundedPrint (font, credits[i]+1, FNT_CMODE_NONE, FNT_ALIGN_CENTER, &box, FNT_colors[3]); } else { FNT_BoundedPrint (font, credits[i], FNT_CMODE_NONE, FNT_ALIGN_CENTER, &box, FNT_colors[7]); } } if ( y < 0 ) credits_start_time = cls.realtime; } const char *M_Credits_Key (menuframework_s *dummy, int key) { if (key == K_ESCAPE) { if (creditsBuffer) FS_FreeFile (creditsBuffer); M_PopMenu (); } return menu_out_sound; } void M_Menu_Credits_f( void ) { static menuframework_s dummy; CHASELINK(dummy.rwidth) = viddef.width; creditsBuffer = NULL; credits = idcredits; credits_start_time = cls.realtime; M_PushMenu (M_Credits_MenuDraw, M_Credits_Key, &dummy); } /* ============================================================================= GAME MENU ============================================================================= */ static void StartGame( void ) { extern cvar_t *name; char pw[64]; // disable updates cl.servercount = -1; M_ForceMenuOff (); Cvar_SetValue( "deathmatch", 1 ); Cvar_SetValue( "ctf", 0 ); //listen servers are passworded sprintf(pw, "%s%4.2f", name->string, crand()); Cvar_Set ("password", pw); Cvar_SetValue( "gamerules", 0 ); //PGM Cbuf_AddText ("loading ; killserver ; wait ; newgame\n"); cls.key_dest = key_game; } static void SinglePlayerGameFunc (void *data) { char skill[2]; skill[1] = '\0'; skill[0] = ((menuaction_s*)data)->generic.localints[0]+'0'; Cvar_ForceSet ("skill", skill); StartGame (); } static void M_Menu_Game_f (void) { static menuframework_s s_game_screen; static menuframework_s s_game_menu; static const char *singleplayer_skill_level_names[][2] = { {"Easy", "You will win"}, {"Medium", "You might win"}, {"Hard", "Very challenging"}, {"Ultra", "Only the best will win"} }; #define num_singleplayer_skill_levels static_array_size(singleplayer_skill_level_names) static menuaction_s s_singleplayer_game_actions[num_singleplayer_skill_levels]; int i; setup_window (s_game_screen, s_game_menu, "SINGLE PLAYER"); for (i = 0; i < num_singleplayer_skill_levels; i++) { s_singleplayer_game_actions[i].generic.type = MTYPE_ACTION; s_singleplayer_game_actions[i].generic.flags = QMF_BUTTON; s_singleplayer_game_actions[i].generic.name = singleplayer_skill_level_names[i][0]; s_singleplayer_game_actions[i].generic.tooltip = singleplayer_skill_level_names[i][1]; s_singleplayer_game_actions[i].generic.localints[0] = i; s_singleplayer_game_actions[i].generic.callback = SinglePlayerGameFunc; Menu_AddItem (&s_game_menu, &s_singleplayer_game_actions[i]); } Menu_AutoArrange (&s_game_screen); Menu_Center (&s_game_screen); M_PushMenu_Defaults (s_game_screen); } /* ============================================================================= JOIN SERVER MENU ============================================================================= */ #define MAX_LOCAL_SERVERS 128 #define MAX_SERVER_MODS 16 #define SERVER_LIST_COLUMNS 4 static const char *updown_names[] = { "menu/midarrow", "menu/dnarrow", "menu/uparrow", 0 }; //Lists for all stock mutators and game modes, plus some of the more popular //custom ones. (NOTE: For non-boolean cvars, i.e. those which have values //other than 0 or 1, you get a string of the form cvar=value. In the future, //we may do something special to parse these, but since no such cvars are //actually recognized right now anyway, we currently don't.) //TODO: Have a menu to explore this list? //Names. If a cvar isn't recognized, the name of the cvar itself is used. static char mod_names[] = //cannot be wider than this boundary: | "\\ctf" "\\capture the flag" "\\tca" "\\team core assault" "\\cp" "\\cattle prod" "\\instagib" "\\instagib" "\\rocket_arena" "\\rocket arena" "\\low_grav" "\\low gravity" "\\regeneration" "\\regeneration" "\\vampire" "\\vampire" "\\excessive" "\\excessive" "\\grapple" "\\grappling hook" "\\classbased" "\\class based" "\\g_duel" "\\duel mode" "\\quickweap" "\\quick switch" "\\anticamp" "\\anticamp" "\\sv_joustmode" "\\joust mode" "\\playerspeed" "\\player speed" "\\insta_rockets" "\\insta/rockets" "\\chaingun_arena" "\\chaingun arena" "\\instavap" "\\vaporizer arena" "\\vape_arena" "\\vaporizer arena" "\\testcode" "\\code testing" "\\testmap" "\\map testing" "\\dodgedelay=0" "\\rapid dodging" "\\g_tactical" "\\aa tactical" "\\g_dm_lights" "\\player lights" "\\"; //Descriptions. If a cvar isn't recognized, "(no description)" is used. static char mods_desc[] = //cannot be wider than this boundary: | "\\ctf" "\\capture the enemy team's flag to earn points" "\\tca" "\\destroy the enemy team's spider node to win" "\\cp" "\\herd cows through your team's goal for points" "\\instagib" "\\disruptor only, instant kill, infinite ammo" "\\rocket_arena" "\\rocket launcher only, infinite ammo" "\\low_grav" "\\reduced gravity" "\\regeneration" "\\regain health over time" "\\vampire" "\\regain health by damaging people" "\\excessive" "\\all weapons enhanced, infinite ammo" "\\grapple" "\\spawn with a grappling hook" "\\classbased" "\\different races have different strengths" "\\g_duel" "\\wait in line for your turn to duel" "\\quickweap" "\\switch weapons instantly" "\\anticamp" "\\you are punished for holding still too long" "\\sv_joustmode" "\\you can still jump while in midair" "\\playerspeed" "\\run much faster than normal" "\\insta_rockets" "\\hybrid of instagib and rocket_arena" "\\chaingun_arena" "\\chaingun only, infinite ammo" "\\instavap" "\\vaporizer only, infinite ammo" "\\vape_arena" "\\vaporizer only, infinite ammo" "\\testcode" "\\server is testing experimental code" "\\testmap" "\\server is testing an unfinished map" "\\dodgedelay=0" "\\no minimum time between dodges" "\\g_tactical" "\\humans vs martians, destroy enemy bases" "\\g_dm_lights" "\\high-visibility lights on players" "\\"; char *GetLine (char **contents, int *len) { int num; int i; char line[2048]; char *ret; num = 0; line[0] = '\0'; if (*len <= 0) return NULL; for (i = 0; i < *len; i++) { if ((*contents)[i] == '\n') { *contents += (num + 1); *len -= (num + 1); line[num] = '\0'; ret = (char *)malloc (sizeof(line)); strcpy (ret, line); return ret; } line[num] = (*contents)[i]; num++; } ret = (char *)malloc (sizeof(line)); strcpy (ret, line); return ret; } SERVERDATA mservers[MAX_LOCAL_SERVERS]; PLAYERSTATS thisPlayer; #define m_num_servers (s_serverlist_submenu.nitems) static char local_mods_data[16][53]; //53 is measured max tooltip width static struct { menuframework_s screen; menuframework_s menu; menutxt_s name; menuaction_s connect; menuitem_s levelshot; char levelshot_path[MAX_QPATH]; menuframework_s serverinfo_submenu; menuframework_s serverinfo_table; menuframework_s serverinfo_rows[8]; menutxt_s serverinfo_columns[8][2]; menuframework_s modlist_submenu; menuaction_s modlist[MAX_SERVER_MODS]; char modtxt[MAX_SERVER_MODS][48]; char modnames[MAX_SERVER_MODS][24]; menuframework_s playerlist_submenu; menuaction_s playerlist_label; menuframework_s playerlist_header; menuframework_s playerlist_scrollingmenu; menutxt_s playerlist_header_columns[SVDATA_PLAYERINFO]; menuframework_s playerlist_rows[MAX_PLAYERS]; menutxt_s playerlist_columns[MAX_PLAYERS][SVDATA_PLAYERINFO]; char ranktxt[MAX_PLAYERS][32]; } s_servers[MAX_LOCAL_SERVERS]; static int serverindex; void JoinServerFunc (void *unused) { int i; char buffer[128]; cl.tactical = false; remoteserver_runspeed = 300; //default for ( i = 0; i < 16; i++) { if( !strcmp("aa tactical", Info_ValueForKey(mod_names, local_mods_data[i])) ) { remoteserver_runspeed = 200; //for correct prediction M_Menu_Tactical_f(); return; } else if( !strcmp("excessive", Info_ValueForKey(mod_names, local_mods_data[i])) ) remoteserver_runspeed = 450; else if( !strcmp("playerspeed", Info_ValueForKey(mod_names, local_mods_data[i])) ) remoteserver_runspeed = 450; } //TO DO: We need to do the speed check on connect instead - meaning the server will need to be pinged and parsed there as well(but only if not done already through the menu). Com_sprintf (buffer, sizeof(buffer), "connect %s\n", NET_AdrToString (mservers[serverindex].local_server_netadr)); Cbuf_AddText (buffer); M_ForceMenuOff (); } void ModList_SubmenuInit (void) { int i; char modstring[64]; char *token; s_servers[serverindex].modlist_submenu.generic.type = MTYPE_SUBMENU; s_servers[serverindex].modlist_submenu.navagable = true; s_servers[serverindex].modlist_submenu.nitems = 0; for ( i = 0; i < MAX_SERVER_MODS; i++ ) { s_servers[serverindex].modlist[i].generic.type = MTYPE_ACTION; s_servers[serverindex].modlist[i].generic.flags = QMF_RIGHT_COLUMN; s_servers[serverindex].modlist[i].generic.name = s_servers[serverindex].modnames[i]; s_servers[serverindex].modlist[i].generic.tooltip = s_servers[serverindex].modtxt[i]; Menu_AddItem( &s_servers[serverindex].modlist_submenu, &s_servers[serverindex].modlist[i] ); } s_servers[serverindex].modlist_submenu.maxlines = 5; //Copy modstring over since strtok will modify it Q_strncpyz(modstring, mservers[serverindex].modInfo, sizeof(modstring)); // populate all the data token = strtok(modstring, "%%"); for (i=0; i 0) s_servers[serverindex].playerlist_header_columns[i].generic.flags = QMF_RIGHT_COLUMN; Menu_AddItem (&s_servers[serverindex].playerlist_header, &s_servers[serverindex].playerlist_header_columns[i]); } Menu_AddItem (&s_servers[serverindex].playerlist_submenu, &s_servers[serverindex].playerlist_header); for (i = 0; i < mservers[serverindex].players; i++) { int ranking = mservers[serverindex].playerRankings[i]; if (ranking == 1000) Com_sprintf(s_servers[serverindex].ranktxt[i], sizeof(s_servers[serverindex].ranktxt[i]), "Player is unranked"); else Com_sprintf(s_servers[serverindex].ranktxt[i], sizeof(s_servers[serverindex].ranktxt[i]), "Player is ranked %i", ranking); s_servers[serverindex].playerlist_rows[i].generic.tooltip = s_servers[serverindex].ranktxt[i]; for (j = 0; j < SVDATA_PLAYERINFO; j++) local_player_info_ptrs[i*SVDATA_PLAYERINFO+j] = &mservers[serverindex].playerInfo[i][j][0]; } Menu_MakeTable ( &s_servers[serverindex].playerlist_scrollingmenu, mservers[serverindex].players, SVDATA_PLAYERINFO, sizes, &s_servers[serverindex].playerlist_header, s_servers[serverindex].playerlist_rows, s_servers[serverindex].playerlist_columns, local_player_info_ptrs ); Menu_AddItem (&s_servers[serverindex].playerlist_submenu, &s_servers[serverindex].playerlist_scrollingmenu); s_servers[serverindex].playerlist_scrollingmenu.maxlines = 7; s_servers[serverindex].playerlist_scrollingmenu.nitems = mservers[serverindex].players; s_servers[serverindex].playerlist_scrollingmenu.yscroll = 0; LINK (s_servers[serverindex].serverinfo_submenu.rwidth, s_servers[serverindex].playerlist_scrollingmenu.rwidth); LINK (s_servers[serverindex].serverinfo_submenu.lwidth, s_servers[serverindex].playerlist_scrollingmenu.lwidth); } static void M_Menu_SelectedServer_f (void) { setup_window (s_servers[serverindex].screen, s_servers[serverindex].menu, "SERVER"); ServerInfo_SubmenuInit (); PlayerList_SubmenuInit (); // "connect" button at the bottom s_servers[serverindex].connect.generic.type = MTYPE_ACTION; s_servers[serverindex].connect.generic.flags = QMF_BUTTON | QMF_RIGHT_COLUMN; s_servers[serverindex].connect.generic.name = "Connect"; s_servers[serverindex].connect.generic.callback = JoinServerFunc; Menu_AddItem (&s_servers[serverindex].menu, &s_servers[serverindex].connect); s_servers[serverindex].serverinfo_submenu.statusbar = NULL; s_servers[serverindex].connect.generic.statusbar = NULL; if (serverIsOutdated (mservers[serverindex].szVersion)) s_servers[serverindex].serverinfo_submenu.statusbar = "Warning: server is ^1outdated!^7 It may have bugs or different gameplay."; else if (!PLAYER_NAME_UNIQUE) s_servers[serverindex].connect.generic.statusbar = "You must change your player name from the default before connecting!"; else s_servers[serverindex].connect.generic.statusbar = "Hit ENTER or CLICK to connect"; M_PushMenu_Defaults (s_servers[serverindex].screen); s_servers[serverindex].menu.default_cursor_selection = (menuitem_s *)&s_servers[serverindex].connect; } //TODO: Move this out of the menu section! qboolean M_ParseServerInfo (netadr_t adr, char *status_string, SERVERDATA *destserver) { char *rLine; char *token; #ifdef TACTICAL char *token2; char modstring[64]; qboolean isTactical; int i; #endif char skillLevel[24]; char lasttoken[256]; char seps[] = "\\"; int players = 0; int bots = 0; int result; char playername[PLAYERNAME_SIZE]; int score, ping, rankTotal, starttime; PLAYERSTATS player; destserver->local_server_netadr = adr; // starttime now sourced per server. starttime = CL_GetPingStartTime(adr); if (starttime != 0) destserver->ping = Sys_Milliseconds() - starttime; else { // Local LAN? destserver->ping = 1; } if ( destserver->ping < 1 ) destserver->ping = 1; /* for LAN and address book entries */ //parse it result = strlen(status_string); //server info rLine = GetLine (&status_string, &result); /* Establish string and get the first token: */ token = strtok( rLine, seps ); if ( token != NULL ) { Com_sprintf(lasttoken, sizeof(lasttoken), "%s", token); token = strtok( NULL, seps ); } // HACK for backward compatibility memset (destserver->modInfo, 0, sizeof(destserver->modInfo)); /* Loop through the rest of them */ while( token != NULL ) { /* While there are tokens in "string" */ if (!Q_strcasecmp (lasttoken, "admin")) Com_sprintf(destserver->szAdmin, sizeof(destserver->szAdmin), "%s", token); else if (!Q_strcasecmp (lasttoken, "website")) Com_sprintf(destserver->szWebsite, sizeof(destserver->szWebsite), "%s", token); else if (!Q_strcasecmp (lasttoken, "fraglimit")) Com_sprintf(destserver->fraglimit, sizeof(destserver->fraglimit), "%s", token); else if (!Q_strcasecmp (lasttoken, "timelimit")) Com_sprintf(destserver->timelimit, sizeof(destserver->timelimit), "%s", token); else if (!Q_strcasecmp (lasttoken, "version")) Com_sprintf(destserver->szVersion, sizeof(destserver->szVersion), "%s", token); else if (!Q_strcasecmp (lasttoken, "mapname")) { Com_sprintf(destserver->szMapName, sizeof(destserver->szMapName), "%s", token); Com_sprintf(destserver->fullMapName, sizeof(destserver->fullMapName), "%s", token); } else if (!Q_strcasecmp (lasttoken, "hostname")) Com_sprintf(destserver->szHostName, sizeof(destserver->szHostName), "%s", token); else if (!Q_strcasecmp (lasttoken, "maxclients")) Com_sprintf(destserver->maxClients, sizeof(destserver->maxClients), "%s", token); else if (!Q_strcasecmp (lasttoken, "mods")) Com_sprintf(destserver->modInfo, sizeof(destserver->modInfo), "%s", token); else if (!Q_strcasecmp (lasttoken, "sv_joustmode")) destserver->joust = atoi(token); /* Get next token: */ Com_sprintf(lasttoken, sizeof(lasttoken), "%s", token); token = strtok( NULL, seps ); } free (rLine); #ifdef TACTICAL isTactical = false; //Copy modstring over since strtok will modify it Q_strncpyz(modstring, destserver->modInfo, sizeof(modstring)); // populate all the data token2 = strtok(modstring, "%%"); for (i = 0; i < MAX_SERVER_MODS; i++) { if (!token2) break; if(!strcmp("g_tactical", token2)) isTactical = true; token2 = strtok(NULL, "%%"); } if(!isTactical) return false; #endif //playerinfo rankTotal = 0; strcpy (seps, " "); while ((rLine = GetLine (&status_string, &result)) && players < MAX_PLAYERS) { /* Establish string and get the first token: */ token = strtok( rLine, seps); score = atoi(token); token = strtok( NULL, seps); ping = atoi(token); token = strtok( NULL, "\""); if (token) strncpy (playername, token, sizeof(playername)-1); else playername[0] = '\0'; free (rLine); playername[sizeof(playername)-1] = '\0'; //get ranking Q_strncpyz2( player.playername, playername, sizeof(player.playername)); player.totalfrags = player.totaltime = player.ranking = 0; player = getPlayerRanking ( player ); Com_sprintf ( destserver->playerInfo[players][SVDATA_PLAYERINFO_NAME], SVDATA_PLAYERINFO_COLSIZE, "%s", playername ); Com_sprintf ( destserver->playerInfo[players][SVDATA_PLAYERINFO_SCORE], SVDATA_PLAYERINFO_COLSIZE, "%i", score ); Com_sprintf ( destserver->playerInfo[players][SVDATA_PLAYERINFO_PING], SVDATA_PLAYERINFO_COLSIZE, "%i", ping ); destserver->playerRankings[players] = player.ranking; rankTotal += player.ranking; players++; if(ping == 0) bots++; } if(players) { if(thisPlayer.ranking < (rankTotal/players) - 100) strcpy(skillLevel, "Your Skill is ^1Higher"); else if(thisPlayer.ranking > (rankTotal/players + 100)) strcpy(skillLevel, "Your Skill is ^4Lower"); else strcpy(skillLevel, "Your Skill is ^3Even"); Com_sprintf(destserver->skill, sizeof(destserver->skill), "%s", skillLevel); } else Com_sprintf(destserver->skill, sizeof(destserver->skill), "Unknown"); destserver->players = players; //build the string for the server (hostname - address - mapname - players/maxClients) if(strlen(destserver->maxClients) > 2) strcpy(destserver->maxClients, "??"); Com_sprintf (destserver->szPlayers, sizeof(destserver->szPlayers), "%i(%i)/%s", min(99,players), min(99,bots), destserver->maxClients); Com_sprintf (destserver->szPing, sizeof(destserver->szPing), "%i", min(9999,destserver->ping)); return true; } static menuframework_s s_serverbrowser_screen; static menuframework_s s_joinserver_menu; static menuframework_s s_joinserver_header; static menuframework_s s_serverlist_submenu; static menuframework_s s_serverlist_header; static menulist_s s_serverlist_header_columns[SERVER_LIST_COLUMNS]; static menuframework_s s_serverlist_rows[MAX_LOCAL_SERVERS]; static menutxt_s s_serverlist_columns[MAX_LOCAL_SERVERS][SERVER_LIST_COLUMNS]; void M_AddToServerList (netadr_t adr, char *status_string) { //if by some chance this gets called without the menu being up, return if(cls.key_dest != key_menu) return; if (m_num_servers == MAX_LOCAL_SERVERS) return; if(M_ParseServerInfo (adr, status_string, &mservers[m_num_servers])) { CON_Clear(); m_num_servers++; } } void M_UpdateConnectedServerInfo (netadr_t adr, char *status_string) { M_ParseServerInfo (adr, status_string, &connectedserver); remoteserver_jousting = connectedserver.joust; } void DeselectServer (void) { serverindex = -1; s_servers[serverindex].serverinfo_submenu.nitems = 0; s_servers[serverindex].playerlist_scrollingmenu.nitems = 0; s_servers[serverindex].modlist_submenu.nitems = 0; } void SelectServer (int index) { // used if the player hits enter without his mouse over the server list serverindex = index; M_Menu_SelectedServer_f (); } //join on double click, return info on single click - to do - might consider putting player info in a tooltip on single click/right click void ClickServerFunc( void *self ) { int index = ( menuframework_s * ) self - s_serverlist_rows; if(serverindex != index) { SelectServer (index); if (cursor.buttonclicks[MOUSEBUTTON1] != 2) return; } if(!PLAYER_NAME_UNIQUE) { M_Menu_PlayerConfig_f(); return; } JoinServerFunc (NULL); } void AddressBookFunc( void *self ) { M_Menu_AddressBook_f(); } void PlayerRankingFunc( void *self ) { M_Menu_PlayerRanking_f(); } void SearchLocalGames( void ) { m_num_servers = 0; DeselectServer (); s_serverlist_submenu.nitems = 0; s_serverlist_submenu.yscroll = 0; Draw_Fill (0, 0, viddef.width, viddef.height, RGBA (0, 0, 0, 0.85)); SCR_CenterPrint ("Fetching server list..."); SCR_DrawCenterString (); R_EndFrame (); // send out info packets CL_PingServers_f(); CON_Clear(); Com_Printf (" Got %d servers- stragglers may follow.\n", m_num_servers); } void SearchLocalGamesFunc( void *self ) { SearchLocalGames(); } static qboolean QSortReverse; static int QSortColumn; static int SortServerList_Compare (const void *_a, const void *_b) { int ret = 0; const menuframework_s *a, *b; const char *a_s, *b_s; a = *(menuframework_s **)_a; b = *(menuframework_s **)_b; a_s = ((menutxt_s *)(a->items[QSortColumn]))->generic.name; b_s = ((menutxt_s *)(b->items[QSortColumn]))->generic.name; if (QSortColumn > 1) { // do numeric sort for player count and ping if (atoi (a_s) > atoi (b_s)) ret = 1; else if (atoi (a_s) < atoi (b_s)) ret = -1; } else // because strcmp doesn't handle ^colors while (*a_s && *b_s) { if (*a_s == '^') { a_s++; } else if (*b_s == '^') { b_s++; } else if (tolower(*a_s) > tolower(*b_s)) { ret = 1; break; } else if (tolower(*a_s) < tolower(*b_s)) { ret = -1; break; } a_s++; b_s++; } if (QSortReverse) return -ret; return ret; } static void SortServerList_Func ( void *_self ) { int column_num, i; menulist_s *self = (menulist_s *)_self; column_num = self-s_serverlist_header_columns; for (i = 0; i < SERVER_LIST_COLUMNS; i++) if (i != column_num) s_serverlist_header_columns[i].curvalue = 0; if (self->curvalue == 0) { if (column_num == 3) { self->curvalue = 1; } else { s_serverlist_header_columns[3].curvalue = 1; SortServerList_Func (&s_serverlist_header_columns[3]); return; } } QSortColumn = column_num; QSortReverse = self->curvalue == 2; qsort (s_serverlist_submenu.items, s_serverlist_submenu.nitems, sizeof (void*), SortServerList_Compare); s_serverlist_submenu.yscroll = 0; } void ServerList_SubmenuInit (void) { int i, j; s_serverlist_submenu.generic.type = MTYPE_SUBMENU; s_serverlist_submenu.generic.flags = QMF_SUBMENU_CAPTURE; s_serverlist_submenu.navagable = true; s_serverlist_submenu.nitems = 0; s_serverlist_submenu.bordertexture = "menu/sm_"; s_serverlist_header.generic.type = MTYPE_SUBMENU; s_serverlist_header.horizontal = true; s_serverlist_header.navagable = true; s_serverlist_header.nitems = 0; s_serverlist_header_columns[0].generic.name = "^3Server"; s_serverlist_header_columns[1].generic.name = "^3Map"; s_serverlist_header_columns[2].generic.name = "^3Players"; s_serverlist_header_columns[3].generic.name = "^3Ping"; for (j = 0; j < SERVER_LIST_COLUMNS; j++) { s_serverlist_header_columns[j].generic.type = MTYPE_SPINCONTROL; s_serverlist_header_columns[j].generic.flags = QMF_RIGHT_COLUMN|QMF_ALLOW_WRAP; s_serverlist_header_columns[j].itemnames = updown_names; s_serverlist_header_columns[j].generic.itemsizecallback = IconSpinSizeFunc; s_serverlist_header_columns[j].generic.itemdraw = IconSpinDrawFunc; s_serverlist_header_columns[j].curvalue = 0; s_serverlist_header_columns[j].generic.callback = SortServerList_Func; Menu_AddItem (&s_serverlist_header, &s_serverlist_header_columns[j]); } s_serverlist_header_columns[3].curvalue = 1; Menu_AddItem (&s_joinserver_menu, &s_serverlist_header); for ( i = 0; i < MAX_LOCAL_SERVERS; i++ ) { s_serverlist_rows[i].generic.type = MTYPE_SUBMENU; s_serverlist_rows[i].generic.callback = ClickServerFunc; s_serverlist_rows[i].nitems = 0; s_serverlist_rows[i].horizontal = true; s_serverlist_rows[i].enable_highlight = true; s_serverlist_columns[i][0].generic.name = mservers[i].szHostName; s_serverlist_columns[i][1].generic.name = mservers[i].szMapName; s_serverlist_columns[i][2].generic.name = mservers[i].szPlayers; s_serverlist_columns[i][3].generic.name = mservers[i].szPing; for (j = 0; j < SERVER_LIST_COLUMNS; j++) { s_serverlist_columns[i][j].generic.type = MTYPE_TEXT; s_serverlist_columns[i][j].generic.flags = QMF_RIGHT_COLUMN; LINK(s_serverlist_header_columns[j].generic.x, s_serverlist_columns[i][j].generic.x); Menu_AddItem (&s_serverlist_rows[i], &s_serverlist_columns[i][j]); } LINK(s_serverlist_header.lwidth, s_serverlist_rows[i].lwidth); LINK(s_serverlist_header.rwidth, s_serverlist_rows[i].rwidth); Menu_AddItem( &s_serverlist_submenu, &s_serverlist_rows[i] ); } Menu_AddItem (&s_joinserver_menu, &s_serverlist_submenu); s_serverlist_submenu.maxlines = 25; } void ServerListHeader_SubmenuInit (void) { s_joinserver_header.generic.type = MTYPE_SUBMENU; s_joinserver_header.nitems = 0; s_joinserver_header.horizontal = true; s_joinserver_header.navagable = true; // doesn't actually do anything yet // add_action (s_joinserver_header, "Address Book", AddressBookFunc, 0); add_action (s_joinserver_header, "Refresh", SearchLocalGamesFunc, 0); add_action (s_joinserver_header, "Rank/Stats", PlayerRankingFunc, 0); Menu_AddItem (&s_joinserver_menu, &s_joinserver_header); } static void M_Menu_JoinServer_f (void) { extern cvar_t *name; static qboolean gotServers = false; if(!gotServers) { STATS_getStatsDB(); getLatestGameVersion(); } ValidatePlayerName( name->string, (strlen(name->string)+1) ); Q_strncpyz2( thisPlayer.playername, name->string, sizeof(thisPlayer.playername) ); thisPlayer.totalfrags = thisPlayer.totaltime = thisPlayer.ranking = 0; thisPlayer = getPlayerRanking ( thisPlayer ); serverindex = -1; if (!gotServers) { setup_window (s_serverbrowser_screen, s_joinserver_menu, "SERVER LIST"); ServerListHeader_SubmenuInit (); ServerList_SubmenuInit (); SearchLocalGames(); s_joinserver_menu.default_cursor_selection = (menuitem_s *)&s_serverlist_submenu; } gotServers = true; M_PushMenu_Defaults (s_serverbrowser_screen); } /* ============================================================================= MUTATORS MENU ============================================================================= */ static menuframework_s s_mutators_screen; static menuframework_s s_mutators_menu; // weapon modes are different from regular mutators in that they cannot be // combined static const char *weaponModeNames[][2] = { {"instagib", "instagib"}, {"rocket arena", "rocket_arena"}, {"insta/rockets", "insta_rockets"}, {"excessive", "excessive"}, {"class based", "classbased"} }; #define num_weapon_modes static_array_size(weaponModeNames) static menulist_s s_weaponmode_list[num_weapon_modes]; static const char *mutatorNames[][2] = { {"vampire", "vampire"}, {"regen", "regeneration"}, {"quick weapons", "quickweap"}, {"anticamp", "anticamp"}, {"speed", "playerspeed"}, {"low gravity", "low_grav"}, {"jousting", "sv_joustmode"}, {"grapple hook", "grapple"} }; #define num_mutators static_array_size(mutatorNames) static menulist_s s_mutator_list[num_mutators]; static menufield_s s_camptime; static char dmflags_display_buffer[128]; static void DMFlagCallback( void *self ) { menulist_s *f = ( menulist_s * ) self; int flags; int bit; qboolean invert, enabled; flags = Cvar_VariableValue( "dmflags" ); if (f != NULL) { bit = f->generic.localints[0]; invert = f->generic.localints[1]; enabled = f->curvalue != 0; if (invert != enabled) flags |= bit; else flags &= ~bit; } Cvar_SetValue ("dmflags", flags); Com_sprintf( dmflags_display_buffer, sizeof( dmflags_display_buffer ), "(dmflags = %d)", flags ); } typedef struct { char *display_name; qboolean invert; int bit; } DMFlag_control_t; static const DMFlag_control_t dmflag_control_names[] = { {"falling damage", true, DF_NO_FALLING}, {"weapons stay", false, DF_WEAPONS_STAY}, {"instant powerups", false, DF_INSTANT_ITEMS}, {"allow powerups", true, DF_NO_ITEMS}, {"allow health", true, DF_NO_HEALTH}, {"allow armor", true, DF_NO_ARMOR}, {"spawn farthest", false, DF_SPAWN_FARTHEST}, {"same map", false, DF_SAME_LEVEL}, {"force respawn", false, DF_FORCE_RESPAWN}, {"team deathmatch", false, DF_SKINTEAMS}, {"allow exit", false, DF_ALLOW_EXIT}, {"infinite ammo", false, DF_INFINITE_AMMO}, {"quad drop", false, DF_QUAD_DROP}, {"friendly fire", true, DF_NO_FRIENDLY_FIRE}, {"bot chat", false, DF_BOTCHAT}, {"bot fuzzy aim", false, DF_BOT_FUZZYAIM}, {"auto node save", false, DF_BOT_AUTOSAVENODES}, {"repeat level if " "bot wins", true, DF_BOT_LEVELAD}, {"bots in game", true, DF_BOTS} }; #define num_dmflag_controls static_array_size(dmflag_control_names) static menuframework_s s_dmflags_submenu; static menulist_s s_dmflag_controls[num_dmflag_controls]; void SetWeaponModeFunc(void *_self) { menulist_s *self; int i, value; self = (menulist_s*)_self; value = self->curvalue; if (self->curvalue) { for (i = 0; i < num_weapon_modes; i++) { Cvar_SetValue (weaponModeNames[i][1], 0); s_weaponmode_list[i].curvalue = 0; } } Cvar_SetValue (self->generic.localstrings[0], value); self->curvalue = value; } static void M_Menu_Mutators_f (void) { int i; int dmflags = Cvar_VariableValue( "dmflags" ); setup_window (s_mutators_screen, s_mutators_menu, "MUTATORS"); for (i = 0; i < num_weapon_modes; i++) { s_weaponmode_list[i].generic.name = weaponModeNames[i][0]; s_weaponmode_list[i].generic.callback = SetWeaponModeFunc; s_weaponmode_list[i].generic.localstrings[0] = weaponModeNames[i][1]; s_weaponmode_list[i].curvalue = Cvar_VariableValue (weaponModeNames[i][1]); setup_radiobutton (s_weaponmode_list[i]); Menu_AddItem (&s_mutators_menu, &s_weaponmode_list[i]); } s_camptime.generic.type = MTYPE_FIELD; s_camptime.generic.name = "camp time"; s_camptime.generic.flags = QMF_NUMBERSONLY; s_camptime.generic.localstrings[0] = "camptime"; s_camptime.length = 3; s_camptime.generic.visible_length = 3; strcpy( s_camptime.buffer, Cvar_VariableString("camptime") ); s_camptime.generic.callback = IntFieldCallback; for (i = 0; i < num_mutators; i++) { s_mutator_list[i].generic.name = mutatorNames[i][0]; s_mutator_list[i].generic.callback = SpinOptionFunc; s_mutator_list[i].generic.localstrings[0] = weaponModeNames[i][1]; s_mutator_list[i].curvalue = Cvar_VariableValue (mutatorNames[i][1]); setup_tickbox (s_mutator_list[i]); Menu_AddItem (&s_mutators_menu, &s_mutator_list[i]); // camptime goes after anticamp control-- we put this here so we can // insert it in the right place in the menu if (!strcmp (mutatorNames[i][0], "anticamp")) Menu_AddItem( &s_mutators_menu, &s_camptime ); } add_text (s_mutators_menu, dmflags_display_buffer, 0); s_dmflags_submenu.generic.type = MTYPE_SUBMENU; s_dmflags_submenu.generic.flags = QMF_SNUG_LEFT | QMF_SUBMENU_CAPTURE; s_dmflags_submenu.navagable = true; s_dmflags_submenu.bordertexture = "menu/sm_"; s_dmflags_submenu.nitems = 0; s_dmflags_submenu.maxlines = 15; for (i = 0; i < num_dmflag_controls; i++) { s_dmflag_controls[i].generic.name = dmflag_control_names[i].display_name; s_dmflag_controls[i].generic.callback = DMFlagCallback; setup_tickbox (s_dmflag_controls[i]); s_dmflag_controls[i].generic.localints[0] = dmflag_control_names[i].bit; s_dmflag_controls[i].generic.localints[1] = dmflag_control_names[i].invert; s_dmflag_controls[i].curvalue = (dmflags & dmflag_control_names[i].bit) != 0; if (dmflag_control_names[i].invert) { s_dmflag_controls[i].curvalue = s_dmflag_controls[i].curvalue == 0; } Menu_AddItem (&s_dmflags_submenu, &s_dmflag_controls[i]); } Menu_AddItem (&s_mutators_menu, &s_dmflags_submenu); // initialize the dmflags display buffer DMFlagCallback( 0 ); M_PushMenu_Defaults (s_mutators_screen); } /* ============================================================================= ADD BOTS MENU ============================================================================= */ // For going from weapon pickup name to weapon icon. Used for displaying icon // previews of the bots' favorite weapons. static char *weapon_icon_names[][2] = { {"Hover", "hover"}, {"Bomber", "bomber"}, {"Strafer", "strafer"}, {"Grapple", "grapple"}, {"Blaster", "blaster"}, {"Violator", "violator"}, {"Alien Smartgun", "smartgun"}, {"Pulse Rifle", "chaingun"}, {"Flame Thrower", "flamethrower"}, {"Rocket Launcher", "rocketlauncher"}, {"Alien Disruptor", "disruptor"}, {"Disruptor", "beamgun"}, {"Alien Vaporizer", "vaporizor"} // note the different spellings }; #define num_weapon_icons static_array_size(weapon_icon_names) static menuframework_s s_addbots_screen; static menuframework_s s_addbots_menu; static menuframework_s s_addbots_header; static menutxt_s s_addbots_name_label; static menutxt_s s_addbots_skill_label; static menutxt_s s_addbots_faveweap_label; int totalbots; #define MAX_BOTS 16 struct botdata { char name[32]; char model[64]; char userinfo[MAX_INFO_STRING]; char faveweap[64]; int skill; // menu entities menuframework_s row; menuaction_s action; char skill_buf[2]; menutxt_s m_skill; menutxt_s m_faveweap; } bots[MAX_BOTS]; static menulist_s s_startmap_list; static menulist_s s_rules_box; static menulist_s s_bots_bot_action[8]; #define MAX_MAPS 256 static char *mapnames[MAX_MAPS + 2]; struct botinfo { char name[32]; char userinfo[MAX_INFO_STRING]; } bot[8]; int slot; void LoadBotInfo( void ) { FILE *pIn; int i, count; char *name; char *skin; char fullpath[MAX_OSPATH]; if ( !FS_FullPath( fullpath, sizeof(fullpath), BOT_GAMEDATA"/allbots.tmp" ) ) { Com_DPrintf("LoadBotInfo: %s/allbots.tmp not found\n", BOT_GAMEDATA ); return; } if( (pIn = fopen( fullpath, "rb" )) == NULL ) { Com_DPrintf("LoadBotInfo: failed file open: %s\n", fullpath ); return; } szr = fread(&count,sizeof (int),1,pIn); if(count>MAX_BOTS) count = MAX_BOTS; for(i=0;i -1; i--) { if(strcmp(bot[i].name, "...empty slot")) szr = fwrite(bot[i].userinfo,sizeof (char) * MAX_INFO_STRING,1,pOut); } fclose(pOut); //kick back to previous menu M_PopMenu(); } static void M_Menu_AddBots_f (void) { int i, j; totalbots = 0; LoadBotInfo(); setup_window (s_addbots_screen, s_addbots_menu, "CHOOSE A BOT"); s_addbots_menu.maxlines = 16; s_addbots_header.generic.type = MTYPE_SUBMENU; s_addbots_header.horizontal = true; s_addbots_header.nitems = 0; s_addbots_name_label.generic.type = MTYPE_TEXT; s_addbots_name_label.generic.name = "^3bot"; Menu_AddItem (&s_addbots_header, &s_addbots_name_label); s_addbots_skill_label.generic.type = MTYPE_TEXT; s_addbots_skill_label.generic.name = "^3skill"; Menu_AddItem (&s_addbots_header, &s_addbots_skill_label); s_addbots_faveweap_label.generic.type = MTYPE_TEXT; s_addbots_faveweap_label.generic.flags = QMF_RIGHT_COLUMN; s_addbots_faveweap_label.generic.name = "^3favorite ^3weapon"; Menu_AddItem (&s_addbots_header, &s_addbots_faveweap_label); Menu_AddItem (&s_addbots_menu, &s_addbots_header); for(i = 0; i < totalbots; i++) { bots[i].row.generic.type = MTYPE_SUBMENU; bots[i].row.generic.flags = QMF_SNUG_LEFT; bots[i].row.nitems = 0; bots[i].row.horizontal = true; bots[i].row.enable_highlight = true; bots[i].row.generic.callback = AddbotFunc; bots[i].action.generic.type = MTYPE_ACTION; bots[i].action.generic.name = bots[i].name; bots[i].action.generic.localstrings[0] = bots[i].model; VectorSet (bots[i].action.generic.localints, 2, 2, RCOLUMN_OFFSET); bots[i].action.generic.itemsizecallback = PicSizeFunc; bots[i].action.generic.itemdraw = PicDrawFunc; LINK(s_addbots_name_label.generic.x, bots[i].action.generic.x); Menu_AddItem (&bots[i].row, &bots[i].action); bots[i].m_skill.generic.type = MTYPE_TEXT; bots[i].m_skill.generic.name = bots[i].skill_buf; LINK(s_addbots_skill_label.generic.x, bots[i].m_skill.generic.x); Menu_AddItem (&bots[i].row, &bots[i].m_skill); bots[i].m_faveweap.generic.type = MTYPE_NOT_INTERACTIVE; bots[i].m_faveweap.generic.flags = QMF_RIGHT_COLUMN; // Start by assuming that we won't find a thumbnail image for the // bot's favorite weapon, and set the widget up to simply show the // weapon's name. bots[i].m_faveweap.generic.itemsizecallback = NULL; bots[i].m_faveweap.generic.itemdraw = NULL; bots[i].m_faveweap.generic.name = bots[i].faveweap; for (j = 0; j < num_weapon_icons; j++) { if (!strcmp (bots[i].faveweap, weapon_icon_names[j][0])) { // We have found a matching thumbnail image, so disable the // display of text and instead show the image. bots[i].m_faveweap.generic.name = NULL; VectorSet (bots[i].m_faveweap.generic.localints, 4, 2, 0); bots[i].m_faveweap.generic.itemsizecallback = PicSizeFunc; bots[i].m_faveweap.generic.itemdraw = PicDrawFunc; bots[i].m_faveweap.generic.localstrings[0] = weapon_icon_names[j][1]; break; } } LINK(s_addbots_faveweap_label.generic.x, bots[i].m_faveweap.generic.x); Menu_AddItem (&bots[i].row, &bots[i].m_faveweap); LINK(s_addbots_header.lwidth, bots[i].row.lwidth); LINK(s_addbots_header.rwidth, bots[i].row.rwidth); Menu_AddItem( &s_addbots_menu, &bots[i].row ); } M_PushMenu_Defaults (s_addbots_screen); } /* ============================================================================= START SERVER MENU ============================================================================= */ static menuframework_s s_startserver_screen; static menuframework_s s_startserver_menu; static menuframework_s s_startserver_main_submenu; static int nummaps = 0; static menufield_s s_timelimit_field; static menufield_s s_fraglimit_field; static menufield_s s_maxclients_field; static menufield_s s_hostname_field; static menulist_s s_antilag_box; static menulist_s s_public_box; static menulist_s s_dedicated_box; static menulist_s s_skill_box; static menuframework_s s_levelshot_submenu; static menuitem_s s_levelshot_preview; static menulist_s s_startserver_map_data[5]; void BotOptionsFunc( void *self ) { M_Menu_BotOptions_f(); } void MutatorFunc( void *self ) { M_Menu_Mutators_f(); } int Menu_FindFile (char *filename, FILE **file) { *file = fopen (filename, "rb"); if (!*file) { *file = NULL; return -1; } return 1; } void MapInfoFunc( void *self ) { // FILE *map_file; // unused FILE *desc_file; char line[500]; char *pLine; char *rLine; int result; int i; char seps[] = "//"; char *token; char startmap[128]; char path[MAX_QPATH]; static char levelshot[MAX_QPATH]; //get a map description if it is there if(mapnames[0]) strcpy( startmap, strchr( mapnames[s_startmap_list.curvalue], '\n' ) + 1 ); else strcpy( startmap, "missing"); Com_sprintf(path, sizeof(path), "levelshots/%s.txt", startmap); FS_FOpenFile(path, &desc_file); if (desc_file) { if(fgets(line, 500, desc_file)) { pLine = line; result = strlen(line); rLine = GetLine (&pLine, &result); /* Establish string and get the first token: */ token = strtok( rLine, seps ); i = 0; while( token != NULL && i < 5) { /* Get next token: */ token = strtok( NULL, seps ); /* While there are tokens in "string" */ s_startserver_map_data[i].generic.type = MTYPE_TEXT; s_startserver_map_data[i].generic.name = token; s_startserver_map_data[i].generic.flags = QMF_RIGHT_COLUMN; i++; } } fclose(desc_file); } else { for (i = 0; i < 5; i++ ) { s_startserver_map_data[i].generic.type = MTYPE_TEXT; s_startserver_map_data[i].generic.name = "no data"; s_startserver_map_data[i].generic.flags = QMF_RIGHT_COLUMN; } } Com_sprintf( levelshot, sizeof(levelshot), "/levelshots/%s", startmap ); s_levelshot_preview.generic.localstrings[0] = levelshot; } static const char *game_mode_names[] = { #ifndef TACTICAL "deathmatch", "ctf", #endif "tactical", #ifndef TACTICAL "all out assault", "deathball", "team core assault", "cattle prod", "duel", #endif NULL }; #define num_game_modes (static_array_size(game_mode_names)-1) //same order as game_mode_names static const char *map_prefixes[num_game_modes][3] = { #ifndef TACTICAL {"dm", "tourney", NULL}, {"ctf", NULL}, {"tac", NULL}, {"aoa", NULL}, {"db", NULL}, {"tca", NULL}, {"cp", NULL}, {"dm", "tourney", NULL} #else {"tac", NULL} #endif }; void RulesChangeFunc ( void *self ) //this has been expanded to rebuild map list { char *buffer; char mapsname[1024]; char *s; int length; int i, k; FILE *fp; char shortname[MAX_TOKEN_CHARS]; char longname[MAX_TOKEN_CHARS]; char scratch[200]; char *curMap; int nmaps = 0; int totalmaps; char **mapfiles; // char *path = NULL; // unused static char **bspnames; int j, l; //clear out list first for ( i = 0; i < nummaps; i++ ) free( mapnames[i] ); nummaps = 0; /* ** reload the list of map names, based on rules */ // maps.lst normally in "data1/" // need to add a function to FS_ if that is the only place it is allowed if ( !FS_FullPath( mapsname, sizeof( mapsname ), "maps.lst" ) ) { Com_Error( ERR_DROP, "couldn't find maps.lst\n" ); return; // for show, no maps.lst is fatal error } if ( ( fp = fopen( mapsname, "rb" ) ) == 0 ) { Com_Error( ERR_DROP, "couldn't open maps.lst\n" ); return; // for "show". above is fatal error. } length = FS_filelength( fp ); buffer = malloc( length + 1 ); szr = fread( buffer, length, 1, fp ); buffer[length] = 0; i = 0; while ( i < length ) { if ( buffer[i] == '\r' ) nummaps++; i++; } totalmaps = nummaps; if ( nummaps == 0 ) { fclose( fp ); free( buffer ); Com_Error( ERR_DROP, "no maps in maps.lst\n" ); return; // for showing above is fatal. } memset( mapnames, 0, sizeof( char * ) * ( MAX_MAPS + 2 ) ); bspnames = malloc( sizeof( char * ) * ( MAX_MAPS + 2 ) ); //was + 1, but caused memory errors memset( bspnames, 0, sizeof( char * ) * ( MAX_MAPS + 2 ) ); s = buffer; k = 0; for ( i = 0; i < nummaps; i++ ) { strcpy( shortname, COM_Parse( &s ) ); l = strlen(shortname); #if defined WIN32_VARIANT for (j=0 ; j8) count = 8; for(i=0;icurvalue; count = 8; if(!strcmp(f->generic.name, "...empty slot")) { //open the bot menu M_Menu_AddBots_f(); for(i = 0; i < 8; i++) { if(!strcmp(s_bots_bot_action[i].generic.name, "...empty slot")) { //clear it, it's slot is empty strcpy(bot[i].name, "...empty slot"); bot[i].userinfo[0] = 0; count--; } } } else { f->generic.name = "...empty slot"; //clear the bot out of the struct...hmmm...kinda hokey, but - need to know which slot for(i = 0; i < 8; i++) { if(!strcmp(s_bots_bot_action[i].generic.name, "...empty slot")) { //clear it, it's slot is empty strcpy(bot[i].name, "...empty slot"); bot[i].userinfo[0] = 0; count--; } } } //write out bot file if(s_rules_box.curvalue == 1 || s_rules_box.curvalue == 4 || s_rules_box.curvalue == 5) { // team game strcpy( stem, "team" ); } else { // non-team, bots per map strcpy( stem, strchr( mapnames[s_startmap_list.curvalue], '\n' ) + 1 ); for(i = 0; i < strlen(stem); i++) stem[i] = tolower( stem[i] ); } Com_sprintf( relative_path, sizeof(relative_path), BOT_GAMEDATA"/%s.tmp", stem ); FS_FullWritePath( bot_filename, sizeof(bot_filename), relative_path ); if((pOut = fopen(bot_filename, "wb" )) == NULL) { Com_DPrintf("BotAction: failed fopen for write: %s\n", bot_filename ); return; // bail } szr = fwrite(&count,sizeof (int),1,pOut); // Write number of bots for (i = 7; i > -1; i--) { if(strcmp(bot[i].name, "...empty slot")) szr = fwrite(bot[i].userinfo,sizeof (char) * MAX_INFO_STRING,1,pOut); } fclose(pOut); return; } /* ============================================================================= ADDRESS BOOK MENU ============================================================================= */ #define NUM_ADDRESSBOOK_ENTRIES 9 static menuframework_s s_addressbook_menu; static char s_addressbook_cvarnames[NUM_ADDRESSBOOK_ENTRIES][20]; static menufield_s s_addressbook_fields[NUM_ADDRESSBOOK_ENTRIES]; static void M_Menu_AddressBook_f (void) { int i; s_addressbook_menu.nitems = 0; for ( i = 0; i < NUM_ADDRESSBOOK_ENTRIES; i++ ) { cvar_t *adr; Com_sprintf( s_addressbook_cvarnames[i], sizeof( s_addressbook_cvarnames[i] ), "adr%d", i ); adr = Cvar_Get( s_addressbook_cvarnames[i], "", CVAR_ARCHIVE ); s_addressbook_fields[i].generic.type = MTYPE_FIELD; s_addressbook_fields[i].generic.callback = StrFieldCallback; s_addressbook_fields[i].generic.localstrings[0] = &s_addressbook_cvarnames[i][0]; s_addressbook_fields[i].cursor = strlen (adr->string); s_addressbook_fields[i].generic.visible_length = LONGINPUT_SIZE; strcpy( s_addressbook_fields[i].buffer, adr->string ); Menu_AddItem( &s_addressbook_menu, &s_addressbook_fields[i] ); } Menu_AutoArrange (&s_addressbook_menu); Menu_Center (&s_addressbook_menu); M_PushMenu_Defaults (s_addressbook_menu); } /* ============================================================================= PLAYER RANKING MENU ============================================================================= */ static menuframework_s s_playerranking_screen; static menuframework_s s_playerranking_menu; static menuaction_s s_playerranking_title; static menuaction_s s_playerranking_ttheader; static menuaction_s s_playerranking_topten[10]; char rank[32]; char fragrate[32]; char playername[64]; // a print field, not just name char totaltime[32]; char totalfrags[32]; char topTenList[10][64]; static void M_Menu_PlayerRanking_f (void) { extern cvar_t *name; PLAYERSTATS player; PLAYERSTATS topTenPlayers[10]; int i; setup_window (s_playerranking_screen, s_playerranking_menu, "PLAYER RANKINGS"); Q_strncpyz2( player.playername, name->string, sizeof(player.playername) ); player.totalfrags = player.totaltime = player.ranking = 0; player = getPlayerRanking ( player ); Com_sprintf(playername, sizeof(playername), "Name: %s", player.playername); if(player.ranking > 0) Com_sprintf(rank, sizeof(rank), "Rank: ^1%i", player.ranking); else Com_sprintf(rank, sizeof(rank), "Rank: ^1Unranked"); if ( player.totaltime > 1.0f ) Com_sprintf(fragrate, sizeof(fragrate), "Frag Rate: %6.2f", (float)(player.totalfrags)/(player.totaltime - 1.0f) ); else Com_sprintf(fragrate, sizeof(fragrate), "Frag Rate: 0" ); Com_sprintf(totalfrags, sizeof(totalfrags), "Total Frags: ^1%i", player.totalfrags); Com_sprintf(totaltime, sizeof(totaltime), "Total Time: %6.2f", player.totaltime - 1.0f); s_playerranking_title.generic.type = MTYPE_ACTION; s_playerranking_title.generic.name = "Player Ranking and Stats"; s_playerranking_title.generic.flags = QMF_RIGHT_COLUMN; Menu_AddItem( &s_playerranking_menu, &s_playerranking_title ); add_text(s_playerranking_menu, playername, QMF_RIGHT_COLUMN); add_text(s_playerranking_menu, rank, QMF_RIGHT_COLUMN); add_text(s_playerranking_menu, fragrate, QMF_RIGHT_COLUMN); add_text(s_playerranking_menu, totalfrags, QMF_RIGHT_COLUMN); add_text(s_playerranking_menu, totaltime, QMF_RIGHT_COLUMN); s_playerranking_ttheader.generic.type = MTYPE_ACTION; s_playerranking_ttheader.generic.name = "Top Ten Players"; s_playerranking_ttheader.generic.flags = QMF_RIGHT_COLUMN; Menu_AddItem (&s_playerranking_menu, &s_playerranking_ttheader); for(i = 0; i < 10; i++) { topTenPlayers[i].totalfrags = topTenPlayers[i].totaltime = topTenPlayers[i].ranking = 0; topTenPlayers[i] = getPlayerByRank ( i+1, topTenPlayers[i] ); if(i < 9) Com_sprintf(topTenList[i], sizeof(topTenList[i]), "Rank: ^1%i %s", topTenPlayers[i].ranking, topTenPlayers[i].playername); else Com_sprintf(topTenList[i], sizeof(topTenList[i]), "Rank:^1%i %s", topTenPlayers[i].ranking, topTenPlayers[i].playername); s_playerranking_topten[i].generic.type = MTYPE_TEXT; s_playerranking_topten[i].generic.name = topTenList[i]; s_playerranking_topten[i].generic.flags = QMF_RIGHT_COLUMN; Menu_AddItem( &s_playerranking_menu, &s_playerranking_topten[i] ); } M_PushMenu_Defaults (s_playerranking_screen); } /* ============================================================================= PLAYER CONFIG MENU ============================================================================= */ typedef struct { menucommon_s generic; const char *name; const char *skin; float w, h; float mframe, yaw; } menumodel_s; static menuvec2_t PlayerModelSizeFunc (void *_self, FNT_font_t font) { menuvec2_t ret; menumodel_s *self = (menumodel_s*) _self; ret.x = (self->w+2)*font->size; ret.y = (self->h+2)*font->size; return ret; } static void PlayerModelDrawFunc (void *_self, FNT_font_t font) { refdef_t refdef; char scratch[MAX_OSPATH]; FILE *modelfile; int i; extern float CalcFov( float fov_x, float w, float h ); float scale; entity_t entity[3]; menumodel_s *self = (menumodel_s*) _self; self->mframe += cls.frametime*150; if ( self->mframe > 390 ) self->mframe = 10; if ( self->mframe < 10) self->mframe = 10; self->yaw += cls.frametime*50; if (self->yaw > 360) self->yaw = 0; scale = (float)(viddef.height)/600; memset( &refdef, 0, sizeof( refdef ) ); refdef.width = self->w*font->size; refdef.height = self->h*font->size; refdef.x = Item_GetX(*self); refdef.y = Item_GetY(*self); refdef.x -= refdef.width; Menu_DrawBox (refdef.x, refdef.y, refdef.width, refdef.height, 1, NULL, "menu/sm_"); refdef.width -= font->size; refdef.height -= font->size; refdef.fov_x = 35; refdef.fov_y = CalcFov( refdef.fov_x, refdef.width, refdef.height ); refdef.time = cls.realtime*0.001; memset( &entity, 0, sizeof( entity ) ); Com_sprintf( scratch, sizeof( scratch ), "players/%s/tris.md2", self->name ); entity[0].model = R_RegisterModel( scratch ); Com_sprintf( scratch, sizeof( scratch ), "players/%s/%s.jpg", self->name, self->skin ); entity[0].skin = R_RegisterSkin( scratch ); entity[0].flags = RF_FULLBRIGHT | RF_MENUMODEL; Com_sprintf( scratch, sizeof( scratch ), "players/%s/weapon.md2", self->name ); entity[1].model = R_RegisterModel( scratch ); Com_sprintf( scratch, sizeof( scratch ), "players/%s/weapon.tga", self->name ); entity[1].skin = R_RegisterSkin( scratch ); entity[1].flags = RF_FULLBRIGHT | RF_MENUMODEL; refdef.num_entities = 2; //if a helmet or other special device Com_sprintf( scratch, sizeof( scratch ), "players/%s/helmet.md2", self->name ); FS_FOpenFile( scratch, &modelfile ); if ( modelfile ) { fclose(modelfile); entity[2].model = R_RegisterModel( scratch ); Com_sprintf( scratch, sizeof( scratch ), "players/%s/helmet.tga", self->name ); entity[2].skin = R_RegisterSkin( scratch ); entity[2].flags = RF_FULLBRIGHT | RF_TRANSLUCENT | RF_MENUMODEL; entity[2].alpha = 0.4; refdef.num_entities = 3; } for (i = 0; i < refdef.num_entities; i++) { // seems a little odd to use frame-1 for oldframe and frame%1 for // backlerp, but it works out entity[i].frame = (int)(self->mframe/10); entity[i].oldframe = (int)(self->mframe/10) - 1; entity[i].backlerp = (float)((int)self->mframe%10)/10.0f; entity[i].angles[1] = (int)self->yaw; VectorSet (entity[i].origin, 80, 0, -5); VectorCopy (entity[i].origin, entity[i].oldorigin); } refdef.areabits = 0; refdef.entities = entity; refdef.lightstyles = 0; refdef.rdflags = RDF_NOWORLDMODEL; R_RenderFramePlayerSetup( &refdef ); } static menuframework_s s_player_config_menu; static menufield_s s_player_name_field; static menuframework_s s_player_password_submenu; static menuframework_s s_player_password_field_submenu; static menufield_s s_player_password_field; static menuframework_s s_player_skin_submenu; static menuframework_s s_player_skin_controls_submenu; static menulist_s s_player_model_box; static menulist_s s_player_skin_box; static menuitem_s s_player_thumbnail; static menuframework_s s_player_skin_preview_submenu; static menumodel_s s_player_skin_preview; #define MAX_DISPLAYNAME 16 #define MAX_PLAYERMODELS 1024 typedef struct { int nskins; char **skindisplaynames; char displayname[MAX_DISPLAYNAME]; char directory[MAX_OSPATH]; } playermodelinfo_s; static playermodelinfo_s s_pmi[MAX_PLAYERMODELS]; static char *s_pmnames[MAX_PLAYERMODELS]; static int s_numplayermodels = 0; static void ModelCallback (void *unused) { s_player_skin_box.itemnames = (const char **) s_pmi[s_player_model_box.curvalue].skindisplaynames; s_player_skin_box.curvalue = 0; Menu_ActivateItem ((menuitem_s *)&s_player_skin_box); } static void SkinCallback (void *unused) { char scratch[MAX_QPATH]; Com_sprintf( scratch, sizeof( scratch ), "%s/%s", s_pmi[s_player_model_box.curvalue].directory, s_pmi[s_player_model_box.curvalue].skindisplaynames[s_player_skin_box.curvalue] ); Cvar_Set( "skin", scratch ); } static qboolean IconOfSkinExists( char *skin, char **pcxfiles, int npcxfiles ) { int i; char scratch[1024]; strcpy( scratch, skin ); *strrchr( scratch, '.' ) = 0; strcat( scratch, "_i.tga" ); for ( i = 0; i < npcxfiles; i++ ) { if ( strcmp( pcxfiles[i], scratch ) == 0 ) return true; } strcpy( scratch, skin ); *strrchr( scratch, '.' ) = 0; strcat( scratch, "_i.jpg" ); for ( i = 0; i < npcxfiles; i++ ) { if ( strcmp( pcxfiles[i], scratch ) == 0 ) return true; } return false; } static void PlayerConfig_ScanDirectories( void ) { char scratch[1024]; int ndirs = 0, npms = 0; char **dirnames; int i; // check if we need to do anything if (s_numplayermodels != 0) return; //get dirs from gamedir first. dirnames = FS_ListFilesInFS( "players/*.*", &ndirs, SFF_SUBDIR, 0 ); if ( !dirnames ) return; /* ** go through the subdirectories */ npms = ndirs; if ( npms > MAX_PLAYERMODELS ) npms = MAX_PLAYERMODELS; for ( i = 0; i < npms; i++ ) { int k, s; char *a, *b, *c; char **pcxnames; char **skinnames; int npcxfiles; int nskins = 0; if ( dirnames[i] == 0 ) continue; // verify the existence of tris.md2 strcpy( scratch, dirnames[i] ); strcat( scratch, "/tris.md2" ); if (!FS_FileExists(scratch)) { //try for tris.iqm if no md2 strcpy( scratch, dirnames[i] ); strcat( scratch, "/tris.iqm" ); if (!FS_FileExists(scratch)) { free( dirnames[i] ); dirnames[i] = 0; continue; } } // verify the existence of at least one skin(note, do not mix .tga and .jpeg) strcpy( scratch, dirnames[i] ); strcat( scratch, "/*.jpg" ); pcxnames = FS_ListFilesInFS( scratch, &npcxfiles, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM ); if(!pcxnames) { // check for .tga, though this is no longer used for current models strcpy( scratch, dirnames[i] ); strcat( scratch, "/*.tga" ); pcxnames = FS_ListFilesInFS( scratch, &npcxfiles, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM ); } if ( !pcxnames ) { free( dirnames[i] ); dirnames[i] = 0; continue; } // count valid skins, which consist of a skin with a matching "_i" icon for ( k = 0; k < npcxfiles; k++ ) { if ( !strstr( pcxnames[k], "_i.tga" ) || !strstr( pcxnames[k], "_i.jpg" )) { if ( IconOfSkinExists( pcxnames[k], pcxnames, npcxfiles) ) { nskins++; } } } if ( !nskins ) continue; skinnames = malloc( sizeof( char * ) * ( nskins + 1 ) ); memset( skinnames, 0, sizeof( char * ) * ( nskins + 1 ) ); // copy the valid skins for ( s = 0, k = 0; k < npcxfiles; k++ ) { char *a, *b, *c; if ( !strstr( pcxnames[k], "_i.tga" ) ) { if ( IconOfSkinExists( pcxnames[k], pcxnames, npcxfiles ) ) { a = strrchr( pcxnames[k], '/' ); b = strrchr( pcxnames[k], '\\' ); if ( a > b ) c = a; else c = b; strcpy( scratch, c + 1 ); if ( strrchr( scratch, '.' ) ) *strrchr( scratch, '.' ) = 0; skinnames[s] = _strdup( scratch ); s++; } } } // at this point we have a valid player model s_pmi[s_numplayermodels].nskins = nskins; s_pmi[s_numplayermodels].skindisplaynames = skinnames; // make short name for the model a = strrchr( dirnames[i], '/' ); b = strrchr( dirnames[i], '\\' ); if ( a > b ) c = a; else c = b; strncpy( s_pmi[s_numplayermodels].displayname, c + 1, MAX_DISPLAYNAME-1 ); strcpy( s_pmi[s_numplayermodels].directory, c + 1 ); FS_FreeFileList( pcxnames, npcxfiles ); s_numplayermodels++; } if ( dirnames ) free( dirnames ); } static int pmicmpfnc( const void *_a, const void *_b ) { const playermodelinfo_s *a = ( const playermodelinfo_s * ) _a; const playermodelinfo_s *b = ( const playermodelinfo_s * ) _b; /* ** sort by male, female, then alphabetical */ if ( strcmp( a->directory, "male" ) == 0 ) return -1; else if ( strcmp( b->directory, "male" ) == 0 ) return 1; if ( strcmp( a->directory, "female" ) == 0 ) return -1; else if ( strcmp( b->directory, "female" ) == 0 ) return 1; return strcmp( a->directory, b->directory ); } static void PlayerPicDrawFunc (void *_self, FNT_font_t font) { int x, y; char scratch[MAX_QPATH]; menuitem_s *self = (menuitem_s *)_self; x = Item_GetX (*self); y = Item_GetY (*self); Com_sprintf( scratch, sizeof( scratch ), "/players/%s_i.tga", Cvar_VariableString ("skin") ); Draw_StretchPic (x, y, font->size*5, font->size*5, scratch); } static void PasswordCallback (void *_self) { menufield_s *self = (menufield_s *)_self; //was the password changed? if(strcmp("********", self->buffer)) { //if this is a virgin password, don't change, just authenticate if(!strcmp(stats_password->string, "password")) { Cvar_FullSet( "stats_password", self->buffer, CVAR_PROFILE); stats_password = Cvar_Get("stats_password", "password", CVAR_PROFILE); Cvar_FullSet( "stats_pw_hashed", "0", CVAR_PROFILE); currLoginState.validated = false; STATS_RequestVerification(); } else { Cvar_FullSet( "stats_password", self->buffer, CVAR_PROFILE); stats_password = Cvar_Get("stats_password", "password", CVAR_PROFILE); Cvar_FullSet( "stats_pw_hashed", "0", CVAR_PROFILE); STATS_RequestPwChange(); } } } void PConfigApplyFunc (void *self) { Menu_ApplyMenu (Menu_GetItemTree ((menuitem_s *)self)); } static menuvec2_t PlayerConfigModelSizeFunc (void *_self, FNT_font_t font) { menuvec2_t ret; menumodel_s *self = (menumodel_s*) _self; ret.x = 20*font->size; ret.y = 29*font->size; self->w = (float)ret.x/(float)font->size; self->h = (float)ret.y/(float)font->size; return ret; } void PlayerConfig_MenuInit( void ) { extern cvar_t *name; // extern cvar_t *team; // unused // extern cvar_t *skin; // unused char currentdirectory[1024]; char currentskin[1024]; int i = 0; float scale; int currentdirectoryindex = 0; int currentskinindex = 0; cvar_t *hand = Cvar_Get( "hand", "0", CVAR_USERINFO | CVAR_ARCHIVE ); scale = (float)(viddef.height)/600; PlayerConfig_ScanDirectories(); if (s_numplayermodels == 0) return; if ( hand->value < 0 || hand->value > 2 ) Cvar_SetValue( "hand", 0 ); Q_strncpyz( currentdirectory, Cvar_VariableString ("skin"), sizeof(currentdirectory)-1); if ( strchr( currentdirectory, '/' ) ) { strcpy( currentskin, strchr( currentdirectory, '/' ) + 1 ); *strchr( currentdirectory, '/' ) = 0; } else if ( strchr( currentdirectory, '\\' ) ) { strcpy( currentskin, strchr( currentdirectory, '\\' ) + 1 ); *strchr( currentdirectory, '\\' ) = 0; } else { strcpy( currentdirectory, "martianenforcer" ); strcpy( currentskin, "default" ); } qsort( s_pmi, s_numplayermodels, sizeof( s_pmi[0] ), pmicmpfnc ); memset( s_pmnames, 0, sizeof( s_pmnames ) ); for ( i = 0; i < s_numplayermodels; i++ ) { s_pmnames[i] = s_pmi[i].displayname; if ( Q_strcasecmp( s_pmi[i].directory, currentdirectory ) == 0 ) { int j; currentdirectoryindex = i; for ( j = 0; j < s_pmi[i].nskins; j++ ) { if ( Q_strcasecmp( s_pmi[i].skindisplaynames[j], currentskin ) == 0 ) { currentskinindex = j; break; } } } } setup_window (s_player_config_screen, s_player_config_menu, "PLAYER SETUP"); s_player_name_field.generic.type = MTYPE_FIELD; s_player_name_field.generic.name = "name"; s_player_name_field.generic.localstrings[0] = "name"; s_player_name_field.generic.callback = StrFieldCallback; s_player_name_field.length = 20; s_player_name_field.generic.visible_length = LONGINPUT_SIZE; Q_strncpyz2( s_player_name_field.buffer, name->string, sizeof(s_player_name_field.buffer) ); s_player_name_field.cursor = strlen( s_player_name_field.buffer ); // Horizontal submenu with two items. The first is a password field. The // second is an apply button for the password. s_player_password_submenu.generic.type = MTYPE_SUBMENU; // Keep the password field horizontally lined up: s_player_password_submenu.generic.flags = QMF_SNUG_LEFT; s_player_password_submenu.navagable = true; s_player_password_submenu.horizontal = true; s_player_password_submenu.nitems = 0; // sub-submenu for the password field. Purely for formatting/layout // purposes. s_player_password_field_submenu.generic.type = MTYPE_SUBMENU; s_player_password_field_submenu.navagable = true; s_player_password_field_submenu.horizontal = true; s_player_password_field_submenu.nitems = 0; // keep the password field horizontally lined up: LINK (s_player_config_menu.lwidth, s_player_password_field_submenu.lwidth); // keep it vertically centered on the apply button LINK (s_player_password_submenu.height, s_player_password_field_submenu.height); s_player_password_field.generic.type = MTYPE_FIELD; s_player_password_field.generic.name = "password"; s_player_password_field.generic.flags = QMF_ACTION_WAIT; s_player_password_field.generic.callback = PasswordCallback; s_player_password_field.length = 20; s_player_password_field.generic.visible_length = LONGINPUT_SIZE; s_player_password_field.generic.statusbar = "COR Entertainment is not responsible for lost or stolen passwords"; Q_strncpyz2( s_player_password_field.buffer, "********", sizeof(s_player_password_field.buffer) ); s_player_password_field.cursor = 0; Menu_AddItem( &s_player_password_submenu, &s_player_password_field_submenu); Menu_AddItem( &s_player_password_field_submenu, &s_player_password_field); add_action (s_player_password_submenu, "Apply", PConfigApplyFunc, 0); // Horizontal submenu with two items. The first is a submenu with the // model/skin controls. The second is just a thumbnail of the current // selection. s_player_skin_submenu.generic.type = MTYPE_SUBMENU; // Keep the model/skin controls horizontally lined up: s_player_skin_submenu.generic.flags = QMF_SNUG_LEFT; s_player_skin_submenu.navagable = true; s_player_skin_submenu.horizontal = true; s_player_skin_submenu.nitems = 0; // Vertical sub-submenu with two items. The first is the model control. // The second is the skin control. s_player_skin_controls_submenu.generic.type = MTYPE_SUBMENU; s_player_skin_controls_submenu.navagable = true; s_player_skin_controls_submenu.nitems = 0; // keep the model/skin controls horizontally lined up: LINK (s_player_config_menu.lwidth, s_player_skin_controls_submenu.lwidth); s_player_model_box.generic.type = MTYPE_SPINCONTROL; s_player_model_box.generic.name = "model"; s_player_model_box.generic.callback = ModelCallback; s_player_model_box.curvalue = currentdirectoryindex; s_player_model_box.itemnames = (const char **) s_pmnames; s_player_skin_box.generic.type = MTYPE_SPINCONTROL; s_player_skin_box.generic.callback = SkinCallback; s_player_skin_box.generic.name = "skin"; s_player_skin_box.curvalue = currentskinindex; s_player_skin_box.itemnames = (const char **) s_pmi[currentdirectoryindex].skindisplaynames; Menu_AddItem( &s_player_skin_controls_submenu, &s_player_model_box ); if ( s_player_skin_box.itemnames ) Menu_AddItem( &s_player_skin_controls_submenu, &s_player_skin_box ); Menu_AddItem (&s_player_skin_submenu, &s_player_skin_controls_submenu); // TODO: click this to cycle skins s_player_thumbnail.generic.type = MTYPE_NOT_INTERACTIVE; VectorSet(s_player_thumbnail.generic.localints, 5, 5, 0); s_player_thumbnail.generic.itemsizecallback = PicSizeFunc; s_player_thumbnail.generic.itemdraw = PlayerPicDrawFunc; Menu_AddItem (&s_player_skin_submenu, &s_player_thumbnail); s_player_skin_preview_submenu.generic.type = MTYPE_SUBMENU; s_player_skin_preview_submenu.generic.flags = QMF_SNUG_LEFT; s_player_skin_preview_submenu.nitems = 0; Menu_AddItem( &s_player_config_menu, &s_player_name_field ); Menu_AddItem( &s_player_config_menu, &s_player_password_submenu); Menu_AddItem( &s_player_config_menu, &s_player_skin_submenu); s_player_skin_preview.generic.type = MTYPE_NOT_INTERACTIVE; s_player_skin_preview.generic.namesizecallback = PlayerConfigModelSizeFunc; s_player_skin_preview.generic.namedraw = PlayerModelDrawFunc; Menu_AddItem (&s_player_config_menu, &s_player_skin_preview_submenu); Menu_AddItem (&s_player_skin_preview_submenu, &s_player_skin_preview); //add in shader support for player models, if the player goes into the menu before entering a //level, that way we see the shaders. We only want to do this if they are NOT loaded yet. scriptsloaded = Cvar_Get("scriptsloaded", "0", 0); if(!scriptsloaded->value) { Cvar_SetValue("scriptsloaded", 1); //this needs to be reset on vid_restart RS_ScanPathForScripts(); RS_LoadScript("scripts/models.rscript"); RS_LoadScript("scripts/caustics.rscript"); RS_LoadSpecialScripts(); } } void PlayerConfig_MenuDraw (menuframework_s *dummy, menuvec2_t offset) { if(!PLAYER_NAME_UNIQUE) s_player_config_menu.statusbar = "You must change your player name before joining a server!"; if ( s_pmi[s_player_model_box.curvalue].skindisplaynames ) { s_player_skin_preview.name = s_pmi[s_player_model_box.curvalue].directory; s_player_skin_preview.skin = s_pmi[s_player_model_box.curvalue].skindisplaynames[s_player_skin_box.curvalue]; Screen_Draw (&s_player_config_screen, offset); } } void M_Menu_PlayerConfig_f (void) { PlayerConfig_MenuInit(); M_PushMenu (PlayerConfig_MenuDraw, Default_MenuKey, &s_player_config_screen); } /* ======================================================================= ALIEN ARENA TACTICAL MENU ======================================================================= */ static menuframework_s s_tactical_screen; static menuaction_s s_tactical_title_action; #define num_tactical_teams 2 #define num_tactical_classes 3 static const char *tactical_skin_names[num_tactical_teams][num_tactical_classes][2] = { //ALIEN CLASSES { {"Enforcer", "martianenforcer"}, {"Warrior", "martianwarrior"}, {"Overlord", "martianoverlord"} }, //HUMAN CLASSES { {"Lauren", "lauren"}, {"Enforcer", "enforcer"}, {"Commander", "commander"} } }; static const char *tactical_team_names[num_tactical_teams] = { "ALIENS", "HUMANS" }; static menuframework_s s_tactical_menus[num_tactical_teams]; static menuframework_s s_tactical_columns[num_tactical_teams][num_tactical_classes]; static menuaction_s s_tactical_skin_actions[num_tactical_teams][num_tactical_classes]; static menumodel_s s_tactical_skin_previews[num_tactical_teams][num_tactical_classes]; static void TacticalJoinFunc ( void *item ) { menuaction_s *self; char buffer[128]; self = (menuaction_s*)item; cl.tactical = true; //set skin and model Com_sprintf (buffer, sizeof(buffer), "%s/default", self->generic.localstrings[0]); Cvar_Set ("skin", buffer); //join server Com_sprintf (buffer, sizeof(buffer), "connect %s\n", NET_AdrToString (mservers[serverindex].local_server_netadr)); Cbuf_AddText (buffer); M_ForceMenuOff (); } static void TacticalScreen_Draw (menuframework_s *screen, menuvec2_t offset) { FNT_font_t font = FNT_AutoGet (CL_menuFont); screen->x = offset.x; Menu_AutoArrange (screen); // force it to use up the whole screen CHASELINK(s_tactical_screen.rwidth) = viddef.width - CHASELINK(s_tactical_screen.lwidth); Menu_Draw (screen, font); } static void M_Menu_Tactical_f (void) { extern cvar_t *name; float scale; int i, j; scale = (float)(viddef.height)/600; for (i = 0; i < num_tactical_teams; i++) { // kinda hacky but this is the only place we have two windows in one // screen setup_nth_window (s_tactical_screen, i, s_tactical_menus[i], tactical_team_names[i]); s_tactical_menus[i].horizontal = true; for (j = 0; j < num_tactical_classes; j++) { s_tactical_columns[i][j].generic.type = MTYPE_SUBMENU; s_tactical_columns[i][j].nitems = 0; s_tactical_columns[i][j].navagable = true; Menu_AddItem (&s_tactical_menus[i], &s_tactical_columns[i][j]); s_tactical_skin_previews[i][j].generic.type = MTYPE_NOT_INTERACTIVE; s_tactical_skin_previews[i][j].generic.namesizecallback = PlayerModelSizeFunc; s_tactical_skin_previews[i][j].generic.namedraw = PlayerModelDrawFunc; s_tactical_skin_previews[i][j].name = tactical_skin_names[i][j][1]; s_tactical_skin_previews[i][j].skin = "default"; s_tactical_skin_previews[i][j].h = 14; s_tactical_skin_previews[i][j].w = 10; Menu_AddItem (&s_tactical_columns[i][j], &s_tactical_skin_previews[i][j]); s_tactical_skin_actions[i][j].generic.type = MTYPE_ACTION; s_tactical_skin_actions[i][j].generic.flags = QMF_BUTTON; s_tactical_skin_actions[i][j].generic.name = tactical_skin_names[i][j][0]; s_tactical_skin_actions[i][j].generic.localstrings[0] = tactical_skin_names[i][j][1]; s_tactical_skin_actions[i][j].generic.callback = TacticalJoinFunc; Menu_AddItem (&s_tactical_columns[i][j], &s_tactical_skin_actions[i][j]); } } //add in shader support for player models, if the player goes into the menu before entering a //level, that way we see the shaders. We only want to do this if they are NOT loaded yet. scriptsloaded = Cvar_Get("scriptsloaded", "0", 0); if(!scriptsloaded->value) { Cvar_SetValue("scriptsloaded", 1); //this needs to be reset on vid_restart RS_ScanPathForScripts(); RS_LoadScript("scripts/models.rscript"); RS_LoadScript("scripts/caustics.rscript"); RS_LoadSpecialScripts(); } M_PushMenu (TacticalScreen_Draw, Default_MenuKey, &s_tactical_screen); } /* ======================================================================= QUIT MENU ======================================================================= */ static menuframework_s s_quit_screen; static menuframework_s s_quit_menu; void quitActionNo (void *blah) { M_PopMenu(); } void quitActionYes (void *blah) { CL_Quit_f(); } static void M_Menu_Quit_f (void) { setup_window (s_quit_screen, s_quit_menu, "EXIT ALIEN ARENA"); add_text (s_quit_menu, "Are you sure?", 0); add_action (s_quit_menu, "Yes", quitActionYes, 0); add_action (s_quit_menu, "No", quitActionNo, 0); Menu_AutoArrange (&s_quit_screen); Menu_Center (&s_quit_screen); M_PushMenu_Defaults (s_quit_screen); } //============================================================================= /* Menu Subsystem */ /* ================= M_Init ================= */ void M_Init (void) { Cmd_AddCommand ("menu_main", M_Menu_Main_f); Cmd_AddCommand ("menu_quit", M_Menu_Quit_f); } /* ================================= Menu Mouse Cursor ================================= */ void refreshCursorLink (void) { Cursor_SelectItem (NULL); cursor.click_menuitem = NULL; } int Slider_CursorPositionX ( menuslider_s *s ) { float range; FNT_font_t font; font = FNT_AutoGet( CL_menuFont ); range = ( s->curvalue - s->minvalue ) / ( float ) ( s->maxvalue - s->minvalue ); if ( range < 0) range = 0; if ( range > 1) range = 1; return ( int )( font->width + RCOLUMN_OFFSET + (LONGINPUT_SIZE) * font->width * range ); } int newSliderValueForX (int x, menuslider_s *s) { float newValue; int newValueInt; FNT_font_t font; int pos; font = FNT_AutoGet( CL_menuFont ); pos = x - (font->width + RCOLUMN_OFFSET + CHASELINK(s->generic.x)) - Menu_GetCtrX(*(s->generic.parent)); newValue = ((float)pos)/((LONGINPUT_SIZE-1)*font->width); newValueInt = s->minvalue + newValue * (float)( s->maxvalue - s->minvalue ); return newValueInt; } void Slider_CheckSlide( menuslider_s *s ) { if ( s->curvalue > s->maxvalue ) s->curvalue = s->maxvalue; else if ( s->curvalue < s->minvalue ) s->curvalue = s->minvalue; if ( s->generic.callback ) s->generic.callback( s ); } void Menu_DragSlideItem (void) { menuslider_s *slider = ( menuslider_s * ) cursor.menuitem; slider->curvalue = newSliderValueForX(cursor.x, slider); Slider_CheckSlide ( slider ); } void Menu_ClickSlideItem (void) { int min, max; menuslider_s *slider = ( menuslider_s * ) cursor.menuitem; min = Item_GetX (*slider) + Slider_CursorPositionX(slider) - 4; max = Item_GetX (*slider) + Slider_CursorPositionX(slider) + 4; if (cursor.x < min) Menu_SlideItem (-1 ); if (cursor.x > max) Menu_SlideItem (1); } void Menu_DragVertScrollItem (void) { float scrollbar_pos; menuframework_s *menu = cursor.menuitem->generic.parent; scrollbar_pos = (float)cursor.y - menu->scroll_top; menu->yscroll = scrollbar_pos*menu->maxscroll/(menu->scroll_range-menu->scrollbar_size); if (menu->yscroll < 0) menu->yscroll = 0; if (menu->yscroll > menu->maxscroll) menu->yscroll = menu->maxscroll; } void M_Draw_Cursor (void) { Draw_Pic (cursor.x, cursor.y, "m_mouse_cursor"); } // draw all menus on screen void M_Draw (void) { if (cls.key_dest != key_menu) return; Draw_Fill (0, 0, viddef.width, viddef.height, RGBA(0, 0, 0, 1)); Menuscreens_Animate (); if (mstate.state == mstate_steady) Menu_DrawHighlight (); M_Draw_Cursor(); } // send key presses to the appropriate menu void M_Keydown (int key) { const char *s; if (mstate.state != mstate_steady) return; if (key == K_ESCAPE && mstate.active.num_layers > 0) { if ((s = layergroup_last(mstate.active).key (layergroup_last(mstate.active).screen, key))) S_StartLocalSound (s); return; } if (cursor.menulayer == -1) M_Main_Key (key); else if (activelayer(cursor.menulayer).key != NULL && (s = activelayer(cursor.menulayer).key (activelayer(cursor.menulayer).screen, key))) S_StartLocalSound (s); } // send mouse movement to the appropriate menu void M_Think_MouseCursor (void) { int coordidx; menuframework_s *m; char * sound = NULL; if (mstate.state != mstate_steady) return; coordidx = activelayer_coordidx (cursor.x); if (coordidx < 0) { CheckMainMenuMouse (); return; } if (cursor.buttondown[MOUSEBUTTON2] && cursor.buttonclicks[MOUSEBUTTON2] == 2 && !cursor.buttonused[MOUSEBUTTON2]) { M_PopMenu (); // we've "used" the click sequence and will begin another refreshCursorButton (MOUSEBUTTON2); S_StartLocalSound (menu_out_sound); return; } if (coordidx == mstate.active.num_layers) { if (cursor.mouseaction) cursor.menuitem = NULL; return; } if (coordidx != cursor.menulayer && cursor.mouseaction) Cursor_SelectMenu(activelayer(coordidx).screen); Menu_AssignCursor (activelayer(coordidx).screen); if (cursor.menuitem == NULL) return; m = cursor.menuitem->generic.parent; if (!m) return; if (cursor.buttondown[MOUSEBUTTON1] && !cursor.suppress_drag) { if (cursor.click_menuitem != NULL) Cursor_SelectItem (cursor.click_menuitem); else if (cursor.menuitem != NULL) cursor.click_menuitem = cursor.menuitem; } else cursor.click_menuitem = NULL; if (!cursor.buttondown[MOUSEBUTTON1]) cursor.suppress_drag = false; else if (!cursor.menuitem) cursor.suppress_drag = true; if (cursor.suppress_drag || cursor.menuitem == NULL) return; //MOUSE1 if (cursor.buttondown[MOUSEBUTTON1]) { if (cursor.menuitem->generic.type == MTYPE_SLIDER) { Menu_DragSlideItem (); } else if (cursor.menuitem->generic.type == MTYPE_VERT_SCROLLBAR) { Menu_DragVertScrollItem (); } else if (!cursor.buttonused[MOUSEBUTTON1]) { if (cursor.menuitem->generic.type == MTYPE_SPINCONTROL) Menu_SlideItem (1); else Menu_ActivateItem (cursor.menuitem); // we've "used" the click sequence and will begin another refreshCursorButton (MOUSEBUTTON1); sound = menu_move_sound; } } //MOUSE2 else if (cursor.buttondown[MOUSEBUTTON2] && !cursor.buttonused[MOUSEBUTTON2]) { if (cursor.menuitem->generic.type == MTYPE_SPINCONTROL) Menu_SlideItem (-1); else if (cursor.menuitem->generic.type == MTYPE_SLIDER) Menu_ClickSlideItem (); else return; // we've "used" the click sequence and will begin another refreshCursorButton (MOUSEBUTTON2); sound = menu_move_sound; } if ( sound ) S_StartLocalSound( sound ); } alien-arena-7.66+dfsg/source/client/cl_view.c0000600000175000017500000005670012161402010020164 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // cl_view.c -- player rendering positioning #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "client.h" //============= // // development tools for weapons // int gun_frame; struct model_s *gun_model; //============= int r_numgrasses; grass_t r_grasses[MAX_GRASSES]; int r_numbeams; beam_t r_beams[MAX_BEAMS]; extern cvar_t *cl_showPlayerNames; extern cvar_t *name; extern char map_music[260]; extern cvar_t *background_music; extern qboolean IsVisible(vec3_t org1,vec3_t org2); extern void R_VCFreeFrame(void); cvar_t *crosshair; cvar_t *cl_testparticles; cvar_t *cl_testentities; cvar_t *cl_testlights; cvar_t *cl_testblend; cvar_t *cl_stats; qboolean need_free_vbo; int r_numdlights; dlight_t r_dlights[MAX_DLIGHTS]; int r_numentities; entity_t r_entities[MAX_ENTITIES]; int r_numviewentities; entity_t r_viewentities[MAX_ENTITIES]; int r_numparticles; particle_t *r_particles[MAX_PARTICLES]; lightstyle_t r_lightstyles[MAX_LIGHTSTYLES]; char cl_weaponmodels[MAX_CLIENTWEAPONMODELS][MAX_QPATH]; int num_cl_weaponmodels; /* ==================== V_ClearScene Specifies the model that will be used as the world ==================== */ void V_ClearScene (void) { r_numdlights = 0; r_numentities = 0; r_numviewentities = 0; r_numparticles = 0; } /* ===================== V_AddEntity ===================== */ void V_AddEntity (entity_t *ent) { if (r_numentities >= MAX_ENTITIES) return; r_entities[r_numentities++] = *ent; } /* ===================== V_AddViewEntity ===================== */ void V_AddViewEntity (entity_t *ent) { if (r_numviewentities >= MAX_ENTITIES) return; r_viewentities[r_numviewentities++] = *ent; } /* ===================== V_AddParticle ===================== */ void V_AddParticle (particle_t *p) { if (r_numparticles >= MAX_PARTICLES) return; r_particles[r_numparticles++] = p; } /* ===================== V_AddLight ===================== */ extern cvar_t *gl_dynamic; void V_AddLight (vec3_t org, float intensity, float r, float g, float b) { dlight_t *dl; if (gl_dynamic->integer == 0) return; if (r_numdlights >= MAX_DLIGHTS) return; dl = &r_dlights[r_numdlights++]; VectorCopy (org, dl->origin); dl->intensity = intensity; dl->color[0] = r; dl->color[1] = g; dl->color[2] = b; } /* ===================== V_AddLightStyle ===================== */ void V_AddLightStyle (int style, float r, float g, float b) { lightstyle_t *ls; if (style < 0 || style > MAX_LIGHTSTYLES) Com_Error (ERR_DROP, "Bad light style %i", style); ls = &r_lightstyles[style]; ls->white = r+g+b; ls->rgb[0] = r; ls->rgb[1] = g; ls->rgb[2] = b; } /* ================ V_TestParticles If cl_testparticles is set, create 4096 particles in the view ================ */ void CL_LogoutEffect (vec3_t org, int type); void V_TestParticles (void) { vec3_t org; VectorMA (cl.refdef.vieworg, 128, cl.v_forward, org); CL_LogoutEffect (org, MZ_LOGOUT); } /* ================ V_TestEntities If cl_testentities is set, create 32 player models ================ */ void V_TestEntities (void) { int i, j; float f, r; entity_t *ent; r_numentities = 32; memset (r_entities, 0, sizeof(r_entities)); for (i=0 ; iorigin[j] = cl.refdef.vieworg[j] + cl.v_forward[j]*f + cl.v_right[j]*r; ent->model = cl.baseclientinfo.model; ent->skin = cl.baseclientinfo.skin; } } /* ================ V_TestLights If cl_testlights is set, create 32 lights models ================ */ void V_TestLights (void) { int i, j; float f, r; dlight_t *dl; r_numdlights = 32; memset (r_dlights, 0, sizeof(r_dlights)); for (i=0 ; iorigin[j] = cl.refdef.vieworg[j] + cl.v_forward[j]*f + cl.v_right[j]*r; dl->color[0] = ((i%6)+1) & 1; dl->color[1] = (((i%6)+1) & 2)>>1; dl->color[2] = (((i%6)+1) & 4)>>2; dl->intensity = 200; } } //=================================================================== /* ================= CL_PrepRefresh Call before entering a new level, or after changing dlls ================= */ qboolean needLoadingPlaque (void); extern int seconds, minutes; void CL_PrepRefresh ( void ) { char mapname[32]; int i, max; char name[MAX_QPATH]; float rotate; vec3_t axis; qboolean newPlaque = needLoadingPlaque(); loadingPercent = 0; rocketlauncher = 0; rocketlauncher_drawn = 0; smartgun = 0; smartgun_drawn = 0; disruptor = 0; disruptor_drawn = 0; flamethrower = 0; flamethrower_drawn = 0; beamgun = 0; beamgun_drawn = 0; chaingun = 0; chaingun_drawn = 0; vaporizer = 0; vaporizer_drawn = 0; quad = 0; quad_drawn = 0; haste = 0; haste_drawn = 0; sproing = 0; sproing_drawn = 0; inv = 0; inv_drawn = 0; adren = 0; adren_drawn = 0; numitemicons = 0; //reset clock seconds = minutes = 0; if (!cl.configstrings[CS_MODELS+1][0]) return; // no map loaded if (newPlaque) SCR_BeginLoadingPlaque(); loadingMessage = true; memset( loadingMessages , 0 , sizeof( loadingMessages ) ); Com_sprintf (loadingMessages[0][0], CL_LOADMSG_LENGTH, "Loading map..."); Com_sprintf (loadingMessages[1][0], CL_LOADMSG_LENGTH, "Loading models..."); Com_sprintf (loadingMessages[2][0], CL_LOADMSG_LENGTH, "Loading pics..."); Com_sprintf (loadingMessages[3][0], CL_LOADMSG_LENGTH, "Loading clients..."); // let the render dll load the map strcpy (mapname, cl.configstrings[CS_MODELS+1] + 5); // skip "maps/" mapname[strlen(mapname)-4] = 0; // cut off ".bsp" // register models, pics, and skins //this was moved here, to prevent having a pic loaded over and over again, which was //totally killing performance after a dozen or so maps. // 2010-10 modified on suspicion of affecting possible compiler bug. see R_RegisterPic() map_pic_loaded = false; if ( R_RegisterPic( va("/levelshots/%s.pcx", mapname)) != NULL ) { map_pic_loaded = true; } Com_Printf ("Map: %s\r", mapname); Com_sprintf( loadingMessages[0][1] , CL_LOADMSG_LENGTH , "^3in progress" ); SCR_UpdateScreen (); R_BeginRegistration (mapname); Com_Printf (" \r"); Com_sprintf (loadingMessages[0][1], CL_LOADMSG_LENGTH, "^2done"); loadingPercent += 20; // precache status bar pics Com_Printf ("pics\r"); SCR_UpdateScreen (); SCR_TouchPics (); Com_Printf (" \r"); num_cl_weaponmodels = 1; strcpy(cl_weaponmodels[0], "weapon.md2"); for (i=1, max=0 ; ivalue) R_RegisterCustomPlayerModels(); Com_sprintf (loadingMessages[1][1], CL_LOADMSG_LENGTH, "^2done"); Com_Printf ("images\r", i); SCR_UpdateScreen (); for (i=1, max=0 ; i 179) Com_Error (ERR_DROP, "Bad fov: %f", fov_x); x = width/tanf(fov_x/360*M_PI); a = atan (height/x); a = a*360/M_PI; return a; } /* ================= SCR_DrawCrosshair ================= */ extern cvar_t *hand; void SCR_DrawCrosshair (refdef_t *fd) { int x, y, crosshairposition; if (!strcmp(crosshair->string, "none")) return; if (crosshair->modified) { crosshair->modified = false; SCR_TouchPics (); } if (!crosshair_pic[0]) return; x = fd->x + ((fd->width - crosshair_width)>>1); y = fd->y + ((fd->height - crosshair_height)>>1); // get rid of the old crosshair adjustment built into the texture x -= 4; y -= 4; // add a new crosshair adjustment offset crosshairposition = cl.frame.playerstate.stats[STAT_FLAGS] & STAT_FLAGS_CROSSHAIRPOSITION; if (crosshairposition != STAT_FLAGS_CROSSHAIRCENTER) { double x_offs, y_offs; switch (crosshairposition) { default: // other crosshair positions reserved for future use case STAT_FLAGS_CROSSHAIRPOS1: // use the original default x_offs = y_offs = 4.0; break; case STAT_FLAGS_CROSSHAIRPOS2: x_offs = 2.0; y_offs = 3.0; break; } y_offs *= (double)fd->height/480.0; x_offs *= (double)fd->width/640.0; if (y_offs-(int)y_offs >= 0.5) y_offs = (int)y_offs + 1; if (x_offs-(int)x_offs >= 0.5) x_offs = (int)x_offs + 1; if (hand->integer == 1) x_offs = -x_offs; else if (hand->integer == 2) x_offs = 0; x += x_offs; y += y_offs; } Draw_Pic (x, y, crosshair_pic); } qboolean InFront (vec3_t target) { vec3_t vec; float dot; vec3_t forward; AngleVectors (cl.refdef.viewangles, forward, NULL, NULL); VectorSubtract (target, cl.refdef.vieworg, vec); VectorNormalize (vec); dot = DotProduct (vec, forward); if (dot > 0.3) return true; return false; } //============== //SCR_DrawPlayerNamesCenter // shows player names at center of screen //============== void SCR_DrawPlayerNamesCenter( void ) { static vec3_t mins = { -8, -8, -8 }; static vec3_t maxs = { 8, 8, 8 }; FNT_font_t font; struct FNT_window_s box; int i; centity_t * cent; float dist, mindist; trace_t trace; vec3_t vecdist; vec3_t temp; vec3_t axis[3]; int closest; if( !cl_showPlayerNames->integer ) return; mindist = 1000; closest = 0; for( i = 0; i < MAX_CLIENTS; i++ ) { cent = cl_entities + i + 1; if( !cent->current.modelindex ) continue; if(!strcmp(cl.clientinfo[i].name, name->string)) continue; trace = CL_Trace ( cl.refdef.vieworg, mins, maxs, cent->current.origin, -1, MASK_PLAYERSOLID, true, NULL); if (trace.fraction != 1.0) continue; VectorSubtract(cent->current.origin, cl.refdef.vieworg, vecdist); dist = VectorLength(vecdist); if (dist >= 1000) continue; if(dist < mindist && (strlen(cl.clientinfo[i].name) > 1) && InFront(cent->current.origin) ) { mindist = dist; closest = i; } VectorSubtract (cent->current.origin, cl.refdef.vieworg, temp); VectorNormalize (temp); AngleVectors(cl.refdef.viewangles, axis[0], axis[1], axis[2]); if (DotProduct (temp, axis[0]) < 0) continue; } if (!closest) { return; } font = FNT_AutoGet( CL_gameFont ); box.x = (int)( ( cl.refdef.width - 200 ) / 2 ); box.y = (int)( cl.refdef.height / 1.8 ); box.width = 400; box.height = 0; FNT_BoundedPrint( font , cl.clientinfo[closest].name , FNT_CMODE_QUAKE_SRS , FNT_ALIGN_CENTER , &box , FNT_colors[ 2 ] ); } //============== //SCR_DrawPlayerNames // shows player names at their feets. //============== extern void R_TransformVectorToScreen( refdef_t *rd, vec3_t in, vec2_t out ); void SCR_DrawPlayerNames( void ) { // static vec4_t whiteTransparent = { 1.0f, 1.0f, 1.0f, 0.5f }; FNT_font_t font; int i; centity_t * cent; float dist; trace_t trace; vec2_t screen_pos; vec3_t vecdist; vec3_t temp; vec3_t axis[3]; static vec3_t mins = { -4, -4, -4 }; static vec3_t maxs = { 4, 4, 4 }; font = FNT_AutoGet( CL_gameFont ); for( i = 0; i < MAX_CLIENTS; i++ ) { struct FNT_window_s box; cent = cl_entities + i + 1; if( !cent->current.modelindex ) continue; if(!strcmp(cl.clientinfo[i].name, name->string)) continue; trace = CL_Trace ( cl.refdef.vieworg, mins, maxs, cent->current.origin, -1, MASK_PLAYERSOLID, true, NULL); if (trace.fraction != 1.0) continue; VectorSubtract(cent->current.origin, cl.refdef.vieworg, vecdist); dist = VectorLength(vecdist); if (dist >= 1000 || !InFront(cent->current.origin)) continue; VectorSubtract (cent->current.origin, cl.refdef.vieworg, temp); VectorNormalize (temp); AngleVectors(cl.refdef.viewangles, axis[0], axis[1], axis[2]); if (DotProduct (temp, axis[0]) < 0) continue; R_TransformVectorToScreen(&cl.refdef, cent->current.origin, screen_pos); box.x = (int)screen_pos[0]; box.y = cl.refdef.height-(int)screen_pos[1]-cl.refdef.height/6; box.width = box.height = 0; FNT_BoundedPrint( font , cl.clientinfo[i].name , FNT_CMODE_QUAKE_SRS , FNT_ALIGN_LEFT , &box , FNT_colors[ 2 ] ); } } void SCR_DrawBases (void) { FNT_font_t font; int i; entity_t * ent; vec2_t screen_pos; font = FNT_AutoGet( CL_gameFont ); for (i=0 ; iteam) continue; if (!InFront(ent->origin)) continue; R_TransformVectorToScreen(&cl.refdef, ent->origin, screen_pos); box.x = (int)screen_pos[0]; box.y = cl.refdef.height-(int)screen_pos[1]-cl.refdef.height/6; box.width = box.height = 0; if(ent->team == 2) str = "^4Blue Flag"; else if(ent->team == 1) str = "^1Red Flag"; else str = "Flag"; FNT_BoundedPrint( font , str , FNT_CMODE_QUAKE_SRS , FNT_ALIGN_LEFT , &box , FNT_colors[ 2 ] ); } } /* ================== V_RenderView ================== */ extern cvar_t *scr_netgraph; extern cvar_t *scr_timegraph; extern cvar_t *scr_debuggraph; extern cvar_t *scr_graphheight; void V_RenderView( float stereo_separation ) { extern int entitycmpfnc( const entity_t *, const entity_t * ); if (cls.state != ca_active) return; if (!cl.refresh_prepped) return; // still loading if ( cl_timedemo && cl_timedemo->integer ) { if ( cl.timedemo_start > 0 ) { /* frame counter increment for timedemo benchmark */ cl.timedemo_frames++; } else { /* time demo start trigger */ cl.timedemo_start = Sys_Milliseconds (); cl.timedemo_frames = 0; } } // an invalid frame will just use the exact previous refdef // we can't use the old frame if the video mode has changed, though... if ( cl.frame.valid && (cl.force_refdef || !cl_paused->value) ) { cl.force_refdef = false; // build a refresh entity list and calc cl.sim* // this also calls CL_CalcViewValues which loads // v_forward, etc. CL_AddEntities (); if (cl_testparticles->value) V_TestParticles (); if (cl_testentities->value) V_TestEntities (); if (cl_testlights->value) V_TestLights (); if (cl_testblend->value) { cl.refdef.blend[0] = 1; cl.refdef.blend[1] = 0.5; cl.refdef.blend[2] = 0.25; cl.refdef.blend[3] = 0.5; } // offset vieworg appropriately if we're doing stereo separation if ( stereo_separation != 0 ) { vec3_t tmp; VectorScale( cl.v_right, stereo_separation, tmp ); VectorAdd( cl.refdef.vieworg, tmp, cl.refdef.vieworg ); } // never let it sit exactly on a node line, because a water plane can // dissapear when viewed with the eye exactly on it. // the server protocol only specifies to 1/8 pixel, so add 1/16 in each axis cl.refdef.vieworg[0] += 1.0/16; cl.refdef.vieworg[1] += 1.0/16; cl.refdef.vieworg[2] += 1.0/16; cl.refdef.x = scr_vrect.x; cl.refdef.y = scr_vrect.y; cl.refdef.width = scr_vrect.width; cl.refdef.height = scr_vrect.height; if (scr_debuggraph->integer || scr_timegraph->integer || scr_netgraph->integer) cl.refdef.height -= scr_graphheight->integer; cl.refdef.fov_y = CalcFov (cl.refdef.fov_x, cl.refdef.width, cl.refdef.height); cl.refdef.time = cl.time*0.001; cl.refdef.areabits = cl.frame.areabits; if (!cl_add_entities->value) { r_numentities = 0; r_numviewentities = 0; } if (!cl_add_particles->value) r_numparticles = 0; if (!cl_add_lights->value) r_numdlights = 0; if (!cl_add_blend->value) { Vector4Clear (cl.refdef.blend); } cl.refdef.num_entities = r_numentities; cl.refdef.entities = r_entities; cl.refdef.num_viewentities = r_numviewentities; cl.refdef.viewentities = r_viewentities; cl.refdef.num_particles = r_numparticles; cl.refdef.particles = r_particles; cl.refdef.num_dlights = r_numdlights; cl.refdef.dlights = r_dlights; cl.refdef.lightstyles = r_lightstyles; cl.refdef.num_grasses = r_numgrasses; cl.refdef.grasses = r_grasses; cl.refdef.num_beams = r_numbeams; cl.refdef.beams = r_beams; cl.refdef.rdflags = cl.frame.playerstate.rdflags; // sort entities for better cache locality qsort( cl.refdef.entities, cl.refdef.num_entities, sizeof( cl.refdef.entities[0] ), (int (*)(const void *, const void *))entitycmpfnc ); V_ClearScene (); } cl.refdef.rdflags |= RDF_BLOOM; //BLOOMS R_VCFreeFrame(); need_free_vbo = false; R_RenderFrame (&cl.refdef); if (cl_stats->value) Com_Printf ("ent:%i lt:%i part:%i\n", r_numentities, r_numdlights, r_numparticles); if ( log_stats->value && ( log_stats_file != 0 ) ) fprintf( log_stats_file, "%i,%i,%i,",r_numentities, r_numdlights, r_numparticles); SCR_DrawCrosshair (&cl.refdef); if(cl_showPlayerNames->integer) { if(cl_showPlayerNames->integer == 2) SCR_DrawPlayerNames(); else SCR_DrawPlayerNamesCenter(); SCR_DrawBases(); } } /** * @brief Console output of position and orientation * * Target of 'viewpos' command. Modified 2011-02. Added pitch. * Helps with repeatable positioning for timerefresh command * and other performance testing. */ void V_Viewpos_f (void) { Com_Printf ("x:%#1.0f y:%#1.0f z:%#1.0f yaw:%#1.0f pitch:%#1.0f\n", cl.refdef.vieworg[0], cl.refdef.vieworg[1], cl.refdef.vieworg[2], cl.refdef.viewangles[YAW], cl.refdef.viewangles[PITCH] ); } /* ============= V_Init ============= */ void V_Init (void) { Cmd_AddCommand ("viewpos", V_Viewpos_f); crosshair = Cvar_Get ("crosshair", "0", CVAR_ARCHIVE); cl_testblend = Cvar_Get ("cl_testblend", "0", 0); cl_testparticles = Cvar_Get ("cl_testparticles", "0", 0); cl_testentities = Cvar_Get ("cl_testentities", "0", 0); cl_testlights = Cvar_Get ("cl_testlights", "0", 0); cl_stats = Cvar_Get ("cl_stats", "0", 0); } alien-arena-7.66+dfsg/source/client/console.c0000600000175000017500000005550212204310130020174 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // console.c #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "client.h" #include "ref_gl/qgl.h" /* The console's main structure */ struct CON_console_s CON_console; /* CVar for notifications display time */ cvar_t * con_notifytime; /**************************************************************************/ /* VARIOUS COMMANDS */ /**************************************************************************/ /* * Show or hide the console. */ void CON_ToggleConsole( void ) { SCR_EndLoadingPlaque (); // get rid of loading plaque Key_ClearTyping (); CON_ClearNotify( ); if (cls.key_dest == key_console) { M_ForceMenuOff (); Cvar_Set ("paused", "0"); } else { M_ForceMenuOff (); cls.key_dest = key_console; if (Cvar_VariableValue ("maxclients") == 1 && Com_ServerState ()) Cvar_Set ("paused", "1"); } } /* * Clear the chat area */ static void _CON_ToggleChat( void ) { Key_ClearTyping( ); if ( cls.key_dest == key_console ) { if ( cls.state == ca_active ) { M_ForceMenuOff( ); cls.key_dest = key_game; } } else { cls.key_dest = key_console; } CON_ClearNotify( ); } /* * Toggle the general chat input */ static void _CON_GeneralChatInput( void ) { chat_team = false; chat_irc = false; cls.key_dest = key_message; Cbuf_AddText("chatbubble\n"); Cbuf_Execute (); } /* * Toggle the team chat input */ static void _CON_TeamChatInput( void ) { chat_team = true; chat_irc = false; cls.key_dest = key_message; Cbuf_AddText("chatbubble\n"); Cbuf_Execute (); } /* * Toggle the IRC input */ static void _CON_IRCInput( void ) { chat_team = false; chat_irc = true; cls.key_dest = key_message; } /**************************************************************************/ /* CONSOLE BUFFER ACCESS */ /**************************************************************************/ /* * Find the start of the current line * * Parameters: * line the initial line to look from * * Returns: * the identifier of the current line in the buffer */ static int _CON_FindLineStart( int line ) { line = ( line + CON_MAX_LINES ) % CON_MAX_LINES; while ( CON_console.lCount[ line ] == 0 ) { line = ( line - 1 + CON_MAX_LINES ) % CON_MAX_LINES; } return line; } /* * Find the start of the next line * * Parameters: * line the current location * * Returns: * the identifier of the next line in the buffer */ static int _CON_FindNextLine( int line ) { line = ( line + CON_MAX_LINES ) % CON_MAX_LINES; if ( CON_console.lCount[ line ] == 0 ) { while ( CON_console.lCount[ line ] == 0 ) { line = ( line + 1 ) % CON_MAX_LINES; } } else { line = ( line + CON_console.lCount[ line ] ) % CON_MAX_LINES; } return line; } /* * Find the start of the previous line * * Parameters: * line the current location * * Returns: * the identifier of the previous line in the buffer */ static int _CON_FindPreviousLine( int line ) { return _CON_FindLineStart( _CON_FindLineStart( line ) - 1 ); } /* * End the current line and start a new one */ static void _CON_NewLine( ) { CON_console.times[ CON_console.curTime ] = cls.realtime; CON_console.curTime = ( CON_console.curTime + 1 ) % CON_MAX_NOTIFY; CON_console.curLine = ( CON_console.curLine + 1 ) % CON_MAX_LINES; CON_console.lines += 1 - CON_console.lCount[ CON_console.curLine ]; CON_console.lCount[ CON_console.curLine ] = 1; CON_console.offset = 0; memset( CON_console.text[ CON_console.curLine ] , 0 , CON_LINE_LENGTH ); CON_console.heights[ CON_console.curLine ] = 0; } /* * Go back to the start of the current line */ static void _CON_RestartLine( ) { CON_console.curLine = _CON_FindLineStart( CON_console.curLine ); CON_console.offset = 0; } /* * Append a character to the console buffer * * Parameters: * new_char the character to append */ static void _CON_AppendChar( char new_char ) { int lStart = _CON_FindLineStart( CON_console.curLine ); CON_console.text[ CON_console.curLine ][ CON_console.offset ] = new_char; CON_console.offset = ( CON_console.offset + 1 ) % CON_LINE_LENGTH; CON_console.heights[ lStart ] = 0; if ( CON_console.offset == 0 ) { // Start a new buffer line that is part of the current logical line CON_console.lCount[ lStart ] ++; CON_console.curLine = ( CON_console.curLine + 1 ) % CON_MAX_LINES; CON_console.lines += 1 - CON_console.lCount[ CON_console.curLine ]; memset( CON_console.text[ CON_console.curLine ] , 0 , CON_LINE_LENGTH ); } } /* * Copy the specified logical line into a buffer * * If the current buffer line is full, the logical line will be extended to * include the next buffer line. * * Parameters: * buffer the buffer to copy to * line the first buffer line of the logical line * * Notes: * The buffer should have a sufficient size, which can be computed * using lCount[ line ] * CON_LINE_LENGTH. */ static void _CON_CopyLine( char * buffer , int line ) { int len = CON_console.lCount[ line ]; int i; for ( i = 0 ; i < len ; i ++ ) { memcpy( buffer , CON_console.text[ line ] , CON_LINE_LENGTH ); buffer += CON_LINE_LENGTH; line = ( line + 1 ) % CON_MAX_LINES; } } /**************************************************************************/ /* NOTIFICATIONS */ /**************************************************************************/ /* Clear all notifications */ void CON_ClearNotify( ) { int i; for ( i = 0 ; i < CON_MAX_NOTIFY ; i ++ ) { CON_console.times[ i ] = 0; } } /* Draw the few last lines of the console transparently over the game */ void CON_DrawNotify( ) { FNT_font_t font; struct FNT_window_s box; int line; int bLines; int count; int timeIndex; font = FNT_AutoGet( CL_gameFont ); box.x = 0; box.y = 0; if (cls.key_dest == key_message) { const char * to_draw; int height; if (chat_team) { to_draw = "say_team: "; } else if (chat_irc) { to_draw = "say_IRC: "; } else { to_draw = "say: "; } box.width = viddef.width; box.height = 0; FNT_BoundedPrint( font , to_draw , FNT_CMODE_NONE , FNT_ALIGN_LEFT , &box , FNT_colors[ 7 ] ); height = box.height; box.x = box.width + 1; box.width = viddef.width - box.width; box.height = 0; FNT_WrappedPrint( font , chat_buffer , FNT_CMODE_NONE , FNT_ALIGN_LEFT , 30 , &box , FNT_colors[ 7 ] ); box.x = 0; box.y = ( height > box.height ) ? height : box.height; } // Find the first logical line to display line = _CON_FindLineStart( CON_console.curLine ); bLines = CON_console.lines - CON_console.lCount[ line ]; timeIndex = ( CON_console.curTime - 1 + CON_MAX_NOTIFY ) % CON_MAX_NOTIFY; for ( count = 0 ; count < CON_MAX_NOTIFY && bLines > 0 ; count ++ ) { int time = CON_console.times[ timeIndex ]; if ( time == 0 || cls.realtime - time > con_notifytime->value * 1000 ) { break; } timeIndex = ( timeIndex - 1 + CON_MAX_NOTIFY ) % CON_MAX_NOTIFY; line = _CON_FindPreviousLine( line ); bLines -= CON_console.lCount[ line ]; } // No lines to display if ( count == 0 ) { return; } // Display lines while ( count > 0 ) { box.width = viddef.width; box.height = 0; if ( CON_console.lCount[ line ] == 1 ) { FNT_WrappedPrint( font , CON_console.text[ line ] , FNT_CMODE_QUAKE_SRS , FNT_ALIGN_LEFT , 30 , &box , FNT_colors[ 7 ] ); } else { char * buffer = Z_Malloc( CON_LINE_LENGTH * CON_console.lCount[ line ] ); _CON_CopyLine( buffer , line ); FNT_WrappedPrint( font , buffer , FNT_CMODE_QUAKE_SRS , FNT_ALIGN_LEFT , 30 , &box , FNT_colors[ 7 ] ); Z_Free( buffer ); } box.y += box.height; line = _CON_FindNextLine( line ); timeIndex = ( timeIndex + 1 ) % CON_MAX_NOTIFY; count --; } } /**************************************************************************/ /* CONSOLE ACCESS FUNCTIONS */ /**************************************************************************/ /* Save the console contents out to a file. */ static void _CON_Dump( void ) { char name[MAX_OSPATH]; int line , lastLine; FILE * f; if ( Cmd_Argc( ) != 2 ) { Com_Printf ("usage: condump \n"); return; } Com_sprintf( name , sizeof( name ) , "%s/%s.txt" , FS_Gamedir( ) , Cmd_Argv( 1 ) ); Com_Printf( "Dumping console text to %s.\n" , name ); FS_CreatePath( name ); f = fopen( name, "w" ); if (!f) { Com_Printf( "ERROR: couldn't open %s.\n" , name ); return; } lastLine = _CON_FindLineStart( CON_console.curLine ); line = ( CON_console.curLine + 1 + CON_MAX_LINES - CON_console.lines ) % CON_MAX_LINES; while ( line != lastLine ) { if ( CON_console.text[ line ][ 0 ] != 0 ) { if ( CON_console.lCount[ line ] == 1 ) { fprintf( f , "%s\n" , CON_console.text[ line ] ); } else { char * buffer = Z_Malloc( CON_LINE_LENGTH * CON_console.lCount[ line ] ); _CON_CopyLine( buffer , line ); fprintf( f , "%s\n" , buffer ); Z_Free( buffer ); } } line = _CON_FindNextLine( line ); } fclose( f ); } /* Clears the console */ void CON_Clear( void ) { memset( &CON_console , 0 , sizeof( CON_console ) ); CON_console.lines = 1; CON_console.lCount[ 0 ] = 1; CON_console.curLine = 0; CON_console.offset = 0; CON_console.initialised = true; } /* Initialise the console. */ void CON_Initialise( ) { CON_Clear( ); Com_Printf( "Console initialized.\n" ); // Register CVars con_notifytime = Cvar_Get( "con_notifytime" , "3" , 0 ); // Register commands Cmd_AddCommand( "toggleconsole", CON_ToggleConsole ); Cmd_AddCommand( "togglechat", _CON_ToggleChat ); Cmd_AddCommand( "messagemode", _CON_GeneralChatInput ); Cmd_AddCommand( "messagemode2", _CON_TeamChatInput ); Cmd_AddCommand( "messagemode3", _CON_IRCInput ); Cmd_AddCommand( "clear" , CON_Clear ); Cmd_AddCommand( "condump" , _CON_Dump ); } /* Add text to the console. */ void CON_Print( const char * text ) { char curChar; if ( ! CON_console.initialised ) { return; } while ( ( curChar = *text ) != 0 ) { if ( curChar == '\r' ) { _CON_RestartLine( ); } else if ( curChar == '\n' ) { _CON_NewLine( ); } else { _CON_AppendChar( curChar ); } text ++; } } /**************************************************************************/ /* CONSOLE DISPLAY FUNCTIONS */ /**************************************************************************/ /* * Compute the height of a logical console line and update the console's * data structure accordingly. * * Parameters: * font the current console font * line the start of the logical line for which the computation will * be performed */ static void _CON_ComputeLineHeight( FNT_font_t font , int line ) { if ( CON_console.text[ line ][ 0 ] == 0 ) { // Empty lines are a special case, as we don't need to draw them CON_console.heights[ line ] = font->size; } else { // "Print" the line outside of the screen struct FNT_window_s box; box.x = 0 , box.y = viddef.height; box.width = viddef.width - font->size * 5 , box.height = 0; if ( CON_console.lCount[ line ] == 1 ) { FNT_WrappedPrint( font , CON_console.text[ line ] , FNT_CMODE_QUAKE_SRS , FNT_ALIGN_LEFT , 0 , &box , FNT_colors[ 0 ] ); } else { char * buffer = Z_Malloc( CON_console.lCount[ line ] * CON_LINE_LENGTH ); _CON_CopyLine( buffer , line ); FNT_WrappedPrint( font , buffer , FNT_CMODE_QUAKE_SRS , FNT_ALIGN_LEFT , 0 , &box , FNT_colors[ 0 ] ); Z_Free( buffer ); } if ( box.height == 0 ) { CON_console.heights[ line ] = font->size; } else { CON_console.heights[ line ] = box.height; } } } /* * Compute the height of all active lines in the console. * * Parameters: * font the console's current font * * Returns: * the total height of the console */ static unsigned int _CON_ComputeHeight( FNT_font_t font ) { int line , lastLine; unsigned int total = 0; lastLine = _CON_FindLineStart( CON_console.curLine ); line = ( CON_console.curLine + 1 + CON_MAX_LINES - CON_console.lines ) % CON_MAX_LINES; while ( 1 ) { if ( ! CON_console.heights[ line ] ) { _CON_ComputeLineHeight( font , line ); } total += CON_console.heights[ line ]; if ( line == lastLine ) { break; } line = _CON_FindNextLine( line ); } return total; } /* * Check for font or resolution changes. * * Parameters: * font the console's current font * * Returns: * true if the resolution or fonts have changed, false otherwise */ static qboolean _CON_CheckResize( FNT_font_t font ) { return ( viddef.width != CON_console.pWidth || font->size != CON_console.pSize || strcmp( font->face->name , CON_console.pFace ) ); } /* * Draw the console's text. * * Parameters: * font the current console font * start the vertical offset relative to the top of the console's * contents at which drawing is to begin * dHeight the height of the display area */ static void _CON_DrawConsoleText( FNT_font_t font , int start , int dHeight ) { struct FNT_window_s box; int line , lastLine , total; qglScissor( 0 , viddef.height - dHeight , viddef.width , dHeight ); qglEnable( GL_SCISSOR_TEST ); total = 0; lastLine = _CON_FindLineStart( CON_console.curLine ); line = ( CON_console.curLine + 1 + CON_MAX_LINES - CON_console.lines ) % CON_MAX_LINES; do { if ( total + CON_console.heights[ line ] >= start && CON_console.text[ line ][ 0 ] ) { box.x = font->size*2; box.y = total - start; box.width = viddef.width - font->size * 5; box.height = 0; if ( CON_console.lCount[ line ] == 1 ) { FNT_WrappedPrint( font , CON_console.text[ line ] , FNT_CMODE_QUAKE_SRS , FNT_ALIGN_LEFT , 0 , &box , FNT_colors[ 2 ] ); } else { char * buffer = Z_Malloc( CON_console.lCount[ line ] * CON_LINE_LENGTH ); _CON_CopyLine( buffer , line ); FNT_WrappedPrint( font , buffer , FNT_CMODE_QUAKE_SRS , FNT_ALIGN_LEFT , 0 , &box , FNT_colors[ 2 ] ); Z_Free( buffer ); } } total += CON_console.heights[ line ]; if ( line == lastLine ) { break; } line = _CON_FindNextLine( line ); } while ( total - start < dHeight ); qglDisable( GL_SCISSOR_TEST ); } /* * Draw the scroller on the right of the console. * * For now this is not interactive, it only exists to indicate where in the * console's contents the current view is located. * * This function uses Draw_Fill to generate the scroller's graphics. It uses * the following fill colours: 15 (white, outside of the box), 201 (dark * green, inside of the box) and 208 (bright green, selected area). * * Parameters: * font_size The size of the font (used as the vertical offset and * the scroller's width) * text_height Total height of the console's text contents. * display_height Height of the viewing area. */ static void _CON_DrawScroller( int font_size , int text_height , int display_height ) { // FIXME: lots of copy-pasted code here. Doesn't matter, we will // eventually redo the whole console using the menu code. int hStart = viddef.width - 3 * font_size; int vStart = font_size / 2; int tHeight = display_height - font_size; int bHeight , bStart; Draw_AlphaStretchTilingPic (hStart, vStart, font_size, font_size, "menu/scroll_border_end", 1); Draw_AlphaStretchTilingPic (hStart, vStart+font_size, font_size, tHeight-vStart, "menu/scroll_border", 1); Draw_AlphaStretchTilingPic (hStart+font_size, vStart+tHeight+font_size, -font_size, -font_size, "menu/scroll_border_end", 1); if ( display_height >= text_height ) { // Fill whole bar bStart = vStart; bHeight = tHeight; } else { bHeight = tHeight * display_height / text_height; if ( bHeight < font_size ) bHeight = font_size; // "Top" offset is height - dHeight, "bottom" offset is 0 // "Top" bar location is vStart, bottom location is vStart + tHeight - bHeight. bStart = vStart + ( tHeight - bHeight ) * ( CON_console.displayOffset - text_height + display_height ) / ( display_height - text_height ); } Draw_AlphaStretchTilingPic (hStart, bStart, font_size, font_size, "menu/scroll_cursor_end", 1); Draw_AlphaStretchTilingPic (hStart, bStart+font_size, font_size, bHeight-font_size, "menu/scroll_cursor", 1); Draw_AlphaStretchTilingPic (hStart+font_size, bStart+bHeight+font_size, -font_size, -font_size, "menu/scroll_cursor_end", 1); } /* * Draw the console's input line. * * Parameters: * font the current console font * inputY the height at which the input line is located */ static void _CON_DrawInputLine( FNT_font_t font , int inputY ) { struct FNT_window_s box; char text[ MAXCMDLINE + 1 ]; unsigned int wToCursor; unsigned int wAfterCursor; unsigned int align; char old; if ( cls.key_dest == key_menu || ( cls.key_dest != key_console && cls.state == ca_active ) ) return; // Copy current line memcpy( text , key_lines[ edit_line ] , key_linelen ); text[ key_linelen ] = 0; // Determine width of text before the cursor ... old = text[ key_linepos ]; text[ key_linepos ] = 0; box.x = 0; box.y = viddef.height; box.width = box.height = 0; FNT_BoundedPrint( font , text , FNT_CMODE_QUAKE_SRS , FNT_ALIGN_LEFT , &box , FNT_colors[ 2 ] ); wToCursor = box.width; text[ key_linepos ] = old; // ... and after the cursor if ( key_linelen > key_linepos ) { box.width = box.height = 0; FNT_BoundedPrint( font , text + key_linepos , FNT_CMODE_QUAKE_SRS , FNT_ALIGN_LEFT , &box , FNT_colors[ 2 ] ); wAfterCursor = box.width; } else { wAfterCursor = 0; } box.x = font->size; box.y = inputY; box.height = 0; text[ key_linepos ] = 0; if ( wToCursor + font->size * 5 < viddef.width ) { // There is enough space for the start of the line align = FNT_ALIGN_LEFT; } else { // Not enough space, print with right alignment wToCursor = viddef.width * 0.9; align = FNT_ALIGN_RIGHT; } box.width = wToCursor; FNT_BoundedPrint( font , text , FNT_CMODE_QUAKE_SRS , align , &box , FNT_colors[ 2 ] ); // Draw cursor if ( ( (int)( cls.realtime >> 8 ) & 1) != 0 ) { Draw_Fill (box.x + box.width + 1 , box.y + 1 , font->size - 2 , font->size - 2 , RGBA(0,1,0,1)); } // Draw whatever is after the cursor if ( wAfterCursor ) { text[ key_linepos ] = old; box.x += box.width + font->size; box.width = viddef.width - ( box.width + font->size * 5 ); box.height = 0; FNT_BoundedPrint( font , text + key_linepos , FNT_CMODE_QUAKE_SRS , FNT_ALIGN_LEFT , &box , FNT_colors[ 2 ] ); } } /* * Draw the line at the bottom of the console. * * This line includes the version string and the current download status. * * Parameters: * y vertical offset of the bottom of the console * * Returns: * vertical offset above the line at the bottom of the console * */ static int _CON_DrawConsoleBottom( int y ) { FNT_font_t font; char buffer[ MAX_STRING_CHARS ]; int kb , sz; font = FNT_AutoGet( CL_gameFont ); y -= font->size; // Draw version string sz = sizeof( VERSION ); FNT_RawPrint( font , VERSION , sz , false , viddef.width - font->size * 5 * sz / 2 , y , FNT_colors[ 7 ] ); // Draw download status if needed if ( ! ( cls.download && ( kb = (int)ftell( cls.download ) / 1024 ) ) ) { return y; } Com_sprintf( buffer , MAX_STRING_CHARS , "Downloading %s [%s] ... %dKB" , cls.downloadname , ( cls.downloadhttp ? "HTTP" : "UDP" ), kb ); FNT_RawPrint( font , buffer , strlen( buffer ) , false , font->size * 3 , y , FNT_colors[ 3 ] ); return y; } /* Draw the console. */ void CON_DrawConsole( float relSize ) { FNT_font_t font; int dHeight; int height; int start; int fontSize; // Don't draw if there's no video if ( viddef.width < 1 ) { return; } // Check for changes and act accordingly font = FNT_AutoGet( CL_consoleFont ); if ( _CON_CheckResize( font ) ) { CON_console.pWidth = viddef.width; CON_console.pSize = font->size; strcpy( CON_console.pFace , font->face->name ); memset( CON_console.heights , 0 , sizeof( CON_console.heights ) ); } fontSize = font->size; // Compute display height and draw background dHeight = viddef.height * relSize; // FIXME: lots of copy-pasted code here. Doesn't matter, we will // eventually redo the whole console using the menu code. { int _tile_w, _tile_h; float tile_w, tile_h; // assume all tiles are the same size Draw_GetPicSize (&_tile_w, &_tile_h, "menu/m_topcorner" ); tile_w = (float)_tile_w/64.0*(float)font->size*4.0; tile_h = (float)_tile_h/64.0*(float)font->size*4.0; Draw_AlphaStretchTilingPic( -tile_w/4, dHeight-tile_h/2, tile_w, tile_h, "menu/m_bottomcorner", 1 ); Draw_AlphaStretchTilingPic( viddef.width+tile_w/4, dHeight-tile_h/2, -tile_w, tile_h, "menu/m_bottomcorner", 1 ); Draw_AlphaStretchTilingPic( tile_w*0.75, dHeight-tile_h/2, viddef.width-tile_w*1.5, tile_h, "menu/m_bottom", 1 ); Draw_AlphaStretchTilingPic( -tile_w/4, 0, tile_w, dHeight-tile_h/2, "menu/m_side", 1 ); Draw_AlphaStretchTilingPic( viddef.width+tile_w/4, 0, -tile_w, dHeight-tile_h/2, "menu/m_side", 1 ); Draw_AlphaStretchTilingPic( tile_w*0.75, 0, viddef.width-tile_w, dHeight-tile_h/2, "menu/m_background", 1 ); } // Draw version string and download status dHeight = _CON_DrawConsoleBottom( dHeight ) - fontSize; // Compute heights height = _CON_ComputeHeight( font ); if ( height < dHeight ) { CON_console.displayOffset = 0; } else if ( CON_console.displayOffset > height - dHeight ) { CON_console.displayOffset = height - dHeight; } start = height - dHeight - CON_console.displayOffset; // Draw console contents & input line _CON_DrawConsoleText( font , start , dHeight ); _CON_DrawScroller( font->size , height , dHeight ); _CON_DrawInputLine( font , dHeight ); } alien-arena-7.66+dfsg/source/client/cl_inv.c0000600000175000017500000001001412161402010017772 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // cl_inv.c -- client inventory screen #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "client.h" /* ================ CL_ParseInventory ================ */ void CL_ParseInventory (void) { int i; for (i=0 ; isize / 8.0; // determine scroll point top = selected_num - DISPLAY_ITEMS/2; if (num - top < DISPLAY_ITEMS) top = num - DISPLAY_ITEMS; if (top < 0) top = 0; // Draw frame and headers box.x = (int)( ( viddef.width - 416 * scale ) / 2 ); box.y = (int)( ( viddef.height - 256 * scale ) / 2 ); Draw_StretchPic( box.x , box.y , 416 * scale , 256 * scale , "inventory" ); colPos[ 0 ] = ( box.x += 56 * scale ) , box.y += 32 * scale; colWidth[ 0 ] = box.width = 55 * scale , box.height = 0; FNT_BoundedPrint( font , "Hotkey" , FNT_CMODE_NONE , FNT_ALIGN_RIGHT , &box , FNT_colors[ 7 ] ); colPos[ 1 ] = ( box.x += 60 * scale ); colWidth[ 1 ] = box.width = 43 * scale , box.height = 0; FNT_BoundedPrint( font , "###" , FNT_CMODE_NONE , FNT_ALIGN_CENTER , &box , FNT_colors[ 7 ] ); colPos[ 2 ] = ( box.x += 48 * scale ); colWidth[ 2 ] = box.width = 100 * scale , box.height = 0; FNT_BoundedPrint( font , "Item" , FNT_CMODE_NONE , FNT_ALIGN_LEFT , &box , FNT_colors[ 7 ] ); Draw_Fill( colPos[ 0 ] + scale , box.y + 11 * scale , 302 * scale , 2 * scale , RGBA8(235,235,235,255)); // Draw inventory contents box.y += 16 * scale; for ( i = top ; i < num && i < top + DISPLAY_ITEMS ; i++ ) { int item = index[ i ]; char binding[ MAX_QPATH + 5 ]; const char * bind; const float * color = FNT_colors[ index[ i ] == selected ? 7 : 2 ]; char count[ 5 ]; // search for a binding Com_sprintf (binding, sizeof(binding), "use %s", cl.configstrings[CS_ITEMS+item]); bind = ""; for (j=0 ; j<256 ; j++) { if (keybindings[j] && !Q_strcasecmp (keybindings[j], binding)) { bind = Key_KeynumToString(j); break; } } // Draw inventory line Com_sprintf( count , sizeof( count ) , "%i" , cl.inventory[item] ); box.x = colPos[ 0 ] , box.width = colWidth[ 0 ] , box.height = 0; FNT_BoundedPrint( font , bind , FNT_CMODE_NONE , FNT_ALIGN_RIGHT , &box , color ); box.x = colPos[ 1 ] , box.width = colWidth[ 1 ] , box.height = 0; FNT_BoundedPrint( font , count , FNT_CMODE_NONE , FNT_ALIGN_CENTER , &box , color ); box.x = colPos[ 2 ] , box.width = colWidth[ 2 ] , box.height = 0; FNT_BoundedPrint( font , cl.configstrings[ CS_ITEMS + item ] , FNT_CMODE_NONE , FNT_ALIGN_LEFT , &box , color ); box.y += 8 * scale; } } alien-arena-7.66+dfsg/source/client/cl_tent.c0000600000175000017500000003414712161402010020165 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // cl_tent.c -- client side temporary entities #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "client.h" cl_sustain_t cl_sustains[MAX_SUSTAINS]; struct sfx_s *cl_sfx_ric1; struct sfx_s *cl_sfx_ric2; struct sfx_s *cl_sfx_ric3; // [no file] struct sfx_s *cl_sfx_lashit; struct sfx_s *cl_sfx_spark5; struct sfx_s *cl_sfx_spark6; struct sfx_s *cl_sfx_spark7; struct sfx_s *cl_sfx_railg; struct sfx_s *cl_sfx_rockexp; struct sfx_s *cl_sfx_watrexp; struct sfx_s *cl_sfx_footsteps[4]; struct sfx_s *cl_sfx_metal_footsteps[4]; /* ================= CL_RegisterTEntSounds ================= */ void CL_RegisterTEntSounds (void) { int i; char name[MAX_QPATH]; cl_sfx_ric1 = S_RegisterSound ("world/ric1.wav"); cl_sfx_ric2 = S_RegisterSound ("world/ric2.wav"); cl_sfx_ric3 = S_RegisterSound ("world/ric3.wav"); // [no file] cl_sfx_lashit = S_RegisterSound("weapons/lashit.wav"); cl_sfx_railg = S_RegisterSound ("weapons/railgf1a.wav"); cl_sfx_rockexp = S_RegisterSound ("weapons/rocklx1a.wav"); S_RegisterSound ("player/land1.wav"); S_RegisterSound ("player/fall2.wav"); S_RegisterSound ("player/fall1.wav"); for (i=0 ; i<4 ; i++) { Com_sprintf (name, sizeof(name), "player/step%i.wav", i+1); cl_sfx_footsteps[i] = S_RegisterSound (name); } for (i=0 ; i<4 ; i++) { Com_sprintf (name, sizeof(name), "player/step_metal%i.wav", i+1); cl_sfx_metal_footsteps[i] = S_RegisterSound (name); } } /* ================= CL_ClearTEnts ================= */ void CL_ClearTEnts (void) { memset (cl_sustains, 0, sizeof(cl_sustains)); } /* ================= CL_ParseParticles ================= */ void CL_ParseParticles (void) { int color, count; vec3_t pos, dir; MSG_ReadPos (&net_message, pos); MSG_ReadDir (&net_message, dir); color = MSG_ReadByte (&net_message); count = MSG_ReadByte (&net_message); CL_ParticleEffect (pos, dir, color, count); } //============= //ROGUE void CL_ParseSteam (void) { vec3_t pos, dir; int i; int r; int cnt; cl_sustain_t *s, *free_sustain; free_sustain = NULL; for (i=0, s=cl_sustains; iid == 0) { free_sustain = s; break; } } if (free_sustain) { s->id = 25; //unused for now s->count = MSG_ReadByte (&net_message); if (!s->count) s->count = 32; MSG_ReadPos (&net_message, s->org); MSG_ReadDir (&net_message, s->dir); r = MSG_ReadByte (&net_message); if(!r) r = 15; //light gray else { switch(r) { case 1: r = 0xd2; //lime green break; case 2: r = 0x74; //blue break; case 3: r = 0xe8; //red break; default: r = 15; //light gray break; } } s->color = r; s->magnitude = 30; s->endtime = cl.time + 10000000; s->think = CL_ParticleSteamEffect; s->thinkinterval = 512/s->count; //~ 60 fps s->nextthink = cl.time; } else { // read the stuff anyway cnt = MSG_ReadByte (&net_message); MSG_ReadPos (&net_message, pos); MSG_ReadDir (&net_message, dir); r = MSG_ReadByte (&net_message); } } void CL_ParseFire (void) { vec3_t pos, dir; int id, i; int r; int cnt; int magnitude; cl_sustain_t *s, *free_sustain; // id = MSG_ReadShort (&net_message); // an id of -1 is an instant effect id = 25; if (id != -1) // sustains { // Com_Printf ("Sustain effect id %d\n", id); free_sustain = NULL; for (i=0, s=cl_sustains; iid == 0) { free_sustain = s; break; } } if (free_sustain) { s->id = id; s->count = MSG_ReadByte (&net_message); s->count = 10;//just for testing here MSG_ReadPos (&net_message, s->org); MSG_ReadDir (&net_message, s->dir); r = MSG_ReadByte (&net_message); s->color = r & 0xff; s->magnitude = 150;//MSG_ReadShort (&net_message); s->endtime = cl.time + 10000000;//MSG_ReadLong (&net_message); s->think = CL_ParticleFireEffect2; s->thinkinterval = 16; //~ 60 fps s->nextthink = cl.time; } else { // Com_Printf ("No free sustains!\n"); // FIXME - read the stuff anyway cnt = MSG_ReadByte (&net_message); MSG_ReadPos (&net_message, pos); MSG_ReadDir (&net_message, dir); r = MSG_ReadByte (&net_message); magnitude = MSG_ReadShort (&net_message); magnitude = MSG_ReadLong (&net_message); // really interval } } } void CL_ParseSmoke (void) { vec3_t pos, dir; int id, i; int r; int cnt; int magnitude; cl_sustain_t *s, *free_sustain; // id = MSG_ReadShort (&net_message); // an id of -1 is an instant effect id = 25; if (id != -1) // sustains { // Com_Printf ("Sustain effect id %d\n", id); free_sustain = NULL; for (i=0, s=cl_sustains; iid == 0) { free_sustain = s; break; } } if (free_sustain) { s->id = id; s->count = MSG_ReadByte (&net_message); MSG_ReadPos (&net_message, s->org); MSG_ReadDir (&net_message, s->dir); r = MSG_ReadByte (&net_message); s->color = r & 0xff; s->magnitude = 400;//MSG_ReadShort (&net_message); s->endtime = cl.time + 10000000;//MSG_ReadLong (&net_message); s->think = CL_ParticleSmokeEffect2; s->thinkinterval = 16; //~ 60 fps s->nextthink = cl.time; } else { // Com_Printf ("No free sustains!\n"); // FIXME - read the stuff anyway cnt = MSG_ReadByte (&net_message); MSG_ReadPos (&net_message, pos); MSG_ReadDir (&net_message, dir); r = MSG_ReadByte (&net_message); magnitude = MSG_ReadShort (&net_message); magnitude = MSG_ReadLong (&net_message); // really interval } } } //ROGUE //============= /* ================= CL_ParseTEnt ================= */ static byte splash_color[] = {0x00, 0xe0, 0xb0, 0x50, 0xd0, 0xe0, 0xe8}; extern void R_ApplyForceToRagdolls(vec3_t origin, float force); void CL_ParseTEnt (void) { int type; vec3_t pos, pos2, dir; int cnt; int color; int r; trace_t trace; static vec3_t mins = { -8, -8, -8 }; static vec3_t maxs = { 8, 8, 8 }; type = MSG_ReadByte (&net_message); switch (type) { case TE_BLOOD: // bullet hitting flesh MSG_ReadPos (&net_message, pos); MSG_ReadDir (&net_message, dir); CL_ParticleEffect (pos, dir, 450, 60);// doing the blood here - color is red break; case TE_GREENBLOOD: MSG_ReadPos (&net_message, pos); MSG_ReadDir (&net_message, dir); CL_ParticleEffect (pos, dir, 550, 60);// doing the blood here - color is green break; case TE_GUNSHOT: case TE_SPARKS: case TE_BULLET_SPARKS: MSG_ReadPos (&net_message, pos); MSG_ReadDir (&net_message, dir); if (type == TE_GUNSHOT) { CL_ParticleEffect (pos, dir, 425, 10); trace = CL_Trace ( pos, mins, maxs, pos, -1, MASK_SOLID, true, NULL); if(trace.contents) { CL_BulletMarks(pos, dir); R_ApplyForceToRagdolls(pos, 40); } } else CL_ParticleEffect (pos, dir, 425, 2); // bullets, color is 0xe0 CL_BulletSparks( pos, dir); if (type != TE_SPARKS) { // impact sound cnt = rand()&15; if (cnt == 1) S_StartSound (pos, 0, 0, cl_sfx_ric1, 1, ATTN_NORM, 0); else if (cnt == 2) S_StartSound (pos, 0, 0, cl_sfx_ric2, 1, ATTN_NORM, 0); else if (cnt == 3) S_StartSound (pos, 0, 0, cl_sfx_ric3, 1, ATTN_NORM, 0); } break; case TE_SCREEN_SPARKS: MSG_ReadPos (&net_message, pos); MSG_ReadDir (&net_message, dir); if (type == TE_SCREEN_SPARKS) { trace = CL_Trace ( pos, mins, maxs, pos, -1, MASK_SOLID, true, NULL); if(trace.contents) { CL_BeamgunMark(pos, dir, 0.8, false); R_ApplyForceToRagdolls(pos, 40); } CL_LaserSparks (pos, dir, 0xd0, 20); } else CL_ParticleEffect (pos, dir, 0xb0, 40); // [no file] S_StartSound (pos, 0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0); break; case TE_LASERBEAM: // martian laser effect MSG_ReadPos (&net_message, pos); MSG_ReadPos (&net_message, pos2); CL_LaserBeam (pos, pos2); break; case TE_SPLASH: // bullet hitting water cnt = MSG_ReadByte (&net_message); MSG_ReadPos (&net_message, pos); MSG_ReadDir (&net_message, dir); r = MSG_ReadByte (&net_message); if (r > 6) color = 0x00; else color = splash_color[r]; CL_SplashEffect (pos, dir, color, cnt); if (r == SPLASH_SPARKS) { r = rand() & 3; if (r == 0) S_StartSound (pos, 0, 0, cl_sfx_spark5, 1, ATTN_STATIC, 0); else if (r == 1) S_StartSound (pos, 0, 0, cl_sfx_spark6, 1, ATTN_STATIC, 0); else S_StartSound (pos, 0, 0, cl_sfx_spark7, 1, ATTN_STATIC, 0); } break; case TE_LASER_SPARKS: cnt = MSG_ReadByte (&net_message); MSG_ReadPos (&net_message, pos); MSG_ReadDir (&net_message, dir); color = MSG_ReadByte (&net_message); CL_ParticleEffect2 (pos, dir, color, cnt); break; case TE_BLASTER: // blaster hitting wall MSG_ReadPos (&net_message, pos); MSG_ReadDir (&net_message, dir); CL_BlasterParticles (pos, dir); R_ApplyForceToRagdolls(pos, 100); break; case TE_RAILTRAIL: // beam effect MSG_ReadPos (&net_message, pos); MSG_ReadPos (&net_message, pos2); CL_DisruptorBeam (pos, pos2); trace = CL_Trace ( pos, mins, maxs, pos2, -1, MASK_SOLID, true, NULL); if(trace.contents) { CL_BeamgunMark(pos2, trace.plane.normal, 0.4, true); R_ApplyForceToRagdolls(pos2, 100); } S_StartSound (pos, 0, 0, cl_sfx_railg, 1, ATTN_NORM, 0); CL_PlasmaFlashParticle(pos, cl.refdef.viewangles, false); break; case TE_EXPLOSION2: //using this for a "dust" explosion, ie big, big footsteps effect MSG_ReadPos (&net_message, pos); CL_DustParticles (pos); break; case TE_EXPLOSION1: case TE_ROCKET_EXPLOSION: case TE_ROCKET_EXPLOSION_WATER: MSG_ReadPos (&net_message, pos); //remember to add explosion stain CL_ExplosionParticles (pos); if (type == TE_ROCKET_EXPLOSION_WATER) S_StartSound (pos, 0, 0, cl_sfx_watrexp, 1, ATTN_NORM, 0); else S_StartSound (pos, 0, 0, cl_sfx_rockexp, 1, ATTN_NORM, 0); R_ApplyForceToRagdolls(pos, 100); break; case TE_BFG_BIGEXPLOSION: MSG_ReadPos (&net_message, pos); CL_BFGExplosionParticles (pos); R_ApplyForceToRagdolls(pos, 200); break; case TE_BUBBLETRAIL: MSG_ReadPos (&net_message, pos); MSG_ReadPos (&net_message, pos2); CL_BubbleTrail (pos, pos2); break; case TE_REDLASER: MSG_ReadPos (&net_message, pos); MSG_ReadPos (&net_message, pos2); CL_RedBlasterBeam (pos, pos2); break; case TE_BOSSTPORT: // boss teleporting to station MSG_ReadPos (&net_message, pos); CL_BigTeleportParticles (pos); S_StartSound (pos, 0, 0, S_RegisterSound ("misc/bigtele.wav"), 1, ATTN_NONE, 0); break; case TE_LIGHTNING: MSG_ReadPos (&net_message, pos); MSG_ReadPos (&net_message, pos2); CL_NewLightning (pos, pos2); break; case TE_VAPORBEAM: MSG_ReadPos (&net_message, pos); MSG_ReadPos (&net_message, pos2); CL_VaporizerBeam (pos, pos2); trace = CL_Trace ( pos, mins, maxs, pos2, -1, MASK_SOLID, true, NULL); if(trace.contents) CL_VaporizerMarks(pos2, trace.plane.normal); break; case TE_STEAM: CL_ParseSteam(); break; case TE_FIRE: CL_ParseFire(); break; case TE_SMOKE: CL_ParseSmoke(); break; case TE_SAYICON: MSG_ReadPos(&net_message, pos); CL_SayIcon(pos); break; case TE_TELEPORT_EFFECT: MSG_ReadPos (&net_message, pos); CL_TeleportParticles (pos); break; case TE_LEADERBLASTER: MSG_ReadPos (&net_message, pos); MSG_ReadPos (&net_message, pos2); CL_RedBlasterBeam (pos, pos2); S_StartSound (pos, 0, 0, S_RegisterSound ("weapons/biglaser.wav"), 1, ATTN_NONE, 0); break; case TE_CHAINGUNSMOKE: MSG_ReadPos (&net_message, pos); CL_MuzzleParticles (pos); CL_MuzzleFlashParticle(pos, cl.refdef.viewangles, false); break; case TE_BLUE_MUZZLEFLASH: MSG_ReadPos (&net_message, pos); CL_BlueMuzzleParticles (pos); break; case TE_SMART_MUZZLEFLASH: MSG_ReadPos (&net_message, pos); CL_SmartMuzzle (pos); break; case TE_VOLTAGE: MSG_ReadPos (&net_message, pos); MSG_ReadDir (&net_message, dir); CL_Voltage (pos); R_ApplyForceToRagdolls(pos, -50); break; case TE_DEATHFIELD: MSG_ReadPos (&net_message, pos); CL_Deathfield (pos, 0); break; case TE_DEATHFIELD2: MSG_ReadPos (&net_message, pos); MSG_ReadDir (&net_message, dir); CL_Deathfield (pos, 1); break; case TE_BLASTERBEAM: // blaster beam effect MSG_ReadPos (&net_message, pos); MSG_ReadPos (&net_message, pos2); CL_BlasterBeam (pos, pos2); trace = CL_Trace ( pos, mins, maxs, pos2, -1, MASK_SOLID, true, NULL); if(trace.contents) { CL_BlasterMark(pos2, trace.plane.normal); R_ApplyForceToRagdolls(pos2, 100); } break; default: // Do we really want to drop an error for this? //Com_Error (ERR_DROP, "CL_ParseTEnt: bad type"); Com_Printf("CL_ParseTEnt: bad type\n"); } } extern cvar_t *hand; /* PMM - CL_Sustains */ void CL_ProcessSustain () { cl_sustain_t *s; int i; for (i=0, s=cl_sustains; i< MAX_SUSTAINS; i++, s++) { if (s->id && CM_inPVS (cl.refdef.vieworg, s->org)) { if ((s->endtime >= cl.time) && (cl.time >= s->nextthink)) { s->think (s); } else if (s->endtime < cl.time) s->id = 0; } } } /* ================= CL_AddTEnts ================= */ void CL_AddTEnts (void) { CL_ProcessSustain(); } alien-arena-7.66+dfsg/source/client/cl_scrn.c0000600000175000017500000014670712161402010020166 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // cl_scrn.c -- master for refresh, status bar, console, chat, notify, etc /* full screen console put up loading plaque blanked background with loading plaque blanked background with menu full screen image for quit and victory end of unit intermissions */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "client.h" #include "qmenu.h" float scr_con_current; // aproaches scr_conlines at scr_conspeed float scr_conlines; // 0.0 to 1.0 lines of console to display qboolean scr_initialized; // ready to draw int scr_draw_loading; vrect_t scr_vrect; // position of render window on screen cvar_t *scr_conspeed; cvar_t *scr_centertime; cvar_t *scr_showturtle; cvar_t *scr_showpause; cvar_t *scr_printspeed; cvar_t *scr_netgraph; cvar_t *scr_timegraph; cvar_t *scr_debuggraph; cvar_t *scr_graphheight; cvar_t *scr_graphscale; cvar_t *scr_graphshift; cvar_t *scr_timerefcount; // for timerefresh command cvar_t *scr_consize; cvar_t *cl_drawfps; cvar_t *cl_drawtimer; cvar_t *cl_drawbandwidth; cvar_t *cl_drawframesover; cvar_t *cl_drawtime; char crosshair_pic[MAX_QPATH]; int crosshair_width, crosshair_height; void SCR_TimeRefresh_f (void); void SCR_Loading_f (void); extern void R_VCFreeFrame(void); extern cvar_t *rs_hasflag; extern cvar_t *rs_team; /* * map performance counters * * Used to measure the complexity of map areas. * Modified for display in performance counter array * Replace general "r_speed" cvar. * * Note: c_visible_textures seems to be always 0 and * c_visible_lightmaps is not used */ // extern cvar_t *r_speeds; cvar_t *rspeed_wpolys; cvar_t *rspeed_epolys; cvar_t *rspeed_flares; cvar_t *rspeed_grasses; cvar_t *rspeed_beams; cvar_t *rspeed_vbobatches; cvar_t *rspeed_particles; extern int c_brush_polys; /* "wpoly" polygons from brushes */ extern int c_alias_polys; /* "epoly" polygons from .md2 meshes */ extern int c_flares; /* "flares" lens flares */ extern int c_grasses; /* "grasses" vegetation instances */ extern int c_beams; /* "beams" light beams (?) */ extern int c_vbo_batches; /* "vbobatches" batched draw commands */ /* =============================================================================== BAR GRAPHS =============================================================================== */ /* ============== CL_AddNetgraph A new packet was just parsed ============== */ void CL_AddNetgraph (void) { int i; int in; int ping; // if using the debuggraph for something else, don't // add the net lines if (scr_debuggraph->value || scr_timegraph->value) return; for (i=0 ; i 30) ping = 30; SCR_DebugGraph (ping, RGBA(0,1,0,1)); } typedef struct { float value; float color[4]; } graphsamp_t; #define DEBUGGRAPH_VALUES 4096 static int current; static graphsamp_t values[DEBUGGRAPH_VALUES]; /* ============== SCR_DebugGraph ============== */ void SCR_DebugGraph (float value, const float color[]) { int i; int limit; limit = scr_vrect.width; if (limit > DEBUGGRAPH_VALUES) limit = DEBUGGRAPH_VALUES; values[current%limit].value = value; for (i = 0; i < 4; i++) values[current%limit].color[i] = color[i]; current++; } /* ============== SCR_DrawDebugGraph ============== */ void SCR_DrawDebugGraph (void) { int a, x, y, w, i, h; float v; const float *color; // // draw the graph // w = scr_vrect.width; if (w > DEBUGGRAPH_VALUES) w = DEBUGGRAPH_VALUES; x = scr_vrect.x; y = scr_vrect.y+scr_vrect.height; Draw_Fill (x, y-scr_graphheight->value, w, scr_graphheight->value, RGBA8(123,123,123,255)); for (a=0 ; avalue + scr_graphshift->value; if (v < 0) v += scr_graphheight->value * (1+(int)(-v/scr_graphheight->value)); h = (int)v % scr_graphheight->integer; Draw_Fill (x+w-1-a, y - h, 1, h, color); } } /* =============================================================================== CENTER PRINTING =============================================================================== */ char scr_centerstring[1024]; float scr_centertime_start; // for slow victory printing float scr_centertime_off; int scr_center_lines; int scr_erase_center; /* ============== SCR_CenterPrint Called for important messages that should stay in the center of the screen for a few moments ============== */ void SCR_CenterPrint (char *str) { char *s; if(!cl_centerprint->value) return; strncpy (scr_centerstring, str, sizeof(scr_centerstring)-1); scr_centertime_off = scr_centertime->value; scr_centertime_start = cl.time; // count the number of lines for centering scr_center_lines = 1; s = str; while (*s) { if (*s == '\n') scr_center_lines++; s++; } } void SCR_DrawCenterString (void) { FNT_font_t font; struct FNT_window_s box; float colors[ 8 ] = { 1, 1, 1, 1, 0.25, 1, 0.25, 1 }; if ( scr_centertime_off <= scr_centertime->value / 5.0 ) { colors[ 3 ] = colors[ 7 ] = scr_centertime_off * 5.0 / scr_centertime->value; } box.x = 0; if ( scr_center_lines <= 4 ) { box.y = viddef.height * 0.35; } else { box.y = 48; } box.height = viddef.height - box.y; box.width = viddef.width; font = FNT_AutoGet( CL_centerFont ); FNT_BoundedPrint( font , scr_centerstring , FNT_CMODE_TWO , FNT_ALIGN_CENTER , &box , colors ); } void SCR_CheckDrawCenterString (void) { scr_centertime_off -= cls.frametime; if (scr_centertime_off <= 0) return; SCR_DrawCenterString (); } /* =============================================================================== IRC PRINTING we'll have 5 lines stored. once full, start bumping lines, as in copying line 1 into line 0, and so forth =============================================================================== */ extern vec4_t Color_Table[8]; #define SCR_IRC_LINES 5 #define SCR_IRC_LENGTH 1024 #define SCR_IRC_INDENT 8 #define SCR_IRC_DISPLAY_HIDE 0 // During line bumping #define SCR_IRC_DISPLAY_PARTIAL 1 // When a new line is being added #define SCR_IRC_DISPLAY_FULL 2 // No problemo char scr_IRCstring_contents[ SCR_IRC_LINES ][ SCR_IRC_LENGTH ]; char * scr_IRCstring[ SCR_IRC_LINES ]; float scr_IRCtime_start; // for slow victory printing float scr_IRCtime_off; int scr_IRC_lines = -1; int scr_IRC_display = SCR_IRC_DISPLAY_FULL; /* ============== SCR_IRCPrint Called for IRC messages ============== */ void IRC_SetNextLine( int len , const char *buffer ) { char * to_set; int i; // Access the correct line buffer scr_IRC_display = SCR_IRC_DISPLAY_HIDE; if ( scr_IRC_lines < SCR_IRC_LINES - 1 ) { scr_IRC_lines ++; to_set = scr_IRCstring_contents[ scr_IRC_lines ]; } else { to_set = scr_IRCstring[ 0 ]; for ( i = 0 ; i < SCR_IRC_LINES - 1 ; i ++ ) scr_IRCstring[ i ] = scr_IRCstring[ i + 1 ]; } scr_IRCstring[ scr_IRC_lines ] = to_set; scr_IRC_display = SCR_IRC_DISPLAY_PARTIAL; // Copy string Q_strncpyz2( to_set , buffer , SCR_IRC_LENGTH ); // Restore IRC display and update time-related variables scr_IRCtime_off = 15; scr_IRCtime_start = cl.time; scr_IRC_display = SCR_IRC_DISPLAY_FULL; } void SCR_IRCPrintf (char *fmt, ...) { va_list argptr; char msg[1024]; int len; va_start (argptr,fmt); len = vsnprintf(msg, sizeof(msg), fmt, argptr); va_end (argptr); if ( len >= sizeof(msg) ) len = sizeof( msg ) - 1; IRC_SetNextLine( len , msg ); } void SCR_CheckDrawIRCString (void) { FNT_font_t font; struct FNT_window_s box; int i , last_line; static float color[ 4 ] = { 1 , 1 , 1 , 1 }; scr_IRCtime_off -= cls.frametime; if (scr_IRCtime_off <= 0 || scr_IRC_display == SCR_IRC_DISPLAY_HIDE) return; last_line = ( scr_IRC_display == SCR_IRC_DISPLAY_FULL ) ? scr_IRC_lines : ( scr_IRC_lines - 1 ); if ( last_line == -1 ) return; font = FNT_AutoGet( CL_gameFont ); box.x = 0; box.y = font->size * 5; for ( i = 0 ; i <= last_line ; i++ ) { box.width = viddef.width; box.height = font->size * 15 - box.y; FNT_WrappedPrint( font , scr_IRCstring[ i ] , FNT_CMODE_QUAKE , FNT_ALIGN_LEFT , SCR_IRC_INDENT , &box , color ); box.y += box.height; if ( box.y >= font->size * 15 ) { break; } } } //============================================================================= /* ================= SCR_CalcVrect Sets scr_vrect, the coordinates of the rendered window ================= */ static void SCR_CalcVrect (void) { scr_vrect.width = viddef.width; scr_vrect.height = viddef.height; // calculate left and top margins-- for now always 0 scr_vrect.x = (viddef.width - scr_vrect.width)/2; scr_vrect.y = (viddef.height - scr_vrect.height)/2; } /* ================= SCR_Sky_f Set a specific sky and rotation speed ================= */ void SCR_Sky_f (void) { float rotate; vec3_t axis; if (Cmd_Argc() < 2) { Com_Printf ("Usage: sky \n"); return; } if (Cmd_Argc() > 2) rotate = atof(Cmd_Argv(2)); else rotate = 0; if (Cmd_Argc() == 6) { axis[0] = atof(Cmd_Argv(3)); axis[1] = atof(Cmd_Argv(4)); axis[2] = atof(Cmd_Argv(5)); } else { axis[0] = 0; axis[1] = 0; axis[2] = 1; } R_SetSky (Cmd_Argv(1), rotate, axis); } //============================================================================ /* ================== SCR_Init ================== */ void SCR_Init (void) { scr_conspeed = Cvar_Get ("scr_conspeed", "3", CVAR_ARCHIVE); scr_consize = Cvar_Get ("scr_consize", "0.5", CVAR_ARCHIVE); scr_showturtle = Cvar_Get ("scr_showturtle", "0", 0); // default back to 1 if we ever actually make a pause icon: scr_showpause = Cvar_Get ("scr_showpause", "0", 0); scr_centertime = Cvar_Get ("scr_centertime", "2.5", CVAR_ARCHIVE); scr_printspeed = Cvar_Get ("scr_printspeed", "8", CVAR_ARCHIVE); scr_netgraph = Cvar_Get ("netgraph", "0", 0); scr_timegraph = Cvar_Get ("timegraph", "0", 0); scr_debuggraph = Cvar_Get ("debuggraph", "0", 0); scr_graphheight = Cvar_Get ("graphheight", "32", 0); scr_graphscale = Cvar_Get ("graphscale", "1", 0); scr_graphshift = Cvar_Get ("graphshift", "0", 0); // configurable number of frames for timerefresh command scr_timerefcount = Cvar_Get("scr_timerefcount", "128", 0 ); cl_drawfps = Cvar_Get ("cl_drawfps", "0", CVAR_ARCHIVE); cl_drawtimer = Cvar_Get("cl_drawtimer", "0", CVAR_ARCHIVE); cl_drawbandwidth = Cvar_Get ("cl_drawbandwidth", "0", CVAR_ARCHIVE); cl_drawframesover = Cvar_Get ("cl_drawframesover", "0", CVAR_ARCHIVE); rspeed_wpolys = Cvar_Get("rspeed_wpolys", "0", 0); rspeed_epolys = Cvar_Get("rspeed_epolys", "0", 0); rspeed_flares = Cvar_Get("rspeed_flares", "0", 0); rspeed_grasses = Cvar_Get("rspeed_grasses", "0", 0); rspeed_beams = Cvar_Get("rspeed_beams", "0", 0); rspeed_vbobatches = Cvar_Get("rspeed_vbobatches", "0", 0); rspeed_particles = Cvar_Get("rspeed_particles", "0", 0); memset (perftests, 0, sizeof(perftests)); // // register our commands // Cmd_AddCommand ("timerefresh",SCR_TimeRefresh_f); Cmd_AddCommand ("loading",SCR_Loading_f); Cmd_AddCommand ("sky",SCR_Sky_f); scr_initialized = true; } /* ============== SCR_DrawNet ============== */ void SCR_DrawNet (void) { if (cls.netchan.outgoing_sequence - cls.netchan.incoming_acknowledged < CMD_BACKUP-1) return; Draw_Pic (scr_vrect.x+64, scr_vrect.y, "net"); } void SCR_DrawAlertMessagePicture (char *name, qboolean center) { float ratio; int scale; int w, h; scale = viddef.width/MENU_STATIC_WIDTH; Draw_GetPicSize (&w, &h, name ); if (w) { ratio = 35.0/(float)h; h = 35; w *= ratio; } else return; if(center) Draw_StretchPic ( viddef.width / 2 - w*scale/2, viddef.height/ 2 - h*scale/2, scale*w, scale*h, name); else Draw_StretchPic ( viddef.width / 2 - w*scale/2, scale * 100, scale*w, scale*h, name); } void SCR_DrawPause (void) { if (!scr_showpause->value) // turn off for screenshots return; if (!cl_paused->value) return; if (cls.key_dest == key_menu) return; SCR_DrawAlertMessagePicture("pause", true); } /* ============== SCR_DrawLoading ============== */ void SCR_DrawRotatingIcon( void ) { extern float CalcFov( float fov_x, float w, float h ); refdef_t refdef; static float yaw; entity_t entity; memset( &refdef, 0, sizeof( refdef ) ); refdef.width = viddef.width; refdef.height = viddef.height; refdef.x = 0; refdef.y = 0; refdef.fov_x = 90; refdef.fov_y = CalcFov( refdef.fov_x, refdef.width, refdef.height ); refdef.time = cls.realtime*0.001; memset( &entity, 0, sizeof( entity ) ); yaw += cls.frametime*50; if (yaw > 360) yaw = 0; entity.model = R_RegisterModel( "models/objects/icon/tris.md2" ); entity.flags = RF_FULLBRIGHT | RF_MENUMODEL; entity.origin[0] = 80; entity.origin[1] = 30; entity.origin[2] = -5; VectorCopy( entity.origin, entity.oldorigin ); entity.frame = 0; entity.oldframe = 0; entity.backlerp = 0.0; entity.angles[1] = (int)yaw; refdef.areabits = 0; refdef.num_entities = 1; refdef.entities = &entity; refdef.lightstyles = 0; refdef.rdflags = RDF_NOWORLDMODEL; refdef.height += 4; R_RenderFrame( &refdef ); free(entity.model); } void SCR_DrawLoadingBar (int percent, int scale) { float hudscale; hudscale = (float)(viddef.height)/600; if(hudscale < 1) hudscale = 1; if (R_RegisterPic("bar_background") && R_RegisterPic("bar_loading")) { Draw_StretchPic ( viddef.width/2-scale*15 + 1*hudscale,viddef.height/2 + scale*5.4, scale*30-2*hudscale, scale*10, "bar_background"); Draw_StretchPic ( viddef.width/2-scale*15 + 1*hudscale,viddef.height/2 + scale*6.2, (scale*30-2*hudscale)*percent/100, scale*2, "bar_loading"); } else { Draw_Fill ( viddef.width/2-scale*15 + 1,viddef.height/2 + scale*5+1, scale*30-2, scale*2-2, RGBA8(47,47,47,255)); Draw_Fill ( viddef.width/2-scale*15 + 1,viddef.height/2 + scale*5+1, (scale*30-2)*percent/100, scale*2-2, RGBA8(107,107,107,255)); } } void SCR_DrawLoading (void) { FNT_font_t font; struct FNT_window_s box; char mapfile[32]; qboolean isMap = false; float hudscale; if (!scr_draw_loading) return; scr_draw_loading = false; font = FNT_AutoGet( CL_gameFont ); hudscale = (float)(viddef.height)/600; if(hudscale < 1) hudscale = 1; //loading a map... if (loadingMessage && cl.configstrings[CS_MODELS+1][0]) { strcpy (mapfile, cl.configstrings[CS_MODELS+1] + 5); // skip "maps/" mapfile[strlen(mapfile)-4] = 0; // cut off ".bsp" if(map_pic_loaded) Draw_StretchPic (0, 0, viddef.width, viddef.height, va("/levelshots/%s.pcx", mapfile)); else Draw_Fill (0, 0, viddef.width, viddef.height, RGBA(0,0,0,1)); isMap = true; } else Draw_Fill (0, 0, viddef.width, viddef.height, RGBA(0,0,0,1)); #if 0 // no m_background pic, but a pic here over-writes the levelshot Draw_StretchPic (0, 0, viddef.width, viddef.height, "m_background"); #endif //loading message stuff... if (isMap) { char loadMessage[ MAX_QPATH * 6 ]; int i; Com_sprintf( loadMessage , sizeof( loadMessage ) , "Loading Map [%s]\n^3%s" , mapfile , cl.configstrings[CS_NAME] ); box.x = 0; box.y = viddef.height / 2 - font->size * 5; box.width = viddef.width; box.height = 0; FNT_BoundedPrint( font , loadMessage , FNT_CMODE_QUAKE , FNT_ALIGN_CENTER , &box , FNT_colors[ 7 ] ); box.y += font->size * 4; for ( i = 0 ; i < 5 ; i ++ ) { box.x = viddef.width / 2 - font->size * 15; box.width = box.height = 0; FNT_BoundedPrint( font , loadingMessages[i][0] , FNT_CMODE_QUAKE , FNT_ALIGN_LEFT , &box , FNT_colors[ 7 ] ); box.x += box.width + font->size; box.width = viddef.width / 2 + font->size * 15 - box.x; box.height = 0; FNT_BoundedPrint( font , loadingMessages[i][1] , FNT_CMODE_QUAKE , FNT_ALIGN_RIGHT , &box , FNT_colors[ 7 ] ); box.y += font->size; } //check for instance of icons we would like to show in loading process, ala q3 if(rocketlauncher) { Draw_ScaledPic((int)(viddef.width/3), (int)(viddef.height/3.2), hudscale, "w_rlauncher"); if(!rocketlauncher_drawn){ rocketlauncher_drawn = 40*hudscale; } } if(chaingun) { Draw_ScaledPic((int)(viddef.width/3) + rocketlauncher_drawn, (int)(viddef.height/3.2), hudscale, "w_sshotgun"); if(!chaingun_drawn) { chaingun_drawn = 40*hudscale; } } if(smartgun) { Draw_ScaledPic((int)(viddef.width/3) + rocketlauncher_drawn+chaingun_drawn, (int)(viddef.height/3.2), hudscale, "w_shotgun"); if(!smartgun_drawn) { smartgun_drawn = 40*hudscale; } } if(beamgun) { Draw_ScaledPic((int)(viddef.width/3) + rocketlauncher_drawn+chaingun_drawn+smartgun_drawn, (int)(viddef.height/3.2), hudscale, "w_railgun"); if(!beamgun_drawn) { beamgun_drawn = 40*hudscale; } } if(flamethrower) { Draw_ScaledPic((int)(viddef.width/3) + rocketlauncher_drawn+chaingun_drawn+smartgun_drawn+beamgun_drawn , (int)(viddef.height/3.2), hudscale, "w_chaingun"); if(!flamethrower_drawn) { flamethrower_drawn = 40*hudscale; } } if(disruptor) { Draw_ScaledPic((int)(viddef.width/3) + rocketlauncher_drawn+chaingun_drawn+smartgun_drawn+beamgun_drawn+flamethrower_drawn , (int)(viddef.height/3.2), hudscale, "w_hyperblaster"); if(!disruptor_drawn) { disruptor_drawn = 40*hudscale; } } if(vaporizer) { Draw_ScaledPic((int)(viddef.width/3) + rocketlauncher_drawn+chaingun_drawn+smartgun_drawn+beamgun_drawn+flamethrower_drawn+disruptor_drawn , (int)(viddef.height/3.2), hudscale, "w_bfg"); if(!vaporizer_drawn) { vaporizer_drawn = 40*hudscale; } } if(quad) { Draw_ScaledPic((int)(viddef.width/3) + rocketlauncher_drawn+chaingun_drawn+smartgun_drawn+beamgun_drawn+flamethrower_drawn+disruptor_drawn+vaporizer_drawn , (int)(viddef.height/3.2), hudscale, "p_quad"); if(!quad_drawn) { quad_drawn = 40*hudscale; } } if(haste) { Draw_ScaledPic((int)(viddef.width/3) + rocketlauncher_drawn+chaingun_drawn+smartgun_drawn+beamgun_drawn+flamethrower_drawn+disruptor_drawn+vaporizer_drawn+quad_drawn , (int)(viddef.height/3.2), hudscale, "p_haste"); if(!haste_drawn) { haste_drawn = 40*hudscale; } } if(sproing) { Draw_ScaledPic((int)(viddef.width/3) + rocketlauncher_drawn+chaingun_drawn+smartgun_drawn+beamgun_drawn+flamethrower_drawn+disruptor_drawn+vaporizer_drawn+quad_drawn+haste_drawn , (int)(viddef.height/3.2), hudscale, "p_sproing"); if(!sproing_drawn) { sproing_drawn = 40*hudscale; } } if(inv) { Draw_ScaledPic((int)(viddef.width/3) + rocketlauncher_drawn+chaingun_drawn+smartgun_drawn+beamgun_drawn+flamethrower_drawn+disruptor_drawn+vaporizer_drawn+quad_drawn+haste_drawn+sproing_drawn , (int)(viddef.height/3.2), hudscale, "p_invulnerability"); if(!inv_drawn) { inv_drawn = 40*hudscale; } } if(adren) { Draw_ScaledPic((int)(viddef.width/3) + rocketlauncher_drawn+chaingun_drawn+smartgun_drawn+beamgun_drawn+flamethrower_drawn+disruptor_drawn+vaporizer_drawn+quad_drawn+haste_drawn+sproing_drawn+inv_drawn , (int)(viddef.height/3.2), hudscale, "p_adrenaline"); } } else { box.x = 0; box.y = ( viddef.height - font->size ) / 2; box.width = viddef.width; box.height = 0; FNT_BoundedPrint( font , "Awaiting Connection ..." , FNT_CMODE_NONE , FNT_ALIGN_CENTER , &box , FNT_colors[ 7 ] ); } // Add Download info stuff... if (cls.download && ( (int)ftell( cls.download ) / 1024 ) != 0 ) { if ( cls.key_dest != key_console ) //drop the console because of CURL's readout { CON_ToggleConsole(); } } else if (isMap) //loading bar... { //to do - fix //SCR_DrawRotatingIcon(); SCR_DrawLoadingBar(loadingPercent, font->size); box.x = 0; box.y = 2 + viddef.height / 2 + font->size * 6.3; box.width = viddef.width; box.height = 0; FNT_BoundedPrint( font , va("%3d%%", (int)loadingPercent) , FNT_CMODE_NONE , FNT_ALIGN_CENTER , &box , FNT_colors[ 7 ] ); } } //============================================================================= /* ================== SCR_RunConsole Scroll it up or down ================== */ void SCR_RunConsole (void) { // decide on the height of the console if (cls.key_dest == key_console) scr_conlines = scr_consize->value; else scr_conlines = 0; // none visible if (scr_conlines < scr_con_current) { scr_con_current -= scr_conspeed->value*cls.frametime; if (scr_conlines > scr_con_current) scr_con_current = scr_conlines; } else if (scr_conlines > scr_con_current) { scr_con_current += scr_conspeed->value*cls.frametime; if (scr_conlines < scr_con_current) scr_con_current = scr_conlines; } } /* ================== SCR_DrawConsole ================== */ float sendBubbleNow; void SCR_DrawConsole (void) { if (cls.state == ca_disconnected || cls.state == ca_connecting) { // forced full screen console CON_DrawConsole( scr_consize->value ); return; } if (cls.state != ca_active || !cl.refresh_prepped) { // connected, but can't render CON_DrawConsole( scr_consize->value ); Draw_Fill (0, viddef.height/2, viddef.width, viddef.height/2, RGBA(0,0,0,1)); return; } if (scr_con_current) { CON_DrawConsole( scr_con_current ); } else { if (cls.key_dest == key_game || cls.key_dest == key_message) CON_DrawNotify (); // only draw notify in game } //draw chat bubble if(cls.key_dest == key_message || scr_con_current) { //only send this every couple of seconds no need to flood sendBubbleNow += cls.frametime; if(sendBubbleNow >= 1) { Cbuf_AddText("chatbubble\n"); Cbuf_Execute (); sendBubbleNow = 0; } } } //============================================================================= /* ================ SCR_BeginLoadingPlaque ================ */ qboolean needLoadingPlaque (void) { if (!cls.disable_screen || !scr_draw_loading) return true; return false; } void SCR_BeginLoadingPlaque (void) { S_StopAllSounds (); cl.sound_prepped = false; // don't play ambients scr_draw_loading = 1; SCR_UpdateScreen (); cls.disable_screen = Sys_Milliseconds (); cls.disable_servercount = cl.servercount; } /* ================ SCR_EndLoadingPlaque ================ */ void SCR_EndLoadingPlaque (void) { cls.disable_screen = 0; scr_draw_loading = 0; CON_ClearNotify( ); Cvar_Set ("paused", "0"); } /* ================ SCR_Loading_f ================ */ void SCR_Loading_f (void) { SCR_BeginLoadingPlaque (); } int entitycmpfnc( const entity_t *a, const entity_t *b ) { /* ** all other models are sorted by model then skin */ if ( a->model == b->model ) { return ( ( ptrdiff_t ) a->skin - ( ptrdiff_t ) b->skin ); } else { return ( ( ptrdiff_t ) a->model - ( ptrdiff_t ) b->model ); } } /** * @brief Rendering performance test. * * Target of 'timerefresh' command. When invoked with an argument, end of * frame flush and page flipping are not done. Modified 2011-02 with * additional info in result. Use 'viewpos' (also modified) command * for repeatable, consistent positioning. * * Modified 2012-12 */ void SCR_TimeRefresh_f( void ) { int t_start, t_stop; float d_time; float frames_per_sec; float msec_per_frame; float save_yaw; int frame_count; float num_frames; float yaw_increment; float frame_yaw; char *cmd_arg; if ( cls.state != ca_active ) return; save_yaw = cl.refdef.viewangles[YAW]; num_frames = scr_timerefcount->value; frame_count = scr_timerefcount->integer; if ( frame_count < 1 || frame_count > 1440 ) { // silently protect against unreasonable setting num_frames = 128.0f; frame_count = 128; } cmd_arg = Cmd_Argv(1); switch ( *cmd_arg ) { case '1': // rotate yaw_increment = 360.0f / num_frames; break; case '2': // no rotate yaw_increment = 0.0f; break; default: Com_Printf("usage: timerefresh , 1=rotate,2=fixed\n"); return; } // show position Com_Printf ("x:%#1.0f y:%#1.0f z:%#1.0f yaw:%#1.0f pitch:%#1.0f\n", cl.refdef.vieworg[0], cl.refdef.vieworg[1], cl.refdef.vieworg[2], cl.refdef.viewangles[YAW], cl.refdef.viewangles[PITCH] ); // test loop frame_yaw = save_yaw; t_start = Sys_Milliseconds(); while ( frame_count-- ) { cl.refdef.viewangles[YAW] = frame_yaw; R_BeginFrame( 0 ); R_RenderFrame( &cl.refdef ); R_EndFrame(); frame_yaw += yaw_increment; } t_stop = Sys_Milliseconds(); // restore original yaw (not included in test frame count) cl.refdef.viewangles[YAW] = save_yaw; R_BeginFrame( 0 ); R_RenderFrame( &cl.refdef ); R_EndFrame(); // report d_time = (float)(t_stop - t_start); d_time += 0.5f; msec_per_frame = d_time / num_frames; d_time /= 1000.0f; frames_per_sec = num_frames / d_time; Com_Printf( "%1.0f frames, %1.3f sec, %1.3f msec/frame, %1.1f FPS\n", num_frames, d_time, msec_per_frame, frames_per_sec ); } //=============================================================== #define STAT_MINUS 10 // num frame for '-' stats digit char *sb_nums[2][11] = { {"num_0", "num_1", "num_2", "num_3", "num_4", "num_5", "num_6", "num_7", "num_8", "num_9", "num_minus"}, {"anum_0", "anum_1", "anum_2", "anum_3", "anum_4", "anum_5", "anum_6", "anum_7", "anum_8", "anum_9", "anum_minus"} }; #define ICON_WIDTH 24 #define ICON_HEIGHT 24 #define CHAR_WIDTH 16 #define ICON_SPACE 8 /* ================ SizeHUDString Allow embedded \n in the string ================ */ void SizeHUDString (char *string, int *w, int *h) { int lines, width, current; int charscale; charscale = (float)(viddef.height)*8/600; if(charscale < 8) charscale = 8; lines = 1; width = 0; current = 0; while (*string) { if (*string == '\n') { lines++; current = 0; } else { current++; if (current > width) width = current; } string++; } *w = width * charscale; *h = lines * charscale; } /* ============== SCR_DrawField ============== */ void SCR_DrawField (int x, int y, int color, int width, int value, float scale) { char num[16], *ptr; int l; int frame; if (width < 1) return; // draw number string if (width > 5) width = 5; Com_sprintf (num, sizeof(num), "%i", value); l = strlen(num); if (l > width) l = width; x += 2 + CHAR_WIDTH*(width - l)*scale; ptr = num; while (*ptr && l) { if (*ptr == '-') frame = STAT_MINUS; else frame = *ptr -'0'; Draw_ScaledPic (x,y,scale/1.8,sb_nums[color][frame]); x += CHAR_WIDTH*scale; ptr++; l--; } } /* =============== SCR_TouchPics Allows rendering code to cache all needed sbar graphics =============== */ void SCR_TouchPics (void) { int i, j; for (i=0 ; i<2 ; i++) for (j=0 ; j<11 ; j++) R_RegisterPic (sb_nums[i][j]); if (strcmp(crosshair->string, "none")) { Com_sprintf (crosshair_pic, sizeof(crosshair_pic), "%s", crosshair->string); Draw_GetPicSize (&crosshair_width, &crosshair_height, crosshair_pic); if (!crosshair_width) crosshair_pic[0] = 0; } } /* ================ SCR_ExecuteLayoutString ================ */ void SCR_ExecuteLayoutString (char *s) { FNT_font_t font; struct FNT_window_s box; int x, y, ny=0; //ny is coordinates used for new sb layout client tags only int value; char * token; int numwidth = 3; //amount of digits of number being drawn int index; clientinfo_t * ci; int charscale; float scale; qboolean newSBlayout = false; int left, top, right, bottom, width, height, midx, midy; if (cls.state != ca_active || !cl.refresh_prepped) return; if (!s[0]) return; font = FNT_AutoGet( CL_gameFont ); charscale = font->size; scale = charscale * 0.125; width = cl.refdef.width; height = cl.refdef.height; x = left = cl.refdef.x; y = ny = top = cl.refdef.y; right = left+width; bottom = top+height; midx = left+width/2; midy = top+height/2; if (width < 1024 || height < 768) { // Below 1024x768, start scaling things down to make sure everything // fits. We scale x and y by the same amount to keep things square, // but we figure out the ratios separately and use the ratio which // results in the smallest scale. float xscale, yscale; xscale = (float)width/1024.0f; yscale = (float)height/768.0f; if (xscale < yscale) scale *= xscale; else scale *= yscale; } while (s) { token = COM_Parse (&s); if (!strcmp(token, "xl")) { token = COM_Parse (&s); x = left + atoi(token)*scale; continue; } if (!strcmp(token, "xr")) { token = COM_Parse (&s); x = right + atoi(token)*scale; continue; } if (!strcmp(token, "xv")) { token = COM_Parse (&s); x = midx + (atoi(token) - 160)*scale; continue; } if (!strcmp(token, "yt")) { token = COM_Parse (&s); y = top + atoi(token)*scale; continue; } if (!strcmp(token, "yb")) { token = COM_Parse (&s); y = bottom + atoi(token)*scale; continue; } if (!strcmp(token, "yv")) { token = COM_Parse (&s); y = midy + (atoi(token) - 100)*scale; ny = midy + (atoi(token)/2 - 100)*scale; continue; } if (!strcmp(token, "pic")) { // draw a pic from a stat number if(strcmp(cl_hudimage1->string, "none")) { token = COM_Parse (&s); value = cl.frame.playerstate.stats[atoi(token)]; if (value >= MAX_IMAGES) Com_Error (ERR_DROP, "Pic >= MAX_IMAGES"); if( cl.configstrings[CS_IMAGES+value][0] ) { Draw_ScaledPic (x, y, scale, cl.configstrings[CS_IMAGES+value]); if(!strcmp(cl.configstrings[CS_IMAGES+value], "i_team1") || !strcmp(cl.configstrings[CS_IMAGES+value], "i_team2")) { r_gotFlag = false; r_lostFlag = true; Cvar_Set("rs_hasflag", "0"); if(!strcmp(cl.configstrings[CS_IMAGES+value], "i_team1")) Cvar_Set("rs_team", "blue"); else Cvar_Set("rs_team", "red"); } else if(!strcmp(cl.configstrings[CS_IMAGES+value], "i_flag1") || !strcmp(cl.configstrings[CS_IMAGES+value], "i_flag2")) { r_gotFlag = true; r_lostFlag = false; Cvar_Set("rs_hasflag", "1"); if(!strcmp(cl.configstrings[CS_IMAGES+value], "i_flag1")) Cvar_Set("rs_team", "blue"); else Cvar_Set("rs_team", "red"); } } } continue; } if (!strcmp(token, "newsb")) { //print header here x = midx - 160*scale; y = midy - 64*scale; box.x = x + 4 * scale , box.y = y; FNT_RawPrint( font , "Player" , 6 , false , box.x , box.y , FNT_colors[ 7 ] ); box.x += 160 * scale , box.width = 56 * scale , box.height = 0; FNT_BoundedPrint( font , "Score" , FNT_CMODE_NONE , FNT_ALIGN_RIGHT , &box , FNT_colors[ 7 ] ); box.x += 56 * scale , box.width = 48 * scale , box.height = 0; FNT_BoundedPrint( font , "Ping" , FNT_CMODE_NONE , FNT_ALIGN_RIGHT , &box , FNT_colors[ 7 ] ); box.x += 48 * scale , box.width = 48 * scale , box.height = 0; FNT_BoundedPrint( font , "Time" , FNT_CMODE_NONE , FNT_ALIGN_RIGHT , &box , FNT_colors[ 7 ] ); newSBlayout = true; continue; } if (!strcmp(token, "newctfsb")) { //print header here x = midx - 256*scale; y = midy - 72*scale; while ( x <= midx ) { box.x = x + 14 * scale , box.y = y; FNT_RawPrint( font , "Player" , 6 , false , box.x , box.y , FNT_colors[ 7 ] ); box.x += 118 * scale , box.width = 56 * scale , box.height = 0; FNT_BoundedPrint( font , "Score" , FNT_CMODE_NONE , FNT_ALIGN_RIGHT , &box , FNT_colors[ 7 ] ); box.x += 56 * scale , box.width = 48 * scale , box.height = 0; FNT_BoundedPrint( font , "Ping" , FNT_CMODE_NONE , FNT_ALIGN_RIGHT , &box , FNT_colors[ 7 ] ); x += 256 * scale; } newSBlayout = true; continue; } if (!strcmp(token, "client") || !strcmp(token, "queued")) { // draw a deathmatch client block qboolean isQueued = ( token[ 0 ] == 'q' ); int score, ping, time; const char * timeMessage; int timeColor; token = COM_Parse (&s); x = midx + (atoi(token) - 160)*scale; token = COM_Parse (&s); if(newSBlayout) y = midy + (atoi(token)/2 - 100)*scale; else y = midy + (atoi(token) - 100)*scale; token = COM_Parse (&s); value = atoi(token); if (value >= MAX_CLIENTS || value < 0) Com_Error (ERR_DROP, "client >= MAX_CLIENTS"); ci = &cl.clientinfo[value]; token = COM_Parse (&s); score = atoi(token); token = COM_Parse (&s); ping = atoi(token); token = COM_Parse (&s); time = atoi(token); if ( isQueued ) { COM_Parse (&s); timeMessage = "Queue:"; timeColor = 1; } else { timeMessage = "Time:"; timeColor = 7; } if(newSBlayout) { //new scoreboard layout box.x = x + 4 * scale , box.y = y + 34 * scale; box.width = 160 * scale , box.height = 0; FNT_BoundedPrint( font , ci->name , FNT_CMODE_QUAKE_SRS , FNT_ALIGN_LEFT , &box , FNT_colors[ 2 ] ); box.x += 160 * scale , box.width = 56 * scale , box.height = 0; FNT_BoundedPrint( font , va( "%i" , score ) , FNT_CMODE_NONE , FNT_ALIGN_RIGHT , &box , FNT_colors[ 2 ] ); box.x += 56 * scale , box.width = 48 * scale , box.height = 0; FNT_BoundedPrint( font , va( "%i" , ping ) , FNT_CMODE_NONE , FNT_ALIGN_RIGHT , &box , FNT_colors[ 7 ] ); box.x += 48 * scale , box.width = 48 * scale , box.height = 0; FNT_BoundedPrint( font , va( "%i" , time ) , FNT_CMODE_QUAKE , FNT_ALIGN_RIGHT , &box , FNT_colors[ timeColor ] ); } else { box.x = x + 32 * scale , box.y = y; box.width = 288 * scale , box.height = 0; FNT_BoundedPrint( font , ci->name , FNT_CMODE_QUAKE_SRS , FNT_ALIGN_LEFT , &box , FNT_colors[ 2 ] ); box.y += 8 * scale; box.width = 100 * scale , box.height = 0; FNT_BoundedPrint( font , "Score:" , FNT_CMODE_NONE , FNT_ALIGN_LEFT , &box , FNT_colors[ 7 ] ); box.x += box.width; box.width = 100 * scale - box.width , box.height = 0; FNT_BoundedPrint( font , va( "%i" , score ) , FNT_CMODE_NONE , FNT_ALIGN_RIGHT , &box , FNT_colors[ 2 ] ); box.y += 8 * scale , box.x = x + 32 * scale; box.width = 100 * scale , box.height = 0; FNT_BoundedPrint( font , "Ping:" , FNT_CMODE_NONE , FNT_ALIGN_LEFT , &box , FNT_colors[ 7 ] ); box.x += box.width; box.width = 100 * scale - box.width , box.height = 0; FNT_BoundedPrint( font , va( "%i" , ping ) , FNT_CMODE_NONE , FNT_ALIGN_RIGHT , &box , FNT_colors[ 7 ] ); box.y += 8 * scale , box.x = x + 32 * scale; box.width = 100 * scale , box.height = 0; FNT_BoundedPrint( font , timeMessage , FNT_CMODE_NONE , FNT_ALIGN_LEFT , &box , FNT_colors[ timeColor ] ); box.x += box.width; box.width = 100 * scale - box.width , box.height = 0; FNT_BoundedPrint( font , va( "%i" , time ) , FNT_CMODE_NONE , FNT_ALIGN_RIGHT , &box , FNT_colors[ timeColor ] ); if (!ci->icon) ci = &cl.baseclientinfo; Draw_ScaledPic (x, y, scale/2, ci->iconname); } continue; } if (!strcmp(token, "ctf")) { // draw a ctf client block int score, ping; char block[80]; int team; token = COM_Parse (&s); x = midx + (atoi(token) - 160)*scale; if(atoi(token) < 0) team = 0; else team = 1; token = COM_Parse (&s); y = midy + (atoi(token) - 100)*scale; token = COM_Parse (&s); value = atoi(token); if (value >= MAX_CLIENTS || value < 0) Com_Error (ERR_DROP, "client >= MAX_CLIENTS"); ci = &cl.clientinfo[value]; token = COM_Parse (&s); score = atoi(token); token = COM_Parse (&s); ping = atoi(token); if (ping > 999) ping = 999; if(newSBlayout) { box.x = x + 14 * scale , box.y = y + 2 * scale; box.width = 118 * scale , box.height = 0; FNT_BoundedPrint( font , ci->name , FNT_CMODE_QUAKE_SRS , FNT_ALIGN_LEFT , &box , FNT_colors[ 2 ] ); box.x += 120 * scale , box.width = 56 * scale , box.height = 0; FNT_BoundedPrint( font , va( "%i" , score ) , FNT_CMODE_NONE , FNT_ALIGN_RIGHT , &box , FNT_colors[ 2 ] ); box.x += 56 * scale , box.width = 48 * scale , box.height = 0; FNT_BoundedPrint( font , va( "%i" , ping ) , FNT_CMODE_NONE , FNT_ALIGN_RIGHT , &box , FNT_colors[ 7 ] ); if(team) { //draw pic on left side(done client side to save packetsize Draw_ScaledPic (x, y-2*scale, scale, "/pics/blueplayerbox"); } else Draw_ScaledPic(x, y-2*scale, scale, "/pics/redplayerbox"); } else { sprintf(block, "%3d %3d %s", score, ping, ci->name); box.x = x , box.y = y , box.width = 256 , box.height = 0; FNT_BoundedPrint( font , block , FNT_CMODE_QUAKE_SRS , FNT_ALIGN_LEFT , &box , FNT_colors[ 2 ] ); } continue; } if (!strcmp(token, "picn")) { // draw a pic from a name token = COM_Parse (&s); if(newSBlayout && !strcmp(token, "playerbox")) { //cannot simply fill y = ny here Draw_ScaledPic (x, ny+32*scale, scale, token); } else { Draw_ScaledPic (x, y, scale, token); } continue; } if (!strcmp(token, "num")) { // draw a number if(strcmp(cl_hudimage1->string, "none")) { token = COM_Parse (&s); numwidth = atoi(token); token = COM_Parse (&s); value = cl.frame.playerstate.stats[atoi(token)]; SCR_DrawField (x, y, 0, numwidth, value, scale); } continue; } if (!strcmp(token, "hnum")) { // health number if(strcmp(cl_hudimage1->string, "none")) { int color; numwidth = 3; value = cl.frame.playerstate.stats[STAT_HEALTH]; if (value > 25) color = 0; // green else if (value > 0) color = (cl.frame.serverframe>>2) & 1; // flash else color = 1; SCR_DrawField (x, y, color, numwidth, value, scale); } //draw the zoom scope pic if we are using the zoom alt-fire of disruptor if (cl.frame.playerstate.stats[STAT_ZOOMED]) { char zoompic[32]; sprintf(zoompic, "zoomscope%i", cl.frame.playerstate.stats[STAT_ZOOMED]); Draw_StretchPic (left, top, width, height, zoompic); } continue; } if (!strcmp(token, "anum")) { // ammo number if(strcmp(cl_hudimage1->string, "none")) { int color; numwidth = 3; value = cl.frame.playerstate.stats[STAT_AMMO]; if (value > 5) color = 0; // green else if (value >= 0) color = (cl.frame.serverframe>>2) & 1; // flash else continue; // negative number = don't show SCR_DrawField (x, y, color, numwidth, value, scale); } continue; } if (!strcmp(token, "rnum")) { // armor number if(strcmp(cl_hudimage1->string, "none")) { int color; numwidth = 3; value = cl.frame.playerstate.stats[STAT_ARMOR]; if (value < 1) continue; color = 0; // green SCR_DrawField (x, y, color, numwidth, value, scale); } continue; } if (!strcmp(token, "stat_string")) { token = COM_Parse (&s); index = atoi(token); if (index < 0 || index >= MAX_CONFIGSTRINGS) Com_Error (ERR_DROP, "Bad stat_string index"); index = cl.frame.playerstate.stats[index]; if (index < 0 || index >= MAX_CONFIGSTRINGS) Com_Error (ERR_DROP, "Bad stat_string index"); FNT_RawPrint( font , cl.configstrings[index] , strlen( cl.configstrings[index] ) , false , x , y , FNT_colors[ 7 ] ); continue; } if (!strcmp(token, "cstring")) { token = COM_Parse (&s); box.width = 2*(x>midx?(right-x):x); box.x = x-box.width/2; box.y = y; box.height = 0; FNT_BoundedPrint( font , token , FNT_CMODE_NONE , FNT_ALIGN_CENTER , &box , FNT_colors[ 7 ] ); continue; } if (!strcmp(token, "string")) { token = COM_Parse (&s); //this line is an Alien Arena specific hack of sorts, remove if needed if(!strcmp(token, "Vote")) Draw_ScaledPic (midx - 85*scale, y-8*scale, scale, "votebox"); FNT_RawPrint( font , token , strlen( token ) , false , x , y , FNT_colors[ 7 ] ); continue; } if (!strcmp(token, "cstring2")) { token = COM_Parse (&s); box.width = 2*(x>midx?(right-x):x); box.x = x-box.width/2; box.y = y; box.height = 0; FNT_BoundedPrint( font , token , FNT_CMODE_NONE , FNT_ALIGN_CENTER , &box , FNT_colors[ 3 ] ); continue; } if (!strcmp(token, "string2")) { token = COM_Parse (&s); FNT_RawPrint( font , token , strlen( token ) , false , x , y , FNT_colors[ 7 ] ); continue; } if (!strcmp(token, "if")) { // draw a number token = COM_Parse (&s); value = cl.frame.playerstate.stats[atoi(token)]; if (!value) { // skip to endif while (s && strcmp(token, "endif") ) { token = COM_Parse (&s); } } continue; } } } /* ================ SCR_DrawStats The status bar is a small layout program that is based on the stats array ================ */ void SCR_DrawStats (void) { SCR_ExecuteLayoutString (cl.configstrings[CS_STATUSBAR]); } /* ================ SCR_DrawLayout ================ */ #define STAT_LAYOUTS 13 void SCR_DrawLayout (void) { if (!cl.frame.playerstate.stats[STAT_LAYOUTS]) return; SCR_ExecuteLayoutString (cl.layout); } /* ================= SCR_DrawPlayerIcon ================= */ char scr_playericon[MAX_OSPATH]; char scr_playername[PLAYERNAME_SIZE]; float scr_playericonalpha; void SCR_DrawPlayerIcon(void) { FNT_font_t font; struct FNT_window_s box; int w, h; float scale, iconPos; if (cls.key_dest == key_menu || cls.key_dest == key_console) return; if(scr_playericonalpha <= 0.0) return; scr_playericonalpha -= cls.frametime; //fade map pic in if(scr_playericonalpha < 1.0) iconPos = scr_playericonalpha; else iconPos = 1.0; scale = (float)(viddef.height)/600; if(scale < 1) scale = 1; w = h = 64; //icon size, will change to be larger w*=scale; h*=scale; Draw_AlphaStretchPlayerIcon( -w+(w*iconPos), viddef.height/2 + h/2, w, h, scr_playericon, scr_playericonalpha); font = FNT_AutoGet( CL_gameFont ); box.x = -w+(w*iconPos); box.y = viddef.height/2 + h + 32*scale; box.width = viddef.width - box.x; box.height = 0; FNT_BoundedPrint( font , scr_playername , FNT_CMODE_QUAKE , FNT_ALIGN_LEFT , &box , FNT_colors[ 2 ] ); } /* ================ SCR_showTimer ================ */ int seconds, minutes; void SCR_showTimer(void) { static char temptime[ 32 ]; static int timecounter; FNT_font_t font; if (cls.key_dest == key_menu || cls.key_dest == key_console) return; if ((cls.realtime + 2000) < timecounter) timecounter = cl.time + 1000; if (cls.realtime > timecounter) { seconds += 1; if(seconds >= 60) { minutes++; seconds = 0; } Com_sprintf(temptime, sizeof(temptime),"%i:%2.2i", minutes, seconds); timecounter = cls.realtime + 1000; } font = FNT_AutoGet( CL_gameFont ); Draw_StretchPic( viddef.width - 13 * font->size , viddef.height - 5.25 * font->size , 4 * font->size , 4 * font->size , "timer"); FNT_RawPrint( font , temptime , strlen( temptime ) , false , viddef.width - 8 * font->size , viddef.height - 3.75 * font->size , FNT_colors[ 7 ] ); } /* ================ SCR_showPerfTest ================ */ perftest_t *get_perftest(char *name) { int i; perftest_t *test = NULL; for (i = 0; i < MAX_PERFTESTS; i++) { if (!perftests[i].in_use) { test = &perftests[i]; break; } if (!strncmp(perftests[i].name, name, sizeof(perftests[i].name))) return &perftests[i]; } if (!test) return NULL; //remember to handle this in your code! memset(test, 0, sizeof(perftest_t)); test->in_use = true; strncpy (test->name, name, sizeof(test->name)); return test; } //slotnum is used for the vertical offset on the screen void SCR_showPerfTest (perftest_t *test, int slotnum) { FNT_font_t font; int end_msec; float time_sec; float rate; int height; if (!test->in_use) return; if (cls.key_dest == key_menu || cls.key_dest == key_console || !test->cvar->integer) { test->restart = true; return; } if (test->restart) { test->start_msec = Sys_Milliseconds(); test->counter = 0.0f; test->framecounter = 0.0f; test->update_trigger = 10.0f; //initial delay to update test->text[0] = 0; //blank the text buffer test->restart = false; return; } test->framecounter += 1.0f; if (test->framecounter >= test->update_trigger) { end_msec = Sys_Milliseconds(); time_sec = ((float)(end_msec - test->start_msec)) / 1000.0f; if (test->is_timerate) { //calculate rate to display rate = test->scale * test->counter / time_sec; } else { rate = test->scale * test->counter; } //update text buffer for display Com_sprintf( test->text, sizeof(test->text), test->format, rate ); test->start_msec = end_msec; if (test->is_timerate) //setup for next update - 0.25 sec update interval test->update_trigger = test->framecounter / (4.0 * time_sec); else //0.05 sec update interval test->update_trigger = test->framecounter / (20.0 * time_sec); test->framecounter = 0.0f; test->counter = 0.0f; } font = FNT_AutoGet( CL_gameFont ); height = viddef.height - 2.0 * font->size * (slotnum + 1); if (cl_drawtimer->integer) height -= 5.25 * font->size; FNT_RawPrint( font , test->text , strlen( test->text ) , false , viddef.width - 8 * font->size , height, FNT_colors[ 2 ] ); } void SCR_showAllPerfTests (void) { int i, testsDrawn; for (i = 0, testsDrawn = 0; i < MAX_PERFTESTS; i++) { if (perftests[i].in_use && perftests[i].cvar->integer) { SCR_showPerfTest (&perftests[i], testsDrawn); testsDrawn++; } } } void SCR_showFPS(void) { static perftest_t *test = NULL; if (!test) { test = get_perftest("fps"); if (!test) return; //couldn't acquire test test->cvar = cl_drawfps; test->is_timerate = true; strcpy (test->format, "%3.0ffps"); test->scale = 1.0f; } test->counter += 1.0f; } // Shows kilobytes per second from the server extern int c_incoming_bytes; void SCR_showBandwidth (void) { static perftest_t *test = NULL; if (!test) { test = get_perftest("bandwidth"); if (!test) return; //couldn't acquire test test->is_timerate = true; test->cvar = cl_drawbandwidth; strcpy (test->format, "%2.2fkibps"); test->scale = 1.0f/1024.0f; //the SI is wrong, it's 1024 } test->counter += c_incoming_bytes; c_incoming_bytes = 0; } // Shows number of frames per second which took longer than a configurable // amount of milliseconds. This is a useful measure of jitter, which isn't // usually reflected in average FPS rates but which can still be visually // annoying. void SCR_showFramesOver (void) { static perftest_t *test = NULL; static int old_milliseconds = 0; int new_milliseconds; if (!test) { test = get_perftest("framesover"); if (!test) return; //couldn't acquire test test->is_timerate = true; test->cvar = cl_drawframesover; strcpy (test->format, "%3.0fjfps"); //jfps = jitter frames per second test->scale = 1.0f; old_milliseconds = Sys_Milliseconds(); } new_milliseconds = Sys_Milliseconds(); if ((new_milliseconds - old_milliseconds) > cl_drawframesover->integer) test->counter++; old_milliseconds = new_milliseconds; } /** * * @brief Construct map-maker's "r_speed" performance counter displays * * the traditional r_speeds cvar is replaced by individual counter cvars, * named "rspeed_*" */ static void show_rspeed_helper( cvar_t* test_cvar, perftest_t* test_obj, char* test_name, char* test_format, int test_counter ) { if ( test_cvar && test_cvar->integer ) { if ( test_obj == NULL ) { /* constructor */ test_obj = get_perftest( test_name ); if ( test_obj != NULL ) { /* slot allocated, construct */ test_obj->is_timerate = false; test_obj->cvar = test_cvar; strcpy( test_obj->format, test_format ); test_obj->scale = 1.0f; test_obj->counter = test_counter; } else { /* no slot, force disable */ (void)Cvar_ForceSet( test_cvar->name, "0" ); } } else { /* running, update counter from refresh counter */ test_obj->counter = test_counter; } } } void SCR_showRSpeeds( void ) { static perftest_t *test_wpoly = NULL; static perftest_t *test_epoly = NULL; static perftest_t *test_flares = NULL; static perftest_t *test_grasses = NULL; static perftest_t *test_beams = NULL; static perftest_t *test_vbobatches = NULL; static perftest_t *test_particles = NULL; show_rspeed_helper( rspeed_wpolys, test_wpoly, "wpolys", "%5.0f wpolys", c_brush_polys ); show_rspeed_helper( rspeed_epolys, test_epoly, "epolys", "%5.0f epolys", c_alias_polys ); show_rspeed_helper( rspeed_flares, test_flares, "flares", "%5.0f flares", c_flares ); show_rspeed_helper( rspeed_grasses, test_grasses, "grasses", "%5.0f grasses", c_grasses ); show_rspeed_helper( rspeed_beams, test_beams, "beams", "%5.0f beams", c_beams ); show_rspeed_helper( rspeed_vbobatches, test_vbobatches, "vbobatches", "%5.0f vbobatches", c_vbo_batches ); show_rspeed_helper( rspeed_particles, test_particles, "particles", "%5.0f particles", cl.refdef.num_particles ); } /* ================== SCR_UpdateScreen This is called every frame, and can also be called explicitly to flush text to the screen. ================== */ void SCR_UpdateScreen (void) { int numframes; int i; float separation[2] = { 0, 0 }; // if the screen is disabled (loading plaque is up, or vid mode changing) // do nothing at all if (cls.disable_screen) { if (Sys_Milliseconds() - cls.disable_screen > 120000) { cls.disable_screen = 0; Com_Printf ("Loading plaque timed out.\n"); return; } scr_draw_loading = 2; } if (!scr_initialized) return; // not initialized yet /* ** range check cl_camera_separation so we don't inadvertently fry someone's ** brain */ if ( cl_stereo_separation->value > 1.0 ) Cvar_SetValue( "cl_stereo_separation", 1.0 ); else if ( cl_stereo_separation->value < 0 ) Cvar_SetValue( "cl_stereo_separation", 0.0 ); if ( cl_stereo->value ) { numframes = 2; separation[0] = -cl_stereo_separation->value / 2; separation[1] = cl_stereo_separation->value / 2; } else { separation[0] = 0; separation[1] = 0; numframes = 1; } for ( i = 0; i < numframes; i++ ) { R_BeginFrame( separation[i] ); if (scr_draw_loading == 2) { // loading plaque over black screen SCR_DrawLoading (); if (cls.disable_screen) scr_draw_loading = 2; //NO CONSOLE!!! continue; } else { // do 3D refresh drawing, and then update the screen SCR_CalcVrect (); need_free_vbo = true; V_RenderView ( separation[i] ); SCR_DrawStats (); if (cl.frame.playerstate.stats[STAT_LAYOUTS] & 1) SCR_DrawLayout (); if (cl.frame.playerstate.stats[STAT_LAYOUTS] & 2) CL_DrawInventory (); SCR_DrawNet (); SCR_CheckDrawCenterString (); SCR_CheckDrawIRCString(); if (scr_timegraph->value) SCR_DebugGraph (cls.frametime*600, RGBA(0,0,0,1)); if (scr_debuggraph->value || scr_timegraph->value || scr_netgraph->value) SCR_DrawDebugGraph (); SCR_DrawPause (); SCR_DrawConsole (); if (need_free_vbo) R_VCFreeFrame(); M_Draw (); SCR_DrawLoading (); if(cl_drawfps->integer) { SCR_showFPS(); } if(cl_drawbandwidth->integer) { SCR_showBandwidth(); } if(cl_drawframesover->integer) { SCR_showFramesOver(); } SCR_showRSpeeds(); /* map-maker's performance counters */ SCR_showAllPerfTests(); if(cl_drawtimer->integer) { SCR_showTimer(); } SCR_DrawPlayerIcon(); } } R_EndFrame(); } alien-arena-7.66+dfsg/source/client/qal.c0000600000175000017500000004440312161402010017306 0ustar zero79zero79/* Copyright (C) 2009 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * qal.c * * OpenAL functions * * All OpenAL 1.1 functions are declared here, but may not currently be used. * * Note: functions wrap the function pointers for ease of development. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #if defined WIN32_VARIANT # include #endif #if defined HAVE_AL_H #include #include #elif defined HAVE_AL_AL_H #include #include #elif defined HAVE_OPENAL_AL_H #include #include #else #error OpenAL header includes not defined. #endif #include "client.h" #include "qal.h" /* * OpenAL symbol addresses */ LPALENABLE pqalEnable; LPALDISABLE pqalDisable; LPALISENABLED pqalIsEnabled; LPALGETBOOLEANV pqalGetBooleanv; LPALGETINTEGERV pqalGetIntegerv; LPALGETSTRING pqalGetString; LPALGETFLOATV pqalGetFloatv; LPALGETDOUBLEV pqalGetDoublev; LPALGETBOOLEAN pqalGetBoolean; LPALGETINTEGER pqalGetInteger; LPALGETFLOAT pqalGetFloat; LPALGETDOUBLE pqalGetDouble; LPALGETERROR pqalGetError; LPALISEXTENSIONPRESENT pqalIsExtensionPresent; LPALGETPROCADDRESS pqalGetProcAddress; LPALGETENUMVALUE pqalGetEnumValue; LPALLISTENERF pqalListenerf; LPALLISTENER3F pqalListener3f; LPALLISTENERFV pqalListenerfv; LPALLISTENERI pqalListeneri; LPALLISTENER3I pqalListener3i; LPALLISTENERIV pqalListeneriv; LPALGETLISTENERF pqalGetListenerf; LPALGETLISTENER3F pqalGetListener3f; LPALGETLISTENERFV pqalGetListenerfv; LPALGETLISTENERI pqalGetListeneri; LPALGETLISTENER3I pqalGetListener3i; LPALGETLISTENERIV pqalGetListeneriv; LPALGENSOURCES pqalGenSources; LPALDELETESOURCES pqalDeleteSources; LPALISSOURCE pqalIsSource; LPALSOURCEF pqalSourcef; LPALSOURCE3F pqalSource3f; LPALSOURCEFV pqalSourcefv; LPALSOURCEI pqalSourcei; LPALSOURCE3I pqalSource3i; LPALSOURCEIV pqalSourceiv; LPALGETSOURCEF pqalGetSourcef; LPALGETSOURCE3F pqalGetSource3f; LPALGETSOURCEFV pqalGetSourcefv; LPALGETSOURCEI pqalGetSourcei; LPALGETSOURCE3I pqalGetSource3i; LPALGETSOURCEIV pqalGetSourceiv; LPALSOURCEPLAYV pqalSourcePlayv; LPALSOURCESTOPV pqalSourceStopv; LPALSOURCEREWINDV pqalSourceRewindv; LPALSOURCEPAUSEV pqalSourcePausev; LPALSOURCEPLAY pqalSourcePlay; LPALSOURCESTOP pqalSourceStop; LPALSOURCEREWIND pqalSourceRewind; LPALSOURCEPAUSE pqalSourcePause; LPALSOURCEQUEUEBUFFERS pqalSourceQueueBuffers; LPALSOURCEUNQUEUEBUFFERS pqalSourceUnqueueBuffers; LPALGENBUFFERS pqalGenBuffers; LPALDELETEBUFFERS pqalDeleteBuffers; LPALISBUFFER pqalIsBuffer; LPALBUFFERDATA pqalBufferData; LPALBUFFERF pqalBufferf; LPALBUFFER3F pqalBuffer3f; LPALBUFFERFV pqalBufferfv; LPALBUFFERI pqalBufferi; LPALBUFFER3I pqalBuffer3i; LPALBUFFERIV pqalBufferiv; LPALGETBUFFERF pqalGetBufferf; LPALGETBUFFER3F pqalGetBuffer3f; LPALGETBUFFERFV pqalGetBufferfv; LPALGETBUFFERI pqalGetBufferi; LPALGETBUFFER3I pqalGetBuffer3i; LPALGETBUFFERIV pqalGetBufferiv; LPALDOPPLERFACTOR pqalDopplerFactor; LPALDOPPLERVELOCITY pqalDopplerVelocity; LPALSPEEDOFSOUND pqalSpeedOfSound; LPALDISTANCEMODEL pqalDistanceModel; LPALCCREATECONTEXT pqalcCreateContext; LPALCMAKECONTEXTCURRENT pqalcMakeContextCurrent; LPALCPROCESSCONTEXT pqalcProcessContext; LPALCSUSPENDCONTEXT pqalcSuspendContext; LPALCDESTROYCONTEXT pqalcDestroyContext; LPALCGETCURRENTCONTEXT pqalcGetCurrentContext; LPALCGETCONTEXTSDEVICE pqalcGetContextsDevice; LPALCOPENDEVICE pqalcOpenDevice; LPALCCLOSEDEVICE pqalcCloseDevice; LPALCGETERROR pqalcGetError; LPALCISEXTENSIONPRESENT pqalcIsExtensionPresent; LPALCGETPROCADDRESS pqalcGetProcAddress; LPALCGETENUMVALUE pqalcGetEnumValue; LPALCGETSTRING pqalcGetString; LPALCGETINTEGERV pqalcGetIntegerv; LPALCCAPTUREOPENDEVICE pqalcCaptureOpenDevice; LPALCCAPTURECLOSEDEVICE pqalcCaptureCloseDevice; LPALCCAPTURESTART pqalcCaptureStart; LPALCCAPTURESTOP pqalcCaptureStop; LPALCCAPTURESAMPLES pqalcCaptureSamples; /* * Renderer State management */ void qalEnable( ALenum capability ) { ( *pqalEnable )( capability ); } void qalDisable( ALenum capability ) { ( *pqalDisable )( capability ); } ALboolean qalIsEnabled( ALenum capability ) { return ( *pqalIsEnabled )( capability ); } /* State retrieval */ const ALchar* qalGetString( ALenum param ) { return ( *pqalGetString )( param ); } void qalGetBooleanv( ALenum param, ALboolean* data ) { ( *pqalGetBooleanv )( param, data ); } void qalGetIntegerv( ALenum param, ALint* data ) { ( *pqalGetIntegerv )( param, data ); } void qalGetFloatv( ALenum param, ALfloat* data ) { ( *pqalGetFloatv )( param, data ); } void qalGetDoublev( ALenum param, ALdouble* data ) { ( *pqalGetDoublev )( param, data ); } ALboolean qalGetBoolean( ALenum param ) { return ( *pqalGetBoolean )( param ); } ALint qalGetInteger( ALenum param ) { return ( *pqalGetInteger )( param ); } ALfloat qalGetFloat( ALenum param ) { return ( *pqalGetFloat )( param ); } ALdouble qalGetDouble( ALenum param ) { return ( *pqalGetDouble )( param ); } /* * Error support. * Obtain the most recent error generated in the AL state machine. */ ALenum qalGetError( void ) { return ( *pqalGetError )(); } /* * Extension support. * Query for the presence of an extension, and obtain any appropriate * function pointers and enum values. */ ALboolean qalIsExtensionPresent( const ALchar* extname ) { return ( *pqalIsExtensionPresent )( extname ); } void* qalGetProcAddress( const ALchar* fname ) { return ( *pqalGetProcAddress )( fname ); } ALenum qalGetEnumValue( const ALchar* ename ) { return ( *pqalGetEnumValue )( ename ); } /* * LISTENER * Listener represents the location and orientation of the * 'user' in 3D-space. * * Properties include: - * * Gain AL_GAIN ALfloat * Position AL_POSITION ALfloat[3] * Velocity AL_VELOCITY ALfloat[3] * Orientation AL_ORIENTATION ALfloat[6] (Forward then Up vectors) */ /* * Set Listener parameters */ void qalListenerf( ALenum param, ALfloat value ) { ( *pqalListenerf )( param, value ); } void qalListener3f( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ) { ( *pqalListener3f )( param, value1, value2, value3 ); } void qalListenerfv( ALenum param, const ALfloat* values ) { ( *pqalListenerfv )( param, values ); } void qalListeneri( ALenum param, ALint value ) { ( *pqalListeneri )( param, value ); } void qalListener3i( ALenum param, ALint value1, ALint value2, ALint value3 ) { ( *pqalListener3i )( param, value1, value2, value3 ); } void qalListeneriv( ALenum param, const ALint* values ) { ( *pqalListeneriv )( param, values ); } /* * Get Listener parameters */ void qalGetListenerf( ALenum param, ALfloat* value ) { ( *pqalGetListenerf )( param, value ); } void qalGetListener3f( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 ) { ( *pqalGetListener3f )( param, value1, value2, value3 ); } void qalGetListenerfv( ALenum param, ALfloat* values ) { ( *pqalGetListenerfv )( param, values ); } void qalGetListeneri( ALenum param, ALint* value ) { ( *pqalGetListeneri )( param, value ); } void qalGetListener3i( ALenum param, ALint *value1, ALint *value2, ALint *value3 ) { ( *pqalGetListener3i )( param, value1, value2, value3 ); } void qalGetListeneriv( ALenum param, ALint* values ) { ( *pqalGetListeneriv )( param, values ); } /** * SOURCE * Sources represent individual sound objects in 3D-space. * Sources take the PCM data provided in the specified Buffer, * apply Source-specific modifications, and then * submit them to be mixed according to spatial arrangement etc. * * Properties include: - * * Gain AL_GAIN ALfloat * Min Gain AL_MIN_GAIN ALfloat * Max Gain AL_MAX_GAIN ALfloat * Position AL_POSITION ALfloat[3] * Velocity AL_VELOCITY ALfloat[3] * Direction AL_DIRECTION ALfloat[3] * Head Relative Mode AL_SOURCE_RELATIVE ALint (AL_TRUE,AL_FALSE) * Reference Distance AL_REFERENCE_DISTANCE ALfloat * Max Distance AL_MAX_DISTANCE ALfloat * RollOff Factor AL_ROLLOFF_FACTOR ALfloat * Inner Angle AL_CONE_INNER_ANGLE ALint or ALfloat * Outer Angle AL_CONE_OUTER_ANGLE ALint or ALfloat * Cone Outer Gain AL_CONE_OUTER_GAIN ALint or ALfloat * Pitch AL_PITCH ALfloat * Looping AL_LOOPING ALint (AL_TRUE,AL_FALSE) * MS Offset AL_MSEC_OFFSET ALint or ALfloat * Byte Offset AL_BYTE_OFFSET ALint or ALfloat * Sample Offset AL_SAMPLE_OFFSET ALint or ALfloat * Attached Buffer AL_BUFFER ALint * State (Query only) AL_SOURCE_STATE ALint * Buffers Queued (Query only) AL_BUFFERS_QUEUED ALint * Buffers Processed (Query only) AL_BUFFERS_PROCESSED ALint */ /* Create Source objects */ void qalGenSources( ALsizei n, ALuint* sources ) { ( *pqalGenSources )( n, sources ); } /* Delete Source objects */ void qalDeleteSources( ALsizei n, const ALuint* sources ) { ( *pqalDeleteSources )( n, sources ); } /* Verify a handle is a valid Source */ ALboolean qalIsSource( ALuint sid ) { return ( *pqalIsSource )( sid ); } /* * Set Source parameters */ void qalSourcef( ALuint sid, ALenum param, ALfloat value ) { ( *pqalSourcef )( sid, param, value ); } void qalSource3f( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ) { ( *pqalSource3f )( sid, param, value1, value2, value3 ); } void qalSourcefv( ALuint sid, ALenum param, const ALfloat* values ) { ( *pqalSourcefv )( sid, param, values ); } void qalSourcei( ALuint sid, ALenum param, ALint value ) { ( *pqalSourcei )( sid, param, value ); } void qalSource3i( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 ) { ( *pqalSource3i )( sid, param, value1, value2, value3 ); } void qalSourceiv( ALuint sid, ALenum param, const ALint* values ) { ( *pqalSourceiv )( sid, param, values ); } /* * Get Source parameters */ void qalGetSourcef( ALuint sid, ALenum param, ALfloat* value ) { ( *pqalGetSourcef )( sid, param, value ); } void qalGetSource3f( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3 ) { ( *pqalGetSource3f )( sid, param, value1, value2, value3 ); } void qalGetSourcefv( ALuint sid, ALenum param, ALfloat* values ) { ( *pqalGetSourcefv )( sid, param, values ); } void qalGetSourcei( ALuint sid, ALenum param, ALint* value ) { ( *pqalGetSourcei )( sid, param, value ); } void qalGetSource3i( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3 ) { ( *pqalGetSource3i )( sid, param, value1, value2, value3 ); } void qalGetSourceiv( ALuint sid, ALenum param, ALint* values ) { ( *pqalGetSourceiv )( sid, param, values ); } /* * Source vector based playback calls */ /* Play, replay, or resume (if paused) a list of Sources */ void qalSourcePlayv( ALsizei ns, const ALuint *sids ) { ( *pqalSourcePlayv )( ns, sids ); } /* Stop a list of Sources */ void qalSourceStopv( ALsizei ns, const ALuint *sids ) { ( *pqalSourceStopv )( ns, sids ); } /* Rewind a list of Sources */ void qalSourceRewindv( ALsizei ns, const ALuint *sids ) { ( *pqalSourceRewindv )( ns, sids ); } /* Pause a list of Sources */ void qalSourcePausev( ALsizei ns, const ALuint *sids ) { ( *pqalSourcePausev )( ns, sids ); } /* * Source based playback calls */ /* Play, replay, or resume a Source */ void qalSourcePlay( ALuint sid ) { ( *pqalSourcePlay )( sid ); } /* Stop a Source */ void qalSourceStop( ALuint sid ) { ( *pqalSourceStop )( sid ); } /* Rewind a Source (set playback postiton to beginning) */ void qalSourceRewind( ALuint sid ) { ( *pqalSourceRewind )( sid ); } /* Pause a Source */ void qalSourcePause( ALuint sid ) { ( *pqalSourcePause )( sid ); } /* * Source Queuing */ void qalSourceQueueBuffers( ALuint sid, ALsizei numEntries, const ALuint *bids ) { ( *pqalSourceQueueBuffers )( sid, numEntries, bids ); } void qalSourceUnqueueBuffers( ALuint sid, ALsizei numEntries, ALuint *bids ) { ( *pqalSourceUnqueueBuffers )( sid, numEntries, bids ); } /** * BUFFER * Buffer objects are storage space for sample data. * Buffers are referred to by Sources. One Buffer can be used * by multiple Sources. * * Properties include: - * * Frequency (Query only) AL_FREQUENCY ALint * Size (Query only) AL_SIZE ALint * Bits (Query only) AL_BITS ALint * Channels (Query only) AL_CHANNELS ALint */ /* Create Buffer objects */ void qalGenBuffers( ALsizei n, ALuint* buffers ) { ( *pqalGenBuffers )( n, buffers ); } /* Delete Buffer objects */ void qalDeleteBuffers( ALsizei n, const ALuint* buffers ) { ( *pqalDeleteBuffers )( n, buffers ); } /* Verify a handle is a valid Buffer */ ALboolean qalIsBuffer( ALuint bid ) { return ( *pqalIsBuffer )( bid ); } /* Specify the data to be copied into a buffer */ void qalBufferData( ALuint bid, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq ) { ( *pqalBufferData )( bid, format, data, size, freq ); } /* * Set Buffer parameters */ void qalBufferf( ALuint bid, ALenum param, ALfloat value ) { ( *pqalBufferf )( bid, param, value ); } void qalBuffer3f( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ) { ( *pqalBuffer3f )( bid, param, value1, value2, value3 ); } void qalBufferfv( ALuint bid, ALenum param, const ALfloat* values ) { ( *pqalBufferfv )( bid, param, values ); } void qalBufferi( ALuint bid, ALenum param, ALint value ) { ( *pqalBufferi )( bid, param, value ); } void qalBuffer3i( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 ) { ( *pqalBuffer3i )( bid, param, value1, value2, value3 ); } void qalBufferiv( ALuint bid, ALenum param, const ALint* values ) { ( *pqalBufferiv )( bid, param, values ); } /* * Get Buffer parameters */ void qalGetBufferf( ALuint bid, ALenum param, ALfloat* value ) { ( *pqalGetBufferf )( bid, param, value ); } void qalGetBuffer3f( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3 ) { ( *pqalGetBuffer3f )( bid, param, value1, value2, value3 ); } void qalGetBufferfv( ALuint bid, ALenum param, ALfloat* values ) { ( *pqalGetBufferfv )( bid, param, values ); } void qalGetBufferi( ALuint bid, ALenum param, ALint* value ) { ( *pqalGetBufferi )( bid, param, value ); } void qalGetBuffer3i( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3 ) { ( *pqalGetBuffer3i )( bid, param, value1, value2, value3 ); } void qalGetBufferiv( ALuint bid, ALenum param, ALint* values ) { ( *pqalGetBufferiv )( bid, param, values ); } /* * Global Parameters */ void qalDopplerFactor( ALfloat value ) { ( *pqalDopplerFactor )( value ); } void qalDopplerVelocity( ALfloat value ) { ( *pqalDopplerVelocity )( value ); } void qalSpeedOfSound( ALfloat value ) { ( *pqalSpeedOfSound )( value ); } void qalDistanceModel( ALenum distanceModel ) { ( *pqalDistanceModel )( distanceModel ); } /* * Context Management */ ALCcontext* qalcCreateContext( ALCdevice *device, const ALCint* attrlist ) { return ( *pqalcCreateContext )( device, attrlist ); } ALCboolean qalcMakeContextCurrent( ALCcontext *context ) { return ( *pqalcMakeContextCurrent )( context ); } void qalcProcessContext( ALCcontext *context ) { ( *pqalcProcessContext )( context ); } void qalcSuspendContext( ALCcontext *context ) { ( *pqalcSuspendContext )( context ); } void qalcDestroyContext( ALCcontext *context ) { ( *pqalcDestroyContext )( context ); } ALCcontext* qalcGetCurrentContext( void ) { return ( *pqalcGetCurrentContext )(); } ALCdevice* qalcGetContextsDevice( ALCcontext *context ) { return ( *pqalcGetContextsDevice )( context ); } /* * Device Management */ ALCdevice* qalcOpenDevice( const ALCchar *devicename ) { return ( *pqalcOpenDevice )( devicename ); } ALCboolean qalcCloseDevice( ALCdevice *device ) { return ( *pqalcCloseDevice )( device ); } /* * Error support. * Obtain the most recent Context error */ ALCenum qalcGetError( ALCdevice *device ) { return ( *pqalcGetError )( device ); } /* * Extension support. * Query for the presence of an extension, and obtain any appropriate * function pointers and enum values. */ ALCboolean qalcIsExtensionPresent( ALCdevice *device, const ALCchar *extname ) { return ( *pqalcIsExtensionPresent )( device, extname ); } void* qalcGetProcAddress( ALCdevice *device, const ALCchar *funcname ) { return ( *pqalcGetProcAddress )( device, funcname ); } ALCenum qalcGetEnumValue( ALCdevice *device, const ALCchar *enumname ) { return ( *pqalcGetEnumValue )( device, enumname ); } /* * Query functions */ const ALCchar* qalcGetString( ALCdevice *device, ALCenum param ) { return ( *pqalcGetString )( device, param ); } void qalcGetIntegerv( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *data ) { ( *pqalcGetIntegerv )( device, param, size, data ); } /* * Capture functions */ ALCdevice* qalcCaptureOpenDevice( const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize ) { return ( *pqalcCaptureOpenDevice )( devicename, frequency, format, buffersize ); } ALCboolean qalcCaptureCloseDevice( ALCdevice *device ) { return ( *pqalcCaptureCloseDevice )( device ); } void qalcCaptureStart( ALCdevice *device ) { ( *pqalcCaptureStart )( device ); } void qalcCaptureStop( ALCdevice *device ) { ( *pqalcCaptureStop )( device ); } void qalcCaptureSamples( ALCdevice *device, ALCvoid *buffer, ALCsizei samples ) { ( *pqalcCaptureSamples )( device, buffer, samples ); } alien-arena-7.66+dfsg/source/client/cl_pred.c0000600000175000017500000002233212161402010020136 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "client.h" /* =================== CL_CheckPredictionError =================== */ void CL_CheckPredictionError (void) { int frame; int delta[3]; int i; int len; if (!cl_predict->value || (cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION)) return; // calculate the last usercmd_t we sent that the server has processed frame = cls.netchan.incoming_acknowledged; frame &= (CMD_BACKUP-1); // compare what the server returned with what we had predicted it to be VectorSubtract (cl.frame.playerstate.pmove.origin, cl.predicted_origins[frame], delta); // save the prediction error for interpolation len = abs(delta[0]) + abs(delta[1]) + abs(delta[2]); if (len > 640) // 80 world units { // a teleport or something VectorClear (cl.prediction_error); } else { if (cl_showmiss->value && (delta[0] || delta[1] || delta[2]) ) { // use sum of absolute differences from above, scaled to quake units Com_Printf("prediction miss: frame %i: %0.3f\n", cl.frame.serverframe, ((float)len)/8.0f ); } VectorCopy (cl.frame.playerstate.pmove.origin, cl.predicted_origins[frame]); // save for error itnerpolation for (i=0 ; i<3 ; i++) cl.prediction_error[i] = delta[i]*0.125; } } /* ==================== CL_ClipMoveToEntities ==================== */ void CL_ClipMoveToEntities ( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, trace_t *tr ) { int i, x, zd, zu; trace_t trace; int headnode; float *angles; entity_state_t *ent; int num; cmodel_t *cmodel; vec3_t bmins, bmaxs; for (i=0 ; isolid) continue; if (ent->number == cl.playernum+1) continue; if (ent->solid == 31) { // special value for bmodel cmodel = cl.model_clip[ent->modelindex]; if (!cmodel) continue; headnode = cmodel->headnode; angles = ent->angles; } else { // encoded bbox x = 8*(ent->solid & 31); zd = 8*((ent->solid>>5) & 31); zu = 8*((ent->solid>>10) & 63) - 32; bmins[0] = bmins[1] = -x; bmaxs[0] = bmaxs[1] = x; bmins[2] = -zd; bmaxs[2] = zu; headnode = CM_HeadnodeForBox (bmins, bmaxs); angles = vec3_origin; // boxes don't rotate } if (tr->allsolid) return; trace = CM_TransformedBoxTrace (start, end, mins, maxs, headnode, MASK_PLAYERSOLID, ent->origin, angles); if (trace.allsolid || trace.startsolid || trace.fraction < tr->fraction) { trace.ent = (struct edict_s *)ent; if (tr->startsolid) { *tr = trace; tr->startsolid = true; } else *tr = trace; } else if (trace.startsolid) tr->startsolid = true; } } /* ================ CL_PMTrace ================ */ trace_t CL_PMTrace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end) { trace_t t; // check against world t = CM_BoxTrace (start, end, mins, maxs, 0, MASK_PLAYERSOLID); if (t.fraction < 1.0) t.ent = (struct edict_s *)1; // check all other solid models CL_ClipMoveToEntities (start, mins, maxs, end, &t); return t; } int CL_PMpointcontents (vec3_t point) { int i; entity_state_t *ent; int num; cmodel_t *cmodel; int contents; contents = CM_PointContents (point, 0); for (i=0 ; isolid != 31) // special value for bmodel continue; cmodel = cl.model_clip[ent->modelindex]; if (!cmodel) continue; contents |= CM_TransformedPointContents (point, cmodel->headnode, ent->origin, ent->angles); } return contents; } //Knightmare added- this can check using masks, good for checking surface flags // also checks for bmodels /* ================ CL_PMSurfaceTrace ================ */ trace_t CL_PMSurfaceTrace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int contentmask) { trace_t t; if (!mins) mins = vec3_origin; if (!maxs) maxs = vec3_origin; // check against world t = CM_BoxTrace (start, end, mins, maxs, 0, contentmask); if (t.fraction < 1.0) t.ent = (struct edict_s *)1; // check all other solid models CL_ClipMoveToEntities (start, mins, maxs, end, &t); return t; } /* ================= CL_PredictMovement Sets cl.predicted_origin and cl.predicted_angles ================= */ void CL_PredictMovement (void) { int ack, current; int frame; int oldframe; usercmd_t *cmd; pmove_t pm; int i; int step; int oldz; if (cls.state != ca_active) return; if (cl_paused->value) return; if (!cl_predict->value || (cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION)) { // just set angles for (i=0 ; i<3 ; i++) { cl.last_predicted_angles[i] = cl.predicted_angles[i] = cl.viewangles[i] + SHORT2ANGLE(cl.frame.playerstate.pmove.delta_angles[i]); } return; } ack = cls.netchan.incoming_acknowledged; current = cls.netchan.outgoing_sequence; // if we are too far out of date, just freeze if (current - ack >= CMD_BACKUP) { if (cl_showmiss->value) Com_Printf ("exceeded CMD_BACKUP\n"); return; } // copy current state to pmove memset (&pm, 0, sizeof(pm)); pm.trace = CL_PMTrace; pm.pointcontents = CL_PMpointcontents; pm_airaccelerate = atof(cl.configstrings[CS_AIRACCEL]); pm.s = cl.frame.playerstate.pmove; // SCR_DebugGraph (current - ack - 1, 0); frame = 0; // run frames while (++ack < current) { frame = ack & (CMD_BACKUP-1); cmd = &cl.cmds[frame]; pm.cmd = *cmd; Pmove (&pm); // save for debug checking VectorCopy (pm.s.origin, cl.predicted_origins[frame]); } oldframe = (ack-2) & (CMD_BACKUP-1); oldz = cl.predicted_origins[oldframe][2]; step = pm.s.origin[2] - oldz; if (step > 63 && step < 160 && (pm.s.pm_flags & PMF_ON_GROUND) ) { cl.predicted_step = step * 0.125; cl.predicted_step_time = cls.realtime - cls.frametime * 500; } // copy results out for rendering cl.predicted_origin[0] = pm.s.origin[0]*0.125; cl.predicted_origin[1] = pm.s.origin[1]*0.125; cl.predicted_origin[2] = pm.s.origin[2]*0.125; cl.predicted_velocity[0] = pm.s.velocity[0]*0.125; cl.predicted_velocity[1] = pm.s.velocity[1]*0.125; cl.predicted_velocity[2] = pm.s.velocity[2]*0.125; VectorCopy (pm.viewangles, cl.predicted_angles); VectorCopy (pm.viewangles, cl.last_predicted_angles); } /* ================= CL_Trace ================= */ trace_t CL_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int skipNumber, int brushMask, qboolean brushOnly, int *entNumber){ trace_t trace, tmp; entity_state_t *ent; cmodel_t *cmodel; vec3_t bmins, bmaxs; int i, xy, zd, zu, headNode, num; // Check against world trace = CM_BoxTrace(start, end, mins, maxs, 0, brushMask); if (trace.fraction < 1.0){ if (entNumber) *entNumber = 0; trace.ent = (struct edict_s *)1; } if (trace.allsolid || trace.fraction == 0.0) return trace; // Check all other solid models for (i=0 ; inumber == skipNumber) continue; if (ent->solid == 31){ // Special value for brush model cmodel = cl.model_clip[ent->modelindex]; if (!cmodel) continue; tmp = CM_TransformedBoxTrace(start, end, mins, maxs, cmodel->headnode, brushMask, ent->origin, ent->angles); } else { if (brushOnly) continue; // Encoded bounding box xy = 8 * (ent->solid & 31); zd = 8 * ((ent->solid >> 5) & 31); zu = 8 * ((ent->solid >> 10) & 63) - 32; bmins[0] = bmins[1] = -xy; bmaxs[0] = bmaxs[1] = xy; bmins[2] = -zd; bmaxs[2] = zu; headNode = CM_HeadnodeForBox (bmins, bmaxs); tmp = CM_TransformedBoxTrace(start, end, mins, maxs, headNode, brushMask, ent->origin, vec3_origin); } if (tmp.allsolid || tmp.startsolid || tmp.fraction < trace.fraction){ if (entNumber) *entNumber = ent->number; tmp.ent = (struct edict_s *)ent; if (trace.startsolid){ trace = tmp; trace.startsolid = true; } else trace = tmp; } else if (tmp.startsolid) trace.startsolid = true; if (trace.allsolid) break; } return trace; } alien-arena-7.66+dfsg/source/client/sound.h0000600000175000017500000000405612161402010017666 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ struct sfx_s; void S_Init (void); void S_Shutdown (void); // if origin is NULL, the sound will be dynamically sourced from the entity void S_StartSound (vec3_t origin, int entnum, int entchannel, struct sfx_s *sfx, float fvol, float attenuation, float timeofs); void S_StartLocalSound (const char *s); void S_StartMusic (char *s); void S_StartMenuMusic( void ); void S_StartMapMusic( void ); void S_RawSamples (int samples, int rate, int width, int channels, byte *data); void S_StopAllSounds( void ); void S_Update (vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up); void S_Activate (qboolean active); void S_BeginRegistration (void); struct sfx_s *S_RegisterSound (char *sample); void S_EndRegistration (void); struct sfx_s *S_FindName (const char *name, qboolean create); void S_UpdateDopplerFactor( void ); extern qboolean S_LoadSound( char *filename, // in qboolean ogg_substitute, // in void** readbfr, // out void** pcmdata, // out int *bytewidth, // out int *channels, // out int *samplerate, // out size_t *byte_count // out ); // the sound code makes callbacks to the client for entitiy position // information, so entities can be dynamically re-spatialized void CL_GetEntitySoundOrigin (int ent, vec3_t org); alien-arena-7.66+dfsg/source/client/ref.h0000600000175000017500000002346212204310130017313 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __REF_H #define __REF_H #include "qcommon/qcommon.h" #define DIV254BY255 (0.9960784313725490196078431372549f) #define DIV255 (0.003921568627450980392156862745098f) #define DIV256 (0.00390625f) #define DIV512 (0.001953125f) #define MAX_DLIGHTS 32 #define MAX_ENTITIES 256 //was 128 - use of static meshes necessitates an increase. #define MAX_PARTICLES 8192 #define MAX_LIGHTSTYLES 256 #define MAX_FLARES 512 #define MAX_GRASSES 2048 #define MAX_BEAMS 128 typedef struct { vec3_t origin; vec3_t color; int size; int style; float alpha; float time; int leafnum; } flare_t; typedef struct { int type; vec3_t origin; vec3_t color; float size; int texsize; int texnum; char name[MAX_QPATH]; int leafnum; qboolean sunVisible; //can cast shadows in sunlight vec3_t static_light; } grass_t; typedef struct { int type; vec3_t origin; vec3_t color; float size; float xang; float yang; qboolean rotating; int texsize; int texnum; char name[MAX_QPATH]; int leafnum; int leafnum2; } beam_t; #define SHELL_RED_COLOR 0xF2 #define SHELL_GREEN_COLOR 0xD0 #define SHELL_BLUE_COLOR 0xF3 #define SHELL_RG_COLOR 0xDC //#define SHELL_RB_COLOR 0x86 #define SHELL_RB_COLOR 0x68 #define SHELL_BG_COLOR 0x78 //ROGUE #define SHELL_DOUBLE_COLOR 0xDF // 223 #define SHELL_HALF_DAM_COLOR 0x90 #define SHELL_CYAN_COLOR 0x72 //ROGUE #define SHELL_WHITE_COLOR 0xD7 #define PARTICLE_NONE 0 #define PARTICLE_STANDARD 1 #define PARTICLE_BEAM 2 #define PARTICLE_DECAL 3 #define PARTICLE_FLAT 4 #define PARTICLE_WEATHER 5 #define PARTICLE_FLUTTERWEATHER 6 #define PARTICLE_RAISEDDECAL 7 #define PARTICLE_ROTATINGYAW 8 #define PARTICLE_ROTATINGROLL 9 #define PARTICLE_ROTATINGYAWMINUS 10 #define PARTICLE_VERT 11 #define PARTICLE_CHAINED 12 #define RDF_BLOOM 4 //BLOOMS #define MAX_VERTEX_CACHES 4096 #define MAX_VBO_XYZs 65536 typedef enum { VBO_STATIC, VBO_DYNAMIC } vertCacheMode_t; typedef enum { VBO_STORE_ANY, VBO_STORE_XYZ, VBO_STORE_INDICES, VBO_STORE_ST, VBO_STORE_NORMAL, VBO_STORE_BINORMAL, VBO_STORE_TANGENT } vertStoreMode_t; typedef struct vertCache_s { struct vertCache_s *prev; struct vertCache_s *next; vertCacheMode_t mode; int size; void *pointer; vertStoreMode_t store; struct model_s *mod; unsigned id; } vertCache_t; typedef struct { vertCache_t *freeVertCache; vertCache_t activeVertCache; vertCache_t vertCacheList[MAX_VERTEX_CACHES]; } vertCacheManager_t; vertCacheManager_t vcm; typedef struct entity_s { char name[MAX_QPATH]; struct model_s *model; // opaque type outside refresh struct model_s *lod1; struct model_s *lod2; float angles[3]; /* ** most recent data */ float origin[3]; int frame; /* ** previous data for lerping */ float oldorigin[3]; int oldframe; /* ** frame and timestamp (iqm lerping) */ float frametime; int prevframe; /* ** misc */ float backlerp; // 0.0 = current, 1.0 = old int skinnum; int lightstyle; // for flashing entities float alpha; // ignore if RF_TRANSLUCENT isn't set struct image_s *skin; // NULL for inline skin int flags; int team; float bob; int number; //edict number; struct rscript_s *script; } entity_t; //for saving persistent data about entities across frames typedef struct { /* ** for saving non-dynamic lighting of static meshes */ qboolean setlightstuff; float oldnumlights; vec3_t oldlightadd; vec3_t oldorigin; float oldlightintens; } cl_entity_pers_t; cl_entity_pers_t cl_persistent_ents[MAX_EDICTS]; #define ENTITY_FLAGS 68 typedef struct { vec3_t origin; vec3_t color; float intensity; } dlight_t; typedef struct { float strength; vec3_t direction; vec3_t color; } m_dlight_t; // ======== // PGM typedef struct { qboolean isactive; vec3_t lightcol; float light; float lightvel; } cplight_t; #define P_LIGHTS_MAX 8 typedef struct particle_s { struct particle_s *next; cplight_t lights[P_LIGHTS_MAX]; float time; vec3_t org; vec3_t angle; vec3_t vel; vec3_t accel; vec3_t end; float color; float colorvel; float alpha; float alphavel; int type; // 0 standard, 1 smoke, etc etc... struct image_s *image; int blenddst; int blendsrc; float scale; float scalevel; qboolean fromsustainedeffect; float dist; // These are computed from the foo and foovel values-- for example, // current_color is computed from color and colorvel and its value // changes every frame. vec3_t current_origin; int current_color; float current_alpha; float current_scale; // For particle chains-- the particle renderer will automatically play // connect-the-dots with these. struct particle_s *chain_prev; vec3_t current_pspan; } particle_t; typedef struct { float rgb[3]; // 0.0 - 2.0 float white; // highest of rgb } lightstyle_t; typedef struct { int x, y, width, height;// in virtual screen coordinates float fov_x, fov_y; float vieworg[3]; float viewangles[3]; float blend[4]; // rgba 0-1 full screen blend float time; // time is uesed to auto animate int rdflags; // RDF_UNDERWATER, etc byte *areabits; // must not be NULL if you want to do BSP rendering qboolean areabits_changed; lightstyle_t *lightstyles; // [MAX_LIGHTSTYLES] int num_entities; entity_t *entities; int num_viewentities; entity_t *viewentities; int num_dlights; dlight_t *dlights; qboolean dlights_changed; int num_dlight_surfaces; int num_particles; particle_t **particles; int num_grasses; grass_t *grasses; int num_beams; beam_t *beams; // Because the mirror texture doesn't have to updatea more than 60 times // per second. int last_mirrorupdate_time; // in ms } refdef_t; // // view origin moved from r_local.h. -M. // extern vec3_t vup; extern vec3_t vpn; extern vec3_t vright; extern vec3_t r_origin; // Knightmare- added Psychospaz's menu cursor //cursor - psychospaz #define MENU_CURSOR_BUTTON_MAX 2 typedef struct { //only 2 buttons for menus float buttontime[MENU_CURSOR_BUTTON_MAX]; int buttonclicks[MENU_CURSOR_BUTTON_MAX]; qboolean buttonused[MENU_CURSOR_BUTTON_MAX]; qboolean buttondown[MENU_CURSOR_BUTTON_MAX]; qboolean mouseaction; //this is the active item that cursor is on. int menulayer; struct _tag_menuitem *menuitem; //this is whatever menuitem it was on when a click-and-drag maneuver was //begun. struct _tag_menuitem *click_menuitem; qboolean suppress_drag; //started clicking with nothing selected //coords int x; int y; int oldx; int oldy; } cursor_t; float *RGBA (float r, float g, float b, float a); #define RGBA8(a,b,c,d) RGBA((a)/255.0f, (b)/255.0f, (c)/255.0f, (d)/255.0f) qboolean Draw_PicExists (const char *name); void Draw_GetPicSize (int *w, int *h, const char *name); void Draw_Pic (float x, float y, const char *name); void Draw_ScaledPic (float x, float y, float scale, const char *pic); void Draw_StretchPic (float x, float y, float w, float h, const char *name); void Draw_AlphaStretchTilingPic (float x, float y, float w, float h, const char *name, float alphaval); void Draw_AlphaStretchPic (float x, float y, float w, float h, const char *name, float alphaval); void Draw_AlphaStretchPlayerIcon (int x, int y, int w, int h, const char *pic, float alphaval); void Draw_Fill (float x, float y, float w, float h, const float rgba[]); void Draw_FadeScreen (void); void R_BeginFrame( float camera_separation ); void R_SwapBuffers( int ); void R_SetPalette ( const unsigned char *palette); struct model_s *R_RegisterModel (char *name); struct image_s *R_RegisterSkin (char *name); struct image_s *R_RegisterPic (const char *name); void R_SetSky (char *name, float rotate, vec3_t axis); void R_RegisterBasePlayerModels(void); void R_RegisterCustomPlayerModels(void); void S_RegisterSoundsForPlayer (char *playername); void R_BeginRegistration (char *map); void R_EndRegistration (void); void R_RenderFrame (refdef_t *fd); void R_RenderFramePlayerSetup (refdef_t *fd); void R_EndFrame (void); int R_Init( void *hinstance, void *hWnd ); void R_Shutdown (void); void R_AppActivate( qboolean active ); // TrueType struct ttf_font_s; typedef struct ttf_font_s * ttf_font_t; ttf_font_t TTF_GetFont( const char * name , unsigned int size ); void TTF_GetSize( ttf_font_t font , const char * text , unsigned int * width , unsigned int * height ); void TTF_RawPrint( ttf_font_t font , const char * text , float x , float y , const float color[4] ); #define MAX_RADAR_ENTS 512 typedef struct RadarEnt_s{ float color[4]; vec3_t org; }RadarEnt_t; extern int numRadarEnts; extern RadarEnt_t RadarEnts[MAX_RADAR_ENTS]; extern cursor_t cursor; qboolean is_localhost; //because ref_gl can't access cls.servername. #endif // __REF_H alien-arena-7.66+dfsg/source/client/vid.h0000600000175000017500000000241712161402010017317 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // vid.h -- video driver defs typedef struct vrect_s { int x,y,width,height; } vrect_t; typedef struct { int width, height; // coordinates from main game } viddef_t; extern viddef_t viddef; // global video state // Video module initialisation etc void VID_Init (void); void VID_Shutdown (void); void VID_CheckChanges (void); qboolean VID_GetModeInfo( int *width, int *height, int mode ); void R_Register (void); //defined in ref_gl void VID_MenuInit( void ); void VID_NewWindow( int width, int height ); alien-arena-7.66+dfsg/source/client/snd_openal.c0000600000175000017500000022544612161402010020663 0ustar zero79zero79/* Copyright (C) 2009 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * snd_openal.c * * Reference: * OpenAL 1.1 Specification and Reference (June 2005) * OpenAL Programmer's Guide : OpenAL Version 1.1 (June 2007) * OpenAL Deployment Guide (PC Windows) Version 0.16 (June 2007) * http://www.openal.org (at creativelabs.com) * http://kcat.strangesoft.net/openal.html (OpenAL Soft) * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #if defined HAVE_MALLOC_H #include #elif defined HAVE_MALLOC_MALLOC_H #include #endif #include #if defined HAVE_AL_H #include #include #elif defined HAVE_AL_AL_H #include #include #elif defined HAVE_OPENAL_AL_H #include #include #endif #include "client.h" #include "qal.h" /* * Sound CVARS */ #define MAX_SRC 128 #define MAX_SRC_DEFAULT 96 #define MIN_SRC_DEFAULT 64 /*--- previous system ---*/ // These 2 are defined in cl_main.c //cvar_t *background_music; // enable/disable music //cvar_t *background_music_vol; // music volume setting cvar_t *s_initsound; // in cfg or on command line, to disable sound cvar_t *s_volume; // global volume setting /*--- OpenAL additions ---*/ cvar_t *s_doppler; // 0=doppler off, non-zero Doppler Factor cvar_t *s_maxsources; // upper limit on generated Sources cvar_t *s_minsources; // lower limit on generated Sources cvar_t *s_device; // name of device to use /*--- debug ---*/ cvar_t *snd_developer; // for debug printf's /* * Sound System State Control */ qboolean sound_system_enable; qboolean s_registering; // loading pre-cache sound effects in "batch" mode int s_registration_sequence; // id for current "batch" /* * Sound FX & OpenAL Buffer */ typedef struct sfx_s { void *backlink; // link to the sfx_link node qboolean silent; // for when sound effect file is missing qboolean bg_music; // this is background music int registration_sequence; // used for culling stale sfx's from pre-cache int byte_width; // 1=8-bit, 2=16-bit int channels; // 1=mono, 2=stereo, int samplerate; // samples-per-sec, aka Hz size_t byte_count; // size of the sound data void *filebfr; // intermediate buffer for file reading void *pcmbfr; // where PCM data is in filebfr qboolean buffered; // data has been read into OpenAL buffer int oalFormat; // file format code from OpenAL ALuint oalBuffer; // index into collection of OpenAL buffers qboolean aliased; // the file loaded is an alias for the truename char name[MAX_QPATH]; // relative file path char truename[MAX_QPATH]; // in case 'name' is an 'alias' } sfx_t; typedef struct sfxlink_s // node for the sfx_t lists { struct sfxlink_s *prev; struct sfxlink_s *next; sfx_t *sfx; } sfxlink_t; #define MAX_SFX 256 sfxlink_t *sfx_datahead; sfxlink_t *sfx_freehead; sfxlink_t sfx_link[MAX_SFX]; sfx_t sfx_data[MAX_SFX]; int actual_sfx_count; /* * OpenAL Sources and related data */ typedef enum loop_mark_e { lpmk_nonloop, lpmk_start, lpmk_continue, lpmk_stop } loop_mark_t; typedef enum velocity_state_e { velst_nodoppler, velst_update, velst_init } velocity_state_t; typedef struct src_s { void *backlink; // link to the src_link node int start_timer; // for delayed start int stop_timer; // for delayed forced stop int entnum; // the entity identifier, index into cl_entities[] int entchannel; // the "channel", AUTO, WEAP, etc. qboolean fixed_origin; // non-moving point implied by non-NULL origin arg int attn_class; // attenuation classification ATTN_NORM, etc. qboolean looping; // for AL_LOOPING Sources loop_mark_t loop_mark; // for finding "automatic" looping sounds int entity_index; // for CL_GetEntitySoundOrigin() int sound_field; // entity_state_t .sound velocity_state_t velocity_state; //velocity tracking for doppler sfx_t *sfx; // the associated sound effect ALuint oalSource; // the OpenAL Source name/id } src_t; typedef struct srclink_s // node for the src_t lists { struct srclink_s *prev; struct srclink_s *next; src_t *src; } srclink_t; srclink_t *src_datahead; srclink_t *src_freehead; srclink_t src_link[MAX_SRC]; src_t src_data[MAX_SRC]; int actual_src_count; // number of sources generated int source_counter; // current number of sources in use int max_sources_used; // for tracking max number of sources used int source_failed_counter; // for counting source alloc failures int max_sources_failed; // single dedicated background sound, stereo enabled // "Your only Source for Alien Arena Music" // on/off switch is cvar: background_music // volume control is cvar: background_music_volume extern cvar_t *background_music_vol; // missing in header file struct music_s { qboolean playing; sfx_t *sfx; ALuint oalSource; } music; /* * Defaults for OpenAL Sources, Listener */ const ALfloat zero_position[3] = { 0.0f, 0.0f, 0.0f }; const ALfloat zero_velocity[3] = { 0.0f, 0.0f, 0.0f }; const ALfloat default_orientation[6] = { 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f }; const ALfloat zero_direction[3] = { 0.0f, 0.0f, 0.0f }; /* * Settings for OpenAL context * * The Exponent Distance Clamped Model: * distance = max(distance, AL_REFERENCE_DISTANCE) * distance = min(distance, AL_MAX_DISTANCE) * gain = (distance / AL_REFERENCE_DISTANCE) ^ (- AL_ROLLOFF_FACTOR) * * Doppler: * speed_of_sound : lower for more doppler effect * doppler_factor : higher for more doppler effect * * Velocities are in QuakeMapUnits-per-millisecond * Just FYI: * if 8 QuakeMapUnits == 1 foot, 9/8 feet == 1.125 ft * 1.125 feet-per-millisec == 1125 feet-per-second * Speed of Sound is 1125 feet-per-second, 343 meters-per-second * * Doppler defaults to OFF, because lower performance systems * might have problems */ const ALenum distance_model = AL_EXPONENT_DISTANCE_CLAMPED; const ALfloat default_doppler_factor = (ALfloat)0.0f; const ALfloat maximum_doppler_factor = (ALfloat)5.0f; const ALfloat speed_of_sound = (ALfloat)9.0f; const ALfloat velocity_max_valid = (ALfloat)( 3.0f * 3.0f ); ALfloat doppler_factor; const struct source_default_s { // Source properties ALfloat pitch; ALfloat gain; ALfloat looping_gain; ALfloat max_distance; ALfloat rolloff_factor; ALfloat reference_distance; ALfloat idle_max_distance; ALfloat idle_rolloff_factor; ALfloat idle_reference_distance; ALfloat static_max_distance; ALfloat static_rolloff_factor; ALfloat static_reference_distance; ALfloat looping_max_distance; ALfloat looping_rolloff_factor; ALfloat looping_reference_distance; ALfloat min_gain; ALfloat max_gain; ALfloat cone_outer_gain; ALfloat cone_inner_angle; ALfloat cone_outer_angle; // int stop_timer_delay; } source_default = { (ALfloat)1.0f, // AL_PITCH (ALfloat)1.0f, // AL_GAIN (ALfloat)0.7f, // AL_GAIN for auto loop sounds // ATTN_NORM: (ALfloat)3200.0f, // AL_MAX_DISTANCE (ATTN_NORM) (ALfloat)1.5f, // AL_ROLLOFF_FACTOR (ATTN_NORM) (ALfloat)320.0f, // AL_REFERENCE_DISTANCE (ATTN_NORM) // ATTN_IDLE: (ALfloat)2800.0f, // AL_MAX_DISTANCE (ATTN_IDLE) (ALfloat)2.0f, // AL_ROLLOFF_FACTOR (ATTN_IDLE) (ALfloat)280.0f, // AL_REFERENCE_DISTANCE (ATTN_IDLE) // ATTN_STATIC: (ALfloat)1600.0f, // AL_MAX_DISTANCE (ATTN_STATIC) (ALfloat)2.2f, // AL_ROLLOFF_FACTOR (ATTN_STATIC) (ALfloat)160.0f, // AL_REFERENCE_DISTANCE (ATTN_STATIC) // "Auto Looping" (ALfloat)1600.0f, // AL_MAX_DISTANCE (Looping) (ALfloat)1.8f, // AL_ROLLOFF_FACTOR (Looping) (ALfloat)160.0f, // AL_REFERENCE_DISTANCE (Looping) // (ALfloat)0.0f, // AL_MIN_GAIN (ALfloat)1.0f, // AL_MAX_GAIN (ALfloat)0.0f, // AL_CONE_OUTER_GAIN (ALfloat)360.0f, // AL_CONE_INNER_ANGLE (ALfloat)360.0f // AL_CONE_OUTER_ANGLE }; /* * Settings for Distance Culling * * - OpenAL does not cull by distance, just scales gain. Its up to * the application to cull. * - Today's theory is that the cull distance should take into account * longest line-of-sight paths in maps, so visible events are heard. * And, then, depend mostly on the distance attenuation model to * keep things reasonable. */ const ALfloat norm_sq_cull_distance = (ALfloat)( 3296.0f * 3296.0f ); const ALfloat idle_sq_cull_distance = (ALfloat)( 2864.0f * 2864.0f ); const ALfloat static_sq_cull_distance = (ALfloat)( 1664.0f * 1664.0f ); const ALfloat looping_sq_cull_distance = (ALfloat)( 1664.0f * 1664.0f ); const ALfloat looping_cull_hysteresis = (ALfloat)( 64.0f * 64.0f ); /* * OpenAL Device */ #define MAX_OAL_DEVICES 16 const ALCchar* oalDeviceList; // pointer to OpenAL's nul-separated device list int oalDeviceCount; // number of valid devices ALCchar* pDeviceNames[MAX_OAL_DEVICES]; // pointers to valid devices in list /* * Other settings */ const int stop_timer_msecs = 750; // for src_t stop_timer field /* alBufferData( bfrid, AL_MONO16, pcmNil, sizeof(pcmNil), 44100 ); * should allow OpenAL to free pcm data */ unsigned short pcmNil[] = { 0 }; /* == Snd_DPrintf() debug printf when "snd_developer" cvar is set does not print messages where level > snd_developer cvar value use 1 for "normal" developer error/status messages, >1 for higher rate event monitoring, for example. Note: the usual Com_DPrintf() sometimes floods the console output == */ void Snd_DPrintf( int level, char *fmt, ... ) { va_list argptr; char msg[256]; if( !snd_developer || !snd_developer->value || level > snd_developer->value ) return; va_start( argptr, fmt ); vsnprintf(msg, sizeof(msg), fmt, argptr ); va_end (argptr); Com_Printf ("%s", msg); } /* == calErrorCheckAL() == */ ALenum calErrorCheckAL( int line_no ) { ALenum error_code; error_code = qalGetError(); switch( error_code ) { case AL_NO_ERROR: break; case AL_INVALID_NAME: Snd_DPrintf( 1,"OpenAL Error: AL_INVALID_NAME (%i)\n", line_no ); break; case AL_INVALID_ENUM: Snd_DPrintf( 1, "OpenAL Error: AL_INVALID_ENUM (%i)\n", line_no ); break; case AL_INVALID_VALUE: Snd_DPrintf( 1, "OpenAL Error: AL_INVALID_VALUE (%i)\n", line_no ); break; case AL_INVALID_OPERATION: Snd_DPrintf( 1, "OpenAL Error: AL_INVALID_OPERATION (%i)\n", line_no ); break; case AL_OUT_OF_MEMORY: Snd_DPrintf( 1, "OpenAL Error: AL_OUT_OF_MEMORY (%i)\n", line_no ); break; default: Snd_DPrintf( 1, "OpenAL Error: AL Code = %i (%#X) (%i)\n", error_code, error_code, line_no ); break; } return error_code; } /* == calErrorCheckALC() == */ ALCenum calErrorCheckALC( ALCdevice *device, int line_no ) { ALCenum error_code; error_code = qalcGetError( device ); switch( error_code ) { case ALC_NO_ERROR: break; case ALC_INVALID_DEVICE: Snd_DPrintf( 1, "OpenALC Error: ALC_INVALID_DEVICE (%i)\n", line_no ); break; case ALC_INVALID_CONTEXT: Snd_DPrintf( 1, "OpenALC Error: ALC_INVALID_CONTEXT (%i)\n", line_no ); break; case ALC_INVALID_ENUM: Snd_DPrintf( 1, "OpenALC Error: ALC_INVALID_ENUM (%i)\n", line_no ); break; case ALC_INVALID_VALUE: Snd_DPrintf( 1, "OpenALC Error: ALC_INVALID_VALUE (%i)\n", line_no ); break; case ALC_OUT_OF_MEMORY: Snd_DPrintf( 1, "OpenALC Error: ALC_OUT_OF_MEMORY (%i)\n", line_no ); break; default: Snd_DPrintf( 1, "OpenALC Error: ALC Code = %i (%#X) (%i)\n", error_code, error_code, line_no ); break; } return error_code; } /* == calSourcesInitialize() calSourceAlloc() calSourceFree() generate and list manage the collection of OpenAL Sources and related info == */ void calSourcesInitialize( ALint device_sources ) { int ix; int last; ALuint gensrc[MAX_SRC]; ALint sources_n; char cvarset[16]; // init Source lists to empty src_datahead = NULL; src_freehead = NULL; source_counter = 0; // gather statistics about Source use max_sources_used = 0; source_failed_counter = 0; max_sources_failed = 0; // generate a collection of OpenAL Sources // may be limited by what the current Device supports // otherwise use the s_maxsources cvar if( s_maxsources->integer > MAX_SRC || s_maxsources->integer <= 0 ) { // set to default Com_sprintf(cvarset, sizeof(cvarset),"%i", MAX_SRC ); Cvar_ForceSet( "s_maxsources", cvarset ); } sources_n = s_maxsources->integer; // cvar sets limit on sources if( device_sources > 0 && sources_n > device_sources ) { // less one seems to work better sources_n = device_sources; if( sources_n > 1 ) --sources_n; } qalGetError(); qalGenSources( sources_n, gensrc ); // generate the collection of Sources if( calErrorCheckAL( __LINE__ ) != AL_NO_ERROR ) { Com_Printf("Failed to generate %i OpenAL Sources. " " Sound effects disabled\n", sources_n ); return; } // init free Sources list src_freehead = src_link; last = 0; for( ix = 0; ix < sources_n; ix++ ) { src_link[ix].next = &src_link[ix + 1]; src_link[ix].prev = &src_link[ix - 1]; src_link[ix].src = &src_data[ix]; src_data[ix].backlink = (void*) &src_link[ix]; src_data[ix].start_timer = 0; src_data[ix].stop_timer = 0; src_data[ix].entnum = 0; src_data[ix].entchannel = CHAN_AUTO; src_data[ix].fixed_origin = false; src_data[ix].attn_class = ATTN_NONE; src_data[ix].looping = 0; src_data[ix].loop_mark = lpmk_nonloop; src_data[ix].entity_index = 0; src_data[ix].sound_field = 0; src_data[ix].velocity_state = velst_nodoppler; src_data[ix].sfx = NULL; src_data[ix].oalSource = gensrc[ix]; last = ix; // Set Source properties to distance settings and defaults qalSourcef( src_data[ix].oalSource, AL_GAIN, (ALfloat)0.0f ); qalSourcei( src_data[ix].oalSource, AL_LOOPING, AL_FALSE ); qalSourcef( src_data[ix].oalSource, AL_REFERENCE_DISTANCE, source_default.reference_distance ); qalSourcef( src_data[ix].oalSource, AL_MAX_DISTANCE, source_default.max_distance ); qalSourcef( src_data[ix].oalSource, AL_ROLLOFF_FACTOR, source_default.rolloff_factor ); qalSourcef( src_data[ix].oalSource, AL_PITCH, source_default.pitch ); qalSourcef( src_data[ix].oalSource, AL_MIN_GAIN, source_default.min_gain ); qalSourcef( src_data[ix].oalSource, AL_MAX_GAIN, source_default.max_gain ); qalSourcefv( src_data[ix].oalSource, AL_VELOCITY, zero_velocity ); qalSourcefv( src_data[ix].oalSource, AL_DIRECTION, zero_direction ); qalSourcef( src_data[ix].oalSource, AL_CONE_OUTER_GAIN, source_default.cone_outer_gain ); qalSourcef( src_data[ix].oalSource, AL_CONE_INNER_ANGLE, source_default.cone_inner_angle ); qalSourcef( src_data[ix].oalSource, AL_CONE_OUTER_ANGLE, source_default.cone_outer_angle ); } src_link[0].prev = NULL; src_link[last].next = NULL; actual_src_count = last + 1; } src_t *calSourceAlloc( void ) { src_t *src = NULL; srclink_t *srclink; if( src_freehead ) { // at least one avail on freelist srclink = src_freehead; if( srclink->next == NULL ) { // the free list is now empty src_freehead = NULL; } else { // unlink from freelist src_freehead = srclink->next; src_freehead->prev = NULL; } if( src_datahead ) { // link to head of active Sources list srclink->next = src_datahead; srclink->prev = NULL; src_datahead->prev = srclink; src_datahead = srclink; } else { // first entry on active Sources list srclink->next = NULL; srclink->prev = NULL; src_datahead = srclink; } // get the return src, backlink to link record src = srclink->src; if( ++source_counter > max_sources_used ) { // update maximum used statistic max_sources_used = source_counter; } source_failed_counter = 0; } else { if( ++source_failed_counter > max_sources_failed ) { max_sources_failed = source_failed_counter; } //Snd_DPrintf( 3, "[Source Allocation Failed]\n" ); } return src; } void calSourceFree( src_t *src ) { srclink_t *srclink; srclink_t *srclink_prev; srclink_t *srclink_next; --source_counter; // statistics update // unlink from active list srclink = src->backlink; srclink_prev = srclink->prev; srclink_next = srclink->next; if( srclink_next == NULL ) { // tail entry on active list if( srclink_prev == NULL ) { // active list is now empty src_datahead = NULL; } else { srclink_prev->next = NULL; } } else if( srclink_prev == NULL ) { // first entry on active list srclink_next->prev = NULL; src_datahead = srclink_next; } else { // inbetween srclink_prev->next = srclink_next; srclink_next->prev = srclink_prev; } // link to freelist if( src_freehead ) { // link to head of non-empty free list srclink->next = src_freehead; srclink->prev = NULL; src_freehead->prev = srclink; src_freehead = srclink; } else { // freelist was empty srclink->next = NULL; srclink->prev = NULL; src_freehead = srclink; } } /* == calSoundFXInitialize() calSoundFXAlloc() calSoundFXFree() generate and manage OpenAL Buffers and associated Sound Effects data == */ void calSoundFXInitialize( void ) { int ix; int last; ALuint genbfr[MAX_SFX]; ALint buffers_n; // generate a collection of OpenAL Buffers buffers_n = MAX_SFX; qalGetError(); for( ;; ) { qalGenBuffers( buffers_n, genbfr );// generate the collection of Buffers if( qalGetError() == AL_NO_ERROR ) { break; } // If failed, OpenAL creates no Buffers. Try for a lower number. buffers_n -= 2; if( buffers_n < 128 ) // somewhat arbitrary { // give up return; } } // init active SoundFX list to empty sfx_datahead = NULL; // init free SoundFX list sfx_freehead = sfx_link; last = 0; for( ix = 0; ix < buffers_n; ix++ ) { sfx_link[ix].next = &sfx_link[ix + 1]; sfx_link[ix].prev = &sfx_link[ix - 1]; sfx_link[ix].sfx = &sfx_data[ix]; sfx_data[ix].backlink = (void*) &sfx_link[ix]; sfx_data[ix].silent = false; sfx_data[ix].bg_music = false; sfx_data[ix].registration_sequence = 0; sfx_data[ix].byte_width = 0; sfx_data[ix].channels = 0; sfx_data[ix].samplerate = 0; sfx_data[ix].byte_count = 0; sfx_data[ix].pcmbfr = NULL; sfx_data[ix].buffered = false; sfx_data[ix].oalFormat = 0; sfx_data[ix].oalBuffer = genbfr[ix]; sfx_data[ix].aliased = false; memset( sfx_data[ix].name, '\0', MAX_QPATH ); memset( sfx_data[ix].truename, '\0', MAX_QPATH ); last = ix; } sfx_link[0].prev = NULL; sfx_link[last].next = NULL; actual_sfx_count = last + 1; } sfx_t *calSoundFXAlloc( void ) { sfx_t *sfx = NULL; sfxlink_t *sfxlink; if( sfx_freehead ) { // at least one avail on freelist sfxlink = sfx_freehead; if( sfxlink->next == NULL ) { // the free list is now empty sfx_freehead = NULL; } else { // unlink from freelist sfx_freehead = sfxlink->next; sfx_freehead->prev = NULL; } if( sfx_datahead ) { // link to head of active Sources list sfxlink->next = sfx_datahead; sfxlink->prev = NULL; sfx_datahead->prev = sfxlink; sfx_datahead = sfxlink; } else { // first entry on active Sources list sfxlink->next = NULL; sfxlink->prev = NULL; sfx_datahead = sfxlink; } // get the return sfx, backlink to link record sfx = sfxlink->sfx; } return sfx; } void calSoundFXFree( sfx_t *sfx ) { sfxlink_t *sfxlink; sfxlink_t *sfxlink_prev; sfxlink_t *sfxlink_next; // unlink from active list sfxlink = sfx->backlink; sfxlink_prev = sfxlink->prev; sfxlink_next = sfxlink->next; if( sfxlink_next == NULL ) { // tail entry on active list if( sfxlink_prev == NULL ) { // active list is now empty sfx_datahead = NULL; } else { sfxlink_prev->next = NULL; } } else if( sfxlink_prev == NULL ) { // first entry on active list sfxlink_next->prev = NULL; sfx_datahead = sfxlink_next; } else { // inbetween sfxlink_prev->next = sfxlink_next; sfxlink_next->prev = sfxlink_prev; } // link to freelist if( sfx_freehead ) { // link to head of non-empty free list sfxlink->next = sfx_freehead; sfxlink->prev = NULL; sfx_freehead->prev = sfxlink; sfx_freehead = sfxlink; } else { // freelist was empty sfxlink->next = NULL; sfxlink->prev = NULL; sfx_freehead = sfxlink; } // the oalBuffer is not deleted, but this should free the memory qalBufferData( sfx->oalBuffer, AL_FORMAT_MONO16, pcmNil, sizeof( pcmNil ), 44100 ); } /* == calALFormat() Standard OpenAL buffers may contain: unsigned 8-bit, mono unsigned 8-bit, stereo signed 16-bit, mono signed 16-bit, stereo unsigned 8-bit is 0 to 255 signed 16-bit is -32768 to 32767 stereo data is interleaved, left channel first == */ ALuint calALFormat( int byte_width, int channels ) { ALuint al_format = 0; switch( byte_width ) { case 1: switch( channels ) { case 1: al_format = AL_FORMAT_MONO8; break; case 2: al_format = AL_FORMAT_STEREO8; break; default: break; } break; case 2: switch( channels ) { case 1: al_format = AL_FORMAT_MONO16; break; case 2: al_format = AL_FORMAT_STEREO16; break; default: break; } break; default: break; } return al_format; } /* == calDistanceFromListenerSq() calculate the squared distance from the Listener to the Source. returns the SQUARED distance Note: OpenAL does not cull by distance (see documentation for the why) == */ ALfloat calDistanceFromListenerSq( ALfloat *listener_position, ALfloat *source_position ) { ALfloat dvector[3]; ALfloat distance; dvector[0] = listener_position[0] - source_position[0]; dvector[1] = listener_position[1] - source_position[1]; dvector[2] = listener_position[2] - source_position[2]; distance = dvector[0] * dvector[0] + dvector[1] * dvector[1] + dvector[2] * dvector[2]; return distance; } /* == calNewSrc() calNewLocalSrc() calNewSrcAutoLoop() create a new instance of a sound. special cases for "automatic" looping sounds and local (non-3D) sources. == */ src_t *calNewSrc( int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float gain, float fvol, float attenuation, float timeofs ) { src_t *src = NULL; src_t *src2; srclink_t *srclink; ALfloat position[3]; vec_t distance_squared; vec3_t delta; ALfloat max_distance = 0.0f; ALfloat rolloff_factor = 0.0f; ALfloat reference_distance = 0.0f; ALint state; ALint attn_class; attn_class = (int)( attenuation + 0.5f ); if( attn_class < ATTN_NONE || attn_class > ATTN_STATIC ) { Snd_DPrintf( 1, "Program Error: Invalid Attenuation (%i)\n", __LINE__); return NULL; } src = calSourceAlloc(); if( src == NULL ) { return NULL; } src->sfx = sfx; src->start_timer = (int)( timeofs * 1000.0f ); // to int msecs src->stop_timer = 0; src->entnum = entnum; src->entchannel = entchannel; src->fixed_origin = ( origin != NULL ); src->attn_class = attn_class; src->looping = false; src->loop_mark = lpmk_nonloop; src->entity_index = entnum; // might be 0. fixed_origin overrides. src->sound_field = 0; src->velocity_state = velst_nodoppler; // might change below if( !src->fixed_origin && ( ( src->entchannel == CHAN_WEAPON && src->attn_class == ATTN_NORM ) || ( src->start_timer != 0 && src->entchannel == CHAN_AUTO && src->attn_class == ATTN_NORM ))) { // setup for updating velocity for doppler. src->velocity_state = velst_init; } if( src->entnum != 0 && src->entchannel != 0 ) { // Theory: Stop anything playing with the same entity and non-zero channel /* * it seems unnecessary to stop same channel sounds in most cases * * Some special hacks here. * - moving things (plats, doors) require the "closing/landing" sound * to stop the "traveling" sound. * - other things, "sproing", for instance, can lose their sound. * The solution here is to use a timer to delay before stopping the * sound. It appears to work. * (Possible that "sproing" or what stops it is on the wrong entchannel) */ for( srclink = src_datahead; srclink != NULL; srclink = srclink->next ) { src2 = srclink->src; if( src2 == src || src2->start_timer != 0 || src->start_timer != 0 || src2->attn_class != src->attn_class ) { // don't stop self plus some other overriding conditions continue; } if( ( ( src->entnum == src2->entnum ) ) && ( src->entchannel == src2->entchannel ) ) { // found one, set timer to stop this sound qalGetSourcei( src2->oalSource, AL_SOURCE_STATE, &state ); if( state == AL_PLAYING ) { src2->stop_timer = stop_timer_msecs; } } } } /* * Determine positioning settings */ if( src->attn_class == ATTN_NONE ) { // like local. announcements. qalSourcei( src->oalSource, AL_SOURCE_RELATIVE, AL_TRUE ); qalSourcefv( src->oalSource, AL_POSITION, zero_position ); } else if( src->entnum == cl.playernum + 1 ) { // associated with listener entity if( origin == NULL ) { // same as Listener qalSourcei( src->oalSource, AL_SOURCE_RELATIVE, AL_TRUE ); qalSourcefv( src->oalSource, AL_POSITION, zero_position ); } else { // just close to Listener qalSourcei( src->oalSource, AL_SOURCE_RELATIVE, AL_TRUE ); qalGetListenerfv( AL_POSITION, position ); VectorSubtract( position, origin, position ); qalSourcefv( src->oalSource, AL_POSITION, position ); } } else if( src->entnum != 0 ) { // some other entity qalSourcei( src->oalSource, AL_SOURCE_RELATIVE, AL_FALSE ); if( origin == NULL ) { // position from entity CL_GetEntitySoundOrigin( src->entity_index, position ); qalSourcefv( src->oalSource, AL_POSITION, position ); } else { // position from function arg qalSourcefv( src->oalSource, AL_POSITION, origin ); } } else { // no entity if( origin != NULL ) { // position from function arg // // SPECIAL CASE: if close to Listener, make it RELATIVE // otherwise, alien disruptor sound gets lost // qalGetListenerfv( AL_POSITION, position ); VectorSubtract( origin, position, delta ); distance_squared = ( delta[0] * delta[0] + delta[1] * delta[1] + delta[2] * delta[2] ); if( distance_squared < ( 128.0f * 128.0f ) ) // just a guess { // Probably Listener local qalSourcei( src->oalSource, AL_SOURCE_RELATIVE, AL_TRUE ); qalSourcefv( src->oalSource, AL_POSITION, zero_position ); } else { // regular qalSourcei( src->oalSource, AL_SOURCE_RELATIVE, AL_FALSE ); qalSourcefv( src->oalSource, AL_POSITION, origin ); } } else { // no entnum, no origin, must be local qalSourcei( src->oalSource, AL_SOURCE_RELATIVE, AL_TRUE ); qalSourcefv( src->oalSource, AL_POSITION, zero_position ); } } /* * Set up distance model parameters * (Note: for "local" sounds, does not really matter) */ switch( src->attn_class ) { // distance attenuation variants. case ATTN_NONE: // "full volume the entire level" reference_distance = 0.0f; max_distance = 0.0f; rolloff_factor = 0.0f; break; case ATTN_NORM: // normal distance attenuation reference_distance = source_default.reference_distance; max_distance = source_default.max_distance; rolloff_factor = source_default.rolloff_factor; break; case ATTN_IDLE: // "idle" (meaning?) distance attenuation reference_distance = source_default.idle_reference_distance; max_distance = source_default.idle_max_distance; rolloff_factor = source_default.idle_rolloff_factor; break; case ATTN_STATIC: // "diminish very rapidly with distance" reference_distance = source_default.static_reference_distance; max_distance = source_default.static_max_distance; rolloff_factor = source_default.static_rolloff_factor; break; default: // should be impossible, checked above Sys_Error("In snd_openal.c:calNewSrc()"); break; } // set properties qalSourcef( src->oalSource, AL_GAIN, gain ); qalSourcei( src->oalSource, AL_LOOPING, AL_FALSE ); qalSourcef( src->oalSource, AL_PITCH, source_default.pitch ); qalSourcef( src->oalSource, AL_MAX_DISTANCE, max_distance ); qalSourcef( src->oalSource, AL_ROLLOFF_FACTOR, rolloff_factor ); qalSourcef( src->oalSource, AL_REFERENCE_DISTANCE, reference_distance ); qalSourcefv( src->oalSource, AL_VELOCITY, zero_velocity ); qalSourcef( src->oalSource, AL_MIN_GAIN, source_default.min_gain ); qalSourcef( src->oalSource, AL_MAX_GAIN, source_default.max_gain ); qalSourcefv( src->oalSource, AL_DIRECTION, zero_direction ); // when direction vector is the zero vector, these disabled //qalSourcef( src->oalSource, AL_CONE_OUTER_GAIN, source_default.cone_outer_gain ); //qalSourcef( src->oalSource, AL_CONE_INNER_ANGLE, source_default.cone_inner_angle ); //qalSourcef( src->oalSource, AL_CONE_OUTER_ANGLE, source_default.cone_outer_angle ); // attach the Buffer qalSourcei( src->oalSource, AL_BUFFER, src->sfx->oalBuffer ); calErrorCheckAL( __LINE__ ); return src; } src_t *calNewLocalSrc( sfx_t *sfx, float gain ) { src_t *src; src = calSourceAlloc(); if( src == NULL ) { return NULL; } src->sfx = sfx; src->start_timer = 0; src->stop_timer = 0; src->entnum = 0; src->entchannel = 0; src->fixed_origin = false; src->attn_class = 0; src->looping = false; src->loop_mark = lpmk_nonloop; src->entity_index = 0; src->sound_field = 0; src->velocity_state = velst_nodoppler; // Set as a local Source with the requested gain (usually 1.0) qalSourcei( src->oalSource, AL_SOURCE_RELATIVE, AL_TRUE ); qalSourcefv( src->oalSource, AL_POSITION, zero_position ); qalSourcef( src->oalSource, AL_GAIN, gain ); qalSourcei( src->oalSource, AL_LOOPING, AL_FALSE ); qalSourcefv( src->oalSource, AL_VELOCITY, zero_velocity ); // Make sure Source properties are at defaults qalSourcef( src->oalSource, AL_PITCH, source_default.pitch ); qalSourcef( src->oalSource, AL_MAX_DISTANCE, source_default.max_distance ); qalSourcef( src->oalSource, AL_ROLLOFF_FACTOR, source_default.rolloff_factor ); qalSourcef( src->oalSource, AL_REFERENCE_DISTANCE, source_default.reference_distance ); qalSourcef( src->oalSource, AL_MIN_GAIN, source_default.min_gain ); qalSourcef( src->oalSource, AL_MAX_GAIN, source_default.max_gain ); qalSourcefv( src->oalSource, AL_DIRECTION, zero_direction ); // when direction vector is the zero vector, these disabled //qalSourcef( src->oalSource, AL_CONE_OUTER_GAIN, source_default.cone_outer_gain ); //qalSourcef( src->oalSource, AL_CONE_INNER_ANGLE, source_default.cone_inner_angle ); //qalSourcef( src->oalSource, AL_CONE_OUTER_ANGLE, source_default.cone_outer_angle ); // Attach the Buffer qalSourcei( src->oalSource, AL_BUFFER, src->sfx->oalBuffer ); calErrorCheckAL( __LINE__ ); return src; } src_t *calNewSrcAutoLoop( int entity_index, int sound_field ) { sfx_t *sfx; src_t *src; ALfloat source_position[3]; sfx = cl.sound_precache[sound_field]; // get SFX from the precache. if( sfx == NULL ) { // note: sound_precache sfx pointers are determined by S_RegisterSound() //Snd_DPrintf( 3, "[looping sound not registered (%i)", __LINE__ ); return NULL; } if( sfx->bg_music || !Q_strncasecmp( sfx->name, "music", 5 )) { // background music from speakers is obsolete //Snd_DPrintf( 3, "[background music looping sound (%i)", __LINE__ ); return NULL; } src = calSourceAlloc(); // get Src from free list if( src == NULL ) { return NULL; } src->start_timer = 0; src->stop_timer = 0; src->entnum = entity_index; src->entchannel = CHAN_AUTO; src->fixed_origin = false; src->attn_class = ATTN_NONE; // Does not apply src->looping = true; src->loop_mark = lpmk_start; src->entity_index = entity_index; src->sound_field = sound_field; src->velocity_state = velst_init; src->sfx = sfx; qalSourcei( src->oalSource, AL_LOOPING, AL_TRUE ); if( src->entnum == cl.playernum + 1 ) { // associated with listener entity, for instance, "smartgun hum" src->velocity_state = velst_nodoppler; // of course qalSourcei( src->oalSource, AL_SOURCE_RELATIVE, AL_TRUE ); qalSourcefv( src->oalSource, AL_POSITION, zero_position ); } else { // set position from entity information CL_GetEntitySoundOrigin( entity_index, source_position ); qalSourcei( src->oalSource, AL_SOURCE_RELATIVE, AL_FALSE ); qalSourcefv( src->oalSource, AL_POSITION, source_position ); } qalSourcef( src->oalSource, AL_GAIN, source_default.looping_gain ); qalSourcef( src->oalSource, AL_REFERENCE_DISTANCE, source_default.looping_reference_distance ); qalSourcef( src->oalSource, AL_MAX_DISTANCE, source_default.looping_max_distance ); qalSourcef( src->oalSource, AL_ROLLOFF_FACTOR, source_default.looping_rolloff_factor ); qalSourcefv( src->oalSource, AL_VELOCITY, zero_velocity ); // Make sure Source properties are at defaults qalSourcef( src->oalSource, AL_PITCH, source_default.pitch ); qalSourcef( src->oalSource, AL_MIN_GAIN, source_default.min_gain ); qalSourcef( src->oalSource, AL_MAX_GAIN, source_default.max_gain ); qalSourcefv( src->oalSource, AL_DIRECTION, zero_direction ); // when direction vector is the zero vector, these disabled //qalSourcef( src->oalSource, AL_CONE_OUTER_GAIN, source_default.cone_outer_gain ); //qalSourcef( src->oalSource, AL_CONE_INNER_ANGLE, source_default.cone_inner_angle ); //qalSourcef( src->oalSource, AL_CONE_OUTER_ANGLE, source_default.cone_outer_angle ); // attach Buffer qalSourcei( src->oalSource, AL_BUFFER, src->sfx->oalBuffer ); return src; } /* == calLoadSound() Load an initialized/registered sound effect into an OpenAL Buffer == */ void calLoadSound( sfx_t *sfx ) { char *name; char namebuffer[MAX_OSPATH]; qboolean success; if( sfx->buffered || sfx->silent ) { // already done for this one return; } if( sfx->name[0] == '*' ) { // Model specific sounds are loaded in S_StartSound() when entity is known // use this SFX for the default // set it up as an aliased SFX Com_sprintf(sfx->truename, MAX_QPATH, "player/male/%s",&(sfx->name[1])); sfx->aliased = true; } // figure out full filepath name = sfx->aliased ? sfx->truename : sfx->name; if( name[0] == '#' ) { // not in sound subdirectory, normally, #player/blah, strncpy( namebuffer, &name[1], MAX_OSPATH ); // strip off '#' } else { // standard sound effect location Com_sprintf( namebuffer, sizeof( namebuffer ), "sound/%s", name ); } // read the sound file PCM data into an intermediate buffer // enable Ogg Vorbis substition for background music files success = S_LoadSound( namebuffer, sfx->bg_music, &sfx->filebfr, &sfx->pcmbfr, &sfx->byte_width, &sfx->channels, &sfx->samplerate, &sfx->byte_count ); if( !success ) { sfx->silent = true; // prevent repetitive searching for missing/bad file } if( sfx->silent ) { // unable to get sound effect data Snd_DPrintf( 1, "Sound File %s could not be read.\n", ( sfx->aliased ? sfx->truename : sfx->name ) ); return; } // transfer PCM data to OpenAL Buffer sfx->oalFormat = calALFormat( sfx->byte_width, sfx->channels ); if( sfx->oalFormat ) { qalGetError(); qalBufferData( sfx->oalBuffer, sfx->oalFormat, sfx->pcmbfr, (ALsizei)( sfx->byte_count ), (ALsizei)( sfx->samplerate ) ); if( calErrorCheckAL( __LINE__ ) != AL_NO_ERROR ) { // failed to transfer sfx->silent = true; Snd_DPrintf( 1, "Sound File %s failed to load into OpenAL buffer\n", ( sfx->aliased ? sfx->truename : sfx->name ) ); } else { // success sfx->buffered = true; } } else { // not a supported file format sfx->silent = true; Snd_DPrintf( 1, "Sound File %s's format is not supported.\n", ( sfx->aliased ? sfx->truename : sfx->name ) ); } // done with file buffer FS_FreeFile( sfx->filebfr ); sfx->filebfr = NULL; sfx->pcmbfr = NULL; } /* == calContextInfo() info about sound system configuration == */ void calContextInfo( ALCdevice *pDevice ) { ALCint alc_frequency; ALCint alc_mono_sources; ALCint alc_stereo_sources; ALCint alc_refresh; ALCint alc_sync; int ix; calErrorCheckALC( pDevice, __LINE__ ); Com_Printf( "OpenAL Information:\n" ); Com_Printf( "Active Device: %s\n", qalcGetString( pDevice, ALC_DEVICE_SPECIFIER )); Com_Printf( " Vendor: %s\n", qalGetString( AL_VENDOR ) ); Com_Printf( " Version: %s\n", qalGetString( AL_VERSION ) ); Com_Printf( " Renderer: %s\n", qalGetString( AL_RENDERER ) ); qalcGetIntegerv( pDevice, ALC_FREQUENCY, 1, &alc_frequency ); Com_Printf( " ALC Frequency: %i\n", alc_frequency ); Com_Printf( " Generated Buffer Count: %i\n", actual_sfx_count ); // Source statistics qalcGetIntegerv( pDevice, ALC_MONO_SOURCES, 1, &alc_mono_sources ); Com_Printf( " ALC Mono Sources: %i\n", alc_mono_sources ); qalcGetIntegerv( pDevice, ALC_STEREO_SOURCES, 1, &alc_stereo_sources ); Com_Printf( " ALC Stereo Sources: %i\n", alc_stereo_sources ); Com_Printf( " Generated Source Count: %i\n", actual_src_count ); if( max_sources_used > 0 ) { Com_Printf( " Maximum Sources Used: %i\n", max_sources_used ); if( max_sources_failed > 0 ) { Com_Printf( " Maximum Sources Requested: %i\n", max_sources_used + max_sources_failed ); } } Snd_DPrintf( 1, " AL Extensions: %s\n", qalGetString( AL_EXTENSIONS ) ); Snd_DPrintf( 1, " ALC Extensions: %s\n", qalcGetString( pDevice,ALC_EXTENSIONS ) ); qalcGetIntegerv( pDevice, ALC_REFRESH, 1, &alc_refresh ); Snd_DPrintf( 1, " ALC Refresh: %i\n", alc_refresh); qalcGetIntegerv( pDevice, ALC_SYNC, 1, &alc_sync ); Snd_DPrintf( 1, " ALC Sync: %i\n", alc_sync ); Com_Printf( "Available Devices:\n" ); for( ix = 0; ix < oalDeviceCount; ++ix ) { Com_Printf(" %s\n", pDeviceNames[ix] ); } Snd_DPrintf( 1, "Speed of Sound: %f\n", speed_of_sound ); Snd_DPrintf( 1, "Doppler Factor: %f\n", doppler_factor ); calErrorCheckALC( pDevice, __LINE__ ); } /* == S_UpdateDopplerFactor() for update from menu, according to cvar setting, == */ void S_UpdateDopplerFactor( void ) { doppler_factor = s_doppler->value; if( doppler_factor < 0.0f ) { doppler_factor = 0.0f; Cvar_Set( "s_doppler", "0" ); } else if( doppler_factor > maximum_doppler_factor ) { doppler_factor = maximum_doppler_factor; Cvar_SetValue( "s_doppler", maximum_doppler_factor ); } if ( sound_system_enable ) { qalDopplerFactor( doppler_factor ); } s_doppler->modified = false; } /* == calEnumerateDevices() Builds a list of devices supporting OpenAL 1.1 or greater An empty list probably indicates OpenAL 1.0 devices only Notes: The OpenAL device list is a null-separated, double-null terminated list of device name strings snd_restart command should rebuild list because devices can change == */ void calEnumerateDevices( void ) { ALCchar* pDeviceName; ALCdevice *pDevice; ALCint major_version; ALCint minor_version; int ix; int len; int pos; qboolean success; ix = 0; pos = 0; if( qalcIsExtensionPresent( NULL, "ALC_ENUMERATION_EXT" ) ) { oalDeviceList = qalcGetString( NULL, ALC_DEVICE_SPECIFIER ); pDeviceName = (ALCchar*)oalDeviceList; while( pDeviceName && (len = strlen( pDeviceName )) ) { pDevice = qalcOpenDevice( pDeviceName ); calErrorCheckALC( pDevice, __LINE__ ); // clear any device error if( pDevice ) { // the device can be opened qalcGetIntegerv( pDevice, ALC_MAJOR_VERSION, 1, &major_version ); qalcGetIntegerv( pDevice, ALC_MINOR_VERSION, 1, &minor_version ); if( (major_version == 1 && minor_version >= 1) || major_version > 1 ) { // device supports OpenAL 1.1 or greater if( ix >= MAX_OAL_DEVICES ) { Snd_DPrintf(1, "Program Error: Valid devices > %i\n", MAX_OAL_DEVICES ); } else { pDeviceNames[ix++] = pDeviceName; Snd_DPrintf( 1, "Adding Valid Device %s\n", pDeviceName ); } } calErrorCheckALC( pDevice, __LINE__ ); // clear any device error success = qalcCloseDevice( pDevice ); if( !success ) { Snd_DPrintf( 1, "Close failed on %s\n", pDeviceName ); } } else { Snd_DPrintf(1, "Open failed on %s\n", pDeviceName ); } pos += len + 1; pDeviceName = (ALCchar*)&oalDeviceList[ pos ]; // next device string } } oalDeviceCount = ix; // store count of available devices in list } /* == calSelectDevice() Theory is: Always accept the device specified by the user set cvar (provided it opens) Otherwise, use the default device. For the special Windows XP case, override the generic hardware default if it has less than the minimum specified in the s_minsources cvar. == */ ALCdevice *calSelectDevice( void ) { ALCdevice *pDevice = NULL; ALCdevice *pDevice2 = NULL; ALCchar *pDeviceName; ALCint alc_mono_sources; ALenum result; int len; int pos; // selected device (note: case insensitive compare) if( oalDeviceCount > 0 && s_device && Q_strcasecmp(s_device->string, "Default" ) ) { // cvar set and it is not 'Default' // alcOpenDevice needs case sensitive name from device list pDeviceName = (ALCchar*)oalDeviceList; pos = 0; while( (len = strlen( pDeviceName )) > 0 ) { if( !Q_strcasecmp( s_device->string, pDeviceName ) ) { // found cvar device selection in list pDevice = qalcOpenDevice( pDeviceName ); if( pDevice != NULL ) { if( calErrorCheckALC( pDevice, __LINE__ ) != ALC_NO_ERROR ) { qalcCloseDevice( pDevice ); Com_Printf("Error opening sound device: %s\n", pDeviceName ); pDevice = NULL; } } else { Com_Printf( "Failed to open sound device: %s\n", pDeviceName ); } break; // exit loop } pos += len + 1; pDeviceName = (ALCchar*)&oalDeviceList[ pos ]; // next device name } if( len == 0 ) { // no match to cvar found in list Com_Printf( "Device %s not in available device list\n" " (check that cvar: s_device is correct.)\n", s_device->string ); } } // default device if (pDevice == NULL) { // open the Default device pDevice = qalcOpenDevice(NULL); if( pDevice != NULL ) { // handle Windows XP "Generic Hardware" case result = calErrorCheckALC( pDevice, __LINE__ ); pDeviceName = (ALCchar*)qalcGetString( pDevice, ALC_DEVICE_SPECIFIER ); if( !Q_strcasecmp( (char*)pDeviceName, "Generic Hardware") ) { qalcGetIntegerv(pDevice, ALC_MONO_SOURCES, 1, &alc_mono_sources); if ( alc_mono_sources < s_minsources->integer ) { // supported sources are below limit pDevice2 = qalcOpenDevice( "Generic Software" ); if( pDevice2 != NULL ) { // use Generic Software device instead qalcCloseDevice( pDevice ); pDevice = pDevice2; } } } } } return pDevice; } /* == S_Init() - cold-start initialization - also target of snd_restart command == */ // some forward declarations void sndCvarInit( void ); void sndCmdInit( void ); void sndCmdRemove( void ); void S_Init( void ) { ALCdevice *pDevice; ALCchar *pDeviceName; ALCcontext *pContext; qboolean success; ALCenum result; ALCint alc_mono_sources; sound_system_enable = false; Com_Printf( "\n------- sound initialization -------\n" ); // init global device state oalDeviceCount = 0; /* * Setup CVARS */ sndCvarInit(); // setup s_* cvars doppler_factor = s_doppler->value; if( doppler_factor < 0.0f ) doppler_factor = 0.0f; else if( doppler_factor > maximum_doppler_factor ) doppler_factor = maximum_doppler_factor; if( s_initsound->value <= 0 ) { // command line disable of sound system Com_Printf( "!Sound Disabled!\n" ); return; } // Link to OpenAL library success = QAL_Init(); if( !success ) { Com_Printf("Sound failed: Unable to start OpenAL.\n" "Game will continue without sound.\n" ); return; } // Enumerate Devices calEnumerateDevices(); if( oalDeviceCount == 0 ) { Com_Printf("Sound failed: OpenAL 1.1 or greater required\n" "Game will continue without sound.\n"); return; } // Select Device pDevice = calSelectDevice(); if( pDevice == NULL ) { Com_Printf("Sound failed: Unable to open sound device\n" "Game will continue without sound.\n" ); return; } pContext = qalcCreateContext( pDevice, NULL ); // 2. create context if ( pContext == NULL ) { qalcCloseDevice( pDevice ); pDevice = NULL; Com_Printf( "Sound failed: Possible OpenAL or device configuration problem\n" "Game will continue without sound.\n" ); return; } qalcMakeContextCurrent( pContext ); // 3. make context current result = calErrorCheckALC( pDevice, __LINE__ ); // warn about number of Sources qalcGetIntegerv( pDevice, ALC_MONO_SOURCES, 1, &alc_mono_sources ); if ( alc_mono_sources < s_minsources->integer ) { pDeviceName = (ALCchar*)qalcGetString( pDevice, ALC_DEVICE_SPECIFIER ); Com_Printf( "Warning: \"%s\" supports %i OpenAL Sources.\n" " Minimum Sources (cvar: s_minsources) set to %i.\n" " Some sound effects may not be heard\n", pDeviceName, alc_mono_sources, s_minsources->integer ); } // Setup 3D Audio State qalDistanceModel( distance_model ); qalDopplerFactor( doppler_factor ); qalSpeedOfSound( speed_of_sound ); // Initialize Listener if ( s_volume->value > 0 ) qalListenerf( AL_GAIN, (ALfloat)0.1f ); // start quiet, need some for menu clicks else qalListenerf( AL_GAIN, (ALfloat)0.0f ); // sound is off qalListenerfv( AL_POSITION, zero_position ); qalListenerfv( AL_VELOCITY, zero_velocity ); qalListenerfv( AL_ORIENTATION, default_orientation ); qalcGetIntegerv( pDevice, ALC_MONO_SOURCES, 1, &alc_mono_sources ); result = calErrorCheckALC( pDevice, __LINE__ ); if( result != ALC_NO_ERROR || alc_mono_sources <= 0 ) { Com_Printf("OpenAL Device error: Number of Mono Sources\n"); alc_mono_sources = 0; } else { // generate OpenAL sound effects Sources. calSourcesInitialize( alc_mono_sources ); } calSoundFXInitialize(); // generate OpenAL Buffers sndCmdInit(); // setup snd* console commands calContextInfo( pDevice ); // display OpenAL technical info // Initialize background music dedicated source record // other intialization done in S_StartMusic music.playing = false; music.sfx = NULL; music.oalSource = 0; sound_system_enable = true; Com_Printf( "------------------------------------\n" ); } /* == S_StopAllSounds() - quiet all sounds. Called on program state changes. - also target of console command: stopsound == */ void S_StopAllSounds( void ) { src_t *src; srclink_t *srclink; if( !QAL_Loaded() || !sound_system_enable ) return; srclink = src_datahead; while( srclink != NULL ) { src = srclink->src; srclink=srclink->next; qalSourceStop( src->oalSource ); // ok from any state per spec qalSourcei( src->oalSource, AL_BUFFER, AL_NONE ); // disconnect Buffer calSourceFree( src ); } if ( music.oalSource && qalIsSource( music.oalSource ) ) { // special case for music qalSourceStop( music.oalSource ); qalSourcei( music.oalSource, AL_BUFFER, AL_NONE ); // disconnect Buffer // special for music, only one Source using this Buffer // NOTE: not freeing sfx means 2 music files are resident which uses // more memory, but means the Ogg Vorbis decode does not have to // be done everytime the menu is accessed. // calSoundFXFree( music.sfx ); music.sfx = NULL; music.playing = false; } } /* == S_Shutdown() Complete shutdown of sound system for program exit or sound system restart == */ void S_Shutdown( void ) { ALCdevice *pDevice; ALCcontext *pContext; ALCboolean result; int ix; int count; ALuint delsrc[MAX_SRC]; ALuint delbfr[MAX_SFX]; if( !QAL_Loaded() ) { return; } S_StopAllSounds(); // quiets all sources, disconnects Sources from Buffers qalGetError(); // Special case for music. delete the Source only, here. if ( music.oalSource && qalIsSource( music.oalSource ) ) { qalDeleteSources( 1, &music.oalSource ); } // Delete all other Sources and all Buffers count = 0; for( ix = 0; ix < MAX_SRC; ix++ ) { if( qalIsSource( src_data[ix].oalSource ) ) { delsrc[count++ ] = src_data[ix].oalSource; } } qalDeleteSources( count, delsrc ); count = 0; for( ix = 0; ix < MAX_SFX; ix++ ) { if( qalIsBuffer( sfx_data[ix].oalBuffer ) ) { delbfr[count++ ] = sfx_data[ix].oalBuffer; } } qalDeleteBuffers( count, delbfr ); calErrorCheckAL( __LINE__ ); // Empty the src and sfx data, so its all clean if restarting src_datahead = NULL; src_freehead = NULL; sfx_datahead = NULL; sfx_freehead = NULL; actual_src_count = 0; actual_sfx_count = 0; memset( src_link, 0, sizeof( src_link ) ); memset( src_data, 0, sizeof( src_link ) ); memset( sfx_link, 0, sizeof( sfx_link ) ); memset( sfx_data, 0, sizeof( sfx_link ) ); // Close OpenAL Context pContext = qalcGetCurrentContext(); pDevice = qalcGetContextsDevice( pContext ); calErrorCheckALC( pDevice, __LINE__ ); result = qalcMakeContextCurrent( NULL ); if( result ) { qalcDestroyContext( pContext ); } else { Snd_DPrintf( 1, "qalcMakeContextCurrent(NULL) failed\n" ); } // Close OpenAL Device result = qalcCloseDevice( pDevice ); if( !result ) { Snd_DPrintf( 1, "qalcCloseDevice failed\n" ); } QAL_Shutdown(); // Unlink OpenAL dynamic/shared library sndCmdRemove(); // remove certain console commands sound_system_enable = false; } /* == S_FindName() Lookup a sound effects record. If it does not exist and 'create' requested, create a new one == */ sfx_t *S_FindName( const char *name, qboolean create ) { sfxlink_t *sfxlink; sfx_t *sfx = NULL; for( sfxlink = sfx_datahead; sfxlink != NULL; sfxlink = sfxlink->next ) { sfx = sfxlink->sfx; if( strncmp( sfx->name, name, MAX_QPATH ) == 0 ) { return sfx; } } if( create ) { sfx = calSoundFXAlloc(); // from free list if( sfx != NULL ) { // set registration seq, file name. clear or default others sfx->silent = false; sfx->bg_music = false; sfx->registration_sequence = s_registration_sequence; sfx->byte_width = 0; sfx->channels = 0; sfx->samplerate = 0; sfx->byte_count = 0; sfx->pcmbfr = NULL; sfx->buffered = false; sfx->oalFormat = 0; sfx->aliased = false; memset( sfx->name, '\0', MAX_QPATH ); strncpy( sfx->name, name, MAX_QPATH - 1 ); memset( sfx->truename, '\0', MAX_QPATH ); } } return sfx; } /* == S_BeginRegistration Start registration of sound effects. Preloads commonly used and looping sounds == */ void S_BeginRegistration( void ) { if( sound_system_enable ) { s_registration_sequence++ ; s_registering = true; } } /* == calFreeOldSndFX() free the SFX's not in the current registration sequence == */ void calFreeOldSndFX( void ) { sfxlink_t *sfxlink; sfx_t *sfx; sfxlink = sfx_datahead; while( sfxlink ) { sfx = sfxlink->sfx; sfxlink = sfxlink->next; // must advance pointer *before* list modify if( sfx->registration_sequence != s_registration_sequence ) { calSoundFXFree( sfx ); } } } /* == S_RegisterSound() if pre-caching, add a sound effect to the collection, but don't load it yet otherwise, register and load the sound effect the returned sfx_t pointer is just a "handle" to other parts of the system == */ sfx_t *S_RegisterSound( char *name ) { sfx_t *sfx = NULL; if( sound_system_enable ) { sfx = S_FindName( name, true ); if( sfx == NULL ) { // out of SFX's, free up some, try again. // this may free an SFX that will be registered later in the // sequence -- the downside of only having as many SFXs as // there are OpenAL Buffers. calFreeOldSndFX(); sfx = S_FindName( name, true ); } if( sfx != NULL ) { // if it already existed, needs to be put in current sequence sfx->registration_sequence = s_registration_sequence; if( !s_registering ) { // not doing a pre-cache sequence, load the data calLoadSound( sfx ); } } else { Snd_DPrintf( 1, "S_RegisterSound(): Failed to register %s\n", name ); } } return sfx; } /* == S_EndRegistration() Finish cache processing. Does actual loading of sound data. == */ void S_EndRegistration( void ) { sfxlink_t *sfxlink; if( sound_system_enable ) { // free now unused SFX's from previous registration sequence calFreeOldSndFX(); // load up this registration sequence for( sfxlink = sfx_datahead; sfxlink != NULL; sfxlink = sfxlink->next ) { calLoadSound( sfxlink->sfx ); } s_registering = false; // done with this registration sequence } } /* == calModelFilename extract the model name from configstrings, and construct the filename format of model/skin names in configstrings is: \/ == */ void calModelFilename( entity_state_t *ent, const char *basename, char* qfilepath ) { int cfgstr_ix; char *ptr; char model[MAX_QPATH]; cfgstr_ix = CS_PLAYERSKINS + ent->number - 1; ptr = cl.configstrings[cfgstr_ix]; model[0] = '\0'; if( *ptr ) { // non-empty string with player\model/skin ptr = strchr( ptr, '\\' ); if( ptr ) { ++ptr; strncpy( model, ptr, MAX_QPATH ); ptr = strchr( model, '/' ); if( ptr ) *ptr = '\0'; } } if( model[0] == '\0' ) { *qfilepath = '\0'; // return empty string } else { // return path to model specific sound Com_sprintf( qfilepath, MAX_QPATH, "#players/%s/%s", model, basename ); } } /* == S_RegisterSoundsForPlayer() Register the model-specific sounds (pain, jumping, etc.) that should be present for each player model. This function is called from the model loading code. It relies on the fact that the server precaches sounds before models, so the generic (fallback) version of each model-specific sound is already in the precache list at this point. == */ void S_RegisterSoundsForPlayer (char *playername) { int i; char soundpath[MAX_QPATH]; return; // FIXME: figure out why Windows doesn't like this. for (i=1 ; ibg_music || !Q_strncasecmp( arg_sfx->name, "music", 5 ) ) { // background music from speakers is obsolete return; } // cull sound by distance attn_class = (int)(attenuation + 0.5f); if( attn_class != ATTN_NONE ) { switch( attn_class ) { case ATTN_NORM: sq_cull_distance = norm_sq_cull_distance; break; case ATTN_IDLE: sq_cull_distance = idle_sq_cull_distance; break; case ATTN_STATIC: sq_cull_distance = static_sq_cull_distance; break; default: Snd_DPrintf( 1, "Program Error: ATTN_ value (%i)\n", __LINE__); sq_cull_distance = 0.0f; break; } qalGetListenerfv( AL_POSITION, listener_position ); if( origin != NULL ) { dist_sq = calDistanceFromListenerSq( listener_position, origin ); if( dist_sq > sq_cull_distance) { //Snd_DPrintf( 3, "[Culled-1: %s]\n", arg_sfx->name); return; } } else if( entnum != 0 ) { CL_GetEntitySoundOrigin( entnum, source_position ); dist_sq = calDistanceFromListenerSq( listener_position, source_position ); if( dist_sq > sq_cull_distance) { //Snd_DPrintf( 3, "[Culled-2: %s]\n", arg_sfx->name); return; } } } model_sfx = NULL; sfx = arg_sfx; if( sfx->name[0] == '*' ) { // model specific sound // get the model specific filename ent = &cl_entities[entnum].current; calModelFilename( ent, &( sfx->name[1] ), qfilename ); if( qfilename[0] != '\0' ) { // there is a model specific name, register it model_sfx = S_RegisterSound( qfilename ); if( model_sfx != NULL ) { // use it, otherwise the default (aliased) SFX is used sfx = model_sfx; } } } calLoadSound( sfx ); if( !sfx->buffered || sfx->silent ) { // not available return; } src = calNewSrc( entnum, entchannel, sfx, origin, 1.0, fvol, attenuation, timeofs ); if( src == NULL ) { // no src available return; } if( src->start_timer < 5 ) { src->start_timer = 0; qalSourcePlay( src->oalSource ); // !make some noise! } /* if( origin != NULL ) { Snd_DPrintf( 3, "[StartSound: CHAN=%i, ATTN=%i, timer=%i, origin=(%f,%f,%f) %s]\n", src->entchannel, src->attn_class, src->start_timer, origin[0], origin[1], origin[2], src->sfx->name ); } else { Snd_DPrintf( 3, "[StartSound: CHAN=%i, ATTN=%i, timer=%i, %s]\n", src->entchannel, src->attn_class, src->start_timer, src->sfx->name ); } */ } /* == S_StartMusic() Note: background music has it own dedicated src-like struct, but gets its sfx from the general pool. (Memo to self: Remember This.) == */ void S_StartMusic( char *qfilename ) { ALfloat gain; if( !sound_system_enable ) { return; } if( music.playing ) { if ( background_music->value && !Q_strcasecmp( qfilename, music.sfx->name) ) { // music is enabled and this song already playing. return; } } if ( music.oalSource && qalIsSource( music.oalSource ) ) { // stop the music qalSourceStop( music.oalSource ); // ok from any state, per spec qalSourcei( music.oalSource, AL_BUFFER, AL_NONE ); // disconnect Buffer // special for music, only one Source using this Buffer // NOTE: not freeing sfx means 2 music files are resident, map music // and menu music. This uses more memory, but means the Ogg Vorbis // decode does not have to be done everytime the menu is accessed. // calSoundFXFree( music.sfx ); music.sfx = NULL; } music.playing = false; if( background_music->value == 0 ) { // disabled return; } music.sfx = S_FindName( qfilename, true ); // get a new sfx from pool if( music.sfx != NULL ) { music.sfx->bg_music = true; // special case sfx marker calLoadSound( music.sfx ); // load the music file into a Buffer } else { Snd_DPrintf( 1, "No SFX for music file %s\n", qfilename ); } if ( music.sfx->silent ) { Snd_DPrintf( 1, "Music file %s failed load\n", qfilename); return; } // music file is loaded, attach to a source and play it if( music.oalSource == 0 ) { // haven't generated the dedicated Source yet, so do that first qalGenSources( 1, &( music.oalSource ) ); } if( qalIsSource( music.oalSource ) ) { // got a Source // make sure Source is set to defaults qalSourcef( music.oalSource, AL_REFERENCE_DISTANCE,source_default.reference_distance ); qalSourcef( music.oalSource, AL_MAX_DISTANCE, source_default.max_distance ); qalSourcef( music.oalSource, AL_ROLLOFF_FACTOR, source_default.rolloff_factor ); qalSourcef( music.oalSource, AL_PITCH, source_default.pitch ); qalSourcef( music.oalSource, AL_MIN_GAIN, source_default.min_gain ); qalSourcef( music.oalSource, AL_MAX_GAIN, source_default.max_gain ); qalSourcefv( music.oalSource, AL_DIRECTION, zero_direction ); qalSourcef( music.oalSource, AL_CONE_OUTER_GAIN, source_default.cone_outer_gain ); qalSourcef( music.oalSource, AL_CONE_INNER_ANGLE, source_default.cone_inner_angle ); qalSourcef( music.oalSource, AL_CONE_OUTER_ANGLE, source_default.cone_outer_angle ); // set gain gain = (ALfloat)( background_music_vol->value ); if( gain > 0.2f ) { gain = 0.2f; // start softly, will go up in S_Update() } qalSourcef( music.oalSource, AL_GAIN, gain ); // set for looping and "local" qalSourcei( music.oalSource, AL_LOOPING, AL_TRUE ); qalSourcei( music.oalSource, AL_SOURCE_RELATIVE, AL_TRUE ); qalSourcefv( music.oalSource, AL_POSITION, zero_position ); qalSourcefv( music.oalSource, AL_VELOCITY, zero_velocity ); // attach to buffer qalSourcei( music.oalSource, AL_BUFFER, music.sfx->oalBuffer ); // and start playing qalSourcePlay( music.oalSource ); music.playing = true; } else { // failed to obtain a Source Com_Printf( "Sound Error: Disabling background music.\n" ); Cvar_Set( "background_music", "0" ); } } /* == S_StartMenuMusic() S_StartMapMusic() Note: added to get better control of background music. These functions expect S_StartMusic() to do checks for music enabled, etc. = */ void S_StartMenuMusic( void ) { S_StartMusic( "music/menumusic.wav" ); } extern char map_music[260]; // declared and set in r_model.c void S_StartMapMusic( void ) { S_StartMusic( map_music ); } /* == S_StartLocalSound() for sounds that are not position dependent always client-side origination ? == */ void S_StartLocalSound( const char *qfilename ) { sfx_t *sfx; src_t *src; if( !sound_system_enable ) { return; } // Start the new local sound sfx = S_FindName( qfilename, true ); if( sfx != NULL ) { calLoadSound( sfx ); } if( sfx != NULL && !sfx->silent ) { src = calNewLocalSrc( sfx, source_default.gain ); if( src ) { qalSourcePlay( src->oalSource ); } } } /* == calVelocityVector() calculate and validate the velocity vector deltaT : time difference in msecs, the frame time == **/ typedef ALfloat ALvector[3]; typedef ALfloat ALpoint[3]; qboolean calVelocityVector( int deltaT, ALpoint in_previous, ALpoint in_current, ALvector out_velocity ) { qboolean valid; ALfloat mag_sq; ALfloat dT; dT = (ALfloat)(float)deltaT; out_velocity[0] = ( in_current[0] - in_previous[0] ) / dT; out_velocity[1] = ( in_current[1] - in_previous[1] ) / dT; out_velocity[2] = ( in_current[2] - in_previous[2] ) / dT; // note: so velocity is in QuakeUnits-per-millisecond // spawning, transporter jumps, and probably other stuff will cause // wildly inaccurate velocities. use squared values; no need for sqrt() mag_sq = out_velocity[0] * out_velocity[0] + out_velocity[1] * out_velocity[1] + out_velocity[2] * out_velocity[2]; valid = ( mag_sq <= velocity_max_valid ); return valid; } /* == calUpdateLoopSounds() manage the "automatic" looping sounds these are triggered by the entity_state_t .sound field the .number field and the .sound field identify the looping object == */ void calUpdateLoopSounds( int deltaT, ALpoint listener_position ) { int num; int ix; entity_state_t *ent; src_t *src; srclink_t *srclink; int new_entity_index; int new_sound_field; qboolean src_marked; ALvector velocity; ALpoint old_position; ALpoint new_position; ALint state; ALfloat dist_sq; ALpoint source_position; qboolean valid_velocity; if( cl_paused->value || cls.state != ca_active || !cl.sound_prepped ) { // not in a game playing state return; } for( srclink = src_datahead; srclink; srclink = srclink->next ) { // first phase, mark all running looping sounds for stopping src = srclink->src; if( src->looping ) { src->loop_mark = lpmk_stop; // may be overridden below } } for( ix = 0; ix < cl.frame.num_entities; ix++ ) { // second phase, update with continuation mark, or new one with start mark // get the data that implicitly implies a looping sound effect num = ( cl.frame.parse_entities + ix ) & ( MAX_PARSE_ENTITIES - 1 ); ent = &cl_parse_entities[num]; new_sound_field = ent->sound; if( new_sound_field == 0 ) { // nothing in .sound field, no looping continue; }; new_entity_index = ent->number; src_marked = false; for( srclink = src_datahead; srclink; srclink = srclink->next ) { // second marking phase, mark for continuing the loop src = srclink->src; if( src->entity_index == new_entity_index && src->sound_field == new_sound_field ) { // still exists, keep on looping src->loop_mark = lpmk_continue; src_marked = true; } } if( !src_marked ) { // this must be a new entity w/ .sound field, add a new looping src // but watch out for any obsolete speakers, music/*.wav CL_GetEntitySoundOrigin( new_entity_index, source_position ); dist_sq = calDistanceFromListenerSq( listener_position, source_position ); if( dist_sq < looping_sq_cull_distance ) { // within cull distance src = calNewSrcAutoLoop( new_entity_index, new_sound_field ); } } } // third phase, perform the actions according to the marks srclink = src_datahead; while( srclink != NULL ) { src = srclink->src; srclink = srclink->next; // before list modification switch( src->loop_mark ) { case lpmk_nonloop: break; case lpmk_start: qalSourcePlay( src->oalSource ); //Snd_DPrintf( 7, "[lpmk_start %s]\n", src->sfx->name ); break; case lpmk_continue: qalGetSourcei( src->oalSource, AL_SOURCE_RELATIVE, &state ); if( state == AL_FALSE ) { // not Listener relative, so update the position and velocity qalGetSourcefv( src->oalSource, AL_POSITION, old_position ); CL_GetEntitySoundOrigin( src->entity_index, new_position ); qalSourcefv( src->oalSource, AL_POSITION, new_position ); dist_sq = calDistanceFromListenerSq( listener_position, new_position ); if( dist_sq > (looping_sq_cull_distance + looping_cull_hysteresis )) { // beyond cull distance w/ some hysteresis // might re-start if it comes inside of cull distance //Snd_DPrintf( 7, "[lpmk_continue culled %s]\n", src->sfx->name); qalSourceStop( src->oalSource ); qalSourcei( src->oalSource, AL_BUFFER, AL_NONE ); calSourceFree( src ); break; } switch( src->velocity_state ) { case velst_nodoppler: break; case velst_update: valid_velocity = calVelocityVector( deltaT, old_position, new_position, velocity ); if( valid_velocity ) { qalSourcefv( src->oalSource, AL_VELOCITY, velocity ); } else { src->velocity_state = velst_init; qalSourcefv( src->oalSource, AL_VELOCITY, zero_velocity ); } break; case velst_init: valid_velocity = calVelocityVector( deltaT, old_position, new_position, velocity ); if( valid_velocity ) { src->velocity_state = velst_update; } break; } } //Snd_DPrintf( 7, "[lpmk_continue %s]\n", src->sfx->name ); break; case lpmk_stop: //Snd_DPrintf( 7, "[lpmk_stop %s]\n", src->sfx->name ); qalSourceStop( src->oalSource ); qalSourcei( src->oalSource, AL_BUFFER, AL_NONE ); calSourceFree( src ); break; default: break; } } } /* == S_Update() Called every frame to update sound system state. == */ void S_Update( vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up ) { src_t *src; srclink_t *srclink; ALint state; ALfloat gain; ALfloat lgain; ALfloat dgain; static int prev_systime = 0; int difftime; ALfloat old_lposition[3]; ALfloat lorientation[6]; ALfloat lvelocity[3]; ALfloat new_origin[3]; ALfloat old_origin[3]; ALfloat velocity[3]; qboolean valid_velocity; if( !sound_system_enable ) { prev_systime = 0; return; } if( prev_systime == 0 ) { // first time prev_systime = Sys_Milliseconds(); return; } difftime = Sys_Milliseconds() - prev_systime; prev_systime += difftime; qalGetError(); // update Listener position, orientation and velocity qalGetListenerfv( AL_POSITION, old_lposition ); lorientation[0] = v_forward[0]; lorientation[1] = v_forward[1]; lorientation[2] = v_forward[2]; lorientation[3] = v_up[0]; lorientation[4] = v_up[1]; lorientation[5] = v_up[2]; qalListenerfv( AL_POSITION, origin ); qalListenerfv( AL_ORIENTATION, lorientation ); valid_velocity = calVelocityVector( difftime, old_lposition, origin, lvelocity ); qalListenerfv( AL_VELOCITY, ( valid_velocity ? lvelocity : zero_velocity ) ); // update listener gain, aka global volume gain = (ALfloat)s_volume->value; gain = ( gain > 1.0f ? 1.0f : ( gain < 0.0f ? 0.0f : gain ) ); // clamp qalGetListenerf( AL_GAIN, &lgain ); dgain = gain - lgain; if( dgain < (ALfloat) -0.05 ) { // turn gain down, qalListenerf( AL_GAIN, gain ); } else if( dgain > 0.05 ) { // turn gain up, incrementally lgain += (ALfloat)0.005f; qalListenerf( AL_GAIN, lgain ); } // do "automatic" looping sounds calUpdateLoopSounds( difftime, origin ); // do other sound updates srclink = src_datahead; while( srclink != NULL ) { src = srclink->src; srclink = srclink->next; // advance pointer before link list is updated if( src->looping ) { // handled above continue; } // delayed start sound effect if( src->start_timer > 0 ) { // delayed start src->start_timer -= difftime; if( src->start_timer <= 5 ) { src->start_timer = 0; if( src->entity_index != 0 && !src->fixed_origin ) { qalGetSourcei( src->oalSource, AL_SOURCE_RELATIVE, &state ); if( state == AL_FALSE ) { // not Listener relative, so update the position CL_GetEntitySoundOrigin( src->entity_index, new_origin ); qalSourcefv( src->oalSource, AL_POSITION, new_origin ); } } qalSourcePlay( src->oalSource ); //Snd_DPrintf( 3, "[Delayed start %s]\n", src->sfx->name); } continue; } // update sounds according to current state qalGetSourcei( src->oalSource, AL_SOURCE_STATE, &state ); switch( state ) { case AL_PLAYING: if( src->stop_timer ) { // stop initiated by SFX with same entnum/CHAN_*/ATTN_* src->stop_timer -= difftime; if( src->stop_timer < 5 ) { //Snd_DPrintf( 3, "[Timed stop %s]\n", src->sfx->name); src->stop_timer = 0; qalSourceStop( src->oalSource ); qalSourcei( src->oalSource, AL_BUFFER, AL_NONE ); calSourceFree( src ); break; } } if( src->fixed_origin ) { // special case, leave position as is break; } qalGetSourcei( src->oalSource, AL_SOURCE_RELATIVE, &state ); if( state == AL_TRUE ) { // 'travels' with listener break; } if( src->entity_index != 0 ) { // there is an entity. update position and velocity qalGetSourcefv( src->oalSource, AL_POSITION, old_origin ); CL_GetEntitySoundOrigin( src->entity_index, new_origin ); qalSourcefv( src->oalSource, AL_POSITION, new_origin ); switch( src->velocity_state ) { case velst_nodoppler: break; case velst_update: valid_velocity = calVelocityVector( difftime, old_origin, new_origin, velocity ); if( valid_velocity ) { qalSourcefv( src->oalSource, AL_VELOCITY, velocity ); } else { // re-initialize src->velocity_state = velst_init; qalSourcefv( src->oalSource, AL_VELOCITY, zero_velocity ); } break; case velst_init: valid_velocity = calVelocityVector( difftime, old_origin, new_origin, velocity ); if( valid_velocity ) { src->velocity_state = velst_update; } break; default: break; } } break; case AL_STOPPED: // has finished playing, free the src //Snd_DPrintf( 3, "[Done playing %s]\n", src->sfx->name); qalSourcei( src->oalSource, AL_BUFFER, AL_NONE ); calSourceFree( src ); break; case AL_INITIAL: case AL_PAUSED: default: break; } } if( music.playing ) { // update per background cvars: enable and volume if( background_music->modified ) { // either on->off or off->on if( background_music->value == 0 ) { // here, turning down probably better than fully shutting down qalSourcef( music.oalSource, AL_GAIN, (ALfloat)0.0f ); } } if ( background_music->value ) { gain = background_music_vol->value; gain = gain < 0.0 ? 0.0 : (gain > 1.0 ? 1.0 : gain ); //clamp qalGetSourcef( music.oalSource, AL_GAIN, &lgain ); dgain = gain - lgain; // difference between setting and current if( dgain < (ALfloat)(-0.05f) ) { // turn gain down to setting qalSourcef( music.oalSource, AL_GAIN, gain ); } else if( dgain > (ALfloat)0.05f ) { // turn gain up, incrementally lgain += (ALfloat)0.005f; qalSourcef( music.oalSource, AL_GAIN, lgain ); } background_music->modified = false; background_music_vol->modified = false; } } if ( s_doppler->modified ) { // for console Doppler factor changes S_UpdateDopplerFactor(); } calErrorCheckAL( __LINE__ ); } /* == S_Play() target of console command: playsounds [.wav] [[.wav]] ... plays all simultaneously, possibly by design, in order to test mixing. changed command from 'play' to 'playsound' to prevent confusion == */ void S_Play( void ) { int ix; char filename[MAX_QPATH]; Com_Printf( "playsound starting..." ); for( ix = 1; ix < Cmd_Argc(); ix++ ) { if( !strrchr( Cmd_Argv( ix ), '.' ) ) { strncpy( filename, Cmd_Argv( ix ), sizeof( filename ) - 5 ); strcat( filename, ".wav" ); } else { strncpy( filename, Cmd_Argv( ix ), sizeof( filename ) - 1 ); } S_StartLocalSound( filename ); } Com_Printf( " use stopsound command to stop.\n" ); } /* == S_SoundInfo_f() target of console command: soundinfo == */ void S_SoundInfo_f( void ) { ALCdevice *pDevice; ALCcontext *pContext; // get current device in current context pContext = qalcGetCurrentContext(); pDevice = qalcGetContextsDevice( pContext ); // dump some info calContextInfo( pDevice ); } /* == S_SoundList() target of console command: soundlist == */ void S_SoundList( void ) { sfxlink_t *sfxlink; sfx_t *sfx = NULL; size_t total = 0; for( sfxlink = sfx_datahead; sfxlink != NULL; sfxlink = sfxlink->next ) { sfx = sfxlink->sfx; if ( !sfx->silent && sfx->registration_sequence ) { if ( sfx->buffered ) { if ( sfx->name[0] == '#') { Com_Printf("(%2db) %10i : %s\n", sfx->byte_width*8, sfx->byte_count, &sfx->name[1]); } else { Com_Printf("(%2db) %10i : sound/%s\n", sfx->byte_width*8, sfx->byte_count, (sfx->aliased ? sfx->truename : sfx->name ) ); } total += sfx->byte_count; } } } Com_Printf ("Total resident: %i\n", total); } /* == S_Activate() Windows only. gain window focus/lose window focus == */ void S_Activate( qboolean active ) { /* TODO: may not be anything to do here. */ Snd_DPrintf( 1, "S_Activate() is a stub.\n" ); } /** == sndCmdInit() sndCmdRemove() sound related console commands == **/ void sndCmdInit( void ) { Cmd_AddCommand( "playsound", S_Play ); Cmd_AddCommand( "stopsound", S_StopAllSounds ); Cmd_AddCommand( "soundlist", S_SoundList ); Cmd_AddCommand( "soundinfo", S_SoundInfo_f ); } void sndCmdRemove( void ) { Cmd_RemoveCommand( "playsound" ); Cmd_RemoveCommand( "stopsound" ); Cmd_RemoveCommand( "soundlist" ); Cmd_RemoveCommand( "soundinfo" ); } /* == sndCvarInit() sound related console variables for OpenAL The following cvar's are not implemented in this version s_khz, s_loadas8bit, s_mixahead, s_show, s_testsound, s_primary == */ void sndCvarInit( void ) { char cvarset[16]; s_initsound = Cvar_Get( "s_initsound", "1", 0 ); s_volume = Cvar_Get( "s_volume", "0.1", CVAR_ARCHIVE ); // OpenAL CVARs s_doppler = Cvar_Get( "s_doppler", "0.0", CVAR_ARCHIVE ); Com_sprintf(cvarset, sizeof(cvarset),"%i", MAX_SRC_DEFAULT ); s_maxsources = Cvar_Get( "s_maxsources", cvarset , CVAR_ARCHIVE ); Com_sprintf(cvarset, sizeof(cvarset),"%i", MIN_SRC_DEFAULT ); s_minsources = Cvar_Get( "s_minsources", cvarset, CVAR_ARCHIVE ); s_device = Cvar_Get( "s_device", "Default", CVAR_ARCHIVE ); // for debug snd_developer = Cvar_Get( "snd_developer", "0", 0); } alien-arena-7.66+dfsg/source/client/cl_fx.c0000600000175000017500000025273712161402010017637 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // cl_fx.c -- entity effects parsing and management #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "client.h" #include "ref_gl/r_image.h" #include "ref_gl/qgl.h" extern particle_t particles[MAX_PARTICLES]; extern int cl_numparticles; extern cvar_t *vid_ref; extern void MakeNormalVectors (vec3_t forward, vec3_t right, vec3_t up); void CL_LogoutEffect (vec3_t org, int type); void CL_ItemRespawnParticles (vec3_t org); void CL_TeleportParticles (vec3_t start); static vec3_t avelocities [NUMVERTEXNORMALS]; /* ============================================================== LIGHT STYLE MANAGEMENT ============================================================== */ typedef struct { int length; float value[3]; float map[MAX_QPATH]; } clightstyle_t; clightstyle_t cl_lightstyle[MAX_LIGHTSTYLES]; int lastofs; /* ================ CL_ClearLightStyles ================ */ void CL_ClearLightStyles (void) { memset (cl_lightstyle, 0, sizeof(cl_lightstyle)); lastofs = -1; } /* ================ CL_RunLightStyles ================ */ void CL_RunLightStyles (void) { int ofs; int i; clightstyle_t *ls; ofs = cl.time / 25; if (ofs == lastofs) return; lastofs = ofs; for (i=0,ls=cl_lightstyle ; ilength || !cl_flicker->integer) { ls->value[0] = ls->value[1] = ls->value[2] = 1.0; continue; } if (ls->length == 1) ls->value[0] = ls->value[1] = ls->value[2] = ls->map[0]; else { // nonlinear interpolation of the lightstyles for smoothness while // still preserving some "jaggedness" float a, b, dist; a = ls->map[(ofs/4)%ls->length]; b = ls->map[(ofs/4+1)%ls->length]; dist = (float)(ofs%4)/4.0f; if (dist != 0.75) dist = 0; ls->value[0] = ls->value[1] = ls->value[2] = a+(b-a)*dist; } } } void CL_SetLightstyle (int i) { char *s; int j, k; s = cl.configstrings[i+CS_LIGHTS]; j = strlen (s); if (j >= MAX_QPATH) Com_Error (ERR_DROP, "svc_lightstyle length=%i", j); cl_lightstyle[i].length = j; for (k=0 ; kvalue[0], ls->value[1], ls->value[2]); } /* ============================================================== DLIGHT MANAGEMENT ============================================================== */ cdlight_t cl_dlights[MAX_DLIGHTS]; /* ================ CL_ClearDlights ================ */ void CL_ClearDlights (void) { memset (cl_dlights, 0, sizeof(cl_dlights)); } /* =============== CL_AllocDlight =============== */ cdlight_t *CL_AllocDlight (int key) { int i; cdlight_t *dl; // first look for an exact key match if (key) { dl = cl_dlights; for (i=0 ; ikey == key) { memset (dl, 0, sizeof(*dl)); dl->key = key; return dl; } } } // then look for anything else dl = cl_dlights; for (i=0 ; idie < cl.time) { memset (dl, 0, sizeof(*dl)); dl->key = key; return dl; } } dl = &cl_dlights[0]; memset (dl, 0, sizeof(*dl)); dl->key = key; return dl; } /* =============== CL_NewDlight =============== */ void CL_NewDlight (int key, float x, float y, float z, float radius, float time) { cdlight_t *dl; dl = CL_AllocDlight (key); dl->origin[0] = x; dl->origin[1] = y; dl->origin[2] = z; dl->radius = radius; dl->die = cl.time + time; } /* =============== CL_RunDLights =============== */ void CL_RunDLights (void) { int i; cdlight_t *dl; dl = cl_dlights; for (i=0 ; iradius) continue; if (dl->die < cl.time) { dl->radius = 0; return; } dl->radius -= cls.frametime*dl->decay; if (dl->radius < 0) dl->radius = 0; } } void RotateForNormal(vec3_t normal, vec3_t result){ float forward, pitch, yaw; forward = sqrt(normal[0] * normal[0] + normal[1] * normal[1]); pitch = (int)(atan2(normal[2], forward) * 180 / M_PI); yaw = (int)(atan2(normal[1], normal[0]) * 180 / M_PI); if(pitch < 0) pitch += 360; result[PITCH] = -pitch; result[YAW] = yaw; } void vectoanglerolled (vec3_t value1, float angleyaw, vec3_t angles) { float forward, yaw, pitch; yaw = (int) (atan2(value1[1], value1[0]) * 180 / M_PI); forward = sqrt (value1[0]*value1[0] + value1[1]*value1[1]); pitch = (int) (atan2(value1[2], forward) * 180 / M_PI); if (pitch < 0) pitch += 360; angles[PITCH] = -pitch; angles[YAW] = yaw; angles[ROLL] = -angleyaw; } /* ============== CL_ParseMuzzleFlash ============== */ void CL_ParseMuzzleFlash (void) { vec3_t fv, rv, shell_brass, dir, up; cdlight_t *dl; int i, j, weapon; centity_t *pl; int silenced; float volume; char soundname[64]; i = MSG_ReadShort (&net_message); if (i < 1 || i >= MAX_EDICTS) Com_Error (ERR_DROP, "CL_ParseMuzzleFlash: bad entity"); weapon = MSG_ReadByte (&net_message); silenced = weapon & MZ_SILENCED; weapon &= ~MZ_SILENCED; pl = &cl_entities[i]; dl = CL_AllocDlight (i); VectorCopy (pl->current.origin, dl->origin); AngleVectors (pl->current.angles, fv, rv, up); VectorMA (dl->origin, 18, fv, dl->origin); VectorMA (dl->origin, 16, rv, dl->origin); if (silenced) dl->radius = 100 + (rand()&31); else dl->radius = 200 + (rand()&31); dl->minlight = 32; dl->die = cl.time; // + 0.1; if (silenced) volume = 0.2; else volume = 1; VectorMA(pl->current.origin, 10, fv, shell_brass); VectorMA(shell_brass, 6, rv, shell_brass); VectorMA(shell_brass, 21, up, shell_brass); for (j = 0; j < 3; j++) dir[j] = fv[j] + rv[j] + up[j] * 2; // NOTE: sounds started here are subject to PVS rather than PHS // which results in these sounds not being heard when others // in same location can be heard switch (weapon) { case MZ_BLASTER: dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/blastf1a.wav"), volume, ATTN_NORM, 0); break; case MZ_HYPERBLASTER: dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/hyprbf1a.wav"), volume, ATTN_NORM, 0); break; case MZ_MACHINEGUN: dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0); break; case MZ_SHOTGUN: dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/shotgf1b.wav"), volume, ATTN_NORM, 0); //[no file] S_StartSound (NULL, i, CHAN_AUTO, S_RegisterSound("weapons/shotgr1b.wav"), volume, ATTN_NORM, 0.1); break; case MZ_SSHOTGUN: dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/sshotf1b.wav"), volume, ATTN_NORM, 0); break; case MZ_CHAINGUN1: dl->radius = 200 + (rand()&31); dl->color[0] = 1;dl->color[1] = 0.25;dl->color[2] = 0; Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0); CL_BrassShells(shell_brass, dir, 1); break; case MZ_CHAINGUN2: dl->radius = 225 + (rand()&31); dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0; dl->die = cl.time + 0.1; // long delay Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0); Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0.05); CL_BrassShells(shell_brass, dir, 1); break; case MZ_CHAINGUN3: dl->radius = 250 + (rand()&31); dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; dl->die = cl.time + 0.1; // long delay Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0); Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0.033); Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0.066); CL_BrassShells(shell_brass, dir, 1); break; case MZ_RAILGUN: dl->color[0] = 0.5;dl->color[1] = 0.5;dl->color[2] = 1.0; // S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/railgf1a.wav"), volume, ATTN_NORM, 0); break; case MZ_ROCKET: dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0.2; S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/rocklf1a.wav"), volume, ATTN_NORM, 0); S_StartSound (NULL, i, CHAN_AUTO, S_RegisterSound("weapons/rocklr1b.wav"), volume, ATTN_NORM, 0.1); break; case MZ_GRENADE: dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0; S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/grenlf1a.wav"), volume, ATTN_NORM, 0); S_StartSound (NULL, i, CHAN_AUTO, S_RegisterSound("weapons/grenlr1b.wav"), volume, ATTN_NORM, 0.1); break; case MZ_BFG: dl->color[0] = 0;dl->color[1] = 1;dl->color[2] = 0; S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/bfg__f1y.wav"), volume, ATTN_NORM, 0); break; case MZ_LOGIN: dl->color[0] = 0;dl->color[1] = 1; dl->color[2] = 0; dl->die = cl.time + 1.0; S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/grenlf1a.wav"), 1, ATTN_NORM, 0); //CL_LogoutEffect (pl->current.origin, weapon); CL_TeleportParticles (pl->current.origin); break; case MZ_LOGOUT: dl->color[0] = 1;dl->color[1] = 0; dl->color[2] = 0; dl->die = cl.time + 1.0; S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/grenlf1a.wav"), 1, ATTN_NORM, 0); CL_LogoutEffect (pl->current.origin, weapon); break; case MZ_RESPAWN: dl->color[0] = 1;dl->color[1] = 1; dl->color[2] = 0; dl->die = cl.time + 1.0; S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/grenlf1a.wav"), 1, ATTN_NORM, 0); CL_LogoutEffect (pl->current.origin, weapon); break; } } /* =============== CL_AddDLights =============== */ void CL_AddDLights (void) { int i; cdlight_t *dl; dl = cl_dlights; //===== //PGM for (i=0 ; iradius) continue; V_AddLight (dl->origin, dl->radius, dl->color[0], dl->color[1], dl->color[2]); } //PGM //===== } /* ============================================================== PARTICLE MANAGEMENT ============================================================== */ particle_t *active_particles, *free_particles; particle_t particles[MAX_PARTICLES]; int cl_numparticles = MAX_PARTICLES; void addParticleLight (particle_t *p, float light, float lightvel, float lcol0, float lcol1, float lcol2) { int i; for (i=0; ilights[i]; if (!plight->isactive) { plight->isactive = true; plight->light = light; plight->lightvel = lightvel; plight->lightcol[0] = lcol0; plight->lightcol[1] = lcol1; plight->lightcol[2] = lcol2; return; } } } /* =============== CL_ClearParticles =============== */ /* Cl_ClearParticle */ void CL_ClearParticles (void) { int i; free_particles = &particles[0]; active_particles = NULL; for (i=0 ;inext; p->next = active_particles; p->type = 0; p->image = NULL; p->blenddst = 0; p->blendsrc = 0; p->scalevel = 0; p->time = cl.time; for(j=0; j<3; j++) p->angle[j]=0; for (j=0;jlights[j]; plight->isactive = false; plight->light = 0; plight->lightvel = 0; plight->lightcol[0] = 0; plight->lightcol[1] = 0; plight->lightcol[2] = 0; } p->fromsustainedeffect = false; p->chain_prev = NULL; return (active_particles = p); } float getColor(void) { float color; switch(cl_disbeamclr->integer) { case 0: default: color = 0xd6; //bright green break; case 1: color = 0x74; //blue break; case 2: color = 0x40; //red break; case 3: color = 0xe0; //yellow break; case 4: color = 0xff; //purple break; } return color; } void getColorvec(vec3_t colorvec) { switch(cl_disbeamclr->integer) { case 0: default: colorvec[0] = 0; //bright green colorvec[1] = 1; colorvec[2] = 0.6; break; case 1: colorvec[0] = 0; //blue colorvec[1] = 0.5; colorvec[2] = 0.7; break; case 2: colorvec[0] = 0.6; //red colorvec[1] = 0; colorvec[2] = 0; break; case 3: colorvec[0] = 0.7; //yellow colorvec[1] = 0.7; colorvec[2] = 0; break; case 4: colorvec[0] = 0.7; //purple colorvec[1] = 0; colorvec[2] = 0.7; break; } } /* =============== CL_ParticleEffect Wall impact puffs =============== */ void CL_ParticleEffect (vec3_t org, vec3_t dir, int color, int count) { int i, j; particle_t *p; float d; if((color == 450 || color == 550) && cl_noblood->value) return; for (i=0 ; iorg[j] = org[j] + ((rand()&7)-4) + d*dir[j]; p->vel[j] = crand()*50; } p->accel[0] = p->accel[1] = 0; p->accel[2] = -PARTICLE_GRAVITY; if (color == 425) // gunshots: FIXME should be using type { p->type = PARTICLE_STANDARD; p->image = r_pufftexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE_MINUS_SRC_ALPHA; p->scale = 4 + (rand()&2); p->scalevel = 0; p->alpha = 0.2; p->alphavel = -1.0 / (1.5 + frand()*0.3); p->accel[2] = PARTICLE_GRAVITY; } else if (color == 450) { p->type = PARTICLE_STANDARD; p->image = r_bloodtexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE_MINUS_SRC_ALPHA; p->alpha = 0.2; p->alphavel = -1.0 / (4.5 + frand()*0.3); p->color = 0xe8; p->scale = 6; p->scalevel = 0; } else if (color == 550) { p->type = PARTICLE_STANDARD; p->image = r_bloodtexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE_MINUS_SRC_ALPHA; p->alpha = 0.2; p->alphavel = -1.0 / (4.5 + frand()*0.3); p->color = 0xd0 + (rand()&3); p->scale = 6; p->scalevel = 0; } else { p->type = PARTICLE_NONE; p->image = r_particletexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->scale = 1; p->scalevel = 0; p->alpha = 1.0; p->color = color; p->alphavel = -1.0 / (0.5 + frand()*0.3); } } } /* =============== CL_ParticleEffect2 =============== */ void CL_ParticleEffect2 (vec3_t org, vec3_t dir, int color, int count) { int i, j; particle_t *p; float d; for (i=0 ; itype = PARTICLE_STANDARD; p->image = r_particletexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->scale = 1; p->scalevel = 0; p->color = color; d = rand()&7; for (j=0 ; j<3 ; j++) { p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j]; p->vel[j] = crand()*20; } p->accel[0] = p->accel[1] = 0; p->accel[2] = -PARTICLE_GRAVITY; p->alpha = 1.0; p->alphavel = -1.0 / (0.5 + frand()*0.3); } } /* =============== CL_BulletSparks =============== */ void CL_BulletSparks (vec3_t org, vec3_t dir) { int i, j, k; float inc, scale, nudge; particle_t *p; particle_t *pr; particle_t *center; for( i=0; i<3; i++) { nudge = frand(); if(nudge < 0.5) dir[i] += frand(); else dir[i] -= frand(); } //draw a fatter glow at the impact point if(!(p = new_particle())) return; p->type = PARTICLE_STANDARD; p->image = r_particletexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->scale = 1; p->scalevel = 0; p->color = 0xe0 + (rand()&2); for (j=0 ; j<3 ; j++) { p->org[j] = org[j]; p->vel[j] = 0; } p->accel[0] = p->accel[1] = p->accel[2] = 0; p->alpha = .5; p->alphavel = -1.0 / (3 + frand()*0.3); center = p; //shoot off sparks VectorNormalize(dir); for( k=0; k<2; k++) { scale = frand()*3.0; pr = NULL; i = 0; for (inc=1.0 ; inc<2.0 ; inc+=0.25, i++) { if (!(p = new_particle())) return; p->color = 0xe0 + (rand()&2); p->type = PARTICLE_CHAINED; p->image = r_raintexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->scale = 1.25*scale/inc; p->scalevel = 0; for (j=0 ; j<3 ; j++) { p->org[j] = org[j] + i*(-1.25*scale)*dir[j]; p->vel[j] = 60*dir[j]; } p->accel[0] = 0; p->accel[1] = 0; p->accel[2] = -(PARTICLE_GRAVITY)/(.5*inc); p->alpha = .5; p->alphavel = -1.0 / (2.5 + frand()*0.3); if (pr) { p->chain_prev = pr; } pr = p; } } } /* =============== CL_SplashEffect =============== */ void CL_SplashEffect (vec3_t org, vec3_t dir, int color, int count) { int i, j, k; float scale, nudge; particle_t *p; vec3_t angle; //draw rings that expand outward if(!(p = new_particle())) return; p->type = PARTICLE_RAISEDDECAL; p->image = r_splashtexture; p->blendsrc = GL_DST_COLOR; p->blenddst = GL_SRC_COLOR; p->scale = 1; p->scalevel = 8; p->color = 0 + (rand() & 1); VectorScale(dir, -1, angle); RotateForNormal(angle, p->angle); p->angle[ROLL] = rand() % 360; VectorAdd(org, dir, p->org); for (j=0 ; j<3 ; j++) { p->org[j] = org[j]; p->vel[j] = 0; } p->accel[0] = p->accel[1] = p->accel[2] = 0; p->alpha = .1; p->alphavel = -0.1 / (1 + frand()*0.3); for( k=0; kcolor = color - (rand()&2); p->type = PARTICLE_VERT; p->image = r_splash2texture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->scale = 4*(rand()&8); p->scalevel = 2; for (j=0; j<3; j++) { p->org[j] = org[j] + 10*dir[j]; p->vel[j] = 60*dir[j]; } p->org[2]+=32; p->accel[0] = 0; p->accel[1] = 0; p->accel[2] = -(PARTICLE_GRAVITY)/0.5; p->alpha = .5; p->alphavel = -1.0 / (1.5 + frand()*0.3); } } } /* =============== CL_LaserSparks =============== */ void CL_LaserSparks (vec3_t org, vec3_t dir, int color, int count) { int i, j, k; float inc, scale, nudge; particle_t *p; for( i=0; i<3; i++) { nudge = frand(); if(nudge < 0.5) dir[i] += frand(); else dir[i] -= frand(); } //shoot off sparks for( k=0; k<2; k++) { VectorNormalize(dir); scale = frand(); i = 0; for (inc=1.0 ; inc<2.0 ; inc+=0.1, i++) { if (!(p = new_particle())) return; p->color = color + (rand()&2); p->type = PARTICLE_STANDARD; p->image = r_particletexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->scale = 1.5*scale/inc; p->scalevel = 0; for (j=0 ; j<3 ; j++) { p->org[j] = org[j] + i*(-1.5*scale)*dir[j]; p->vel[j] = 60*dir[j]; } p->accel[0] = 0; p->accel[1] = 0; p->accel[2] = -(PARTICLE_GRAVITY)/(.5*inc); p->alpha = .5; p->alphavel = -1.0 / (1.5 + frand()*0.3); } } } /* =============== CL_LogoutEffect =============== */ void CL_LogoutEffect (vec3_t org, int type) { int i, j; particle_t *p; for (i=0 ; i<500 ; i++) { if (!(p = new_particle())) return; p->type = PARTICLE_STANDARD; p->scale = 1; p->image = r_particletexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; if (type == MZ_LOGIN) p->color = 0xd0 + (rand()&7); // green else if (type == MZ_LOGOUT) p->color = 0x40 + (rand()&7); // red else p->color = 0xe0 + (rand()&7); // yellow p->org[0] = org[0] - 16 + frand()*32; p->org[1] = org[1] - 16 + frand()*32; p->org[2] = org[2] - 24 + frand()*56; for (j=0 ; j<3 ; j++) p->vel[j] = crand()*20; p->accel[0] = p->accel[1] = 0; p->accel[2] = -PARTICLE_GRAVITY; p->alpha = 1.0; p->alphavel = -1.0 / (1.0 + frand()*0.3); } } /* =============== CL_ItemRespawnParticles =============== */ void CL_ItemRespawnParticles (vec3_t org) { int i, j; particle_t *p; for (i=0 ; i<64 ; i++) { if (!(p = new_particle())) return; p->color = 0x74 + (rand()&7); p->scale = 12 + (rand()&7) ; p->scalevel = 0; p->type = PARTICLE_STANDARD; p->image = r_explosiontexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->org[0] = org[0] + crand()*16; p->org[1] = org[1] + crand()*16; p->org[2] = org[2] + crand()*16; for (j=0 ; j<3 ; j++) p->vel[j] = crand()*8; p->accel[0] = p->accel[1] = 0; p->accel[2] = -PARTICLE_GRAVITY*0.2; p->alpha = .3; p->alphavel = -1.0 / (1.0 + frand()*0.3); if (i < 4) addParticleLight (p, p->scale*30, 10, 0, 1, 1); } } /* =============== CL_ExplosionParticles - new version - =============== */ extern int r_drawing_fbeffect; extern int r_fbFxType; extern float r_fbeffectTime; extern vec3_t r_explosionOrigin; extern float rs_realtime; void CL_ExplosionParticles (vec3_t org) { int i, j, k; particle_t *p; //for glsl framebuffer distortion effects if(!r_drawing_fbeffect && cl_explosiondist->value) { r_fbFxType = 1; //EXPLOSION r_drawing_fbeffect = true; VectorCopy(org, r_explosionOrigin); r_fbeffectTime = rs_realtime; } for (i=0 ; i<7; i++) { for (k = 0; k<(12-i); k++) { if (!(p = new_particle())) return; for (j=0 ; j<3 ; j++) { p->org[j] = org[j] + ((rand()%16)-8); p->vel[j] = 0; } p->type = PARTICLE_STANDARD; p->accel[0] = p->accel[1] = p->accel[2] = 0; p->alpha = 0.2; p->scale = 6; p->scalevel = 52; p->color = 0xd9 + (rand()&7); p->alphavel = -1.0 / (1 + i + k/5); p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; switch(i) { case 0: p->image = r_explosion1texture; break; case 1: p->image = r_explosion2texture; break; case 2: p->image = r_explosion3texture; break; case 3: p->image = r_explosion4texture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE_MINUS_SRC_ALPHA; break; case 4: p->image = r_explosion5texture; break; case 5: p->image = r_explosion6texture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; break; case 6: p->image = r_explosion7texture; break; default: p->image = r_explosion1texture; break; } if (p && i < 4) addParticleLight (p, p->scale*50*i, 0, .4, .4, 0.1); } } //place a big shock wave effect if (!(p = new_particle())) return; p->alpha = 1.0; p->alphavel = -2.0; p->type = PARTICLE_FLAT; p->image = r_explosion5texture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->color = 0xd9 + (rand()&7); p->scale = 12 + (rand()&4) ; p->scalevel = 100; for(j = 0; j < 3; j++) { p->org[j] = org[j]; p->vel[j] = 0; p->accel[j] = 0; } //add smoke for (i=0 ; i<7; i++) { if (!(p = new_particle())) return; for (j=0 ; j<3 ; j++) { p->org[j] = org[j] + ((rand()%32)-16); p->vel[j] = 0; } p->type = PARTICLE_STANDARD; p->accel[0] = p->accel[1] = p->accel[2] = 0; p->alpha = 0.2; p->alphavel = -2.0 / (30+frand()*1.4); //smoke lingers longer p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE_MINUS_SRC_ALPHA; p->scale = 1 + (rand()&4); p->scalevel = 12.0; p->color = 1 + (rand()&10); p->accel[2] = 10; p->image = r_smoketexture; } } /* =============== CL_MuzzleParticles - changed this to a smoke effect in 6.06 =============== */ void CL_MuzzleParticles (vec3_t org) { int i, j; particle_t *p; for ( i = 0; i < 4; i++) { if (!(p = new_particle())) return; for (j=0 ; j<3 ; j++) { p->org[j] = org[j] + crand()*1; p->vel[j] = crand()*5; } p->alphavel = -1.0 / (30+frand()*1.4); //smoke lingers longer p->alpha = .07; p->type = PARTICLE_STANDARD; p->image = r_smoketexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE_MINUS_SRC_ALPHA; p->scale = 1 + (rand()&4); p->scalevel = 12.0; p->color = 15; p->accel[2] = 20; } } /* =============== CL_MuzzleParticles - Blue =============== */ void CL_BlueMuzzleParticles (vec3_t org) { int i, j; particle_t *p; for ( i = 0; i < 4; i++) { if (!(p = new_particle())) return; p->type = PARTICLE_STANDARD; p->image = r_cflashtexture; p->scale = 16 + (rand()&7); p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; for (j=0 ; j<3 ; j++) { p->org[j] = org[j] + ((rand()%2)-1); p->vel[j] = 0; } p->accel[0] = p->accel[1] = 0; p->accel[2] = 0; p->alpha = 0.4; p->color = 0x74; p->alphavel = -2.8 / (0.5 + frand()*0.3); } } /* =============== CL_MuzzleFlashParticle =============== */ extern cvar_t *r_lefthand; void CL_MuzzleFlashParticle (vec3_t org, vec3_t angles, qboolean from_client) { int j; particle_t *p; vec3_t mflashorg, vforward, vright, vup, vec; float rightoffset, len; if(!from_client) { VectorSubtract (org, cl.refdef.vieworg, vec); len = VectorNormalize (vec); if(len < 128) return; } VectorCopy(org, mflashorg); for (j=0 ; j<3 ; j++) { mflashorg[j] = mflashorg[j] + ((rand()%2)-1); } if(from_client) { AngleVectors (angles, vforward, vright, vup); if (r_lefthand->value == 1.0F) rightoffset = -2.4; else rightoffset = 2.4; VectorMA(mflashorg, 24, vforward, mflashorg); VectorMA(mflashorg, rightoffset, vright, mflashorg); VectorMA(mflashorg, -2.5, vup, mflashorg); } if (!(p = new_particle())) return; p->type = PARTICLE_STANDARD; p->image = r_bflashtexture; p->scale = 7 + (rand()&4); p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; for (j=0 ; j<3 ; j++) { p->org[j] = mflashorg[j]; p->vel[j] = 0; } p->accel[0] = p->accel[1] = 0; p->accel[2] = 0; p->alpha = 0.8; p->color = 0xd9; p->alphavel = -100; } void CL_PlasmaFlashParticle (vec3_t org, vec3_t angles, qboolean from_client) { int i, j; particle_t *p; vec3_t mflashorg, vforward, vright, vup, vec; float rightoffset, len, color; if(!from_client) { VectorSubtract (org, cl.refdef.vieworg, vec); len = VectorNormalize (vec); if(len < 128) return; } VectorCopy(org, mflashorg); for (j=0 ; j<3 ; j++) { mflashorg[j] = mflashorg[j] + ((rand()%2)-1); } if(from_client) { AngleVectors (angles, vforward, vright, vup); if (r_lefthand->value == 1.0F) rightoffset = -4.4; else rightoffset = 4.4; VectorMA(mflashorg, 24, vforward, mflashorg); VectorMA(mflashorg, rightoffset, vright, mflashorg); VectorMA(mflashorg, -4.5, vup, mflashorg); } //muzzleflash color = getColor(); for(i = 0; i < 3; i++) { if (!(p = new_particle())) return; p->alpha = 0.4; p->alphavel = -2.8 / (0.6+frand()*0.2); p->blenddst = GL_ONE; p->blendsrc = GL_SRC_ALPHA; p->image = r_cflashtexture; p->scale = 20/(i+1); p->type = PARTICLE_STANDARD; p->scalevel = 12; p->color = color; for (j=0 ; j<3 ; j++) { p->org[j] = mflashorg[j]; p->vel[j] = 0; p->accel[j] = 0; } } } /* =============== CL_SmartMuzzle =============== */ void CL_SmartMuzzle (vec3_t org) { int i, j; particle_t *p; for ( i = 0; i < 3; i++) { if (!(p = new_particle())) return; p->type = PARTICLE_STANDARD; p->image = r_leaderfieldtexture; p->scale = 24 + (rand()&2); p->color = 0xff; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; for (j=0 ; j<3 ; j++) { p->org[j] = org[j] + ((rand()%2)-1); p->vel[j] = 0; } p->accel[0] = p->accel[1] = 0; p->accel[2] = 0; p->alpha = 0.7; p->alphavel = -2.8 / (0.5 + frand()*0.3); } } /* =============== CL_SmartMuzzle =============== */ void CL_Voltage (vec3_t org) { int i, j; particle_t *p; for ( i = 0; i < 3; i++) { if (!(p = new_particle())) return; p->type = PARTICLE_STANDARD; p->image = r_voltagetexture; p->scale = 14 + (rand()&14); p->color = 0xff; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; for (j=0 ; j<3 ; j++) { p->org[j] = org[j] + ((rand()%2)-1); p->vel[j] = 0; } p->accel[0] = p->accel[1] = 0; p->accel[2] = 0; p->alpha = 0.7; p->alphavel = -2.8 / (0.5 + frand()*0.3); } } /* =============== CL_Deathfield =============== */ void CL_Deathfield (vec3_t org, int type) { int j; particle_t *p; if (!(p = new_particle())) return; p->type = PARTICLE_STANDARD; if(type) p->image = r_deathfieldtexture2; else p->image = r_deathfieldtexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; for (j=0 ; j<3 ; j++) { p->org[j] = org[j] + ((rand()%2)-1); p->vel[j] = 0; } p->accel[0] = p->accel[1] = 0; p->accel[2] = 0; p->alpha = 1.5; p->scale = 10 + (rand()&2); p->scalevel = 12; p->color = 0x72; p->accel[0] = p->accel[1] = 0; p->accel[2] = PARTICLE_GRAVITY; p->alphavel = -1.28 / (2.0 + frand()*0.3); } /* =============== CL_SayIcon Displays an icon above a player when talking =============== */ void CL_SayIcon(vec3_t org) { particle_t *p; int j; if(!(p = new_particle())) return; p->type = PARTICLE_STANDARD; p->image = r_sayicontexture; p->scale = 5; p->scalevel = 0; p->color = 15; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE_MINUS_SRC_ALPHA; for(j=0; j<3; j++) { p->org[j] = org[j]; p->vel[j] = 0; p->accel[j] = 0; } p->org[2]+=40; p->alpha = 0.9; p->alphavel = -0.5; } /* =============== CL_DustParticles =============== */ void CL_DustParticles (vec3_t org) { int i, j; particle_t *p; for (i=0 ; i<64 ; i++) { if (!(p = new_particle())) return; p->type = PARTICLE_STANDARD; p->image = r_pufftexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE_MINUS_SRC_ALPHA; p->scale = 4 + (rand()&2); p->color = 15; p->scalevel = 1.5; for (j=0 ; j<3 ; j++) { p->org[j] = org[j] + ((rand()%4)-2); p->vel[j] = (rand()%88)-44; } p->accel[0] = p->accel[1] = 0; p->accel[2] = -PARTICLE_GRAVITY; p->alpha = 0.5; p->alphavel = -0.8 / (0.5 + frand()*0.3); } } /* =============== CL_BigTeleportParticles =============== */ void CL_BigTeleportParticles (vec3_t org) { int i, j; particle_t *p; for (i=1 ; i<3 ; i++) { if (!(p = new_particle())) return; if(i == 1) p->type = PARTICLE_ROTATINGROLL; else p->type = PARTICLE_STANDARD; p->image = r_leaderfieldtexture; p->scale = 16*i + (rand()&7); p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; if(i>1) p->color = 0xd4; else p->color = 0x74; p->scalevel = 30; for (j=0 ; j<3 ; j++) { p->org[j] = org[j]; p->vel[j] = 0; } p->accel[0] = p->accel[1] = 0; p->accel[2] = 0; p->alpha = 0.5; p->alphavel = -0.9 / (0.5 + frand()*0.3); addParticleLight (p, p->scale*(2+(rand()&5)), 0, 0, .6, 0.4); } } /* =============== CL_HealthParticles =============== */ void CL_SmallHealthParticles (vec3_t org) { particle_t *p; float angle, dist; if (!(p = new_particle())) return; p->type = PARTICLE_STANDARD; p->image = r_cflashtexture; p->scale = 10 + (rand()&7); p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->color = 0xd4 + (rand() & 1); angle = M_PI*2*(rand()&1023)/1023.0; dist = rand()&5; p->org[0] = org[0] + cos(angle)*dist; p->vel[0] = cos(angle)*(6+(rand()&6)); p->accel[0] = -cos(angle)*6; p->org[1] = org[1] + sin(angle)*dist; p->vel[1] = sin(angle)*(6+(rand()&6)); p->accel[1] = -sin(angle)*100; p->org[2] = org[2] + 8 + (rand()%10); p->vel[2] = -10 + (rand()&6); p->accel[2] = PARTICLE_GRAVITY*10; p->alpha = 0.2; p->alphavel = -2.6 / (0.5 + frand()*0.3); } void CL_MedHealthParticles (vec3_t org) { particle_t *p; float angle, dist; if (!(p = new_particle())) return; p->type = PARTICLE_STANDARD; p->image = r_cflashtexture; p->scale = 10 + (rand()&7); p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->color = 0x74 + (rand() & 1); angle = M_PI*2*(rand()&1023)/1023.0; dist = rand()&5; p->org[0] = org[0] + cos(angle)*dist; p->vel[0] = cos(angle)*(6+(rand()&6)); p->accel[0] = -cos(angle)*6; p->org[1] = org[1] + sin(angle)*dist; p->vel[1] = sin(angle)*(6+(rand()&6)); p->accel[1] = -sin(angle)*100; p->org[2] = org[2] + 8 + (rand()%10); p->vel[2] = -10 + (rand()&6); p->accel[2] = PARTICLE_GRAVITY*10; p->alpha = 0.3; p->alphavel = -2.6 / (0.5 + frand()*0.3); } void CL_LargeHealthParticles (vec3_t org) { particle_t *p; float angle, dist; if (!(p = new_particle())) return; p->type = PARTICLE_STANDARD; p->image = r_cflashtexture; p->scale = 10 + (rand()&7); p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->color = 0xff + (rand() & 1); angle = M_PI*2*(rand()&1023)/1023.0; dist = rand()&5; p->org[0] = org[0] + cos(angle)*dist; p->vel[0] = cos(angle)*(6+(rand()&6)); p->accel[0] = -cos(angle)*6; p->org[1] = org[1] + sin(angle)*dist; p->vel[1] = sin(angle)*(6+(rand()&6)); p->accel[1] = -sin(angle)*100; p->org[2] = org[2] + 8 + (rand()%10); p->vel[2] = -10 + (rand()&6); p->accel[2] = PARTICLE_GRAVITY*10; p->alpha = 0.3; p->alphavel = -2.6 / (0.5 + frand()*0.3); } /* =============== CL_BlasterParticles Wall impact puffs for standard blaster. =============== */ void CL_BlasterParticles (vec3_t org, vec3_t dir) { int i, j; particle_t *p; float d; for (i=0 ; i<16 ; i++) { if (!(p = new_particle())) return; p->type = PARTICLE_STANDARD; p->image = r_cflashtexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->color = 0x74; p->scale = (.75 * (i+1)) + (rand()&2); p->scalevel = 12; d = rand()&7; for (j=0 ; j<3 ; j++) { p->org[j] = org[j] + d*dir[j]; p->vel[j] = 0; p->accel[j] = 0; } p->alpha = 0.3; p->alphavel = -8.8 / ((i*2) + frand()*0.3); if (i > 4) addParticleLight (p, p->scale*25, 50, 0, .8, 1); } } /* =============== CL_BlasterBall =============== */ void CL_BlasterBall (vec3_t start, vec3_t end) { vec3_t move; vec3_t vec; float len; int j; particle_t *p; VectorCopy (start, move); VectorSubtract (end, start, vec); len = VectorNormalize (vec); VectorScale (vec, 5, vec); if (!(p = new_particle())) return; p->alpha = 1; p->alphavel = INSTANT_PARTICLE; p->type = PARTICLE_ROTATINGROLL; p->image = r_shottexture; p->scale = 8; p->angle[1] = cl.refdef.viewangles[0]; p->angle[0] = sin(len); p->angle[2] = cl.refdef.viewangles[2]; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->color = 0x72; for (j=0 ; j<3 ; j++) { p->org[j] = move[j]; p->vel[j] = 0; p->accel[j] = 0; } if (!(p = new_particle())) return; p->alpha = .95; p->alphavel = INSTANT_PARTICLE; p->type = PARTICLE_STANDARD; p->image = r_cflashtexture; p->scale = 15+5*frand(); p->blendsrc = GL_ONE; p->blenddst = GL_ONE; p->color = 0x79; for (j=0 ; j<3 ; j++) { p->org[j] = move[j]; p->vel[j] = 0; p->accel[j] = 0; } } /* =============== Team Lights =============== */ void CL_BlueTeamLight(vec3_t pos) { int i,j; particle_t *p; if(!server_is_team && !cl_dmlights->value) return; for(i=1; i<3; i++) { if (!(p = new_particle())) return; VectorClear (p->accel); p->alpha = .7; p->type = PARTICLE_STANDARD; p->image = r_flaretexture; p->blendsrc = GL_ONE; p->blenddst = GL_ONE; if (server_is_team) p->color = 0x74; else p->color = 0xd3; p->scale = 10*i; p->alphavel = INSTANT_PARTICLE; for (j=0 ; j<3 ; j++) { p->org[j] = pos[j]; p->vel[j] = 0; p->accel[j] = 0; } } } void CL_RedTeamLight(vec3_t pos) { int j,i; particle_t *p; for(i=1; i<3; i++) { if (!(p = new_particle())) return; VectorClear (p->accel); p->alpha = .7; p->type = PARTICLE_STANDARD; p->image = r_flaretexture; p->blendsrc = GL_ONE; p->blenddst = GL_ONE; p->color = 0xe8; p->scale = 10*i; p->alphavel = INSTANT_PARTICLE; for (j=0 ; j<3 ; j++) { p->org[j] = pos[j]; p->vel[j] = 0; p->accel[j] = 0; } } } void CL_FlagEffects(vec3_t pos, qboolean team) { int i; particle_t *p; float dist, angle; if (!(p = new_particle())) return; VectorClear (p->accel); p->alpha = 1.0; p->type = PARTICLE_ROTATINGYAW; p->image = r_flagtexture; p->blendsrc = GL_ONE; p->blenddst = GL_ONE; if(team) p->color = 0x74; else p->color = 0xe8; p->scale = 15; p->alphavel = INSTANT_PARTICLE; for (i=0 ; i<3 ; i++) { p->org[i] = pos[i]; p->vel[i] = 0; p->accel[i] = 0; } p->org[2] += 64; if (!(p = new_particle())) return; p->type = PARTICLE_STANDARD; p->image = r_cflashtexture; p->scale = 20 + (rand()&7); p->blendsrc = GL_ONE; p->blenddst = GL_ONE; if(team) p->color = 0x74; else p->color = 0xe8; angle = M_PI*2*(rand()&1023)/1023.0; dist = rand()&5; p->org[0] = pos[0] + cos(angle)*dist; p->vel[0] = cos(angle)*(6+(rand()&6)); p->accel[0] = -cos(angle)*6; p->org[1] = pos[1] + sin(angle)*dist; p->vel[1] = sin(angle)*(6+(rand()&6)); p->accel[1] = -sin(angle)*100; p->org[2] = pos[2] + 56 + (rand()%10); p->vel[2] = -10 + (rand()&6); p->accel[2] = PARTICLE_GRAVITY*10; p->alpha = 0.2; p->alphavel = -50 / (0.5 + frand()*0.3); } /* =============== CL_BloodSplatter - simple blood effects =============== */ void CL_BloodSplatter ( vec3_t pos, vec3_t pos2, int color, int blend ) { particle_t *p; vec3_t v; int j; trace_t trace; static vec3_t mins = { -1, -1, -1 }; static vec3_t maxs = { 1, 1, 1 }; //trace to see if impact occurs with nearby brush trace = CL_Trace ( pos, mins, maxs, pos2, -1, MASK_SOLID, true, NULL); if(trace.contents) { //hit a brush if(!(p = new_particle())) return; p->image = r_bloodtexture; p->color = color + (rand() & 1); p->type = PARTICLE_DECAL; p->blendsrc = GL_SRC_ALPHA; if(blend) //glowing blood p->blenddst = GL_ONE; else p->blenddst = GL_ONE_MINUS_SRC_ALPHA; p->scale = 2; p->scalevel = 0; VectorScale(trace.plane.normal, -1, v); RotateForNormal(v, p->angle); p->angle[ROLL] = rand() % 360; VectorAdd(pos2, trace.plane.normal, p->org); p->alpha = 0.7; p->alphavel = -0.2 / (2.0 + frand() * 0.3); for (j=0 ; j<3 ; j++) { p->accel[j] = 0; p->vel[j] = 0; } } } /* =============== CL_DiminishingTrail =============== */ void CL_DiminishingTrail (vec3_t start, vec3_t end, centity_t *old, int flags) { vec3_t move; vec3_t vec; float len; int j; particle_t *p; float dec; float orgscale; float velscale; if (((flags & EF_GIB) || (flags & EF_GREENGIB)) && cl_noblood->value) return; VectorCopy (start, move); VectorSubtract (end, start, vec); len = VectorNormalize (vec); dec = 2.5; VectorScale (vec, dec, vec); if (old->trailcount > 900) { orgscale = 4; velscale = 15; } else if (old->trailcount > 800) { orgscale = 2; velscale = 10; } else { orgscale = 1; velscale = 5; } // add stains if moving if ( len && !cl_noblood->value ) { if ( flags & EF_GIB ) { CL_BloodSplatter(start, end, 0xe8, 0); } else if ( flags & EF_GREENGIB ) { CL_BloodSplatter(start, end, 0xd0, 1); } } while (len > 0) { len -= dec; if (!free_particles) return; // drop less particles as it flies if ((rand()&1023) < old->trailcount) { if (!(p = new_particle())) return; if (flags & EF_GIB) { p->alpha = .6;//1.0; p->alphavel = -1.0 / (1+frand()*0.4); p->type = PARTICLE_STANDARD; p->image = r_bloodtexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE_MINUS_SRC_ALPHA; p->color = 0xe8; p->scale = 6; p->scalevel = 1.5; for (j=0 ; j<3 ; j++) { p->org[j] = move[j] + crand()*orgscale; p->vel[j] = crand()*velscale; p->accel[j] = 0; } p->vel[2] -= PARTICLE_GRAVITY; } else if (flags & EF_GREENGIB) { p->alpha = .6; p->alphavel = -1.0 / (1+frand()*0.4); p->type = PARTICLE_STANDARD; p->image = r_bloodtexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE_MINUS_SRC_ALPHA; p->color = 0xd0+ (rand()&3); p->scale = 6; p->scalevel = 1.5; for (j=0; j< 3; j++) { p->org[j] = move[j] + crand()*orgscale; p->vel[j] = crand()*velscale; p->accel[j] = 0; } p->vel[2] -= PARTICLE_GRAVITY; } else { dec = 10; //less smoke for (j=0 ; j<3 ; j++) { p->org[j] = move[j] + crand()*orgscale; p->vel[j] = crand()*velscale; } p->alphavel = -1.0 / (10+frand()*1.4); //smoke lingers longer p->alpha = .07; p->type = PARTICLE_STANDARD; p->image = r_smoketexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE_MINUS_SRC_ALPHA; p->scale = 1 + (rand()&4); p->scalevel = 15.0; p->color = 15; p->accel[2] = 20; } } old->trailcount -= 5; if (old->trailcount < 100) old->trailcount = 100; VectorAdd (move, vec, move); } } void MakeNormalVectors (vec3_t forward, vec3_t right, vec3_t up) { float d; // this rotate and negat guarantees a vector // not colinear with the original right[1] = -forward[0]; right[2] = forward[1]; right[0] = forward[2]; d = DotProduct (right, forward); VectorMA (right, -d, forward, right); VectorNormalize (right); CrossProduct (right, forward, up); } /* =============== CL_RocketTrail =============== */ void CL_RocketTrail (vec3_t start, vec3_t end, centity_t *old) { // smoke CL_DiminishingTrail (start, end, old, EF_ROCKET); } void CL_BlasterTrail (vec3_t start, vec3_t end, centity_t *old) { vec3_t move; vec3_t vec; float len; int j; particle_t *p; float dec; VectorCopy (start, move); VectorSubtract (end, start, vec); len = VectorNormalize (vec); dec = 20; VectorScale (vec, dec, vec); while (len > 0) { len -= dec; if ( (rand()&6) == 0) { if (!(p = new_particle())) return; VectorClear (p->accel); p->color = 0xd0 + (rand()&2); p->scale = 2 + (rand()&7); p->scalevel = 5; p->alpha = .3; p->alphavel = -1.0 / (3+frand()*0.2); p->type = PARTICLE_STANDARD; p->image = r_cflashtexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; for (j=0 ; j<3 ; j++) { p->org[j] = move[j] + crand()*2; p->vel[j] = crand()*2; } p->accel[2] = 0; } VectorAdd (move, vec, move); } } void CL_ShipExhaust (vec3_t start, vec3_t end, centity_t *old) { vec3_t move; vec3_t vec; float len; int j; particle_t *p; float dec; VectorCopy (start, move); VectorSubtract (end, start, vec); len = VectorNormalize (vec); dec = 3; VectorScale (vec, dec, vec); while (len > 0) { len -= dec; if ( (rand()&6) == 0) { if (!(p = new_particle())) return; VectorClear (p->accel); p->color = 0xc0 + (rand()&2); p->scale = 2 + (rand()&7); p->scalevel = 5; p->alpha = .3; p->alphavel = -1.0 / (3+frand()*0.2); p->type = PARTICLE_STANDARD; p->image = r_explosiontexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; for (j=0 ; j<3 ; j++) { p->org[j] = move[j] + crand()*2; p->vel[j] = crand()*2; } p->accel[2] = 0; } VectorAdd (move, vec, move); } } void CL_RocketExhaust (vec3_t start, vec3_t end, centity_t *old) { vec3_t move; vec3_t vec; float len; int j; particle_t *p; VectorCopy (start, move); VectorSubtract (end, start, vec); len = VectorNormalize (vec); VectorScale (vec, 5, vec); if (!(p = new_particle())) return; VectorClear (p->accel); p->alpha = .3; p->alphavel = INSTANT_PARTICLE; p->type = PARTICLE_ROTATINGROLL; p->image = r_bflashtexture; p->scale = 5; p->angle[0] = cl.refdef.viewangles[0]; p->angle[1] = cl.refdef.viewangles[1]; p->angle[2] = cl.refdef.viewangles[2]; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->color = 0xc0 + (rand()&2); for (j=0 ; j<3 ; j++) { p->org[j] = move[j]; p->vel[j] = 0; p->accel[j] = 0; } if (!(p = new_particle())) return; VectorClear (p->accel); p->alpha = .7; p->alphavel = INSTANT_PARTICLE; p->type = PARTICLE_STANDARD; p->image = r_bflashtexture; p->scale = 5; p->angle[0] = cl.refdef.viewangles[0]; p->angle[1] = cl.refdef.viewangles[1]; p->angle[2] = cl.refdef.viewangles[2]; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->color = 0xc0 + (rand()&2); for (j=0 ; j<3 ; j++) { p->org[j] = move[j]; p->vel[j] = 0; p->accel[j] = 0; } if (!(p = new_particle())) return; VectorClear (p->accel); p->alpha = .7; p->alphavel = INSTANT_PARTICLE; p->type = PARTICLE_STANDARD; p->image = r_flaretexture; p->scale = 10; p->angle[0] = cl.refdef.viewangles[0]; p->angle[1] = cl.refdef.viewangles[1]; p->angle[2] = cl.refdef.viewangles[2]; p->blendsrc = GL_ONE; p->blenddst = GL_ONE; p->color = 0xc0 + (rand()&2); for (j=0 ; j<3 ; j++) { p->org[j] = move[j]; p->vel[j] = 0; p->accel[j] = 0; } VectorAdd (move, vec, move); } /* =============== Wall Impacts =============== */ void CL_BulletMarks(vec3_t org, vec3_t dir){ particle_t *p; vec3_t v; int j; if(!(p = new_particle())) return; p->image = r_bulletnormal; p->color = 0 + (rand() & 1); p->type = PARTICLE_RAISEDDECAL; p->blendsrc = GL_DST_COLOR; p->blenddst = GL_SRC_COLOR; VectorScale(dir, -1, v); RotateForNormal(v, p->angle); p->angle[ROLL] = rand() % 360; VectorAdd(org, dir, p->org); p->scale = .5; p->alpha = 0.5; p->alphavel = -0.2 / (2.0 + frand() * 0.3); for (j=0 ; j<3 ; j++) { p->accel[j] = 0; p->vel[j] = 0; } } void CL_BeamgunMark(vec3_t org, vec3_t dir, float dur, qboolean isDis){ particle_t *p; vec3_t v; int j; float color; vec3_t colorvec; if(isDis) color = getColor(); else color = 0xd4; if(!(p = new_particle())) return; p->image = r_bullettexture; p->color = color + (rand() & 1); p->type = PARTICLE_DECAL; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->scale = .75; p->scalevel = 0; VectorScale(dir, -1, v); RotateForNormal(v, p->angle); p->angle[ROLL] = rand() % 360; VectorAdd(org, dir, p->org); p->alpha = 0.5; p->alphavel = -dur / (2.0 + frand() * 0.3); for (j=0 ; j<3 ; j++) { p->accel[j] = 0; p->vel[j] = 0; } if(!(p = new_particle())) return; p->image = r_bullettexture; p->color = color + (rand() & 1); p->type = PARTICLE_DECAL; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->scale = 1.5; p->scalevel = 0; VectorScale(dir, -1, v); RotateForNormal(v, p->angle); p->angle[ROLL] = rand() % 360; VectorAdd(org, dir, p->org); p->alpha = 0.5; p->alphavel = -dur / (2.0 + frand() * 0.3); for (j=0 ; j<3 ; j++) { p->accel[j] = 0; p->vel[j] = 0; } //add small shockwave effect if(!(p = new_particle())) return; p->image = r_hittexture; p->color = color + (rand() & 1); p->type = PARTICLE_DECAL; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->scale = .1; p->scalevel = 10; VectorScale(dir, -1, v); RotateForNormal(v, p->angle); p->angle[ROLL] = rand() % 360; VectorAdd(org, dir, p->org); p->alpha = 1.0; p->alphavel = -2.0; for (j=0 ; j<3 ; j++) { p->accel[j] = 0; p->vel[j] = 0; } if(isDis) getColorvec(colorvec); else { colorvec[0] = 0; //bright green colorvec[1] = 1; colorvec[2] = 0.2; } addParticleLight (p, isDis ? 120:80, 5, colorvec[0], colorvec[1], colorvec[2]); } void CL_BlasterMark(vec3_t org, vec3_t dir){ particle_t *p; vec3_t v; int j; if(!(p = new_particle())) return; p->image = r_bullettexture; p->color = 0x74 + (rand() & 1); p->type = PARTICLE_DECAL; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->scale = .75; p->scalevel = 0; VectorScale(dir, -1, v); RotateForNormal(v, p->angle); p->angle[ROLL] = rand() % 360; VectorAdd(org, dir, p->org); p->alpha = 0.7; p->alphavel = -0.4 / (2.0 + frand() * 0.3); for (j=0 ; j<3 ; j++) { p->accel[j] = 0; p->vel[j] = 0; } if(!(p = new_particle())) return; p->image = r_bullettexture; p->color = 0x74 + (rand() & 1); p->type = PARTICLE_DECAL; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->scale = 1.5; p->scalevel = 0; VectorScale(dir, -1, v); RotateForNormal(v, p->angle); p->angle[ROLL] = rand() % 360; VectorAdd(org, dir, p->org); p->alpha = 0.5; p->alphavel = -0.4 / (2.0 + frand() * 0.3); for (j=0 ; j<3 ; j++) { p->accel[j] = 0; p->vel[j] = 0; } } void CL_VaporizerMarks(vec3_t org, vec3_t dir){ particle_t *p; vec3_t v, forward, right, up; int i,j; float scatter; for(i = 0; i < 6; i ++) { if(!(p = new_particle())) return; p->image = r_bullettexture; p->color = 0xd4 + (rand()&7); p->type = PARTICLE_DECAL; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->scale = .75; p->scalevel = 0; VectorScale(dir, -1, v); RotateForNormal(v, p->angle); p->angle[ROLL] = rand() % 360; VectorAdd(org, dir, p->org); AngleVectors(p->angle, forward, right, up); scatter = ((rand()%8)-4); VectorMA(p->org, scatter, up, p->org); p->alpha = 0.7; p->alphavel = -0.4 / (2.0 + frand() * 0.3); for (j=0 ; j<3 ; j++) { p->accel[j] = 0; p->vel[j] = 0; } if(!(p = new_particle())) return; p->image = r_bullettexture; p->color = 0x74 + (rand()&7); p->type = PARTICLE_DECAL; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->scale = 1.5; p->scalevel = 0; VectorScale(dir, -1, v); RotateForNormal(v, p->angle); p->angle[ROLL] = rand() % 360; VectorAdd(org, dir, p->org); VectorMA(p->org, scatter, up, p->org); p->alpha = 0.5; p->alphavel = -0.4 / (2.0 + frand() * 0.3); for (j=0 ; j<3 ; j++) { p->accel[j] = 0; p->vel[j] = 0; } } } /* =============== Particle Beams =============== */ //this is the length of each piece... #define RAILTRAILSPACE 20 #define LASERTRAILSPACE 10 void CL_DisruptorBeam (vec3_t start, vec3_t end) { vec3_t move; vec3_t vec, point, last, vec2; float len, color; vec3_t right, up; particle_t *p; int i,j; float v; color = getColor(); VectorSubtract (end, start, vec); len = VectorNormalize (vec); VectorCopy (vec, point); MakeNormalVectors (vec, right, up); VectorCopy (vec, vec2); VectorScale (vec, RAILTRAILSPACE, vec); VectorCopy (start, move); for (i = 0; len>0; len -= RAILTRAILSPACE, i+=100) { VectorCopy (move, last); VectorAdd (move, vec, move); if (!(p = new_particle())) return; p->alpha = 1; p->alphavel = -1.0 - (len/(float)i); p->blenddst = GL_ONE; p->blendsrc = GL_SRC_ALPHA; v = frand(); if(v < 0.2) p->image = r_dis3texture; else if(v < 0.5) p->image = r_dis2texture; else p->image = r_dis1texture; p->scale = 4; VectorCopy(move, p->angle); p->type = PARTICLE_BEAM; p->scalevel = 0; p->color = color; for (j=0 ; j<3 ; j++) { p->org[j] = last[j]; p->vel[j] = 0; p->accel[j] = 0; } } } void CL_LaserBeam (vec3_t start, vec3_t end) { vec3_t move; vec3_t vec, point, last, vec2; float len; vec3_t right, up; particle_t *p, *pr; int i,j; VectorSubtract (end, start, vec); len = VectorNormalize (vec); VectorCopy (vec, point); MakeNormalVectors (vec, right, up); VectorCopy (vec, vec2); VectorScale (vec, RAILTRAILSPACE, vec); VectorCopy (start, move); //muzzleflash VectorScale (vec2, -RAILTRAILSPACE/2, vec2); VectorAdd(start, vec2, start); for(i = 0; i < 3; i++) { if (!(p = new_particle())) return; p->alpha = 0.9; p->alphavel = -2.8 / (0.6+frand()*0.2); p->blenddst = GL_ONE; p->blendsrc = GL_SRC_ALPHA; p->image = r_cflashtexture; p->scale = 12/(i+1); for(j=0; j< 3; j++) p->angle[j] = 0; p->type = PARTICLE_STANDARD; p->scalevel = 8; p->color = 0xd4; for (j=0 ; j<3 ; j++) { p->org[j] = start[j]; p->vel[j] = 0; p->accel[j] = 0; } } //Dummy particle that won't get drawn -- the first particle in a chain is //always skipped. if (!(pr = new_particle ())) return; pr->alpha = 0.9; pr->alphavel = -2.8; pr->scale = 4; pr->scalevel = 0; VectorCopy (start, pr->org); VectorClear (pr->vel); VectorClear (pr->accel); pr->type = PARTICLE_CHAINED; pr->color = 0xd4; pr->image = r_beam2texture; if (!(p = new_particle())) return; p->alpha = 0.9; p->alphavel = -2.8; p->blenddst = GL_ONE; p->blendsrc = GL_SRC_ALPHA; p->image = r_beam2texture; p->scale = 4; VectorCopy(move, p->angle); p->type = PARTICLE_CHAINED; p->scalevel = 0; p->color = 0xd4; p->chain_prev = pr; for (j=0 ; j<3 ; j++) { p->org[j] = end[j]; p->vel[j] = 0; p->accel[j] = 0; } for (; len>0; len -= RAILTRAILSPACE) { VectorCopy (move, last); VectorAdd (move, vec, move); if (len > 40) continue; if (!(p = new_particle())) return; p->alpha = 0.9; p->alphavel = -2.8; p->blenddst = GL_ONE; p->blendsrc = GL_SRC_ALPHA; p->image = r_flaretexture; p->scale = 24; for(j=0; j< 3; j++) p->angle[j] = 0; p->type = PARTICLE_STANDARD; p->scalevel = 12; p->color = 0xd4; for (j=0 ; j<3 ; j++) { p->org[j] = last[j]; p->vel[j] = 0; p->accel[j] = 0; } } } void CL_BlasterBeam (vec3_t start, vec3_t end) { vec3_t move; vec3_t vec, point, vec2; float len; vec3_t right, up; particle_t *p, *pr; int i,j; VectorSubtract (end, start, vec); len = VectorNormalize (vec); VectorCopy (vec, point); MakeNormalVectors (vec, right, up); VectorCopy (vec, vec2); VectorScale (vec, LASERTRAILSPACE, vec); VectorCopy (start, move); //puff of blue gas VectorScale (vec2, -LASERTRAILSPACE/2, vec2); VectorAdd(start, vec2, start); for(i = 0; i < 6; i++) { if (!(p = new_particle())) return; p->alpha = 0.9; p->alphavel = -1.8 / (0.6+frand()*0.2); p->blenddst = GL_ONE; p->blendsrc = GL_SRC_ALPHA; p->image = r_cflashtexture; p->scale = 8/(i+1); for(j=0; j< 3; j++) p->angle[j] = 0; p->type = PARTICLE_STANDARD; p->scalevel = 4; p->color = 0x74; for (j=0 ; j<3 ; j++) { p->org[j] = start[j]; p->vel[j] = 0; p->accel[j] = 0; } } //Dummy particle that won't get drawn -- the first particle in a chain is //always skipped. if (!(pr = new_particle ())) return; pr->alpha = 0.9; pr->alphavel = -1.8; pr->scale = 2; pr->scalevel = 0; VectorCopy (start, pr->org); VectorClear (pr->vel); VectorClear (pr->accel); pr->type = PARTICLE_CHAINED; pr->color = 0x74; pr->image = r_beam2texture; for (i = 0; i < 3; i++) { if (!(p = new_particle())) return; p->alpha = 0.9; p->alphavel = -1.8; p->blenddst = GL_ONE; p->blendsrc = GL_SRC_ALPHA; p->image = r_beam2texture; p->scale = 2; VectorCopy(move, p->angle); p->type = PARTICLE_CHAINED; p->scalevel = 0; p->color = 0x74; p->chain_prev = pr; for (j=0 ; j<3 ; j++) { p->org[j] = end[j]; p->vel[j] = 0; p->accel[j] = 0; } } } #define VAPORIZORTRAILSPACE 20 void CL_VaporizerBeam (vec3_t start, vec3_t end) { vec3_t move; vec3_t vec, point, last, vec2; float len; vec3_t right, up; particle_t *p; int i,j; VectorSubtract (end, start, vec); len = VectorNormalize (vec); VectorCopy (vec, point); MakeNormalVectors (vec, right, up); VectorCopy (vec, vec2); VectorScale (vec, VAPORIZORTRAILSPACE, vec); VectorCopy (start, move); //muzzleflash VectorScale (vec2, -VAPORIZORTRAILSPACE/2, vec2); VectorAdd(start, vec2, start); for(i = 0; i < 8; i++) { if (!(p = new_particle())) return; p->alpha = 0.9; p->alphavel = -.8 / (0.6+frand()*0.2); p->blenddst = GL_ONE; p->blendsrc = GL_SRC_ALPHA; p->image = r_leaderfieldtexture; p->scale = 24/(i+1); for(j=0; j< 3; j++) p->angle[j] = 0; p->type = PARTICLE_STANDARD; p->scalevel = 12; p->color = 0x74 + (rand()&12);; for (j=0 ; j<3 ; j++) { p->org[j] = start[j]; p->vel[j] = 0; p->accel[j] = 0; } } for (; len>0; len -= VAPORIZORTRAILSPACE) { VectorCopy (move, last); VectorAdd (move, vec, move); for(i = 0; i < 3; i++) { if (!(p = new_particle())) return; p->alpha = 1; p->alphavel = -.8 / (0.6+frand()*0.2); p->blenddst = GL_ONE; p->blendsrc = GL_SRC_ALPHA; p->image = r_beam2texture; p->scale = 4; VectorCopy(move, p->angle); p->type = PARTICLE_BEAM; p->scalevel = 0; p->color = 0x74 + (rand()&7); for (j=0 ; j<3 ; j++) { p->org[j] = last[j]; p->vel[j] = 0; p->accel[j] = 0; } } //do lightning effects if (!(p = new_particle())) return; p->alpha = 1; p->alphavel = -.8 / (0.6+frand()*0.2); p->blenddst = GL_ONE; p->blendsrc = GL_SRC_ALPHA; p->image = r_beam3texture; p->scale = 4; VectorCopy(move, p->angle); p->type = PARTICLE_BEAM; p->scalevel = 0; p->color = 0x74; for (j=0 ; j<3 ; j++) { p->org[j] = last[j]; p->vel[j] = 0; p->accel[j] = 0; } } } void CL_NewLightning (vec3_t start, vec3_t end) { vec3_t move; vec3_t vec; float len; int j; particle_t *p; particle_t *pr = NULL; float dec; vec3_t right, up; int i; float skewx, skewy, skewz; float x, y, z; // byte clr = 0xd4; VectorCopy (start, move); VectorSubtract (end, start, vec); len = VectorNormalize (vec); MakeNormalVectors (vec, right, up); dec = .75; VectorScale (vec, dec, vec); VectorCopy (start, move); skewx = skewy = skewz = .1; i = 0; x = y = z = 0; while (len > 0) { len -= dec; i++; if (!(p = new_particle())) return; VectorClear (p->accel); x++; y++; z++; // somehow increment x,y,z in random direction if (i > 10)//reset { i = 0; x = y = z = 0; if (frand() < 0.5) skewx = skewx * -1; if (frand() < 0.5) skewy = skewy * -1; if (frand() < 0.5) skewz = skewz * -1; } p->org[0] = move[0] + skewx * ++x; p->org[1] = move[1] + skewy * ++y; p->org[2] = move[2] + skewz * ++z; p->alpha = 1.2; p->alphavel = -3.33; p->type = PARTICLE_CHAINED; p->image = r_raintexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->scale = 1 + (rand()&2); p->scalevel = 0; p->color = 0xff; for (j=0 ; j<3 ; j++) { p->vel[j] = 0; p->accel[j] = 0; } if (len < 4) addParticleLight (p, p->scale*75, 0, .25, 0, .3); VectorAdd (p->org, vec, move); if (pr) { p->chain_prev = pr; } pr = p; } } void CL_RedBlasterBeam (vec3_t start, vec3_t end) { vec3_t move; vec3_t vec, point, last, vec2; float len; vec3_t right, up; particle_t *p; int i,j; VectorCopy (start, move); VectorSubtract (end, start, vec); len = VectorNormalize (vec); VectorCopy (vec, point); MakeNormalVectors (vec, right, up); VectorCopy (vec, vec2); VectorScale (vec, LASERTRAILSPACE, vec); VectorCopy (start, move); //puff of blue gas VectorScale (vec2, -LASERTRAILSPACE/2, vec2); VectorAdd(start, vec2, start); for(i = 0; i < 6; i++) { if (!(p = new_particle())) return; p->alpha = 0.9; p->alphavel = -1.8 / (0.6+frand()*0.2); p->blenddst = GL_ONE; p->blendsrc = GL_SRC_ALPHA; p->image = r_cflashtexture; p->scale = 8/(i+1); for(j=0; j< 3; j++) p->angle[j] = 0; p->type = PARTICLE_STANDARD; p->scalevel = 4; p->color = 0xe8; for (j=0 ; j<3 ; j++) { p->org[j] = start[j]; p->vel[j] = 0; p->accel[j] = 0; } } for (; len>0; len -= LASERTRAILSPACE) { VectorCopy (move, last); VectorAdd (move, vec, move); for(i = 0; i < 3; i++) { if (!(p = new_particle())) return; p->alpha = 0.9; p->alphavel = -1.8; p->blenddst = GL_ONE; p->blendsrc = GL_SRC_ALPHA; p->image = r_beam2texture; p->scale = 2; VectorCopy(move, p->angle); p->type = PARTICLE_BEAM; p->scalevel = 0; p->color = 0xe8; for (j=0 ; j<3 ; j++) { p->org[j] = last[j]; p->vel[j] = 0; p->accel[j] = 0; } } } } /* =============== CL_BubbleTrail =============== */ void CL_BubbleTrail (vec3_t start, vec3_t end) { vec3_t move; vec3_t vec; float len; int i, j; particle_t *p; float dec; VectorCopy (start, move); VectorSubtract (end, start, vec); len = VectorNormalize (vec); dec = 32; VectorScale (vec, dec, vec); for (i=0 ; iaccel); p->alpha = 1.0; p->alphavel = -1.0 / (1+frand()*0.2); p->color = 4 + (rand()&7); p->type = PARTICLE_STANDARD; p->image = r_bubbletexture; p->scale = 2 + (rand()&2); p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE_MINUS_SRC_ALPHA; for (j=0 ; j<3 ; j++) { p->org[j] = move[j] + crand()*2; p->vel[j] = crand()*5; } p->vel[2] += 6; VectorAdd (move, vec, move); } } /* =============== CL_BFGExplosionParticles =============== */ void CL_BFGExplosionParticles (vec3_t org) { int i, j; particle_t *p; //for glsl framebuffer distortion effects if(!r_drawing_fbeffect && cl_explosiondist->value) { r_fbFxType = 1; //EXPLOSION r_drawing_fbeffect = true; VectorCopy(org, r_explosionOrigin); r_fbeffectTime = rs_realtime; } for (i=0 ; i<32 ; i++) { if (!(p = new_particle())) return; for (j=0 ; j<3 ; j++) { p->org[j] = org[j] + ((rand()%62)-32); p->vel[j] = (rand()%32)-16; } p->accel[0] = p->accel[1] = 5+(rand()&7); p->accel[2] = 5+(rand()&7); p->scale = (24 + (rand()&2)); p->scalevel = 24; p->type = PARTICLE_STANDARD; p->image = r_explosiontexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->color = 0x74 + (rand()&7); p->alpha = 0.4; p->alphavel = -0.8 / (2.5 + frand()*0.3); if (i > 28) addParticleLight (p, p->scale*(15+(rand()&5)), 10, 0, 0.6, 0.5); } //place a big shock wave effect if (!(p = new_particle())) return; p->alpha = 1.0; p->alphavel = -1.0; p->type = PARTICLE_FLAT; p->image = r_hittexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->color = 0x74 + (rand()&7); p->scale = 24 + (rand()&4) ; p->scalevel = 100; for(j = 0; j < 3; j++) { p->org[j] = org[j]; p->vel[j] = 0; p->accel[j] = 0; } } /* =============== CL_TeleportParticles =============== */ void CL_TeleportParticles (vec3_t orig_start) { vec3_t move; vec3_t vec; vec3_t start; vec3_t end; float len; int j; particle_t *p; int i; vec3_t pos1, pos2, v; float step = 16.0; // static vec3_t mins = { -1, -1, -1 }; // static vec3_t maxs = { 1, 1, 1 }; //make a copy to prevent modifying an important vector VectorCopy(orig_start, start); VectorCopy(start, pos1); pos2[2] = 1; pos2[0] = pos2[1] = 0; pos1[2] -= 32; if(!(p = new_particle())) return; p->image = r_logotexture; p->color = 0x74 + (rand()&7); p->type = PARTICLE_DECAL; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->scale = 4; p->scalevel = 0; VectorScale(pos2, -1, v); RotateForNormal(v, p->angle); p->angle[ROLL] = rand() % 360; VectorCopy( pos1, p->org); p->alpha = 0.7; p->alphavel = -0.15; for (j=0 ; j<3 ; j++) { p->accel[j] = 0; p->vel[j] = 0; } //place a big shock wave effect if (!(p = new_particle())) return; p->alpha = 1.0; p->alphavel = -.250; p->type = PARTICLE_DECAL; p->image = r_explosion5texture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->color = 0x74 + (rand()&7); p->scale = 1 + (rand()&4) ; p->scalevel = 4; VectorScale(pos2, -1, v); RotateForNormal(v, p->angle); p->angle[ROLL] = rand() % 360; VectorCopy( pos1, p->org); for(j = 0; j < 3; j++) { p->vel[j] = 0; p->accel[j] = 0; } VectorCopy (start, move); VectorCopy (start, end); end[2] += 32; start[2] -= 48; VectorSubtract (end, start, vec); len = VectorNormalize (vec); for (i=0 ; iaccel); p->alpha = 1.0; p->alphavel = -2.5 / (2+frand()*0.2); p->type = PARTICLE_FLAT; p->image = r_hittexture; p->blendsrc = GL_ONE; p->blenddst = GL_ONE; p->color = 0x74 + (rand()&7); p->scale = 24 + (rand()&4) ; p->scalevel = 0; for(j = 0; j < 3; j++) { p->org[j] = start[j]; p->vel[j] = 0; } p->vel[2] = PARTICLE_GRAVITY*2; if (i < 1) addParticleLight (p, p->scale, 10, 0, 1, 1); start[2] += 16; } } #define WEATHER_PARTICLES 2048 static int weather_particles; extern unsigned r_weather; /* Cl_WeatherEffects - originally adopted from Jay Dolan's Q2W */ void Cl_WeatherEffects() { int i, j, k; vec3_t start, end; trace_t tr; float ceiling; particle_t *p; if(!r_weather) return; i = weather_particles; // we count up from current particles p = NULL; // so that we add the right amount k = 0; if(r_weather == 5) { while(i++ < WEATHER_PARTICLES && k++ < 1) { VectorCopy(cl.refdef.vieworg, start); start[0] = start[0] + (rand() % 5096) - 2048; start[1] = start[1] + (rand() % 5096) - 2048; VectorCopy(start, end); end[2] += 8192; // trace up looking for sky tr = CM_BoxTrace(start, end, vec3_origin, vec3_origin, 0, MASK_SHOT); if(!(tr.surface->flags & SURF_SKY)) continue; // drop down somewhere between sky and player ceiling = tr.endpos[2] > start[2] + 1024 ? start[2] + 1024 : tr.endpos[2]; tr.endpos[2] = tr.endpos[2] - ((ceiling - start[2]) * frand()); if (!(p = new_particle())) return; VectorCopy(tr.endpos, p->org); p->org[2] -= 1; VectorCopy(start, end); end[2] -= 8192; tr = CM_BoxTrace(p->org, end, vec3_origin, vec3_origin, 0, MASK_ALL); if(!tr.surface) // this shouldn't happen VectorCopy(start, p->end); else VectorCopy(tr.endpos, p->end); p->type = PARTICLE_FLUTTERWEATHER; // setup the particles //trash p->image = r_trashtexture; p->vel[2] = -80; p->accel[2] = 0; p->alpha = 0.9; p->alphavel = 0; p->color = 8; p->scale = 12; p->scalevel = 0; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE_MINUS_SRC_ALPHA; for(j = 0; j < 2; j++) { p->vel[j] = crand() * 40; p->accel[j] = crand() * 50; } weather_particles++; } } else if(r_weather == 3 || r_weather == 4) { while(i++ < WEATHER_PARTICLES && k++ < 2) { VectorCopy(cl.refdef.vieworg, start); start[0] = start[0] + (rand() % 2048) - 1024; start[1] = start[1] + (rand() % 2048) - 1024; VectorCopy(start, end); end[2] += 8192; // trace up looking for sky tr = CM_BoxTrace(start, end, vec3_origin, vec3_origin, 0, MASK_SHOT); if(!(tr.surface->flags & SURF_SKY)) continue; // drop down somewhere between sky and player ceiling = tr.endpos[2] > start[2] + 1024 ? start[2] + 1024 : tr.endpos[2]; tr.endpos[2] = tr.endpos[2] - ((ceiling - start[2]) * frand()); if (!(p = new_particle())) return; VectorCopy(tr.endpos, p->org); p->org[2] -= 1; VectorCopy(start, end); end[2] -= 8192; tr = CM_BoxTrace(p->org, end, vec3_origin, vec3_origin, 0, MASK_ALL); if(!tr.surface) // this shouldn't happen VectorCopy(start, p->end); else VectorCopy(tr.endpos, p->end); // setup the particles if(r_weather == 3) //leaves { p->type = PARTICLE_FLUTTERWEATHER; p->image = r_leaftexture; p->vel[2] = -80; p->accel[2] = 0; p->alpha = 0.9; p->alphavel = 0; p->color = 8; p->scale = 2; p->scalevel = 0; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE_MINUS_SRC_ALPHA; } else if(r_weather == 4) //embers { p->type = PARTICLE_WEATHER; p->image = r_particletexture; p->vel[2] = -80; p->accel[2] = 0; p->alpha = 0.9; p->alphavel = frand() * -1; p->color = 0xe8; p->scale = 2; p->scalevel = 0; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; } for(j = 0; j < 2; j++) { p->vel[j] = crand() * 25; p->accel[j] = crand() * 50; } weather_particles++; } } else { while(i++ < WEATHER_PARTICLES && k++ < 25) { VectorCopy(cl.refdef.vieworg, start); start[0] = start[0] + (rand() % 2048) - 1024; start[1] = start[1] + (rand() % 2048) - 1024; VectorCopy(start, end); end[2] += 8192; // trace up looking for sky tr = CM_BoxTrace(start, end, vec3_origin, vec3_origin, 0, MASK_SHOT); if(!(tr.surface->flags & SURF_SKY)) continue; // drop down somewhere between sky and player ceiling = tr.endpos[2] > start[2] + 1024 ? start[2] + 1024 : tr.endpos[2]; tr.endpos[2] = tr.endpos[2] - ((ceiling - start[2]) * frand()); if (!(p = new_particle())) return; VectorCopy(tr.endpos, p->org); p->org[2] -= 1; VectorCopy(start, end); end[2] -= 8192; tr = CM_BoxTrace(p->org, end, vec3_origin, vec3_origin, 0, MASK_ALL); if(!tr.surface) // this shouldn't happen VectorCopy(start, p->end); else VectorCopy(tr.endpos, p->end); p->type = PARTICLE_WEATHER; // setup the particles if(r_weather == 1) //rain { p->image = r_raintexture; p->vel[2] = -800; p->accel[2] = 0; p->alpha = 0.3; p->alphavel = frand() * -1; p->color = 8; p->scale = 6; p->scalevel = 0; } else if(r_weather == 2) //snow { p->image = r_particletexture; p->vel[2] = -120; p->accel[2] = 0; p->alpha = 0.8; p->alphavel = frand() * -1; p->color = 8; p->scale = 1; p->scalevel = 0; } p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; for(j = 0; j < 2; j++) { p->vel[j] = crand() * 2; p->accel[j] = crand() * 2; } weather_particles++; } } } /* Powered up effects */ #define BEAMLENGTH 16 void CL_PoweredEffects (vec3_t origin) { int i; particle_t *p; float angle; float sr, sp, sy, cr, cp, cy; vec3_t forward; float dist = 64; float ltime; if (!avelocities[0][0]) { for (i=0 ; iorg[0] = origin[0] + bytedirs[i][0]*dist + forward[0]*BEAMLENGTH; p->org[1] = origin[1] + bytedirs[i][1]*dist + forward[1]*BEAMLENGTH; p->org[2] = origin[2] + bytedirs[i][2]*dist + forward[2]*BEAMLENGTH; VectorClear (p->vel); VectorClear (p->accel); p->type = PARTICLE_STANDARD; p->image = r_logotexture; p->blendsrc = GL_ONE; p->blenddst = GL_ONE; p->scale = 2; p->scalevel = 2; p->color = 0xd4; p->alpha = .7; p->alphavel = -50 / (0.5 + frand()*0.3); } } /* ====== vectoangles2 - this is duplicated in the game DLL, but I need it here. ====== */ void vectoangles2 (vec3_t value1, vec3_t angles) { float forward; float yaw, pitch; if (value1[1] == 0 && value1[0] == 0) { yaw = 0; if (value1[2] > 0) pitch = 90; else pitch = 270; } else { // PMM - fixed to correct for pitch of 0 if (value1[0]) yaw = (atan2(value1[1], value1[0]) * 180 / M_PI); else if (value1[1] > 0) yaw = 90; else yaw = 270; if (yaw < 0) yaw += 360; forward = sqrt (value1[0]*value1[0] + value1[1]*value1[1]); pitch = (atan2(value1[2], forward) * 180 / M_PI); if (pitch < 0) pitch += 360; } angles[PITCH] = -pitch; angles[YAW] = yaw; angles[ROLL] = 0; } /* =============== CL_SmokeTrail =============== */ void CL_SmokeTrail (vec3_t start, vec3_t end, int colorStart, int colorRun, int spacing) { vec3_t move; vec3_t vec; float len; int j; particle_t *p; VectorCopy (start, move); VectorSubtract (end, start, vec); len = VectorNormalize (vec); VectorScale (vec, spacing, vec); // FIXME: this is a really silly way to have a loop while (len > 0) { len -= spacing; if (!(p = new_particle())) return; VectorClear (p->accel); p->alpha = 1.0; p->alphavel = -1.0 / (1+frand()*0.5); p->color = colorStart + (rand() % colorRun); for (j=0 ; j<3 ; j++) { p->org[j] = move[j] + crand()*3; p->accel[j] = 0; } p->vel[2] = 20 + crand()*5; VectorAdd (move, vec, move); } } /* =============== CL_ParticleSteamEffect Puffs with velocity along direction, with some randomness thrown in =============== */ void CL_ParticleSteamEffect (cl_sustain_t *self) { int i, j; particle_t *p; float d; vec3_t r, u; vec3_t dir; VectorCopy (self->dir, dir); MakeNormalVectors (dir, r, u); for (i=0 ; i<2 ; i++) { if (!(p = new_particle())) return; p->type = PARTICLE_STANDARD; p->image = r_pufftexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE_MINUS_SRC_ALPHA; p->scale = 4 + (rand()&2); p->scalevel = 10; p->color = self->color; for (j=0 ; j<3 ; j++) { p->org[j] = self->org[j] + self->magnitude*0.1*crand(); } VectorScale (dir, self->magnitude, p->vel); d = crand()*self->magnitude/3; VectorMA (p->vel, d, r, p->vel); d = crand()*self->magnitude/3; VectorMA (p->vel, d, u, p->vel); p->accel[0] = p->accel[1] = 0; p->accel[2] = -PARTICLE_GRAVITY/2; p->alpha = 0.1; p->alphavel = -1.0 / (6.5 + frand()*0.3); p->fromsustainedeffect = true; } self->nextthink += self->thinkinterval; } void CL_ParticleFireEffect2 (cl_sustain_t *self) { int i, j; particle_t *p; float d; vec3_t r, u; vec3_t dir; VectorCopy (self->dir, dir); MakeNormalVectors (dir, r, u); for (i=0 ; i<1 ; i++) { if (!(p = new_particle())) return; p->type = PARTICLE_STANDARD; p->image = r_explosiontexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE; p->color = 0xe0; p->scale = 24 + (rand()&7); p->scalevel = 4; for (j=0 ; j<3 ; j++) { p->org[j] = self->org[j] + self->magnitude*0.1*crand(); } p->vel[2] = 100; VectorScale (dir, self->magnitude, p->vel); d = crand()*self->magnitude/3; VectorMA (p->vel, d, r, p->vel); d = crand()*self->magnitude/3; VectorMA (p->vel, d, u, p->vel); p->accel[0] = p->accel[1] = 0; p->accel[2] = -PARTICLE_GRAVITY/3; p->alpha = 0.03; p->alphavel = -.015 / (0.8 + frand()*0.3); p->fromsustainedeffect = true; } self->nextthink += self->thinkinterval; } void CL_ParticleSmokeEffect2 (cl_sustain_t *self) { int i, j; particle_t *p; float d; vec3_t r, u; vec3_t dir; VectorCopy (self->dir, dir); MakeNormalVectors (dir, r, u); for (i=0 ; icount ; i++) { if (!(p = new_particle())) return; p->type = PARTICLE_STANDARD; p->image = r_smoketexture; p->blendsrc = GL_SRC_ALPHA; p->blenddst = GL_ONE_MINUS_SRC_ALPHA; p->scale = 6 + (rand()&7); p->color = 14; p->scalevel = 4.5; for (j=0 ; j<3 ; j++) { p->org[j] = self->org[j] + self->magnitude*0.1*crand(); } p->vel[2] = 10; VectorScale (dir, self->magnitude, p->vel); d = crand()*self->magnitude/3; VectorMA (p->vel, d, r, p->vel); d = crand()*self->magnitude/3; VectorMA (p->vel, d, u, p->vel); p->accel[0] = p->accel[1] = 0; p->accel[2] = -PARTICLE_GRAVITY/3; p->alpha = 0.03; p->alphavel = -.015 / (7.8 + frand()*0.3); p->fromsustainedeffect = true; } self->nextthink += self->thinkinterval; } /* =============== CL_AddParticles =============== */ void CL_AddParticles (void) { particle_t *p, *next; float light; float time = 0.0f; particle_t *active, *tail; int i; Cl_WeatherEffects(); active = NULL; tail = NULL; for (p=active_particles ; p ; p=next) { next = p->next; // PMM - added INSTANT_PARTICLE handling for heat beam if (p->alphavel != INSTANT_PARTICLE) { time = (cl.time - p->time)*0.001; p->current_alpha = p->alpha + time*p->alphavel; if (p->current_alpha <= 0) { // faded out if(p->type == PARTICLE_WEATHER || p->type == PARTICLE_FLUTTERWEATHER) weather_particles--; p->next = free_particles; free_particles = p; continue; } } else { p->current_alpha = p->alpha; p->alpha = p->alphavel = 0.0; } if(p->scalevel > 1) { time = (cl.time - p->time)*0.001; p->current_scale = p->scale + time * p->scalevel; } else p->current_scale = p->scale; if (p->colorvel != 0) { time = (cl.time - p->time)*0.001; p->current_color = (p->color + time * p->colorvel); } else p->current_color = p->color; if(p->current_scale > 64) p->current_scale = 64; //don't want them getting too large. if(p->current_scale < 0) p->current_scale = 0; if(p->current_color < 0) p->current_color = 0; // update origin for(i = 0; i < 3; i++) { p->current_origin[i] = p->org[i] + p->vel[i]*time + p->accel[i]*(time*time); } // free up weather particles that have hit the ground if(p->type == PARTICLE_WEATHER || p->type == PARTICLE_FLUTTERWEATHER) { if (p->current_origin[2] <= p->end[2]){ p->next = free_particles; free_particles = p; weather_particles--; continue; } } // some weather particles flutter around as they fall if (p->type == PARTICLE_FLUTTERWEATHER) { // An accurate-looking model of particle rotation is to model the // particle as a sphere rotating on a surface (or a circle on each // axis.) If the particle was a marble moving on some hypothetical // 3D tabletop, how many degrees in each direction has it rotated // since it was spawned? float circumference; vec3_t distance; // Use a slightly larger radius so it rotates slower. circumference = 2.0*M_PI*(3.5*p->current_scale); VectorSubtract (p->current_origin, p->org, distance); VectorScale (distance, 360.0/circumference, p->angle); } p->next = NULL; if (!tail) active = tail = p; else { tail->next = p; tail = p; } if (p->current_alpha > 1.0) p->current_alpha = 1; for (i=0;ilights[i]; if (plight->isactive && !p->fromsustainedeffect) { light = plight->light*p->current_alpha*2.0 + plight->lightvel*time; V_AddLight (p->current_origin, light, plight->lightcol[0], plight->lightcol[1], plight->lightcol[2]); } } // hack a scale up to keep particles from disapearing p->dist = ( p->current_origin[0] - r_origin[0] ) * vpn[0] + ( p->current_origin[1] - r_origin[1] ) * vpn[1] + ( p->current_origin[2] - r_origin[2] ) * vpn[2]; if (p->type != PARTICLE_CHAINED && p->dist < 0) continue; else if (p->dist >= 40) p->dist = 2 + p->dist * 0.004; else p->dist = 2; if ((p->type == PARTICLE_CHAINED && true) != (p->chain_prev && true)) continue; if (p->type == PARTICLE_CHAINED && p->chain_prev) { vec3_t span, delta; VectorSubtract (p->current_origin, p->chain_prev->current_origin, span); VectorSubtract (r_origin, p->current_origin, delta); CrossProduct (span, delta, p->current_pspan); VectorNormalize (p->current_pspan); VectorScale (p->current_pspan, p->dist*p->current_scale, p->current_pspan); } V_AddParticle (p); } active_particles = active; } /* ============== CL_EntityEvent An entity has just been parsed that has an event value the female events are there for backwards compatability ============== */ extern struct sfx_s *cl_sfx_footsteps[4]; extern struct sfx_s *cl_sfx_metal_footsteps[4]; //Knightmare- modified by Irritant /* =============== CL_Footsteps Plays appropriate footstep sound depending on surface flags of the ground surface. Since this is a replacement for plain Jane EV_FOOTSTEP, we already know the player is definitely on the ground when this is called. =============== */ void CL_FootSteps (entity_state_t *ent, qboolean loud) { trace_t tr; vec3_t end; int r; int surface; struct sfx_s *stepsound; float volume = 0.5; r = (rand()&3); VectorCopy(ent->origin,end); end[2] -= 64; tr = CL_PMSurfaceTrace (ent->origin,NULL,NULL,end,MASK_SOLID | MASK_WATER); if (!tr.surface) return; surface = tr.surface->flags; switch (surface) { case SURF_TRANS66: case SURF_TRANS33|SURF_TRANS66: //all metal grates in AA have these flags set stepsound = cl_sfx_metal_footsteps[r]; break; default: stepsound = cl_sfx_footsteps[r]; break; } volume = 1.0; S_StartSound (NULL, ent->number, CHAN_BODY, stepsound, volume, ATTN_NORM, 0); } void CL_WaterWade (entity_state_t *ent) { particle_t *p; trace_t tr; vec3_t end, angle; int j; S_StartSound (NULL, ent->number, CHAN_BODY, S_RegisterSound("player/wade1.wav"), 1, ATTN_NORM, 0); VectorCopy(ent->origin,end); end[2] -= 64; tr = CL_PMSurfaceTrace (ent->origin,NULL,NULL,end,MASK_SOLID | MASK_WATER); if (!tr.surface) return; //draw rings that expand outward if(!(p = new_particle())) return; p->type = PARTICLE_RAISEDDECAL; p->image = r_splashtexture; p->blendsrc = GL_DST_COLOR; p->blenddst = GL_SRC_COLOR; p->scale = 1; p->scalevel = 8; p->color = 0 + (rand() & 1); VectorScale(tr.plane.normal, -1, angle); RotateForNormal(angle, p->angle); p->angle[ROLL] = rand() % 360; VectorAdd(tr.endpos, tr.plane.normal, p->org); for (j=0 ; j<3 ; j++) { p->org[j] = tr.endpos[j]; p->vel[j] = 0; } p->accel[0] = p->accel[1] = p->accel[2] = 0; p->alpha = .1; p->alphavel = -0.1 / (1 + frand()*0.3); } void CL_EntityEvent (entity_state_t *ent) { switch (ent->event) { case EV_ITEM_RESPAWN: S_StartSound (NULL, ent->number, CHAN_WEAPON, S_RegisterSound("items/respawn1.wav"), 1, ATTN_IDLE, 0); CL_ItemRespawnParticles (ent->origin); break; case EV_PLAYER_TELEPORT: S_StartSound (NULL, ent->number, CHAN_WEAPON, S_RegisterSound("misc/tele1.wav"), 1, ATTN_IDLE, 0); CL_TeleportParticles (ent->origin); break; case EV_FOOTSTEP: if (cl_footsteps->value) CL_FootSteps (ent, false); break; case EV_WADE: if (cl_footsteps->value) CL_WaterWade ( ent ); break; case EV_FALLSHORT: S_StartSound (NULL, ent->number, CHAN_AUTO, S_RegisterSound ("player/land1.wav"), 1, ATTN_NORM, 0); break; case EV_FALL: S_StartSound (NULL, ent->number, CHAN_AUTO, S_RegisterSound ("*fall2.wav"), 1, ATTN_NORM, 0); break; case EV_FALLFAR: S_StartSound (NULL, ent->number, CHAN_AUTO, S_RegisterSound ("*fall1.wav"), 1, ATTN_NORM, 0); break; } } /* ============== CL_ClearEffects ============== */ void CL_ClearEffects (void) { CL_ClearParticles (); CL_ClearDlights (); CL_ClearLightStyles (); CL_ClearClEntities(); } alien-arena-7.66+dfsg/source/client/snd_file.c0000600000175000017500000002502612161402010020314 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. Copyright (C) 2009 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * snd_file.c * * .wav and .ogg (vorbis) file support for OpenAL version * * Reference: * Vorbisfile API Reference (vorbisfile version 1.2.0 - 20070723) * from: http://www.xiph.org/vorbis/doc/vorbisfile/index.html */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "client.h" typedef struct { int rate; int width; int channels; // int loopstart; int samples; int dataofs; // chunk starts this many bytes from file start } pcminfo_t; /* return 0 for little endian, 1 for big endian */ int bigendian( void ) { long one = 1; return !(*((char*)(&one))); } /* == .WAV file parsing == */ byte *data_p; byte *iff_end; byte *last_chunk; byte *iff_data; int iff_chunk_len; short GetLittleShort( void ) { short val = 0; val = *data_p; val = val + ( *( data_p + 1 ) << 8 ); data_p += 2; return val; } int GetLittleLong( void ) { int val = 0; val = *data_p; val = val + ( *( data_p + 1 ) << 8 ); val = val + ( *( data_p + 2 ) << 16 ); val = val + ( *( data_p + 3 ) << 24 ); data_p += 4; return val; } void FindNextChunk( char *name ) { while( 1 ) { data_p = last_chunk; if( data_p >= iff_end ) { // didn't find the chunk data_p = NULL; return; } data_p += 4; iff_chunk_len = GetLittleLong(); if( iff_chunk_len < 0 ) { data_p = NULL; return; } data_p -= 8; last_chunk = data_p + 8 + ( ( iff_chunk_len + 1 ) & ~1 ); if( !strncmp( (const char *)data_p, name, 4 ) ) return; } } void FindChunk( char *name ) { last_chunk = iff_data; FindNextChunk( name ); } /* ============ ReadWavFile ============ */ qboolean ReadWavFile( const char *name, byte *wav, int wavlength, pcminfo_t *info ) { int format; int samples; memset( info, 0, sizeof(pcminfo_t) ); if( !wav ) return false; iff_data = wav; iff_end = wav + wavlength; // find "RIFF" chunk FindChunk( "RIFF" ); if( !( data_p && !strncmp( (const char *)data_p + 8, "WAVE", 4 ) ) ) { Com_DPrintf( "%s: Missing RIFF/WAVE chunks\n", name ); return false; } // get "fmt " chunk iff_data = data_p + 12; FindChunk( "fmt " ); if( !data_p ) { Com_DPrintf( "%s: Missing fmt chunk\n", name ); return false; } data_p += 8; format = GetLittleShort(); if( format != 1 ) // format 1 is PCM data, { Com_DPrintf( "%s: audio format %i not supported\n", name, format ); return false; } info->channels = GetLittleShort(); info->rate = GetLittleLong(); data_p += 4 + 2; info->width = GetLittleShort(); if( info->width != 8 && info->width != 16 ) { Com_DPrintf( "%s: %i bits-per-sample not supported\n", name, info->width ); return false; } info->width /= 8; // "cue " chunk handling removed, no need for it with OpenAL // find data chunk FindChunk( "data" ); if( !data_p ) { Com_DPrintf( "%s: Missing data chunk\n", name ); return false; } data_p += 4; samples = GetLittleLong() / info->width; info->samples = samples; info->dataofs = data_p - wav; if ( (info->width == 2) && bigendian() ) { /* for big-endian byte swap little-endian 16-bit samples */ short *psample = (short*)data_p; while ( samples-- ) { *psample++ = GetLittleShort(); /* note: increments data_p */ } } return true; } /* * Ogg/Vorbis Buffer I/O */ /* typedef struct { size_t (*read_func) (void *ptr, size_t size, size_t nmemb, void *datasource); int (*seek_func) (void *datasource, ogg_int64_t offset, int whence); int (*close_func) (void *datasource); long (*tell_func) (void *datasource); } ov_callbacks; */ typedef struct ovbfr_s { byte *pdata; size_t offset; size_t length; } ovbfr_t; size_t ovbfr_read(void *ptr, size_t size, size_t nmemb, void *datasource) { size_t bytes_remaining; size_t byte_count; size_t nmemb_read; ovbfr_t *pbfr = (ovbfr_t *)datasource; byte_count = size * nmemb; bytes_remaining = pbfr->length - pbfr->offset; nmemb_read = nmemb; if ( bytes_remaining < byte_count ) { nmemb_read = bytes_remaining / size ; byte_count = size * nmemb_read; } memcpy( ptr, pbfr->pdata + pbfr->offset , byte_count ); pbfr->offset += byte_count; return nmemb_read; } int ovbfr_seek(void *datasource, ogg_int64_t offset, int whence) { ovbfr_t *pbfr = (ovbfr_t *)datasource; switch( whence ) { case SEEK_SET: break; case SEEK_CUR: offset += pbfr->offset; break; case SEEK_END: offset += pbfr->length; break; default: return -1; break; } if( offset < 0 || offset > pbfr->length ) return -1; pbfr->offset = offset; return 0; } /* No need for a 'fclose' function int ovbfr_close(void *datasource) { ovbfr_t *pbfr = (ovbfr_t *)datasource; return 0; } */ long ovbfr_tell( void *datasource ) { ovbfr_t *pbfr = (ovbfr_t *)datasource; return pbfr->offset; } // function pointers for Ogg Vorbis file-like io ov_callbacks ovbfr_callbacks = { ovbfr_read, ovbfr_seek, NULL, ovbfr_tell }; /* ============ ReadVorbisFile ============ */ qboolean ReadVorbisFile( const char *name, byte *pdata, int filelength, pcminfo_t *info, byte **pcmbfr ) { int result; ogg_int64_t samples; vorbis_info *vi; OggVorbis_File vf; ovbfr_t ovbfr; size_t pcmbfr_size; char *pcmbfr_pdata; char *pdest; size_t bytes_remaining; long read_result; int bitstream; int bigendianp; Com_DPrintf("ReadVorbisFile: %s\n", name ); memset( info, 0, sizeof(pcminfo_t) ); // clear return data *pcmbfr = NULL; info->width = 2; // always 16-bit ovbfr.pdata = pdata; // open the Ogg Vorbis file i/o buffer ovbfr.offset = 0; ovbfr.length = filelength; result = ov_open_callbacks( &ovbfr, &vf, NULL, 0, ovbfr_callbacks ); Com_DPrintf("..result: %i\n", result); vi = ov_info( &vf, -1 ); info->channels = vi->channels; info->rate = vi->rate; Com_DPrintf("..channels: %i, rate: %li\n", vi->channels, vi->rate ); samples = ov_pcm_total( &vf, -1 ); info->samples = samples; Com_DPrintf("..samples: %li\n", samples ); bytes_remaining = pcmbfr_size = info->samples * info->channels * info->width; if ( pcmbfr_size > 0 ) { pdest = pcmbfr_pdata = (char *)Z_Malloc( pcmbfr_size ); if ( pdest == NULL ) { // unable to allocate buffer for decoded pcm data Com_DPrintf("Memory allocation error: decode buffer for %s.\n", name ); result = ov_clear( &vf ); // close Ogg Vorbis read/decode return false; } } else { Com_DPrintf("File size or format error: %s\n", name ); result = ov_clear( &vf ); // close Ogg Vorbis read/decode return false; } bigendianp = bigendian(); do { // decode Ogg Vorbis data to host endian, 16-bit, signed PCM data read_result = ov_read( &vf, pdest, bytes_remaining, bigendianp, 2, 1, &bitstream ); if ( read_result > 0 ) { bytes_remaining -= (size_t)read_result; pdest += read_result; } else { switch( read_result ) { case 0: // premature end of file Com_DPrintf("ov_read(): file size error, %s \n", name ); break; case OV_HOLE: // interruption in data Com_DPrintf("ov_read(): OV_HOLE error, %s \n", name ); break; case OV_EBADLINK: // invalid stream section, or corrupt data Com_DPrintf("ov_read(): OV_EBADLINK error, %s \n", name ); break; default: Com_DPrintf("ov_read(): invalid return value, %s\n", name ); break; } Z_Free( pcmbfr_pdata ); result = ov_clear( &vf ); // close Ogg Vorbis read/decode return false; } } while ( bytes_remaining > 0 ); result = ov_clear( &vf ); // close Ogg Vorbis read/decode *pcmbfr = (byte *)pcmbfr_pdata; // return the decoded buffer return true; } /* == S_LoadSound() creates a buffer containing PCM data, 8- or 16-bit, mono or stereo. stereo samples are left-channel first OUTPUTS: readbfr : the whole file, caller must FS_FileFree() this pcmdata : start of PCM data, for transfer to OpenAL buffer channels : 1=mono, 2=stereo bytewidth : 1=8-bit, 2=16-bit samplerate : samples-per-second (aka, frequency) byte_count : number of bytes of PCM data == */ qboolean S_LoadSound( char *filename, // in qboolean ogg_substitute, // in void** filebfr, // out void** pcmbfr, // out int *bytewidth, // out int *channels, // out int *samplerate, // out size_t *byte_count // out ) { byte *data; // for buffer allocated by FS_LoadFile byte *decoded_data; // for buffer allocated by ReadVorbisFile int size; pcminfo_t info; qboolean success; char *pfile_ext; // clear return values *filebfr = NULL; *pcmbfr = NULL; *channels = 0; *bytewidth = 0; *samplerate = 0; *byte_count = 0; if( ogg_substitute ) { // .wav => .ogg if .ogg exists if ( !Q_strncasecmp( (pfile_ext = &filename[ strlen(filename)-4 ]), ".wav", 4) ) { // look for .ogg alternative, by mangling the filename strncpy( pfile_ext, ".ogg", 4 ); if ( !FS_FileExists( filename ) ) { // no .ogg alternative, unmangle strncpy( pfile_ext, ".wav", 4 ); } } } // load sound file from game directories size = FS_LoadFile( (char*)filename, (void **) &data ); if( !data ) { Com_DPrintf( "Could not load %s\n", filename ); return false; } if ( !Q_strncasecmp( &filename[ strlen(filename)-4 ], ".ogg", 4) ) { success = ReadVorbisFile( filename, data, size, &info, &decoded_data ); FS_FreeFile( data ); // free the file image buffer if ( !success ) { Com_DPrintf("Could not decode %s\n", filename ); return false; } // return values *filebfr = decoded_data; *pcmbfr = decoded_data; // return values *channels = info.channels; *bytewidth = info.width; *samplerate = info.rate; *byte_count = info.samples * info.channels * info.width; } else { success = ReadWavFile( filename, data, size, &info ); if( !success ) { FS_FreeFile( data ); // discard sound data return false; } // return values *filebfr = data; *pcmbfr = data + info.dataofs; // return values *channels = info.channels; *bytewidth = info.width; *samplerate = info.rate; *byte_count = info.samples * info.width; } return true; } alien-arena-7.66+dfsg/source/client/cl_updates.c0000600000175000017500000001627712161402010020664 0ustar zero79zero79/* Copyright (C) 2011 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #if defined HAVE_UNISTD_H #include #endif #include #include "curl/curl.h" #include "client.h" extern cvar_t *cl_latest_game_version_url; static char versionstr[32]; static size_t versionstr_sz = 0; struct dotted_triple { unsigned long major; unsigned long minor; unsigned long point; }; static struct dotted_triple this_version; static struct dotted_triple latest_version; static char update_notice[256]; /** * * valid dotted version numbers * double <0..99>.<0..99> (.point is 0) * triple <0..99>.<0..99>.<1..99> * with the exceptions: 0.0 and 0.0.d are not valid * * @param vstring string from server * @param version_out parsed dotted triple output * @return true if valid, false otherwise */ static qboolean parse_version( const char* vstring, struct dotted_triple *version_out ) { char* pch_start; char* pch_end; qboolean valid_version = false; unsigned long major; unsigned long minor; unsigned long point; pch_start = (char*)vstring; if ( isdigit( *pch_start ) ) { major = strtoul( vstring, &pch_end, 10 ); if ( major <= 99UL && *pch_end == '.' ) { pch_start = pch_end + 1; if ( isdigit( *pch_start ) ) { minor = strtoul( pch_start, &pch_end, 10 ); if ( ((major >= 1UL && minor >= 0UL) || (major == 0UL && minor >= 1UL)) && minor <= 99UL ) { if ( *pch_end == '.' ) { pch_start = pch_end + 1; if ( isdigit( *pch_start ) ) { point = strtoul( pch_start, &pch_end, 10 ); if ( point >= 1UL && point <= 99UL && *pch_end == '\0') { /* valid x.y.z */ version_out->major = major; version_out->minor = minor; version_out->point = point; valid_version = true; } } } else if ( *pch_end == '\0' ) { /* valid x.y */ version_out->major = major; version_out->minor = minor; version_out->point = 0UL; valid_version = true; } } } } } return valid_version; } /** * Compare dotted triple structs * * @param version1 Dotted triple struct * @param version2 Dotted triple struct * @return True if version2 newer than version1, false otherwise * */ static qboolean compare_version (const struct dotted_triple *version1, const struct dotted_triple *version2) { if ( version1->major < version2->major ) { return true; } if ( version1->major == version2->major && version1->minor < version2->minor ) { return true; } if ( version1->major == version2->major && version1->minor == version2->minor && version1->point < version2->point ) { return true; } return false; } /** * generate a version update notice, or nul the string * see VersionUpdateNotice() below * * @param vstring the latest version from the server * */ static void update_version( const char* vstring ) { qboolean valid_version; qboolean update_message = false; valid_version = parse_version( vstring, &latest_version ); if ( valid_version ) { /* valid from server */ valid_version = parse_version( VERSION, &this_version ); if ( valid_version ) { /* local should always be valid */ update_message = compare_version (&this_version, &latest_version); } } if ( update_message ) { char this_string[16]; char latest_string[16]; if ( latest_version.point == 0UL ) { /* x.y */ Com_sprintf( latest_string, sizeof(latest_string), "%d.%d", latest_version.major, latest_version.minor ); } else { /* x.y.z */ Com_sprintf( latest_string, sizeof(latest_string), "%d.%d.%d", latest_version.major, latest_version.minor, latest_version.point ); } if ( this_version.point == 0UL ) { /* x.y */ Com_sprintf( this_string, sizeof(this_string), "%d.%d", this_version.major, this_version.minor ); } else { /* x.y.z */ Com_sprintf( this_string, sizeof(this_string), "%d.%d.%d", this_version.major, this_version.minor, this_version.point ); } Com_sprintf( update_notice, sizeof(update_notice), "version %s available (%s currently installed)", latest_string, this_string ); } else { /* not available */ update_notice[0] = '\0'; } } static size_t write_data(const void *buffer, size_t size, size_t nmemb, void *userp) { size_t bytecount = size*nmemb; if ( (versionstr_sz + bytecount) < sizeof(versionstr) ) { memcpy( &versionstr[versionstr_sz], buffer, bytecount ); versionstr_sz += bytecount; versionstr[versionstr_sz] = 0; } else { bytecount = 0; // will cause curl to return an error } return bytecount; } void getLatestGameVersion( void ) { char url[128]; CURL* easyhandle; memset( versionstr, 0, sizeof(versionstr) ); versionstr_sz = 0; easyhandle = curl_easy_init() ; Com_sprintf(url, sizeof(url), "%s", cl_latest_game_version_url->string); if (curl_easy_setopt( easyhandle, CURLOPT_URL, url ) != CURLE_OK) return ; // time out in 5s if (curl_easy_setopt(easyhandle, CURLOPT_CONNECTTIMEOUT, 5) != CURLE_OK) return ; if (curl_easy_setopt( easyhandle, CURLOPT_WRITEFUNCTION, write_data ) != CURLE_OK) return ; if (curl_easy_perform( easyhandle ) != CURLE_OK) return; (void)curl_easy_cleanup( easyhandle ); update_version( versionstr ); } /** * * @returns NULL if program is latest version, pointer to update notice otherwise */ char* VersionUpdateNotice( void ) { if ( update_notice[0] == '\0' ) return NULL; else return update_notice; } /** * * @param server_vstring the version string from a remote game server * @returns True if the the server is out of date or if the string is malformed, false otherwise. * * NOTE: getLatestGameVersion has to have been called at least once before * calling this! */ qboolean serverIsOutdated (char *server_vstring){ char *end; struct dotted_triple server_version; qboolean valid_version; // have to get rid of everything after the first space memset( versionstr, 0, sizeof(versionstr) ); strncpy (versionstr, server_vstring, sizeof(versionstr)); end = strchr (versionstr, ' '); if (end != NULL) *end = '\0'; valid_version = parse_version( versionstr, &server_version ); // assume it's out of date if the version string is malformed if (!valid_version) return true; return compare_version (&server_version, &latest_version); } alien-arena-7.66+dfsg/source/client/qmenu.c0000600000175000017500000012165312204310130017660 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. Copyright (C) 2013 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "client.h" #include "qmenu.h" static void ItemName_Draw (menuaction_s *a, FNT_font_t font, const float *color); static void Action_Draw (menuaction_s *a, FNT_font_t font); static void Menu_DrawStatusBar( const char *string ); static void Menu_DrawToolTip (const menuitem_s *item); static void Label_Draw (menutxt_s *s, FNT_font_t font, const float *color); static void Slider_DoSlide( menuslider_s *s, int dir ); static void Slider_Draw (menuslider_s *s, FNT_font_t font); static void SpinControl_Draw (menulist_s *s, FNT_font_t font); static void SpinControl_DoSlide( menulist_s *s, int dir ); static void SubMenu_Draw (menuframework_s *s, FNT_font_t font); static void Menu_DrawHorizBar (const char *pathbase, float x, float y, float w, float base_size, float alpha); static void Menu_DrawVertBar (const char *pathbase, float x, float y, float h, float base_size, float alpha); void Menu_DrawBorder (menuframework_s *menu, const char *title, const char *prefix); static menuvec2_t Menu_GetBorderSize (menuframework_s *s); // dark color = same blue as icons, light color = white const float dark_color[4] = {0, 1, 200.0f/255.0f, 1}; const float light_color[4] = {1, 1, 1, 1}; const float highlight_color[4] = {1, 1, 1, 0.95}; #define VID_WIDTH viddef.width #define VID_HEIGHT viddef.height int Menu_PredictSize (const char *str) { FNT_font_t font; font = FNT_AutoGet( CL_menuFont ); return FNT_PredictSize (font, str, true); } void ItemName_Draw (menuitem_s *a, FNT_font_t font, const float *color) { int text_x, text_y; unsigned int align, cmode; if (a->generic.namedraw != NULL) { a->generic.namedraw (a, font); return; } if (a->generic.name == NULL) return; text_x = Item_GetX (*a); text_y = Item_GetY (*a) + MenuText_UpperMargin (a, font->size); if ((a->generic.flags & QMF_BUTTON)) { int border_x, width; width = CHASELINK(a->generic.lsize).x+CHASELINK(a->generic.rsize).x; if (!a->generic.parent->horizontal) { align = FNT_ALIGN_CENTER; text_x = a->generic.parent->x + width/2; border_x = a->generic.parent->x; } else { align = FNT_ALIGN_RIGHT; border_x = text_x - width + RCOLUMN_OFFSET/2; } // HACK if (color == dark_color) Menu_DrawHorizBar ("menu/button_border", border_x, Item_GetY(*a)+2, width, font->height*2-4, a->generic.highlight_alpha*a->generic.highlight_alpha); } else if ( a->generic.flags & QMF_RIGHT_COLUMN ) { align = FNT_ALIGN_LEFT; } else { if (a->generic.parent->horizontal) { align = FNT_ALIGN_RIGHT; text_x += LCOLUMN_OFFSET; } else { align = FNT_ALIGN_LEFT; text_x = a->generic.parent->x; } } if ( a->generic.flags & QMF_STRIP_COLOR || color == highlight_color ) cmode = FNT_CMODE_TWO; else cmode = FNT_CMODE_QUAKE_SRS; Menu_DrawString ( text_x, text_y, a->generic.name, cmode, align, color ); } void Action_Draw (menuaction_s *a, FNT_font_t font) { if ( a->generic.itemdraw ) a->generic.itemdraw( a, font ); } void Field_Draw (menufield_s *f, FNT_font_t font) { char tempbuffer[128]=""; int x, y; y = Item_GetY (*f) + MenuText_UpperMargin (f, font->size); x = Item_GetX (*f) + RCOLUMN_OFFSET; strncpy( tempbuffer, f->buffer, f->generic.visible_length); Menu_DrawHorizBar ( "menu/slide_border", (float)x, (float)y-2.0, (float)(f->generic.visible_length*font->size)+4.0, (float)(font->size)+4.0, f->generic.highlight_alpha*f->generic.highlight_alpha ); menu_box.x = x+4; menu_box.y = y; menu_box.height = 0; menu_box.width = f->generic.visible_length*font->width; FNT_BoundedPrint (font, f->buffer, FNT_CMODE_QUAKE_SRS, FNT_ALIGN_LEFT, &menu_box, light_color); if ( cursor.menuitem == f ) { if ( ( ( int ) ( Sys_Milliseconds() / 300 ) ) & 1 ) Draw_StretchPic (menu_box.x + menu_box.width - font->size / 8, menu_box.y-1, font->size, font->size+4, "menu/field_cursor"); } } qboolean Field_Key (int key) { menufield_s *f; extern int keydown[]; f = cursor.menuitem; if (f == NULL || f->generic.type != MTYPE_FIELD || key > 127) return false; switch ( key ) { case K_KP_SLASH: key = '/'; break; case K_KP_MINUS: key = '-'; break; case K_KP_PLUS: key = '+'; break; case K_KP_HOME: key = '7'; break; case K_KP_UPARROW: key = '8'; break; case K_KP_PGUP: key = '9'; break; case K_KP_LEFTARROW: key = '4'; break; case K_KP_5: key = '5'; break; case K_KP_RIGHTARROW: key = '6'; break; case K_KP_END: key = '1'; break; case K_KP_DOWNARROW: key = '2'; break; case K_KP_PGDN: key = '3'; break; case K_KP_INS: key = '0'; break; case K_KP_DEL: key = '.'; break; } /* ** support pasting from the clipboard */ if ( ( toupper( key ) == 'V' && keydown[K_CTRL] ) || ( ( ( key == K_INS ) || ( key == K_KP_INS ) ) && keydown[K_SHIFT] ) ) { char *cbd; if ( ( cbd = Sys_GetClipboardData() ) != 0 ) { strtok( cbd, "\n\r\b" ); strncpy( f->buffer, cbd, f->length - 1 ); f->cursor = strlen( f->buffer ); free( cbd ); } return true; } switch ( key ) { case K_KP_LEFTARROW: case K_LEFTARROW: case K_BACKSPACE: if ( f->cursor > 0 ) { memmove( &f->buffer[f->cursor-1], &f->buffer[f->cursor], strlen( &f->buffer[f->cursor] ) + 1 ); f->cursor--; } break; case K_KP_DEL: case K_DEL: memmove( &f->buffer[f->cursor], &f->buffer[f->cursor+1], strlen( &f->buffer[f->cursor+1] ) + 1 ); break; case K_KP_ENTER: case K_ENTER: case K_ESCAPE: case K_TAB: return false; case K_SPACE: default: if ( !isdigit( key ) && ( f->generic.flags & QMF_NUMBERSONLY ) ) return false; { int maxlength = f->length; if (f->length > sizeof(f->buffer)-2 || f->length == 0) { maxlength = sizeof(f->buffer)-2; } if ( f->cursor < maxlength ) { f->buffer[f->cursor++] = key; f->buffer[f->cursor] = 0; } } } return true; } void _Menu_AddItem( menuframework_s *menu, menucommon_s *item ) { if ( menu->nitems < MAXMENUITEMS ) { menu->items[menu->nitems] = item; ( ( menucommon_s * ) menu->items[menu->nitems] )->parent = menu; menu->nitems++; } } // Returns true or false depending on whether the given item is selectable. static inline qboolean Menu_ItemSelectable (menuitem_s *item) { if (item->generic.type == MTYPE_NOT_INTERACTIVE) return false; if (item->generic.type == MTYPE_SUBMENU) return ((menuframework_s *)item)->enable_highlight; return true; } void Cursor_SelectItem (menuitem_s *item) { cursor.menuitem = item; if (item == NULL) { cursor.menulayer = -1; return; } cursor.menulayer = Cursor_GetLayer (); } // Returns the top level node of the menu tree that contains the item menuframework_s *Menu_GetItemTree (menuitem_s *item) { if (item->generic.parent == NULL) return (menuframework_s *)item; return Menu_GetItemTree ((menuitem_s *)item->generic.parent); } // Returns true if the current cursor item is within the specified menu tree. qboolean Menu_ContainsCursorItem (menuframework_s *menu) { menuitem_s *item; item = cursor.menuitem; if (item != NULL) { menuframework_s *menu2 = item->generic.parent; while (menu2 != NULL) { if (menu2 == menu) return true; menu2 = menu2->generic.parent; } } return false; } // Attempt to select the first reasonable menu item in the specified menu tree // as the cursor item. Returns false if unsuccessful (if there are no // selectable menu items within the menu or any of its submenus.) Does nothing // if the cursor item is already within the menu or one of its submenus. qboolean Cursor_SelectMenu (menuframework_s *menu) { int i; menuitem_s *item; if (Menu_ContainsCursorItem (menu)) return true; refreshCursorLink (); if (menu->default_cursor_selection != NULL) { if (Menu_ItemSelectable (menu->default_cursor_selection)) { Cursor_SelectItem (menu->default_cursor_selection); return true; } if (menu->default_cursor_selection->generic.type == MTYPE_SUBMENU) { if (Cursor_SelectMenu ((menuframework_s *)menu->default_cursor_selection)) return true; } } for (i = 0; i < menu->nitems; i++) { item = menu->items[i]; if (Menu_ItemSelectable (item)) { Cursor_SelectItem (item); return true; } if (item->generic.type == MTYPE_SUBMENU) { menuframework_s *sm = (menuframework_s *)item; if (sm->navagable && Cursor_SelectMenu (sm)) return true; } } return false; } // Find the index of the item within its parent menu. int Menu_ItemIndex (menuitem_s *item) { int ret; menuframework_s *menu; menu = item->generic.parent; for (ret = 0; ret < menu->nitems; ret++) { if (menu->items[ret] == item) return ret; } Com_Error (ERR_FATAL, "CAN'T HAPPEN: Item is not in its own parent menu!"); return 0; } // returns true if the item is a submenu that the cursor can advance "into." static qboolean CanAdvanceInto (menuitem_s *item, qboolean allow_capture) { if (item->generic.type != MTYPE_SUBMENU) return false; // if the submenu will "capture" the cursor, only advance into it if the // tab key has been pressed instead an arrow key. if (!allow_capture && (item->generic.flags & QMF_SUBMENU_CAPTURE)) return false; // selectable submenus aren't treated like submenus if (Menu_ItemSelectable (item)) return false; return true; } // returns true if the cursor can advance out of the submenu static qboolean CanAdvanceOutOf (menuframework_s *submenu, qboolean allow_capture) { // if the submenu has "captured" the cursor, only advance out of it if the // tab key has been pressed instead of an arrow key. if (!allow_capture && (submenu->generic.flags & QMF_SUBMENU_CAPTURE)) return false; return true; } // Selects either the next or the previous menu item. void Menu_AdvanceCursor (int dir, qboolean allow_capture) { int item_index; menuframework_s *menu; menuitem_s *item, *newitem; item = cursor.menuitem; if (item == NULL) return; menu = item->generic.parent; if (item->generic.type == MTYPE_VERT_SCROLLBAR) { menu->yscroll += 2*dir; if (menu->yscroll < 0) menu->yscroll = 0; if (menu->yscroll > menu->maxscroll) menu->yscroll = menu->maxscroll; return; } item_index = Menu_ItemIndex (item); do { item_index += dir; while (item_index < 0 || item_index >= menu->nitems) { menuframework_s *parent = menu->generic.parent; if (parent == NULL || !CanAdvanceOutOf (menu, allow_capture)) { item_index += menu->nitems; item_index %= menu->nitems; } else { item_index = Menu_ItemIndex ((menuitem_s *)menu) + dir; menu = parent; } } newitem = menu->items[item_index]; while (CanAdvanceInto (newitem, allow_capture)) { menu = (menuframework_s *)newitem; if (dir == 1) item_index = 0; else item_index = menu->nitems-1; newitem = menu->items[item_index]; } } while (!Menu_ItemSelectable (newitem)); Cursor_SelectItem (newitem); } void Menu_Center( menuframework_s *menu ) { menu->y = ( (int)VID_HEIGHT - Menu_TrueHeight(*menu) ) / 2; } int SpinControl_MaxLines (menulist_s *s) { int i; for (i = 0; s->itemnames[i]; i++) { if (strchr( s->itemnames[i], '\n' )) return 2; } return 1; } int SpinControl_MaxWidth (menulist_s *s) { char buffer[100]; int i; int ret = 0; for (i = 0; s->itemnames[i]; i++) { if ( !strchr( s->itemnames[i], '\n' ) ) { int npix = Menu_PredictSize (s->itemnames[i]); if (npix > ret) ret = npix; } else { int npix; strcpy( buffer, s->itemnames[i] ); *strchr( buffer, '\n' ) = 0; npix = Menu_PredictSize (buffer); if (npix > ret) ret = npix; strcpy( buffer, strchr( s->itemnames[i], '\n' ) + 1 ); npix = Menu_PredictSize (buffer); if (npix > ret) ret = npix; } } return ret; } static inline menuvec2_t Menu_Item_LeftSize (menucommon_s *self, FNT_font_t font) { menuvec2_t ret; ret.x = ret.y = 0; if (self->type == MTYPE_SUBMENU) { ret = Menu_GetBorderSize ((menuframework_s *)self); if (self->flags & QMF_SNUG_LEFT) ret.x += CHASELINK(self->parent->lwidth); return ret; } if (self->name && !(self->flags & QMF_RIGHT_COLUMN)) { ret.x = Menu_PredictSize (self->name); if (self->type != MTYPE_TEXT) ret.x -= LCOLUMN_OFFSET; } if ((self->flags & QMF_BUTTON)) { ret.y = 2*font->height; if (ret.x < CHASELINK(self->parent->lwidth) && !self->parent->horizontal) ret.x = CHASELINK(self->parent->lwidth); } else { ret.y = font->height; } return ret; } static inline menuvec2_t Menu_Item_RightSize (menucommon_s *self, FNT_font_t font) { menuvec2_t ret; ret.x = ret.y = 0; ret.y = font->height; if (self->name && (self->flags & QMF_RIGHT_COLUMN)) { ret.x = Menu_PredictSize (self->name); if (self->type != MTYPE_TEXT) ret.x += RCOLUMN_OFFSET; } if (self->visible_length != 0) ret.x += font->width * self->visible_length + RCOLUMN_OFFSET; switch ( self->type ) { case MTYPE_SLIDER: ret.x = font->width * LONGINPUT_SIZE + RCOLUMN_OFFSET; break; case MTYPE_FIELD: ret.y += 4; break; case MTYPE_SPINCONTROL: ret.x += SpinControl_MaxWidth ((menulist_s *)self); ret.y = SpinControl_MaxLines ((menulist_s *)self)*font->height; if (ret.y > font->height) ret.y += font->height-font->size; break; case MTYPE_SUBMENU: ret.y = Menu_TrueHeight(*(menuframework_s *)self); ret.x = CHASELINK(((menuframework_s *)self)->lwidth) + CHASELINK(((menuframework_s *)self)->rwidth); if (self->flags & QMF_SNUG_LEFT) ret.x -= CHASELINK(self->parent->lwidth); { menuvec2_t border = Menu_GetBorderSize ((menuframework_s*)self); if (ret.x < border.x + border.x/2) ret.x = border.x + border.x/2; ret.x += border.x; ret.y += border.y; } break; case MTYPE_ACTION: case MTYPE_TEXT: break; } if ((self->flags & QMF_BUTTON) && ret.x < CHASELINK(self->parent->rwidth) && !self->parent->horizontal) ret.x = CHASELINK(self->parent->rwidth); return ret; } /* ============= Menu_AutoArrange This section of code is responsible for taking a menu tree and arranging all the submenus and menu items on screen, in such a way that they fit the constraints imposed on them. I'm afraid this is complicated enough to justify a small essay. The reason this is so complicated is because of those constraints. Menu width, menu item x, and menu item y are all "linkable" attributes, meaning they can be linked together so they always have the same value. If updated in one place, the updates show up everywhere else. Here's the problem: these linkable attributes depend on each other, sometimes in complex ways. For example, take a table with two rows: ITEMA ITEMB ITEMC ITEMD ITEME ITEMF ITEMA and ITEMD's x-coordinates are linked, ITEMB and ITEME's x-coordinates are linked, etc. Now the easy way to do this would be to lay out the entirety of row 1, then the entirety of row 2. But suppose you have a case where ITEMA and ITEME are narrow, while ITEMD and ITEMB are wide? Here's what the table looks like before it's been laid out at all: [ITEMA][=ITEMB=][ITEMC] [=ITEMD=][ITEME][ITEMF] Laying out the first row goes well. The required amount of space is inserted between ITEMA and ITEMB, and because ITEMB and ITEME are linked, that change is propagated to the second row automatically. Likewise for the space between ITEMB and ITEMC, and the propagation from ITEMC to ITEMF. [ITEMA]---[=ITEMB=]---[ITEMC] [=ITEMD=]-[ITEME]-----[ITEMF] Then the second row is laid out. Since ITEMD is wider, the space between it and ITEME isn't enough, so ITEME has to be moved for the space to be sufficient. Because ITEMF is still far enough away from ITEME, it doesn't get moved, and as a result, ITEMC doesn't get moved either! ITEMC's position is no longer valid, so the first row has to be laid out again. [ITEMA]-----[=ITEMB=]-[ITEMC] [=ITEMD=]---[ITEME]---[ITEMF] To insure a proper layout, Menu_Arrange is simply called over and over again until no more movement is detected. Actually, the number of calls is limited at 5 to prevent things from getting too out of hand. ============= */ static int changes = 0; #define MENU_INCREASELINK(l,v) \ {\ if ((l).status == linkstatus_link) \ {\ if (*((l).ptr) < v) \ { \ changes++; \ *((l).ptr) = v; \ } \ else \ v = *((l).ptr); \ }\ else if (reset || (l).val < v) \ {\ changes++;\ (l).val = v; \ }\ else \ {\ v = (l).val;\ }\ } void Menu_Arrange (menuframework_s *menu, qboolean reset, FNT_font_t font) { int i, x, y; int itemheight, horiz_height; menucommon_s *item; // TODO: move this into its own function? if (!menu->initialized) { menu->initialized = true; menu->vertical_scrollbar.parent = menu; menu->vertical_scrollbar.type = MTYPE_VERT_SCROLLBAR; } x = y = 0; horiz_height = 0; if (reset) { RESETLINK (menu->rwidth, 0); RESETLINK (menu->lwidth, 0); RESETLINK (menu->height, 0); } for (i = 0; i < menu->nitems; i++ ) { int lwidth; int rwidth; item = ((menucommon_s * )menu->items[i]); if (item->type == MTYPE_SUBMENU) { menuvec2_t border; int ntries; int old_nchanges = changes; border = Menu_GetBorderSize ((menuframework_s*)item); y += border.y; MENU_INCREASELINK (item->y, y); y -= border.y; Menu_Arrange ((menuframework_s *)item, reset, font); ntries = 0; // attempt to keep repetition localized where possible while (old_nchanges != changes && ++ntries < 3) { old_nchanges = changes; Menu_Arrange ((menuframework_s *)item, false, font); } } else MENU_INCREASELINK (item->y, y); if (item->namesizecallback) CHASELINK(item->lsize) = item->namesizecallback (item, font); else CHASELINK(item->lsize) = Menu_Item_LeftSize (item, font); if (item->itemsizecallback) CHASELINK(item->rsize) = item->itemsizecallback (item, font); else CHASELINK(item->rsize) = Menu_Item_RightSize (item, font); itemheight = Item_GetHeight(*((menuitem_s *)item)); lwidth = CHASELINK(item->lsize).x; rwidth = CHASELINK(item->rsize).x; if (menu->horizontal) { if (horiz_height < itemheight) horiz_height = itemheight; } else y += itemheight; if (menu->horizontal) { if (i == 0) MENU_INCREASELINK (menu->lwidth, lwidth) else x += lwidth + RCOLUMN_OFFSET - LCOLUMN_OFFSET; MENU_INCREASELINK (item->x, x) x += rwidth; } else { MENU_INCREASELINK (menu->lwidth, lwidth); MENU_INCREASELINK (menu->rwidth, rwidth); } } if (menu->horizontal) { MENU_INCREASELINK (menu->rwidth, x); MENU_INCREASELINK (menu->height, horiz_height); } else MENU_INCREASELINK (menu->height, y); if (!menu->horizontal && menu->maxlines != 0 && menu->maxlines < menu->nitems) menu->maxheight = CHASELINK (((menucommon_s*)menu->items[menu->maxlines])->y); menu->maxscroll = CHASELINK(menu->height) - menu->maxheight; menu->scroll_range = (float)menu->maxheight - font->size/2.0; menu->scrollbar_size = menu->scroll_range - menu->maxscroll; if (menu->scrollbar_size < font->size) menu->scrollbar_size = font->size; menu->scroll_top = (float)menu->y+font->size/4.0; } void Menu_AutoArrange (menuframework_s *menu) { int ntries; FNT_font_t font; font = FNT_AutoGet( CL_menuFont ); Menu_Arrange (menu, true, font); ntries = 0; while (changes && ++ntries < 5) { changes = 0; Menu_Arrange (menu, false, font); } } static inline qboolean Item_ScrollVisible (menuitem_s *item) { menuframework_s *menu = item->generic.parent; // scrolling disabled on this item if (menu->maxheight == 0) return true; if (CHASELINK(item->generic.y)-menu->yscroll < 0) return false; if (CHASELINK(item->generic.y)-menu->yscroll + Item_GetHeight(*item) > menu->maxheight) return false; return true; } void Item_UpdateHighlightAlpha (menuitem_s *item) { if (cursor.menuitem == item) { item->generic.highlight_alpha += cls.frametime*0.5f; if (item->generic.highlight_alpha > 1.0) item->generic.highlight_alpha = 1.0; } else { item->generic.highlight_alpha -= cls.frametime*0.5f; if (item->generic.highlight_alpha < 0.9) item->generic.highlight_alpha = 0.9; } } void Menu_Draw (menuframework_s *menu, FNT_font_t font) { int i; menuitem_s *item; if (menu->bordertexture != NULL) Menu_DrawBorder (menu, menu->bordertitle, menu->bordertexture); // may get covered up later by a higher-priority status bar if (menu->num_apply_pending != 0) Menu_DrawStatusBar ("Some changes must be applied!\n"); else Menu_DrawStatusBar (menu->statusbar); Item_UpdateHighlightAlpha ((menuitem_s *)&menu->vertical_scrollbar); /* ** draw contents */ for ( i = 0; i < menu->nitems; i++ ) { item = ((menuitem_s * )menu->items[i]); if (!Item_ScrollVisible (item)) continue; Item_UpdateHighlightAlpha (item); // TODO: cleaner method if (item->generic.type == MTYPE_NOT_INTERACTIVE) { if (item->generic.itemdraw != NULL) item->generic.itemdraw (item, font); if (item->generic.namedraw != NULL) item->generic.namedraw (item, font); else Label_Draw ((menutxt_s *) menu->items[i], font, dark_color); } else if (item->generic.type != MTYPE_SUBMENU) { ItemName_Draw ((menuitem_s *) menu->items[i], font, dark_color); } switch ( item->generic.type ) { case MTYPE_FIELD: Field_Draw ((menufield_s *) menu->items[i], font); break; case MTYPE_SLIDER: Slider_Draw ((menuslider_s *) menu->items[i], font); break; case MTYPE_SPINCONTROL: SpinControl_Draw ((menulist_s *) menu->items[i], font); break; case MTYPE_ACTION: Action_Draw ((menuaction_s *) menu->items[i], font); break; case MTYPE_TEXT: break; case MTYPE_SUBMENU: SubMenu_Draw ((menuframework_s *) menu->items[i], font); break; } } } static void Cursor_MouseSelectItem (menuitem_s *item) { menuitem_s *lastitem = (menuitem_s *)cursor.menuitem; // Selected a new item-- reset double-click count if (lastitem != item) { memset (cursor.buttonclicks, 0, sizeof(cursor.buttonclicks)); memset (cursor.buttontime, 0, sizeof(cursor.buttontime)); } Cursor_SelectItem (item); cursor.mouseaction = false; } void Menu_AssignCursor (menuframework_s *menu) { int i; float right; menuitem_s *item; if (!menu->navagable || !cursor.mouseaction) return; right = menu->x + CHASELINK(menu->rwidth) + CHASELINK(menu->lwidth); if (menu->maxheight != 0 && CHASELINK(menu->height) > menu->maxheight && cursor.x > right) { // select the scrollbar item = &menu->vertical_scrollbar; Cursor_MouseSelectItem (item); } else for ( i = 0; i < menu->nitems; i++ ) { int mincoord, maxcoord; item = ((menuitem_s * )menu->items[i]); if (!item) continue; if (menu->horizontal) { maxcoord = mincoord = Item_GetX (*item); maxcoord += CHASELINK(item->generic.rsize).x; mincoord -= CHASELINK(item->generic.lsize).x; if (cursor.x < mincoord || cursor.x > maxcoord) continue; } else { maxcoord = mincoord = Item_GetY (*item); maxcoord += Item_GetHeight (*item); if (cursor.y < mincoord || cursor.y > maxcoord) continue; } if (item->generic.type == MTYPE_SUBMENU && ((menuframework_s *)item)->navagable) { // navagable menus should have at least one selectable item in // them. Menu_AssignCursor ((menuframework_s *)item); return; } if (!Menu_ItemSelectable (item)) continue; // We've found a valid candiate for selection Cursor_MouseSelectItem (item); return; } } void Menu_DrawHighlightItem (menuitem_s *item); // Draws only the item labels, and draws everything highlighted. For cases // where the menu itself is being used as a sort of complex widget. void Menu_DrawHighlightMenu (menuframework_s *menu, FNT_font_t font) { int i; menuitem_s *item; for ( i = 0; i < menu->nitems; i++ ) { item = ((menuitem_s * )menu->items[i]); Menu_DrawHighlightItem (item); } } void Menu_DrawHighlightItem (menuitem_s *item) { FNT_font_t font = FNT_AutoGet (CL_menuFont); if (!Item_ScrollVisible (item)) return; if (item->generic.cursorcallback) item->generic.cursorcallback (item, font); // highlighting if (item->generic.cursordraw != NULL) { item->generic.cursordraw( item, font ); return; } if (item->generic.namedraw != NULL) return; if (item->generic.type == MTYPE_SUBMENU && ((menuframework_s *)item)->enable_highlight) Menu_DrawHighlightMenu ((menuframework_s *)item, font); else if (item->generic.type == MTYPE_TEXT) Label_Draw (item, font, highlight_color); else ItemName_Draw (item, font, highlight_color); } void Menu_DrawHighlight (void) { menuframework_s *menu; menuitem_s *item = cursor.menuitem; if (item == NULL || item->generic.type == MTYPE_VERT_SCROLLBAR) return; menu = item->generic.parent; // Scrolling - make sure the selected item is entirely on screen if // possible. TODO: add smoothing? if (menu->maxheight != 0) { int newscroll; int y = CHASELINK(item->generic.y); newscroll = clamp (menu->yscroll, y + Item_GetHeight(*item) - menu->maxheight, y); if (newscroll != menu->yscroll) { menu->yscroll = newscroll; return; // we'll draw it next frame - not in the right position now } } if (item->generic.cursordraw == NULL && menu->cursordraw != NULL) { menu->cursordraw( menu ); return; } if (item->generic.type == MTYPE_SUBMENU) Menu_DrawBorder ((menuframework_s *)item, NULL, "menu/sm_"); // no actions you can do with these types, so use them only for scrolling // and then return if (item->generic.type == MTYPE_NOT_INTERACTIVE) return; Menu_DrawHighlightItem (item); if ( item->generic.statusbar ) Menu_DrawStatusBar( item->generic.statusbar ); if ( item->generic.tooltip ) Menu_DrawToolTip (item); } // needed because global_menu_xoffset must be added to only the top level of // any menu tree. void Screen_Draw (menuframework_s *screen, menuvec2_t offset) { FNT_font_t font = FNT_AutoGet (CL_menuFont); screen->x = offset.x; //TODO: figure out what to do about centered windows /* screen->y = offset.y;*/ Menu_AutoArrange (screen); Menu_Draw (screen, font); } static menuvec2_t Menu_GetBorderSize (menuframework_s *s) { char topcorner_name[MAX_QPATH]; menuvec2_t ret; FNT_font_t font; font = FNT_AutoGet( CL_menuFont ); ret.x = ret.y = 0; if (s->bordertexture != NULL) { Com_sprintf (topcorner_name, MAX_QPATH, "%stopcorner.tga", s->bordertexture); Draw_GetPicSize (&ret.x, &ret.y, topcorner_name ); ret.x = (int)((float)ret.x/64.0*(float)font->size*4.0); ret.y = (int)((float)ret.y/64.0*(float)font->size*4.0); ret.x -= font->size; ret.y -= font->size; } return ret; } void Menu_DrawBox (int x, int y, int w, int h, float alpha, const char *title, const char *prefix) { char topcorner_name[MAX_QPATH]; char bottomcorner_name[MAX_QPATH]; char top_name[MAX_QPATH]; char bottom_name[MAX_QPATH]; char side_name[MAX_QPATH]; char background_name[MAX_QPATH]; int _tile_w, _tile_h; float tile_w, tile_h; FNT_font_t font; font = FNT_AutoGet( CL_menuFont ); Com_sprintf (topcorner_name, MAX_QPATH, "%stopcorner.tga", prefix); Com_sprintf (bottomcorner_name, MAX_QPATH, "%sbottomcorner.tga", prefix); Com_sprintf (top_name, MAX_QPATH, "%stop.tga", prefix); Com_sprintf (bottom_name, MAX_QPATH, "%sbottom.tga", prefix); Com_sprintf (side_name, MAX_QPATH, "%sside.tga", prefix); Com_sprintf (background_name, MAX_QPATH, "%sbackground.tga", prefix); // assume all tiles are the same size Draw_GetPicSize (&_tile_w, &_tile_h, topcorner_name ); tile_w = (float)_tile_w/64.0*(float)font->size*4.0; tile_h = (float)_tile_h/64.0*(float)font->size*4.0; // make room for the scrollbar if (!strcmp (prefix, "menu/sm_")) { w += font->size; x -= font->size/2; } if (w < tile_w) { w = tile_w; } if (h < tile_h) { h = tile_h; } // hacky stuff to make things look right if (strcmp (prefix, "menu/sm_")) { x -= tile_w/2; w += tile_w; } if (!strcmp (prefix, "menu/m_")) { y -= tile_h/8; if (h > tile_h) h += tile_h/4; } Draw_AlphaStretchTilingPic( x-tile_w/2, y-tile_h/2, tile_w, tile_h, topcorner_name, alpha ); Draw_AlphaStretchTilingPic( x+w+tile_w/2, y-tile_h/2, -tile_w, tile_h, topcorner_name, alpha ); Draw_AlphaStretchTilingPic( x-tile_w/2, y+h-tile_h/2, tile_w, tile_h, bottomcorner_name, alpha ); Draw_AlphaStretchTilingPic( x+w+tile_w/2, y+h-tile_h/2, -tile_w, tile_h, bottomcorner_name, alpha ); if (w > tile_w) { Draw_AlphaStretchTilingPic( x+tile_w/2, y-tile_h/2, w-tile_w, tile_h, top_name, alpha ); Draw_AlphaStretchTilingPic( x+tile_w/2, y+h-tile_h/2, w-tile_w, tile_h, bottom_name, alpha ); } if (h > tile_h) { Draw_AlphaStretchTilingPic( x-tile_w/2, y+tile_h/2, tile_w, h-tile_h, side_name, alpha ); Draw_AlphaStretchTilingPic( x+w+tile_w/2, y+tile_h/2, -tile_w, h-tile_h, side_name, alpha ); if (w > tile_w) Draw_AlphaStretchTilingPic( x+tile_w/2, y+tile_h/2, w-tile_w, h-tile_h, background_name, alpha ); } if (title != NULL) { int i; int textwidth = Menu_PredictSize (title); Menu_DrawHorizBar ("menu/slide_border", x+w/2-textwidth/2-2, y-font->size-2, textwidth+4, font->size+4, 1); // Redraw multiple times to get a bold effect for (i = 0; i < 4; i++) Menu_DrawString (x+w/2, y-font->size, title, FNT_CMODE_QUAKE, FNT_ALIGN_CENTER, highlight_color); } } void Menu_DrawVertBar (const char *pathbase, float x, float y, float h, float base_size, float alpha) { char scratch[MAX_QPATH]; Com_sprintf( scratch, sizeof( scratch ), "%s%s", pathbase, "_end"); Draw_AlphaStretchTilingPic (x, y-base_size/2.0, base_size, base_size, scratch, alpha); Draw_AlphaStretchTilingPic (x+base_size, y+h+base_size/2.0, -base_size, -base_size, scratch, alpha); if (h > base_size) Draw_AlphaStretchTilingPic (x, y+base_size/2.0, base_size, h-base_size, pathbase, alpha); } void Menu_DrawHorizBar (const char *pathbase, float x, float y, float w, float base_size, float alpha) { char scratch[MAX_QPATH]; Com_sprintf( scratch, sizeof( scratch ), "%s%s", pathbase, "_end"); Draw_AlphaStretchTilingPic (x-base_size/2.0, y, base_size, base_size, scratch, alpha); Draw_AlphaStretchTilingPic (x+w+base_size/2.0, y+base_size, -base_size, -base_size, scratch, alpha); if (w > base_size) Draw_AlphaStretchTilingPic (x+base_size/2.0, y, w-base_size, base_size, pathbase, alpha); } void Menu_DrawScrollbar (menuframework_s *menu) { float scrollbar_pos; float charscale, right; float alpha; FNT_font_t font; font = FNT_AutoGet( CL_menuFont ); charscale = font->size; if (menu->maxheight == 0 || CHASELINK(menu->height) <= menu->maxheight) return; right = menu->x + CHASELINK(menu->rwidth) + CHASELINK(menu->lwidth) + charscale/2.0; scrollbar_pos = menu->scroll_top + (float)menu->yscroll*(menu->scroll_range-menu->scrollbar_size)/menu->maxscroll; alpha = menu->vertical_scrollbar.highlight_alpha; Menu_DrawVertBar ("menu/scroll_border", right, menu->y, menu->maxheight, charscale, alpha*alpha); Menu_DrawVertBar ("menu/scroll_cursor", right, scrollbar_pos, menu->scrollbar_size, charscale, alpha); } void Menu_DrawBorder (menuframework_s *menu, const char *title, const char *prefix) { int height, width; height = CHASELINK(menu->height); if (menu->maxheight != 0 && height > menu->maxheight) height = menu->maxheight; if (strcmp (prefix, "menu/m_")) { menu->borderalpha = 0.50; } else if (Menu_ContainsCursorItem (menu)) { menu->borderalpha += cls.frametime*2; if (menu->borderalpha > 1.0) menu->borderalpha = 1.0; } else { menu->borderalpha -= cls.frametime*2; if (menu->borderalpha < 0.5) menu->borderalpha = 0.5; } width = CHASELINK(menu->lwidth) + CHASELINK(menu->rwidth); Menu_DrawBox (menu->x, menu->y, width, height, menu->borderalpha, title, prefix); } void Menu_DrawToolTip (const menuitem_s *item) { int x, y; int width; FNT_font_t font; font = FNT_AutoGet (CL_menuFont); width = Menu_PredictSize (item->generic.tooltip); x = clamp (cursor.x, Item_GetX (*item) - width, VID_WIDTH - width); y = clamp (cursor.y - font->size - 4, Item_GetY(*item) - font->size, Item_GetY(*item)); Menu_DrawHorizBar ("menu/slide_border", x-2, y, width+4, font->size+4, 1); Menu_DrawString ( x, y, item->generic.tooltip, FNT_CMODE_QUAKE_SRS, FNT_ALIGN_LEFT, light_color ); } void Menu_DrawString (int x, int y, const char *string, unsigned int cmode, unsigned int align, const float *color) { FNT_font_t font; font = FNT_AutoGet( CL_menuFont ); if (align == FNT_ALIGN_RIGHT) { menu_box.x = 0; menu_box.width = x; } else if (align == FNT_ALIGN_CENTER) { //width only needs to be an upper bound int width = strlen(string)*font->size; menu_box.x = x-width/2; menu_box.width = width; } else { menu_box.x = x; menu_box.width = 0; } menu_box.y = y; menu_box.height = 0; FNT_BoundedPrint (font, string, cmode, align, &menu_box, color); if (align == FNT_ALIGN_RIGHT) menu_box.x = x-menu_box.width; else if (align == FNT_ALIGN_CENTER) menu_box.x = x-menu_box.width/2; } void Menu_DrawStatusBar( const char *string ) { FNT_font_t font; font = FNT_AutoGet( CL_menuFont ); if ( string ) { Draw_Fill (0, VID_HEIGHT-font->size-10, VID_WIDTH, font->size+10, RGBA(0.25, 0.25, 0.25, 1)); Menu_DrawString (VID_WIDTH/2, VID_HEIGHT-font->size-5, string, FNT_CMODE_QUAKE, FNT_ALIGN_CENTER, light_color); } } void Menu_ActivateItem (menuitem_s *item) { if (item == NULL || item->generic.callback == NULL) return; if ((item->generic.flags & QMF_ACTION_WAIT)) { if (!item->generic.apply_pending) { item->generic.apply_pending = true; Menu_GetItemTree (item)->num_apply_pending++; } } else { item->generic.callback (item); } } void Menu_ApplyItem (menuitem_s *item) { if (item != NULL && item->generic.callback != NULL && (item->generic.flags & QMF_ACTION_WAIT) && item->generic.apply_pending) { Menu_GetItemTree (item)->num_apply_pending--; item->generic.callback (item); item->generic.apply_pending = false; } } void Menu_ApplyMenu (menuframework_s *menu) { int i; menuitem_s *item; for ( i = 0; i < menu->nitems; i++ ) { item = ((menuitem_s * )menu->items[i]); if (item->generic.type == MTYPE_SUBMENU) Menu_ApplyMenu ((menuframework_s *)item); else Menu_ApplyItem (item); } } void Menu_SetStatusBar( menuframework_s *m, const char *string ) { m->statusbar = string; } void Menu_SlideItem (int dir) { menucommon_s *item = cursor.menuitem; if ( item ) { switch ( item->type ) { case MTYPE_SLIDER: Slider_DoSlide( ( menuslider_s * ) item, dir ); break; case MTYPE_SPINCONTROL: SpinControl_DoSlide( ( menulist_s * ) item, dir ); break; } } } void Label_Draw (menutxt_s *s, FNT_font_t font, const float *color) { unsigned int align; unsigned int cmode; if ( s->generic.name == NULL) return; if ( s->generic.flags & QMF_RIGHT_COLUMN ) align = FNT_ALIGN_LEFT; else align = FNT_ALIGN_RIGHT; cmode = FNT_CMODE_QUAKE_SRS; if (color == highlight_color) cmode = FNT_CMODE_TWO; Menu_DrawString ( Item_GetX (*s), Item_GetY (*s) + MenuText_UpperMargin (s, font->size), s->generic.name, cmode, align, color ); } void Slider_DoSlide( menuslider_s *s, int dir ) { s->curvalue += dir; if ( s->curvalue > s->maxvalue ) s->curvalue = s->maxvalue; else if ( s->curvalue < s->minvalue ) s->curvalue = s->minvalue; Menu_ActivateItem (s); } void Slider_Draw (menuslider_s *s, FNT_font_t font) { float maxscroll, curscroll, scroll_range, cursor_size, x, y, width; float charscale; charscale = font->size; x = Item_GetX (*s) + RCOLUMN_OFFSET; y = Item_GetY (*s) + MenuText_UpperMargin (s, font->size); curscroll = s->curvalue - s->minvalue; maxscroll = s->maxvalue - s->minvalue; s->range = (float) curscroll / ( float ) maxscroll; width = charscale * (float)LONGINPUT_SIZE; scroll_range = width-charscale/2.0; cursor_size = charscale; Menu_DrawHorizBar ( "menu/slide_border", x, y, width, charscale, s->generic.highlight_alpha*s->generic.highlight_alpha ); Menu_DrawHorizBar ( "menu/slide_cursor", x+charscale/4.0+s->range*(scroll_range-cursor_size), y, cursor_size, charscale, s->generic.highlight_alpha ); } void SpinControl_DoSlide( menulist_s *s, int dir ) { int i; s->curvalue += dir; if ( s->curvalue < 0 ) { if (s->generic.flags & QMF_ALLOW_WRAP) { for (i = 0; s->itemnames[i]; i++) continue; s->curvalue += i; } else s->curvalue = 0; } else if ( s->itemnames[s->curvalue] == 0 ) { if (s->generic.flags & QMF_ALLOW_WRAP) s->curvalue = 0; else s->curvalue--; } Menu_ActivateItem (s); } void SpinControl_Draw (menulist_s *s, FNT_font_t font) { char buffer[100]; int item_x, item_y; item_x = Item_GetX (*s) + RCOLUMN_OFFSET; item_y = Item_GetY (*s) + MenuText_UpperMargin (s, SpinControl_MaxLines (s)*font->size); if (s->generic.namedraw == NULL && s->generic.name != NULL && s->generic.flags & QMF_RIGHT_COLUMN) { // Both the name and item go in the right column. item_x += Menu_PredictSize (s->generic.name); } if (s->generic.itemdraw != NULL) { s->generic.itemdraw (s, font); } else if ( !strchr( s->itemnames[s->curvalue], '\n' ) ) { Menu_DrawString ( item_x, item_y, s->itemnames[s->curvalue], FNT_CMODE_QUAKE_SRS, FNT_ALIGN_LEFT, light_color ); } else { strcpy( buffer, s->itemnames[s->curvalue] ); *strchr( buffer, '\n' ) = 0; Menu_DrawString ( item_x, item_y, buffer, FNT_CMODE_QUAKE_SRS, FNT_ALIGN_LEFT, light_color ); strcpy( buffer, strchr( s->itemnames[s->curvalue], '\n' ) + 1 ); Menu_DrawString ( item_x, menu_box.y + font->height, buffer, FNT_CMODE_QUAKE_SRS, FNT_ALIGN_LEFT, light_color ); } } void SubMenu_Draw (menuframework_s *sm, FNT_font_t font) { sm->x = Item_GetX (*sm); if (sm->generic.flags & QMF_SNUG_LEFT) sm->x -= CHASELINK(sm->generic.parent->lwidth); sm->y = Item_GetY (*sm); if (sm->navagable) Menu_DrawScrollbar (sm); Menu_Draw (sm, font); } // utility functions void Menu_MakeTable (menuframework_s *menu, int nrows, int ncolumns, size_t *celltype_size, menuframework_s *header, menuframework_s *rows, void *columns, const char **contents) { int i, j; menuframework_s *cur_row = rows; // char because the measurements in celltype_size are in bytes char *cur_cell_p = columns; menu->nitems = 0; for (i = 0; i < nrows; i++) { cur_row->nitems = 0; cur_row->generic.type = MTYPE_SUBMENU; cur_row->horizontal = true; cur_row->navagable = false; cur_row->enable_highlight = true; if (cur_row != header) { LINK(header->lwidth, cur_row->lwidth); LINK(header->rwidth, cur_row->rwidth); } for (j = 0; j < ncolumns; j++) { menuitem_s *cur_cell = (menuitem_s *)cur_cell_p; if (cur_row != header) { menucommon_s *header_cell = (menucommon_s *)header->items[j]; memcpy (cur_cell, header_cell, sizeof (menucommon_s)); //reset after memcpy cur_cell->generic.x.status = linkstatus_literal; LINK(header_cell->x, cur_cell->generic.x); } cur_cell->generic.name = contents[i*ncolumns+j]; Menu_AddItem (cur_row, cur_cell); cur_cell_p += celltype_size[j]; } Menu_AddItem (menu, cur_row); cur_row++; } Menu_AutoArrange (menu); } alien-arena-7.66+dfsg/source/client/screen.h0000600000175000017500000000267112161402010020016 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // screen.h void SCR_Init (void); void SCR_UpdateScreen (void); void SCR_SizeUp (void); void SCR_SizeDown (void); void SCR_CenterPrint (char *str); void SCR_BeginLoadingPlaque (void); void SCR_EndLoadingPlaque (void); void SCR_DebugGraph (float value, const float color[]); void SCR_TouchPics (void); void SCR_RunConsole (void); extern float scr_con_current; extern float scr_conlines; // lines of console to display extern int sb_lines; extern cvar_t *crosshair; extern cvar_t *cl_hudimage1; extern cvar_t *cl_hudimage2; extern vrect_t scr_vrect; // position of render window extern char crosshair_pic[MAX_QPATH]; extern int crosshair_width, crosshair_height; alien-arena-7.66+dfsg/source/client/keys.h0000600000175000017500000000716312161402010017513 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // // these are the key numbers that should be passed to Key_Event // #define K_TAB 9 #define K_ENTER 13 #define K_ESCAPE 27 #define K_SPACE 32 // normal keys should be passed as lowercased ascii #define K_BACKSPACE 127 #define K_UPARROW 128 #define K_DOWNARROW 129 #define K_LEFTARROW 130 #define K_RIGHTARROW 131 #define K_ALT 132 #define K_CTRL 133 #define K_SHIFT 134 #define K_F1 135 #define K_F2 136 #define K_F3 137 #define K_F4 138 #define K_F5 139 #define K_F6 140 #define K_F7 141 #define K_F8 142 #define K_F9 143 #define K_F10 144 #define K_F11 145 #define K_F12 146 #define K_INS 147 #define K_DEL 148 #define K_PGDN 149 #define K_PGUP 150 #define K_HOME 151 #define K_END 152 #define K_KP_HOME 160 #define K_KP_UPARROW 161 #define K_KP_PGUP 162 #define K_KP_LEFTARROW 163 #define K_KP_5 164 #define K_KP_RIGHTARROW 165 #define K_KP_END 166 #define K_KP_DOWNARROW 167 #define K_KP_PGDN 168 #define K_KP_ENTER 169 #define K_KP_INS 170 #define K_KP_DEL 171 #define K_KP_SLASH 172 #define K_KP_MINUS 173 #define K_KP_PLUS 174 #define K_PAUSE 255 // // mouse buttons generate virtual keys // #define K_MOUSE1 200 #define K_MOUSE2 201 #define K_MOUSE3 202 #define K_MOUSE4 241 #define K_MOUSE5 242 #define K_MOUSE6 243 #define K_MOUSE7 244 #define K_MOUSE8 245 #define K_MOUSE9 246 // // joystick buttons // #define K_JOY1 203 #define K_JOY2 204 #define K_JOY3 205 #define K_JOY4 206 // // aux keys are for multi-buttoned joysticks to generate so they can use // the normal binding process // #define K_AUX1 207 #define K_AUX2 208 #define K_AUX3 209 #define K_AUX4 210 #define K_AUX5 211 #define K_AUX6 212 #define K_AUX7 213 #define K_AUX8 214 #define K_AUX9 215 #define K_AUX10 216 #define K_AUX11 217 #define K_AUX12 218 #define K_AUX13 219 #define K_AUX14 220 #define K_AUX15 221 #define K_AUX16 222 #define K_AUX17 223 #define K_AUX18 224 #define K_AUX19 225 #define K_AUX20 226 #define K_AUX21 227 #define K_AUX22 228 #define K_AUX23 229 #define K_AUX24 230 #define K_AUX25 231 #define K_AUX26 232 #define K_AUX27 233 #define K_AUX28 234 #define K_AUX29 235 #define K_AUX30 236 #define K_AUX31 237 #define K_AUX32 238 #define K_MWHEELDOWN 239 #define K_MWHEELUP 240 extern char *keybindings[256]; extern int key_repeats[256]; extern int anykeydown; extern char chat_buffer[]; extern int chat_bufferlen; extern qboolean chat_team; extern qboolean chat_irc; //to do - replace these with chat_type void Key_Event (int key, qboolean down, unsigned time); void Key_Init (void); void Key_WriteBindings (FILE *f); void Key_SetBinding (int keynum, char *binding); void Key_ClearStates (void); int Key_GetKey (void); void Key_ClearTyping (void); alien-arena-7.66+dfsg/source/client/cl_parse.c0000600000175000017500000005460212161402010020323 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // cl_parse.c -- parse a message received from the server #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "client.h" char *svc_strings[256] = { "svc_bad", "svc_muzzleflash", "svc_muzzlflash2", "svc_temp_entity", "svc_layout", "svc_inventory", "svc_nop", "svc_disconnect", "svc_reconnect", "svc_sound", "svc_print", "svc_stufftext", "svc_serverdata", "svc_configstring", "svc_spawnbaseline", "svc_centerprint", "svc_download", "svc_playerinfo", "svc_packetentities", "svc_deltapacketentities", "svc_frame" }; static size_t szr; // just for unused result warnings /* ============== Q_strncpyz ============== */ void Q_strncpyz( char *dest, const char *src, size_t size ) { #if defined HAVE_STRLCPY strlcpy( dest, src, size ); #else if( size ) { while( --size && (*dest++ = *src++) ); *dest = '\0'; } #endif } //============================================================================= void CL_DownloadFileName(char *dest, int destlen, char *fn) { Com_sprintf (dest, destlen, "%s/%s", FS_Gamedir(), fn); } /* =============== CL_CheckOrDownloadFile Returns true if the file exists, otherwise it attempts to start a download from the server. =============== */ qboolean CL_CheckOrDownloadFile (char *filename) { FILE *fp; char name[MAX_OSPATH]; char shortname[MAX_OSPATH]; char shortname2[MAX_OSPATH]; qboolean jpg = false; if (strstr (filename, "..")) { Com_Printf ("Refusing to download a path with ..\n"); return true; } //if pcx, strip extension and change to .jpg, we do not use .pcx anymore if(filename[strlen(filename)-1] == 'x') { //Filter out any potentially screwed up texture paths(meshes only reside in these folders) if (strncmp(filename, "models", 6) && strncmp(filename, "vehicles", 8) && strncmp(filename, "maps", 4)) return true; COM_StripExtension ( filename, shortname ); sprintf(filename, "%s.jpg", shortname); } //if jpg, be sure to also try tga if(filename[strlen(filename)-2] == 'p' && filename[strlen(filename)-1] == 'g') jpg = true; if (FS_LoadFile (filename, NULL) != -1) { // it exists, no need to download return true; } if(jpg) { //didn't find .jpg skin, try for .tga skin //check for presence of a local .tga(but leave filename as original extension) //if we find a .tga, don't try to download anything COM_StripExtension ( filename, shortname ); sprintf(shortname2, "%s.tga", shortname); if (FS_LoadFile (shortname2, NULL) != -1) { // it exists, no need to download return true; } } strcpy (cls.downloadname, filename); // download to a temp name, and only rename // to the real name when done, so if interrupted // a runt file wont be left COM_StripExtension (cls.downloadname, cls.downloadtempname); strcat (cls.downloadtempname, ".tmp"); // attempt an http download if available(never try to dl game model skins here) if(cls.downloadurl[0] && CL_HttpDownload()) return false; //ZOID // check to see if we already have a tmp for this file, if so, try to resume // open the file if not opened yet CL_DownloadFileName(name, sizeof(name), cls.downloadtempname); // FS_CreatePath (name); fp = fopen (name, "r+b"); if (fp) { // it exists int len; len = FS_filelength( fp ); cls.download = fp; // give the server an offset to start the download Com_Printf ("Resuming %s\n", cls.downloadname); MSG_WriteByte (&cls.netchan.message, clc_stringcmd); MSG_WriteString (&cls.netchan.message, va("download %s %i", cls.downloadname, len)); } else { Com_Printf ("Downloading %s\n", cls.downloadname); MSG_WriteByte (&cls.netchan.message, clc_stringcmd); MSG_WriteString (&cls.netchan.message, va("download %s", cls.downloadname)); } cls.downloadnumber++; send_packet_now = true; return false; } /* =============== CL_Download_f Request a download from the server =============== */ void CL_Download_f (void) { char filename[MAX_OSPATH]; if (Cmd_Argc() != 2) { Com_Printf("Usage: download \n"); return; } Com_sprintf(filename, sizeof(filename), "%s", Cmd_Argv(1)); if (strstr (filename, "..")) { Com_Printf ("Refusing to download a path with ..\n"); return; } if (FS_LoadFile (filename, NULL) != -1) { // it exists, no need to download Com_Printf("File already exists.\n"); return; } strcpy (cls.downloadname, filename); Com_Printf ("Downloading %s\n", cls.downloadname); // download to a temp name, and only rename // to the real name when done, so if interrupted // a runt file wont be left COM_StripExtension (cls.downloadname, cls.downloadtempname); strcat (cls.downloadtempname, ".tmp"); MSG_WriteByte (&cls.netchan.message, clc_stringcmd); MSG_WriteString (&cls.netchan.message, va("download %s", cls.downloadname)); cls.downloadnumber++; } /* ====================== CL_RegisterSounds ====================== */ void CL_RegisterSounds (void) { int i; S_BeginRegistration (); CL_RegisterTEntSounds (); for (i=1 ; istring || !*fs_gamedirvar->string || strcmp(fs_gamedirvar->string, str))) || (!*str && (fs_gamedirvar->string || *fs_gamedirvar->string))) Cvar_Set("game", str); // parse player entity number cl.playernum = MSG_ReadShort (&net_message); // get the full level name str = MSG_ReadString (&net_message); // seperate the printfs so the server message can have a color Com_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n"); Com_Printf ("%c%s\n", 2, str); // need to prep refresh at next oportunity cl.refresh_prepped = false; } /* ================== CL_ParseBaseline ================== */ void CL_ParseBaseline (void) { entity_state_t *es; int bits; int newnum; entity_state_t nullstate; memset (&nullstate, 0, sizeof(nullstate)); newnum = CL_ParseEntityBits ( (unsigned *)&bits ); es = &cl_entities[newnum].baseline; CL_ParseDelta (&nullstate, es, newnum, bits); } /* ================ CL_LoadClientinfo ================ */ void CL_LoadClientinfo (clientinfo_t *ci, char *s) { int i; char *t; char model_name[MAX_QPATH]; char skin_name[MAX_QPATH]; char model_filename[MAX_QPATH]; char skin_filename[MAX_QPATH]; char weapon_filename[MAX_QPATH]; FILE *file; strncpy(ci->cinfo, s, sizeof(ci->cinfo)); ci->cinfo[sizeof(ci->cinfo)-1] = 0; // isolate the player's name strncpy(ci->name, s, sizeof(ci->name)); ci->name[sizeof(ci->name)-1] = 0; t = strstr (s, "\\"); if (t) { ci->name[t-s] = 0; s = t+1; } // isolate the model name strcpy (model_name, s); t = strstr(model_name, "/"); if (!t) t = strstr(model_name, "\\"); if (!t) t = model_name; *t = 0; ci->helmet = NULL; //we only worry about this in these cases of missing textures or models ci->lod1 = NULL; ci->lod2 = NULL; if (cl_noskins->value || *s == 0) { Com_sprintf (model_filename, sizeof(model_filename), "players/martianenforcer/tris.md2"); Com_sprintf (weapon_filename, sizeof(weapon_filename), "players/martianenforcer/weapon.md2"); Com_sprintf (skin_filename, sizeof(skin_filename), "players/martianenforcer/default.pcx"); Com_sprintf (ci->iconname, sizeof(ci->iconname), "/players/martianenforcer/default_i.pcx"); ci->model = R_RegisterModel (model_filename); ci->helmet = R_RegisterModel("players/martianenforcer/helmet.md2"); // weapon file for (i = 0; i < num_cl_weaponmodels; i++) { Com_sprintf (weapon_filename, sizeof(weapon_filename), "players/martianenforcer/%s", cl_weaponmodels[i]); ci->weaponmodel[i] = R_RegisterModel(weapon_filename); if (!cl_vwep->value) break; // only one when vwep is off } ci->skin = R_RegisterSkin (skin_filename); ci->icon = R_RegisterPic (ci->iconname); } else { // isolate the skin name strcpy (skin_name, s + strlen(model_name) + 1); // model file Com_sprintf (model_filename, sizeof(model_filename), "players/%s/tris.md2", model_name); ci->model = R_RegisterModel (model_filename); if (!ci->model) { Com_sprintf (model_filename, sizeof(model_filename), "players/martianenforcer/tris.md2"); ci->model = R_RegisterModel (model_filename); ci->helmet = R_RegisterModel("players/martianenforcer/helmet.md2"); strcpy(model_name, "martianenforcer"); } // skin file Com_sprintf (skin_filename, sizeof(skin_filename), "players/%s/%s.pcx", model_name, skin_name); ci->skin = R_RegisterSkin (skin_filename); // if don't have a skin, it means that the model didn't have // it, so default if (!ci->skin) { strcpy(skin_name, "default"); Com_sprintf (skin_filename, sizeof(skin_filename), "players/%s/default.pcx", model_name); ci->skin = R_RegisterSkin (skin_filename); } // weapon file for (i = 0; i < num_cl_weaponmodels; i++) { Com_sprintf (weapon_filename, sizeof(weapon_filename), "players/%s/%s", model_name, cl_weaponmodels[i]); ci->weaponmodel[i] = R_RegisterModel(weapon_filename); if (!ci->weaponmodel[i] == 0) { Com_sprintf (weapon_filename, sizeof(weapon_filename), "players/martianenforcer/%s", cl_weaponmodels[i]); ci->weaponmodel[i] = R_RegisterModel(weapon_filename); } if (!cl_vwep->value) break; // only one when vwep is off } // icon file Com_sprintf (ci->iconname, sizeof(ci->iconname), "/players/%s/%s_i.pcx", model_name, skin_name); ci->icon = R_RegisterPic (ci->iconname); } //check for level of detail models if (cl_noskins->value || *s == 0) strcpy(model_name, "martianenforcer"); Com_sprintf(model_filename, sizeof(model_filename), "players/%s/lod1.md2", model_name); i = 0; do model_filename[i] = tolower(model_filename[i]); while (model_filename[i++]); FS_FOpenFile (model_filename, &file); if(file) { //exists fclose(file); ci->lod1 = R_RegisterModel(model_filename); } else ci->lod1 = NULL; Com_sprintf(model_filename, sizeof(model_filename), "players/%s/lod2.md2", model_name); i = 0; do model_filename[i] = tolower(model_filename[i]); while (model_filename[i++]); FS_FOpenFile (model_filename, &file); if(file) { //exists fclose(file); ci->lod2 = R_RegisterModel(model_filename); } else ci->lod2 = NULL; // must have loaded all data types to be valid if (!ci->skin || !ci->icon || !ci->model || !ci->weaponmodel[0]) { ci->skin = NULL; ci->icon = NULL; ci->model = NULL; ci->weaponmodel[0] = NULL; return; } } /* ================ CL_ParseClientinfo Load the skin, icon, and model for a client ================ */ void CL_ParseClientinfo (int player) { char *s; clientinfo_t *ci; s = cl.configstrings[player+CS_PLAYERSKINS]; ci = &cl.clientinfo[player]; CL_LoadClientinfo (ci, s); } void CL_ParseTaunt( char *s) { int l, j; char tauntsound[MAX_OSPATH]; //parse strcpy( scr_playericon, COM_Parse( &s ) ); l = strlen(scr_playericon); for (j=0 ; jvalue) { S_StartSound (NULL, 0, 0, S_RegisterSound (tauntsound), 1, ATTN_NONE, 0); scr_playericonalpha = 2.0; } } /* ================ CL_ParseConfigString ================ */ void CL_ParseConfigString (void) { int i; char *s; char olds[MAX_QPATH]; size_t length; i = MSG_ReadShort (&net_message); if (i < 0 || i >= MAX_CONFIGSTRINGS) Com_Error (ERR_DROP, "configstring > MAX_CONFIGSTRINGS"); s = MSG_ReadString(&net_message); strncpy (olds, cl.configstrings[i], sizeof(olds)); olds[sizeof(olds) - 1] = 0; //r1: overflow may be desired by some mods in stats programs for example. who knows. length = strlen(s); if (length >= (sizeof(cl.configstrings[0]) * (MAX_CONFIGSTRINGS-i)) - 1) Com_Error (ERR_DROP, "CL_ParseConfigString: configstring %d exceeds available space", i); //r1: don't allow basic things to overflow if (i != CS_NAME && i < CS_GENERAL) { if (i >= CS_STATUSBAR && i < CS_AIRACCEL) { strncpy (cl.configstrings[i], s, (sizeof(cl.configstrings[i]) * (CS_AIRACCEL - i))-1); } else { // Alien Arena client/server protocol depends on MAX_QPATH being 64 if (length >= MAX_QPATH) Com_Printf ("WARNING: Configstring %d of length %d exceeds MAX_QPATH.\n", i, length); Q_strncpyz (cl.configstrings[i], s, sizeof(cl.configstrings[i])-1); } } else { strcpy (cl.configstrings[i], s); } // do something apropriate if (i >= CS_LIGHTS && i < CS_LIGHTS+MAX_LIGHTSTYLES) CL_SetLightstyle (i - CS_LIGHTS); else if (i >= CS_MODELS && i < CS_MODELS+MAX_MODELS) { if (cl.refresh_prepped) { cl.model_draw[i-CS_MODELS] = R_RegisterModel (cl.configstrings[i]); if (cl.configstrings[i][0] == '*') cl.model_clip[i-CS_MODELS] = CM_InlineModel (cl.configstrings[i]); else cl.model_clip[i-CS_MODELS] = NULL; } } else if (i >= CS_SOUNDS && i < CS_SOUNDS+MAX_MODELS) { if (cl.refresh_prepped) cl.sound_precache[i-CS_SOUNDS] = S_RegisterSound (cl.configstrings[i]); } else if (i >= CS_IMAGES && i < CS_IMAGES+MAX_MODELS) { if (cl.refresh_prepped) cl.image_precache[i-CS_IMAGES] = R_RegisterPic (cl.configstrings[i]); } else if (i >= CS_PLAYERSKINS && i < CS_PLAYERSKINS+MAX_CLIENTS) { if (cl.refresh_prepped && strcmp(olds, s)) CL_ParseClientinfo (i-CS_PLAYERSKINS); } else if ( i == CS_GENERAL) CL_ParseTaunt(s); } /* ===================================================================== ACTION MESSAGES ===================================================================== */ /* ================== CL_ParseStartSoundPacket ================== */ void CL_ParseStartSoundPacket(void) { vec3_t pos_v; float *pos; int channel, ent; int sound_num; float volume; float attenuation; int flags; float ofs; flags = MSG_ReadByte (&net_message); sound_num = MSG_ReadByte (&net_message); if (flags & SND_VOLUME) volume = MSG_ReadByte (&net_message) / 255.0; else volume = DEFAULT_SOUND_PACKET_VOLUME; if (flags & SND_ATTENUATION) attenuation = MSG_ReadByte (&net_message) / 64.0; else attenuation = DEFAULT_SOUND_PACKET_ATTENUATION; if (flags & SND_OFFSET) ofs = MSG_ReadByte (&net_message) / 1000.0; else ofs = 0; if (flags & SND_ENT) { // entity reletive channel = MSG_ReadShort(&net_message); ent = channel>>3; if (ent > MAX_EDICTS) Com_Error (ERR_DROP,"CL_ParseStartSoundPacket: ent = %i", ent); channel &= 7; } else { ent = 0; channel = 0; } if (flags & SND_POS) { // positioned in space MSG_ReadPos (&net_message, pos_v); pos = pos_v; } else // use entity number pos = NULL; if (!cl.sound_precache[sound_num]) return; S_StartSound (pos, ent, channel, cl.sound_precache[sound_num], volume, attenuation, ofs); } void SHOWNET(char *s) { if (cl_shownet->value>=2) Com_Printf ("%3i:%s\n", net_message.readcount-1, s); } /* ===================== CL_ParseServerMessage ===================== */ void CL_ParseServerMessage (void) { int cmd; char *s; int i; // // if recording demos, copy the message out // if (cl_shownet->value == 1) Com_Printf ("%i ",net_message.cursize); else if (cl_shownet->value >= 2) Com_Printf ("------------------\n"); // // parse the message // while (1) { if (net_message.readcount > net_message.cursize) { Com_Error (ERR_DROP,"CL_ParseServerMessage: Bad server message"); break; } cmd = MSG_ReadByte (&net_message); if (cmd == -1) { SHOWNET("END OF MESSAGE"); break; } if (cl_shownet->value>=2) { if (!svc_strings[cmd]) Com_Printf ("%3i:BAD CMD %i\n", net_message.readcount-1,cmd); else SHOWNET(svc_strings[cmd]); } // other commands switch (cmd) { default: Com_Error (ERR_DROP,"CL_ParseServerMessage: Illegible server message\n"); break; case svc_nop: // Com_Printf ("svc_nop\n"); break; case svc_disconnect: Com_Error (ERR_DISCONNECT,"Server disconnected\n"); break; case svc_reconnect: Com_Printf ("Server disconnected, reconnecting\n"); // stop download if(cls.download) { if(cls.downloadhttp) // clean up http downloads CL_HttpDownloadCleanup(); else // or just stop legacy ones fclose(cls.download); cls.download = NULL; } cls.state = ca_connecting; cls.connect_time = -99999; // CL_CheckForResend() will fire immediately break; case svc_print: i = MSG_ReadByte (&net_message); if (i == PRINT_CHAT) { S_StartLocalSound ("misc/talk.wav"); } Com_Printf ("%s", MSG_ReadString (&net_message)); break; case svc_centerprint: SCR_CenterPrint (MSG_ReadString (&net_message)); break; case svc_stufftext: s = MSG_ReadString (&net_message); Com_DPrintf ("stufftext: %s\n", s); Cbuf_AddText (s); break; case svc_serverdata: Cbuf_Execute (); // make sure any stuffed commands are done CL_ParseServerData (); break; case svc_configstring: CL_ParseConfigString (); break; case svc_sound: CL_ParseStartSoundPacket(); break; case svc_spawnbaseline: CL_ParseBaseline (); break; case svc_temp_entity: CL_ParseTEnt (); break; case svc_muzzleflash: CL_ParseMuzzleFlash (); break; case svc_download: CL_ParseDownload (); break; case svc_frame: CL_ParseFrame (); break; case svc_inventory: CL_ParseInventory (); break; case svc_layout: s = MSG_ReadString (&net_message); strncpy (cl.layout, s, sizeof(cl.layout)-1); break; case svc_playerinfo: case svc_packetentities: case svc_deltapacketentities: Com_Error (ERR_DROP, "Out of place frame data"); break; } } CL_AddNetgraph (); // // we don't know if it is ok to save a demo message until // after we have parsed the frame // if (cls.demorecording && !cls.demowaiting) CL_WriteDemoMessage (); } alien-arena-7.66+dfsg/source/client/cl_http.c0000600000175000017500000001666312161402010020175 0ustar zero79zero79/* * Copyright (C) 1997-2001 Id Software, Inc. * Copyright (C) 2002 The Quakeforge Project. * Copyright (C) 2006 Quake2World. * Copyright (C) 2010 COR Entertainment, LLC. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or(at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "client.h" #if defined HAVE_UNISTD_H #include #endif #if defined HAVE_UNLINK && !defined HAVE__UNLINK #define _unlink unlink #endif #include "curl/curl.h" static CURLM *curlm; static CURL *curl; // generic encapsulation for common http response codes typedef struct response_s { int code; char *text; } response_t; response_t responses[] = { {400, "Bad request"}, {401, "Unauthorized"}, {403, "Forbidden"}, {404, "Not found"}, {500, "Internal server error"}, {0, NULL} }; char curlerr[MAX_STRING_CHARS]; // curl's error buffer char url[MAX_OSPATH]; // remote url to fetch from char dnld_file[MAX_OSPATH]; // local path to save to long status, length; // for current transfer qboolean success; /* CL_HttpDownloadRecv */ size_t CL_HttpDownloadRecv(void *buffer, size_t size, size_t nmemb, void *p){ return fwrite(buffer, size, nmemb, cls.download); } /* CL_HttpDownload Queue up an http download. The url is resolved from cls.downloadurl and the current gamedir. We use cURL's multi interface, even tho we only ever perform one download at a time, because it is non-blocking. */ qboolean CL_HttpDownload(void){ char game[64]; if(!curlm) return false; if(!curl) return false; memset(dnld_file, 0, sizeof(dnld_file)); // resolve local file name Com_sprintf(dnld_file, sizeof(dnld_file) - 1, "%s/%s", FS_Gamedir(), cls.downloadname); FS_CreatePath(dnld_file); // create the directory if(!(cls.download = fopen(dnld_file, "wb"))){ Com_Printf("Failed to open %s.\n", dnld_file); return false; // and open the file } cls.downloadhttp = true; memset(game, 0, sizeof(game)); // resolve gamedir strncpy(game, Cvar_VariableString("game"), sizeof(game) - 1); if(!strlen(game)) // use default if not set strcpy(game, "arena"); memset(url, 0, sizeof(url)); // construct url Com_sprintf(url, sizeof(url) - 1, "%s/%s/%s", cls.downloadurl, game, cls.downloadname); // set handle to default state curl_easy_reset(curl); // set url from which to retrieve the file if (curl_easy_setopt(curl, CURLOPT_URL, url) != CURLE_OK) return false; // time out in 5s if (curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5) != CURLE_OK) return false; // set error buffer so we may print meaningful messages memset(curlerr, 0, sizeof(curlerr)); if (curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curlerr) != CURLE_OK) return false; // set the callback for when data is received if (curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CL_HttpDownloadRecv) != CURLE_OK) return false; if (curl_multi_add_handle(curlm, curl) != CURLM_OK) return false; return true; } /* CL_HttpResponseCode */ char *CL_HttpResponseCode(long code){ int i = 0; while(responses[i].code){ if(responses[i].code == code) return responses[i].text; i++; } return "Unknown"; } /* CL_HttpDownloadCleanup If a download is currently taking place, clean it up. This is called both to finalize completed downloads as well as abort incomplete ones. */ void CL_HttpDownloadCleanup(){ char *c; if(!cls.download || !cls.downloadhttp) return; (void)curl_multi_remove_handle(curlm, curl); // cleanup curl fclose(cls.download); // always close the file cls.download = NULL; if(success){ cls.downloadname[0] = 0; } else { // retry via legacy udp download c = strlen(curlerr) ? curlerr : CL_HttpResponseCode(status); Com_DPrintf("Failed to download %s via HTTP: %s.\n" "Trying UDP..", cls.downloadname, c); MSG_WriteByte(&cls.netchan.message, clc_stringcmd); MSG_WriteString(&cls.netchan.message, va("download %s", cls.downloadname)); _unlink(dnld_file); // delete partial or empty file } cls.downloadpercent = 0; cls.downloadhttp = false; status = length = 0; success = false; } /* CL_HttpDownloadThink Process the pending download by giving cURL some time to think. Poll it for feedback on the transfer to determine what action to take. If a transfer fails, stuff a stringcmd to download it via UDP. Since we leave cls.download.tempname in tact during our cleanup, when the download is parsed back in the client, it will fopen and begin. */ void CL_HttpDownloadThink(void){ CURLMsg *msg; int i; int runt; if(!cls.downloadurl[0] || !cls.download) return; // nothing to do // process the download as long as data is avaialble while(curl_multi_perform(curlm, &i) == CURLM_CALL_MULTI_PERFORM){} // fail fast on any curl error if(strlen(curlerr)){ CL_HttpDownloadCleanup(); return; } // check for http status code if(!status){ if (curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status) != CURLE_OK || (status > 0 && status != 200)){ // 404, 403, etc.. CL_HttpDownloadCleanup(); return; } } // check for completion while((msg = curl_multi_info_read(curlm, &i))){ if(msg->msg == CURLMSG_DONE){ //not so fast, curl gives false positives sometimes runt = FS_LoadFile (cls.downloadname, NULL); if(runt > 2048) { //the curl bug produces a 2kb chunk of data success = true; CL_HttpDownloadCleanup(); CL_RequestNextDownload(); } else { success = false; CL_HttpDownloadCleanup(); } return; } } } /* CL_InitHttpDownload */ void CL_InitHttpDownload(void){ if(!(curlm = curl_multi_init())) return; if(!(curl = curl_easy_init())) return; } /* CL_ShutdownHttpDownload */ void CL_ShutdownHttpDownload(void){ CL_HttpDownloadCleanup(); curl_easy_cleanup(curl); curl = NULL; (void)curl_multi_cleanup(curlm); curlm = NULL; } alien-arena-7.66+dfsg/source/client/cl_ents.c0000600000175000017500000013212412161402010020156 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // cl_ents.c -- entity parsing and management #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "client.h" clentity_t *active_clentities, *free_clentities; clentity_t clentities[MAX_CLENTITIES]; /* ========================================================================= FRAME PARSING ========================================================================= */ /* ================= CL_ParseEntityBits Returns the entity number and the header bits ================= */ int bitcounts[32]; /// just for protocol profiling int CL_ParseEntityBits (unsigned *bits) { unsigned b, total; int i; int number; total = MSG_ReadByte (&net_message); if (total & U_MOREBITS1) { b = MSG_ReadByte (&net_message); total |= b<<8; } if (total & U_MOREBITS2) { b = MSG_ReadByte (&net_message); total |= b<<16; } if (total & U_MOREBITS3) { b = MSG_ReadByte (&net_message); total |= b<<24; } // count the bits for net profiling for (i=0 ; i<32 ; i++) if (total&(1<origin, to->old_origin); to->number = number; if (bits & U_MODEL) to->modelindex = MSG_ReadByte (&net_message); if (bits & U_MODEL2) to->modelindex2 = MSG_ReadByte (&net_message); if (bits & U_MODEL3) to->modelindex3 = MSG_ReadByte (&net_message); if (bits & U_MODEL4) to->modelindex4 = MSG_ReadByte (&net_message); if (bits & U_FRAME8) to->frame = MSG_ReadByte (&net_message); if (bits & U_FRAME16) to->frame = MSG_ReadShort (&net_message); if ((bits & U_SKIN8) && (bits & U_SKIN16)) //used for laser colors to->skinnum = MSG_ReadLong(&net_message); else if (bits & U_SKIN8) to->skinnum = MSG_ReadByte(&net_message); else if (bits & U_SKIN16) to->skinnum = MSG_ReadShort(&net_message); if ( (bits & (U_EFFECTS8|U_EFFECTS16)) == (U_EFFECTS8|U_EFFECTS16) ) to->effects = MSG_ReadLong(&net_message); else if (bits & U_EFFECTS8) to->effects = MSG_ReadByte(&net_message); else if (bits & U_EFFECTS16) to->effects = MSG_ReadShort(&net_message); if ( (bits & (U_RENDERFX8|U_RENDERFX16)) == (U_RENDERFX8|U_RENDERFX16) ) to->renderfx = MSG_ReadLong(&net_message); else if (bits & U_RENDERFX8) to->renderfx = MSG_ReadByte(&net_message); else if (bits & U_RENDERFX16) to->renderfx = MSG_ReadShort(&net_message); if (bits & U_ORIGIN1) to->origin[0] = MSG_ReadCoord (&net_message); if (bits & U_ORIGIN2) to->origin[1] = MSG_ReadCoord (&net_message); if (bits & U_ORIGIN3) to->origin[2] = MSG_ReadCoord (&net_message); if (bits & U_ANGLE1) to->angles[0] = MSG_ReadAngle(&net_message); if (bits & U_ANGLE2) to->angles[1] = MSG_ReadAngle(&net_message); if (bits & U_ANGLE3) to->angles[2] = MSG_ReadAngle(&net_message); if (bits & U_OLDORIGIN) MSG_ReadPos (&net_message, to->old_origin); if (bits & U_SOUND) to->sound = MSG_ReadByte (&net_message); if (bits & U_EVENT) to->event = MSG_ReadByte (&net_message); else to->event = 0; if (bits & U_SOLID) to->solid = MSG_ReadShort (&net_message); } /* ================== CL_DeltaEntity Parses deltas from the given base and adds the resulting entity to the current frame ================== */ void CL_DeltaEntity (frame_t *frame, int newnum, entity_state_t *old, int bits) { centity_t *ent; entity_state_t *state; ent = &cl_entities[newnum]; state = &cl_parse_entities[cl.parse_entities & (MAX_PARSE_ENTITIES-1)]; cl.parse_entities++; frame->num_entities++; CL_ParseDelta (old, state, newnum, bits); // some data changes will force no lerping if (state->modelindex != ent->current.modelindex || state->modelindex2 != ent->current.modelindex2 || state->modelindex3 != ent->current.modelindex3 || state->modelindex4 != ent->current.modelindex4 || abs(state->origin[0] - ent->current.origin[0]) > 512 || abs(state->origin[1] - ent->current.origin[1]) > 512 || abs(state->origin[2] - ent->current.origin[2]) > 512 || state->event == EV_PLAYER_TELEPORT || state->event == EV_OTHER_TELEPORT ) { ent->serverframe = -99; } if (ent->serverframe != cl.frame.serverframe - 1) { // wasn't in last update, so initialize some things ent->trailcount = 1024; // for diminishing rocket / grenade trails ent->pr = NULL; // for chained particle trails // duplicate the current state so lerping doesn't hurt anything ent->prev = *state; if (state->event == EV_OTHER_TELEPORT) { VectorCopy (state->origin, ent->prev.origin); VectorCopy (state->origin, ent->lerp_origin); } else { VectorCopy (state->old_origin, ent->prev.origin); VectorCopy (state->old_origin, ent->lerp_origin); } } else { // shuffle the last state to previous ent->prev = ent->current; } ent->serverframe = cl.frame.serverframe; ent->current = *state; } /* ================== CL_ParsePacketEntities An svc_packetentities has just been parsed, deal with the rest of the data stream. ================== */ void CL_ParsePacketEntities (frame_t *oldframe, frame_t *newframe) { int newnum; int bits; entity_state_t *oldstate = NULL; int oldindex, oldnum; newframe->parse_entities = cl.parse_entities; newframe->num_entities = 0; // delta from the entities present in oldframe oldindex = 0; if (!oldframe) oldnum = 99999; else { if (oldindex >= oldframe->num_entities) oldnum = 99999; else { oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)]; oldnum = oldstate->number; } } while (1) { newnum = CL_ParseEntityBits ( (unsigned *)&bits ); if (newnum >= MAX_EDICTS) Com_Error (ERR_DROP,"CL_ParsePacketEntities: bad number:%i", newnum); if (net_message.readcount > net_message.cursize) Com_Error (ERR_DROP,"CL_ParsePacketEntities: end of message"); if (!newnum) break; while (oldnum < newnum) { // one or more entities from the old packet are unchanged if (cl_shownet->value == 3) Com_Printf (" unchanged: %i\n", oldnum); CL_DeltaEntity (newframe, oldnum, oldstate, 0); oldindex++; if (oldindex >= oldframe->num_entities) oldnum = 99999; else { oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)]; oldnum = oldstate->number; } } if (bits & U_REMOVE) { // the entity present in oldframe is not in the current frame if (cl_shownet->value == 3) Com_Printf (" remove: %i\n", newnum); if (oldnum != newnum) Com_Printf ("U_REMOVE: oldnum != newnum\n"); oldindex++; if (oldindex >= oldframe->num_entities) oldnum = 99999; else { oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)]; oldnum = oldstate->number; } continue; } if (oldnum == newnum) { // delta from previous state if (cl_shownet->value == 3) Com_Printf (" delta: %i\n", newnum); CL_DeltaEntity (newframe, newnum, oldstate, bits); oldindex++; if (oldindex >= oldframe->num_entities) oldnum = 99999; else { oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)]; oldnum = oldstate->number; } continue; } if (oldnum > newnum) { // delta from baseline if (cl_shownet->value == 3) Com_Printf (" baseline: %i\n", newnum); CL_DeltaEntity (newframe, newnum, &cl_entities[newnum].baseline, bits); continue; } } // any remaining entities in the old frame are copied over while (oldnum != 99999) { // one or more entities from the old packet are unchanged if (cl_shownet->value == 3) Com_Printf (" unchanged: %i\n", oldnum); CL_DeltaEntity (newframe, oldnum, oldstate, 0); oldindex++; if (oldindex >= oldframe->num_entities) oldnum = 99999; else { oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)]; oldnum = oldstate->number; } } } /* =================== CL_ParsePlayerstate =================== */ void CL_ParsePlayerstate (frame_t *oldframe, frame_t *newframe) { int flags; player_state_t *state; int i; int statbits; state = &newframe->playerstate; // clear to old value before delta parsing if (oldframe) *state = oldframe->playerstate; else memset (state, 0, sizeof(*state)); flags = MSG_ReadShort (&net_message); // // parse the pmove_state_t // if (flags & PS_M_TYPE) state->pmove.pm_type = MSG_ReadByte (&net_message); if (flags & PS_M_ORIGIN) { state->pmove.origin[0] = MSG_ReadSizeInt (&net_message, coord_bytes); state->pmove.origin[1] = MSG_ReadSizeInt (&net_message, coord_bytes); state->pmove.origin[2] = MSG_ReadSizeInt (&net_message, coord_bytes); } if (flags & PS_M_VELOCITY) { state->pmove.velocity[0] = MSG_ReadShort (&net_message); state->pmove.velocity[1] = MSG_ReadShort (&net_message); state->pmove.velocity[2] = MSG_ReadShort (&net_message); } if (flags & PS_M_TIME) state->pmove.pm_time = MSG_ReadByte (&net_message); if (flags & PS_M_FLAGS) state->pmove.pm_flags = MSG_ReadByte (&net_message); if (flags & PS_M_GRAVITY) state->pmove.gravity = MSG_ReadShort (&net_message); if (flags & PS_M_DELTA_ANGLES) { state->pmove.delta_angles[0] = MSG_ReadShort (&net_message); state->pmove.delta_angles[1] = MSG_ReadShort (&net_message); state->pmove.delta_angles[2] = MSG_ReadShort (&net_message); } if (cl.attractloop) state->pmove.pm_type = PM_FREEZE; // demo playback // // parse the rest of the player_state_t // if (flags & PS_VIEWOFFSET) { state->viewoffset[0] = MSG_ReadChar (&net_message) * 0.25; state->viewoffset[1] = MSG_ReadChar (&net_message) * 0.25; state->viewoffset[2] = MSG_ReadChar (&net_message) * 0.25; } if (flags & PS_VIEWANGLES) { state->viewangles[0] = MSG_ReadAngle16 (&net_message); state->viewangles[1] = MSG_ReadAngle16 (&net_message); state->viewangles[2] = MSG_ReadAngle16 (&net_message); } if (flags & PS_KICKANGLES) { state->kick_angles[0] = MSG_ReadChar (&net_message) * 0.25; state->kick_angles[1] = MSG_ReadChar (&net_message) * 0.25; state->kick_angles[2] = MSG_ReadChar (&net_message) * 0.25; } if (flags & PS_WEAPONINDEX) { state->gunindex = MSG_ReadByte (&net_message); } if (flags & PS_WEAPONFRAME) { state->gunframe = MSG_ReadByte (&net_message); state->gunoffset[0] = MSG_ReadChar (&net_message)*0.25; state->gunoffset[1] = MSG_ReadChar (&net_message)*0.25; state->gunoffset[2] = MSG_ReadChar (&net_message)*0.25; state->gunangles[0] = MSG_ReadChar (&net_message)*0.25; state->gunangles[1] = MSG_ReadChar (&net_message)*0.25; state->gunangles[2] = MSG_ReadChar (&net_message)*0.25; } if (flags & PS_BLEND) { state->blend[0] = MSG_ReadByte (&net_message)/255.0; state->blend[1] = MSG_ReadByte (&net_message)/255.0; state->blend[2] = MSG_ReadByte (&net_message)/255.0; state->blend[3] = MSG_ReadByte (&net_message)/255.0; } if (flags & PS_FOV) state->fov = MSG_ReadByte (&net_message); if (flags & PS_RDFLAGS) state->rdflags = MSG_ReadByte (&net_message); // parse stats statbits = MSG_ReadLong (&net_message); for (i=0 ; istats[i] = MSG_ReadShort(&net_message); } /* ================== CL_FireEntityEvents ================== */ void CL_FireEntityEvents (frame_t *frame) { entity_state_t *s1; int pnum, num; for (pnum = 0 ; pnumnum_entities ; pnum++) { num = (frame->parse_entities + pnum)&(MAX_PARSE_ENTITIES-1); s1 = &cl_parse_entities[num]; if (s1->event) CL_EntityEvent (s1); // EF_TELEPORTER acts like an event, but is not cleared each frame if (s1->effects & EF_TELEPORTER) CL_BigTeleportParticles(s1->origin); } } /* ================ CL_ParseFrame ================ */ void CL_ParseFrame (void) { int cmd; int len; frame_t *old; byte new_areabits[MAX_MAP_AREAS/8]; //HACK: reduce the number of areabit changes detected memcpy (new_areabits, cl.frame.areabits, MAX_MAP_AREAS/8); memset (&cl.frame, 0, sizeof(cl.frame)); memcpy (cl.frame.areabits, new_areabits, MAX_MAP_AREAS/8); cl.frame.serverframe = MSG_ReadLong (&net_message); cl.frame.deltaframe = MSG_ReadLong (&net_message); cl.frame.servertime = cl.frame.serverframe*100; // BIG HACK to let old demos continue to work if (cls.serverProtocol != 26) cl.surpressCount = MSG_ReadByte (&net_message); if (cl_shownet->value == 3) Com_Printf (" frame:%i delta:%i\n", cl.frame.serverframe, cl.frame.deltaframe); // If the frame is delta compressed from data that we // no longer have available, we must suck up the rest of // the frame, but not use it, then ask for a non-compressed // message if (cl.frame.deltaframe <= 0) { cl.frame.valid = true; // uncompressed frame old = NULL; cls.demowaiting = false; // we can start recording now } else { old = &cl.frames[cl.frame.deltaframe & UPDATE_MASK]; if (!old->valid) { // should never happen Com_Printf ("Delta from invalid frame (not supposed to happen!).\n"); } if (old->serverframe != cl.frame.deltaframe) { // The frame that the server did the delta from // is too old, so we can't reconstruct it properly. Com_Printf ("Delta frame too old.\n"); } else if (cl.parse_entities - old->parse_entities > MAX_PARSE_ENTITIES-128) { Com_Printf ("Delta parse_entities too old.\n"); } else cl.frame.valid = true; // valid delta parse } // clamp time if (cl.time > cl.frame.servertime) cl.time = cl.frame.servertime; else if (cl.time < cl.frame.servertime - 100) cl.time = cl.frame.servertime - 100; // read areabits len = MSG_ReadByte (&net_message); MSG_ReadData (&net_message, &new_areabits, len); if (memcmp (cl.frame.areabits, new_areabits, len)) { memcpy (cl.frame.areabits, new_areabits, len); cl.refdef.areabits_changed = true; } // read playerinfo cmd = MSG_ReadByte (&net_message); SHOWNET(svc_strings[cmd]); if (cmd != svc_playerinfo) Com_Error (ERR_DROP, "CL_ParseFrame: not playerinfo"); CL_ParsePlayerstate (old, &cl.frame); // read packet entities cmd = MSG_ReadByte (&net_message); SHOWNET(svc_strings[cmd]); if (cmd != svc_packetentities) Com_Error (ERR_DROP, "CL_ParseFrame: not packetentities"); CL_ParsePacketEntities (old, &cl.frame); // save the frame off in the backup array for later delta comparisons cl.frames[cl.frame.serverframe & UPDATE_MASK] = cl.frame; if (cl.frame.valid) { // getting a valid frame message ends the connection process if (cls.state != ca_active) { cls.state = ca_active; cl.force_refdef = true; cl.predicted_origin[0] = cl.frame.playerstate.pmove.origin[0]*0.125; cl.predicted_origin[1] = cl.frame.playerstate.pmove.origin[1]*0.125; cl.predicted_origin[2] = cl.frame.playerstate.pmove.origin[2]*0.125; VectorCopy (cl.frame.playerstate.viewangles, cl.predicted_angles); if (cls.disable_servercount != cl.servercount && cl.refresh_prepped) SCR_EndLoadingPlaque (); // get rid of loading plaque } cl.sound_prepped = true; // can start mixing ambient sounds // fire entity events CL_FireEntityEvents (&cl.frame); CL_CheckPredictionError (); } } /* ========================================================================== INTERPOLATE BETWEEN FRAMES TO GET RENDERING PARMS ========================================================================== */ /* =============== CL_AddPacketEntities =============== */ struct model_s { char name[MAX_QPATH]; }; void CL_AddPacketEntities (frame_t *frame) { entity_t ent; entity_state_t *s1; float autorotate; float bob, bob_scale; int i; int pnum; centity_t *cent; int autoanim; clientinfo_t *ci; unsigned int effects, renderfx; qboolean playermodel; // bonus items rotate at a fixed rate autorotate = anglemod(cl.time/10); // brush models can auto animate their frames autoanim = 2*cl.time/1000; memset (&ent, 0, sizeof(ent)); for (pnum = 0 ; pnumnum_entities ; pnum++) { s1 = &cl_parse_entities[(frame->parse_entities+pnum)&(MAX_PARSE_ENTITIES-1)]; cent = &cl_entities[s1->number]; ent.number = s1->number; playermodel = false; effects = s1->effects; renderfx = s1->renderfx; // set frame if (effects & EF_ANIM01) ent.frame = autoanim & 1; else if (effects & EF_ANIM23) ent.frame = 2 + (autoanim & 1); else if (effects & EF_ANIM_ALL) ent.frame = autoanim; else if (effects & EF_ANIM_ALLFAST) ent.frame = cl.time / 100; else ent.frame = s1->frame; // quad and pent can do different things on client if (effects & EF_PENT) { effects &= ~EF_PENT; effects |= EF_COLOR_SHELL; renderfx |= RF_SHELL_RED; } if (effects & EF_QUAD) { effects &= ~EF_QUAD; effects |= EF_COLOR_SHELL; renderfx |= RF_SHELL_BLUE; } ent.oldframe = cent->prev.frame; ent.backlerp = 1.0 - cl.lerpfrac; //animation timestamps are set here if(cent->prevframe != s1->frame) { cent->prevframe = s1->frame; cent->frametime = Sys_Milliseconds(); } ent.prevframe = cent->prevframe; ent.frametime = cent->frametime; // create a new entity ent.lod1 = NULL; ent.lod2 = NULL; ent.team = 0; // set skin if (s1->modelindex == 255) { // use custom player skin ent.skinnum = 0; ci = &cl.clientinfo[s1->skinnum & 0xff]; ent.skin = ci->skin; ent.model = ci->model; ent.lod1 = ci->lod1; ent.lod2 = ci->lod2; if (!ent.skin || !ent.model) { ent.skin = cl.baseclientinfo.skin; ent.model = cl.baseclientinfo.model; } playermodel = true; strcpy(ent.name, ci->name); } else { ent.skinnum = s1->skinnum; ent.skin = NULL; ent.model = cl.model_draw[s1->modelindex]; } if (renderfx & (RF_FRAMELERP)) { // step origin discretely, because the frames // do the animation properly VectorCopy (cent->current.origin, ent.origin); VectorCopy (cent->current.old_origin, ent.oldorigin); } else if (s1->number == cl.playernum+1) { for (i=0; i<3; i++) { ent.origin[i] = ent.oldorigin[i] = cent->current.origin[i] + cl.lerpfrac * (cent->current.origin[i] - cent->prev.origin[i]); } } else { // interpolate origin for (i=0 ; i<3 ; i++) { ent.origin[i] = ent.oldorigin[i] = cent->prev.origin[i] + cl.lerpfrac * (cent->current.origin[i] - cent->prev.origin[i]); } } // calculate angles if (effects & EF_ROTATE) { // some bonus items auto-rotate ent.angles[0] = 0; ent.angles[1] = autorotate; ent.angles[2] = 0; // bobbing items bob_scale = (0.005f + s1->number * 0.00001f) * 0.5; bob = 5 + cos( (cl.time + 1000) * bob_scale ) * 5; ent.oldorigin[2] += bob; ent.origin[2] += bob; ent.bob = bob; renderfx |= RF_BOBBING; } else { // interpolate angles float a1, a2; for (i=0 ; i<3 ; i++) { a1 = cent->current.angles[i]; a2 = cent->prev.angles[i]; ent.angles[i] = LerpAngle (a2, a1, cl.lerpfrac); } } // render effects (fullbright, translucent, etc) if ((effects & EF_COLOR_SHELL)) ent.flags = 0; // renderfx go on color shell entity else ent.flags = renderfx; if (s1->number == cl.playernum+1) { ent.flags |= RF_VIEWERMODEL; // only draw from mirrors // fixed player origin - fixes the "jittery" player shadows too if ((cl_predict->value) && !(cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION)) { VectorCopy (cl.predicted_origin, ent.origin); VectorCopy (cl.predicted_origin, ent.oldorigin); } } // Sigh, this is the reason for the RF_NODRAW workaround. #if 1 // TODO: replace this with an IFDEF for non Alien Arena CRX games // if set to invisible, skip if (!s1->modelindex) continue; #endif if (effects & EF_PLASMA) { ent.flags |= RF_TRANSLUCENT; ent.alpha = 0.6; } if (effects & EF_BUBBLES) { CL_PoweredEffects (ent.origin); } //cool new ctf flag effects if (!Q_strcasecmp (cl.configstrings[CS_MODELS+(s1->modelindex)], "models/items/flags/flag1.md2")) { CL_FlagEffects(ent.origin, 0); ent.team = 1; } else if (!Q_strcasecmp (cl.configstrings[CS_MODELS+(s1->modelindex)], "models/items/flags/flag2.md2")) { CL_FlagEffects(ent.origin, 1); ent.team = 2; } if (s1->modelindex != 0 && !(renderfx & RF_NODRAW)) { // add to refresh list V_AddEntity (&ent); // color shells generate a seperate entity for the main model if ((effects & EF_COLOR_SHELL) && !(s1->number == cl.playernum+1)) { ent.flags = renderfx | RF_TRANSLUCENT; ent.alpha = 0.30; V_AddViewEntity (&ent); } } ent.skin = NULL; // never use a custom skin on others ent.skinnum = 0; ent.flags = 0; ent.alpha = 0; ent.lod1 = NULL; // only player models get lods ent.lod2 = NULL; ent.team = 0; ci = &cl.clientinfo[s1->skinnum & 0xff]; if (s1->modelindex != 0 && !(renderfx & RF_NODRAW)) { //give health an "aura" if(cl_healthaura->value && !cl_simpleitems->value) { if (!Q_strcasecmp (cl.configstrings[CS_MODELS+(s1->modelindex)], "models/items/healing/small/tris.md2")) CL_SmallHealthParticles(ent.origin); if (!Q_strcasecmp (cl.configstrings[CS_MODELS+(s1->modelindex)], "models/items/healing/medium/tris.md2")) CL_MedHealthParticles(ent.origin); if (!Q_strcasecmp (cl.configstrings[CS_MODELS+(s1->modelindex)], "models/items/healing/large/tris.md2")) CL_LargeHealthParticles(ent.origin); } if (!Q_strcasecmp (cl.configstrings[CS_MODELS+(s1->modelindex)], "models/weapons/g_rocket/tris.md2")) { //add clear cover if (!cl_simpleitems->integer) { ent.model = R_RegisterModel("models/weapons/g_rocket/cover.md2"); ent.flags |= RF_TRANSLUCENT; ent.alpha = 0.30; V_AddEntity (&ent); } } if (!Q_strcasecmp (cl.configstrings[CS_MODELS+(s1->modelindex)], "models/weapons/g_hyperb/tris.md2")) { //add clear cover if (!cl_simpleitems->integer) { ent.model = R_RegisterModel("models/weapons/g_hyperb/cover.md2"); ent.flags |= RF_TRANSLUCENT; ent.alpha = 0.30; V_AddEntity (&ent); } } } if (s1->modelindex2) { if (s1->modelindex2 == 255 || (ci->helmet && playermodel)) { // custom weapon i = (s1->skinnum >> 8); // 0 is default weapon model if (!cl_vwep->value || i > MAX_CLIENTWEAPONMODELS - 1) i = 0; ent.model = ci->weaponmodel[i]; if (!ent.model) { if (i != 0) ent.model = ci->weaponmodel[0]; if (!ent.model) ent.model = cl.baseclientinfo.weaponmodel[0]; } } else { ent.model = cl.model_draw[s1->modelindex2]; } //here is where we will set the alpha for certain model parts - would like to eventually //do something a little less uh, hardcoded. if (!Q_strcasecmp (cl.configstrings[CS_MODELS+(s1->modelindex2)], "models/items/healing/globe/tris.md2")) { if(cl_simpleitems->value) continue; ent.alpha = 0.4; ent.flags = RF_TRANSLUCENT; } else if (!Q_strcasecmp (cl.configstrings[CS_MODELS+(s1->modelindex2)], "models/items/quaddama/unit.md2")) { if(cl_simpleitems->value) continue; ent.alpha = 0.4; ent.flags = RF_TRANSLUCENT; } if (s1->number == cl.playernum+1) ent.flags |= RF_VIEWERMODEL; V_AddEntity (&ent); //PGM - make sure these get reset. ent.flags = 0; ent.alpha = 0; //PGM } if (s1->modelindex3 || (ci->helmet && playermodel)) //index 3 is only used for clear entities now, no need for all that checking { if(ci->helmet && playermodel) ent.model = ci->helmet; else ent.model = cl.model_draw[s1->modelindex3]; ent.alpha = 0.4; ent.flags = RF_TRANSLUCENT; if (s1->number == cl.playernum+1) { ent.flags |= RF_VIEWERMODEL; } V_AddEntity (&ent); } if (s1->number == cl.playernum+1) goto end; if (s1->modelindex4) { ent.flags = 0; ent.alpha = 1.0; //new ctf flag effects if (!Q_strcasecmp (cl.configstrings[CS_MODELS+(s1->modelindex4)], "models/items/flags/flag1.md2")) { CL_FlagEffects(ent.origin, 0); ent.model = 0; } else if (!Q_strcasecmp (cl.configstrings[CS_MODELS+(s1->modelindex4)], "models/items/flags/flag2.md2")) { CL_FlagEffects(ent.origin, 1); ent.model = 0; } else { ent.model = cl.model_draw[s1->modelindex4]; V_AddEntity (&ent); } } // add automatic particle trails if ( (effects&~EF_ROTATE) ) { if (effects & EF_ROCKET) { CL_RocketTrail (cent->lerp_origin, ent.origin, cent); V_AddLight (ent.origin, 200, .4, .4, .1); } if (effects & EF_SHIPEXHAUST) { CL_ShipExhaust (cent->lerp_origin, ent.origin, cent); } if (effects & EF_ROCKETEXHAUST) { CL_RocketExhaust (cent->lerp_origin, ent.origin, cent); } else if (effects & EF_HYPERBLASTER) { V_AddLight (ent.origin, 400*crand(), 1, 0, 1); } else if (effects & EF_GIB) { CL_DiminishingTrail (cent->lerp_origin, ent.origin, cent, effects); } else if (effects & EF_GRENADE) { CL_DiminishingTrail (cent->lerp_origin, ent.origin, cent, effects); } else if (effects & EF_TEAM1) { vec3_t right; vec3_t start; vec3_t up; AngleVectors (ent.angles, NULL, right, up); VectorMA (ent.origin, 16, right, start); VectorMA (start, 32, up, start); CL_RedTeamLight(start); VectorMA (ent.origin, -16, right, start); VectorMA (start, 32, up, start); CL_RedTeamLight(start); } else if (effects & EF_TEAM2) { vec3_t right; vec3_t start; vec3_t up; AngleVectors (ent.angles, NULL, right, up); VectorMA (ent.origin, 16, right, start); VectorMA (start, 32, up, start); CL_BlueTeamLight(start); VectorMA (ent.origin, -16, right, start); VectorMA (start, 32, up, start); CL_BlueTeamLight(start); } else if (effects & EF_GREENGIB) { CL_DiminishingTrail (cent->lerp_origin, ent.origin, cent, effects); } else if (effects & EF_PLASMA) { CL_BlasterBall (cent->lerp_origin, ent.origin); V_AddLight (ent.origin, 200, 0, 1, 1); } else if (effects & EF_BLASTER) { CL_BlasterTrail(cent->lerp_origin, ent.origin, cent); V_AddLight (ent.origin, 200, 0, .5, .1); } } end: VectorCopy (ent.origin, cent->lerp_origin); } } /* ======================= Berserker@quake2 shell brass effect. No change ======================= */ void CL_BrassShells(vec3_t org, vec3_t dir, int count) { int i, j; clentity_t *le; float d; if (!cl_brass->value || !count) return; for (i = 0; i < count; i++) { if (!free_clentities) return; le = free_clentities; free_clentities = le->next; le->next = active_clentities; active_clentities = le; le->time = cl.time; d = (192 + rand()) & 63; VectorClear(le->accel); VectorClear(le->vel); le->accel[0] = le->accel[1] = 0; le->accel[2] = -6 * PARTICLE_GRAVITY; le->alpha = 1.0; le->alphavel = -0.1; le->flags = CLM_BOUNCE | CLM_FRICTION | CLM_ROTATE | CLM_NOSHADOW | CLM_BRASS; le->model = R_RegisterModel("models/objects/brass/tris.md2"); le->ang = crand() * 360; le->avel = crand() * 500; for (j = 0; j < 3; j++) { le->lastOrg[j] = le->org[j] = org[j]; le->vel[j] = crand() * 24 + d * dir[j]; } } } void CL_GlassShards(vec3_t org, vec3_t dir, int count) { int i, j; clentity_t *le; float d; if (!count) return; for (i = 0; i < count; i++) { if (!free_clentities) return; le = free_clentities; free_clentities = le->next; le->next = active_clentities; active_clentities = le; le->time = cl.time; d = (192 + rand()) & 13; VectorClear(le->accel); VectorClear(le->vel); le->accel[0] = le->accel[1] = 0; le->accel[2] = -3 * PARTICLE_GRAVITY; le->alpha = 1.0; le->alphavel = -0.01; le->flags = CLM_BOUNCE | CLM_FRICTION | CLM_ROTATE | CLM_NOSHADOW | CLM_GLASS; le->model = R_RegisterModel("models/objects/debris1/tris.md2"); le->ang = crand() * 360; le->avel = crand() * 500; for (j = 0; j < 3; j++) { le->lastOrg[j] = le->org[j] = org[j]; le->vel[j] = crand() * 12 + d * dir[j]; } } } /* ============== CL_AddViewWeapon ============== */ void CL_AddViewWeapon (player_state_t *ps, player_state_t *ops) { entity_t gun; // view model int i; qboolean useFX = false; vec3_t offset_down; vec3_t offset_right; memset (&gun, 0, sizeof(gun)); gun.model = cl.model_draw[ps->gunindex]; gun.lod1 = NULL; gun.lod2 = NULL; if (!gun.model) return; //if a vehicle console, we want to render as a 2D HUD now, if a player choses to if(cl_vehicle_huds->value) { if(!(strcmp("vehicles/bomber/v_wep.md2", gun.model->name))) { vehicle_hud = 1; return; } else if(!(strcmp("vehicles/strafer/v_wep.md2", gun.model->name))) { vehicle_hud = 2; return; } else if(!(strcmp("vehicles/hover/v_wep.md2", gun.model->name))) { vehicle_hud = 3; return; } else vehicle_hud = 0; } else vehicle_hud = 0; // nudge gun down and right if in wide angle view if(cl.refdef.fov_x > 90) { VectorScale(cl.v_up, 0.2 * (cl.refdef.fov_x - 90), offset_down); VectorScale(cl.v_right, -0.15 * (cl.refdef.fov_x - 90), offset_right); } else offset_down[0] = offset_down[1] = offset_down[2] = offset_right[0] = offset_right[1] = offset_right[2] = 0; // set up gun position for (i=0 ; i<3 ; i++) { gun.origin[i] = cl.refdef.vieworg[i] + ops->gunoffset[i] + cl.lerpfrac * (ps->gunoffset[i] - ops->gunoffset[i]); gun.angles[i] = cl.refdef.viewangles[i] + LerpAngle (ops->gunangles[i], ps->gunangles[i], cl.lerpfrac); } gun.frame = ps->gunframe; if (gun.frame == 0) gun.oldframe = 0; // just changed weapons, don't lerp from old else gun.oldframe = ops->gunframe; VectorSubtract(gun.origin, offset_down, gun.origin); VectorSubtract(gun.origin, offset_right, gun.origin); gun.flags = RF_MINLIGHT | RF_DEPTHHACK | RF_WEAPONMODEL; gun.backlerp = 1.0 - cl.lerpfrac; VectorCopy (gun.origin, gun.oldorigin); // don't lerp at all //add an attached muzzleflash for chaingun if(!(strcmp("models/weapons/v_shotg2/tris.md2", gun.model->name))) { if(gun.frame > 4 && gun.frame < 14) CL_MuzzleFlashParticle(gun.origin, gun.angles, true); } else if(!(strcmp("models/weapons/v_hyperb/tris.md2", gun.model->name))) { if(gun.frame > 5 && gun.frame < 7) { CL_PlasmaFlashParticle(gun.origin, gun.angles, true); useFX = true; } } V_AddViewEntity (&gun); //add shells for viewweaps (all of em!) { int oldeffects = gun.flags, pnum; entity_state_t *s1; for (pnum = 0 ; pnumnumber == cl.playernum+1) { int effects = s1->renderfx; if (effects & (RF_SHELL_RED|RF_SHELL_BLUE|RF_SHELL_GREEN) || s1->effects&(EF_PENT|EF_QUAD) || useFX) { if (effects & RF_SHELL_RED) gun.flags |= RF_SHELL_RED; if (effects & RF_SHELL_BLUE) gun.flags |= RF_SHELL_BLUE; if (effects & RF_SHELL_GREEN) gun.flags |= RF_SHELL_GREEN; if (useFX) gun.flags |= RF_SHELL_GREEN; gun.flags |= RF_TRANSLUCENT; gun.alpha = 0.30; if ( ( s1->effects & EF_COLOR_SHELL && gun.flags & (RF_SHELL_RED|RF_SHELL_BLUE|RF_SHELL_GREEN) ) || useFX) { V_AddViewEntity (&gun); } if (s1->effects & EF_PENT) { gun.flags = oldeffects | RF_TRANSLUCENT | RF_SHELL_RED; V_AddViewEntity (&gun); } if (s1->effects & EF_QUAD && cl_gun->value) { gun.flags = oldeffects | RF_TRANSLUCENT | RF_SHELL_BLUE; V_AddViewEntity (&gun); } } } gun.flags = oldeffects; } //add glass pieces if(!(strcmp("models/weapons/v_rocket/tris.md2", gun.model->name))) { gun.model = R_RegisterModel("models/weapons/v_rocket/cover.md2"); gun.flags |= RF_TRANSLUCENT; gun.alpha = 0.30; V_AddViewEntity (&gun); } if(!(strcmp("models/weapons/v_hyperb/tris.md2", gun.model->name))) { gun.model = R_RegisterModel("models/weapons/v_hyperb/cover.md2"); gun.flags |= RF_TRANSLUCENT; gun.alpha = 0.30; V_AddViewEntity (&gun); } if(!(strcmp("models/weapons/v_blast/tris.md2", gun.model->name))) { gun.model = R_RegisterModel("models/weapons/v_blast/cover.md2"); gun.flags |= RF_TRANSLUCENT; gun.alpha = 0.30; V_AddViewEntity (&gun); } if(!(strcmp("models/weapons/v_alienblast/tris.md2", gun.model->name))) { gun.model = R_RegisterModel("models/weapons/v_alienblast/cover.md2"); gun.flags |= RF_TRANSLUCENT; gun.alpha = 0.30; V_AddViewEntity (&gun); } } /* =============== CL_CalcViewValues Sets cl.refdef view values =============== */ void CL_CalcViewValues (void) { int i; float lerp, backlerp; centity_t *ent; frame_t *oldframe; player_state_t *ps, *ops; // find the previous frame to interpolate from ps = &cl.frame.playerstate; i = (cl.frame.serverframe - 1) & UPDATE_MASK; oldframe = &cl.frames[i]; if (oldframe->serverframe != cl.frame.serverframe-1 || !oldframe->valid) oldframe = &cl.frame; // previous frame was dropped or involid ops = &oldframe->playerstate; // see if the player entity was teleported this frame if ( fabs(ops->pmove.origin[0] - ps->pmove.origin[0]) > 256*8 || abs(ops->pmove.origin[1] - ps->pmove.origin[1]) > 256*8 || abs(ops->pmove.origin[2] - ps->pmove.origin[2]) > 256*8) ops = ps; // don't interpolate ent = &cl_entities[cl.playernum+1]; lerp = cl.lerpfrac; // calculate the origin if ( !cl.attractloop && !ps->stats[STAT_CHASE] && cl_predict->value && !(cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION)) //not for demo/chasecam { // use predicted values unsigned delta; backlerp = 1.0 - lerp; for (i=0 ; i<3 ; i++) { cl.refdef.vieworg[i] = cl.predicted_origin[i] + ops->viewoffset[i] + cl.lerpfrac * (ps->viewoffset[i] - ops->viewoffset[i]) - backlerp * cl.prediction_error[i]; } // smooth out stair climbing delta = cls.realtime - cl.predicted_step_time; if (delta < 100) cl.refdef.vieworg[2] -= cl.predicted_step * (100 - delta) * 0.01; } else { // just use interpolated values for (i=0 ; i<3 ; i++) cl.refdef.vieworg[i] = ops->pmove.origin[i]*0.125 + ops->viewoffset[i] + lerp * (ps->pmove.origin[i]*0.125 + ps->viewoffset[i] - (ops->pmove.origin[i]*0.125 + ops->viewoffset[i]) ); } // if not running a demo or on a locked frame, add the local angle movement if ( cl.frame.playerstate.pmove.pm_type < PM_DEAD ) { // use predicted values for (i=0 ; i<3 ; i++) cl.refdef.viewangles[i] = cl.predicted_angles[i]; } else { // just use interpolated values for (i=0 ; i<3 ; i++) cl.refdef.viewangles[i] = LerpAngle (ops->viewangles[i], ps->viewangles[i], lerp); } for (i=0 ; i<3 ; i++) cl.refdef.viewangles[i] += LerpAngle (ops->kick_angles[i], ps->kick_angles[i], lerp); AngleVectors (cl.refdef.viewangles, cl.v_forward, cl.v_right, cl.v_up); // interpolate field of view cl.refdef.fov_x = ops->fov + lerp * (ps->fov - ops->fov); // don't interpolate blend color for (i=0 ; i<4 ; i++) cl.refdef.blend[i] = ps->blend[i]; // add the weapon CL_AddViewWeapon (ps, ops); } /* =============== CL_AddEntities Emits all entities, particles, and lights to the refresh =============== */ void CL_AddEntities (void) { if (cls.state != ca_active) return; if (cl.time > cl.frame.servertime) { if (cl_showclamp->value) Com_Printf ("high clamp %i\n", cl.time - cl.frame.servertime); cl.time = cl.frame.servertime; cl.lerpfrac = 1.0; } else if (cl.time < cl.frame.servertime - 100) { if (cl_showclamp->value) Com_Printf ("low clamp %i\n", cl.frame.servertime-100 - cl.time); cl.time = cl.frame.servertime - 100; cl.lerpfrac = 0; } else cl.lerpfrac = 1.0 - (cl.frame.servertime - cl.time) * 0.01; if (cl_timedemo->value) cl.lerpfrac = 1.0; CL_CalcViewValues (); // PMM - moved this here so the heat beam has the right values for the vieworg, and can lock the beam to the gun CL_AddPacketEntities (&cl.frame); CL_AddTEnts (); CL_AddParticles (); CL_AddDLights (); CL_AddClEntities(); CL_AddLightStyles (); } /* =============== CL_GetEntitySoundOrigin Called to get the sound spatialization origin =============== */ void CL_GetEntitySoundOrigin (int ent, vec3_t org) { centity_t *old; if (ent < 0 || ent >= MAX_EDICTS) Com_Error (ERR_DROP, "CL_GetEntitySoundOrigin: bad ent"); old = &cl_entities[ent]; VectorCopy (old->lerp_origin, org); // FIXME: bmodel issues... } /* ================ Client side entities(ejecting brass, etc ================ */ /* ----------------------------- ClipMoveEntitiesWorld ----------------------------- */ void CL_ClipMoveToEntitiesWorld(vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, trace_t * tr, int mask) { int i; trace_t trace; int headnode; float *angles; entity_state_t *ent; int num; cmodel_t *cmodel; for (i = 0; i < cl.frame.num_entities; i++) { num = (cl.frame.parse_entities + i) & (MAX_PARSE_ENTITIES - 1); ent = &cl_parse_entities[num]; if (!ent->solid) continue; if (ent->solid != 31) // special value for bmodel continue; cmodel = cl.model_clip[ent->modelindex]; if (!cmodel) continue; headnode = cmodel->headnode; angles = ent->angles; if (tr->allsolid) return; trace = CM_TransformedBoxTrace(start, end, mins, maxs, headnode, mask, ent->origin, angles); if (trace.allsolid || trace.startsolid || trace.fraction < tr->fraction) { trace.ent = (struct edict_s *) ent; if (tr->startsolid) { *tr = trace; tr->startsolid = true; } else *tr = trace; } else if (trace.startsolid) tr->startsolid = true; } } trace_t CL_PMTraceWorld(vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int mask) { trace_t t; // check against world t = CM_BoxTrace(start, end, mins, maxs, 0, mask); if (t.fraction < 1.0) t.ent = (struct edict_s *) 1; // check all other solid models CL_ClipMoveToEntitiesWorld(start, mins, maxs, end, &t, mask); return t; } void VectorReflect(const vec3_t v, const vec3_t normal, vec3_t out) { float d; d = 2.0 * (v[0] * normal[0] + v[1] * normal[1] + v[2] * normal[2]); out[0] = v[0] - normal[0] * d; out[1] = v[1] - normal[1] * d; out[2] = v[2] - normal[2] * d; } extern int CL_PMpointcontents (vec3_t point); void CL_AddClEntities() { entity_t ent; clentity_t *le, *next; clentity_t *active, *tail; vec3_t org, dir; float alpha, bak; int contents; qboolean onground; char soundname[64]; float time, time2, grav = Cvar_VariableValue("sv_gravity"); static vec3_t mins = { -2, -2, -2 }; static vec3_t maxs = { 2, 2, 2 }; if (!grav) grav = 1; else grav /= 800; active = NULL; tail = NULL; memset(&ent, 0, sizeof(ent)); for (le = active_clentities; le; le = next) { next = le->next; time = (cl.time - le->time) * 0.001; alpha = le->alpha + time * le->alphavel; if (alpha <= 0) { // faded out le->next = free_clentities; free_clentities = le; continue; } time2 = time * time; org[0] = le->org[0] + le->vel[0] * time + le->accel[0] * time2; org[1] = le->org[1] + le->vel[1] * time + le->accel[1] * time2; bak = le->org[2] + le->vel[2] * time + le->accel[2] * time2 * grav; org[2] = bak - 1; contents = CL_PMpointcontents(org); org[2] = bak; onground = contents & MASK_SOLID; if (onground) { le->flags &= ~CLM_ROTATE; le->avel = 0; } else if (le->flags & CLM_STOPPED) { le->flags &= ~CLM_STOPPED; le->flags |= CLM_BOUNCE; le->accel[2] = -15 * PARTICLE_GRAVITY; // Reset le->alpha = 1; le->time = cl.time; VectorCopy(org, le->org); } le->next = NULL; if (!tail) active = tail = le; else { tail->next = le; tail = le; } if (alpha > 1.0) alpha = 1; if(le->flags & CLM_NOSHADOW) ent.flags |= RF_NOSHADOWS; if (le->flags & CLM_FRICTION) { // Water friction affected cl model if (contents & MASK_WATER) { if (contents & CONTENTS_LAVA) { // kill entity in lava VectorSet(dir, 0, 0, 1); le->alpha = 0; continue; } else { // Add friction VectorScale(le->vel, 0.25, le->vel); VectorScale(le->accel, 0.25, le->accel); // Don't add friction again le->flags &= ~(CLM_FRICTION | CLM_ROTATE); // Reset le->time = cl.time; VectorCopy(org, le->org); } } } if (le->flags & CLM_BOUNCE) { trace_t trace = CL_PMTraceWorld (le->lastOrg, mins, maxs, org, MASK_SOLID); if (trace.fraction > 0.0001f && trace.fraction < 0.9999f ) { vec3_t vel; // Reflect velocity float time = cl.time - (cls.frametime + cls.frametime * trace.fraction) * 1000; time = (time - le->time) * 0.001; VectorSet(vel, le->vel[0], le->vel[1], le->vel[2] + le->accel[2] * time * grav); VectorReflect(vel, trace.plane.normal, le->vel); // Check for stop or slide along the plane if (trace.plane.normal[2] > 0 && le->vel[2] < 1) { if (trace.plane.normal[2] > 0.9) { VectorClear(le->vel); VectorClear(le->accel); le->avel = 0; le->flags &= ~CLM_BOUNCE; le->flags |= CLM_STOPPED; } else { // FIXME: check for new plane or free fall float dot = DotProduct(le->vel, trace.plane.normal); VectorMA(le->vel, -dot, trace.plane.normal, le->vel); dot = DotProduct(le->accel, trace.plane.normal); VectorMA(le->accel, -dot, trace.plane.normal, le->accel); } } VectorCopy(trace.endpos, org); // Reset le->time = cl.time; VectorCopy(org, le->org); //play a sound if brass if ( (le->flags & (CLM_BRASS)) && (le->flags & (CLM_BOUNCE)) ) { Com_sprintf(soundname, sizeof(soundname), "weapons/clink0%i.wav", (rand() % 2) + 1); S_StartSound (le->org, 0, CHAN_WEAPON, S_RegisterSound(soundname), 1.0, ATTN_NORM, 0); } //play a sound if glass if ( (le->flags & (CLM_GLASS)) && (le->flags & (CLM_BOUNCE)) ) { Com_sprintf(soundname, sizeof(soundname), "weapons/clink0%i.wav", (rand() % 2) + 1); //to do - get glass sound S_StartSound (le->org, 0, CHAN_WEAPON, S_RegisterSound(soundname), 1.0, ATTN_NORM, 0); } } } // Save current origin if needed if (le->flags & (CLM_BOUNCE)) { VectorCopy(le->lastOrg, ent.origin); VectorCopy(org, le->lastOrg); // FIXME: pause } else VectorCopy(org, ent.origin); if (CL_PMpointcontents(ent.origin) & MASK_SOLID) { // kill entity // in solid le->alpha = 0; continue; } ent.model = le->model; if (!ent.model) continue; ent.lod1 = NULL; ent.lod2 = NULL; ent.angles[0] = le->ang + ((le->flags & CLM_ROTATE) ? (time * le->avel) : 0);; ent.angles[2] = le->ang + ((le->flags & CLM_ROTATE) ? (time * le->avel) : 0);; ent.angles[1] = le->ang + ((le->flags & CLM_ROTATE) ? (time * le->avel) : 0); ent.frame = ent.oldframe = 0; if(le->flags & CLM_GLASS) ent.flags |= RF_TRANSLUCENT; V_AddEntity(&ent); } active_clentities = active; } void CL_ClearClEntities() { int i; free_clentities = &clentities[0]; active_clentities = NULL; for (i = 0; i < MAX_CLENTITIES-1; i++) clentities[i].next = &clentities[i + 1]; clentities[MAX_CLENTITIES - 1].next = NULL; } alien-arena-7.66+dfsg/source/client/cl_stats.c0000600000175000017500000002371412161402010020347 0ustar zero79zero79/* Copyright (C) 2010 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "client.h" #include "qcommon/md5.h" #if defined HAVE_UNISTD_H #include #endif #include "curl/curl.h" CURLM *curlm; CURL *curl; #define STAT_PROTOCOL 1 extern cvar_t *cl_master; extern cvar_t *cl_stats_server; extern cvar_t *name; extern cvar_t *stats_password; extern cvar_t *pw_hashed; static char szVerificationString[64]; static char *cpr; // mostly for unused result warnings static FILE* statsdb_open( const char* mode ) { FILE* file; char pathbfr[MAX_OSPATH]; Com_sprintf (pathbfr, sizeof(pathbfr)-1, "%s/%s", FS_Gamedir(), "stats.db"); file = fopen( pathbfr, mode ); return file; } static size_t write_data(const void *buffer, size_t size, size_t nmemb, void *userp) { FILE* file; size_t bytecount = 0; file = statsdb_open( "a" ); //append, don't rewrite if(file) { //write buffer to file bytecount = fwrite( buffer, size, nmemb, file ); fclose(file); } return bytecount; } //get the stats database void STATS_getStatsDB( void ) { FILE* file; char statserver[128]; CURL* easyhandle = curl_easy_init() ; file = statsdb_open( "w" ); //create new, blank file for writing if(file) fclose(file); Com_sprintf(statserver, sizeof(statserver), "%s%s", cl_stats_server->string, "/playerrank.db"); curl_easy_setopt( easyhandle, CURLOPT_URL, statserver ) ; // time out in 5s curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5); curl_easy_setopt( easyhandle, CURLOPT_WRITEFUNCTION, write_data ) ; curl_easy_perform( easyhandle ); curl_easy_cleanup( easyhandle ); } //parse the stats database, looking for player match PLAYERSTATS getPlayerRanking ( PLAYERSTATS player ) { FILE* file; char name[34], points[32], frags[32], totalfrags[32], time[16], totaltime[16], ip[32], poll[16], remote_address[21]; int foundplayer = false; //open file, file = statsdb_open( "r" ) ; if(file != NULL) { //parse it, and compare to player name while(player.ranking < 1000) { //name. upto 31 chars total, 15 are printable. // fgets needs at least 33 chars. 31 + newline + terminating nul cpr = fgets(name, sizeof(name), file); if ( cpr == NULL ) { // end-of-file break; } if ( name[strlen(name) - 1] == '\n' ) { name[strlen(name) - 1] = 0; //truncate garbage byte } //remote address cpr = fgets(remote_address, sizeof(remote_address), file); //points cpr = fgets(points, sizeof(points), file); //frags cpr = fgets(frags, sizeof(frags), file); //total frags cpr = fgets(totalfrags, sizeof(totalfrags), file); if(!strcmp(player.playername, name)) player.totalfrags = atoi(totalfrags); //current time in poll cpr = fgets(time, sizeof(time), file); //total time cpr = fgets(totaltime, sizeof(totaltime), file); if(!strcmp(player.playername, name)) player.totaltime = atof(totaltime); //last server.ip cpr = fgets(ip, sizeof(ip), file); //what poll cpr = fgets(poll, sizeof(poll), file); player.ranking++; if(!strcmp(player.playername, name)) { foundplayer = true; break; //get out we are done } } fclose(file); } if(!foundplayer) { player.ranking = 1000; player.totalfrags = 0; player.totaltime = 1; } return player; } //get player info by rank PLAYERSTATS getPlayerByRank ( int rank, PLAYERSTATS player ) { FILE* file; char name[32], points[32], frags[32], totalfrags[32], time[16], totaltime[16], ip[32], poll[16], remote_address[21]; int foundplayer = false; //open file, file = statsdb_open( "r" ) ; if(file != NULL) { //parse it, and compare to player name while(player.ranking < 1000) { //name cpr = fgets(name, sizeof(name), file); strcpy(player.playername, name); player.playername[strlen(player.playername)-1] = 0; //remove line feed //remote address cpr = fgets(remote_address, sizeof(remote_address), file); //points cpr = fgets(points, sizeof(points), file); //frags cpr = fgets(frags, sizeof(frags), file); //total frags cpr = fgets(totalfrags, sizeof(totalfrags), file); player.totalfrags = atoi(totalfrags); //current time in poll cpr = fgets(time, sizeof(time), file); //total time cpr = fgets(totaltime, sizeof(totaltime), file); player.totaltime = atof(totaltime); //last server.ip cpr = fgets(ip, sizeof(ip), file); //what poll cpr = fgets(poll, sizeof(poll), file); player.ranking++; if(player.ranking == rank) { foundplayer = true; break; //get out we are done } } fclose(file); } if(!foundplayer) { player.totalfrags = 0; player.totaltime = 1; strcpy(player.playername, "unknown"); } return player; } //This next section deals with account verification //Passwords are hashed before storing or sending, raw strings are never exposed. //Send request for login(vstrings are random, unique strings that the server generates for each player - provides an extra layer of encryption) void STATS_RequestVerification (void) { char *requeststring; netadr_t adr; if(currLoginState.validated) return; //already validated NET_Config (true); currLoginState.requestType = STATSLOGIN; requeststring = va("requestvstring\\\\%i\\\\%s", STAT_PROTOCOL, name->string); if( NET_StringToAdr( cl_master->string, &adr ) ) { if( !adr.port ) adr.port = BigShort( PORT_STATS ); Netchan_OutOfBandPrint( NS_CLIENT, adr, requeststring ); } else { Com_Printf( "Bad address: %s\n", cl_master->string); } } //Send request for password change void STATS_RequestPwChange (void) { char *requeststring; netadr_t adr; currLoginState.validated = false; //force new login with new password NET_Config (true); currLoginState.requestType = STATSPWCHANGE; requeststring = va("requestvstring\\\\%i\\\\%s", STAT_PROTOCOL, name->string); if( NET_StringToAdr( cl_master->string, &adr ) ) { if( !adr.port ) adr.port = BigShort( PORT_STATS ); Netchan_OutOfBandPrint( NS_CLIENT, adr, requeststring ); } else { Com_Printf( "Bad address: %s\n", cl_master->string); } } void STATS_EncryptPassword(void) { char szPassword[256]; char szPassHash[256]; char szPassHash2[256]; //salt Com_sprintf(szPassword, sizeof(szPassword), "%s%s", stats_password->string, szVerificationString); Com_MD5HashString (szPassword, strlen(szPassword), szPassHash, sizeof(szPassHash)); //salt Com_sprintf(szPassword, sizeof(szPassword), "%s%s", szPassHash, szVerificationString); Com_MD5HashString (szPassword, strlen(szPassword), szPassHash, sizeof(szPassHash)); Com_HMACMD5String(szPassHash, strlen(szPassHash), szVerificationString, strlen(szVerificationString), szPassHash2, sizeof(szPassHash2)); Cvar_FullSet("stats_pw_hashed", "1", CVAR_PROFILE); Cvar_FullSet("stats_password", szPassHash2, CVAR_PROFILE); currLoginState.hashed = true; //get new hashed password stats_password = Cvar_Get("stats_password", "password", CVAR_PROFILE); } //Send stats server authentication pw void STATS_AuthenticateStats (char *vstring) { char *requeststring; netadr_t adr; Q_strncpyz2(szVerificationString, vstring, sizeof(szVerificationString)); NET_Config (true); //use md5 encryption on password, never send or store a raw password! if(!pw_hashed->integer) { STATS_EncryptPassword(); } requeststring = va("login\\\\%i\\\\%s\\\\%s\\\\%s\\\\", STAT_PROTOCOL, name->string, stats_password->string, szVerificationString ); if( NET_StringToAdr( cl_master->string, &adr ) ) { if( !adr.port ) adr.port = BigShort( PORT_STATS ); Netchan_OutOfBandPrint( NS_CLIENT, adr, requeststring ); } else { Com_Printf( "Bad address: %s\n", cl_master->string); } } //Send password change request to server(this is to be called from the menu when a password is edited) void STATS_ChangePassword (char *vstring) { char *requeststring; netadr_t adr; Q_strncpyz2(szVerificationString, vstring, sizeof(szVerificationString)); NET_Config (true); STATS_EncryptPassword(); requeststring = va("changepw\\\\%i\\\\%s\\\\%s\\\\%s\\\\%s\\\\", STAT_PROTOCOL, name->string, currLoginState.old_password, stats_password->string, szVerificationString); if( NET_StringToAdr( cl_master->string, &adr ) ) { if( !adr.port ) adr.port = BigShort( PORT_STATS ); Netchan_OutOfBandPrint( NS_CLIENT, adr, requeststring ); } else { Com_Printf( "Bad address: %s\n", cl_master->string); } } //Logout of stats server void STATS_Logout (void) { char *requeststring; netadr_t adr; if(!currLoginState.validated) return; //no point in logging out, we were never validated! NET_Config (true); //use md5 encryption on password, never send or store a raw password! if(!pw_hashed->integer) { STATS_EncryptPassword(); } requeststring = va("logout\\\\%i\\\\%s\\\\%s\\\\%s\\\\", STAT_PROTOCOL, name->string, stats_password->string, szVerificationString ); if( NET_StringToAdr( cl_master->string, &adr ) ) { if( !adr.port ) adr.port = BigShort( PORT_STATS ); Netchan_OutOfBandPrint( NS_CLIENT, adr, requeststring ); } else { Com_Printf( "Bad address: %s\n", cl_master->string); } } alien-arena-7.66+dfsg/source/client/console.h0000600000175000017500000001107712161402010020201 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CL_CONSOLE_H #define __CL_CONSOLE_H // // console // /**************************************************************************/ /* CONSTANTS */ /**************************************************************************/ /* Maximal length of a command line */ #define MAXCMDLINE 256 /* Maximal amount of lines in the console's buffer */ #define CON_MAX_LINES 4096 /* Length of a line in the console's buffer */ #define CON_LINE_LENGTH 128 /* Maximal amount of in-game notifications */ #define CON_MAX_NOTIFY 4 /**************************************************************************/ /* DATA STRUCTURES */ /**************************************************************************/ /* * The console's main data structure. * * It includes the console's buffers, notification timestamps, and display * status. */ struct CON_console_s { /* Indicates that the console has been initialised */ qboolean initialised; /* Text in the console buffer */ char text[ CON_MAX_LINES ][ CON_LINE_LENGTH ]; int lCount[ CON_MAX_LINES ]; /* Height of the various lines */ int heights[ CON_MAX_LINES ]; /* Amount of lines in the console buffer */ int lines; /* Current line */ int curLine; /* Offset in the current line */ int offset; /* Time at which the last lines were generated - used for notifications */ float times[ CON_MAX_NOTIFY ]; int curTime; /* Previous display parameters, if any */ int pWidth; char pFace[ FNT_FACE_NAME_MAX ]; unsigned int pSize; /* Offset from which the console is being displayed */ int displayOffset; }; /* The console's main structure */ extern struct CON_console_s CON_console; /**************************************************************************/ /* CONSOLE FUNCTIONS */ /**************************************************************************/ /* * Initialise the console. * * This function prepares the console for text storage, and registers CVars * and commands associated with both the console and the in-game chat line. */ void CON_Initialise( ); /* * Add text to the console. * * This function prints text to the console's buffer. Notification timestamps * are updated, and line heights are set to 0 for modified lines. * * Parameters: * text the text to add */ void CON_Print( const char * text ); /* * Clear the console. * * This function resets the console's buffer as well as notification * timestamps. */ void CON_Clear( ); /* * Draw the console. * * Parameters: * relSize vertical size of the console relative to the screen's * size */ void CON_DrawConsole( float relSize ); /* * Show or hide the console */ void CON_ToggleConsole( ); /**************************************************************************/ /* NOTIFICATION FUNCTIONS */ /**************************************************************************/ /* * Clear notification timestamps. * * This function resets the console's notification timestamps without * affecting the rest of the console's data. */ void CON_ClearNotify( ); /* * Draw the few last lines of the console transparently over the game. */ void CON_DrawNotify( ); /**************************************************************************/ /* CONSOLE LINE EDITION DATA */ /**************************************************************************/ extern char key_lines[32][MAXCMDLINE]; extern int edit_line; extern int key_linepos; extern int key_linelen; #endif // __CL_CONSOLE_H alien-arena-7.66+dfsg/source/client/client.h0000600000175000017500000005362412161402010020021 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // client.h -- primary header for client //define PARANOID // speed sapping error checking #include #include #include #include #include #include "ref.h" #include "ref_gl/r_text.h" #include "vid.h" #include "screen.h" #include "sound.h" #include "input.h" #include "keys.h" #include "console.h" //============================================================================= typedef struct { qboolean valid; // cleared if delta parsing was invalid int serverframe; int servertime; // server time the message is valid for (in msec) int deltaframe; byte areabits[MAX_MAP_AREAS/8]; // portalarea visibility bits player_state_t playerstate; int num_entities; int parse_entities; // non-masked index into cl_parse_entities array } frame_t; typedef struct { entity_state_t baseline; // delta from this if not from a previous frame entity_state_t current; entity_state_t prev; // will always be valid, but might just be a copy of current int serverframe; // if not current, this ent isn't in the frame int trailcount; // for diminishing grenade trails vec3_t lerp_origin; // for trails (variable hz) int fly_stoptime; float frametime; int prevframe; particle_t *pr; // for chained particles (such as EF_SHIPEXHAUST) } centity_t; #define MAX_CLIENTWEAPONMODELS 20 // PGM -- upped from 16 to fit the chainfist vwep typedef struct { char name[MAX_QPATH]; char cinfo[MAX_QPATH]; struct image_s *skin; struct image_s *icon; char iconname[MAX_QPATH]; struct model_s *model; struct model_s *weaponmodel[MAX_CLIENTWEAPONMODELS]; struct model_s *helmet; struct model_s *lod1; struct model_s *lod2; } clientinfo_t; extern char cl_weaponmodels[MAX_CLIENTWEAPONMODELS][MAX_QPATH]; extern int num_cl_weaponmodels; extern char scr_playericon[MAX_OSPATH]; extern char scr_playername[PLAYERNAME_SIZE]; extern float scr_playericonalpha; #define CMD_BACKUP 64 // allow a lot of command backups for very fast systems // // the client_state_t structure is wiped completely at every // server map change // typedef struct { int timeoutcount; int timedemo_frames; int timedemo_start; qboolean refresh_prepped; // false if on new level or new ref dll qboolean sound_prepped; // ambient sounds can start qboolean force_refdef; // vid has changed, so we can't use a paused refdef int parse_entities; // index (not anded off) into cl_parse_entities[] usercmd_t cmd; usercmd_t cmds[CMD_BACKUP]; // each mesage will send several old cmds int cmd_time[CMD_BACKUP]; // time sent, for calculating pings int predicted_origins[CMD_BACKUP][3]; // for debug comparing against server float predicted_step; // for stair up smoothing unsigned predicted_step_time; vec3_t predicted_origin; // generated by CL_PredictMovement vec3_t predicted_angles; vec3_t last_predicted_angles; vec3_t predicted_velocity; // for speedometer vec3_t prediction_error; frame_t frame; // received from server int surpressCount; // number of messages rate supressed frame_t frames[UPDATE_BACKUP]; // the client maintains its own idea of view angles, which are // sent to the server each frame. It is cleared to 0 upon entering each level. // the server sends a delta each frame which is added to the locally // tracked view angles to account for standing on rotating objects, // and teleport direction changes vec3_t viewangles; int time; // this is the time value that the client // is rendering at. always <= cls.realtime float lerpfrac; // between oldframe and frame refdef_t refdef; vec3_t v_forward, v_right, v_up; // set when refdef.angles is set // // transient data from server // char layout[1024]; // general 2D overlay int inventory[MAX_ITEMS]; // // server state information // qboolean attractloop; // running the attract loop, any key will menu int servercount; // server identification for prespawns char gamedir[MAX_QPATH]; int playernum; qboolean tactical; //used for certain client needs // Alien Arena client/server protocol depends on MAX_QPATH being 64. char configstrings[MAX_CONFIGSTRINGS][MAX_QPATH]; // // locally derived information from server state // struct model_s *model_draw[MAX_MODELS]; struct cmodel_s *model_clip[MAX_MODELS]; struct sfx_s *sound_precache[MAX_SOUNDS]; struct image_s *image_precache[MAX_IMAGES]; clientinfo_t clientinfo[MAX_CLIENTS]; clientinfo_t baseclientinfo; } client_state_t; extern client_state_t cl; /* ================================================================== the client_static_t structure is persistant through an arbitrary number of server connections ================================================================== */ typedef enum { ca_uninitialized, ca_disconnected, // not talking to a server ca_connecting, // sending request packets to the server ca_connected, // netchan_t established, waiting for svc_serverdata ca_active // game views should be displayed } connstate_t; typedef enum { dl_none, dl_model, dl_sound, dl_skin, dl_single } dltype_t; // download type typedef enum {key_game, key_console, key_message, key_menu} keydest_t; typedef struct { connstate_t state; keydest_t key_dest; int framecount; int realtime; // always increasing, no clamping, etc float frametime; // seconds since last frame // screen rendering information float disable_screen; // showing loading plaque between levels // or changing rendering dlls // if time gets > 30 seconds ahead, break it int disable_servercount; // when we receive a frame and cl.servercount // > cls.disable_servercount, clear disable_screen // connection information char servername[MAX_OSPATH]; // name of server from original connect float connect_time; // for connection retransmits int quakePort; // a 16 bit value that allows quake servers // to work around address translating routers netchan_t netchan; int serverProtocol; // in case we are doing some kind of version hack int challenge; // from the server to use for connecting FILE *download; // file transfer from server char downloadtempname[MAX_OSPATH]; char downloadname[MAX_OSPATH]; int downloadnumber; dltype_t downloadtype; int downloadpercent; char downloadurl[MAX_OSPATH]; // for http downloads qboolean downloadhttp; // demo recording info must be here, so it isn't cleared on level change qboolean demorecording; qboolean demowaiting; // don't record until a non-delta message is received FILE *demofile; } client_static_t; extern client_static_t cls; //============================================================================= // // cvars // extern cvar_t *cl_stereo_separation; extern cvar_t *cl_stereo; extern cvar_t *cl_maxfps; extern cvar_t *cl_gun; extern cvar_t *cl_add_blend; extern cvar_t *cl_add_lights; extern cvar_t *cl_add_particles; extern cvar_t *cl_add_entities; extern cvar_t *cl_predict; extern cvar_t *cl_footsteps; extern cvar_t *cl_noskins; extern cvar_t *cl_autoskins; extern cvar_t *cl_healthaura; extern cvar_t *cl_noblood; extern cvar_t *cl_disbeamclr; extern cvar_t *cl_dmlights; extern cvar_t *cl_brass; extern cvar_t *cl_playtaunts; extern cvar_t *cl_centerprint; extern cvar_t *cl_precachecustom; extern cvar_t *cl_simpleitems; extern cvar_t *cl_flicker; extern cvar_t *cl_paindist; extern cvar_t *cl_explosiondist; extern cvar_t *cl_raindist; extern cvar_t *cl_upspeed; extern cvar_t *cl_forwardspeed; extern cvar_t *cl_sidespeed; extern cvar_t *cl_yawspeed; extern cvar_t *cl_pitchspeed; extern cvar_t *cl_run; extern cvar_t *cl_anglespeedkey; extern cvar_t *cl_shownet; extern cvar_t *cl_showmiss; extern cvar_t *cl_showclamp; extern cvar_t *lookspring; extern cvar_t *lookstrafe; extern cvar_t *m_accel; extern cvar_t *sensitivity; extern cvar_t *menu_sensitivity; extern cvar_t *m_smoothing; extern cvar_t *m_filter; extern cvar_t *m_pitch; extern cvar_t *m_yaw; extern cvar_t *m_forward; extern cvar_t *m_side; extern cvar_t *freelook; extern cvar_t *cl_paused; extern cvar_t *cl_timedemo; extern cvar_t *cl_vwep; extern cvar_t *cl_vehicle_huds; extern cvar_t *background_music; extern cvar_t *cl_IRC_connect_at_startup; extern cvar_t *cl_IRC_server; extern cvar_t *cl_IRC_channel; extern cvar_t *cl_IRC_port; extern cvar_t *cl_IRC_override_nickname; extern cvar_t *cl_IRC_nickname; extern cvar_t *cl_IRC_kick_rejoin; extern cvar_t *cl_IRC_reconnect_delay; extern cvar_t *cl_latest_game_version; extern cvar_t *cl_test; typedef struct { int key; // so entities can reuse same entry vec3_t color; vec3_t origin; float radius; float die; // stop lighting after this time float decay; // drop this each second float minlight; // don't add when contributing less } cdlight_t; extern centity_t cl_entities[MAX_EDICTS]; extern cdlight_t cl_dlights[MAX_DLIGHTS]; // the cl_parse_entities must be large enough to hold UPDATE_BACKUP frames of // entities, so that when a delta compressed message arives from the server // it can be un-deltad from the original #define MAX_PARSE_ENTITIES 1024 extern entity_state_t cl_parse_entities[MAX_PARSE_ENTITIES]; //============================================================================= extern netadr_t net_from; extern sizebuf_t net_message; qboolean CL_CheckOrDownloadFile (char *filename); void CL_AddNetgraph (void); //ROGUE typedef struct cl_sustain { int id; int type; int endtime; int nextthink; int thinkinterval; vec3_t org; vec3_t dir; int color; int count; int magnitude; void (*think)(struct cl_sustain *self); } cl_sustain_t; #define MAX_SUSTAINS 32 //================================================= #define PARTICLE_GRAVITY 40 #define BLASTER_PARTICLE_COLOR 0xe0 // PMM #define INSTANT_PARTICLE -10000.0 // PGM // ======== // Berserker client entities code #define MAX_CLENTITIES 256 #define CLM_BOUNCE 1 #define CLM_FRICTION 2 #define CLM_ROTATE 4 #define CLM_NOSHADOW 8 #define CLM_STOPPED 16 #define CLM_BRASS 32 #define CLM_GLASS 64 typedef struct clentity_s { struct clentity_s *next; float time; vec3_t org; vec3_t lastOrg; vec3_t vel; vec3_t accel; struct model_s *model; float ang; float avel; float alpha; float alphavel; int flags; } clentity_t; void CL_AddClEntities(void); void CL_ClearClEntities(void); void CL_ClearEffects (void); void CL_ClearTEnts (void); void CL_BlasterBall (vec3_t start, vec3_t end); void CL_DisruptorBeam (vec3_t start, vec3_t end); void CL_LaserBeam (vec3_t start, vec3_t end); void CL_BlasterBeam (vec3_t start, vec3_t end); void CL_RedBlasterBeam (vec3_t start, vec3_t end); void CL_VaporizerBeam (vec3_t start, vec3_t end); void CL_BubbleTrail (vec3_t start, vec3_t end); void CL_NewLightning (vec3_t start, vec3_t end); void CL_BlueTeamLight(vec3_t pos); void CL_RedTeamLight(vec3_t pos); void CL_FlagEffects(vec3_t pos, qboolean team); void CL_PoweredEffects (vec3_t pos); void CL_SmokeTrail (vec3_t start, vec3_t end, int colorStart, int colorRun, int spacing); void CL_SayIcon(vec3_t org); void CL_TeleportParticles (vec3_t org); void CL_BlasterParticles (vec3_t org, vec3_t dir); void CL_ExplosionParticles (vec3_t org); void CL_MuzzleParticles (vec3_t org); void CL_BlueMuzzleParticles (vec3_t org); void CL_SmartMuzzle (vec3_t org); void CL_Voltage(vec3_t org); void CL_Deathfield (vec3_t org, int type); void CL_BFGExplosionParticles (vec3_t org); void CL_DustParticles (vec3_t org); void CL_BlueBlasterParticles (vec3_t org, vec3_t dir); void CL_ParticleSteamEffect(cl_sustain_t *self); void CL_ParticleFireEffect2(cl_sustain_t *self); void CL_ParticleSmokeEffect2(cl_sustain_t *self); void CL_ParticleEffect (vec3_t org, vec3_t dir, int color, int count); void CL_ParticleEffect2 (vec3_t org, vec3_t dir, int color, int count); void CL_BulletSparks ( vec3_t org, vec3_t dir); void CL_SplashEffect ( vec3_t org, vec3_t dir, int color, int count); void CL_LaserSparks ( vec3_t org, vec3_t dir, int color, int count); void CL_SmallHealthParticles(vec3_t org); void CL_MedHealthParticles(vec3_t org); void CL_LargeHealthParticles(vec3_t org); void CL_BrassShells(vec3_t org, vec3_t dir, int count); void CL_MuzzleFlashParticle (vec3_t org, vec3_t angles, qboolean from_client); void CL_PlasmaFlashParticle (vec3_t org, vec3_t angles, qboolean from_client); int CL_ParseEntityBits (unsigned *bits); void CL_ParseDelta (entity_state_t *from, entity_state_t *to, int number, int bits); void CL_ParseFrame (void); void CL_ParseTEnt (void); void CL_ParseConfigString (void); void CL_ParseMuzzleFlash (void); void CL_ParseMuzzleFlash2 (void); void SmokeAndFlash(vec3_t origin); void CL_SetLightstyle (int i); void CL_RunParticles (void); void CL_RunDLights (void); void CL_RunLightStyles (void); void CL_AddEntities (void); void CL_AddDLights (void); void CL_AddTEnts (void); void CL_AddLightStyles (void); //================================================= void CL_PrepRefresh (void); void CL_RegisterSounds (void); void CL_RegisterModels (void); void CL_Quit_f (void); void IN_Accumulate (void); void CL_ParseLayout (void); // // cl_main // extern qboolean send_packet_now; void CL_Init (void); void CL_FixUpGender(void); void CL_Disconnect (void); void CL_Disconnect_f (void); void CL_GetChallengePacket (void); void CL_PingServers_f (void); void CL_Snd_Restart_f (void); void CL_RequestNextDownload (void); // // cl_input // typedef struct { int down[2]; // key nums holding it down unsigned downtime; // msec timestamp unsigned msec; // msec down this frame int state; } kbutton_t; extern kbutton_t in_mlook, in_klook; extern kbutton_t in_strafe; extern kbutton_t in_speed; void CL_InitInput (void); void CL_SendCmd (void); void CL_SendMove (usercmd_t *cmd); void CL_ClearState (void); int CL_ReadFromServer (void); void CL_WriteToServer (usercmd_t *cmd); void CL_BaseMove (usercmd_t *cmd); void IN_CenterView (void); float CL_KeyState (kbutton_t *key); char *Key_KeynumToString (int keynum); extern qboolean mouse_available; void IN_MLookDown (void); void IN_MLookUp (void); //cl_irc.c void CL_IRCSetup(void); void CL_InitIRC(void); void CL_IRCInitiateShutdown(void); void CL_IRCWaitShutdown(void); void CL_IRCSay(void); qboolean CL_IRCIsConnected(void); qboolean CL_IRCIsRunning(void); // // cl_demo.c // void CL_WriteDemoMessage (void); void CL_Stop_f (void); void CL_Record_f (void); // // cl_parse.c // extern char *svc_strings[256]; extern void Q_strncpyz( char *dest, const char *src, size_t size ); void CL_ParseServerMessage (void); void CL_LoadClientinfo (clientinfo_t *ci, char *s); void SHOWNET(char *s); void CL_ParseClientinfo (int player); void CL_Download_f (void); // // cl_scrn.c // void SCR_IRCPrintf (char *fmt, ...); // // cl_stats.c // typedef struct _PLAYERSTATS { char playername[PLAYERNAME_SIZE]; int totalfrags; double totaltime; int ranking; } PLAYERSTATS; typedef struct _STATSLOGINSTATE { int requestType; qboolean validated; qboolean hashed; char old_password[256]; } LOGINSTATE; #define STATSLOGIN 1 #define STATSPWCHANGE 2 void STATS_getStatsDB( void ); void STATS_RequestVerification( void ); void STATS_RequestPwChange (void); void STATS_AuthenticateStats (char *vstring); void STATS_ChangePassword (char *vstring); void STATS_Logout (void); PLAYERSTATS getPlayerRanking ( PLAYERSTATS player ); PLAYERSTATS getPlayerByRank ( int rank, PLAYERSTATS player ); LOGINSTATE currLoginState; // // cl_updates.c // void getLatestGameVersion( void ); qboolean serverIsOutdated (char *server_vstring); char* VersionUpdateNotice( void ); // // cl_view.c // #define CL_LOADMSG_LENGTH 96 extern qboolean need_free_vbo; qboolean loadingMessage; char loadingMessages[5][2][CL_LOADMSG_LENGTH]; float loadingPercent; int rocketlauncher; int rocketlauncher_drawn; int chaingun; int chaingun_drawn; int smartgun; int smartgun_drawn; int flamethrower; int flamethrower_drawn; int disruptor; int disruptor_drawn; int beamgun; int beamgun_drawn; int vaporizer; int vaporizer_drawn; int quad; int quad_drawn; int haste; int haste_drawn; int inv; int inv_drawn; int adren; int adren_drawn; int sproing; int sproing_drawn; int numitemicons; int vehicle_hud; void V_Init (void); void V_RenderView( float stereo_separation ); void V_AddEntity (entity_t *ent); void V_AddViewEntity (entity_t *ent); void V_AddParticle (particle_t *p); void V_AddLight (vec3_t org, float intensity, float r, float g, float b); void V_AddTeamLight (vec3_t org, float intensity, float r, float g, float b, int team); void V_AddLightStyle (int style, float r, float g, float b); void V_AddStain (vec3_t org, float intensity, float r, float g, float b, float a); // // cl_tent.c // void CL_RegisterTEntSounds (void); void CL_RegisterTEntModels(void); // // cl_pred.c // void CL_InitPrediction (void); void CL_PredictMove (void); void CL_CheckPredictionError (void); trace_t CL_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int skipNumber, int brushMask, qboolean brushOnly, int *entNumber); trace_t CL_PMSurfaceTrace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int contentmask); // // cl_fx.c // cdlight_t *CL_AllocDlight (int key); void CL_BigTeleportParticles (vec3_t org); void CL_RocketTrail (vec3_t start, vec3_t end, centity_t *old); void CL_BlasterTrail (vec3_t start, vec3_t end, centity_t *old); void CL_ShipExhaust (vec3_t start, vec3_t end, centity_t *old); void CL_RocketExhaust (vec3_t start, vec3_t end, centity_t *old); void CL_BeamgunMark(vec3_t org, vec3_t dir, float dur, qboolean isDis); void CL_BulletMarks(vec3_t org, vec3_t dir); void CL_VaporizerMarks(vec3_t org, vec3_t dir); void CL_BlasterMark(vec3_t org, vec3_t dir); void CL_DiminishingTrail (vec3_t start, vec3_t end, centity_t *old, int flags); void CL_BfgParticles (entity_t *ent); void CL_AddParticles (void); void CL_EntityEvent (entity_state_t *ent); qboolean server_is_team; //used for player visibility light code // // menus // #define MAX_PLAYERS 64 typedef struct _SERVERDATA { char szHostName[48]; char szMapName[24], fullMapName[128]; char szAdmin[64]; char szVersion[32]; char szWebsite[32]; char maxClients[32]; char fraglimit[32]; char timelimit[32]; #define SVDATA_PLAYERINFO_NAME 0 #define SVDATA_PLAYERINFO_SCORE 1 #define SVDATA_PLAYERINFO_PING 2 #define SVDATA_PLAYERINFO 3 #define SVDATA_PLAYERINFO_COLSIZE 80 char playerInfo[MAX_PLAYERS][SVDATA_PLAYERINFO][SVDATA_PLAYERINFO_COLSIZE]; int playerRankings[MAX_PLAYERS]; char skill[32]; int players; char szPlayers[11]; int ping; char szPing[6]; netadr_t local_server_netadr; char serverInfo[256]; char modInfo[64]; qboolean joust; //for client-side prediction } SERVERDATA; SERVERDATA connectedserver; void M_Init (void); void M_Keydown (int key); void M_Draw (void); void M_Menu_Main_f (void); void M_ForceMenuOff (void); void M_AddToServerList (netadr_t adr, char *status_string); void M_UpdateConnectedServerInfo (netadr_t adr, char *status_string); // // cl_inv.c // void CL_ParseInventory (void); void CL_KeyInventory (int key); void CL_DrawInventory (void); // // cl_pred.c // void CL_PredictMovement (void); // // cl_view, cl_scrn // qboolean map_pic_loaded; int stringLen (char *string); // // perf testing // A performance test measures some form of "something per second." // typedef struct perftest_s { //these get set by get_perftest for you: qboolean in_use; char name[48]; //set these when first setting up the perf counter: cvar_t *cvar; //the cvar used for detecting whether to draw it char format[32]; //format one float, never output >32 chars float scale; //for scaling the rate qboolean is_timerate; //true to display "something per second." //update this once per frame: float counter; //for whatever you're measuring //these are internal to SCR_showPerfTest: float framecounter; qboolean restart; int start_msec; float update_trigger; char text[32]; } perftest_t; #define MAX_PERFTESTS 16 perftest_t perftests[MAX_PERFTESTS]; perftest_t *get_perftest(char *name); // //mouse // void refreshCursorLink (void); void M_Think_MouseCursor (void); // //cl_http.c // void CL_InitHttpDownload(void); void CL_HttpDownloadCleanup(void); qboolean CL_HttpDownload(void); void CL_HttpDownloadThink(void); void CL_ShutdownHttpDownload(void); // // Fonts used by various elements // extern FNT_auto_t CL_gameFont; extern FNT_auto_t CL_menuFont; extern FNT_auto_t CL_centerFont; extern FNT_auto_t CL_consoleFont; //external renderer extern void R_AddSimpleItem(int type, vec3_t origin); extern qboolean r_gotFlag; extern qboolean r_lostFlag; alien-arena-7.66+dfsg/source/client/input.h0000600000175000017500000000223212161402010017667 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // input.h -- external (non-keyboard) input devices void IN_Init (void); void IN_Shutdown (void); void IN_Commands (void); // oportunity for devices to stick commands on the script buffer void IN_Frame (void); // add movement from mouse on top of the keyboard move cmd void IN_Move (usercmd_t *cmd); // add movement from joystick on top of the keyboard and mouse move cmd void IN_JoyMove (usercmd_t *cmd); void IN_Activate (qboolean active); alien-arena-7.66+dfsg/source/client/qal.h0000600000175000017500000002613412161402010017314 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef QAL_H_ #define QAL_H_ /* * function pointers for library loaders */ extern LPALENABLE pqalEnable; extern LPALDISABLE pqalDisable; extern LPALISENABLED pqalIsEnabled; extern LPALGETBOOLEANV pqalGetBooleanv; extern LPALGETINTEGERV pqalGetIntegerv; extern LPALGETSTRING pqalGetString; extern LPALGETFLOATV pqalGetFloatv; extern LPALGETDOUBLEV pqalGetDoublev; extern LPALGETBOOLEAN pqalGetBoolean; extern LPALGETINTEGER pqalGetInteger; extern LPALGETFLOAT pqalGetFloat; extern LPALGETDOUBLE pqalGetDouble; extern LPALGETERROR pqalGetError; extern LPALISEXTENSIONPRESENT pqalIsExtensionPresent; extern LPALGETPROCADDRESS pqalGetProcAddress; extern LPALGETENUMVALUE pqalGetEnumValue; extern LPALLISTENERF pqalListenerf; extern LPALLISTENER3F pqalListener3f; extern LPALLISTENERFV pqalListenerfv; extern LPALLISTENERI pqalListeneri; extern LPALLISTENER3I pqalListener3i; extern LPALLISTENERIV pqalListeneriv; extern LPALGETLISTENERF pqalGetListenerf; extern LPALGETLISTENER3F pqalGetListener3f; extern LPALGETLISTENERFV pqalGetListenerfv; extern LPALGETLISTENERI pqalGetListeneri; extern LPALGETLISTENER3I pqalGetListener3i; extern LPALGETLISTENERIV pqalGetListeneriv; extern LPALGENSOURCES pqalGenSources; extern LPALDELETESOURCES pqalDeleteSources; extern LPALISSOURCE pqalIsSource; extern LPALSOURCEF pqalSourcef; extern LPALSOURCE3F pqalSource3f; extern LPALSOURCEFV pqalSourcefv; extern LPALSOURCEI pqalSourcei; extern LPALSOURCE3I pqalSource3i; extern LPALSOURCEIV pqalSourceiv; extern LPALGETSOURCEF pqalGetSourcef; extern LPALGETSOURCE3F pqalGetSource3f; extern LPALGETSOURCEFV pqalGetSourcefv; extern LPALGETSOURCEI pqalGetSourcei; extern LPALGETSOURCE3I pqalGetSource3i; extern LPALGETSOURCEIV pqalGetSourceiv; extern LPALSOURCEPLAYV pqalSourcePlayv; extern LPALSOURCESTOPV pqalSourceStopv; extern LPALSOURCEREWINDV pqalSourceRewindv; extern LPALSOURCEPAUSEV pqalSourcePausev; extern LPALSOURCEPLAY pqalSourcePlay; extern LPALSOURCESTOP pqalSourceStop; extern LPALSOURCEREWIND pqalSourceRewind; extern LPALSOURCEPAUSE pqalSourcePause; extern LPALSOURCEQUEUEBUFFERS pqalSourceQueueBuffers; extern LPALSOURCEUNQUEUEBUFFERS pqalSourceUnqueueBuffers; extern LPALGENBUFFERS pqalGenBuffers; extern LPALDELETEBUFFERS pqalDeleteBuffers; extern LPALISBUFFER pqalIsBuffer; extern LPALBUFFERDATA pqalBufferData; extern LPALBUFFERF pqalBufferf; extern LPALBUFFER3F pqalBuffer3f; extern LPALBUFFERFV pqalBufferfv; extern LPALBUFFERI pqalBufferi; extern LPALBUFFER3I pqalBuffer3i; extern LPALBUFFERIV pqalBufferiv; extern LPALGETBUFFERF pqalGetBufferf; extern LPALGETBUFFER3F pqalGetBuffer3f; extern LPALGETBUFFERFV pqalGetBufferfv; extern LPALGETBUFFERI pqalGetBufferi; extern LPALGETBUFFER3I pqalGetBuffer3i; extern LPALGETBUFFERIV pqalGetBufferiv; extern LPALDOPPLERFACTOR pqalDopplerFactor; extern LPALDOPPLERVELOCITY pqalDopplerVelocity; extern LPALSPEEDOFSOUND pqalSpeedOfSound; extern LPALDISTANCEMODEL pqalDistanceModel; extern LPALCCREATECONTEXT pqalcCreateContext; extern LPALCMAKECONTEXTCURRENT pqalcMakeContextCurrent; extern LPALCPROCESSCONTEXT pqalcProcessContext; extern LPALCSUSPENDCONTEXT pqalcSuspendContext; extern LPALCDESTROYCONTEXT pqalcDestroyContext; extern LPALCGETCURRENTCONTEXT pqalcGetCurrentContext; extern LPALCGETCONTEXTSDEVICE pqalcGetContextsDevice; extern LPALCOPENDEVICE pqalcOpenDevice; extern LPALCCLOSEDEVICE pqalcCloseDevice; extern LPALCGETERROR pqalcGetError; extern LPALCISEXTENSIONPRESENT pqalcIsExtensionPresent; extern LPALCGETPROCADDRESS pqalcGetProcAddress; extern LPALCGETENUMVALUE pqalcGetEnumValue; extern LPALCGETSTRING pqalcGetString; extern LPALCGETINTEGERV pqalcGetIntegerv; extern LPALCCAPTUREOPENDEVICE pqalcCaptureOpenDevice; extern LPALCCAPTURECLOSEDEVICE pqalcCaptureCloseDevice; extern LPALCCAPTURESTART pqalcCaptureStart; extern LPALCCAPTURESTOP pqalcCaptureStop; extern LPALCCAPTURESAMPLES pqalcCaptureSamples; /* * Note: using functions that wrap the function pointers for easier development */ extern void qalEnable( ALenum capability ); extern void qalDisable( ALenum capability ); extern ALboolean qalIsEnabled( ALenum capability ); extern const ALchar *qalGetString( ALenum param ); extern void qalGetBooleanv( ALenum param, ALboolean *data ); extern void qalGetIntegerv( ALenum param, ALint *data ); extern void qalGetFloatv( ALenum param, ALfloat *data ); extern void qalGetDoublev( ALenum param, ALdouble *data ); extern ALboolean qalGetBoolean( ALenum param ); extern ALint qalGetInteger( ALenum param ); extern ALfloat qalGetFloat( ALenum param ); extern ALdouble qalGetDouble( ALenum param ); extern ALenum qalGetError( void ); extern void qalClearError( void ); extern ALboolean qalIsExtensionPresent( const ALchar *extname ); extern void *qalGetProcAddress( const ALchar *fname ); extern ALenum qalGetEnumValue( const ALchar *ename ); extern void qalListenerf( ALenum param, ALfloat value ); extern void qalListener3f( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ); extern void qalListenerfv( ALenum param, const ALfloat *values ); extern void qalListeneri( ALenum param, ALint value ); extern void qalListener3i( ALenum param, ALint value1, ALint value2, ALint value3 ); extern void qalListeneriv( ALenum param, const ALint *values ); extern void qalGetListenerf( ALenum param, ALfloat *value ); extern void qalGetListener3f( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 ); extern void qalGetListenerfv( ALenum param, ALfloat *values ); extern void qalGetListeneri( ALenum param, ALint *value ); extern void qalGetListener3i( ALenum param, ALint *value1, ALint *value2, ALint *value3 ); extern void qalGetListeneriv( ALenum param, ALint *values ); extern void qalGenSources( ALsizei n, ALuint *sources ); extern void qalDeleteSources( ALsizei n, const ALuint *sources ); extern ALboolean qalIsSource( ALuint sid ); extern void qalSourcef( ALuint sid, ALenum param, ALfloat value ); extern void qalSource3f( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ); extern void qalSourcefv( ALuint sid, ALenum param, const ALfloat *values ); extern void qalSourcei( ALuint sid, ALenum param, ALint value ); extern void qalSource3i( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 ); extern void qalSourceiv( ALuint sid, ALenum param, const ALint *values ); extern void qalGetSourcef( ALuint sid, ALenum param, ALfloat *value ); extern void qalGetSource3f( ALuint sid, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 ); extern void qalGetSourcefv( ALuint sid, ALenum param, ALfloat *values ); extern void qalGetSourcei( ALuint sid, ALenum param, ALint *value ); extern void qalGetSource3i( ALuint sid, ALenum param, ALint *value1, ALint *value2, ALint *value3 ); extern void qalGetSourceiv( ALuint sid, ALenum param, ALint *values ); extern void qalSourcePlayv( ALsizei ns, const ALuint *sids ); extern void qalSourceStopv( ALsizei ns, const ALuint *sids ); extern void qalSourceRewindv( ALsizei ns, const ALuint *sids ); extern void qalSourcePausev( ALsizei ns, const ALuint *sids ); extern void qalSourcePlay( ALuint sid ); extern void qalSourceStop( ALuint sid ); extern void qalSourceRewind( ALuint sid ); extern void qalSourcePause( ALuint sid ); extern void qalSourceQueueBuffers( ALuint sid, ALsizei numEntries, const ALuint *bids ); extern void qalSourceUnqueueBuffers( ALuint sid, ALsizei numEntries, ALuint *bids ); extern void qalGenBuffers( ALsizei n, ALuint *buffers ); extern void qalDeleteBuffers( ALsizei n, const ALuint *buffers ); extern ALboolean qalIsBuffer( ALuint bid ); extern void qalBufferData( ALuint bid, ALenum format, const ALvoid *data, ALsizei size, ALsizei freq ); extern void qalBufferf( ALuint bid, ALenum param, ALfloat value ); extern void qalBuffer3f( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ); extern void qalBufferfv( ALuint bid, ALenum param, const ALfloat *values ); extern void qalBufferi( ALuint bid, ALenum param, ALint value ); extern void qalBuffer3i( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 ); extern void qalBufferiv( ALuint bid, ALenum param, const ALint *values ); extern void qalGetBufferf( ALuint bid, ALenum param, ALfloat *value ); extern void qalGetBuffer3f( ALuint bid, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 ); extern void qalGetBufferfv( ALuint bid, ALenum param, ALfloat *values ); extern void qalGetBufferi( ALuint bid, ALenum param, ALint *value ); extern void qalGetBuffer3i( ALuint bid, ALenum param, ALint *value1, ALint *value2, ALint *value3 ); extern void qalGetBufferiv( ALuint bid, ALenum param, ALint *values ); extern void qalDopplerFactor( ALfloat value ); extern void qalDopplerVelocity( ALfloat value ); extern void qalSpeedOfSound( ALfloat value ); extern void qalDistanceModel( ALenum distanceModel ); extern ALCcontext *qalcCreateContext( ALCdevice *device, const ALCint *attrlist ); extern ALCboolean qalcMakeContextCurrent( ALCcontext *context ); extern void qalcProcessContext( ALCcontext *context ); extern void qalcSuspendContext( ALCcontext *context ); extern void qalcDestroyContext( ALCcontext *context ); extern ALCcontext *qalcGetCurrentContext( void ); extern ALCdevice *qalcGetContextsDevice( ALCcontext *context ); extern ALCdevice *qalcOpenDevice( const ALCchar *devicename ); extern ALCboolean qalcCloseDevice( ALCdevice *device ); extern ALCenum qalcGetError( ALCdevice *device ); extern ALCboolean qalcIsExtensionPresent( ALCdevice *device, const ALCchar *extname ); extern void *qalcGetProcAddress( ALCdevice *device, const ALCchar *funcname ); extern ALCenum qalcGetEnumValue( ALCdevice *device, const ALCchar *enumname ); extern const ALCchar *qalcGetString( ALCdevice *device, ALCenum param ); extern void qalcGetIntegerv( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *data ); extern ALCdevice *qalcCaptureOpenDevice( const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize ); extern ALCboolean qalcCaptureCloseDevice( ALCdevice *device ); extern void qalcCaptureStart( ALCdevice *device ); extern void qalcCaptureStop( ALCdevice *device ); extern void qalcCaptureSamples( ALCdevice *device, ALCvoid *buffer, ALCsizei samples ); /* * System dependent dynamic/shared lib managment */ extern qboolean QAL_Init( void ); extern void QAL_Shutdown( void ); extern qboolean QAL_Loaded( void ); #endif /* QAL_H_ */ alien-arena-7.66+dfsg/source/qcommon/0000700000175000017500000000000012207204656016572 5ustar zero79zero79alien-arena-7.66+dfsg/source/qcommon/cmodel.c0000600000175000017500000013475612161402010020202 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // cmodel.c -- model loading #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "qcommon.h" typedef struct { cplane_t *plane; int children[2]; // negative numbers are leafs } cnode_t; typedef struct { cplane_t *plane; mapsurface_t *surface; } cbrushside_t; typedef struct { int contents; int cluster; int area; unsigned short firstleafbrush; unsigned short numleafbrushes; } cleaf_t; typedef struct { int contents; int numsides; int firstbrushside; int checkcount; // to avoid repeated testings } cbrush_t; typedef struct { int numareaportals; int firstareaportal; int floodnum; // if two areas have equal floodnums, they are connected int floodvalid; } carea_t; int checkcount; char map_name[MAX_QPATH]; int numbrushsides; cbrushside_t map_brushsides[MAX_MAP_BRUSHSIDES]; int numtexinfo; mapsurface_t map_surfaces[MAX_MAP_TEXINFO]; int numplanes; cplane_t map_planes[MAX_MAP_PLANES+6]; // extra for box hull int numnodes; cnode_t map_nodes[MAX_MAP_NODES+6]; // extra for box hull int numleafs = 1; // allow leaf funcs to be called without a map cleaf_t map_leafs[MAX_MAP_LEAFS]; int emptyleaf, solidleaf; int numleafbrushes; unsigned short map_leafbrushes[MAX_MAP_LEAFBRUSHES]; int numcmodels; cmodel_t map_cmodels[MAX_MAP_MODELS]; int numbrushes; cbrush_t map_brushes[MAX_MAP_BRUSHES]; int numvisibility; byte map_visibility[MAX_MAP_VISIBILITY]; dvis_t *map_vis = (dvis_t *)map_visibility; int numentitychars; char map_entitystring[MAX_MAP_ENTSTRING]; int numareas = 1; carea_t map_areas[MAX_MAP_AREAS]; int numareaportals; dareaportal_t map_areaportals[MAX_MAP_AREAPORTALS]; int numclusters = 1; mapsurface_t nullsurface; int floodvalid; qboolean portalopen[MAX_MAP_AREAPORTALS]; cvar_t *map_noareas; void CM_InitBoxHull (void); void FloodAreaConnections (void); int c_pointcontents; int c_traces, c_brush_traces; /** * calculate the 3 signbits for a plane normal. * * @param plane * @return the signbits */ static byte signbits_for_plane(const cplane_t *plane) { byte bits; bits = plane->normal[0] < 0.0f ? (byte)0x01 : 0 ; bits |= plane->normal[1] < 0.0f ? (byte)0x02 : 0 ; bits |= plane->normal[2] < 0.0f ? (byte)0x04 : 0 ; return bits; } /* =============================================================================== MAP LOADING =============================================================================== */ byte *cmod_base; //Performs a sanity check on the BSP file, making sure all the lumps are nice //and shipshape and won't lead off a cliff somewhere. This does mean that the //BSP file format has been made less extensible, but we've tended to add more //data using separate files instead of adding lumps to the BSP, so I think we //can live with that. qboolean checkLumps (lump_t *l, size_t header_size, int *lump_order, void *_file_base, int num_lumps, int file_len) { int i = 0; lump_t *in; byte *lumpdata_base; byte *file_base = (byte *)_file_base; byte *lumpdata_next = file_base+header_size+sizeof(lump_t)*num_lumps; byte *file_end = file_base + file_len; for (i = 0; i < num_lumps; i++) { in = l+lump_order[i]; lumpdata_base = file_base+in->fileofs; if (lumpdata_base != lumpdata_next) return true; lumpdata_next = lumpdata_base+((in->filelen+3)&~3); if (lumpdata_next < lumpdata_base) return true; } if (lumpdata_next != file_end) return true; return false; } /* ================= CMod_LoadSubmodels ================= */ void CMod_LoadSubmodels (lump_t *l) { dmodel_t *in; cmodel_t *out; int i, j, count; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "CMod_LoadSubmodels: funny lump size"); count = l->filelen / sizeof(*in); if (count < 1) Com_Error (ERR_DROP, "Map with no models"); if (count > MAX_MAP_MODELS) Com_Error (ERR_DROP, "Map has too many models"); numcmodels = count; for ( i=0 ; imins[j] = LittleFloat (in->mins[j]) - 1; out->maxs[j] = LittleFloat (in->maxs[j]) + 1; out->origin[j] = LittleFloat (in->origin[j]); } out->headnode = LittleLong (in->headnode); } } /* ================= CMod_LoadSurfaces ================= */ void CMod_LoadSurfaces (lump_t *l) { texinfo_t *in; mapsurface_t *out; int i, count; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "CMod_LoadSurfaces: funny lump size"); count = l->filelen / sizeof(*in); if (count < 1) Com_Error (ERR_DROP, "Map with no surfaces"); if (count > MAX_MAP_TEXINFO) Com_Error (ERR_DROP, "Map has too many surfaces"); numtexinfo = count; out = map_surfaces; for ( i=0 ; ic.name, in->texture, sizeof(out->c.name)-1); strncpy (out->rname, in->texture, sizeof(out->rname)-1); out->c.flags = LittleLong (in->flags); out->c.value = LittleLong (in->value); } } /* ================= CMod_LoadNodes ================= */ void CMod_LoadNodes (lump_t *l) { dnode_t *in; int child; cnode_t *out; int i, j, count; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "CMod_LoadNodes: funny lump size"); count = l->filelen / sizeof(*in); if (count < 1) Com_Error (ERR_DROP, "Map has no nodes"); if (count > MAX_MAP_NODES) Com_Error (ERR_DROP, "Map has too many nodes"); out = map_nodes; numnodes = count; for (i=0 ; iplane = map_planes + LittleLong(in->planenum); for (j=0 ; j<2 ; j++) { child = LittleLong (in->children[j]); out->children[j] = child; } } } /* ================= CMod_LoadBrushes ================= */ void CMod_LoadBrushes (lump_t *l) { dbrush_t *in; cbrush_t *out; int i, count; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "CMod_LoadBrushes: funny lump size"); count = l->filelen / sizeof(*in); if (count > MAX_MAP_BRUSHES) Com_Error (ERR_DROP, "Map has too many brushes"); out = map_brushes; numbrushes = count; for (i=0 ; ifirstbrushside = LittleLong(in->firstside); out->numsides = LittleLong(in->numsides); out->contents = LittleLong(in->contents); } } /* ================= CMod_LoadLeafs ================= */ void CMod_LoadLeafs (lump_t *l) { int i; cleaf_t *out; dleaf_t *in; int count; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "CMod_LoadLeafs: funny lump size"); count = l->filelen / sizeof(*in); if (count < 1) Com_Error (ERR_DROP, "Map with no leafs"); // need to save space for box planes if (count > MAX_MAP_LEAFS) Com_Error (ERR_DROP, "Map has too many leafs"); out = map_leafs; numleafs = count; numclusters = 0; for ( i=0 ; icontents = LittleLong (in->contents); out->cluster = LittleShort (in->cluster); out->area = LittleShort (in->area); out->firstleafbrush = LittleShort (in->firstleafbrush); out->numleafbrushes = LittleShort (in->numleafbrushes); if (out->cluster >= numclusters) numclusters = out->cluster + 1; } if (map_leafs[0].contents != CONTENTS_SOLID) Com_Error (ERR_DROP, "Map leaf 0 is not CONTENTS_SOLID"); solidleaf = 0; emptyleaf = -1; for (i=1 ; ifileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "CMod_LoadPlanes: funny lump size"); count = l->filelen / sizeof(*in); if (count < 1) Com_Error (ERR_DROP, "Map with no planes"); // need to save space for box planes if (count > MAX_MAP_PLANES) Com_Error (ERR_DROP, "Map has too many planes"); out = map_planes; numplanes = count; for ( ; count-- ; in++, out++) { for (i=0 ; i<3 ; i++) { out->normal[i] = LittleFloat( in->normal[i] ); } out->dist = LittleFloat (in->dist); out->type = LittleLong (in->type); out->signbits = signbits_for_plane( out ); } } /* ================= CMod_LoadLeafBrushes ================= */ void CMod_LoadLeafBrushes (lump_t *l) { int i; unsigned short *out; unsigned short *in; int count; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "CMod_LoadLeafBrushes: funny lump size"); count = l->filelen / sizeof(*in); if (count < 1) Com_Error (ERR_DROP, "Map with no leafbrushes"); // need to save space for box planes if (count > MAX_MAP_LEAFBRUSHES) Com_Error (ERR_DROP, "Map has too many leafbrushes"); out = map_leafbrushes; numleafbrushes = count; for ( i=0 ; ifileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "CMod_LoadBrushSides: funny lump size"); count = l->filelen / sizeof(*in); // need to save space for box planes if (count > MAX_MAP_BRUSHSIDES) Com_Error (ERR_DROP, "Map has too many brushsides"); out = map_brushsides; numbrushsides = count; for ( i=0 ; iplanenum); out->plane = &map_planes[num]; j = LittleShort (in->texinfo); if (j >= numtexinfo) Com_Error (ERR_DROP, "Bad brushside texinfo"); out->surface = &map_surfaces[j]; } } /* ================= CMod_LoadAreas ================= */ void CMod_LoadAreas (lump_t *l) { int i; carea_t *out; darea_t *in; int count; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "CMod_LoadAreas: funny lump size"); count = l->filelen / sizeof(*in); if (count > MAX_MAP_AREAS) Com_Error (ERR_DROP, "Map has too many areas"); out = map_areas; numareas = count; for ( i=0 ; inumareaportals = LittleLong (in->numareaportals); out->firstareaportal = LittleLong (in->firstareaportal); out->floodvalid = 0; out->floodnum = 0; } } /* ================= CMod_LoadAreaPortals ================= */ void CMod_LoadAreaPortals (lump_t *l) { int i; dareaportal_t *out; dareaportal_t *in; int count; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "CMod_LoadAreaPortals: funny lump size"); count = l->filelen / sizeof(*in); if (count > MAX_MAP_AREAPORTALS) Com_Error (ERR_DROP, "Map has too many areaportals"); out = map_areaportals; numareaportals = count; for ( i=0 ; iportalnum = LittleLong (in->portalnum); out->otherarea = LittleLong (in->otherarea); } } /* ================= CMod_LoadVisibility ================= */ void CMod_LoadVisibility (lump_t *l) { int i; numvisibility = l->filelen; if (l->filelen > MAX_MAP_VISIBILITY) Com_Error (ERR_DROP, "Map has too large visibility lump"); memcpy (map_visibility, cmod_base + l->fileofs, l->filelen); map_vis->numclusters = LittleLong (map_vis->numclusters); for (i=0 ; inumclusters ; i++) { map_vis->bitofs[i][0] = LittleLong (map_vis->bitofs[i][0]); if (map_vis->bitofs[i][0] < 0 || map_vis->bitofs[i][0] >= numvisibility) Com_Error ( ERR_DROP, "Map contains invalid PVS bit offsets!\n" "The file is likely corrupted, please obtain a fresh copy."); map_vis->bitofs[i][1] = LittleLong (map_vis->bitofs[i][1]); if (map_vis->bitofs[i][1] < 0 || map_vis->bitofs[i][1] >= numvisibility) Com_Error ( ERR_DROP, "Map contains invalid PHS bit offsets!\n" "The file is likely corrupted, please obtain a fresh copy."); } } /* ================= CMod_LoadEntityString ================= */ void CMod_LoadEntityString (lump_t *l) { numentitychars = l->filelen; if (l->filelen > MAX_MAP_ENTSTRING) Com_Error (ERR_DROP, "Map has too large entity lump"); memcpy (map_entitystring, cmod_base + l->fileofs, l->filelen); } /* ================= CMod_LoadAlternateEntityData ================= */ void CMod_LoadAlternateEntityData (char *entity_file_name) { char *buf; numentitychars = FS_LoadFile (entity_file_name, (void **)&buf); if (numentitychars >= MAX_MAP_ENTSTRING) Com_Error (ERR_DROP, "Entity data has too large entity lump"); memcpy (map_entitystring, buf, numentitychars); map_entitystring[numentitychars] = '\0'; FS_FreeFile (buf); } /* ================== CM_LoadMap Loads in the map and all submodels ================== */ cmodel_t *CM_LoadBSP (char *name, qboolean clientload, unsigned *checksum) { unsigned *buf; unsigned int i; dheader_t header; int length; static unsigned last_checksum; int bsp_lump_order[HEADER_LUMPS] = { LUMP_PLANES, LUMP_LEAFS, LUMP_VERTEXES, LUMP_NODES, LUMP_TEXINFO, LUMP_FACES, LUMP_BRUSHES, LUMP_BRUSHSIDES, LUMP_LEAFFACES, LUMP_LEAFBRUSHES, LUMP_SURFEDGES, LUMP_EDGES, LUMP_MODELS, LUMP_AREAS, LUMP_AREAPORTALS, LUMP_LIGHTING, LUMP_VISIBILITY, LUMP_ENTITIES, LUMP_POP }; map_noareas = Cvar_Get ("map_noareas", "0", 0); if ( !strcmp (map_name, name) && (clientload || !Cvar_VariableValue ("flushmap")) ) { *checksum = last_checksum; if (!clientload) { memset (portalopen, 0, sizeof(portalopen)); FloodAreaConnections (); } return &map_cmodels[0]; // still have the right version } // free old stuff numplanes = 0; numnodes = 0; numleafs = 0; numcmodels = 0; numvisibility = 0; numentitychars = 0; map_entitystring[0] = 0; map_name[0] = 0; if (!name || !name[0]) { numleafs = 1; numclusters = 1; numareas = 1; *checksum = 0; return &map_cmodels[0]; // cinematic servers won't have anything at all } // // load the file // length = FS_LoadFile (name, (void **)&buf); if (!buf) Com_Error (ERR_DROP, "Could not load %s", name); last_checksum = LittleLong (Com_BlockChecksum (buf, length)); *checksum = last_checksum; header = *(dheader_t *)buf; for (i=0 ; i= numcmodels) Com_Error (ERR_DROP, "CM_InlineModel: bad number"); return &map_cmodels[num]; } int CM_NumClusters (void) { return numclusters; } int CM_NumInlineModels (void) { return numcmodels; } char *CM_EntityString (void) { return map_entitystring; } int CM_LeafContents (int leafnum) { if (leafnum < 0 || leafnum >= numleafs) Com_Error (ERR_DROP, "CM_LeafContents: bad number"); return map_leafs[leafnum].contents; } int CM_LeafCluster (int leafnum) { if (leafnum < 0 || leafnum >= numleafs) { Com_Error (ERR_DROP, "CM_LeafCluster: bad number"); return 0; /* unreachable. quiets bogus compiler array index warning */ } return map_leafs[leafnum].cluster; } int CM_LeafArea (int leafnum) { if (leafnum < 0 || leafnum >= numleafs) Com_Error (ERR_DROP, "CM_LeafArea: bad number"); return map_leafs[leafnum].area; } //======================================================================= cplane_t *box_planes; int box_headnode; cbrush_t *box_brush; cleaf_t *box_leaf; /* =================== CM_InitBoxHull Set up the planes and nodes so that the six floats of a bounding box can just be stored out and get a proper clipping hull structure. =================== */ void CM_InitBoxHull (void) { int i; int side; cnode_t *c; cplane_t *p; cbrushside_t *s; box_headnode = numnodes; box_planes = &map_planes[numplanes]; if (numnodes+6 > MAX_MAP_NODES || numbrushes+1 > MAX_MAP_BRUSHES || numleafbrushes+1 > MAX_MAP_LEAFBRUSHES || numbrushsides+6 > MAX_MAP_BRUSHSIDES || numplanes+12 > MAX_MAP_PLANES) Com_Error (ERR_DROP, "Not enough room for box tree"); box_brush = &map_brushes[numbrushes]; box_brush->numsides = 6; box_brush->firstbrushside = numbrushsides; box_brush->contents = CONTENTS_MONSTER; box_leaf = &map_leafs[numleafs]; box_leaf->contents = CONTENTS_MONSTER; box_leaf->firstleafbrush = numleafbrushes; box_leaf->numleafbrushes = 1; map_leafbrushes[numleafbrushes] = numbrushes; for (i=0 ; i<6 ; i++) { side = i&1; // brush sides s = &map_brushsides[numbrushsides+i]; s->plane = map_planes + (numplanes+i*2+side); s->surface = &nullsurface; // nodes c = &map_nodes[box_headnode+i]; c->plane = map_planes + (numplanes+i*2); c->children[side] = -1 - emptyleaf; if (i != 5) c->children[side^1] = box_headnode+i + 1; else c->children[side^1] = -1 - numleafs; // planes p = &box_planes[i*2]; p->type = i>>1; VectorClear (p->normal); p->normal[i>>1] = 1; p->signbits = signbits_for_plane( p ); p = &box_planes[i*2+1]; p->type = 3 + (i>>1); VectorClear (p->normal); p->normal[i>>1] = -1; p->signbits = signbits_for_plane( p ); } } /* =================== CM_HeadnodeForBox To keep everything totally uniform, bounding boxes are turned into small BSP trees instead of being compared directly. =================== */ int CM_HeadnodeForBox (vec3_t mins, vec3_t maxs) { box_planes[0].dist = maxs[0]; box_planes[1].dist = -maxs[0]; box_planes[2].dist = mins[0]; box_planes[3].dist = -mins[0]; box_planes[4].dist = maxs[1]; box_planes[5].dist = -maxs[1]; box_planes[6].dist = mins[1]; box_planes[7].dist = -mins[1]; box_planes[8].dist = maxs[2]; box_planes[9].dist = -maxs[2]; box_planes[10].dist = mins[2]; box_planes[11].dist = -mins[2]; return box_headnode; } /* ================== CM_PointLeafnum_r ================== */ int CM_PointLeafnum_r (vec3_t p, int num) { float d; cnode_t *node; cplane_t *plane; while (num >= 0) { node = map_nodes + num; plane = node->plane; if (plane->type < 3) d = p[plane->type] - plane->dist; else d = DotProduct (plane->normal, p) - plane->dist; if (d < 0) num = node->children[1]; else num = node->children[0]; } c_pointcontents++; // optimize counter return -1 - num; } int CM_PointLeafnum (vec3_t p) { if (!numplanes) return 0; // sound may call this without map loaded return CM_PointLeafnum_r (p, 0); } /* ============= CM_BoxLeafnums Fills in a list of all the leafs touched ============= */ int leaf_count, leaf_maxcount; int *leaf_list; float *leaf_mins, *leaf_maxs; int leaf_topnode; void CM_BoxLeafnums_r (int nodenum) { cplane_t *plane; cnode_t *node; int s; while (1) { if (nodenum < 0) { if (leaf_count >= leaf_maxcount) { // Com_Printf ("CM_BoxLeafnums_r: overflow\n"); return; } leaf_list[leaf_count++] = -1 - nodenum; return; } node = &map_nodes[nodenum]; plane = node->plane; // s = BoxOnPlaneSide (leaf_mins, leaf_maxs, plane); s = BOX_ON_PLANE_SIDE(leaf_mins, leaf_maxs, plane); if (s == 1) nodenum = node->children[0]; else if (s == 2) nodenum = node->children[1]; else { // go down both if (leaf_topnode == -1) leaf_topnode = nodenum; CM_BoxLeafnums_r (node->children[0]); nodenum = node->children[1]; } } } int CM_BoxLeafnums_headnode (vec3_t mins, vec3_t maxs, int *list, int listsize, int headnode, int *topnode) { leaf_list = list; leaf_count = 0; leaf_maxcount = listsize; leaf_mins = mins; leaf_maxs = maxs; leaf_topnode = -1; CM_BoxLeafnums_r (headnode); if (topnode) *topnode = leaf_topnode; return leaf_count; } int CM_BoxLeafnums (vec3_t mins, vec3_t maxs, int *list, int listsize, int *topnode) { return CM_BoxLeafnums_headnode (mins, maxs, list, listsize, map_cmodels[0].headnode, topnode); } /* ================== CM_PointContents ================== */ int CM_PointContents (vec3_t p, int headnode) { int l; if (!numnodes) // map not loaded return 0; l = CM_PointLeafnum_r (p, headnode); return map_leafs[l].contents; } /* ================== CM_TransformedPointContents Handles offseting and rotation of the end points for moving and rotating entities ================== */ int CM_TransformedPointContents (vec3_t p, int headnode, vec3_t origin, vec3_t angles) { vec3_t p_l; vec3_t temp; vec3_t forward, right, up; int l; // subtract origin offset VectorSubtract (p, origin, p_l); // rotate start and end into the models frame of reference if (headnode != box_headnode && (angles[0] || angles[1] || angles[2]) ) { AngleVectors (angles, forward, right, up); VectorCopy (p_l, temp); p_l[0] = DotProduct (temp, forward); p_l[1] = -DotProduct (temp, right); p_l[2] = DotProduct (temp, up); } l = CM_PointLeafnum_r (p_l, headnode); return map_leafs[l].contents; } /* =============================================================================== BOX TRACING =============================================================================== */ // 1/32 epsilon to keep floating point happy #define DIST_EPSILON (0.03125) vec3_t trace_start, trace_end; vec3_t trace_mins, trace_maxs; vec3_t trace_extents; trace_t trace_trace; int trace_contents; qboolean trace_ispoint; // optimized case /** * @brief intersect test for axis-aligned box and a brush in a leaf. * * This is the innermost loop for CM_BoxTrace() general and point cases. * Does not use file level static variables; not sure why. * * @returns if intersection occurred, information about the brush in the * trace_t record. otherwise does not touch trace_t record * */ void CM_ClipBoxToBrush( vec3_t mins, vec3_t maxs,vec3_t p1, vec3_t p2, trace_t *trace, cbrush_t *brush ) { int i; cplane_t *plane, *clipplane; float dist; float enterfrac, leavefrac; float d1, d2; qboolean getout, startout; float f; cbrushside_t *side, *leadside; enterfrac = -1.0f; leavefrac = 1.0f; clipplane = NULL; if (!brush->numsides) return; c_brush_traces++; getout = false; startout = false; leadside = NULL; for (i=0 ; inumsides ; i++) { side = &map_brushsides[brush->firstbrushside+i]; plane = side->plane; if ( !trace_ispoint ) { switch ( plane->type ) { case PLANE_X: if ( plane->signbits == 0x01 ) dist = plane->dist - (maxs[0]*plane->normal[0]); else dist = plane->dist - (mins[0]*plane->normal[0]); break; case PLANE_Y: if ( plane->signbits == 0x02 ) dist = plane->dist - (maxs[1]*plane->normal[1]); else dist = plane->dist - (mins[1]*plane->normal[1]); break; case PLANE_Z: if ( plane->signbits == 0x04 ) dist = plane->dist - (maxs[2]*plane->normal[2]); else dist = plane->dist - (mins[2]*plane->normal[2]); break; default: switch ( plane->signbits ) /* bit2=z<0, bit1=y<0, bit0=x<0 */ { case 0: /* 000b */ dist = plane->dist - (mins[0]*plane->normal[0] + mins[1]*plane->normal[1] + mins[2]*plane->normal[2]); break; case 1: /* 001b */ dist = plane->dist - (maxs[0]*plane->normal[0] + mins[1]*plane->normal[1] + mins[2]*plane->normal[2]); break; case 2: /* 010b */ dist = plane->dist - (mins[0]*plane->normal[0] + maxs[1]*plane->normal[1] + mins[2]*plane->normal[2]); break; case 3: /* 011b */ dist = plane->dist - (maxs[0]*plane->normal[0] + maxs[1]*plane->normal[1] + mins[2]*plane->normal[2]); break; case 4: /* 100b */ dist = plane->dist - (mins[0]*plane->normal[0] + mins[1]*plane->normal[1] + maxs[2]*plane->normal[2]); break; case 5: /* 101b */ dist = plane->dist - (maxs[0]*plane->normal[0] + mins[1]*plane->normal[1] + maxs[2]*plane->normal[2]); break; case 6: /* 110b */ dist = plane->dist - (mins[0]*plane->normal[0] + maxs[1]*plane->normal[1] + maxs[2]*plane->normal[2]); break; case 7: /* 111b */ dist = plane->dist - (maxs[0]*plane->normal[0] + maxs[1]*plane->normal[1] + maxs[2]*plane->normal[2]); break; default: Com_Error( ERR_DROP, "CM_ClipBoxToBrush: bad plane signbits\n"); return; // unreachable. suppress bogus compiler warning } } } else { // special point case dist = plane->dist; } d1 = DotProduct (p1, plane->normal) - dist; d2 = DotProduct (p2, plane->normal) - dist; if ( d2 > 0.0f ) getout = true; // endpoint is not in solid if ( d1 > 0.0f ) startout = true; // if completely in front of face, no intersection if ( d1 > 0.0f && d2 >= d1 ) return; if ( d1 <= 0.0f && d2 <= 0.0f ) continue; // crosses face if (d1 > d2) { // enter f = (d1-DIST_EPSILON) / (d1-d2); if (f > enterfrac) { enterfrac = f; clipplane = plane; leadside = side; } } else if ( d1 < d2 ) { // leave f = (d1+DIST_EPSILON) / (d1-d2); if (f < leavefrac) leavefrac = f; } /* else d1 == d2, line segment is parallel to plane, cannot intersect. formerly processed like d1 < d2. now just continue to next brushside plane. */ } if (!startout) { // original point was inside brush trace->startsolid = true; if (!getout) trace->allsolid = true; return; } if (enterfrac < leavefrac) { if (enterfrac > -1 && enterfrac < trace->fraction) { if (enterfrac < 0) enterfrac = 0; trace->fraction = enterfrac; trace->plane = *clipplane; trace->surface = &(leadside->surface->c); trace->contents = brush->contents; } } } /* ================ CM_TestBoxInBrush ================ */ void CM_TestBoxInBrush (vec3_t mins, vec3_t maxs, vec3_t p1, trace_t *trace, cbrush_t *brush) { int i, j; cplane_t *plane; float dist; vec3_t ofs; float d1; cbrushside_t *side; if (!brush->numsides) return; for (i=0 ; inumsides ; i++) { side = &map_brushsides[brush->firstbrushside+i]; plane = side->plane; // FIXME: special case for axial // general box case // push the plane out apropriately for mins/maxs // FIXME: use signbits into 8 way lookup for each mins/maxs for (j=0 ; j<3 ; j++) { if (plane->normal[j] < 0) ofs[j] = maxs[j]; else ofs[j] = mins[j]; } dist = DotProduct (ofs, plane->normal); dist = plane->dist - dist; d1 = DotProduct (p1, plane->normal) - dist; // if completely in front of face, no intersection if (d1 > (DIST_EPSILON * 0.5f) ) return; } // inside this brush trace->startsolid = trace->allsolid = true; trace->fraction = 0; trace->contents = brush->contents; } /* ================ CM_TraceToLeaf ================ */ void CM_TraceToLeaf (int leafnum) { int k; int brushnum; cleaf_t *leaf; cbrush_t *b; leaf = &map_leafs[leafnum]; if ( !(leaf->contents & trace_contents)) return; // trace line against all brushes in the leaf for (k=0 ; knumleafbrushes ; k++) { brushnum = map_leafbrushes[leaf->firstleafbrush+k]; b = &map_brushes[brushnum]; if (b->checkcount == checkcount) continue; // already checked this brush in another leaf b->checkcount = checkcount; if ( !(b->contents & trace_contents)) continue; CM_ClipBoxToBrush (trace_mins, trace_maxs, trace_start, trace_end, &trace_trace, b); if (!trace_trace.fraction) return; } } /* ================ CM_TestInLeaf ================ */ void CM_TestInLeaf (int leafnum) { int k; int brushnum; cleaf_t *leaf; cbrush_t *b; leaf = &map_leafs[leafnum]; if ( !(leaf->contents & trace_contents)) return; // trace line against all brushes in the leaf for (k=0 ; knumleafbrushes ; k++) { brushnum = map_leafbrushes[leaf->firstleafbrush+k]; b = &map_brushes[brushnum]; if (b->checkcount == checkcount) continue; // already checked this brush in another leaf b->checkcount = checkcount; if ( !(b->contents & trace_contents)) continue; CM_TestBoxInBrush (trace_mins, trace_maxs, trace_start, &trace_trace, b); if (!trace_trace.fraction) return; } } /* ================== CM_RecursiveHullCheck ================== */ void CM_RecursiveHullCheck (int num, float p1f, float p2f, vec3_t p1, vec3_t p2) { cnode_t *node; cplane_t *plane; float t1, t2, offset; float frac, frac2; float idist; vec3_t mid; int side; float midf; vec3_t p1_copy; re_test: if (trace_trace.fraction <= p1f) return; // already hit something nearer // if < 0, we are in a leaf node if (num < 0) { CM_TraceToLeaf (-1-num); return; } // // find the point distances to the seperating plane // and the offset for the size of the box // node = map_nodes + num; plane = node->plane; if (plane->type < 3) { t1 = p1[plane->type] - plane->dist; t2 = p2[plane->type] - plane->dist; offset = trace_extents[plane->type]; } else { t1 = DotProduct (plane->normal, p1) - plane->dist; t2 = DotProduct (plane->normal, p2) - plane->dist; if (trace_ispoint) offset = 0; else offset = fabs(trace_extents[0]*plane->normal[0]) + fabs(trace_extents[1]*plane->normal[1]) + fabs(trace_extents[2]*plane->normal[2]); } #if 0 CM_RecursiveHullCheck (node->children[0], p1f, p2f, p1, p2); CM_RecursiveHullCheck (node->children[1], p1f, p2f, p1, p2); return; #endif // see which sides we need to consider if (t1 >= offset && t2 >= offset) { num = node->children[0]; goto re_test; } if (t1 < -offset && t2 < -offset) { num = node->children[1]; goto re_test; } // put the crosspoint DIST_EPSILON pixels on the near side if (t1 < t2) { idist = 1.0/(t1-t2); side = 1; frac2 = (t1 + offset + DIST_EPSILON)*idist; frac = (t1 - offset + DIST_EPSILON)*idist; } else if (t1 > t2) { idist = 1.0/(t1-t2); side = 0; frac2 = (t1 - offset - DIST_EPSILON)*idist; frac = (t1 + offset + DIST_EPSILON)*idist; } else { side = 0; frac = 1; frac2 = 0; } // move up to the node if (frac < 0) frac = 0; if (frac > 1) frac = 1; midf = p1f + (p2f - p1f)*frac; mid[0] = p1[0] + frac*(p2[0] - p1[0]); mid[1] = p1[1] + frac*(p2[1] - p1[1]); mid[2] = p1[2] + frac*(p2[2] - p1[2]); // so we can modify p1 VectorCopy (p1, p1_copy); // this is the only case where the function actually recurses CM_RecursiveHullCheck (node->children[side], p1f, midf, p1_copy, mid); // go past the node if (frac2 < 0) frac2 = 0; if (frac2 > 1) frac2 = 1; p1f += (p2f - p1f)*frac2; p1[0] += frac2*(p2[0] - p1[0]); p1[1] += frac2*(p2[1] - p1[1]); p1[2] += frac2*(p2[2] - p1[2]); num = node->children[side^1]; goto re_test; } //====================================================================== /* ================== CM_BoxTrace ================== */ trace_t CM_BoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int headnode, int brushmask) { int i; vec3_t local_start, local_end; checkcount++; // for multi-check avoidance c_traces++; // for statistics, may be zeroed // fill in a default trace memset (&trace_trace, 0, sizeof(trace_trace)); trace_trace.fraction = 1; trace_trace.surface = &(nullsurface.c); if (!numnodes) // map not loaded return trace_trace; trace_contents = brushmask; VectorCopy (start, trace_start); VectorCopy (end, trace_end); VectorCopy (mins, trace_mins); VectorCopy (maxs, trace_maxs); if ( !(start == end) && (start[0] != end[0] || start[1] != end[1] || start[2] != end[2]) ) { if (( mins == maxs ) || ( mins[0] == 0.0f && mins[1] == 0.0f && mins[2] == 0.0f && maxs[0] == 0.0f && maxs[1] == 0.0f && maxs[2] == 0.0f )) { // point special case trace_ispoint = true; VectorClear (trace_extents); } else { // general axis-aligned box case trace_ispoint = false; trace_extents[0] = -mins[0] > maxs[0] ? -mins[0] : maxs[0]; trace_extents[1] = -mins[1] > maxs[1] ? -mins[1] : maxs[1]; trace_extents[2] = -mins[2] > maxs[2] ? -mins[2] : maxs[2]; } // // general sweeping through world // VectorCopy (start, local_start); // so the function can modify these in-place VectorCopy (end, local_end); CM_RecursiveHullCheck (headnode, 0, 1, local_start, local_end); if (trace_trace.fraction == 1) { VectorCopy (end, trace_trace.endpos); } else { for (i=0 ; i<3 ; i++) trace_trace.endpos[i] = start[i] + trace_trace.fraction * (end[i] - start[i]); } } else { // position test special case int leafs[1024]; int i, numleafs; vec3_t c1, c2; int topnode; VectorAdd (start, mins, c1); VectorAdd (start, maxs, c2); for (i=0 ; i<3 ; i++) { c1[i] -= 1; c2[i] += 1; } numleafs = CM_BoxLeafnums_headnode (c1, c2, leafs, 1024, headnode, &topnode); for (i=0 ; i>3; out_p = out; if (!in || !numvisibility) { // no vis info, so make all visible while (row) { *out_p++ = 0xff; row--; } return; } do { if (*in) { *out_p++ = *in++; continue; } c = in[1]; in += 2; if ((out_p - out) + c > row) { c = row - (out_p - out); Com_DPrintf ("warning: Vis decompression overrun\n"); } while (c) { *out_p++ = 0; c--; } } while (out_p - out < row); } byte pvsrow[MAX_MAP_LEAFS/8]; byte phsrow[MAX_MAP_LEAFS/8]; byte *CM_ClusterPVS (int cluster) { static int old_cluster = -1; if (cluster == old_cluster) return pvsrow; old_cluster = cluster; if (cluster == -1) memset (pvsrow, 0, (numclusters+7)>>3); else CM_DecompressVis (map_visibility + map_vis->bitofs[cluster][DVIS_PVS], pvsrow); return pvsrow; } byte *CM_ClusterPHS (int cluster) { static int old_cluster = -1; if (cluster == old_cluster) return phsrow; old_cluster = cluster; if (cluster == -1) memset (phsrow, 0, (numclusters+7)>>3); else CM_DecompressVis (map_visibility + map_vis->bitofs[cluster][DVIS_PHS], phsrow); return phsrow; } /* =============================================================================== AREAPORTALS =============================================================================== */ void FloodArea_r (carea_t *area, int floodnum) { int i; dareaportal_t *p; if (area->floodvalid == floodvalid) { if (area->floodnum == floodnum) return; Com_Error (ERR_DROP, "FloodArea_r: reflooded"); } area->floodnum = floodnum; area->floodvalid = floodvalid; p = &map_areaportals[area->firstareaportal]; for (i=0 ; inumareaportals ; i++, p++) { if (portalopen[p->portalnum]) FloodArea_r (&map_areas[p->otherarea], floodnum); } } /* ==================== FloodAreaConnections ==================== */ void FloodAreaConnections (void) { int i; carea_t *area; int floodnum; // all current floods are now invalid floodvalid++; floodnum = 0; // area 0 is not used for (i=1 ; ifloodvalid == floodvalid) continue; // already flooded into floodnum++; FloodArea_r (area, floodnum); } } void CM_SetAreaPortalState (int portalnum, qboolean open) { if (portalnum > numareaportals) Com_Error (ERR_DROP, "areaportal > numareaportals"); portalopen[portalnum] = open; FloodAreaConnections (); } qboolean CM_AreasConnected (int area1, int area2) { if (map_noareas->value) return true; if (area1 > numareas || area2 > numareas) Com_Error (ERR_DROP, "area > numareas"); if (map_areas[area1].floodnum == map_areas[area2].floodnum) return true; return false; } /* ================= CM_WriteAreaBits Writes a length byte followed by a bit vector of all the areas that area in the same flood as the area parameter This is used by the client refreshes to cull visibility ================= */ int CM_WriteAreaBits (byte *buffer, int area) { int i; int floodnum; int bytes; bytes = (numareas+7)>>3; if (map_noareas->value) { // for debugging, send everything memset (buffer, 255, bytes); } else { memset (buffer, 0, bytes); floodnum = map_areas[area].floodnum; for (i=0 ; i>3] |= 1<<(i&7); } } return bytes; } /* =================== CM_WritePortalState Writes the portal state to a savegame file =================== */ /* // unused void CM_WritePortalState (FILE *f) { fwrite (portalopen, sizeof(portalopen), 1, f); } */ /* =================== CM_ReadPortalState Reads the portal state from a savegame file and recalculates the area connections =================== */ /* // unused void CM_ReadPortalState (FILE *f) { FS_Read (portalopen, sizeof(portalopen), f); FloodAreaConnections (); } */ /* ============= CM_HeadnodeVisible Returns true if any leaf under headnode has a cluster that is potentially visible ============= */ qboolean CM_HeadnodeVisible (int nodenum, byte *visbits) { int leafnum; int cluster; cnode_t *node; if (nodenum < 0) { leafnum = -1-nodenum; cluster = map_leafs[leafnum].cluster; if (cluster == -1) return false; if (visbits[cluster>>3] & (1<<(cluster&7))) return true; return false; } node = &map_nodes[nodenum]; if (CM_HeadnodeVisible(node->children[0], visbits)) return true; return CM_HeadnodeVisible(node->children[1], visbits); } /* ================= CM_inPVS Also checks portalareas so that doors block sight ================= */ qboolean CM_inPVS (vec3_t p1, vec3_t p2) { int leafnum; int cluster; int area1, area2; byte *mask; leafnum = CM_PointLeafnum (p1); cluster = CM_LeafCluster (leafnum); area1 = CM_LeafArea (leafnum); mask = CM_ClusterPVS (cluster); leafnum = CM_PointLeafnum (p2); cluster = CM_LeafCluster (leafnum); area2 = CM_LeafArea (leafnum); if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) ) return false; if (!CM_AreasConnected (area1, area2)) return false; // a door blocks sight return true; } //similar to CM_inPVS but with leafnums qboolean CM_inPVS_leafs (int leafnum1, int leafnum2) { int cluster; int area1, area2; byte *mask; cluster = CM_LeafCluster (leafnum1); area1 = CM_LeafArea (leafnum1); mask = CM_ClusterPVS (cluster); cluster = CM_LeafCluster (leafnum2); area2 = CM_LeafArea (leafnum2); if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) ) return false; if (!CM_AreasConnected (area1, area2)) return false; // a door blocks sight return true; } /* ================= CM_inPHS Also checks portalareas so that doors block sound ================= */ qboolean CM_inPHS (vec3_t p1, vec3_t p2) { int leafnum; int cluster; int area1, area2; byte *mask; leafnum = CM_PointLeafnum (p1); cluster = CM_LeafCluster (leafnum); area1 = CM_LeafArea (leafnum); mask = CM_ClusterPHS (cluster); leafnum = CM_PointLeafnum (p2); cluster = CM_LeafCluster (leafnum); area2 = CM_LeafArea (leafnum); if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) ) return false; // more than one bounce away if (!CM_AreasConnected (area1, area2)) return false; // a door blocks hearing return true; } alien-arena-7.66+dfsg/source/qcommon/htable.c0000600000175000017500000004021612161402010020161 0ustar zero79zero79/* Copyright (C) 2010 COR Entertainment This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "qcommon.h" #include "htable.h" /*=============================================* * Type definitions * *=============================================*/ /* * "List heads" - used to store various lists */ struct listhead_t { struct listhead_t * previous; struct listhead_t * next; }; /* * Resets a list head */ #define RESET_LIST(LPTR) \ ( (LPTR)->previous = (LPTR)->next = (LPTR) ) /* * Table entry - used to store actual items */ struct tentry_t { /* Entry in one of the table's sub-lists */ struct listhead_t loc_list; /* Entry in the table's main list */ struct listhead_t full_list; /* Cached hash value */ unsigned int hash; }; /* * Function pointers */ typedef unsigned int ( * getkey_t )( const char * key ); typedef char * ( * keyfromentry_t )( struct tentry_t * entry , size_t key_offset ); typedef int ( * comparekey_t )( const char * k1 , const char * k2 ); /* * Main hash table structure */ struct hashtable_s { /* Actual size of the table */ size_t size; /* Table flags */ unsigned int flags; /* Item size */ size_t item_size; /* Key offset in an item */ size_t key_offset; /* Length of key (0 for pointer) */ size_t key_length; /* Functions */ getkey_t GetKey; keyfromentry_t KeyFromEntry; comparekey_t CompareKey; /* List of all items */ struct listhead_t all_items; }; /* * Macro that finds the first list head after a table's main structure */ #define TABLE_START(TABLE) \ ( (struct listhead_t *)( ((char*)(TABLE)) + sizeof( struct hashtable_s ) ) ) /*=============================================* * Internal functions prototypes * *=============================================*/ /* Checks if a size is a prime number */ static qboolean _HT_IsPrime( size_t n ); /* Finds the next higher prime number */ static size_t _HT_NextPrime( size_t n ); /* Computes a string's hash key (case insensitive) */ static unsigned int _HT_GetCIKey( const char * key ); /* Computes a string's hash key (case sensitive) */ static unsigned int _HT_GetKey( const char * key ); /* Returns a table entry's key (in-table items, fixed size key) */ static char * _HT_KeyFromEntryII( struct tentry_t * entry , size_t key_offset ); /* Returns a table entry's key (in-table items, pointer key) */ static char * _HT_KeyFromEntryIP( struct tentry_t * entry , size_t key_offset ); /* Returns a table entry's key (external items, fixed size key) */ static char * _HT_KeyFromEntryPI( struct tentry_t * entry , size_t key_offset ); /* Returns a table entry's key (external items, pointer key) */ static char * _HT_KeyFromEntryPP( struct tentry_t * entry , size_t key_offset ); /* Allocate and initialise a table entry. */ static struct tentry_t * _HT_CreateEntry( hashtable_t table , unsigned int hash , struct listhead_t * list_entry , const char * key ); /* Insert a table entry into a table's global list */ static void _HT_InsertInGlobalList( hashtable_t table , struct tentry_t * t_entry , const char * key ); /*=============================================* * Hash table public functions * *=============================================*/ hashtable_t HT_Create( size_t size , unsigned int flags , size_t item_size , size_t key_offset , size_t key_length ) { hashtable_t table; size_t real_size; struct listhead_t * t_item; // Allocate table real_size = _HT_NextPrime( size ); table = Z_Malloc( sizeof( struct hashtable_s ) + real_size * sizeof( struct listhead_t ) ); assert( table ); // Initialise main table fields table->size = real_size; table->flags = flags; table->item_size = item_size; table->key_offset = key_offset; table->key_length = key_length; RESET_LIST( &table->all_items ); // Set functions table->GetKey = ( flags & HT_FLAG_CASE ) ? _HT_GetKey : _HT_GetCIKey; table->CompareKey = ( flags & HT_FLAG_CASE ) ? strcmp : Q_strcasecmp; if ( ( flags & HT_FLAG_INTABLE ) == 0 ) { table->KeyFromEntry = key_length ? _HT_KeyFromEntryPI : _HT_KeyFromEntryPP; } else { table->KeyFromEntry = key_length ? _HT_KeyFromEntryII : _HT_KeyFromEntryIP; } // Initialise table entries t_item = TABLE_START( table ); while ( real_size > 0 ) { RESET_LIST( t_item ); t_item ++, real_size --; } return table; } void HT_Destroy( hashtable_t table ) { qboolean del_key; struct listhead_t * list_head; struct listhead_t * list_entry; struct tentry_t * t_entry; del_key = ( table->key_length == 0 && ( table->flags & ( HT_FLAG_INTABLE | HT_FLAG_FREE ) ) != 0 ); list_head = &( table->all_items ); list_entry = list_head->next; while ( list_entry != list_head ) { t_entry = (struct tentry_t *)( ( (char *) list_entry ) - HT_OffsetOfField( struct tentry_t , full_list ) ); list_entry = list_entry->next; if ( del_key ) Z_Free( table->KeyFromEntry( t_entry , table->key_offset ) ); if ( ( table->flags & ( HT_FLAG_INTABLE | HT_FLAG_FREE ) ) == HT_FLAG_FREE ) { void ** data = (void **)( ( (char *) t_entry ) + sizeof( struct tentry_t ) ); Z_Free( *data ); } Z_Free( t_entry ); } Z_Free( table ); } void * HT_GetItem( hashtable_t table , const char * key , qboolean * created ) { unsigned int hash; struct listhead_t * list_head; struct listhead_t * list_entry; struct tentry_t * t_entry; void * data; assert( table->key_length == 0 || table->key_length >= strlen( key ) ); // Try finding the item hash = table->GetKey( key ); list_head = ( TABLE_START( table ) + ( hash % table->size ) ); list_entry = list_head->next; while ( list_entry != list_head ) { t_entry = ( struct tentry_t * ) list_entry; if ( t_entry->hash > hash ) break; if ( t_entry->hash == hash ) { char * item_key = table->KeyFromEntry( t_entry , table->key_offset ); if ( ! table->CompareKey( key , item_key ) ) { data = (void *)( ( (char *)t_entry ) + sizeof( struct tentry_t ) ); if ( created != NULL ) *created = false; return ( table->flags & HT_FLAG_INTABLE ) ? data : ( *(void**)data ); } } list_entry = list_entry->next; } // Check if we can create the entry if ( created == NULL ) return NULL; // Create entry *created = true; t_entry = _HT_CreateEntry( table , hash , list_entry , key ); // Initialise data data = (void *)( ( (char *)t_entry ) + sizeof( struct tentry_t ) ); if ( ( table->flags & HT_FLAG_INTABLE ) == 0 ) { *(void **) data = Z_Malloc( table->item_size ); data = *(void **) data; } memset( data , 0 , table->item_size ); // Copy key if ( table->key_length == 0 ) { char ** key_ptr = (char **)( ( (char*) data ) + table->key_offset ); *key_ptr = Z_Malloc( strlen( key ) + 1 ); strcpy( *key_ptr , key ); } else { char * key_ptr = ( (char*) data ) + table->key_offset; strcpy( key_ptr , key ); } return data; } void * HT_PutItem( hashtable_t table , void * item , qboolean allow_replacement ) { void * ret_val = NULL; void * prev_entry = NULL; const char * insert_key; unsigned int hash; struct listhead_t * list_head; struct listhead_t * list_entry; struct tentry_t * t_entry; // Extract item key if ( table->key_length ) { insert_key = ( (const char *) item ) + table->key_offset; } else { insert_key = *(const char **)( ( (char *) item ) + table->key_offset ); } // Try finding an item with that key, or the new item's location hash = table->GetKey( insert_key ); list_head = ( TABLE_START( table ) + ( hash % table->size ) ); list_entry = list_head->next; while ( list_entry != list_head ) { t_entry = ( struct tentry_t * ) list_entry; if ( t_entry->hash > hash ) break; if ( t_entry->hash == hash ) { const char * item_key = table->KeyFromEntry( t_entry , table->key_offset ); int cres = table->CompareKey( insert_key , item_key ); if ( ! cres ) { prev_entry = ( ( (char *)t_entry ) + sizeof( struct tentry_t ) ); ret_val = ( table->flags & HT_FLAG_INTABLE ) ? prev_entry : ( *(void**)prev_entry ); if ( ! allow_replacement ) return ret_val; break; } else if ( cres > 0 ) { break; } } list_entry = list_entry->next; } if ( ret_val != NULL ) { // Delete previous item's key if it was a pointer and either // items are in-table or should be freed automatically if ( table->key_length == 0 && ( table->flags & ( HT_FLAG_INTABLE | HT_FLAG_FREE ) ) != 0 ) Z_Free( table->KeyFromEntry( t_entry , table->key_offset ) ); if ( ( table->flags & HT_FLAG_INTABLE ) != 0 ) { // Copy item data memcpy( prev_entry , item , table->item_size ); ret_val = NULL; } else { if ( ( table->flags & HT_FLAG_FREE ) != 0 ) { // Free previous item Z_Free( ret_val ); ret_val = NULL; } *(void **) prev_entry = item; } } else { void * data; t_entry = _HT_CreateEntry( table , hash , list_entry , insert_key ); data = (void *)( ( (char *)t_entry ) + sizeof( struct tentry_t ) ); if ( ( table->flags & HT_FLAG_INTABLE ) != 0 ) { memcpy( data , item , table->item_size ); } else { *(void **) data = item; } } return ret_val; } qboolean HT_DeleteItem( hashtable_t table , const char * key , void ** found ) { unsigned int hash; struct listhead_t * list_head; struct listhead_t * list_entry; struct tentry_t * t_entry; void * data = NULL; // Try finding the item hash = table->GetKey( key ); list_head = ( TABLE_START( table ) + ( hash % table->size ) ); list_entry = list_head->next; while ( list_entry != list_head ) { t_entry = ( struct tentry_t * ) list_entry; if ( t_entry->hash > hash ) break; if ( t_entry->hash == hash ) { char * item_key = table->KeyFromEntry( t_entry , table->key_offset ); if ( ! table->CompareKey( key , item_key ) ) { data = (void *)( ( (char *)t_entry ) + sizeof( struct tentry_t ) ); data = ( table->flags & HT_FLAG_INTABLE ) ? data : ( *(void**)data ); break; } } list_entry = list_entry->next; } // Did we find it? if ( data == NULL ) { if ( found != NULL ) *found = NULL; return false; } // Detach it from its lists t_entry->loc_list.previous->next = t_entry->loc_list.next; t_entry->loc_list.next->previous = t_entry->loc_list.previous; t_entry->full_list.previous->next = t_entry->full_list.next; t_entry->full_list.next->previous = t_entry->full_list.previous; // Delete key if ( table->key_length == 0 && ( table->flags & ( HT_FLAG_INTABLE | HT_FLAG_FREE ) ) != 0 ) Z_Free( table->KeyFromEntry( t_entry , table->key_offset ) ); // Delete item if ( ( table->flags & ( HT_FLAG_INTABLE | HT_FLAG_FREE ) ) == HT_FLAG_FREE ) Z_Free( data ); // Delete entry Z_Free( t_entry ); // Set found pointer if ( found != NULL ) { if ( ( table->flags & ( HT_FLAG_INTABLE | HT_FLAG_FREE ) ) != 0 ) data = NULL; *found = data; } return true; } void HT_Apply( hashtable_t table , ht_apply_funct function , void * data ) { struct listhead_t * list_head; struct listhead_t * list_entry; list_head = &( table->all_items ); list_entry = list_head->next; while ( list_entry != list_head ) { void * item; item = ( (char *) list_entry ) - HT_OffsetOfField( struct tentry_t , full_list ) + sizeof( struct tentry_t ); list_entry = list_entry->next; if ( ( table->flags & HT_FLAG_INTABLE ) == 0 ) item = *(void**) item; if ( ! function( item , data ) ) return; } } /*=============================================* * Functions related to prime numbers * *=============================================*/ static qboolean _HT_IsPrime( size_t n ) { size_t temp; size_t nsq; size_t inc; if ( n == 0 ) return false; nsq = ceil( sqrt( (double)n ) ); for ( inc = 1 , temp = 2 ; temp <= nsq ; temp += inc ) { if ( n % temp == 0 ) return false; if ( temp == 3 ) inc = 2; } return true; } static size_t _HT_NextPrime( size_t n ) { size_t value = n; while ( ! _HT_IsPrime( value ) ) value ++; return value; } /*=============================================* * Key computation functions * *=============================================*/ static unsigned int _HT_GetCIKey( const char * key ) { const char * current = key; unsigned int hash = 111119; while ( *current ) { hash += (unsigned char)tolower( *current ); hash += ( hash << 10 ); hash ^= ( hash >> 6 ); current ++; } hash += ( hash << 3 ); hash ^= ( hash >> 11 ); hash += ( hash << 15 ); return hash; } static unsigned int _HT_GetKey( const char * key ) { const char * current = key; unsigned int hash = 111119; while ( *current ) { hash += (unsigned char) *current; hash += ( hash << 10 ); hash ^= ( hash >> 6 ); current ++; } hash += ( hash << 3 ); hash ^= ( hash >> 11 ); hash += ( hash << 15 ); return hash; } /*=============================================* * Key retrieval * *=============================================*/ static char * _HT_KeyFromEntryII( struct tentry_t * entry , size_t key_offset ) { void * item_addr; item_addr = (void*)( ( (char*)entry ) + sizeof( struct tentry_t ) ); return (char *)( ( (char*)item_addr ) + key_offset ); } static char * _HT_KeyFromEntryIP( struct tentry_t * entry , size_t key_offset ) { void * item_addr; item_addr = (void*)( ( (char*)entry ) + sizeof( struct tentry_t ) ); return *(char **)( ( (char*)item_addr ) + key_offset ); } static char * _HT_KeyFromEntryPI( struct tentry_t * entry , size_t key_offset ) { void * item_addr; item_addr = *(void**)( ( (char*)entry ) + sizeof( struct tentry_t ) ); return (char *)( ( (char*)item_addr ) + key_offset ); } static char * _HT_KeyFromEntryPP( struct tentry_t * entry , size_t key_offset ) { void * item_addr; item_addr = *(void**)( ( (char*)entry ) + sizeof( struct tentry_t ) ); return *(char **)( ( (char*)item_addr ) + key_offset ); } /*=============================================* * Other internal functions * *=============================================*/ static struct tentry_t * _HT_CreateEntry( hashtable_t table , unsigned int hash , struct listhead_t * list_entry , const char * key ) { // Allocate new entry struct tentry_t * t_entry; size_t entry_size = sizeof( struct tentry_t ); entry_size += ( table->flags & HT_FLAG_INTABLE ) ? table->item_size : sizeof( void * ); t_entry = Z_Malloc( entry_size ); t_entry->hash = hash; // Add entry to local list t_entry->loc_list.previous = list_entry->previous; t_entry->loc_list.next = list_entry; list_entry->previous = t_entry->loc_list.previous->next = &( t_entry->loc_list ); _HT_InsertInGlobalList( table , t_entry , key ); return t_entry; } static void _HT_InsertInGlobalList( hashtable_t table , struct tentry_t * t_entry , const char * key ) { if ( ( table->flags & HT_FLAG_SORTED ) == 0 ) { // Append to global list t_entry->full_list.previous = table->all_items.previous; t_entry->full_list.next = &( table->all_items ); table->all_items.previous = t_entry->full_list.previous->next = &( t_entry->full_list ); } else { // Global list must be kept sorted, find insert location struct listhead_t * list_entry = table->all_items.next; while ( list_entry != &( table->all_items ) ) { struct tentry_t * ai_entry; const char * ai_key; int cres; ai_entry = (struct tentry_t *)( ( (char *) list_entry ) - HT_OffsetOfField( struct tentry_t , full_list ) ); ai_key = table->KeyFromEntry( ai_entry , table->key_offset ); cres = table->CompareKey( ai_key , key ); assert( cres != 0 ); if ( cres > 0 ) break; list_entry = list_entry->next; } t_entry->full_list.previous = list_entry->previous; t_entry->full_list.next = list_entry; list_entry->previous = t_entry->full_list.previous->next = &( t_entry->full_list ); } } alien-arena-7.66+dfsg/source/qcommon/cmd.c0000600000175000017500000005442412161402010017473 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // cmd.c -- Quake script command processing module #ifdef HAVE_CONFIG_H #include "config.h" #endif #if defined UNIX_VARIANT #if defined HAVE_UNISTD_H #include #endif #endif #include "qcommon.h" #define MAX_ALIAS_NAME 32 typedef struct cmdalias_s { struct cmdalias_s *next; unsigned int hash_key; char name[MAX_ALIAS_NAME]; char *value; } cmdalias_t; cmdalias_t *cmd_alias; qboolean cmd_wait; #define ALIAS_LOOP_COUNT 16 int alias_count; // for detecting runaway loops //============================================================================= /* ============ Cmd_Wait_f Causes execution of the remainder of the command buffer to be delayed until next frame. This allows commands like: bind g "impulse 5 ; +attack ; wait ; -attack ; impulse 2" ============ */ void Cmd_Wait_f (void) { cmd_wait = true; } /* ============================================================================= COMMAND BUFFER ============================================================================= */ sizebuf_t cmd_text; byte cmd_text_buf[8192]; byte defer_text_buf[8192]; /* ============ Cbuf_Init ============ */ void Cbuf_Init (void) { SZ_Init (&cmd_text, cmd_text_buf, sizeof(cmd_text_buf)); SZ_SetName (&cmd_text, "Command buffer", true); } /* ============ Cbuf_AddText Adds command text at the end of the buffer ============ */ void Cbuf_AddText (char *text) { int l; l = strlen (text); if (cmd_text.cursize + l >= cmd_text.maxsize) { Com_Printf ("Cbuf_AddText: overflow! Discarding text: %s\n", text); return; } SZ_Write (&cmd_text, text, l); } /* ============ Cbuf_InsertText Adds command text immediately after the current command Adds a \n to the text FIXME: actually change the command buffer to do less copying ============ */ void Cbuf_InsertText (char *text) { char *temp; int templen; // copy off any commands still remaining in the exec buffer templen = cmd_text.cursize; if (templen) { temp = Z_Malloc (templen); memcpy (temp, cmd_text.data, templen); SZ_Clear (&cmd_text); } else temp = NULL; // shut up compiler // add the entire text of the file Cbuf_AddText (text); // add the copied off data if (templen) { if (cmd_text.cursize + templen >= cmd_text.maxsize) /* possible "graceful" solution: Cbuf_Execute here to flush the * buffer? Would change behavior of successive Cbuf_InsertText * calls and probably screw things up with exec'd cfgs within * exec'd cfgs, possibly resulting in infinite recursion loops. * TODO: study this option with some pathological test cfgs. */ Com_Printf ("Cbuf_InsertText: overflow! Discarding text: %s\n", temp); else SZ_Write (&cmd_text, temp, templen); Z_Free (temp); } } /* ============ Cbuf_CopyToDefer ============ */ void Cbuf_CopyToDefer (void) { memcpy(defer_text_buf, cmd_text_buf, cmd_text.cursize); defer_text_buf[cmd_text.cursize] = 0; cmd_text.cursize = 0; } /* ============ Cbuf_InsertFromDefer ============ */ void Cbuf_InsertFromDefer (void) { Cbuf_InsertText ( (char *)defer_text_buf ); defer_text_buf[0] = 0; } /* ============ Cbuf_ExecuteText ============ */ void Cbuf_ExecuteText (int exec_when, char *text) { switch (exec_when) { case EXEC_NOW: Cmd_ExecuteString (text); break; case EXEC_INSERT: Cbuf_InsertText (text); break; case EXEC_APPEND: Cbuf_AddText (text); break; default: Com_Error (ERR_FATAL, "Cbuf_ExecuteText: bad exec_when"); } } /* ============ Cbuf_Execute ============ */ void Cbuf_Execute (void) { int i; char *text; char line[1024]; int quotes; alias_count = 0; // don't allow infinite alias loops while (cmd_text.cursize) { // find a \n or ; line break text = (char *)cmd_text.data; quotes = 0; for (i=0 ; i< cmd_text.cursize ; i++) { if (text[i] == '"') quotes++; if ( !(quotes&1) && text[i] == ';') break; // don't break if inside a quoted string if (text[i] == '\n') break; } // sku - removed potentional buffer overflow vulnerability if( i > sizeof( line ) - 1 ) { i = sizeof( line ) - 1; } memcpy (line, text, i); line[i] = 0; // delete the text from the command buffer and move remaining commands down // this is necessary because commands (exec, alias) can insert data at the // beginning of the text buffer if (i == cmd_text.cursize) cmd_text.cursize = 0; else { i++; cmd_text.cursize -= i; memmove (text, text+i, cmd_text.cursize); } // execute the command line Cmd_ExecuteString (line); if (cmd_wait) { // skip out while text still remains in buffer, leaving it // for next frame cmd_wait = false; break; } } } /* =============== Cbuf_AddEarlyCommands Adds command line parameters as script statements Commands lead with a +, and continue until another + Set commands are added early, so they are guaranteed to be set before the client and server initialize for the first time. Other commands are added late, after all initialization is complete. =============== */ void Cbuf_AddEarlyCommands (qboolean clear) { int i; char *s; for (i=0 ; i\n"); } #if defined UNIX_VARIANT #if defined HAVE_UNISTD_H usleep (atoi(Cmd_Argv(1))*1000); #endif #endif } /* =============== Cmd_Exec_f =============== */ void Cmd_Exec_f (void) { char *f, *f2; int len; if (Cmd_Argc () != 2) { Com_Printf ("exec : execute a script file\n"); return; } len = FS_LoadFile (Cmd_Argv(1), (void **)&f); if (!f) { Com_Printf ("Could not exec %s\n",Cmd_Argv(1)); return; } Com_Printf ("execing %s\n",Cmd_Argv(1)); // the file doesn't have a trailing 0, so we need to copy it off f2 = Z_Malloc(len+1); memcpy (f2, f, len); f2[len] = 0; Cbuf_InsertText (f2); Z_Free (f2); FS_FreeFile (f); } /* =============== Cmd_Echo_f Just prints the rest of the line to the console =============== */ void Cmd_Echo_f (void) { int i; for (i=1 ; inext) Com_Printf ("%s : %s\n", a->name, a->value); return; } s = Cmd_Argv(1); if (strlen(s) >= MAX_ALIAS_NAME) { Com_Printf ("Alias name is too long\n"); return; } // compute the hash key for this alias COMPUTE_HASH_KEY( hash_key, s , i ); // if the alias already exists, reuse it prev = &cmd_alias; for (a = cmd_alias ; a && a->hash_key <= hash_key ; a=a->next) { if (a->hash_key == hash_key && !Q_strcasecmp(s, a->name)) { Z_Free (a->value); break; } prev = &( a->next ); } if (!a) { a = Z_Malloc (sizeof(cmdalias_t)); a->next = NULL; *prev = a; } else if ( a->hash_key != hash_key ) { na = Z_Malloc (sizeof(cmdalias_t)); na->next = a; *prev = na; a = na; } strcpy (a->name, s); a->hash_key = hash_key; // copy the rest of the command line cmd[0] = 0; // start out with a null string c = Cmd_Argc(); for (i=2 ; i< c ; i++) { strcat (cmd, Cmd_Argv(i)); if (i != (c - 1)) strcat (cmd, " "); } strcat (cmd, "\n"); a->value = CopyString (cmd); } /* =============== Cmd_Unalias_f Removes an existing alias using its name to look it up =============== */ void Cmd_Unalias_f (void) { cmdalias_t *a, **prev; unsigned int hash_key; int i; char *s; if (Cmd_Argc() != 2) { Com_Printf ("usage: unalias \n"); return; } s = Cmd_Argv(1); // compute the hash key for this alias COMPUTE_HASH_KEY( hash_key, s , i ); // find the alias prev = &cmd_alias; for (a = cmd_alias ; a && a->hash_key <= hash_key ; a=a->next) { if (a->hash_key == hash_key && !Q_strcasecmp(s, a->name)) { break; } prev = &( a->next ); } if (!a || a->hash_key != hash_key) { Com_Printf ("Alias not found\n"); return; } *prev = a->next; Z_Free (a->value); Z_Free (a); } /* ============================================================================= COMMAND EXECUTION ============================================================================= */ typedef struct cmd_function_s { struct cmd_function_s *next; unsigned int hash_key; char *name; xcommand_t function; } cmd_function_t; static qboolean cmd_force_command; static int cmd_argc; static char *cmd_argv[MAX_STRING_TOKENS]; static char *cmd_null_string = ""; static char cmd_args[MAX_STRING_CHARS]; static cmd_function_t *cmd_functions; // possible commands to execute /* ============ Cmd_Argc ============ */ int Cmd_Argc (void) { return cmd_argc; } /* ============ Cmd_Argv ============ */ char *Cmd_Argv (int arg) { if ( (unsigned)arg >= cmd_argc ) return cmd_null_string; return cmd_argv[arg]; } /* ============ Cmd_Args Returns a single string containing argv(1) to argv(argc()-1) ============ */ char *Cmd_Args (void) { return cmd_args; } /* ====================== Cmd_MacroExpandString ====================== */ char *Cmd_MacroExpandString (char *text) { int i, j, count, len; qboolean inquote; char *scan; static char expanded[MAX_STRING_CHARS]; char temporary[MAX_STRING_CHARS]; char *token, *start; inquote = false; scan = text; len = strlen (scan); if (len >= MAX_STRING_CHARS) { Com_Printf ("Line exceeded %i chars, discarded.\n", MAX_STRING_CHARS); return NULL; } count = 0; for (i=0 ; i= MAX_STRING_CHARS) { Com_Printf ("Expanded line exceeded %i chars, discarded.\n", MAX_STRING_CHARS); return NULL; } strncpy (temporary, scan, i); strcpy (temporary+i, token); strcpy (temporary+i+j, start); strcpy (expanded, temporary); scan = expanded; i--; if (++count == 100) { Com_Printf ("Macro expansion loop, discarded.\n"); return NULL; } } if (inquote) { Com_Printf ("Line has unmatched quote, discarded.\n"); return NULL; } return scan; } /* ============ Cmd_TokenizeString Parses the given string into command line tokens. $Cvars will be expanded unless they are in a quoted token ============ */ void Cmd_TokenizeString (char *text, qboolean macroExpand) { int i; char *com_token; // clear the args from the last string for (i=0 ; i= 0 ; l--) if (cmd_args[l] <= ' ') cmd_args[l] = 0; else break; } com_token = COM_Parse (&text); if (!text) return; // if we're parsing the first arguments, check for "forced" // commands beginning with slashes or backslashes if ( cmd_argc == 0 && ! cmd_force_command ) { cmd_force_command = ( com_token[0] == '/' || com_token[0] == '\\' ); if ( cmd_force_command ) { // if there was white space after the slash // or backslash, skip to the next token if ( com_token[1] == 0 ) continue; // if not, skip the first character com_token ++; } } if (cmd_argc < MAX_STRING_TOKENS) { cmd_argv[cmd_argc] = Z_Malloc (strlen(com_token)+1); strcpy (cmd_argv[cmd_argc], com_token); cmd_argc++; } } } /* ============ Cmd_AddCommand ============ */ void Cmd_AddCommand (char *cmd_name, xcommand_t function) { cmd_function_t *cmd, **prev, *ncmd; unsigned int hash_key, i; // fail if the command is a variable name if (Cvar_VariableString(cmd_name)[0]) { Com_Printf ("Cmd_AddCommand: %s already defined as a var\n", cmd_name); return; } // compute the hash key for this command COMPUTE_HASH_KEY( hash_key, cmd_name , i ); // fail if the command already exists (harmless if it's already the same.) prev = &cmd_functions; for (cmd=cmd_functions ; cmd && cmd->hash_key <= hash_key ; cmd=cmd->next) { if (cmd->hash_key == hash_key && !Q_strcasecmp (cmd_name, cmd->name)) { if (cmd->function != function) Com_Printf ("Cmd_AddCommand: %s already defined\n", cmd_name); return; } prev = &( cmd->next ); } ncmd = Z_Malloc (sizeof(cmd_function_t)); ncmd->name = cmd_name; ncmd->hash_key = hash_key; ncmd->function = function; ncmd->next = cmd; *prev = ncmd; } /* ============ Cmd_RemoveCommand ============ */ void Cmd_RemoveCommand (char *cmd_name) { cmd_function_t *cmd, **back; unsigned int i, hash_key; // compute the hash key for the command COMPUTE_HASH_KEY( hash_key, cmd_name , i ); back = &cmd_functions; while (1) { cmd = *back; if (!cmd || cmd->hash_key > hash_key) { Com_Printf ("Cmd_RemoveCommand: %s not added\n", cmd_name); return; } if (cmd->hash_key == hash_key && !Q_strcasecmp (cmd_name, cmd->name)) { *back = cmd->next; Z_Free (cmd); return; } back = &cmd->next; } } /* ============ Cmd_Exists ============ */ qboolean Cmd_Exists (char *cmd_name) { cmd_function_t *cmd; unsigned int i, hash_key; // compute the hash key for the command name COMPUTE_HASH_KEY( hash_key, cmd_name , i ); for (cmd=cmd_functions ; cmd && cmd->hash_key <= hash_key; cmd=cmd->next) { if (cmd->hash_key == hash_key && !Q_strcasecmp (cmd_name,cmd->name)) return true; } return false; } /* ============ Cmd_CompleteCommand ============ */ char retval[256]; char *Cmd_CompleteCommand (char *partial) { cmd_function_t *cmd; int len, i, o, p; cmdalias_t *a; cvar_t *cvar; char *pmatch[1024]; qboolean diff = false; unsigned int hash_key; len = strlen(partial); if (!len) return NULL; /* check for exact match */ COMPUTE_HASH_KEY( hash_key , partial , i ); for (cmd = cmd_functions; cmd && cmd->hash_key <= hash_key; cmd = cmd->next) if (hash_key == cmd->hash_key && !Q_strcasecmp(partial, cmd->name)) return cmd->name; for (a = cmd_alias; a && a->hash_key <= hash_key; a = a->next) if (hash_key == a->hash_key && !Q_strcasecmp(partial, a->name)) return a->name; for (cvar = cvar_vars; cvar && cvar->hash_key <= hash_key; cvar = cvar->next) if (hash_key == cvar->hash_key && !Q_strcasecmp(partial, cvar->name)) return cvar->name; // clear matches for (i = 0; i < 1024; i++) pmatch[i] = NULL; i = 0; /* check for partial match */ for (cmd = cmd_functions; cmd; cmd = cmd->next) if (!Q_strncasecmp(partial, cmd->name, len)) { pmatch[i] = cmd->name; i++; } for (a = cmd_alias; a; a = a->next) if (!Q_strncasecmp(partial, a->name, len)) { pmatch[i] = a->name; i++; } for (cvar = cvar_vars; cvar; cvar = cvar->next) if (!Q_strncasecmp(partial, cvar->name, len)) { pmatch[i] = cvar->name; i++; } if (i) { if (i == 1) return pmatch[0]; Com_Printf("\nListing matches for '%s'...\n", partial); for (o = 0; o < i; o++) Com_Printf(" %s\n", pmatch[o]); strcpy(retval, ""); p = 0; while (!diff && p < 256) { retval[p] = pmatch[0][p]; for (o = 0; o < i; o++) { if (p > strlen(pmatch[o])) continue; if (retval[p] != pmatch[o][p]) { retval[p] = 0; diff = true; } } p++; } Com_Printf("Found %i matches\n", i); return retval; } return NULL; } qboolean Cmd_IsComplete(char *command) { cmd_function_t *cmd; cmdalias_t *a; cvar_t *cvar; unsigned int hash_key, i; /* check for exact match */ COMPUTE_HASH_KEY( hash_key , command , i ); for (cmd = cmd_functions; cmd && cmd->hash_key <= hash_key; cmd = cmd->next) if (hash_key == cmd->hash_key && !Q_strcasecmp(command, cmd->name)) return true; for (a = cmd_alias; a && a->hash_key <= hash_key; a = a->next) if (hash_key == a->hash_key && !Q_strcasecmp(command, a->name)) return true; for (cvar = cvar_vars; cvar && cvar->hash_key <= hash_key; cvar = cvar->next) if (hash_key == cvar->hash_key && !Q_strcasecmp(command, cvar->name)) return true; return false; } /* ============ Cmd_ExecuteString A complete command line has been parsed, so try to execute it FIXME: lookupnoadd the token to speed search? ============ */ void Cmd_ExecuteString (char *text) { cmd_function_t *cmd; cmdalias_t *a; unsigned int i, hash_key; Cmd_TokenizeString (text, true); // execute the command line if (!Cmd_Argc()) return; // no tokens // compute the hash key for the command COMPUTE_HASH_KEY( hash_key, cmd_argv[0] , i ); // check functions for (cmd=cmd_functions ; cmd && cmd->hash_key <= hash_key; cmd=cmd->next) { if (cmd->hash_key == hash_key && !Q_strcasecmp (cmd_argv[0],cmd->name)) { if (!cmd->function) { // forward to server command Cmd_ExecuteString (va("cmd %s %s", cmd_argv[0], cmd_args)); } else cmd->function (); return; } } // check alias for (a=cmd_alias ; a && a->hash_key <= hash_key ; a=a->next) { if (a->hash_key == hash_key && !Q_strcasecmp (cmd_argv[0], a->name)) { if (++alias_count == ALIAS_LOOP_COUNT) { Com_Printf ("ALIAS_LOOP_COUNT\n"); return; } Cbuf_InsertText (a->value); return; } } // check cvars if (Cvar_Command ()) return; // send it as a server command if we are connected // and if the command wasn't forced if ( ! cmd_force_command ) Cmd_ForwardToServer (); else Com_Printf ("Unknown command \"%s\"\n", cmd_argv[0]); } /* ============ Cmd_List_f ============ */ void Cmd_List_f (void) { cmd_function_t *cmd; int i; i = 0; for (cmd=cmd_functions ; cmd ; cmd=cmd->next, i++) Com_Printf ("%s\n", cmd->name); Com_Printf ("%i commands\n", i); } /* ============ Cmd_Init ============ */ void Cmd_Init (void) { // // register our commands // Cmd_AddCommand ("cmdlist",Cmd_List_f); Cmd_AddCommand ("exec",Cmd_Exec_f); Cmd_AddCommand ("echo",Cmd_Echo_f); Cmd_AddCommand ("alias",Cmd_Alias_f); Cmd_AddCommand ("unalias",Cmd_Unalias_f); Cmd_AddCommand ("wait", Cmd_Wait_f); Cmd_AddCommand ("hang", Cmd_SimulateHang_f); } alien-arena-7.66+dfsg/source/qcommon/htable.h0000600000175000017500000001107212161402010020164 0ustar zero79zero79/* Copyright (C) 2010 COR Entertainment This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // Hash table interface #ifndef __H_HASHTABLE #define __H_HASHTABLE #include "game/q_shared.h" /*=============================================* * Hash table types * *=============================================*/ /* Hash table (opaque type) */ struct hashtable_s; typedef struct hashtable_s * hashtable_t; /* Function pointer for HT_Apply */ typedef qboolean ( * ht_apply_funct )( void * item , void * extra ); /*=============================================* * Hash table flags * *=============================================*/ /* Items are stored inside the table */ #define HT_FLAG_INTABLE ( 1 << 0 ) /* Free items on table destruction */ #define HT_FLAG_FREE ( 1 << 1 ) /* Keys are case-sensitive */ #define HT_FLAG_CASE ( 1 << 2 ) /* Iteration is sorted by key */ #define HT_FLAG_SORTED ( 1 << 3 ) /*=============================================* * Hash table functions * *=============================================*/ /* * Hash table creation * * Parameters: * size size of the table (will be rounded up to the next * prime number) * flags combination of HT_FLAG_* for the table * item_size size of the table's items * key_offset offset of the key in the table's items * key_length maximal length of the key in the table; if 0, the key * will be accessed as a pointer instead of an array */ hashtable_t HT_Create( size_t size , unsigned int flags , size_t item_size , size_t key_offset , size_t key_length ); /* * Macro that determines the offset of a field in a structure */ #define HT_OffsetOfField(TYPE,FIELD) \ ( (char *)( &( ( (TYPE *) NULL )->FIELD ) ) - (char *) NULL ) /* * Hash table destruction */ void HT_Destroy( hashtable_t table ); /* * Gets an item from the table. * * Parameters: * table the hash table to access * key the key to look up * create pointer to a boolean which will be set to true if * the item was created; if NULL, no creation will take * place */ void * HT_GetItem( hashtable_t table , const char * key , qboolean * created ); /* * Stores an item into the table * * Parameters: * table the hash table to add an item to * item the item to add to the table * allow_replacement whether replacement of a previous item * is allowed * * Returns: * the item that matched the specified key, or NULL if no item * using the same key existed * * Note: * Replacement behaviour varies greatly depending on the flags. * If the items are stored in-table, or if the table must free the * memory they use, a replacement will still return NULL, as the * memory will have been freed or reused. */ void * HT_PutItem( hashtable_t table , void * item , qboolean allow_replacement ); /* * Deletes an item from the table * * Parameters: * table the hash table from which an item is to be * deleted * key the key to delete * found a pointer to a pointer which will be set to * the deleted item's value; may be NULL * * Returns: * true if an item was deleted, false otherwise * * Note: * If the items are stored in-table or are freed automatically, then * the "found" parameter will always be ignored. */ qboolean HT_DeleteItem( hashtable_t table , const char * key , void ** found ); /* * Applies a function to all items in the table. * * Parameters: * table the hash table onto which the function is to * be applied * function pointer to the function to apply * data extra data to pass as the function's second * parameter * * Notes: * The order in which the function is applied is either the insertion * order or, if the table has HT_FLAG_SORTED set, the increasing key * order. * The function should return false if processing is to stop. */ void HT_Apply( hashtable_t table , ht_apply_funct function , void * data ); #endif // __H_HASHTABLE alien-arena-7.66+dfsg/source/qcommon/net_chan.c0000600000175000017500000002467712161402010020516 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "qcommon.h" /* packet header ------------- 31 sequence 1 does this message contain a reliable payload 31 acknowledge sequence 1 acknowledge receipt of even/odd message 16 qport The remote connection never knows if it missed a reliable message, the local side detects that it has been dropped by seeing a sequence acknowledge higher thatn the last reliable sequence, but without the correct evon/odd bit for the reliable set. If the sender notices that a reliable message has been dropped, it will be retransmitted. It will not be retransmitted again until a message after the retransmit has been acknowledged and the reliable still failed to get there. if the sequence number is -1, the packet should be handled without a netcon The reliable message can be added to at any time by doing MSG_Write* (&netchan->message, ). If the message buffer is overflowed, either by a single message, or by multiple frames worth piling up while the last reliable transmit goes unacknowledged, the netchan signals a fatal error. Reliable messages are always placed first in a packet, then the unreliable message is included if there is sufficient room. To the receiver, there is no distinction between the reliable and unreliable parts of the message, they are just processed out as a single larger message. Illogical packet sequence numbers cause the packet to be dropped, but do not kill the connection. This, combined with the tight window of valid reliable acknowledgement numbers provides protection against malicious address spoofing. The qport field is a workaround for bad address translating routers that sometimes remap the client's source port on a packet during gameplay. If the base part of the net address matches and the qport matches, then the channel matches even if the IP port differs. The IP port should be updated to the new value before sending out any replies. If there is no information that needs to be transfered on a given frame, such as during the connection stage while waiting for the client to load, then a packet only needs to be delivered if there is something in the unacknowledged reliable */ cvar_t *showpackets; cvar_t *showdrop; cvar_t *qport; netadr_t net_from; sizebuf_t net_message; byte net_message_buffer[MAX_MSGLEN]; /* =============== Netchan_Init =============== */ void Netchan_Init (void) { int port; // pick a port value that should be nice and random port = Sys_Milliseconds() & 0xffff; showpackets = Cvar_Get ("showpackets", "0", 0); showdrop = Cvar_Get ("showdrop", "0", 0); qport = Cvar_Get ("qport", va("%i", port), CVAR_NOSET); } /* =============== Netchan_OutOfBand Sends an out-of-band datagram ================ */ void Netchan_OutOfBand (int net_socket, netadr_t adr, int length, byte *data) { sizebuf_t send; byte send_buf[MAX_MSGLEN]; // write the packet header SZ_Init (&send, send_buf, sizeof(send_buf)); SZ_SetName (&send, "Net OOB buffer", false); MSG_WriteLong (&send, -1); // -1 sequence means out of band SZ_Write (&send, data, length); // send the datagram NET_SendPacket (net_socket, send.cursize, send.data, adr); } /* =============== Netchan_OutOfBandPrint Sends a text message in an out-of-band datagram ================ */ void Netchan_OutOfBandPrint (int net_socket, netadr_t adr, char *format, ...) { va_list argptr; static char string[MAX_MSGLEN - 4]; va_start (argptr, format); vsnprintf(string, sizeof(string), format, argptr); va_end (argptr); Netchan_OutOfBand (net_socket, adr, strlen(string), (byte *)string); } /* ============== Netchan_Setup called to open a channel to a remote system ============== */ void Netchan_Setup (netsrc_t sock, netchan_t *chan, netadr_t adr, int qport) { memset (chan, 0, sizeof(*chan)); chan->sock = sock; chan->remote_address = adr; chan->qport = qport; chan->last_received = curtime; chan->incoming_sequence = 0; chan->outgoing_sequence = 1; SZ_Init (&chan->message, chan->message_buf, sizeof(chan->message_buf)); SZ_SetName (&chan->message, va("Net channel %s", NET_AdrToString(adr)), true); chan->message.allowoverflow = true; } /* =============== Netchan_CanReliable Returns true if the last reliable message has acked ================ */ qboolean Netchan_CanReliable (netchan_t *chan) { if (chan->reliable_length) return false; // waiting for ack return true; } qboolean Netchan_NeedReliable (netchan_t *chan) { qboolean send_reliable; // if the remote side dropped the last reliable message, resend it send_reliable = false; if (chan->incoming_acknowledged > chan->last_reliable_sequence && chan->incoming_reliable_acknowledged != chan->reliable_sequence) send_reliable = true; // if the reliable transmit buffer is empty, copy the current message out if (!chan->reliable_length && chan->message.cursize) { send_reliable = true; } return send_reliable; } /* =============== Netchan_Transmit tries to send an unreliable message to a connection, and handles the transmition / retransmition of the reliable messages. A 0 length will still generate a packet and deal with the reliable messages. ================ */ void Netchan_Transmit (netchan_t *chan, int length, byte *data) { sizebuf_t send; byte send_buf[MAX_MSGLEN]; qboolean send_reliable; unsigned w1, w2; // check for message overflow if (chan->message.overflowed) { chan->fatal_error = true; Com_Printf ("%s:Outgoing message overflow\n" , NET_AdrToString (chan->remote_address)); return; } send_reliable = Netchan_NeedReliable (chan); if (!chan->reliable_length && chan->message.cursize) { memcpy (chan->reliable_buf, chan->message_buf, chan->message.cursize); chan->reliable_length = chan->message.cursize; chan->message.cursize = 0; chan->reliable_sequence ^= 1; } // write the packet header SZ_Init (&send, send_buf, sizeof(send_buf)); SZ_SetName (&send, va("Transmit buffer (%s)", NET_AdrToString(chan->remote_address)), false); w1 = ( chan->outgoing_sequence & ~(1<<31) ) | (send_reliable<<31); w2 = ( chan->incoming_sequence & ~(1<<31) ) | (chan->incoming_reliable_sequence<<31); chan->outgoing_sequence++; chan->last_sent = curtime; MSG_WriteLong (&send, w1); MSG_WriteLong (&send, w2); // send the qport if we are a client if (chan->sock == NS_CLIENT) MSG_WriteShort (&send, qport->value); // copy the reliable message to the packet first if (send_reliable) { SZ_Write (&send, chan->reliable_buf, chan->reliable_length); chan->last_reliable_sequence = chan->outgoing_sequence; } // add the unreliable part if space is available if (send.maxsize - send.cursize >= length) SZ_Write (&send, data, length); else Com_Printf ("Netchan_Transmit: dumped unreliable\n"); // send the datagram NET_SendPacket (chan->sock, send.cursize, send.data, chan->remote_address); if (showpackets->value) { if (send_reliable) Com_Printf ("send %4i : s=%i reliable=%i ack=%i rack=%i\n" , send.cursize , chan->outgoing_sequence - 1 , chan->reliable_sequence , chan->incoming_sequence , chan->incoming_reliable_sequence); else Com_Printf ("send %4i : s=%i ack=%i rack=%i\n" , send.cursize , chan->outgoing_sequence - 1 , chan->incoming_sequence , chan->incoming_reliable_sequence); } } /* ================= Netchan_Process called when the current net_message is from remote_address modifies net_message so that it points to the packet payload ================= */ qboolean Netchan_Process (netchan_t *chan, sizebuf_t *msg) { unsigned sequence, sequence_ack; unsigned reliable_ack, reliable_message; int qport; // get sequence numbers MSG_BeginReading (msg); sequence = MSG_ReadLong (msg); sequence_ack = MSG_ReadLong (msg); // read the qport if we are a server if (chan->sock == NS_SERVER) qport = MSG_ReadShort (msg); reliable_message = sequence >> 31; reliable_ack = sequence_ack >> 31; sequence &= ~(1<<31); sequence_ack &= ~(1<<31); if (showpackets->value) { if (reliable_message) Com_Printf ("recv %4i : s=%i reliable=%i ack=%i rack=%i\n" , msg->cursize , sequence , chan->incoming_reliable_sequence ^ 1 , sequence_ack , reliable_ack); else Com_Printf ("recv %4i : s=%i ack=%i rack=%i\n" , msg->cursize , sequence , sequence_ack , reliable_ack); } // // discard stale or duplicated packets // if (sequence <= chan->incoming_sequence) { if (showdrop->value) Com_Printf ("%s:Out of order packet %i at %i\n" , NET_AdrToString (chan->remote_address) , sequence , chan->incoming_sequence); return false; } // // dropped packets don't keep the message from being used // chan->dropped = sequence - (chan->incoming_sequence+1); if (chan->dropped > 0) { if (showdrop->value) Com_Printf ("%s:Dropped %i packets at %i\n" , NET_AdrToString (chan->remote_address) , chan->dropped , sequence); } // // if the current outgoing reliable message has been acknowledged // clear the buffer to make way for the next // if (reliable_ack == chan->reliable_sequence) chan->reliable_length = 0; // it has been received // // if this message contains a reliable message, bump incoming_reliable_sequence // chan->incoming_sequence = sequence; chan->incoming_acknowledged = sequence_ack; chan->incoming_reliable_acknowledged = reliable_ack; if (reliable_message) { chan->incoming_reliable_sequence ^= 1; } // // the message can now be read from the current message pointer // chan->last_received = curtime; return true; } alien-arena-7.66+dfsg/source/qcommon/crc.h0000600000175000017500000000171212161402010017474 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* crc.h */ void CRC_Init(unsigned short *crcvalue); void CRC_ProcessByte(unsigned short *crcvalue, byte data); unsigned short CRC_Value(unsigned short crcvalue); unsigned short CRC_Block (byte *start, int count); alien-arena-7.66+dfsg/source/qcommon/md5.c0000600000175000017500000002635412161402010017416 0ustar zero79zero79 #ifdef HAVE_CONFIG_H #include "config.h" #endif //#pragma hdrstop #include #include "qcommon.h" #if !defined max #define max(a,b) (((a)<(b)) ? (b) : (a)) #endif /* MD5 Message Digest Algorithm. (RFC1321) */ /* This code implements the MD5 message-digest algorithm. The algorithm is due to Ron Rivest. This code was written by Colin Plumb in 1993, no copyright is claimed. This code is in the public domain; do with it what you wish. Equivalent code is available from RSA Data Security, Inc. This code has been tested against that, and is equivalent, except that you don't need to include two pages of legalese with every copy. To compute the message digest of a chunk of bytes, declare an MD5Context structure, pass it to MD5Init, call MD5Update as needed on buffers full of bytes, and then call MD5Final, which will fill a supplied 16-byte array with the digest. */ // MD5 context. typedef struct { unsigned int state[4]; unsigned int bits[2]; unsigned char in[64]; } MD5_CTX; // The four core functions - F1 is optimized somewhat // #define F1(x, y, z)(x & y | ~x & z) #define F1(x, y, z)(z ^ (x & (y ^ z))) #define F2(x, y, z)F1(z, x, y) #define F3(x, y, z)(x ^ y ^ z) #define F4(x, y, z)(y ^ (x | ~z)) // This is the central step in the MD5 algorithm. #define MD5STEP(f, w, x, y, z, data, s)(w += f(x, y, z)+ data, w = w<>(32-s), w += x) static void ByteReverse (unsigned char *buf, unsigned longs) { unsigned int t; do { t = (unsigned int)((unsigned)buf[3] << 8 | buf[2])<< 16 | ((unsigned)buf[1] << 8 | buf[0]); *(unsigned int *)buf = t; buf += 4; } while (--longs); } /* ================= MD5_Transform The core of the MD5 algorithm, this alters an existing MD5 hash to reflect the addition of 16 longwords of new data. MD5Update blocks the data and converts bytes into longwords for this routine. ================= */ static void MD5_Transform (unsigned int state[4], unsigned int in[16]) { register unsigned int a, b, c, d; a = state[0]; b = state[1]; c = state[2]; d = state[3]; ByteReverse((unsigned char *)in, 16); MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); ByteReverse((unsigned char *)in, 16); state[0] += a; state[1] += b; state[2] += c; state[3] += d; } /* ================== MD5_Init MD5 initialization. Begins an MD5 operation, writing a new context. ================== */ static void MD5_Init (MD5_CTX *ctx) { ctx->state[0] = 0x67452301; ctx->state[1] = 0xefcdab89; ctx->state[2] = 0x98badcfe; ctx->state[3] = 0x10325476; ctx->bits[0] = 0; ctx->bits[1] = 0; } /* =================== MD5_Update MD5 block update operation. Continues an MD5 message-digest operation, processing another message block, and updating the context. =================== */ static void MD5_Update (MD5_CTX *ctx, unsigned char const *buf, unsigned int len) { unsigned int t; // Update bitcount t = ctx->bits[0]; if ((ctx->bits[0] = t + ((unsigned int)len << 3)) < t) ctx->bits[1]++; // Carry from low to high ctx->bits[1] += len >> 29; t = (t >> 3)& 0x3f; // Bytes already in shsInfo->data // Handle any leading odd-sized chunks if (t) { unsigned char *p = (unsigned char *)ctx->in + t; t = 64 - t; if (len < t) { memcpy(p, buf, len); return; } memcpy(p, buf, t); MD5_Transform(ctx->state, (unsigned int *)ctx->in); buf += t; len -= t; } // Process data in 64-byte chunks while (len >= 64) { memcpy(ctx->in, buf, 64); MD5_Transform(ctx->state, (unsigned int *)ctx->in); buf += 64; len -= 64; } // Handle any remaining bytes of data. memcpy(ctx->in, buf, len); } /* =============== MD5_Final MD5 finalization. Ends an MD5 message-digest operation, writing the message digest and zeroizing the context. =============== */ static void MD5_Final (MD5_CTX *ctx, unsigned char digest[16]) { unsigned count; unsigned char *p; // Compute number of bytes mod 64 count = (ctx->bits[0] >> 3)& 0x3F; // Set the first char of padding to 0x80. This is safe since there is // always at least one byte free p = ctx->in + count; *p++ = 0x80; // Bytes of padding needed to make 64 bytes count = 64 - 1 - count; // Pad out to 56 mod 64 if (count < 8) { // Two lots of padding: Pad the first block to 64 bytes memset(p, 0, count); MD5_Transform(ctx->state, (unsigned int *)ctx->in); // Now fill the next block with 56 bytes memset(ctx->in, 0, 56); } else { // Pad block to 56 bytes memset(p, 0, count - 8); } // Append length in bits and transform ((unsigned int *)ctx->in)[14] = ctx->bits[0]; ((unsigned int *)ctx->in)[15] = ctx->bits[1]; MD5_Transform(ctx->state, (unsigned int *)ctx->in); memcpy(digest, ctx->state, 16); memset(ctx, 0, sizeof(ctx)); // In case it's sensitive } //=================================================================== unsigned Com_MD5Checksum (void *buffer, int length) { int digest[4]; unsigned val; MD5_CTX ctx; MD5_Init(&ctx); MD5_Update(&ctx, (unsigned char *)buffer, length); MD5_Final(&ctx, (unsigned char *)digest); val = digest[0] ^ digest[1] ^ digest[2] ^ digest[3]; return val; } // jit - string version void BinToHex (void *pData, size_t sizeData, char *HexString, size_t sizeOut) // jit { int i, Length; unsigned char LeftHalf, RightHalf; const unsigned char *BinData = pData; Length = sizeOut / 2 - 1; // make sure we don't have any buffer overruns if (sizeData < Length) Length = sizeData; for (i = 0; i < Length; i++) { LeftHalf = BinData[i]; LeftHalf >>= 4; RightHalf = BinData[i] & 0xF; if (LeftHalf > 9) LeftHalf += 'a' - 10; else LeftHalf += '0'; if (RightHalf > 9) RightHalf += 'a' - 10; else RightHalf += '0'; *HexString++ = LeftHalf; *HexString++ = RightHalf; } *HexString = '\0'; } char *Com_MD5HashString (const void *buffer, int length, char *pMD5Out, size_t sizeMD5Out) { int digest[4]; MD5_CTX ctx; MD5_Init(&ctx); MD5_Update(&ctx, (unsigned char *)buffer, length); MD5_Final(&ctx, (unsigned char *)digest); // Will this work on a big-endian system? BinToHex(digest, sizeof(int) * 4, pMD5Out, sizeMD5Out); return pMD5Out; } // hmac( key, m ) = h( (key ^ opad) + h( (key ^ ipad) + m ) ) char *Com_HMACMD5String (const void *key, size_t keylen, const void *msg, int msglen, char *out, size_t outsize) { unsigned char *pOPad; unsigned char *pIPad; const unsigned char *pKey = key; unsigned char *pTemp; int i, len; char szMD5Str[40]; pOPad = Z_Malloc(keylen); pIPad = Z_Malloc(keylen); len = (int)max(keylen + msglen, keylen + 32); pTemp = Z_Malloc(len); for (i = 0; i < keylen; ++i) { pOPad[i] = pKey[i] ^ 0x5C; pIPad[i] = pKey[i] ^ 0x36; } memcpy(pTemp, pIPad, keylen); memcpy(pTemp + keylen, msg, msglen); Com_MD5HashString(pTemp, (int)(keylen + msglen), szMD5Str, sizeof(szMD5Str)); memcpy(pTemp, pOPad, keylen); memcpy(pTemp + keylen, szMD5Str, strlen(szMD5Str)); Com_MD5HashString(pTemp, (int)(keylen + strlen(szMD5Str)), out, outsize); Z_Free(pTemp); Z_Free(pOPad); Z_Free(pIPad); return out; } unsigned Com_MD5ChecksumKey (void *buffer, int length, int key) { int digest[4]; unsigned val; MD5_CTX ctx; MD5_Init(&ctx); MD5_Update(&ctx, (unsigned char *)&key, 4); MD5_Update(&ctx, (unsigned char *)buffer, length); MD5_Final(&ctx, (unsigned char *)digest); val = digest[0] ^ digest[1] ^ digest[2] ^ digest[3]; return val; } alien-arena-7.66+dfsg/source/qcommon/pmove.c0000600000175000017500000007201312161402010020050 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "qcommon.h" #define STEPSIZE 18 extern cvar_t *sv_joustmode; extern cvar_t *sv_tactical; extern cvar_t *sv_excessive; // all of the locals will be zeroed before each // pmove, just to make damn sure we don't have // any differences when running on client or server typedef struct { vec3_t origin; // full float precision vec3_t velocity; // full float precision vec3_t forward, right, up; float frametime; csurface_t *groundsurface; cplane_t groundplane; int groundcontents; vec3_t previous_origin; qboolean ladder; } pml_t; pmove_t *pm; pml_t pml; // movement parameters float pm_stopspeed = 100; float pm_maxspeed = 300; float pm_duckspeed = 100; float pm_accelerate = 10; float pm_airaccelerate = 0; float pm_wateraccelerate = 10; float pm_friction = 6; float pm_waterfriction = 1; float pm_waterspeed = 400; /* walking up a step should kill some velocity */ /* ================== PM_ClipVelocity Slide off of the impacting object returns the blocked flags (1 = floor, 2 = step / wall) ================== */ #define STOP_EPSILON 0.1 void PM_ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce) { float backoff; float change; int i; backoff = DotProduct (in, normal) * overbounce; for (i=0 ; i<3 ; i++) { change = normal[i]*backoff; out[i] = in[i] - change; if (out[i] > -STOP_EPSILON && out[i] < STOP_EPSILON) out[i] = 0; } } /* ================== PM_StepSlideMove Each intersection will try to step over the obstruction instead of sliding along it. Returns a new origin, velocity, and contact entity Does not modify any world state? ================== */ #define MIN_STEP_NORMAL 0.7 // can't step up onto very steep slopes #define MAX_CLIP_PLANES 5 void PM_StepSlideMove_ (void) { int bumpcount, numbumps; vec3_t dir; float d; int numplanes; vec3_t planes[MAX_CLIP_PLANES]; vec3_t primal_velocity; int i, j; trace_t trace; vec3_t end; float time_left; numbumps = 4; VectorCopy (pml.velocity, primal_velocity); numplanes = 0; time_left = pml.frametime; for (bumpcount=0 ; bumpcounttrace (pml.origin, pm->mins, pm->maxs, end); if (trace.allsolid) { // entity is trapped in another solid pml.velocity[2] = 0; // don't build up falling damage return; } if (trace.fraction > 0) { // actually covered some distance VectorCopy (trace.endpos, pml.origin); numplanes = 0; } if (trace.fraction == 1) break; // moved the entire distance // save entity for contact if (pm->numtouch < MAXTOUCH && trace.ent) { pm->touchents[pm->numtouch] = trace.ent; pm->numtouch++; } time_left -= time_left * trace.fraction; // slide along this plane if (numplanes >= MAX_CLIP_PLANES) { // this shouldn't really happen VectorCopy (vec3_origin, pml.velocity); break; } VectorCopy (trace.plane.normal, planes[numplanes]); numplanes++; #if 0 float rub; // // modify velocity so it parallels all of the clip planes // if (numplanes == 1) { // go along this plane VectorCopy (pml.velocity, dir); VectorNormalize (dir); rub = 1.0 + 0.5 * DotProduct (dir, planes[0]); // slide along the plane PM_ClipVelocity (pml.velocity, planes[0], pml.velocity, 1.01); // rub some extra speed off on xy axis // not on Z, or you can scrub down walls pml.velocity[0] *= rub; pml.velocity[1] *= rub; pml.velocity[2] *= rub; } else if (numplanes == 2) { // go along the crease VectorCopy (pml.velocity, dir); VectorNormalize (dir); rub = 1.0 + 0.5 * DotProduct (dir, planes[0]); // slide along the plane CrossProduct (planes[0], planes[1], dir); d = DotProduct (dir, pml.velocity); VectorScale (dir, d, pml.velocity); // rub some extra speed off VectorScale (pml.velocity, rub, pml.velocity); } else { // Con_Printf ("clip velocity, numplanes == %i\n",numplanes); VectorCopy (vec3_origin, pml.velocity); break; } #else // // modify original_velocity so it parallels all of the clip planes // for (i=0 ; is.pm_time) { VectorCopy (primal_velocity, pml.velocity); } } /* ================== PM_StepSlideMove ================== */ void PM_StepSlideMove (void) { vec3_t start_o, start_v; vec3_t down_o, down_v; trace_t trace; float down_dist, up_dist; // vec3_t delta; vec3_t up, down; VectorCopy (pml.origin, start_o); VectorCopy (pml.velocity, start_v); PM_StepSlideMove_ (); VectorCopy (pml.origin, down_o); VectorCopy (pml.velocity, down_v); VectorCopy (start_o, up); up[2] += STEPSIZE; trace = pm->trace (up, pm->mins, pm->maxs, up); if (trace.allsolid) return; // can't step up // try sliding above VectorCopy (up, pml.origin); VectorCopy (start_v, pml.velocity); PM_StepSlideMove_ (); // push down the final amount VectorCopy (pml.origin, down); down[2] -= STEPSIZE; trace = pm->trace (pml.origin, pm->mins, pm->maxs, down); if (!trace.allsolid) { VectorCopy (trace.endpos, pml.origin); } #if 0 VectorSubtract (pml.origin, up, delta); up_dist = DotProduct (delta, start_v); VectorSubtract (down_o, start_o, delta); down_dist = DotProduct (delta, start_v); #else VectorCopy(pml.origin, up); // decide which one went farther down_dist = (down_o[0] - start_o[0])*(down_o[0] - start_o[0]) + (down_o[1] - start_o[1])*(down_o[1] - start_o[1]); up_dist = (up[0] - start_o[0])*(up[0] - start_o[0]) + (up[1] - start_o[1])*(up[1] - start_o[1]); #endif if (down_dist > up_dist || trace.plane.normal[2] < MIN_STEP_NORMAL) { VectorCopy (down_o, pml.origin); VectorCopy (down_v, pml.velocity); return; } //!! Special case // if we were walking along a plane, then we need to copy the Z over pml.velocity[2] = down_v[2]; } /* ================== PM_Friction Handles both ground friction and water friction ================== */ void PM_Friction (void) { float *vel; float speed, newspeed, control; float friction; float drop; vel = pml.velocity; speed = sqrt(vel[0]*vel[0] +vel[1]*vel[1] + vel[2]*vel[2]); if (speed < 1) { vel[0] = 0; vel[1] = 0; return; } drop = 0; // apply ground friction if ((pm->groundentity && pml.groundsurface && !(pml.groundsurface->flags & SURF_SLICK) ) || (pml.ladder) ) { friction = pm_friction; control = speed < pm_stopspeed ? pm_stopspeed : speed; drop += control*friction*pml.frametime; } // apply water friction if (pm->waterlevel && !pml.ladder) drop += speed*pm_waterfriction*pm->waterlevel*pml.frametime; // scale the velocity newspeed = speed - drop; if (newspeed < 0) { newspeed = 0; } newspeed /= speed; vel[0] = vel[0] * newspeed; vel[1] = vel[1] * newspeed; vel[2] = vel[2] * newspeed; } /* ============== PM_Accelerate Handles user intended acceleration ============== */ void PM_Accelerate (vec3_t wishdir, float wishspeed, float accel) { int i; float addspeed, accelspeed, currentspeed; currentspeed = DotProduct (pml.velocity, wishdir); addspeed = wishspeed - currentspeed; if (addspeed <= 0) return; accelspeed = accel*pml.frametime*wishspeed; if (accelspeed > addspeed) accelspeed = addspeed; for (i=0 ; i<3 ; i++) pml.velocity[i] += accelspeed*wishdir[i]; } void PM_AirAccelerate (vec3_t wishdir, float wishspeed, float accel) { int i; float addspeed, accelspeed, currentspeed, wishspd = wishspeed; if (wishspd > 30) wishspd = 30; currentspeed = DotProduct (pml.velocity, wishdir); addspeed = wishspd - currentspeed; if (addspeed <= 0) return; accelspeed = accel * wishspeed * pml.frametime; if (accelspeed > addspeed) accelspeed = addspeed; for (i=0 ; i<3 ; i++) pml.velocity[i] += accelspeed*wishdir[i]; } /* ============= PM_AddCurrents ============= */ void PM_AddCurrents (vec3_t wishvel) { vec3_t v; float s; // // account for ladders // if (pml.ladder && fabs(pml.velocity[2]) <= 200) { if ((pm->viewangles[PITCH] <= -15) && (pm->cmd.forwardmove > 0)) wishvel[2] = 200; else if ((pm->viewangles[PITCH] >= 15) && (pm->cmd.forwardmove > 0)) wishvel[2] = -200; else if (pm->cmd.upmove > 0) wishvel[2] = 200; else if (pm->cmd.upmove < 0) wishvel[2] = -200; else wishvel[2] = 0; // limit horizontal speed when on a ladder if (wishvel[0] < -25) wishvel[0] = -25; else if (wishvel[0] > 25) wishvel[0] = 25; if (wishvel[1] < -25) wishvel[1] = -25; else if (wishvel[1] > 25) wishvel[1] = 25; } // // add water currents // if (pm->watertype & MASK_CURRENT) { VectorClear (v); if (pm->watertype & CONTENTS_CURRENT_0) v[0] += 1; if (pm->watertype & CONTENTS_CURRENT_90) v[1] += 1; if (pm->watertype & CONTENTS_CURRENT_180) v[0] -= 1; if (pm->watertype & CONTENTS_CURRENT_270) v[1] -= 1; if (pm->watertype & CONTENTS_CURRENT_UP) v[2] += 1; if (pm->watertype & CONTENTS_CURRENT_DOWN) v[2] -= 1; s = pm_waterspeed; if ((pm->waterlevel == 1) && (pm->groundentity)) s /= 2; VectorMA (wishvel, s, v, wishvel); } // // add conveyor belt velocities // if (pm->groundentity) { VectorClear (v); if (pml.groundcontents & CONTENTS_CURRENT_0) v[0] += 1; if (pml.groundcontents & CONTENTS_CURRENT_90) v[1] += 1; if (pml.groundcontents & CONTENTS_CURRENT_180) v[0] -= 1; if (pml.groundcontents & CONTENTS_CURRENT_270) v[1] -= 1; if (pml.groundcontents & CONTENTS_CURRENT_UP) v[2] += 1; if (pml.groundcontents & CONTENTS_CURRENT_DOWN) v[2] -= 1; VectorMA (wishvel, 100 /* pm->groundentity->speed */, v, wishvel); } } /* =================== PM_WaterMove =================== */ void PM_WaterMove (void) { int i; vec3_t wishvel; float wishspeed; vec3_t wishdir; if(sv_tactical->value) pm_maxspeed = 200; else if(sv_excessive->value) pm_maxspeed = 450; else pm_maxspeed = remoteserver_runspeed; // // user intentions // for (i=0 ; i<3 ; i++) wishvel[i] = pml.forward[i]*pm->cmd.forwardmove + pml.right[i]*pm->cmd.sidemove; if (!pm->cmd.forwardmove && !pm->cmd.sidemove && !pm->cmd.upmove) wishvel[2] -= 60; // drift towards bottom else wishvel[2] += pm->cmd.upmove; PM_AddCurrents (wishvel); VectorCopy (wishvel, wishdir); wishspeed = VectorNormalize(wishdir); if (wishspeed > pm_maxspeed) { VectorScale (wishvel, pm_maxspeed/wishspeed, wishvel); wishspeed = pm_maxspeed; } wishspeed *= 0.5; PM_Accelerate (wishdir, wishspeed, pm_wateraccelerate); PM_StepSlideMove (); } /* =================== PM_AirMove =================== */ void PM_AirMove (void) { int i; vec3_t wishvel; float fmove, smove; vec3_t wishdir; float wishspeed; float maxspeed; if(sv_tactical->value) pm_maxspeed = 200; else if(sv_excessive->value) pm_maxspeed = 450; else pm_maxspeed = remoteserver_runspeed; fmove = pm->cmd.forwardmove; smove = pm->cmd.sidemove; //!!!!! pitch should be 1/3 so this isn't needed??! #if 0 pml.forward[2] = 0; pml.right[2] = 0; VectorNormalize (pml.forward); VectorNormalize (pml.right); #endif for (i=0 ; i<2 ; i++) wishvel[i] = pml.forward[i]*fmove + pml.right[i]*smove; wishvel[2] = 0; PM_AddCurrents (wishvel); VectorCopy (wishvel, wishdir); wishspeed = VectorNormalize(wishdir); // // clamp to server defined max speed // maxspeed = (pm->s.pm_flags & PMF_DUCKED) ? pm_duckspeed : pm_maxspeed; if (wishspeed > maxspeed) { VectorScale (wishvel, maxspeed/wishspeed, wishvel); wishspeed = maxspeed; } if ( pml.ladder ) { PM_Accelerate (wishdir, wishspeed, pm_accelerate); if (!wishvel[2]) { if (pml.velocity[2] > 0) { pml.velocity[2] -= pm->s.gravity * pml.frametime; if (pml.velocity[2] < 0) pml.velocity[2] = 0; } else { pml.velocity[2] += pm->s.gravity * pml.frametime; if (pml.velocity[2] > 0) pml.velocity[2] = 0; } } PM_StepSlideMove (); } else if ( pm->groundentity ) { // walking on ground pml.velocity[2] = 0; //!!! this is before the accel PM_Accelerate (wishdir, wishspeed, pm_accelerate); // PGM -- fix for negative trigger_gravity fields // pml.velocity[2] = 0; if(pm->s.gravity > 0) pml.velocity[2] = 0; else pml.velocity[2] -= pm->s.gravity * pml.frametime; // PGM if (!pml.velocity[0] && !pml.velocity[1]) return; PM_StepSlideMove (); } else { // not on ground, so little effect on velocity if (pm_airaccelerate) PM_AirAccelerate (wishdir, wishspeed, pm_accelerate); else PM_Accelerate (wishdir, wishspeed, 1); // add gravity pml.velocity[2] -= pm->s.gravity * pml.frametime; PM_StepSlideMove (); } } /* ============= PM_CatagorizePosition ============= */ void PM_CatagorizePosition (void) { vec3_t point; int cont; trace_t trace; int sample1; int sample2; // if the player hull point one unit down is solid, the player // is on ground // see if standing on something solid point[0] = pml.origin[0]; point[1] = pml.origin[1]; point[2] = pml.origin[2] - 0.15; //Irritant - changed from 0.25 - this seems to fix the issue //in which sometimes while strafejumping it seemed the jump //was getting "lost" if (pml.velocity[2] > 180) //!!ZOID changed from 100 to 180 (ramp accel) { pm->s.pm_flags &= ~PMF_ON_GROUND; pm->groundentity = NULL; } else { trace = pm->trace (pml.origin, pm->mins, pm->maxs, point); pml.groundplane = trace.plane; pml.groundsurface = trace.surface; pml.groundcontents = trace.contents; if (!trace.ent || (trace.plane.normal[2] < 0.7 && !trace.startsolid) ) { pm->groundentity = NULL; pm->s.pm_flags &= ~PMF_ON_GROUND; } else { pm->groundentity = trace.ent; // hitting solid ground will end a waterjump if (pm->s.pm_flags & PMF_TIME_WATERJUMP) { pm->s.pm_flags &= ~(PMF_TIME_WATERJUMP | PMF_TIME_LAND | PMF_TIME_TELEPORT); pm->s.pm_time = 0; } if (! (pm->s.pm_flags & PMF_ON_GROUND) ) { // just hit the ground pm->s.pm_flags |= PMF_ON_GROUND; // don't do landing time if we were just going down a slope if (pml.velocity[2] < -200) { pm->s.pm_flags |= PMF_TIME_LAND; // don't allow another jump for a little while if (pml.velocity[2] < -400) pm->s.pm_time = 25; else pm->s.pm_time = 18; } } } #if 0 if (trace.fraction < 1.0 && trace.ent && pml.velocity[2] < 0) pml.velocity[2] = 0; #endif if (pm->numtouch < MAXTOUCH && trace.ent) { pm->touchents[pm->numtouch] = trace.ent; pm->numtouch++; } } // // get waterlevel, accounting for ducking // pm->waterlevel = 0; pm->watertype = 0; sample2 = pm->viewheight - pm->mins[2]; sample1 = sample2 / 2; point[2] = pml.origin[2] + pm->mins[2] + 1; cont = pm->pointcontents (point); if (cont & MASK_WATER) { pm->watertype = cont; pm->waterlevel = 1; point[2] = pml.origin[2] + pm->mins[2] + sample1; cont = pm->pointcontents (point); if (cont & MASK_WATER) { pm->waterlevel = 2; point[2] = pml.origin[2] + pm->mins[2] + sample2; cont = pm->pointcontents (point); if (cont & MASK_WATER) pm->waterlevel = 3; } } } /* ============= PM_CheckJump ============= */ void PM_CheckJump (void) { qboolean jousting = false; if(sv_joustmode->value) jousting = true; if (remoteserver_jousting) jousting = true; // if (pm->s.pm_flags & PMF_TIME_LAND) // { // hasn't been long enough since landing to jump again // return; // } if (pm->cmd.upmove < 10) { // not holding jump pm->s.pm_flags &= ~PMF_JUMP_HELD; return; } // must wait for jump to be released if (pm->s.pm_flags & PMF_JUMP_HELD) return; if (pm->s.pm_type == PM_DEAD) return; if (pm->waterlevel >= 2) { // swimming, not jumping pm->groundentity = NULL; if (pml.velocity[2] <= -300) return; if (pm->watertype == CONTENTS_WATER) pml.velocity[2] = 100; else if (pm->watertype == CONTENTS_SLIME) pml.velocity[2] = 80; else pml.velocity[2] = 50; return; } if (pm->groundentity == NULL && !jousting) return; // in air, so no effect //joust mode if(pm->joustattempts > 30 && jousting) { return; } pm->s.pm_flags |= PMF_JUMP_HELD; pm->groundentity = NULL; pml.velocity[2] += 270; if (pml.velocity[2] < 270) pml.velocity[2] = 270; } /* ============= PM_CheckSpecialMovement ============= */ void PM_CheckSpecialMovement (void) { vec3_t spot; int cont; vec3_t flatforward; trace_t trace; if (pm->s.pm_time) return; pml.ladder = false; // check for ladder flatforward[0] = pml.forward[0]; flatforward[1] = pml.forward[1]; flatforward[2] = 0; VectorNormalize (flatforward); VectorMA (pml.origin, 1, flatforward, spot); trace = pm->trace (pml.origin, pm->mins, pm->maxs, spot); if ((trace.fraction < 1) && (trace.contents & CONTENTS_LADDER)) pml.ladder = true; // check for water jump if (pm->waterlevel != 2) return; VectorMA (pml.origin, 30, flatforward, spot); spot[2] += 4; cont = pm->pointcontents (spot); if (!(cont & CONTENTS_SOLID)) return; spot[2] += 16; cont = pm->pointcontents (spot); if (cont) return; // jump out of water VectorScale (flatforward, 50, pml.velocity); pml.velocity[2] = 350; pm->s.pm_flags |= PMF_TIME_WATERJUMP; pm->s.pm_time = 255; } /* =============== PM_FlyMove =============== */ void PM_FlyMove (qboolean doclip) { float speed, drop, friction, control, newspeed; float currentspeed, addspeed, accelspeed; int i; vec3_t wishvel; float fmove, smove; vec3_t wishdir; float wishspeed; vec3_t end; trace_t trace; if(sv_tactical->value) pm_maxspeed = 200; else if(sv_excessive->value) pm_maxspeed = 450; else pm_maxspeed = remoteserver_runspeed; pm->viewheight = 22; // friction speed = VectorLength (pml.velocity); if (speed < 1) { VectorCopy (vec3_origin, pml.velocity); } else { drop = 0; friction = pm_friction*1.5; // extra friction control = speed < pm_stopspeed ? pm_stopspeed : speed; drop += control*friction*pml.frametime; // scale the velocity newspeed = speed - drop; if (newspeed < 0) newspeed = 0; newspeed /= speed; VectorScale (pml.velocity, newspeed, pml.velocity); } // accelerate fmove = pm->cmd.forwardmove; smove = pm->cmd.sidemove; VectorNormalize (pml.forward); VectorNormalize (pml.right); for (i=0 ; i<3 ; i++) wishvel[i] = pml.forward[i]*fmove + pml.right[i]*smove; wishvel[2] += pm->cmd.upmove; VectorCopy (wishvel, wishdir); wishspeed = VectorNormalize(wishdir); // // clamp to server defined max speed // if (wishspeed > pm_maxspeed) { VectorScale (wishvel, pm_maxspeed/wishspeed, wishvel); wishspeed = pm_maxspeed; } currentspeed = DotProduct(pml.velocity, wishdir); addspeed = wishspeed - currentspeed; if (addspeed <= 0) return; accelspeed = pm_accelerate*pml.frametime*wishspeed; if (accelspeed > addspeed) accelspeed = addspeed; for (i=0 ; i<3 ; i++) pml.velocity[i] += accelspeed*wishdir[i]; if (doclip) { for (i=0 ; i<3 ; i++) end[i] = pml.origin[i] + pml.frametime * pml.velocity[i]; trace = pm->trace (pml.origin, pm->mins, pm->maxs, end); VectorCopy (trace.endpos, pml.origin); } else { // move VectorMA (pml.origin, pml.frametime, pml.velocity, pml.origin); } } /* ============== PM_CheckDuck Sets mins, maxs, and pm->viewheight ============== */ void PM_CheckDuck (void) { trace_t trace; pm->mins[0] = -16; pm->mins[1] = -16; pm->maxs[0] = 16; pm->maxs[1] = 16; if (pm->s.pm_type == PM_GIB) { pm->mins[2] = 0; pm->maxs[2] = 16; pm->viewheight = 8; return; } pm->mins[2] = -24; if (pm->s.pm_type == PM_DEAD) { pm->s.pm_flags |= PMF_DUCKED; } else if (pm->cmd.upmove < 0 && (pm->s.pm_flags & PMF_ON_GROUND) ) { // duck pm->s.pm_flags |= PMF_DUCKED; } else { // stand up if possible if (pm->s.pm_flags & PMF_DUCKED) { // try to stand up pm->maxs[2] = 32; trace = pm->trace (pml.origin, pm->mins, pm->maxs, pml.origin); if (!trace.allsolid) pm->s.pm_flags &= ~PMF_DUCKED; } } if (pm->s.pm_flags & PMF_DUCKED) { pm->maxs[2] = 20; pm->viewheight = -2; } else { pm->maxs[2] = 32; pm->viewheight = 22; } } /* ============== PM_DeadMove ============== */ void PM_DeadMove (void) { float forward; if (!pm->groundentity) return; // extra friction forward = VectorLength (pml.velocity); forward -= 20; if (forward <= 0) { VectorClear (pml.velocity); } else { VectorNormalize (pml.velocity); VectorScale (pml.velocity, forward, pml.velocity); } } qboolean PM_GoodPosition (void) { trace_t trace; vec3_t origin, end; int i; if (pm->s.pm_type == PM_SPECTATOR) return true; for (i=0 ; i<3 ; i++) origin[i] = end[i] = pm->s.origin[i]*0.125; trace = pm->trace (origin, pm->mins, pm->maxs, end); return !trace.allsolid; } /* ================ PM_SnapPosition On exit, the origin will have a value that is pre-quantized to the 0.125 precision of the network channel and in a valid position. ================ */ void PM_SnapPosition (void) { int sign[3]; int i, j, bits; int base[3]; // try all single bits first static int jitterbits[8] = {0,4,1,2,3,5,6,7}; // snap velocity to eigths for (i=0 ; i<3 ; i++) pm->s.velocity[i] = (int)(pml.velocity[i]*8); for (i=0 ; i<3 ; i++) { if (pml.origin[i] >= 0) sign[i] = 1; else sign[i] = -1; pm->s.origin[i] = (int)(pml.origin[i]*8); if (pm->s.origin[i]*0.125 == pml.origin[i]) sign[i] = 0; } VectorCopy (pm->s.origin, base); // try all combinations for (j=0 ; j<8 ; j++) { bits = jitterbits[j]; VectorCopy (base, pm->s.origin); for (i=0 ; i<3 ; i++) if (bits & (1<s.origin[i] += sign[i]; if (PM_GoodPosition ()) return; } // go back to the last position VectorCopy (pml.previous_origin, pm->s.origin); // Com_DPrintf ("using previous_origin\n"); } #if 0 //NO LONGER USED /* ================ PM_InitialSnapPosition ================ */ void PM_InitialSnapPosition (void) { int x, y, z; short base[3]; VectorCopy (pm->s.origin, base); for (z=1 ; z>=-1 ; z--) { pm->s.origin[2] = base[2] + z; for (y=1 ; y>=-1 ; y--) { pm->s.origin[1] = base[1] + y; for (x=1 ; x>=-1 ; x--) { pm->s.origin[0] = base[0] + x; if (PM_GoodPosition ()) { pml.origin[0] = pm->s.origin[0]*0.125; pml.origin[1] = pm->s.origin[1]*0.125; pml.origin[2] = pm->s.origin[2]*0.125; VectorCopy (pm->s.origin, pml.previous_origin); return; } } } } Com_DPrintf ("Bad InitialSnapPosition\n"); } #else /* ================ PM_InitialSnapPosition ================ */ void PM_InitialSnapPosition(void) { int x, y, z; int base[3]; static int offset[3] = { 0, -1, 1 }; VectorCopy (pm->s.origin, base); for ( z = 0; z < 3; z++ ) { pm->s.origin[2] = base[2] + offset[ z ]; for ( y = 0; y < 3; y++ ) { pm->s.origin[1] = base[1] + offset[ y ]; for ( x = 0; x < 3; x++ ) { pm->s.origin[0] = base[0] + offset[ x ]; if (PM_GoodPosition ()) { pml.origin[0] = pm->s.origin[0]*0.125; pml.origin[1] = pm->s.origin[1]*0.125; pml.origin[2] = pm->s.origin[2]*0.125; VectorCopy (pm->s.origin, pml.previous_origin); return; } } } } Com_DPrintf ("Bad InitialSnapPosition\n"); } #endif /* ================ PM_ClampAngles ================ */ void PM_ClampAngles (void) { short temp; int i; if (pm->s.pm_flags & PMF_TIME_TELEPORT) { pm->viewangles[YAW] = SHORT2ANGLE(pm->cmd.angles[YAW] + pm->s.delta_angles[YAW]); pm->viewangles[PITCH] = 0; pm->viewangles[ROLL] = 0; } else { // circularly clamp the angles with deltas for (i=0 ; i<3 ; i++) { temp = pm->cmd.angles[i] + pm->s.delta_angles[i]; pm->viewangles[i] = SHORT2ANGLE(temp); } // don't let the player look up or down more than 90 degrees if (pm->viewangles[PITCH] > 89 && pm->viewangles[PITCH] < 180) pm->viewangles[PITCH] = 89; else if (pm->viewangles[PITCH] < 271 && pm->viewangles[PITCH] >= 180) pm->viewangles[PITCH] = 271; } AngleVectors (pm->viewangles, pml.forward, pml.right, pml.up); } /* ================ Pmove Can be called by either the server or the client ================ */ void Pmove (pmove_t *pmove) { pm = pmove; // clear results pm->numtouch = 0; VectorClear (pm->viewangles); pm->viewheight = 0; pm->groundentity = 0; pm->watertype = 0; pm->waterlevel = 0; // clear all pmove local vars memset (&pml, 0, sizeof(pml)); // convert origin and velocity to float values pml.origin[0] = pm->s.origin[0]*0.125f; pml.origin[1] = pm->s.origin[1]*0.125f; pml.origin[2] = pm->s.origin[2]*0.125f; pml.velocity[0] = pm->s.velocity[0]*0.125f; pml.velocity[1] = pm->s.velocity[1]*0.125f; pml.velocity[2] = pm->s.velocity[2]*0.125f; // save old org in case we get stuck VectorCopy (pm->s.origin, pml.previous_origin); pml.frametime = pm->cmd.msec * 0.001f; PM_ClampAngles (); if (pm->s.pm_type == PM_SPECTATOR) { PM_FlyMove (false); PM_SnapPosition (); return; } if (pm->s.pm_type >= PM_DEAD) { pm->cmd.forwardmove = 0; pm->cmd.sidemove = 0; pm->cmd.upmove = 0; } if (pm->s.pm_type == PM_FREEZE) return; // no movement at all // set mins, maxs, and viewheight PM_CheckDuck (); if (pm->snapinitial) PM_InitialSnapPosition (); // set groundentity, watertype, and waterlevel PM_CatagorizePosition (); if (pm->s.pm_type == PM_DEAD) PM_DeadMove (); PM_CheckSpecialMovement (); // drop timing counter if (pm->s.pm_time) { int msec; msec = pm->cmd.msec >> 3; if (!msec) msec = 1; if ( msec >= pm->s.pm_time) { pm->s.pm_flags &= ~(PMF_TIME_WATERJUMP | PMF_TIME_LAND | PMF_TIME_TELEPORT); pm->s.pm_time = 0; } else pm->s.pm_time -= msec; } if (pm->s.pm_flags & PMF_TIME_TELEPORT) { // teleport pause stays exactly in place } else if (pm->s.pm_flags & PMF_TIME_WATERJUMP) { // waterjump has no control, but falls pml.velocity[2] -= pm->s.gravity * pml.frametime; if (pml.velocity[2] < 0) { // cancel as soon as we are falling down again pm->s.pm_flags &= ~(PMF_TIME_WATERJUMP | PMF_TIME_LAND | PMF_TIME_TELEPORT); pm->s.pm_time = 0; } PM_StepSlideMove (); } else { PM_CheckJump (); PM_Friction (); if (pm->waterlevel >= 2) PM_WaterMove (); else { vec3_t angles; VectorCopy(pm->viewangles, angles); if (angles[PITCH] > 180) angles[PITCH] = angles[PITCH] - 360; angles[PITCH] /= 3; AngleVectors (angles, pml.forward, pml.right, pml.up); PM_AirMove (); } } // set groundentity, watertype, and waterlevel for final spot PM_CatagorizePosition (); PM_SnapPosition (); } alien-arena-7.66+dfsg/source/qcommon/common.c0000600000175000017500000012675012161402010020222 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // common.c -- misc functions used in client and server #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "qcommon.h" #include //zlib currently not needed server-side (FOR NOW!) //Also, due to the ld flags for zlib not being used server side, it won't //compile without this workaround. #ifdef DEDICATED_ONLY #undef HAVE_ZLIB #endif #ifdef HAVE_ZLIB #include #endif #define MAXPRINTMSG 8192 #define MAX_NUM_ARGVS 50 #ifndef DEDICATED_ONLY extern void S_StartMenuMusic( void ); #endif extern void CL_Disconnect(void); int com_argc; char *com_argv[MAX_NUM_ARGVS+1]; int realtime; jmp_buf abortframe; // an ERR_DROP occured, exit the entire frame FILE *log_stats_file; cvar_t *host_speeds; cvar_t *log_stats; cvar_t *developer; cvar_t *timescale; cvar_t *fixedtime; cvar_t *logfile_active; // 1 = buffer log, 2 = flush after each print cvar_t *logfile_name; cvar_t *showtrace; cvar_t *dedicated; FILE *logfile; int server_state; // host_speeds times int time_before_game; int time_after_game; int time_before_ref; int time_after_ref; /* ============================================================================ CLIENT / SERVER interactions ============================================================================ */ static int rd_target; static char *rd_buffer; static int rd_buffersize; static void (*rd_flush)(int target, char *buffer); void Com_BeginRedirect (int target, char *buffer, int buffersize, void (*flush)) { if (!target || !buffer || !buffersize || !flush) return; rd_target = target; rd_buffer = buffer; rd_buffersize = buffersize; rd_flush = flush; *rd_buffer = 0; } void Com_EndRedirect (void) { rd_flush(rd_target, rd_buffer); rd_target = 0; rd_buffer = NULL; rd_buffersize = 0; rd_flush = NULL; } /* ============= Com_Printf Both client and server can use this, and it will output to the apropriate place. ============= */ void Com_Printf (char *fmt, ...) { va_list argptr; char msg[MAXPRINTMSG]; va_start (argptr,fmt); vsnprintf(msg, sizeof(msg), fmt, argptr); va_end (argptr); if (rd_target) { if ((strlen (msg) + strlen(rd_buffer)) > (rd_buffersize - 1)) { rd_flush(rd_target, rd_buffer); *rd_buffer = 0; } strcat (rd_buffer, msg); return; } CON_Print( msg ); // also echo to debugging console Sys_ConsoleOutput (msg); #if defined WIN32_VARIANT // Also echo to dedicated console Sys_Print(msg); #endif // if logfile_active or logfile_name have been modified, close the current log file if ( ( (logfile_active && logfile_active->modified) || (logfile_name && logfile_name->modified) ) && logfile ) { fclose (logfile); logfile = NULL; if (logfile_active) { logfile_active->modified = false; } if (logfile_name) { logfile_name->modified = false; } } // logfile if (logfile_active && logfile_active->value) { char name[MAX_OSPATH]; const char *f_name; if (!logfile) { f_name = logfile_name ? logfile_name->string : "qconsole.log"; Com_sprintf (name, sizeof(name), "%s/%s", FS_Gamedir (), f_name); if (logfile_active->value > 2) logfile = fopen (name, "a"); else logfile = fopen (name, "w"); } if (logfile) { fprintf (logfile, "%s", msg); if (logfile_active->value > 1) fflush (logfile); // force it to save every time } } } /* ================ Com_DPrintf A Com_Printf that only shows up if the "developer" cvar is set ================ */ void Com_DPrintf (char *fmt, ...) { va_list argptr; char msg[MAXPRINTMSG]; if (!developer || !developer->value) return; // don't confuse non-developers with techie stuff... va_start (argptr,fmt); vsnprintf(msg, sizeof(msg), fmt, argptr); va_end (argptr); Com_Printf ("%s", msg); } /* ============= Com_Error Both client and server can use this, and it will do the apropriate things. ============= */ void Com_Error (int code, char *fmt, ...) { va_list argptr; static char msg[MAXPRINTMSG]; static qboolean recursive = false; if (recursive) Sys_Error ("recursive error after: %s", msg); recursive = true; va_start (argptr,fmt); vsnprintf(msg, sizeof(msg), fmt, argptr); va_end (argptr); if (code == ERR_DISCONNECT) { CL_Drop (); recursive = false; longjmp (abortframe, -1); } else if (code == ERR_DROP) { Com_Printf ("********************\nERROR: %s\n********************\n", msg); SV_Shutdown (va("Server crashed: %s\n", msg), false); CL_Drop (); recursive = false; longjmp (abortframe, -1); } else { SV_Shutdown (va("Server fatal crashed: %s\n", msg), false); CL_Shutdown (); } if (logfile) { fclose (logfile); logfile = NULL; } Sys_Error ("%s", msg); } /* ============= Com_Quit Both client and server can use this, and it will do the apropriate things. ============= */ void Com_Quit (void) { SV_Shutdown ("Server quit\n", false); CL_Shutdown (); if (logfile) { fclose (logfile); logfile = NULL; } Sys_Quit (); } /* ================== Com_ServerState ================== */ int Com_ServerState (void) { return server_state; } /* ================== Com_SetServerState ================== */ void Com_SetServerState (int state) { server_state = state; } /* ============================================================================== MESSAGE IO FUNCTIONS Handles byte ordering and avoids alignment errors ============================================================================== */ vec3_t bytedirs[NUMVERTEXNORMALS] = { #include "../client/anorms.h" }; // // writing functions // void MSG_WriteChar (sizebuf_t *sb, int c) { byte *buf; #ifdef PARANOID if (c < -128 || c > 127) { // Com_Printf( "MSG_WriteChar: range error: %i\n", c); Com_Error (ERR_FATAL, "MSG_WriteChar: range error"); } #endif buf = SZ_GetSpace (sb, 1); buf[0] = c; } void MSG_WriteByte (sizebuf_t *sb, int c) { byte *buf; #ifdef PARANOID if (c < 0 || c > 255) { //Com_Printf( "MSG_WriteByte: range error: %i\n", c ); Com_Error (ERR_FATAL, "MSG_WriteByte: range error"); } #endif buf = SZ_GetSpace (sb, 1); buf[0] = c; } void MSG_WriteShort (sizebuf_t *sb, int c) { #if 0 /* Original Version */ byte *buf; #ifdef PARANOID if ( c > 65535 ) { // unsigned short actually //Com_Printf("MSG_WriteShort: range error: %i \n", c); Com_Error (ERR_FATAL, "MSG_WriteShort: range error"); } #endif buf = SZ_GetSpace (sb, 2); buf[0] = c&0xff; buf[1] = c>>8; #else /* Experimental Version */ short *buf; buf = (short*)SZ_GetSpace( sb , 2 ); *buf = LittleShort( c ); #endif } void MSG_WriteLong (sizebuf_t *sb, int c) { #if 0 /* Original Version */ byte *buf; buf = SZ_GetSpace (sb, 4); buf[0] = c&0xff; buf[1] = (c>>8)&0xff; buf[2] = (c>>16)&0xff; buf[3] = c>>24; #else /* Experimental Version */ int *buf; buf = (int*)SZ_GetSpace( sb, 4 ); *buf = LittleLong( c ); #endif } void MSG_WriteSizeInt (sizebuf_t *sb, int bytes, int c) { byte *buf; int i; // manually construct two's complement encoding with appropriate bit depth if (c < 0 && bytes != sizeof(c)) c += 1<<(8*bytes); buf = SZ_GetSpace (sb, bytes); for (i = 0; i < bytes; i++) buf[i] = (byte)((c>>(8*i))&0xff); } void MSG_WriteFloat (sizebuf_t *sb, float f) { union { float f; int l; } dat; dat.f = f; dat.l = LittleLong (dat.l); SZ_Write (sb, &dat.l, 4); } void MSG_WriteString (sizebuf_t *sb, char *s) { if (!s) SZ_Write (sb, "", 1); else SZ_Write (sb, s, strlen(s)+1); } void MSG_WriteCoord (sizebuf_t *sb, float f) { MSG_WriteSizeInt (sb, coord_bytes, (int)(f*8)); } void MSG_WritePos (sizebuf_t *sb, vec3_t pos) { MSG_WriteSizeInt (sb, coord_bytes, (int)(pos[0]*8)); MSG_WriteSizeInt (sb, coord_bytes, (int)(pos[1]*8)); MSG_WriteSizeInt (sb, coord_bytes, (int)(pos[2]*8)); } void MSG_WriteAngle (sizebuf_t *sb, float f) { MSG_WriteByte (sb, (int)(f*256/360) & 255); } void MSG_WriteAngle16 (sizebuf_t *sb, float f) { MSG_WriteShort (sb, ANGLE2SHORT(f)); } void MSG_WriteDeltaUsercmd (sizebuf_t *buf, usercmd_t *from, usercmd_t *cmd) { int bits; // // send the movement message // bits = 0; if (cmd->angles[0] != from->angles[0]) bits |= CM_ANGLE1; if (cmd->angles[1] != from->angles[1]) bits |= CM_ANGLE2; if (cmd->angles[2] != from->angles[2]) bits |= CM_ANGLE3; if (cmd->forwardmove != from->forwardmove) bits |= CM_FORWARD; if (cmd->sidemove != from->sidemove) bits |= CM_SIDE; if (cmd->upmove != from->upmove) bits |= CM_UP; if (cmd->buttons != from->buttons) bits |= CM_BUTTONS; if (cmd->impulse != from->impulse) bits |= CM_IMPULSE; MSG_WriteByte (buf, bits); if (bits & CM_ANGLE1) MSG_WriteShort (buf, cmd->angles[0]); if (bits & CM_ANGLE2) MSG_WriteShort (buf, cmd->angles[1]); if (bits & CM_ANGLE3) MSG_WriteShort (buf, cmd->angles[2]); if (bits & CM_FORWARD) MSG_WriteShort (buf, cmd->forwardmove); if (bits & CM_SIDE) MSG_WriteShort (buf, cmd->sidemove); if (bits & CM_UP) MSG_WriteShort (buf, cmd->upmove); if (bits & CM_BUTTONS) MSG_WriteByte (buf, cmd->buttons); if (bits & CM_IMPULSE) MSG_WriteByte (buf, cmd->impulse); MSG_WriteByte (buf, cmd->msec); MSG_WriteByte (buf, cmd->lightlevel); } void MSG_WriteDir (sizebuf_t *sb, vec3_t dir) { int i, best; float d,x,y,z; if (!dir) { MSG_WriteByte (sb, 0); return; } x = dir[0]; y = dir[1]; z = dir[2]; best = 0; d = (x*x) + (y*y) + (z*z); // sometimes dir is {0,0,0} if ( d == 0.0f ) { MSG_WriteByte( sb, 0 ); return; } // sometimes dir is not normalized if ( d < 0.999f || d > 1.001f ) { d = 1.0 / sqrt( d ); x *= d; y *= d; z *= d; } // frequently occurring axial cases, use known best index if ( x == 0.0f && y == 0.0f ) { best = ( z >= 0.999f ) ? 5 : 84; } else if ( x == 0.0f && z == 0.0f ) { best = ( y >= 0.999f ) ? 32 : 104; } else if ( y == 0.0f && z == 0.0f ) { best = ( x >= 0.999f ) ? 52 : 143; } else { // general case float bestd = 0.0f; for ( i = 0 ; i < NUMVERTEXNORMALS ; i++ ) { // search for closest match d = (x*bytedirs[i][0]) + (y*bytedirs[i][1]) + (z*bytedirs[i][2]); if ( d > 0.998f ) { // no other entry could be a closer match // 0.9679495 is max dot product between anorm.h entries best = i; break; } if ( d > bestd ) { bestd = d; best = i; } } } MSG_WriteByte (sb, best); } void MSG_ReadDir (sizebuf_t *sb, vec3_t dir) { int b; b = MSG_ReadByte (sb); if (b >= NUMVERTEXNORMALS) Com_Error (ERR_DROP, "MSG_ReadDir: out of range"); VectorCopy (bytedirs[b], dir); } /* ================== MSG_WriteDeltaEntity Writes part of a packetentities message. Can delta from either a baseline or a previous packet_entity ================== */ void MSG_WriteDeltaEntity (entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qboolean force, qboolean newentity) { int bits; if (!to->number) Com_Error (ERR_FATAL, "Unset entity number"); if (to->number >= MAX_EDICTS) Com_Error (ERR_FATAL, "Entity number >= MAX_EDICTS"); // send an update bits = 0; if (to->number >= 256) bits |= U_NUMBER16; // number8 is implicit otherwise if (to->origin[0] != from->origin[0]) bits |= U_ORIGIN1; if (to->origin[1] != from->origin[1]) bits |= U_ORIGIN2; if (to->origin[2] != from->origin[2]) bits |= U_ORIGIN3; if ( to->angles[0] != from->angles[0] ) bits |= U_ANGLE1; if ( to->angles[1] != from->angles[1] ) bits |= U_ANGLE2; if ( to->angles[2] != from->angles[2] ) bits |= U_ANGLE3; if ( to->skinnum != from->skinnum ) { if ((unsigned)to->skinnum < 256) bits |= U_SKIN8; else if ((unsigned)to->skinnum < 0x10000) bits |= U_SKIN16; else bits |= (U_SKIN8|U_SKIN16); } if ( to->frame != from->frame ) { if (to->frame < 256) bits |= U_FRAME8; else bits |= U_FRAME16; } if ( to->effects != from->effects ) { if (to->effects < 256) bits |= U_EFFECTS8; else if (to->effects < 0x8000) bits |= U_EFFECTS16; else bits |= U_EFFECTS8|U_EFFECTS16; } if ( to->renderfx != from->renderfx ) { if (to->renderfx < 256) bits |= U_RENDERFX8; else if (to->renderfx < 0x8000) bits |= U_RENDERFX16; else bits |= U_RENDERFX8|U_RENDERFX16; } if ( to->solid != from->solid ) bits |= U_SOLID; // event is not delta compressed, just 0 compressed if ( to->event ) bits |= U_EVENT; if ( to->modelindex != from->modelindex ) bits |= U_MODEL; if ( to->modelindex2 != from->modelindex2 ) bits |= U_MODEL2; if ( to->modelindex3 != from->modelindex3 ) bits |= U_MODEL3; if ( to->modelindex4 != from->modelindex4 ) bits |= U_MODEL4; if ( to->sound != from->sound ) bits |= U_SOUND; if (newentity || (to->renderfx & RF_BEAM)) bits |= U_OLDORIGIN; // // write the message // if (!bits && !force) return; // nothing to send! //---------- if (bits & 0xff000000) bits |= U_MOREBITS3 | U_MOREBITS2 | U_MOREBITS1; else if (bits & 0x00ff0000) bits |= U_MOREBITS2 | U_MOREBITS1; else if (bits & 0x0000ff00) bits |= U_MOREBITS1; MSG_WriteByte (msg, bits&255 ); if (bits & 0xff000000) { MSG_WriteByte (msg, (bits>>8)&255 ); MSG_WriteByte (msg, (bits>>16)&255 ); MSG_WriteByte (msg, (bits>>24)&255 ); } else if (bits & 0x00ff0000) { MSG_WriteByte (msg, (bits>>8)&255 ); MSG_WriteByte (msg, (bits>>16)&255 ); } else if (bits & 0x0000ff00) { MSG_WriteByte (msg, (bits>>8)&255 ); } //---------- if (bits & U_NUMBER16) MSG_WriteShort (msg, to->number); else MSG_WriteByte (msg, to->number); if (bits & U_MODEL) MSG_WriteByte (msg, to->modelindex); if (bits & U_MODEL2) MSG_WriteByte (msg, to->modelindex2); if (bits & U_MODEL3) MSG_WriteByte (msg, to->modelindex3); if (bits & U_MODEL4) MSG_WriteByte (msg, to->modelindex4); if (bits & U_FRAME8) MSG_WriteByte (msg, to->frame); if (bits & U_FRAME16) MSG_WriteShort (msg, to->frame); if ((bits & U_SKIN8) && (bits & U_SKIN16)) //used for laser colors MSG_WriteLong (msg, to->skinnum); else if (bits & U_SKIN8) MSG_WriteByte (msg, to->skinnum); else if (bits & U_SKIN16) MSG_WriteShort (msg, to->skinnum); if ( (bits & (U_EFFECTS8|U_EFFECTS16)) == (U_EFFECTS8|U_EFFECTS16) ) MSG_WriteLong (msg, to->effects); else if (bits & U_EFFECTS8) MSG_WriteByte (msg, to->effects); else if (bits & U_EFFECTS16) MSG_WriteShort (msg, to->effects); if ( (bits & (U_RENDERFX8|U_RENDERFX16)) == (U_RENDERFX8|U_RENDERFX16) ) MSG_WriteLong (msg, to->renderfx); else if (bits & U_RENDERFX8) MSG_WriteByte (msg, to->renderfx); else if (bits & U_RENDERFX16) MSG_WriteShort (msg, to->renderfx); if (bits & U_ORIGIN1) MSG_WriteCoord (msg, to->origin[0]); if (bits & U_ORIGIN2) MSG_WriteCoord (msg, to->origin[1]); if (bits & U_ORIGIN3) MSG_WriteCoord (msg, to->origin[2]); if (bits & U_ANGLE1) MSG_WriteAngle(msg, to->angles[0]); if (bits & U_ANGLE2) MSG_WriteAngle(msg, to->angles[1]); if (bits & U_ANGLE3) MSG_WriteAngle(msg, to->angles[2]); if (bits & U_OLDORIGIN) { MSG_WriteCoord (msg, to->old_origin[0]); MSG_WriteCoord (msg, to->old_origin[1]); MSG_WriteCoord (msg, to->old_origin[2]); } if (bits & U_SOUND) MSG_WriteByte (msg, to->sound); if (bits & U_EVENT) MSG_WriteByte (msg, to->event); if (bits & U_SOLID) MSG_WriteShort (msg, to->solid); } //============================================================ // // reading functions // void MSG_BeginReading (sizebuf_t *msg) { msg->readcount = 0; } // returns -1 if no more characters are available int MSG_ReadChar (sizebuf_t *msg_read) { int c; if (msg_read->readcount+1 > msg_read->cursize) c = -1; else c = (signed char)msg_read->data[msg_read->readcount]; msg_read->readcount++; return c; } int MSG_ReadByte (sizebuf_t *msg_read) { int c; if (msg_read->readcount+1 > msg_read->cursize) c = -1; else c = (unsigned char)msg_read->data[msg_read->readcount]; msg_read->readcount++; return c; } int MSG_ReadShort (sizebuf_t *msg_read) { #if 0 /* Origninal Version */ int c; if (msg_read->readcount+2 > msg_read->cursize) c = -1; else c = (short)(msg_read->data[msg_read->readcount] + (msg_read->data[msg_read->readcount+1]<<8)); msg_read->readcount += 2; return c; #else /* Experimental Version */ int c = -1; int rc = msg_read->readcount; short *pi = (short*)(&msg_read->data[ rc ]); rc += 2; if ( rc <= msg_read->cursize ) { c = LittleShort( *pi ); msg_read->readcount = rc; } return c; #endif } int MSG_ReadLong (sizebuf_t *msg_read) { #if 0 /* Original Version */ int c; if (msg_read->readcount+4 > msg_read->cursize) c = -1; else c = msg_read->data[msg_read->readcount] + (msg_read->data[msg_read->readcount+1]<<8) + (msg_read->data[msg_read->readcount+2]<<16) + (msg_read->data[msg_read->readcount+3]<<24); msg_read->readcount += 4; return c; #else /* Experimental Version */ int c = -1; int rc = msg_read->readcount; int *pi = (int*)(&msg_read->data[rc]); rc += 4; if ( rc <= msg_read->cursize ) { c = LittleLong( *pi ); msg_read->readcount = rc; } return c; #endif } int MSG_ReadSizeInt (sizebuf_t *msg_read, int bytes) { int c, i; if (msg_read->readcount+bytes > msg_read->cursize) c = -1; else { c = 0; for (i = 0; i < bytes; i++) c += msg_read->data[msg_read->readcount++] << (8*i); // check sign bit and sign-extend to 32 bits if needed if (bytes != sizeof(c) && (c & 1<<(8*bytes-1))) for (; i < sizeof(c); i++) c += 0xff<<(8*i); } return c; } float MSG_ReadFloat (sizebuf_t *msg_read) { union { byte b[4]; float f; int l; } dat; if (msg_read->readcount+4 > msg_read->cursize) dat.f = -1; else { dat.b[0] = msg_read->data[msg_read->readcount]; dat.b[1] = msg_read->data[msg_read->readcount+1]; dat.b[2] = msg_read->data[msg_read->readcount+2]; dat.b[3] = msg_read->data[msg_read->readcount+3]; } msg_read->readcount += 4; dat.l = LittleLong (dat.l); return dat.f; } char *MSG_ReadString (sizebuf_t *msg_read) { static char string[2048]; int l,c; l = 0; do { // sku - replaced MSG_ReadChar with MSG_ReadByte to avoid // potentional vulnerability c = MSG_ReadByte (msg_read); if (c == -1 || c == 0) break; string[l] = c; l++; } while (l < sizeof(string)-1); string[l] = 0; return string; } char *MSG_ReadStringLine (sizebuf_t *msg_read) { static char string[2048]; int l,c; l = 0; do { // sku - replaced MSG_ReadChar with MSG_ReadByte to avoid // potentional vulnerability c = MSG_ReadByte (msg_read); if (c == -1 || c == 0 || c == '\n') break; string[l] = c; l++; } while (l < sizeof(string)-1); string[l] = 0; return string; } float MSG_ReadCoord (sizebuf_t *msg_read) { return MSG_ReadSizeInt(msg_read, coord_bytes) * (1.0/8); } void MSG_ReadPos (sizebuf_t *msg_read, vec3_t pos) { pos[0] = MSG_ReadSizeInt(msg_read, coord_bytes) * (1.0/8); pos[1] = MSG_ReadSizeInt(msg_read, coord_bytes) * (1.0/8); pos[2] = MSG_ReadSizeInt(msg_read, coord_bytes) * (1.0/8); } float MSG_ReadAngle (sizebuf_t *msg_read) { return MSG_ReadChar(msg_read) * (360.0/256); } float MSG_ReadAngle16 (sizebuf_t *msg_read) { return SHORT2ANGLE(MSG_ReadShort(msg_read)); } void MSG_ReadDeltaUsercmd (sizebuf_t *msg_read, usercmd_t *from, usercmd_t *move) { int bits; memcpy (move, from, sizeof(*move)); bits = MSG_ReadByte (msg_read); // read current angles if (bits & CM_ANGLE1) move->angles[0] = MSG_ReadShort (msg_read); if (bits & CM_ANGLE2) move->angles[1] = MSG_ReadShort (msg_read); if (bits & CM_ANGLE3) move->angles[2] = MSG_ReadShort (msg_read); // read movement if (bits & CM_FORWARD) move->forwardmove = MSG_ReadShort (msg_read); if (bits & CM_SIDE) move->sidemove = MSG_ReadShort (msg_read); if (bits & CM_UP) move->upmove = MSG_ReadShort (msg_read); // read buttons if (bits & CM_BUTTONS) move->buttons = MSG_ReadByte (msg_read); if (bits & CM_IMPULSE) move->impulse = MSG_ReadByte (msg_read); // read time to run command move->msec = MSG_ReadByte (msg_read); // read the light level move->lightlevel = MSG_ReadByte (msg_read); } void MSG_ReadData (sizebuf_t *msg_read, void *data, int len) { int i; for (i=0 ; idata = data; buf->maxsize = length; } #ifdef BUFFER_DEBUG void SZ_SetName(sizebuf_t * buf, const char * name, qboolean print_it) { strncpy(buf->name, name, sizeof(buf->name) - 1); if ( print_it ) Com_DPrintf("SZ_SetName: buffer '%s' (address = 0x%.12x) initialised\n", buf->name, buf); } #endif //BUFFER_DEBUG void SZ_Clear (sizebuf_t *buf) { buf->cursize = 0; buf->overflowed = false; } void *SZ_GetSpace (sizebuf_t *buf, int length) { void *data; if (buf->cursize + length > buf->maxsize) { if (!buf->allowoverflow) Com_Error (ERR_FATAL, "SZ_GetSpace: overflow without allowoverflow set"); if (length > buf->maxsize) Com_Error (ERR_FATAL, "SZ_GetSpace: %i is > full buffer size", length); #ifdef BUFFER_DEBUG Com_Printf ("SZ_GetSpace (%s at 0x%.12x): overflow\n", buf->name, buf); #else //BUFFER_DEBUG Com_Printf ("SZ_GetSpace: overflow\n"); #endif //BUFFER_DEBUG SZ_Clear (buf); buf->overflowed = true; } data = buf->data + buf->cursize; buf->cursize += length; return data; } void SZ_Write (sizebuf_t *buf, void *data, int length) { memcpy (SZ_GetSpace(buf,length),data,length); } void SZ_Print (sizebuf_t *buf, char *data) { int len; len = strlen(data)+1; if (buf->cursize) { if (buf->data[buf->cursize-1]) memcpy ((byte *)SZ_GetSpace(buf, len),data,len); // no trailing 0 else memcpy ((byte *)SZ_GetSpace(buf, len-1)-1,data,len); // write over trailing 0 } else memcpy ((byte *)SZ_GetSpace(buf, len),data,len); } //============================================================================ /* ================ COM_CheckParm Returns the position (1 to argc-1) in the program's argument list where the given parameter apears, or 0 if not present ================ */ int COM_CheckParm (char *parm) { int i; for (i=1 ; i= com_argc || !com_argv[arg]) return ""; return com_argv[arg]; } void COM_ClearArgv (int arg) { if (arg < 0 || arg >= com_argc || !com_argv[arg]) return; com_argv[arg] = ""; } /* ================ COM_InitArgv ================ */ void COM_InitArgv (int argc, char **argv) { int i; if (argc > MAX_NUM_ARGVS) Com_Error (ERR_FATAL, "argc > MAX_NUM_ARGVS"); com_argc = argc; for (i=0 ; i= MAX_TOKEN_CHARS ) com_argv[i] = ""; else com_argv[i] = argv[i]; } } /* ================ COM_AddParm Adds the given string at the end of the current argument list ================ */ void COM_AddParm (char *parm) { if (com_argc == MAX_NUM_ARGVS) Com_Error (ERR_FATAL, "COM_AddParm: MAX_NUM)ARGS"); com_argv[com_argc++] = parm; } /// just for debugging int memsearch (byte *start, int count, int search) { int i; for (i=0 ; imagic != Z_MAGIC) Com_Error (ERR_FATAL, "Z_Free: bad magic"); z->prev->next = z->next; z->next->prev = z->prev; z_count--; z_bytes -= z->size; free (z); } /* ======================== Z_Stats_f ======================== */ void Z_Stats_f (void) { Com_Printf ("%i bytes in %i blocks\n", z_bytes, z_count); } /* ======================== Z_FreeTags ======================== */ void Z_FreeTags (int tag) { zhead_t *z, *next; for (z=z_chain.next ; z != &z_chain ; z=next) { next = z->next; if (z->tag == tag) Z_Free ((void *)(z+1)); } } /* ======================== Z_TagMalloc ======================== */ void *Z_TagMalloc (int size, int tag) { zhead_t *z; size = size + sizeof(zhead_t); z = malloc(size); if (!z) Com_Error (ERR_FATAL, "Z_Malloc: failed on allocation of %i bytes",size); memset (z, 0, size); z_count++; z_bytes += size; z->magic = Z_MAGIC; z->tag = tag; z->size = size; z->next = z_chain.next; z->prev = &z_chain; z_chain.next->prev = z; z_chain.next = z; return (void *)(z+1); } /* ======================== Z_Malloc ======================== */ void *Z_Malloc (int size) { return Z_TagMalloc (size, 0); } //============================================================================ /* ==================== COM_BlockSequenceCheckByte For proxy protecting // THIS IS MASSIVELY BROKEN! CHALLENGE MAY BE NEGATIVE // DON'T USE THIS FUNCTION!!!!! ==================== */ byte COM_BlockSequenceCheckByte (byte *base, int length, int sequence, int challenge) { Sys_Error("COM_BlockSequenceCheckByte called\n"); #if 0 int checksum; byte buf[68]; byte *p; float temp; byte c; temp = bytedirs[(sequence/3) % NUMVERTEXNORMALS][sequence % 3]; temp = LittleFloat(temp); p = ((byte *)&temp); if (length > 60) length = 60; memcpy (buf, base, length); buf[length] = (sequence & 0xff) ^ p[0]; buf[length+1] = p[1]; buf[length+2] = ((sequence>>8) & 0xff) ^ p[2]; buf[length+3] = p[3]; temp = bytedirs[((sequence+challenge)/3) % NUMVERTEXNORMALS][(sequence+challenge) % 3]; temp = LittleFloat(temp); p = ((byte *)&temp); buf[length+4] = (sequence & 0xff) ^ p[3]; buf[length+5] = (challenge & 0xff) ^ p[2]; buf[length+6] = ((sequence>>8) & 0xff) ^ p[1]; buf[length+7] = ((challenge >> 7) & 0xff) ^ p[0]; length += 8; checksum = LittleLong(Com_BlockChecksum (buf, length)); checksum &= 0xff; return checksum; #endif return 0; } static byte chktbl[1024] = { 0x84, 0x47, 0x51, 0xc1, 0x93, 0x22, 0x21, 0x24, 0x2f, 0x66, 0x60, 0x4d, 0xb0, 0x7c, 0xda, 0x88, 0x54, 0x15, 0x2b, 0xc6, 0x6c, 0x89, 0xc5, 0x9d, 0x48, 0xee, 0xe6, 0x8a, 0xb5, 0xf4, 0xcb, 0xfb, 0xf1, 0x0c, 0x2e, 0xa0, 0xd7, 0xc9, 0x1f, 0xd6, 0x06, 0x9a, 0x09, 0x41, 0x54, 0x67, 0x46, 0xc7, 0x74, 0xe3, 0xc8, 0xb6, 0x5d, 0xa6, 0x36, 0xc4, 0xab, 0x2c, 0x7e, 0x85, 0xa8, 0xa4, 0xa6, 0x4d, 0x96, 0x19, 0x19, 0x9a, 0xcc, 0xd8, 0xac, 0x39, 0x5e, 0x3c, 0xf2, 0xf5, 0x5a, 0x72, 0xe5, 0xa9, 0xd1, 0xb3, 0x23, 0x82, 0x6f, 0x29, 0xcb, 0xd1, 0xcc, 0x71, 0xfb, 0xea, 0x92, 0xeb, 0x1c, 0xca, 0x4c, 0x70, 0xfe, 0x4d, 0xc9, 0x67, 0x43, 0x47, 0x94, 0xb9, 0x47, 0xbc, 0x3f, 0x01, 0xab, 0x7b, 0xa6, 0xe2, 0x76, 0xef, 0x5a, 0x7a, 0x29, 0x0b, 0x51, 0x54, 0x67, 0xd8, 0x1c, 0x14, 0x3e, 0x29, 0xec, 0xe9, 0x2d, 0x48, 0x67, 0xff, 0xed, 0x54, 0x4f, 0x48, 0xc0, 0xaa, 0x61, 0xf7, 0x78, 0x12, 0x03, 0x7a, 0x9e, 0x8b, 0xcf, 0x83, 0x7b, 0xae, 0xca, 0x7b, 0xd9, 0xe9, 0x53, 0x2a, 0xeb, 0xd2, 0xd8, 0xcd, 0xa3, 0x10, 0x25, 0x78, 0x5a, 0xb5, 0x23, 0x06, 0x93, 0xb7, 0x84, 0xd2, 0xbd, 0x96, 0x75, 0xa5, 0x5e, 0xcf, 0x4e, 0xe9, 0x50, 0xa1, 0xe6, 0x9d, 0xb1, 0xe3, 0x85, 0x66, 0x28, 0x4e, 0x43, 0xdc, 0x6e, 0xbb, 0x33, 0x9e, 0xf3, 0x0d, 0x00, 0xc1, 0xcf, 0x67, 0x34, 0x06, 0x7c, 0x71, 0xe3, 0x63, 0xb7, 0xb7, 0xdf, 0x92, 0xc4, 0xc2, 0x25, 0x5c, 0xff, 0xc3, 0x6e, 0xfc, 0xaa, 0x1e, 0x2a, 0x48, 0x11, 0x1c, 0x36, 0x68, 0x78, 0x86, 0x79, 0x30, 0xc3, 0xd6, 0xde, 0xbc, 0x3a, 0x2a, 0x6d, 0x1e, 0x46, 0xdd, 0xe0, 0x80, 0x1e, 0x44, 0x3b, 0x6f, 0xaf, 0x31, 0xda, 0xa2, 0xbd, 0x77, 0x06, 0x56, 0xc0, 0xb7, 0x92, 0x4b, 0x37, 0xc0, 0xfc, 0xc2, 0xd5, 0xfb, 0xa8, 0xda, 0xf5, 0x57, 0xa8, 0x18, 0xc0, 0xdf, 0xe7, 0xaa, 0x2a, 0xe0, 0x7c, 0x6f, 0x77, 0xb1, 0x26, 0xba, 0xf9, 0x2e, 0x1d, 0x16, 0xcb, 0xb8, 0xa2, 0x44, 0xd5, 0x2f, 0x1a, 0x79, 0x74, 0x87, 0x4b, 0x00, 0xc9, 0x4a, 0x3a, 0x65, 0x8f, 0xe6, 0x5d, 0xe5, 0x0a, 0x77, 0xd8, 0x1a, 0x14, 0x41, 0x75, 0xb1, 0xe2, 0x50, 0x2c, 0x93, 0x38, 0x2b, 0x6d, 0xf3, 0xf6, 0xdb, 0x1f, 0xcd, 0xff, 0x14, 0x70, 0xe7, 0x16, 0xe8, 0x3d, 0xf0, 0xe3, 0xbc, 0x5e, 0xb6, 0x3f, 0xcc, 0x81, 0x24, 0x67, 0xf3, 0x97, 0x3b, 0xfe, 0x3a, 0x96, 0x85, 0xdf, 0xe4, 0x6e, 0x3c, 0x85, 0x05, 0x0e, 0xa3, 0x2b, 0x07, 0xc8, 0xbf, 0xe5, 0x13, 0x82, 0x62, 0x08, 0x61, 0x69, 0x4b, 0x47, 0x62, 0x73, 0x44, 0x64, 0x8e, 0xe2, 0x91, 0xa6, 0x9a, 0xb7, 0xe9, 0x04, 0xb6, 0x54, 0x0c, 0xc5, 0xa9, 0x47, 0xa6, 0xc9, 0x08, 0xfe, 0x4e, 0xa6, 0xcc, 0x8a, 0x5b, 0x90, 0x6f, 0x2b, 0x3f, 0xb6, 0x0a, 0x96, 0xc0, 0x78, 0x58, 0x3c, 0x76, 0x6d, 0x94, 0x1a, 0xe4, 0x4e, 0xb8, 0x38, 0xbb, 0xf5, 0xeb, 0x29, 0xd8, 0xb0, 0xf3, 0x15, 0x1e, 0x99, 0x96, 0x3c, 0x5d, 0x63, 0xd5, 0xb1, 0xad, 0x52, 0xb8, 0x55, 0x70, 0x75, 0x3e, 0x1a, 0xd5, 0xda, 0xf6, 0x7a, 0x48, 0x7d, 0x44, 0x41, 0xf9, 0x11, 0xce, 0xd7, 0xca, 0xa5, 0x3d, 0x7a, 0x79, 0x7e, 0x7d, 0x25, 0x1b, 0x77, 0xbc, 0xf7, 0xc7, 0x0f, 0x84, 0x95, 0x10, 0x92, 0x67, 0x15, 0x11, 0x5a, 0x5e, 0x41, 0x66, 0x0f, 0x38, 0x03, 0xb2, 0xf1, 0x5d, 0xf8, 0xab, 0xc0, 0x02, 0x76, 0x84, 0x28, 0xf4, 0x9d, 0x56, 0x46, 0x60, 0x20, 0xdb, 0x68, 0xa7, 0xbb, 0xee, 0xac, 0x15, 0x01, 0x2f, 0x20, 0x09, 0xdb, 0xc0, 0x16, 0xa1, 0x89, 0xf9, 0x94, 0x59, 0x00, 0xc1, 0x76, 0xbf, 0xc1, 0x4d, 0x5d, 0x2d, 0xa9, 0x85, 0x2c, 0xd6, 0xd3, 0x14, 0xcc, 0x02, 0xc3, 0xc2, 0xfa, 0x6b, 0xb7, 0xa6, 0xef, 0xdd, 0x12, 0x26, 0xa4, 0x63, 0xe3, 0x62, 0xbd, 0x56, 0x8a, 0x52, 0x2b, 0xb9, 0xdf, 0x09, 0xbc, 0x0e, 0x97, 0xa9, 0xb0, 0x82, 0x46, 0x08, 0xd5, 0x1a, 0x8e, 0x1b, 0xa7, 0x90, 0x98, 0xb9, 0xbb, 0x3c, 0x17, 0x9a, 0xf2, 0x82, 0xba, 0x64, 0x0a, 0x7f, 0xca, 0x5a, 0x8c, 0x7c, 0xd3, 0x79, 0x09, 0x5b, 0x26, 0xbb, 0xbd, 0x25, 0xdf, 0x3d, 0x6f, 0x9a, 0x8f, 0xee, 0x21, 0x66, 0xb0, 0x8d, 0x84, 0x4c, 0x91, 0x45, 0xd4, 0x77, 0x4f, 0xb3, 0x8c, 0xbc, 0xa8, 0x99, 0xaa, 0x19, 0x53, 0x7c, 0x02, 0x87, 0xbb, 0x0b, 0x7c, 0x1a, 0x2d, 0xdf, 0x48, 0x44, 0x06, 0xd6, 0x7d, 0x0c, 0x2d, 0x35, 0x76, 0xae, 0xc4, 0x5f, 0x71, 0x85, 0x97, 0xc4, 0x3d, 0xef, 0x52, 0xbe, 0x00, 0xe4, 0xcd, 0x49, 0xd1, 0xd1, 0x1c, 0x3c, 0xd0, 0x1c, 0x42, 0xaf, 0xd4, 0xbd, 0x58, 0x34, 0x07, 0x32, 0xee, 0xb9, 0xb5, 0xea, 0xff, 0xd7, 0x8c, 0x0d, 0x2e, 0x2f, 0xaf, 0x87, 0xbb, 0xe6, 0x52, 0x71, 0x22, 0xf5, 0x25, 0x17, 0xa1, 0x82, 0x04, 0xc2, 0x4a, 0xbd, 0x57, 0xc6, 0xab, 0xc8, 0x35, 0x0c, 0x3c, 0xd9, 0xc2, 0x43, 0xdb, 0x27, 0x92, 0xcf, 0xb8, 0x25, 0x60, 0xfa, 0x21, 0x3b, 0x04, 0x52, 0xc8, 0x96, 0xba, 0x74, 0xe3, 0x67, 0x3e, 0x8e, 0x8d, 0x61, 0x90, 0x92, 0x59, 0xb6, 0x1a, 0x1c, 0x5e, 0x21, 0xc1, 0x65, 0xe5, 0xa6, 0x34, 0x05, 0x6f, 0xc5, 0x60, 0xb1, 0x83, 0xc1, 0xd5, 0xd5, 0xed, 0xd9, 0xc7, 0x11, 0x7b, 0x49, 0x7a, 0xf9, 0xf9, 0x84, 0x47, 0x9b, 0xe2, 0xa5, 0x82, 0xe0, 0xc2, 0x88, 0xd0, 0xb2, 0x58, 0x88, 0x7f, 0x45, 0x09, 0x67, 0x74, 0x61, 0xbf, 0xe6, 0x40, 0xe2, 0x9d, 0xc2, 0x47, 0x05, 0x89, 0xed, 0xcb, 0xbb, 0xb7, 0x27, 0xe7, 0xdc, 0x7a, 0xfd, 0xbf, 0xa8, 0xd0, 0xaa, 0x10, 0x39, 0x3c, 0x20, 0xf0, 0xd3, 0x6e, 0xb1, 0x72, 0xf8, 0xe6, 0x0f, 0xef, 0x37, 0xe5, 0x09, 0x33, 0x5a, 0x83, 0x43, 0x80, 0x4f, 0x65, 0x2f, 0x7c, 0x8c, 0x6a, 0xa0, 0x82, 0x0c, 0xd4, 0xd4, 0xfa, 0x81, 0x60, 0x3d, 0xdf, 0x06, 0xf1, 0x5f, 0x08, 0x0d, 0x6d, 0x43, 0xf2, 0xe3, 0x11, 0x7d, 0x80, 0x32, 0xc5, 0xfb, 0xc5, 0xd9, 0x27, 0xec, 0xc6, 0x4e, 0x65, 0x27, 0x76, 0x87, 0xa6, 0xee, 0xee, 0xd7, 0x8b, 0xd1, 0xa0, 0x5c, 0xb0, 0x42, 0x13, 0x0e, 0x95, 0x4a, 0xf2, 0x06, 0xc6, 0x43, 0x33, 0xf4, 0xc7, 0xf8, 0xe7, 0x1f, 0xdd, 0xe4, 0x46, 0x4a, 0x70, 0x39, 0x6c, 0xd0, 0xed, 0xca, 0xbe, 0x60, 0x3b, 0xd1, 0x7b, 0x57, 0x48, 0xe5, 0x3a, 0x79, 0xc1, 0x69, 0x33, 0x53, 0x1b, 0x80, 0xb8, 0x91, 0x7d, 0xb4, 0xf6, 0x17, 0x1a, 0x1d, 0x5a, 0x32, 0xd6, 0xcc, 0x71, 0x29, 0x3f, 0x28, 0xbb, 0xf3, 0x5e, 0x71, 0xb8, 0x43, 0xaf, 0xf8, 0xb9, 0x64, 0xef, 0xc4, 0xa5, 0x6c, 0x08, 0x53, 0xc7, 0x00, 0x10, 0x39, 0x4f, 0xdd, 0xe4, 0xb6, 0x19, 0x27, 0xfb, 0xb8, 0xf5, 0x32, 0x73, 0xe5, 0xcb, 0x32 }; /* ==================== COM_BlockSequenceCRCByte For proxy protecting ==================== */ byte COM_BlockSequenceCRCByte (byte *base, int length, int sequence) { int n; byte *p; int x; byte chkb[60 + 4]; unsigned short crc; if (sequence < 0) Sys_Error("sequence < 0, this shouldn't happen\n"); p = chktbl + (sequence % (sizeof(chktbl) - 4)); if (length > 60) length = 60; memcpy (chkb, base, length); chkb[length] = p[0]; chkb[length+1] = p[1]; chkb[length+2] = p[2]; chkb[length+3] = p[3]; length += 4; crc = CRC_Block(chkb, length); for (x=0, n=0; nvalue) Cmd_AddCommand ("quit", Com_Quit); Sys_Init (); NET_Init (); Netchan_Init (); SV_Init (); dedicated->modified = false; if(!dedicated->value) CL_Init (); // add + commands from command line if (!Cbuf_AddLateCommands ()) { // if the user didn't give any commands, run default action if (!dedicated->value) Cbuf_AddText("menu_main\n"); else Cbuf_AddText ("dedicated_start\n"); Cbuf_Execute (); } else { // the user asked for something explicit // so drop the loading plaque SCR_EndLoadingPlaque (); } //drop console, to get it into menu SCR_EndLoadingPlaque (); // clear any lines of console text Cbuf_AddText ("clear\n"); #ifndef DEDICATED_ONLY //play music if (!dedicated->value) S_StartMenuMusic(); #endif Com_Printf ("======== Alien Arena Initialized ========\n\n"); } /* ================= Qcommon_Frame ================= */ void Qcommon_Frame (int msec) { int time_before=0, time_between=0, time_after=0; #if defined UNIX_VARIANT char *s; #endif if (setjmp (abortframe) ) return; // an ERR_DROP was thrown if ( log_stats->modified ) { log_stats->modified = false; if ( log_stats->value ) { if ( log_stats_file ) { fclose( log_stats_file ); log_stats_file = 0; } log_stats_file = fopen( "stats.log", "w" ); if ( log_stats_file ) fprintf( log_stats_file, "entities,dlights,parts,frame time\n" ); } else { if ( log_stats_file ) { fclose( log_stats_file ); log_stats_file = 0; } } } if (fixedtime->value) msec = fixedtime->value; else if (timescale->value) { msec *= timescale->value; if (msec < 1) msec = 1; } if (showtrace->value) { extern int c_traces, c_brush_traces; extern int c_pointcontents; if ( c_traces > 0 || c_brush_traces > 0 || c_pointcontents > 0 ) { Com_Printf ("%4i traces %4i brush %4i points\n", c_traces, c_brush_traces, c_pointcontents); c_traces = 0; c_brush_traces = 0; c_pointcontents = 0; } } #if defined UNIX_VARIANT do { s = Sys_ConsoleInput (); if (s) Cbuf_AddText (va("%s\n",s)); } while (s); #else // Get input from dedicated server console if (dedicated->integer){ char *cmd; cmd = Sys_GetCommand(); if (cmd){ Cbuf_AddText(cmd); Cbuf_AddText("\n"); } } #endif Cbuf_Execute (); if (host_speeds->value) time_before = Sys_Milliseconds (); SV_Frame (msec); #if defined WIN32_VARIANT // not good for Linux when run from menu or icon without a terminal if(dedicated->modified) { dedicated->modified = false; if ( dedicated->value ) { //shutdown the client CL_Shutdown(); } } #endif if (host_speeds->value) time_between = Sys_Milliseconds (); CL_Frame (msec); if (host_speeds->value) time_after = Sys_Milliseconds (); if (host_speeds->value) { int all, sv, gm, cl, rf; all = time_after - time_before; sv = time_between - time_before; cl = time_after - time_between; gm = time_after_game - time_before_game; rf = time_after_ref - time_before_ref; sv -= gm; cl -= rf; Com_Printf ("all:%3i sv:%3i gm:%3i cl:%3i rf:%3i\n", all, sv, gm, cl, rf); } } /* ================= Qcommon_Shutdown ================= */ void Qcommon_Shutdown (void) { } #ifdef HAVE_ZLIB //This compression code was originally from the Lua branch. More of it will //eventually be merged when packet compression is added, but currently we //are only decompressing zlib data and only need it on the client side. //Following function ripped off from R1Q2, then modified to use sizebufs int ZLibDecompress (sizebuf_t *in, sizebuf_t *out, int wbits) { z_stream zs; char *err_summary; int result; memset (&zs, 0, sizeof(zs)); zs.next_in = in->data + in->readcount; zs.avail_in = 0; zs.next_out = out->data + out->cursize; zs.avail_out = out->maxsize - out->cursize; result = inflateInit2(&zs, wbits); if (result != Z_OK) { switch (result) { default: err_summary = "unknown"; break; case Z_MEM_ERROR: err_summary = "system memory exhausted"; break; case Z_STREAM_ERROR: err_summary = "invalid z_stream"; break; case Z_VERSION_ERROR: err_summary = "incompatible zlib version"; break; } Com_Printf ("ZLib data error! Error %d on inflateInit.\nMessage: %s\n", result, zs.msg); return 0; } zs.avail_in = in->cursize; result = inflate(&zs, Z_FINISH); if (result != Z_STREAM_END) { switch (result) { default: err_summary = "unknown"; break; case Z_STREAM_END: err_summary = "premature end of stream"; break; case Z_NEED_DICT: err_summary = "missing preset dictionary"; break; case Z_STREAM_ERROR: err_summary = "invalid z_stream"; break; case Z_DATA_ERROR: err_summary = "corrupted data"; break; case Z_BUF_ERROR: err_summary = "too much compressed data"; break; case Z_OK: err_summary = "shouldn't happen with Z_FINISH"; break; } Com_Printf ("ZLib data error! Error %d (%s) on inflate.\nMessage: %s\n", result, err_summary, zs.msg); return 0; } result = inflateEnd(&zs); if (result != Z_OK) { switch (result) { default: err_summary = "unknown"; break; case Z_STREAM_ERROR: err_summary = "invalid z_stream"; break; case Z_DATA_ERROR: err_summary = "prematurely freed z_stream"; break; } Com_Printf ("ZLib data error! Error %d (%s) on inflateEnd.\nMessage: %s\n", result, err_summary, zs.msg); return 0; } return zs.total_out; } #endif //HAVE_ZLIB void qdecompress (sizebuf_t *src, sizebuf_t *dst, int type){ int newsize = 0; switch (type) { #ifdef HAVE_ZLIB case compression_zlib_raw: //raw DEFLATE data, no header/trailer newsize = ZLibDecompress (src, dst, -15); break; #endif #if 0 case compression_lzo: newsize = LzoDecompress (src, dst); break; #endif #ifdef HAVE_ZLIB case compression_zlib_header: //automatically detect gzip/zlib header/trailer newsize = ZLibDecompress (src, dst, 47); break; #endif } if ( newsize == 0) dst->cursize = 0; else dst->cursize += newsize; } alien-arena-7.66+dfsg/source/qcommon/files.c0000600000175000017500000006716312161402010020036 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. Copyright (C) 2010 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* ------------------------------------------------------------------------------- Alien Arena File System (August 2010) *** with autotools build and filesystem update modifications *** ------ Windows XP, Vista, Windows 7 (MSVC or MinGW builds) ------ c:\alienarena\ data1\ --- game data from release package arena\ --- 3rd party, legacy, and downloaded game data --- screenshots, demos config.cfg autoexec.cfg qconsole.log botinfo\ Tools\doc\ crx.exe ------ Linux, Unix, Darwin ------ --- Standard Install --- $prefix/ /usr/local/ $bindir/ /usr/local/bin/ crx crx-ded $datadir/ /usr/local/share/ $pkgdatadir /usr/local/share/alienarena/ data1/ --- shared game data from release package arena/ --- shared 3rd party and legacy game data botinfo/ --- shared bot information $COR_GAME ~/.codered arena/ --- downloaded 3rd party, legacy game data --- screenshots, demos config.cfg autoexec.cfg qconsole.log botinfo/ --- user custom bot information --- Alternate (Traditional) Install --- /home/user/games/alienarena/ (for example) crx crx-ded data1/ arena/ botinfo/ $COR_GAME $(HOME)/.codered --- Same as Standard Install --- Alien Arena ACEBOT File System --- - botinfo can be in one place or two places depending on the installation -- botinfo files and file types -- - allbots.tmp : data for bots included in the Add Bot menu. - team.tmp : data for default set of bots spawned for a team game. - .cfg : config data for bots by name. - .tmp : data for the set of bots spawned in a map. --- Other Notes --- .pak file support removed because: 1. Alien Arena does not use it. 2. simplifies filesystem modifications link command removed because: 1. it is probably obsolete (hack for DOS to simulate Unix link?) 2. simplifies filesystem modifications 3. might be a security issue? basedir cvar removed because: 1. it is probably an unnecessary complication. --- Original Quake File System Comments --- All of Quake's data access is through a hierchal file system, but the contents of the file system can be transparently merged from several sources. The "base directory" is the path to the directory holding the quake.exe and all game directories. The sys_* files pass this to host_init in quakeparms_t->basedir. This can be overridden with the "-basedir" command line parm to allow code debugging in a different directory. The base directory is only used during filesystem initialization. The "game directory" is the first tree on the search path and directory that all generated files (savegames, screenshots, demos, config files) will be saved to. This can be overridden with the "-game" command line parameter. The game directory can never be changed while quake is executing. This is a precacution against having a malicious server instruct clients to write files over areas they shouldn't. ------------------------------------------------------------------------------- */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #if defined HAVE_UNISTD_H #include #elif defined HAVE_DIRECT_H /* for _getcwd in Windows */ #include #endif #if defined HAVE_SYS_STAT_H #include #endif #if defined HAVE_ZLIB # include #endif #include #include "qcommon.h" #include "game/q_shared.h" #include "unix/glob.h" #if !defined HAVE__GETCWD && defined HAVE_GETCWD #define _getcwd getcwd #endif char fs_gamedir[MAX_OSPATH]; cvar_t *fs_gamedirvar; // for the "game" cvar, default is "arena" /* --- Search Paths --- * * Pathname strings do not include a trailing '/' * The last slot is guard, containing an empty string * The bot pathname strings do not include the "botinfo" part. * */ #define GAME_SEARCH_SLOTS 7 char fs_gamesearch[GAME_SEARCH_SLOTS][MAX_OSPATH]; #define BOT_SEARCH_SLOTS 3 char fs_botsearch[BOT_SEARCH_SLOTS][MAX_OSPATH]; /** * @brief Initialize paths: data1, arena, botinfo, etc. * * @note This gets executed after command line "+set" commands are executed * the first time. But, before any other commands from command line * or .cfg files are executed. */ static void FS_init_paths( void ) { int i; char fs_bindir[MAX_OSPATH]; char fs_datadir[MAX_OSPATH]; char fs_homedir[MAX_OSPATH]; char *cwdstr; char *homestr; char base_gamedata[MAX_OSPATH]; char game_gamedata[MAX_OSPATH]; char bot_gamedata[MAX_OSPATH]; #if defined UNIX_VARIANT char user_base_gamedata[MAX_OSPATH]; // possibly never used in Alien Arena char user_game_gamedata[MAX_OSPATH]; // configuration, logs, downloaded data char user_bot_gamedata[MAX_OSPATH]; // user custom bot data #endif memset(fs_bindir, 0, sizeof(fs_bindir)); memset(fs_datadir, 0, sizeof(fs_datadir)); memset(fs_homedir, 0, sizeof(fs_homedir)); cwdstr = _getcwd( fs_bindir, sizeof(fs_bindir) ); if ( cwdstr == NULL ) { Sys_Error( "path initialization (getcwd error: %i)", strerror(errno) ); } #if defined UNIX_VARIANT homestr = getenv( "COR_GAME" ); if ( homestr != NULL ) { if ( strlen( homestr) >= sizeof(fs_homedir) || !strlen( homestr ) ) { Sys_Error( "path initialization (getenv COR_GAME is %s)", homestr ); } Q_strncpyz2( fs_homedir, homestr, sizeof( fs_homedir) ); } else { homestr = getenv( "HOME" ); if ( homestr != NULL ) { Com_sprintf( fs_homedir, sizeof( fs_homedir), "%s/%s", homestr, USER_GAMEDATA ); } else { fs_homedir[0] = 0; } } #else homestr = NULL; fs_homedir[0] = 0; #endif #if !defined DATADIR // "Traditional" install, expect game data in current directory Q_strncpyz2( fs_datadir, fs_bindir, sizeof(fs_datadir) ); #else if ( !Q_strncasecmp( fs_bindir, DATADIR, sizeof(fs_bindir)) ) { // DATADIR defined, but it is current directory for executable // note: this may not need to be a special case Q_strncpyz2( fs_datadir, fs_bindir, sizeof(fs_datadir) ); } else { // "Standard" install. game data is not in same directory as executables if ( strlen( DATADIR ) >= sizeof( fs_datadir ) ) { Sys_Error("DATADIR size error"); } Q_strncpyz2( fs_datadir, DATADIR, sizeof(fs_datadir) ); } #endif // set path for "data1" memset( base_gamedata, 0, sizeof(base_gamedata) ); Com_sprintf( base_gamedata, sizeof(base_gamedata), "%s/%s", fs_datadir, BASE_GAMEDATA ); // set path for "arena" or mod memset( game_gamedata, 0, sizeof(game_gamedata) ); fs_gamedirvar = Cvar_Get( "game", "", CVAR_LATCH|CVAR_SERVERINFO); if ( *fs_gamedirvar->string && fs_gamedirvar->string[0] ) { // not empty if ( Q_strncasecmp( fs_gamedirvar->string, BASE_GAMEDATA, MAX_OSPATH ) && Q_strncasecmp( fs_gamedirvar->string, GAME_GAMEDATA, MAX_OSPATH )) { // not "data1" nor "arena". expect a mod data directory. Com_sprintf( game_gamedata, sizeof(game_gamedata), "%s/%s", fs_datadir, fs_gamedirvar->string ); } else { // was "data1" or "arena", use "arena" Com_sprintf( game_gamedata, sizeof(game_gamedata), "%s/%s", fs_datadir, GAME_GAMEDATA ); } } else { // was empty, set to "arena" fs_gamedirvar = Cvar_ForceSet("gamedir", GAME_GAMEDATA ); Com_sprintf( game_gamedata, sizeof(game_gamedata), "%s/%s", fs_datadir, GAME_GAMEDATA ); } // set path for "botinfo" // note: the "botinfo" part of the path, will be in the relative path // so do not include it here memset( bot_gamedata, 0, sizeof(bot_gamedata) ); Com_sprintf( bot_gamedata, sizeof(bot_gamedata), "%s", fs_datadir ); #if defined UNIX_VARIANT if ( fs_homedir[0] ) { // have a user HOME as expected /* * use the ".codered" or $COR_GAME directory, * even if this is a Traditional install. */ // set "data1" path for user writeable data // Alien Arena maybe never uses this memset( user_base_gamedata, 0, sizeof(user_base_gamedata) ); Com_sprintf( user_base_gamedata, sizeof(user_base_gamedata), "%s/%s", fs_homedir, BASE_GAMEDATA ); // set "arena" path for user writeable data memset( user_game_gamedata, 0, sizeof(user_game_gamedata) ); Com_sprintf( user_game_gamedata, sizeof(user_game_gamedata), "%s/%s", fs_homedir, GAME_GAMEDATA ); // set "botinfo" path for user writeable data memset( user_bot_gamedata, 0, sizeof(user_bot_gamedata) ); Com_sprintf( user_bot_gamedata, sizeof(user_bot_gamedata), "%s", fs_homedir ); } else { // unexpected missing $HOME directory Sys_Error("set environment variable HOME (or COR_GAME) to a writeable directory."); } #endif // // set up search priority sequence // // 2 or 4 places for game data for ( i = 0 ; i < GAME_SEARCH_SLOTS ; i++ ) { memset( fs_gamesearch[i], 0, MAX_OSPATH ); } i = 0; #if defined UNIX_VARIANT if ( user_game_gamedata[0] ) { // default: ~/.codered/arena or $COR_GAME/arena Q_strncpyz2( fs_gamesearch[i], user_game_gamedata, sizeof(fs_gamesearch[0])); i++; } #endif if ( game_gamedata[0] ) { // default: DATADIR/arena or $CWD/arena Q_strncpyz2( fs_gamesearch[i], game_gamedata, sizeof(fs_gamesearch[0])); i++; } #if defined UNIX_VARIANT if ( user_base_gamedata[0] ) { // default: ~/.codered/data1 or $COR_GAME/data1 (may not be needed) Q_strncpyz2( fs_gamesearch[i], user_base_gamedata, sizeof(fs_gamesearch[0])); i++; } #endif if ( base_gamedata[0] ) { // default: DATADIR/data1 or $CWD/data1 Q_strncpyz2( fs_gamesearch[i], base_gamedata, sizeof(fs_gamesearch[0])); } // one or two places for bot information for ( i = 0 ; i < BOT_SEARCH_SLOTS ; i++ ) { memset( fs_botsearch[i], 0, MAX_OSPATH ); } i = 0; #if defined UNIX_VARIANT if ( user_bot_gamedata[0] ) { Q_strncpyz2( fs_botsearch[i], user_bot_gamedata, sizeof(fs_botsearch[0])); i++; } #endif if ( bot_gamedata[0] ) { Q_strncpyz2( fs_botsearch[i], bot_gamedata, sizeof(fs_botsearch[0])); } // set up fs_gamedir, location for writing various files // this is the first directory in the search path Q_strncpyz2( fs_gamedir, fs_gamesearch[0], sizeof(fs_gamedir) ); } /* ================ FS_filelength ================ */ int FS_filelength( FILE *f ) { int length = -1; #if defined HAVE_FILELENGTH length = filelength( fileno( f ) ); #elif defined HAVE_FSTAT struct stat statbfr; int result; result = fstat( fileno(f), &statbfr ); if ( result != -1 ) { length = (int)statbfr.st_size; } #else long int pos; pos = ftell( f ); fseek( f, 0L, SEEK_END ); length = ftell( f ); fseek( f, pos, SEEK_SET ); #endif return length; } /* ============ FS_CreatePath Creates any directories needed to store the given filename ============ */ void FS_CreatePath (char *path) { char *ofs; for (ofs = path+1 ; *ofs ; ofs++) { if (*ofs == '/') { // create the directory *ofs = 0; Sys_Mkdir (path); *ofs = '/'; } } } /* === FS_CheckFile Given the full path to a file, find out whether or not the file actually exists. === */ #if defined HAVE_STAT static qboolean FS_CheckFile( const char * search_path ) { struct stat statbfr; int result; result = stat( search_path, &statbfr ); return ( result != -1 && S_ISREG(statbfr.st_mode) ); } #else // HAVE_STAT static qboolean FS_CheckFile( const char * search_path ) { FILE *pfile; pfile = fopen( search_path, "rb"); if ( ! pfile ) return false; fclose( pfile ); return true; } #endif // HAVE_STAT /* === FS_FullPath Given a relative path to a file search for the file in the installation-dependent filesystem hierarchy if found, return true, with the constructed full path otherwise return false, with full_path set to zero-length string Corrected 2012-11, was: otherwise, return false, with a constructed writeable full path (which clearly it might not, and could not do). === */ qboolean FS_FullPath( char *full_path, size_t pathsize, const char *relative_path ) { char search_path[MAX_OSPATH]; char * to_search; qboolean found = false; *full_path = 0; if ( strlen( relative_path ) >= MAX_QPATH ) { Com_DPrintf("FS_FullPath: relative path size error: %s\n", relative_path ); return false; } if ( !Q_strncasecmp( relative_path, BOT_GAMEDATA, strlen(BOT_GAMEDATA) ) ) { // search in botinfo places to_search = &fs_botsearch[0][0]; } else { // search in the usual game data places to_search = &fs_gamesearch[0][0]; } while ( to_search[0] && !found ) { Com_sprintf( search_path, sizeof(search_path), "%s/%s", to_search, relative_path); found = FS_CheckFile( search_path ); to_search += MAX_OSPATH; } if ( found ) { if ( strlen( search_path ) < pathsize ) { Q_strncpyz2( full_path, search_path, pathsize ); if ( developer && developer->integer == 2 ) { // tracing for found files, not an error. Com_DPrintf("FS_FullPath: found : %s\n", full_path ); } } else { Com_DPrintf("FS_FullPath: full path size error: %s\n", search_path ); found = false; } } else if ( developer && developer->integer == 2 ) { // tracing for not found files, not necessarily an error. Com_DPrintf("FS_FullPath: not found : %s\n", relative_path ); } return found; } /* === FS_FullWritePath() Given a relative path for a file to be written Using the game writeable directory Create any sub-directories required Return the generated full path for file === */ void FS_FullWritePath( char *full_path, size_t pathsize, const char* relative_path) { if ( strlen( relative_path ) >= MAX_QPATH ) { Com_DPrintf("FS_FullPath: relative path size error: %s\n", relative_path ); *full_path = 0; return; } if ( !Q_strncasecmp( relative_path, BOT_GAMEDATA, strlen(BOT_GAMEDATA) ) ) { // a "botinfo/" prefixed relative path Com_sprintf( full_path, pathsize, "%s/%s", fs_botsearch[0], relative_path); } else { // writeable path for game data, same as fs_gamesearch[0] Com_sprintf( full_path, pathsize, "%s/%s", fs_gamedir, relative_path); } FS_CreatePath( full_path ); } /* ============== FS_FCloseFile ============== */ void FS_FCloseFile (FILE *f) { fclose (f); } /* =========== FS_FOpenFile Given relative path, search for a file if found, open it and return length if not found, return length -1 and NULL file =========== */ int FS_FOpenFile (char *filename, FILE **file) { char netpath[MAX_OSPATH]; qboolean found; int length = -1; found = FS_FullPath( netpath, sizeof(netpath), filename ); if ( found ) { *file = fopen( netpath, "rb" ); if ( !(*file) ) { Com_DPrintf("FS_FOpenFile: failed file open: %s:\n", netpath); } else { length = FS_filelength( *file ); // On error, the file's length will be negative, and we probably // can't read from that. if ( length < 0 ) { FS_FCloseFile( *file ); *file = NULL; } } } else { *file = NULL; } return length; } /* ================= FS_ReadFile Properly handles partial reads ================= */ #define MAX_READ 0x10000 // read in blocks of 64k void FS_Read (void *buffer, int len, FILE *f) { int block, remaining; int read; byte *buf; int tries; buf = (byte *)buffer; // read in chunks for progress bar remaining = len; tries = 0; while (remaining) { block = remaining; if (block > MAX_READ) block = MAX_READ; read = fread (buf, 1, block, f); if (read == 0) { if ( feof( f ) ) Com_Error( ERR_FATAL, "FS_Read: premature end-of-file"); if ( ferror( f ) ) Com_Error( ERR_FATAL, "FS_Read: file read error"); Com_Error (ERR_FATAL, "FS_Read: 0 bytes read"); } if (read == -1) Com_Error (ERR_FATAL, "FS_Read: -1 bytes read"); // do some progress bar thing here... remaining -= read; buf += read; } } /* ================== FS_TolowerPath Makes the path to the given file lowercase on case-sensitive systems. Kludge for case-sensitive and case-insensitive systems inteoperability. Background: Some people may extract game paths/files as uppercase onto their HDD (while their system is case-insensitive, so game will work, but will case trouble for case-sensitive systems if they are acting as servers [propagating their maps etc. in uppercase]). Indeed the best approach here would be to make fopen()ing always case- insensitive, but due to resulting complexity and fact that Linux people will always install the game files with correct name casing, this is just fine. -JR / 20050802 / 1 ================== */ char *FS_TolowerPath (char *path) { int i = 0; static char buf[MAX_OSPATH]; // path can be const char *, so thats why do buf[i] = tolower(path[i]); while (path[i++]); return buf; } /* ============ FS_LoadFile Given relative path if buffer arg is NULL, just return the file length otherwise, Z_malloc a buffer, read the file into it, return pointer to the new buffer ============ */ int FS_LoadFile (char *path, void **buffer) { FILE *h; byte *buf = NULL; int len; char lc_path[MAX_OSPATH]; len = FS_FOpenFile (path, &h); //-JR if (!h) { Q_strncpyz2( lc_path, FS_TolowerPath( path ), sizeof(lc_path) ); if ( strcmp( path, lc_path ) ) { // lowercase conversion changed something len = FS_FOpenFile( lc_path, &h); } } if (!h) { if (buffer) *buffer = NULL; return -1; } if (!buffer) { FS_FCloseFile (h); return len; } buf = Z_Malloc(len+1); buf[len] = 0; *buffer = buf; FS_Read (buf, len, h); FS_FCloseFile (h); return len; } /* ============ FS_LoadFile_TryStatic Given relative path, and assuming statbuffer is already allocated with at least statbuffer_len bytes, if buffer or statbuffer arg is NULL, just return the file length. Otherwise, If the file length is less than statbuffer_len, load file contents into it and return it in the buffer output pointer. Otherwise, Z_malloc a buffer, read the file into it, return pointer to the new buffer. This is a variation on FS_LoadFile which attempts to reduce needless dynamic memory allocations, by using a static buffer when possible. The calling function is responsible for comparing the value of *buffer with statbuffer, and determining whether or not to use FS_FreeFile on it. ============ */ int FS_LoadFile_TryStatic (char *path, void **buffer, void *statbuffer, size_t statbuffer_len) { FILE *h; byte *buf = NULL; int len; char lc_path[MAX_OSPATH]; len = FS_FOpenFile (path, &h); //-JR if (!h) { Q_strncpyz2( lc_path, FS_TolowerPath( path ), sizeof(lc_path) ); if ( strcmp( path, lc_path ) ) { // lowercase conversion changed something len = FS_FOpenFile( lc_path, &h); } } if (!h) { if (buffer) *buffer = NULL; return -1; } if (buffer == NULL || statbuffer == NULL || statbuffer_len == 0) { FS_FCloseFile (h); return len; } if (statbuffer_len > len) { memset (statbuffer, 0, statbuffer_len); buf = statbuffer; } else { buf = Z_Malloc(len+1); } buf[len] = 0; *buffer = buf; FS_Read (buf, len, h); FS_FCloseFile (h); return len; } /* ============= FS_FreeFile ============= */ void FS_FreeFile (void *buffer) { Z_Free (buffer); } /* ========= FS_FileExists Given relative path, search for a file if found, return true if not found, return false ======== */ qboolean FS_FileExists(char *path) { char fullpath[MAX_OSPATH]; return ( FS_FullPath( fullpath, sizeof(fullpath), path ) ); } /* ============ FS_Gamedir Called to find where to write a file (demos, savegames, etc) ============ */ char *FS_Gamedir (void) { return fs_gamedir; } /* ============= FS_ExecAutoexec ============= */ void FS_ExecAutoexec (void) { char name [MAX_OSPATH]; int i; // search through all the paths for an autoexec.cfg file for ( i = 0; fs_gamesearch[i][0] ; i++ ) { Com_sprintf(name, sizeof(name), "%s/autoexec.cfg", fs_gamesearch[i] ); if (Sys_FindFirst(name, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM)) { Cbuf_AddText ("exec autoexec.cfg\n"); Sys_FindClose(); break; } Sys_FindClose(); } } /* ================ FS_SetGamedir Sets the gamedir and path to a different directory. ================ */ void FS_SetGamedir (char *dir) { if (strstr(dir, "..") || strstr(dir, "/") || strstr(dir, "\\") || strstr(dir, ":") ) { Com_Printf ("Gamedir should be a single filename, not a path\n"); return; } // // flush all data, so it will be forced to reload // if ( dedicated && !dedicated->value ) { // set up for client restart Cbuf_AddText ("vid_restart\nsnd_restart\n"); } // note: FullSet triggers sending info to client if ( !strcmp( dir, BASE_GAMEDATA ) || ( *dir == 0 ) ) { // either "data1" or "", set to empty string. Cvar_FullSet ("gamedir", "", CVAR_SERVERINFO|CVAR_NOSET); } else { Cvar_FullSet ("gamedir", dir, CVAR_SERVERINFO|CVAR_NOSET); } // re-initialize search paths FS_init_paths(); } /* ** FS_ListFiles ** ** IMPORTANT: does not count the guard in returned "numfiles" anymore, to ** avoid adding/subtracting 1 all the time. */ char **FS_ListFiles( char *findname, int *numfiles, unsigned musthave, unsigned canthave ) { char *namestr; int nfiles = 0; char **list = NULL; // pointer to array of pointers // --- count the matching files --- namestr = Sys_FindFirst( findname, musthave, canthave ); while ( namestr ) { if ( namestr[ strlen( namestr )-1 ] != '.' ) // not '..' nor '.' nfiles++; namestr = Sys_FindNext( musthave, canthave ); } Sys_FindClose (); if ( !nfiles ) return NULL; *numfiles = nfiles; nfiles++; // add space for a guard // --- create the file name string array --- list = malloc( sizeof( char * ) * nfiles ); // array of pointers memset( list, 0, sizeof( char * ) * nfiles ); namestr = Sys_FindFirst( findname, musthave, canthave ); nfiles = 0; while ( namestr ) { if ( namestr[ strlen(namestr) - 1] != '.' ) // not ".." nor "." { list[nfiles] = strdup( namestr ); // list[n] <- malloc'd pointer #if defined WIN32_VARIANT _strlwr( list[nfiles] ); #endif nfiles++; } namestr = Sys_FindNext( musthave, canthave ); } Sys_FindClose (); return list; } void FS_FreeFileList (char **list, int n) // jit { int i; for (i = 0; i < n; i++) { free(list[i]); list[i] = 0; } free(list); } /* * FS_ListFilesInFS * * Create a list of files that match a criteria. * * Searchs are relative to the game directory and use all the search paths */ char ** FS_ListFilesInFS(char *findname, int *numfiles, unsigned musthave, unsigned canthave) { // searchpath_t *search; /* Search path. */ int i, j; /* Loop counters. */ int nfiles; /* Number of files found. */ int tmpnfiles; /* Temp number of files. */ char **tmplist; /* Temporary list of files. */ char **list; /* List of files found. */ char **new_list; char path[MAX_OSPATH]; /* Temporary path. */ int s; nfiles = 0; list = malloc(sizeof(char *)); for ( s = 0 ; fs_gamesearch[s][0]; s++ ) { // for non-empty search slots Com_sprintf(path, sizeof(path), "%s/%s",fs_gamesearch[s], findname); tmplist = FS_ListFiles(path, &tmpnfiles, musthave, canthave); if (tmplist != NULL) { nfiles += tmpnfiles; new_list = realloc(list, nfiles * sizeof(char *)); if (new_list == NULL) { FS_FreeFileList (tmplist, tmpnfiles); Com_Printf ("WARN: SYSTEM MEMORY EXHAUSTION!\n"); break; } list = new_list; for (i = 0, j = nfiles - tmpnfiles; i < tmpnfiles; i++, j++) { // copy from full path to relative path list[j] = strdup( tmplist[i] + strlen( fs_gamesearch[s] ) + 1 ); } FS_FreeFileList(tmplist, tmpnfiles); } } /* Delete duplicates. */ tmpnfiles = 0; for (i = 0; i < nfiles; i++) { if (list[i] == NULL) continue; for (j = i + 1; j < nfiles; j++) if (list[j] != NULL && strcmp(list[i], list[j]) == 0) { free(list[j]); list[j] = NULL; tmpnfiles++; } } if (tmpnfiles > 0) { nfiles -= tmpnfiles; tmplist = malloc(nfiles * sizeof(char *)); for (i = 0, j = 0; i < nfiles + tmpnfiles; i++) if (list[i] != NULL) tmplist[j++] = list[i]; free(list); list = tmplist; } /* Add a guard. */ if (nfiles > 0) { nfiles++; new_list = realloc(list, nfiles * sizeof(char *)); if (new_list == NULL) { Com_Printf ("WARN: SYSTEM MEMORY EXHAUSTION!\n"); nfiles--; // convert previous entry into a guard } else { list = new_list; } list[nfiles - 1] = NULL; } else { free(list); list = NULL; } /* IMPORTANT: Don't count the guard when returning nfiles. */ nfiles--; *numfiles = nfiles; return (list); } /* ** FS_Dir_f ** ** target of "dir" command */ void FS_Dir_f( void ) { char *path = NULL; char findname[1024]; char wildcard[1024] = "*.*"; char **dirnames; int ndirs; if ( Cmd_Argc() != 1 ) { strcpy( wildcard, Cmd_Argv( 1 ) ); } while ( ( path = FS_NextPath( path ) ) != NULL ) { char *tmp = findname; Com_sprintf( findname, sizeof(findname), "%s/%s", path, wildcard ); // limit to game directories. // FIXME: figure out a way to look in botinfo directories if ( strstr( findname, ".." ) ) { continue; } while ( *tmp != 0 ) { if ( *tmp == '\\' ) *tmp = '/'; tmp++; } Com_Printf( "Directory of %s\n", findname ); Com_Printf( "----\n" ); if ( ( dirnames = FS_ListFiles( findname, &ndirs, 0, 0 ) ) != 0 ) { int i; for ( i = 0; i < ndirs; i++ ) { if ( strrchr( dirnames[i], '/' ) ) Com_Printf( "%s\n", strrchr( dirnames[i], '/' ) + 1 ); else Com_Printf( "%s\n", dirnames[i] ); free( dirnames[i] ); } free( dirnames ); } Com_Printf( "\n" ); }; } /* ============ FS_Path_f target of "path" command ============ */ void FS_Path_f (void) { int i; Com_Printf ("Game data search path:\n"); for ( i = 0; fs_gamesearch[i][0] ; i++ ) { Com_Printf( "%s/\n", fs_gamesearch[i] ); } Com_Printf ("Bot data search path:\n"); for ( i = 0; fs_botsearch[i][0] ; i++ ) { Com_Printf( "%s/%s/\n", fs_botsearch[i], BOT_GAMEDATA ); } } /* ================ FS_NextPath Allows enumerating all of the directories in the search path prevpath to NULL on first call, previously returned char* on subsequent returns NULL when done ================ */ char *FS_NextPath (char *prevpath) { char *nextpath; int i = 0; if ( prevpath == NULL ) { // return the first nextpath = fs_gamesearch[0]; } else { // scan the fs_gamesearch elements for an address match with prevpath nextpath = NULL; while ( prevpath != fs_gamesearch[i++] ) { if ( i >= GAME_SEARCH_SLOTS ) { Sys_Error("Program Error in FS_NextPath()"); } } if ( fs_gamesearch[i][0] ) { // non-empty slot nextpath = fs_gamesearch[i]; } } return nextpath; } /* ================ FS_InitFilesystem ================ */ void FS_InitFilesystem (void) { #if defined UNIX_VARIANT char dummy_path[MAX_OSPATH]; #endif Cmd_AddCommand ("path", FS_Path_f); Cmd_AddCommand ("dir", FS_Dir_f ); FS_init_paths(); #if defined UNIX_VARIANT Com_Printf("using %s for writing\n", fs_gamedir ); /* * Create the writeable directory if it does not exist. * Otherwise, a dedicated server may fail to create a logfile. * "dummy" is there just so FS_CreatePath works, no file is created. */ Com_sprintf( dummy_path, sizeof(dummy_path), "%s/dummy", fs_gamedir ); FS_CreatePath( dummy_path ); #endif #if defined HAVE_ZLIB && !defined DEDICATED_ONLY Com_Printf("using zlib version %s\n", zlibVersion() ); #endif } alien-arena-7.66+dfsg/source/qcommon/qcommon.h0000600000175000017500000006544012204310130020405 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // qcommon.h -- definitions common between client and server, but not game module #if !defined Q_COMMON_H_ #define Q_COMMON_H_ #include "game/q_shared.h" #if !defined VERSION #define VERSION "7.66" #endif /* ---- Default locations of game data ---*/ #if !defined BASE_GAMEDATA #define BASE_GAMEDATA "data1" #endif #if !defined GAME_GAMEDATA #define GAME_GAMEDATA "arena" #endif #if !defined BOT_GAMEDATA #define BOT_GAMEDATA "botinfo" #endif #if !defined USER_GAMEDATA // default for COR_GAME environment variable #define USER_GAMEDATA ".codered" #endif /*----------------------------------------*/ #define MENU_STATIC_WIDTH 720.0f #define DEFAULTMODEL "martianenforcer" #define DEFAULTSKIN "default" #if defined WIN32_VARIANT #define BUFFER_DEBUG 0 #if !defined BUILDSTRING #ifdef NDEBUG #define BUILDSTRING "Win32 RELEASE" #else #define BUILDSTRING "Win32 DEBUG" #endif #endif #if !defined CPUSTRING #define CPUSTRING "x86" #endif #else #if !defined BUILDSTRING #define BUILDSTRING "?OS?" #endif #if !defined CPUSTRING #define CPUSTRING "?CPU?" #endif #endif //============================================================================ // Hash key computation macro, because that piece of code gets around a lot #define COMPUTE_HASH_KEY_CHAR(key, schar ) \ key = 31 * key + tolower(schar) #define COMPUTE_HASH_KEY(key, str, counter) \ { \ key = 0; \ for ( counter = 0; str[counter] ; counter ++ ) \ COMPUTE_HASH_KEY_CHAR(key, str[counter]); \ } //============================================================================ typedef struct sizebuf_s { qboolean allowoverflow; // if false, do a Com_Error qboolean overflowed; // set to true if the buffer size failed byte *data; int maxsize; int cursize; int readcount; #ifdef BUFFER_DEBUG char name[48]; #endif //BUFFER_DEBUG } sizebuf_t; void SZ_Init (sizebuf_t *buf, byte *data, int length); void SZ_Clear (sizebuf_t *buf); void *SZ_GetSpace (sizebuf_t *buf, int length); void SZ_Write (sizebuf_t *buf, void *data, int length); void SZ_Print (sizebuf_t *buf, char *data); // strcats onto the sizebuf #ifdef BUFFER_DEBUG void SZ_SetName( sizebuf_t *buf, const char * name, qboolean print_it ); #else //BUFFER_DEBUG # define SZ_SetName(buf, name, print) #endif // BUFFER_DEBUG //============================================================================ struct usercmd_s; struct entity_state_s; void MSG_WriteChar (sizebuf_t *sb, int c); void MSG_WriteByte (sizebuf_t *sb, int c); void MSG_WriteShort (sizebuf_t *sb, int c); void MSG_WriteLong (sizebuf_t *sb, int c); void MSG_WriteFloat (sizebuf_t *sb, float f); void MSG_WriteString (sizebuf_t *sb, char *s); void MSG_WriteCoord (sizebuf_t *sb, float f); void MSG_WritePos (sizebuf_t *sb, vec3_t pos); void MSG_WriteAngle (sizebuf_t *sb, float f); void MSG_WriteAngle16 (sizebuf_t *sb, float f); void MSG_WriteDeltaUsercmd (sizebuf_t *sb, struct usercmd_s *from, struct usercmd_s *cmd); void MSG_WriteDeltaEntity (struct entity_state_s *from, struct entity_state_s *to, sizebuf_t *msg, qboolean force, qboolean newentity); void MSG_WriteDir (sizebuf_t *sb, vec3_t vector); void MSG_BeginReading (sizebuf_t *sb); int MSG_ReadChar (sizebuf_t *sb); int MSG_ReadByte (sizebuf_t *sb); int MSG_ReadShort (sizebuf_t *sb); int MSG_ReadLong (sizebuf_t *sb); int MSG_ReadSizeInt (sizebuf_t *msg_read, int bytes); float MSG_ReadFloat (sizebuf_t *sb); char *MSG_ReadString (sizebuf_t *sb); char *MSG_ReadStringLine (sizebuf_t *sb); float MSG_ReadCoord (sizebuf_t *sb); void MSG_ReadPos (sizebuf_t *sb, vec3_t pos); float MSG_ReadAngle (sizebuf_t *sb); float MSG_ReadAngle16 (sizebuf_t *sb); void MSG_ReadDeltaUsercmd (sizebuf_t *sb, struct usercmd_s *from, struct usercmd_s *cmd); void MSG_ReadDir (sizebuf_t *sb, vec3_t vector); void MSG_ReadData (sizebuf_t *sb, void *buffer, int size); //============================================================================ extern qboolean bigendien; extern short BigShort (short l); extern short LittleShort (short l); extern int BigLong (int l); extern int LittleLong (int l); extern float BigFloat (float l); extern float LittleFloat (float l); //============================================================================ int COM_Argc (void); char *COM_Argv (int arg); // range and null checked void COM_ClearArgv (int arg); int COM_CheckParm (char *parm); void COM_AddParm (char *parm); void COM_Init (void); void COM_InitArgv (int argc, char **argv); char *CopyString (const char *in); //============================================================================ void Info_Print (char *s); /* crc.h */ void CRC_Init(unsigned short *crcvalue); void CRC_ProcessByte(unsigned short *crcvalue, byte data); unsigned short CRC_Value(unsigned short crcvalue); unsigned short CRC_Block (byte *start, int count); /* ============================================================== PROTOCOL ============================================================== */ // protocol.h -- communications protocols #define PROTOCOL_VERSION 34 //========================================= #define PORT_MASTER 27900 #define PORT_CLIENT 27901 #define PORT_STATS 27902 #define PORT_SERVER 27910 //========================================= #define UPDATE_BACKUP 16 // copies of entity_state_t to keep buffered // must be power of two #define UPDATE_MASK (UPDATE_BACKUP-1) //================== // the svc_strings[] array in cl_parse.c should mirror this //================== // // server to client // enum svc_ops_e { svc_bad, // these ops are known to the game dll svc_muzzleflash, svc_muzzleflash2, svc_temp_entity, svc_layout, svc_inventory, // the rest are private to the client and server svc_nop, svc_disconnect, svc_reconnect, svc_sound, // svc_print, // [byte] id [string] null terminated string svc_stufftext, // [string] stuffed into client's console buffer, should be \n terminated svc_serverdata, // [long] protocol ... svc_configstring, // [short] [string] svc_spawnbaseline, svc_centerprint, // [string] to put in center of the screen svc_download, // [short] size [size bytes] svc_playerinfo, // variable svc_packetentities, // [...] svc_deltapacketentities, // [...] svc_frame }; //============================================== // // client to server // enum clc_ops_e { clc_bad, clc_nop, clc_move, // [[usercmd_t] clc_userinfo, // [[userinfo string] clc_stringcmd // [string] message }; //============================================== // plyer_state_t communication #define PS_M_TYPE (1<<0) #define PS_M_ORIGIN (1<<1) #define PS_M_VELOCITY (1<<2) #define PS_M_TIME (1<<3) #define PS_M_FLAGS (1<<4) #define PS_M_GRAVITY (1<<5) #define PS_M_DELTA_ANGLES (1<<6) #define PS_VIEWOFFSET (1<<7) #define PS_VIEWANGLES (1<<8) #define PS_KICKANGLES (1<<9) #define PS_BLEND (1<<10) #define PS_FOV (1<<11) #define PS_WEAPONINDEX (1<<12) #define PS_WEAPONFRAME (1<<13) #define PS_RDFLAGS (1<<14) //============================================== // user_cmd_t communication // ms and light always sent, the others are optional #define CM_ANGLE1 (1<<0) #define CM_ANGLE2 (1<<1) #define CM_ANGLE3 (1<<2) #define CM_FORWARD (1<<3) #define CM_SIDE (1<<4) #define CM_UP (1<<5) #define CM_BUTTONS (1<<6) #define CM_IMPULSE (1<<7) //============================================== // a sound without an ent or pos will be a local only sound #define SND_VOLUME (1<<0) // a byte #define SND_ATTENUATION (1<<1) // a byte #define SND_POS (1<<2) // three coordinates #define SND_ENT (1<<3) // a short 0-2: channel, 3-12: entity #define SND_OFFSET (1<<4) // a byte, msec offset from frame start #define DEFAULT_SOUND_PACKET_VOLUME 1.0 #define DEFAULT_SOUND_PACKET_ATTENUATION 1.0 //============================================== // entity_state_t communication // try to pack the common update flags into the first byte #define U_ORIGIN1 (1<<0) #define U_ORIGIN2 (1<<1) #define U_ANGLE2 (1<<2) #define U_ANGLE3 (1<<3) #define U_FRAME8 (1<<4) // frame is a byte #define U_EVENT (1<<5) #define U_REMOVE (1<<6) // REMOVE this entity, don't add it #define U_MOREBITS1 (1<<7) // read one additional byte // second byte #define U_NUMBER16 (1<<8) // NUMBER8 is implicit if not set #define U_ORIGIN3 (1<<9) #define U_ANGLE1 (1<<10) #define U_MODEL (1<<11) #define U_RENDERFX8 (1<<12) // fullbright, etc #define U_EFFECTS8 (1<<14) // autorotate, trails, etc #define U_MOREBITS2 (1<<15) // read one additional byte // third byte #define U_SKIN8 (1<<16) #define U_FRAME16 (1<<17) // frame is a short #define U_RENDERFX16 (1<<18) // 8 + 16 = 32 #define U_EFFECTS16 (1<<19) // 8 + 16 = 32 #define U_MODEL2 (1<<20) // weapons, flags, etc #define U_MODEL3 (1<<21) #define U_MODEL4 (1<<22) #define U_MOREBITS3 (1<<23) // read one additional byte // fourth byte #define U_OLDORIGIN (1<<24) // FIXME: get rid of this #define U_SKIN16 (1<<25) #define U_SOUND (1<<26) #define U_SOLID (1<<27) /* ============================================================== CMD Command text buffering and command execution ============================================================== */ /* Any number of commands can be added in a frame, from several different sources. Most commands come from either keybindings or console line input, but remote servers can also send across commands and entire text files can be execed. The + command line options are also added to the command buffer. The game starts with a Cbuf_AddText ("exec quake.rc\n"); Cbuf_Execute (); */ #define EXEC_NOW 0 // don't return until completed #define EXEC_INSERT 1 // insert at current position, but don't run yet #define EXEC_APPEND 2 // add to end of the command buffer void Cbuf_Init (void); // allocates an initial text buffer that will grow as needed void Cbuf_AddText (char *text); // as new commands are generated from the console or keybindings, // the text is added to the end of the command buffer. void Cbuf_InsertText (char *text); // when a command wants to issue other commands immediately, the text is // inserted at the beginning of the buffer, before any remaining unexecuted // commands. void Cbuf_ExecuteText (int exec_when, char *text); // this can be used in place of either Cbuf_AddText or Cbuf_InsertText void Cbuf_AddEarlyCommands (qboolean clear); // adds all the +set commands from the command line qboolean Cbuf_AddLateCommands (void); // adds all the remaining + commands from the command line // Returns true if any late commands were added, which // will keep the demoloop from immediately starting void Cbuf_Execute (void); // Pulls off \n terminated lines of text from the command buffer and sends // them through Cmd_ExecuteString. Stops when the buffer is empty. // Normally called once per frame, but may be explicitly invoked. // Do not call inside a command function! void Cbuf_CopyToDefer (void); void Cbuf_InsertFromDefer (void); // These two functions are used to defer any pending commands while a map // is being loaded //=========================================================================== /* Command execution takes a null terminated string, breaks it into tokens, then searches for a command or variable that matches the first token. */ typedef void (*xcommand_t) (void); void Cmd_Init (void); void Cmd_AddCommand (char *cmd_name, xcommand_t function); // called by the init functions of other parts of the program to // register commands and functions to call for them. // The cmd_name is referenced later, so it should not be in temp memory // if function is NULL, the command will be forwarded to the server // as a clc_stringcmd instead of executed locally void Cmd_RemoveCommand (char *cmd_name); qboolean Cmd_Exists (char *cmd_name); // used by the cvar code to check for cvar / command name overlap char *Cmd_CompleteCommand (char *partial); // attempts to match a partial command for automatic command line completion // returns NULL if nothing fits int Cmd_Argc (void); char *Cmd_Argv (int arg); char *Cmd_Args (void); // The functions that execute commands get their parameters with these // functions. Cmd_Argv () will return an empty string, not a NULL // if arg > argc, so string operations are always safe. void Cmd_TokenizeString (char *text, qboolean macroExpand); // Takes a null terminated string. Does not need to be /n terminated. // breaks the string up into arg tokens. void Cmd_ExecuteString (char *text); // Parses a single line of text into arguments and tries to execute it // as if it was typed at the console void Cmd_ForwardToServer (void); // adds the current command line as a clc_stringcmd to the client message. // things like godmode, noclip, etc, are commands directed to the server, // so when they are typed in at the console, they will need to be forwarded. /* ============================================================== CVAR ============================================================== */ /* cvar_t variables are used to hold scalar or string variables that can be changed or displayed at the console or prog code as well as accessed directly in C code. The user can access cvars from the console in three ways: r_draworder prints the current value r_draworder 0 sets the current value to 0 set r_draworder 0 as above, but creates the cvar if not present Cvars are restricted from having the same names as commands to keep this interface from being ambiguous. */ extern cvar_t *cvar_vars; // Creates the variable if it doesn't exist, or returns the existing one // if it exists, the value will not be changed, but flags will be ORed in. // That allows variables to be unarchived without needing bitflags. NOTE: the // value and name strings are copied, so you don't need to keep track of any // strings you use with this function. cvar_t *Cvar_Get (const char *var_name, const char *value, int flags); // will create the variable if it doesn't exist void Cvar_Set (const char *var_name, const char *value); // will set the variable even if NOSET or LATCH cvar_t *Cvar_ForceSet (const char *var_name, const char *value); void Cvar_FullSet (const char *var_name, const char *value, int flags); // expands value to a string and calls Cvar_Set void Cvar_SetValue (const char *var_name, float value); // returns 0 if not defined or non numeric float Cvar_VariableValue (const char *var_name); // returns an empty string if not defined char *Cvar_VariableString (const char *var_name); // attempts to match a partial variable name for command line completion // returns NULL if nothing fits char *Cvar_CompleteVariable (const char *partial); // any CVAR_LATCHED variables that have been set will now take effect void Cvar_GetLatchedVars (void); // called by Cmd_ExecuteString when Cmd_Argv(0) doesn't match a known // command. Returns true if the command was a variable reference that // was handled. (print or change) qboolean Cvar_Command (void); // appends lines containing "set variable value" for all variables // with the archive flag set to true. void Cvar_WriteVariables (char *path); // setup the cvar subsystem and related console commands void Cvar_Init (void); // returns an info string containing all the CVAR_USERINFO cvars char *Cvar_Userinfo (void); // returns an info string containing all the CVAR_SERVERINFO cvars char *Cvar_Serverinfo (void); // Initializes a new cvar struct holding just a value, with no name in it. // Used in some places where a weak-typed variable is needed. void Anon_Cvar_Set(cvar_t *nvar, const char *var_value); // Copies the description string into the cvar. Useful for documenting cvars. // The description string is copied, so it need not be kept in memory for the // life of the cvar. void Cvar_Describe(cvar_t *var, const char *description_string); void Cvar_Describe_ByName(const char *var_name, const char *description_string); // this is set each time a CVAR_USERINFO variable is changed // so that the client knows to send it to the server extern qboolean userinfo_modified; /* ============================================================== NET ============================================================== */ // net.h -- quake's interface to the networking layer #define PORT_ANY -1 #define MAX_MSGLEN 2800 // max length of a message #define PACKET_HEADER 20 // two ints and a short typedef enum {NA_LOOPBACK, NA_BROADCAST, NA_IP, NA_IPX, NA_BROADCAST_IPX} netadrtype_t; typedef enum {NS_CLIENT, NS_SERVER} netsrc_t; typedef struct { netadrtype_t type; byte ip[4]; byte ipx[10]; unsigned short port; /* network byte order (bigendian) */ } netadr_t; void NET_Init (void); void NET_Shutdown (void); void NET_Config (qboolean multiplayer); qboolean NET_GetPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message); void NET_SendPacket (netsrc_t sock, int length, void *data, netadr_t to); qboolean NET_CompareAdr (netadr_t a, netadr_t b); qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b); qboolean NET_IsLocalAddress (netadr_t adr); char *NET_AdrToString (netadr_t a); qboolean NET_StringToAdr (char *s, netadr_t *a); void NET_Sleep(int msec); #define NET_IsLocalHost(x) \ ((x)->type == NA_LOOPBACK) //============================================================================ #define OLD_AVG 0.99 // total = oldtotal*OLD_AVG + new*(1-OLD_AVG) #define MAX_LATENT 32 typedef struct { qboolean fatal_error; netsrc_t sock; // either NS_CLIENT or NS_SERVER int dropped; // between last packet and previous int last_received; // for timeouts int last_sent; // for retransmits netadr_t remote_address; int qport; // qport value to write when transmitting // sequencing variables int incoming_sequence; int incoming_acknowledged; int incoming_reliable_acknowledged; // single bit int incoming_reliable_sequence; // single bit, maintained local int outgoing_sequence; int reliable_sequence; // single bit int last_reliable_sequence; // sequence number of last send // reliable staging and holding areas sizebuf_t message; // writing buffer to send to server byte message_buf[MAX_MSGLEN-16]; // leave space for header // message is copied to this buffer when it is first transfered int reliable_length; byte reliable_buf[MAX_MSGLEN-16]; // unacked reliable message } netchan_t; extern netadr_t net_from; extern sizebuf_t net_message; extern byte net_message_buffer[MAX_MSGLEN]; void Netchan_Init (void); void Netchan_Setup (netsrc_t sock, netchan_t *chan, netadr_t adr, int qport); qboolean Netchan_NeedReliable (netchan_t *chan); void Netchan_Transmit (netchan_t *chan, int length, byte *data); void Netchan_OutOfBand (int net_socket, netadr_t adr, int length, byte *data); void Netchan_OutOfBandPrint (int net_socket, netadr_t adr, char *format, ...); qboolean Netchan_Process (netchan_t *chan, sizebuf_t *msg); qboolean Netchan_CanReliable (netchan_t *chan); /* ============================================================== CMODEL ============================================================== */ #include "qcommon/qfiles.h" cmodel_t *CM_LoadMap (char *name, qboolean clientload, unsigned *checksum); cmodel_t *CM_LoadBSP (char *name, qboolean clientload, unsigned *checksum); cmodel_t *CM_InlineModel (char *name); // *1, *2, etc int CM_NumClusters (void); int CM_NumInlineModels (void); char *CM_EntityString (void); // creates a clipping hull for an arbitrary box int CM_HeadnodeForBox (vec3_t mins, vec3_t maxs); // returns an ORed contents mask int CM_PointContents (vec3_t p, int headnode); int CM_TransformedPointContents (vec3_t p, int headnode, vec3_t origin, vec3_t angles); trace_t CM_BoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int headnode, int brushmask); trace_t CM_TransformedBoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int headnode, int brushmask, vec3_t origin, vec3_t angles); byte *CM_ClusterPVS (int cluster); byte *CM_ClusterPHS (int cluster); int CM_PointLeafnum (vec3_t p); // call with topnode set to the headnode, returns with topnode // set to the first node that splits the box int CM_BoxLeafnums (vec3_t mins, vec3_t maxs, int *list, int listsize, int *topnode); int CM_LeafContents (int leafnum); int CM_LeafCluster (int leafnum); int CM_LeafArea (int leafnum); void CM_SetAreaPortalState (int portalnum, qboolean open); qboolean CM_AreasConnected (int area1, int area2); int CM_WriteAreaBits (byte *buffer, int area); qboolean CM_HeadnodeVisible (int headnode, byte *visbits); void CM_WritePortalState (FILE *f); void CM_ReadPortalState (FILE *f); qboolean CM_inPVS (vec3_t p1, vec3_t p2); qboolean CM_inPVS_leafs (int leafnum1, int leafnum2); qboolean CM_inPHS (vec3_t p1, vec3_t p2); extern char map_name[MAX_QPATH]; /* ============================================================== PLAYER MOVEMENT CODE Common between server and client so prediction matches ============================================================== */ extern float pm_airaccelerate; qboolean remoteserver_jousting; int remoteserver_runspeed; void Pmove (pmove_t *pmove); /* ============================================================== FILESYSTEM ============================================================== */ int FS_filelength( FILE *f ); void FS_InitFilesystem (void); void FS_SetGamedir (char *dir); char *FS_Gamedir (void); char *FS_NextPath (char *prevpath); void FS_ExecAutoexec (void); // 2 Filesystem functions added 2010-08 qboolean FS_FullPath( char *full_path, size_t pathsize,const char *relative_path ); void FS_FullWritePath( char *full_path, size_t pathsize,const char *relative_path ); int FS_FOpenFile (char *filename, FILE **file); void FS_FCloseFile (FILE *f); // note: this can't be called from another DLL, due to MS libc issues int FS_LoadFile (char *path, void **buffer); int FS_LoadFile_TryStatic (char *path, void **buffer, void *statbuffer, size_t statbuffer_len); void FS_Read (void *buffer, int len, FILE *f); // properly handles partial reads void FS_FreeFile (void *buffer); void FS_CreatePath (char *path); qboolean FS_FileExists(char *path); #define SFF_INPACK 0x20 /* For FS_ListFilesInFS(). */ char **FS_ListFiles(char *findname, int *numfiles, unsigned musthave, unsigned canthave); char **FS_ListFilesInFS(char *findname, int *numfiles, unsigned musthave, unsigned canthave); void FS_FreeFileList (char **list, int n); /* ============================================================== MISC ============================================================== */ #define ERR_FATAL 0 // exit the entire game with a popup window #define ERR_DROP 1 // print to console and disconnect from game #define ERR_QUIT 2 // not an error, just a normal exit // redundant //#define EXEC_NOW 0 // don't return until completed //#define EXEC_INSERT 1 // insert at current position, but don't run yet //#define EXEC_APPEND 2 // add to end of the command buffer #define PRINT_ALL 0 #define PRINT_DEVELOPER 1 // only print when "developer 1" void Com_BeginRedirect (int target, char *buffer, int buffersize, void (*flush)); void Com_EndRedirect (void); void Com_Printf (char *fmt, ...); void Com_DPrintf (char *fmt, ...); void Com_Error (int code, char *fmt, ...); void Com_Quit (void); int Com_ServerState (void); // this should have just been a cvar... void Com_SetServerState (int state); unsigned Com_BlockChecksum (void *buffer, int length); byte COM_BlockSequenceCRCByte (byte *base, int length, int sequence); float frand(void); // 0 ti 1 float crand(void); // -1 to 1 extern cvar_t *developer; extern cvar_t *dedicated; extern cvar_t *host_speeds; extern cvar_t *log_stats; extern FILE *log_stats_file; // host_speeds times extern int time_before_game; extern int time_after_game; extern int time_before_ref; extern int time_after_ref; void Z_Free (void *ptr); void *Z_Malloc (int size); // returns 0 filled memory void *Z_TagMalloc (int size, int tag); void Z_FreeTags (int tag); void Qcommon_Init (int argc, char **argv); void Qcommon_Frame (int msec); void Qcommon_Shutdown (void); #define NUMVERTEXNORMALS 162 extern vec3_t bytedirs[NUMVERTEXNORMALS]; // this is in the client code, but can be used for debugging from server void SCR_DebugGraph (float value, const float color[]); //used for render effect void CL_GlassShards(vec3_t org, vec3_t dir, int count); #define static_array_size(array) (sizeof(array)/sizeof((array)[0])) /* ============================================================== NON-PORTABLE SYSTEM SERVICES ============================================================== */ char *Sys_GetCommand (void); void Sys_Print (const char *text); void Sys_ShowConsole (qboolean show); void Sys_Init (void); void Sys_AppActivate (void); void Sys_UnloadGame (void); void *Sys_GetGameAPI (void *parms); // loads the game dll and calls the api init function char *Sys_ConsoleInput (void); void Sys_ConsoleOutput (char *string); void Sys_SendKeyEvents (void); void Sys_Error (char *error, ...); void Sys_Quit (void); char *Sys_GetClipboardData( void ); void Sys_CopyProtect (void); /* ============================================================== CLIENT / SERVER SYSTEMS ============================================================== */ void CL_Init (void); void CL_Drop (void); void CL_Shutdown (void); void CL_Frame (int msec); void CON_Print (const char *text); void SCR_BeginLoadingPlaque (void); void SV_Init (void); void SV_Shutdown (char *finalmsg, qboolean reconnect); void SV_Frame (int msec); // // compression // void qdecompress (sizebuf_t *src, sizebuf_t *dst, int type); #endif /* Q_COMMON_H_ */ alien-arena-7.66+dfsg/source/qcommon/md5.h0000600000175000017500000000070412161402010017412 0ustar zero79zero79#ifndef _MD5_H #define _MD5_H #ifdef __cplusplus extern "C" { #endif unsigned Com_MD5Checksum (void *buffer, int length); unsigned Com_MD5ChecksumKey (void *buffer, int length, int key); char *Com_MD5HashString (const void *buffer, int length, char *pMD5Out, size_t sizeMD5Out); char *Com_HMACMD5String (const void *key, size_t keylen, const void *msg, int msglen, char *out, size_t outsize); #ifdef __cplusplus } #endif #endif alien-arena-7.66+dfsg/source/qcommon/mdfour.c0000600000175000017500000001255412161402010020222 0ustar zero79zero79/* $RCSfile: mdfour.c,v $ Copyright (C) 1997-1998 Andrew Tridgell Copyright (C) 2000 Jeff Teunissen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to: Free Software Foundation, Inc. 59 Temple Place - Suite 330 Boston, MA 02111-1307, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include /* NOTE: This code makes no attempt to be fast! It assumes that a int is at least 32 bits long */ struct mdfour { unsigned A, B, C, D; unsigned totalN; }; static struct mdfour *m; #define F(X,Y,Z) (((X)&(Y)) | ((~(X))&(Z))) #define G(X,Y,Z) (((X)&(Y)) | ((X)&(Z)) | ((Y)&(Z))) #define H(X,Y,Z) ((X)^(Y)^(Z)) #define lshift(x,s) (((x)<<(s)) | ((x)>>(32-(s)))) #define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s) #define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + 0x5A827999,s) #define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + 0x6ED9EBA1,s) /* this applies md4 to 64 byte chunks */ static void mdfour64 (unsigned *M) { int j; unsigned AA, BB, CC, DD; unsigned X[16]; unsigned A, B, C, D; for (j = 0; j < 16; j++) X[j] = M[j]; A = m->A; B = m->B; C = m->C; D = m->D; AA = A; BB = B; CC = C; DD = D; ROUND1 (A, B, C, D, 0, 3); ROUND1 (D, A, B, C, 1, 7); ROUND1 (C, D, A, B, 2, 11); ROUND1 (B, C, D, A, 3, 19); ROUND1 (A, B, C, D, 4, 3); ROUND1 (D, A, B, C, 5, 7); ROUND1 (C, D, A, B, 6, 11); ROUND1 (B, C, D, A, 7, 19); ROUND1 (A, B, C, D, 8, 3); ROUND1 (D, A, B, C, 9, 7); ROUND1 (C, D, A, B, 10, 11); ROUND1 (B, C, D, A, 11, 19); ROUND1 (A, B, C, D, 12, 3); ROUND1 (D, A, B, C, 13, 7); ROUND1 (C, D, A, B, 14, 11); ROUND1 (B, C, D, A, 15, 19); ROUND2 (A, B, C, D, 0, 3); ROUND2 (D, A, B, C, 4, 5); ROUND2 (C, D, A, B, 8, 9); ROUND2 (B, C, D, A, 12, 13); ROUND2 (A, B, C, D, 1, 3); ROUND2 (D, A, B, C, 5, 5); ROUND2 (C, D, A, B, 9, 9); ROUND2 (B, C, D, A, 13, 13); ROUND2 (A, B, C, D, 2, 3); ROUND2 (D, A, B, C, 6, 5); ROUND2 (C, D, A, B, 10, 9); ROUND2 (B, C, D, A, 14, 13); ROUND2 (A, B, C, D, 3, 3); ROUND2 (D, A, B, C, 7, 5); ROUND2 (C, D, A, B, 11, 9); ROUND2 (B, C, D, A, 15, 13); ROUND3 (A, B, C, D, 0, 3); ROUND3 (D, A, B, C, 8, 9); ROUND3 (C, D, A, B, 4, 11); ROUND3 (B, C, D, A, 12, 15); ROUND3 (A, B, C, D, 2, 3); ROUND3 (D, A, B, C, 10, 9); ROUND3 (C, D, A, B, 6, 11); ROUND3 (B, C, D, A, 14, 15); ROUND3 (A, B, C, D, 1, 3); ROUND3 (D, A, B, C, 9, 9); ROUND3 (C, D, A, B, 5, 11); ROUND3 (B, C, D, A, 13, 15); ROUND3 (A, B, C, D, 3, 3); ROUND3 (D, A, B, C, 11, 9); ROUND3 (C, D, A, B, 7, 11); ROUND3 (B, C, D, A, 15, 15); A += AA; B += BB; C += CC; D += DD; for (j = 0; j < 16; j++) X[j] = 0; m->A = A; m->B = B; m->C = C; m->D = D; } static void copy64 (unsigned *M, unsigned char *in) { int i; for (i = 0; i < 16; i++) M[i] = (in[i * 4 + 3] << 24) | (in[i * 4 + 2] << 16) | (in[i * 4 + 1] << 8) | (in[i * 4 + 0] << 0); } static void copy4 (unsigned char *out, unsigned x) { out[0] = (unsigned char)(x & 0xFF); out[1] = (unsigned char)((x >> 8) & 0xFF); out[2] = (unsigned char)((x >> 16) & 0xFF); out[3] = (unsigned char)((x >> 24) & 0xFF); } void mdfour_begin (struct mdfour *md) { md->A = 0x67452301; md->B = 0xefcdab89; md->C = 0x98badcfe; md->D = 0x10325476; md->totalN = 0; } static void mdfour_tail (unsigned char *in, int n) { unsigned char buf[128]; unsigned M[16]; unsigned b; m->totalN += n; b = m->totalN * 8; memset (buf, 0, 128); if (n) memcpy (buf, in, n); buf[n] = 0x80; if (n <= 55) { copy4 (buf + 56, b); copy64 (M, buf); mdfour64 (M); } else { copy4 (buf + 120, b); copy64 (M, buf); mdfour64 (M); copy64 (M, buf + 64); mdfour64 (M); } } void mdfour_update (struct mdfour *md, unsigned char *in, int n) { unsigned M[16]; if (n == 0) mdfour_tail (in, n); m = md; while (n >= 64) { copy64 (M, in); mdfour64 (M); in += 64; n -= 64; m->totalN += 64; } mdfour_tail (in, n); } void mdfour_result (struct mdfour *md, unsigned char *out) { m = md; copy4 (out, m->A); copy4 (out + 4, m->B); copy4 (out + 8, m->C); copy4 (out + 12, m->D); } void mdfour (unsigned char *out, unsigned char *in, int n) { struct mdfour md; mdfour_begin (&md); mdfour_update (&md, in, n); mdfour_result (&md, out); } unsigned Com_BlockChecksum (void *buffer, int length) { unsigned char digest[16]; mdfour ((unsigned char *) digest, (unsigned char *) buffer, length); /* * This is intentional. digest can't be 4 unsigned integers because of * possible alignment issues. */ return ((unsigned *)digest)[0] ^ ((unsigned *)digest)[1] ^ ((unsigned *)digest)[2] ^ ((unsigned *)digest)[3]; } alien-arena-7.66+dfsg/source/qcommon/cvar.c0000600000175000017500000004156312161402010017663 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. Copyright (C) 2010 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // cvar.c -- dynamic variable tracking #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "qcommon.h" cvar_t *cvar_vars; /* ============ Cvar_InfoValidate ============ */ static qboolean Cvar_InfoValidate (const char *s) { if (strstr (s, "\\")) return false; if (strstr (s, "\"")) return false; if (strstr (s, ";")) return false; return true; } /* ============ Cvar_FindVar ============ */ static cvar_t *Cvar_FindVar (const char *var_name) { cvar_t *var; unsigned int i, hash_key; COMPUTE_HASH_KEY( hash_key, var_name , i ); for (var=cvar_vars ; var && var->hash_key <= hash_key ; var=var->next) if (var->hash_key == hash_key && !Q_strcasecmp (var_name, var->name)) return var; return NULL; } /* ============ Cvar_VariableValue ============ */ float Cvar_VariableValue (const char *var_name) { cvar_t *var; var = Cvar_FindVar (var_name); if (!var) return 0; return var->value; } /* ============ Cvar_VariableString ============ */ char *Cvar_VariableString (const char *var_name) { cvar_t *var; var = Cvar_FindVar (var_name); if (!var) return ""; return var->string; } /* ============ Cvar_CompleteVariable ============ */ char *Cvar_CompleteVariable (const char *partial) { cvar_t *cvar; int len, i; unsigned int hash_key; len = strlen(partial); if (!len) return NULL; // check exact match COMPUTE_HASH_KEY( hash_key, partial , i ); for (cvar=cvar_vars ; cvar && cvar->hash_key <= hash_key; cvar=cvar->next) if (cvar->hash_key == hash_key && !Q_strcasecmp (partial,cvar->name)) return cvar->name; // check partial match for (cvar=cvar_vars ; cvar ; cvar=cvar->next) if (!Q_strncasecmp (partial,cvar->name, len)) return cvar->name; return NULL; } /* ============ Cvar_Allocate Creates a new variable's record ============ */ inline static cvar_t *Cvar_Allocate(const char *var_name, const char *var_value, int flags, unsigned int hash_key) { cvar_t *nvar; nvar = Z_Malloc (sizeof(cvar_t)); nvar->name = CopyString (var_name); nvar->string = CopyString (var_value); nvar->modified = true; nvar->value = atof (nvar->string); nvar->default_value = atof (nvar->string); nvar->integer = atoi (nvar->string); nvar->flags = flags; nvar->hash_key = hash_key; nvar->description = NULL; return nvar; } /* ============ Anon_Cvar_Allocate Initializes a new cvar struct holding just a value, with no name in it. Used in some places where a weak-typed variable is needed. ============ */ void Anon_Cvar_Set(cvar_t *nvar, const char *var_value) { if (nvar->string) Z_Free (nvar->string); nvar->string = CopyString (var_value); nvar->value = atof (nvar->string); nvar->default_value = atof (nvar->string); nvar->integer = atoi (nvar->string); } /* ============ Cvar_AddBetween Adds a variable between two others. ============ */ inline static cvar_t *Cvar_AddBetween(const char *var_name, const char *var_value, int flags, unsigned int hash_key,cvar_t **prev, cvar_t *next) { cvar_t *nvar; // variable needs to be created, check parameters if (!var_value) return NULL; if (flags & (CVAR_USERINFO | CVAR_SERVERINFO | CVAR_GAMEINFO)) { if (!Cvar_InfoValidate (var_value)) { Com_Printf("invalid info cvar value\n"); return NULL; } } // create the variable nvar = Cvar_Allocate( var_name , var_value , flags , hash_key ); // link the variable in nvar->next = next; *prev = nvar; return nvar; } /* ============ Cvar_Get If the variable already exists, the value will not be set The flags will be or'ed in if the variable exists. ============ */ cvar_t *Cvar_Get (const char *var_name, const char *var_value, int flags) { cvar_t *var, **prev; unsigned int i, hash_key; // validate variable name if (flags & (CVAR_USERINFO | CVAR_SERVERINFO | CVAR_GAMEINFO)) { if (!Cvar_InfoValidate (var_value)) { Com_Printf("invalid info cvar value\n"); return NULL; } } // try finding the variable prev = &cvar_vars; COMPUTE_HASH_KEY( hash_key , var_name , i ); for (var = cvar_vars ; var && var->hash_key <= hash_key ; var=var->next) { if (var->hash_key == hash_key && !Q_strcasecmp (var_name, var->name)) { var->flags |= flags; if (var_value) var->default_value = atof (var_value); return var; } prev = &( var->next ); } return Cvar_AddBetween(var_name , var_value , flags , hash_key , prev , var); } /* ============ Cvar_FindOrCreate This function is mostly similar to Cvar_Get(name,value,0). However, it starts by attempting to find the variable, as there are no flags. In addition, it returns a boolean depending on whether the variable was found or created, and sets the pointer to the variable through a parameter. ============ */ inline static qboolean Cvar_FindOrCreate ( const char *var_name, const char *var_value, int flags, cvar_t **found) { cvar_t *var, **prev; unsigned int i, hash_key; // try finding the variable prev = &cvar_vars; COMPUTE_HASH_KEY( hash_key , var_name , i ); for (var = cvar_vars ; var && var->hash_key <= hash_key ; var=var->next) { if (var->hash_key == hash_key && !Q_strcasecmp (var_name, var->name)) { var->flags |= flags; *found = var; return true; } prev = &( var->next ); } *found = Cvar_AddBetween(var_name , var_value , flags , hash_key , prev , var); return false; } /* ============ Cvar_Set2 ============ */ cvar_t *Cvar_Set2 (const char *var_name, const char *value, qboolean force) { cvar_t *var; // Find the variable; if it does not exist, create it and return at once if (!Cvar_FindOrCreate (var_name, value, 0, &var)) return var; if (var->flags & (CVAR_USERINFO | CVAR_SERVERINFO | CVAR_GAMEINFO)) { if (!Cvar_InfoValidate (value)) { Com_Printf("invalid info cvar value\n"); return var; } } if (!force) { if (var->flags & CVAR_NOSET) { Com_Printf ("%s is write protected.\n", var_name); return var; } if (var->flags & CVAR_LATCH) { if (var->latched_string) { if (strcmp(value, var->latched_string) == 0) return var; Z_Free (var->latched_string); } else { if (strcmp(value, var->string) == 0) return var; } if (Com_ServerState()) { Com_Printf ("%s cvar will be changed for next game.\n", var_name); Com_Printf( " startmap will start next game.\n"); var->latched_string = CopyString(value); } else { var->string = CopyString(value); var->value = atof (var->string); var->integer = atoi (var->string); if (!Q_strcasecmp(var->name, "game")) { FS_SetGamedir (var->string); FS_ExecAutoexec (); } } return var; } } else { if (var->latched_string) { Z_Free (var->latched_string); var->latched_string = NULL; } } if (!strcmp(value, var->string)) return var; // not changed var->modified = true; if (var->flags & CVAR_USERINFO) userinfo_modified = true; // transmit at next oportunity Z_Free (var->string); // free the old value string var->string = CopyString(value); var->value = atof (var->string); var->integer = atoi(var->string); return var; } /* ============ Cvar_ForceSet ============ */ cvar_t *Cvar_ForceSet (const char *var_name, const char *value) { return Cvar_Set2 (var_name, value, true); } /* ============ Cvar_Set ============ */ void Cvar_Set (const char *var_name, const char *value) { (void)Cvar_Set2 (var_name, value, false); } /* ============ Cvar_FullSet ============ */ void Cvar_FullSet (const char *var_name, const char *value, int flags) { cvar_t *var; if (!Cvar_FindOrCreate (var_name, value, flags, &var)) return; var->modified = true; if (var->flags & CVAR_USERINFO) userinfo_modified = true; // transmit at next oportunity Z_Free (var->string); // free the old value string var->string = CopyString(value); var->value = atof (var->string); var->default_value = var->value; var->integer = atoi(var->string); var->flags = flags; } /* ============ Cvar_SetValue ============ */ void Cvar_SetValue (const char *var_name, float value) { char val[32]; if (value == (int)value) Com_sprintf (val, sizeof(val), "%i",(int)value); else Com_sprintf (val, sizeof(val), "%f",value); Cvar_Set (var_name, val); } /* ============ Cvar_GetLatchedVars Any variables with latched values will now be updated ============ */ void Cvar_GetLatchedVars (void) { cvar_t *var; for (var = cvar_vars ; var ; var = var->next) { if (!var->latched_string) continue; // observe when latched cvars are updated Com_Printf("Updating latched cvar %s from %s to %s\n", var->name, var->string, var->latched_string ); Z_Free (var->string); var->string = var->latched_string; var->latched_string = NULL; var->value = atof(var->string); var->integer = atoi(var->string); if (!Q_strcasecmp(var->name, "game")) { FS_SetGamedir (var->string); FS_ExecAutoexec (); } } } /* ============ Cvar_Command Handles variable inspection and changing from the console ============ */ qboolean Cvar_Command (void) { cvar_t *v; // check variables v = Cvar_FindVar (Cmd_Argv(0)); if (!v) return false; // perform a variable print or set if (Cmd_Argc() == 1) { Com_Printf ("\"%s\" is \"%s\"\n", v->name, v->string); return true; } Cvar_Set (v->name, Cmd_Argv(1)); return true; } /* ============ Cvar_Set_f Allows setting and defining of arbitrary cvars from console ============ */ void Cvar_Set_f (void) { int c; int flags; c = Cmd_Argc(); if (c != 3 && c != 4) { Com_Printf ("usage: set [u / s / g]\n"); return; } if (c == 4) { if (!strcmp(Cmd_Argv(3), "u")) flags = CVAR_USERINFO; else if (!strcmp(Cmd_Argv(3), "s")) flags = CVAR_SERVERINFO; else if (!strcmp(Cmd_Argv(3), "g")) flags = CVAR_GAMEINFO; else { Com_Printf ("flags can only be 'u', 's', or 'g'\n"); return; } Cvar_FullSet (Cmd_Argv(1), Cmd_Argv(2), flags); } else Cvar_Set (Cmd_Argv(1), Cmd_Argv(2)); } /* ============ Cvar_WriteVariables Appends lines containing "set variable value" for all variables with the archive flag set to true. ============ */ void Cvar_WriteVariables (char *path) { cvar_t *var; char buffer[1024]; FILE *f; f = fopen (path, "a"); for (var = cvar_vars ; var ; var = var->next) { if (var->flags & CVAR_ARCHIVE) { Com_sprintf (buffer, sizeof(buffer), "set %s \"%s\"\n", var->name, var->string); fprintf (f, "%s", buffer); } } fclose (f); } /* ============ Cvar_List_f List all cvars, also displaying their documentation if appropriate ============ */ void Cvar_List_f (void) { cvar_t *var; int i; i = 0; for (var = cvar_vars ; var ; var = var->next, i++) { if (var->flags & CVAR_ARCHIVE) Com_Printf ("*"); else Com_Printf (" "); if (var->flags & CVAR_USERINFO) Com_Printf ("U"); else Com_Printf (" "); if (var->flags & CVAR_SERVERINFO) Com_Printf ("S"); else Com_Printf (" "); if (var->flags & CVAR_NOSET) Com_Printf ("-"); else if (var->flags & CVAR_LATCH) Com_Printf ("L"); else Com_Printf (" "); Com_Printf (" %s \"%s\"", var->name, var->string); if (var->description) Com_Printf (" - %s", var->description); Com_Printf ("\n"); } Com_Printf ("%i cvars\n", i); } /* ============ Cvar_Help_f If the cvar exists, display its current value and documentation ============ */ void Cvar_Help_f (void) { cvar_t *var; char *var_name; int flags; if (Cmd_Argc() != 2) { Com_Printf ("Usage: help \n"); Com_Printf ("Displays the cvar's type, value, and help string if present.\n"); return; } var_name = Cmd_Argv(1); var = Cvar_Get (var_name, 0, 0); if (var == NULL) { Com_Printf ("Nonexistant cvar \"%s\"\n", var_name); return; } Com_Printf ("Name: \"%s\"\n", var_name); flags = var->flags; if (flags != 0) { Com_Printf ("Type: "); #define HANDLE_FLAG(flag,str)\ if (flags & (flag))\ {\ Com_Printf (str);\ flags &= ~(flag);\ if (flags != 0) \ Com_Printf (", ");\ } HANDLE_FLAG (CVAR_ARCHIVE, "saved in config.cfg"); HANDLE_FLAG (CVAR_USERINFO, "player setting"); HANDLE_FLAG (CVAR_SERVERINFO, "server setting"); HANDLE_FLAG (CVAR_NOSET, "can be set only at the command line"); HANDLE_FLAG (CVAR_LATCH, "changes not applied until next game"); HANDLE_FLAG (CVAR_ROM, "read-only"); HANDLE_FLAG (CVAR_GAMEINFO, "gameplay setting"); HANDLE_FLAG (CVAR_PROFILE, "saved in profile.cfg"); // Usually, at most one of these will be set. HANDLE_FLAG (CVARDOC_BOOL, "0 for disabled, nonzero for enabled"); HANDLE_FLAG (CVARDOC_STR, "not a number"); HANDLE_FLAG (CVARDOC_FLOAT, "floating-point number"); HANDLE_FLAG (CVARDOC_INT, "integer"); #undef HANDLE_FLAG Com_Printf ("\n"); } Com_Printf ("Value: \"%s\"\n", var->string); if (var->description != NULL) Com_Printf ("Description: %s\n", var->description); } qboolean userinfo_modified; char *Cvar_BitInfo (int bit) { static char info[MAX_INFO_STRING]; cvar_t *var; info[0] = 0; for (var = cvar_vars ; var ; var = var->next) { if (var->flags & bit) { Info_SetValueForKey (info, var->name, var->string); } } return info; } // returns an info string containing all the CVAR_USERINFO cvars char *Cvar_Userinfo (void) { return Cvar_BitInfo (CVAR_USERINFO); } // returns an info string containing all the CVAR_SERVERINFO cvars char *Cvar_Serverinfo (void) { //add the "mods" field char *gameinfo; char ruleset[MAX_INFO_KEY]; char *token; char lasttoken[MAX_INFO_KEY]; char current_rule[MAX_INFO_KEY]; static char info[MAX_INFO_STRING]; cvar_t *cur_cvr; Com_sprintf(info, sizeof(info), Cvar_BitInfo (CVAR_SERVERINFO)); gameinfo = Cvar_BitInfo (CVAR_GAMEINFO); lasttoken[0] = 0; memset(ruleset, 0, sizeof(ruleset)); token = strtok (gameinfo, "\\"); while (token) { cur_cvr = Cvar_Get(lasttoken, NULL, 0); if (!cur_cvr || !strlen(token) || (atof(token) == cur_cvr->default_value)) { //cvar either doesn't exist or is set to its default value //we only send existent, non-default cvars current_rule[0] = 0; //empty string } else if (atof(token) == 1.0f) { //if the value is 1, don't add the value Com_sprintf(current_rule, sizeof(current_rule), "%%%s", lasttoken); } else { //any value which is not 1 will be displayed Com_sprintf(current_rule, sizeof(current_rule), "%%%s=%s", lasttoken, token); } if (strlen(current_rule)+strlen(ruleset)+strlen("mods")+strlen("\\\\")+strlen(info) >= MAX_INFO_STRING) //this mod cannot be added to the ruleset because it would make //ruleset too long to fit in info. break; strncat(ruleset, current_rule, MAX_INFO_KEY-strlen(ruleset)-1); Com_sprintf(lasttoken, sizeof(lasttoken), "%s", token); token = strtok(NULL, "\\"); } Info_SetValueForKey (info, "mods", ruleset); return info; } void Cvar_Describe(cvar_t *var, const char *description_string) { if (var == NULL) return; if (var->description != NULL) Z_Free (var->description); if (description_string == NULL) var->description = NULL; else var->description = CopyString (description_string); } void Cvar_Describe_ByName(const char *var_name, const char *description_string) { cvar_t *var; if (var_name == NULL) return; var = Cvar_Get (var_name, 0, 0); Cvar_Describe (var, description_string); } /* ============ Cvar_Init Reads in all archived cvars ============ */ void Cvar_Init (void) { Cmd_AddCommand ("set", Cvar_Set_f); Cmd_AddCommand ("cvarlist", Cvar_List_f); Cmd_AddCommand ("help", Cvar_Help_f); } alien-arena-7.66+dfsg/source/qcommon/qfiles.h0000600000175000017500000003317612161402010020221 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // // qfiles.h: quake file formats // This file must be identical in the quake and utils directories // /* ======================================================================== The .pak files are just a linear collapse of a directory tree ======================================================================== */ #define IDPAKHEADER (('K'<<24)+('C'<<16)+('A'<<8)+'P') typedef struct { char name[56]; int filepos, filelen; } dpackfile_t; typedef struct { int ident; // == IDPAKHEADER int dirofs; int dirlen; } dpackheader_t; #define MAX_FILES_IN_PACK 4096 /* ======================================================================== PCX files are used for as many images as possible ======================================================================== */ typedef struct { char manufacturer; char version; char encoding; char bits_per_pixel; unsigned short xmin,ymin,xmax,ymax; unsigned short hres,vres; unsigned char palette[48]; char reserved; char color_planes; unsigned short bytes_per_line; unsigned short palette_type; char filler[58]; unsigned char data; // unbounded } pcx_t; /* ======================================================================== .MD2 triangle model file format ======================================================================== */ #define IDALIASHEADER (('2'<<24)+('P'<<16)+('D'<<8)+'I') #define ALIAS_VERSION 8 #define MAX_TRIANGLES 4096 #define MAX_VERTS 2048 #define MAX_FRAMES 512 #define MAX_MD2SKINS 32 #define MAX_SKINNAME 64 typedef struct { short s; short t; } dstvert_t; typedef struct { float s; float t; } fstvert_t; typedef struct { short index_xyz[3]; short index_st[3]; } dtriangle_t; typedef struct { byte v[3]; // scaled byte to fit in frame mins/maxs byte lightnormalindex; } dtrivertx_t; #define DTRIVERTX_V0 0 #define DTRIVERTX_V1 1 #define DTRIVERTX_V2 2 #define DTRIVERTX_LNI 3 #define DTRIVERTX_SIZE 4 typedef struct { float scale[3]; // multiply byte verts by this float translate[3]; // then add this char name[16]; // frame name from grabbing dtrivertx_t verts[1]; // variable sized } daliasframe_t; // the glcmd format: // a positive integer starts a tristrip command, followed by that many // vertex structures. // a negative integer starts a trifan command, followed by -x vertexes // a zero indicates the end of the command list. // a vertex consists of a floating point s, a floating point t, // and an integer vertex index. typedef struct { int ident; int version; int skinwidth; int skinheight; int framesize; // byte size of each frame int num_skins; int num_xyz; int num_st; // greater than num_xyz for seams int num_tris; int num_glcmds; // dwords in strip/fan command list int num_frames; int ofs_skins; // each skin is a MAX_SKINNAME string int ofs_st; // byte offset from start for stverts int ofs_tris; // offset for dtriangles int ofs_frames; // offset for first frame int ofs_glcmds; int ofs_end; // end of file } dmdl_t; /* ============================================================================== .WAL texture file format ============================================================================== */ #define MIPLEVELS 4 typedef struct miptex_s { char name[32]; unsigned width, height; unsigned offsets[MIPLEVELS]; // four mip maps stored char animname[32]; // next frame in animation chain int flags; int contents; int value; } miptex_t; /* ============================================================================== .BSP file format ============================================================================== */ #define IDBSPHEADER (('P'<<24)+('S'<<16)+('B'<<8)+'I') // little-endian "IBSP" #define BSPVERSION 38 // upper design bounds // leaffaces, leafbrushes, planes, and verts are still bounded by // 16 bit short limits #define MAX_MAP_MODELS 1024 #define MAX_MAP_BRUSHES 8192 #define MAX_MAP_ENTITIES 2048 #define MAX_MAP_ENTSTRING 0x40000 #define MAX_MAP_TEXINFO 8192 #define MAX_MAP_AREAS 256 #define MAX_MAP_AREAPORTALS 1024 #define MAX_MAP_PLANES 65536 #define MAX_MAP_NODES 65536 #define MAX_MAP_BRUSHSIDES 65536 #define MAX_MAP_LEAFS 65536 #define MAX_MAP_VERTS 65536 #define MAX_MAP_FACES 65536 #define MAX_MAP_LEAFFACES 65536 #define MAX_MAP_LEAFBRUSHES 65536 #define MAX_MAP_PORTALS 65536 #define MAX_MAP_EDGES 128000 #define MAX_MAP_SURFEDGES 256000 #define MAX_MAP_LIGHTING 0x200000 #define MAX_MAP_VISIBILITY 0x100000 // key / value pair sizes #define MAX_KEY 32 #define MAX_VALUE 1024 //============================================================================= typedef struct { int fileofs, filelen; } lump_t; #define LUMP_ENTITIES 0 #define LUMP_PLANES 1 #define LUMP_VERTEXES 2 #define LUMP_VISIBILITY 3 #define LUMP_NODES 4 #define LUMP_TEXINFO 5 #define LUMP_FACES 6 #define LUMP_LIGHTING 7 #define LUMP_LEAFS 8 #define LUMP_LEAFFACES 9 #define LUMP_LEAFBRUSHES 10 #define LUMP_EDGES 11 #define LUMP_SURFEDGES 12 #define LUMP_MODELS 13 #define LUMP_BRUSHES 14 #define LUMP_BRUSHSIDES 15 #define LUMP_POP 16 #define LUMP_AREAS 17 #define LUMP_AREAPORTALS 18 #define HEADER_LUMPS 19 typedef struct { int ident; int version; lump_t lumps[HEADER_LUMPS]; } dheader_t; qboolean checkLumps (lump_t *l, size_t header_size, int *lump_order, void *_file_base, int num_lumps, int file_len); typedef struct { float mins[3], maxs[3]; float origin[3]; // for sounds or lights int headnode; int firstface, numfaces; // submodels just draw faces // without walking the bsp tree } dmodel_t; typedef struct { float point[3]; } 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 // planes (x&~1) and (x&~1)+1 are always opposites typedef struct { float normal[3]; float dist; int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate } dplane_t; // contents flags are seperate bits // a given brush can contribute multiple content bits // multiple brushes can be in a single leaf // these definitions also need to be in q_shared.h! // lower bits are stronger, and will eat weaker brushes completely #define CONTENTS_SOLID 1 // an eye is never valid in a solid #define CONTENTS_WINDOW 2 // translucent, but not watery #define CONTENTS_AUX 4 #define CONTENTS_LAVA 8 #define CONTENTS_SLIME 16 #define CONTENTS_WATER 32 #define CONTENTS_MIST 64 #define LAST_VISIBLE_CONTENTS 64 // remaining contents are non-visible, and don't eat brushes #define CONTENTS_AREAPORTAL 0x8000 #define CONTENTS_PLAYERCLIP 0x10000 #define CONTENTS_MONSTERCLIP 0x20000 // currents can be added to any other contents, and may be mixed #define CONTENTS_CURRENT_0 0x40000 #define CONTENTS_CURRENT_90 0x80000 #define CONTENTS_CURRENT_180 0x100000 #define CONTENTS_CURRENT_270 0x200000 #define CONTENTS_CURRENT_UP 0x400000 #define CONTENTS_CURRENT_DOWN 0x800000 #define CONTENTS_ORIGIN 0x1000000 // removed before bsping an entity #define CONTENTS_MONSTER 0x2000000 // should never be on a brush, only in game #define CONTENTS_DEADMONSTER 0x4000000 #define CONTENTS_DETAIL 0x8000000 // brushes to be added after vis leafs #define CONTENTS_TRANSLUCENT 0x10000000 // auto set if any surface has trans #define CONTENTS_LADDER 0x20000000 #define SURF_LIGHT 0x1 // value will hold the light strength #define SURF_SLICK 0x2 // effects game physics #define SURF_SKY 0x4 // don't draw, but add to skybox #define SURF_WARP 0x8 // turbulent water warp #define SURF_TRANS33 0x10 #define SURF_TRANS66 0x20 #define SURF_FLOWING 0x40 // scroll towards angle #define SURF_NODRAW 0x80 // don't bother referencing the texture #define SURF_BLOOD 0x400 // dripping blood surface #define SURF_WATER 0x800 // dripping water surface #define SURF_SHINY 0x1000 // shiny wet surface #define SURF_UNDERWATER 0x2000 // reflecting ripples; applied automatically // to underwater surfs but could be applied // manually as well typedef struct { int planenum; int children[2]; // negative numbers are -(leafs+1), not nodes short mins[3]; // for frustum culling short maxs[3]; unsigned short firstface; unsigned short numfaces; // counting both sides } dnode_t; typedef struct texinfo_s { float vecs[2][4]; // [s/t][xyz offset] int flags; // miptex flags + overrides int value; // light emission, etc char texture[32]; // texture name (textures/*.wal) int nexttexinfo; // for animations, -1 = end of chain } texinfo_t; // 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 } dedge_t; #define MAXLIGHTMAPS 4 typedef struct { unsigned 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 } dface_t; typedef struct { int contents; // OR of all brushes (not needed?) short cluster; short area; short mins[3]; // for frustum culling short maxs[3]; unsigned short firstleafface; unsigned short numleaffaces; unsigned short firstleafbrush; unsigned short numleafbrushes; } dleaf_t; typedef struct { unsigned short planenum; // facing out of the leaf short texinfo; } dbrushside_t; typedef struct { int firstside; int numsides; int contents; } dbrush_t; #define ANGLE_UP -1 #define ANGLE_DOWN -2 // the visibility lump consists of a header with a count, then // byte offsets for the PVS and PHS of each cluster, then the raw // compressed bit vectors #define DVIS_PVS 0 #define DVIS_PHS 1 typedef struct { int numclusters; int bitofs[8][2]; // bitofs[numclusters][2] } dvis_t; // each area has a list of portals that lead into other areas // when portals are closed, other areas may not be visible or // hearable even if the vis info says that it should be typedef struct { int portalnum; int otherarea; } dareaportal_t; typedef struct { int numareaportals; int firstareaportal; } darea_t; // FOR REFINE #define MAX_OVERRIDE_LIGHTING 0x6000000 //2048*2048*8*3 // little-endian "LTMP" for "lightmap" #define IDLIGHTMAPHEADER (('P'<<24)+('M'<<16)+('T'<<8)+'L') // Increase this number whenever incompatible changes are made to the file // format #define LTMPVERSION 2 // Increase this number whenever backwards-compatible changes are made to the // file format #define LTMPVERSION_MINOR 0 #define LTMP_LUMP_FACELOOKUP 0 #define LTMP_LUMP_LIGHTING 1 #define LTMP_LUMPS 2 // Each override has its own pixel format. Currently, the only one is 24-bit // RGB, but we may eventually add S3TC/ASTC formats as well. #define LTMP_PIXFMT_RGB24 0 #define LTMP_NUM_SUPPORTED_PIXFMTS 1 // Current versions of the client will refuse to open lightmap files with more // data than this. However, current versions of the map compiler will refuse // to create files anywhere near this big, and the client has other, stricter // restrictions on how much lightmap data it will actually use. #define LTMP_MAX_UNCOMPRESSED_DATA (\ sizeof(lightmapheader_t)+\ sizeof(ltmp_facelookup_t)*MAX_MAP_FACES*4+\ MAX_OVERRIDE_LIGHTING*4+16\ ) typedef struct { int ident; int version; int version_minor; lump_t lumps[LTMP_LUMPS]; } lightmapheader_t; // There may be zero or more of these for each surface (maximum total number // of these is four times the maximum number of surfaces.) The client is // responsible for picking which if any to use for each surface. Current // behavior of the client is to skip any pixel formats it doesn't understand, // and otherwise pick the last one in the list for each surface. However, that // behavior may change arbitrarily in the future. typedef struct { int offset; // an offset in LTMP_LUMP_LIGHTING, starting at 1 int facenum; // the face being overridden by this entry, // starting at 0 int format; // currently only LTMP_PIXFMT_RGB24 // qrad3 may output different hights/widths for each face at some point in // the future int width; // width in pixels int height; // height in pixels // qrad3 may output heights scaled differently from widths at some point // in the future float xscale; // xscale in game units per lightmap pixel float yscale; // yscale in game units per lightmap pixel } ltmp_facelookup_t; alien-arena-7.66+dfsg/source/qcommon/crc.c0000600000175000017500000000724112161402010017472 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* crc.c */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "qcommon.h" // 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 static unsigned short crctable[256] = { 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 }; void CRC_Init(unsigned short *crcvalue) { *crcvalue = CRC_INIT_VALUE; } void CRC_ProcessByte(unsigned short *crcvalue, byte data) { *crcvalue = (*crcvalue << 8) ^ crctable[(*crcvalue >> 8) ^ data]; } unsigned short CRC_Value(unsigned short crcvalue) { return crcvalue ^ CRC_XOR_VALUE; } unsigned short CRC_Block (byte *start, int count) { unsigned short crc; CRC_Init (&crc); while (count--) crc = (crc << 8) ^ crctable[(crc >> 8) ^ *start++]; return crc; } alien-arena-7.66+dfsg/source/Makefile.am0000600000175000017500000003453212161402010017145 0ustar zero79zero79# Process this file with automake to produce Makefile.in # # Copyright (C) 2010 COR Entertainment, LLC # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # if USE_SYSTEM_LIBODE noinst_LIBRARIES = libgame.a else if BUILD_CLIENT noinst_LIBRARIES = libgame.a libode.a else noinst_LIBRARIES = libgame.a endif endif # # Setup the integrated ODE library. # note: the -isystem option is for making #include look in # the build directory before the system directory. # if USE_SYSTEM_LIBODE AM_CPPFLAGS = -I $(top_srcdir)/source else AM_CPPFLAGS = -I $(top_srcdir)/source -isystem $(top_srcdir)/source/unix endif # CPP flags for standard installation if !ALTERNATE_INSTALL AM_CPPFLAGS += -DDATADIR='"$(pkgdatadir)"' endif # Dedicated Server libraries and flags alienarena_ded_LDADD = libgame.a alienarena_ded_CPPFLAGS = $(AM_CPPFLAGS) -DDEDICATED_ONLY # Client libraries and flags alienarena_CPPFLAGS = $(AM_CPPFLAGS) \ $(PTHREAD_CFLAGS) \ $(X11_CLAGS) \ $(DEPS_CFLAGS) \ $(ODE_CFLAGS) \ $(XXF86VM_CFLAGS) \ $(XXF86DGA_CFLAGS) \ $(ZLIB_CFLAGS) if USE_SYSTEM_LIBODE # # alienarena with system libode # alienarena_LDADD = libgame.a \ $(PTHREAD_LIBS) \ $(X11_LIBS) \ $(DEPS_LIBS) \ $(ODE_LIBS) \ $(XXF86VM_LIBS) \ $(XXF86DGA_LIBS) \ $(ZLIB_LIBS) else # # alienarena with integrated libode # alienarena_LDADD = libgame.a \ libode.a \ $(PTHREAD_LIBS) \ $(X11_LIBS) \ $(DEPS_LIBS) \ $(XXF86VM_LIBS) \ $(XXF86DGA_LIBS) \ $(ZLIB_LIBS) \ -lstdc++ libode_a_CPPFLAGS = -I$(top_srcdir)/source/unix/odesrc/OPCODE \ -isystem $(top_srcdir)/source/unix \ -DdDOUBLE \ -DdTRIMESH_ENABLED \ -DdTRIMESH_OPCODE # ODE has an additional custom "no debug" variable libode_a_CPPFLAGS += -DNDEBUG -DdNODEBUG endif if BUILD_WIN32 # On Win32, always build the client # TODO: maybe fixup libs, cppflags hacks bin_PROGRAMS = alienarena alienarena_LDADD += $(WIN32_LIBS) alienarena_CPPFLAGS += -DCURL_STATICLIB -DNDEBUG else # On Unix, always build the server, and the client if BUILD_CLIENT is enabled bin_PROGRAMS = alienarena-ded if BUILD_CLIENT bin_PROGRAMS += alienarena endif endif # common client sources alienarena_SOURCES = \ client/anorms.h \ client/cl_ents.c \ client/cl_fx.c \ client/cl_http.c \ client/client.h \ client/cl_input.c \ client/cl_inv.c \ client/cl_irc.c \ client/cl_main.c \ client/cl_parse.c \ client/cl_pred.c \ client/cl_scrn.c \ client/cl_stats.c \ client/cl_updates.c \ client/cl_tent.c \ client/cl_view.c \ client/console.c \ client/console.h \ client/input.h \ client/keys.c \ client/keys.h \ client/menu.c \ client/qal.c \ client/qal.h \ client/qmenu.c \ client/qmenu.h \ client/ref.h \ client/screen.h \ client/snd_file.c \ client/snd_openal.c \ client/sound.h \ client/vid.h \ game/game.h \ game/q_shared.c \ game/q_shared.h \ qcommon/cmd.c \ qcommon/cmodel.c \ qcommon/common.c \ qcommon/crc.c \ qcommon/crc.h \ qcommon/cvar.c \ qcommon/files.c \ qcommon/htable.c \ qcommon/htable.h \ qcommon/md5.c \ qcommon/md5.h \ qcommon/mdfour.c \ qcommon/net_chan.c \ qcommon/pmove.c \ qcommon/qcommon.h \ qcommon/qfiles.h \ ref_gl/anorms.h \ ref_gl/anormtab.h \ ref_gl/glext.h \ ref_gl/qgl.h \ ref_gl/r_bloom.c \ ref_gl/r_draw.c \ ref_gl/r_image.c \ ref_gl/r_image.h \ ref_gl/r_iqm.h \ ref_gl/r_iqm.c \ ref_gl/r_light.c \ ref_gl/r_local.h \ ref_gl/r_lodcalc.h \ ref_gl/r_main.c \ ref_gl/r_math.c \ ref_gl/r_math.h \ ref_gl/r_mesh.c \ ref_gl/r_misc.c \ ref_gl/r_model.c \ ref_gl/r_model.h \ ref_gl/r_particle.c \ ref_gl/r_postprocess.c \ ref_gl/r_program.c \ ref_gl/r_ragdoll.c \ ref_gl/r_ragdoll.h \ ref_gl/r_script.c \ ref_gl/r_script.h \ ref_gl/r_shadowmaps.c \ ref_gl/r_shadows.c \ ref_gl/r_surf.c \ ref_gl/r_text.c \ ref_gl/r_text.h \ ref_gl/r_ttf.c \ ref_gl/r_ttf.h \ ref_gl/r_varray.c \ ref_gl/r_vbo.c \ ref_gl/r_vlights.c \ ref_gl/r_warp.c \ ref_gl/warpsin.h \ server/server.h \ server/sv_ccmds.c \ server/sv_ents.c \ server/sv_game.c \ server/sv_init.c \ server/sv_main.c \ server/sv_send.c \ server/sv_user.c \ server/sv_world.c \ unix/glob.c \ unix/glob.h # Unix Client sources if BUILD_UNIX alienarena_SOURCES += \ unix/gl_glx.c \ unix/glw_unix.h \ unix/net_udp.c \ unix/qal_unix.c \ unix/qgl_unix.c \ unix/q_shunix.c \ unix/rw_unix.c \ unix/rw_unix.h \ unix/sys_unix.c \ unix/vid_so.c endif # Win32 MinGW Client sources if BUILD_WIN32 alienarena_SOURCES += \ win32/conproc.c \ win32/conproc.h \ win32/glw_imp.c \ win32/glw_win.h \ win32/in_win.c \ win32/net_wins.c \ win32/qal_win.c \ win32/qgl_win.c \ win32/q_shwin.c \ win32/sys_win.c \ win32/vid_dll.c \ win32/winquake.h \ win32/resource.h endif # Dedicated Server sources (Unix only) alienarena_ded_SOURCES = \ client/anorms.h \ game/game.h \ game/q_shared.c \ game/q_shared.h \ null/cl_null.c \ qcommon/cmd.c \ qcommon/cmodel.c \ qcommon/common.c \ qcommon/crc.c \ qcommon/cvar.c \ qcommon/files.c \ qcommon/htable.c \ qcommon/htable.h \ qcommon/mdfour.c \ qcommon/net_chan.c \ qcommon/pmove.c \ qcommon/qcommon.h \ qcommon/qfiles.h \ server/server.h \ server/sv_ccmds.c \ server/sv_ents.c \ server/sv_game.c \ server/sv_init.c \ server/sv_main.c \ server/sv_send.c \ server/sv_user.c \ server/sv_world.c \ unix/glob.c \ unix/glob.h \ unix/net_udp.c \ unix/q_shunix.c \ unix/rw_unix.h \ unix/sys_unix.c # Game module sources libgame_a_SOURCES = \ client/anorms.h \ game/acesrc/acebot_ai.c \ game/acesrc/acebot_cmds.c \ game/acesrc/acebot.h \ game/acesrc/acebot_items.c \ game/acesrc/acebot_movement.c \ game/acesrc/acebot_nodes.c \ game/acesrc/acebot_spawn.c \ game/c_cam.c \ game/cow.h \ game/g_ai.c \ game/game.h \ game/g_chase.c \ game/g_cmds.c \ game/g_combat.c \ game/g_cow.c \ game/g_ctf.c \ game/g_deathball.c \ game/g_deathray.c \ game/g_deathray.h \ game/g_func.c \ game/g_items.c \ game/g_local.h \ game/g_main.c \ game/g_misc.c \ game/g_monster.c \ game/g_phys.c \ game/g_save.c \ game/g_spawn.c \ game/g_svcmds.c \ game/g_target.c \ game/g_trigger.c \ game/g_unlagged.c \ game/g_utils.c \ game/g_vehicles.c \ game/g_spider.c \ game/g_spider.h \ game/g_weapon.c \ game/m_move.c \ game/m_player.h \ game/p_client.c \ game/p_hud.c \ game/p_trail.c \ game/p_view.c \ game/p_weapon.c \ game/q_shared.c \ game/q_shared.h \ qcommon/qfiles.h # # Integrated Open Dynamic Engine (ODE) Library # libode_a_SOURCES = \ unix/ode/collision.h \ unix/ode/collision_space.h \ unix/ode/collision_trimesh.h \ unix/ode/common.h \ unix/ode/compatibility.h \ unix/ode/contact.h \ unix/ode/error.h \ unix/ode/export-dif.h \ unix/ode/mass.h \ unix/ode/matrix.h \ unix/ode/memory.h \ unix/ode/misc.h \ unix/ode/objects.h \ unix/ode/odeconfig.h \ unix/ode/odecpp_collision.h \ unix/ode/odecpp.h \ unix/ode/ode.h \ unix/ode/odeinit.h \ unix/ode/odemath.h \ unix/ode/rotation.h \ unix/ode/timer.h libode_a_SOURCES += \ unix/odesrc/array.cpp \ unix/odesrc/array.h \ unix/odesrc/box.cpp \ unix/odesrc/capsule.cpp \ unix/odesrc/collision_cylinder_box.cpp \ unix/odesrc/collision_cylinder_plane.cpp \ unix/odesrc/collision_cylinder_sphere.cpp \ unix/odesrc/collision_kernel.cpp \ unix/odesrc/collision_kernel.h \ unix/odesrc/collision_quadtreespace.cpp \ unix/odesrc/collision_sapspace.cpp \ unix/odesrc/collision_space.cpp \ unix/odesrc/collision_space_internal.h \ unix/odesrc/collision_std.h \ unix/odesrc/collision_transform.cpp \ unix/odesrc/collision_transform.h \ unix/odesrc/collision_trimesh_colliders.h \ unix/odesrc/collision_trimesh_disabled.cpp \ unix/odesrc/collision_trimesh_internal.h \ unix/odesrc/collision_util.cpp \ unix/odesrc/collision_util.h \ unix/odesrc/convex.cpp \ unix/odesrc/cylinder.cpp \ unix/odesrc/error.cpp \ unix/odesrc/export-dif.cpp \ unix/odesrc/heightfield.cpp \ unix/odesrc/heightfield.h \ unix/odesrc/lcp.cpp \ unix/odesrc/lcp.h \ unix/odesrc/mass.cpp \ unix/odesrc/mat.cpp \ unix/odesrc/mat.h \ unix/odesrc/matrix.cpp \ unix/odesrc/memory.cpp \ unix/odesrc/misc.cpp \ unix/odesrc/objects.h \ unix/odesrc/obstack.cpp \ unix/odesrc/obstack.h \ unix/odesrc/ode.cpp \ unix/odesrc/odeinit.cpp \ unix/odesrc/odemath.cpp \ unix/odesrc/odeou.h \ unix/odesrc/odetls.h \ unix/odesrc/plane.cpp \ unix/odesrc/quickstep.cpp \ unix/odesrc/quickstep.h \ unix/odesrc/ray.cpp \ unix/odesrc/rotation.cpp \ unix/odesrc/sphere.cpp \ unix/odesrc/step.cpp \ unix/odesrc/stepfast.cpp \ unix/odesrc/step.h \ unix/odesrc/testing.cpp \ unix/odesrc/testing.h \ unix/odesrc/timer.cpp \ unix/odesrc/util.cpp \ unix/odesrc/util.h libode_a_SOURCES += \ unix/odesrc/fastldlt.c \ unix/odesrc/fastltsolve.c \ unix/odesrc/fastdot.c \ unix/odesrc/fastlsolve.c libode_a_SOURCES += \ unix/odesrc/collision_cylinder_trimesh.cpp \ unix/odesrc/collision_trimesh_box.cpp \ unix/odesrc/collision_trimesh_ccylinder.cpp \ unix/odesrc/collision_trimesh_distance.cpp \ unix/odesrc/collision_trimesh_internal.h \ unix/odesrc/collision_trimesh_opcode.cpp \ unix/odesrc/collision_trimesh_plane.cpp \ unix/odesrc/collision_trimesh_ray.cpp \ unix/odesrc/collision_trimesh_sphere.cpp \ unix/odesrc/collision_trimesh_trimesh.cpp \ unix/odesrc/collision_trimesh_trimesh_new.cpp libode_a_SOURCES += \ unix/odesrc/joints/amotor.cpp \ unix/odesrc/joints/amotor.h \ unix/odesrc/joints/ball.cpp \ unix/odesrc/joints/ball.h \ unix/odesrc/joints/contact.cpp \ unix/odesrc/joints/contact.h \ unix/odesrc/joints/fixed.cpp \ unix/odesrc/joints/fixed.h \ unix/odesrc/joints/hinge2.cpp \ unix/odesrc/joints/hinge2.h \ unix/odesrc/joints/hinge.cpp \ unix/odesrc/joints/hinge.h \ unix/odesrc/joints/joint.cpp \ unix/odesrc/joints/joint.h \ unix/odesrc/joints/joint_internal.h \ unix/odesrc/joints/joints.h \ unix/odesrc/joints/lmotor.cpp \ unix/odesrc/joints/lmotor.h \ unix/odesrc/joints/null.cpp \ unix/odesrc/joints/null.h \ unix/odesrc/joints/piston.cpp \ unix/odesrc/joints/piston.h \ unix/odesrc/joints/plane2d.cpp \ unix/odesrc/joints/plane2d.h \ unix/odesrc/joints/pr.cpp \ unix/odesrc/joints/pr.h \ unix/odesrc/joints/pu.cpp \ unix/odesrc/joints/pu.h \ unix/odesrc/joints/slider.cpp \ unix/odesrc/joints/slider.h \ unix/odesrc/joints/universal.cpp \ unix/odesrc/joints/universal.h libode_a_SOURCES += \ unix/odesrc/OPCODE/OPC_AABBCollider.cpp \ unix/odesrc/OPCODE/OPC_AABBCollider.h \ unix/odesrc/OPCODE/OPC_AABBTree.cpp \ unix/odesrc/OPCODE/OPC_AABBTree.h \ unix/odesrc/OPCODE/OPC_BaseModel.cpp \ unix/odesrc/OPCODE/OPC_BaseModel.h \ unix/odesrc/OPCODE/OPC_BoxBoxOverlap.h \ unix/odesrc/OPCODE/OPC_Collider.cpp \ unix/odesrc/OPCODE/OPC_Collider.h \ unix/odesrc/OPCODE/OPC_Common.cpp \ unix/odesrc/OPCODE/OPC_Common.h \ unix/odesrc/OPCODE/OPC_HybridModel.cpp \ unix/odesrc/OPCODE/OPC_HybridModel.h \ unix/odesrc/OPCODE/OPC_IceHook.h \ unix/odesrc/OPCODE/OPC_LSSAABBOverlap.h \ unix/odesrc/OPCODE/OPC_LSSCollider.cpp \ unix/odesrc/OPCODE/OPC_LSSCollider.h \ unix/odesrc/OPCODE/OPC_LSSTriOverlap.h \ unix/odesrc/OPCODE/OPC_MeshInterface.cpp \ unix/odesrc/OPCODE/OPC_MeshInterface.h \ unix/odesrc/OPCODE/OPC_Model.cpp \ unix/odesrc/OPCODE/OPC_Model.h \ unix/odesrc/OPCODE/OPC_OBBCollider.cpp \ unix/odesrc/OPCODE/OPC_OBBCollider.h \ unix/odesrc/OPCODE/Opcode.cpp \ unix/odesrc/OPCODE/Opcode.h \ unix/odesrc/OPCODE/OPC_OptimizedTree.cpp \ unix/odesrc/OPCODE/OPC_OptimizedTree.h \ unix/odesrc/OPCODE/OPC_Picking.cpp \ unix/odesrc/OPCODE/OPC_Picking.h \ unix/odesrc/OPCODE/OPC_PlanesAABBOverlap.h \ unix/odesrc/OPCODE/OPC_PlanesCollider.cpp \ unix/odesrc/OPCODE/OPC_PlanesCollider.h \ unix/odesrc/OPCODE/OPC_PlanesTriOverlap.h \ unix/odesrc/OPCODE/OPC_RayAABBOverlap.h \ unix/odesrc/OPCODE/OPC_RayCollider.cpp \ unix/odesrc/OPCODE/OPC_RayCollider.h \ unix/odesrc/OPCODE/OPC_RayTriOverlap.h \ unix/odesrc/OPCODE/OPC_Settings.h \ unix/odesrc/OPCODE/OPC_SphereAABBOverlap.h \ unix/odesrc/OPCODE/OPC_SphereCollider.cpp \ unix/odesrc/OPCODE/OPC_SphereCollider.h \ unix/odesrc/OPCODE/OPC_SphereTriOverlap.h \ unix/odesrc/OPCODE/OPC_TreeBuilders.cpp \ unix/odesrc/OPCODE/OPC_TreeBuilders.h \ unix/odesrc/OPCODE/OPC_TreeCollider.cpp \ unix/odesrc/OPCODE/OPC_TreeCollider.h \ unix/odesrc/OPCODE/OPC_TriBoxOverlap.h \ unix/odesrc/OPCODE/OPC_TriTriOverlap.h \ unix/odesrc/OPCODE/OPC_VolumeCollider.cpp \ unix/odesrc/OPCODE/OPC_VolumeCollider.h \ unix/odesrc/OPCODE/Stdafx.h libode_a_SOURCES += \ unix/odesrc/OPCODE/Ice/IceAABB.cpp \ unix/odesrc/OPCODE/Ice/IceAABB.h \ unix/odesrc/OPCODE/Ice/IceAxes.h \ unix/odesrc/OPCODE/Ice/IceBoundingSphere.h \ unix/odesrc/OPCODE/Ice/IceContainer.cpp \ unix/odesrc/OPCODE/Ice/IceContainer.h \ unix/odesrc/OPCODE/Ice/IceFPU.h \ unix/odesrc/OPCODE/Ice/IceHPoint.cpp \ unix/odesrc/OPCODE/Ice/IceHPoint.h \ unix/odesrc/OPCODE/Ice/IceIndexedTriangle.cpp \ unix/odesrc/OPCODE/Ice/IceIndexedTriangle.h \ unix/odesrc/OPCODE/Ice/IceLSS.h \ unix/odesrc/OPCODE/Ice/IceMatrix3x3.cpp \ unix/odesrc/OPCODE/Ice/IceMatrix3x3.h \ unix/odesrc/OPCODE/Ice/IceMatrix4x4.cpp \ unix/odesrc/OPCODE/Ice/IceMatrix4x4.h \ unix/odesrc/OPCODE/Ice/IceMemoryMacros.h \ unix/odesrc/OPCODE/Ice/IceOBB.cpp \ unix/odesrc/OPCODE/Ice/IceOBB.h \ unix/odesrc/OPCODE/Ice/IcePairs.h \ unix/odesrc/OPCODE/Ice/IcePlane.cpp \ unix/odesrc/OPCODE/Ice/IcePlane.h \ unix/odesrc/OPCODE/Ice/IcePoint.cpp \ unix/odesrc/OPCODE/Ice/IcePoint.h \ unix/odesrc/OPCODE/Ice/IcePreprocessor.h \ unix/odesrc/OPCODE/Ice/IceRandom.cpp \ unix/odesrc/OPCODE/Ice/IceRandom.h \ unix/odesrc/OPCODE/Ice/IceRay.cpp \ unix/odesrc/OPCODE/Ice/IceRay.h \ unix/odesrc/OPCODE/Ice/IceRevisitedRadix.cpp \ unix/odesrc/OPCODE/Ice/IceRevisitedRadix.h \ unix/odesrc/OPCODE/Ice/IceSegment.cpp \ unix/odesrc/OPCODE/Ice/IceSegment.h \ unix/odesrc/OPCODE/Ice/IceTriangle.cpp \ unix/odesrc/OPCODE/Ice/IceTriangle.h \ unix/odesrc/OPCODE/Ice/IceTriList.h \ unix/odesrc/OPCODE/Ice/IceTypes.h \ unix/odesrc/OPCODE/Ice/IceUtils.cpp \ unix/odesrc/OPCODE/Ice/IceUtils.h alien-arena-7.66+dfsg/source/ref_gl/0000700000175000017500000000000012207204657016360 5ustar zero79zero79alien-arena-7.66+dfsg/source/ref_gl/r_shadowmaps.c0000600000175000017500000011265112161402007021207 0ustar zero79zero79/* Copyright (C) 2010 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "r_local.h" #include "r_ragdoll.h" #include extern void MYgluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar); // GL_EXT_framebuffer_object GLboolean(APIENTRY * qglIsRenderbufferEXT) (GLuint renderbuffer); void (APIENTRY * qglBindRenderbufferEXT) (GLenum target, GLuint renderbuffer); void (APIENTRY * qglDeleteRenderbuffersEXT) (GLsizei n, const GLuint * renderbuffers); void (APIENTRY * qglGenRenderbuffersEXT) (GLsizei n, GLuint * renderbuffers); void (APIENTRY * qglRenderbufferStorageEXT) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); void (APIENTRY * qglGetRenderbufferParameterivEXT) (GLenum target, GLenum pname, GLint * params); GLboolean(APIENTRY * qglIsFramebufferEXT) (GLuint framebuffer); void (APIENTRY * qglBindFramebufferEXT) (GLenum target, GLuint framebuffer); void (APIENTRY * qglDeleteFramebuffersEXT) (GLsizei n, const GLuint * framebuffers); void (APIENTRY * qglGenFramebuffersEXT) (GLsizei n, GLuint * framebuffers); GLenum(APIENTRY * qglCheckFramebufferStatusEXT) (GLenum target); void (APIENTRY * qglFramebufferTexture1DEXT) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); void (APIENTRY * qglFramebufferTexture2DEXT) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); void (APIENTRY * qglFramebufferTexture3DEXT) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); void (APIENTRY * qglFramebufferRenderbufferEXT) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); void (APIENTRY * qglGetFramebufferAttachmentParameterivEXT) (GLenum target, GLenum attachment, GLenum pname, GLint * params); void (APIENTRY * qglGenerateMipmapEXT) (GLenum target); // GL_EXT_framebuffer_blit void (APIENTRY * qglBlitFramebufferEXT) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); GLuint fboId[3]; GLuint rboId; void R_CheckFBOExtensions (void) { gl_state.fbo = true; gl_state.hasFBOblit = false; qglGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) qwglGetProcAddress("glGenFramebuffersEXT"); qglBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) qwglGetProcAddress("glBindFramebufferEXT"); qglFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) qwglGetProcAddress("glFramebufferTexture2DEXT"); qglCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) qwglGetProcAddress("glCheckFramebufferStatusEXT"); qglGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)qwglGetProcAddress("glGenRenderbuffersEXT"); qglBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)qwglGetProcAddress("glBindRenderbufferEXT"); qglRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)qwglGetProcAddress("glRenderbufferStorageEXT"); qglFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)qwglGetProcAddress("glFramebufferRenderbufferEXT"); qglBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC)qwglGetProcAddress("glBlitFramebufferEXT"); if(!qglGenFramebuffersEXT || !qglBindFramebufferEXT || !qglFramebufferTexture2DEXT || !qglCheckFramebufferStatusEXT || !qglGenRenderbuffersEXT || !qglBindRenderbufferEXT || !qglRenderbufferStorageEXT || !qglFramebufferRenderbufferEXT) { Com_Printf("...Cannot find OpenGL Framebuffer extension, CANNOT use FBO\n"); gl_state.fbo = false; return; } // Framebuffer object blit if (strstr(gl_config.extensions_string, "GL_EXT_framebuffer_blit")) { Com_Printf("...using GL_EXT_framebuffer_blit\n"); gl_state.hasFBOblit = true; } else { Com_Printf("...GL_EXT_framebuffer_blit not found\n"); } //must check for ability to blit(Many old ATI drivers do not support) //TODO: redundant with previous check? if(gl_state.hasFBOblit) { if(!qglBlitFramebufferEXT) { Com_Printf("glBlitFramebufferEXT not found...\n"); gl_state.hasFBOblit = false; } } } //used for post process stencil volume blurring and shadowmapping void R_GenerateShadowFBO() { int shadowMapWidth = vid.width * r_shadowmapscale->value; int shadowMapHeight = vid.height * r_shadowmapscale->value; GLenum FBOstatus; if (!gl_state.fbo || !gl_state.hasFBOblit) return; //FBO for shadowmapping qglBindTexture(GL_TEXTURE_2D, r_depthtexture->texnum); // GL_LINEAR removes pixelation - GL_NEAREST removes artifacts on outer edges in some cases qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Remove artefact on the edges of the shadowmap qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); // This is to allow usage of shadow2DProj function in the shader qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); qglTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); // No need to force GL_DEPTH_COMPONENT24, drivers usually give you the max precision if available qglTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, shadowMapWidth, shadowMapHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0); qglBindTexture(GL_TEXTURE_2D, 0); // create a framebuffer object qglGenFramebuffersEXT(1, &fboId[0]); qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId[0]); // Instruct openGL that we won't bind a color texture with the currently binded FBO qglDrawBuffer(GL_NONE); qglReadBuffer(GL_NONE); // attach the texture to FBO depth attachment point qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, r_depthtexture->texnum, 0); // check FBO status FBOstatus = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if(FBOstatus != GL_FRAMEBUFFER_COMPLETE_EXT) { Com_Printf("GL_FRAMEBUFFER_COMPLETE_EXT failed, CANNOT use FBO\n"); gl_state.fbo = false; qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } //Second FBO for shadowmapping qglBindTexture(GL_TEXTURE_2D, r_depthtexture2->texnum); // GL_LINEAR removes pixelation - GL_NEAREST removes artifacts on outer edges in some cases qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // This is to allow usage of shadow2DProj function in the shader qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); qglTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); // No need to force GL_DEPTH_COMPONENT24, drivers usually give you the max precision if available qglTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, shadowMapWidth, shadowMapHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0); qglBindTexture(GL_TEXTURE_2D, 0); // create a framebuffer object qglGenFramebuffersEXT(1, &fboId[1]); qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId[1]); // Instruct openGL that we won't bind a color texture with the currently binded FBO qglDrawBuffer(GL_NONE); qglReadBuffer(GL_NONE); // attach the texture to FBO depth attachment point qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, r_depthtexture2->texnum, 0); // check FBO status FBOstatus = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if(FBOstatus != GL_FRAMEBUFFER_COMPLETE_EXT) { Com_Printf("GL_FRAMEBUFFER_COMPLETE_EXT failed, CANNOT use FBO\n"); gl_state.fbo = false; qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } //FBO for capturing stencil volumes qglBindTexture(GL_TEXTURE_2D, r_colorbuffer->texnum); qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, vid.width, vid.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); qglBindTexture(GL_TEXTURE_2D, 0); qglGenFramebuffersEXT(1, &fboId[2]); qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId[2]); qglGenRenderbuffersEXT(1, &rboId); qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rboId); qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT, vid.width, vid.height); qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); // attach a texture to FBO color attachement point qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, r_colorbuffer->texnum, 0); // attach a renderbuffer to depth attachment point qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboId); // attach a renderbuffer to stencil attachment point qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboId); qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId[2]); // check FBO status FBOstatus = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if(FBOstatus != GL_FRAMEBUFFER_COMPLETE_EXT) Com_Printf("GL_FRAMEBUFFER_COMPLETE_EXT failed, CANNOT use secondary FBO\n"); // In the case we render the shadowmap to a higher resolution, the viewport must be modified accordingly. qglViewport(0,0,vid.width,vid.height); // Initialize frame values. // This only makes a difference if the viewport is less than the screen // size, like when the netgraph is on-- otherwise it's redundant with // later glClear calls. qglClearColor (1, 1, 1, 1); qglClear( GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT ); // back to previous screen coordinates R_SetupViewport (); // switch back to window-system-provided framebuffer qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } #define M3D_INV_PI_DIV_180 (57.2957795130823229) #define m3dRadToDeg(x) ((x)*M3D_INV_PI_DIV_180) static void normalize( float vec[3] ) { float len; len = sqrt( vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2] ); if ( len > 0 ) { vec[0] /= len; vec[1] /= len; vec[2] /= len; } } static void cross( float result[3] , float v1[3] , float v2[3] ) { result[0] = v1[1] * v2[2] - v1[2] * v2[1]; result[1] = v1[2] * v2[0] - v1[0] * v2[2]; result[2] = v1[0] * v2[1] - v1[1] * v2[0]; } static void lookAt( float position_x , float position_y , float position_z , float lookAt_x , float lookAt_y , float lookAt_z ) { float forward[3] , side[3] , up[3]; float matrix[4][4]; int i; // forward = normalized( lookAt - position ) forward[0] = lookAt_x - position_x; forward[1] = lookAt_y - position_y; forward[2] = lookAt_z - position_z; normalize( forward ); // side = normalized( forward x [0;1;0] ) side[0] = -forward[2]; side[1] = 0; side[2] = forward[0]; normalize( side ); // up = side x forward cross( up , side , forward ); // Build matrix for ( i = 0 ; i < 3 ; i ++ ) { matrix[i][0] = side[i]; matrix[i][1] = up[i]; matrix[i][2] = - forward[i]; } for ( i = 0 ; i < 3 ; i ++ ) matrix[i][3] = matrix[3][i] = 0; matrix[3][3] = 1; qglMultMatrixf( (const GLfloat *) &matrix[0][0] ); qglTranslated( -position_x , -position_y , -position_z ); } void SM_SetupMatrices(float position_x,float position_y,float position_z,float lookAt_x,float lookAt_y,float lookAt_z) { qglMatrixMode(GL_PROJECTION); qglLoadIdentity(); MYgluPerspective(120.0f, r_newrefdef.width/r_newrefdef.height, 10.0f, 4096.0f); qglMatrixMode(GL_MODELVIEW); qglLoadIdentity(); lookAt( position_x , position_y , position_z , lookAt_x , lookAt_y , lookAt_z ); } void SM_SetTextureMatrix( qboolean mapnum ) { static double modelView[16]; static double projection[16]; // Moving from unit cube [-1,1] to [0,1] const GLdouble bias[16] = { 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0}; // Grab modelview and transformation matrices qglGetDoublev(GL_MODELVIEW_MATRIX, modelView); qglGetDoublev(GL_PROJECTION_MATRIX, projection); qglMatrixMode(GL_TEXTURE); if(mapnum) { qglActiveTextureARB(GL_TEXTURE6); qglBindTexture(GL_TEXTURE_2D, r_depthtexture2->texnum); } else { qglActiveTextureARB(GL_TEXTURE7); qglBindTexture(GL_TEXTURE_2D, r_depthtexture->texnum); } qglLoadIdentity(); qglLoadMatrixd(bias); // concatating all matrice into one. qglMultMatrixd (projection); qglMultMatrixd (modelView); // Go back to normal matrix mode qglMatrixMode(GL_MODELVIEW); qglActiveTextureARB(GL_TEXTURE0); } /* ================ SM_RecursiveWorldNode - this variant of the classic routine renders both sides for shadowing ================ */ void SM_RecursiveWorldNode (mnode_t *node, int clipflags) { int c; msurface_t *surf, **mark; mleaf_t *pleaf; if (node->contents == CONTENTS_SOLID) return; // solid if (node->visframe != r_visframecount) return; if (!r_nocull->value) { int i, clipped; cplane_t *clipplane; for (i=0,clipplane=frustum ; i<4 ; i++,clipplane++) { if (!(clipflags & (1<minmaxs, node->minmaxs+3, clipplane); if (clipped == 1) clipflags &= ~(1<contents != -1) { pleaf = (mleaf_t *)node; // check for door connected areas if (r_newrefdef.areabits) { if (! (r_newrefdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) ) return; // not visible } mark = pleaf->firstmarksurface; if (! (c = pleaf->nummarksurfaces) ) return; do { (*mark++)->visframe = r_framecount; } while (--c); return; } // recurse down the children, front side first SM_RecursiveWorldNode (node->children[0], clipflags); // draw stuff for ( c = node->numsurfaces, surf = r_worldmodel->surfaces + node->firstsurface; c ; c--, surf++) { if (surf->visframe != r_framecount) continue; if (R_CullBox (surf->mins, surf->maxs)) continue; if (surf->texinfo->flags & SURF_SKY) { // no skies here continue; } else if (SurfaceIsTranslucent(surf) && !SurfaceIsAlphaBlended(surf)) { // no trans surfaces continue; } else { if (!( surf->iflags & ISURF_DRAWTURB ) ) { BSP_DrawTexturelessPoly (surf); } } } // recurse down the back side SM_RecursiveWorldNode (node->children[1], clipflags); } inline float point_dist_from_plane (cplane_t *plane, vec3_t point) { switch (plane->type) { case PLANE_X: return point[0] - plane->dist; case PLANE_Y: return point[1] - plane->dist; case PLANE_Z: return point[2] - plane->dist; default: return DotProduct (point, plane->normal) - plane->dist; } } /* ================ SM_RecursiveWorldNode2 - this variant of the classic routine renders only one side for shadowing ================ */ static float fadeshadow_cutoff; void SM_RecursiveWorldNode2 (mnode_t *node, int clipflags, vec3_t origin, vec3_t absmins, vec3_t absmaxs) { int c; float dist, dist_model, dist_light; int side, side_model, side_light; cplane_t *plane; msurface_t *surf, **mark; mleaf_t *pleaf; qboolean caster_off_plane; if (node->contents == CONTENTS_SOLID) return; // solid if (node->visframe != r_visframecount) return; if (!r_nocull->value) { int i, clipped; cplane_t *clipplane; for (i=0,clipplane=frustum ; i<4 ; i++,clipplane++) { if (!(clipflags & (1<minmaxs, node->minmaxs+3, clipplane); if (clipped == 1) clipflags &= ~(1<contents != -1) { pleaf = (mleaf_t *)node; // check for door connected areas if (r_newrefdef.areabits) { if (! (r_newrefdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) ) return; // not visible } mark = pleaf->firstmarksurface; if (! (c = pleaf->nummarksurfaces) ) return; do { (*mark++)->visframe = r_framecount; } while (--c); return; } // node is just a decision point, so go down the apropriate sides // find which side of the node we are on plane = node->plane; dist = point_dist_from_plane (plane, r_origin); dist_model = point_dist_from_plane (plane, origin); dist_light = point_dist_from_plane (plane, statLightPosition); side = dist < 0; side_model = dist_model < 0; side_light = dist_light < 0; dist = fabs (dist); dist_model = fabs (dist_model); dist_light = fabs (dist_light); //TODO: figure out the cutoff distance based on mins and maxs? caster_off_plane = (dist_model > 64.0f) || (BoxOnPlaneSide (absmins, absmaxs, plane) != 3); if (side != side_model && caster_off_plane) { if (side != side_light) { if (dist_light < dist_model) goto skip_draw; } else goto skip_draw; } // recurse down the children, front side first SM_RecursiveWorldNode2 (node->children[side], clipflags, origin, absmins, absmaxs); // draw stuff for ( c = node->numsurfaces, surf = r_worldmodel->surfaces + node->firstsurface; c ; c--, surf++) { if (surf->visframe != r_framecount) continue; if (R_CullBox (surf->mins, surf->maxs)) continue; if (surf->texinfo->flags & SURF_SKY) { // no skies here continue; } else if (SurfaceIsTranslucent(surf) || SurfaceIsAlphaBlended(surf)) { // no trans surfaces continue; } else { if (!( surf->iflags & ISURF_DRAWTURB ) ) { BSP_DrawShadowPoly (surf, origin); } } } if (side == side_model && caster_off_plane) { if (side == side_light) { if (dist_light < dist_model) return; } else return; } skip_draw: if (dist >= fadeshadow_cutoff+512) return; // recurse down the back side SM_RecursiveWorldNode2 (node->children[!side], clipflags, origin, absmins, absmaxs); } /* ============= R_DrawWorld ============= */ void R_DrawShadowMapWorld (qboolean forEnt, vec3_t origin) { int i; if (!r_drawworld->value) return; if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) return; if(forEnt) { vec3_t absmins, absmaxs; glUseProgramObjectARB( g_shadowprogramObj ); glUniform1iARB( g_location_entShadow, 6); qglActiveTextureARB(GL_TEXTURE6); qglBindTexture(GL_TEXTURE_2D, r_depthtexture2->texnum); glUniform1fARB( g_location_xOffset, 1.0/(r_newrefdef.width*r_shadowmapscale->value)); glUniform1fARB( g_location_yOffset, 1.0/(r_newrefdef.height*r_shadowmapscale->value)); glUniform1fARB( g_location_fadeShadow, fadeShadow ); R_InitVArrays(VERT_NO_TEXTURE); VectorAdd (currentmodel->mins, origin, absmins); VectorAdd (currentmodel->maxs, origin, absmaxs); SM_RecursiveWorldNode2 (r_worldmodel->nodes, 15, origin, absmins, absmaxs); R_KillVArrays(); glUseProgramObjectARB( 0 ); qglActiveTextureARB(GL_TEXTURE0); return; } else { R_InitVArrays(VERT_NO_TEXTURE); SM_RecursiveWorldNode (r_worldmodel->nodes, 15); R_KillVArrays(); //draw brush models(not for ent shadow, for now) for (i=0 ; iflags & RF_TRANSLUCENT) continue; // transluscent currentmodel = currententity->model; if (!currentmodel) { continue; } if( currentmodel->type == mod_brush) BSP_DrawTexturelessBrushModel (currententity); else continue; } } } #include "r_lodcalc.h" extern cvar_t *cl_simpleitems; void R_DrawDynamicCaster(void) { int i; vec3_t dist, mins, maxs; trace_t r_trace; int RagDollID; vec3_t origin = {0, 0, 0}; VectorSet(mins, 0, 0, 0); VectorSet(maxs, 0, 0, 0); r_shadowmapcount = 0; if(!dynLight) return; //we have no lights of consequence qglBindTexture(GL_TEXTURE_2D, r_depthtexture->texnum); qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboId[0]); // In the case we render the shadowmap to a higher resolution, the viewport must be modified accordingly. qglViewport(0,0,(int)(vid.width * r_shadowmapscale->value),(int)(vid.height * r_shadowmapscale->value)); // Clear previous frame values qglClear( GL_DEPTH_BUFFER_BIT); //Disable color rendering, we only want to write to the Z-Buffer qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // Culling switching, rendering only frontfaces qglCullFace(GL_BACK); // attach the texture to FBO depth attachment point qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, r_depthtexture->texnum, 0); //set camera SM_SetupMatrices(dynLight->origin[0],dynLight->origin[1],dynLight->origin[2]+64,dynLight->origin[0],dynLight->origin[1],dynLight->origin[2]-128); qglEnable( GL_POLYGON_OFFSET_FILL ); qglPolygonOffset( 0.5f, 0.5f ); //render world - very basic geometry R_DrawShadowMapWorld(false, origin); //render entities near light for (i=0 ; iflags & RF_NOSHADOWS || currententity->flags & RF_TRANSLUCENT) continue; if(!currententity->model) continue; if (currententity->model->type != mod_alias && currententity->model->type != mod_iqm) { continue; } if (cl_simpleitems->integer && currententity->model->simple_texnum != 0) continue; //TODO: simple items casting shadows? if(r_ragdolls->value && currententity->model->type == mod_iqm && currententity->model->hasRagDoll) { if(currententity->frame > 198) continue; } //distance from light, if too far, don't render(to do - check against brightness for dist!) VectorSubtract(dynLight->origin, currententity->origin, dist); if(VectorLength(dist) > 256.0f) continue; //trace visibility from light - we don't render objects the light doesn't hit! r_trace = CM_BoxTrace(dynLight->origin, currententity->origin, mins, maxs, r_worldmodel->firstnode, MASK_OPAQUE); if(r_trace.fraction != 1.0) continue; currentmodel = currententity->model; //get distance VectorSubtract(r_origin, currententity->origin, dist); //set lod if available if(VectorLength(dist) > LOD_DIST*(3.0/5.0)) { if(currententity->lod2) currentmodel = currententity->lod2; } else if(VectorLength(dist) > LOD_DIST*(1.0/5.0)) { if(currententity->lod1) currentmodel = currententity->lod1; } if (currententity->lod2) currentmodel = currententity->lod2; if(currentmodel->type == mod_iqm) IQM_DrawCaster (); else MD2_DrawCaster (); } for(RagDollID = 0; RagDollID < MAX_RAGDOLLS; RagDollID++) { if(RagDoll[RagDollID].destroyed) continue; //distance from light, if too far, don't render(to do - check against brightness for dist!) VectorSubtract(dynLight->origin, RagDoll[RagDollID].curPos, dist); if(VectorLength(dist) > 256.0f) continue; //trace visibility from light - we don't render objects the light doesn't hit! r_trace = CM_BoxTrace(dynLight->origin, RagDoll[RagDollID].curPos, mins, maxs, r_worldmodel->firstnode, MASK_OPAQUE); if(r_trace.fraction != 1.0) continue; IQM_DrawRagDollCaster (RagDollID); } SM_SetTextureMatrix(0); r_shadowmapcount = 1; dynLight = NULL; //done with dynamic light shadows for this frame qglDepthMask (1); // back to writing qglPolygonOffset( 0.0f, 0.0f ); qglDisable( GL_POLYGON_OFFSET_FILL ); } void R_Vectoangles (vec3_t value1, vec3_t angles) { float forward; float yaw, pitch; if (value1[1] == 0.0f && value1[0] == 0.0f ) { yaw = 0.0f; if (value1[2] > 0.0f) pitch = 90.0f; else pitch = 270.0f; } else { // PMM - fixed to correct for pitch of 0 if (value1[0]) yaw = (atan2(value1[1], value1[0]) * 180.0f / M_PI); else if (value1[1] > 0) yaw = 90.0f; else yaw = 270.0f; if (yaw < 0.0f) yaw += 360.0f; forward = sqrt (value1[0]*value1[0] + value1[1]*value1[1]); pitch = (atan2(value1[2], forward) * 180.0f / M_PI); if (pitch < 0.0f) pitch += 360.0f; } angles[PITCH] = -pitch; angles[YAW] = yaw; angles[ROLL] = 0.0f; } void R_DrawVegetationCasters ( qboolean forShadows ) { int i, k; grass_t *grass; float scale; vec3_t dir, origin, angle, right, up, corner[4]; float *corner0 = corner[0]; float sway; if(r_newrefdef.rdflags & RDF_NOWORLDMODEL) return; grass = r_grasses; R_InitVArrays (VERT_SINGLE_TEXTURED); for (i=0; itype) continue; //only deal with leaves, grass shadows look kind of bad if(grass->sunVisible) { scale = 10.0*grass->size; VectorSubtract(r_sunLight->origin, r_sunLight->target, dir); R_Vectoangles(dir, angle); AngleVectors(angle, NULL, right, up); VectorScale(right, scale, right); VectorScale(up, scale, up); VectorCopy(grass->origin, origin); //render grass polygon GL_SelectTexture( GL_TEXTURE0); qglBindTexture (GL_TEXTURE_2D, grass->texnum); GLSTATE_ENABLE_ALPHATEST qglColor4f( 0, 0, 0, 1 ); VectorSet (corner[0], origin[0] + (up[0] + right[0])*(-0.5), origin[1] + (up[1] + right[1])*(-0.5), origin[2] + (up[2] + right[2])*(-0.5)); sway = 3; VectorSet ( corner[1], corner0[0] + up[0] + sway*sin (rs_realtime*sway), corner0[1] + up[1] + sway*sin (rs_realtime*sway), corner0[2] + up[2]); VectorSet ( corner[2], corner0[0] + (up[0]+right[0] + sway*sin (rs_realtime*sway)), corner0[1] + (up[1]+right[1] + sway*sin (rs_realtime*sway)), corner0[2] + (up[2]+right[2])); VectorSet ( corner[3], corner0[0] + right[0], corner0[1] + right[1], corner0[2] + right[2]); VArray = &VArrayVerts[0]; for(k = 0; k < 4; k++) { VArray[0] = corner[k][0]; VArray[1] = corner[k][1]; VArray[2] = corner[k][2]; switch(k) { case 0: VArray[3] = 1; VArray[4] = 1; break; case 1: VArray[3] = 0; VArray[4] = 1; break; case 2: VArray[3] = 0; VArray[4] = 0; break; case 3: VArray[3] = 1; VArray[4] = 0; break; } VArray += VertexSizes[VERT_SINGLE_TEXTURED]; } R_DrawVarrays(GL_QUADS, 0, 4); if(forShadows) r_shadowmapcount = 2; } } R_KillVArrays (); qglColor4f( 1,1,1,1 ); GLSTATE_DISABLE_ALPHATEST } void R_DrawVegetationCaster(void) { if(!r_sunLight->has_Sun || !r_hasleaves) return; //no point if there is no sun or leaves! qglBindTexture(GL_TEXTURE_2D, r_depthtexture2->texnum); qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboId[1]); // In the case we render the shadowmap to a higher resolution, the viewport must be modified accordingly. qglViewport(0,0,(int)(vid.width * r_shadowmapscale->value),(int)(vid.height * r_shadowmapscale->value)); //Clear previous frame values qglClear( GL_DEPTH_BUFFER_BIT); //Disable color rendering, we only want to write to the Z-Buffer qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // Culling switching, rendering only frontfaces qglDisable(GL_CULL_FACE); // attach the texture to FBO depth attachment point qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, r_depthtexture2->texnum, 0); //get sun light origin and target from map info, at map load //set camera SM_SetupMatrices(r_sunLight->origin[0],r_sunLight->origin[1],r_sunLight->origin[2],r_sunLight->target[0],r_sunLight->target[1],r_sunLight->target[2]); qglEnable( GL_POLYGON_OFFSET_FILL ); qglPolygonOffset( 0.5f, 0.5f ); //render vegetation R_DrawVegetationCasters(true); SM_SetTextureMatrix(1); qglDepthMask (1); // back to writing qglPolygonOffset( 0.0f, 0.0f ); qglDisable( GL_POLYGON_OFFSET_FILL ); qglEnable(GL_CULL_FACE); } void R_DrawEntityCaster(entity_t *ent) { vec3_t dist, mins, maxs; trace_t r_trace; VectorSet(mins, 0, 0, 0); VectorSet(maxs, 0, 0, 0); r_shadowmapcount = 0; //check caster validity if (ent->flags & RF_NOSHADOWS || ent->flags & RF_TRANSLUCENT) return; if(!ent->model) return; if (cl_simpleitems->integer && ent->model->simple_texnum != 0) return; if(r_ragdolls->value && ent->model->type == mod_iqm && ent->model->hasRagDoll) { if(ent->frame > 198) return; } //trace visibility from light - we don't render objects the light doesn't hit! r_trace = CM_BoxTrace(statLightPosition, ent->origin, mins, maxs, r_worldmodel->firstnode, MASK_OPAQUE); if(r_trace.fraction != 1.0) return; qglMatrixMode(GL_PROJECTION); qglPushMatrix(); qglMatrixMode(GL_MODELVIEW); qglPushMatrix(); qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboId[1]); // In the case we render the shadowmap to a higher resolution, the viewport must be modified accordingly. qglViewport(0,0,(int)(vid.width * r_shadowmapscale->value),(int)(vid.height * r_shadowmapscale->value)); //Clear previous frame values qglClear( GL_DEPTH_BUFFER_BIT); //Disable color rendering, we only want to write to the Z-Buffer qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // Culling switching, rendering only frontfaces qglDisable(GL_CULL_FACE); // attach the texture to FBO depth attachment point qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, r_depthtexture2->texnum, 0); //get light origin //set camera SM_SetupMatrices(statLightPosition[0],statLightPosition[1],statLightPosition[2]+64,ent->origin[0],ent->origin[1],ent->origin[2]-128); qglEnable( GL_POLYGON_OFFSET_FILL ); qglPolygonOffset( 0.5f, 0.5f ); //we could loop the entities here, and render any nearby models, to make sure we get shadows on the this entity if a mesh is nearby. //this would be only if we want to do self shadowing, or have player shadows cast on other mesh objects. At this time, I think that the //performance losses would not be worth doing this, but we can revisit. currentmodel = ent->model; //get view distance VectorSubtract(r_origin, ent->origin, dist); //set lod if available if(VectorLength(dist) > LOD_DIST*(3.0/5.0)) { if(currententity->lod2) currentmodel = currententity->lod2; } else if(VectorLength(dist) > LOD_DIST*(1.0/5.0)) { if(currententity->lod1) currentmodel = currententity->lod1; } if (currententity->lod2) currentmodel = currententity->lod2; if(currentmodel->type == mod_iqm) IQM_DrawCaster (); else MD2_DrawCaster (); SM_SetTextureMatrix(1); qglDepthMask (1); // back to writing qglPolygonOffset( 0.0f, 0.0f ); qglDisable( GL_POLYGON_OFFSET_FILL ); qglEnable(GL_CULL_FACE); // back to previous screen coordinates R_SetupViewport (); qglPopMatrix(); qglMatrixMode(GL_PROJECTION); qglPopMatrix(); qglMatrixMode(GL_MODELVIEW); r_shadowmapcount = 1; } void R_GenerateEntityShadow( void ) { if(gl_shadowmaps->integer && gl_state.vbo && gl_glsl_shaders->integer && gl_state.glsl_shaders && gl_normalmaps->integer) { vec3_t dist, tmp; float rad; if((r_newrefdef.rdflags & RDF_NOWORLDMODEL) || (currententity->flags & RF_MENUMODEL)) return; if (r_newrefdef.vieworg[2] < (currententity->origin[2] - 128)) return; VectorSubtract(currententity->model->maxs, currententity->model->mins, tmp); VectorScale (tmp, 1.666, tmp); rad = VectorLength (tmp); if( R_CullSphere( currententity->origin, rad, 15 ) ) return; //get view distance VectorSubtract(r_origin, currententity->origin, dist); //fade out shadows both by distance from view, and by distance from light fadeshadow_cutoff = r_shadowcutoff->value * (LOD_DIST/LOD_BASE_DIST); if (r_shadowcutoff->value < 0.1) fadeShadow = 1.0; else if (VectorLength (dist) > fadeshadow_cutoff) { fadeShadow = VectorLength(dist) - fadeshadow_cutoff; if (fadeShadow > 512) return; else fadeShadow = 1.0 - fadeShadow/512.0; //fade out smoothly over 512 units. } else fadeShadow = 1.0; qglEnable(GL_DEPTH_TEST); qglClearColor(0,0,0,1.0f); qglHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); R_DrawEntityCaster(currententity); qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0); //Enabling color write (previously disabled for light POV z-buffer rendering) qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); //re-render affected polys with shadowmap for this entity if(r_shadowmapcount > 0) { qglEnable( GL_BLEND ); qglBlendFunc (GL_ZERO, GL_SRC_COLOR); R_DrawShadowMapWorld(true, currententity->origin); qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); qglDisable ( GL_BLEND ); } currentmodel = currententity->model; r_shadowmapcount = 0; } } void R_DrawRagdollCaster(int RagDollID) { vec3_t mins, maxs; trace_t r_trace; VectorSet(mins, 0, 0, 0); VectorSet(maxs, 0, 0, 0); r_shadowmapcount = 0; //trace visibility from light - we don't render objects the light doesn't hit! r_trace = CM_BoxTrace(statLightPosition, RagDoll[RagDollID].origin, mins, maxs, r_worldmodel->firstnode, MASK_OPAQUE); if(r_trace.fraction != 1.0) return; qglMatrixMode(GL_PROJECTION); qglPushMatrix(); qglMatrixMode(GL_MODELVIEW); qglPushMatrix(); qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboId[1]); // In the case we render the shadowmap to a higher resolution, the viewport must be modified accordingly. qglViewport(0,0,(int)(vid.width * r_shadowmapscale->value),(int)(vid.height * r_shadowmapscale->value)); //Clear previous frame values qglClear( GL_DEPTH_BUFFER_BIT); //Disable color rendering, we only want to write to the Z-Buffer qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // Culling switching, rendering only frontfaces qglDisable(GL_CULL_FACE); // attach the texture to FBO depth attachment point qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, r_depthtexture2->texnum, 0); //get light origin //set camera SM_SetupMatrices(statLightPosition[0],statLightPosition[1],statLightPosition[2]+64,RagDoll[RagDollID].origin[0],RagDoll[RagDollID].origin[1],RagDoll[RagDollID].origin[2]-128); qglEnable( GL_POLYGON_OFFSET_FILL ); qglPolygonOffset( 0.5f, 0.5f ); IQM_DrawRagDollCaster ( RagDollID ); SM_SetTextureMatrix(1); qglDepthMask (1); // back to writing qglPolygonOffset( 0.0f, 0.0f ); qglDisable( GL_POLYGON_OFFSET_FILL ); qglEnable(GL_CULL_FACE); // back to previous screen coordinates R_SetupViewport (); qglPopMatrix(); qglMatrixMode(GL_PROJECTION); qglPopMatrix(); qglMatrixMode(GL_MODELVIEW); r_shadowmapcount = 1; } void R_GenerateRagdollShadow( int RagDollID ) { if(gl_shadowmaps->integer && gl_state.vbo && gl_glsl_shaders->integer && gl_state.glsl_shaders && gl_normalmaps->integer) { vec3_t dist, tmp; float rad; VectorSubtract(RagDoll[RagDollID].ragDollMesh->maxs, RagDoll[RagDollID].ragDollMesh->mins, tmp); VectorScale (tmp, 1.666, tmp); rad = VectorLength (tmp); if( R_CullSphere( RagDoll[RagDollID].origin, rad, 15 ) ) return; //get view distance VectorSubtract(r_origin, RagDoll[RagDollID].origin, dist); //fade out shadows both by distance from view, and by distance from light fadeshadow_cutoff = r_shadowcutoff->value * (LOD_DIST/LOD_BASE_DIST); if (r_shadowcutoff->value < 0.1) fadeShadow = 1.0; else if (VectorLength (dist) > fadeshadow_cutoff) { fadeShadow = VectorLength(dist) - fadeshadow_cutoff; if (fadeShadow > 512) return; else fadeShadow = 1.0 - fadeShadow/512.0; //fade out smoothly over 512 units. } else fadeShadow = 1.0; qglEnable(GL_DEPTH_TEST); qglClearColor(0,0,0,1.0f); qglHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); R_DrawRagdollCaster(RagDollID); qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0); //Enabling color write (previously disabled for light POV z-buffer rendering) qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); //re-render affected polys with shadowmap for this entity(note - blend "if darker"). if(r_shadowmapcount > 0) { qglEnable( GL_BLEND ); qglBlendFunc (GL_ZERO, GL_SRC_COLOR); R_DrawShadowMapWorld(true, RagDoll[RagDollID].origin); qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); qglDisable ( GL_BLEND ); } currentmodel = RagDoll[RagDollID].ragDollMesh; r_shadowmapcount = 0; } } alien-arena-7.66+dfsg/source/ref_gl/anorms.h0000600000175000017500000001451412161402007020023 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ {-0.525731, 0.000000, 0.850651}, {-0.442863, 0.238856, 0.864188}, {-0.295242, 0.000000, 0.955423}, {-0.309017, 0.500000, 0.809017}, {-0.162460, 0.262866, 0.951056}, {0.000000, 0.000000, 1.000000}, {0.000000, 0.850651, 0.525731}, {-0.147621, 0.716567, 0.681718}, {0.147621, 0.716567, 0.681718}, {0.000000, 0.525731, 0.850651}, {0.309017, 0.500000, 0.809017}, {0.525731, 0.000000, 0.850651}, {0.295242, 0.000000, 0.955423}, {0.442863, 0.238856, 0.864188}, {0.162460, 0.262866, 0.951056}, {-0.681718, 0.147621, 0.716567}, {-0.809017, 0.309017, 0.500000}, {-0.587785, 0.425325, 0.688191}, {-0.850651, 0.525731, 0.000000}, {-0.864188, 0.442863, 0.238856}, {-0.716567, 0.681718, 0.147621}, {-0.688191, 0.587785, 0.425325}, {-0.500000, 0.809017, 0.309017}, {-0.238856, 0.864188, 0.442863}, {-0.425325, 0.688191, 0.587785}, {-0.716567, 0.681718, -0.147621}, {-0.500000, 0.809017, -0.309017}, {-0.525731, 0.850651, 0.000000}, {0.000000, 0.850651, -0.525731}, {-0.238856, 0.864188, -0.442863}, {0.000000, 0.955423, -0.295242}, {-0.262866, 0.951056, -0.162460}, {0.000000, 1.000000, 0.000000}, {0.000000, 0.955423, 0.295242}, {-0.262866, 0.951056, 0.162460}, {0.238856, 0.864188, 0.442863}, {0.262866, 0.951056, 0.162460}, {0.500000, 0.809017, 0.309017}, {0.238856, 0.864188, -0.442863}, {0.262866, 0.951056, -0.162460}, {0.500000, 0.809017, -0.309017}, {0.850651, 0.525731, 0.000000}, {0.716567, 0.681718, 0.147621}, {0.716567, 0.681718, -0.147621}, {0.525731, 0.850651, 0.000000}, {0.425325, 0.688191, 0.587785}, {0.864188, 0.442863, 0.238856}, {0.688191, 0.587785, 0.425325}, {0.809017, 0.309017, 0.500000}, {0.681718, 0.147621, 0.716567}, {0.587785, 0.425325, 0.688191}, {0.955423, 0.295242, 0.000000}, {1.000000, 0.000000, 0.000000}, {0.951056, 0.162460, 0.262866}, {0.850651, -0.525731, 0.000000}, {0.955423, -0.295242, 0.000000}, {0.864188, -0.442863, 0.238856}, {0.951056, -0.162460, 0.262866}, {0.809017, -0.309017, 0.500000}, {0.681718, -0.147621, 0.716567}, {0.850651, 0.000000, 0.525731}, {0.864188, 0.442863, -0.238856}, {0.809017, 0.309017, -0.500000}, {0.951056, 0.162460, -0.262866}, {0.525731, 0.000000, -0.850651}, {0.681718, 0.147621, -0.716567}, {0.681718, -0.147621, -0.716567}, {0.850651, 0.000000, -0.525731}, {0.809017, -0.309017, -0.500000}, {0.864188, -0.442863, -0.238856}, {0.951056, -0.162460, -0.262866}, {0.147621, 0.716567, -0.681718}, {0.309017, 0.500000, -0.809017}, {0.425325, 0.688191, -0.587785}, {0.442863, 0.238856, -0.864188}, {0.587785, 0.425325, -0.688191}, {0.688191, 0.587785, -0.425325}, {-0.147621, 0.716567, -0.681718}, {-0.309017, 0.500000, -0.809017}, {0.000000, 0.525731, -0.850651}, {-0.525731, 0.000000, -0.850651}, {-0.442863, 0.238856, -0.864188}, {-0.295242, 0.000000, -0.955423}, {-0.162460, 0.262866, -0.951056}, {0.000000, 0.000000, -1.000000}, {0.295242, 0.000000, -0.955423}, {0.162460, 0.262866, -0.951056}, {-0.442863, -0.238856, -0.864188}, {-0.309017, -0.500000, -0.809017}, {-0.162460, -0.262866, -0.951056}, {0.000000, -0.850651, -0.525731}, {-0.147621, -0.716567, -0.681718}, {0.147621, -0.716567, -0.681718}, {0.000000, -0.525731, -0.850651}, {0.309017, -0.500000, -0.809017}, {0.442863, -0.238856, -0.864188}, {0.162460, -0.262866, -0.951056}, {0.238856, -0.864188, -0.442863}, {0.500000, -0.809017, -0.309017}, {0.425325, -0.688191, -0.587785}, {0.716567, -0.681718, -0.147621}, {0.688191, -0.587785, -0.425325}, {0.587785, -0.425325, -0.688191}, {0.000000, -0.955423, -0.295242}, {0.000000, -1.000000, 0.000000}, {0.262866, -0.951056, -0.162460}, {0.000000, -0.850651, 0.525731}, {0.000000, -0.955423, 0.295242}, {0.238856, -0.864188, 0.442863}, {0.262866, -0.951056, 0.162460}, {0.500000, -0.809017, 0.309017}, {0.716567, -0.681718, 0.147621}, {0.525731, -0.850651, 0.000000}, {-0.238856, -0.864188, -0.442863}, {-0.500000, -0.809017, -0.309017}, {-0.262866, -0.951056, -0.162460}, {-0.850651, -0.525731, 0.000000}, {-0.716567, -0.681718, -0.147621}, {-0.716567, -0.681718, 0.147621}, {-0.525731, -0.850651, 0.000000}, {-0.500000, -0.809017, 0.309017}, {-0.238856, -0.864188, 0.442863}, {-0.262866, -0.951056, 0.162460}, {-0.864188, -0.442863, 0.238856}, {-0.809017, -0.309017, 0.500000}, {-0.688191, -0.587785, 0.425325}, {-0.681718, -0.147621, 0.716567}, {-0.442863, -0.238856, 0.864188}, {-0.587785, -0.425325, 0.688191}, {-0.309017, -0.500000, 0.809017}, {-0.147621, -0.716567, 0.681718}, {-0.425325, -0.688191, 0.587785}, {-0.162460, -0.262866, 0.951056}, {0.442863, -0.238856, 0.864188}, {0.162460, -0.262866, 0.951056}, {0.309017, -0.500000, 0.809017}, {0.147621, -0.716567, 0.681718}, {0.000000, -0.525731, 0.850651}, {0.425325, -0.688191, 0.587785}, {0.587785, -0.425325, 0.688191}, {0.688191, -0.587785, 0.425325}, {-0.955423, 0.295242, 0.000000}, {-0.951056, 0.162460, 0.262866}, {-1.000000, 0.000000, 0.000000}, {-0.850651, 0.000000, 0.525731}, {-0.955423, -0.295242, 0.000000}, {-0.951056, -0.162460, 0.262866}, {-0.864188, 0.442863, -0.238856}, {-0.951056, 0.162460, -0.262866}, {-0.809017, 0.309017, -0.500000}, {-0.864188, -0.442863, -0.238856}, {-0.951056, -0.162460, -0.262866}, {-0.809017, -0.309017, -0.500000}, {-0.681718, 0.147621, -0.716567}, {-0.681718, -0.147621, -0.716567}, {-0.850651, 0.000000, -0.525731}, {-0.688191, 0.587785, -0.425325}, {-0.587785, 0.425325, -0.688191}, {-0.425325, 0.688191, -0.587785}, {-0.425325, -0.688191, -0.587785}, {-0.587785, -0.425325, -0.688191}, {-0.688191, -0.587785, -0.425325}, alien-arena-7.66+dfsg/source/ref_gl/r_misc.c0000600000175000017500000005656012161402007020002 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // r_misc.c #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "r_local.h" //For screenshots #if defined HAVE_JPEG_JPEGLIB_H #include "jpeg/jpeglib.h" #else #include "jpeglib.h" #endif image_t *r_notexture; // use for bad textures image_t *r_particletexture; // little dot for particles image_t *r_smoketexture; // for smoke, etc... image_t *r_explosiontexture; image_t *r_explosion1texture; image_t *r_explosion2texture; image_t *r_explosion3texture; image_t *r_explosion4texture; image_t *r_explosion5texture; image_t *r_explosion6texture; image_t *r_explosion7texture; image_t *r_bloodtexture; image_t *r_pufftexture; image_t *r_bflashtexture; image_t *r_cflashtexture; image_t *r_leaderfieldtexture; image_t *r_deathfieldtexture; image_t *r_deathfieldtexture2; image_t *r_shelltexture; image_t *r_shelltexture2; image_t *r_shellnormal; image_t *r_hittexture; image_t *r_bubbletexture; image_t *r_reflecttexture; image_t *r_shottexture; image_t *r_sayicontexture; image_t *r_flaretexture; image_t *r_flagtexture; image_t *r_logotexture; image_t *r_beamtexture; image_t *r_beam2texture; image_t *r_beam3texture; image_t *r_dis1texture; image_t *r_dis2texture; image_t *r_dis3texture; image_t *r_bullettexture; image_t *r_bulletnormal; image_t *r_voltagetexture; image_t *r_raintexture; image_t *r_leaftexture; image_t *r_trashtexture; image_t *r_splashtexture; image_t *r_splash2texture; image_t *r_radarmap; image_t *r_around; image_t *r_flare; image_t *r_flare1; image_t *r_mirrorspec; image_t *r_distort; image_t *sun_object; image_t *sun1_object; image_t *sun2_object; static size_t szr; // just for unused result warnings //Normalisation cube map GLuint normalisationCubeMap; #define CUBEMAP_MAXSIZE 32 static void getCubeVector (int i, int cubesize, int x, int y, float *vector) { float s, t, sc, tc, mag; s = ((float) x + 0.5) / (float) cubesize; t = ((float) y + 0.5) / (float) cubesize; sc = s * 2.0 - 1.0; tc = t * 2.0 - 1.0; // cleaned manky braces again here... switch (i) { case 0: vector[0] = 1.0; vector[1] = - tc; vector[2] = - sc; break; case 1: vector[0] = - 1.0; vector[1] = - tc; vector[2] = sc; break; case 2: vector[0] = sc; vector[1] = 1.0; vector[2] = tc; break; case 3: vector[0] = sc; vector[1] = - 1.0; vector[2] = - tc; break; case 4: vector[0] = sc; vector[1] = - tc; vector[2] = 1.0; break; case 5: vector[0] = - sc; vector[1] = - tc; vector[2] = - 1.0; break; } mag = 1.0 / sqrt (vector[0]* vector[0]+ vector[1]* vector[1]+ vector[2]* vector[2]); vector[0]*= mag; vector[1]*= mag; vector[2]*= mag; } void R_InitCubemapTextures (void) { float vector[3]; int i, x, y; byte pixels[CUBEMAP_MAXSIZE * CUBEMAP_MAXSIZE * 4]; qglDisable (GL_TEXTURE_2D); qglEnable (GL_TEXTURE_CUBE_MAP_ARB); qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, normalisationCubeMap); // set up the texture parameters - did a clamp on R as well... qglTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); qglTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); qglTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); qglTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); qglTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); for (i = 0; i < 6; i++) { for (y = 0; y < CUBEMAP_MAXSIZE; y++) { for (x = 0; x < CUBEMAP_MAXSIZE; x++) { getCubeVector (i, CUBEMAP_MAXSIZE, x, y, vector); pixels[4 * (y * CUBEMAP_MAXSIZE + x) + 0] = 128 + 127 * vector[0]; pixels[4 * (y * CUBEMAP_MAXSIZE + x) + 1] = 128 + 127 * vector[1]; pixels[4 * (y * CUBEMAP_MAXSIZE + x) + 2] = 128 + 127 * vector[2]; } } // cube map me baybeee qglTexImage2D (GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + i, 0, GL_RGBA, CUBEMAP_MAXSIZE, CUBEMAP_MAXSIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); } // done - restore the texture state qglDisable (GL_TEXTURE_CUBE_MAP_ARB); qglEnable (GL_TEXTURE_2D); } /* ================== R_InitParticleTexture ================== */ byte dottexture[16][16] = { {0,0,0,0,0,2,6,7,7,5,2,0,0,0,0,0}, {0,0,0,1,8,20,33,40,39,30,18,7,0,0,0,0}, {0,0,1,12,35,60,78,87,87,76,56,30,10,0,0,0}, {0,0,9,37,72,103,125,136,135,122,98,67,31,7,0,0}, {0,3,25,66,108,142,168,180,179,164,137,102,60,20,2,0}, {0,9,44,91,137,175,206,220,219,201,170,130,84,38,6,0}, {0,15,58,109,157,200,233,249,248,229,194,150,101,51,11,0}, {1,18,66,118,167,212,245,254,254,242,206,159,110,57,14,0}, {1,18,64,116,165,209,243,254,254,239,203,158,108,56,13,0}, {0,13,54,104,152,193,225,242,240,221,187,144,97,47,9,0}, {0,7,39,84,128,165,194,209,207,190,160,122,77,32,5,0}, {0,2,20,57,97,130,154,167,166,152,125,91,51,15,1,0}, {0,0,6,27,60,89,111,121,120,108,85,55,23,5,0,0}, {0,0,0,7,24,46,63,72,72,61,43,20,6,0,0,0}, {0,0,0,0,4,11,20,26,26,20,10,3,0,0,0,0}, {0,0,0,0,0,0,2,3,3,2,0,0,0,0,0,0}, }; void R_InitParticleTexture (void) { int x,y; byte data[16][16][4]; char flares[MAX_QPATH]; // // particle texture // for (x=0 ; x<16 ; x++) { for (y=0 ; y<16 ; y++) { data[y][x][0] = 255; data[y][x][1] = 255; data[y][x][2] = 255; data[y][x][3] = dottexture[x][y]; } } r_particletexture = R_RegisterParticlePic("particle"); if (!r_particletexture) { r_particletexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_smoketexture = R_RegisterParticlePic("smoke"); if (!r_smoketexture) { r_smoketexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_explosiontexture = R_RegisterParticlePic("explosion"); if (!r_explosiontexture) { r_explosiontexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_explosion1texture = R_RegisterParticlePic("r_explod_1"); if (!r_explosion1texture) { r_explosion1texture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_explosion2texture = R_RegisterParticlePic("r_explod_2"); if (!r_explosion2texture) { r_explosion2texture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_explosion3texture = R_RegisterParticlePic("r_explod_3"); if (!r_explosion3texture) { r_explosion3texture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_explosion4texture = R_RegisterParticlePic("r_explod_4"); if (!r_explosion4texture) { r_explosion4texture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_explosion5texture = R_RegisterParticlePic("r_explod_5"); if (!r_explosion5texture) { r_explosion5texture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_explosion6texture = R_RegisterParticlePic("r_explod_6"); if (!r_explosion6texture) { r_explosion6texture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_explosion7texture = R_RegisterParticlePic("r_explod_7"); if (!r_explosion7texture) { r_explosion7texture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_bloodtexture = R_RegisterParticlePic("blood"); if (!r_bloodtexture) { r_bloodtexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_pufftexture = R_RegisterParticlePic("puff"); if (!r_pufftexture) { r_pufftexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_bflashtexture = R_RegisterParticlePic("bflash"); if (!r_bflashtexture) { r_bflashtexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_cflashtexture = R_RegisterParticlePic("cflash"); if (!r_cflashtexture) { r_cflashtexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_leaderfieldtexture = R_RegisterParticlePic("leaderfield"); if (!r_leaderfieldtexture) { r_leaderfieldtexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_deathfieldtexture = R_RegisterParticlePic("deathfield"); if (!r_deathfieldtexture) { r_deathfieldtexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_deathfieldtexture2 = R_RegisterParticlePic("deathfield2"); if (!r_deathfieldtexture2) { r_deathfieldtexture2 = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_shelltexture = R_RegisterParticlePic("shell"); if (!r_shelltexture) { r_shelltexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_shelltexture2 = R_RegisterParticlePic("shell2"); if (!r_shelltexture2) { r_shelltexture2 = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_shellnormal = R_RegisterParticlePic("shell2_normal"); if (!r_shellnormal) { r_shellnormal = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_hittexture = R_RegisterParticlePic("aflash"); if (!r_hittexture) { r_hittexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_bubbletexture = R_RegisterParticlePic("bubble"); if (!r_bubbletexture) { r_bubbletexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_reflecttexture = R_RegisterGfxPic("reflect"); if (!r_reflecttexture) { r_reflecttexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_mirrorspec = R_RegisterGfxPic("mirrorspec"); if (!r_mirrorspec) { r_mirrorspec = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_shottexture = R_RegisterParticlePic("dflash"); if (!r_shottexture) { r_shottexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_sayicontexture = R_RegisterParticlePic("sayicon"); if (!r_sayicontexture) { r_sayicontexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_flaretexture = R_RegisterParticlePic("flare"); if (!r_flaretexture) { r_flaretexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_flagtexture = R_RegisterParticlePic("flag"); if (!r_flagtexture) { r_flagtexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_logotexture = R_RegisterParticlePic("logo"); if (!r_logotexture) { r_logotexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_beamtexture = R_RegisterGfxPic("glightning"); if (!r_beamtexture) { r_beamtexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_beam2texture = R_RegisterGfxPic("greenline"); if (!r_beam2texture) { r_beam2texture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_beam3texture = R_RegisterGfxPic("electrics3d"); if (!r_beam3texture) { r_beam3texture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_bullettexture = R_RegisterParticlePic("bullethole"); if (!r_bullettexture) { r_bullettexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_bulletnormal = R_RegisterParticleNormal("bullethole2"); if (!r_bulletnormal) { r_bulletnormal = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_voltagetexture = R_RegisterParticlePic("voltage"); if (!r_voltagetexture) { r_voltagetexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_raintexture = R_RegisterParticlePic("beam"); if (!r_raintexture) { r_raintexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_leaftexture = R_RegisterParticlePic("leaf"); if (!r_leaftexture) { r_leaftexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_trashtexture = R_RegisterParticlePic("trash"); if (!r_trashtexture) { r_trashtexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_splashtexture = R_RegisterParticlePic("ripples"); if (!r_splashtexture) { r_splashtexture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_splash2texture = R_RegisterParticlePic("watersplash"); if (!r_splash2texture) { r_splash2texture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } //to do - move more or all of this to their appropriate places r_radarmap = GL_FindImage("gfx/radar/radarmap",it_pic); if (!r_radarmap) { r_radarmap = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_around = GL_FindImage("gfx/radar/around",it_pic); if (!r_around) { r_around = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_distort = GL_FindImage("gfx/water/distort1.tga", it_pic); if (!r_distort) { r_distort = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } sun_object = R_RegisterGfxPic("sun"); if(!sun_object) { sun_object = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } sun1_object = R_RegisterGfxPic("sun1"); if(!sun1_object) { sun1_object = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } sun2_object = R_RegisterGfxPic("sun2"); if(!sun2_object) { sun2_object = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_dis1texture = R_RegisterParticlePic("disbeam1"); if (!r_dis1texture) { r_dis1texture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_dis2texture = R_RegisterParticlePic("disbeam2"); if (!r_dis2texture) { r_dis2texture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } r_dis3texture = R_RegisterParticlePic("disbeam3"); if (!r_dis3texture) { r_dis3texture = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } // // also use this for bad textures, but without alpha // for (x=0 ; x<16 ; x++) { for (y=0 ; y<16 ; y++) { data[y][x][0] = dottexture[x&3][y&3]*255; data[y][x][1] = 0; data[y][x][2] = 0; data[y][x][3] = 255; } } r_notexture = GL_LoadPic ("***r_notexture***", (byte *)data, 16, 16, it_wall, 32); //R_InitCubemapTextures (); //not used for now - may use later for HDR, and others //will eventually add more flaretypes Com_sprintf (flares, sizeof(flares), "gfx/flares/flare0.tga"); r_flare = GL_FindImage(flares, it_pic); if (!r_flare) { r_flare = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } Com_sprintf (flares, sizeof(flares), "gfx/flares/flare1.tga"); r_flare1 = GL_FindImage(flares, it_pic); if (!r_flare1) { r_flare1 = GL_LoadPic ("***particle***", (byte *)data, 16, 16, it_sprite, 32); } } /* ============================================================================== SCREEN SHOTS ============================================================================== */ typedef struct _TargaHeader { unsigned char id_length, colormap_type, image_type; unsigned short colormap_index, colormap_length; unsigned char colormap_size; unsigned short x_origin, y_origin, width, height; unsigned char pixel_size, attributes; } TargaHeader; /* ================== GL_ScreenShot_JPEG ================== */ void GL_ScreenShot_JPEG(void) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; byte *rgbdata; JSAMPROW s[1]; FILE *f; char picname[80], checkname[MAX_OSPATH]; int i, offset; cvar_t *blocking_cvars[20]; int nblocking = 0; // Yes, you can set gl_picmip to 40. No, we don't want you to show anyone. if (gl_picmip->integer > 1) blocking_cvars[nblocking++] = gl_picmip; if (gl_fog->integer < 1) blocking_cvars[nblocking++] = gl_fog; // TODO: check for other avant-garde video settings here. if (nblocking > 0) { Com_Printf ("Screenshots are disabled because of your settings for the following cvar"); if (nblocking > 1) Com_Printf ("s"); Com_Printf (":\n"); for (i = 0; i < nblocking; i++) { Com_Printf (" %s: %s\n", blocking_cvars[i]->name, blocking_cvars[i]->string); } return; } /* Create the scrnshots directory if it doesn't exist */ Com_sprintf(checkname, sizeof(checkname), "%s/scrnshot/", FS_Gamedir()); FS_CreatePath( checkname ); strcpy(picname,"AlienArena_000.jpg"); for (i=0 ; i<=999 ; i++) { picname[11] = i/100 + '0'; picname[12] = (i/10)%10 + '0'; picname[13] = i%10 + '0'; Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot/%s", FS_Gamedir(), picname); f = fopen (checkname, "rb"); if (!f) break; // file doesn't exist fclose (f); } if (i == 1000) { Com_Printf(PRINT_ALL, "GL_ScreenShot_JPEG: Couldn't create a file (You probably have taken to many screenshots!)\n"); return; } /* Open the file for Binary Output */ f = fopen(checkname, "wb"); if (!f) { Com_Printf(PRINT_ALL, "GL_ScreenShot_JPEG: Couldn't create a file\n"); return; } /* Allocate room for a copy of the framebuffer */ rgbdata = malloc(vid.width * vid.height * 3); if (!rgbdata) { fclose(f); return; } /* Read the framebuffer into our storage */ qglReadPixels(0, 0, vid.width, vid.height, GL_RGB, GL_UNSIGNED_BYTE, rgbdata); /* Initialise the JPEG compression object */ cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); jpeg_stdio_dest(&cinfo, f); /* Setup JPEG Parameters */ cinfo.image_width = vid.width; cinfo.image_height = vid.height; cinfo.in_color_space = JCS_RGB; cinfo.input_components = 3; jpeg_set_defaults(&cinfo); if ((gl_screenshot_jpeg_quality->integer >= 101) || (gl_screenshot_jpeg_quality->integer <= 0)) Cvar_Set("gl_screenshot_jpeg_quality", "85"); jpeg_set_quality(&cinfo, gl_screenshot_jpeg_quality->integer, TRUE); /* Start Compression */ jpeg_start_compress(&cinfo, true); /* Feed Scanline data */ offset = (cinfo.image_width * cinfo.image_height * 3) - (cinfo.image_width * 3); while (cinfo.next_scanline < cinfo.image_height) { s[0] = &rgbdata[offset - (cinfo.next_scanline * (cinfo.image_width * 3))]; jpeg_write_scanlines(&cinfo, s, 1); } /* Finish Compression */ jpeg_finish_compress(&cinfo); /* Destroy JPEG object */ jpeg_destroy_compress(&cinfo); /* Close File */ fclose(f); /* Free Temp Framebuffer */ free(rgbdata); /* Done! */ Com_Printf ("Wrote %s\n", picname); } /* ================== GL_ScreenShot_TGA ================== */ void GL_ScreenShot_TGA (void) { byte *buffer; char picname[80]; char checkname[MAX_OSPATH]; int i, c, temp; FILE *f; // create the scrnshots directory if it doesn't exist Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot/", FS_Gamedir()); FS_CreatePath( checkname ); // find a file name to save it to strcpy(picname,"AlienArena_000.tga"); for (i=0 ; i<=999 ; i++) { picname[11] = i/100 + '0'; picname[12] = (i/10)%10 + '0'; picname[13] = i%10 + '0'; Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot/%s", FS_Gamedir(), picname); f = fopen (checkname, "rb"); if (!f) break; // file doesn't exist fclose (f); } if (i==1000) { Com_Printf ("GL_ScreenShot_TGA: Couldn't create file %s (You probably have taken to many screenshots!)\n", picname); return; } buffer = malloc(vid.width*vid.height*3 + 18); memset (buffer, 0, 18); buffer[2] = 2; // uncompressed type buffer[12] = vid.width&255; buffer[13] = vid.width>>8; buffer[14] = vid.height&255; buffer[15] = vid.height>>8; buffer[16] = 24; // pixel size qglReadPixels (0, 0, vid.width, vid.height, GL_RGB, GL_UNSIGNED_BYTE, buffer+18 ); // swap rgb to bgr c = 18+vid.width*vid.height*3; for (i=18 ; istring, "jpeg") == 0) GL_ScreenShot_JPEG(); else if (strcmp(gl_screenshot_type->string, "tga") == 0) GL_ScreenShot_TGA(); else { Com_Printf("Invalid screenshot type %s; resetting to jpeg.\n", gl_screenshot_type->string); Cvar_Set("gl_screenshot_type", "jpeg"); GL_ScreenShot_JPEG(); } } /* ** GL_Strings_f */ void GL_Strings_f( void ) { Com_Printf ("GL_VENDOR: %s\n", gl_config.vendor_string ); Com_Printf ("GL_RENDERER: %s\n", gl_config.renderer_string ); Com_Printf ("GL_VERSION: %s\n", gl_config.version_string ); Com_Printf ("GL_EXTENSIONS: %s\n", gl_config.extensions_string ); } /* ** GL_SetDefaultState */ void GL_SetDefaultState( void ) { qglClearColor (1,0, 0.5 , 0.5); qglCullFace(GL_FRONT); qglEnable(GL_TEXTURE_2D); qglEnable(GL_ALPHA_TEST); qglAlphaFunc(GL_GREATER, 0.666); qglDisable (GL_DEPTH_TEST); qglDisable (GL_CULL_FACE); qglDisable (GL_BLEND); qglColor4f (1,1,1,1); qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); qglShadeModel (GL_FLAT); GL_TextureMode( gl_texturemode->string ); GL_TextureAlphaMode( gl_texturealphamode->string ); GL_TextureSolidMode( gl_texturesolidmode->string ); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GL_TexEnv( GL_REPLACE ); if ( qglPointParameterfEXT ) { float attenuations[3]; attenuations[0] = gl_particle_att_a->value; attenuations[1] = gl_particle_att_b->value; attenuations[2] = gl_particle_att_c->value; qglEnable( GL_POINT_SMOOTH ); qglPointParameterfEXT( GL_POINT_SIZE_MIN_EXT, gl_particle_min_size->value ); qglPointParameterfEXT( GL_POINT_SIZE_MAX_EXT, gl_particle_max_size->value ); qglPointParameterfvEXT( GL_DISTANCE_ATTENUATION_EXT, attenuations ); } GL_UpdateSwapInterval(); /* set memory alignment for glReadPixels() and glDrawPixels(). * default is 4, screenshots with 1366 vid width fail with that. * setting to 1 should work with any custom vid width. * also affects glTexImage2D() and other commands, so might cause problems. */ qglPixelStorei(GL_PACK_ALIGNMENT, 1); qglPixelStorei(GL_UNPACK_ALIGNMENT, 1); } void GL_UpdateSwapInterval( void ) { if ( gl_swapinterval->modified ) { gl_swapinterval->modified = false; if ( !gl_state.stereo_enabled ) { #if defined WIN32_VARIANT if ( qwglSwapIntervalEXT ) qwglSwapIntervalEXT( gl_swapinterval->value ); #endif } } } alien-arena-7.66+dfsg/source/ref_gl/r_draw.c0000600000175000017500000003256212204310130017771 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // r_draw.c #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "r_local.h" image_t *draw_chars; image_t *menu_chars; extern qboolean scrap_dirty; extern cvar_t *con_font; void Scrap_Upload (void); //small dot used for failsafe blank texture byte blanktexture[16][16] = { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, }; void RefreshFont (void) { int x,y; byte data[16][16][4]; // // tiny blank texture // for (x=0 ; x<16 ; x++) { for (y=0 ; y<16 ; y++) { data[y][x][0] = 255; data[y][x][1] = 255; data[y][x][2] = 255; data[y][x][3] = blanktexture[x][y]; } } draw_chars = GL_FindImage (va("fonts/%s.tga", con_font->string), it_pic); if (!draw_chars) { draw_chars = GL_FindImage ("fonts/default.tga", it_pic); Cvar_Set( "con_font", "default" ); if(!draw_chars) draw_chars = GL_LoadPic ("***font***", (byte *)data, 16, 16, it_pic, 32); } GL_Bind( draw_chars->texnum ); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); menu_chars = GL_FindImage ("fonts/menu.tga", it_pic); if(!menu_chars) menu_chars = GL_LoadPic ("***font***", (byte *)data, 16, 16, it_pic, 32); GL_Bind( menu_chars->texnum ); con_font->modified = false; } /* =============== Draw_InitLocal =============== */ void Draw_InitLocal (void) { RefreshFont(); } /* ============= R_RegisterPic ============= */ image_t *R_RegisterPic (const char *name) { image_t *gl; char fullname[MAX_QPATH]; if (name[0] != '/' && name[0] != '\\') { Com_sprintf (fullname, sizeof(fullname), "pics/%s.pcx", name); gl = GL_FindImage (fullname, it_pic); } else { // note: levelshot graphic is loaded here strcpy( fullname, &name[1] ); gl = GL_FindImage( fullname, it_pic ); // gl = GL_FindImage (name+1, it_pic); // sometimes gets "evelshot" instead of "levelshot", compiler bug??? } return gl; } image_t *R_RegisterParticlePic (const char *name) { image_t *gl; char fullname[MAX_QPATH]; if (name[0] != '/' && name[0] != '\\') { Com_sprintf (fullname, sizeof(fullname), "particles/%s.tga", name); gl = GL_FindImage (fullname, it_particle); } else { // 2010-10 match above workaround (paranoid) strcpy( fullname, &name[1] ); gl = GL_FindImage( fullname, it_particle ); } return gl; } image_t *R_RegisterParticleNormal (const char *name) { image_t *gl; char fullname[MAX_QPATH]; if (name[0] != '/' && name[0] != '\\') { Com_sprintf (fullname, sizeof(fullname), "particles/%s.tga", name); gl = GL_FindImage (fullname, it_pic); } else { // 2010-10 match above workaround (paranoid) strcpy( fullname, &name[1] ); gl = GL_FindImage( fullname, it_pic ); } return gl; } image_t *R_RegisterGfxPic (const char *name) { image_t *gl; char fullname[MAX_QPATH]; if (name[0] != '/' && name[0] != '\\') { Com_sprintf (fullname, sizeof(fullname), "gfx/%s.tga", name); gl = GL_FindImage (fullname, it_pic); } else { // 2010-10 match above workaround (paranoid) strcpy( fullname, &name[1] ); gl = GL_FindImage( fullname, it_pic ); } return gl; } image_t *R_RegisterPlayerIcon (const char *name) { image_t *gl; char fullname[MAX_QPATH]; if (name[0] != '/' && name[0] != '\\') { Com_sprintf (fullname, sizeof(fullname), "players/%s.tga", name); gl = GL_FindImage (fullname, it_pic); } else { // 2010-10 match above workaround (paranoid) strcpy( fullname, &name[1] ); gl = GL_FindImage( fullname, it_pic ); } return gl; } /* ============= Draw_PicExists ============= */ qboolean Draw_PicExists (const char *pic) { return R_RegisterPic (pic) != NULL; } /* ============= Draw_GetPicSize ============= */ void Draw_GetPicSize (int *w, int *h, const char *pic) { image_t *gl; gl = R_RegisterPic (pic); if (!gl) { *w = *h = -1; return; } *w = gl->width; *h = gl->height; } #define DIV254BY255 (0.9960784313725490196078431372549f) /* ============= Draw_AlphaStretchPic - Note: If tiling is true, the texture wrapping flags are adjusted to prevent gaps from appearing if the texture is tiled with itself or with other textures. This adjustment is permanent, although it would be easy to change the code to undo it after rendering. ============= */ enum draw_tiling_s { draw_without_tiling, draw_with_tiling }; void Draw_AlphaStretchImage (float x, float y, float w, float h, const image_t *gl, float alphaval, enum draw_tiling_s tiling) { rscript_t *rs; float alpha,s,t; rs_stage_t *stage; char shortname[MAX_QPATH]; float xscale, yscale; float cropped_x, cropped_y, cropped_w, cropped_h; if (scrap_dirty) Scrap_Upload (); COM_StripExtension ( gl->name, shortname ); rs = gl->script; //if we draw the red team bar, we are on red team if(!strcmp(shortname, "pics/i_team1")) r_teamColor = 1; else if(!strcmp(shortname, "pics/i_team2")) r_teamColor = 2; R_InitQuadVarrays(); if (!rs) { qglDisable (GL_ALPHA_TEST); qglEnable (GL_BLEND); GLSTATE_DISABLE_ALPHATEST GLSTATE_ENABLE_BLEND GL_TexEnv( GL_MODULATE ); xscale = (float)w/(float)gl->upload_width; yscale = (float)h/(float)gl->upload_height; cropped_x = x + xscale*(float)gl->crop_left; cropped_y = y + yscale*(float)gl->crop_top; cropped_w = xscale*(float)gl->crop_width; cropped_h = yscale*(float)gl->crop_height; VA_SetElem2(vert_array[0], cropped_x, cropped_y); VA_SetElem2(vert_array[1], cropped_x+cropped_w, cropped_y); VA_SetElem2(vert_array[2], cropped_x+cropped_w, cropped_y+cropped_h); VA_SetElem2(vert_array[3], cropped_x, cropped_y+cropped_h); qglColor4f(1,1,1, alphaval); //set color of hud by team if(r_teamColor == 1) { if(!strcmp(shortname, "pics/i_health")) qglColor4f(1, .2, .2, alphaval); } else if(r_teamColor == 2) { if(!strcmp(shortname, "pics/i_health")) qglColor4f(.1, .4, .8, alphaval); } VA_SetElem4(col_array[0], 1,1,1,1); VA_SetElem4(col_array[1], 1,1,1,1); VA_SetElem4(col_array[2], 1,1,1,1); VA_SetElem4(col_array[3], 1,1,1,1); GL_Bind (gl->texnum); if (tiling == draw_with_tiling) { qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); } VA_SetElem2(tex_array[0], gl->crop_sl, gl->crop_tl); VA_SetElem2(tex_array[1], gl->crop_sh, gl->crop_tl); VA_SetElem2(tex_array[2], gl->crop_sh, gl->crop_th); VA_SetElem2(tex_array[3], gl->crop_sl, gl->crop_th); R_DrawVarrays (GL_QUADS, 0, 4); qglEnable (GL_ALPHA_TEST); qglDisable (GL_BLEND); GLSTATE_DISABLE_BLEND GLSTATE_ENABLE_ALPHATEST R_KillVArrays(); } else { VA_SetElem2(vert_array[0], x, y); VA_SetElem2(vert_array[1], x+w, y); VA_SetElem2(vert_array[2], x+w, y+h); VA_SetElem2(vert_array[3], x, y+h); RS_ReadyScript(rs); stage=rs->stage; while (stage) { float red = 1, green = 1, blue = 1; if (stage->blendfunc.blend) { GLSTATE_ENABLE_BLEND GL_BlendFunction(stage->blendfunc.source,stage->blendfunc.dest); } else { GLSTATE_DISABLE_BLEND } alpha=1.0f; if (stage->alphashift.min || stage->alphashift.speed) { if (!stage->alphashift.speed && stage->alphashift.min > 0) { alpha=stage->alphashift.min; } else if (stage->alphashift.speed) { alpha=sin(rs_realtime * stage->alphashift.speed); alpha=(alpha+1)*0.5f; if (alpha > stage->alphashift.max) alpha=stage->alphashift.max; if (alpha < stage->alphashift.min) alpha=stage->alphashift.min; } } if (stage->alphamask) { GLSTATE_ENABLE_ALPHATEST } else { GLSTATE_DISABLE_ALPHATEST } if (stage->colormap.enabled) { red = stage->colormap.red/255.0; green = stage->colormap.green/255.0; blue = stage->colormap.blue/255.0; } qglColor4f(red,green,blue, alpha); VA_SetElem4(col_array[0], red,green,blue, alpha); VA_SetElem4(col_array[1], red,green,blue, alpha); VA_SetElem4(col_array[2], red,green,blue, alpha); VA_SetElem4(col_array[3], red,green,blue, alpha); if (stage->colormap.enabled) qglDisable (GL_TEXTURE_2D); else if (stage->anim_count) GL_Bind(RS_Animate(stage)); else GL_Bind (stage->texture->texnum); s = 0; t = 1; RS_SetTexcoords2D (stage, &s, &t); VA_SetElem2(tex_array[3],s, t); s = 0; t = 0; RS_SetTexcoords2D (stage, &s, &t); VA_SetElem2(tex_array[0],s, t); s = 1; t = 0; RS_SetTexcoords2D (stage, &s, &t); VA_SetElem2(tex_array[1],s, t); s = 1; t = 1; RS_SetTexcoords2D (stage, &s, &t); VA_SetElem2(tex_array[2],s, t); R_DrawVarrays(GL_QUADS, 0, 4); qglColor4f(1,1,1,1); if (stage->colormap.enabled) qglEnable (GL_TEXTURE_2D); stage=stage->next; } qglColor4f(1,1,1,1); GLSTATE_ENABLE_ALPHATEST GLSTATE_DISABLE_BLEND GL_BlendFunction (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); R_KillVArrays(); } } void Draw_AlphaStretchTilingPic (float x, float y, float w, float h, const char *pic, float alphaval) { image_t *gl; gl = R_RegisterPic (pic); if (!gl) { return; } Draw_AlphaStretchImage (x, y, w, h, gl, alphaval, draw_with_tiling); } /* ============= Draw_AlphaStretchPic ============= */ void Draw_AlphaStretchPic (float x, float y, float w, float h, const char *pic, float alphaval) { image_t *gl; gl = R_RegisterPic (pic); if (!gl) { return; } Draw_AlphaStretchImage (x, y, w, h, gl, alphaval, draw_without_tiling); } /* ============= Draw_StretchPic ============= */ void Draw_StretchPic (float x, float y, float w, float h, const char *pic) { Draw_AlphaStretchPic (x, y, w, h, pic, DIV254BY255); } /* ============= Draw_ScaledPic ============= */ void Draw_ScaledPic (float x, float y, float scale, const char *pic) { image_t *gl; float w, h; gl = R_RegisterPic (pic); if (!gl) { return; } w = (float)gl->width*scale; h = (float)gl->height*scale; Draw_AlphaStretchImage (x, y, w, h, gl, DIV254BY255, draw_without_tiling); } /* ============= Draw_Pic ============= */ void Draw_Pic (float x, float y, const char *pic) { Draw_ScaledPic (x, y, 1.0, pic); } /* ============= Draw_AlphaStretchPlayerIcon ============= */ void Draw_AlphaStretchPlayerIcon (int x, int y, int w, int h, const char *pic, float alphaval) { image_t *gl; gl = R_RegisterPlayerIcon (pic); if (!gl) { return; } Draw_AlphaStretchImage (x, y, w, h, gl, alphaval, draw_without_tiling); } /* ============= Draw_Fill Fills a box of pixels with a single color ============= */ void Draw_Fill (float x, float y, float w, float h, const float rgba[]) { qglDisable (GL_TEXTURE_2D); // FIXME HACK qglDisable (GL_ALPHA_TEST); qglEnable (GL_BLEND); GLSTATE_ENABLE_BLEND; GLSTATE_DISABLE_ALPHATEST; qglColor4fv (rgba); qglBegin (GL_QUADS); qglVertex2f (x,y); qglVertex2f (x+w, y); qglVertex2f (x+w, y+h); qglVertex2f (x, y+h); qglEnd (); GLSTATE_DISABLE_BLEND; qglColor3f (1,1,1); qglEnable (GL_TEXTURE_2D); } //============================================================================= /* ================ Draw_FadeScreen ================ */ void Draw_FadeScreen (void) { qglEnable (GL_BLEND); qglDisable (GL_TEXTURE_2D); qglColor4f (0, 0, 0, 0.8); qglBegin (GL_QUADS); qglVertex2f (0,0); qglVertex2f (vid.width, 0); qglVertex2f (vid.width, vid.height); qglVertex2f (0, vid.height); qglEnd (); qglColor4f (1,1,1,1); qglEnable (GL_TEXTURE_2D); qglDisable (GL_BLEND); } //============================================================================= /* ================ RGBA - This really should be a macro, but MSVC doesn't support C99. ================ */ float *RGBA (float r, float g, float b, float a) { static float ret[4]; ret[0] = r; ret[1] = g; ret[2] = b; ret[3] = a; return ret; } alien-arena-7.66+dfsg/source/ref_gl/glext.h0000600000175000017500000173070012161402007017652 0ustar zero79zero79#ifndef __glext_h_ #define __glext_h_ #ifdef __cplusplus extern "C" { #endif /* ** Copyright (c) 2007-2009 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and/or associated documentation files (the ** "Materials"), to deal in the Materials without restriction, including ** without limitation the rights to use, copy, modify, merge, publish, ** distribute, sublicense, and/or sell copies of the Materials, and to ** permit persons to whom the Materials are furnished to do so, subject to ** the following conditions: ** ** The above copyright notice and this permission notice shall be included ** in all copies or substantial portions of the Materials. ** ** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. */ /* Header file version number, required by OpenGL ABI for Linux */ /* glext.h last updated $Date: 2009-09-24 13:55:03 -0700 (Thu, 24 Sep 2009) $ */ /* Current version at http://www.opengl.org/registry/ */ #define GL_GLEXT_VERSION 56 /* Function declaration macros - to move into glplatform.h */ #if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) #define WIN32_LEAN_AND_MEAN 1 #include #endif #ifndef APIENTRY #define APIENTRY #endif #ifndef APIENTRYP #define APIENTRYP APIENTRY * #endif #ifndef GLAPI #define GLAPI extern #endif /*************************************************************/ #ifndef GL_VERSION_1_2 #define GL_UNSIGNED_BYTE_3_3_2 0x8032 #define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 #define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 #define GL_UNSIGNED_INT_8_8_8_8 0x8035 #define GL_UNSIGNED_INT_10_10_10_2 0x8036 #define GL_TEXTURE_BINDING_3D 0x806A #define GL_PACK_SKIP_IMAGES 0x806B #define GL_PACK_IMAGE_HEIGHT 0x806C #define GL_UNPACK_SKIP_IMAGES 0x806D #define GL_UNPACK_IMAGE_HEIGHT 0x806E #define GL_TEXTURE_3D 0x806F #define GL_PROXY_TEXTURE_3D 0x8070 #define GL_TEXTURE_DEPTH 0x8071 #define GL_TEXTURE_WRAP_R 0x8072 #define GL_MAX_3D_TEXTURE_SIZE 0x8073 #define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 #define GL_UNSIGNED_SHORT_5_6_5 0x8363 #define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 #define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 #define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 #define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 #define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 #define GL_BGR 0x80E0 #define GL_BGRA 0x80E1 #define GL_MAX_ELEMENTS_VERTICES 0x80E8 #define GL_MAX_ELEMENTS_INDICES 0x80E9 #define GL_CLAMP_TO_EDGE 0x812F #define GL_TEXTURE_MIN_LOD 0x813A #define GL_TEXTURE_MAX_LOD 0x813B #define GL_TEXTURE_BASE_LEVEL 0x813C #define GL_TEXTURE_MAX_LEVEL 0x813D #define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 #define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 #define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 #define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 #define GL_ALIASED_LINE_WIDTH_RANGE 0x846E #endif #ifndef GL_VERSION_1_2_DEPRECATED #define GL_RESCALE_NORMAL 0x803A #define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 #define GL_SINGLE_COLOR 0x81F9 #define GL_SEPARATE_SPECULAR_COLOR 0x81FA #define GL_ALIASED_POINT_SIZE_RANGE 0x846D #endif #ifndef GL_ARB_imaging #define GL_CONSTANT_COLOR 0x8001 #define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 #define GL_CONSTANT_ALPHA 0x8003 #define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 #define GL_BLEND_COLOR 0x8005 #define GL_FUNC_ADD 0x8006 #define GL_MIN 0x8007 #define GL_MAX 0x8008 #define GL_BLEND_EQUATION 0x8009 #define GL_FUNC_SUBTRACT 0x800A #define GL_FUNC_REVERSE_SUBTRACT 0x800B #endif #ifndef GL_ARB_imaging_DEPRECATED #define GL_CONVOLUTION_1D 0x8010 #define GL_CONVOLUTION_2D 0x8011 #define GL_SEPARABLE_2D 0x8012 #define GL_CONVOLUTION_BORDER_MODE 0x8013 #define GL_CONVOLUTION_FILTER_SCALE 0x8014 #define GL_CONVOLUTION_FILTER_BIAS 0x8015 #define GL_REDUCE 0x8016 #define GL_CONVOLUTION_FORMAT 0x8017 #define GL_CONVOLUTION_WIDTH 0x8018 #define GL_CONVOLUTION_HEIGHT 0x8019 #define GL_MAX_CONVOLUTION_WIDTH 0x801A #define GL_MAX_CONVOLUTION_HEIGHT 0x801B #define GL_POST_CONVOLUTION_RED_SCALE 0x801C #define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D #define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E #define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F #define GL_POST_CONVOLUTION_RED_BIAS 0x8020 #define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 #define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 #define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 #define GL_HISTOGRAM 0x8024 #define GL_PROXY_HISTOGRAM 0x8025 #define GL_HISTOGRAM_WIDTH 0x8026 #define GL_HISTOGRAM_FORMAT 0x8027 #define GL_HISTOGRAM_RED_SIZE 0x8028 #define GL_HISTOGRAM_GREEN_SIZE 0x8029 #define GL_HISTOGRAM_BLUE_SIZE 0x802A #define GL_HISTOGRAM_ALPHA_SIZE 0x802B #define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C #define GL_HISTOGRAM_SINK 0x802D #define GL_MINMAX 0x802E #define GL_MINMAX_FORMAT 0x802F #define GL_MINMAX_SINK 0x8030 #define GL_TABLE_TOO_LARGE 0x8031 #define GL_COLOR_MATRIX 0x80B1 #define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 #define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 #define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 #define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 #define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 #define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 #define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 #define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 #define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA #define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB #define GL_COLOR_TABLE 0x80D0 #define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 #define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 #define GL_PROXY_COLOR_TABLE 0x80D3 #define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 #define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 #define GL_COLOR_TABLE_SCALE 0x80D6 #define GL_COLOR_TABLE_BIAS 0x80D7 #define GL_COLOR_TABLE_FORMAT 0x80D8 #define GL_COLOR_TABLE_WIDTH 0x80D9 #define GL_COLOR_TABLE_RED_SIZE 0x80DA #define GL_COLOR_TABLE_GREEN_SIZE 0x80DB #define GL_COLOR_TABLE_BLUE_SIZE 0x80DC #define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD #define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE #define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF #define GL_CONSTANT_BORDER 0x8151 #define GL_REPLICATE_BORDER 0x8153 #define GL_CONVOLUTION_BORDER_COLOR 0x8154 #endif #ifndef GL_VERSION_1_3 #define GL_TEXTURE0 0x84C0 #define GL_TEXTURE1 0x84C1 #define GL_TEXTURE2 0x84C2 #define GL_TEXTURE3 0x84C3 #define GL_TEXTURE4 0x84C4 #define GL_TEXTURE5 0x84C5 #define GL_TEXTURE6 0x84C6 #define GL_TEXTURE7 0x84C7 #define GL_TEXTURE8 0x84C8 #define GL_TEXTURE9 0x84C9 #define GL_TEXTURE10 0x84CA #define GL_TEXTURE11 0x84CB #define GL_TEXTURE12 0x84CC #define GL_TEXTURE13 0x84CD #define GL_TEXTURE14 0x84CE #define GL_TEXTURE15 0x84CF #define GL_TEXTURE16 0x84D0 #define GL_TEXTURE17 0x84D1 #define GL_TEXTURE18 0x84D2 #define GL_TEXTURE19 0x84D3 #define GL_TEXTURE20 0x84D4 #define GL_TEXTURE21 0x84D5 #define GL_TEXTURE22 0x84D6 #define GL_TEXTURE23 0x84D7 #define GL_TEXTURE24 0x84D8 #define GL_TEXTURE25 0x84D9 #define GL_TEXTURE26 0x84DA #define GL_TEXTURE27 0x84DB #define GL_TEXTURE28 0x84DC #define GL_TEXTURE29 0x84DD #define GL_TEXTURE30 0x84DE #define GL_TEXTURE31 0x84DF #define GL_ACTIVE_TEXTURE 0x84E0 #define GL_MULTISAMPLE 0x809D #define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E #define GL_SAMPLE_ALPHA_TO_ONE 0x809F #define GL_SAMPLE_COVERAGE 0x80A0 #define GL_SAMPLE_BUFFERS 0x80A8 #define GL_SAMPLES 0x80A9 #define GL_SAMPLE_COVERAGE_VALUE 0x80AA #define GL_SAMPLE_COVERAGE_INVERT 0x80AB #define GL_TEXTURE_CUBE_MAP 0x8513 #define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 #define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A #define GL_PROXY_TEXTURE_CUBE_MAP 0x851B #define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C #define GL_COMPRESSED_RGB 0x84ED #define GL_COMPRESSED_RGBA 0x84EE #define GL_TEXTURE_COMPRESSION_HINT 0x84EF #define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 #define GL_TEXTURE_COMPRESSED 0x86A1 #define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 #define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 #define GL_CLAMP_TO_BORDER 0x812D #endif #ifndef GL_VERSION_1_3_DEPRECATED #define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 #define GL_MAX_TEXTURE_UNITS 0x84E2 #define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 #define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 #define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 #define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 #define GL_MULTISAMPLE_BIT 0x20000000 #define GL_NORMAL_MAP 0x8511 #define GL_REFLECTION_MAP 0x8512 #define GL_COMPRESSED_ALPHA 0x84E9 #define GL_COMPRESSED_LUMINANCE 0x84EA #define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB #define GL_COMPRESSED_INTENSITY 0x84EC #define GL_COMBINE 0x8570 #define GL_COMBINE_RGB 0x8571 #define GL_COMBINE_ALPHA 0x8572 #define GL_SOURCE0_RGB 0x8580 #define GL_SOURCE1_RGB 0x8581 #define GL_SOURCE2_RGB 0x8582 #define GL_SOURCE0_ALPHA 0x8588 #define GL_SOURCE1_ALPHA 0x8589 #define GL_SOURCE2_ALPHA 0x858A #define GL_OPERAND0_RGB 0x8590 #define GL_OPERAND1_RGB 0x8591 #define GL_OPERAND2_RGB 0x8592 #define GL_OPERAND0_ALPHA 0x8598 #define GL_OPERAND1_ALPHA 0x8599 #define GL_OPERAND2_ALPHA 0x859A #define GL_RGB_SCALE 0x8573 #define GL_ADD_SIGNED 0x8574 #define GL_INTERPOLATE 0x8575 #define GL_SUBTRACT 0x84E7 #define GL_CONSTANT 0x8576 #define GL_PRIMARY_COLOR 0x8577 #define GL_PREVIOUS 0x8578 #define GL_DOT3_RGB 0x86AE #define GL_DOT3_RGBA 0x86AF #endif #ifndef GL_VERSION_1_4 #define GL_BLEND_DST_RGB 0x80C8 #define GL_BLEND_SRC_RGB 0x80C9 #define GL_BLEND_DST_ALPHA 0x80CA #define GL_BLEND_SRC_ALPHA 0x80CB #define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 #define GL_DEPTH_COMPONENT16 0x81A5 #define GL_DEPTH_COMPONENT24 0x81A6 #define GL_DEPTH_COMPONENT32 0x81A7 #define GL_MIRRORED_REPEAT 0x8370 #define GL_MAX_TEXTURE_LOD_BIAS 0x84FD #define GL_TEXTURE_LOD_BIAS 0x8501 #define GL_INCR_WRAP 0x8507 #define GL_DECR_WRAP 0x8508 #define GL_TEXTURE_DEPTH_SIZE 0x884A #define GL_TEXTURE_COMPARE_MODE 0x884C #define GL_TEXTURE_COMPARE_FUNC 0x884D #endif #ifndef GL_VERSION_1_4_DEPRECATED #define GL_POINT_SIZE_MIN 0x8126 #define GL_POINT_SIZE_MAX 0x8127 #define GL_POINT_DISTANCE_ATTENUATION 0x8129 #define GL_GENERATE_MIPMAP 0x8191 #define GL_GENERATE_MIPMAP_HINT 0x8192 #define GL_FOG_COORDINATE_SOURCE 0x8450 #define GL_FOG_COORDINATE 0x8451 #define GL_FRAGMENT_DEPTH 0x8452 #define GL_CURRENT_FOG_COORDINATE 0x8453 #define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 #define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 #define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 #define GL_FOG_COORDINATE_ARRAY 0x8457 #define GL_COLOR_SUM 0x8458 #define GL_CURRENT_SECONDARY_COLOR 0x8459 #define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A #define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B #define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C #define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D #define GL_SECONDARY_COLOR_ARRAY 0x845E #define GL_TEXTURE_FILTER_CONTROL 0x8500 #define GL_DEPTH_TEXTURE_MODE 0x884B #define GL_COMPARE_R_TO_TEXTURE 0x884E #endif #ifndef GL_VERSION_1_5 #define GL_BUFFER_SIZE 0x8764 #define GL_BUFFER_USAGE 0x8765 #define GL_QUERY_COUNTER_BITS 0x8864 #define GL_CURRENT_QUERY 0x8865 #define GL_QUERY_RESULT 0x8866 #define GL_QUERY_RESULT_AVAILABLE 0x8867 #define GL_ARRAY_BUFFER 0x8892 #define GL_ELEMENT_ARRAY_BUFFER 0x8893 #define GL_ARRAY_BUFFER_BINDING 0x8894 #define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 #define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F #define GL_READ_ONLY 0x88B8 #define GL_WRITE_ONLY 0x88B9 #define GL_READ_WRITE 0x88BA #define GL_BUFFER_ACCESS 0x88BB #define GL_BUFFER_MAPPED 0x88BC #define GL_BUFFER_MAP_POINTER 0x88BD #define GL_STREAM_DRAW 0x88E0 #define GL_STREAM_READ 0x88E1 #define GL_STREAM_COPY 0x88E2 #define GL_STATIC_DRAW 0x88E4 #define GL_STATIC_READ 0x88E5 #define GL_STATIC_COPY 0x88E6 #define GL_DYNAMIC_DRAW 0x88E8 #define GL_DYNAMIC_READ 0x88E9 #define GL_DYNAMIC_COPY 0x88EA #define GL_SAMPLES_PASSED 0x8914 #endif #ifndef GL_VERSION_1_5_DEPRECATED #define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 #define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 #define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 #define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 #define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A #define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B #define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C #define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D #define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E #define GL_FOG_COORD_SRC 0x8450 #define GL_FOG_COORD 0x8451 #define GL_CURRENT_FOG_COORD 0x8453 #define GL_FOG_COORD_ARRAY_TYPE 0x8454 #define GL_FOG_COORD_ARRAY_STRIDE 0x8455 #define GL_FOG_COORD_ARRAY_POINTER 0x8456 #define GL_FOG_COORD_ARRAY 0x8457 #define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D #define GL_SRC0_RGB 0x8580 #define GL_SRC1_RGB 0x8581 #define GL_SRC2_RGB 0x8582 #define GL_SRC0_ALPHA 0x8588 #define GL_SRC1_ALPHA 0x8589 #define GL_SRC2_ALPHA 0x858A #endif #ifndef GL_VERSION_2_0 #define GL_BLEND_EQUATION_RGB 0x8009 #define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 #define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 #define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 #define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 #define GL_CURRENT_VERTEX_ATTRIB 0x8626 #define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 #define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 #define GL_STENCIL_BACK_FUNC 0x8800 #define GL_STENCIL_BACK_FAIL 0x8801 #define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 #define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 #define GL_MAX_DRAW_BUFFERS 0x8824 #define GL_DRAW_BUFFER0 0x8825 #define GL_DRAW_BUFFER1 0x8826 #define GL_DRAW_BUFFER2 0x8827 #define GL_DRAW_BUFFER3 0x8828 #define GL_DRAW_BUFFER4 0x8829 #define GL_DRAW_BUFFER5 0x882A #define GL_DRAW_BUFFER6 0x882B #define GL_DRAW_BUFFER7 0x882C #define GL_DRAW_BUFFER8 0x882D #define GL_DRAW_BUFFER9 0x882E #define GL_DRAW_BUFFER10 0x882F #define GL_DRAW_BUFFER11 0x8830 #define GL_DRAW_BUFFER12 0x8831 #define GL_DRAW_BUFFER13 0x8832 #define GL_DRAW_BUFFER14 0x8833 #define GL_DRAW_BUFFER15 0x8834 #define GL_BLEND_EQUATION_ALPHA 0x883D #define GL_MAX_VERTEX_ATTRIBS 0x8869 #define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A #define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 #define GL_FRAGMENT_SHADER 0x8B30 #define GL_VERTEX_SHADER 0x8B31 #define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 #define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A #define GL_MAX_VARYING_FLOATS 0x8B4B #define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C #define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D #define GL_SHADER_TYPE 0x8B4F #define GL_FLOAT_VEC2 0x8B50 #define GL_FLOAT_VEC3 0x8B51 #define GL_FLOAT_VEC4 0x8B52 #define GL_INT_VEC2 0x8B53 #define GL_INT_VEC3 0x8B54 #define GL_INT_VEC4 0x8B55 #define GL_BOOL 0x8B56 #define GL_BOOL_VEC2 0x8B57 #define GL_BOOL_VEC3 0x8B58 #define GL_BOOL_VEC4 0x8B59 #define GL_FLOAT_MAT2 0x8B5A #define GL_FLOAT_MAT3 0x8B5B #define GL_FLOAT_MAT4 0x8B5C #define GL_SAMPLER_1D 0x8B5D #define GL_SAMPLER_2D 0x8B5E #define GL_SAMPLER_3D 0x8B5F #define GL_SAMPLER_CUBE 0x8B60 #define GL_SAMPLER_1D_SHADOW 0x8B61 #define GL_SAMPLER_2D_SHADOW 0x8B62 #define GL_DELETE_STATUS 0x8B80 #define GL_COMPILE_STATUS 0x8B81 #define GL_LINK_STATUS 0x8B82 #define GL_VALIDATE_STATUS 0x8B83 #define GL_INFO_LOG_LENGTH 0x8B84 #define GL_ATTACHED_SHADERS 0x8B85 #define GL_ACTIVE_UNIFORMS 0x8B86 #define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 #define GL_SHADER_SOURCE_LENGTH 0x8B88 #define GL_ACTIVE_ATTRIBUTES 0x8B89 #define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A #define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B #define GL_SHADING_LANGUAGE_VERSION 0x8B8C #define GL_CURRENT_PROGRAM 0x8B8D #define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 #define GL_LOWER_LEFT 0x8CA1 #define GL_UPPER_LEFT 0x8CA2 #define GL_STENCIL_BACK_REF 0x8CA3 #define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 #define GL_STENCIL_BACK_WRITEMASK 0x8CA5 #endif #ifndef GL_VERSION_2_0_DEPRECATED #define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 #define GL_POINT_SPRITE 0x8861 #define GL_COORD_REPLACE 0x8862 #define GL_MAX_TEXTURE_COORDS 0x8871 #endif #ifndef GL_VERSION_2_1 #define GL_PIXEL_PACK_BUFFER 0x88EB #define GL_PIXEL_UNPACK_BUFFER 0x88EC #define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED #define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF #define GL_FLOAT_MAT2x3 0x8B65 #define GL_FLOAT_MAT2x4 0x8B66 #define GL_FLOAT_MAT3x2 0x8B67 #define GL_FLOAT_MAT3x4 0x8B68 #define GL_FLOAT_MAT4x2 0x8B69 #define GL_FLOAT_MAT4x3 0x8B6A #define GL_SRGB 0x8C40 #define GL_SRGB8 0x8C41 #define GL_SRGB_ALPHA 0x8C42 #define GL_SRGB8_ALPHA8 0x8C43 #define GL_COMPRESSED_SRGB 0x8C48 #define GL_COMPRESSED_SRGB_ALPHA 0x8C49 #endif #ifndef GL_VERSION_2_1_DEPRECATED #define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F #define GL_SLUMINANCE_ALPHA 0x8C44 #define GL_SLUMINANCE8_ALPHA8 0x8C45 #define GL_SLUMINANCE 0x8C46 #define GL_SLUMINANCE8 0x8C47 #define GL_COMPRESSED_SLUMINANCE 0x8C4A #define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B #endif #ifndef GL_VERSION_3_0 #define GL_COMPARE_REF_TO_TEXTURE 0x884E #define GL_CLIP_DISTANCE0 0x3000 #define GL_CLIP_DISTANCE1 0x3001 #define GL_CLIP_DISTANCE2 0x3002 #define GL_CLIP_DISTANCE3 0x3003 #define GL_CLIP_DISTANCE4 0x3004 #define GL_CLIP_DISTANCE5 0x3005 #define GL_CLIP_DISTANCE6 0x3006 #define GL_CLIP_DISTANCE7 0x3007 #define GL_MAX_CLIP_DISTANCES 0x0D32 #define GL_MAJOR_VERSION 0x821B #define GL_MINOR_VERSION 0x821C #define GL_NUM_EXTENSIONS 0x821D #define GL_CONTEXT_FLAGS 0x821E #define GL_DEPTH_BUFFER 0x8223 #define GL_STENCIL_BUFFER 0x8224 #define GL_COMPRESSED_RED 0x8225 #define GL_COMPRESSED_RG 0x8226 #define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001 #define GL_RGBA32F 0x8814 #define GL_RGB32F 0x8815 #define GL_RGBA16F 0x881A #define GL_RGB16F 0x881B #define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD #define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF #define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 #define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 #define GL_CLAMP_READ_COLOR 0x891C #define GL_FIXED_ONLY 0x891D #define GL_MAX_VARYING_COMPONENTS 0x8B4B #define GL_TEXTURE_1D_ARRAY 0x8C18 #define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 #define GL_TEXTURE_2D_ARRAY 0x8C1A #define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B #define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C #define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D #define GL_R11F_G11F_B10F 0x8C3A #define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B #define GL_RGB9_E5 0x8C3D #define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E #define GL_TEXTURE_SHARED_SIZE 0x8C3F #define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 #define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 #define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 #define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 #define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 #define GL_PRIMITIVES_GENERATED 0x8C87 #define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 #define GL_RASTERIZER_DISCARD 0x8C89 #define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B #define GL_INTERLEAVED_ATTRIBS 0x8C8C #define GL_SEPARATE_ATTRIBS 0x8C8D #define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E #define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F #define GL_RGBA32UI 0x8D70 #define GL_RGB32UI 0x8D71 #define GL_RGBA16UI 0x8D76 #define GL_RGB16UI 0x8D77 #define GL_RGBA8UI 0x8D7C #define GL_RGB8UI 0x8D7D #define GL_RGBA32I 0x8D82 #define GL_RGB32I 0x8D83 #define GL_RGBA16I 0x8D88 #define GL_RGB16I 0x8D89 #define GL_RGBA8I 0x8D8E #define GL_RGB8I 0x8D8F #define GL_RED_INTEGER 0x8D94 #define GL_GREEN_INTEGER 0x8D95 #define GL_BLUE_INTEGER 0x8D96 #define GL_RGB_INTEGER 0x8D98 #define GL_RGBA_INTEGER 0x8D99 #define GL_BGR_INTEGER 0x8D9A #define GL_BGRA_INTEGER 0x8D9B #define GL_SAMPLER_1D_ARRAY 0x8DC0 #define GL_SAMPLER_2D_ARRAY 0x8DC1 #define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 #define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 #define GL_SAMPLER_CUBE_SHADOW 0x8DC5 #define GL_UNSIGNED_INT_VEC2 0x8DC6 #define GL_UNSIGNED_INT_VEC3 0x8DC7 #define GL_UNSIGNED_INT_VEC4 0x8DC8 #define GL_INT_SAMPLER_1D 0x8DC9 #define GL_INT_SAMPLER_2D 0x8DCA #define GL_INT_SAMPLER_3D 0x8DCB #define GL_INT_SAMPLER_CUBE 0x8DCC #define GL_INT_SAMPLER_1D_ARRAY 0x8DCE #define GL_INT_SAMPLER_2D_ARRAY 0x8DCF #define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 #define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 #define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 #define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 #define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 #define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 #define GL_QUERY_WAIT 0x8E13 #define GL_QUERY_NO_WAIT 0x8E14 #define GL_QUERY_BY_REGION_WAIT 0x8E15 #define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 #define GL_BUFFER_ACCESS_FLAGS 0x911F #define GL_BUFFER_MAP_LENGTH 0x9120 #define GL_BUFFER_MAP_OFFSET 0x9121 /* Reuse tokens from ARB_depth_buffer_float */ /* reuse GL_DEPTH_COMPONENT32F */ /* reuse GL_DEPTH32F_STENCIL8 */ /* reuse GL_FLOAT_32_UNSIGNED_INT_24_8_REV */ /* Reuse tokens from ARB_framebuffer_object */ /* reuse GL_INVALID_FRAMEBUFFER_OPERATION */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE */ /* reuse GL_FRAMEBUFFER_DEFAULT */ /* reuse GL_FRAMEBUFFER_UNDEFINED */ /* reuse GL_DEPTH_STENCIL_ATTACHMENT */ /* reuse GL_INDEX */ /* reuse GL_MAX_RENDERBUFFER_SIZE */ /* reuse GL_DEPTH_STENCIL */ /* reuse GL_UNSIGNED_INT_24_8 */ /* reuse GL_DEPTH24_STENCIL8 */ /* reuse GL_TEXTURE_STENCIL_SIZE */ /* reuse GL_TEXTURE_RED_TYPE */ /* reuse GL_TEXTURE_GREEN_TYPE */ /* reuse GL_TEXTURE_BLUE_TYPE */ /* reuse GL_TEXTURE_ALPHA_TYPE */ /* reuse GL_TEXTURE_DEPTH_TYPE */ /* reuse GL_UNSIGNED_NORMALIZED */ /* reuse GL_FRAMEBUFFER_BINDING */ /* reuse GL_DRAW_FRAMEBUFFER_BINDING */ /* reuse GL_RENDERBUFFER_BINDING */ /* reuse GL_READ_FRAMEBUFFER */ /* reuse GL_DRAW_FRAMEBUFFER */ /* reuse GL_READ_FRAMEBUFFER_BINDING */ /* reuse GL_RENDERBUFFER_SAMPLES */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */ /* reuse GL_FRAMEBUFFER_COMPLETE */ /* reuse GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT */ /* reuse GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT */ /* reuse GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER */ /* reuse GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER */ /* reuse GL_FRAMEBUFFER_UNSUPPORTED */ /* reuse GL_MAX_COLOR_ATTACHMENTS */ /* reuse GL_COLOR_ATTACHMENT0 */ /* reuse GL_COLOR_ATTACHMENT1 */ /* reuse GL_COLOR_ATTACHMENT2 */ /* reuse GL_COLOR_ATTACHMENT3 */ /* reuse GL_COLOR_ATTACHMENT4 */ /* reuse GL_COLOR_ATTACHMENT5 */ /* reuse GL_COLOR_ATTACHMENT6 */ /* reuse GL_COLOR_ATTACHMENT7 */ /* reuse GL_COLOR_ATTACHMENT8 */ /* reuse GL_COLOR_ATTACHMENT9 */ /* reuse GL_COLOR_ATTACHMENT10 */ /* reuse GL_COLOR_ATTACHMENT11 */ /* reuse GL_COLOR_ATTACHMENT12 */ /* reuse GL_COLOR_ATTACHMENT13 */ /* reuse GL_COLOR_ATTACHMENT14 */ /* reuse GL_COLOR_ATTACHMENT15 */ /* reuse GL_DEPTH_ATTACHMENT */ /* reuse GL_STENCIL_ATTACHMENT */ /* reuse GL_FRAMEBUFFER */ /* reuse GL_RENDERBUFFER */ /* reuse GL_RENDERBUFFER_WIDTH */ /* reuse GL_RENDERBUFFER_HEIGHT */ /* reuse GL_RENDERBUFFER_INTERNAL_FORMAT */ /* reuse GL_STENCIL_INDEX1 */ /* reuse GL_STENCIL_INDEX4 */ /* reuse GL_STENCIL_INDEX8 */ /* reuse GL_STENCIL_INDEX16 */ /* reuse GL_RENDERBUFFER_RED_SIZE */ /* reuse GL_RENDERBUFFER_GREEN_SIZE */ /* reuse GL_RENDERBUFFER_BLUE_SIZE */ /* reuse GL_RENDERBUFFER_ALPHA_SIZE */ /* reuse GL_RENDERBUFFER_DEPTH_SIZE */ /* reuse GL_RENDERBUFFER_STENCIL_SIZE */ /* reuse GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE */ /* reuse GL_MAX_SAMPLES */ /* Reuse tokens from ARB_framebuffer_sRGB */ /* reuse GL_FRAMEBUFFER_SRGB */ /* Reuse tokens from ARB_half_float_vertex */ /* reuse GL_HALF_FLOAT */ /* Reuse tokens from ARB_map_buffer_range */ /* reuse GL_MAP_READ_BIT */ /* reuse GL_MAP_WRITE_BIT */ /* reuse GL_MAP_INVALIDATE_RANGE_BIT */ /* reuse GL_MAP_INVALIDATE_BUFFER_BIT */ /* reuse GL_MAP_FLUSH_EXPLICIT_BIT */ /* reuse GL_MAP_UNSYNCHRONIZED_BIT */ /* Reuse tokens from ARB_texture_compression_rgtc */ /* reuse GL_COMPRESSED_RED_RGTC1 */ /* reuse GL_COMPRESSED_SIGNED_RED_RGTC1 */ /* reuse GL_COMPRESSED_RG_RGTC2 */ /* reuse GL_COMPRESSED_SIGNED_RG_RGTC2 */ /* Reuse tokens from ARB_texture_rg */ /* reuse GL_RG */ /* reuse GL_RG_INTEGER */ /* reuse GL_R8 */ /* reuse GL_R16 */ /* reuse GL_RG8 */ /* reuse GL_RG16 */ /* reuse GL_R16F */ /* reuse GL_R32F */ /* reuse GL_RG16F */ /* reuse GL_RG32F */ /* reuse GL_R8I */ /* reuse GL_R8UI */ /* reuse GL_R16I */ /* reuse GL_R16UI */ /* reuse GL_R32I */ /* reuse GL_R32UI */ /* reuse GL_RG8I */ /* reuse GL_RG8UI */ /* reuse GL_RG16I */ /* reuse GL_RG16UI */ /* reuse GL_RG32I */ /* reuse GL_RG32UI */ /* Reuse tokens from ARB_vertex_array_object */ /* reuse GL_VERTEX_ARRAY_BINDING */ #endif #ifndef GL_VERSION_3_0_DEPRECATED #define GL_CLAMP_VERTEX_COLOR 0x891A #define GL_CLAMP_FRAGMENT_COLOR 0x891B #define GL_ALPHA_INTEGER 0x8D97 /* Reuse tokens from ARB_framebuffer_object */ /* reuse GL_TEXTURE_LUMINANCE_TYPE */ /* reuse GL_TEXTURE_INTENSITY_TYPE */ #endif #ifndef GL_VERSION_3_1 #define GL_SAMPLER_2D_RECT 0x8B63 #define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 #define GL_SAMPLER_BUFFER 0x8DC2 #define GL_INT_SAMPLER_2D_RECT 0x8DCD #define GL_INT_SAMPLER_BUFFER 0x8DD0 #define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 #define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 #define GL_TEXTURE_BUFFER 0x8C2A #define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B #define GL_TEXTURE_BINDING_BUFFER 0x8C2C #define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D #define GL_TEXTURE_BUFFER_FORMAT 0x8C2E #define GL_TEXTURE_RECTANGLE 0x84F5 #define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 #define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 #define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 #define GL_RED_SNORM 0x8F90 #define GL_RG_SNORM 0x8F91 #define GL_RGB_SNORM 0x8F92 #define GL_RGBA_SNORM 0x8F93 #define GL_R8_SNORM 0x8F94 #define GL_RG8_SNORM 0x8F95 #define GL_RGB8_SNORM 0x8F96 #define GL_RGBA8_SNORM 0x8F97 #define GL_R16_SNORM 0x8F98 #define GL_RG16_SNORM 0x8F99 #define GL_RGB16_SNORM 0x8F9A #define GL_RGBA16_SNORM 0x8F9B #define GL_SIGNED_NORMALIZED 0x8F9C #define GL_PRIMITIVE_RESTART 0x8F9D #define GL_PRIMITIVE_RESTART_INDEX 0x8F9E /* Reuse tokens from ARB_copy_buffer */ /* reuse GL_COPY_READ_BUFFER */ /* reuse GL_COPY_WRITE_BUFFER */ /* Would reuse tokens from ARB_draw_instanced, but it has none */ /* Reuse tokens from ARB_uniform_buffer_object */ /* reuse GL_UNIFORM_BUFFER */ /* reuse GL_UNIFORM_BUFFER_BINDING */ /* reuse GL_UNIFORM_BUFFER_START */ /* reuse GL_UNIFORM_BUFFER_SIZE */ /* reuse GL_MAX_VERTEX_UNIFORM_BLOCKS */ /* reuse GL_MAX_FRAGMENT_UNIFORM_BLOCKS */ /* reuse GL_MAX_COMBINED_UNIFORM_BLOCKS */ /* reuse GL_MAX_UNIFORM_BUFFER_BINDINGS */ /* reuse GL_MAX_UNIFORM_BLOCK_SIZE */ /* reuse GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS */ /* reuse GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS */ /* reuse GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT */ /* reuse GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH */ /* reuse GL_ACTIVE_UNIFORM_BLOCKS */ /* reuse GL_UNIFORM_TYPE */ /* reuse GL_UNIFORM_SIZE */ /* reuse GL_UNIFORM_NAME_LENGTH */ /* reuse GL_UNIFORM_BLOCK_INDEX */ /* reuse GL_UNIFORM_OFFSET */ /* reuse GL_UNIFORM_ARRAY_STRIDE */ /* reuse GL_UNIFORM_MATRIX_STRIDE */ /* reuse GL_UNIFORM_IS_ROW_MAJOR */ /* reuse GL_UNIFORM_BLOCK_BINDING */ /* reuse GL_UNIFORM_BLOCK_DATA_SIZE */ /* reuse GL_UNIFORM_BLOCK_NAME_LENGTH */ /* reuse GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS */ /* reuse GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES */ /* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER */ /* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER */ /* reuse GL_INVALID_INDEX */ #endif #ifndef GL_VERSION_3_2 #define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 #define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 #define GL_LINES_ADJACENCY 0x000A #define GL_LINE_STRIP_ADJACENCY 0x000B #define GL_TRIANGLES_ADJACENCY 0x000C #define GL_TRIANGLE_STRIP_ADJACENCY 0x000D #define GL_PROGRAM_POINT_SIZE 0x8642 #define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 #define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 #define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 #define GL_GEOMETRY_SHADER 0x8DD9 #define GL_GEOMETRY_VERTICES_OUT 0x8916 #define GL_GEOMETRY_INPUT_TYPE 0x8917 #define GL_GEOMETRY_OUTPUT_TYPE 0x8918 #define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF #define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 #define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 #define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 #define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 #define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 #define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 #define GL_CONTEXT_PROFILE_MASK 0x9126 /* reuse GL_MAX_VARYING_COMPONENTS */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */ /* Reuse tokens from ARB_depth_clamp */ /* reuse GL_DEPTH_CLAMP */ /* Would reuse tokens from ARB_draw_elements_base_vertex, but it has none */ /* Would reuse tokens from ARB_fragment_coord_conventions, but it has none */ /* Reuse tokens from ARB_provoking_vertex */ /* reuse GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION */ /* reuse GL_FIRST_VERTEX_CONVENTION */ /* reuse GL_LAST_VERTEX_CONVENTION */ /* reuse GL_PROVOKING_VERTEX */ /* Reuse tokens from ARB_seamless_cube_map */ /* reuse GL_TEXTURE_CUBE_MAP_SEAMLESS */ /* Reuse tokens from ARB_sync */ /* reuse GL_MAX_SERVER_WAIT_TIMEOUT */ /* reuse GL_OBJECT_TYPE */ /* reuse GL_SYNC_CONDITION */ /* reuse GL_SYNC_STATUS */ /* reuse GL_SYNC_FLAGS */ /* reuse GL_SYNC_FENCE */ /* reuse GL_SYNC_GPU_COMMANDS_COMPLETE */ /* reuse GL_UNSIGNALED */ /* reuse GL_SIGNALED */ /* reuse GL_ALREADY_SIGNALED */ /* reuse GL_TIMEOUT_EXPIRED */ /* reuse GL_CONDITION_SATISFIED */ /* reuse GL_WAIT_FAILED */ /* reuse GL_TIMEOUT_IGNORED */ /* reuse GL_SYNC_FLUSH_COMMANDS_BIT */ /* reuse GL_TIMEOUT_IGNORED */ /* Reuse tokens from ARB_texture_multisample */ /* reuse GL_SAMPLE_POSITION */ /* reuse GL_SAMPLE_MASK */ /* reuse GL_SAMPLE_MASK_VALUE */ /* reuse GL_MAX_SAMPLE_MASK_WORDS */ /* reuse GL_TEXTURE_2D_MULTISAMPLE */ /* reuse GL_PROXY_TEXTURE_2D_MULTISAMPLE */ /* reuse GL_TEXTURE_2D_MULTISAMPLE_ARRAY */ /* reuse GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY */ /* reuse GL_TEXTURE_BINDING_2D_MULTISAMPLE */ /* reuse GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY */ /* reuse GL_TEXTURE_SAMPLES */ /* reuse GL_TEXTURE_FIXED_SAMPLE_LOCATIONS */ /* reuse GL_SAMPLER_2D_MULTISAMPLE */ /* reuse GL_INT_SAMPLER_2D_MULTISAMPLE */ /* reuse GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE */ /* reuse GL_SAMPLER_2D_MULTISAMPLE_ARRAY */ /* reuse GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY */ /* reuse GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY */ /* reuse GL_MAX_COLOR_TEXTURE_SAMPLES */ /* reuse GL_MAX_DEPTH_TEXTURE_SAMPLES */ /* reuse GL_MAX_INTEGER_SAMPLES */ /* Don't need to reuse tokens from ARB_vertex_array_bgra since they're already in 1.2 core */ #endif #ifndef GL_ARB_multitexture #define GL_TEXTURE0_ARB 0x84C0 #define GL_TEXTURE1_ARB 0x84C1 #define GL_TEXTURE2_ARB 0x84C2 #define GL_TEXTURE3_ARB 0x84C3 #define GL_TEXTURE4_ARB 0x84C4 #define GL_TEXTURE5_ARB 0x84C5 #define GL_TEXTURE6_ARB 0x84C6 #define GL_TEXTURE7_ARB 0x84C7 #define GL_TEXTURE8_ARB 0x84C8 #define GL_TEXTURE9_ARB 0x84C9 #define GL_TEXTURE10_ARB 0x84CA #define GL_TEXTURE11_ARB 0x84CB #define GL_TEXTURE12_ARB 0x84CC #define GL_TEXTURE13_ARB 0x84CD #define GL_TEXTURE14_ARB 0x84CE #define GL_TEXTURE15_ARB 0x84CF #define GL_TEXTURE16_ARB 0x84D0 #define GL_TEXTURE17_ARB 0x84D1 #define GL_TEXTURE18_ARB 0x84D2 #define GL_TEXTURE19_ARB 0x84D3 #define GL_TEXTURE20_ARB 0x84D4 #define GL_TEXTURE21_ARB 0x84D5 #define GL_TEXTURE22_ARB 0x84D6 #define GL_TEXTURE23_ARB 0x84D7 #define GL_TEXTURE24_ARB 0x84D8 #define GL_TEXTURE25_ARB 0x84D9 #define GL_TEXTURE26_ARB 0x84DA #define GL_TEXTURE27_ARB 0x84DB #define GL_TEXTURE28_ARB 0x84DC #define GL_TEXTURE29_ARB 0x84DD #define GL_TEXTURE30_ARB 0x84DE #define GL_TEXTURE31_ARB 0x84DF #define GL_ACTIVE_TEXTURE_ARB 0x84E0 #define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 #define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 #endif #ifndef GL_ARB_transpose_matrix #define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 #define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 #define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 #define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 #endif #ifndef GL_ARB_multisample #define GL_MULTISAMPLE_ARB 0x809D #define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E #define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F #define GL_SAMPLE_COVERAGE_ARB 0x80A0 #define GL_SAMPLE_BUFFERS_ARB 0x80A8 #define GL_SAMPLES_ARB 0x80A9 #define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA #define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB #define GL_MULTISAMPLE_BIT_ARB 0x20000000 #endif #ifndef GL_ARB_texture_env_add #endif #ifndef GL_ARB_texture_cube_map #define GL_NORMAL_MAP_ARB 0x8511 #define GL_REFLECTION_MAP_ARB 0x8512 #define GL_TEXTURE_CUBE_MAP_ARB 0x8513 #define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 #define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A #define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B #define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C #endif #ifndef GL_ARB_texture_compression #define GL_COMPRESSED_ALPHA_ARB 0x84E9 #define GL_COMPRESSED_LUMINANCE_ARB 0x84EA #define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB #define GL_COMPRESSED_INTENSITY_ARB 0x84EC #define GL_COMPRESSED_RGB_ARB 0x84ED #define GL_COMPRESSED_RGBA_ARB 0x84EE #define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF #define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 #define GL_TEXTURE_COMPRESSED_ARB 0x86A1 #define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 #define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 #endif #ifndef GL_ARB_texture_border_clamp #define GL_CLAMP_TO_BORDER_ARB 0x812D #endif #ifndef GL_ARB_point_parameters #define GL_POINT_SIZE_MIN_ARB 0x8126 #define GL_POINT_SIZE_MAX_ARB 0x8127 #define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 #define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 #endif #ifndef GL_ARB_vertex_blend #define GL_MAX_VERTEX_UNITS_ARB 0x86A4 #define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 #define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 #define GL_VERTEX_BLEND_ARB 0x86A7 #define GL_CURRENT_WEIGHT_ARB 0x86A8 #define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 #define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA #define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB #define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC #define GL_WEIGHT_ARRAY_ARB 0x86AD #define GL_MODELVIEW0_ARB 0x1700 #define GL_MODELVIEW1_ARB 0x850A #define GL_MODELVIEW2_ARB 0x8722 #define GL_MODELVIEW3_ARB 0x8723 #define GL_MODELVIEW4_ARB 0x8724 #define GL_MODELVIEW5_ARB 0x8725 #define GL_MODELVIEW6_ARB 0x8726 #define GL_MODELVIEW7_ARB 0x8727 #define GL_MODELVIEW8_ARB 0x8728 #define GL_MODELVIEW9_ARB 0x8729 #define GL_MODELVIEW10_ARB 0x872A #define GL_MODELVIEW11_ARB 0x872B #define GL_MODELVIEW12_ARB 0x872C #define GL_MODELVIEW13_ARB 0x872D #define GL_MODELVIEW14_ARB 0x872E #define GL_MODELVIEW15_ARB 0x872F #define GL_MODELVIEW16_ARB 0x8730 #define GL_MODELVIEW17_ARB 0x8731 #define GL_MODELVIEW18_ARB 0x8732 #define GL_MODELVIEW19_ARB 0x8733 #define GL_MODELVIEW20_ARB 0x8734 #define GL_MODELVIEW21_ARB 0x8735 #define GL_MODELVIEW22_ARB 0x8736 #define GL_MODELVIEW23_ARB 0x8737 #define GL_MODELVIEW24_ARB 0x8738 #define GL_MODELVIEW25_ARB 0x8739 #define GL_MODELVIEW26_ARB 0x873A #define GL_MODELVIEW27_ARB 0x873B #define GL_MODELVIEW28_ARB 0x873C #define GL_MODELVIEW29_ARB 0x873D #define GL_MODELVIEW30_ARB 0x873E #define GL_MODELVIEW31_ARB 0x873F #endif #ifndef GL_ARB_matrix_palette #define GL_MATRIX_PALETTE_ARB 0x8840 #define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 #define GL_MAX_PALETTE_MATRICES_ARB 0x8842 #define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 #define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 #define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 #define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 #define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 #define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 #define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 #endif #ifndef GL_ARB_texture_env_combine #define GL_COMBINE_ARB 0x8570 #define GL_COMBINE_RGB_ARB 0x8571 #define GL_COMBINE_ALPHA_ARB 0x8572 #define GL_SOURCE0_RGB_ARB 0x8580 #define GL_SOURCE1_RGB_ARB 0x8581 #define GL_SOURCE2_RGB_ARB 0x8582 #define GL_SOURCE0_ALPHA_ARB 0x8588 #define GL_SOURCE1_ALPHA_ARB 0x8589 #define GL_SOURCE2_ALPHA_ARB 0x858A #define GL_OPERAND0_RGB_ARB 0x8590 #define GL_OPERAND1_RGB_ARB 0x8591 #define GL_OPERAND2_RGB_ARB 0x8592 #define GL_OPERAND0_ALPHA_ARB 0x8598 #define GL_OPERAND1_ALPHA_ARB 0x8599 #define GL_OPERAND2_ALPHA_ARB 0x859A #define GL_RGB_SCALE_ARB 0x8573 #define GL_ADD_SIGNED_ARB 0x8574 #define GL_INTERPOLATE_ARB 0x8575 #define GL_SUBTRACT_ARB 0x84E7 #define GL_CONSTANT_ARB 0x8576 #define GL_PRIMARY_COLOR_ARB 0x8577 #define GL_PREVIOUS_ARB 0x8578 #endif #ifndef GL_ARB_texture_env_crossbar #endif #ifndef GL_ARB_texture_env_dot3 #define GL_DOT3_RGB_ARB 0x86AE #define GL_DOT3_RGBA_ARB 0x86AF #endif #ifndef GL_ARB_texture_mirrored_repeat #define GL_MIRRORED_REPEAT_ARB 0x8370 #endif #ifndef GL_ARB_depth_texture #define GL_DEPTH_COMPONENT16_ARB 0x81A5 #define GL_DEPTH_COMPONENT24_ARB 0x81A6 #define GL_DEPTH_COMPONENT32_ARB 0x81A7 #define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A #define GL_DEPTH_TEXTURE_MODE_ARB 0x884B #endif #ifndef GL_ARB_shadow #define GL_TEXTURE_COMPARE_MODE_ARB 0x884C #define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D #define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E #endif #ifndef GL_ARB_shadow_ambient #define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF #endif #ifndef GL_ARB_window_pos #endif #ifndef GL_ARB_vertex_program #define GL_COLOR_SUM_ARB 0x8458 #define GL_VERTEX_PROGRAM_ARB 0x8620 #define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 #define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 #define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 #define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 #define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 #define GL_PROGRAM_LENGTH_ARB 0x8627 #define GL_PROGRAM_STRING_ARB 0x8628 #define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E #define GL_MAX_PROGRAM_MATRICES_ARB 0x862F #define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 #define GL_CURRENT_MATRIX_ARB 0x8641 #define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 #define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 #define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 #define GL_PROGRAM_ERROR_POSITION_ARB 0x864B #define GL_PROGRAM_BINDING_ARB 0x8677 #define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 #define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A #define GL_PROGRAM_ERROR_STRING_ARB 0x8874 #define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 #define GL_PROGRAM_FORMAT_ARB 0x8876 #define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 #define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 #define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 #define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 #define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 #define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 #define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 #define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 #define GL_PROGRAM_PARAMETERS_ARB 0x88A8 #define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 #define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA #define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB #define GL_PROGRAM_ATTRIBS_ARB 0x88AC #define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD #define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE #define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF #define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 #define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 #define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 #define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 #define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 #define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 #define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 #define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 #define GL_MATRIX0_ARB 0x88C0 #define GL_MATRIX1_ARB 0x88C1 #define GL_MATRIX2_ARB 0x88C2 #define GL_MATRIX3_ARB 0x88C3 #define GL_MATRIX4_ARB 0x88C4 #define GL_MATRIX5_ARB 0x88C5 #define GL_MATRIX6_ARB 0x88C6 #define GL_MATRIX7_ARB 0x88C7 #define GL_MATRIX8_ARB 0x88C8 #define GL_MATRIX9_ARB 0x88C9 #define GL_MATRIX10_ARB 0x88CA #define GL_MATRIX11_ARB 0x88CB #define GL_MATRIX12_ARB 0x88CC #define GL_MATRIX13_ARB 0x88CD #define GL_MATRIX14_ARB 0x88CE #define GL_MATRIX15_ARB 0x88CF #define GL_MATRIX16_ARB 0x88D0 #define GL_MATRIX17_ARB 0x88D1 #define GL_MATRIX18_ARB 0x88D2 #define GL_MATRIX19_ARB 0x88D3 #define GL_MATRIX20_ARB 0x88D4 #define GL_MATRIX21_ARB 0x88D5 #define GL_MATRIX22_ARB 0x88D6 #define GL_MATRIX23_ARB 0x88D7 #define GL_MATRIX24_ARB 0x88D8 #define GL_MATRIX25_ARB 0x88D9 #define GL_MATRIX26_ARB 0x88DA #define GL_MATRIX27_ARB 0x88DB #define GL_MATRIX28_ARB 0x88DC #define GL_MATRIX29_ARB 0x88DD #define GL_MATRIX30_ARB 0x88DE #define GL_MATRIX31_ARB 0x88DF #endif #ifndef GL_ARB_fragment_program #define GL_FRAGMENT_PROGRAM_ARB 0x8804 #define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 #define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 #define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 #define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 #define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 #define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A #define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B #define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C #define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D #define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E #define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F #define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 #define GL_MAX_TEXTURE_COORDS_ARB 0x8871 #define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 #endif #ifndef GL_ARB_vertex_buffer_object #define GL_BUFFER_SIZE_ARB 0x8764 #define GL_BUFFER_USAGE_ARB 0x8765 #define GL_ARRAY_BUFFER_ARB 0x8892 #define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 #define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 #define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 #define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 #define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 #define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 #define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 #define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A #define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B #define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C #define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D #define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E #define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F #define GL_READ_ONLY_ARB 0x88B8 #define GL_WRITE_ONLY_ARB 0x88B9 #define GL_READ_WRITE_ARB 0x88BA #define GL_BUFFER_ACCESS_ARB 0x88BB #define GL_BUFFER_MAPPED_ARB 0x88BC #define GL_BUFFER_MAP_POINTER_ARB 0x88BD #define GL_STREAM_DRAW_ARB 0x88E0 #define GL_STREAM_READ_ARB 0x88E1 #define GL_STREAM_COPY_ARB 0x88E2 #define GL_STATIC_DRAW_ARB 0x88E4 #define GL_STATIC_READ_ARB 0x88E5 #define GL_STATIC_COPY_ARB 0x88E6 #define GL_DYNAMIC_DRAW_ARB 0x88E8 #define GL_DYNAMIC_READ_ARB 0x88E9 #define GL_DYNAMIC_COPY_ARB 0x88EA #endif #ifndef GL_ARB_occlusion_query #define GL_QUERY_COUNTER_BITS_ARB 0x8864 #define GL_CURRENT_QUERY_ARB 0x8865 #define GL_QUERY_RESULT_ARB 0x8866 #define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 #define GL_SAMPLES_PASSED_ARB 0x8914 #endif #ifndef GL_ARB_shader_objects #define GL_PROGRAM_OBJECT_ARB 0x8B40 #define GL_SHADER_OBJECT_ARB 0x8B48 #define GL_OBJECT_TYPE_ARB 0x8B4E #define GL_OBJECT_SUBTYPE_ARB 0x8B4F #define GL_FLOAT_VEC2_ARB 0x8B50 #define GL_FLOAT_VEC3_ARB 0x8B51 #define GL_FLOAT_VEC4_ARB 0x8B52 #define GL_INT_VEC2_ARB 0x8B53 #define GL_INT_VEC3_ARB 0x8B54 #define GL_INT_VEC4_ARB 0x8B55 #define GL_BOOL_ARB 0x8B56 #define GL_BOOL_VEC2_ARB 0x8B57 #define GL_BOOL_VEC3_ARB 0x8B58 #define GL_BOOL_VEC4_ARB 0x8B59 #define GL_FLOAT_MAT2_ARB 0x8B5A #define GL_FLOAT_MAT3_ARB 0x8B5B #define GL_FLOAT_MAT4_ARB 0x8B5C #define GL_SAMPLER_1D_ARB 0x8B5D #define GL_SAMPLER_2D_ARB 0x8B5E #define GL_SAMPLER_3D_ARB 0x8B5F #define GL_SAMPLER_CUBE_ARB 0x8B60 #define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 #define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 #define GL_SAMPLER_2D_RECT_ARB 0x8B63 #define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 #define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 #define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 #define GL_OBJECT_LINK_STATUS_ARB 0x8B82 #define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 #define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 #define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 #define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 #define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 #define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 #endif #ifndef GL_ARB_vertex_shader #define GL_VERTEX_SHADER_ARB 0x8B31 #define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A #define GL_MAX_VARYING_FLOATS_ARB 0x8B4B #define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C #define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D #define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 #define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A #endif #ifndef GL_ARB_fragment_shader #define GL_FRAGMENT_SHADER_ARB 0x8B30 #define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 #define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B #endif #ifndef GL_ARB_shading_language_100 #define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C #endif #ifndef GL_ARB_texture_non_power_of_two #endif #ifndef GL_ARB_point_sprite #define GL_POINT_SPRITE_ARB 0x8861 #define GL_COORD_REPLACE_ARB 0x8862 #endif #ifndef GL_ARB_fragment_program_shadow #endif #ifndef GL_ARB_draw_buffers #define GL_MAX_DRAW_BUFFERS_ARB 0x8824 #define GL_DRAW_BUFFER0_ARB 0x8825 #define GL_DRAW_BUFFER1_ARB 0x8826 #define GL_DRAW_BUFFER2_ARB 0x8827 #define GL_DRAW_BUFFER3_ARB 0x8828 #define GL_DRAW_BUFFER4_ARB 0x8829 #define GL_DRAW_BUFFER5_ARB 0x882A #define GL_DRAW_BUFFER6_ARB 0x882B #define GL_DRAW_BUFFER7_ARB 0x882C #define GL_DRAW_BUFFER8_ARB 0x882D #define GL_DRAW_BUFFER9_ARB 0x882E #define GL_DRAW_BUFFER10_ARB 0x882F #define GL_DRAW_BUFFER11_ARB 0x8830 #define GL_DRAW_BUFFER12_ARB 0x8831 #define GL_DRAW_BUFFER13_ARB 0x8832 #define GL_DRAW_BUFFER14_ARB 0x8833 #define GL_DRAW_BUFFER15_ARB 0x8834 #endif #ifndef GL_ARB_texture_rectangle #define GL_TEXTURE_RECTANGLE_ARB 0x84F5 #define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 #define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 #define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 #endif #ifndef GL_ARB_color_buffer_float #define GL_RGBA_FLOAT_MODE_ARB 0x8820 #define GL_CLAMP_VERTEX_COLOR_ARB 0x891A #define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B #define GL_CLAMP_READ_COLOR_ARB 0x891C #define GL_FIXED_ONLY_ARB 0x891D #endif #ifndef GL_ARB_half_float_pixel #define GL_HALF_FLOAT_ARB 0x140B #endif #ifndef GL_ARB_texture_float #define GL_TEXTURE_RED_TYPE_ARB 0x8C10 #define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 #define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 #define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 #define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 #define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 #define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 #define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 #define GL_RGBA32F_ARB 0x8814 #define GL_RGB32F_ARB 0x8815 #define GL_ALPHA32F_ARB 0x8816 #define GL_INTENSITY32F_ARB 0x8817 #define GL_LUMINANCE32F_ARB 0x8818 #define GL_LUMINANCE_ALPHA32F_ARB 0x8819 #define GL_RGBA16F_ARB 0x881A #define GL_RGB16F_ARB 0x881B #define GL_ALPHA16F_ARB 0x881C #define GL_INTENSITY16F_ARB 0x881D #define GL_LUMINANCE16F_ARB 0x881E #define GL_LUMINANCE_ALPHA16F_ARB 0x881F #endif #ifndef GL_ARB_pixel_buffer_object #define GL_PIXEL_PACK_BUFFER_ARB 0x88EB #define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC #define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED #define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF #endif #ifndef GL_ARB_depth_buffer_float #define GL_DEPTH_COMPONENT32F 0x8CAC #define GL_DEPTH32F_STENCIL8 0x8CAD #define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD #endif #ifndef GL_ARB_draw_instanced #endif #ifndef GL_ARB_framebuffer_object #define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 #define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 #define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 #define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 #define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 #define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 #define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 #define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 #define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 #define GL_FRAMEBUFFER_DEFAULT 0x8218 #define GL_FRAMEBUFFER_UNDEFINED 0x8219 #define GL_DEPTH_STENCIL_ATTACHMENT 0x821A #define GL_MAX_RENDERBUFFER_SIZE 0x84E8 #define GL_DEPTH_STENCIL 0x84F9 #define GL_UNSIGNED_INT_24_8 0x84FA #define GL_DEPTH24_STENCIL8 0x88F0 #define GL_TEXTURE_STENCIL_SIZE 0x88F1 #define GL_TEXTURE_RED_TYPE 0x8C10 #define GL_TEXTURE_GREEN_TYPE 0x8C11 #define GL_TEXTURE_BLUE_TYPE 0x8C12 #define GL_TEXTURE_ALPHA_TYPE 0x8C13 #define GL_TEXTURE_DEPTH_TYPE 0x8C16 #define GL_UNSIGNED_NORMALIZED 0x8C17 #define GL_FRAMEBUFFER_BINDING 0x8CA6 #define GL_DRAW_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING #define GL_RENDERBUFFER_BINDING 0x8CA7 #define GL_READ_FRAMEBUFFER 0x8CA8 #define GL_DRAW_FRAMEBUFFER 0x8CA9 #define GL_READ_FRAMEBUFFER_BINDING 0x8CAA #define GL_RENDERBUFFER_SAMPLES 0x8CAB #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 #define GL_FRAMEBUFFER_COMPLETE 0x8CD5 #define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 #define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 #define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB #define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC #define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD #define GL_MAX_COLOR_ATTACHMENTS 0x8CDF #define GL_COLOR_ATTACHMENT0 0x8CE0 #define GL_COLOR_ATTACHMENT1 0x8CE1 #define GL_COLOR_ATTACHMENT2 0x8CE2 #define GL_COLOR_ATTACHMENT3 0x8CE3 #define GL_COLOR_ATTACHMENT4 0x8CE4 #define GL_COLOR_ATTACHMENT5 0x8CE5 #define GL_COLOR_ATTACHMENT6 0x8CE6 #define GL_COLOR_ATTACHMENT7 0x8CE7 #define GL_COLOR_ATTACHMENT8 0x8CE8 #define GL_COLOR_ATTACHMENT9 0x8CE9 #define GL_COLOR_ATTACHMENT10 0x8CEA #define GL_COLOR_ATTACHMENT11 0x8CEB #define GL_COLOR_ATTACHMENT12 0x8CEC #define GL_COLOR_ATTACHMENT13 0x8CED #define GL_COLOR_ATTACHMENT14 0x8CEE #define GL_COLOR_ATTACHMENT15 0x8CEF #define GL_DEPTH_ATTACHMENT 0x8D00 #define GL_STENCIL_ATTACHMENT 0x8D20 #define GL_FRAMEBUFFER 0x8D40 #define GL_RENDERBUFFER 0x8D41 #define GL_RENDERBUFFER_WIDTH 0x8D42 #define GL_RENDERBUFFER_HEIGHT 0x8D43 #define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 #define GL_STENCIL_INDEX1 0x8D46 #define GL_STENCIL_INDEX4 0x8D47 #define GL_STENCIL_INDEX8 0x8D48 #define GL_STENCIL_INDEX16 0x8D49 #define GL_RENDERBUFFER_RED_SIZE 0x8D50 #define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 #define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 #define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 #define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 #define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 #define GL_MAX_SAMPLES 0x8D57 #endif #ifndef GL_ARB_framebuffer_object_DEPRECATED #define GL_INDEX 0x8222 #define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 #define GL_TEXTURE_INTENSITY_TYPE 0x8C15 #endif #ifndef GL_ARB_framebuffer_sRGB #define GL_FRAMEBUFFER_SRGB 0x8DB9 #endif #ifndef GL_ARB_geometry_shader4 #define GL_LINES_ADJACENCY_ARB 0x000A #define GL_LINE_STRIP_ADJACENCY_ARB 0x000B #define GL_TRIANGLES_ADJACENCY_ARB 0x000C #define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0x000D #define GL_PROGRAM_POINT_SIZE_ARB 0x8642 #define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29 #define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7 #define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8 #define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9 #define GL_GEOMETRY_SHADER_ARB 0x8DD9 #define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA #define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB #define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC #define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD #define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE #define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF #define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0 #define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1 /* reuse GL_MAX_VARYING_COMPONENTS */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */ #endif #ifndef GL_ARB_half_float_vertex #define GL_HALF_FLOAT 0x140B #endif #ifndef GL_ARB_instanced_arrays #define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE #endif #ifndef GL_ARB_map_buffer_range #define GL_MAP_READ_BIT 0x0001 #define GL_MAP_WRITE_BIT 0x0002 #define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 #define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 #define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 #define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 #endif #ifndef GL_ARB_texture_buffer_object #define GL_TEXTURE_BUFFER_ARB 0x8C2A #define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B #define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C #define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D #define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E #endif #ifndef GL_ARB_texture_compression_rgtc #define GL_COMPRESSED_RED_RGTC1 0x8DBB #define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC #define GL_COMPRESSED_RG_RGTC2 0x8DBD #define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE #endif #ifndef GL_ARB_texture_rg #define GL_RG 0x8227 #define GL_RG_INTEGER 0x8228 #define GL_R8 0x8229 #define GL_R16 0x822A #define GL_RG8 0x822B #define GL_RG16 0x822C #define GL_R16F 0x822D #define GL_R32F 0x822E #define GL_RG16F 0x822F #define GL_RG32F 0x8230 #define GL_R8I 0x8231 #define GL_R8UI 0x8232 #define GL_R16I 0x8233 #define GL_R16UI 0x8234 #define GL_R32I 0x8235 #define GL_R32UI 0x8236 #define GL_RG8I 0x8237 #define GL_RG8UI 0x8238 #define GL_RG16I 0x8239 #define GL_RG16UI 0x823A #define GL_RG32I 0x823B #define GL_RG32UI 0x823C #endif #ifndef GL_ARB_vertex_array_object #define GL_VERTEX_ARRAY_BINDING 0x85B5 #endif #ifndef GL_ARB_uniform_buffer_object #define GL_UNIFORM_BUFFER 0x8A11 #define GL_UNIFORM_BUFFER_BINDING 0x8A28 #define GL_UNIFORM_BUFFER_START 0x8A29 #define GL_UNIFORM_BUFFER_SIZE 0x8A2A #define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B #define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C #define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D #define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E #define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F #define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 #define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 #define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 #define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 #define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 #define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 #define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 #define GL_UNIFORM_TYPE 0x8A37 #define GL_UNIFORM_SIZE 0x8A38 #define GL_UNIFORM_NAME_LENGTH 0x8A39 #define GL_UNIFORM_BLOCK_INDEX 0x8A3A #define GL_UNIFORM_OFFSET 0x8A3B #define GL_UNIFORM_ARRAY_STRIDE 0x8A3C #define GL_UNIFORM_MATRIX_STRIDE 0x8A3D #define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E #define GL_UNIFORM_BLOCK_BINDING 0x8A3F #define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 #define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 #define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 #define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 #define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 #define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 #define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 #define GL_INVALID_INDEX 0xFFFFFFFFu #endif #ifndef GL_ARB_compatibility /* ARB_compatibility just defines tokens from core 3.0 */ #endif #ifndef GL_ARB_copy_buffer #define GL_COPY_READ_BUFFER 0x8F36 #define GL_COPY_WRITE_BUFFER 0x8F37 #endif #ifndef GL_ARB_shader_texture_lod #endif #ifndef GL_ARB_depth_clamp #define GL_DEPTH_CLAMP 0x864F #endif #ifndef GL_ARB_draw_elements_base_vertex #endif #ifndef GL_ARB_fragment_coord_conventions #endif #ifndef GL_ARB_provoking_vertex #define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C #define GL_FIRST_VERTEX_CONVENTION 0x8E4D #define GL_LAST_VERTEX_CONVENTION 0x8E4E #define GL_PROVOKING_VERTEX 0x8E4F #endif #ifndef GL_ARB_seamless_cube_map #define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F #endif #ifndef GL_ARB_sync #define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 #define GL_OBJECT_TYPE 0x9112 #define GL_SYNC_CONDITION 0x9113 #define GL_SYNC_STATUS 0x9114 #define GL_SYNC_FLAGS 0x9115 #define GL_SYNC_FENCE 0x9116 #define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 #define GL_UNSIGNALED 0x9118 #define GL_SIGNALED 0x9119 #define GL_ALREADY_SIGNALED 0x911A #define GL_TIMEOUT_EXPIRED 0x911B #define GL_CONDITION_SATISFIED 0x911C #define GL_WAIT_FAILED 0x911D #define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 #define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull #endif #ifndef GL_ARB_texture_multisample #define GL_SAMPLE_POSITION 0x8E50 #define GL_SAMPLE_MASK 0x8E51 #define GL_SAMPLE_MASK_VALUE 0x8E52 #define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 #define GL_TEXTURE_2D_MULTISAMPLE 0x9100 #define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 #define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 #define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 #define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 #define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 #define GL_TEXTURE_SAMPLES 0x9106 #define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 #define GL_SAMPLER_2D_MULTISAMPLE 0x9108 #define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 #define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A #define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B #define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C #define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D #define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E #define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F #define GL_MAX_INTEGER_SAMPLES 0x9110 #endif #ifndef GL_ARB_vertex_array_bgra /* reuse GL_BGRA */ #endif #ifndef GL_ARB_draw_buffers_blend #endif #ifndef GL_ARB_sample_shading #define GL_SAMPLE_SHADING 0x8C36 #define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 #endif #ifndef GL_ARB_texture_cube_map_array #define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 #define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A #define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B #define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C #define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D #define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E #define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F #endif #ifndef GL_ARB_texture_gather #define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E #define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F #define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS 0x8F9F #endif #ifndef GL_ARB_texture_query_lod #endif #ifndef GL_EXT_abgr #define GL_ABGR_EXT 0x8000 #endif #ifndef GL_EXT_blend_color #define GL_CONSTANT_COLOR_EXT 0x8001 #define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 #define GL_CONSTANT_ALPHA_EXT 0x8003 #define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 #define GL_BLEND_COLOR_EXT 0x8005 #endif #ifndef GL_EXT_polygon_offset #define GL_POLYGON_OFFSET_EXT 0x8037 #define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 #define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 #endif #ifndef GL_EXT_texture #define GL_ALPHA4_EXT 0x803B #define GL_ALPHA8_EXT 0x803C #define GL_ALPHA12_EXT 0x803D #define GL_ALPHA16_EXT 0x803E #define GL_LUMINANCE4_EXT 0x803F #define GL_LUMINANCE8_EXT 0x8040 #define GL_LUMINANCE12_EXT 0x8041 #define GL_LUMINANCE16_EXT 0x8042 #define GL_LUMINANCE4_ALPHA4_EXT 0x8043 #define GL_LUMINANCE6_ALPHA2_EXT 0x8044 #define GL_LUMINANCE8_ALPHA8_EXT 0x8045 #define GL_LUMINANCE12_ALPHA4_EXT 0x8046 #define GL_LUMINANCE12_ALPHA12_EXT 0x8047 #define GL_LUMINANCE16_ALPHA16_EXT 0x8048 #define GL_INTENSITY_EXT 0x8049 #define GL_INTENSITY4_EXT 0x804A #define GL_INTENSITY8_EXT 0x804B #define GL_INTENSITY12_EXT 0x804C #define GL_INTENSITY16_EXT 0x804D #define GL_RGB2_EXT 0x804E #define GL_RGB4_EXT 0x804F #define GL_RGB5_EXT 0x8050 #define GL_RGB8_EXT 0x8051 #define GL_RGB10_EXT 0x8052 #define GL_RGB12_EXT 0x8053 #define GL_RGB16_EXT 0x8054 #define GL_RGBA2_EXT 0x8055 #define GL_RGBA4_EXT 0x8056 #define GL_RGB5_A1_EXT 0x8057 #define GL_RGBA8_EXT 0x8058 #define GL_RGB10_A2_EXT 0x8059 #define GL_RGBA12_EXT 0x805A #define GL_RGBA16_EXT 0x805B #define GL_TEXTURE_RED_SIZE_EXT 0x805C #define GL_TEXTURE_GREEN_SIZE_EXT 0x805D #define GL_TEXTURE_BLUE_SIZE_EXT 0x805E #define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F #define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 #define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 #define GL_REPLACE_EXT 0x8062 #define GL_PROXY_TEXTURE_1D_EXT 0x8063 #define GL_PROXY_TEXTURE_2D_EXT 0x8064 #define GL_TEXTURE_TOO_LARGE_EXT 0x8065 #endif #ifndef GL_EXT_texture3D #define GL_PACK_SKIP_IMAGES_EXT 0x806B #define GL_PACK_IMAGE_HEIGHT_EXT 0x806C #define GL_UNPACK_SKIP_IMAGES_EXT 0x806D #define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E #define GL_TEXTURE_3D_EXT 0x806F #define GL_PROXY_TEXTURE_3D_EXT 0x8070 #define GL_TEXTURE_DEPTH_EXT 0x8071 #define GL_TEXTURE_WRAP_R_EXT 0x8072 #define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 #endif #ifndef GL_SGIS_texture_filter4 #define GL_FILTER4_SGIS 0x8146 #define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 #endif #ifndef GL_EXT_subtexture #endif #ifndef GL_EXT_copy_texture #endif #ifndef GL_EXT_histogram #define GL_HISTOGRAM_EXT 0x8024 #define GL_PROXY_HISTOGRAM_EXT 0x8025 #define GL_HISTOGRAM_WIDTH_EXT 0x8026 #define GL_HISTOGRAM_FORMAT_EXT 0x8027 #define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 #define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 #define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A #define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B #define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C #define GL_HISTOGRAM_SINK_EXT 0x802D #define GL_MINMAX_EXT 0x802E #define GL_MINMAX_FORMAT_EXT 0x802F #define GL_MINMAX_SINK_EXT 0x8030 #define GL_TABLE_TOO_LARGE_EXT 0x8031 #endif #ifndef GL_EXT_convolution #define GL_CONVOLUTION_1D_EXT 0x8010 #define GL_CONVOLUTION_2D_EXT 0x8011 #define GL_SEPARABLE_2D_EXT 0x8012 #define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 #define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 #define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 #define GL_REDUCE_EXT 0x8016 #define GL_CONVOLUTION_FORMAT_EXT 0x8017 #define GL_CONVOLUTION_WIDTH_EXT 0x8018 #define GL_CONVOLUTION_HEIGHT_EXT 0x8019 #define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A #define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B #define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C #define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D #define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E #define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F #define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 #define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 #define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 #define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 #endif #ifndef GL_SGI_color_matrix #define GL_COLOR_MATRIX_SGI 0x80B1 #define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 #define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 #define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 #define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 #define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 #define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 #define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 #define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 #define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA #define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB #endif #ifndef GL_SGI_color_table #define GL_COLOR_TABLE_SGI 0x80D0 #define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 #define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 #define GL_PROXY_COLOR_TABLE_SGI 0x80D3 #define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 #define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 #define GL_COLOR_TABLE_SCALE_SGI 0x80D6 #define GL_COLOR_TABLE_BIAS_SGI 0x80D7 #define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 #define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 #define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA #define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB #define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC #define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD #define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE #define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF #endif #ifndef GL_SGIS_pixel_texture #define GL_PIXEL_TEXTURE_SGIS 0x8353 #define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 #define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 #define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 #endif #ifndef GL_SGIX_pixel_texture #define GL_PIXEL_TEX_GEN_SGIX 0x8139 #define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B #endif #ifndef GL_SGIS_texture4D #define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 #define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 #define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 #define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 #define GL_TEXTURE_4D_SGIS 0x8134 #define GL_PROXY_TEXTURE_4D_SGIS 0x8135 #define GL_TEXTURE_4DSIZE_SGIS 0x8136 #define GL_TEXTURE_WRAP_Q_SGIS 0x8137 #define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 #define GL_TEXTURE_4D_BINDING_SGIS 0x814F #endif #ifndef GL_SGI_texture_color_table #define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC #define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD #endif #ifndef GL_EXT_cmyka #define GL_CMYK_EXT 0x800C #define GL_CMYKA_EXT 0x800D #define GL_PACK_CMYK_HINT_EXT 0x800E #define GL_UNPACK_CMYK_HINT_EXT 0x800F #endif #ifndef GL_EXT_texture_object #define GL_TEXTURE_PRIORITY_EXT 0x8066 #define GL_TEXTURE_RESIDENT_EXT 0x8067 #define GL_TEXTURE_1D_BINDING_EXT 0x8068 #define GL_TEXTURE_2D_BINDING_EXT 0x8069 #define GL_TEXTURE_3D_BINDING_EXT 0x806A #endif #ifndef GL_SGIS_detail_texture #define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 #define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 #define GL_LINEAR_DETAIL_SGIS 0x8097 #define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 #define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 #define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A #define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B #define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C #endif #ifndef GL_SGIS_sharpen_texture #define GL_LINEAR_SHARPEN_SGIS 0x80AD #define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE #define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF #define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 #endif #ifndef GL_EXT_packed_pixels #define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 #define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 #define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 #define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 #define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 #endif #ifndef GL_SGIS_texture_lod #define GL_TEXTURE_MIN_LOD_SGIS 0x813A #define GL_TEXTURE_MAX_LOD_SGIS 0x813B #define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C #define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D #endif #ifndef GL_SGIS_multisample #define GL_MULTISAMPLE_SGIS 0x809D #define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E #define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F #define GL_SAMPLE_MASK_SGIS 0x80A0 #define GL_1PASS_SGIS 0x80A1 #define GL_2PASS_0_SGIS 0x80A2 #define GL_2PASS_1_SGIS 0x80A3 #define GL_4PASS_0_SGIS 0x80A4 #define GL_4PASS_1_SGIS 0x80A5 #define GL_4PASS_2_SGIS 0x80A6 #define GL_4PASS_3_SGIS 0x80A7 #define GL_SAMPLE_BUFFERS_SGIS 0x80A8 #define GL_SAMPLES_SGIS 0x80A9 #define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA #define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB #define GL_SAMPLE_PATTERN_SGIS 0x80AC #endif #ifndef GL_EXT_rescale_normal #define GL_RESCALE_NORMAL_EXT 0x803A #endif #ifndef GL_EXT_vertex_array #define GL_VERTEX_ARRAY_EXT 0x8074 #define GL_NORMAL_ARRAY_EXT 0x8075 #define GL_COLOR_ARRAY_EXT 0x8076 #define GL_INDEX_ARRAY_EXT 0x8077 #define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 #define GL_EDGE_FLAG_ARRAY_EXT 0x8079 #define GL_VERTEX_ARRAY_SIZE_EXT 0x807A #define GL_VERTEX_ARRAY_TYPE_EXT 0x807B #define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C #define GL_VERTEX_ARRAY_COUNT_EXT 0x807D #define GL_NORMAL_ARRAY_TYPE_EXT 0x807E #define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F #define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 #define GL_COLOR_ARRAY_SIZE_EXT 0x8081 #define GL_COLOR_ARRAY_TYPE_EXT 0x8082 #define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 #define GL_COLOR_ARRAY_COUNT_EXT 0x8084 #define GL_INDEX_ARRAY_TYPE_EXT 0x8085 #define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 #define GL_INDEX_ARRAY_COUNT_EXT 0x8087 #define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 #define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 #define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A #define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B #define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C #define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D #define GL_VERTEX_ARRAY_POINTER_EXT 0x808E #define GL_NORMAL_ARRAY_POINTER_EXT 0x808F #define GL_COLOR_ARRAY_POINTER_EXT 0x8090 #define GL_INDEX_ARRAY_POINTER_EXT 0x8091 #define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 #define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 #endif #ifndef GL_EXT_misc_attribute #endif #ifndef GL_SGIS_generate_mipmap #define GL_GENERATE_MIPMAP_SGIS 0x8191 #define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 #endif #ifndef GL_SGIX_clipmap #define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 #define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 #define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 #define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 #define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 #define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 #define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 #define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 #define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 #define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D #define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E #define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F #endif #ifndef GL_SGIX_shadow #define GL_TEXTURE_COMPARE_SGIX 0x819A #define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B #define GL_TEXTURE_LEQUAL_R_SGIX 0x819C #define GL_TEXTURE_GEQUAL_R_SGIX 0x819D #endif #ifndef GL_SGIS_texture_edge_clamp #define GL_CLAMP_TO_EDGE_SGIS 0x812F #endif #ifndef GL_SGIS_texture_border_clamp #define GL_CLAMP_TO_BORDER_SGIS 0x812D #endif #ifndef GL_EXT_blend_minmax #define GL_FUNC_ADD_EXT 0x8006 #define GL_MIN_EXT 0x8007 #define GL_MAX_EXT 0x8008 #define GL_BLEND_EQUATION_EXT 0x8009 #endif #ifndef GL_EXT_blend_subtract #define GL_FUNC_SUBTRACT_EXT 0x800A #define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B #endif #ifndef GL_EXT_blend_logic_op #endif #ifndef GL_SGIX_interlace #define GL_INTERLACE_SGIX 0x8094 #endif #ifndef GL_SGIX_pixel_tiles #define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E #define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F #define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 #define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 #define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 #define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 #define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 #define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 #endif #ifndef GL_SGIS_texture_select #define GL_DUAL_ALPHA4_SGIS 0x8110 #define GL_DUAL_ALPHA8_SGIS 0x8111 #define GL_DUAL_ALPHA12_SGIS 0x8112 #define GL_DUAL_ALPHA16_SGIS 0x8113 #define GL_DUAL_LUMINANCE4_SGIS 0x8114 #define GL_DUAL_LUMINANCE8_SGIS 0x8115 #define GL_DUAL_LUMINANCE12_SGIS 0x8116 #define GL_DUAL_LUMINANCE16_SGIS 0x8117 #define GL_DUAL_INTENSITY4_SGIS 0x8118 #define GL_DUAL_INTENSITY8_SGIS 0x8119 #define GL_DUAL_INTENSITY12_SGIS 0x811A #define GL_DUAL_INTENSITY16_SGIS 0x811B #define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C #define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D #define GL_QUAD_ALPHA4_SGIS 0x811E #define GL_QUAD_ALPHA8_SGIS 0x811F #define GL_QUAD_LUMINANCE4_SGIS 0x8120 #define GL_QUAD_LUMINANCE8_SGIS 0x8121 #define GL_QUAD_INTENSITY4_SGIS 0x8122 #define GL_QUAD_INTENSITY8_SGIS 0x8123 #define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 #define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 #endif #ifndef GL_SGIX_sprite #define GL_SPRITE_SGIX 0x8148 #define GL_SPRITE_MODE_SGIX 0x8149 #define GL_SPRITE_AXIS_SGIX 0x814A #define GL_SPRITE_TRANSLATION_SGIX 0x814B #define GL_SPRITE_AXIAL_SGIX 0x814C #define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D #define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E #endif #ifndef GL_SGIX_texture_multi_buffer #define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E #endif #ifndef GL_EXT_point_parameters #define GL_POINT_SIZE_MIN_EXT 0x8126 #define GL_POINT_SIZE_MAX_EXT 0x8127 #define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 #define GL_DISTANCE_ATTENUATION_EXT 0x8129 #endif #ifndef GL_SGIS_point_parameters #define GL_POINT_SIZE_MIN_SGIS 0x8126 #define GL_POINT_SIZE_MAX_SGIS 0x8127 #define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 #define GL_DISTANCE_ATTENUATION_SGIS 0x8129 #endif #ifndef GL_SGIX_instruments #define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 #define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 #endif #ifndef GL_SGIX_texture_scale_bias #define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 #define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A #define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B #define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C #endif #ifndef GL_SGIX_framezoom #define GL_FRAMEZOOM_SGIX 0x818B #define GL_FRAMEZOOM_FACTOR_SGIX 0x818C #define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D #endif #ifndef GL_SGIX_tag_sample_buffer #endif #ifndef GL_FfdMaskSGIX #define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 #define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 #endif #ifndef GL_SGIX_polynomial_ffd #define GL_GEOMETRY_DEFORMATION_SGIX 0x8194 #define GL_TEXTURE_DEFORMATION_SGIX 0x8195 #define GL_DEFORMATIONS_MASK_SGIX 0x8196 #define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 #endif #ifndef GL_SGIX_reference_plane #define GL_REFERENCE_PLANE_SGIX 0x817D #define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E #endif #ifndef GL_SGIX_flush_raster #endif #ifndef GL_SGIX_depth_texture #define GL_DEPTH_COMPONENT16_SGIX 0x81A5 #define GL_DEPTH_COMPONENT24_SGIX 0x81A6 #define GL_DEPTH_COMPONENT32_SGIX 0x81A7 #endif #ifndef GL_SGIS_fog_function #define GL_FOG_FUNC_SGIS 0x812A #define GL_FOG_FUNC_POINTS_SGIS 0x812B #define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C #endif #ifndef GL_SGIX_fog_offset #define GL_FOG_OFFSET_SGIX 0x8198 #define GL_FOG_OFFSET_VALUE_SGIX 0x8199 #endif #ifndef GL_HP_image_transform #define GL_IMAGE_SCALE_X_HP 0x8155 #define GL_IMAGE_SCALE_Y_HP 0x8156 #define GL_IMAGE_TRANSLATE_X_HP 0x8157 #define GL_IMAGE_TRANSLATE_Y_HP 0x8158 #define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 #define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A #define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B #define GL_IMAGE_MAG_FILTER_HP 0x815C #define GL_IMAGE_MIN_FILTER_HP 0x815D #define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E #define GL_CUBIC_HP 0x815F #define GL_AVERAGE_HP 0x8160 #define GL_IMAGE_TRANSFORM_2D_HP 0x8161 #define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 #define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 #endif #ifndef GL_HP_convolution_border_modes #define GL_IGNORE_BORDER_HP 0x8150 #define GL_CONSTANT_BORDER_HP 0x8151 #define GL_REPLICATE_BORDER_HP 0x8153 #define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 #endif #ifndef GL_INGR_palette_buffer #endif #ifndef GL_SGIX_texture_add_env #define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE #endif #ifndef GL_EXT_color_subtable #endif #ifndef GL_PGI_vertex_hints #define GL_VERTEX_DATA_HINT_PGI 0x1A22A #define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B #define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C #define GL_MAX_VERTEX_HINT_PGI 0x1A22D #define GL_COLOR3_BIT_PGI 0x00010000 #define GL_COLOR4_BIT_PGI 0x00020000 #define GL_EDGEFLAG_BIT_PGI 0x00040000 #define GL_INDEX_BIT_PGI 0x00080000 #define GL_MAT_AMBIENT_BIT_PGI 0x00100000 #define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 #define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 #define GL_MAT_EMISSION_BIT_PGI 0x00800000 #define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 #define GL_MAT_SHININESS_BIT_PGI 0x02000000 #define GL_MAT_SPECULAR_BIT_PGI 0x04000000 #define GL_NORMAL_BIT_PGI 0x08000000 #define GL_TEXCOORD1_BIT_PGI 0x10000000 #define GL_TEXCOORD2_BIT_PGI 0x20000000 #define GL_TEXCOORD3_BIT_PGI 0x40000000 #define GL_TEXCOORD4_BIT_PGI 0x80000000 #define GL_VERTEX23_BIT_PGI 0x00000004 #define GL_VERTEX4_BIT_PGI 0x00000008 #endif #ifndef GL_PGI_misc_hints #define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 #define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD #define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE #define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 #define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 #define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 #define GL_ALWAYS_FAST_HINT_PGI 0x1A20C #define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D #define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E #define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F #define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 #define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 #define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 #define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 #define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 #define GL_FULL_STIPPLE_HINT_PGI 0x1A219 #define GL_CLIP_NEAR_HINT_PGI 0x1A220 #define GL_CLIP_FAR_HINT_PGI 0x1A221 #define GL_WIDE_LINE_HINT_PGI 0x1A222 #define GL_BACK_NORMALS_HINT_PGI 0x1A223 #endif #ifndef GL_EXT_paletted_texture #define GL_COLOR_INDEX1_EXT 0x80E2 #define GL_COLOR_INDEX2_EXT 0x80E3 #define GL_COLOR_INDEX4_EXT 0x80E4 #define GL_COLOR_INDEX8_EXT 0x80E5 #define GL_COLOR_INDEX12_EXT 0x80E6 #define GL_COLOR_INDEX16_EXT 0x80E7 #define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED #endif #ifndef GL_EXT_clip_volume_hint #define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 #endif #ifndef GL_SGIX_list_priority #define GL_LIST_PRIORITY_SGIX 0x8182 #endif #ifndef GL_SGIX_ir_instrument1 #define GL_IR_INSTRUMENT1_SGIX 0x817F #endif #ifndef GL_SGIX_calligraphic_fragment #define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 #endif #ifndef GL_SGIX_texture_lod_bias #define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E #define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F #define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 #endif #ifndef GL_SGIX_shadow_ambient #define GL_SHADOW_AMBIENT_SGIX 0x80BF #endif #ifndef GL_EXT_index_texture #endif #ifndef GL_EXT_index_material #define GL_INDEX_MATERIAL_EXT 0x81B8 #define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 #define GL_INDEX_MATERIAL_FACE_EXT 0x81BA #endif #ifndef GL_EXT_index_func #define GL_INDEX_TEST_EXT 0x81B5 #define GL_INDEX_TEST_FUNC_EXT 0x81B6 #define GL_INDEX_TEST_REF_EXT 0x81B7 #endif #ifndef GL_EXT_index_array_formats #define GL_IUI_V2F_EXT 0x81AD #define GL_IUI_V3F_EXT 0x81AE #define GL_IUI_N3F_V2F_EXT 0x81AF #define GL_IUI_N3F_V3F_EXT 0x81B0 #define GL_T2F_IUI_V2F_EXT 0x81B1 #define GL_T2F_IUI_V3F_EXT 0x81B2 #define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 #define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 #endif #ifndef GL_EXT_compiled_vertex_array #define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 #define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 #endif #ifndef GL_EXT_cull_vertex #define GL_CULL_VERTEX_EXT 0x81AA #define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB #define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC #endif #ifndef GL_SGIX_ycrcb #define GL_YCRCB_422_SGIX 0x81BB #define GL_YCRCB_444_SGIX 0x81BC #endif #ifndef GL_SGIX_fragment_lighting #define GL_FRAGMENT_LIGHTING_SGIX 0x8400 #define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 #define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 #define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 #define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 #define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 #define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 #define GL_LIGHT_ENV_MODE_SGIX 0x8407 #define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 #define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 #define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A #define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B #define GL_FRAGMENT_LIGHT0_SGIX 0x840C #define GL_FRAGMENT_LIGHT1_SGIX 0x840D #define GL_FRAGMENT_LIGHT2_SGIX 0x840E #define GL_FRAGMENT_LIGHT3_SGIX 0x840F #define GL_FRAGMENT_LIGHT4_SGIX 0x8410 #define GL_FRAGMENT_LIGHT5_SGIX 0x8411 #define GL_FRAGMENT_LIGHT6_SGIX 0x8412 #define GL_FRAGMENT_LIGHT7_SGIX 0x8413 #endif #ifndef GL_IBM_rasterpos_clip #define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 #endif #ifndef GL_HP_texture_lighting #define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 #define GL_TEXTURE_POST_SPECULAR_HP 0x8168 #define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 #endif #ifndef GL_EXT_draw_range_elements #define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 #define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 #endif #ifndef GL_WIN_phong_shading #define GL_PHONG_WIN 0x80EA #define GL_PHONG_HINT_WIN 0x80EB #endif #ifndef GL_WIN_specular_fog #define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC #endif #ifndef GL_EXT_light_texture #define GL_FRAGMENT_MATERIAL_EXT 0x8349 #define GL_FRAGMENT_NORMAL_EXT 0x834A #define GL_FRAGMENT_COLOR_EXT 0x834C #define GL_ATTENUATION_EXT 0x834D #define GL_SHADOW_ATTENUATION_EXT 0x834E #define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F #define GL_TEXTURE_LIGHT_EXT 0x8350 #define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 #define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 /* reuse GL_FRAGMENT_DEPTH_EXT */ #endif #ifndef GL_SGIX_blend_alpha_minmax #define GL_ALPHA_MIN_SGIX 0x8320 #define GL_ALPHA_MAX_SGIX 0x8321 #endif #ifndef GL_SGIX_impact_pixel_texture #define GL_PIXEL_TEX_GEN_Q_CEILING_SGIX 0x8184 #define GL_PIXEL_TEX_GEN_Q_ROUND_SGIX 0x8185 #define GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX 0x8186 #define GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187 #define GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188 #define GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX 0x8189 #define GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX 0x818A #endif #ifndef GL_EXT_bgra #define GL_BGR_EXT 0x80E0 #define GL_BGRA_EXT 0x80E1 #endif #ifndef GL_SGIX_async #define GL_ASYNC_MARKER_SGIX 0x8329 #endif #ifndef GL_SGIX_async_pixel #define GL_ASYNC_TEX_IMAGE_SGIX 0x835C #define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D #define GL_ASYNC_READ_PIXELS_SGIX 0x835E #define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F #define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 #define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 #endif #ifndef GL_SGIX_async_histogram #define GL_ASYNC_HISTOGRAM_SGIX 0x832C #define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D #endif #ifndef GL_INTEL_texture_scissor #endif #ifndef GL_INTEL_parallel_arrays #define GL_PARALLEL_ARRAYS_INTEL 0x83F4 #define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 #define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 #define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 #define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 #endif #ifndef GL_HP_occlusion_test #define GL_OCCLUSION_TEST_HP 0x8165 #define GL_OCCLUSION_TEST_RESULT_HP 0x8166 #endif #ifndef GL_EXT_pixel_transform #define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 #define GL_PIXEL_MAG_FILTER_EXT 0x8331 #define GL_PIXEL_MIN_FILTER_EXT 0x8332 #define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 #define GL_CUBIC_EXT 0x8334 #define GL_AVERAGE_EXT 0x8335 #define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 #define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 #define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 #endif #ifndef GL_EXT_pixel_transform_color_table #endif #ifndef GL_EXT_shared_texture_palette #define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB #endif #ifndef GL_EXT_separate_specular_color #define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 #define GL_SINGLE_COLOR_EXT 0x81F9 #define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA #endif #ifndef GL_EXT_secondary_color #define GL_COLOR_SUM_EXT 0x8458 #define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 #define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A #define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B #define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C #define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D #define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E #endif #ifndef GL_EXT_texture_perturb_normal #define GL_PERTURB_EXT 0x85AE #define GL_TEXTURE_NORMAL_EXT 0x85AF #endif #ifndef GL_EXT_multi_draw_arrays #endif #ifndef GL_EXT_fog_coord #define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 #define GL_FOG_COORDINATE_EXT 0x8451 #define GL_FRAGMENT_DEPTH_EXT 0x8452 #define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 #define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 #define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 #define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 #define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 #endif #ifndef GL_REND_screen_coordinates #define GL_SCREEN_COORDINATES_REND 0x8490 #define GL_INVERTED_SCREEN_W_REND 0x8491 #endif #ifndef GL_EXT_coordinate_frame #define GL_TANGENT_ARRAY_EXT 0x8439 #define GL_BINORMAL_ARRAY_EXT 0x843A #define GL_CURRENT_TANGENT_EXT 0x843B #define GL_CURRENT_BINORMAL_EXT 0x843C #define GL_TANGENT_ARRAY_TYPE_EXT 0x843E #define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F #define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 #define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 #define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 #define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 #define GL_MAP1_TANGENT_EXT 0x8444 #define GL_MAP2_TANGENT_EXT 0x8445 #define GL_MAP1_BINORMAL_EXT 0x8446 #define GL_MAP2_BINORMAL_EXT 0x8447 #endif #ifndef GL_EXT_texture_env_combine #define GL_COMBINE_EXT 0x8570 #define GL_COMBINE_RGB_EXT 0x8571 #define GL_COMBINE_ALPHA_EXT 0x8572 #define GL_RGB_SCALE_EXT 0x8573 #define GL_ADD_SIGNED_EXT 0x8574 #define GL_INTERPOLATE_EXT 0x8575 #define GL_CONSTANT_EXT 0x8576 #define GL_PRIMARY_COLOR_EXT 0x8577 #define GL_PREVIOUS_EXT 0x8578 #define GL_SOURCE0_RGB_EXT 0x8580 #define GL_SOURCE1_RGB_EXT 0x8581 #define GL_SOURCE2_RGB_EXT 0x8582 #define GL_SOURCE0_ALPHA_EXT 0x8588 #define GL_SOURCE1_ALPHA_EXT 0x8589 #define GL_SOURCE2_ALPHA_EXT 0x858A #define GL_OPERAND0_RGB_EXT 0x8590 #define GL_OPERAND1_RGB_EXT 0x8591 #define GL_OPERAND2_RGB_EXT 0x8592 #define GL_OPERAND0_ALPHA_EXT 0x8598 #define GL_OPERAND1_ALPHA_EXT 0x8599 #define GL_OPERAND2_ALPHA_EXT 0x859A #endif #ifndef GL_APPLE_specular_vector #define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 #endif #ifndef GL_APPLE_transform_hint #define GL_TRANSFORM_HINT_APPLE 0x85B1 #endif #ifndef GL_SGIX_fog_scale #define GL_FOG_SCALE_SGIX 0x81FC #define GL_FOG_SCALE_VALUE_SGIX 0x81FD #endif #ifndef GL_SUNX_constant_data #define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 #define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 #endif #ifndef GL_SUN_global_alpha #define GL_GLOBAL_ALPHA_SUN 0x81D9 #define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA #endif #ifndef GL_SUN_triangle_list #define GL_RESTART_SUN 0x0001 #define GL_REPLACE_MIDDLE_SUN 0x0002 #define GL_REPLACE_OLDEST_SUN 0x0003 #define GL_TRIANGLE_LIST_SUN 0x81D7 #define GL_REPLACEMENT_CODE_SUN 0x81D8 #define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 #define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 #define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 #define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 #define GL_R1UI_V3F_SUN 0x85C4 #define GL_R1UI_C4UB_V3F_SUN 0x85C5 #define GL_R1UI_C3F_V3F_SUN 0x85C6 #define GL_R1UI_N3F_V3F_SUN 0x85C7 #define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 #define GL_R1UI_T2F_V3F_SUN 0x85C9 #define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA #define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB #endif #ifndef GL_SUN_vertex #endif #ifndef GL_EXT_blend_func_separate #define GL_BLEND_DST_RGB_EXT 0x80C8 #define GL_BLEND_SRC_RGB_EXT 0x80C9 #define GL_BLEND_DST_ALPHA_EXT 0x80CA #define GL_BLEND_SRC_ALPHA_EXT 0x80CB #endif #ifndef GL_INGR_color_clamp #define GL_RED_MIN_CLAMP_INGR 0x8560 #define GL_GREEN_MIN_CLAMP_INGR 0x8561 #define GL_BLUE_MIN_CLAMP_INGR 0x8562 #define GL_ALPHA_MIN_CLAMP_INGR 0x8563 #define GL_RED_MAX_CLAMP_INGR 0x8564 #define GL_GREEN_MAX_CLAMP_INGR 0x8565 #define GL_BLUE_MAX_CLAMP_INGR 0x8566 #define GL_ALPHA_MAX_CLAMP_INGR 0x8567 #endif #ifndef GL_INGR_interlace_read #define GL_INTERLACE_READ_INGR 0x8568 #endif #ifndef GL_EXT_stencil_wrap #define GL_INCR_WRAP_EXT 0x8507 #define GL_DECR_WRAP_EXT 0x8508 #endif #ifndef GL_EXT_422_pixels #define GL_422_EXT 0x80CC #define GL_422_REV_EXT 0x80CD #define GL_422_AVERAGE_EXT 0x80CE #define GL_422_REV_AVERAGE_EXT 0x80CF #endif #ifndef GL_NV_texgen_reflection #define GL_NORMAL_MAP_NV 0x8511 #define GL_REFLECTION_MAP_NV 0x8512 #endif #ifndef GL_EXT_texture_cube_map #define GL_NORMAL_MAP_EXT 0x8511 #define GL_REFLECTION_MAP_EXT 0x8512 #define GL_TEXTURE_CUBE_MAP_EXT 0x8513 #define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 #define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A #define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B #define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C #endif #ifndef GL_SUN_convolution_border_modes #define GL_WRAP_BORDER_SUN 0x81D4 #endif #ifndef GL_EXT_texture_env_add #endif #ifndef GL_EXT_texture_lod_bias #define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD #define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 #define GL_TEXTURE_LOD_BIAS_EXT 0x8501 #endif #ifndef GL_EXT_texture_filter_anisotropic #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF #endif #ifndef GL_EXT_vertex_weighting #define GL_MODELVIEW0_STACK_DEPTH_EXT GL_MODELVIEW_STACK_DEPTH #define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 #define GL_MODELVIEW0_MATRIX_EXT GL_MODELVIEW_MATRIX #define GL_MODELVIEW1_MATRIX_EXT 0x8506 #define GL_VERTEX_WEIGHTING_EXT 0x8509 #define GL_MODELVIEW0_EXT GL_MODELVIEW #define GL_MODELVIEW1_EXT 0x850A #define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B #define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C #define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D #define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E #define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F #define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 #endif #ifndef GL_NV_light_max_exponent #define GL_MAX_SHININESS_NV 0x8504 #define GL_MAX_SPOT_EXPONENT_NV 0x8505 #endif #ifndef GL_NV_vertex_array_range #define GL_VERTEX_ARRAY_RANGE_NV 0x851D #define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E #define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F #define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 #define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 #endif #ifndef GL_NV_register_combiners #define GL_REGISTER_COMBINERS_NV 0x8522 #define GL_VARIABLE_A_NV 0x8523 #define GL_VARIABLE_B_NV 0x8524 #define GL_VARIABLE_C_NV 0x8525 #define GL_VARIABLE_D_NV 0x8526 #define GL_VARIABLE_E_NV 0x8527 #define GL_VARIABLE_F_NV 0x8528 #define GL_VARIABLE_G_NV 0x8529 #define GL_CONSTANT_COLOR0_NV 0x852A #define GL_CONSTANT_COLOR1_NV 0x852B #define GL_PRIMARY_COLOR_NV 0x852C #define GL_SECONDARY_COLOR_NV 0x852D #define GL_SPARE0_NV 0x852E #define GL_SPARE1_NV 0x852F #define GL_DISCARD_NV 0x8530 #define GL_E_TIMES_F_NV 0x8531 #define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 #define GL_UNSIGNED_IDENTITY_NV 0x8536 #define GL_UNSIGNED_INVERT_NV 0x8537 #define GL_EXPAND_NORMAL_NV 0x8538 #define GL_EXPAND_NEGATE_NV 0x8539 #define GL_HALF_BIAS_NORMAL_NV 0x853A #define GL_HALF_BIAS_NEGATE_NV 0x853B #define GL_SIGNED_IDENTITY_NV 0x853C #define GL_SIGNED_NEGATE_NV 0x853D #define GL_SCALE_BY_TWO_NV 0x853E #define GL_SCALE_BY_FOUR_NV 0x853F #define GL_SCALE_BY_ONE_HALF_NV 0x8540 #define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 #define GL_COMBINER_INPUT_NV 0x8542 #define GL_COMBINER_MAPPING_NV 0x8543 #define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 #define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 #define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 #define GL_COMBINER_MUX_SUM_NV 0x8547 #define GL_COMBINER_SCALE_NV 0x8548 #define GL_COMBINER_BIAS_NV 0x8549 #define GL_COMBINER_AB_OUTPUT_NV 0x854A #define GL_COMBINER_CD_OUTPUT_NV 0x854B #define GL_COMBINER_SUM_OUTPUT_NV 0x854C #define GL_MAX_GENERAL_COMBINERS_NV 0x854D #define GL_NUM_GENERAL_COMBINERS_NV 0x854E #define GL_COLOR_SUM_CLAMP_NV 0x854F #define GL_COMBINER0_NV 0x8550 #define GL_COMBINER1_NV 0x8551 #define GL_COMBINER2_NV 0x8552 #define GL_COMBINER3_NV 0x8553 #define GL_COMBINER4_NV 0x8554 #define GL_COMBINER5_NV 0x8555 #define GL_COMBINER6_NV 0x8556 #define GL_COMBINER7_NV 0x8557 /* reuse GL_TEXTURE0_ARB */ /* reuse GL_TEXTURE1_ARB */ /* reuse GL_ZERO */ /* reuse GL_NONE */ /* reuse GL_FOG */ #endif #ifndef GL_NV_fog_distance #define GL_FOG_DISTANCE_MODE_NV 0x855A #define GL_EYE_RADIAL_NV 0x855B #define GL_EYE_PLANE_ABSOLUTE_NV 0x855C /* reuse GL_EYE_PLANE */ #endif #ifndef GL_NV_texgen_emboss #define GL_EMBOSS_LIGHT_NV 0x855D #define GL_EMBOSS_CONSTANT_NV 0x855E #define GL_EMBOSS_MAP_NV 0x855F #endif #ifndef GL_NV_blend_square #endif #ifndef GL_NV_texture_env_combine4 #define GL_COMBINE4_NV 0x8503 #define GL_SOURCE3_RGB_NV 0x8583 #define GL_SOURCE3_ALPHA_NV 0x858B #define GL_OPERAND3_RGB_NV 0x8593 #define GL_OPERAND3_ALPHA_NV 0x859B #endif #ifndef GL_MESA_resize_buffers #endif #ifndef GL_MESA_window_pos #endif #ifndef GL_EXT_texture_compression_s3tc #define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 #define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 #define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 #define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 #endif #ifndef GL_IBM_cull_vertex #define GL_CULL_VERTEX_IBM 103050 #endif #ifndef GL_IBM_multimode_draw_arrays #endif #ifndef GL_IBM_vertex_array_lists #define GL_VERTEX_ARRAY_LIST_IBM 103070 #define GL_NORMAL_ARRAY_LIST_IBM 103071 #define GL_COLOR_ARRAY_LIST_IBM 103072 #define GL_INDEX_ARRAY_LIST_IBM 103073 #define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 #define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 #define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 #define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 #define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 #define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 #define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 #define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 #define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 #define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 #define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 #define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 #endif #ifndef GL_SGIX_subsample #define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 #define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 #define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 #define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 #define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 #endif #ifndef GL_SGIX_ycrcb_subsample #endif #ifndef GL_SGIX_ycrcba #define GL_YCRCB_SGIX 0x8318 #define GL_YCRCBA_SGIX 0x8319 #endif #ifndef GL_SGI_depth_pass_instrument #define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310 #define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311 #define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312 #endif #ifndef GL_3DFX_texture_compression_FXT1 #define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 #define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 #endif #ifndef GL_3DFX_multisample #define GL_MULTISAMPLE_3DFX 0x86B2 #define GL_SAMPLE_BUFFERS_3DFX 0x86B3 #define GL_SAMPLES_3DFX 0x86B4 #define GL_MULTISAMPLE_BIT_3DFX 0x20000000 #endif #ifndef GL_3DFX_tbuffer #endif #ifndef GL_EXT_multisample #define GL_MULTISAMPLE_EXT 0x809D #define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E #define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F #define GL_SAMPLE_MASK_EXT 0x80A0 #define GL_1PASS_EXT 0x80A1 #define GL_2PASS_0_EXT 0x80A2 #define GL_2PASS_1_EXT 0x80A3 #define GL_4PASS_0_EXT 0x80A4 #define GL_4PASS_1_EXT 0x80A5 #define GL_4PASS_2_EXT 0x80A6 #define GL_4PASS_3_EXT 0x80A7 #define GL_SAMPLE_BUFFERS_EXT 0x80A8 #define GL_SAMPLES_EXT 0x80A9 #define GL_SAMPLE_MASK_VALUE_EXT 0x80AA #define GL_SAMPLE_MASK_INVERT_EXT 0x80AB #define GL_SAMPLE_PATTERN_EXT 0x80AC #define GL_MULTISAMPLE_BIT_EXT 0x20000000 #endif #ifndef GL_SGIX_vertex_preclip #define GL_VERTEX_PRECLIP_SGIX 0x83EE #define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF #endif #ifndef GL_SGIX_convolution_accuracy #define GL_CONVOLUTION_HINT_SGIX 0x8316 #endif #ifndef GL_SGIX_resample #define GL_PACK_RESAMPLE_SGIX 0x842C #define GL_UNPACK_RESAMPLE_SGIX 0x842D #define GL_RESAMPLE_REPLICATE_SGIX 0x842E #define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F #define GL_RESAMPLE_DECIMATE_SGIX 0x8430 #endif #ifndef GL_SGIS_point_line_texgen #define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 #define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 #define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 #define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 #define GL_EYE_POINT_SGIS 0x81F4 #define GL_OBJECT_POINT_SGIS 0x81F5 #define GL_EYE_LINE_SGIS 0x81F6 #define GL_OBJECT_LINE_SGIS 0x81F7 #endif #ifndef GL_SGIS_texture_color_mask #define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF #endif #ifndef GL_EXT_texture_env_dot3 #define GL_DOT3_RGB_EXT 0x8740 #define GL_DOT3_RGBA_EXT 0x8741 #endif #ifndef GL_ATI_texture_mirror_once #define GL_MIRROR_CLAMP_ATI 0x8742 #define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 #endif #ifndef GL_NV_fence #define GL_ALL_COMPLETED_NV 0x84F2 #define GL_FENCE_STATUS_NV 0x84F3 #define GL_FENCE_CONDITION_NV 0x84F4 #endif #ifndef GL_IBM_texture_mirrored_repeat #define GL_MIRRORED_REPEAT_IBM 0x8370 #endif #ifndef GL_NV_evaluators #define GL_EVAL_2D_NV 0x86C0 #define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 #define GL_MAP_TESSELLATION_NV 0x86C2 #define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 #define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 #define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 #define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 #define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 #define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 #define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 #define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA #define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB #define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC #define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD #define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE #define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF #define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 #define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 #define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 #define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 #define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 #define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 #define GL_MAX_MAP_TESSELLATION_NV 0x86D6 #define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 #endif #ifndef GL_NV_packed_depth_stencil #define GL_DEPTH_STENCIL_NV 0x84F9 #define GL_UNSIGNED_INT_24_8_NV 0x84FA #endif #ifndef GL_NV_register_combiners2 #define GL_PER_STAGE_CONSTANTS_NV 0x8535 #endif #ifndef GL_NV_texture_compression_vtc #endif #ifndef GL_NV_texture_rectangle #define GL_TEXTURE_RECTANGLE_NV 0x84F5 #define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 #define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 #define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 #endif #ifndef GL_NV_texture_shader #define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C #define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D #define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E #define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 #define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA #define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB #define GL_DSDT_MAG_INTENSITY_NV 0x86DC #define GL_SHADER_CONSISTENT_NV 0x86DD #define GL_TEXTURE_SHADER_NV 0x86DE #define GL_SHADER_OPERATION_NV 0x86DF #define GL_CULL_MODES_NV 0x86E0 #define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 #define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 #define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 #define GL_OFFSET_TEXTURE_2D_MATRIX_NV GL_OFFSET_TEXTURE_MATRIX_NV #define GL_OFFSET_TEXTURE_2D_SCALE_NV GL_OFFSET_TEXTURE_SCALE_NV #define GL_OFFSET_TEXTURE_2D_BIAS_NV GL_OFFSET_TEXTURE_BIAS_NV #define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 #define GL_CONST_EYE_NV 0x86E5 #define GL_PASS_THROUGH_NV 0x86E6 #define GL_CULL_FRAGMENT_NV 0x86E7 #define GL_OFFSET_TEXTURE_2D_NV 0x86E8 #define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 #define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA #define GL_DOT_PRODUCT_NV 0x86EC #define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED #define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE #define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 #define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 #define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 #define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 #define GL_HILO_NV 0x86F4 #define GL_DSDT_NV 0x86F5 #define GL_DSDT_MAG_NV 0x86F6 #define GL_DSDT_MAG_VIB_NV 0x86F7 #define GL_HILO16_NV 0x86F8 #define GL_SIGNED_HILO_NV 0x86F9 #define GL_SIGNED_HILO16_NV 0x86FA #define GL_SIGNED_RGBA_NV 0x86FB #define GL_SIGNED_RGBA8_NV 0x86FC #define GL_SIGNED_RGB_NV 0x86FE #define GL_SIGNED_RGB8_NV 0x86FF #define GL_SIGNED_LUMINANCE_NV 0x8701 #define GL_SIGNED_LUMINANCE8_NV 0x8702 #define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 #define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 #define GL_SIGNED_ALPHA_NV 0x8705 #define GL_SIGNED_ALPHA8_NV 0x8706 #define GL_SIGNED_INTENSITY_NV 0x8707 #define GL_SIGNED_INTENSITY8_NV 0x8708 #define GL_DSDT8_NV 0x8709 #define GL_DSDT8_MAG8_NV 0x870A #define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B #define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C #define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D #define GL_HI_SCALE_NV 0x870E #define GL_LO_SCALE_NV 0x870F #define GL_DS_SCALE_NV 0x8710 #define GL_DT_SCALE_NV 0x8711 #define GL_MAGNITUDE_SCALE_NV 0x8712 #define GL_VIBRANCE_SCALE_NV 0x8713 #define GL_HI_BIAS_NV 0x8714 #define GL_LO_BIAS_NV 0x8715 #define GL_DS_BIAS_NV 0x8716 #define GL_DT_BIAS_NV 0x8717 #define GL_MAGNITUDE_BIAS_NV 0x8718 #define GL_VIBRANCE_BIAS_NV 0x8719 #define GL_TEXTURE_BORDER_VALUES_NV 0x871A #define GL_TEXTURE_HI_SIZE_NV 0x871B #define GL_TEXTURE_LO_SIZE_NV 0x871C #define GL_TEXTURE_DS_SIZE_NV 0x871D #define GL_TEXTURE_DT_SIZE_NV 0x871E #define GL_TEXTURE_MAG_SIZE_NV 0x871F #endif #ifndef GL_NV_texture_shader2 #define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF #endif #ifndef GL_NV_vertex_array_range2 #define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 #endif #ifndef GL_NV_vertex_program #define GL_VERTEX_PROGRAM_NV 0x8620 #define GL_VERTEX_STATE_PROGRAM_NV 0x8621 #define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 #define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 #define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 #define GL_CURRENT_ATTRIB_NV 0x8626 #define GL_PROGRAM_LENGTH_NV 0x8627 #define GL_PROGRAM_STRING_NV 0x8628 #define GL_MODELVIEW_PROJECTION_NV 0x8629 #define GL_IDENTITY_NV 0x862A #define GL_INVERSE_NV 0x862B #define GL_TRANSPOSE_NV 0x862C #define GL_INVERSE_TRANSPOSE_NV 0x862D #define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E #define GL_MAX_TRACK_MATRICES_NV 0x862F #define GL_MATRIX0_NV 0x8630 #define GL_MATRIX1_NV 0x8631 #define GL_MATRIX2_NV 0x8632 #define GL_MATRIX3_NV 0x8633 #define GL_MATRIX4_NV 0x8634 #define GL_MATRIX5_NV 0x8635 #define GL_MATRIX6_NV 0x8636 #define GL_MATRIX7_NV 0x8637 #define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 #define GL_CURRENT_MATRIX_NV 0x8641 #define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 #define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 #define GL_PROGRAM_PARAMETER_NV 0x8644 #define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 #define GL_PROGRAM_TARGET_NV 0x8646 #define GL_PROGRAM_RESIDENT_NV 0x8647 #define GL_TRACK_MATRIX_NV 0x8648 #define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 #define GL_VERTEX_PROGRAM_BINDING_NV 0x864A #define GL_PROGRAM_ERROR_POSITION_NV 0x864B #define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 #define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 #define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 #define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 #define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 #define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 #define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 #define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 #define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 #define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 #define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A #define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B #define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C #define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D #define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E #define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F #define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 #define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 #define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 #define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 #define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 #define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 #define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 #define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 #define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 #define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 #define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A #define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B #define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C #define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D #define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E #define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F #define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 #define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 #define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 #define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 #define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 #define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 #define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 #define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 #define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 #define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 #define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A #define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B #define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C #define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D #define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E #define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F #endif #ifndef GL_SGIX_texture_coordinate_clamp #define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 #define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A #define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B #endif #ifndef GL_SGIX_scalebias_hint #define GL_SCALEBIAS_HINT_SGIX 0x8322 #endif #ifndef GL_OML_interlace #define GL_INTERLACE_OML 0x8980 #define GL_INTERLACE_READ_OML 0x8981 #endif #ifndef GL_OML_subsample #define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 #define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 #endif #ifndef GL_OML_resample #define GL_PACK_RESAMPLE_OML 0x8984 #define GL_UNPACK_RESAMPLE_OML 0x8985 #define GL_RESAMPLE_REPLICATE_OML 0x8986 #define GL_RESAMPLE_ZERO_FILL_OML 0x8987 #define GL_RESAMPLE_AVERAGE_OML 0x8988 #define GL_RESAMPLE_DECIMATE_OML 0x8989 #endif #ifndef GL_NV_copy_depth_to_color #define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E #define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F #endif #ifndef GL_ATI_envmap_bumpmap #define GL_BUMP_ROT_MATRIX_ATI 0x8775 #define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 #define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 #define GL_BUMP_TEX_UNITS_ATI 0x8778 #define GL_DUDV_ATI 0x8779 #define GL_DU8DV8_ATI 0x877A #define GL_BUMP_ENVMAP_ATI 0x877B #define GL_BUMP_TARGET_ATI 0x877C #endif #ifndef GL_ATI_fragment_shader #define GL_FRAGMENT_SHADER_ATI 0x8920 #define GL_REG_0_ATI 0x8921 #define GL_REG_1_ATI 0x8922 #define GL_REG_2_ATI 0x8923 #define GL_REG_3_ATI 0x8924 #define GL_REG_4_ATI 0x8925 #define GL_REG_5_ATI 0x8926 #define GL_REG_6_ATI 0x8927 #define GL_REG_7_ATI 0x8928 #define GL_REG_8_ATI 0x8929 #define GL_REG_9_ATI 0x892A #define GL_REG_10_ATI 0x892B #define GL_REG_11_ATI 0x892C #define GL_REG_12_ATI 0x892D #define GL_REG_13_ATI 0x892E #define GL_REG_14_ATI 0x892F #define GL_REG_15_ATI 0x8930 #define GL_REG_16_ATI 0x8931 #define GL_REG_17_ATI 0x8932 #define GL_REG_18_ATI 0x8933 #define GL_REG_19_ATI 0x8934 #define GL_REG_20_ATI 0x8935 #define GL_REG_21_ATI 0x8936 #define GL_REG_22_ATI 0x8937 #define GL_REG_23_ATI 0x8938 #define GL_REG_24_ATI 0x8939 #define GL_REG_25_ATI 0x893A #define GL_REG_26_ATI 0x893B #define GL_REG_27_ATI 0x893C #define GL_REG_28_ATI 0x893D #define GL_REG_29_ATI 0x893E #define GL_REG_30_ATI 0x893F #define GL_REG_31_ATI 0x8940 #define GL_CON_0_ATI 0x8941 #define GL_CON_1_ATI 0x8942 #define GL_CON_2_ATI 0x8943 #define GL_CON_3_ATI 0x8944 #define GL_CON_4_ATI 0x8945 #define GL_CON_5_ATI 0x8946 #define GL_CON_6_ATI 0x8947 #define GL_CON_7_ATI 0x8948 #define GL_CON_8_ATI 0x8949 #define GL_CON_9_ATI 0x894A #define GL_CON_10_ATI 0x894B #define GL_CON_11_ATI 0x894C #define GL_CON_12_ATI 0x894D #define GL_CON_13_ATI 0x894E #define GL_CON_14_ATI 0x894F #define GL_CON_15_ATI 0x8950 #define GL_CON_16_ATI 0x8951 #define GL_CON_17_ATI 0x8952 #define GL_CON_18_ATI 0x8953 #define GL_CON_19_ATI 0x8954 #define GL_CON_20_ATI 0x8955 #define GL_CON_21_ATI 0x8956 #define GL_CON_22_ATI 0x8957 #define GL_CON_23_ATI 0x8958 #define GL_CON_24_ATI 0x8959 #define GL_CON_25_ATI 0x895A #define GL_CON_26_ATI 0x895B #define GL_CON_27_ATI 0x895C #define GL_CON_28_ATI 0x895D #define GL_CON_29_ATI 0x895E #define GL_CON_30_ATI 0x895F #define GL_CON_31_ATI 0x8960 #define GL_MOV_ATI 0x8961 #define GL_ADD_ATI 0x8963 #define GL_MUL_ATI 0x8964 #define GL_SUB_ATI 0x8965 #define GL_DOT3_ATI 0x8966 #define GL_DOT4_ATI 0x8967 #define GL_MAD_ATI 0x8968 #define GL_LERP_ATI 0x8969 #define GL_CND_ATI 0x896A #define GL_CND0_ATI 0x896B #define GL_DOT2_ADD_ATI 0x896C #define GL_SECONDARY_INTERPOLATOR_ATI 0x896D #define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E #define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F #define GL_NUM_PASSES_ATI 0x8970 #define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 #define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 #define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 #define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 #define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 #define GL_SWIZZLE_STR_ATI 0x8976 #define GL_SWIZZLE_STQ_ATI 0x8977 #define GL_SWIZZLE_STR_DR_ATI 0x8978 #define GL_SWIZZLE_STQ_DQ_ATI 0x8979 #define GL_SWIZZLE_STRQ_ATI 0x897A #define GL_SWIZZLE_STRQ_DQ_ATI 0x897B #define GL_RED_BIT_ATI 0x00000001 #define GL_GREEN_BIT_ATI 0x00000002 #define GL_BLUE_BIT_ATI 0x00000004 #define GL_2X_BIT_ATI 0x00000001 #define GL_4X_BIT_ATI 0x00000002 #define GL_8X_BIT_ATI 0x00000004 #define GL_HALF_BIT_ATI 0x00000008 #define GL_QUARTER_BIT_ATI 0x00000010 #define GL_EIGHTH_BIT_ATI 0x00000020 #define GL_SATURATE_BIT_ATI 0x00000040 #define GL_COMP_BIT_ATI 0x00000002 #define GL_NEGATE_BIT_ATI 0x00000004 #define GL_BIAS_BIT_ATI 0x00000008 #endif #ifndef GL_ATI_pn_triangles #define GL_PN_TRIANGLES_ATI 0x87F0 #define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 #define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 #define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 #define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 #define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 #define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 #define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 #define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 #endif #ifndef GL_ATI_vertex_array_object #define GL_STATIC_ATI 0x8760 #define GL_DYNAMIC_ATI 0x8761 #define GL_PRESERVE_ATI 0x8762 #define GL_DISCARD_ATI 0x8763 #define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 #define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 #define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 #define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 #endif #ifndef GL_EXT_vertex_shader #define GL_VERTEX_SHADER_EXT 0x8780 #define GL_VERTEX_SHADER_BINDING_EXT 0x8781 #define GL_OP_INDEX_EXT 0x8782 #define GL_OP_NEGATE_EXT 0x8783 #define GL_OP_DOT3_EXT 0x8784 #define GL_OP_DOT4_EXT 0x8785 #define GL_OP_MUL_EXT 0x8786 #define GL_OP_ADD_EXT 0x8787 #define GL_OP_MADD_EXT 0x8788 #define GL_OP_FRAC_EXT 0x8789 #define GL_OP_MAX_EXT 0x878A #define GL_OP_MIN_EXT 0x878B #define GL_OP_SET_GE_EXT 0x878C #define GL_OP_SET_LT_EXT 0x878D #define GL_OP_CLAMP_EXT 0x878E #define GL_OP_FLOOR_EXT 0x878F #define GL_OP_ROUND_EXT 0x8790 #define GL_OP_EXP_BASE_2_EXT 0x8791 #define GL_OP_LOG_BASE_2_EXT 0x8792 #define GL_OP_POWER_EXT 0x8793 #define GL_OP_RECIP_EXT 0x8794 #define GL_OP_RECIP_SQRT_EXT 0x8795 #define GL_OP_SUB_EXT 0x8796 #define GL_OP_CROSS_PRODUCT_EXT 0x8797 #define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 #define GL_OP_MOV_EXT 0x8799 #define GL_OUTPUT_VERTEX_EXT 0x879A #define GL_OUTPUT_COLOR0_EXT 0x879B #define GL_OUTPUT_COLOR1_EXT 0x879C #define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D #define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E #define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F #define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 #define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 #define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 #define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 #define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 #define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 #define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 #define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 #define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 #define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 #define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA #define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB #define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC #define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD #define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE #define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF #define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 #define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 #define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 #define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 #define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 #define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 #define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 #define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 #define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 #define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 #define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA #define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB #define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC #define GL_OUTPUT_FOG_EXT 0x87BD #define GL_SCALAR_EXT 0x87BE #define GL_VECTOR_EXT 0x87BF #define GL_MATRIX_EXT 0x87C0 #define GL_VARIANT_EXT 0x87C1 #define GL_INVARIANT_EXT 0x87C2 #define GL_LOCAL_CONSTANT_EXT 0x87C3 #define GL_LOCAL_EXT 0x87C4 #define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 #define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 #define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 #define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 #define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 #define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA #define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB #define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC #define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD #define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE #define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF #define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 #define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 #define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 #define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 #define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 #define GL_X_EXT 0x87D5 #define GL_Y_EXT 0x87D6 #define GL_Z_EXT 0x87D7 #define GL_W_EXT 0x87D8 #define GL_NEGATIVE_X_EXT 0x87D9 #define GL_NEGATIVE_Y_EXT 0x87DA #define GL_NEGATIVE_Z_EXT 0x87DB #define GL_NEGATIVE_W_EXT 0x87DC #define GL_ZERO_EXT 0x87DD #define GL_ONE_EXT 0x87DE #define GL_NEGATIVE_ONE_EXT 0x87DF #define GL_NORMALIZED_RANGE_EXT 0x87E0 #define GL_FULL_RANGE_EXT 0x87E1 #define GL_CURRENT_VERTEX_EXT 0x87E2 #define GL_MVP_MATRIX_EXT 0x87E3 #define GL_VARIANT_VALUE_EXT 0x87E4 #define GL_VARIANT_DATATYPE_EXT 0x87E5 #define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 #define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 #define GL_VARIANT_ARRAY_EXT 0x87E8 #define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 #define GL_INVARIANT_VALUE_EXT 0x87EA #define GL_INVARIANT_DATATYPE_EXT 0x87EB #define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC #define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED #endif #ifndef GL_ATI_vertex_streams #define GL_MAX_VERTEX_STREAMS_ATI 0x876B #define GL_VERTEX_STREAM0_ATI 0x876C #define GL_VERTEX_STREAM1_ATI 0x876D #define GL_VERTEX_STREAM2_ATI 0x876E #define GL_VERTEX_STREAM3_ATI 0x876F #define GL_VERTEX_STREAM4_ATI 0x8770 #define GL_VERTEX_STREAM5_ATI 0x8771 #define GL_VERTEX_STREAM6_ATI 0x8772 #define GL_VERTEX_STREAM7_ATI 0x8773 #define GL_VERTEX_SOURCE_ATI 0x8774 #endif #ifndef GL_ATI_element_array #define GL_ELEMENT_ARRAY_ATI 0x8768 #define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 #define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A #endif #ifndef GL_SUN_mesh_array #define GL_QUAD_MESH_SUN 0x8614 #define GL_TRIANGLE_MESH_SUN 0x8615 #endif #ifndef GL_SUN_slice_accum #define GL_SLICE_ACCUM_SUN 0x85CC #endif #ifndef GL_NV_multisample_filter_hint #define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 #endif #ifndef GL_NV_depth_clamp #define GL_DEPTH_CLAMP_NV 0x864F #endif #ifndef GL_NV_occlusion_query #define GL_PIXEL_COUNTER_BITS_NV 0x8864 #define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 #define GL_PIXEL_COUNT_NV 0x8866 #define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 #endif #ifndef GL_NV_point_sprite #define GL_POINT_SPRITE_NV 0x8861 #define GL_COORD_REPLACE_NV 0x8862 #define GL_POINT_SPRITE_R_MODE_NV 0x8863 #endif #ifndef GL_NV_texture_shader3 #define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 #define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 #define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 #define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 #define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 #define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 #define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 #define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 #define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 #define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 #define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A #define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B #define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C #define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D #define GL_HILO8_NV 0x885E #define GL_SIGNED_HILO8_NV 0x885F #define GL_FORCE_BLUE_TO_ONE_NV 0x8860 #endif #ifndef GL_NV_vertex_program1_1 #endif #ifndef GL_EXT_shadow_funcs #endif #ifndef GL_EXT_stencil_two_side #define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 #define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 #endif #ifndef GL_ATI_text_fragment_shader #define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 #endif #ifndef GL_APPLE_client_storage #define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 #endif #ifndef GL_APPLE_element_array #define GL_ELEMENT_ARRAY_APPLE 0x8768 #define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8769 #define GL_ELEMENT_ARRAY_POINTER_APPLE 0x876A #endif #ifndef GL_APPLE_fence #define GL_DRAW_PIXELS_APPLE 0x8A0A #define GL_FENCE_APPLE 0x8A0B #endif #ifndef GL_APPLE_vertex_array_object #define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 #endif #ifndef GL_APPLE_vertex_array_range #define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D #define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E #define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F #define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 #define GL_STORAGE_CACHED_APPLE 0x85BE #define GL_STORAGE_SHARED_APPLE 0x85BF #endif #ifndef GL_APPLE_ycbcr_422 #define GL_YCBCR_422_APPLE 0x85B9 #define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA #define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB #endif #ifndef GL_S3_s3tc #define GL_RGB_S3TC 0x83A0 #define GL_RGB4_S3TC 0x83A1 #define GL_RGBA_S3TC 0x83A2 #define GL_RGBA4_S3TC 0x83A3 #endif #ifndef GL_ATI_draw_buffers #define GL_MAX_DRAW_BUFFERS_ATI 0x8824 #define GL_DRAW_BUFFER0_ATI 0x8825 #define GL_DRAW_BUFFER1_ATI 0x8826 #define GL_DRAW_BUFFER2_ATI 0x8827 #define GL_DRAW_BUFFER3_ATI 0x8828 #define GL_DRAW_BUFFER4_ATI 0x8829 #define GL_DRAW_BUFFER5_ATI 0x882A #define GL_DRAW_BUFFER6_ATI 0x882B #define GL_DRAW_BUFFER7_ATI 0x882C #define GL_DRAW_BUFFER8_ATI 0x882D #define GL_DRAW_BUFFER9_ATI 0x882E #define GL_DRAW_BUFFER10_ATI 0x882F #define GL_DRAW_BUFFER11_ATI 0x8830 #define GL_DRAW_BUFFER12_ATI 0x8831 #define GL_DRAW_BUFFER13_ATI 0x8832 #define GL_DRAW_BUFFER14_ATI 0x8833 #define GL_DRAW_BUFFER15_ATI 0x8834 #endif #ifndef GL_ATI_pixel_format_float #define GL_TYPE_RGBA_FLOAT_ATI 0x8820 #define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 #endif #ifndef GL_ATI_texture_env_combine3 #define GL_MODULATE_ADD_ATI 0x8744 #define GL_MODULATE_SIGNED_ADD_ATI 0x8745 #define GL_MODULATE_SUBTRACT_ATI 0x8746 #endif #ifndef GL_ATI_texture_float #define GL_RGBA_FLOAT32_ATI 0x8814 #define GL_RGB_FLOAT32_ATI 0x8815 #define GL_ALPHA_FLOAT32_ATI 0x8816 #define GL_INTENSITY_FLOAT32_ATI 0x8817 #define GL_LUMINANCE_FLOAT32_ATI 0x8818 #define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 #define GL_RGBA_FLOAT16_ATI 0x881A #define GL_RGB_FLOAT16_ATI 0x881B #define GL_ALPHA_FLOAT16_ATI 0x881C #define GL_INTENSITY_FLOAT16_ATI 0x881D #define GL_LUMINANCE_FLOAT16_ATI 0x881E #define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F #endif #ifndef GL_NV_float_buffer #define GL_FLOAT_R_NV 0x8880 #define GL_FLOAT_RG_NV 0x8881 #define GL_FLOAT_RGB_NV 0x8882 #define GL_FLOAT_RGBA_NV 0x8883 #define GL_FLOAT_R16_NV 0x8884 #define GL_FLOAT_R32_NV 0x8885 #define GL_FLOAT_RG16_NV 0x8886 #define GL_FLOAT_RG32_NV 0x8887 #define GL_FLOAT_RGB16_NV 0x8888 #define GL_FLOAT_RGB32_NV 0x8889 #define GL_FLOAT_RGBA16_NV 0x888A #define GL_FLOAT_RGBA32_NV 0x888B #define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C #define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D #define GL_FLOAT_RGBA_MODE_NV 0x888E #endif #ifndef GL_NV_fragment_program #define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 #define GL_FRAGMENT_PROGRAM_NV 0x8870 #define GL_MAX_TEXTURE_COORDS_NV 0x8871 #define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 #define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 #define GL_PROGRAM_ERROR_STRING_NV 0x8874 #endif #ifndef GL_NV_half_float #define GL_HALF_FLOAT_NV 0x140B #endif #ifndef GL_NV_pixel_data_range #define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 #define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 #define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A #define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B #define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C #define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D #endif #ifndef GL_NV_primitive_restart #define GL_PRIMITIVE_RESTART_NV 0x8558 #define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 #endif #ifndef GL_NV_texture_expand_normal #define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F #endif #ifndef GL_NV_vertex_program2 #endif #ifndef GL_ATI_map_object_buffer #endif #ifndef GL_ATI_separate_stencil #define GL_STENCIL_BACK_FUNC_ATI 0x8800 #define GL_STENCIL_BACK_FAIL_ATI 0x8801 #define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 #define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 #endif #ifndef GL_ATI_vertex_attrib_array_object #endif #ifndef GL_OES_read_format #define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A #define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B #endif #ifndef GL_EXT_depth_bounds_test #define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 #define GL_DEPTH_BOUNDS_EXT 0x8891 #endif #ifndef GL_EXT_texture_mirror_clamp #define GL_MIRROR_CLAMP_EXT 0x8742 #define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 #define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 #endif #ifndef GL_EXT_blend_equation_separate #define GL_BLEND_EQUATION_RGB_EXT 0x8009 #define GL_BLEND_EQUATION_ALPHA_EXT 0x883D #endif #ifndef GL_MESA_pack_invert #define GL_PACK_INVERT_MESA 0x8758 #endif #ifndef GL_MESA_ycbcr_texture #define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA #define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB #define GL_YCBCR_MESA 0x8757 #endif #ifndef GL_EXT_pixel_buffer_object #define GL_PIXEL_PACK_BUFFER_EXT 0x88EB #define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC #define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED #define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF #endif #ifndef GL_NV_fragment_program_option #endif #ifndef GL_NV_fragment_program2 #define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 #define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 #define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 #define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 #define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 #endif #ifndef GL_NV_vertex_program2_option /* reuse GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */ /* reuse GL_MAX_PROGRAM_CALL_DEPTH_NV */ #endif #ifndef GL_NV_vertex_program3 /* reuse GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */ #endif #ifndef GL_EXT_framebuffer_object #define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 #define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 #define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 #define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 #define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 #define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 #define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 #define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 #define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA #define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB #define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC #define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD #define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF #define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 #define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 #define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 #define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 #define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 #define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 #define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 #define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 #define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 #define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 #define GL_COLOR_ATTACHMENT10_EXT 0x8CEA #define GL_COLOR_ATTACHMENT11_EXT 0x8CEB #define GL_COLOR_ATTACHMENT12_EXT 0x8CEC #define GL_COLOR_ATTACHMENT13_EXT 0x8CED #define GL_COLOR_ATTACHMENT14_EXT 0x8CEE #define GL_COLOR_ATTACHMENT15_EXT 0x8CEF #define GL_DEPTH_ATTACHMENT_EXT 0x8D00 #define GL_STENCIL_ATTACHMENT_EXT 0x8D20 #define GL_FRAMEBUFFER_EXT 0x8D40 #define GL_RENDERBUFFER_EXT 0x8D41 #define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 #define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 #define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 #define GL_STENCIL_INDEX1_EXT 0x8D46 #define GL_STENCIL_INDEX4_EXT 0x8D47 #define GL_STENCIL_INDEX8_EXT 0x8D48 #define GL_STENCIL_INDEX16_EXT 0x8D49 #define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 #define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 #define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 #define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 #define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 #define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 #endif #ifndef GL_GREMEDY_string_marker #endif #ifndef GL_EXT_packed_depth_stencil #define GL_DEPTH_STENCIL_EXT 0x84F9 #define GL_UNSIGNED_INT_24_8_EXT 0x84FA #define GL_DEPTH24_STENCIL8_EXT 0x88F0 #define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 #endif #ifndef GL_EXT_stencil_clear_tag #define GL_STENCIL_TAG_BITS_EXT 0x88F2 #define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 #endif #ifndef GL_EXT_texture_sRGB #define GL_SRGB_EXT 0x8C40 #define GL_SRGB8_EXT 0x8C41 #define GL_SRGB_ALPHA_EXT 0x8C42 #define GL_SRGB8_ALPHA8_EXT 0x8C43 #define GL_SLUMINANCE_ALPHA_EXT 0x8C44 #define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 #define GL_SLUMINANCE_EXT 0x8C46 #define GL_SLUMINANCE8_EXT 0x8C47 #define GL_COMPRESSED_SRGB_EXT 0x8C48 #define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 #define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A #define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B #define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F #endif #ifndef GL_EXT_framebuffer_blit #define GL_READ_FRAMEBUFFER_EXT 0x8CA8 #define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 #define GL_DRAW_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING_EXT #define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA #endif #ifndef GL_EXT_framebuffer_multisample #define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 #define GL_MAX_SAMPLES_EXT 0x8D57 #endif #ifndef GL_MESAX_texture_stack #define GL_TEXTURE_1D_STACK_MESAX 0x8759 #define GL_TEXTURE_2D_STACK_MESAX 0x875A #define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B #define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C #define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D #define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E #endif #ifndef GL_EXT_timer_query #define GL_TIME_ELAPSED_EXT 0x88BF #endif #ifndef GL_EXT_gpu_program_parameters #endif #ifndef GL_APPLE_flush_buffer_range #define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 #define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 #endif #ifndef GL_NV_gpu_program4 #define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 #define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905 #define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 #define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 #define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 #define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 #define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 #define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 #endif #ifndef GL_NV_geometry_program4 #define GL_LINES_ADJACENCY_EXT 0x000A #define GL_LINE_STRIP_ADJACENCY_EXT 0x000B #define GL_TRIANGLES_ADJACENCY_EXT 0x000C #define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D #define GL_GEOMETRY_PROGRAM_NV 0x8C26 #define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 #define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 #define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA #define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB #define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC #define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 #define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 #define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 #define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 #define GL_PROGRAM_POINT_SIZE_EXT 0x8642 #endif #ifndef GL_EXT_geometry_shader4 #define GL_GEOMETRY_SHADER_EXT 0x8DD9 /* reuse GL_GEOMETRY_VERTICES_OUT_EXT */ /* reuse GL_GEOMETRY_INPUT_TYPE_EXT */ /* reuse GL_GEOMETRY_OUTPUT_TYPE_EXT */ /* reuse GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT */ #define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD #define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE #define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B #define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF #define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 #define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 /* reuse GL_LINES_ADJACENCY_EXT */ /* reuse GL_LINE_STRIP_ADJACENCY_EXT */ /* reuse GL_TRIANGLES_ADJACENCY_EXT */ /* reuse GL_TRIANGLE_STRIP_ADJACENCY_EXT */ /* reuse GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT */ /* reuse GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */ /* reuse GL_PROGRAM_POINT_SIZE_EXT */ #endif #ifndef GL_NV_vertex_program4 #define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD #endif #ifndef GL_EXT_gpu_shader4 #define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 #define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 #define GL_SAMPLER_BUFFER_EXT 0x8DC2 #define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 #define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 #define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 #define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 #define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 #define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 #define GL_INT_SAMPLER_1D_EXT 0x8DC9 #define GL_INT_SAMPLER_2D_EXT 0x8DCA #define GL_INT_SAMPLER_3D_EXT 0x8DCB #define GL_INT_SAMPLER_CUBE_EXT 0x8DCC #define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD #define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE #define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF #define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 #define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 #define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 #define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 #define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 #define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 #define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 #define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 #define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 #endif #ifndef GL_EXT_draw_instanced #endif #ifndef GL_EXT_packed_float #define GL_R11F_G11F_B10F_EXT 0x8C3A #define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B #define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C #endif #ifndef GL_EXT_texture_array #define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 #define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 #define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A #define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B #define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C #define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D #define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF #define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E /* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */ #endif #ifndef GL_EXT_texture_buffer_object #define GL_TEXTURE_BUFFER_EXT 0x8C2A #define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B #define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C #define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D #define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E #endif #ifndef GL_EXT_texture_compression_latc #define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 #define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 #define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 #define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 #endif #ifndef GL_EXT_texture_compression_rgtc #define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB #define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC #define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD #define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE #endif #ifndef GL_EXT_texture_shared_exponent #define GL_RGB9_E5_EXT 0x8C3D #define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E #define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F #endif #ifndef GL_NV_depth_buffer_float #define GL_DEPTH_COMPONENT32F_NV 0x8DAB #define GL_DEPTH32F_STENCIL8_NV 0x8DAC #define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD #define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF #endif #ifndef GL_NV_fragment_program4 #endif #ifndef GL_NV_framebuffer_multisample_coverage #define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB #define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 #define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11 #define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 #endif #ifndef GL_EXT_framebuffer_sRGB #define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 #define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA #endif #ifndef GL_NV_geometry_shader4 #endif #ifndef GL_NV_parameter_buffer_object #define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 #define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 #define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 #define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 #define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 #endif #ifndef GL_EXT_draw_buffers2 #endif #ifndef GL_NV_transform_feedback #define GL_BACK_PRIMARY_COLOR_NV 0x8C77 #define GL_BACK_SECONDARY_COLOR_NV 0x8C78 #define GL_TEXTURE_COORD_NV 0x8C79 #define GL_CLIP_DISTANCE_NV 0x8C7A #define GL_VERTEX_ID_NV 0x8C7B #define GL_PRIMITIVE_ID_NV 0x8C7C #define GL_GENERIC_ATTRIB_NV 0x8C7D #define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E #define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 #define GL_ACTIVE_VARYINGS_NV 0x8C81 #define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 #define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 #define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 #define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 #define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 #define GL_PRIMITIVES_GENERATED_NV 0x8C87 #define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 #define GL_RASTERIZER_DISCARD_NV 0x8C89 #define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_ATTRIBS_NV 0x8C8A #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B #define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C #define GL_SEPARATE_ATTRIBS_NV 0x8C8D #define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E #define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F #endif #ifndef GL_EXT_bindable_uniform #define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 #define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 #define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 #define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED #define GL_UNIFORM_BUFFER_EXT 0x8DEE #define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF #endif #ifndef GL_EXT_texture_integer #define GL_RGBA32UI_EXT 0x8D70 #define GL_RGB32UI_EXT 0x8D71 #define GL_ALPHA32UI_EXT 0x8D72 #define GL_INTENSITY32UI_EXT 0x8D73 #define GL_LUMINANCE32UI_EXT 0x8D74 #define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 #define GL_RGBA16UI_EXT 0x8D76 #define GL_RGB16UI_EXT 0x8D77 #define GL_ALPHA16UI_EXT 0x8D78 #define GL_INTENSITY16UI_EXT 0x8D79 #define GL_LUMINANCE16UI_EXT 0x8D7A #define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B #define GL_RGBA8UI_EXT 0x8D7C #define GL_RGB8UI_EXT 0x8D7D #define GL_ALPHA8UI_EXT 0x8D7E #define GL_INTENSITY8UI_EXT 0x8D7F #define GL_LUMINANCE8UI_EXT 0x8D80 #define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 #define GL_RGBA32I_EXT 0x8D82 #define GL_RGB32I_EXT 0x8D83 #define GL_ALPHA32I_EXT 0x8D84 #define GL_INTENSITY32I_EXT 0x8D85 #define GL_LUMINANCE32I_EXT 0x8D86 #define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 #define GL_RGBA16I_EXT 0x8D88 #define GL_RGB16I_EXT 0x8D89 #define GL_ALPHA16I_EXT 0x8D8A #define GL_INTENSITY16I_EXT 0x8D8B #define GL_LUMINANCE16I_EXT 0x8D8C #define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D #define GL_RGBA8I_EXT 0x8D8E #define GL_RGB8I_EXT 0x8D8F #define GL_ALPHA8I_EXT 0x8D90 #define GL_INTENSITY8I_EXT 0x8D91 #define GL_LUMINANCE8I_EXT 0x8D92 #define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 #define GL_RED_INTEGER_EXT 0x8D94 #define GL_GREEN_INTEGER_EXT 0x8D95 #define GL_BLUE_INTEGER_EXT 0x8D96 #define GL_ALPHA_INTEGER_EXT 0x8D97 #define GL_RGB_INTEGER_EXT 0x8D98 #define GL_RGBA_INTEGER_EXT 0x8D99 #define GL_BGR_INTEGER_EXT 0x8D9A #define GL_BGRA_INTEGER_EXT 0x8D9B #define GL_LUMINANCE_INTEGER_EXT 0x8D9C #define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D #define GL_RGBA_INTEGER_MODE_EXT 0x8D9E #endif #ifndef GL_GREMEDY_frame_terminator #endif #ifndef GL_NV_conditional_render #define GL_QUERY_WAIT_NV 0x8E13 #define GL_QUERY_NO_WAIT_NV 0x8E14 #define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 #define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 #endif #ifndef GL_NV_present_video #define GL_FRAME_NV 0x8E26 #define GL_FIELDS_NV 0x8E27 #define GL_CURRENT_TIME_NV 0x8E28 #define GL_NUM_FILL_STREAMS_NV 0x8E29 #define GL_PRESENT_TIME_NV 0x8E2A #define GL_PRESENT_DURATION_NV 0x8E2B #endif #ifndef GL_EXT_transform_feedback #define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E #define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84 #define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85 #define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F #define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C #define GL_SEPARATE_ATTRIBS_EXT 0x8C8D #define GL_PRIMITIVES_GENERATED_EXT 0x8C87 #define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88 #define GL_RASTERIZER_DISCARD_EXT 0x8C89 #define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80 #define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83 #define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F #define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76 #endif #ifndef GL_EXT_direct_state_access #define GL_PROGRAM_MATRIX_EXT 0x8E2D #define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E #define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F #endif #ifndef GL_EXT_vertex_array_bgra /* reuse GL_BGRA */ #endif #ifndef GL_EXT_texture_swizzle #define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42 #define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43 #define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44 #define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45 #define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46 #endif #ifndef GL_NV_explicit_multisample #define GL_SAMPLE_POSITION_NV 0x8E50 #define GL_SAMPLE_MASK_NV 0x8E51 #define GL_SAMPLE_MASK_VALUE_NV 0x8E52 #define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53 #define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54 #define GL_TEXTURE_RENDERBUFFER_NV 0x8E55 #define GL_SAMPLER_RENDERBUFFER_NV 0x8E56 #define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57 #define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58 #define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59 #endif #ifndef GL_NV_transform_feedback2 #define GL_TRANSFORM_FEEDBACK_NV 0x8E22 #define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23 #define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24 #define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25 #endif #ifndef GL_ATI_meminfo #define GL_VBO_FREE_MEMORY_ATI 0x87FB #define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC #define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD #endif #ifndef GL_AMD_performance_monitor #define GL_COUNTER_TYPE_AMD 0x8BC0 #define GL_COUNTER_RANGE_AMD 0x8BC1 #define GL_UNSIGNED_INT64_AMD 0x8BC2 #define GL_PERCENTAGE_AMD 0x8BC3 #define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 #define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 #define GL_PERFMON_RESULT_AMD 0x8BC6 #endif #ifndef GL_AMD_texture_texture4 #endif #ifndef GL_AMD_vertex_shader_tesselator #define GL_SAMPLER_BUFFER_AMD 0x9001 #define GL_INT_SAMPLER_BUFFER_AMD 0x9002 #define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003 #define GL_TESSELLATION_MODE_AMD 0x9004 #define GL_TESSELLATION_FACTOR_AMD 0x9005 #define GL_DISCRETE_AMD 0x9006 #define GL_CONTINUOUS_AMD 0x9007 #endif #ifndef GL_EXT_provoking_vertex #define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C #define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D #define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E #define GL_PROVOKING_VERTEX_EXT 0x8E4F #endif #ifndef GL_EXT_texture_snorm #define GL_ALPHA_SNORM 0x9010 #define GL_LUMINANCE_SNORM 0x9011 #define GL_LUMINANCE_ALPHA_SNORM 0x9012 #define GL_INTENSITY_SNORM 0x9013 #define GL_ALPHA8_SNORM 0x9014 #define GL_LUMINANCE8_SNORM 0x9015 #define GL_LUMINANCE8_ALPHA8_SNORM 0x9016 #define GL_INTENSITY8_SNORM 0x9017 #define GL_ALPHA16_SNORM 0x9018 #define GL_LUMINANCE16_SNORM 0x9019 #define GL_LUMINANCE16_ALPHA16_SNORM 0x901A #define GL_INTENSITY16_SNORM 0x901B /* reuse GL_RED_SNORM */ /* reuse GL_RG_SNORM */ /* reuse GL_RGB_SNORM */ /* reuse GL_RGBA_SNORM */ /* reuse GL_R8_SNORM */ /* reuse GL_RG8_SNORM */ /* reuse GL_RGB8_SNORM */ /* reuse GL_RGBA8_SNORM */ /* reuse GL_R16_SNORM */ /* reuse GL_RG16_SNORM */ /* reuse GL_RGB16_SNORM */ /* reuse GL_RGBA16_SNORM */ /* reuse GL_SIGNED_NORMALIZED */ #endif #ifndef GL_AMD_draw_buffers_blend #endif #ifndef GL_APPLE_texture_range #define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7 #define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8 #define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC #define GL_STORAGE_PRIVATE_APPLE 0x85BD /* reuse GL_STORAGE_CACHED_APPLE */ /* reuse GL_STORAGE_SHARED_APPLE */ #endif #ifndef GL_APPLE_float_pixels #define GL_HALF_APPLE 0x140B #define GL_RGBA_FLOAT32_APPLE 0x8814 #define GL_RGB_FLOAT32_APPLE 0x8815 #define GL_ALPHA_FLOAT32_APPLE 0x8816 #define GL_INTENSITY_FLOAT32_APPLE 0x8817 #define GL_LUMINANCE_FLOAT32_APPLE 0x8818 #define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819 #define GL_RGBA_FLOAT16_APPLE 0x881A #define GL_RGB_FLOAT16_APPLE 0x881B #define GL_ALPHA_FLOAT16_APPLE 0x881C #define GL_INTENSITY_FLOAT16_APPLE 0x881D #define GL_LUMINANCE_FLOAT16_APPLE 0x881E #define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F #define GL_COLOR_FLOAT_APPLE 0x8A0F #endif #ifndef GL_APPLE_vertex_program_evaluators #define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00 #define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01 #define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02 #define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03 #define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04 #define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05 #define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06 #define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07 #define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08 #define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09 #endif #ifndef GL_APPLE_aux_depth_stencil #define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14 #endif #ifndef GL_APPLE_object_purgeable #define GL_BUFFER_OBJECT_APPLE 0x85B3 #define GL_RELEASED_APPLE 0x8A19 #define GL_VOLATILE_APPLE 0x8A1A #define GL_RETAINED_APPLE 0x8A1B #define GL_UNDEFINED_APPLE 0x8A1C #define GL_PURGEABLE_APPLE 0x8A1D #endif #ifndef GL_APPLE_row_bytes #define GL_PACK_ROW_BYTES_APPLE 0x8A15 #define GL_UNPACK_ROW_BYTES_APPLE 0x8A16 #endif #ifndef GL_APPLE_rgb_422 #define GL_RGB_422_APPLE 0x8A1F /* reuse GL_UNSIGNED_SHORT_8_8_APPLE */ /* reuse GL_UNSIGNED_SHORT_8_8_REV_APPLE */ #endif #ifndef GL_NV_video_capture #define GL_VIDEO_BUFFER_NV 0x9020 #define GL_VIDEO_BUFFER_BINDING_NV 0x9021 #define GL_FIELD_UPPER_NV 0x9022 #define GL_FIELD_LOWER_NV 0x9023 #define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024 #define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025 #define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026 #define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027 #define GL_VIDEO_BUFFER_PITCH_NV 0x9028 #define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029 #define GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A #define GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B #define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C #define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D #define GL_PARTIAL_SUCCESS_NV 0x902E #define GL_SUCCESS_NV 0x902F #define GL_FAILURE_NV 0x9030 #define GL_YCBYCR8_422_NV 0x9031 #define GL_YCBAYCR8A_4224_NV 0x9032 #define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033 #define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034 #define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035 #define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036 #define GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037 #define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038 #define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039 #define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A #define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B #define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C #endif #ifndef GL_NV_copy_image #endif #ifndef GL_EXT_separate_shader_objects #define GL_ACTIVE_PROGRAM_EXT 0x8B8D #endif #ifndef GL_NV_parameter_buffer_object2 #endif #ifndef GL_NV_shader_buffer_load #define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D #define GL_GPU_ADDRESS_NV 0x8F34 #define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35 #endif #ifndef GL_NV_vertex_buffer_unified_memory #define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E #define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F #define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20 #define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21 #define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22 #define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23 #define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24 #define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25 #define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26 #define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27 #define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28 #define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29 #define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A #define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B #define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C #define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D #define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E #define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F #define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30 #define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31 #define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32 #define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33 #endif #ifndef GL_NV_texture_barrier #endif /*************************************************************/ #include #ifndef GL_VERSION_2_0 /* GL type for program/shader text */ typedef char GLchar; #endif #ifndef GL_VERSION_1_5 /* GL types for handling large vertex buffer objects */ typedef ptrdiff_t GLintptr; typedef ptrdiff_t GLsizeiptr; #endif #ifndef GL_ARB_vertex_buffer_object /* GL types for handling large vertex buffer objects */ typedef ptrdiff_t GLintptrARB; typedef ptrdiff_t GLsizeiptrARB; #endif #ifndef GL_ARB_shader_objects /* GL types for program/shader text and shader object handles */ typedef char GLcharARB; typedef unsigned int GLhandleARB; #endif /* GL type for "half" precision (s10e5) float data in host memory */ #ifndef GL_ARB_half_float_pixel typedef unsigned short GLhalfARB; #endif #ifndef GL_NV_half_float typedef unsigned short GLhalfNV; #endif #ifndef GLEXT_64_TYPES_DEFINED /* This code block is duplicated in glxext.h, so must be protected */ #define GLEXT_64_TYPES_DEFINED /* Define int32_t, int64_t, and uint64_t types for UST/MSC */ /* (as used in the GL_EXT_timer_query extension). */ #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #include #elif defined(__sun__) || defined(__digital__) #include #if defined(__STDC__) #if defined(__arch64__) || defined(_LP64) typedef long int int64_t; typedef unsigned long int uint64_t; #else typedef long long int int64_t; typedef unsigned long long int uint64_t; #endif /* __arch64__ */ #endif /* __STDC__ */ #elif defined( __VMS ) || defined(__sgi) #include #elif defined(__SCO__) || defined(__USLC__) #include #elif defined(__UNIXOS2__) || defined(__SOL64__) typedef long int int32_t; typedef long long int int64_t; typedef unsigned long long int uint64_t; #elif defined(_WIN32) && defined(__GNUC__) #include #elif defined(_WIN32) typedef __int32 int32_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; #else /* Fallback if nothing above works */ #include #endif #endif #ifndef GL_EXT_timer_query typedef int64_t GLint64EXT; typedef uint64_t GLuint64EXT; #endif #ifndef ARB_sync typedef int64_t GLint64; typedef uint64_t GLuint64; typedef struct __GLsync *GLsync; #endif #ifndef GL_VERSION_1_2 #define GL_VERSION_1_2 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendColor (GLclampf, GLclampf, GLclampf, GLclampf); GLAPI void APIENTRY glBlendEquation (GLenum); GLAPI void APIENTRY glDrawRangeElements (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); GLAPI void APIENTRY glTexImage3D (GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glCopyTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode); typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); #endif #ifndef GL_VERSION_1_2_DEPRECATED #define GL_VERSION_1_2_DEPRECATED 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glColorTable (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glColorTableParameterfv (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY glColorTableParameteriv (GLenum, GLenum, const GLint *); GLAPI void APIENTRY glCopyColorTable (GLenum, GLenum, GLint, GLint, GLsizei); GLAPI void APIENTRY glGetColorTable (GLenum, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY glGetColorTableParameterfv (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetColorTableParameteriv (GLenum, GLenum, GLint *); GLAPI void APIENTRY glColorSubTable (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glCopyColorSubTable (GLenum, GLsizei, GLint, GLint, GLsizei); GLAPI void APIENTRY glConvolutionFilter1D (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glConvolutionFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glConvolutionParameterf (GLenum, GLenum, GLfloat); GLAPI void APIENTRY glConvolutionParameterfv (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY glConvolutionParameteri (GLenum, GLenum, GLint); GLAPI void APIENTRY glConvolutionParameteriv (GLenum, GLenum, const GLint *); GLAPI void APIENTRY glCopyConvolutionFilter1D (GLenum, GLenum, GLint, GLint, GLsizei); GLAPI void APIENTRY glCopyConvolutionFilter2D (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei); GLAPI void APIENTRY glGetConvolutionFilter (GLenum, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY glGetConvolutionParameterfv (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetConvolutionParameteriv (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetSeparableFilter (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *); GLAPI void APIENTRY glSeparableFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *); GLAPI void APIENTRY glGetHistogram (GLenum, GLboolean, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY glGetHistogramParameterfv (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetHistogramParameteriv (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetMinmax (GLenum, GLboolean, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY glGetMinmaxParameterfv (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetMinmaxParameteriv (GLenum, GLenum, GLint *); GLAPI void APIENTRY glHistogram (GLenum, GLsizei, GLenum, GLboolean); GLAPI void APIENTRY glMinmax (GLenum, GLenum, GLboolean); GLAPI void APIENTRY glResetHistogram (GLenum); GLAPI void APIENTRY glResetMinmax (GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); typedef void (APIENTRYP PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); typedef void (APIENTRYP PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); typedef void (APIENTRYP PFNGLRESETHISTOGRAMPROC) (GLenum target); typedef void (APIENTRYP PFNGLRESETMINMAXPROC) (GLenum target); #endif #ifndef GL_VERSION_1_3 #define GL_VERSION_1_3 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glActiveTexture (GLenum); GLAPI void APIENTRY glSampleCoverage (GLclampf, GLboolean); GLAPI void APIENTRY glCompressedTexImage3D (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTexImage2D (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTexImage1D (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTexSubImage2D (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTexSubImage1D (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glGetCompressedTexImage (GLenum, GLint, GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img); #endif #ifndef GL_VERSION_1_3_DEPRECATED #define GL_VERSION_1_3_DEPRECATED 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glClientActiveTexture (GLenum); GLAPI void APIENTRY glMultiTexCoord1d (GLenum, GLdouble); GLAPI void APIENTRY glMultiTexCoord1dv (GLenum, const GLdouble *); GLAPI void APIENTRY glMultiTexCoord1f (GLenum, GLfloat); GLAPI void APIENTRY glMultiTexCoord1fv (GLenum, const GLfloat *); GLAPI void APIENTRY glMultiTexCoord1i (GLenum, GLint); GLAPI void APIENTRY glMultiTexCoord1iv (GLenum, const GLint *); GLAPI void APIENTRY glMultiTexCoord1s (GLenum, GLshort); GLAPI void APIENTRY glMultiTexCoord1sv (GLenum, const GLshort *); GLAPI void APIENTRY glMultiTexCoord2d (GLenum, GLdouble, GLdouble); GLAPI void APIENTRY glMultiTexCoord2dv (GLenum, const GLdouble *); GLAPI void APIENTRY glMultiTexCoord2f (GLenum, GLfloat, GLfloat); GLAPI void APIENTRY glMultiTexCoord2fv (GLenum, const GLfloat *); GLAPI void APIENTRY glMultiTexCoord2i (GLenum, GLint, GLint); GLAPI void APIENTRY glMultiTexCoord2iv (GLenum, const GLint *); GLAPI void APIENTRY glMultiTexCoord2s (GLenum, GLshort, GLshort); GLAPI void APIENTRY glMultiTexCoord2sv (GLenum, const GLshort *); GLAPI void APIENTRY glMultiTexCoord3d (GLenum, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glMultiTexCoord3dv (GLenum, const GLdouble *); GLAPI void APIENTRY glMultiTexCoord3f (GLenum, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glMultiTexCoord3fv (GLenum, const GLfloat *); GLAPI void APIENTRY glMultiTexCoord3i (GLenum, GLint, GLint, GLint); GLAPI void APIENTRY glMultiTexCoord3iv (GLenum, const GLint *); GLAPI void APIENTRY glMultiTexCoord3s (GLenum, GLshort, GLshort, GLshort); GLAPI void APIENTRY glMultiTexCoord3sv (GLenum, const GLshort *); GLAPI void APIENTRY glMultiTexCoord4d (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glMultiTexCoord4dv (GLenum, const GLdouble *); GLAPI void APIENTRY glMultiTexCoord4f (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glMultiTexCoord4fv (GLenum, const GLfloat *); GLAPI void APIENTRY glMultiTexCoord4i (GLenum, GLint, GLint, GLint, GLint); GLAPI void APIENTRY glMultiTexCoord4iv (GLenum, const GLint *); GLAPI void APIENTRY glMultiTexCoord4s (GLenum, GLshort, GLshort, GLshort, GLshort); GLAPI void APIENTRY glMultiTexCoord4sv (GLenum, const GLshort *); GLAPI void APIENTRY glLoadTransposeMatrixf (const GLfloat *); GLAPI void APIENTRY glLoadTransposeMatrixd (const GLdouble *); GLAPI void APIENTRY glMultTransposeMatrixf (const GLfloat *); GLAPI void APIENTRY glMultTransposeMatrixd (const GLdouble *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m); typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m); typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m); typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m); #endif #ifndef GL_VERSION_1_4 #define GL_VERSION_1_4 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendFuncSeparate (GLenum, GLenum, GLenum, GLenum); GLAPI void APIENTRY glMultiDrawArrays (GLenum, GLint *, GLsizei *, GLsizei); GLAPI void APIENTRY glMultiDrawElements (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei); GLAPI void APIENTRY glPointParameterf (GLenum, GLfloat); GLAPI void APIENTRY glPointParameterfv (GLenum, const GLfloat *); GLAPI void APIENTRY glPointParameteri (GLenum, GLint); GLAPI void APIENTRY glPointParameteriv (GLenum, const GLint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); #endif #ifndef GL_VERSION_1_4_DEPRECATED #define GL_VERSION_1_4_DEPRECATED 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFogCoordf (GLfloat); GLAPI void APIENTRY glFogCoordfv (const GLfloat *); GLAPI void APIENTRY glFogCoordd (GLdouble); GLAPI void APIENTRY glFogCoorddv (const GLdouble *); GLAPI void APIENTRY glFogCoordPointer (GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glSecondaryColor3b (GLbyte, GLbyte, GLbyte); GLAPI void APIENTRY glSecondaryColor3bv (const GLbyte *); GLAPI void APIENTRY glSecondaryColor3d (GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glSecondaryColor3dv (const GLdouble *); GLAPI void APIENTRY glSecondaryColor3f (GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glSecondaryColor3fv (const GLfloat *); GLAPI void APIENTRY glSecondaryColor3i (GLint, GLint, GLint); GLAPI void APIENTRY glSecondaryColor3iv (const GLint *); GLAPI void APIENTRY glSecondaryColor3s (GLshort, GLshort, GLshort); GLAPI void APIENTRY glSecondaryColor3sv (const GLshort *); GLAPI void APIENTRY glSecondaryColor3ub (GLubyte, GLubyte, GLubyte); GLAPI void APIENTRY glSecondaryColor3ubv (const GLubyte *); GLAPI void APIENTRY glSecondaryColor3ui (GLuint, GLuint, GLuint); GLAPI void APIENTRY glSecondaryColor3uiv (const GLuint *); GLAPI void APIENTRY glSecondaryColor3us (GLushort, GLushort, GLushort); GLAPI void APIENTRY glSecondaryColor3usv (const GLushort *); GLAPI void APIENTRY glSecondaryColorPointer (GLint, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glWindowPos2d (GLdouble, GLdouble); GLAPI void APIENTRY glWindowPos2dv (const GLdouble *); GLAPI void APIENTRY glWindowPos2f (GLfloat, GLfloat); GLAPI void APIENTRY glWindowPos2fv (const GLfloat *); GLAPI void APIENTRY glWindowPos2i (GLint, GLint); GLAPI void APIENTRY glWindowPos2iv (const GLint *); GLAPI void APIENTRY glWindowPos2s (GLshort, GLshort); GLAPI void APIENTRY glWindowPos2sv (const GLshort *); GLAPI void APIENTRY glWindowPos3d (GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glWindowPos3dv (const GLdouble *); GLAPI void APIENTRY glWindowPos3f (GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glWindowPos3fv (const GLfloat *); GLAPI void APIENTRY glWindowPos3i (GLint, GLint, GLint); GLAPI void APIENTRY glWindowPos3iv (const GLint *); GLAPI void APIENTRY glWindowPos3s (GLshort, GLshort, GLshort); GLAPI void APIENTRY glWindowPos3sv (const GLshort *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFOGCOORDFPROC) (GLfloat coord); typedef void (APIENTRYP PFNGLFOGCOORDFVPROC) (const GLfloat *coord); typedef void (APIENTRYP PFNGLFOGCOORDDPROC) (GLdouble coord); typedef void (APIENTRYP PFNGLFOGCOORDDVPROC) (const GLdouble *coord); typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLWINDOWPOS2DVPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); typedef void (APIENTRYP PFNGLWINDOWPOS2FVPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); typedef void (APIENTRYP PFNGLWINDOWPOS2IVPROC) (const GLint *v); typedef void (APIENTRYP PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); typedef void (APIENTRYP PFNGLWINDOWPOS2SVPROC) (const GLshort *v); typedef void (APIENTRYP PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLWINDOWPOS3DVPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLWINDOWPOS3FVPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); typedef void (APIENTRYP PFNGLWINDOWPOS3IVPROC) (const GLint *v); typedef void (APIENTRYP PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNGLWINDOWPOS3SVPROC) (const GLshort *v); #endif #ifndef GL_VERSION_1_5 #define GL_VERSION_1_5 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGenQueries (GLsizei, GLuint *); GLAPI void APIENTRY glDeleteQueries (GLsizei, const GLuint *); GLAPI GLboolean APIENTRY glIsQuery (GLuint); GLAPI void APIENTRY glBeginQuery (GLenum, GLuint); GLAPI void APIENTRY glEndQuery (GLenum); GLAPI void APIENTRY glGetQueryiv (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetQueryObjectiv (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetQueryObjectuiv (GLuint, GLenum, GLuint *); GLAPI void APIENTRY glBindBuffer (GLenum, GLuint); GLAPI void APIENTRY glDeleteBuffers (GLsizei, const GLuint *); GLAPI void APIENTRY glGenBuffers (GLsizei, GLuint *); GLAPI GLboolean APIENTRY glIsBuffer (GLuint); GLAPI void APIENTRY glBufferData (GLenum, GLsizeiptr, const GLvoid *, GLenum); GLAPI void APIENTRY glBufferSubData (GLenum, GLintptr, GLsizeiptr, const GLvoid *); GLAPI void APIENTRY glGetBufferSubData (GLenum, GLintptr, GLsizeiptr, GLvoid *); GLAPI GLvoid* APIENTRY glMapBuffer (GLenum, GLenum); GLAPI GLboolean APIENTRY glUnmapBuffer (GLenum); GLAPI void APIENTRY glGetBufferParameteriv (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetBufferPointerv (GLenum, GLenum, GLvoid* *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids); typedef void (APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids); typedef GLboolean (APIENTRYP PFNGLISQUERYPROC) (GLuint id); typedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); typedef void (APIENTRYP PFNGLENDQUERYPROC) (GLenum target); typedef void (APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params); typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer); typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data); typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target); typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid* *params); #endif #ifndef GL_VERSION_2_0 #define GL_VERSION_2_0 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendEquationSeparate (GLenum, GLenum); GLAPI void APIENTRY glDrawBuffers (GLsizei, const GLenum *); GLAPI void APIENTRY glStencilOpSeparate (GLenum, GLenum, GLenum, GLenum); GLAPI void APIENTRY glStencilFuncSeparate (GLenum, GLenum, GLint, GLuint); GLAPI void APIENTRY glStencilMaskSeparate (GLenum, GLuint); GLAPI void APIENTRY glAttachShader (GLuint, GLuint); GLAPI void APIENTRY glBindAttribLocation (GLuint, GLuint, const GLchar *); GLAPI void APIENTRY glCompileShader (GLuint); GLAPI GLuint APIENTRY glCreateProgram (void); GLAPI GLuint APIENTRY glCreateShader (GLenum); GLAPI void APIENTRY glDeleteProgram (GLuint); GLAPI void APIENTRY glDeleteShader (GLuint); GLAPI void APIENTRY glDetachShader (GLuint, GLuint); GLAPI void APIENTRY glDisableVertexAttribArray (GLuint); GLAPI void APIENTRY glEnableVertexAttribArray (GLuint); GLAPI void APIENTRY glGetActiveAttrib (GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *); GLAPI void APIENTRY glGetActiveUniform (GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *); GLAPI void APIENTRY glGetAttachedShaders (GLuint, GLsizei, GLsizei *, GLuint *); GLAPI GLint APIENTRY glGetAttribLocation (GLuint, const GLchar *); GLAPI void APIENTRY glGetProgramiv (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetProgramInfoLog (GLuint, GLsizei, GLsizei *, GLchar *); GLAPI void APIENTRY glGetShaderiv (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetShaderInfoLog (GLuint, GLsizei, GLsizei *, GLchar *); GLAPI void APIENTRY glGetShaderSource (GLuint, GLsizei, GLsizei *, GLchar *); GLAPI GLint APIENTRY glGetUniformLocation (GLuint, const GLchar *); GLAPI void APIENTRY glGetUniformfv (GLuint, GLint, GLfloat *); GLAPI void APIENTRY glGetUniformiv (GLuint, GLint, GLint *); GLAPI void APIENTRY glGetVertexAttribdv (GLuint, GLenum, GLdouble *); GLAPI void APIENTRY glGetVertexAttribfv (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY glGetVertexAttribiv (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint, GLenum, GLvoid* *); GLAPI GLboolean APIENTRY glIsProgram (GLuint); GLAPI GLboolean APIENTRY glIsShader (GLuint); GLAPI void APIENTRY glLinkProgram (GLuint); GLAPI void APIENTRY glShaderSource (GLuint, GLsizei, const GLchar* *, const GLint *); GLAPI void APIENTRY glUseProgram (GLuint); GLAPI void APIENTRY glUniform1f (GLint, GLfloat); GLAPI void APIENTRY glUniform2f (GLint, GLfloat, GLfloat); GLAPI void APIENTRY glUniform3f (GLint, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glUniform4f (GLint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glUniform1i (GLint, GLint); GLAPI void APIENTRY glUniform2i (GLint, GLint, GLint); GLAPI void APIENTRY glUniform3i (GLint, GLint, GLint, GLint); GLAPI void APIENTRY glUniform4i (GLint, GLint, GLint, GLint, GLint); GLAPI void APIENTRY glUniform1fv (GLint, GLsizei, const GLfloat *); GLAPI void APIENTRY glUniform2fv (GLint, GLsizei, const GLfloat *); GLAPI void APIENTRY glUniform3fv (GLint, GLsizei, const GLfloat *); GLAPI void APIENTRY glUniform4fv (GLint, GLsizei, const GLfloat *); GLAPI void APIENTRY glUniform1iv (GLint, GLsizei, const GLint *); GLAPI void APIENTRY glUniform2iv (GLint, GLsizei, const GLint *); GLAPI void APIENTRY glUniform3iv (GLint, GLsizei, const GLint *); GLAPI void APIENTRY glUniform4iv (GLint, GLsizei, const GLint *); GLAPI void APIENTRY glUniformMatrix2fv (GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY glUniformMatrix3fv (GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY glUniformMatrix4fv (GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY glValidateProgram (GLuint); GLAPI void APIENTRY glVertexAttrib1d (GLuint, GLdouble); GLAPI void APIENTRY glVertexAttrib1dv (GLuint, const GLdouble *); GLAPI void APIENTRY glVertexAttrib1f (GLuint, GLfloat); GLAPI void APIENTRY glVertexAttrib1fv (GLuint, const GLfloat *); GLAPI void APIENTRY glVertexAttrib1s (GLuint, GLshort); GLAPI void APIENTRY glVertexAttrib1sv (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttrib2d (GLuint, GLdouble, GLdouble); GLAPI void APIENTRY glVertexAttrib2dv (GLuint, const GLdouble *); GLAPI void APIENTRY glVertexAttrib2f (GLuint, GLfloat, GLfloat); GLAPI void APIENTRY glVertexAttrib2fv (GLuint, const GLfloat *); GLAPI void APIENTRY glVertexAttrib2s (GLuint, GLshort, GLshort); GLAPI void APIENTRY glVertexAttrib2sv (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttrib3d (GLuint, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glVertexAttrib3dv (GLuint, const GLdouble *); GLAPI void APIENTRY glVertexAttrib3f (GLuint, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glVertexAttrib3fv (GLuint, const GLfloat *); GLAPI void APIENTRY glVertexAttrib3s (GLuint, GLshort, GLshort, GLshort); GLAPI void APIENTRY glVertexAttrib3sv (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttrib4Nbv (GLuint, const GLbyte *); GLAPI void APIENTRY glVertexAttrib4Niv (GLuint, const GLint *); GLAPI void APIENTRY glVertexAttrib4Nsv (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttrib4Nub (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); GLAPI void APIENTRY glVertexAttrib4Nubv (GLuint, const GLubyte *); GLAPI void APIENTRY glVertexAttrib4Nuiv (GLuint, const GLuint *); GLAPI void APIENTRY glVertexAttrib4Nusv (GLuint, const GLushort *); GLAPI void APIENTRY glVertexAttrib4bv (GLuint, const GLbyte *); GLAPI void APIENTRY glVertexAttrib4d (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glVertexAttrib4dv (GLuint, const GLdouble *); GLAPI void APIENTRY glVertexAttrib4f (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glVertexAttrib4fv (GLuint, const GLfloat *); GLAPI void APIENTRY glVertexAttrib4iv (GLuint, const GLint *); GLAPI void APIENTRY glVertexAttrib4s (GLuint, GLshort, GLshort, GLshort, GLshort); GLAPI void APIENTRY glVertexAttrib4sv (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttrib4ubv (GLuint, const GLubyte *); GLAPI void APIENTRY glVertexAttrib4uiv (GLuint, const GLuint *); GLAPI void APIENTRY glVertexAttrib4usv (GLuint, const GLushort *); GLAPI void APIENTRY glVertexAttribPointer (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs); typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name); typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader); typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void); typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type); typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program); typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader); typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj); typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params); typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, GLvoid* *pointer); typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program); typedef GLboolean (APIENTRYP PFNGLISSHADERPROC) (GLuint shader); typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program); typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length); typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program); typedef void (APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); typedef void (APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); typedef void (APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0); typedef void (APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); typedef void (APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); typedef void (APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); typedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); #endif #ifndef GL_VERSION_2_1 #define GL_VERSION_2_1 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glUniformMatrix2x3fv (GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY glUniformMatrix3x2fv (GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY glUniformMatrix2x4fv (GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY glUniformMatrix4x2fv (GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY glUniformMatrix3x4fv (GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY glUniformMatrix4x3fv (GLint, GLsizei, GLboolean, const GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); #endif #ifndef GL_VERSION_3_0 #define GL_VERSION_3_0 1 /* OpenGL 3.0 also reuses entry points from these extensions: */ /* ARB_framebuffer_object */ /* ARB_map_buffer_range */ /* ARB_vertex_array_object */ #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glColorMaski (GLuint, GLboolean, GLboolean, GLboolean, GLboolean); GLAPI void APIENTRY glGetBooleani_v (GLenum, GLuint, GLboolean *); GLAPI void APIENTRY glGetIntegeri_v (GLenum, GLuint, GLint *); GLAPI void APIENTRY glEnablei (GLenum, GLuint); GLAPI void APIENTRY glDisablei (GLenum, GLuint); GLAPI GLboolean APIENTRY glIsEnabledi (GLenum, GLuint); GLAPI void APIENTRY glBeginTransformFeedback (GLenum); GLAPI void APIENTRY glEndTransformFeedback (void); GLAPI void APIENTRY glBindBufferRange (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr); GLAPI void APIENTRY glBindBufferBase (GLenum, GLuint, GLuint); GLAPI void APIENTRY glTransformFeedbackVaryings (GLuint, GLsizei, const GLchar* *, GLenum); GLAPI void APIENTRY glGetTransformFeedbackVarying (GLuint, GLuint, GLsizei, GLsizei *, GLsizei *, GLenum *, GLchar *); GLAPI void APIENTRY glClampColor (GLenum, GLenum); GLAPI void APIENTRY glBeginConditionalRender (GLuint, GLenum); GLAPI void APIENTRY glEndConditionalRender (void); GLAPI void APIENTRY glVertexAttribIPointer (GLuint, GLint, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glGetVertexAttribIiv (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetVertexAttribIuiv (GLuint, GLenum, GLuint *); GLAPI void APIENTRY glVertexAttribI1i (GLuint, GLint); GLAPI void APIENTRY glVertexAttribI2i (GLuint, GLint, GLint); GLAPI void APIENTRY glVertexAttribI3i (GLuint, GLint, GLint, GLint); GLAPI void APIENTRY glVertexAttribI4i (GLuint, GLint, GLint, GLint, GLint); GLAPI void APIENTRY glVertexAttribI1ui (GLuint, GLuint); GLAPI void APIENTRY glVertexAttribI2ui (GLuint, GLuint, GLuint); GLAPI void APIENTRY glVertexAttribI3ui (GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glVertexAttribI4ui (GLuint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glVertexAttribI1iv (GLuint, const GLint *); GLAPI void APIENTRY glVertexAttribI2iv (GLuint, const GLint *); GLAPI void APIENTRY glVertexAttribI3iv (GLuint, const GLint *); GLAPI void APIENTRY glVertexAttribI4iv (GLuint, const GLint *); GLAPI void APIENTRY glVertexAttribI1uiv (GLuint, const GLuint *); GLAPI void APIENTRY glVertexAttribI2uiv (GLuint, const GLuint *); GLAPI void APIENTRY glVertexAttribI3uiv (GLuint, const GLuint *); GLAPI void APIENTRY glVertexAttribI4uiv (GLuint, const GLuint *); GLAPI void APIENTRY glVertexAttribI4bv (GLuint, const GLbyte *); GLAPI void APIENTRY glVertexAttribI4sv (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttribI4ubv (GLuint, const GLubyte *); GLAPI void APIENTRY glVertexAttribI4usv (GLuint, const GLushort *); GLAPI void APIENTRY glGetUniformuiv (GLuint, GLint, GLuint *); GLAPI void APIENTRY glBindFragDataLocation (GLuint, GLuint, const GLchar *); GLAPI GLint APIENTRY glGetFragDataLocation (GLuint, const GLchar *); GLAPI void APIENTRY glUniform1ui (GLint, GLuint); GLAPI void APIENTRY glUniform2ui (GLint, GLuint, GLuint); GLAPI void APIENTRY glUniform3ui (GLint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glUniform4ui (GLint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glUniform1uiv (GLint, GLsizei, const GLuint *); GLAPI void APIENTRY glUniform2uiv (GLint, GLsizei, const GLuint *); GLAPI void APIENTRY glUniform3uiv (GLint, GLsizei, const GLuint *); GLAPI void APIENTRY glUniform4uiv (GLint, GLsizei, const GLuint *); GLAPI void APIENTRY glTexParameterIiv (GLenum, GLenum, const GLint *); GLAPI void APIENTRY glTexParameterIuiv (GLenum, GLenum, const GLuint *); GLAPI void APIENTRY glGetTexParameterIiv (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetTexParameterIuiv (GLenum, GLenum, GLuint *); GLAPI void APIENTRY glClearBufferiv (GLenum, GLint, const GLint *); GLAPI void APIENTRY glClearBufferuiv (GLenum, GLint, const GLuint *); GLAPI void APIENTRY glClearBufferfv (GLenum, GLint, const GLfloat *); GLAPI void APIENTRY glClearBufferfi (GLenum, GLint, GLfloat, GLint); GLAPI const GLubyte * APIENTRY glGetStringi (GLenum, GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOLORMASKIPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data); typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data); typedef void (APIENTRYP PFNGLENABLEIPROC) (GLenum target, GLuint index); typedef void (APIENTRYP PFNGLDISABLEIPROC) (GLenum target, GLuint index); typedef GLboolean (APIENTRYP PFNGLISENABLEDIPROC) (GLenum target, GLuint index); typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode); typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void); typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer); typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode); typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); typedef void (APIENTRYP PFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp); typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode); typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC) (void); typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params); typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint x); typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint x, GLint y); typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint x, GLint y, GLint z); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint x); typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint x, GLuint y); typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params); typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint color, const GLchar *name); typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name); typedef void (APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0); typedef void (APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1); typedef void (APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); typedef void (APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint *params); typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint *params); typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value); typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value); typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value); typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index); #endif #ifndef GL_VERSION_3_1 #define GL_VERSION_3_1 1 /* OpenGL 3.1 also reuses entry points from these extensions: */ /* ARB_copy_buffer */ /* ARB_uniform_buffer_object */ #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawArraysInstanced (GLenum, GLint, GLsizei, GLsizei); GLAPI void APIENTRY glDrawElementsInstanced (GLenum, GLsizei, GLenum, const GLvoid *, GLsizei); GLAPI void APIENTRY glTexBuffer (GLenum, GLenum, GLuint); GLAPI void APIENTRY glPrimitiveRestartIndex (GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); typedef void (APIENTRYP PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalformat, GLuint buffer); typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint index); #endif #ifndef GL_VERSION_3_2 #define GL_VERSION_3_2 1 /* OpenGL 3.2 also reuses entry points from these extensions: */ /* ARB_draw_elements_base_vertex */ /* ARB_provoking_vertex */ /* ARB_sync */ /* ARB_texture_multisample */ #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetInteger64i_v (GLenum, GLuint, GLint64 *); GLAPI void APIENTRY glGetBufferParameteri64v (GLenum, GLenum, GLint64 *); GLAPI void APIENTRY glProgramParameteri (GLuint, GLenum, GLint); GLAPI void APIENTRY glFramebufferTexture (GLenum, GLenum, GLuint, GLint); GLAPI void APIENTRY glFramebufferTextureFace (GLenum, GLenum, GLuint, GLint, GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data); typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params); typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); #endif #ifndef GL_ARB_multitexture #define GL_ARB_multitexture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glActiveTextureARB (GLenum); GLAPI void APIENTRY glClientActiveTextureARB (GLenum); GLAPI void APIENTRY glMultiTexCoord1dARB (GLenum, GLdouble); GLAPI void APIENTRY glMultiTexCoord1dvARB (GLenum, const GLdouble *); GLAPI void APIENTRY glMultiTexCoord1fARB (GLenum, GLfloat); GLAPI void APIENTRY glMultiTexCoord1fvARB (GLenum, const GLfloat *); GLAPI void APIENTRY glMultiTexCoord1iARB (GLenum, GLint); GLAPI void APIENTRY glMultiTexCoord1ivARB (GLenum, const GLint *); GLAPI void APIENTRY glMultiTexCoord1sARB (GLenum, GLshort); GLAPI void APIENTRY glMultiTexCoord1svARB (GLenum, const GLshort *); GLAPI void APIENTRY glMultiTexCoord2dARB (GLenum, GLdouble, GLdouble); GLAPI void APIENTRY glMultiTexCoord2dvARB (GLenum, const GLdouble *); GLAPI void APIENTRY glMultiTexCoord2fARB (GLenum, GLfloat, GLfloat); GLAPI void APIENTRY glMultiTexCoord2fvARB (GLenum, const GLfloat *); GLAPI void APIENTRY glMultiTexCoord2iARB (GLenum, GLint, GLint); GLAPI void APIENTRY glMultiTexCoord2ivARB (GLenum, const GLint *); GLAPI void APIENTRY glMultiTexCoord2sARB (GLenum, GLshort, GLshort); GLAPI void APIENTRY glMultiTexCoord2svARB (GLenum, const GLshort *); GLAPI void APIENTRY glMultiTexCoord3dARB (GLenum, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glMultiTexCoord3dvARB (GLenum, const GLdouble *); GLAPI void APIENTRY glMultiTexCoord3fARB (GLenum, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glMultiTexCoord3fvARB (GLenum, const GLfloat *); GLAPI void APIENTRY glMultiTexCoord3iARB (GLenum, GLint, GLint, GLint); GLAPI void APIENTRY glMultiTexCoord3ivARB (GLenum, const GLint *); GLAPI void APIENTRY glMultiTexCoord3sARB (GLenum, GLshort, GLshort, GLshort); GLAPI void APIENTRY glMultiTexCoord3svARB (GLenum, const GLshort *); GLAPI void APIENTRY glMultiTexCoord4dARB (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glMultiTexCoord4dvARB (GLenum, const GLdouble *); GLAPI void APIENTRY glMultiTexCoord4fARB (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glMultiTexCoord4fvARB (GLenum, const GLfloat *); GLAPI void APIENTRY glMultiTexCoord4iARB (GLenum, GLint, GLint, GLint, GLint); GLAPI void APIENTRY glMultiTexCoord4ivARB (GLenum, const GLint *); GLAPI void APIENTRY glMultiTexCoord4sARB (GLenum, GLshort, GLshort, GLshort, GLshort); GLAPI void APIENTRY glMultiTexCoord4svARB (GLenum, const GLshort *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture); typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); #endif #ifndef GL_ARB_transpose_matrix #define GL_ARB_transpose_matrix 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glLoadTransposeMatrixfARB (const GLfloat *); GLAPI void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *); GLAPI void APIENTRY glMultTransposeMatrixfARB (const GLfloat *); GLAPI void APIENTRY glMultTransposeMatrixdARB (const GLdouble *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); #endif #ifndef GL_ARB_multisample #define GL_ARB_multisample 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glSampleCoverageARB (GLclampf, GLboolean); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert); #endif #ifndef GL_ARB_texture_env_add #define GL_ARB_texture_env_add 1 #endif #ifndef GL_ARB_texture_cube_map #define GL_ARB_texture_cube_map 1 #endif #ifndef GL_ARB_texture_compression #define GL_ARB_texture_compression 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glCompressedTexImage3DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTexImage2DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTexImage1DARB (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTexSubImage3DARB (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTexSubImage2DARB (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTexSubImage1DARB (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum, GLint, GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, GLvoid *img); #endif #ifndef GL_ARB_texture_border_clamp #define GL_ARB_texture_border_clamp 1 #endif #ifndef GL_ARB_point_parameters #define GL_ARB_point_parameters 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPointParameterfARB (GLenum, GLfloat); GLAPI void APIENTRY glPointParameterfvARB (GLenum, const GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat *params); #endif #ifndef GL_ARB_vertex_blend #define GL_ARB_vertex_blend 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glWeightbvARB (GLint, const GLbyte *); GLAPI void APIENTRY glWeightsvARB (GLint, const GLshort *); GLAPI void APIENTRY glWeightivARB (GLint, const GLint *); GLAPI void APIENTRY glWeightfvARB (GLint, const GLfloat *); GLAPI void APIENTRY glWeightdvARB (GLint, const GLdouble *); GLAPI void APIENTRY glWeightubvARB (GLint, const GLubyte *); GLAPI void APIENTRY glWeightusvARB (GLint, const GLushort *); GLAPI void APIENTRY glWeightuivARB (GLint, const GLuint *); GLAPI void APIENTRY glWeightPointerARB (GLint, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glVertexBlendARB (GLint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLWEIGHTBVARBPROC) (GLint size, const GLbyte *weights); typedef void (APIENTRYP PFNGLWEIGHTSVARBPROC) (GLint size, const GLshort *weights); typedef void (APIENTRYP PFNGLWEIGHTIVARBPROC) (GLint size, const GLint *weights); typedef void (APIENTRYP PFNGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights); typedef void (APIENTRYP PFNGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights); typedef void (APIENTRYP PFNGLWEIGHTUBVARBPROC) (GLint size, const GLubyte *weights); typedef void (APIENTRYP PFNGLWEIGHTUSVARBPROC) (GLint size, const GLushort *weights); typedef void (APIENTRYP PFNGLWEIGHTUIVARBPROC) (GLint size, const GLuint *weights); typedef void (APIENTRYP PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLVERTEXBLENDARBPROC) (GLint count); #endif #ifndef GL_ARB_matrix_palette #define GL_ARB_matrix_palette 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glCurrentPaletteMatrixARB (GLint); GLAPI void APIENTRY glMatrixIndexubvARB (GLint, const GLubyte *); GLAPI void APIENTRY glMatrixIndexusvARB (GLint, const GLushort *); GLAPI void APIENTRY glMatrixIndexuivARB (GLint, const GLuint *); GLAPI void APIENTRY glMatrixIndexPointerARB (GLint, GLenum, GLsizei, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); typedef void (APIENTRYP PFNGLMATRIXINDEXUBVARBPROC) (GLint size, const GLubyte *indices); typedef void (APIENTRYP PFNGLMATRIXINDEXUSVARBPROC) (GLint size, const GLushort *indices); typedef void (APIENTRYP PFNGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint *indices); typedef void (APIENTRYP PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); #endif #ifndef GL_ARB_texture_env_combine #define GL_ARB_texture_env_combine 1 #endif #ifndef GL_ARB_texture_env_crossbar #define GL_ARB_texture_env_crossbar 1 #endif #ifndef GL_ARB_texture_env_dot3 #define GL_ARB_texture_env_dot3 1 #endif #ifndef GL_ARB_texture_mirrored_repeat #define GL_ARB_texture_mirrored_repeat 1 #endif #ifndef GL_ARB_depth_texture #define GL_ARB_depth_texture 1 #endif #ifndef GL_ARB_shadow #define GL_ARB_shadow 1 #endif #ifndef GL_ARB_shadow_ambient #define GL_ARB_shadow_ambient 1 #endif #ifndef GL_ARB_window_pos #define GL_ARB_window_pos 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glWindowPos2dARB (GLdouble, GLdouble); GLAPI void APIENTRY glWindowPos2dvARB (const GLdouble *); GLAPI void APIENTRY glWindowPos2fARB (GLfloat, GLfloat); GLAPI void APIENTRY glWindowPos2fvARB (const GLfloat *); GLAPI void APIENTRY glWindowPos2iARB (GLint, GLint); GLAPI void APIENTRY glWindowPos2ivARB (const GLint *); GLAPI void APIENTRY glWindowPos2sARB (GLshort, GLshort); GLAPI void APIENTRY glWindowPos2svARB (const GLshort *); GLAPI void APIENTRY glWindowPos3dARB (GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glWindowPos3dvARB (const GLdouble *); GLAPI void APIENTRY glWindowPos3fARB (GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glWindowPos3fvARB (const GLfloat *); GLAPI void APIENTRY glWindowPos3iARB (GLint, GLint, GLint); GLAPI void APIENTRY glWindowPos3ivARB (const GLint *); GLAPI void APIENTRY glWindowPos3sARB (GLshort, GLshort, GLshort); GLAPI void APIENTRY glWindowPos3svARB (const GLshort *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLWINDOWPOS2DVARBPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); typedef void (APIENTRYP PFNGLWINDOWPOS2FVARBPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); typedef void (APIENTRYP PFNGLWINDOWPOS2IVARBPROC) (const GLint *v); typedef void (APIENTRYP PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); typedef void (APIENTRYP PFNGLWINDOWPOS2SVARBPROC) (const GLshort *v); typedef void (APIENTRYP PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLWINDOWPOS3DVARBPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLWINDOWPOS3FVARBPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); typedef void (APIENTRYP PFNGLWINDOWPOS3IVARBPROC) (const GLint *v); typedef void (APIENTRYP PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNGLWINDOWPOS3SVARBPROC) (const GLshort *v); #endif #ifndef GL_ARB_vertex_program #define GL_ARB_vertex_program 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexAttrib1dARB (GLuint, GLdouble); GLAPI void APIENTRY glVertexAttrib1dvARB (GLuint, const GLdouble *); GLAPI void APIENTRY glVertexAttrib1fARB (GLuint, GLfloat); GLAPI void APIENTRY glVertexAttrib1fvARB (GLuint, const GLfloat *); GLAPI void APIENTRY glVertexAttrib1sARB (GLuint, GLshort); GLAPI void APIENTRY glVertexAttrib1svARB (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttrib2dARB (GLuint, GLdouble, GLdouble); GLAPI void APIENTRY glVertexAttrib2dvARB (GLuint, const GLdouble *); GLAPI void APIENTRY glVertexAttrib2fARB (GLuint, GLfloat, GLfloat); GLAPI void APIENTRY glVertexAttrib2fvARB (GLuint, const GLfloat *); GLAPI void APIENTRY glVertexAttrib2sARB (GLuint, GLshort, GLshort); GLAPI void APIENTRY glVertexAttrib2svARB (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttrib3dARB (GLuint, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glVertexAttrib3dvARB (GLuint, const GLdouble *); GLAPI void APIENTRY glVertexAttrib3fARB (GLuint, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glVertexAttrib3fvARB (GLuint, const GLfloat *); GLAPI void APIENTRY glVertexAttrib3sARB (GLuint, GLshort, GLshort, GLshort); GLAPI void APIENTRY glVertexAttrib3svARB (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttrib4NbvARB (GLuint, const GLbyte *); GLAPI void APIENTRY glVertexAttrib4NivARB (GLuint, const GLint *); GLAPI void APIENTRY glVertexAttrib4NsvARB (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttrib4NubARB (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); GLAPI void APIENTRY glVertexAttrib4NubvARB (GLuint, const GLubyte *); GLAPI void APIENTRY glVertexAttrib4NuivARB (GLuint, const GLuint *); GLAPI void APIENTRY glVertexAttrib4NusvARB (GLuint, const GLushort *); GLAPI void APIENTRY glVertexAttrib4bvARB (GLuint, const GLbyte *); GLAPI void APIENTRY glVertexAttrib4dARB (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glVertexAttrib4dvARB (GLuint, const GLdouble *); GLAPI void APIENTRY glVertexAttrib4fARB (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glVertexAttrib4fvARB (GLuint, const GLfloat *); GLAPI void APIENTRY glVertexAttrib4ivARB (GLuint, const GLint *); GLAPI void APIENTRY glVertexAttrib4sARB (GLuint, GLshort, GLshort, GLshort, GLshort); GLAPI void APIENTRY glVertexAttrib4svARB (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttrib4ubvARB (GLuint, const GLubyte *); GLAPI void APIENTRY glVertexAttrib4uivARB (GLuint, const GLuint *); GLAPI void APIENTRY glVertexAttrib4usvARB (GLuint, const GLushort *); GLAPI void APIENTRY glVertexAttribPointerARB (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *); GLAPI void APIENTRY glEnableVertexAttribArrayARB (GLuint); GLAPI void APIENTRY glDisableVertexAttribArrayARB (GLuint); GLAPI void APIENTRY glProgramStringARB (GLenum, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glBindProgramARB (GLenum, GLuint); GLAPI void APIENTRY glDeleteProgramsARB (GLsizei, const GLuint *); GLAPI void APIENTRY glGenProgramsARB (GLsizei, GLuint *); GLAPI void APIENTRY glProgramEnvParameter4dARB (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glProgramEnvParameter4dvARB (GLenum, GLuint, const GLdouble *); GLAPI void APIENTRY glProgramEnvParameter4fARB (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glProgramEnvParameter4fvARB (GLenum, GLuint, const GLfloat *); GLAPI void APIENTRY glProgramLocalParameter4dARB (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glProgramLocalParameter4dvARB (GLenum, GLuint, const GLdouble *); GLAPI void APIENTRY glProgramLocalParameter4fARB (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glProgramLocalParameter4fvARB (GLenum, GLuint, const GLfloat *); GLAPI void APIENTRY glGetProgramEnvParameterdvARB (GLenum, GLuint, GLdouble *); GLAPI void APIENTRY glGetProgramEnvParameterfvARB (GLenum, GLuint, GLfloat *); GLAPI void APIENTRY glGetProgramLocalParameterdvARB (GLenum, GLuint, GLdouble *); GLAPI void APIENTRY glGetProgramLocalParameterfvARB (GLenum, GLuint, GLfloat *); GLAPI void APIENTRY glGetProgramivARB (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetProgramStringARB (GLenum, GLenum, GLvoid *); GLAPI void APIENTRY glGetVertexAttribdvARB (GLuint, GLenum, GLdouble *); GLAPI void APIENTRY glGetVertexAttribfvARB (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY glGetVertexAttribivARB (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetVertexAttribPointervARB (GLuint, GLenum, GLvoid* *); GLAPI GLboolean APIENTRY glIsProgramARB (GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); typedef void (APIENTRYP PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const GLvoid *string); typedef void (APIENTRYP PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); typedef void (APIENTRYP PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs); typedef void (APIENTRYP PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs); typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, GLvoid *string); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid* *pointer); typedef GLboolean (APIENTRYP PFNGLISPROGRAMARBPROC) (GLuint program); #endif #ifndef GL_ARB_fragment_program #define GL_ARB_fragment_program 1 /* All ARB_fragment_program entry points are shared with ARB_vertex_program. */ #endif #ifndef GL_ARB_vertex_buffer_object #define GL_ARB_vertex_buffer_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBindBufferARB (GLenum, GLuint); GLAPI void APIENTRY glDeleteBuffersARB (GLsizei, const GLuint *); GLAPI void APIENTRY glGenBuffersARB (GLsizei, GLuint *); GLAPI GLboolean APIENTRY glIsBufferARB (GLuint); GLAPI void APIENTRY glBufferDataARB (GLenum, GLsizeiptrARB, const GLvoid *, GLenum); GLAPI void APIENTRY glBufferSubDataARB (GLenum, GLintptrARB, GLsizeiptrARB, const GLvoid *); GLAPI void APIENTRY glGetBufferSubDataARB (GLenum, GLintptrARB, GLsizeiptrARB, GLvoid *); GLAPI GLvoid* APIENTRY glMapBufferARB (GLenum, GLenum); GLAPI GLboolean APIENTRY glUnmapBufferARB (GLenum); GLAPI void APIENTRY glGetBufferParameterivARB (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetBufferPointervARB (GLenum, GLenum, GLvoid* *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers); typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers); typedef GLboolean (APIENTRYP PFNGLISBUFFERARBPROC) (GLuint buffer); typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage); typedef void (APIENTRYP PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data); typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data); typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERARBPROC) (GLenum target); typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid* *params); #endif #ifndef GL_ARB_occlusion_query #define GL_ARB_occlusion_query 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGenQueriesARB (GLsizei, GLuint *); GLAPI void APIENTRY glDeleteQueriesARB (GLsizei, const GLuint *); GLAPI GLboolean APIENTRY glIsQueryARB (GLuint); GLAPI void APIENTRY glBeginQueryARB (GLenum, GLuint); GLAPI void APIENTRY glEndQueryARB (GLenum); GLAPI void APIENTRY glGetQueryivARB (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetQueryObjectivARB (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetQueryObjectuivARB (GLuint, GLenum, GLuint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint *ids); typedef void (APIENTRYP PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint *ids); typedef GLboolean (APIENTRYP PFNGLISQUERYARBPROC) (GLuint id); typedef void (APIENTRYP PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); typedef void (APIENTRYP PFNGLENDQUERYARBPROC) (GLenum target); typedef void (APIENTRYP PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint *params); #endif #ifndef GL_ARB_shader_objects #define GL_ARB_shader_objects 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDeleteObjectARB (GLhandleARB); GLAPI GLhandleARB APIENTRY glGetHandleARB (GLenum); GLAPI void APIENTRY glDetachObjectARB (GLhandleARB, GLhandleARB); GLAPI GLhandleARB APIENTRY glCreateShaderObjectARB (GLenum); GLAPI void APIENTRY glShaderSourceARB (GLhandleARB, GLsizei, const GLcharARB* *, const GLint *); GLAPI void APIENTRY glCompileShaderARB (GLhandleARB); GLAPI GLhandleARB APIENTRY glCreateProgramObjectARB (void); GLAPI void APIENTRY glAttachObjectARB (GLhandleARB, GLhandleARB); GLAPI void APIENTRY glLinkProgramARB (GLhandleARB); GLAPI void APIENTRY glUseProgramObjectARB (GLhandleARB); GLAPI void APIENTRY glValidateProgramARB (GLhandleARB); GLAPI void APIENTRY glUniform1fARB (GLint, GLfloat); GLAPI void APIENTRY glUniform2fARB (GLint, GLfloat, GLfloat); GLAPI void APIENTRY glUniform3fARB (GLint, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glUniform4fARB (GLint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glUniform1iARB (GLint, GLint); GLAPI void APIENTRY glUniform2iARB (GLint, GLint, GLint); GLAPI void APIENTRY glUniform3iARB (GLint, GLint, GLint, GLint); GLAPI void APIENTRY glUniform4iARB (GLint, GLint, GLint, GLint, GLint); GLAPI void APIENTRY glUniform1fvARB (GLint, GLsizei, const GLfloat *); GLAPI void APIENTRY glUniform2fvARB (GLint, GLsizei, const GLfloat *); GLAPI void APIENTRY glUniform3fvARB (GLint, GLsizei, const GLfloat *); GLAPI void APIENTRY glUniform4fvARB (GLint, GLsizei, const GLfloat *); GLAPI void APIENTRY glUniform1ivARB (GLint, GLsizei, const GLint *); GLAPI void APIENTRY glUniform2ivARB (GLint, GLsizei, const GLint *); GLAPI void APIENTRY glUniform3ivARB (GLint, GLsizei, const GLint *); GLAPI void APIENTRY glUniform4ivARB (GLint, GLsizei, const GLint *); GLAPI void APIENTRY glUniformMatrix2fvARB (GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY glUniformMatrix3fvARB (GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY glUniformMatrix4fvARB (GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY glGetObjectParameterfvARB (GLhandleARB, GLenum, GLfloat *); GLAPI void APIENTRY glGetObjectParameterivARB (GLhandleARB, GLenum, GLint *); GLAPI void APIENTRY glGetInfoLogARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *); GLAPI void APIENTRY glGetAttachedObjectsARB (GLhandleARB, GLsizei, GLsizei *, GLhandleARB *); GLAPI GLint APIENTRY glGetUniformLocationARB (GLhandleARB, const GLcharARB *); GLAPI void APIENTRY glGetActiveUniformARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *); GLAPI void APIENTRY glGetUniformfvARB (GLhandleARB, GLint, GLfloat *); GLAPI void APIENTRY glGetUniformivARB (GLhandleARB, GLint, GLint *); GLAPI void APIENTRY glGetShaderSourceARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); typedef GLhandleARB (APIENTRYP PFNGLGETHANDLEARBPROC) (GLenum pname); typedef void (APIENTRYP PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); typedef GLhandleARB (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length); typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); typedef GLhandleARB (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void); typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); typedef void (APIENTRYP PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); typedef void (APIENTRYP PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); typedef void (APIENTRYP PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); typedef void (APIENTRYP PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); typedef void (APIENTRYP PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); typedef void (APIENTRYP PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); typedef void (APIENTRYP PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); typedef void (APIENTRYP PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); typedef void (APIENTRYP PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); typedef void (APIENTRYP PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); typedef void (APIENTRYP PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); typedef void (APIENTRYP PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat *params); typedef void (APIENTRYP PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint *params); typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); #endif #ifndef GL_ARB_vertex_shader #define GL_ARB_vertex_shader 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBindAttribLocationARB (GLhandleARB, GLuint, const GLcharARB *); GLAPI void APIENTRY glGetActiveAttribARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *); GLAPI GLint APIENTRY glGetAttribLocationARB (GLhandleARB, const GLcharARB *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name); typedef void (APIENTRYP PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); #endif #ifndef GL_ARB_fragment_shader #define GL_ARB_fragment_shader 1 #endif #ifndef GL_ARB_shading_language_100 #define GL_ARB_shading_language_100 1 #endif #ifndef GL_ARB_texture_non_power_of_two #define GL_ARB_texture_non_power_of_two 1 #endif #ifndef GL_ARB_point_sprite #define GL_ARB_point_sprite 1 #endif #ifndef GL_ARB_fragment_program_shadow #define GL_ARB_fragment_program_shadow 1 #endif #ifndef GL_ARB_draw_buffers #define GL_ARB_draw_buffers 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawBuffersARB (GLsizei, const GLenum *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum *bufs); #endif #ifndef GL_ARB_texture_rectangle #define GL_ARB_texture_rectangle 1 #endif #ifndef GL_ARB_color_buffer_float #define GL_ARB_color_buffer_float 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glClampColorARB (GLenum, GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); #endif #ifndef GL_ARB_half_float_pixel #define GL_ARB_half_float_pixel 1 #endif #ifndef GL_ARB_texture_float #define GL_ARB_texture_float 1 #endif #ifndef GL_ARB_pixel_buffer_object #define GL_ARB_pixel_buffer_object 1 #endif #ifndef GL_ARB_depth_buffer_float #define GL_ARB_depth_buffer_float 1 #endif #ifndef GL_ARB_draw_instanced #define GL_ARB_draw_instanced 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawArraysInstancedARB (GLenum, GLint, GLsizei, GLsizei); GLAPI void APIENTRY glDrawElementsInstancedARB (GLenum, GLsizei, GLenum, const GLvoid *, GLsizei); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); #endif #ifndef GL_ARB_framebuffer_object #define GL_ARB_framebuffer_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLboolean APIENTRY glIsRenderbuffer (GLuint); GLAPI void APIENTRY glBindRenderbuffer (GLenum, GLuint); GLAPI void APIENTRY glDeleteRenderbuffers (GLsizei, const GLuint *); GLAPI void APIENTRY glGenRenderbuffers (GLsizei, GLuint *); GLAPI void APIENTRY glRenderbufferStorage (GLenum, GLenum, GLsizei, GLsizei); GLAPI void APIENTRY glGetRenderbufferParameteriv (GLenum, GLenum, GLint *); GLAPI GLboolean APIENTRY glIsFramebuffer (GLuint); GLAPI void APIENTRY glBindFramebuffer (GLenum, GLuint); GLAPI void APIENTRY glDeleteFramebuffers (GLsizei, const GLuint *); GLAPI void APIENTRY glGenFramebuffers (GLsizei, GLuint *); GLAPI GLenum APIENTRY glCheckFramebufferStatus (GLenum); GLAPI void APIENTRY glFramebufferTexture1D (GLenum, GLenum, GLenum, GLuint, GLint); GLAPI void APIENTRY glFramebufferTexture2D (GLenum, GLenum, GLenum, GLuint, GLint); GLAPI void APIENTRY glFramebufferTexture3D (GLenum, GLenum, GLenum, GLuint, GLint, GLint); GLAPI void APIENTRY glFramebufferRenderbuffer (GLenum, GLenum, GLenum, GLuint); GLAPI void APIENTRY glGetFramebufferAttachmentParameteriv (GLenum, GLenum, GLenum, GLint *); GLAPI void APIENTRY glGenerateMipmap (GLenum); GLAPI void APIENTRY glBlitFramebuffer (GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum); GLAPI void APIENTRY glRenderbufferStorageMultisample (GLenum, GLsizei, GLenum, GLsizei, GLsizei); GLAPI void APIENTRY glFramebufferTextureLayer (GLenum, GLenum, GLuint, GLint, GLint); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers); typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers); typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers); typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers); typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target); typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); #endif #ifndef GL_ARB_framebuffer_sRGB #define GL_ARB_framebuffer_sRGB 1 #endif #ifndef GL_ARB_geometry_shader4 #define GL_ARB_geometry_shader4 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glProgramParameteriARB (GLuint, GLenum, GLint); GLAPI void APIENTRY glFramebufferTextureARB (GLenum, GLenum, GLuint, GLint); GLAPI void APIENTRY glFramebufferTextureLayerARB (GLenum, GLenum, GLuint, GLint, GLint); GLAPI void APIENTRY glFramebufferTextureFaceARB (GLenum, GLenum, GLuint, GLint, GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); #endif #ifndef GL_ARB_half_float_vertex #define GL_ARB_half_float_vertex 1 #endif #ifndef GL_ARB_instanced_arrays #define GL_ARB_instanced_arrays 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexAttribDivisorARB (GLuint, GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor); #endif #ifndef GL_ARB_map_buffer_range #define GL_ARB_map_buffer_range 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLvoid* APIENTRY glMapBufferRange (GLenum, GLintptr, GLsizeiptr, GLbitfield); GLAPI void APIENTRY glFlushMappedBufferRange (GLenum, GLintptr, GLsizeiptr); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); #endif #ifndef GL_ARB_texture_buffer_object #define GL_ARB_texture_buffer_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexBufferARB (GLenum, GLenum, GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer); #endif #ifndef GL_ARB_texture_compression_rgtc #define GL_ARB_texture_compression_rgtc 1 #endif #ifndef GL_ARB_texture_rg #define GL_ARB_texture_rg 1 #endif #ifndef GL_ARB_vertex_array_object #define GL_ARB_vertex_array_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBindVertexArray (GLuint); GLAPI void APIENTRY glDeleteVertexArrays (GLsizei, const GLuint *); GLAPI void APIENTRY glGenVertexArrays (GLsizei, GLuint *); GLAPI GLboolean APIENTRY glIsVertexArray (GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array); typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays); typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays); typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC) (GLuint array); #endif #ifndef GL_ARB_uniform_buffer_object #define GL_ARB_uniform_buffer_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetUniformIndices (GLuint, GLsizei, const GLchar* *, GLuint *); GLAPI void APIENTRY glGetActiveUniformsiv (GLuint, GLsizei, const GLuint *, GLenum, GLint *); GLAPI void APIENTRY glGetActiveUniformName (GLuint, GLuint, GLsizei, GLsizei *, GLchar *); GLAPI GLuint APIENTRY glGetUniformBlockIndex (GLuint, const GLchar *); GLAPI void APIENTRY glGetActiveUniformBlockiv (GLuint, GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetActiveUniformBlockName (GLuint, GLuint, GLsizei, GLsizei *, GLchar *); GLAPI void APIENTRY glUniformBlockBinding (GLuint, GLuint, GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar* *uniformNames, GLuint *uniformIndices); typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName); typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); typedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); #endif #ifndef GL_ARB_compatibility #define GL_ARB_compatibility 1 #endif #ifndef GL_ARB_copy_buffer #define GL_ARB_copy_buffer 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glCopyBufferSubData (GLenum, GLenum, GLintptr, GLintptr, GLsizeiptr); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); #endif #ifndef GL_ARB_shader_texture_lod #define GL_ARB_shader_texture_lod 1 #endif #ifndef GL_ARB_depth_clamp #define GL_ARB_depth_clamp 1 #endif #ifndef GL_ARB_draw_elements_base_vertex #define GL_ARB_draw_elements_base_vertex 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawElementsBaseVertex (GLenum, GLsizei, GLenum, const GLvoid *, GLint); GLAPI void APIENTRY glDrawRangeElementsBaseVertex (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *, GLint); GLAPI void APIENTRY glDrawElementsInstancedBaseVertex (GLenum, GLsizei, GLenum, const GLvoid *, GLsizei, GLint); GLAPI void APIENTRY glMultiDrawElementsBaseVertex (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei, const GLint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex); typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex); typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount, GLint basevertex); typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount, const GLint *basevertex); #endif #ifndef GL_ARB_fragment_coord_conventions #define GL_ARB_fragment_coord_conventions 1 #endif #ifndef GL_ARB_provoking_vertex #define GL_ARB_provoking_vertex 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glProvokingVertex (GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC) (GLenum mode); #endif #ifndef GL_ARB_seamless_cube_map #define GL_ARB_seamless_cube_map 1 #endif #ifndef GL_ARB_sync #define GL_ARB_sync 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLsync APIENTRY glFenceSync (GLenum, GLbitfield); GLAPI GLboolean APIENTRY glIsSync (GLsync); GLAPI void APIENTRY glDeleteSync (GLsync); GLAPI GLenum APIENTRY glClientWaitSync (GLsync, GLbitfield, GLuint64); GLAPI void APIENTRY glWaitSync (GLsync, GLbitfield, GLuint64); GLAPI void APIENTRY glGetInteger64v (GLenum, GLint64 *); GLAPI void APIENTRY glGetSynciv (GLsync, GLenum, GLsizei, GLsizei *, GLint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags); typedef GLboolean (APIENTRYP PFNGLISSYNCPROC) (GLsync sync); typedef void (APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync); typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); typedef void (APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); typedef void (APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *params); typedef void (APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); #endif #ifndef GL_ARB_texture_multisample #define GL_ARB_texture_multisample 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexImage2DMultisample (GLenum, GLsizei, GLint, GLsizei, GLsizei, GLboolean); GLAPI void APIENTRY glTexImage3DMultisample (GLenum, GLsizei, GLint, GLsizei, GLsizei, GLsizei, GLboolean); GLAPI void APIENTRY glGetMultisamplefv (GLenum, GLuint, GLfloat *); GLAPI void APIENTRY glSampleMaski (GLuint, GLbitfield); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat *val); typedef void (APIENTRYP PFNGLSAMPLEMASKIPROC) (GLuint index, GLbitfield mask); #endif #ifndef GL_ARB_vertex_array_bgra #define GL_ARB_vertex_array_bgra 1 #endif #ifndef GL_ARB_draw_buffers_blend #define GL_ARB_draw_buffers_blend 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendEquationi (GLuint, GLenum); GLAPI void APIENTRY glBlendEquationSeparatei (GLuint, GLenum, GLenum); GLAPI void APIENTRY glBlendFunci (GLuint, GLenum, GLenum); GLAPI void APIENTRY glBlendFuncSeparatei (GLuint, GLenum, GLenum, GLenum, GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode); typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); typedef void (APIENTRYP PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst); typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); #endif #ifndef GL_ARB_sample_shading #define GL_ARB_sample_shading 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glMinSampleShading (GLclampf); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLMINSAMPLESHADINGPROC) (GLclampf value); #endif #ifndef GL_ARB_texture_cube_map_array #define GL_ARB_texture_cube_map_array 1 #endif #ifndef GL_ARB_texture_gather #define GL_ARB_texture_gather 1 #endif #ifndef GL_ARB_texture_query_lod #define GL_ARB_texture_query_lod 1 #endif #ifndef GL_EXT_abgr #define GL_EXT_abgr 1 #endif #ifndef GL_EXT_blend_color #define GL_EXT_blend_color 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendColorEXT (GLclampf, GLclampf, GLclampf, GLclampf); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); #endif #ifndef GL_EXT_polygon_offset #define GL_EXT_polygon_offset 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPolygonOffsetEXT (GLfloat, GLfloat); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); #endif #ifndef GL_EXT_texture #define GL_EXT_texture 1 #endif #ifndef GL_EXT_texture3D #define GL_EXT_texture3D 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexImage3DEXT (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); #endif #ifndef GL_SGIS_texture_filter4 #define GL_SGIS_texture_filter4 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetTexFilterFuncSGIS (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glTexFilterFuncSGIS (GLenum, GLenum, GLsizei, const GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights); typedef void (APIENTRYP PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); #endif #ifndef GL_EXT_subtexture #define GL_EXT_subtexture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexSubImage1DEXT (GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); #endif #ifndef GL_EXT_copy_texture #define GL_EXT_copy_texture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glCopyTexImage1DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint); GLAPI void APIENTRY glCopyTexImage2DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint); GLAPI void APIENTRY glCopyTexSubImage1DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei); GLAPI void APIENTRY glCopyTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); GLAPI void APIENTRY glCopyTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); #endif #ifndef GL_EXT_histogram #define GL_EXT_histogram 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetHistogramEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY glGetHistogramParameterfvEXT (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetHistogramParameterivEXT (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetMinmaxEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY glGetMinmaxParameterfvEXT (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetMinmaxParameterivEXT (GLenum, GLenum, GLint *); GLAPI void APIENTRY glHistogramEXT (GLenum, GLsizei, GLenum, GLboolean); GLAPI void APIENTRY glMinmaxEXT (GLenum, GLenum, GLboolean); GLAPI void APIENTRY glResetHistogramEXT (GLenum); GLAPI void APIENTRY glResetMinmaxEXT (GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); typedef void (APIENTRYP PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); typedef void (APIENTRYP PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); typedef void (APIENTRYP PFNGLRESETMINMAXEXTPROC) (GLenum target); #endif #ifndef GL_EXT_convolution #define GL_EXT_convolution 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glConvolutionFilter1DEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glConvolutionFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glConvolutionParameterfEXT (GLenum, GLenum, GLfloat); GLAPI void APIENTRY glConvolutionParameterfvEXT (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY glConvolutionParameteriEXT (GLenum, GLenum, GLint); GLAPI void APIENTRY glConvolutionParameterivEXT (GLenum, GLenum, const GLint *); GLAPI void APIENTRY glCopyConvolutionFilter1DEXT (GLenum, GLenum, GLint, GLint, GLsizei); GLAPI void APIENTRY glCopyConvolutionFilter2DEXT (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei); GLAPI void APIENTRY glGetConvolutionFilterEXT (GLenum, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY glGetConvolutionParameterfvEXT (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetConvolutionParameterivEXT (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetSeparableFilterEXT (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *); GLAPI void APIENTRY glSeparableFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params); typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params); typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); #endif #ifndef GL_SGI_color_matrix #define GL_SGI_color_matrix 1 #endif #ifndef GL_SGI_color_table #define GL_SGI_color_table 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glColorTableSGI (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glColorTableParameterfvSGI (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY glColorTableParameterivSGI (GLenum, GLenum, const GLint *); GLAPI void APIENTRY glCopyColorTableSGI (GLenum, GLenum, GLint, GLint, GLsizei); GLAPI void APIENTRY glGetColorTableSGI (GLenum, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY glGetColorTableParameterfvSGI (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetColorTableParameterivSGI (GLenum, GLenum, GLint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params); #endif #ifndef GL_SGIX_pixel_texture #define GL_SGIX_pixel_texture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPixelTexGenSGIX (GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); #endif #ifndef GL_SGIS_pixel_texture #define GL_SGIS_pixel_texture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPixelTexGenParameteriSGIS (GLenum, GLint); GLAPI void APIENTRY glPixelTexGenParameterivSGIS (GLenum, const GLint *); GLAPI void APIENTRY glPixelTexGenParameterfSGIS (GLenum, GLfloat); GLAPI void APIENTRY glPixelTexGenParameterfvSGIS (GLenum, const GLfloat *); GLAPI void APIENTRY glGetPixelTexGenParameterivSGIS (GLenum, GLint *); GLAPI void APIENTRY glGetPixelTexGenParameterfvSGIS (GLenum, GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params); #endif #ifndef GL_SGIS_texture4D #define GL_SGIS_texture4D 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexImage4DSGIS (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glTexSubImage4DSGIS (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels); #endif #ifndef GL_SGI_texture_color_table #define GL_SGI_texture_color_table 1 #endif #ifndef GL_EXT_cmyka #define GL_EXT_cmyka 1 #endif #ifndef GL_EXT_texture_object #define GL_EXT_texture_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLboolean APIENTRY glAreTexturesResidentEXT (GLsizei, const GLuint *, GLboolean *); GLAPI void APIENTRY glBindTextureEXT (GLenum, GLuint); GLAPI void APIENTRY glDeleteTexturesEXT (GLsizei, const GLuint *); GLAPI void APIENTRY glGenTexturesEXT (GLsizei, GLuint *); GLAPI GLboolean APIENTRY glIsTextureEXT (GLuint); GLAPI void APIENTRY glPrioritizeTexturesEXT (GLsizei, const GLuint *, const GLclampf *); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLboolean (APIENTRYP PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences); typedef void (APIENTRYP PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); typedef void (APIENTRYP PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures); typedef void (APIENTRYP PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures); typedef GLboolean (APIENTRYP PFNGLISTEXTUREEXTPROC) (GLuint texture); typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities); #endif #ifndef GL_SGIS_detail_texture #define GL_SGIS_detail_texture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDetailTexFuncSGIS (GLenum, GLsizei, const GLfloat *); GLAPI void APIENTRY glGetDetailTexFuncSGIS (GLenum, GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); typedef void (APIENTRYP PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points); #endif #ifndef GL_SGIS_sharpen_texture #define GL_SGIS_sharpen_texture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glSharpenTexFuncSGIS (GLenum, GLsizei, const GLfloat *); GLAPI void APIENTRY glGetSharpenTexFuncSGIS (GLenum, GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); typedef void (APIENTRYP PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points); #endif #ifndef GL_EXT_packed_pixels #define GL_EXT_packed_pixels 1 #endif #ifndef GL_SGIS_texture_lod #define GL_SGIS_texture_lod 1 #endif #ifndef GL_SGIS_multisample #define GL_SGIS_multisample 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glSampleMaskSGIS (GLclampf, GLboolean); GLAPI void APIENTRY glSamplePatternSGIS (GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); typedef void (APIENTRYP PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); #endif #ifndef GL_EXT_rescale_normal #define GL_EXT_rescale_normal 1 #endif #ifndef GL_EXT_vertex_array #define GL_EXT_vertex_array 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glArrayElementEXT (GLint); GLAPI void APIENTRY glColorPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); GLAPI void APIENTRY glDrawArraysEXT (GLenum, GLint, GLsizei); GLAPI void APIENTRY glEdgeFlagPointerEXT (GLsizei, GLsizei, const GLboolean *); GLAPI void APIENTRY glGetPointervEXT (GLenum, GLvoid* *); GLAPI void APIENTRY glIndexPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *); GLAPI void APIENTRY glNormalPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *); GLAPI void APIENTRY glTexCoordPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); GLAPI void APIENTRY glVertexPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLARRAYELEMENTEXTPROC) (GLint i); typedef void (APIENTRYP PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); typedef void (APIENTRYP PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); typedef void (APIENTRYP PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer); typedef void (APIENTRYP PFNGLGETPOINTERVEXTPROC) (GLenum pname, GLvoid* *params); typedef void (APIENTRYP PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); typedef void (APIENTRYP PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); typedef void (APIENTRYP PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); typedef void (APIENTRYP PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); #endif #ifndef GL_EXT_misc_attribute #define GL_EXT_misc_attribute 1 #endif #ifndef GL_SGIS_generate_mipmap #define GL_SGIS_generate_mipmap 1 #endif #ifndef GL_SGIX_clipmap #define GL_SGIX_clipmap 1 #endif #ifndef GL_SGIX_shadow #define GL_SGIX_shadow 1 #endif #ifndef GL_SGIS_texture_edge_clamp #define GL_SGIS_texture_edge_clamp 1 #endif #ifndef GL_SGIS_texture_border_clamp #define GL_SGIS_texture_border_clamp 1 #endif #ifndef GL_EXT_blend_minmax #define GL_EXT_blend_minmax 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendEquationEXT (GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); #endif #ifndef GL_EXT_blend_subtract #define GL_EXT_blend_subtract 1 #endif #ifndef GL_EXT_blend_logic_op #define GL_EXT_blend_logic_op 1 #endif #ifndef GL_SGIX_interlace #define GL_SGIX_interlace 1 #endif #ifndef GL_SGIX_pixel_tiles #define GL_SGIX_pixel_tiles 1 #endif #ifndef GL_SGIX_texture_select #define GL_SGIX_texture_select 1 #endif #ifndef GL_SGIX_sprite #define GL_SGIX_sprite 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glSpriteParameterfSGIX (GLenum, GLfloat); GLAPI void APIENTRY glSpriteParameterfvSGIX (GLenum, const GLfloat *); GLAPI void APIENTRY glSpriteParameteriSGIX (GLenum, GLint); GLAPI void APIENTRY glSpriteParameterivSGIX (GLenum, const GLint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params); #endif #ifndef GL_SGIX_texture_multi_buffer #define GL_SGIX_texture_multi_buffer 1 #endif #ifndef GL_EXT_point_parameters #define GL_EXT_point_parameters 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPointParameterfEXT (GLenum, GLfloat); GLAPI void APIENTRY glPointParameterfvEXT (GLenum, const GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params); #endif #ifndef GL_SGIS_point_parameters #define GL_SGIS_point_parameters 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPointParameterfSGIS (GLenum, GLfloat); GLAPI void APIENTRY glPointParameterfvSGIS (GLenum, const GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); #endif #ifndef GL_SGIX_instruments #define GL_SGIX_instruments 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLint APIENTRY glGetInstrumentsSGIX (void); GLAPI void APIENTRY glInstrumentsBufferSGIX (GLsizei, GLint *); GLAPI GLint APIENTRY glPollInstrumentsSGIX (GLint *); GLAPI void APIENTRY glReadInstrumentsSGIX (GLint); GLAPI void APIENTRY glStartInstrumentsSGIX (void); GLAPI void APIENTRY glStopInstrumentsSGIX (GLint); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLint (APIENTRYP PFNGLGETINSTRUMENTSSGIXPROC) (void); typedef void (APIENTRYP PFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer); typedef GLint (APIENTRYP PFNGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p); typedef void (APIENTRYP PFNGLREADINSTRUMENTSSGIXPROC) (GLint marker); typedef void (APIENTRYP PFNGLSTARTINSTRUMENTSSGIXPROC) (void); typedef void (APIENTRYP PFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker); #endif #ifndef GL_SGIX_texture_scale_bias #define GL_SGIX_texture_scale_bias 1 #endif #ifndef GL_SGIX_framezoom #define GL_SGIX_framezoom 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFrameZoomSGIX (GLint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFRAMEZOOMSGIXPROC) (GLint factor); #endif #ifndef GL_SGIX_tag_sample_buffer #define GL_SGIX_tag_sample_buffer 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTagSampleBufferSGIX (void); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); #endif #ifndef GL_SGIX_polynomial_ffd #define GL_SGIX_polynomial_ffd 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDeformationMap3dSGIX (GLenum, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, const GLdouble *); GLAPI void APIENTRY glDeformationMap3fSGIX (GLenum, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, const GLfloat *); GLAPI void APIENTRY glDeformSGIX (GLbitfield); GLAPI void APIENTRY glLoadIdentityDeformationMapSGIX (GLbitfield); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); typedef void (APIENTRYP PFNGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); typedef void (APIENTRYP PFNGLDEFORMSGIXPROC) (GLbitfield mask); typedef void (APIENTRYP PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask); #endif #ifndef GL_SGIX_reference_plane #define GL_SGIX_reference_plane 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glReferencePlaneSGIX (const GLdouble *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation); #endif #ifndef GL_SGIX_flush_raster #define GL_SGIX_flush_raster 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFlushRasterSGIX (void); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFLUSHRASTERSGIXPROC) (void); #endif #ifndef GL_SGIX_depth_texture #define GL_SGIX_depth_texture 1 #endif #ifndef GL_SGIS_fog_function #define GL_SGIS_fog_function 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFogFuncSGIS (GLsizei, const GLfloat *); GLAPI void APIENTRY glGetFogFuncSGIS (GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points); typedef void (APIENTRYP PFNGLGETFOGFUNCSGISPROC) (GLfloat *points); #endif #ifndef GL_SGIX_fog_offset #define GL_SGIX_fog_offset 1 #endif #ifndef GL_HP_image_transform #define GL_HP_image_transform 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glImageTransformParameteriHP (GLenum, GLenum, GLint); GLAPI void APIENTRY glImageTransformParameterfHP (GLenum, GLenum, GLfloat); GLAPI void APIENTRY glImageTransformParameterivHP (GLenum, GLenum, const GLint *); GLAPI void APIENTRY glImageTransformParameterfvHP (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY glGetImageTransformParameterivHP (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetImageTransformParameterfvHP (GLenum, GLenum, GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params); #endif #ifndef GL_HP_convolution_border_modes #define GL_HP_convolution_border_modes 1 #endif #ifndef GL_SGIX_texture_add_env #define GL_SGIX_texture_add_env 1 #endif #ifndef GL_EXT_color_subtable #define GL_EXT_color_subtable 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glColorSubTableEXT (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glCopyColorSubTableEXT (GLenum, GLsizei, GLint, GLint, GLsizei); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); #endif #ifndef GL_PGI_vertex_hints #define GL_PGI_vertex_hints 1 #endif #ifndef GL_PGI_misc_hints #define GL_PGI_misc_hints 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glHintPGI (GLenum, GLint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLHINTPGIPROC) (GLenum target, GLint mode); #endif #ifndef GL_EXT_paletted_texture #define GL_EXT_paletted_texture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glColorTableEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glGetColorTableEXT (GLenum, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY glGetColorTableParameterivEXT (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetColorTableParameterfvEXT (GLenum, GLenum, GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); typedef void (APIENTRYP PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *data); typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); #endif #ifndef GL_EXT_clip_volume_hint #define GL_EXT_clip_volume_hint 1 #endif #ifndef GL_SGIX_list_priority #define GL_SGIX_list_priority 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetListParameterfvSGIX (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY glGetListParameterivSGIX (GLuint, GLenum, GLint *); GLAPI void APIENTRY glListParameterfSGIX (GLuint, GLenum, GLfloat); GLAPI void APIENTRY glListParameterfvSGIX (GLuint, GLenum, const GLfloat *); GLAPI void APIENTRY glListParameteriSGIX (GLuint, GLenum, GLint); GLAPI void APIENTRY glListParameterivSGIX (GLuint, GLenum, const GLint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params); #endif #ifndef GL_SGIX_ir_instrument1 #define GL_SGIX_ir_instrument1 1 #endif #ifndef GL_SGIX_calligraphic_fragment #define GL_SGIX_calligraphic_fragment 1 #endif #ifndef GL_SGIX_texture_lod_bias #define GL_SGIX_texture_lod_bias 1 #endif #ifndef GL_SGIX_shadow_ambient #define GL_SGIX_shadow_ambient 1 #endif #ifndef GL_EXT_index_texture #define GL_EXT_index_texture 1 #endif #ifndef GL_EXT_index_material #define GL_EXT_index_material 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glIndexMaterialEXT (GLenum, GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); #endif #ifndef GL_EXT_index_func #define GL_EXT_index_func 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glIndexFuncEXT (GLenum, GLclampf); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref); #endif #ifndef GL_EXT_index_array_formats #define GL_EXT_index_array_formats 1 #endif #ifndef GL_EXT_compiled_vertex_array #define GL_EXT_compiled_vertex_array 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glLockArraysEXT (GLint, GLsizei); GLAPI void APIENTRY glUnlockArraysEXT (void); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); typedef void (APIENTRYP PFNGLUNLOCKARRAYSEXTPROC) (void); #endif #ifndef GL_EXT_cull_vertex #define GL_EXT_cull_vertex 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glCullParameterdvEXT (GLenum, GLdouble *); GLAPI void APIENTRY glCullParameterfvEXT (GLenum, GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params); typedef void (APIENTRYP PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params); #endif #ifndef GL_SGIX_ycrcb #define GL_SGIX_ycrcb 1 #endif #ifndef GL_SGIX_fragment_lighting #define GL_SGIX_fragment_lighting 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFragmentColorMaterialSGIX (GLenum, GLenum); GLAPI void APIENTRY glFragmentLightfSGIX (GLenum, GLenum, GLfloat); GLAPI void APIENTRY glFragmentLightfvSGIX (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY glFragmentLightiSGIX (GLenum, GLenum, GLint); GLAPI void APIENTRY glFragmentLightivSGIX (GLenum, GLenum, const GLint *); GLAPI void APIENTRY glFragmentLightModelfSGIX (GLenum, GLfloat); GLAPI void APIENTRY glFragmentLightModelfvSGIX (GLenum, const GLfloat *); GLAPI void APIENTRY glFragmentLightModeliSGIX (GLenum, GLint); GLAPI void APIENTRY glFragmentLightModelivSGIX (GLenum, const GLint *); GLAPI void APIENTRY glFragmentMaterialfSGIX (GLenum, GLenum, GLfloat); GLAPI void APIENTRY glFragmentMaterialfvSGIX (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY glFragmentMaterialiSGIX (GLenum, GLenum, GLint); GLAPI void APIENTRY glFragmentMaterialivSGIX (GLenum, GLenum, const GLint *); GLAPI void APIENTRY glGetFragmentLightfvSGIX (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetFragmentLightivSGIX (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetFragmentMaterialfvSGIX (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetFragmentMaterialivSGIX (GLenum, GLenum, GLint *); GLAPI void APIENTRY glLightEnviSGIX (GLenum, GLint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param); #endif #ifndef GL_IBM_rasterpos_clip #define GL_IBM_rasterpos_clip 1 #endif #ifndef GL_HP_texture_lighting #define GL_HP_texture_lighting 1 #endif #ifndef GL_EXT_draw_range_elements #define GL_EXT_draw_range_elements 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawRangeElementsEXT (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); #endif #ifndef GL_WIN_phong_shading #define GL_WIN_phong_shading 1 #endif #ifndef GL_WIN_specular_fog #define GL_WIN_specular_fog 1 #endif #ifndef GL_EXT_light_texture #define GL_EXT_light_texture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glApplyTextureEXT (GLenum); GLAPI void APIENTRY glTextureLightEXT (GLenum); GLAPI void APIENTRY glTextureMaterialEXT (GLenum, GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); typedef void (APIENTRYP PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); typedef void (APIENTRYP PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); #endif #ifndef GL_SGIX_blend_alpha_minmax #define GL_SGIX_blend_alpha_minmax 1 #endif #ifndef GL_EXT_bgra #define GL_EXT_bgra 1 #endif #ifndef GL_SGIX_async #define GL_SGIX_async 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glAsyncMarkerSGIX (GLuint); GLAPI GLint APIENTRY glFinishAsyncSGIX (GLuint *); GLAPI GLint APIENTRY glPollAsyncSGIX (GLuint *); GLAPI GLuint APIENTRY glGenAsyncMarkersSGIX (GLsizei); GLAPI void APIENTRY glDeleteAsyncMarkersSGIX (GLuint, GLsizei); GLAPI GLboolean APIENTRY glIsAsyncMarkerSGIX (GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLASYNCMARKERSGIXPROC) (GLuint marker); typedef GLint (APIENTRYP PFNGLFINISHASYNCSGIXPROC) (GLuint *markerp); typedef GLint (APIENTRYP PFNGLPOLLASYNCSGIXPROC) (GLuint *markerp); typedef GLuint (APIENTRYP PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); typedef void (APIENTRYP PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); typedef GLboolean (APIENTRYP PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); #endif #ifndef GL_SGIX_async_pixel #define GL_SGIX_async_pixel 1 #endif #ifndef GL_SGIX_async_histogram #define GL_SGIX_async_histogram 1 #endif #ifndef GL_INTEL_parallel_arrays #define GL_INTEL_parallel_arrays 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexPointervINTEL (GLint, GLenum, const GLvoid* *); GLAPI void APIENTRY glNormalPointervINTEL (GLenum, const GLvoid* *); GLAPI void APIENTRY glColorPointervINTEL (GLint, GLenum, const GLvoid* *); GLAPI void APIENTRY glTexCoordPointervINTEL (GLint, GLenum, const GLvoid* *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); typedef void (APIENTRYP PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const GLvoid* *pointer); typedef void (APIENTRYP PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); typedef void (APIENTRYP PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); #endif #ifndef GL_HP_occlusion_test #define GL_HP_occlusion_test 1 #endif #ifndef GL_EXT_pixel_transform #define GL_EXT_pixel_transform 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPixelTransformParameteriEXT (GLenum, GLenum, GLint); GLAPI void APIENTRY glPixelTransformParameterfEXT (GLenum, GLenum, GLfloat); GLAPI void APIENTRY glPixelTransformParameterivEXT (GLenum, GLenum, const GLint *); GLAPI void APIENTRY glPixelTransformParameterfvEXT (GLenum, GLenum, const GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); #endif #ifndef GL_EXT_pixel_transform_color_table #define GL_EXT_pixel_transform_color_table 1 #endif #ifndef GL_EXT_shared_texture_palette #define GL_EXT_shared_texture_palette 1 #endif #ifndef GL_EXT_separate_specular_color #define GL_EXT_separate_specular_color 1 #endif #ifndef GL_EXT_secondary_color #define GL_EXT_secondary_color 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glSecondaryColor3bEXT (GLbyte, GLbyte, GLbyte); GLAPI void APIENTRY glSecondaryColor3bvEXT (const GLbyte *); GLAPI void APIENTRY glSecondaryColor3dEXT (GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glSecondaryColor3dvEXT (const GLdouble *); GLAPI void APIENTRY glSecondaryColor3fEXT (GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glSecondaryColor3fvEXT (const GLfloat *); GLAPI void APIENTRY glSecondaryColor3iEXT (GLint, GLint, GLint); GLAPI void APIENTRY glSecondaryColor3ivEXT (const GLint *); GLAPI void APIENTRY glSecondaryColor3sEXT (GLshort, GLshort, GLshort); GLAPI void APIENTRY glSecondaryColor3svEXT (const GLshort *); GLAPI void APIENTRY glSecondaryColor3ubEXT (GLubyte, GLubyte, GLubyte); GLAPI void APIENTRY glSecondaryColor3ubvEXT (const GLubyte *); GLAPI void APIENTRY glSecondaryColor3uiEXT (GLuint, GLuint, GLuint); GLAPI void APIENTRY glSecondaryColor3uivEXT (const GLuint *); GLAPI void APIENTRY glSecondaryColor3usEXT (GLushort, GLushort, GLushort); GLAPI void APIENTRY glSecondaryColor3usvEXT (const GLushort *); GLAPI void APIENTRY glSecondaryColorPointerEXT (GLint, GLenum, GLsizei, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); #endif #ifndef GL_EXT_texture_perturb_normal #define GL_EXT_texture_perturb_normal 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTextureNormalEXT (GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXTURENORMALEXTPROC) (GLenum mode); #endif #ifndef GL_EXT_multi_draw_arrays #define GL_EXT_multi_draw_arrays 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glMultiDrawArraysEXT (GLenum, GLint *, GLsizei *, GLsizei); GLAPI void APIENTRY glMultiDrawElementsEXT (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); #endif #ifndef GL_EXT_fog_coord #define GL_EXT_fog_coord 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFogCoordfEXT (GLfloat); GLAPI void APIENTRY glFogCoordfvEXT (const GLfloat *); GLAPI void APIENTRY glFogCoorddEXT (GLdouble); GLAPI void APIENTRY glFogCoorddvEXT (const GLdouble *); GLAPI void APIENTRY glFogCoordPointerEXT (GLenum, GLsizei, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFOGCOORDFEXTPROC) (GLfloat coord); typedef void (APIENTRYP PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); typedef void (APIENTRYP PFNGLFOGCOORDDEXTPROC) (GLdouble coord); typedef void (APIENTRYP PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); typedef void (APIENTRYP PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); #endif #ifndef GL_REND_screen_coordinates #define GL_REND_screen_coordinates 1 #endif #ifndef GL_EXT_coordinate_frame #define GL_EXT_coordinate_frame 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTangent3bEXT (GLbyte, GLbyte, GLbyte); GLAPI void APIENTRY glTangent3bvEXT (const GLbyte *); GLAPI void APIENTRY glTangent3dEXT (GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glTangent3dvEXT (const GLdouble *); GLAPI void APIENTRY glTangent3fEXT (GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glTangent3fvEXT (const GLfloat *); GLAPI void APIENTRY glTangent3iEXT (GLint, GLint, GLint); GLAPI void APIENTRY glTangent3ivEXT (const GLint *); GLAPI void APIENTRY glTangent3sEXT (GLshort, GLshort, GLshort); GLAPI void APIENTRY glTangent3svEXT (const GLshort *); GLAPI void APIENTRY glBinormal3bEXT (GLbyte, GLbyte, GLbyte); GLAPI void APIENTRY glBinormal3bvEXT (const GLbyte *); GLAPI void APIENTRY glBinormal3dEXT (GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glBinormal3dvEXT (const GLdouble *); GLAPI void APIENTRY glBinormal3fEXT (GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glBinormal3fvEXT (const GLfloat *); GLAPI void APIENTRY glBinormal3iEXT (GLint, GLint, GLint); GLAPI void APIENTRY glBinormal3ivEXT (const GLint *); GLAPI void APIENTRY glBinormal3sEXT (GLshort, GLshort, GLshort); GLAPI void APIENTRY glBinormal3svEXT (const GLshort *); GLAPI void APIENTRY glTangentPointerEXT (GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glBinormalPointerEXT (GLenum, GLsizei, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz); typedef void (APIENTRYP PFNGLTANGENT3BVEXTPROC) (const GLbyte *v); typedef void (APIENTRYP PFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz); typedef void (APIENTRYP PFNGLTANGENT3DVEXTPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz); typedef void (APIENTRYP PFNGLTANGENT3FVEXTPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz); typedef void (APIENTRYP PFNGLTANGENT3IVEXTPROC) (const GLint *v); typedef void (APIENTRYP PFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz); typedef void (APIENTRYP PFNGLTANGENT3SVEXTPROC) (const GLshort *v); typedef void (APIENTRYP PFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz); typedef void (APIENTRYP PFNGLBINORMAL3BVEXTPROC) (const GLbyte *v); typedef void (APIENTRYP PFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz); typedef void (APIENTRYP PFNGLBINORMAL3DVEXTPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz); typedef void (APIENTRYP PFNGLBINORMAL3FVEXTPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz); typedef void (APIENTRYP PFNGLBINORMAL3IVEXTPROC) (const GLint *v); typedef void (APIENTRYP PFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz); typedef void (APIENTRYP PFNGLBINORMAL3SVEXTPROC) (const GLshort *v); typedef void (APIENTRYP PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); #endif #ifndef GL_EXT_texture_env_combine #define GL_EXT_texture_env_combine 1 #endif #ifndef GL_APPLE_specular_vector #define GL_APPLE_specular_vector 1 #endif #ifndef GL_APPLE_transform_hint #define GL_APPLE_transform_hint 1 #endif #ifndef GL_SGIX_fog_scale #define GL_SGIX_fog_scale 1 #endif #ifndef GL_SUNX_constant_data #define GL_SUNX_constant_data 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFinishTextureSUNX (void); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFINISHTEXTURESUNXPROC) (void); #endif #ifndef GL_SUN_global_alpha #define GL_SUN_global_alpha 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGlobalAlphaFactorbSUN (GLbyte); GLAPI void APIENTRY glGlobalAlphaFactorsSUN (GLshort); GLAPI void APIENTRY glGlobalAlphaFactoriSUN (GLint); GLAPI void APIENTRY glGlobalAlphaFactorfSUN (GLfloat); GLAPI void APIENTRY glGlobalAlphaFactordSUN (GLdouble); GLAPI void APIENTRY glGlobalAlphaFactorubSUN (GLubyte); GLAPI void APIENTRY glGlobalAlphaFactorusSUN (GLushort); GLAPI void APIENTRY glGlobalAlphaFactoruiSUN (GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); #endif #ifndef GL_SUN_triangle_list #define GL_SUN_triangle_list 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glReplacementCodeuiSUN (GLuint); GLAPI void APIENTRY glReplacementCodeusSUN (GLushort); GLAPI void APIENTRY glReplacementCodeubSUN (GLubyte); GLAPI void APIENTRY glReplacementCodeuivSUN (const GLuint *); GLAPI void APIENTRY glReplacementCodeusvSUN (const GLushort *); GLAPI void APIENTRY glReplacementCodeubvSUN (const GLubyte *); GLAPI void APIENTRY glReplacementCodePointerSUN (GLenum, GLsizei, const GLvoid* *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code); typedef void (APIENTRYP PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const GLvoid* *pointer); #endif #ifndef GL_SUN_vertex #define GL_SUN_vertex 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glColor4ubVertex2fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat); GLAPI void APIENTRY glColor4ubVertex2fvSUN (const GLubyte *, const GLfloat *); GLAPI void APIENTRY glColor4ubVertex3fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glColor4ubVertex3fvSUN (const GLubyte *, const GLfloat *); GLAPI void APIENTRY glColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glColor3fVertex3fvSUN (const GLfloat *, const GLfloat *); GLAPI void APIENTRY glNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *); GLAPI void APIENTRY glColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY glTexCoord2fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glTexCoord2fVertex3fvSUN (const GLfloat *, const GLfloat *); GLAPI void APIENTRY glTexCoord4fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glTexCoord4fVertex4fvSUN (const GLfloat *, const GLfloat *); GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fSUN (GLfloat, GLfloat, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fvSUN (const GLfloat *, const GLubyte *, const GLfloat *); GLAPI void APIENTRY glTexCoord2fColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glTexCoord2fColor3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY glReplacementCodeuiVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glReplacementCodeuiVertex3fvSUN (const GLuint *, const GLfloat *); GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fSUN (GLuint, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fvSUN (const GLuint *, const GLubyte *, const GLfloat *); GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v); typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v); typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v); typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v); typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v); typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v); typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v); typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *v); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint *rc, const GLubyte *c, const GLfloat *v); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *v); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *v); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); #endif #ifndef GL_EXT_blend_func_separate #define GL_EXT_blend_func_separate 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendFuncSeparateEXT (GLenum, GLenum, GLenum, GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); #endif #ifndef GL_INGR_blend_func_separate #define GL_INGR_blend_func_separate 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendFuncSeparateINGR (GLenum, GLenum, GLenum, GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINGRPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); #endif #ifndef GL_INGR_color_clamp #define GL_INGR_color_clamp 1 #endif #ifndef GL_INGR_interlace_read #define GL_INGR_interlace_read 1 #endif #ifndef GL_EXT_stencil_wrap #define GL_EXT_stencil_wrap 1 #endif #ifndef GL_EXT_422_pixels #define GL_EXT_422_pixels 1 #endif #ifndef GL_NV_texgen_reflection #define GL_NV_texgen_reflection 1 #endif #ifndef GL_SUN_convolution_border_modes #define GL_SUN_convolution_border_modes 1 #endif #ifndef GL_EXT_texture_env_add #define GL_EXT_texture_env_add 1 #endif #ifndef GL_EXT_texture_lod_bias #define GL_EXT_texture_lod_bias 1 #endif #ifndef GL_EXT_texture_filter_anisotropic #define GL_EXT_texture_filter_anisotropic 1 #endif #ifndef GL_EXT_vertex_weighting #define GL_EXT_vertex_weighting 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexWeightfEXT (GLfloat); GLAPI void APIENTRY glVertexWeightfvEXT (const GLfloat *); GLAPI void APIENTRY glVertexWeightPointerEXT (GLsizei, GLenum, GLsizei, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); typedef void (APIENTRYP PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight); typedef void (APIENTRYP PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer); #endif #ifndef GL_NV_light_max_exponent #define GL_NV_light_max_exponent 1 #endif #ifndef GL_NV_vertex_array_range #define GL_NV_vertex_array_range 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFlushVertexArrayRangeNV (void); GLAPI void APIENTRY glVertexArrayRangeNV (GLsizei, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); typedef void (APIENTRYP PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, const GLvoid *pointer); #endif #ifndef GL_NV_register_combiners #define GL_NV_register_combiners 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glCombinerParameterfvNV (GLenum, const GLfloat *); GLAPI void APIENTRY glCombinerParameterfNV (GLenum, GLfloat); GLAPI void APIENTRY glCombinerParameterivNV (GLenum, const GLint *); GLAPI void APIENTRY glCombinerParameteriNV (GLenum, GLint); GLAPI void APIENTRY glCombinerInputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum); GLAPI void APIENTRY glCombinerOutputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLboolean, GLboolean, GLboolean); GLAPI void APIENTRY glFinalCombinerInputNV (GLenum, GLenum, GLenum, GLenum); GLAPI void APIENTRY glGetCombinerInputParameterfvNV (GLenum, GLenum, GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetCombinerInputParameterivNV (GLenum, GLenum, GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetCombinerOutputParameterfvNV (GLenum, GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetCombinerOutputParameterivNV (GLenum, GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetFinalCombinerInputParameterfvNV (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetFinalCombinerInputParameterivNV (GLenum, GLenum, GLint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); typedef void (APIENTRYP PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); typedef void (APIENTRYP PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params); #endif #ifndef GL_NV_fog_distance #define GL_NV_fog_distance 1 #endif #ifndef GL_NV_texgen_emboss #define GL_NV_texgen_emboss 1 #endif #ifndef GL_NV_blend_square #define GL_NV_blend_square 1 #endif #ifndef GL_NV_texture_env_combine4 #define GL_NV_texture_env_combine4 1 #endif #ifndef GL_MESA_resize_buffers #define GL_MESA_resize_buffers 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glResizeBuffersMESA (void); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLRESIZEBUFFERSMESAPROC) (void); #endif #ifndef GL_MESA_window_pos #define GL_MESA_window_pos 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glWindowPos2dMESA (GLdouble, GLdouble); GLAPI void APIENTRY glWindowPos2dvMESA (const GLdouble *); GLAPI void APIENTRY glWindowPos2fMESA (GLfloat, GLfloat); GLAPI void APIENTRY glWindowPos2fvMESA (const GLfloat *); GLAPI void APIENTRY glWindowPos2iMESA (GLint, GLint); GLAPI void APIENTRY glWindowPos2ivMESA (const GLint *); GLAPI void APIENTRY glWindowPos2sMESA (GLshort, GLshort); GLAPI void APIENTRY glWindowPos2svMESA (const GLshort *); GLAPI void APIENTRY glWindowPos3dMESA (GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glWindowPos3dvMESA (const GLdouble *); GLAPI void APIENTRY glWindowPos3fMESA (GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glWindowPos3fvMESA (const GLfloat *); GLAPI void APIENTRY glWindowPos3iMESA (GLint, GLint, GLint); GLAPI void APIENTRY glWindowPos3ivMESA (const GLint *); GLAPI void APIENTRY glWindowPos3sMESA (GLshort, GLshort, GLshort); GLAPI void APIENTRY glWindowPos3svMESA (const GLshort *); GLAPI void APIENTRY glWindowPos4dMESA (GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glWindowPos4dvMESA (const GLdouble *); GLAPI void APIENTRY glWindowPos4fMESA (GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glWindowPos4fvMESA (const GLfloat *); GLAPI void APIENTRY glWindowPos4iMESA (GLint, GLint, GLint, GLint); GLAPI void APIENTRY glWindowPos4ivMESA (const GLint *); GLAPI void APIENTRY glWindowPos4sMESA (GLshort, GLshort, GLshort, GLshort); GLAPI void APIENTRY glWindowPos4svMESA (const GLshort *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); typedef void (APIENTRYP PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); typedef void (APIENTRYP PFNGLWINDOWPOS2IVMESAPROC) (const GLint *v); typedef void (APIENTRYP PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); typedef void (APIENTRYP PFNGLWINDOWPOS2SVMESAPROC) (const GLshort *v); typedef void (APIENTRYP PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); typedef void (APIENTRYP PFNGLWINDOWPOS3IVMESAPROC) (const GLint *v); typedef void (APIENTRYP PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNGLWINDOWPOS3SVMESAPROC) (const GLshort *v); typedef void (APIENTRYP PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); typedef void (APIENTRYP PFNGLWINDOWPOS4IVMESAPROC) (const GLint *v); typedef void (APIENTRYP PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); typedef void (APIENTRYP PFNGLWINDOWPOS4SVMESAPROC) (const GLshort *v); #endif #ifndef GL_IBM_cull_vertex #define GL_IBM_cull_vertex 1 #endif #ifndef GL_IBM_multimode_draw_arrays #define GL_IBM_multimode_draw_arrays 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glMultiModeDrawArraysIBM (const GLenum *, const GLint *, const GLsizei *, GLsizei, GLint); GLAPI void APIENTRY glMultiModeDrawElementsIBM (const GLenum *, const GLsizei *, GLenum, const GLvoid* const *, GLsizei, GLint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); typedef void (APIENTRYP PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei primcount, GLint modestride); #endif #ifndef GL_IBM_vertex_array_lists #define GL_IBM_vertex_array_lists 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); GLAPI void APIENTRY glSecondaryColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); GLAPI void APIENTRY glEdgeFlagPointerListIBM (GLint, const GLboolean* *, GLint); GLAPI void APIENTRY glFogCoordPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); GLAPI void APIENTRY glIndexPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); GLAPI void APIENTRY glNormalPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); GLAPI void APIENTRY glTexCoordPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); GLAPI void APIENTRY glVertexPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); #endif #ifndef GL_SGIX_subsample #define GL_SGIX_subsample 1 #endif #ifndef GL_SGIX_ycrcba #define GL_SGIX_ycrcba 1 #endif #ifndef GL_SGIX_ycrcb_subsample #define GL_SGIX_ycrcb_subsample 1 #endif #ifndef GL_SGIX_depth_pass_instrument #define GL_SGIX_depth_pass_instrument 1 #endif #ifndef GL_3DFX_texture_compression_FXT1 #define GL_3DFX_texture_compression_FXT1 1 #endif #ifndef GL_3DFX_multisample #define GL_3DFX_multisample 1 #endif #ifndef GL_3DFX_tbuffer #define GL_3DFX_tbuffer 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTbufferMask3DFX (GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); #endif #ifndef GL_EXT_multisample #define GL_EXT_multisample 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glSampleMaskEXT (GLclampf, GLboolean); GLAPI void APIENTRY glSamplePatternEXT (GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); typedef void (APIENTRYP PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); #endif #ifndef GL_SGIX_vertex_preclip #define GL_SGIX_vertex_preclip 1 #endif #ifndef GL_SGIX_convolution_accuracy #define GL_SGIX_convolution_accuracy 1 #endif #ifndef GL_SGIX_resample #define GL_SGIX_resample 1 #endif #ifndef GL_SGIS_point_line_texgen #define GL_SGIS_point_line_texgen 1 #endif #ifndef GL_SGIS_texture_color_mask #define GL_SGIS_texture_color_mask 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTextureColorMaskSGIS (GLboolean, GLboolean, GLboolean, GLboolean); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); #endif #ifndef GL_SGIX_igloo_interface #define GL_SGIX_igloo_interface 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glIglooInterfaceSGIX (GLenum, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, const GLvoid *params); #endif #ifndef GL_EXT_texture_env_dot3 #define GL_EXT_texture_env_dot3 1 #endif #ifndef GL_ATI_texture_mirror_once #define GL_ATI_texture_mirror_once 1 #endif #ifndef GL_NV_fence #define GL_NV_fence 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDeleteFencesNV (GLsizei, const GLuint *); GLAPI void APIENTRY glGenFencesNV (GLsizei, GLuint *); GLAPI GLboolean APIENTRY glIsFenceNV (GLuint); GLAPI GLboolean APIENTRY glTestFenceNV (GLuint); GLAPI void APIENTRY glGetFenceivNV (GLuint, GLenum, GLint *); GLAPI void APIENTRY glFinishFenceNV (GLuint); GLAPI void APIENTRY glSetFenceNV (GLuint, GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); typedef void (APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); typedef GLboolean (APIENTRYP PFNGLISFENCENVPROC) (GLuint fence); typedef GLboolean (APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence); typedef void (APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); typedef void (APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); #endif #ifndef GL_NV_evaluators #define GL_NV_evaluators 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glMapControlPointsNV (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLint, GLint, GLboolean, const GLvoid *); GLAPI void APIENTRY glMapParameterivNV (GLenum, GLenum, const GLint *); GLAPI void APIENTRY glMapParameterfvNV (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY glGetMapControlPointsNV (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLboolean, GLvoid *); GLAPI void APIENTRY glGetMapParameterivNV (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetMapParameterfvNV (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetMapAttribParameterivNV (GLenum, GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetMapAttribParameterfvNV (GLenum, GLuint, GLenum, GLfloat *); GLAPI void APIENTRY glEvalMapsNV (GLenum, GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points); typedef void (APIENTRYP PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points); typedef void (APIENTRYP PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); #endif #ifndef GL_NV_packed_depth_stencil #define GL_NV_packed_depth_stencil 1 #endif #ifndef GL_NV_register_combiners2 #define GL_NV_register_combiners2 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glCombinerStageParameterfvNV (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum, GLenum, GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat *params); #endif #ifndef GL_NV_texture_compression_vtc #define GL_NV_texture_compression_vtc 1 #endif #ifndef GL_NV_texture_rectangle #define GL_NV_texture_rectangle 1 #endif #ifndef GL_NV_texture_shader #define GL_NV_texture_shader 1 #endif #ifndef GL_NV_texture_shader2 #define GL_NV_texture_shader2 1 #endif #ifndef GL_NV_vertex_array_range2 #define GL_NV_vertex_array_range2 1 #endif #ifndef GL_NV_vertex_program #define GL_NV_vertex_program 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLboolean APIENTRY glAreProgramsResidentNV (GLsizei, const GLuint *, GLboolean *); GLAPI void APIENTRY glBindProgramNV (GLenum, GLuint); GLAPI void APIENTRY glDeleteProgramsNV (GLsizei, const GLuint *); GLAPI void APIENTRY glExecuteProgramNV (GLenum, GLuint, const GLfloat *); GLAPI void APIENTRY glGenProgramsNV (GLsizei, GLuint *); GLAPI void APIENTRY glGetProgramParameterdvNV (GLenum, GLuint, GLenum, GLdouble *); GLAPI void APIENTRY glGetProgramParameterfvNV (GLenum, GLuint, GLenum, GLfloat *); GLAPI void APIENTRY glGetProgramivNV (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetProgramStringNV (GLuint, GLenum, GLubyte *); GLAPI void APIENTRY glGetTrackMatrixivNV (GLenum, GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetVertexAttribdvNV (GLuint, GLenum, GLdouble *); GLAPI void APIENTRY glGetVertexAttribfvNV (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY glGetVertexAttribivNV (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetVertexAttribPointervNV (GLuint, GLenum, GLvoid* *); GLAPI GLboolean APIENTRY glIsProgramNV (GLuint); GLAPI void APIENTRY glLoadProgramNV (GLenum, GLuint, GLsizei, const GLubyte *); GLAPI void APIENTRY glProgramParameter4dNV (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glProgramParameter4dvNV (GLenum, GLuint, const GLdouble *); GLAPI void APIENTRY glProgramParameter4fNV (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glProgramParameter4fvNV (GLenum, GLuint, const GLfloat *); GLAPI void APIENTRY glProgramParameters4dvNV (GLenum, GLuint, GLuint, const GLdouble *); GLAPI void APIENTRY glProgramParameters4fvNV (GLenum, GLuint, GLuint, const GLfloat *); GLAPI void APIENTRY glRequestResidentProgramsNV (GLsizei, const GLuint *); GLAPI void APIENTRY glTrackMatrixNV (GLenum, GLuint, GLenum, GLenum); GLAPI void APIENTRY glVertexAttribPointerNV (GLuint, GLint, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glVertexAttrib1dNV (GLuint, GLdouble); GLAPI void APIENTRY glVertexAttrib1dvNV (GLuint, const GLdouble *); GLAPI void APIENTRY glVertexAttrib1fNV (GLuint, GLfloat); GLAPI void APIENTRY glVertexAttrib1fvNV (GLuint, const GLfloat *); GLAPI void APIENTRY glVertexAttrib1sNV (GLuint, GLshort); GLAPI void APIENTRY glVertexAttrib1svNV (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttrib2dNV (GLuint, GLdouble, GLdouble); GLAPI void APIENTRY glVertexAttrib2dvNV (GLuint, const GLdouble *); GLAPI void APIENTRY glVertexAttrib2fNV (GLuint, GLfloat, GLfloat); GLAPI void APIENTRY glVertexAttrib2fvNV (GLuint, const GLfloat *); GLAPI void APIENTRY glVertexAttrib2sNV (GLuint, GLshort, GLshort); GLAPI void APIENTRY glVertexAttrib2svNV (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttrib3dNV (GLuint, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glVertexAttrib3dvNV (GLuint, const GLdouble *); GLAPI void APIENTRY glVertexAttrib3fNV (GLuint, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glVertexAttrib3fvNV (GLuint, const GLfloat *); GLAPI void APIENTRY glVertexAttrib3sNV (GLuint, GLshort, GLshort, GLshort); GLAPI void APIENTRY glVertexAttrib3svNV (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttrib4dNV (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glVertexAttrib4dvNV (GLuint, const GLdouble *); GLAPI void APIENTRY glVertexAttrib4fNV (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glVertexAttrib4fvNV (GLuint, const GLfloat *); GLAPI void APIENTRY glVertexAttrib4sNV (GLuint, GLshort, GLshort, GLshort, GLshort); GLAPI void APIENTRY glVertexAttrib4svNV (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttrib4ubNV (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); GLAPI void APIENTRY glVertexAttrib4ubvNV (GLuint, const GLubyte *); GLAPI void APIENTRY glVertexAttribs1dvNV (GLuint, GLsizei, const GLdouble *); GLAPI void APIENTRY glVertexAttribs1fvNV (GLuint, GLsizei, const GLfloat *); GLAPI void APIENTRY glVertexAttribs1svNV (GLuint, GLsizei, const GLshort *); GLAPI void APIENTRY glVertexAttribs2dvNV (GLuint, GLsizei, const GLdouble *); GLAPI void APIENTRY glVertexAttribs2fvNV (GLuint, GLsizei, const GLfloat *); GLAPI void APIENTRY glVertexAttribs2svNV (GLuint, GLsizei, const GLshort *); GLAPI void APIENTRY glVertexAttribs3dvNV (GLuint, GLsizei, const GLdouble *); GLAPI void APIENTRY glVertexAttribs3fvNV (GLuint, GLsizei, const GLfloat *); GLAPI void APIENTRY glVertexAttribs3svNV (GLuint, GLsizei, const GLshort *); GLAPI void APIENTRY glVertexAttribs4dvNV (GLuint, GLsizei, const GLdouble *); GLAPI void APIENTRY glVertexAttribs4fvNV (GLuint, GLsizei, const GLfloat *); GLAPI void APIENTRY glVertexAttribs4svNV (GLuint, GLsizei, const GLshort *); GLAPI void APIENTRY glVertexAttribs4ubvNV (GLuint, GLsizei, const GLubyte *); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLboolean (APIENTRYP PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint *programs, GLboolean *residences); typedef void (APIENTRYP PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); typedef void (APIENTRYP PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); typedef void (APIENTRYP PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat *params); typedef void (APIENTRYP PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint *programs); typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble *params); typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte *program); typedef void (APIENTRYP PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid* *pointer); typedef GLboolean (APIENTRYP PFNGLISPROGRAMNVPROC) (GLuint id); typedef void (APIENTRYP PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte *program); typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLuint count, const GLdouble *v); typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLuint count, const GLfloat *v); typedef void (APIENTRYP PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); typedef void (APIENTRYP PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, const GLubyte *v); #endif #ifndef GL_SGIX_texture_coordinate_clamp #define GL_SGIX_texture_coordinate_clamp 1 #endif #ifndef GL_SGIX_scalebias_hint #define GL_SGIX_scalebias_hint 1 #endif #ifndef GL_OML_interlace #define GL_OML_interlace 1 #endif #ifndef GL_OML_subsample #define GL_OML_subsample 1 #endif #ifndef GL_OML_resample #define GL_OML_resample 1 #endif #ifndef GL_NV_copy_depth_to_color #define GL_NV_copy_depth_to_color 1 #endif #ifndef GL_ATI_envmap_bumpmap #define GL_ATI_envmap_bumpmap 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexBumpParameterivATI (GLenum, const GLint *); GLAPI void APIENTRY glTexBumpParameterfvATI (GLenum, const GLfloat *); GLAPI void APIENTRY glGetTexBumpParameterivATI (GLenum, GLint *); GLAPI void APIENTRY glGetTexBumpParameterfvATI (GLenum, GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, const GLint *param); typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, const GLfloat *param); typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); #endif #ifndef GL_ATI_fragment_shader #define GL_ATI_fragment_shader 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLuint APIENTRY glGenFragmentShadersATI (GLuint); GLAPI void APIENTRY glBindFragmentShaderATI (GLuint); GLAPI void APIENTRY glDeleteFragmentShaderATI (GLuint); GLAPI void APIENTRY glBeginFragmentShaderATI (void); GLAPI void APIENTRY glEndFragmentShaderATI (void); GLAPI void APIENTRY glPassTexCoordATI (GLuint, GLuint, GLenum); GLAPI void APIENTRY glSampleMapATI (GLuint, GLuint, GLenum); GLAPI void APIENTRY glColorFragmentOp1ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glColorFragmentOp2ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glColorFragmentOp3ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glAlphaFragmentOp1ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glAlphaFragmentOp2ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glAlphaFragmentOp3ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glSetFragmentShaderConstantATI (GLuint, const GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLuint (APIENTRYP PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); typedef void (APIENTRYP PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); typedef void (APIENTRYP PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); typedef void (APIENTRYP PFNGLBEGINFRAGMENTSHADERATIPROC) (void); typedef void (APIENTRYP PFNGLENDFRAGMENTSHADERATIPROC) (void); typedef void (APIENTRYP PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); typedef void (APIENTRYP PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); typedef void (APIENTRYP PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat *value); #endif #ifndef GL_ATI_pn_triangles #define GL_ATI_pn_triangles 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPNTrianglesiATI (GLenum, GLint); GLAPI void APIENTRY glPNTrianglesfATI (GLenum, GLfloat); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); #endif #ifndef GL_ATI_vertex_array_object #define GL_ATI_vertex_array_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLuint APIENTRY glNewObjectBufferATI (GLsizei, const GLvoid *, GLenum); GLAPI GLboolean APIENTRY glIsObjectBufferATI (GLuint); GLAPI void APIENTRY glUpdateObjectBufferATI (GLuint, GLuint, GLsizei, const GLvoid *, GLenum); GLAPI void APIENTRY glGetObjectBufferfvATI (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY glGetObjectBufferivATI (GLuint, GLenum, GLint *); GLAPI void APIENTRY glFreeObjectBufferATI (GLuint); GLAPI void APIENTRY glArrayObjectATI (GLenum, GLint, GLenum, GLsizei, GLuint, GLuint); GLAPI void APIENTRY glGetArrayObjectfvATI (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetArrayObjectivATI (GLenum, GLenum, GLint *); GLAPI void APIENTRY glVariantArrayObjectATI (GLuint, GLenum, GLsizei, GLuint, GLuint); GLAPI void APIENTRY glGetVariantArrayObjectfvATI (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY glGetVariantArrayObjectivATI (GLuint, GLenum, GLint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLuint (APIENTRYP PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const GLvoid *pointer, GLenum usage); typedef GLboolean (APIENTRYP PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); typedef void (APIENTRYP PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve); typedef void (APIENTRYP PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); typedef void (APIENTRYP PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); typedef void (APIENTRYP PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint *params); #endif #ifndef GL_EXT_vertex_shader #define GL_EXT_vertex_shader 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBeginVertexShaderEXT (void); GLAPI void APIENTRY glEndVertexShaderEXT (void); GLAPI void APIENTRY glBindVertexShaderEXT (GLuint); GLAPI GLuint APIENTRY glGenVertexShadersEXT (GLuint); GLAPI void APIENTRY glDeleteVertexShaderEXT (GLuint); GLAPI void APIENTRY glShaderOp1EXT (GLenum, GLuint, GLuint); GLAPI void APIENTRY glShaderOp2EXT (GLenum, GLuint, GLuint, GLuint); GLAPI void APIENTRY glShaderOp3EXT (GLenum, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glSwizzleEXT (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum); GLAPI void APIENTRY glWriteMaskEXT (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum); GLAPI void APIENTRY glInsertComponentEXT (GLuint, GLuint, GLuint); GLAPI void APIENTRY glExtractComponentEXT (GLuint, GLuint, GLuint); GLAPI GLuint APIENTRY glGenSymbolsEXT (GLenum, GLenum, GLenum, GLuint); GLAPI void APIENTRY glSetInvariantEXT (GLuint, GLenum, const GLvoid *); GLAPI void APIENTRY glSetLocalConstantEXT (GLuint, GLenum, const GLvoid *); GLAPI void APIENTRY glVariantbvEXT (GLuint, const GLbyte *); GLAPI void APIENTRY glVariantsvEXT (GLuint, const GLshort *); GLAPI void APIENTRY glVariantivEXT (GLuint, const GLint *); GLAPI void APIENTRY glVariantfvEXT (GLuint, const GLfloat *); GLAPI void APIENTRY glVariantdvEXT (GLuint, const GLdouble *); GLAPI void APIENTRY glVariantubvEXT (GLuint, const GLubyte *); GLAPI void APIENTRY glVariantusvEXT (GLuint, const GLushort *); GLAPI void APIENTRY glVariantuivEXT (GLuint, const GLuint *); GLAPI void APIENTRY glVariantPointerEXT (GLuint, GLenum, GLuint, const GLvoid *); GLAPI void APIENTRY glEnableVariantClientStateEXT (GLuint); GLAPI void APIENTRY glDisableVariantClientStateEXT (GLuint); GLAPI GLuint APIENTRY glBindLightParameterEXT (GLenum, GLenum); GLAPI GLuint APIENTRY glBindMaterialParameterEXT (GLenum, GLenum); GLAPI GLuint APIENTRY glBindTexGenParameterEXT (GLenum, GLenum, GLenum); GLAPI GLuint APIENTRY glBindTextureUnitParameterEXT (GLenum, GLenum); GLAPI GLuint APIENTRY glBindParameterEXT (GLenum); GLAPI GLboolean APIENTRY glIsVariantEnabledEXT (GLuint, GLenum); GLAPI void APIENTRY glGetVariantBooleanvEXT (GLuint, GLenum, GLboolean *); GLAPI void APIENTRY glGetVariantIntegervEXT (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetVariantFloatvEXT (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY glGetVariantPointervEXT (GLuint, GLenum, GLvoid* *); GLAPI void APIENTRY glGetInvariantBooleanvEXT (GLuint, GLenum, GLboolean *); GLAPI void APIENTRY glGetInvariantIntegervEXT (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetInvariantFloatvEXT (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY glGetLocalConstantBooleanvEXT (GLuint, GLenum, GLboolean *); GLAPI void APIENTRY glGetLocalConstantIntegervEXT (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetLocalConstantFloatvEXT (GLuint, GLenum, GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBEGINVERTEXSHADEREXTPROC) (void); typedef void (APIENTRYP PFNGLENDVERTEXSHADEREXTPROC) (void); typedef void (APIENTRYP PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); typedef GLuint (APIENTRYP PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); typedef void (APIENTRYP PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); typedef void (APIENTRYP PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); typedef void (APIENTRYP PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); typedef void (APIENTRYP PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); typedef void (APIENTRYP PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); typedef void (APIENTRYP PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); typedef void (APIENTRYP PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); typedef void (APIENTRYP PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); typedef GLuint (APIENTRYP PFNGLGENSYMBOLSEXTPROC) (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); typedef void (APIENTRYP PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr); typedef void (APIENTRYP PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr); typedef void (APIENTRYP PFNGLVARIANTBVEXTPROC) (GLuint id, const GLbyte *addr); typedef void (APIENTRYP PFNGLVARIANTSVEXTPROC) (GLuint id, const GLshort *addr); typedef void (APIENTRYP PFNGLVARIANTIVEXTPROC) (GLuint id, const GLint *addr); typedef void (APIENTRYP PFNGLVARIANTFVEXTPROC) (GLuint id, const GLfloat *addr); typedef void (APIENTRYP PFNGLVARIANTDVEXTPROC) (GLuint id, const GLdouble *addr); typedef void (APIENTRYP PFNGLVARIANTUBVEXTPROC) (GLuint id, const GLubyte *addr); typedef void (APIENTRYP PFNGLVARIANTUSVEXTPROC) (GLuint id, const GLushort *addr); typedef void (APIENTRYP PFNGLVARIANTUIVEXTPROC) (GLuint id, const GLuint *addr); typedef void (APIENTRYP PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, const GLvoid *addr); typedef void (APIENTRYP PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); typedef void (APIENTRYP PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); typedef GLuint (APIENTRYP PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); typedef GLuint (APIENTRYP PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); typedef GLuint (APIENTRYP PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); typedef GLuint (APIENTRYP PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); typedef GLuint (APIENTRYP PFNGLBINDPARAMETEREXTPROC) (GLenum value); typedef GLboolean (APIENTRYP PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); typedef void (APIENTRYP PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); typedef void (APIENTRYP PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); typedef void (APIENTRYP PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); typedef void (APIENTRYP PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid* *data); typedef void (APIENTRYP PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); typedef void (APIENTRYP PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); typedef void (APIENTRYP PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); typedef void (APIENTRYP PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); typedef void (APIENTRYP PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); typedef void (APIENTRYP PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); #endif #ifndef GL_ATI_vertex_streams #define GL_ATI_vertex_streams 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexStream1sATI (GLenum, GLshort); GLAPI void APIENTRY glVertexStream1svATI (GLenum, const GLshort *); GLAPI void APIENTRY glVertexStream1iATI (GLenum, GLint); GLAPI void APIENTRY glVertexStream1ivATI (GLenum, const GLint *); GLAPI void APIENTRY glVertexStream1fATI (GLenum, GLfloat); GLAPI void APIENTRY glVertexStream1fvATI (GLenum, const GLfloat *); GLAPI void APIENTRY glVertexStream1dATI (GLenum, GLdouble); GLAPI void APIENTRY glVertexStream1dvATI (GLenum, const GLdouble *); GLAPI void APIENTRY glVertexStream2sATI (GLenum, GLshort, GLshort); GLAPI void APIENTRY glVertexStream2svATI (GLenum, const GLshort *); GLAPI void APIENTRY glVertexStream2iATI (GLenum, GLint, GLint); GLAPI void APIENTRY glVertexStream2ivATI (GLenum, const GLint *); GLAPI void APIENTRY glVertexStream2fATI (GLenum, GLfloat, GLfloat); GLAPI void APIENTRY glVertexStream2fvATI (GLenum, const GLfloat *); GLAPI void APIENTRY glVertexStream2dATI (GLenum, GLdouble, GLdouble); GLAPI void APIENTRY glVertexStream2dvATI (GLenum, const GLdouble *); GLAPI void APIENTRY glVertexStream3sATI (GLenum, GLshort, GLshort, GLshort); GLAPI void APIENTRY glVertexStream3svATI (GLenum, const GLshort *); GLAPI void APIENTRY glVertexStream3iATI (GLenum, GLint, GLint, GLint); GLAPI void APIENTRY glVertexStream3ivATI (GLenum, const GLint *); GLAPI void APIENTRY glVertexStream3fATI (GLenum, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glVertexStream3fvATI (GLenum, const GLfloat *); GLAPI void APIENTRY glVertexStream3dATI (GLenum, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glVertexStream3dvATI (GLenum, const GLdouble *); GLAPI void APIENTRY glVertexStream4sATI (GLenum, GLshort, GLshort, GLshort, GLshort); GLAPI void APIENTRY glVertexStream4svATI (GLenum, const GLshort *); GLAPI void APIENTRY glVertexStream4iATI (GLenum, GLint, GLint, GLint, GLint); GLAPI void APIENTRY glVertexStream4ivATI (GLenum, const GLint *); GLAPI void APIENTRY glVertexStream4fATI (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glVertexStream4fvATI (GLenum, const GLfloat *); GLAPI void APIENTRY glVertexStream4dATI (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glVertexStream4dvATI (GLenum, const GLdouble *); GLAPI void APIENTRY glNormalStream3bATI (GLenum, GLbyte, GLbyte, GLbyte); GLAPI void APIENTRY glNormalStream3bvATI (GLenum, const GLbyte *); GLAPI void APIENTRY glNormalStream3sATI (GLenum, GLshort, GLshort, GLshort); GLAPI void APIENTRY glNormalStream3svATI (GLenum, const GLshort *); GLAPI void APIENTRY glNormalStream3iATI (GLenum, GLint, GLint, GLint); GLAPI void APIENTRY glNormalStream3ivATI (GLenum, const GLint *); GLAPI void APIENTRY glNormalStream3fATI (GLenum, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glNormalStream3fvATI (GLenum, const GLfloat *); GLAPI void APIENTRY glNormalStream3dATI (GLenum, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glNormalStream3dvATI (GLenum, const GLdouble *); GLAPI void APIENTRY glClientActiveVertexStreamATI (GLenum); GLAPI void APIENTRY glVertexBlendEnviATI (GLenum, GLint); GLAPI void APIENTRY glVertexBlendEnvfATI (GLenum, GLfloat); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x); typedef void (APIENTRYP PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x); typedef void (APIENTRYP PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x); typedef void (APIENTRYP PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x); typedef void (APIENTRYP PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); typedef void (APIENTRYP PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); typedef void (APIENTRYP PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); typedef void (APIENTRYP PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); typedef void (APIENTRYP PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); typedef void (APIENTRYP PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); typedef void (APIENTRYP PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords); typedef void (APIENTRYP PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); typedef void (APIENTRYP PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords); typedef void (APIENTRYP PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort nx, GLshort ny, GLshort nz); typedef void (APIENTRYP PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); typedef void (APIENTRYP PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint nx, GLint ny, GLint nz); typedef void (APIENTRYP PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); typedef void (APIENTRYP PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); typedef void (APIENTRYP PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); typedef void (APIENTRYP PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); typedef void (APIENTRYP PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); typedef void (APIENTRYP PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); typedef void (APIENTRYP PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); #endif #ifndef GL_ATI_element_array #define GL_ATI_element_array 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glElementPointerATI (GLenum, const GLvoid *); GLAPI void APIENTRY glDrawElementArrayATI (GLenum, GLsizei); GLAPI void APIENTRY glDrawRangeElementArrayATI (GLenum, GLuint, GLuint, GLsizei); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLELEMENTPOINTERATIPROC) (GLenum type, const GLvoid *pointer); typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); #endif #ifndef GL_SUN_mesh_array #define GL_SUN_mesh_array 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawMeshArraysSUN (GLenum, GLint, GLsizei, GLsizei); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDRAWMESHARRAYSSUNPROC) (GLenum mode, GLint first, GLsizei count, GLsizei width); #endif #ifndef GL_SUN_slice_accum #define GL_SUN_slice_accum 1 #endif #ifndef GL_NV_multisample_filter_hint #define GL_NV_multisample_filter_hint 1 #endif #ifndef GL_NV_depth_clamp #define GL_NV_depth_clamp 1 #endif #ifndef GL_NV_occlusion_query #define GL_NV_occlusion_query 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGenOcclusionQueriesNV (GLsizei, GLuint *); GLAPI void APIENTRY glDeleteOcclusionQueriesNV (GLsizei, const GLuint *); GLAPI GLboolean APIENTRY glIsOcclusionQueryNV (GLuint); GLAPI void APIENTRY glBeginOcclusionQueryNV (GLuint); GLAPI void APIENTRY glEndOcclusionQueryNV (void); GLAPI void APIENTRY glGetOcclusionQueryivNV (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetOcclusionQueryuivNV (GLuint, GLenum, GLuint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint *ids); typedef void (APIENTRYP PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint *ids); typedef GLboolean (APIENTRYP PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); typedef void (APIENTRYP PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); typedef void (APIENTRYP PFNGLENDOCCLUSIONQUERYNVPROC) (void); typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint *params); #endif #ifndef GL_NV_point_sprite #define GL_NV_point_sprite 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPointParameteriNV (GLenum, GLint); GLAPI void APIENTRY glPointParameterivNV (GLenum, const GLint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint *params); #endif #ifndef GL_NV_texture_shader3 #define GL_NV_texture_shader3 1 #endif #ifndef GL_NV_vertex_program1_1 #define GL_NV_vertex_program1_1 1 #endif #ifndef GL_EXT_shadow_funcs #define GL_EXT_shadow_funcs 1 #endif #ifndef GL_EXT_stencil_two_side #define GL_EXT_stencil_two_side 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glActiveStencilFaceEXT (GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); #endif #ifndef GL_ATI_text_fragment_shader #define GL_ATI_text_fragment_shader 1 #endif #ifndef GL_APPLE_client_storage #define GL_APPLE_client_storage 1 #endif #ifndef GL_APPLE_element_array #define GL_APPLE_element_array 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glElementPointerAPPLE (GLenum, const GLvoid *); GLAPI void APIENTRY glDrawElementArrayAPPLE (GLenum, GLint, GLsizei); GLAPI void APIENTRY glDrawRangeElementArrayAPPLE (GLenum, GLuint, GLuint, GLint, GLsizei); GLAPI void APIENTRY glMultiDrawElementArrayAPPLE (GLenum, const GLint *, const GLsizei *, GLsizei); GLAPI void APIENTRY glMultiDrawRangeElementArrayAPPLE (GLenum, GLuint, GLuint, const GLint *, const GLsizei *, GLsizei); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const GLvoid *pointer); typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); typedef void (APIENTRYP PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); #endif #ifndef GL_APPLE_fence #define GL_APPLE_fence 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGenFencesAPPLE (GLsizei, GLuint *); GLAPI void APIENTRY glDeleteFencesAPPLE (GLsizei, const GLuint *); GLAPI void APIENTRY glSetFenceAPPLE (GLuint); GLAPI GLboolean APIENTRY glIsFenceAPPLE (GLuint); GLAPI GLboolean APIENTRY glTestFenceAPPLE (GLuint); GLAPI void APIENTRY glFinishFenceAPPLE (GLuint); GLAPI GLboolean APIENTRY glTestObjectAPPLE (GLenum, GLuint); GLAPI void APIENTRY glFinishObjectAPPLE (GLenum, GLint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint *fences); typedef void (APIENTRYP PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint *fences); typedef void (APIENTRYP PFNGLSETFENCEAPPLEPROC) (GLuint fence); typedef GLboolean (APIENTRYP PFNGLISFENCEAPPLEPROC) (GLuint fence); typedef GLboolean (APIENTRYP PFNGLTESTFENCEAPPLEPROC) (GLuint fence); typedef void (APIENTRYP PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); typedef GLboolean (APIENTRYP PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); typedef void (APIENTRYP PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); #endif #ifndef GL_APPLE_vertex_array_object #define GL_APPLE_vertex_array_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBindVertexArrayAPPLE (GLuint); GLAPI void APIENTRY glDeleteVertexArraysAPPLE (GLsizei, const GLuint *); GLAPI void APIENTRY glGenVertexArraysAPPLE (GLsizei, GLuint *); GLAPI GLboolean APIENTRY glIsVertexArrayAPPLE (GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays); typedef void (APIENTRYP PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, GLuint *arrays); typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); #endif #ifndef GL_APPLE_vertex_array_range #define GL_APPLE_vertex_array_range 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexArrayRangeAPPLE (GLsizei, GLvoid *); GLAPI void APIENTRY glFlushVertexArrayRangeAPPLE (GLsizei, GLvoid *); GLAPI void APIENTRY glVertexArrayParameteriAPPLE (GLenum, GLint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer); typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer); typedef void (APIENTRYP PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); #endif #ifndef GL_APPLE_ycbcr_422 #define GL_APPLE_ycbcr_422 1 #endif #ifndef GL_S3_s3tc #define GL_S3_s3tc 1 #endif #ifndef GL_ATI_draw_buffers #define GL_ATI_draw_buffers 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawBuffersATI (GLsizei, const GLenum *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum *bufs); #endif #ifndef GL_ATI_pixel_format_float #define GL_ATI_pixel_format_float 1 /* This is really a WGL extension, but defines some associated GL enums. * ATI does not export "GL_ATI_pixel_format_float" in the GL_EXTENSIONS string. */ #endif #ifndef GL_ATI_texture_env_combine3 #define GL_ATI_texture_env_combine3 1 #endif #ifndef GL_ATI_texture_float #define GL_ATI_texture_float 1 #endif #ifndef GL_NV_float_buffer #define GL_NV_float_buffer 1 #endif #ifndef GL_NV_fragment_program #define GL_NV_fragment_program 1 /* Some NV_fragment_program entry points are shared with ARB_vertex_program. */ #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glProgramNamedParameter4fNV (GLuint, GLsizei, const GLubyte *, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glProgramNamedParameter4dNV (GLuint, GLsizei, const GLubyte *, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glProgramNamedParameter4fvNV (GLuint, GLsizei, const GLubyte *, const GLfloat *); GLAPI void APIENTRY glProgramNamedParameter4dvNV (GLuint, GLsizei, const GLubyte *, const GLdouble *); GLAPI void APIENTRY glGetProgramNamedParameterfvNV (GLuint, GLsizei, const GLubyte *, GLfloat *); GLAPI void APIENTRY glGetProgramNamedParameterdvNV (GLuint, GLsizei, const GLubyte *, GLdouble *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); #endif #ifndef GL_NV_half_float #define GL_NV_half_float 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertex2hNV (GLhalfNV, GLhalfNV); GLAPI void APIENTRY glVertex2hvNV (const GLhalfNV *); GLAPI void APIENTRY glVertex3hNV (GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glVertex3hvNV (const GLhalfNV *); GLAPI void APIENTRY glVertex4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glVertex4hvNV (const GLhalfNV *); GLAPI void APIENTRY glNormal3hNV (GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glNormal3hvNV (const GLhalfNV *); GLAPI void APIENTRY glColor3hNV (GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glColor3hvNV (const GLhalfNV *); GLAPI void APIENTRY glColor4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glColor4hvNV (const GLhalfNV *); GLAPI void APIENTRY glTexCoord1hNV (GLhalfNV); GLAPI void APIENTRY glTexCoord1hvNV (const GLhalfNV *); GLAPI void APIENTRY glTexCoord2hNV (GLhalfNV, GLhalfNV); GLAPI void APIENTRY glTexCoord2hvNV (const GLhalfNV *); GLAPI void APIENTRY glTexCoord3hNV (GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glTexCoord3hvNV (const GLhalfNV *); GLAPI void APIENTRY glTexCoord4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glTexCoord4hvNV (const GLhalfNV *); GLAPI void APIENTRY glMultiTexCoord1hNV (GLenum, GLhalfNV); GLAPI void APIENTRY glMultiTexCoord1hvNV (GLenum, const GLhalfNV *); GLAPI void APIENTRY glMultiTexCoord2hNV (GLenum, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glMultiTexCoord2hvNV (GLenum, const GLhalfNV *); GLAPI void APIENTRY glMultiTexCoord3hNV (GLenum, GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glMultiTexCoord3hvNV (GLenum, const GLhalfNV *); GLAPI void APIENTRY glMultiTexCoord4hNV (GLenum, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glMultiTexCoord4hvNV (GLenum, const GLhalfNV *); GLAPI void APIENTRY glFogCoordhNV (GLhalfNV); GLAPI void APIENTRY glFogCoordhvNV (const GLhalfNV *); GLAPI void APIENTRY glSecondaryColor3hNV (GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glSecondaryColor3hvNV (const GLhalfNV *); GLAPI void APIENTRY glVertexWeighthNV (GLhalfNV); GLAPI void APIENTRY glVertexWeighthvNV (const GLhalfNV *); GLAPI void APIENTRY glVertexAttrib1hNV (GLuint, GLhalfNV); GLAPI void APIENTRY glVertexAttrib1hvNV (GLuint, const GLhalfNV *); GLAPI void APIENTRY glVertexAttrib2hNV (GLuint, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glVertexAttrib2hvNV (GLuint, const GLhalfNV *); GLAPI void APIENTRY glVertexAttrib3hNV (GLuint, GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glVertexAttrib3hvNV (GLuint, const GLhalfNV *); GLAPI void APIENTRY glVertexAttrib4hNV (GLuint, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glVertexAttrib4hvNV (GLuint, const GLhalfNV *); GLAPI void APIENTRY glVertexAttribs1hvNV (GLuint, GLsizei, const GLhalfNV *); GLAPI void APIENTRY glVertexAttribs2hvNV (GLuint, GLsizei, const GLhalfNV *); GLAPI void APIENTRY glVertexAttribs3hvNV (GLuint, GLsizei, const GLhalfNV *); GLAPI void APIENTRY glVertexAttribs4hvNV (GLuint, GLsizei, const GLhalfNV *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEX2HNVPROC) (GLhalfNV x, GLhalfNV y); typedef void (APIENTRYP PFNGLVERTEX2HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEX3HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z); typedef void (APIENTRYP PFNGLVERTEX3HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEX4HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); typedef void (APIENTRYP PFNGLVERTEX4HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLNORMAL3HNVPROC) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); typedef void (APIENTRYP PFNGLNORMAL3HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); typedef void (APIENTRYP PFNGLCOLOR3HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLCOLOR4HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); typedef void (APIENTRYP PFNGLCOLOR4HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLTEXCOORD1HNVPROC) (GLhalfNV s); typedef void (APIENTRYP PFNGLTEXCOORD1HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLTEXCOORD2HNVPROC) (GLhalfNV s, GLhalfNV t); typedef void (APIENTRYP PFNGLTEXCOORD2HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLTEXCOORD3HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r); typedef void (APIENTRYP PFNGLTEXCOORD3HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLTEXCOORD4HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); typedef void (APIENTRYP PFNGLTEXCOORD4HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalfNV s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalfNV *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalfNV *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalfNV *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalfNV *v); typedef void (APIENTRYP PFNGLFOGCOORDHNVPROC) (GLhalfNV fog); typedef void (APIENTRYP PFNGLFOGCOORDHVNVPROC) (const GLhalfNV *fog); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight); typedef void (APIENTRYP PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV *weight); typedef void (APIENTRYP PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); #endif #ifndef GL_NV_pixel_data_range #define GL_NV_pixel_data_range 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPixelDataRangeNV (GLenum, GLsizei, GLvoid *); GLAPI void APIENTRY glFlushPixelDataRangeNV (GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, GLvoid *pointer); typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); #endif #ifndef GL_NV_primitive_restart #define GL_NV_primitive_restart 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPrimitiveRestartNV (void); GLAPI void APIENTRY glPrimitiveRestartIndexNV (GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPRIMITIVERESTARTNVPROC) (void); typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); #endif #ifndef GL_NV_texture_expand_normal #define GL_NV_texture_expand_normal 1 #endif #ifndef GL_NV_vertex_program2 #define GL_NV_vertex_program2 1 #endif #ifndef GL_ATI_map_object_buffer #define GL_ATI_map_object_buffer 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLvoid* APIENTRY glMapObjectBufferATI (GLuint); GLAPI void APIENTRY glUnmapObjectBufferATI (GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLvoid* (APIENTRYP PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); typedef void (APIENTRYP PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); #endif #ifndef GL_ATI_separate_stencil #define GL_ATI_separate_stencil 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glStencilOpSeparateATI (GLenum, GLenum, GLenum, GLenum); GLAPI void APIENTRY glStencilFuncSeparateATI (GLenum, GLenum, GLint, GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); #endif #ifndef GL_ATI_vertex_attrib_array_object #define GL_ATI_vertex_attrib_array_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexAttribArrayObjectATI (GLuint, GLint, GLenum, GLboolean, GLsizei, GLuint, GLuint); GLAPI void APIENTRY glGetVertexAttribArrayObjectfvATI (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY glGetVertexAttribArrayObjectivATI (GLuint, GLenum, GLint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint *params); #endif #ifndef GL_OES_read_format #define GL_OES_read_format 1 #endif #ifndef GL_EXT_depth_bounds_test #define GL_EXT_depth_bounds_test 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDepthBoundsEXT (GLclampd, GLclampd); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); #endif #ifndef GL_EXT_texture_mirror_clamp #define GL_EXT_texture_mirror_clamp 1 #endif #ifndef GL_EXT_blend_equation_separate #define GL_EXT_blend_equation_separate 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendEquationSeparateEXT (GLenum, GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); #endif #ifndef GL_MESA_pack_invert #define GL_MESA_pack_invert 1 #endif #ifndef GL_MESA_ycbcr_texture #define GL_MESA_ycbcr_texture 1 #endif #ifndef GL_EXT_pixel_buffer_object #define GL_EXT_pixel_buffer_object 1 #endif #ifndef GL_NV_fragment_program_option #define GL_NV_fragment_program_option 1 #endif #ifndef GL_NV_fragment_program2 #define GL_NV_fragment_program2 1 #endif #ifndef GL_NV_vertex_program2_option #define GL_NV_vertex_program2_option 1 #endif #ifndef GL_NV_vertex_program3 #define GL_NV_vertex_program3 1 #endif #ifndef GL_EXT_framebuffer_object #define GL_EXT_framebuffer_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLboolean APIENTRY glIsRenderbufferEXT (GLuint); GLAPI void APIENTRY glBindRenderbufferEXT (GLenum, GLuint); GLAPI void APIENTRY glDeleteRenderbuffersEXT (GLsizei, const GLuint *); GLAPI void APIENTRY glGenRenderbuffersEXT (GLsizei, GLuint *); GLAPI void APIENTRY glRenderbufferStorageEXT (GLenum, GLenum, GLsizei, GLsizei); GLAPI void APIENTRY glGetRenderbufferParameterivEXT (GLenum, GLenum, GLint *); GLAPI GLboolean APIENTRY glIsFramebufferEXT (GLuint); GLAPI void APIENTRY glBindFramebufferEXT (GLenum, GLuint); GLAPI void APIENTRY glDeleteFramebuffersEXT (GLsizei, const GLuint *); GLAPI void APIENTRY glGenFramebuffersEXT (GLsizei, GLuint *); GLAPI GLenum APIENTRY glCheckFramebufferStatusEXT (GLenum); GLAPI void APIENTRY glFramebufferTexture1DEXT (GLenum, GLenum, GLenum, GLuint, GLint); GLAPI void APIENTRY glFramebufferTexture2DEXT (GLenum, GLenum, GLenum, GLuint, GLint); GLAPI void APIENTRY glFramebufferTexture3DEXT (GLenum, GLenum, GLenum, GLuint, GLint, GLint); GLAPI void APIENTRY glFramebufferRenderbufferEXT (GLenum, GLenum, GLenum, GLuint); GLAPI void APIENTRY glGetFramebufferAttachmentParameterivEXT (GLenum, GLenum, GLenum, GLint *); GLAPI void APIENTRY glGenerateMipmapEXT (GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers); typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers); typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers); typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers); typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); #endif #ifndef GL_GREMEDY_string_marker #define GL_GREMEDY_string_marker 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glStringMarkerGREMEDY (GLsizei, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const GLvoid *string); #endif #ifndef GL_EXT_packed_depth_stencil #define GL_EXT_packed_depth_stencil 1 #endif #ifndef GL_EXT_stencil_clear_tag #define GL_EXT_stencil_clear_tag 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glStencilClearTagEXT (GLsizei, GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSTENCILCLEARTAGEXTPROC) (GLsizei stencilTagBits, GLuint stencilClearTag); #endif #ifndef GL_EXT_texture_sRGB #define GL_EXT_texture_sRGB 1 #endif #ifndef GL_EXT_framebuffer_blit #define GL_EXT_framebuffer_blit 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlitFramebufferEXT (GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); #endif #ifndef GL_EXT_framebuffer_multisample #define GL_EXT_framebuffer_multisample 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glRenderbufferStorageMultisampleEXT (GLenum, GLsizei, GLenum, GLsizei, GLsizei); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); #endif #ifndef GL_MESAX_texture_stack #define GL_MESAX_texture_stack 1 #endif #ifndef GL_EXT_timer_query #define GL_EXT_timer_query 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetQueryObjecti64vEXT (GLuint, GLenum, GLint64EXT *); GLAPI void APIENTRY glGetQueryObjectui64vEXT (GLuint, GLenum, GLuint64EXT *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT *params); typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT *params); #endif #ifndef GL_EXT_gpu_program_parameters #define GL_EXT_gpu_program_parameters 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glProgramEnvParameters4fvEXT (GLenum, GLuint, GLsizei, const GLfloat *); GLAPI void APIENTRY glProgramLocalParameters4fvEXT (GLenum, GLuint, GLsizei, const GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params); typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params); #endif #ifndef GL_APPLE_flush_buffer_range #define GL_APPLE_flush_buffer_range 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBufferParameteriAPPLE (GLenum, GLenum, GLint); GLAPI void APIENTRY glFlushMappedBufferRangeAPPLE (GLenum, GLintptr, GLsizeiptr); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size); #endif #ifndef GL_NV_gpu_program4 #define GL_NV_gpu_program4 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glProgramLocalParameterI4iNV (GLenum, GLuint, GLint, GLint, GLint, GLint); GLAPI void APIENTRY glProgramLocalParameterI4ivNV (GLenum, GLuint, const GLint *); GLAPI void APIENTRY glProgramLocalParametersI4ivNV (GLenum, GLuint, GLsizei, const GLint *); GLAPI void APIENTRY glProgramLocalParameterI4uiNV (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glProgramLocalParameterI4uivNV (GLenum, GLuint, const GLuint *); GLAPI void APIENTRY glProgramLocalParametersI4uivNV (GLenum, GLuint, GLsizei, const GLuint *); GLAPI void APIENTRY glProgramEnvParameterI4iNV (GLenum, GLuint, GLint, GLint, GLint, GLint); GLAPI void APIENTRY glProgramEnvParameterI4ivNV (GLenum, GLuint, const GLint *); GLAPI void APIENTRY glProgramEnvParametersI4ivNV (GLenum, GLuint, GLsizei, const GLint *); GLAPI void APIENTRY glProgramEnvParameterI4uiNV (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glProgramEnvParameterI4uivNV (GLenum, GLuint, const GLuint *); GLAPI void APIENTRY glProgramEnvParametersI4uivNV (GLenum, GLuint, GLsizei, const GLuint *); GLAPI void APIENTRY glGetProgramLocalParameterIivNV (GLenum, GLuint, GLint *); GLAPI void APIENTRY glGetProgramLocalParameterIuivNV (GLenum, GLuint, GLuint *); GLAPI void APIENTRY glGetProgramEnvParameterIivNV (GLenum, GLuint, GLint *); GLAPI void APIENTRY glGetProgramEnvParameterIuivNV (GLenum, GLuint, GLuint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); #endif #ifndef GL_NV_geometry_program4 #define GL_NV_geometry_program4 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glProgramVertexLimitNV (GLenum, GLint); GLAPI void APIENTRY glFramebufferTextureEXT (GLenum, GLenum, GLuint, GLint); GLAPI void APIENTRY glFramebufferTextureLayerEXT (GLenum, GLenum, GLuint, GLint, GLint); GLAPI void APIENTRY glFramebufferTextureFaceEXT (GLenum, GLenum, GLuint, GLint, GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); #endif #ifndef GL_EXT_geometry_shader4 #define GL_EXT_geometry_shader4 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glProgramParameteriEXT (GLuint, GLenum, GLint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); #endif #ifndef GL_NV_vertex_program4 #define GL_NV_vertex_program4 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexAttribI1iEXT (GLuint, GLint); GLAPI void APIENTRY glVertexAttribI2iEXT (GLuint, GLint, GLint); GLAPI void APIENTRY glVertexAttribI3iEXT (GLuint, GLint, GLint, GLint); GLAPI void APIENTRY glVertexAttribI4iEXT (GLuint, GLint, GLint, GLint, GLint); GLAPI void APIENTRY glVertexAttribI1uiEXT (GLuint, GLuint); GLAPI void APIENTRY glVertexAttribI2uiEXT (GLuint, GLuint, GLuint); GLAPI void APIENTRY glVertexAttribI3uiEXT (GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glVertexAttribI4uiEXT (GLuint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glVertexAttribI1ivEXT (GLuint, const GLint *); GLAPI void APIENTRY glVertexAttribI2ivEXT (GLuint, const GLint *); GLAPI void APIENTRY glVertexAttribI3ivEXT (GLuint, const GLint *); GLAPI void APIENTRY glVertexAttribI4ivEXT (GLuint, const GLint *); GLAPI void APIENTRY glVertexAttribI1uivEXT (GLuint, const GLuint *); GLAPI void APIENTRY glVertexAttribI2uivEXT (GLuint, const GLuint *); GLAPI void APIENTRY glVertexAttribI3uivEXT (GLuint, const GLuint *); GLAPI void APIENTRY glVertexAttribI4uivEXT (GLuint, const GLuint *); GLAPI void APIENTRY glVertexAttribI4bvEXT (GLuint, const GLbyte *); GLAPI void APIENTRY glVertexAttribI4svEXT (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttribI4ubvEXT (GLuint, const GLubyte *); GLAPI void APIENTRY glVertexAttribI4usvEXT (GLuint, const GLushort *); GLAPI void APIENTRY glVertexAttribIPointerEXT (GLuint, GLint, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glGetVertexAttribIivEXT (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetVertexAttribIuivEXT (GLuint, GLenum, GLuint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x); typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params); #endif #ifndef GL_EXT_gpu_shader4 #define GL_EXT_gpu_shader4 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetUniformuivEXT (GLuint, GLint, GLuint *); GLAPI void APIENTRY glBindFragDataLocationEXT (GLuint, GLuint, const GLchar *); GLAPI GLint APIENTRY glGetFragDataLocationEXT (GLuint, const GLchar *); GLAPI void APIENTRY glUniform1uiEXT (GLint, GLuint); GLAPI void APIENTRY glUniform2uiEXT (GLint, GLuint, GLuint); GLAPI void APIENTRY glUniform3uiEXT (GLint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glUniform4uiEXT (GLint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glUniform1uivEXT (GLint, GLsizei, const GLuint *); GLAPI void APIENTRY glUniform2uivEXT (GLint, GLsizei, const GLuint *); GLAPI void APIENTRY glUniform3uivEXT (GLint, GLsizei, const GLuint *); GLAPI void APIENTRY glUniform4uivEXT (GLint, GLsizei, const GLuint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params); typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name); typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name); typedef void (APIENTRYP PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0); typedef void (APIENTRYP PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1); typedef void (APIENTRYP PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); typedef void (APIENTRYP PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); typedef void (APIENTRYP PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); #endif #ifndef GL_EXT_draw_instanced #define GL_EXT_draw_instanced 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawArraysInstancedEXT (GLenum, GLint, GLsizei, GLsizei); GLAPI void APIENTRY glDrawElementsInstancedEXT (GLenum, GLsizei, GLenum, const GLvoid *, GLsizei); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); #endif #ifndef GL_EXT_packed_float #define GL_EXT_packed_float 1 #endif #ifndef GL_EXT_texture_array #define GL_EXT_texture_array 1 #endif #ifndef GL_EXT_texture_buffer_object #define GL_EXT_texture_buffer_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexBufferEXT (GLenum, GLenum, GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); #endif #ifndef GL_EXT_texture_compression_latc #define GL_EXT_texture_compression_latc 1 #endif #ifndef GL_EXT_texture_compression_rgtc #define GL_EXT_texture_compression_rgtc 1 #endif #ifndef GL_EXT_texture_shared_exponent #define GL_EXT_texture_shared_exponent 1 #endif #ifndef GL_NV_depth_buffer_float #define GL_NV_depth_buffer_float 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDepthRangedNV (GLdouble, GLdouble); GLAPI void APIENTRY glClearDepthdNV (GLdouble); GLAPI void APIENTRY glDepthBoundsdNV (GLdouble, GLdouble); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar); typedef void (APIENTRYP PFNGLCLEARDEPTHDNVPROC) (GLdouble depth); typedef void (APIENTRYP PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax); #endif #ifndef GL_NV_fragment_program4 #define GL_NV_fragment_program4 1 #endif #ifndef GL_NV_framebuffer_multisample_coverage #define GL_NV_framebuffer_multisample_coverage 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glRenderbufferStorageMultisampleCoverageNV (GLenum, GLsizei, GLsizei, GLenum, GLsizei, GLsizei); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); #endif #ifndef GL_EXT_framebuffer_sRGB #define GL_EXT_framebuffer_sRGB 1 #endif #ifndef GL_NV_geometry_shader4 #define GL_NV_geometry_shader4 1 #endif #ifndef GL_NV_parameter_buffer_object #define GL_NV_parameter_buffer_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glProgramBufferParametersfvNV (GLenum, GLuint, GLuint, GLsizei, const GLfloat *); GLAPI void APIENTRY glProgramBufferParametersIivNV (GLenum, GLuint, GLuint, GLsizei, const GLint *); GLAPI void APIENTRY glProgramBufferParametersIuivNV (GLenum, GLuint, GLuint, GLsizei, const GLuint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params); typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params); typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params); #endif #ifndef GL_EXT_draw_buffers2 #define GL_EXT_draw_buffers2 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glColorMaskIndexedEXT (GLuint, GLboolean, GLboolean, GLboolean, GLboolean); GLAPI void APIENTRY glGetBooleanIndexedvEXT (GLenum, GLuint, GLboolean *); GLAPI void APIENTRY glGetIntegerIndexedvEXT (GLenum, GLuint, GLint *); GLAPI void APIENTRY glEnableIndexedEXT (GLenum, GLuint); GLAPI void APIENTRY glDisableIndexedEXT (GLenum, GLuint); GLAPI GLboolean APIENTRY glIsEnabledIndexedEXT (GLenum, GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); typedef void (APIENTRYP PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum target, GLuint index, GLboolean *data); typedef void (APIENTRYP PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLint *data); typedef void (APIENTRYP PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); typedef void (APIENTRYP PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); typedef GLboolean (APIENTRYP PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); #endif #ifndef GL_NV_transform_feedback #define GL_NV_transform_feedback 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBeginTransformFeedbackNV (GLenum); GLAPI void APIENTRY glEndTransformFeedbackNV (void); GLAPI void APIENTRY glTransformFeedbackAttribsNV (GLuint, const GLint *, GLenum); GLAPI void APIENTRY glBindBufferRangeNV (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr); GLAPI void APIENTRY glBindBufferOffsetNV (GLenum, GLuint, GLuint, GLintptr); GLAPI void APIENTRY glBindBufferBaseNV (GLenum, GLuint, GLuint); GLAPI void APIENTRY glTransformFeedbackVaryingsNV (GLuint, GLsizei, const GLchar* *, GLenum); GLAPI void APIENTRY glActiveVaryingNV (GLuint, const GLchar *); GLAPI GLint APIENTRY glGetVaryingLocationNV (GLuint, const GLchar *); GLAPI void APIENTRY glGetActiveVaryingNV (GLuint, GLuint, GLsizei, GLsizei *, GLsizei *, GLenum *, GLchar *); GLAPI void APIENTRY glGetTransformFeedbackVaryingNV (GLuint, GLuint, GLint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKNVPROC) (void); typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode); typedef void (APIENTRYP PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); typedef void (APIENTRYP PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer); typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode); typedef void (APIENTRYP PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name); typedef GLint (APIENTRYP PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name); typedef void (APIENTRYP PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location); #endif #ifndef GL_EXT_bindable_uniform #define GL_EXT_bindable_uniform 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glUniformBufferEXT (GLuint, GLint, GLuint); GLAPI GLint APIENTRY glGetUniformBufferSizeEXT (GLuint, GLint); GLAPI GLintptr APIENTRY glGetUniformOffsetEXT (GLuint, GLint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer); typedef GLint (APIENTRYP PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location); typedef GLintptr (APIENTRYP PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location); #endif #ifndef GL_EXT_texture_integer #define GL_EXT_texture_integer 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexParameterIivEXT (GLenum, GLenum, const GLint *); GLAPI void APIENTRY glTexParameterIuivEXT (GLenum, GLenum, const GLuint *); GLAPI void APIENTRY glGetTexParameterIivEXT (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetTexParameterIuivEXT (GLenum, GLenum, GLuint *); GLAPI void APIENTRY glClearColorIiEXT (GLint, GLint, GLint, GLint); GLAPI void APIENTRY glClearColorIuiEXT (GLuint, GLuint, GLuint, GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params); typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params); typedef void (APIENTRYP PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha); typedef void (APIENTRYP PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha); #endif #ifndef GL_GREMEDY_frame_terminator #define GL_GREMEDY_frame_terminator 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFrameTerminatorGREMEDY (void); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFRAMETERMINATORGREMEDYPROC) (void); #endif #ifndef GL_NV_conditional_render #define GL_NV_conditional_render 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBeginConditionalRenderNV (GLuint, GLenum); GLAPI void APIENTRY glEndConditionalRenderNV (void); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode); typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERNVPROC) (void); #endif #ifndef GL_NV_present_video #define GL_NV_present_video 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPresentFrameKeyedNV (GLuint, GLuint64EXT, GLuint, GLuint, GLenum, GLenum, GLuint, GLuint, GLenum, GLuint, GLuint); GLAPI void APIENTRY glPresentFrameDualFillNV (GLuint, GLuint64EXT, GLuint, GLuint, GLenum, GLenum, GLuint, GLenum, GLuint, GLenum, GLuint, GLenum, GLuint); GLAPI void APIENTRY glGetVideoivNV (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetVideouivNV (GLuint, GLenum, GLuint *); GLAPI void APIENTRY glGetVideoi64vNV (GLuint, GLenum, GLint64EXT *); GLAPI void APIENTRY glGetVideoui64vNV (GLuint, GLenum, GLuint64EXT *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); typedef void (APIENTRYP PFNGLPRESENTFRAMEDUALFILLNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3); typedef void (APIENTRYP PFNGLGETVIDEOIVNVPROC) (GLuint video_slot, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint *params); typedef void (APIENTRYP PFNGLGETVIDEOI64VNVPROC) (GLuint video_slot, GLenum pname, GLint64EXT *params); typedef void (APIENTRYP PFNGLGETVIDEOUI64VNVPROC) (GLuint video_slot, GLenum pname, GLuint64EXT *params); #endif #ifndef GL_EXT_transform_feedback #define GL_EXT_transform_feedback 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBeginTransformFeedbackEXT (GLenum); GLAPI void APIENTRY glEndTransformFeedbackEXT (void); GLAPI void APIENTRY glBindBufferRangeEXT (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr); GLAPI void APIENTRY glBindBufferOffsetEXT (GLenum, GLuint, GLuint, GLintptr); GLAPI void APIENTRY glBindBufferBaseEXT (GLenum, GLuint, GLuint); GLAPI void APIENTRY glTransformFeedbackVaryingsEXT (GLuint, GLsizei, const GLchar* *, GLenum); GLAPI void APIENTRY glGetTransformFeedbackVaryingEXT (GLuint, GLuint, GLsizei, GLsizei *, GLsizei *, GLenum *, GLchar *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKEXTPROC) (GLenum primitiveMode); typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKEXTPROC) (void); typedef void (APIENTRYP PFNGLBINDBUFFERRANGEEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); typedef void (APIENTRYP PFNGLBINDBUFFERBASEEXTPROC) (GLenum target, GLuint index, GLuint buffer); typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode); typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); #endif #ifndef GL_EXT_direct_state_access #define GL_EXT_direct_state_access 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glClientAttribDefaultEXT (GLbitfield); GLAPI void APIENTRY glPushClientAttribDefaultEXT (GLbitfield); GLAPI void APIENTRY glMatrixLoadfEXT (GLenum, const GLfloat *); GLAPI void APIENTRY glMatrixLoaddEXT (GLenum, const GLdouble *); GLAPI void APIENTRY glMatrixMultfEXT (GLenum, const GLfloat *); GLAPI void APIENTRY glMatrixMultdEXT (GLenum, const GLdouble *); GLAPI void APIENTRY glMatrixLoadIdentityEXT (GLenum); GLAPI void APIENTRY glMatrixRotatefEXT (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glMatrixRotatedEXT (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glMatrixScalefEXT (GLenum, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glMatrixScaledEXT (GLenum, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glMatrixTranslatefEXT (GLenum, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glMatrixTranslatedEXT (GLenum, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glMatrixFrustumEXT (GLenum, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glMatrixOrthoEXT (GLenum, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glMatrixPopEXT (GLenum); GLAPI void APIENTRY glMatrixPushEXT (GLenum); GLAPI void APIENTRY glMatrixLoadTransposefEXT (GLenum, const GLfloat *); GLAPI void APIENTRY glMatrixLoadTransposedEXT (GLenum, const GLdouble *); GLAPI void APIENTRY glMatrixMultTransposefEXT (GLenum, const GLfloat *); GLAPI void APIENTRY glMatrixMultTransposedEXT (GLenum, const GLdouble *); GLAPI void APIENTRY glTextureParameterfEXT (GLuint, GLenum, GLenum, GLfloat); GLAPI void APIENTRY glTextureParameterfvEXT (GLuint, GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY glTextureParameteriEXT (GLuint, GLenum, GLenum, GLint); GLAPI void APIENTRY glTextureParameterivEXT (GLuint, GLenum, GLenum, const GLint *); GLAPI void APIENTRY glTextureImage1DEXT (GLuint, GLenum, GLint, GLenum, GLsizei, GLint, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glTextureImage2DEXT (GLuint, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glTextureSubImage1DEXT (GLuint, GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glTextureSubImage2DEXT (GLuint, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glCopyTextureImage1DEXT (GLuint, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint); GLAPI void APIENTRY glCopyTextureImage2DEXT (GLuint, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint); GLAPI void APIENTRY glCopyTextureSubImage1DEXT (GLuint, GLenum, GLint, GLint, GLint, GLint, GLsizei); GLAPI void APIENTRY glCopyTextureSubImage2DEXT (GLuint, GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); GLAPI void APIENTRY glGetTextureImageEXT (GLuint, GLenum, GLint, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY glGetTextureParameterfvEXT (GLuint, GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetTextureParameterivEXT (GLuint, GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetTextureLevelParameterfvEXT (GLuint, GLenum, GLint, GLenum, GLfloat *); GLAPI void APIENTRY glGetTextureLevelParameterivEXT (GLuint, GLenum, GLint, GLenum, GLint *); GLAPI void APIENTRY glTextureImage3DEXT (GLuint, GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glTextureSubImage3DEXT (GLuint, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glCopyTextureSubImage3DEXT (GLuint, GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); GLAPI void APIENTRY glMultiTexParameterfEXT (GLenum, GLenum, GLenum, GLfloat); GLAPI void APIENTRY glMultiTexParameterfvEXT (GLenum, GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY glMultiTexParameteriEXT (GLenum, GLenum, GLenum, GLint); GLAPI void APIENTRY glMultiTexParameterivEXT (GLenum, GLenum, GLenum, const GLint *); GLAPI void APIENTRY glMultiTexImage1DEXT (GLenum, GLenum, GLint, GLenum, GLsizei, GLint, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glMultiTexImage2DEXT (GLenum, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glMultiTexSubImage1DEXT (GLenum, GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glMultiTexSubImage2DEXT (GLenum, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glCopyMultiTexImage1DEXT (GLenum, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint); GLAPI void APIENTRY glCopyMultiTexImage2DEXT (GLenum, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint); GLAPI void APIENTRY glCopyMultiTexSubImage1DEXT (GLenum, GLenum, GLint, GLint, GLint, GLint, GLsizei); GLAPI void APIENTRY glCopyMultiTexSubImage2DEXT (GLenum, GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); GLAPI void APIENTRY glGetMultiTexImageEXT (GLenum, GLenum, GLint, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY glGetMultiTexParameterfvEXT (GLenum, GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetMultiTexParameterivEXT (GLenum, GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetMultiTexLevelParameterfvEXT (GLenum, GLenum, GLint, GLenum, GLfloat *); GLAPI void APIENTRY glGetMultiTexLevelParameterivEXT (GLenum, GLenum, GLint, GLenum, GLint *); GLAPI void APIENTRY glMultiTexImage3DEXT (GLenum, GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glMultiTexSubImage3DEXT (GLenum, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glCopyMultiTexSubImage3DEXT (GLenum, GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); GLAPI void APIENTRY glBindMultiTextureEXT (GLenum, GLenum, GLuint); GLAPI void APIENTRY glEnableClientStateIndexedEXT (GLenum, GLuint); GLAPI void APIENTRY glDisableClientStateIndexedEXT (GLenum, GLuint); GLAPI void APIENTRY glMultiTexCoordPointerEXT (GLenum, GLint, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glMultiTexEnvfEXT (GLenum, GLenum, GLenum, GLfloat); GLAPI void APIENTRY glMultiTexEnvfvEXT (GLenum, GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY glMultiTexEnviEXT (GLenum, GLenum, GLenum, GLint); GLAPI void APIENTRY glMultiTexEnvivEXT (GLenum, GLenum, GLenum, const GLint *); GLAPI void APIENTRY glMultiTexGendEXT (GLenum, GLenum, GLenum, GLdouble); GLAPI void APIENTRY glMultiTexGendvEXT (GLenum, GLenum, GLenum, const GLdouble *); GLAPI void APIENTRY glMultiTexGenfEXT (GLenum, GLenum, GLenum, GLfloat); GLAPI void APIENTRY glMultiTexGenfvEXT (GLenum, GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY glMultiTexGeniEXT (GLenum, GLenum, GLenum, GLint); GLAPI void APIENTRY glMultiTexGenivEXT (GLenum, GLenum, GLenum, const GLint *); GLAPI void APIENTRY glGetMultiTexEnvfvEXT (GLenum, GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetMultiTexEnvivEXT (GLenum, GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetMultiTexGendvEXT (GLenum, GLenum, GLenum, GLdouble *); GLAPI void APIENTRY glGetMultiTexGenfvEXT (GLenum, GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetMultiTexGenivEXT (GLenum, GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetFloatIndexedvEXT (GLenum, GLuint, GLfloat *); GLAPI void APIENTRY glGetDoubleIndexedvEXT (GLenum, GLuint, GLdouble *); GLAPI void APIENTRY glGetPointerIndexedvEXT (GLenum, GLuint, GLvoid* *); GLAPI void APIENTRY glCompressedTextureImage3DEXT (GLuint, GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTextureImage2DEXT (GLuint, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTextureImage1DEXT (GLuint, GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTextureSubImage3DEXT (GLuint, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTextureSubImage2DEXT (GLuint, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTextureSubImage1DEXT (GLuint, GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glGetCompressedTextureImageEXT (GLuint, GLenum, GLint, GLvoid *); GLAPI void APIENTRY glCompressedMultiTexImage3DEXT (GLenum, GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedMultiTexImage2DEXT (GLenum, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedMultiTexImage1DEXT (GLenum, GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedMultiTexSubImage3DEXT (GLenum, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedMultiTexSubImage2DEXT (GLenum, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedMultiTexSubImage1DEXT (GLenum, GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glGetCompressedMultiTexImageEXT (GLenum, GLenum, GLint, GLvoid *); GLAPI void APIENTRY glNamedProgramStringEXT (GLuint, GLenum, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glNamedProgramLocalParameter4dEXT (GLuint, GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glNamedProgramLocalParameter4dvEXT (GLuint, GLenum, GLuint, const GLdouble *); GLAPI void APIENTRY glNamedProgramLocalParameter4fEXT (GLuint, GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glNamedProgramLocalParameter4fvEXT (GLuint, GLenum, GLuint, const GLfloat *); GLAPI void APIENTRY glGetNamedProgramLocalParameterdvEXT (GLuint, GLenum, GLuint, GLdouble *); GLAPI void APIENTRY glGetNamedProgramLocalParameterfvEXT (GLuint, GLenum, GLuint, GLfloat *); GLAPI void APIENTRY glGetNamedProgramivEXT (GLuint, GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetNamedProgramStringEXT (GLuint, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY glNamedProgramLocalParameters4fvEXT (GLuint, GLenum, GLuint, GLsizei, const GLfloat *); GLAPI void APIENTRY glNamedProgramLocalParameterI4iEXT (GLuint, GLenum, GLuint, GLint, GLint, GLint, GLint); GLAPI void APIENTRY glNamedProgramLocalParameterI4ivEXT (GLuint, GLenum, GLuint, const GLint *); GLAPI void APIENTRY glNamedProgramLocalParametersI4ivEXT (GLuint, GLenum, GLuint, GLsizei, const GLint *); GLAPI void APIENTRY glNamedProgramLocalParameterI4uiEXT (GLuint, GLenum, GLuint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glNamedProgramLocalParameterI4uivEXT (GLuint, GLenum, GLuint, const GLuint *); GLAPI void APIENTRY glNamedProgramLocalParametersI4uivEXT (GLuint, GLenum, GLuint, GLsizei, const GLuint *); GLAPI void APIENTRY glGetNamedProgramLocalParameterIivEXT (GLuint, GLenum, GLuint, GLint *); GLAPI void APIENTRY glGetNamedProgramLocalParameterIuivEXT (GLuint, GLenum, GLuint, GLuint *); GLAPI void APIENTRY glTextureParameterIivEXT (GLuint, GLenum, GLenum, const GLint *); GLAPI void APIENTRY glTextureParameterIuivEXT (GLuint, GLenum, GLenum, const GLuint *); GLAPI void APIENTRY glGetTextureParameterIivEXT (GLuint, GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetTextureParameterIuivEXT (GLuint, GLenum, GLenum, GLuint *); GLAPI void APIENTRY glMultiTexParameterIivEXT (GLenum, GLenum, GLenum, const GLint *); GLAPI void APIENTRY glMultiTexParameterIuivEXT (GLenum, GLenum, GLenum, const GLuint *); GLAPI void APIENTRY glGetMultiTexParameterIivEXT (GLenum, GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetMultiTexParameterIuivEXT (GLenum, GLenum, GLenum, GLuint *); GLAPI void APIENTRY glProgramUniform1fEXT (GLuint, GLint, GLfloat); GLAPI void APIENTRY glProgramUniform2fEXT (GLuint, GLint, GLfloat, GLfloat); GLAPI void APIENTRY glProgramUniform3fEXT (GLuint, GLint, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glProgramUniform4fEXT (GLuint, GLint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glProgramUniform1iEXT (GLuint, GLint, GLint); GLAPI void APIENTRY glProgramUniform2iEXT (GLuint, GLint, GLint, GLint); GLAPI void APIENTRY glProgramUniform3iEXT (GLuint, GLint, GLint, GLint, GLint); GLAPI void APIENTRY glProgramUniform4iEXT (GLuint, GLint, GLint, GLint, GLint, GLint); GLAPI void APIENTRY glProgramUniform1fvEXT (GLuint, GLint, GLsizei, const GLfloat *); GLAPI void APIENTRY glProgramUniform2fvEXT (GLuint, GLint, GLsizei, const GLfloat *); GLAPI void APIENTRY glProgramUniform3fvEXT (GLuint, GLint, GLsizei, const GLfloat *); GLAPI void APIENTRY glProgramUniform4fvEXT (GLuint, GLint, GLsizei, const GLfloat *); GLAPI void APIENTRY glProgramUniform1ivEXT (GLuint, GLint, GLsizei, const GLint *); GLAPI void APIENTRY glProgramUniform2ivEXT (GLuint, GLint, GLsizei, const GLint *); GLAPI void APIENTRY glProgramUniform3ivEXT (GLuint, GLint, GLsizei, const GLint *); GLAPI void APIENTRY glProgramUniform4ivEXT (GLuint, GLint, GLsizei, const GLint *); GLAPI void APIENTRY glProgramUniformMatrix2fvEXT (GLuint, GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY glProgramUniformMatrix3fvEXT (GLuint, GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY glProgramUniformMatrix4fvEXT (GLuint, GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY glProgramUniformMatrix2x3fvEXT (GLuint, GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY glProgramUniformMatrix3x2fvEXT (GLuint, GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY glProgramUniformMatrix2x4fvEXT (GLuint, GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY glProgramUniformMatrix4x2fvEXT (GLuint, GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY glProgramUniformMatrix3x4fvEXT (GLuint, GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint, GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY glProgramUniform1uiEXT (GLuint, GLint, GLuint); GLAPI void APIENTRY glProgramUniform2uiEXT (GLuint, GLint, GLuint, GLuint); GLAPI void APIENTRY glProgramUniform3uiEXT (GLuint, GLint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glProgramUniform4uiEXT (GLuint, GLint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glProgramUniform1uivEXT (GLuint, GLint, GLsizei, const GLuint *); GLAPI void APIENTRY glProgramUniform2uivEXT (GLuint, GLint, GLsizei, const GLuint *); GLAPI void APIENTRY glProgramUniform3uivEXT (GLuint, GLint, GLsizei, const GLuint *); GLAPI void APIENTRY glProgramUniform4uivEXT (GLuint, GLint, GLsizei, const GLuint *); GLAPI void APIENTRY glNamedBufferDataEXT (GLuint, GLsizeiptr, const GLvoid *, GLenum); GLAPI void APIENTRY glNamedBufferSubDataEXT (GLuint, GLintptr, GLsizeiptr, const GLvoid *); GLAPI GLvoid* APIENTRY glMapNamedBufferEXT (GLuint, GLenum); GLAPI GLboolean APIENTRY glUnmapNamedBufferEXT (GLuint); GLAPI void APIENTRY glGetNamedBufferParameterivEXT (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetNamedBufferPointervEXT (GLuint, GLenum, GLvoid* *); GLAPI void APIENTRY glGetNamedBufferSubDataEXT (GLuint, GLintptr, GLsizeiptr, GLvoid *); GLAPI void APIENTRY glTextureBufferEXT (GLuint, GLenum, GLenum, GLuint); GLAPI void APIENTRY glMultiTexBufferEXT (GLenum, GLenum, GLenum, GLuint); GLAPI void APIENTRY glNamedRenderbufferStorageEXT (GLuint, GLenum, GLsizei, GLsizei); GLAPI void APIENTRY glGetNamedRenderbufferParameterivEXT (GLuint, GLenum, GLint *); GLAPI GLenum APIENTRY glCheckNamedFramebufferStatusEXT (GLuint, GLenum); GLAPI void APIENTRY glNamedFramebufferTexture1DEXT (GLuint, GLenum, GLenum, GLuint, GLint); GLAPI void APIENTRY glNamedFramebufferTexture2DEXT (GLuint, GLenum, GLenum, GLuint, GLint); GLAPI void APIENTRY glNamedFramebufferTexture3DEXT (GLuint, GLenum, GLenum, GLuint, GLint, GLint); GLAPI void APIENTRY glNamedFramebufferRenderbufferEXT (GLuint, GLenum, GLenum, GLuint); GLAPI void APIENTRY glGetNamedFramebufferAttachmentParameterivEXT (GLuint, GLenum, GLenum, GLint *); GLAPI void APIENTRY glGenerateTextureMipmapEXT (GLuint, GLenum); GLAPI void APIENTRY glGenerateMultiTexMipmapEXT (GLenum, GLenum); GLAPI void APIENTRY glFramebufferDrawBufferEXT (GLuint, GLenum); GLAPI void APIENTRY glFramebufferDrawBuffersEXT (GLuint, GLsizei, const GLenum *); GLAPI void APIENTRY glFramebufferReadBufferEXT (GLuint, GLenum); GLAPI void APIENTRY glGetFramebufferParameterivEXT (GLuint, GLenum, GLint *); GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleEXT (GLuint, GLsizei, GLenum, GLsizei, GLsizei); GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleCoverageEXT (GLuint, GLsizei, GLsizei, GLenum, GLsizei, GLsizei); GLAPI void APIENTRY glNamedFramebufferTextureEXT (GLuint, GLenum, GLuint, GLint); GLAPI void APIENTRY glNamedFramebufferTextureLayerEXT (GLuint, GLenum, GLuint, GLint, GLint); GLAPI void APIENTRY glNamedFramebufferTextureFaceEXT (GLuint, GLenum, GLuint, GLint, GLenum); GLAPI void APIENTRY glTextureRenderbufferEXT (GLuint, GLenum, GLuint); GLAPI void APIENTRY glMultiTexRenderbufferEXT (GLenum, GLenum, GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); typedef void (APIENTRYP PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); typedef void (APIENTRYP PFNGLMATRIXLOADFEXTPROC) (GLenum mode, const GLfloat *m); typedef void (APIENTRYP PFNGLMATRIXLOADDEXTPROC) (GLenum mode, const GLdouble *m); typedef void (APIENTRYP PFNGLMATRIXMULTFEXTPROC) (GLenum mode, const GLfloat *m); typedef void (APIENTRYP PFNGLMATRIXMULTDEXTPROC) (GLenum mode, const GLdouble *m); typedef void (APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum mode); typedef void (APIENTRYP PFNGLMATRIXROTATEFEXTPROC) (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLMATRIXROTATEDEXTPROC) (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLMATRIXSCALEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLMATRIXSCALEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLMATRIXFRUSTUMEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); typedef void (APIENTRYP PFNGLMATRIXORTHOEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); typedef void (APIENTRYP PFNGLMATRIXPOPEXTPROC) (GLenum mode); typedef void (APIENTRYP PFNGLMATRIXPUSHEXTPROC) (GLenum mode); typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m); typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m); typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m); typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m); typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLBINDMULTITEXTUREEXTPROC) (GLenum texunit, GLenum target, GLuint texture); typedef void (APIENTRYP PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); typedef void (APIENTRYP PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); typedef void (APIENTRYP PFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); typedef void (APIENTRYP PFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params); typedef void (APIENTRYP PFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params); typedef void (APIENTRYP PFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum target, GLuint index, GLfloat *data); typedef void (APIENTRYP PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum target, GLuint index, GLdouble *data); typedef void (APIENTRYP PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLvoid* *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits); typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint lod, GLvoid *img); typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits); typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits); typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits); typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits); typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits); typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits); typedef void (APIENTRYP PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint lod, GLvoid *img); typedef void (APIENTRYP PFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const GLvoid *string); typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLdouble *params); typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLfloat *params); typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble *params); typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat *params); typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, GLvoid *string); typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params); typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLint *params); typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params); typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLuint *params); typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params); typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint *params); typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint *params); typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLuint *params); typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint *params); typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLuint *params); typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint *params); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const GLvoid *data, GLenum usage); typedef void (APIENTRYP PFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid *data); typedef GLvoid* (APIENTRYP PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access); typedef GLboolean (APIENTRYP PFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer); typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, GLvoid* *params); typedef void (APIENTRYP PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLvoid *data); typedef void (APIENTRYP PFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); typedef void (APIENTRYP PFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint *params); typedef GLenum (APIENTRYP PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target); typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target); typedef void (APIENTRYP PFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target); typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum *bufs); typedef void (APIENTRYP PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); typedef void (APIENTRYP PFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer); typedef void (APIENTRYP PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer); #endif #ifndef GL_EXT_vertex_array_bgra #define GL_EXT_vertex_array_bgra 1 #endif #ifndef GL_EXT_texture_swizzle #define GL_EXT_texture_swizzle 1 #endif #ifndef GL_NV_explicit_multisample #define GL_NV_explicit_multisample 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetMultisamplefvNV (GLenum, GLuint, GLfloat *); GLAPI void APIENTRY glSampleMaskIndexedNV (GLuint, GLbitfield); GLAPI void APIENTRY glTexRenderbufferNV (GLenum, GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVNVPROC) (GLenum pname, GLuint index, GLfloat *val); typedef void (APIENTRYP PFNGLSAMPLEMASKINDEXEDNVPROC) (GLuint index, GLbitfield mask); typedef void (APIENTRYP PFNGLTEXRENDERBUFFERNVPROC) (GLenum target, GLuint renderbuffer); #endif #ifndef GL_NV_transform_feedback2 #define GL_NV_transform_feedback2 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBindTransformFeedbackNV (GLenum, GLuint); GLAPI void APIENTRY glDeleteTransformFeedbacksNV (GLsizei, const GLuint *); GLAPI void APIENTRY glGenTransformFeedbacksNV (GLsizei, GLuint *); GLAPI GLboolean APIENTRY glIsTransformFeedbackNV (GLuint); GLAPI void APIENTRY glPauseTransformFeedbackNV (void); GLAPI void APIENTRY glResumeTransformFeedbackNV (void); GLAPI void APIENTRY glDrawTransformFeedbackNV (GLenum, GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKNVPROC) (GLenum target, GLuint id); typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSNVPROC) (GLsizei n, const GLuint *ids); typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSNVPROC) (GLsizei n, GLuint *ids); typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKNVPROC) (GLuint id); typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKNVPROC) (void); typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKNVPROC) (void); typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKNVPROC) (GLenum mode, GLuint id); #endif #ifndef GL_ATI_meminfo #define GL_ATI_meminfo 1 #endif #ifndef GL_AMD_performance_monitor #define GL_AMD_performance_monitor 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetPerfMonitorGroupsAMD (GLint *, GLsizei, GLuint *); GLAPI void APIENTRY glGetPerfMonitorCountersAMD (GLuint, GLint *, GLint *, GLsizei, GLuint *); GLAPI void APIENTRY glGetPerfMonitorGroupStringAMD (GLuint, GLsizei, GLsizei *, GLchar *); GLAPI void APIENTRY glGetPerfMonitorCounterStringAMD (GLuint, GLuint, GLsizei, GLsizei *, GLchar *); GLAPI void APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint, GLuint, GLenum, void *); GLAPI void APIENTRY glGenPerfMonitorsAMD (GLsizei, GLuint *); GLAPI void APIENTRY glDeletePerfMonitorsAMD (GLsizei, GLuint *); GLAPI void APIENTRY glSelectPerfMonitorCountersAMD (GLuint, GLboolean, GLuint, GLint, GLuint *); GLAPI void APIENTRY glBeginPerfMonitorAMD (GLuint); GLAPI void APIENTRY glEndPerfMonitorAMD (GLuint); GLAPI void APIENTRY glGetPerfMonitorCounterDataAMD (GLuint, GLenum, GLsizei, GLuint *, GLint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups); typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void *data); typedef void (APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); typedef void (APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); typedef void (APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList); typedef void (APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); typedef void (APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); #endif #ifndef GL_AMD_texture_texture4 #define GL_AMD_texture_texture4 1 #endif #ifndef GL_AMD_vertex_shader_tesselator #define GL_AMD_vertex_shader_tesselator 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTessellationFactorAMD (GLfloat); GLAPI void APIENTRY glTessellationModeAMD (GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTESSELLATIONFACTORAMDPROC) (GLfloat factor); typedef void (APIENTRYP PFNGLTESSELLATIONMODEAMDPROC) (GLenum mode); #endif #ifndef GL_EXT_provoking_vertex #define GL_EXT_provoking_vertex 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glProvokingVertexEXT (GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPROVOKINGVERTEXEXTPROC) (GLenum mode); #endif #ifndef GL_EXT_texture_snorm #define GL_EXT_texture_snorm 1 #endif #ifndef GL_AMD_draw_buffers_blend #define GL_AMD_draw_buffers_blend 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendFuncIndexedAMD (GLuint, GLenum, GLenum); GLAPI void APIENTRY glBlendFuncSeparateIndexedAMD (GLuint, GLenum, GLenum, GLenum, GLenum); GLAPI void APIENTRY glBlendEquationIndexedAMD (GLuint, GLenum); GLAPI void APIENTRY glBlendEquationSeparateIndexedAMD (GLuint, GLenum, GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDFUNCINDEXEDAMDPROC) (GLuint buf, GLenum src, GLenum dst); typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); typedef void (APIENTRYP PFNGLBLENDEQUATIONINDEXEDAMDPROC) (GLuint buf, GLenum mode); typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); #endif #ifndef GL_APPLE_texture_range #define GL_APPLE_texture_range 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTextureRangeAPPLE (GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glGetTexParameterPointervAPPLE (GLenum, GLenum, GLvoid* *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, const GLvoid *pointer); typedef void (APIENTRYP PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, GLvoid* *params); #endif #ifndef GL_APPLE_float_pixels #define GL_APPLE_float_pixels 1 #endif #ifndef GL_APPLE_vertex_program_evaluators #define GL_APPLE_vertex_program_evaluators 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glEnableVertexAttribAPPLE (GLuint, GLenum); GLAPI void APIENTRY glDisableVertexAttribAPPLE (GLuint, GLenum); GLAPI GLboolean APIENTRY glIsVertexAttribEnabledAPPLE (GLuint, GLenum); GLAPI void APIENTRY glMapVertexAttrib1dAPPLE (GLuint, GLuint, GLdouble, GLdouble, GLint, GLint, const GLdouble *); GLAPI void APIENTRY glMapVertexAttrib1fAPPLE (GLuint, GLuint, GLfloat, GLfloat, GLint, GLint, const GLfloat *); GLAPI void APIENTRY glMapVertexAttrib2dAPPLE (GLuint, GLuint, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, const GLdouble *); GLAPI void APIENTRY glMapVertexAttrib2fAPPLE (GLuint, GLuint, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, const GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); typedef GLboolean (APIENTRYP PFNGLISVERTEXATTRIBENABLEDAPPLEPROC) (GLuint index, GLenum pname); typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); #endif #ifndef GL_APPLE_aux_depth_stencil #define GL_APPLE_aux_depth_stencil 1 #endif #ifndef GL_APPLE_object_purgeable #define GL_APPLE_object_purgeable 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLenum APIENTRY glObjectPurgeableAPPLE (GLenum, GLuint, GLenum); GLAPI GLenum APIENTRY glObjectUnpurgeableAPPLE (GLenum, GLuint, GLenum); GLAPI void APIENTRY glGetObjectParameterivAPPLE (GLenum, GLuint, GLenum, GLint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLenum (APIENTRYP PFNGLOBJECTPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); typedef GLenum (APIENTRYP PFNGLOBJECTUNPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVAPPLEPROC) (GLenum objectType, GLuint name, GLenum pname, GLint *params); #endif #ifndef GL_APPLE_row_bytes #define GL_APPLE_row_bytes 1 #endif #ifndef GL_APPLE_rgb_422 #define GL_APPLE_rgb_422 1 #endif #ifndef GL_NV_video_capture #define GL_NV_video_capture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBeginVideoCaptureNV (GLuint); GLAPI void APIENTRY glBindVideoCaptureStreamBufferNV (GLuint, GLuint, GLenum, GLintptrARB); GLAPI void APIENTRY glBindVideoCaptureStreamTextureNV (GLuint, GLuint, GLenum, GLenum, GLuint); GLAPI void APIENTRY glEndVideoCaptureNV (GLuint); GLAPI void APIENTRY glGetVideoCaptureivNV (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetVideoCaptureStreamivNV (GLuint, GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetVideoCaptureStreamfvNV (GLuint, GLuint, GLenum, GLfloat *); GLAPI void APIENTRY glGetVideoCaptureStreamdvNV (GLuint, GLuint, GLenum, GLdouble *); GLAPI GLenum APIENTRY glVideoCaptureNV (GLuint, GLuint *, GLuint64EXT *); GLAPI void APIENTRY glVideoCaptureStreamParameterivNV (GLuint, GLuint, GLenum, const GLint *); GLAPI void APIENTRY glVideoCaptureStreamParameterfvNV (GLuint, GLuint, GLenum, const GLfloat *); GLAPI void APIENTRY glVideoCaptureStreamParameterdvNV (GLuint, GLuint, GLenum, const GLdouble *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBEGINVIDEOCAPTURENVPROC) (GLuint video_capture_slot); typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset); typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture); typedef void (APIENTRYP PFNGLENDVIDEOCAPTURENVPROC) (GLuint video_capture_slot); typedef void (APIENTRYP PFNGLGETVIDEOCAPTUREIVNVPROC) (GLuint video_capture_slot, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params); typedef GLenum (APIENTRYP PFNGLVIDEOCAPTURENVPROC) (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time); typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params); #endif #ifndef GL_NV_copy_image #define GL_NV_copy_image 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glCopyImageSubDataNV (GLuint, GLenum, GLint, GLint, GLint, GLint, GLuint, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOPYIMAGESUBDATANVPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); #endif #ifndef GL_EXT_separate_shader_objects #define GL_EXT_separate_shader_objects 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glUseShaderProgramEXT (GLenum, GLuint); GLAPI void APIENTRY glActiveProgramEXT (GLuint); GLAPI GLuint APIENTRY glCreateShaderProgramEXT (GLenum, const GLchar *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLUSESHADERPROGRAMEXTPROC) (GLenum type, GLuint program); typedef void (APIENTRYP PFNGLACTIVEPROGRAMEXTPROC) (GLuint program); typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMEXTPROC) (GLenum type, const GLchar *string); #endif #ifndef GL_NV_parameter_buffer_object2 #define GL_NV_parameter_buffer_object2 1 #endif #ifndef GL_NV_shader_buffer_load #define GL_NV_shader_buffer_load 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glMakeBufferResidentNV (GLenum, GLenum); GLAPI void APIENTRY glMakeBufferNonResidentNV (GLenum); GLAPI GLboolean APIENTRY glIsBufferResidentNV (GLenum); GLAPI void APIENTRY glNamedMakeBufferResidentNV (GLuint, GLenum); GLAPI void APIENTRY glNamedMakeBufferNonResidentNV (GLuint); GLAPI GLboolean APIENTRY glIsNamedBufferResidentNV (GLuint); GLAPI void APIENTRY glGetBufferParameterui64vNV (GLenum, GLenum, GLuint64EXT *); GLAPI void APIENTRY glGetNamedBufferParameterui64vNV (GLuint, GLenum, GLuint64EXT *); GLAPI void APIENTRY glGetIntegerui64vNV (GLenum, GLuint64EXT *); GLAPI void APIENTRY glUniformui64NV (GLint, GLuint64EXT); GLAPI void APIENTRY glUniformui64vNV (GLint, GLsizei, const GLuint64EXT *); GLAPI void APIENTRY glGetUniformui64vNV (GLuint, GLint, GLuint64EXT *); GLAPI void APIENTRY glProgramUniformui64NV (GLuint, GLint, GLuint64EXT); GLAPI void APIENTRY glProgramUniformui64vNV (GLuint, GLint, GLsizei, const GLuint64EXT *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLMAKEBUFFERRESIDENTNVPROC) (GLenum target, GLenum access); typedef void (APIENTRYP PFNGLMAKEBUFFERNONRESIDENTNVPROC) (GLenum target); typedef GLboolean (APIENTRYP PFNGLISBUFFERRESIDENTNVPROC) (GLenum target); typedef void (APIENTRYP PFNGLNAMEDMAKEBUFFERRESIDENTNVPROC) (GLuint buffer, GLenum access); typedef void (APIENTRYP PFNGLNAMEDMAKEBUFFERNONRESIDENTNVPROC) (GLuint buffer); typedef GLboolean (APIENTRYP PFNGLISNAMEDBUFFERRESIDENTNVPROC) (GLuint buffer); typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERUI64VNVPROC) (GLenum target, GLenum pname, GLuint64EXT *params); typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC) (GLuint buffer, GLenum pname, GLuint64EXT *params); typedef void (APIENTRYP PFNGLGETINTEGERUI64VNVPROC) (GLenum value, GLuint64EXT *result); typedef void (APIENTRYP PFNGLUNIFORMUI64NVPROC) (GLint location, GLuint64EXT value); typedef void (APIENTRYP PFNGLUNIFORMUI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); typedef void (APIENTRYP PFNGLGETUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLuint64EXT *params); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64NVPROC) (GLuint program, GLint location, GLuint64EXT value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); #endif #ifndef GL_NV_vertex_buffer_unified_memory #define GL_NV_vertex_buffer_unified_memory 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBufferAddressRangeNV (GLenum, GLuint, GLuint64EXT, GLsizeiptr); GLAPI void APIENTRY glVertexFormatNV (GLint, GLenum, GLsizei); GLAPI void APIENTRY glNormalFormatNV (GLenum, GLsizei); GLAPI void APIENTRY glColorFormatNV (GLint, GLenum, GLsizei); GLAPI void APIENTRY glIndexFormatNV (GLenum, GLsizei); GLAPI void APIENTRY glTexCoordFormatNV (GLint, GLenum, GLsizei); GLAPI void APIENTRY glEdgeFlagFormatNV (GLsizei); GLAPI void APIENTRY glSecondaryColorFormatNV (GLint, GLenum, GLsizei); GLAPI void APIENTRY glFogCoordFormatNV (GLenum, GLsizei); GLAPI void APIENTRY glVertexAttribFormatNV (GLuint, GLint, GLenum, GLboolean, GLsizei); GLAPI void APIENTRY glVertexAttribIFormatNV (GLuint, GLint, GLenum, GLsizei); GLAPI void APIENTRY glGetIntegerui64i_vNV (GLenum, GLuint, GLuint64EXT *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBUFFERADDRESSRANGENVPROC) (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length); typedef void (APIENTRYP PFNGLVERTEXFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); typedef void (APIENTRYP PFNGLNORMALFORMATNVPROC) (GLenum type, GLsizei stride); typedef void (APIENTRYP PFNGLCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); typedef void (APIENTRYP PFNGLINDEXFORMATNVPROC) (GLenum type, GLsizei stride); typedef void (APIENTRYP PFNGLTEXCOORDFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); typedef void (APIENTRYP PFNGLEDGEFLAGFORMATNVPROC) (GLsizei stride); typedef void (APIENTRYP PFNGLSECONDARYCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); typedef void (APIENTRYP PFNGLFOGCOORDFORMATNVPROC) (GLenum type, GLsizei stride); typedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride); typedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); typedef void (APIENTRYP PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT *result); #endif #ifndef GL_NV_texture_barrier #define GL_NV_texture_barrier 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTextureBarrierNV (void); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXTUREBARRIERNVPROC) (void); #endif #ifdef __cplusplus } #endif #endif alien-arena-7.66+dfsg/source/ref_gl/qgl.h0000600000175000017500000014465212161402007017316 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* ** QGL.H */ #ifndef __QGL_H__ #define __QGL_H__ #if defined WIN32_VARIANT # include #endif #include #if defined WIN32_VARIANT # include "glext.h" #endif qboolean QGL_Init( const char *dllname ); void QGL_Shutdown( void ); #ifndef APIENTRY # define APIENTRY #endif extern void ( APIENTRY * qglAccum )(GLenum op, GLfloat value); extern void ( APIENTRY * qglAlphaFunc )(GLenum func, GLclampf ref); extern GLboolean ( APIENTRY * qglAreTexturesResident )(GLsizei n, const GLuint *textures, GLboolean *residences); extern void ( APIENTRY * qglArrayElement )(GLint i); extern void ( APIENTRY * qglBegin )(GLenum mode); extern void ( APIENTRY * qglBindTexture )(GLenum target, GLuint texture); extern void ( APIENTRY * qglBitmap )(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); extern void ( APIENTRY * qglBlendFunc )(GLenum sfactor, GLenum dfactor); extern void ( APIENTRY * qglCallList )(GLuint list); extern void ( APIENTRY * qglCallLists )(GLsizei n, GLenum type, const GLvoid *lists); extern void ( APIENTRY * qglClear )(GLbitfield mask); extern void ( APIENTRY * qglClearAccum )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); extern void ( APIENTRY * qglClearColor )(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); extern void ( APIENTRY * qglClearDepth )(GLclampd depth); extern void ( APIENTRY * qglClearIndex )(GLfloat c); extern void ( APIENTRY * qglClearStencil )(GLint s); extern void ( APIENTRY * qglClipPlane )(GLenum plane, const GLdouble *equation); extern void ( APIENTRY * qglColor3b )(GLbyte red, GLbyte green, GLbyte blue); extern void ( APIENTRY * qglColor3bv )(const GLbyte *v); extern void ( APIENTRY * qglColor3d )(GLdouble red, GLdouble green, GLdouble blue); extern void ( APIENTRY * qglColor3dv )(const GLdouble *v); extern void ( APIENTRY * qglColor3f )(GLfloat red, GLfloat green, GLfloat blue); extern void ( APIENTRY * qglColor3fv )(const GLfloat *v); extern void ( APIENTRY * qglColor3i )(GLint red, GLint green, GLint blue); extern void ( APIENTRY * qglColor3iv )(const GLint *v); extern void ( APIENTRY * qglColor3s )(GLshort red, GLshort green, GLshort blue); extern void ( APIENTRY * qglColor3sv )(const GLshort *v); extern void ( APIENTRY * qglColor3ub )(GLubyte red, GLubyte green, GLubyte blue); extern void ( APIENTRY * qglColor3ubv )(const GLubyte *v); extern void ( APIENTRY * qglColor3ui )(GLuint red, GLuint green, GLuint blue); extern void ( APIENTRY * qglColor3uiv )(const GLuint *v); extern void ( APIENTRY * qglColor3us )(GLushort red, GLushort green, GLushort blue); extern void ( APIENTRY * qglColor3usv )(const GLushort *v); extern void ( APIENTRY * qglColor4b )(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); extern void ( APIENTRY * qglColor4bv )(const GLbyte *v); extern void ( APIENTRY * qglColor4d )(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); extern void ( APIENTRY * qglColor4dv )(const GLdouble *v); extern void ( APIENTRY * qglColor4f )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); extern void ( APIENTRY * qglColor4fv )(const GLfloat *v); extern void ( APIENTRY * qglColor4i )(GLint red, GLint green, GLint blue, GLint alpha); extern void ( APIENTRY * qglColor4iv )(const GLint *v); extern void ( APIENTRY * qglColor4s )(GLshort red, GLshort green, GLshort blue, GLshort alpha); extern void ( APIENTRY * qglColor4sv )(const GLshort *v); extern void ( APIENTRY * qglColor4ub )(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); extern void ( APIENTRY * qglColor4ubv )(const GLubyte *v); extern void ( APIENTRY * qglColor4ui )(GLuint red, GLuint green, GLuint blue, GLuint alpha); extern void ( APIENTRY * qglColor4uiv )(const GLuint *v); extern void ( APIENTRY * qglColor4us )(GLushort red, GLushort green, GLushort blue, GLushort alpha); extern void ( APIENTRY * qglColor4usv )(const GLushort *v); extern void ( APIENTRY * qglColorMask )(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); extern void ( APIENTRY * qglColorMaterial )(GLenum face, GLenum mode); extern void ( APIENTRY * qglColorPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); extern void ( APIENTRY * qglCopyPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); extern void ( APIENTRY * qglCopyTexImage1D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); extern void ( APIENTRY * qglCopyTexImage2D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); extern void ( APIENTRY * qglCopyTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); extern void ( APIENTRY * qglCopyTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); extern void ( APIENTRY * qglCullFace )(GLenum mode); extern void ( APIENTRY * qglDeleteLists )(GLuint list, GLsizei range); extern void ( APIENTRY * qglDeleteTextures )(GLsizei n, const GLuint *textures); extern void ( APIENTRY * qglDepthFunc )(GLenum func); extern void ( APIENTRY * qglDepthMask )(GLboolean flag); extern void ( APIENTRY * qglDepthRange )(GLclampd zNear, GLclampd zFar); extern void ( APIENTRY * qglDisable )(GLenum cap); extern void ( APIENTRY * qglDisableClientState )(GLenum array); extern void ( APIENTRY * qglDrawArrays )(GLenum mode, GLint first, GLsizei count); extern void ( APIENTRY * qglDrawBuffer )(GLenum mode); extern void ( APIENTRY * qglDrawElements )(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); extern void ( APIENTRY * qglDrawRangeElements )(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); extern void ( APIENTRY * qglDrawPixels )(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); extern void ( APIENTRY * qglEdgeFlag )(GLboolean flag); extern void ( APIENTRY * qglEdgeFlagPointer )(GLsizei stride, const GLvoid *pointer); extern void ( APIENTRY * qglEdgeFlagv )(const GLboolean *flag); extern void ( APIENTRY * qglEnable )(GLenum cap); extern void ( APIENTRY * qglEnableClientState )(GLenum array); extern void ( APIENTRY * qglEnd )(void); extern void ( APIENTRY * qglEndList )(void); extern void ( APIENTRY * qglEvalCoord1d )(GLdouble u); extern void ( APIENTRY * qglEvalCoord1dv )(const GLdouble *u); extern void ( APIENTRY * qglEvalCoord1f )(GLfloat u); extern void ( APIENTRY * qglEvalCoord1fv )(const GLfloat *u); extern void ( APIENTRY * qglEvalCoord2d )(GLdouble u, GLdouble v); extern void ( APIENTRY * qglEvalCoord2dv )(const GLdouble *u); extern void ( APIENTRY * qglEvalCoord2f )(GLfloat u, GLfloat v); extern void ( APIENTRY * qglEvalCoord2fv )(const GLfloat *u); extern void ( APIENTRY * qglEvalMesh1 )(GLenum mode, GLint i1, GLint i2); extern void ( APIENTRY * qglEvalMesh2 )(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); extern void ( APIENTRY * qglEvalPoint1 )(GLint i); extern void ( APIENTRY * qglEvalPoint2 )(GLint i, GLint j); extern void ( APIENTRY * qglFeedbackBuffer )(GLsizei size, GLenum type, GLfloat *buffer); extern void ( APIENTRY * qglFinish )(void); extern void ( APIENTRY * qglFlush )(void); extern void ( APIENTRY * qglFogf )(GLenum pname, GLfloat param); extern void ( APIENTRY * qglFogfv )(GLenum pname, const GLfloat *params); extern void ( APIENTRY * qglFogi )(GLenum pname, GLint param); extern void ( APIENTRY * qglFogiv )(GLenum pname, const GLint *params); extern void ( APIENTRY * qglFrontFace )(GLenum mode); extern void ( APIENTRY * qglFrustum )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); extern GLuint ( APIENTRY * qglGenLists )(GLsizei range); extern void ( APIENTRY * qglGenTextures )(GLsizei n, GLuint *textures); extern void ( APIENTRY * qglGetBooleanv )(GLenum pname, GLboolean *params); extern void ( APIENTRY * qglGetClipPlane )(GLenum plane, GLdouble *equation); extern void ( APIENTRY * qglGetDoublev )(GLenum pname, GLdouble *params); extern GLenum ( APIENTRY * qglGetError )(void); extern void ( APIENTRY * qglGetFloatv )(GLenum pname, GLfloat *params); extern void ( APIENTRY * qglGetIntegerv )(GLenum pname, GLint *params); extern void ( APIENTRY * qglGetLightfv )(GLenum light, GLenum pname, GLfloat *params); extern void ( APIENTRY * qglGetLightiv )(GLenum light, GLenum pname, GLint *params); extern void ( APIENTRY * qglGetMapdv )(GLenum target, GLenum query, GLdouble *v); extern void ( APIENTRY * qglGetMapfv )(GLenum target, GLenum query, GLfloat *v); extern void ( APIENTRY * qglGetMapiv )(GLenum target, GLenum query, GLint *v); extern void ( APIENTRY * qglGetMaterialfv )(GLenum face, GLenum pname, GLfloat *params); extern void ( APIENTRY * qglGetMaterialiv )(GLenum face, GLenum pname, GLint *params); extern void ( APIENTRY * qglGetPixelMapfv )(GLenum map, GLfloat *values); extern void ( APIENTRY * qglGetPixelMapuiv )(GLenum map, GLuint *values); extern void ( APIENTRY * qglGetPixelMapusv )(GLenum map, GLushort *values); extern void ( APIENTRY * qglGetPointerv )(GLenum pname, GLvoid* *params); extern void ( APIENTRY * qglGetPolygonStipple )(GLubyte *mask); extern const GLubyte * ( APIENTRY * qglGetString )(GLenum name); extern void ( APIENTRY * qglGetTexEnvfv )(GLenum target, GLenum pname, GLfloat *params); extern void ( APIENTRY * qglGetTexEnviv )(GLenum target, GLenum pname, GLint *params); extern void ( APIENTRY * qglGetTexGendv )(GLenum coord, GLenum pname, GLdouble *params); extern void ( APIENTRY * qglGetTexGenfv )(GLenum coord, GLenum pname, GLfloat *params); extern void ( APIENTRY * qglGetTexGeniv )(GLenum coord, GLenum pname, GLint *params); extern void ( APIENTRY * qglGetTexImage )(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); extern void ( APIENTRY * qglGetTexLevelParameterfv )(GLenum target, GLint level, GLenum pname, GLfloat *params); extern void ( APIENTRY * qglGetTexLevelParameteriv )(GLenum target, GLint level, GLenum pname, GLint *params); extern void ( APIENTRY * qglGetTexParameterfv )(GLenum target, GLenum pname, GLfloat *params); extern void ( APIENTRY * qglGetTexParameteriv )(GLenum target, GLenum pname, GLint *params); extern void ( APIENTRY * qglHint )(GLenum target, GLenum mode); extern void ( APIENTRY * qglIndexMask )(GLuint mask); extern void ( APIENTRY * qglIndexPointer )(GLenum type, GLsizei stride, const GLvoid *pointer); extern void ( APIENTRY * qglIndexd )(GLdouble c); extern void ( APIENTRY * qglIndexdv )(const GLdouble *c); extern void ( APIENTRY * qglIndexf )(GLfloat c); extern void ( APIENTRY * qglIndexfv )(const GLfloat *c); extern void ( APIENTRY * qglIndexi )(GLint c); extern void ( APIENTRY * qglIndexiv )(const GLint *c); extern void ( APIENTRY * qglIndexs )(GLshort c); extern void ( APIENTRY * qglIndexsv )(const GLshort *c); extern void ( APIENTRY * qglIndexub )(GLubyte c); extern void ( APIENTRY * qglIndexubv )(const GLubyte *c); extern void ( APIENTRY * qglInitNames )(void); extern void ( APIENTRY * qglInterleavedArrays )(GLenum format, GLsizei stride, const GLvoid *pointer); extern GLboolean ( APIENTRY * qglIsEnabled )(GLenum cap); extern GLboolean ( APIENTRY * qglIsList )(GLuint list); extern GLboolean ( APIENTRY * qglIsTexture )(GLuint texture); extern void ( APIENTRY * qglLightModelf )(GLenum pname, GLfloat param); extern void ( APIENTRY * qglLightModelfv )(GLenum pname, const GLfloat *params); extern void ( APIENTRY * qglLightModeli )(GLenum pname, GLint param); extern void ( APIENTRY * qglLightModeliv )(GLenum pname, const GLint *params); extern void ( APIENTRY * qglLightf )(GLenum light, GLenum pname, GLfloat param); extern void ( APIENTRY * qglLightfv )(GLenum light, GLenum pname, const GLfloat *params); extern void ( APIENTRY * qglLighti )(GLenum light, GLenum pname, GLint param); extern void ( APIENTRY * qglLightiv )(GLenum light, GLenum pname, const GLint *params); extern void ( APIENTRY * qglLineStipple )(GLint factor, GLushort pattern); extern void ( APIENTRY * qglLineWidth )(GLfloat width); extern void ( APIENTRY * qglListBase )(GLuint base); extern void ( APIENTRY * qglLoadIdentity )(void); extern void ( APIENTRY * qglLoadMatrixd )(const GLdouble *m); extern void ( APIENTRY * qglLoadMatrixf )(const GLfloat *m); extern void ( APIENTRY * qglLoadName )(GLuint name); extern void ( APIENTRY * qglLogicOp )(GLenum opcode); extern void ( APIENTRY * qglMap1d )(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); extern void ( APIENTRY * qglMap1f )(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); extern void ( APIENTRY * qglMap2d )(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); extern void ( APIENTRY * qglMap2f )(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); extern void ( APIENTRY * qglMapGrid1d )(GLint un, GLdouble u1, GLdouble u2); extern void ( APIENTRY * qglMapGrid1f )(GLint un, GLfloat u1, GLfloat u2); extern void ( APIENTRY * qglMapGrid2d )(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); extern void ( APIENTRY * qglMapGrid2f )(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); extern void ( APIENTRY * qglMaterialf )(GLenum face, GLenum pname, GLfloat param); extern void ( APIENTRY * qglMaterialfv )(GLenum face, GLenum pname, const GLfloat *params); extern void ( APIENTRY * qglMateriali )(GLenum face, GLenum pname, GLint param); extern void ( APIENTRY * qglMaterialiv )(GLenum face, GLenum pname, const GLint *params); extern void ( APIENTRY * qglMatrixMode )(GLenum mode); extern void ( APIENTRY * qglMultMatrixd )(const GLdouble *m); extern void ( APIENTRY * qglMultMatrixf )(const GLfloat *m); extern void ( APIENTRY * qglNewList )(GLuint list, GLenum mode); extern void ( APIENTRY * qglNormal3b )(GLbyte nx, GLbyte ny, GLbyte nz); extern void ( APIENTRY * qglNormal3bv )(const GLbyte *v); extern void ( APIENTRY * qglNormal3d )(GLdouble nx, GLdouble ny, GLdouble nz); extern void ( APIENTRY * qglNormal3dv )(const GLdouble *v); extern void ( APIENTRY * qglNormal3f )(GLfloat nx, GLfloat ny, GLfloat nz); extern void ( APIENTRY * qglNormal3fv )(const GLfloat *v); extern void ( APIENTRY * qglNormal3i )(GLint nx, GLint ny, GLint nz); extern void ( APIENTRY * qglNormal3iv )(const GLint *v); extern void ( APIENTRY * qglNormal3s )(GLshort nx, GLshort ny, GLshort nz); extern void ( APIENTRY * qglNormal3sv )(const GLshort *v); extern void ( APIENTRY * qglNormalPointer )(GLenum type, GLsizei stride, const GLvoid *pointer); extern void ( APIENTRY * qglOrtho )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); extern void ( APIENTRY * qglPassThrough )(GLfloat token); extern void ( APIENTRY * qglPixelMapfv )(GLenum map, GLsizei mapsize, const GLfloat *values); extern void ( APIENTRY * qglPixelMapuiv )(GLenum map, GLsizei mapsize, const GLuint *values); extern void ( APIENTRY * qglPixelMapusv )(GLenum map, GLsizei mapsize, const GLushort *values); extern void ( APIENTRY * qglPixelStoref )(GLenum pname, GLfloat param); extern void ( APIENTRY * qglPixelStorei )(GLenum pname, GLint param); extern void ( APIENTRY * qglPixelTransferf )(GLenum pname, GLfloat param); extern void ( APIENTRY * qglPixelTransferi )(GLenum pname, GLint param); extern void ( APIENTRY * qglPixelZoom )(GLfloat xfactor, GLfloat yfactor); extern void ( APIENTRY * qglPointSize )(GLfloat size); extern void ( APIENTRY * qglPolygonMode )(GLenum face, GLenum mode); extern void ( APIENTRY * qglPolygonOffset )(GLfloat factor, GLfloat units); extern void ( APIENTRY * qglPolygonStipple )(const GLubyte *mask); extern void ( APIENTRY * qglPopAttrib )(void); extern void ( APIENTRY * qglPopClientAttrib )(void); extern void ( APIENTRY * qglPopMatrix )(void); extern void ( APIENTRY * qglPopName )(void); extern void ( APIENTRY * qglPrioritizeTextures )(GLsizei n, const GLuint *textures, const GLclampf *priorities); extern void ( APIENTRY * qglPushAttrib )(GLbitfield mask); extern void ( APIENTRY * qglPushClientAttrib )(GLbitfield mask); extern void ( APIENTRY * qglPushMatrix )(void); extern void ( APIENTRY * qglPushName )(GLuint name); extern void ( APIENTRY * qglRasterPos2d )(GLdouble x, GLdouble y); extern void ( APIENTRY * qglRasterPos2dv )(const GLdouble *v); extern void ( APIENTRY * qglRasterPos2f )(GLfloat x, GLfloat y); extern void ( APIENTRY * qglRasterPos2fv )(const GLfloat *v); extern void ( APIENTRY * qglRasterPos2i )(GLint x, GLint y); extern void ( APIENTRY * qglRasterPos2iv )(const GLint *v); extern void ( APIENTRY * qglRasterPos2s )(GLshort x, GLshort y); extern void ( APIENTRY * qglRasterPos2sv )(const GLshort *v); extern void ( APIENTRY * qglRasterPos3d )(GLdouble x, GLdouble y, GLdouble z); extern void ( APIENTRY * qglRasterPos3dv )(const GLdouble *v); extern void ( APIENTRY * qglRasterPos3f )(GLfloat x, GLfloat y, GLfloat z); extern void ( APIENTRY * qglRasterPos3fv )(const GLfloat *v); extern void ( APIENTRY * qglRasterPos3i )(GLint x, GLint y, GLint z); extern void ( APIENTRY * qglRasterPos3iv )(const GLint *v); extern void ( APIENTRY * qglRasterPos3s )(GLshort x, GLshort y, GLshort z); extern void ( APIENTRY * qglRasterPos3sv )(const GLshort *v); extern void ( APIENTRY * qglRasterPos4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w); extern void ( APIENTRY * qglRasterPos4dv )(const GLdouble *v); extern void ( APIENTRY * qglRasterPos4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w); extern void ( APIENTRY * qglRasterPos4fv )(const GLfloat *v); extern void ( APIENTRY * qglRasterPos4i )(GLint x, GLint y, GLint z, GLint w); extern void ( APIENTRY * qglRasterPos4iv )(const GLint *v); extern void ( APIENTRY * qglRasterPos4s )(GLshort x, GLshort y, GLshort z, GLshort w); extern void ( APIENTRY * qglRasterPos4sv )(const GLshort *v); extern void ( APIENTRY * qglReadBuffer )(GLenum mode); extern void ( APIENTRY * qglReadPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); extern void ( APIENTRY * qglRectd )(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); extern void ( APIENTRY * qglRectdv )(const GLdouble *v1, const GLdouble *v2); extern void ( APIENTRY * qglRectf )(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); extern void ( APIENTRY * qglRectfv )(const GLfloat *v1, const GLfloat *v2); extern void ( APIENTRY * qglRecti )(GLint x1, GLint y1, GLint x2, GLint y2); extern void ( APIENTRY * qglRectiv )(const GLint *v1, const GLint *v2); extern void ( APIENTRY * qglRects )(GLshort x1, GLshort y1, GLshort x2, GLshort y2); extern void ( APIENTRY * qglRectsv )(const GLshort *v1, const GLshort *v2); extern GLint ( APIENTRY * qglRenderMode )(GLenum mode); extern void ( APIENTRY * qglRotated )(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); extern void ( APIENTRY * qglRotatef )(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); extern void ( APIENTRY * qglScaled )(GLdouble x, GLdouble y, GLdouble z); extern void ( APIENTRY * qglScalef )(GLfloat x, GLfloat y, GLfloat z); extern void ( APIENTRY * qglScissor )(GLint x, GLint y, GLsizei width, GLsizei height); extern void ( APIENTRY * qglSelectBuffer )(GLsizei size, GLuint *buffer); extern void ( APIENTRY * qglShadeModel )(GLenum mode); extern void ( APIENTRY * qglStencilFunc )(GLenum func, GLint ref, GLuint mask); extern void ( APIENTRY * qglStencilMask )(GLuint mask); extern void ( APIENTRY * qglStencilOp )(GLenum fail, GLenum zfail, GLenum zpass); extern void ( APIENTRY * qglTexCoord1d )(GLdouble s); extern void ( APIENTRY * qglTexCoord1dv )(const GLdouble *v); extern void ( APIENTRY * qglTexCoord1f )(GLfloat s); extern void ( APIENTRY * qglTexCoord1fv )(const GLfloat *v); extern void ( APIENTRY * qglTexCoord1i )(GLint s); extern void ( APIENTRY * qglTexCoord1iv )(const GLint *v); extern void ( APIENTRY * qglTexCoord1s )(GLshort s); extern void ( APIENTRY * qglTexCoord1sv )(const GLshort *v); extern void ( APIENTRY * qglTexCoord2d )(GLdouble s, GLdouble t); extern void ( APIENTRY * qglTexCoord2dv )(const GLdouble *v); extern void ( APIENTRY * qglTexCoord2f )(GLfloat s, GLfloat t); extern void ( APIENTRY * qglTexCoord2fv )(const GLfloat *v); extern void ( APIENTRY * qglTexCoord2i )(GLint s, GLint t); extern void ( APIENTRY * qglTexCoord2iv )(const GLint *v); extern void ( APIENTRY * qglTexCoord2s )(GLshort s, GLshort t); extern void ( APIENTRY * qglTexCoord2sv )(const GLshort *v); extern void ( APIENTRY * qglTexCoord3d )(GLdouble s, GLdouble t, GLdouble r); extern void ( APIENTRY * qglTexCoord3dv )(const GLdouble *v); extern void ( APIENTRY * qglTexCoord3f )(GLfloat s, GLfloat t, GLfloat r); extern void ( APIENTRY * qglTexCoord3fv )(const GLfloat *v); extern void ( APIENTRY * qglTexCoord3i )(GLint s, GLint t, GLint r); extern void ( APIENTRY * qglTexCoord3iv )(const GLint *v); extern void ( APIENTRY * qglTexCoord3s )(GLshort s, GLshort t, GLshort r); extern void ( APIENTRY * qglTexCoord3sv )(const GLshort *v); extern void ( APIENTRY * qglTexCoord4d )(GLdouble s, GLdouble t, GLdouble r, GLdouble q); extern void ( APIENTRY * qglTexCoord4dv )(const GLdouble *v); extern void ( APIENTRY * qglTexCoord4f )(GLfloat s, GLfloat t, GLfloat r, GLfloat q); extern void ( APIENTRY * qglTexCoord4fv )(const GLfloat *v); extern void ( APIENTRY * qglTexCoord4i )(GLint s, GLint t, GLint r, GLint q); extern void ( APIENTRY * qglTexCoord4iv )(const GLint *v); extern void ( APIENTRY * qglTexCoord4s )(GLshort s, GLshort t, GLshort r, GLshort q); extern void ( APIENTRY * qglTexCoord4sv )(const GLshort *v); extern void ( APIENTRY * qglTexCoordPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); extern void ( APIENTRY * qglTexEnvf )(GLenum target, GLenum pname, GLfloat param); extern void ( APIENTRY * qglTexEnvfv )(GLenum target, GLenum pname, const GLfloat *params); extern void ( APIENTRY * qglTexEnvi )(GLenum target, GLenum pname, GLint param); extern void ( APIENTRY * qglTexEnviv )(GLenum target, GLenum pname, const GLint *params); extern void ( APIENTRY * qglTexGend )(GLenum coord, GLenum pname, GLdouble param); extern void ( APIENTRY * qglTexGendv )(GLenum coord, GLenum pname, const GLdouble *params); extern void ( APIENTRY * qglTexGenf )(GLenum coord, GLenum pname, GLfloat param); extern void ( APIENTRY * qglTexGenfv )(GLenum coord, GLenum pname, const GLfloat *params); extern void ( APIENTRY * qglTexGeni )(GLenum coord, GLenum pname, GLint param); extern void ( APIENTRY * qglTexGeniv )(GLenum coord, GLenum pname, const GLint *params); extern void ( APIENTRY * qglTexImage1D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); extern void ( APIENTRY * qglTexImage2D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); extern void ( APIENTRY * qglTexParameterf )(GLenum target, GLenum pname, GLfloat param); extern void ( APIENTRY * qglTexParameterfv )(GLenum target, GLenum pname, const GLfloat *params); extern void ( APIENTRY * qglTexParameteri )(GLenum target, GLenum pname, GLint param); extern void ( APIENTRY * qglTexParameteriv )(GLenum target, GLenum pname, const GLint *params); extern void ( APIENTRY * qglTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); extern void ( APIENTRY * qglTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); extern void ( APIENTRY * qglTranslated )(GLdouble x, GLdouble y, GLdouble z); extern void ( APIENTRY * qglTranslatef )(GLfloat x, GLfloat y, GLfloat z); extern void ( APIENTRY * qglVertex2d )(GLdouble x, GLdouble y); extern void ( APIENTRY * qglVertex2dv )(const GLdouble *v); extern void ( APIENTRY * qglVertex2f )(GLfloat x, GLfloat y); extern void ( APIENTRY * qglVertex2fv )(const GLfloat *v); extern void ( APIENTRY * qglVertex2i )(GLint x, GLint y); extern void ( APIENTRY * qglVertex2iv )(const GLint *v); extern void ( APIENTRY * qglVertex2s )(GLshort x, GLshort y); extern void ( APIENTRY * qglVertex2sv )(const GLshort *v); extern void ( APIENTRY * qglVertex3d )(GLdouble x, GLdouble y, GLdouble z); extern void ( APIENTRY * qglVertex3dv )(const GLdouble *v); extern void ( APIENTRY * qglVertex3f )(GLfloat x, GLfloat y, GLfloat z); extern void ( APIENTRY * qglVertex3fv )(const GLfloat *v); extern void ( APIENTRY * qglVertex3i )(GLint x, GLint y, GLint z); extern void ( APIENTRY * qglVertex3iv )(const GLint *v); extern void ( APIENTRY * qglVertex3s )(GLshort x, GLshort y, GLshort z); extern void ( APIENTRY * qglVertex3sv )(const GLshort *v); extern void ( APIENTRY * qglVertex4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w); extern void ( APIENTRY * qglVertex4dv )(const GLdouble *v); extern void ( APIENTRY * qglVertex4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w); extern void ( APIENTRY * qglVertex4fv )(const GLfloat *v); extern void ( APIENTRY * qglVertex4i )(GLint x, GLint y, GLint z, GLint w); extern void ( APIENTRY * qglVertex4iv )(const GLint *v); extern void ( APIENTRY * qglVertex4s )(GLshort x, GLshort y, GLshort z, GLshort w); extern void ( APIENTRY * qglVertex4sv )(const GLshort *v); extern void ( APIENTRY * qglVertexPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); extern void ( APIENTRY * qglViewport )(GLint x, GLint y, GLsizei width, GLsizei height); extern void ( APIENTRY * qglPointParameterfEXT)( GLenum param, GLfloat value ); extern void ( APIENTRY * qglPointParameterfvEXT)( GLenum param, const GLfloat *value ); extern void ( APIENTRY * qglColorTableEXT)( int, int, int, int, int, const void * ); extern void ( APIENTRY * qglLockArraysEXT) (int , int); extern void ( APIENTRY * qglUnlockArraysEXT) (void); extern void ( APIENTRY * qglMTexCoord2fARB)( GLenum, GLfloat, GLfloat ); extern void ( APIENTRY * qglMTexCoord3fARB)( GLenum, GLfloat, GLfloat, GLfloat ); extern void ( APIENTRY * qglSelectTextureARB)( GLenum ); extern void ( APIENTRY * qglActiveTextureARB)( GLenum ); extern void ( APIENTRY * qglClientActiveTextureARB)( GLenum ); extern void ( APIENTRY * qglMultiTexCoord3fvARB)( GLenum, GLfloat * ); //SEPARATE STENCIL typedef void (APIENTRY * glStencilFuncSeparatePROC)(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); typedef void (APIENTRY * glStencilOpSeparatePROC)(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); typedef void (APIENTRY * glStencilMaskSeparatePROC)(GLenum face, GLuint mask); //VBO #ifndef GL_ARB_vertex_buffer_object /* GL types for handling large vertex buffer objects */ typedef ptrdiff_t GLintptrARB; typedef ptrdiff_t GLsizeiptrARB; #endif extern GLvoid (APIENTRY * qglBindBufferARB)(GLenum target, GLuint buffer); extern GLvoid (APIENTRY * qglDeleteBuffersARB)(GLsizei n, const GLuint *buffers); extern GLvoid (APIENTRY * qglGenBuffersARB)(GLsizei n, GLuint *buffers); extern GLvoid (APIENTRY * qglBufferDataARB)(GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage); extern GLvoid (APIENTRY * qglBufferSubDataARB)(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data); #ifndef GL_ARB_vertex_buffer_object #define GL_BUFFER_SIZE_ARB 0x8764 #define GL_BUFFER_USAGE_ARB 0x8765 #define GL_ARRAY_BUFFER_ARB 0x8892 #define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 #define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 #define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 #define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 #define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 #define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 #define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 #define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A #define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B #define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C #define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D #define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E #define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F #define GL_READ_ONLY_ARB 0x88B8 #define GL_WRITE_ONLY_ARB 0x88B9 #define GL_READ_WRITE_ARB 0x88BA #define GL_BUFFER_ACCESS_ARB 0x88BB #define GL_BUFFER_MAPPED_ARB 0x88BC #define GL_BUFFER_MAP_POINTER_ARB 0x88BD #define GL_STREAM_DRAW_ARB 0x88E0 #define GL_STREAM_READ_ARB 0x88E1 #define GL_STREAM_COPY_ARB 0x88E2 #define GL_STATIC_DRAW_ARB 0x88E4 #define GL_STATIC_READ_ARB 0x88E5 #define GL_STATIC_COPY_ARB 0x88E6 #define GL_DYNAMIC_DRAW_ARB 0x88E8 #define GL_DYNAMIC_READ_ARB 0x88E9 #define GL_DYNAMIC_COPY_ARB 0x88EA #endif //END VBO #if 0 #if !defined UNIX_VARIANT // jitwater - fragment programs (pixel shaders) typedef void (APIENTRY * PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const GLvoid *string); typedef void (APIENTRY * PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); typedef void (APIENTRY * PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs); typedef void (APIENTRY * PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs); typedef void (APIENTRY * PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRY * PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); typedef void (APIENTRY * PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRY * PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); typedef void (APIENTRY * PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRY * PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); typedef void (APIENTRY * PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRY * PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); typedef void (APIENTRY * PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); typedef void (APIENTRY * PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); typedef void (APIENTRY * PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); typedef void (APIENTRY * PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); typedef void (APIENTRY * PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRY * PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, GLvoid *string); //GLSL typedef unsigned int GLhandleARB; /* shader object handle */ typedef char GLcharARB; /* native character */ typedef GLhandleARB (APIENTRY * PFNGLCREATEPROGRAMOBJECTARBPROC) (void); typedef void (APIENTRY * PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); typedef void (APIENTRY * PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); typedef GLhandleARB (APIENTRY * PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); typedef void (APIENTRY * PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, GLint *length); typedef void (APIENTRY * PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); typedef void (APIENTRY * PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params); typedef void (APIENTRY * PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); typedef void (APIENTRY * PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); typedef void (APIENTRY * PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); typedef GLint (APIENTRY * PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); typedef void (APIENTRY * PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); typedef void (APIENTRY * PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); typedef void (APIENTRY * PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); typedef void (APIENTRY * PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); typedef void (APIENTRY * PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, GLfloat [3][3]); typedef void (APIENTRY * PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRY * PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *); typedef void (APIENTRY * PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint); typedef void (APIENTRY * PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name); #endif //Framebuffer objects typedef GLboolean (APIENTRY * PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); typedef void (APIENTRY * PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); typedef void (APIENTRY * PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers); typedef void (APIENTRY * PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers); typedef void (APIENTRY * PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); typedef GLboolean (APIENTRY * PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); typedef void (APIENTRY * PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); typedef void (APIENTRY * PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers); typedef void (APIENTRY * PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers); typedef GLenum (APIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); typedef void (APIENTRY * PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (APIENTRY * PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (APIENTRY * PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); typedef void (APIENTRY * PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); typedef void (APIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); typedef void (APIENTRY * PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); typedef void (APIENTRY * PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); #endif #if defined WIN32_VARIANT extern int ( WINAPI * qwglChoosePixelFormat )(HDC, CONST PIXELFORMATDESCRIPTOR *); extern int ( WINAPI * qwglDescribePixelFormat) (HDC, int, UINT, LPPIXELFORMATDESCRIPTOR); extern int ( WINAPI * qwglGetPixelFormat)(HDC); extern BOOL ( WINAPI * qwglSetPixelFormat)(HDC, int, CONST PIXELFORMATDESCRIPTOR *); extern BOOL ( WINAPI * qwglSwapBuffers)(HDC); extern BOOL ( WINAPI * qwglCopyContext)(HGLRC, HGLRC, UINT); extern HGLRC ( WINAPI * qwglCreateContext)(HDC); extern HGLRC ( WINAPI * qwglCreateLayerContext)(HDC, int); extern BOOL ( WINAPI * qwglDeleteContext)(HGLRC); extern HGLRC ( WINAPI * qwglGetCurrentContext)(VOID); extern HDC ( WINAPI * qwglGetCurrentDC)(VOID); extern PROC ( WINAPI * qwglGetProcAddress)(LPCSTR); extern BOOL ( WINAPI * qwglMakeCurrent)(HDC, HGLRC); extern BOOL ( WINAPI * qwglShareLists)(HGLRC, HGLRC); extern BOOL ( WINAPI * qwglUseFontBitmaps)(HDC, DWORD, DWORD, DWORD); extern BOOL ( WINAPI * qwglUseFontOutlines)(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT); extern BOOL ( WINAPI * qwglDescribeLayerPlane)(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR); extern int ( WINAPI * qwglSetLayerPaletteEntries)(HDC, int, int, int, CONST COLORREF *); extern int ( WINAPI * qwglGetLayerPaletteEntries)(HDC, int, int, int, COLORREF *); extern BOOL ( WINAPI * qwglRealizeLayerPalette)(HDC, int, BOOL); extern BOOL ( WINAPI * qwglSwapLayerBuffers)(HDC, UINT); extern BOOL ( WINAPI * qwglSwapIntervalEXT)( int interval ); extern BOOL ( WINAPI * qwglGetDeviceGammaRampEXT ) ( unsigned char *pRed, unsigned char *pGreen, unsigned char *pBlue ); extern BOOL ( WINAPI * qwglSetDeviceGammaRampEXT ) ( const unsigned char *pRed, const unsigned char *pGreen, const unsigned char *pBlue ); #endif #if defined UNIX_VARIANT #include // local function in dll extern void * (*qwglGetProcAddress) (const char*); extern void (*qgl3DfxSetPaletteEXT)(GLuint *); /* //FX Mesa Functions extern fxMesaContext (*qfxMesaCreateContext)(GLuint win, GrScreenResolution_t, GrScreenRefresh_t, const GLint attribList[]); extern fxMesaContext (*qfxMesaCreateBestContext)(GLuint win, GLint width, GLint height, const GLint attribList[]); extern void (*qfxMesaDestroyContext)(fxMesaContext ctx); extern void (*qfxMesaMakeCurrent)(fxMesaContext ctx); extern fxMesaContext (*qfxMesaGetCurrentContext)(void); extern void (*qfxMesaSwapBuffers)(void); */ //GLX Functions extern XVisualInfo * (*qglXChooseVisual)( Display *dpy, int screen, int *attribList ); extern GLXContext (*qglXCreateContext)( Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct ); extern void (*qglXDestroyContext)( Display *dpy, GLXContext ctx ); extern Bool (*qglXMakeCurrent)( Display *dpy, GLXDrawable drawable, GLXContext ctx); extern void (*qglXCopyContext)( Display *dpy, GLXContext src, GLXContext dst, GLuint mask ); extern void (*qglXSwapBuffers)( Display *dpy, GLXDrawable drawable ); // 3dfxSetPaletteEXT shunt void Fake_glColorTableEXT( GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table ); #endif // linux /* ** extension constants */ #define GL_POINT_SIZE_MIN_EXT 0x8126 #define GL_POINT_SIZE_MAX_EXT 0x8127 #define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 #define GL_DISTANCE_ATTENUATION_EXT 0x8129 #ifdef __sgi #define GL_SHARED_TEXTURE_PALETTE_EXT GL_TEXTURE_COLOR_TABLE_SGI #else #define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB #endif #define GL_TEXTURE0_SGIS 0x835E #define GL_TEXTURE1_SGIS 0x835F #define GL_TEXTURE0_ARB 0x84C0 #define GL_TEXTURE1_ARB 0x84C1 #ifdef GL_TEXTURE0 #undef GL_TEXTURE0 #endif #ifdef GL_TEXTURE1 #undef GL_TEXTURE1 #endif #ifdef GL_TEXTURE2 #undef GL_TEXTURE2 #endif #ifdef GL_TEXTURE3 #undef GL_TEXTURE3 #endif #ifdef GL_TEXTURE4 #undef GL_TEXTURE4 #endif #ifdef GL_TEXTURE5 #undef GL_TEXTURE5 #endif #ifdef GL_TEXTURE6 #undef GL_TEXTURE6 #endif #ifdef GL_TEXTURE7 #undef GL_TEXTURE7 #endif extern int GL_TEXTURE0, GL_TEXTURE1, GL_TEXTURE2, GL_TEXTURE3, GL_TEXTURE4, GL_TEXTURE5, GL_TEXTURE6, GL_TEXTURE7; #define GL_FRAGMENT_PROGRAM_ARB 0x8804 // jitwater #define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 // jitwater #define GL_VERTEX_SHADER_ARB 0x8B31 #define GL_FRAGMENT_SHADER_ARB 0x8B30 #define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 #define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 #define GL_OBJECT_LINK_STATUS_ARB 0x8B82 #define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 #define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 #define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 #define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 #define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 #define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 // Vic - begin #ifndef GL_EXT_texture_env_combine #define GL_COMBINE_EXT 0x8570 #define GL_COMBINE_RGB_EXT 0x8571 #define GL_COMBINE_ALPHA_EXT 0x8572 #define GL_RGB_SCALE_EXT 0x8573 #define GL_ADD_SIGNED_EXT 0x8574 #define GL_INTERPOLATE_EXT 0x8575 #define GL_CONSTANT_EXT 0x8576 #define GL_PRIMARY_COLOR_EXT 0x8577 #define GL_PREVIOUS_EXT 0x8578 #define GL_SOURCE0_RGB_EXT 0x8580 #define GL_SOURCE1_RGB_EXT 0x8581 #define GL_SOURCE2_RGB_EXT 0x8582 #define GL_SOURCE3_RGB_EXT 0x8583 #define GL_SOURCE4_RGB_EXT 0x8584 #define GL_SOURCE5_RGB_EXT 0x8585 #define GL_SOURCE6_RGB_EXT 0x8586 #define GL_SOURCE7_RGB_EXT 0x8587 #define GL_SOURCE0_ALPHA_EXT 0x8588 #define GL_SOURCE1_ALPHA_EXT 0x8589 #define GL_SOURCE2_ALPHA_EXT 0x858A #define GL_SOURCE3_ALPHA_EXT 0x858B #define GL_SOURCE4_ALPHA_EXT 0x858C #define GL_SOURCE5_ALPHA_EXT 0x858D #define GL_SOURCE6_ALPHA_EXT 0x858E #define GL_SOURCE7_ALPHA_EXT 0x858F #define GL_OPERAND0_RGB_EXT 0x8590 #define GL_OPERAND1_RGB_EXT 0x8591 #define GL_OPERAND2_RGB_EXT 0x8592 #define GL_OPERAND3_RGB_EXT 0x8593 #define GL_OPERAND4_RGB_EXT 0x8594 #define GL_OPERAND5_RGB_EXT 0x8595 #define GL_OPERAND6_RGB_EXT 0x8596 #define GL_OPERAND7_RGB_EXT 0x8597 #define GL_OPERAND0_ALPHA_EXT 0x8598 #define GL_OPERAND1_ALPHA_EXT 0x8599 #define GL_OPERAND2_ALPHA_EXT 0x859A #define GL_OPERAND3_ALPHA_EXT 0x859B #define GL_OPERAND4_ALPHA_EXT 0x859C #define GL_OPERAND5_ALPHA_EXT 0x859D #define GL_OPERAND6_ALPHA_EXT 0x859E #define GL_OPERAND7_ALPHA_EXT 0x859F #endif // Vic - end // === jitwater - arb fragmetn program extensions extern PFNGLGENPROGRAMSARBPROC qglGenProgramsARB; extern PFNGLDELETEPROGRAMSARBPROC qglDeleteProgramsARB; extern PFNGLBINDPROGRAMARBPROC qglBindProgramARB; extern PFNGLPROGRAMSTRINGARBPROC qglProgramStringARB; extern PFNGLPROGRAMENVPARAMETER4FARBPROC qglProgramEnvParameter4fARB; extern PFNGLPROGRAMLOCALPARAMETER4FARBPROC qglProgramLocalParameter4fARB; // jitwater === //add glsl program extensions extern PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB; extern PFNGLDELETEOBJECTARBPROC glDeleteObjectARB; extern PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB; extern PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB; extern PFNGLSHADERSOURCEARBPROC glShaderSourceARB; extern PFNGLCOMPILESHADERPROC glCompileShader; extern PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB; extern PFNGLATTACHOBJECTARBPROC glAttachObjectARB; extern PFNGLGETINFOLOGARBPROC glGetInfoLogARB; extern PFNGLLINKPROGRAMARBPROC glLinkProgramARB; extern PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB; extern PFNGLUNIFORM3FARBPROC glUniform3fARB; extern PFNGLUNIFORM2FARBPROC glUniform2fARB; extern PFNGLUNIFORM1IARBPROC glUniform1iARB; extern PFNGLUNIFORM1FARBPROC glUniform1fARB; extern PFNGLUNIFORMMATRIX3FVARBPROC glUniformMatrix3fvARB; #ifndef PFNGLUNIFORMMATRIX3X4FVARBPROC //FIXME HACK to get it compiling on Linux typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); #endif extern PFNGLUNIFORMMATRIX3X4FVARBPROC glUniformMatrix3x4fvARB; extern PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB; extern PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB; extern PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB; extern PFNGLBINDATTRIBLOCATIONARBPROC qglBindAttribLocationARB; //framebuffer objects #ifndef GL_EXT_framebuffer_object #define GL_EXT_framebuffer_object #define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 #define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 #define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 #define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 #define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 #define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 #define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 #define GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT 0x8CD8 #define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 #define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA #define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB #define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC #define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD #define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF #define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 #define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 #define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 #define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 #define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 #define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 #define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 #define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 #define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 #define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 #define GL_COLOR_ATTACHMENT10_EXT 0x8CEA #define GL_COLOR_ATTACHMENT11_EXT 0x8CEB #define GL_COLOR_ATTACHMENT12_EXT 0x8CEC #define GL_COLOR_ATTACHMENT13_EXT 0x8CED #define GL_COLOR_ATTACHMENT14_EXT 0x8CEE #define GL_COLOR_ATTACHMENT15_EXT 0x8CEF #define GL_DEPTH_ATTACHMENT_EXT 0x8D00 #define GL_STENCIL_ATTACHMENT_EXT 0x8D20 #define GL_FRAMEBUFFER_EXT 0x8D40 #define GL_RENDERBUFFER_EXT 0x8D41 #define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 #define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 #define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 #define GL_STENCIL_INDEX1_EXT 0x8D46 #define GL_STENCIL_INDEX4_EXT 0x8D47 #define GL_STENCIL_INDEX8_EXT 0x8D48 #define GL_STENCIL_INDEX16_EXT 0x8D49 #define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 #define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 #define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 #define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 #define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 #define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 #endif extern GLboolean(APIENTRY * qglIsRenderbufferEXT) (GLuint renderbuffer); extern void (APIENTRY * qglBindRenderbufferEXT) (GLenum target, GLuint renderbuffer); extern void (APIENTRY * qglDeleteRenderbuffersEXT) (GLsizei n, const GLuint * renderbuffers); extern void (APIENTRY * qglGenRenderbuffersEXT) (GLsizei n, GLuint * renderbuffers); extern void (APIENTRY * qglRenderbufferStorageEXT) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); extern void (APIENTRY * qglGetRenderbufferParameterivEXT) (GLenum target, GLenum pname, GLint * params); extern GLboolean(APIENTRY * qglIsFramebufferEXT) (GLuint framebuffer); extern void (APIENTRY * qglBindFramebufferEXT) (GLenum target, GLuint framebuffer); extern void (APIENTRY * qglDeleteFramebuffersEXT) (GLsizei n, const GLuint * framebuffers); extern void (APIENTRY * qglGenFramebuffersEXT) (GLsizei n, GLuint * framebuffers); extern GLenum(APIENTRY * qglCheckFramebufferStatusEXT) (GLenum target); extern void (APIENTRY * qglFramebufferTexture1DEXT) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); extern void (APIENTRY * qglFramebufferTexture2DEXT) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); extern void (APIENTRY * qglFramebufferTexture3DEXT) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); extern void (APIENTRY * qglFramebufferRenderbufferEXT) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); extern void (APIENTRY * qglGetFramebufferAttachmentParameterivEXT) (GLenum target, GLenum attachment, GLenum pname, GLint * params); extern void (APIENTRY * qglGenerateMipmapEXT) (GLenum target); // GL_EXT_packed_depth_stencil #ifndef GL_EXT_packed_depth_stencil #define GL_DEPTH_STENCIL_EXT 0x84F9 #define GL_UNSIGNED_INT_24_8_EXT 0x84FA #define GL_DEPTH24_STENCIL8_EXT 0x88F0 #define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 #endif // GL_EXT_framebuffer_blit #ifndef GL_EXT_framebuffer_blit #define GL_READ_FRAMEBUFFER_EXT 0x8CA8 #define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 #define GL_DRAW_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING_EXT #define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA #endif extern void (APIENTRY * qglBlitFramebufferEXT) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); #endif /* __QGL_H__ */ alien-arena-7.66+dfsg/source/ref_gl/r_warp.c0000600000175000017500000004746212162607462020036 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. Copyright (C) 2011 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // r_warp.c -- sky and water polygons #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "r_local.h" extern model_t *loadmodel; char skyname[MAX_QPATH]; float skyrotate; vec3_t skyaxis; image_t *sky_images[6]; msurface_t *warpface; #define SUBDIVIDE_SIZE 64 void BoundPoly (int numverts, float *verts, vec3_t mins, vec3_t maxs) { int i, j; float *v; mins[0] = mins[1] = mins[2] = 9999; maxs[0] = maxs[1] = maxs[2] = -9999; v = verts; for (i=0 ; i maxs[j]) maxs[j] = *v; } } void SubdividePolygon (int numverts, float *verts) { int i, j, k; vec3_t mins, maxs; float m; float *v; vec3_t front[64], back[64]; int f, b; float dist[64]; float frac; glpoly_t *poly; float s, t; vec3_t total; float total_s, total_t; if (numverts > 60) Com_Error (ERR_DROP, "numverts = %i", numverts); BoundPoly (numverts, verts, mins, maxs); for (i=0 ; i<3 ; i++) { m = (mins[i] + maxs[i]) * 0.5; m = SUBDIVIDE_SIZE * floor (m/SUBDIVIDE_SIZE + 0.5); if (maxs[i] - m < 8) continue; if (m - mins[i] < 8) continue; // cut it v = verts + i; for (j=0 ; j= 0) { VectorCopy (v, front[f]); f++; } if (dist[j] <= 0) { VectorCopy (v, back[b]); b++; } if (dist[j] == 0 || dist[j+1] == 0) continue; if ( (dist[j] > 0) != (dist[j+1] > 0) ) { // clip point frac = dist[j] / (dist[j] - dist[j+1]); for (k=0 ; k<3 ; k++) front[f][k] = back[b][k] = v[k] + frac*(v[3+k] - v[k]); f++; b++; } } SubdividePolygon (f, front[0]); SubdividePolygon (b, back[0]); return; } // add a point in the center to help keep warp valid poly = Hunk_Alloc (sizeof(glpoly_t) + ((numverts-4)+2) * VERTEXSIZE*sizeof(float)); poly->next = warpface->polys; warpface->polys = poly; poly->numverts = numverts+2; VectorClear (total); total_s = 0; total_t = 0; for (i=0 ; iverts[i+1]); s = DotProduct (verts, warpface->texinfo->vecs[0]); t = DotProduct (verts, warpface->texinfo->vecs[1]); total_s += s; total_t += t; VectorAdd (total, verts, total); poly->verts[i+1][3] = s; poly->verts[i+1][4] = t; } VectorScale (total, (1.0/numverts), poly->verts[0]); poly->verts[0][3] = total_s/numverts; poly->verts[0][4] = total_t/numverts; // copy first vertex to last memcpy (poly->verts[i+1], poly->verts[1], sizeof(poly->verts[0])); } /* ================ R_SubdivideSurface Breaks a polygon up along axial 64 unit boundaries so that turbulent and sky warps can be done reasonably. ================ */ void R_SubdivideSurface (msurface_t *fa, int firstedge, int numedges) { vec3_t verts[64]; int numverts; int i; int lindex; float *vec; warpface = fa; // // convert edges back to a normal polygon // numverts = 0; for (i=0 ; isurfedges[firstedge + i]; if (lindex > 0) vec = loadmodel->vertexes[loadmodel->edges[lindex].v[0]].position; else vec = loadmodel->vertexes[loadmodel->edges[-lindex].v[1]].position; VectorCopy (vec, verts[numverts]); numverts++; } SubdividePolygon (numverts, verts[0]); } //========================================================= // speed up sin calculations - Ed float r_turbsin[] = { #include "warpsin.h" }; #define TURBOSCALE (256.0f / ((float)M_PI / 4.0f)) /* ============= EmitWaterPolys Does a water warp on the pre-fragmented glpoly_t chain ============= */ void R_RenderWaterPolys (msurface_t *fa, int texnum, float scaleX, float scaleY) { glpoly_t *p; float *v; int i; float s, t, os, ot; float scroll; float rdt = r_newrefdef.time; vec3_t nv; if (fa->texinfo->flags & SURF_FLOWING) scroll = -64.0f * ((r_newrefdef.time * 0.5f) - (int)(r_newrefdef.time * 0.5f)); else scroll = 0.0f; if(gl_state.glsl_shaders && gl_glsl_shaders->value && fa->texinfo->has_normalmap) { if (SurfaceIsAlphaBlended(fa)) qglEnable( GL_ALPHA_TEST ); R_InitVArrays (VERT_COLOURED_TEXTURED); glUseProgramObjectARB( g_waterprogramObj ); GL_EnableMultitexture( true ); qglActiveTextureARB(GL_TEXTURE0); qglBindTexture (GL_TEXTURE_2D, fa->texinfo->image->texnum); glUniform1iARB( g_location_baseTexture, 0); qglActiveTextureARB(GL_TEXTURE1); qglBindTexture(GL_TEXTURE_2D, fa->texinfo->normalMap->texnum); glUniform1iARB( g_location_normTexture, 1); if (texnum) { qglActiveTextureARB(GL_TEXTURE2); qglBindTexture(GL_TEXTURE_2D, texnum); glUniform1iARB( g_location_refTexture, 2); } else { glUniform1iARB( g_location_refTexture, 0); } if(fa->texinfo->flags &(SURF_TRANS33|SURF_TRANS66)) glUniform1fARB( g_location_trans, 0.5); else glUniform1fARB( g_location_trans, 0.75); if(texnum) glUniform1iARB( g_location_reflect, 1); else glUniform1iARB( g_location_reflect, 0); //send these to the shader program glUniformMatrix3fvARB( g_location_tangentSpaceTransform, 1, GL_FALSE, (const GLfloat *) fa->tangentSpaceTransform ); glUniform3fARB( g_location_waterEyePos, r_origin[0], r_origin[1], r_origin[2] ); glUniform3fARB( g_location_lightPos, r_worldLightVec[0], r_worldLightVec[1], r_worldLightVec[2]); glUniform1iARB( g_location_fogamount, map_fog); glUniform1fARB( g_location_time, rs_realtime); R_AddGLSLShadedWarpSurfToVArray (fa, scroll); glUseProgramObjectARB( 0 ); R_KillVArrays (); GL_EnableMultitexture( false ); if (SurfaceIsAlphaBlended(fa)) qglDisable( GL_ALPHA_TEST); return; } else { if (gl_state.fragment_program && fa->texinfo->has_normalmap) { qglEnable(GL_FRAGMENT_PROGRAM_ARB); qglBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, g_water_program_id); qglProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, rs_realtime * (0.2f), 1.0f, 1.0f, 1.0f); qglProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, rs_realtime * -0.2f, 10.0f, 1.0f, 1.0f); qglProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, (fa->polys[0].verts[0][3]-r_newrefdef.vieworg[0]), (fa->polys[0].verts[0][4]-r_newrefdef.vieworg[1]), (fa->polys[0].verts[0][4]-r_newrefdef.vieworg[2]), 1.0f); GL_MBind(GL_TEXTURE1, r_distort->texnum); } GL_MBind(GL_TEXTURE0, fa->texinfo->image->texnum); for (p=fa->polys ; p ; p=p->next) { qglBegin (GL_TRIANGLE_FAN); for (i=0,v=p->verts[0] ; inumverts ; i++, v+=VERTEXSIZE) { os = v[3]; ot = v[4]; s = os + r_turbsin[(int)((ot*0.125+r_newrefdef.time) * TURBSCALE) & 255]; s += scroll; s *= (1.0/64); t = ot + r_turbsin[(int)((os*0.125+rdt) * TURBSCALE) & 255]; t *= (1.0/64); if (gl_state.fragment_program) { qglMTexCoord2fARB(GL_TEXTURE0, s, t); qglMTexCoord2fARB(GL_TEXTURE1, 20*s, 20*t); } else qglTexCoord2f (s, t); if (!(fa->texinfo->flags & SURF_FLOWING)) { nv[0] =v[0]; nv[1] =v[1]; nv[2] =v[2] + r_wave->value *sin(v[0]*0.025+r_newrefdef.time)*sin(v[2]*0.05+r_newrefdef.time) + r_wave->value *sin(v[1]*0.025+r_newrefdef.time*2)*sin(v[2]*0.05+r_newrefdef.time); qglVertex3fv (nv); } else qglVertex3fv (v); } qglEnd (); } if (gl_state.fragment_program) qglDisable(GL_FRAGMENT_PROGRAM_ARB); } //env map if specified by shader if(texnum) GL_Bind(texnum); else return; for (p=fa->polys ; p ; p=p->next) { qglBegin (GL_TRIANGLE_FAN); for (i=0,v=p->verts[0] ; inumverts ; i++, v+=VERTEXSIZE) { os = v[3] - r_newrefdef.vieworg[0] + 128*scaleX; ot = v[4] + r_newrefdef.vieworg[1] + 128*scaleY; if(texnum) qglTexCoord2f(1.0/512*scaleX*os, 1.0/512*scaleY*ot); if (!(fa->texinfo->flags & SURF_FLOWING)) { nv[0] =v[0]; nv[1] =v[1]; nv[2] =v[2] + r_wave->value *sin(v[0]*0.025+r_newrefdef.time)*sin(v[2]*0.05+r_newrefdef.time) + r_wave->value *sin(v[1]*0.025+r_newrefdef.time*2)*sin(v[2]*0.05+r_newrefdef.time); qglVertex3fv (nv); } else qglVertex3fv (v); } qglEnd (); } } vec3_t skyclip[6] = { {1,1,0}, {1,-1,0}, {0,-1,1}, {0,1,1}, {1,0,1}, {-1,0,1} }; // 1 = s, 2 = t, 3 = 2048 int st_to_vec[6][3] = { {3,-1,2}, {-3,1,2}, {1,3,2}, {-1,-3,2}, {-2,-1,3}, // 0 degrees yaw, look straight up {2,-1,-3} // look straight down // {-1,2,3}, // {1,2,-3} }; // s = [0]/[2], t = [1]/[2] int vec_to_st[6][3] = { {-2,3,1}, {2,3,-1}, {1,3,2}, {-1,3,-2}, {-2,-1,3}, {-2,1,-3} // {-1,2,3}, // {1,2,-3} }; float skymins[2][6], skymaxs[2][6]; float sky_min, sky_max; void DrawSkyPolygon (int nump, vec3_t vecs) { int i,j; vec3_t v, av; float s, t, dv; int axis; float *vp; // decide which face it maps to VectorCopy (vec3_origin, v); for (i=0, vp=vecs ; i av[1] && av[0] > av[2]) { if (v[0] < 0) axis = 1; else axis = 0; } else if (av[1] > av[2] && av[1] > av[0]) { if (v[1] < 0) axis = 3; else axis = 2; } else { if (v[2] < 0) axis = 5; else axis = 4; } // project new texture coords for (i=0 ; i 0) dv = vecs[j - 1]; else dv = -vecs[-j - 1]; if (dv < 0.001) continue; // don't divide by zero j = vec_to_st[axis][0]; if (j < 0) s = -vecs[-j -1] / dv; else s = vecs[j-1] / dv; j = vec_to_st[axis][1]; if (j < 0) t = -vecs[-j -1] / dv; else t = vecs[j-1] / dv; if (s < skymins[0][axis]) skymins[0][axis] = s; if (t < skymins[1][axis]) skymins[1][axis] = t; if (s > skymaxs[0][axis]) skymaxs[0][axis] = s; if (t > skymaxs[1][axis]) skymaxs[1][axis] = t; } } #define ON_EPSILON 0.1 // point on plane side epsilon #define MAX_CLIP_VERTS 64 void ClipSkyPolygon (int nump, vec3_t vecs, int stage) { float *norm; float *v; qboolean front, back; float d, e; float dists[MAX_CLIP_VERTS]; int sides[MAX_CLIP_VERTS]; vec3_t newv[2][MAX_CLIP_VERTS]; int newc[2]; int i, j; if (nump > MAX_CLIP_VERTS-2) Com_Error (ERR_DROP, "ClipSkyPolygon: MAX_CLIP_VERTS"); if (stage == 6) { // fully clipped, so draw it DrawSkyPolygon (nump, vecs); return; } front = back = false; norm = skyclip[stage]; for (i=0, v = vecs ; i ON_EPSILON) { front = true; sides[i] = SIDE_FRONT; } else if (d < -ON_EPSILON) { back = true; sides[i] = SIDE_BACK; } else sides[i] = SIDE_ON; dists[i] = d; } if (!front || !back) { // not clipped ClipSkyPolygon (nump, vecs, stage+1); return; } // clip it sides[i] = sides[0]; dists[i] = dists[0]; VectorCopy (vecs, (vecs+(i*3)) ); newc[0] = newc[1] = 0; for (i=0, v = vecs ; ipolys ; p ; p=p->next) { for (i=0 ; inumverts ; i++) { VectorSubtract (p->verts[i], r_origin, verts[i]); } ClipSkyPolygon (p->numverts, verts[0], 0); } } /* ============== R_ClearSkyBox ============== */ void R_ClearSkyBox (void) { int i; for (i=0 ; i<6 ; i++) { skymins[0][i] = skymins[1][i] = 9999; skymaxs[0][i] = skymaxs[1][i] = -9999; } } void MakeSkyVec (float s, float t, int axis, float *tex_s, float *tex_t, float *vec, float size) { vec3_t v, b; int j, k; b[0] = s * size; b[1] = t * size; b[2] = size; for (j=0 ; j<3 ; j++) { k = st_to_vec[axis][j]; if (k < 0) v[j] = -b[-k - 1]; else v[j] = b[k - 1]; } // avoid bilerp seam s = (s+1)*0.5; t = (t+1)*0.5; if (s < sky_min) s = sky_min; else if (s > sky_max) s = sky_max; if (t < sky_min) t = sky_min; else if (t > sky_max) t = sky_max; t = 1.0 - t; *tex_s = s; *tex_t = t; VectorCopy(v, vec); } /* ============== R_DrawSkyBox ============== */ int skytexorder[6] = {0,2,1,3,4,5}; void R_DrawSkyBox (void) { int i; float s ,t; vec3_t point; float alpha; rscript_t *rs = NULL; rs_stage_t *stage = NULL; if (skyrotate) { // check for no sky at all for (i=0 ; i<6 ; i++) if (skymins[0][i] < skymaxs[0][i] && skymins[1][i] < skymaxs[1][i]) break; if (i == 6) return; // nothing visible } qglPushMatrix (); qglTranslatef (r_origin[0], r_origin[1], r_origin[2]); qglRotatef (r_newrefdef.time * skyrotate, skyaxis[0], skyaxis[1], skyaxis[2]); for (i=0 ; i<6 ; i++) { if (skyrotate) { // hack, forces full sky to draw when rotating skymins[0][i] = -1; skymins[1][i] = -1; skymaxs[0][i] = 1; skymaxs[1][i] = 1; } if (skymins[0][i] >= skymaxs[0][i] || skymins[1][i] >= skymaxs[1][i]) continue; GL_Bind (sky_images[skytexorder[i]]->texnum); qglBegin (GL_QUADS); MakeSkyVec (skymins[0][i], skymins[1][i], i, &s, &t, point, 3300); qglTexCoord2f (s, t); qglVertex3fv (point); MakeSkyVec (skymins[0][i], skymaxs[1][i], i, &s, &t, point, 3300); qglTexCoord2f (s, t); qglVertex3fv (point); MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i, &s, &t, point, 3300); qglTexCoord2f (s, t); qglVertex3fv (point); MakeSkyVec (skymaxs[0][i], skymins[1][i], i, &s, &t, point, 3300); qglTexCoord2f (s, t); qglVertex3fv (point); qglEnd (); } qglPopMatrix (); if(r_shaders->value) { //just cloud layers for now, we can expand this qglPushMatrix (); //rotate the clouds qglTranslatef (r_origin[0], r_origin[1], r_origin[2]); qglRotatef (rs_realtime * 20, 0, 1, 0); for (i=0 ; i<6 ; i++) { rs=(rscript_t *)sky_images[skytexorder[i]]->script; if(rs) { stage=rs->stage; while (stage) { qglDepthMask( GL_FALSE ); // no z buffering qglEnable( GL_BLEND); GL_TexEnv( GL_MODULATE ); GLSTATE_DISABLE_ALPHATEST GL_Bind (stage->texture->texnum); if (stage->blendfunc.blend) { GL_BlendFunction(stage->blendfunc.source,stage->blendfunc.dest); GLSTATE_ENABLE_BLEND } else { GLSTATE_DISABLE_BLEND } if (stage->alphashift.min || stage->alphashift.speed) { alpha=0.0f; if (!stage->alphashift.speed && stage->alphashift.min > 0) { alpha=stage->alphashift.min; } else if (stage->alphashift.speed) { alpha=sin(rs_realtime * stage->alphashift.speed); alpha=(alpha+1)*0.5f; if (alpha > stage->alphashift.max) alpha=stage->alphashift.max; if (alpha < stage->alphashift.min) alpha=stage->alphashift.min; } } else alpha=1.0f; qglColor4f(1,1,1,alpha); if (stage->alphamask) { GLSTATE_ENABLE_ALPHATEST } else { GLSTATE_DISABLE_ALPHATEST } skymins[0][i] = -1; skymins[1][i] = -1; skymaxs[0][i] = 1; skymaxs[1][i] = 1; qglBegin (GL_QUADS); MakeSkyVec (skymins[0][i], skymins[1][i], i, &s, &t, point, 2300); RS_SetTexcoords2D (stage, &s, &t); qglTexCoord2f (s, t); qglVertex3fv (point); MakeSkyVec (skymins[0][i], skymaxs[1][i], i, &s, &t, point, 2300); RS_SetTexcoords2D (stage, &s, &t); qglTexCoord2f (s, t); qglVertex3fv (point); MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i, &s, &t, point, 2300); RS_SetTexcoords2D (stage, &s, &t); qglTexCoord2f (s, t); qglVertex3fv (point); MakeSkyVec (skymaxs[0][i], skymins[1][i], i, &s, &t, point, 2300); RS_SetTexcoords2D (stage, &s, &t); qglTexCoord2f (s, t); qglVertex3fv (point); qglEnd(); stage=stage->next; } } } // restore the original blend mode GLSTATE_DISABLE_ALPHATEST GLSTATE_DISABLE_BLEND qglBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); qglColor4f( 1,1,1,1 ); qglDepthMask( GL_TRUE ); // back to normal Z buffering GL_TexEnv( GL_REPLACE ); qglPopMatrix (); } } /* ============ R_SetSky ============ */ // 3dstudio environment map names char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"}; void R_SetSky (char *name, float rotate, vec3_t axis) { int i; char pathname[MAX_QPATH]; strncpy (skyname, name, sizeof(skyname)-1); skyrotate = rotate; VectorCopy (axis, skyaxis); for (i=0 ; i<6 ; i++) { if (gl_skymip->integer) gl_picmip->integer += gl_skymip->integer; Com_sprintf (pathname, sizeof(pathname), "env/%s%s.tga", skyname, suf[i]); sky_images[i] = GL_FindImage (pathname, it_sky); if (!sky_images[i]) sky_images[i] = r_notexture; else { //valid sky, load shader if (r_shaders->value) { strcpy(pathname,sky_images[i]->name); pathname[strlen(pathname)-4]=0; if(sky_images[i]->script) RS_ReadyScript(sky_images[i]->script); } } //set only if not set by fog script if(r_sunX == 0.0 && r_sunY == 0.0 && r_sunZ == 0.0) { if (strstr(pathname, "space")) { VectorSet(sun_origin, -5000, -100000, 115000); spacebox = true; } else if (strstr(pathname, "sea")) { VectorSet(sun_origin, 140000, -80000, 125000); spacebox = false; } else if (strstr(pathname, "hell")) { VectorSet(sun_origin, 140000, 160000, 85000); spacebox = false; } else { VectorSet(sun_origin, 140000, -80000, 45000); spacebox = false; } } else { VectorSet(sun_origin, r_sunX, r_sunY, r_sunZ); spacebox = false; //we will change this to sun vs star } if (gl_skymip->integer) { // take less memory gl_picmip->integer -= gl_skymip->integer; sky_min = 1.0/256; sky_max = 255.0/256; } else { sky_min = 1.0/512; sky_max = 511.0/512; } } } alien-arena-7.66+dfsg/source/ref_gl/anormtab.h0000600000175000017500000005146212161402007020332 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ { {1.23,1.30,1.47,1.35,1.56,1.71,1.37,1.38,1.59,1.60,1.79,1.97,1.88,1.92,1.79,1.02,0.93,1.07,0.82,0.87,0.88,0.94,0.96,1.14,1.11,0.82,0.83,0.89,0.89,0.86,0.94,0.91,1.00,1.21,0.98,1.48,1.30,1.57,0.96,1.07,1.14,1.60,1.61,1.40,1.37,1.72,1.78,1.79,1.93,1.99,1.90,1.68,1.71,1.86,1.60,1.68,1.78,1.86,1.93,1.99,1.97,1.44,1.22,1.49,0.93,0.99,0.99,1.23,1.22,1.44,1.49,0.89,0.89,0.97,0.91,0.98,1.19,0.82,0.76,0.82,0.71,0.72,0.73,0.76,0.79,0.86,0.83,0.72,0.76,0.76,0.89,0.82,0.89,0.82,0.89,0.91,0.83,0.96,1.14,0.97,1.40,1.19,0.98,0.94,1.00,1.07,1.37,1.21,1.48,1.30,1.57,1.61,1.37,0.86,0.83,0.91,0.82,0.82,0.88,0.89,0.96,1.14,0.98,0.87,0.93,0.94,1.02,1.30,1.07,1.35,1.38,1.11,1.56,1.92,1.79,1.79,1.59,1.60,1.72,1.90,1.79,0.80,0.85,0.79,0.93,0.80,0.85,0.77,0.74,0.72,0.77,0.74,0.72,0.70,0.70,0.71,0.76,0.73,0.79,0.79,0.73,0.76,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, {1.26,1.26,1.48,1.23,1.50,1.71,1.14,1.19,1.38,1.46,1.64,1.94,1.87,1.84,1.71,1.02,0.92,1.00,0.79,0.85,0.84,0.91,0.90,0.98,0.99,0.77,0.77,0.83,0.82,0.79,0.86,0.84,0.92,0.99,0.91,1.24,1.03,1.33,0.88,0.94,0.97,1.41,1.39,1.18,1.11,1.51,1.61,1.59,1.80,1.91,1.76,1.54,1.65,1.76,1.70,1.70,1.85,1.85,1.97,1.99,1.93,1.28,1.09,1.39,0.92,0.97,0.99,1.18,1.26,1.52,1.48,0.83,0.85,0.90,0.88,0.93,1.00,0.77,0.73,0.78,0.72,0.71,0.74,0.75,0.79,0.86,0.81,0.75,0.81,0.79,0.96,0.88,0.94,0.86,0.93,0.92,0.85,1.08,1.33,1.05,1.55,1.31,1.01,1.05,1.27,1.31,1.60,1.47,1.70,1.54,1.76,1.76,1.57,0.93,0.90,0.99,0.88,0.88,0.95,0.97,1.11,1.39,1.20,0.92,0.97,1.01,1.10,1.39,1.22,1.51,1.58,1.32,1.64,1.97,1.85,1.91,1.77,1.74,1.88,1.99,1.91,0.79,0.86,0.80,0.94,0.84,0.88,0.74,0.74,0.71,0.82,0.77,0.76,0.70,0.73,0.72,0.73,0.70,0.74,0.85,0.77,0.82,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, {1.34,1.27,1.53,1.17,1.46,1.71,0.98,1.05,1.20,1.34,1.48,1.86,1.82,1.71,1.62,1.09,0.94,0.99,0.79,0.85,0.82,0.90,0.87,0.93,0.96,0.76,0.74,0.79,0.76,0.74,0.79,0.78,0.85,0.92,0.85,1.00,0.93,1.06,0.81,0.86,0.89,1.16,1.12,0.97,0.95,1.28,1.38,1.35,1.60,1.77,1.57,1.33,1.50,1.58,1.69,1.63,1.82,1.74,1.91,1.92,1.80,1.04,0.97,1.21,0.90,0.93,0.97,1.05,1.21,1.48,1.37,0.77,0.80,0.84,0.85,0.88,0.92,0.73,0.71,0.74,0.74,0.71,0.75,0.73,0.79,0.84,0.78,0.79,0.86,0.81,1.05,0.94,0.99,0.90,0.95,0.92,0.86,1.24,1.44,1.14,1.59,1.34,1.02,1.27,1.50,1.49,1.80,1.69,1.86,1.72,1.87,1.80,1.69,1.00,0.98,1.23,0.95,0.96,1.09,1.16,1.37,1.63,1.46,0.99,1.10,1.25,1.24,1.51,1.41,1.67,1.77,1.55,1.72,1.95,1.89,1.98,1.91,1.86,1.97,1.99,1.94,0.81,0.89,0.85,0.98,0.90,0.94,0.75,0.78,0.73,0.89,0.83,0.82,0.72,0.77,0.76,0.72,0.70,0.71,0.91,0.83,0.89,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, {1.46,1.34,1.60,1.16,1.46,1.71,0.94,0.99,1.05,1.26,1.33,1.74,1.76,1.57,1.54,1.23,0.98,1.05,0.83,0.89,0.84,0.92,0.87,0.91,0.96,0.78,0.74,0.79,0.72,0.72,0.75,0.76,0.80,0.88,0.83,0.94,0.87,0.95,0.76,0.80,0.82,0.97,0.96,0.89,0.88,1.08,1.11,1.10,1.37,1.59,1.37,1.07,1.27,1.34,1.57,1.45,1.69,1.55,1.77,1.79,1.60,0.93,0.90,0.99,0.86,0.87,0.93,0.96,1.07,1.35,1.18,0.73,0.76,0.77,0.81,0.82,0.85,0.70,0.71,0.72,0.78,0.73,0.77,0.73,0.79,0.82,0.76,0.83,0.90,0.84,1.18,0.98,1.03,0.92,0.95,0.90,0.86,1.32,1.45,1.15,1.53,1.27,0.99,1.42,1.65,1.58,1.93,1.83,1.94,1.81,1.88,1.74,1.70,1.19,1.17,1.44,1.11,1.15,1.36,1.41,1.61,1.81,1.67,1.22,1.34,1.50,1.42,1.65,1.61,1.82,1.91,1.75,1.80,1.89,1.89,1.98,1.99,1.94,1.98,1.92,1.87,0.86,0.95,0.92,1.14,0.98,1.03,0.79,0.84,0.77,0.97,0.90,0.89,0.76,0.82,0.82,0.74,0.72,0.71,0.98,0.89,0.97,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, {1.60,1.44,1.68,1.22,1.49,1.71,0.93,0.99,0.99,1.23,1.22,1.60,1.68,1.44,1.49,1.40,1.14,1.19,0.89,0.96,0.89,0.97,0.89,0.91,0.98,0.82,0.76,0.82,0.71,0.72,0.73,0.76,0.79,0.86,0.83,0.91,0.83,0.89,0.72,0.76,0.76,0.89,0.89,0.82,0.82,0.98,0.96,0.97,1.14,1.40,1.19,0.94,1.00,1.07,1.37,1.21,1.48,1.30,1.57,1.61,1.37,0.86,0.83,0.91,0.82,0.82,0.88,0.89,0.96,1.14,0.98,0.70,0.72,0.73,0.77,0.76,0.79,0.70,0.72,0.71,0.82,0.77,0.80,0.74,0.79,0.80,0.74,0.87,0.93,0.85,1.23,1.02,1.02,0.93,0.93,0.87,0.85,1.30,1.35,1.07,1.38,1.11,0.94,1.47,1.71,1.56,1.97,1.88,1.92,1.79,1.79,1.59,1.60,1.30,1.35,1.56,1.37,1.38,1.59,1.60,1.79,1.92,1.79,1.48,1.57,1.72,1.61,1.78,1.79,1.93,1.99,1.90,1.86,1.78,1.86,1.93,1.99,1.97,1.90,1.79,1.72,0.94,1.07,1.00,1.37,1.21,1.30,0.86,0.91,0.83,1.14,0.98,0.96,0.82,0.88,0.89,0.79,0.76,0.73,1.07,0.94,1.11,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, {1.74,1.57,1.76,1.33,1.54,1.71,0.94,1.05,0.99,1.26,1.16,1.46,1.60,1.34,1.46,1.59,1.37,1.37,0.97,1.11,0.96,1.10,0.95,0.94,1.08,0.89,0.82,0.88,0.72,0.76,0.75,0.80,0.80,0.88,0.87,0.91,0.83,0.87,0.72,0.76,0.74,0.83,0.84,0.78,0.79,0.96,0.89,0.92,0.98,1.23,1.05,0.86,0.92,0.95,1.11,0.98,1.22,1.03,1.34,1.42,1.14,0.79,0.77,0.84,0.78,0.76,0.82,0.82,0.89,0.97,0.90,0.70,0.71,0.71,0.73,0.72,0.74,0.73,0.76,0.72,0.86,0.81,0.82,0.76,0.79,0.77,0.73,0.90,0.95,0.86,1.18,1.03,0.98,0.92,0.90,0.83,0.84,1.19,1.17,0.98,1.15,0.97,0.89,1.42,1.65,1.44,1.93,1.83,1.81,1.67,1.61,1.36,1.41,1.32,1.45,1.58,1.57,1.53,1.74,1.70,1.88,1.94,1.81,1.69,1.77,1.87,1.79,1.89,1.92,1.98,1.99,1.98,1.89,1.65,1.80,1.82,1.91,1.94,1.75,1.61,1.50,1.07,1.34,1.27,1.60,1.45,1.55,0.93,0.99,0.90,1.35,1.18,1.07,0.87,0.93,0.96,0.85,0.82,0.77,1.15,0.99,1.27,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, {1.86,1.71,1.82,1.48,1.62,1.71,0.98,1.20,1.05,1.34,1.17,1.34,1.53,1.27,1.46,1.77,1.60,1.57,1.16,1.38,1.12,1.35,1.06,1.00,1.28,0.97,0.89,0.95,0.76,0.81,0.79,0.86,0.85,0.92,0.93,0.93,0.85,0.87,0.74,0.78,0.74,0.79,0.82,0.76,0.79,0.96,0.85,0.90,0.94,1.09,0.99,0.81,0.85,0.89,0.95,0.90,0.99,0.94,1.10,1.24,0.98,0.75,0.73,0.78,0.74,0.72,0.77,0.76,0.82,0.89,0.83,0.73,0.71,0.71,0.71,0.70,0.72,0.77,0.80,0.74,0.90,0.85,0.84,0.78,0.79,0.75,0.73,0.92,0.95,0.86,1.05,0.99,0.94,0.90,0.86,0.79,0.81,1.00,0.98,0.91,0.96,0.89,0.83,1.27,1.50,1.23,1.80,1.69,1.63,1.46,1.37,1.09,1.16,1.24,1.44,1.49,1.69,1.59,1.80,1.69,1.87,1.86,1.72,1.82,1.91,1.94,1.92,1.95,1.99,1.98,1.91,1.97,1.89,1.51,1.72,1.67,1.77,1.86,1.55,1.41,1.25,1.33,1.58,1.50,1.80,1.63,1.74,1.04,1.21,0.97,1.48,1.37,1.21,0.93,0.97,1.05,0.92,0.88,0.84,1.14,1.02,1.34,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, {1.94,1.84,1.87,1.64,1.71,1.71,1.14,1.38,1.19,1.46,1.23,1.26,1.48,1.26,1.50,1.91,1.80,1.76,1.41,1.61,1.39,1.59,1.33,1.24,1.51,1.18,0.97,1.11,0.82,0.88,0.86,0.94,0.92,0.99,1.03,0.98,0.91,0.90,0.79,0.84,0.77,0.79,0.84,0.77,0.83,0.99,0.85,0.91,0.92,1.02,1.00,0.79,0.80,0.86,0.88,0.84,0.92,0.88,0.97,1.10,0.94,0.74,0.71,0.74,0.72,0.70,0.73,0.72,0.76,0.82,0.77,0.77,0.73,0.74,0.71,0.70,0.73,0.83,0.85,0.78,0.92,0.88,0.86,0.81,0.79,0.74,0.75,0.92,0.93,0.85,0.96,0.94,0.88,0.86,0.81,0.75,0.79,0.93,0.90,0.85,0.88,0.82,0.77,1.05,1.27,0.99,1.60,1.47,1.39,1.20,1.11,0.95,0.97,1.08,1.33,1.31,1.70,1.55,1.76,1.57,1.76,1.70,1.54,1.85,1.97,1.91,1.99,1.97,1.99,1.91,1.77,1.88,1.85,1.39,1.64,1.51,1.58,1.74,1.32,1.22,1.01,1.54,1.76,1.65,1.93,1.70,1.85,1.28,1.39,1.09,1.52,1.48,1.26,0.97,0.99,1.18,1.00,0.93,0.90,1.05,1.01,1.31,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, {1.97,1.92,1.88,1.79,1.79,1.71,1.37,1.59,1.38,1.60,1.35,1.23,1.47,1.30,1.56,1.99,1.93,1.90,1.60,1.78,1.61,1.79,1.57,1.48,1.72,1.40,1.14,1.37,0.89,0.96,0.94,1.07,1.00,1.21,1.30,1.14,0.98,0.96,0.86,0.91,0.83,0.82,0.88,0.82,0.89,1.11,0.87,0.94,0.93,1.02,1.07,0.80,0.79,0.85,0.82,0.80,0.87,0.85,0.93,1.02,0.93,0.77,0.72,0.74,0.71,0.70,0.70,0.71,0.72,0.77,0.74,0.82,0.76,0.79,0.72,0.73,0.76,0.89,0.89,0.82,0.93,0.91,0.86,0.83,0.79,0.73,0.76,0.91,0.89,0.83,0.89,0.89,0.82,0.82,0.76,0.72,0.76,0.86,0.83,0.79,0.82,0.76,0.73,0.94,1.00,0.91,1.37,1.21,1.14,0.98,0.96,0.88,0.89,0.96,1.14,1.07,1.60,1.40,1.61,1.37,1.57,1.48,1.30,1.78,1.93,1.79,1.99,1.92,1.90,1.79,1.59,1.72,1.79,1.30,1.56,1.35,1.38,1.60,1.11,1.07,0.94,1.68,1.86,1.71,1.97,1.68,1.86,1.44,1.49,1.22,1.44,1.49,1.22,0.99,0.99,1.23,1.19,0.98,0.97,0.97,0.98,1.19,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, {1.94,1.97,1.87,1.91,1.85,1.71,1.60,1.77,1.58,1.74,1.51,1.26,1.48,1.39,1.64,1.99,1.97,1.99,1.70,1.85,1.76,1.91,1.76,1.70,1.88,1.55,1.33,1.57,0.96,1.08,1.05,1.31,1.27,1.47,1.54,1.39,1.20,1.11,0.93,0.99,0.90,0.88,0.95,0.88,0.97,1.32,0.92,1.01,0.97,1.10,1.22,0.84,0.80,0.88,0.79,0.79,0.85,0.86,0.92,1.02,0.94,0.82,0.76,0.77,0.72,0.73,0.70,0.72,0.71,0.74,0.74,0.88,0.81,0.85,0.75,0.77,0.82,0.94,0.93,0.86,0.92,0.92,0.86,0.85,0.79,0.74,0.79,0.88,0.85,0.81,0.82,0.83,0.77,0.78,0.73,0.71,0.75,0.79,0.77,0.74,0.77,0.73,0.70,0.86,0.92,0.84,1.14,0.99,0.98,0.91,0.90,0.84,0.83,0.88,0.97,0.94,1.41,1.18,1.39,1.11,1.33,1.24,1.03,1.61,1.80,1.59,1.91,1.84,1.76,1.64,1.38,1.51,1.71,1.26,1.50,1.23,1.19,1.46,0.99,1.00,0.91,1.70,1.85,1.65,1.93,1.54,1.76,1.52,1.48,1.26,1.28,1.39,1.09,0.99,0.97,1.18,1.31,1.01,1.05,0.90,0.93,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, {1.86,1.95,1.82,1.98,1.89,1.71,1.80,1.91,1.77,1.86,1.67,1.34,1.53,1.51,1.72,1.92,1.91,1.99,1.69,1.82,1.80,1.94,1.87,1.86,1.97,1.59,1.44,1.69,1.05,1.24,1.27,1.49,1.50,1.69,1.72,1.63,1.46,1.37,1.00,1.23,0.98,0.95,1.09,0.96,1.16,1.55,0.99,1.25,1.10,1.24,1.41,0.90,0.85,0.94,0.79,0.81,0.85,0.89,0.94,1.09,0.98,0.89,0.82,0.83,0.74,0.77,0.72,0.76,0.73,0.75,0.78,0.94,0.86,0.91,0.79,0.83,0.89,0.99,0.95,0.90,0.90,0.92,0.84,0.86,0.79,0.75,0.81,0.85,0.80,0.78,0.76,0.77,0.73,0.74,0.71,0.71,0.73,0.74,0.74,0.71,0.76,0.72,0.70,0.79,0.85,0.78,0.98,0.92,0.93,0.85,0.87,0.82,0.79,0.81,0.89,0.86,1.16,0.97,1.12,0.95,1.06,1.00,0.93,1.38,1.60,1.35,1.77,1.71,1.57,1.48,1.20,1.28,1.62,1.27,1.46,1.17,1.05,1.34,0.96,0.99,0.90,1.63,1.74,1.50,1.80,1.33,1.58,1.48,1.37,1.21,1.04,1.21,0.97,0.97,0.93,1.05,1.34,1.02,1.14,0.84,0.88,0.92,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, {1.74,1.89,1.76,1.98,1.89,1.71,1.93,1.99,1.91,1.94,1.82,1.46,1.60,1.65,1.80,1.79,1.77,1.92,1.57,1.69,1.74,1.87,1.88,1.94,1.98,1.53,1.45,1.70,1.18,1.32,1.42,1.58,1.65,1.83,1.81,1.81,1.67,1.61,1.19,1.44,1.17,1.11,1.36,1.15,1.41,1.75,1.22,1.50,1.34,1.42,1.61,0.98,0.92,1.03,0.83,0.86,0.89,0.95,0.98,1.23,1.14,0.97,0.89,0.90,0.78,0.82,0.76,0.82,0.77,0.79,0.84,0.98,0.90,0.98,0.83,0.89,0.97,1.03,0.95,0.92,0.86,0.90,0.82,0.86,0.79,0.77,0.84,0.81,0.76,0.76,0.72,0.73,0.70,0.72,0.71,0.73,0.73,0.72,0.74,0.71,0.78,0.74,0.72,0.75,0.80,0.76,0.94,0.88,0.91,0.83,0.87,0.84,0.79,0.76,0.82,0.80,0.97,0.89,0.96,0.88,0.95,0.94,0.87,1.11,1.37,1.10,1.59,1.57,1.37,1.33,1.05,1.08,1.54,1.34,1.46,1.16,0.99,1.26,0.96,1.05,0.92,1.45,1.55,1.27,1.60,1.07,1.34,1.35,1.18,1.07,0.93,0.99,0.90,0.93,0.87,0.96,1.27,0.99,1.15,0.77,0.82,0.85,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, {1.60,1.78,1.68,1.93,1.86,1.71,1.97,1.99,1.99,1.97,1.93,1.60,1.68,1.78,1.86,1.61,1.57,1.79,1.37,1.48,1.59,1.72,1.79,1.92,1.90,1.38,1.35,1.60,1.23,1.30,1.47,1.56,1.71,1.88,1.79,1.92,1.79,1.79,1.30,1.56,1.35,1.37,1.59,1.38,1.60,1.90,1.48,1.72,1.57,1.61,1.79,1.21,1.00,1.30,0.89,0.94,0.96,1.07,1.14,1.40,1.37,1.14,0.96,0.98,0.82,0.88,0.82,0.89,0.83,0.86,0.91,1.02,0.93,1.07,0.87,0.94,1.11,1.02,0.93,0.93,0.82,0.87,0.80,0.85,0.79,0.80,0.85,0.77,0.72,0.74,0.71,0.70,0.70,0.71,0.72,0.77,0.74,0.72,0.76,0.73,0.82,0.79,0.76,0.73,0.79,0.76,0.93,0.86,0.91,0.83,0.89,0.89,0.82,0.72,0.76,0.76,0.89,0.82,0.89,0.82,0.89,0.91,0.83,0.96,1.14,0.97,1.40,1.44,1.19,1.22,0.99,0.98,1.49,1.44,1.49,1.22,0.99,1.23,0.98,1.19,0.97,1.21,1.30,1.00,1.37,0.94,1.07,1.14,0.98,0.96,0.86,0.91,0.83,0.88,0.82,0.89,1.11,0.94,1.07,0.73,0.76,0.79,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, {1.46,1.65,1.60,1.82,1.80,1.71,1.93,1.91,1.99,1.94,1.98,1.74,1.76,1.89,1.89,1.42,1.34,1.61,1.11,1.22,1.36,1.50,1.61,1.81,1.75,1.15,1.17,1.41,1.18,1.19,1.42,1.44,1.65,1.83,1.67,1.94,1.81,1.88,1.32,1.58,1.45,1.57,1.74,1.53,1.70,1.98,1.69,1.87,1.77,1.79,1.92,1.45,1.27,1.55,0.97,1.07,1.11,1.34,1.37,1.59,1.60,1.35,1.07,1.18,0.86,0.93,0.87,0.96,0.90,0.93,0.99,1.03,0.95,1.15,0.90,0.99,1.27,0.98,0.90,0.92,0.78,0.83,0.77,0.84,0.79,0.82,0.86,0.73,0.71,0.73,0.72,0.70,0.73,0.72,0.76,0.81,0.76,0.76,0.82,0.77,0.89,0.85,0.82,0.75,0.80,0.80,0.94,0.88,0.94,0.87,0.95,0.96,0.88,0.72,0.74,0.76,0.83,0.78,0.84,0.79,0.87,0.91,0.83,0.89,0.98,0.92,1.23,1.34,1.05,1.16,0.99,0.96,1.46,1.57,1.54,1.33,1.05,1.26,1.08,1.37,1.10,0.98,1.03,0.92,1.14,0.86,0.95,0.97,0.90,0.89,0.79,0.84,0.77,0.82,0.76,0.82,0.97,0.89,0.98,0.71,0.72,0.74,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, {1.34,1.51,1.53,1.67,1.72,1.71,1.80,1.77,1.91,1.86,1.98,1.86,1.82,1.95,1.89,1.24,1.10,1.41,0.95,0.99,1.09,1.25,1.37,1.63,1.55,0.96,0.98,1.16,1.05,1.00,1.27,1.23,1.50,1.69,1.46,1.86,1.72,1.87,1.24,1.49,1.44,1.69,1.80,1.59,1.69,1.97,1.82,1.94,1.91,1.92,1.99,1.63,1.50,1.74,1.16,1.33,1.38,1.58,1.60,1.77,1.80,1.48,1.21,1.37,0.90,0.97,0.93,1.05,0.97,1.04,1.21,0.99,0.95,1.14,0.92,1.02,1.34,0.94,0.86,0.90,0.74,0.79,0.75,0.81,0.79,0.84,0.86,0.71,0.71,0.73,0.76,0.73,0.77,0.74,0.80,0.85,0.78,0.81,0.89,0.84,0.97,0.92,0.88,0.79,0.85,0.86,0.98,0.92,1.00,0.93,1.06,1.12,0.95,0.74,0.74,0.78,0.79,0.76,0.82,0.79,0.87,0.93,0.85,0.85,0.94,0.90,1.09,1.27,0.99,1.17,1.05,0.96,1.46,1.71,1.62,1.48,1.20,1.34,1.28,1.57,1.35,0.90,0.94,0.85,0.98,0.81,0.89,0.89,0.83,0.82,0.75,0.78,0.73,0.77,0.72,0.76,0.89,0.83,0.91,0.71,0.70,0.72,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, {1.26,1.39,1.48,1.51,1.64,1.71,1.60,1.58,1.77,1.74,1.91,1.94,1.87,1.97,1.85,1.10,0.97,1.22,0.88,0.92,0.95,1.01,1.11,1.39,1.32,0.88,0.90,0.97,0.96,0.93,1.05,0.99,1.27,1.47,1.20,1.70,1.54,1.76,1.08,1.31,1.33,1.70,1.76,1.55,1.57,1.88,1.85,1.91,1.97,1.99,1.99,1.70,1.65,1.85,1.41,1.54,1.61,1.76,1.80,1.91,1.93,1.52,1.26,1.48,0.92,0.99,0.97,1.18,1.09,1.28,1.39,0.94,0.93,1.05,0.92,1.01,1.31,0.88,0.81,0.86,0.72,0.75,0.74,0.79,0.79,0.86,0.85,0.71,0.73,0.75,0.82,0.77,0.83,0.78,0.85,0.88,0.81,0.88,0.97,0.90,1.18,1.00,0.93,0.86,0.92,0.94,1.14,0.99,1.24,1.03,1.33,1.39,1.11,0.79,0.77,0.84,0.79,0.77,0.84,0.83,0.90,0.98,0.91,0.85,0.92,0.91,1.02,1.26,1.00,1.23,1.19,0.99,1.50,1.84,1.71,1.64,1.38,1.46,1.51,1.76,1.59,0.84,0.88,0.80,0.94,0.79,0.86,0.82,0.77,0.76,0.74,0.74,0.71,0.73,0.70,0.72,0.82,0.77,0.85,0.74,0.70,0.73,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00} } alien-arena-7.66+dfsg/source/ref_gl/r_varray.c0000600000175000017500000004427012161402007020346 0ustar zero79zero79/* Copyright (C) 1997 - 2001 Id Software, Inc. This program is free software; you can redistribute it and / or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 - 1307, USA. */ /* ========================================================================================================================================== VERTEX ARRAYS SUBSYSTEM - Adopted from MHQ2 and modified for CRX This was written to enable much the same rendering code to be used for almost everything. A smallish enough vertex array buffer is used to enable a balance of fast transfers of smaller chunks of data to the 3D card (with - hopefully - a decent level of amortization) and a reduced number of API calls. This system allows up to MAX_VERTS verts to be transferred at once. In reality though, the transfer has to take place at least every time the primitive type changes (that's vertex arrays for you). ========================================================================================================================================== */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "r_local.h" #include "r_ragdoll.h" // this must be equal to MAX_VERTS as it's possible for a single MDL to be composed of only one triangle fan or strip. // the storage overhead is only in the order of 100K anyway, so it's no big deal. // add 2 more verts for surface warping float VArrayVerts[MAX_VARRAY_VERTS * MAX_VARRAY_VERTEX_SIZE]; // pointer for dynamic vert allocation float *VArray = &VArrayVerts[0]; // arrays for normalmapping in glsl static vec3_t NormalsArray[MAX_VERTICES]; // static vec4_t TangentsArray[MAX_VERTICES]; // unused // number of verts allocated static int VertexCounter = 0; float tex_array[MAX_ARRAY][2]; float st_array[MAX_ARRAY][2]; float vert_array[MAX_ARRAY][3]; float norm_array[MAX_ARRAY][3]; float tan_array[MAX_ARRAY][4]; float col_array[MAX_ARRAY][4]; // sizes of our vertexes. the vertex type can be used as an index into this array int VertexSizes[] = {5, 5, 7, 7, 9, 11, 5, 3, 12, 5}; int KillFlags; /* ================= R_InitVArrays Sets up the current vertex arrays we're going to use for rendering. ================= */ void R_InitVArrays (int varraytype) { // it's assumed that the programmer has already called glDrawArrays for everything before calling this, so // here we will just re-init our pointer and counter VArray = &VArrayVerts[0]; VertexCounter = 0; // init the kill flags so we'll know what to kill KillFlags = 0; // all vertex types bring up a vertex pointer // uses array indices 0, 1, 2 qglEnableClientState (GL_VERTEX_ARRAY); qglVertexPointer (3, GL_FLOAT, sizeof (float) * VertexSizes[varraytype], &VArrayVerts[0]); // no texturing at all if (varraytype == VERT_NO_TEXTURE) return; // the simplest possible textured render uses a texcoord pointer for TMU 0 if (varraytype == VERT_SINGLE_TEXTURED) { // uses array indices 3, 4 qglClientActiveTextureARB (GL_TEXTURE0); qglEnableClientState (GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer (2, GL_FLOAT, sizeof (float) * VertexSizes[VERT_SINGLE_TEXTURED], &VArrayVerts[3]); KillFlags |= KILL_TMU0_POINTER; return; } // 2 TMUs which share texcoords if (varraytype == VERT_DUAL_TEXTURED) { // uses array indices 3, 4 qglClientActiveTextureARB (GL_TEXTURE0); qglEnableClientState (GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer (2, GL_FLOAT, sizeof (float) * VertexSizes[VERT_DUAL_TEXTURED], &VArrayVerts[3]); // uses array indices 3, 4 qglClientActiveTextureARB (GL_TEXTURE1); qglEnableClientState (GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer (2, GL_FLOAT, sizeof (float) * VertexSizes[VERT_DUAL_TEXTURED], &VArrayVerts[3]); KillFlags |= (KILL_TMU0_POINTER | KILL_TMU1_POINTER); return; } // the bumpmapped setup gets to reuse the verts as it's texcoords for tmu 0 if (varraytype == VERT_BUMPMAPPED) { // uses array indices 0, 1, 2 qglClientActiveTextureARB (GL_TEXTURE0); qglEnableClientState (GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer (3, GL_FLOAT, sizeof (float) * VertexSizes[VERT_BUMPMAPPED], &VArrayVerts[0]); // uses array indices 3, 4 qglClientActiveTextureARB (GL_TEXTURE1); qglEnableClientState (GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer (2, GL_FLOAT, sizeof (float) * VertexSizes[VERT_BUMPMAPPED], &VArrayVerts[3]); KillFlags |= (KILL_TMU0_POINTER | KILL_TMU1_POINTER); return; } if (varraytype == VERT_BUMPMAPPED_COLOURED) { // uses array indices 0, 1, 2 qglClientActiveTextureARB (GL_TEXTURE0); qglEnableClientState (GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer (3, GL_FLOAT, sizeof (float) * VertexSizes[VERT_BUMPMAPPED_COLOURED], &VArrayVerts[0]); // uses array indices 3, 4 qglClientActiveTextureARB (GL_TEXTURE1); qglEnableClientState (GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer (2, GL_FLOAT, sizeof (float) * VertexSizes[VERT_BUMPMAPPED_COLOURED], &VArrayVerts[3]); // uses array indices 5, 6, 7, 8 qglEnableClientState (GL_COLOR_ARRAY); qglColorPointer (4, GL_FLOAT, sizeof (float) * VertexSizes[VERT_BUMPMAPPED_COLOURED], &VArrayVerts[5]); KillFlags |= (KILL_TMU0_POINTER | KILL_TMU1_POINTER | KILL_RGBA_POINTER); return; } // a standard 2 tmu multitexture needs 2 texcoord pointers. to do - for bsp surface VBO, we will have some changes here if (varraytype == VERT_MULTI_TEXTURED) { // uses array indices 3, 4 qglClientActiveTextureARB (GL_TEXTURE0); qglEnableClientState (GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer (2, GL_FLOAT, sizeof (float) * VertexSizes[VERT_MULTI_TEXTURED], &VArrayVerts[3]); // uses array indices 5, 6 qglClientActiveTextureARB (GL_TEXTURE1); qglEnableClientState (GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer (2, GL_FLOAT, sizeof (float) * VertexSizes[VERT_MULTI_TEXTURED], &VArrayVerts[5]); KillFlags |= (KILL_TMU0_POINTER | KILL_TMU1_POINTER); return; } // no texture is used here but we do specify a colour (used in Q2 for laser beams, etc) if (varraytype == VERT_COLOURED_UNTEXTURED) { // uses array indices 3, 4, 5, 6 qglEnableClientState (GL_COLOR_ARRAY); qglColorPointer (4, GL_FLOAT, sizeof (float) * VertexSizes[VERT_COLOURED_UNTEXTURED], &VArrayVerts[3]); KillFlags |= KILL_RGBA_POINTER; return; } // single texture + colour (water, mdls, and so on) if (varraytype == VERT_COLOURED_TEXTURED) { // uses array indices 3, 4 qglClientActiveTextureARB (GL_TEXTURE0); qglEnableClientState (GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer (2, GL_FLOAT, sizeof (float) * VertexSizes[VERT_COLOURED_TEXTURED], &VArrayVerts[3]); // uses array indices 5, 6, 7, 8 qglEnableClientState (GL_COLOR_ARRAY); qglColorPointer (4, GL_FLOAT, sizeof (float) * VertexSizes[VERT_COLOURED_TEXTURED], &VArrayVerts[5]); KillFlags |= (KILL_TMU0_POINTER | KILL_RGBA_POINTER); return; } // multi texture + colour if (varraytype == VERT_COLOURED_MULTI_TEXTURED) { // uses array indices 3, 4 qglClientActiveTextureARB (GL_TEXTURE0); qglEnableClientState (GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer (2, GL_FLOAT, sizeof (float) * VertexSizes[VERT_COLOURED_MULTI_TEXTURED], &VArrayVerts[3]); // uses array indices 5, 6 qglClientActiveTextureARB (GL_TEXTURE1); qglEnableClientState (GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer (2, GL_FLOAT, sizeof (float) * VertexSizes[VERT_COLOURED_MULTI_TEXTURED], &VArrayVerts[5]); // uses array indices 7, 8, 9, 10 qglEnableClientState (GL_COLOR_ARRAY); qglColorPointer (4, GL_FLOAT, sizeof (float) * VertexSizes[VERT_COLOURED_MULTI_TEXTURED], &VArrayVerts[7]); KillFlags |= (KILL_TMU0_POINTER | KILL_TMU1_POINTER | KILL_RGBA_POINTER); return; } // textured with up to 3 TMU's, with normals if (varraytype == VERT_NORMAL_COLOURED_TEXTURED) { // uses array indices 3, 4 qglClientActiveTextureARB (GL_TEXTURE0); qglEnableClientState (GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer (2, GL_FLOAT, sizeof (float) * VertexSizes[VERT_NORMAL_COLOURED_TEXTURED], &VArrayVerts[3]); qglClientActiveTextureARB (GL_TEXTURE1); qglEnableClientState (GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer (2, GL_FLOAT, sizeof (float) * VertexSizes[VERT_NORMAL_COLOURED_TEXTURED], &VArrayVerts[3]); qglClientActiveTextureARB (GL_TEXTURE2); qglEnableClientState (GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer (2, GL_FLOAT, sizeof (float) * VertexSizes[VERT_NORMAL_COLOURED_TEXTURED], &VArrayVerts[3]); // normal data qglEnableClientState( GL_NORMAL_ARRAY ); KillFlags |= (KILL_TMU0_POINTER | KILL_TMU1_POINTER | KILL_TMU2_POINTER | KILL_NORMAL_POINTER); return; } } /* ================= R_KillVArrays Shuts down the specified vertex arrays. Again, for maximum flexibility no programmer hand-holding is done. ================= */ void R_KillVArrays (void) { if(KillFlags & KILL_NORMAL_POINTER) qglDisableClientState (GL_NORMAL_ARRAY); if (KillFlags & KILL_RGBA_POINTER) qglDisableClientState (GL_COLOR_ARRAY); if (KillFlags & KILL_TMU5_POINTER) { qglClientActiveTextureARB (GL_TEXTURE5); qglDisableClientState (GL_TEXTURE_COORD_ARRAY); } if (KillFlags & KILL_TMU4_POINTER) { qglClientActiveTextureARB (GL_TEXTURE4); qglDisableClientState (GL_TEXTURE_COORD_ARRAY); } if (KillFlags & KILL_TMU3_POINTER) { qglClientActiveTextureARB (GL_TEXTURE3); qglDisableClientState (GL_TEXTURE_COORD_ARRAY); } if (KillFlags & KILL_TMU2_POINTER) { qglClientActiveTextureARB (GL_TEXTURE2); qglDisableClientState (GL_TEXTURE_COORD_ARRAY); } if (KillFlags & KILL_TMU1_POINTER) { qglClientActiveTextureARB (GL_TEXTURE1); qglDisableClientState (GL_TEXTURE_COORD_ARRAY); } if (KillFlags & KILL_TMU0_POINTER) { qglClientActiveTextureARB (GL_TEXTURE0); qglDisableClientState (GL_TEXTURE_COORD_ARRAY); } // always kill qglDisableClientState (GL_VERTEX_ARRAY); } void R_DrawVarrays(GLenum mode, GLint first, GLsizei count) { if(count < 1) return; //do not send arrays of zero size to GPU! if(gl_state.vbo) GL_BindVBO(NULL); //make sure that we aren't using an invalid buffer qglDrawArrays (mode, first, count); } void R_AddSurfToVArray (msurface_t *surf) { glpoly_t *p = surf->polys; float *v; int i; for (; p; p = p->chain) { // reset pointer and counter VArray = &VArrayVerts[0]; VertexCounter = 0; for (v = p->verts[0], i = 0 ; i < p->numverts; i++, v += VERTEXSIZE) { // copy in vertex data VArray[0] = v[0]; VArray[1] = v[1]; VArray[2] = v[2]; // nothing else is needed // increment pointer and counter VArray += VertexSizes[VERT_NO_TEXTURE]; VertexCounter++; } // draw the poly R_DrawVarrays(GL_POLYGON, 0, VertexCounter); } } extern int SignbitsForPlane (cplane_t *out); void R_AddShadowSurfToVArray (msurface_t *surf, vec3_t origin) { glpoly_t *p = surf->polys; float *v, *v2; int i; float sq_len; vec3_t vDist; vec3_t tmp, mins, maxs; qboolean renderPoly; VectorAdd (currentmodel->maxs, origin, maxs); VectorAdd (currentmodel->mins, origin, mins); for (; p; p = p->chain) { // reset pointer and counter VArray = &VArrayVerts[0]; VertexCounter = 0; VectorSubtract(currentmodel->maxs, currentmodel->mins, tmp); /* lengths used for comparison only, so squared lengths may be used.*/ sq_len = tmp[0]*tmp[0] + tmp[1]*tmp[1] + tmp[2]*tmp[2] ; if ( sq_len < 4096.0f ) sq_len = 4096.0f; /* 64^2 */ else if ( sq_len > 65536.0f ) sq_len = 65536.0f; /* 256^2 */ renderPoly = false; for ( v = p->verts[0], i = 0; i < p->numverts; i++, v += VERTEXSIZE ) { // Generate plane out of the triangle between v, v+1, and the // light point. This plane will be one of the borders of the // 3D volume within which an object may cast a shadow on the // world polygon. vec3_t plane_line_1, plane_line_2; cplane_t plane; // generate two vectors representing two sides of the triangle VectorSubtract (v, statLightPosition, plane_line_1); v2 = p->verts[(i+1)%p->numverts]; VectorSubtract (v2, v, plane_line_2); // generate the actual plane CrossProduct (plane_line_1, plane_line_2, plane.normal); VectorNormalize (plane.normal); plane.type = PLANE_ANYZ; plane.dist = DotProduct (v, plane.normal); plane.signbits = SignbitsForPlane (&plane); // CullBox-type operation if (BoxOnPlaneSide (mins, maxs, &plane) == 2) { //completely clipped; we can skip this surface return; } if ( !renderPoly ) { /* once set, no need for calculation */ float vsq_len; VectorSubtract( origin, v, vDist ); vsq_len = vDist[0]*vDist[0] + vDist[1]*vDist[1] + vDist[2]*vDist[2]; if ( vsq_len < sq_len ) { renderPoly = true; } } // copy in vertex data VArray[0] = v[0]; VArray[1] = v[1]; VArray[2] = v[2]; // nothing else is needed // increment pointer and counter VArray += VertexSizes[VERT_NO_TEXTURE]; VertexCounter++; } // draw the poly if(renderPoly) R_DrawVarrays(GL_POLYGON, 0, VertexCounter); } } /* ================= R_AddTexturedSurfToVArray Adds a textured surf to the varray. The surface can have 1 or more polys, and the VArray is flushed immediately after each poly is rendered. It's assumed that the programmer has set up the vertex arrays properly before calling this, otherwise weird things may happen!!! ================= */ void R_AddTexturedSurfToVArray (msurface_t *surf, float scroll) { glpoly_t *p = surf->polys; float *v; int i; for (; p; p = p->chain) { // reset pointer and counter VArray = &VArrayVerts[0]; VertexCounter = 0; for (v = p->verts[0], i = 0 ; i < p->numverts; i++, v += VERTEXSIZE) { // copy in vertex data VArray[0] = v[0]; VArray[1] = v[1]; VArray[2] = v[2]; // world texture coords VArray[3] = v[3] + scroll; VArray[4] = v[4]; // nothing else is needed // increment pointer and counter VArray += VertexSizes[VERT_SINGLE_TEXTURED]; VertexCounter++; } // draw the poly R_DrawVarrays(GL_POLYGON, 0, VertexCounter); } } /* ================= R_AddLightMappedSurfToVArray Adds a lightmapped surf to the varray. The surface can have 1 or more polys, and the VArray is flushed immediately after each poly is rendered. It's assumed that the programmer has set up the vertex arrays properly before calling this, otherwise weird things may happen!!! ================= */ void R_AddLightMappedSurfToVArray (msurface_t *surf, float scroll) { glpoly_t *p = surf->polys; float *v; int i; // reset pointer and counter VArray = &VArrayVerts[0]; VertexCounter = 0; //non warped surfaces only have one poly for (v = p->verts[0], i = 0 ; i < p->numverts; i++, v += VERTEXSIZE) { // copy in vertex data VArray[0] = v[0]; VArray[1] = v[1]; VArray[2] = v[2]; // world texture coords VArray[3] = v[3] + scroll; VArray[4] = v[4]; // lightmap texture coords VArray[5] = v[5]; VArray[6] = v[6]; // nothing else is needed // increment pointer and counter VArray += VertexSizes[VERT_MULTI_TEXTURED]; VertexCounter++; } /* * Mapping tool. Outline the light-mapped polygons. * gl_showpolys == 1 : perform depth test. * gl_showpolys == 2 : disable depth test. everything in "visible set" */ if (gl_showpolys->integer) // restricted cvar, maxclients = 1 { qglDisable (GL_TEXTURE_2D); if (gl_showpolys->integer >= 2) { // lots of lines so make them narrower qglDisable(GL_DEPTH_TEST); qglLineWidth (2.0f); } else { // less busy, wider line qglLineWidth (3.0f); } qglColor4f (1.0f, 1.0f, 1.0f, 1.0f); qglBegin (GL_LINE_LOOP); for (v = p->verts[0], i = 0; i < p->numverts; i++, v += VERTEXSIZE) { qglVertex3fv(p->verts[i]); } qglEnd(); qglEnable (GL_DEPTH_TEST); qglEnable (GL_TEXTURE_2D); } // draw the polys R_DrawVarrays(GL_POLYGON, 0, VertexCounter); } void R_AddGLSLShadedWarpSurfToVArray (msurface_t *surf, float scroll) { glpoly_t *p = surf->polys; float *v; int i; for (; p; p = p->chain) { // reset pointer and counter VArray = &VArrayVerts[0]; VertexCounter = 0; for (v = p->verts[0], i = 0 ; i < p->numverts; i++, v += VERTEXSIZE) { // copy in vertex data VArray[0] = v[0]; VArray[1] = v[1]; VArray[2] = v[2]; // world texture coords VArray[3] = v[3] + scroll; VArray[4] = v[4]; // nothing else is needed // increment pointer and counter VArray += VertexSizes[VERT_COLOURED_TEXTURED]; VertexCounter++; } } // draw the polys R_DrawVarrays(GL_POLYGON, 0, VertexCounter); } /* ==================== R_InitQuadVarrays Used for 2 dimensional quads ==================== */ void R_InitQuadVarrays(void) { qglEnableClientState (GL_VERTEX_ARRAY); qglEnableClientState (GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer (2, GL_FLOAT, sizeof(tex_array[0]), tex_array[0]); qglVertexPointer (3, GL_FLOAT, sizeof(vert_array[0]), vert_array[0]); qglColorPointer (4, GL_FLOAT, sizeof(col_array[0]), col_array[0]); KillFlags |= KILL_TMU0_POINTER; } alien-arena-7.66+dfsg/source/ref_gl/r_math.c0000600000175000017500000001510212161402007017763 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // r_math.c #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "game/q_shared.h" #include "r_math.h" const mat4x4_t mat4x4_identity = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }; void Matrix4_Identity( mat4x4_t m ) { int i; for( i = 0; i < 16; i++ ) { if( i == 0 || i == 5 || i == 10 || i == 15 ) m[i] = 1.0; else m[i] = 0.0; } } void Matrix4_Copy( const mat4x4_t m1, mat4x4_t m2 ) { int i; for( i = 0; i < 16; i++ ) m2[i] = m1[i]; } qboolean Matrix4_Compare( const mat4x4_t m1, const mat4x4_t m2 ) { int i; for( i = 0; i < 16; i++ ) if( m1[i] != m2[i] ) return false; return true; } void Matrix4_Multiply( const mat4x4_t m1, const mat4x4_t m2, mat4x4_t out ) { out[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3]; out[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3]; out[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3]; out[3] = m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3]; out[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7]; out[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7]; out[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7]; out[7] = m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7]; out[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11]; out[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11]; out[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11]; out[11] = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11]; out[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15]; out[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15]; out[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15]; out[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15]; } void Matrix4_MultiplyFast( const mat4x4_t m1, const mat4x4_t m2, mat4x4_t out ) { out[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2]; out[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2]; out[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2]; out[3] = 0.0f; out[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6]; out[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6]; out[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6]; out[7] = 0.0f; out[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10]; out[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10]; out[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10]; out[11] = 0.0f; out[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12]; out[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13]; out[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14]; out[15] = 1.0f; } void Matrix4_Rotate( mat4x4_t m, vec_t angle, vec_t x, vec_t y, vec_t z ) { mat4x4_t t, b; vec_t c = cos( DEG2RAD(angle) ); vec_t s = sin( DEG2RAD(angle) ); vec_t mc = 1 - c, t1, t2; t[0] = (x * x * mc) + c; t[5] = (y * y * mc) + c; t[10] = (z * z * mc) + c; t1 = y * x * mc; t2 = z * s; t[1] = t1 + t2; t[4] = t1 - t2; t1 = x * z * mc; t2 = y * s; t[2] = t1 - t2; t[8] = t1 + t2; t1 = y * z * mc; t2 = x * s; t[6] = t1 + t2; t[9] = t1 - t2; t[3] = t[7] = t[11] = t[12] = t[13] = t[14] = 0; t[15] = 1; Matrix4_Copy( m, b ); Matrix4_MultiplyFast( b, t, m ); } void Matrix4_Translate( mat4x4_t m, vec_t x, vec_t y, vec_t z ) { m[12] = m[0] * x + m[4] * y + m[8] * z + m[12]; m[13] = m[1] * x + m[5] * y + m[9] * z + m[13]; m[14] = m[2] * x + m[6] * y + m[10] * z + m[14]; m[15] = m[3] * x + m[7] * y + m[11] * z + m[15]; } void Matrix4_Scale( mat4x4_t m, vec_t x, vec_t y, vec_t z ) { m[0] *= x; m[4] *= y; m[8] *= z; m[1] *= x; m[5] *= y; m[9] *= z; m[2] *= x; m[6] *= y; m[10] *= z; m[3] *= x; m[7] *= y; m[11] *= z; } void Matrix4_Transpose( const mat4x4_t m, mat4x4_t out ) { out[0] = m[0]; out[1] = m[4]; out[2] = m[8]; out[3] = m[12]; out[4] = m[1]; out[5] = m[5]; out[6] = m[9]; out[7] = m[13]; out[8] = m[2]; out[9] = m[6]; out[10] = m[10]; out[11] = m[14]; out[12] = m[3]; out[13] = m[7]; out[14] = m[11]; out[15] = m[15]; } void Matrix4_Matrix( const mat4x4_t in, vec3_t out[3] ) { out[0][0] = in[0]; out[0][1] = in[4]; out[0][2] = in[8]; out[1][0] = in[1]; out[1][1] = in[5]; out[1][2] = in[9]; out[2][0] = in[2]; out[2][1] = in[6]; out[2][2] = in[10]; } void Matrix4_Multiply_Vector( const mat4x4_t m, const vec4_t v, vec4_t out ) { out[0] = m[0] * v[0] + m[4] * v[1] + m[8] * v[2] + m[12] * v[3]; out[1] = m[1] * v[0] + m[5] * v[1] + m[9] * v[2] + m[13] * v[3]; out[2] = m[2] * v[0] + m[6] * v[1] + m[10] * v[2] + m[14] * v[3]; out[3] = m[3] * v[0] + m[7] * v[1] + m[11] * v[2] + m[15] * v[3]; } //============================================================================ void Matrix4_Copy2D( const mat4x4_t m1, mat4x4_t m2 ) { m2[0] = m1[0]; m2[1] = m1[1]; m2[4] = m1[4]; m2[5] = m1[5]; m2[12] = m1[12]; m2[13] = m1[13]; } void Matrix4_Multiply2D( const mat4x4_t m1, const mat4x4_t m2, mat4x4_t out ) { out[0] = m1[0] * m2[0] + m1[4] * m2[1]; out[1] = m1[1] * m2[0] + m1[5] * m2[1]; out[4] = m1[0] * m2[4] + m1[4] * m2[5]; out[5] = m1[1] * m2[4] + m1[5] * m2[5]; out[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[12]; out[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[13]; } void Matrix4_Scale2D( mat4x4_t m, vec_t x, vec_t y ) { m[0] *= x; m[1] *= x; m[4] *= y; m[5] *= y; } void Matrix4_Translate2D( mat4x4_t m, vec_t x, vec_t y ) { m[12] += x; m[13] += y; } void Matrix4_Stretch2D( mat4x4_t m, vec_t s, vec_t t ) { m[0] *= s; m[1] *= s; m[4] *= s; m[5] *= s; m[12] = s * m[12] + t; m[13] = s * m[13] + t; } alien-arena-7.66+dfsg/source/ref_gl/warpsin.h0000600000175000017500000000624212161402007020206 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 0, 0.19633, 0.392541, 0.588517, 0.784137, 0.979285, 1.17384, 1.3677, 1.56072, 1.75281, 1.94384, 2.1337, 2.32228, 2.50945, 2.69512, 2.87916, 3.06147, 3.24193, 3.42044, 3.59689, 3.77117, 3.94319, 4.11282, 4.27998, 4.44456, 4.60647, 4.76559, 4.92185, 5.07515, 5.22538, 5.37247, 5.51632, 5.65685, 5.79398, 5.92761, 6.05767, 6.18408, 6.30677, 6.42566, 6.54068, 6.65176, 6.75883, 6.86183, 6.9607, 7.05537, 7.14579, 7.23191, 7.31368, 7.39104, 7.46394, 7.53235, 7.59623, 7.65552, 7.71021, 7.76025, 7.80562, 7.84628, 7.88222, 7.91341, 7.93984, 7.96148, 7.97832, 7.99036, 7.99759, 8, 7.99759, 7.99036, 7.97832, 7.96148, 7.93984, 7.91341, 7.88222, 7.84628, 7.80562, 7.76025, 7.71021, 7.65552, 7.59623, 7.53235, 7.46394, 7.39104, 7.31368, 7.23191, 7.14579, 7.05537, 6.9607, 6.86183, 6.75883, 6.65176, 6.54068, 6.42566, 6.30677, 6.18408, 6.05767, 5.92761, 5.79398, 5.65685, 5.51632, 5.37247, 5.22538, 5.07515, 4.92185, 4.76559, 4.60647, 4.44456, 4.27998, 4.11282, 3.94319, 3.77117, 3.59689, 3.42044, 3.24193, 3.06147, 2.87916, 2.69512, 2.50945, 2.32228, 2.1337, 1.94384, 1.75281, 1.56072, 1.3677, 1.17384, 0.979285, 0.784137, 0.588517, 0.392541, 0.19633, 9.79717e-16, -0.19633, -0.392541, -0.588517, -0.784137, -0.979285, -1.17384, -1.3677, -1.56072, -1.75281, -1.94384, -2.1337, -2.32228, -2.50945, -2.69512, -2.87916, -3.06147, -3.24193, -3.42044, -3.59689, -3.77117, -3.94319, -4.11282, -4.27998, -4.44456, -4.60647, -4.76559, -4.92185, -5.07515, -5.22538, -5.37247, -5.51632, -5.65685, -5.79398, -5.92761, -6.05767, -6.18408, -6.30677, -6.42566, -6.54068, -6.65176, -6.75883, -6.86183, -6.9607, -7.05537, -7.14579, -7.23191, -7.31368, -7.39104, -7.46394, -7.53235, -7.59623, -7.65552, -7.71021, -7.76025, -7.80562, -7.84628, -7.88222, -7.91341, -7.93984, -7.96148, -7.97832, -7.99036, -7.99759, -8, -7.99759, -7.99036, -7.97832, -7.96148, -7.93984, -7.91341, -7.88222, -7.84628, -7.80562, -7.76025, -7.71021, -7.65552, -7.59623, -7.53235, -7.46394, -7.39104, -7.31368, -7.23191, -7.14579, -7.05537, -6.9607, -6.86183, -6.75883, -6.65176, -6.54068, -6.42566, -6.30677, -6.18408, -6.05767, -5.92761, -5.79398, -5.65685, -5.51632, -5.37247, -5.22538, -5.07515, -4.92185, -4.76559, -4.60647, -4.44456, -4.27998, -4.11282, -3.94319, -3.77117, -3.59689, -3.42044, -3.24193, -3.06147, -2.87916, -2.69512, -2.50945, -2.32228, -2.1337, -1.94384, -1.75281, -1.56072, -1.3677, -1.17384, -0.979285, -0.784137, -0.588517, -0.392541, -0.19633, alien-arena-7.66+dfsg/source/ref_gl/r_iqm.c0000600000175000017500000021544612162607462017652 0ustar zero79zero79/* Copyright (C) 2010 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "r_local.h" #include "r_iqm.h" #include "r_ragdoll.h" #include "r_lodcalc.h" #define RAGDOLLVBO 1 #if !defined max #define max(a,b) (((a)<(b)) ? (b) : (a)) #endif static vec3_t NormalsArray[MAX_VERTICES]; static vec4_t TangentsArray[MAX_VERTICES]; static vertCache_t *vbo_st; static vertCache_t *vbo_xyz; static vertCache_t *vbo_normals; static vertCache_t *vbo_tangents; static vertCache_t *vbo_indices; static qboolean has_vbo; qboolean use_vbo; float modelpitch; extern void Q_strncpyz( char *dest, const char *src, size_t size ); extern void MYgluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar); //these matrix functions should be moved to matrixlib.c or similar void Matrix3x4_TransformNormal(mnormal_t *out, matrix3x4_t mat, const mnormal_t in) { out->dir[0] = DotProduct(mat.a, in.dir); out->dir[1] = DotProduct(mat.b, in.dir); out->dir[2] = DotProduct(mat.c, in.dir); } void Matrix3x4_TransformTangent(mtangent_t *out, matrix3x4_t mat, const mtangent_t in) { out->dir[0] = DotProduct(mat.a, in.dir); out->dir[1] = DotProduct(mat.b, in.dir); out->dir[2] = DotProduct(mat.c, in.dir); } void Matrix3x4_Invert(matrix3x4_t *out, matrix3x4_t in) { vec3_t a, b, c, trans; VectorSet(a, in.a[0], in.b[0], in.c[0]); VectorSet(b, in.a[1], in.b[1], in.c[1]); VectorSet(c, in.a[2], in.b[2], in.c[2]); VectorScale(a, 1/DotProduct(a, a), a); VectorScale(b, 1/DotProduct(b, b), b); VectorScale(c, 1/DotProduct(c, c), c); VectorSet(trans, in.a[3], in.b[3], in.c[3]); Vector4Set(out->a, a[0], a[1], a[2], -DotProduct(a, trans)); Vector4Set(out->b, b[0], b[1], b[2], -DotProduct(b, trans)); Vector4Set(out->c, c[0], c[1], c[2], -DotProduct(c, trans)); } void Matrix3x4_FromQuatAndVectors(matrix3x4_t *out, vec4_t rot, const float trans[3], const float scale[3]) { vec3_t a, b, c; //Convert the quat { float x = rot[0], y = rot[1], z = rot[2], w = rot[3], tx = 2*x, ty = 2*y, tz = 2*z, txx = tx*x, tyy = ty*y, tzz = tz*z, txy = tx*y, txz = tx*z, tyz = ty*z, twx = w*tx, twy = w*ty, twz = w*tz; VectorSet(a, 1 - (tyy + tzz), txy - twz, txz + twy); VectorSet(b, txy + twz, 1 - (txx + tzz), tyz - twx); VectorSet(c, txz - twy, tyz + twx, 1 - (txx + tyy)); } Vector4Set(out->a, a[0]*scale[0], a[1]*scale[1], a[2]*scale[2], trans[0]); Vector4Set(out->b, b[0]*scale[0], b[1]*scale[1], b[2]*scale[2], trans[1]); Vector4Set(out->c, c[0]*scale[0], c[1]*scale[1], c[2]*scale[2], trans[2]); } void Matrix3x4_Multiply(matrix3x4_t *out, matrix3x4_t mat1, matrix3x4_t mat2) { vec4_t a, b, c, d; Vector4Scale(mat2.a, mat1.a[0], a); Vector4Scale(mat2.b, mat1.a[1], b); Vector4Scale(mat2.c, mat1.a[2], c); Vector4Add(a, b, d); Vector4Add(d, c, d); Vector4Set(out->a, d[0], d[1], d[2], d[3] + mat1.a[3]); Vector4Scale(mat2.a, mat1.b[0], a); Vector4Scale(mat2.b, mat1.b[1], b); Vector4Scale(mat2.c, mat1.b[2], c); Vector4Add(a, b, d); Vector4Add(d, c, d); Vector4Set(out->b, d[0], d[1], d[2], d[3] + mat1.b[3]); Vector4Scale(mat2.a, mat1.c[0], a); Vector4Scale(mat2.b, mat1.c[1], b); Vector4Scale(mat2.c, mat1.c[2], c); Vector4Add(a, b, d); Vector4Add(d, c, d); Vector4Set(out->c, d[0], d[1], d[2], d[3] + mat1.c[3]); } void Matrix3x4_Scale(matrix3x4_t *out, matrix3x4_t in, float scale) { Vector4Scale(in.a, scale, out->a); Vector4Scale(in.b, scale, out->b); Vector4Scale(in.c, scale, out->c); } void Matrix3x4_ScaleAdd (matrix3x4_t *out, matrix3x4_t *base, float scale, matrix3x4_t *add) { out->a[0] = base->a[0] * scale + add->a[0]; out->a[1] = base->a[1] * scale + add->a[1]; out->a[2] = base->a[2] * scale + add->a[2]; out->a[3] = base->a[3] * scale + add->a[3]; out->b[0] = base->b[0] * scale + add->b[0]; out->b[1] = base->b[1] * scale + add->b[1]; out->b[2] = base->b[2] * scale + add->b[2]; out->b[3] = base->b[3] * scale + add->b[3]; out->c[0] = base->c[0] * scale + add->c[0]; out->c[1] = base->c[1] * scale + add->c[1]; out->c[2] = base->c[2] * scale + add->c[2]; out->c[3] = base->c[3] * scale + add->c[3]; } void Matrix3x4_Add(matrix3x4_t *out, matrix3x4_t mat1, matrix3x4_t mat2) { Vector4Add(mat1.a, mat2.a, out->a); Vector4Add(mat1.b, mat2.b, out->b); Vector4Add(mat1.c, mat2.c, out->c); } void Matrix3x4_Subtract(matrix3x4_t *out, matrix3x4_t mat1, matrix3x4_t mat2) { Vector4Sub(mat1.a, mat2.a, out->a); Vector4Sub(mat1.b, mat2.b, out->b); Vector4Sub(mat1.c, mat2.c, out->c); } void Matrix3x4_Copy(matrix3x4_t *out, matrix3x4_t in) { Vector4Copy(in.a, out->a); Vector4Copy(in.b, out->b); Vector4Copy(in.c, out->c); } void Matrix3x4_Transform(mvertex_t *out, matrix3x4_t mat, const mvertex_t in) { out->position[0] = DotProduct(mat.a, in.position) + mat.a[3]; out->position[1] = DotProduct(mat.b, in.position) + mat.b[3]; out->position[2] = DotProduct(mat.c, in.position) + mat.c[3]; } void Matrix3x4GenRotate(matrix3x4_t *out, float angle, const vec3_t axis) { float ck = cos(angle), sk = sin(angle); Vector4Set(out->a, axis[0]*axis[0]*(1-ck)+ck, axis[0]*axis[1]*(1-ck)-axis[2]*sk, axis[0]*axis[2]*(1-ck)+axis[1]*sk, 0); Vector4Set(out->b, axis[1]*axis[0]*(1-ck)+axis[2]*sk, axis[1]*axis[1]*(1-ck)+ck, axis[1]*axis[2]*(1-ck)-axis[0]*sk, 0); Vector4Set(out->c, axis[0]*axis[2]*(1-ck)-axis[1]*sk, axis[1]*axis[2]*(1-ck)+axis[0]*sk, axis[2]*axis[2]*(1-ck)+ck, 0); } void Matrix3x4ForEntity(matrix3x4_t *out, entity_t *ent, float z) { matrix3x4_t rotmat; vec3_t rotaxis; Vector4Set(out->a, 1, 0, 0, 0); Vector4Set(out->b, 0, 1, 0, 0); Vector4Set(out->c, 0, 0, 1, 0); if(ent->angles[2]) { VectorSet(rotaxis, -1, 0, 0); Matrix3x4GenRotate(&rotmat, ent->angles[2]*pi/180, rotaxis); Matrix3x4_Multiply(out, rotmat, *out); } if(ent->angles[0]) { VectorSet(rotaxis, 0, -1, 0); Matrix3x4GenRotate(&rotmat, ent->angles[0]*pi/180, rotaxis); Matrix3x4_Multiply(out, rotmat, *out); } if(ent->angles[1]) { VectorSet(rotaxis, 0, 0, 1); Matrix3x4GenRotate(&rotmat, ent->angles[1]*pi/180, rotaxis); Matrix3x4_Multiply(out, rotmat, *out); } out->a[3] += ent->origin[0]; out->b[3] += ent->origin[1]; out->c[3] += ent->origin[2]; } void Matrix3x4GenFromODE(matrix3x4_t *out, const dReal *rot, const dReal *trans) { Vector4Set(out->a, rot[0], rot[1], rot[2], trans[0]); Vector4Set(out->b, rot[4], rot[5], rot[6], trans[1]); Vector4Set(out->c, rot[8], rot[9], rot[10], trans[2]); } double degreeToRadian(double degree) { double radian = 0; radian = degree * (pi/180); return radian; } void IQM_LoadVertexArrays(model_t *iqmmodel, float *vposition, float *vnormal, float *vtangent) { int i; if(iqmmodel->numvertexes > 16384) return; iqmmodel->vertexes = (mvertex_t*)Hunk_Alloc(iqmmodel->numvertexes * sizeof(mvertex_t)); iqmmodel->normal = (mnormal_t*)Hunk_Alloc(iqmmodel->numvertexes * sizeof(mnormal_t)); iqmmodel->tangent = (mtangent_t*)Hunk_Alloc(iqmmodel->numvertexes * sizeof(mtangent_t)); //set this now for later use iqmmodel->animatevertexes = (mvertex_t*)Hunk_Alloc(iqmmodel->numvertexes * sizeof(mvertex_t)); iqmmodel->animatenormal = (mnormal_t*)Hunk_Alloc(iqmmodel->numvertexes * sizeof(mnormal_t)); iqmmodel->animatetangent = (mtangent_t*)Hunk_Alloc(iqmmodel->numvertexes * sizeof(mtangent_t)); for(i=0; inumvertexes; i++){ VectorSet(iqmmodel->vertexes[i].position, LittleFloat(vposition[0]), LittleFloat(vposition[1]), LittleFloat(vposition[2])); VectorSet(iqmmodel->normal[i].dir, LittleFloat(vnormal[0]), LittleFloat(vnormal[1]), LittleFloat(vnormal[2])); Vector4Set(iqmmodel->tangent[i].dir, LittleFloat(vtangent[0]), LittleFloat(vtangent[1]), LittleFloat(vtangent[2]), LittleFloat(vtangent[3])); vposition +=3; vnormal +=3; vtangent +=4; } } qboolean IQM_ReadSkinFile(char skin_file[MAX_OSPATH], char *skinpath) { FILE *fp; int length; char *buffer; char *s; if((fp = fopen(skin_file, "rb" )) == NULL) { return false; } else { size_t sz; fseek(fp, 0, SEEK_END); length = ftell(fp); fseek(fp, 0, SEEK_SET); buffer = malloc( length + 1 ); sz = fread( buffer, length, 1, fp ); buffer[length] = 0; } s = buffer; strcpy( skinpath, COM_Parse( &s ) ); skinpath[length] = 0; //clear any possible garbage if ( fp != 0 ) { fclose(fp); free( buffer ); } else { FS_FreeFile( buffer ); } return true; } qboolean IQM_ReadRagDollFile(char ragdoll_file[MAX_OSPATH], model_t *mod) { FILE *fp; int length; char *buffer; char *s; int result; char a_string[128]; int i; if((fp = fopen(ragdoll_file, "rb" )) == NULL) { return false; } else { length = FS_filelength( fp ); buffer = malloc( length + 1 ); if ( buffer != NULL ) { buffer[length] = 0; result = fread( buffer, length, 1, fp ); if ( result == 1 ) { s = buffer; for(i = 0; i < RAGDOLL_DIMS; i++) { strcpy( a_string, COM_Parse( &s ) ); mod->ragdoll.RagDollDims[i] = atof(a_string); } strcpy( a_string, COM_Parse( &s ) ); mod->ragdoll.hasHelmet = atoi(a_string); } else { Com_Printf("IQM_ReadRagDollFile: read fail\n"); } free( buffer ); } fclose( fp ); } return true; } qboolean Mod_INTERQUAKEMODEL_Load(model_t *mod, void *buffer) { iqmheader_t *header; int i, j, k; const int *inelements; float *vposition = NULL, *vtexcoord = NULL, *vnormal = NULL, *vtangent = NULL; //unsigned char *vblendweights = NULL; unsigned char *pbase; iqmjoint_t *joint = NULL; iqmjoint2_t *joint2 = NULL; matrix3x4_t *inversebaseframe; iqmpose_t *poses; iqmpose2_t *poses2; iqmbounds_t *bounds; iqmvertexarray_t *va; unsigned short *framedata; char *text; char skinname[MAX_QPATH], shortname[MAX_QPATH], fullname[MAX_OSPATH]; char *pskinpath_buffer; int skinpath_buffer_length; char *parse_string; pbase = (unsigned char *)buffer; header = (iqmheader_t *)buffer; if (memcmp(header->id, "INTERQUAKEMODEL", 16)) { Com_Printf ("Mod_INTERQUAKEMODEL_Load: %s is not an Inter-Quake Model", mod->name); return false; } if (LittleLong(header->version) != 1 && LittleLong(header->version) != 2) { Com_Printf ("Mod_INTERQUAKEMODEL_Load: only version 1 or 2 models are currently supported (name = %s)", mod->name); return false; } mod->type = mod_iqm; // byteswap header header->version = LittleLong(header->version); header->filesize = LittleLong(header->filesize); header->flags = LittleLong(header->flags); header->num_text = LittleLong(header->num_text); header->ofs_text = LittleLong(header->ofs_text); header->num_meshes = LittleLong(header->num_meshes); header->ofs_meshes = LittleLong(header->ofs_meshes); header->num_vertexarrays = LittleLong(header->num_vertexarrays); header->num_vertexes = LittleLong(header->num_vertexes); header->ofs_vertexarrays = LittleLong(header->ofs_vertexarrays); header->num_triangles = LittleLong(header->num_triangles); header->ofs_triangles = LittleLong(header->ofs_triangles); header->ofs_neighbors = LittleLong(header->ofs_neighbors); header->num_joints = LittleLong(header->num_joints); header->ofs_joints = LittleLong(header->ofs_joints); header->num_poses = LittleLong(header->num_poses); header->ofs_poses = LittleLong(header->ofs_poses); header->num_anims = LittleLong(header->num_anims); header->ofs_anims = LittleLong(header->ofs_anims); header->num_frames = LittleLong(header->num_frames); header->num_framechannels = LittleLong(header->num_framechannels); header->ofs_frames = LittleLong(header->ofs_frames); header->ofs_bounds = LittleLong(header->ofs_bounds); header->num_comment = LittleLong(header->num_comment); header->ofs_comment = LittleLong(header->ofs_comment); header->num_extensions = LittleLong(header->num_extensions); header->ofs_extensions = LittleLong(header->ofs_extensions); if (header->num_triangles < 1 || header->num_vertexes < 3 || header->num_vertexarrays < 1 || header->num_meshes < 1) { Com_Printf("%s has no geometry\n", mod->name); return false; } if (header->num_frames < 1 || header->num_anims < 1) { Com_Printf("%s has no animations\n", mod->name); return false; } mod->extradata = Hunk_Begin (0x150000); va = (iqmvertexarray_t *)(pbase + header->ofs_vertexarrays); for (i = 0;i < (int)header->num_vertexarrays;i++) { va[i].type = LittleLong(va[i].type); va[i].flags = LittleLong(va[i].flags); va[i].format = LittleLong(va[i].format); va[i].size = LittleLong(va[i].size); va[i].offset = LittleLong(va[i].offset); switch (va[i].type) { case IQM_POSITION: if (va[i].format == IQM_FLOAT && va[i].size == 3) vposition = (float *)(pbase + va[i].offset); break; case IQM_TEXCOORD: if (va[i].format == IQM_FLOAT && va[i].size == 2) vtexcoord = (float *)(pbase + va[i].offset); break; case IQM_NORMAL: if (va[i].format == IQM_FLOAT && va[i].size == 3) vnormal = (float *)(pbase + va[i].offset); break; case IQM_TANGENT: if (va[i].format == IQM_FLOAT && va[i].size == 4) vtangent = (float *)(pbase + va[i].offset); break; case IQM_BLENDINDEXES: if (va[i].format == IQM_UBYTE && va[i].size == 4) { mod->blendindexes = (unsigned char *)Hunk_Alloc(header->num_vertexes * 4 * sizeof(unsigned char)); memcpy(mod->blendindexes, (unsigned char *)(pbase + va[i].offset), header->num_vertexes * 4 * sizeof(unsigned char)); } break; case IQM_BLENDWEIGHTS: if (va[i].format == IQM_UBYTE && va[i].size == 4) { /*vblendweights = (unsigned char *)Hunk_Alloc(header->num_vertexes * 4 * sizeof(unsigned char)); memcpy(vblendweights, (unsigned char *)(pbase + va[i].offset), header->num_vertexes * 4 * sizeof(unsigned char));*/ mod->blendweights = (unsigned char *)Hunk_Alloc(header->num_vertexes * 4 * sizeof(unsigned char)); memcpy(mod->blendweights, (unsigned char *)(pbase + va[i].offset), header->num_vertexes * 4 * sizeof(unsigned char)); } break; } } if (!vposition || !vtexcoord || !mod->blendindexes || !mod->blendweights) { Com_Printf("%s is missing vertex array data\n", mod->name); return false; } text = header->num_text && header->ofs_text ? (char *)(pbase + header->ofs_text) : ""; mod->jointname = (char *)Hunk_Alloc(header->num_text * sizeof(char *)); memcpy(mod->jointname, text, header->num_text * sizeof(char *)); mod->version = header->version; mod->num_frames = header->num_anims; mod->num_joints = header->num_joints; mod->num_poses = header->num_frames; mod->numvertexes = header->num_vertexes; mod->num_triangles = header->num_triangles; // load the joints if( header->version == 1 ) { joint = (iqmjoint_t *) (pbase + header->ofs_joints); mod->joints = (iqmjoint_t*)Hunk_Alloc (header->num_joints * sizeof(iqmjoint_t)); for (i = 0;i < mod->num_joints;i++) { mod->joints[i].name = LittleLong(joint[i].name); mod->joints[i].parent = LittleLong(joint[i].parent); for (j = 0;j < 3;j++) { mod->joints[i].origin[j] = LittleFloat(joint[i].origin[j]); mod->joints[i].rotation[j] = LittleFloat(joint[i].rotation[j]); mod->joints[i].scale[j] = LittleFloat(joint[i].scale[j]); } } } else { joint2 = (iqmjoint2_t *) (pbase + header->ofs_joints); mod->joints2 = (iqmjoint2_t*)Hunk_Alloc (header->num_joints * sizeof(iqmjoint2_t)); for (i = 0;i < mod->num_joints;i++) { mod->joints2[i].name = LittleLong(joint2[i].name); mod->joints2[i].parent = LittleLong(joint2[i].parent); for (j = 0;j < 3;j++) { mod->joints2[i].origin[j] = LittleFloat(joint2[i].origin[j]); mod->joints2[i].rotation[j] = LittleFloat(joint2[i].rotation[j]); mod->joints2[i].scale[j] = LittleFloat(joint2[i].scale[j]); } mod->joints2[i].rotation[3] = LittleFloat(joint2[i].rotation[3]); } } //these don't need to be a part of mod - remember to free them mod->baseframe = (matrix3x4_t*)Hunk_Alloc (header->num_joints * sizeof(matrix3x4_t)); inversebaseframe = (matrix3x4_t*)malloc (header->num_joints * sizeof(matrix3x4_t)); if( header->version == 1 ) { for(i = 0; i < (int)header->num_joints; i++) { vec3_t rot; vec4_t q_rot; iqmjoint_t j = mod->joints[i]; //first need to make a vec4 quat from our rotation vec VectorSet(rot, j.rotation[0], j.rotation[1], j.rotation[2]); Vector4Set(q_rot, j.rotation[0], j.rotation[1], j.rotation[2], -sqrt(max(1.0 - pow(VectorLength(rot),2), 0.0))); Matrix3x4_FromQuatAndVectors(&mod->baseframe[i], q_rot, j.origin, j.scale); Matrix3x4_Invert(&inversebaseframe[i], mod->baseframe[i]); if(j.parent >= 0) { matrix3x4_t temp; Matrix3x4_Multiply(&temp, mod->baseframe[j.parent], mod->baseframe[i]); mod->baseframe[i] = temp; Matrix3x4_Multiply(&temp, inversebaseframe[i], inversebaseframe[j.parent]); inversebaseframe[i] = temp; } } } else { for(i = 0; i < (int)header->num_joints; i++) { iqmjoint2_t j = mod->joints2[i]; Matrix3x4_FromQuatAndVectors(&mod->baseframe[i], j.rotation, j.origin, j.scale); Matrix3x4_Invert(&inversebaseframe[i], mod->baseframe[i]); assert(j.parent < (int)header->num_joints); if(j.parent >= 0) { matrix3x4_t temp; Matrix3x4_Multiply(&temp, mod->baseframe[j.parent], mod->baseframe[i]); mod->baseframe[i] = temp; Matrix3x4_Multiply(&temp, inversebaseframe[i], inversebaseframe[j.parent]); inversebaseframe[i] = temp; } } } if( header->version == 1 ) { poses = (iqmpose_t *) (pbase + header->ofs_poses); mod->frames = (matrix3x4_t*)Hunk_Alloc (header->num_frames * header->num_poses * sizeof(matrix3x4_t)); framedata = (unsigned short *) (pbase + header->ofs_frames); for(i = 0; i < header->num_frames; i++) { for(j = 0; j < header->num_poses; j++) { iqmpose_t p = poses[j]; vec3_t translate, rotate, scale; vec4_t q_rot; matrix3x4_t m, temp; p.parent = LittleLong(p.parent); p.channelmask = LittleLong(p.channelmask); for(k = 0; k < 9; k++) { p.channeloffset[k] = LittleFloat(p.channeloffset[k]); p.channelscale[k] = LittleFloat(p.channelscale[k]); } translate[0] = p.channeloffset[0]; if(p.channelmask&0x01) translate[0] += (unsigned short)LittleShort(*framedata++) * p.channelscale[0]; translate[1] = p.channeloffset[1]; if(p.channelmask&0x02) translate[1] += (unsigned short)LittleShort(*framedata++) * p.channelscale[1]; translate[2] = p.channeloffset[2]; if(p.channelmask&0x04) translate[2] += (unsigned short)LittleShort(*framedata++) * p.channelscale[2]; rotate[0] = p.channeloffset[3]; if(p.channelmask&0x08) rotate[0] += (unsigned short)LittleShort(*framedata++) * p.channelscale[3]; rotate[1] = p.channeloffset[4]; if(p.channelmask&0x10) rotate[1] += (unsigned short)LittleShort(*framedata++) * p.channelscale[4]; rotate[2] = p.channeloffset[5]; if(p.channelmask&0x20) rotate[2] += (unsigned short)LittleShort(*framedata++) * p.channelscale[5]; scale[0] = p.channeloffset[6]; if(p.channelmask&0x40) scale[0] += (unsigned short)LittleShort(*framedata++) * p.channelscale[6]; scale[1] = p.channeloffset[7]; if(p.channelmask&0x80) scale[1] += (unsigned short)LittleShort(*framedata++) * p.channelscale[7]; scale[2] = p.channeloffset[8]; if(p.channelmask&0x100) scale[2] += (unsigned short)LittleShort(*framedata++) * p.channelscale[8]; // Concatenate each pose with the inverse base pose to avoid doing this at animation time. // If the joint has a parent, then it needs to be pre-concatenated with its parent's base pose. // Thus it all negates at animation time like so: // (parentPose * parentInverseBasePose) * (parentBasePose * childPose * childInverseBasePose) => // parentPose * (parentInverseBasePose * parentBasePose) * childPose * childInverseBasePose => // parentPose * childPose * childInverseBasePose Vector4Set(q_rot, rotate[0], rotate[1], rotate[2], -sqrt(max(1.0 - pow(VectorLength(rotate),2), 0.0))); Matrix3x4_FromQuatAndVectors(&m, q_rot, translate, scale); if(p.parent >= 0) { Matrix3x4_Multiply(&temp, mod->baseframe[p.parent], m); Matrix3x4_Multiply(&mod->frames[i*header->num_poses+j], temp, inversebaseframe[j]); } else Matrix3x4_Multiply(&mod->frames[i*header->num_poses+j], m, inversebaseframe[j]); } } } else { poses2 = (iqmpose2_t *) (pbase + header->ofs_poses); mod->frames = (matrix3x4_t*)Hunk_Alloc (header->num_frames * header->num_poses * sizeof(matrix3x4_t)); framedata = (unsigned short *) (pbase + header->ofs_frames); for(i = 0; i < header->num_frames; i++) { for(j = 0; j < header->num_poses; j++) { iqmpose2_t p = poses2[j]; vec3_t translate, scale; vec4_t rotate; matrix3x4_t m, temp; p.parent = LittleLong(p.parent); p.channelmask = LittleLong(p.channelmask); for(k = 0; k < 10; k++) { p.channeloffset[k] = LittleFloat(p.channeloffset[k]); p.channelscale[k] = LittleFloat(p.channelscale[k]); } translate[0] = p.channeloffset[0]; if(p.channelmask&0x01) translate[0] += (unsigned short)LittleShort(*framedata++) * p.channelscale[0]; translate[1] = p.channeloffset[1]; if(p.channelmask&0x02) translate[1] += (unsigned short)LittleShort(*framedata++) * p.channelscale[1]; translate[2] = p.channeloffset[2]; if(p.channelmask&0x04) translate[2] += (unsigned short)LittleShort(*framedata++) * p.channelscale[2]; rotate[0] = p.channeloffset[3]; if(p.channelmask&0x08) rotate[0] += (unsigned short)LittleShort(*framedata++) * p.channelscale[3]; rotate[1] = p.channeloffset[4]; if(p.channelmask&0x10) rotate[1] += (unsigned short)LittleShort(*framedata++) * p.channelscale[4]; rotate[2] = p.channeloffset[5]; if(p.channelmask&0x20) rotate[2] += (unsigned short)LittleShort(*framedata++) * p.channelscale[5]; rotate[3] = p.channeloffset[6]; if(p.channelmask&0x40) rotate[3] += (unsigned short)LittleShort(*framedata++) * p.channelscale[6]; scale[0] = p.channeloffset[7]; if(p.channelmask&0x80) scale[0] += (unsigned short)LittleShort(*framedata++) * p.channelscale[7]; scale[1] = p.channeloffset[8]; if(p.channelmask&0x100) scale[1] += (unsigned short)LittleShort(*framedata++) * p.channelscale[8]; scale[2] = p.channeloffset[9]; if(p.channelmask&0x200) scale[2] += (unsigned short)LittleShort(*framedata++) * p.channelscale[9]; // Concatenate each pose with the inverse base pose to avoid doing this at animation time. // If the joint has a parent, then it needs to be pre-concatenated with its parent's base pose. // Thus it all negates at animation time like so: // (parentPose * parentInverseBasePose) * (parentBasePose * childPose * childInverseBasePose) => // parentPose * (parentInverseBasePose * parentBasePose) * childPose * childInverseBasePose => // parentPose * childPose * childInverseBasePose Matrix3x4_FromQuatAndVectors(&m, rotate, translate, scale); if(p.parent >= 0) { Matrix3x4_Multiply(&temp, mod->baseframe[p.parent], m); Matrix3x4_Multiply(&mod->frames[i*header->num_poses+j], temp, inversebaseframe[j]); } else Matrix3x4_Multiply(&mod->frames[i*header->num_poses+j], m, inversebaseframe[j]); } } } mod->outframe = (matrix3x4_t *)Hunk_Alloc(mod->num_joints * sizeof(matrix3x4_t)); // load bounding box data if (header->ofs_bounds) { float xyradius = 0, radius = 0; bounds = (iqmbounds_t *) (pbase + header->ofs_bounds); VectorClear(mod->mins); VectorClear(mod->maxs); for (i = 0; i < (int)header->num_frames;i++) { bounds[i].mins[0] = LittleFloat(bounds[i].mins[0]); bounds[i].mins[1] = LittleFloat(bounds[i].mins[1]); bounds[i].mins[2] = LittleFloat(bounds[i].mins[2]); bounds[i].maxs[0] = LittleFloat(bounds[i].maxs[0]); bounds[i].maxs[1] = LittleFloat(bounds[i].maxs[1]); bounds[i].maxs[2] = LittleFloat(bounds[i].maxs[2]); bounds[i].xyradius = LittleFloat(bounds[i].xyradius); bounds[i].radius = LittleFloat(bounds[i].radius); if (mod->mins[0] > bounds[i].mins[0]) mod->mins[0] = bounds[i].mins[0]; if (mod->mins[1] > bounds[i].mins[1]) mod->mins[1] = bounds[i].mins[1]; if (mod->mins[2] > bounds[i].mins[2]) mod->mins[2] = bounds[i].mins[2]; if (mod->maxs[0] < bounds[i].maxs[0]) mod->maxs[0] = bounds[i].maxs[0]; if (mod->maxs[1] < bounds[i].maxs[1]) mod->maxs[1] = bounds[i].maxs[1]; if (mod->maxs[2] < bounds[i].maxs[2]) mod->maxs[2] = bounds[i].maxs[2]; if (bounds[i].xyradius > xyradius) xyradius = bounds[i].xyradius; if (bounds[i].radius > radius) radius = bounds[i].radius; } mod->radius = radius; } //compute a full bounding box for ( i = 0; i < 8; i++ ) { vec3_t tmp; if ( i & 1 ) tmp[0] = mod->mins[0]; else tmp[0] = mod->maxs[0]; if ( i & 2 ) tmp[1] = mod->mins[1]; else tmp[1] = mod->maxs[1]; if ( i & 4 ) tmp[2] = mod->mins[2]; else tmp[2] = mod->maxs[2]; VectorCopy( tmp, mod->bbox[i] ); } // load triangle data inelements = (const int *) (pbase + header->ofs_triangles); mod->tris = (iqmtriangle_t*)Hunk_Alloc(header->num_triangles * sizeof(iqmtriangle_t)); for (i = 0;i < (int)header->num_triangles;i++) { mod->tris[i].vertex[0] = LittleLong(inelements[0]); mod->tris[i].vertex[1] = LittleLong(inelements[1]); mod->tris[i].vertex[2] = LittleLong(inelements[2]); inelements += 3; } //load triangle neighbors if (header->ofs_neighbors) { inelements = (const int *) (pbase + header->ofs_neighbors); mod->neighbors = (neighbors_t*)Hunk_Alloc(header->num_triangles * sizeof(neighbors_t)); for (i = 0;i < (int)header->num_triangles;i++) { mod->neighbors[i].n[0] = LittleLong(inelements[0]); mod->neighbors[i].n[1] = LittleLong(inelements[1]); mod->neighbors[i].n[2] = LittleLong(inelements[2]); inelements += 3; } } // load vertex data IQM_LoadVertexArrays(mod, vposition, vnormal, vtangent); // load texture coodinates mod->st = (fstvert_t*)Hunk_Alloc (header->num_vertexes * sizeof(fstvert_t)); //mod->blendweights = (float *)Hunk_Alloc(header->num_vertexes * 4 * sizeof(float)); for (i = 0;i < (int)header->num_vertexes;i++) { mod->st[i].s = LittleFloat(vtexcoord[0]); mod->st[i].t = LittleFloat(vtexcoord[1]); vtexcoord+=2; } /* * get skin pathname from .skin file and initialize skin */ COM_StripExtension( mod->name, shortname ); strcat( shortname, ".skin" ); skinpath_buffer_length = FS_LoadFile( shortname, (void**)&pskinpath_buffer ); // note: FS_LoadFile handles upper/lowercase, nul-termination, // and path search sequence if ( skinpath_buffer_length > 0 ) { // .skin file found and read, // data is in Z_Malloc'd buffer pointed to by pskin_buffer // get relative image pathname for model's skin from .skin file data parse_string = pskinpath_buffer; strcpy( skinname, COM_Parse( &parse_string ) ); Z_Free( pskinpath_buffer ); // free Z_Malloc'd read buffer // get image file for skin mod->skins[0] = GL_FindImage( skinname, it_skin ); if ( mod->skins[0] != NULL ) { // image file for skin exists strcpy( mod->skinname, skinname ); //load shader for skin mod->script = mod->skins[0]->script; if ( mod->script ) RS_ReadyScript( (rscript_t *)mod->script ); } } /* * get ragdoll info from .rgd file */ mod->hasRagDoll = false; COM_StripExtension( mod->name, shortname ); strcat( shortname, ".rgd" ); if ( FS_FullPath( fullname, sizeof(fullname), shortname ) ) { mod->hasRagDoll = IQM_ReadRagDollFile( fullname, mod ); } //free temp non hunk mem if(inversebaseframe) free(inversebaseframe); return true; } void IQM_AnimateFrame(float curframe, int nextframe) { int i, j; int frame1 = (int)floor(curframe), frame2 = nextframe; float frameoffset = curframe - frame1; frame1 %= currentmodel->num_poses; frame2 %= currentmodel->num_poses; { matrix3x4_t *mat1 = ¤tmodel->frames[frame1 * currentmodel->num_joints], *mat2 = ¤tmodel->frames[frame2 * currentmodel->num_joints]; // Interpolate matrixes between the two closest frames and concatenate with parent matrix if necessary. // Concatenate the result with the inverse of the base pose. // You would normally do animation blending and inter-frame blending here in a 3D engine. for(i = 0; i < currentmodel->num_joints; i++) { matrix3x4_t mat, rmat, temp; vec3_t rot; Matrix3x4_Scale(&mat, mat1[i], 1-frameoffset); Matrix3x4_Scale(&temp, mat2[i], frameoffset); Matrix3x4_Add(&mat, mat, temp); if(currentmodel->version == 1) { if(currentmodel->joints[i].parent >= 0) Matrix3x4_Multiply(¤tmodel->outframe[i], currentmodel->outframe[currentmodel->joints[i].parent], mat); else Matrix3x4_Copy(¤tmodel->outframe[i], mat); } else { if(currentmodel->joints2[i].parent >= 0) Matrix3x4_Multiply(¤tmodel->outframe[i], currentmodel->outframe[currentmodel->joints2[i].parent], mat); else Matrix3x4_Copy(¤tmodel->outframe[i], mat); } //bend the model at the waist for player pitch if(currentmodel->version == 1) { if(!strcmp(¤tmodel->jointname[currentmodel->joints[i].name], "Spine")|| !strcmp(¤tmodel->jointname[currentmodel->joints[i].name], "Spine.001")) { vec3_t basePosition, oldPosition, newPosition; VectorSet(rot, 0, 1, 0); //remember .iqm's are 90 degrees rotated from reality, so this is the pitch axis Matrix3x4GenRotate(&rmat, modelpitch, rot); // concatenate the rotation with the bone Matrix3x4_Multiply(&temp, rmat, currentmodel->outframe[i]); // get the position of the bone in the base frame VectorSet(basePosition, currentmodel->baseframe[i].a[3], currentmodel->baseframe[i].b[3], currentmodel->baseframe[i].c[3]); // add in the correct old bone position and subtract off the wrong new bone position to get the correct rotation pivot VectorSet(oldPosition, DotProduct(basePosition, currentmodel->outframe[i].a) + currentmodel->outframe[i].a[3], DotProduct(basePosition, currentmodel->outframe[i].b) + currentmodel->outframe[i].b[3], DotProduct(basePosition, currentmodel->outframe[i].c) + currentmodel->outframe[i].c[3]); VectorSet(newPosition, DotProduct(basePosition, temp.a) + temp.a[3], DotProduct(basePosition, temp.b) + temp.b[3], DotProduct(basePosition, temp.c) + temp.c[3]); temp.a[3] += oldPosition[0] - newPosition[0]; temp.b[3] += oldPosition[1] - newPosition[1]; temp.c[3] += oldPosition[2] - newPosition[2]; // replace the old matrix with the rotated one Matrix3x4_Copy(¤tmodel->outframe[i], temp); } //now rotate the legs back if(!strcmp(¤tmodel->jointname[currentmodel->joints[i].name], "hip.l")|| !strcmp(¤tmodel->jointname[currentmodel->joints[i].name], "hip.r")) { vec3_t basePosition, oldPosition, newPosition; VectorSet(rot, 0, 1, 0); Matrix3x4GenRotate(&rmat, -modelpitch, rot); // concatenate the rotation with the bone Matrix3x4_Multiply(&temp, rmat, currentmodel->outframe[i]); // get the position of the bone in the base frame VectorSet(basePosition, currentmodel->baseframe[i].a[3], currentmodel->baseframe[i].b[3], currentmodel->baseframe[i].c[3]); // add in the correct old bone position and subtract off the wrong new bone position to get the correct rotation pivot VectorSet(oldPosition, DotProduct(basePosition, currentmodel->outframe[i].a) + currentmodel->outframe[i].a[3], DotProduct(basePosition, currentmodel->outframe[i].b) + currentmodel->outframe[i].b[3], DotProduct(basePosition, currentmodel->outframe[i].c) + currentmodel->outframe[i].c[3]); VectorSet(newPosition, DotProduct(basePosition, temp.a) + temp.a[3], DotProduct(basePosition, temp.b) + temp.b[3], DotProduct(basePosition, temp.c) + temp.c[3]); temp.a[3] += oldPosition[0] - newPosition[0]; temp.b[3] += oldPosition[1] - newPosition[1]; temp.c[3] += oldPosition[2] - newPosition[2]; // replace the old matrix with the rotated one Matrix3x4_Copy(¤tmodel->outframe[i], temp); } } else { if(!strcmp(¤tmodel->jointname[currentmodel->joints2[i].name], "Spine")|| !strcmp(¤tmodel->jointname[currentmodel->joints2[i].name], "Spine.001")) { vec3_t basePosition, oldPosition, newPosition; VectorSet(rot, 0, 1, 0); //remember .iqm's are 90 degrees rotated from reality, so this is the pitch axis Matrix3x4GenRotate(&rmat, modelpitch, rot); // concatenate the rotation with the bone Matrix3x4_Multiply(&temp, rmat, currentmodel->outframe[i]); // get the position of the bone in the base frame VectorSet(basePosition, currentmodel->baseframe[i].a[3], currentmodel->baseframe[i].b[3], currentmodel->baseframe[i].c[3]); // add in the correct old bone position and subtract off the wrong new bone position to get the correct rotation pivot VectorSet(oldPosition, DotProduct(basePosition, currentmodel->outframe[i].a) + currentmodel->outframe[i].a[3], DotProduct(basePosition, currentmodel->outframe[i].b) + currentmodel->outframe[i].b[3], DotProduct(basePosition, currentmodel->outframe[i].c) + currentmodel->outframe[i].c[3]); VectorSet(newPosition, DotProduct(basePosition, temp.a) + temp.a[3], DotProduct(basePosition, temp.b) + temp.b[3], DotProduct(basePosition, temp.c) + temp.c[3]); temp.a[3] += oldPosition[0] - newPosition[0]; temp.b[3] += oldPosition[1] - newPosition[1]; temp.c[3] += oldPosition[2] - newPosition[2]; // replace the old matrix with the rotated one Matrix3x4_Copy(¤tmodel->outframe[i], temp); } //now rotate the legs back if(!strcmp(¤tmodel->jointname[currentmodel->joints2[i].name], "hip.l")|| !strcmp(¤tmodel->jointname[currentmodel->joints2[i].name], "hip.r")) { vec3_t basePosition, oldPosition, newPosition; VectorSet(rot, 0, 1, 0); Matrix3x4GenRotate(&rmat, -modelpitch, rot); // concatenate the rotation with the bone Matrix3x4_Multiply(&temp, rmat, currentmodel->outframe[i]); // get the position of the bone in the base frame VectorSet(basePosition, currentmodel->baseframe[i].a[3], currentmodel->baseframe[i].b[3], currentmodel->baseframe[i].c[3]); // add in the correct old bone position and subtract off the wrong new bone position to get the correct rotation pivot VectorSet(oldPosition, DotProduct(basePosition, currentmodel->outframe[i].a) + currentmodel->outframe[i].a[3], DotProduct(basePosition, currentmodel->outframe[i].b) + currentmodel->outframe[i].b[3], DotProduct(basePosition, currentmodel->outframe[i].c) + currentmodel->outframe[i].c[3]); VectorSet(newPosition, DotProduct(basePosition, temp.a) + temp.a[3], DotProduct(basePosition, temp.b) + temp.b[3], DotProduct(basePosition, temp.c) + temp.c[3]); temp.a[3] += oldPosition[0] - newPosition[0]; temp.b[3] += oldPosition[1] - newPosition[1]; temp.c[3] += oldPosition[2] - newPosition[2]; // replace the old matrix with the rotated one Matrix3x4_Copy(¤tmodel->outframe[i], temp); } } } } // The actual vertex generation based on the matrixes follows... { const mvertex_t *srcpos = (const mvertex_t *)currentmodel->vertexes; const mnormal_t *srcnorm = (const mnormal_t *)currentmodel->normal; const mtangent_t *srctan = (const mtangent_t *)currentmodel->tangent; mvertex_t *dstpos = (mvertex_t *)currentmodel->animatevertexes; mnormal_t *dstnorm = (mnormal_t *)currentmodel->animatenormal; mtangent_t *dsttan = (mtangent_t *)currentmodel->animatetangent; const unsigned char *index = currentmodel->blendindexes; const unsigned char *weight = currentmodel->blendweights; //we need to skip this vbo check if not using a shader - since the animation is done in the shader has_vbo = false; //a lot of conditions need to be enabled in order to use GPU animation if (use_vbo && (gl_state.vbo && gl_glsl_shaders->integer && gl_state.glsl_shaders && gl_normalmaps->integer) && (r_shaders->integer || ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM)))) { vbo_xyz = R_VCFindCache(VBO_STORE_XYZ, currentmodel); vbo_st = R_VCFindCache(VBO_STORE_ST, currentmodel); vbo_normals = R_VCFindCache(VBO_STORE_NORMAL, currentmodel); vbo_tangents = R_VCFindCache(VBO_STORE_TANGENT, currentmodel); vbo_indices = R_VCFindCache(VBO_STORE_INDICES, currentmodel); if(vbo_xyz && vbo_st && vbo_normals && vbo_tangents && vbo_indices) { has_vbo = true; goto skipLoad; } else { R_VCLoadData(VBO_STATIC, currentmodel->numvertexes*sizeof(vec3_t), currentmodel->vertexes, VBO_STORE_XYZ, currentmodel); R_VCLoadData(VBO_STATIC, currentmodel->numvertexes*sizeof(vec2_t), currentmodel->st, VBO_STORE_ST, currentmodel); R_VCLoadData(VBO_STATIC, currentmodel->numvertexes*sizeof(vec3_t), currentmodel->normal, VBO_STORE_NORMAL, currentmodel); R_VCLoadData(VBO_STATIC, currentmodel->numvertexes*sizeof(vec4_t), currentmodel->tangent, VBO_STORE_TANGENT, currentmodel); R_VCLoadData(VBO_STATIC, currentmodel->num_triangles*3*sizeof(unsigned int), currentmodel->tris, VBO_STORE_INDICES, currentmodel); } } for(i = 0; i < currentmodel->numvertexes; i++) { matrix3x4_t mat; // Blend matrixes for this vertex according to its blend weights. // the first index/weight is always present, and the weights are // guaranteed to add up to 255. So if only the first weight is // presented, you could optimize this case by skipping any weight // multiplies and intermediate storage of a blended matrix. // There are only at most 4 weights per vertex, and they are in // sorted order from highest weight to lowest weight. Weights with // 0 values, which are always at the end, are unused. Matrix3x4_Scale(&mat, currentmodel->outframe[index[0]], weight[0]/255.0f); for(j = 1; j < 4 && weight[j]; j++) { Matrix3x4_ScaleAdd (&mat, ¤tmodel->outframe[index[j]], weight[j]/255.0f, &mat); } // Transform attributes by the blended matrix. // Position uses the full 3x4 transformation matrix. // Normals and tangents only use the 3x3 rotation part // of the transformation matrix. Matrix3x4_Transform(dstpos, mat, *srcpos); // Note that if the matrix includes non-uniform scaling, normal vectors // must be transformed by the inverse-transpose of the matrix to have the // correct relative scale. Note that invert(mat) = adjoint(mat)/determinant(mat), // and since the absolute scale is not important for a vector that will later // be renormalized, the adjoint-transpose matrix will work fine, which can be // cheaply generated by 3 cross-products. // // If you don't need to use joint scaling in your models, you can simply use the // upper 3x3 part of the position matrix instead of the adjoint-transpose shown // here. Matrix3x4_TransformNormal(dstnorm, mat, *srcnorm); // Note that input tangent data has 4 coordinates, // so only transform the first 3 as the tangent vector. Matrix3x4_TransformTangent(dsttan, mat, *srctan); srcpos++; srcnorm++; srctan++; dstpos++; dstnorm++; dsttan++; index += 4; weight += 4; } skipLoad: ; } } void IQM_AnimateRagdoll(int RagDollID, int shellEffect) { //we only deal with one frame //animate using the rotations from our corresponding ODE objects. int i, j; { for(i = 0; i < RagDoll[RagDollID].ragDollMesh->num_joints; i++) { matrix3x4_t mat, rmat; int parent; for(j = 0; j < RagDollBindsCount; j++) { if(RagDoll[RagDollID].ragDollMesh->version == 1) { if(!strcmp(&RagDoll[RagDollID].ragDollMesh->jointname[RagDoll[RagDollID].ragDollMesh->joints[i].name], RagDollBinds[j].name)) { int object = RagDollBinds[j].object; const dReal *odeRot = dBodyGetRotation(RagDoll[RagDollID].RagDollObject[object].body); const dReal *odePos = dBodyGetPosition(RagDoll[RagDollID].RagDollObject[object].body); Matrix3x4GenFromODE(&rmat, odeRot, odePos); Matrix3x4_Multiply(&RagDoll[RagDollID].ragDollMesh->outframe[i], rmat, RagDoll[RagDollID].RagDollObject[object].initmat); goto nextjoint; } } else { if(!strcmp(&RagDoll[RagDollID].ragDollMesh->jointname[RagDoll[RagDollID].ragDollMesh->joints2[i].name], RagDollBinds[j].name)) { int object = RagDollBinds[j].object; const dReal *odeRot = dBodyGetRotation(RagDoll[RagDollID].RagDollObject[object].body); const dReal *odePos = dBodyGetPosition(RagDoll[RagDollID].RagDollObject[object].body); Matrix3x4GenFromODE(&rmat, odeRot, odePos); Matrix3x4_Multiply(&RagDoll[RagDollID].ragDollMesh->outframe[i], rmat, RagDoll[RagDollID].RagDollObject[object].initmat); goto nextjoint; } } } if(RagDoll[RagDollID].ragDollMesh->version == 1) parent = RagDoll[RagDollID].ragDollMesh->joints[i].parent; else parent = RagDoll[RagDollID].ragDollMesh->joints2[i].parent; if(parent >= 0) { Matrix3x4_Invert(&mat, RagDoll[RagDollID].initframe[parent]); Matrix3x4_Multiply(&mat, mat, RagDoll[RagDollID].initframe[i]); Matrix3x4_Multiply(&RagDoll[RagDollID].ragDollMesh->outframe[i], RagDoll[RagDollID].ragDollMesh->outframe[parent], mat); } else memset(&RagDoll[RagDollID].ragDollMesh->outframe[i], 0, sizeof(matrix3x4_t)); nextjoint:; } } { const mvertex_t *srcpos = (const mvertex_t *)RagDoll[RagDollID].ragDollMesh->vertexes; const mnormal_t *srcnorm = (const mnormal_t *)RagDoll[RagDollID].ragDollMesh->normal; const mtangent_t *srctan = (const mtangent_t *)RagDoll[RagDollID].ragDollMesh->tangent; mvertex_t *dstpos = (mvertex_t *)RagDoll[RagDollID].ragDollMesh->animatevertexes; mnormal_t *dstnorm = (mnormal_t *)RagDoll[RagDollID].ragDollMesh->animatenormal; mtangent_t *dsttan = (mtangent_t *)RagDoll[RagDollID].ragDollMesh->animatetangent; const unsigned char *index = RagDoll[RagDollID].ragDollMesh->blendindexes; const unsigned char *weight = RagDoll[RagDollID].ragDollMesh->blendweights; //we need to skip this vbo check if not using a shader - since the animation is done in the shader (might want to check for normalmap stage) has_vbo = false; //a lot of conditions need to be enabled in order to use GPU animation if (use_vbo && (gl_state.vbo && RagDoll[RagDollID].script && gl_glsl_shaders->integer && gl_state.glsl_shaders && gl_normalmaps->integer) && (r_shaders->integer || shellEffect)) { vbo_xyz = R_VCFindCache(VBO_STORE_XYZ, RagDoll[RagDollID].ragDollMesh); vbo_st = R_VCFindCache(VBO_STORE_ST, RagDoll[RagDollID].ragDollMesh); vbo_normals = R_VCFindCache(VBO_STORE_NORMAL, RagDoll[RagDollID].ragDollMesh); vbo_tangents = R_VCFindCache(VBO_STORE_TANGENT, RagDoll[RagDollID].ragDollMesh); vbo_indices = R_VCFindCache(VBO_STORE_INDICES, RagDoll[RagDollID].ragDollMesh); if(vbo_xyz && vbo_st && vbo_normals && vbo_tangents && vbo_indices) { has_vbo = true; goto skipLoad; } else { R_VCLoadData(VBO_STATIC, RagDoll[RagDollID].ragDollMesh->numvertexes*sizeof(vec3_t), RagDoll[RagDollID].ragDollMesh->vertexes, VBO_STORE_XYZ, RagDoll[RagDollID].ragDollMesh); R_VCLoadData(VBO_STATIC, RagDoll[RagDollID].ragDollMesh->numvertexes*sizeof(vec2_t), RagDoll[RagDollID].ragDollMesh->st, VBO_STORE_ST, RagDoll[RagDollID].ragDollMesh); R_VCLoadData(VBO_STATIC, RagDoll[RagDollID].ragDollMesh->numvertexes*sizeof(vec3_t), RagDoll[RagDollID].ragDollMesh->normal, VBO_STORE_NORMAL, RagDoll[RagDollID].ragDollMesh); R_VCLoadData(VBO_STATIC, RagDoll[RagDollID].ragDollMesh->numvertexes*sizeof(vec4_t), RagDoll[RagDollID].ragDollMesh->tangent, VBO_STORE_TANGENT, RagDoll[RagDollID].ragDollMesh); R_VCLoadData(VBO_STATIC, RagDoll[RagDollID].ragDollMesh->num_triangles*3*sizeof(unsigned int), RagDoll[RagDollID].ragDollMesh->tris, VBO_STORE_INDICES, RagDoll[RagDollID].ragDollMesh); } } for(i = 0; i < RagDoll[RagDollID].ragDollMesh->numvertexes; i++) { matrix3x4_t mat; Matrix3x4_Scale(&mat, RagDoll[RagDollID].ragDollMesh->outframe[index[0]], weight[0]/255.0f); for(j = 1; j < 4 && weight[j]; j++) { Matrix3x4_ScaleAdd (&mat, &RagDoll[RagDollID].ragDollMesh->outframe[index[j]], weight[j]/255.0f, &mat); } Matrix3x4_Transform(dstpos, mat, *srcpos); Matrix3x4_TransformNormal(dstnorm, mat, *srcnorm); Matrix3x4_TransformTangent(dsttan, mat, *srctan); srcpos++; srcnorm++; srctan++; dstpos++; dstnorm++; dsttan++; index += 4; weight += 4; } skipLoad: ; } } void IQM_Vlight (vec3_t baselight, mnormal_t *normal, vec3_t angles, vec3_t lightOut) { float l; float lscale; VectorScale(baselight, gl_modulate->value, lightOut); //probably will remove this - maybe we can get a faster algorithm and redo one day //if(!gl_vlights->integer) return; lscale = 3.0; l = lscale * VLight_GetLightValue (normal->dir, lightPosition, angles[PITCH], angles[YAW]); VectorScale(baselight, l, lightOut); } void R_Mesh_SetupShell (int shell_skinnum, qboolean ragdoll, qboolean using_varray, vec3_t lightcolor); void R_Mesh_SetupGLSL (int skinnum, rscript_t *rs, vec3_t lightcolor); inline void IQM_DrawVBO (qboolean tangents) { qglEnableClientState( GL_VERTEX_ARRAY ); GL_BindVBO(vbo_xyz); qglVertexPointer(3, GL_FLOAT, 0, 0); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); GL_BindVBO(vbo_st); qglTexCoordPointer(2, GL_FLOAT, 0, 0); KillFlags |= KILL_NORMAL_POINTER; qglEnableClientState( GL_NORMAL_ARRAY ); GL_BindVBO(vbo_normals); qglNormalPointer(GL_FLOAT, 0, 0); if (tangents) { glEnableVertexAttribArrayARB (1); GL_BindVBO(vbo_tangents); glVertexAttribPointerARB(1, 4, GL_FLOAT, GL_FALSE, 0, 0); } GL_BindVBO(NULL); GL_BindIBO(vbo_indices); glEnableVertexAttribArrayARB(6); glEnableVertexAttribArrayARB(7); glVertexAttribPointerARB(6, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(unsigned char)*4, currentmodel->blendweights); glVertexAttribPointerARB(7, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(unsigned char)*4, currentmodel->blendindexes); qglDrawElements(GL_TRIANGLES, currentmodel->num_triangles*3, GL_UNSIGNED_INT, 0); GL_BindIBO(NULL); } void IQM_DrawFrame(int skinnum, qboolean ragdoll, float shellAlpha) { int i, j; vec3_t vectors[3]; rscript_t *rs = NULL; float shellscale; float alpha, basealpha; vec3_t lightcolor; int index_xyz, index_st; int va = 0; qboolean mirror = false; qboolean glass = false; if (r_shaders->integer) rs = currententity->script; VectorCopy(shadelight, lightcolor); for (i=0;iflags & RF_TRANSLUCENT) { alpha = currententity->alpha; if (!(r_newrefdef.rdflags & RDF_NOWORLDMODEL)) { if(gl_mirror->integer) mirror = true; else glass = true; } else glass = true; } else alpha = basealpha = 1.0; AngleVectors (currententity->angles, vectors[0], vectors[1], vectors[2]); //render the model if(( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) ) ) { qglEnable (GL_BLEND); qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); R_Mesh_SetupShell (r_shelltexture2->texnum, ragdoll, !has_vbo, lightcolor); if (ragdoll) shellscale = 1.6; else if((currententity->flags & (RF_WEAPONMODEL | RF_SHELL_GREEN)) || (gl_glsl_shaders->integer && gl_state.glsl_shaders && gl_normalmaps->integer)) shellscale = 0.4; else shellscale = 1.6; if(!has_vbo) { if(gl_glsl_shaders->integer && gl_state.glsl_shaders && gl_normalmaps->integer) { glUniform1iARB(g_location_useGPUanim, 0); } for (i=0; inum_triangles; i++) { for (j=0; j<3; j++) { index_xyz = index_st = currentmodel->tris[i].vertex[j]; VArray[0] = currentmodel->animatevertexes[index_xyz].position[0] + currentmodel->animatenormal[index_xyz].dir[0]*shellscale; VArray[1] = currentmodel->animatevertexes[index_xyz].position[1] + currentmodel->animatenormal[index_xyz].dir[1]*shellscale; VArray[2] = currentmodel->animatevertexes[index_xyz].position[2] + currentmodel->animatenormal[index_xyz].dir[2]*shellscale; VArray[3] = currentmodel->st[index_st].s; VArray[4] = currentmodel->st[index_st].t; VArray[5] = shadelight[0]; VArray[6] = shadelight[1]; VArray[7] = shadelight[2]; // normally fixed at 0.33, decreases gradually for // ragdolls VArray[8] = shellAlpha; if(gl_glsl_shaders->integer && gl_state.glsl_shaders && gl_normalmaps->integer) { VectorCopy(currentmodel->animatenormal[index_xyz].dir, NormalsArray[va]); //shader needs normal array Vector4Copy(currentmodel->animatetangent[index_xyz].dir, TangentsArray[va]); VArray += VertexSizes[VERT_NORMAL_COLOURED_TEXTURED]; // increment pointer and counter } else VArray += VertexSizes[VERT_COLOURED_TEXTURED]; // increment pointer and counter va++; } } R_DrawVarrays(GL_TRIANGLES, 0, va); } else { glUniform1iARB(g_location_useGPUanim, 1); glUniformMatrix3x4fvARB( g_location_outframe, currentmodel->num_joints, GL_FALSE, (const GLfloat *) currentmodel->outframe ); IQM_DrawVBO (true); } if(gl_glsl_shaders->integer && gl_state.glsl_shaders && gl_normalmaps->integer) { glUseProgramObjectARB( 0 ); GL_EnableMultitexture( false ); if (ragdoll) qglDepthMask(true); } } else if((mirror || glass ) && has_vbo) { //render glass with glsl shader vec3_t lightVec; KillFlags |= (KILL_TMU0_POINTER | KILL_TMU1_POINTER | KILL_TMU2_POINTER | KILL_NORMAL_POINTER); qglDepthMask(false); R_ModelViewTransform(lightPosition, lightVec); glUseProgramObjectARB( g_glassprogramObj ); glUniform3fARB( g_location_gLightPos, lightVec[0], lightVec[1], lightVec[2]); GL_SelectTexture( GL_TEXTURE1); if(mirror) { GL_Bind (r_mirrortexture->texnum); } else { GL_Bind (r_mirrorspec->texnum); } glUniform1iARB( g_location_gmirTexture, 1); GL_SelectTexture( GL_TEXTURE0); GL_Bind (r_mirrorspec->texnum); glUniform1iARB( g_location_grefTexture, 0); glUniform1iARB( g_location_gFog, map_fog); glUniformMatrix3x4fvARB( g_location_gOutframe, currentmodel->num_joints, GL_FALSE, (const GLfloat *) currentmodel->outframe ); IQM_DrawVBO (false); glUseProgramObjectARB( 0 ); } else if(mirror || glass) { //glass surfaces //base render, no vbo, no shaders qglDepthMask(false); if(mirror) { if( !(currententity->flags & RF_WEAPONMODEL)) { R_InitVArrays(VERT_COLOURED_MULTI_TEXTURED); GL_EnableMultitexture( true ); GL_SelectTexture( GL_TEXTURE0); GL_TexEnv ( GL_COMBINE_EXT ); GL_Bind (r_mirrortexture->texnum); qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE ); GL_SelectTexture( GL_TEXTURE1); GL_TexEnv ( GL_COMBINE_EXT ); GL_Bind (r_mirrorspec->texnum); qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT ); } else { R_InitVArrays (VERT_COLOURED_TEXTURED); GL_SelectTexture( GL_TEXTURE0); GL_Bind (r_mirrortexture->texnum); } } else { R_InitVArrays (VERT_COLOURED_TEXTURED); GL_SelectTexture( GL_TEXTURE0); GL_Bind (r_reflecttexture->texnum); } for (i=0; inum_triangles; i++) { for (j=0; j<3; j++) { index_xyz = index_st = currentmodel->tris[i].vertex[j]; VArray[0] = currentmodel->animatevertexes[index_xyz].position[0]; VArray[1] = currentmodel->animatevertexes[index_xyz].position[1]; VArray[2] = currentmodel->animatevertexes[index_xyz].position[2]; if(mirror) { VArray[5] = VArray[3] = -(currentmodel->st[index_st].s - DotProduct (currentmodel->animatenormal[index_xyz].dir, vectors[1])); VArray[6] = VArray[4] = currentmodel->st[index_st].t + DotProduct (currentmodel->animatenormal[index_xyz].dir, vectors[2]); } else { VArray[3] = -(currentmodel->st[index_st].s - DotProduct (currentmodel->animatenormal[index_xyz].dir, vectors[1])); VArray[4] = currentmodel->st[index_st].t + DotProduct (currentmodel->animatenormal[index_xyz].dir, vectors[2]); } IQM_Vlight (shadelight, ¤tmodel->animatenormal[index_xyz], currententity->angles, lightcolor); if(mirror && !(currententity->flags & RF_WEAPONMODEL) ) { VArray[7] = lightcolor[0]; VArray[8] = lightcolor[1]; VArray[9] = lightcolor[2]; VArray[10] = alpha; VArray += VertexSizes[VERT_COLOURED_MULTI_TEXTURED]; // increment pointer and counter } else { VArray[5] = lightcolor[0]; VArray[6] = lightcolor[1]; VArray[7] = lightcolor[2]; VArray[8] = alpha; VArray += VertexSizes[VERT_COLOURED_TEXTURED]; // increment pointer and counter } va++; } } R_DrawVarrays(GL_TRIANGLES, 0, va); if(mirror && !(currententity->flags & RF_WEAPONMODEL)) GL_EnableMultitexture( false ); qglDepthMask(true); } else if(rs && rs->stage->normalmap && gl_normalmaps->integer && gl_glsl_shaders->integer && gl_state.glsl_shaders) { R_Mesh_SetupGLSL (skinnum, rs, lightcolor); if(!has_vbo) { glUniform1iARB(g_location_useGPUanim, 0); R_InitVArrays (VERT_NORMAL_COLOURED_TEXTURED); qglNormalPointer(GL_FLOAT, 0, NormalsArray); glEnableVertexAttribArrayARB (1); glVertexAttribPointerARB(1, 4, GL_FLOAT, GL_FALSE, 0, TangentsArray); for (i=0; inum_triangles; i++) { for (j=0; j<3; j++) { index_xyz = index_st = currentmodel->tris[i].vertex[j]; VArray[0] = currentmodel->animatevertexes[index_xyz].position[0]; VArray[1] = currentmodel->animatevertexes[index_xyz].position[1]; VArray[2] = currentmodel->animatevertexes[index_xyz].position[2]; VArray[3] = currentmodel->st[index_st].s; VArray[4] = currentmodel->st[index_st].t; VectorCopy(currentmodel->animatenormal[index_xyz].dir, NormalsArray[va]); Vector4Copy(currentmodel->animatetangent[index_xyz].dir, TangentsArray[va]); VArray += VertexSizes[VERT_NORMAL_COLOURED_TEXTURED]; // increment pointer and counter va++; } } R_DrawVarrays(GL_TRIANGLES, 0, va); } else { glUniform1iARB(g_location_useGPUanim, 1); glUniformMatrix3x4fvARB( g_location_outframe, currentmodel->num_joints, GL_FALSE, (const GLfloat *) currentmodel->outframe ); IQM_DrawVBO (true); } qglColor4f(1,1,1,1); glUseProgramObjectARB( 0 ); GL_EnableMultitexture( false ); } else { //base render no shaders R_InitVArrays (VERT_COLOURED_TEXTURED); GL_SelectTexture( GL_TEXTURE0); GL_Bind (skinnum); for (i=0; inum_triangles; i++) { for (j=0; j<3; j++) { index_xyz = index_st = currentmodel->tris[i].vertex[j]; VArray[0] = currentmodel->animatevertexes[index_xyz].position[0]; VArray[1] = currentmodel->animatevertexes[index_xyz].position[1]; VArray[2] = currentmodel->animatevertexes[index_xyz].position[2]; VArray[3] = currentmodel->st[index_st].s; VArray[4] = currentmodel->st[index_st].t; IQM_Vlight (shadelight, ¤tmodel->animatenormal[index_xyz], currententity->angles, lightcolor); VArray[5] = lightcolor[0] > 0.2 ? lightcolor[0] : 0.2; VArray[6] = lightcolor[1] > 0.2 ? lightcolor[1] : 0.2; VArray[7] = lightcolor[2] > 0.2 ? lightcolor[2] : 0.2; VArray[8] = alpha; VArray += VertexSizes[VERT_COLOURED_TEXTURED]; // increment pointer and counter va++; } } R_DrawVarrays(GL_TRIANGLES, 0, va); } GLSTATE_DISABLE_ALPHATEST GLSTATE_DISABLE_BLEND GLSTATE_DISABLE_TEXGEN glDisableVertexAttribArrayARB(1); glDisableVertexAttribArrayARB(6); glDisableVertexAttribArrayARB(7); R_KillVArrays (); if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM ) ) qglEnable( GL_TEXTURE_2D ); } static qboolean IQM_CullModel( void ) { int i; vec3_t vectors[3]; vec3_t angles; trace_t r_trace; vec3_t dist; vec3_t bbox[8]; if (r_worldmodel ) { //occulusion culling - why draw entities we cannot see? r_trace = CM_BoxTrace(r_origin, currententity->origin, currentmodel->maxs, currentmodel->mins, r_worldmodel->firstnode, MASK_OPAQUE); if(r_trace.fraction != 1.0) return true; } VectorSubtract(r_origin, currententity->origin, dist); /* ** rotate the bounding box */ VectorCopy( currententity->angles, angles ); angles[YAW] = -angles[YAW]; AngleVectors( angles, vectors[0], vectors[1], vectors[2] ); for ( i = 0; i < 8; i++ ) { vec3_t tmp; VectorCopy( currentmodel->bbox[i], tmp ); bbox[i][0] = DotProduct( vectors[0], tmp ); bbox[i][1] = -DotProduct( vectors[1], tmp ); bbox[i][2] = DotProduct( vectors[2], tmp ); VectorAdd( currententity->origin, bbox[i], bbox[i] ); } { int p, f, aggregatemask = ~0; for ( p = 0; p < 8; p++ ) { int mask = 0; for ( f = 0; f < 4; f++ ) { float dp = DotProduct( frustum[f].normal, bbox[p] ); if ( ( dp - frustum[f].dist ) < 0 ) { mask |= ( 1 << f ); } } aggregatemask &= mask; } if ( aggregatemask && (VectorLength(dist) > 150)) //so shadows don't blatantly disappear when out of frustom { return true; } return false; } } //Can these next two be replaced with some type of animation grouping from the model? qboolean IQM_InAnimGroup(int frame, int oldframe) { //check if we are in a player anim group that is commonly looping if(frame >= 0 && frame <= 39 && oldframe >=0 && oldframe <= 39) return true; //standing, or 40 frame static mesh else if(frame >= 40 && frame <=45 && oldframe >= 40 && oldframe <=45) return true; //running else if(frame >= 66 && frame <= 71 && oldframe >= 66 && oldframe <= 71) return true; //jumping else if(frame >= 0 && frame <= 23 && oldframe >= 0 && oldframe <= 23) return true; //static meshes are 24 frames else return false; } int IQM_NextFrame(int frame) { int outframe; //just for now if(currententity->flags & RF_WEAPONMODEL) { outframe = frame + 1; return outframe; } switch(frame) { //map models can be 24 or 40 frames case 23: if(currentmodel->num_poses > 24) outframe = frame + 1; else outframe = 0; break; //player standing case 39: outframe = 0; break; //player running case 45: outframe = 40; break; //player shooting case 53: outframe = 46; break; //player jumping case 71: outframe = 0; break; //player crouched case 153: outframe = 135; break; //player crouched walking case 159: outframe = 154; break; case 168: outframe = 160; break; //deaths case 219: outframe = 219; break; case 237: outframe = 237; break; case 257: outframe = 257; break; default: outframe = frame + 1; break; } return outframe; } /* ================= R_DrawINTERQUAKEMODEL ================= */ void R_DrawINTERQUAKEMODEL ( void ) { int i; image_t *skin; float frame, time; if((r_newrefdef.rdflags & RDF_NOWORLDMODEL ) && !(currententity->flags & RF_MENUMODEL)) return; if ((currententity->flags & RF_WEAPONMODEL) && r_lefthand->integer == 2) return; //do culling if ( IQM_CullModel() ) return; if(r_ragdolls->integer) { //Ragdolls take over at beginning of each death sequence if(!(currententity->flags & RF_TRANSLUCENT)) { if(currententity->frame == 199 || currententity->frame == 220 || currententity->frame == 238) if(currentmodel->hasRagDoll) RGD_AddNewRagdoll(currententity->origin, currententity->name); } //Do not render deathframes if using ragdolls - do not render translucent helmets if((currentmodel->hasRagDoll || (currententity->flags & RF_TRANSLUCENT)) && currententity->frame > 198) return; } //modelpitch = 0.52 * sinf(rs_realtime); //use this for testing only modelpitch = degreeToRadian(currententity->angles[PITCH]); R_GetLightVals(currententity->origin, false); R_GenerateEntityShadow(); if ( currententity->flags & ( RF_SHELL_HALF_DAM | RF_SHELL_GREEN | RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE) ) { VectorClear (shadelight); if (currententity->flags & RF_SHELL_HALF_DAM) { shadelight[0] = 0.56; shadelight[1] = 0.59; shadelight[2] = 0.45; } if ( currententity->flags & RF_SHELL_DOUBLE ) { shadelight[0] = 0.9; shadelight[1] = 0.7; } if ( currententity->flags & RF_SHELL_RED ) shadelight[0] = 1.0; if ( currententity->flags & RF_SHELL_GREEN ) { shadelight[1] = 1.0; shadelight[2] = 0.6; } if ( currententity->flags & RF_SHELL_BLUE ) { shadelight[2] = 1.0; shadelight[0] = 0.6; } } else if (currententity->flags & RF_FULLBRIGHT) { for (i=0 ; i<3 ; i++) shadelight[i] = 1.0; } else { R_LightPoint (currententity->origin, shadelight, true); } if ( currententity->flags & RF_MINLIGHT ) { float minlight; if(gl_glsl_shaders->integer && gl_state.glsl_shaders && gl_normalmaps->integer) minlight = 0.1; else minlight = 0.2; for (i=0 ; i<3 ; i++) if (shadelight[i] > minlight) break; if (i == 3) { shadelight[0] = minlight; shadelight[1] = minlight; shadelight[2] = minlight; } } if ( currententity->flags & RF_GLOW ) { // bonus items will pulse with time float scale; float minlight; scale = 0.2 * sin(r_newrefdef.time*7); if(gl_glsl_shaders->integer && gl_state.glsl_shaders && gl_normalmaps->integer) minlight = 0.1; else minlight = 0.2; for (i=0 ; i<3 ; i++) { shadelight[i] += scale; if (shadelight[i] < minlight) shadelight[i] = minlight; } } if (currententity->flags & RF_DEPTHHACK) // hack the depth range to prevent view model from poking into walls qglDepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin)); if (currententity->flags & RF_WEAPONMODEL) { qglMatrixMode(GL_PROJECTION); qglPushMatrix(); qglLoadIdentity(); if (r_lefthand->integer == 1) { qglScalef(-1, 1, 1); qglCullFace(GL_BACK); } if(r_newrefdef.fov_y < 75.0f) MYgluPerspective(r_newrefdef.fov_y, (float)r_newrefdef.width / (float)r_newrefdef.height, 4.0f, 4096.0f); else MYgluPerspective(75.0f, (float)r_newrefdef.width / (float)r_newrefdef.height, 4.0f, 4096.0f); qglMatrixMode(GL_MODELVIEW); qglPushMatrix (); currententity->angles[PITCH] = -currententity->angles[PITCH]; // sigh. R_RotateForEntity (currententity); currententity->angles[PITCH] = -currententity->angles[PITCH]; // sigh. } else { qglPushMatrix (); currententity->angles[PITCH] = currententity->angles[ROLL] = 0; R_RotateForEntity (currententity); } // select skin if (currententity->skin) { skin = currententity->skin; } else { skin = currentmodel->skins[0]; } if (!skin) skin = r_notexture; // fallback... GL_Bind(skin->texnum); //check for valid script use_vbo = true; if(currententity->script && currententity->script->stage) { if(!strcmp("***r_notexture***", currententity->script->stage->texture->name) || ((currententity->script->stage->fx || currententity->script->stage->glow) && !strcmp("***r_notexture***", currententity->script->stage->texture2->name)) || (currententity->script->stage->cube && !strcmp("***r_notexture***", currententity->script->stage->texture3->name))) { currententity->script = NULL; //bad shader! use_vbo = false; //cannot use vbo without a valid shader } } else if(!(currententity->flags & RF_TRANSLUCENT)) use_vbo = false; // draw it qglShadeModel (GL_SMOOTH); GL_TexEnv( GL_MODULATE ); if ( currententity->flags & RF_TRANSLUCENT ) { qglEnable (GL_BLEND); qglBlendFunc (GL_ONE, GL_ONE); } //frame interpolation time = (Sys_Milliseconds() - currententity->frametime) / 100; if(time > 1.0) time = 1.0; if((currententity->frame == currententity->oldframe ) && !IQM_InAnimGroup(currententity->frame, currententity->oldframe)) time = 0; //Check for stopped death anims if(currententity->frame == 257 || currententity->frame == 237 || currententity->frame == 219) time = 0; frame = currententity->frame + time; IQM_AnimateFrame(frame, IQM_NextFrame(currententity->frame)); if(!(currententity->flags & RF_VIEWERMODEL)) if (!(!cl_gun->integer && ( currententity->flags & RF_WEAPONMODEL ) ) ) IQM_DrawFrame(skin->texnum, false, 0.33); GL_TexEnv( GL_REPLACE ); qglShadeModel (GL_FLAT); qglPopMatrix (); if ( ( currententity->flags & RF_WEAPONMODEL ) ) { qglMatrixMode( GL_PROJECTION ); qglPopMatrix(); qglMatrixMode( GL_MODELVIEW ); qglCullFace( GL_FRONT ); } if ( currententity->flags & RF_TRANSLUCENT ) { qglDisable (GL_BLEND); qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } if (currententity->flags & RF_DEPTHHACK) qglDepthRange (gldepthmin, gldepthmax); qglColor4f (1,1,1,1); if(r_minimap->integer) { if ( currententity->flags & RF_MONSTER) { RadarEnts[numRadarEnts].color[0]= 1.0; RadarEnts[numRadarEnts].color[1]= 0.0; RadarEnts[numRadarEnts].color[2]= 2.0; RadarEnts[numRadarEnts].color[3]= 1.0; } else return; VectorCopy(currententity->origin,RadarEnts[numRadarEnts].org); numRadarEnts++; } } void IQM_DrawCasterFrame () { int i, j; int index_xyz, index_st; int va = 0; if(!has_vbo) { R_InitVArrays (VERT_NO_TEXTURE); for (i=0; inum_triangles; i++) { for (j=0; j<3; j++) { index_xyz = index_st = currentmodel->tris[i].vertex[j]; VArray[0] = currentmodel->animatevertexes[index_xyz].position[0]; VArray[1] = currentmodel->animatevertexes[index_xyz].position[1]; VArray[2] = currentmodel->animatevertexes[index_xyz].position[2]; // increment pointer and counter VArray += VertexSizes[VERT_NO_TEXTURE]; va++; } } R_DrawVarrays(GL_TRIANGLES, 0, va); } else { //to do - just use a very basic shader for this instead of the normal mesh shader glUseProgramObjectARB( g_blankmeshprogramObj ); //send outframe, blendweights, and blendindexes to shader glUniformMatrix3x4fvARB( g_location_bmOutframe, currentmodel->num_joints, GL_FALSE, (const GLfloat *) currentmodel->outframe ); qglEnableClientState( GL_VERTEX_ARRAY ); GL_BindVBO(vbo_xyz); qglVertexPointer(3, GL_FLOAT, 0, 0); GL_BindVBO(NULL); GL_BindIBO(vbo_indices); glEnableVertexAttribArrayARB(6); glEnableVertexAttribArrayARB(7); glVertexAttribPointerARB(6, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(unsigned char)*4, currentmodel->blendweights); glVertexAttribPointerARB(7, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(unsigned char)*4, currentmodel->blendindexes); qglDrawElements(GL_TRIANGLES, currentmodel->num_triangles*3, GL_UNSIGNED_INT, 0); GL_BindIBO(NULL); glUseProgramObjectARB( 0 ); glDisableVertexAttribArrayARB(6); glDisableVertexAttribArrayARB(7); } R_KillVArrays (); } void IQM_DrawCaster ( void ) { float frame, time; vec3_t sv_angles; if(currententity->team) //don't draw flag models, handled by sprites return; if ( currententity->flags & RF_WEAPONMODEL ) //don't draw weapon model shadow casters return; if ( currententity->flags & ( RF_SHELL_HALF_DAM | RF_SHELL_GREEN | RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE) ) //no shells return; //modelpitch = 0.52 * sinf(rs_realtime); //use this for testing only modelpitch = degreeToRadian(currententity->angles[PITCH]); VectorCopy(currententity->angles, sv_angles); qglPushMatrix (); currententity->angles[PITCH] = currententity->angles[ROLL] = 0; R_RotateForEntity (currententity); VectorCopy(sv_angles, currententity->angles); //frame interpolation time = (Sys_Milliseconds() - currententity->frametime) / 100; if(time > 1.0) time = 1.0; if((currententity->frame == currententity->oldframe ) && !IQM_InAnimGroup(currententity->frame, currententity->oldframe)) time = 0; //Check for stopped death anims if(currententity->frame == 257 || currententity->frame == 237 || currententity->frame == 219) time = 0; frame = currententity->frame + time; use_vbo = true; IQM_AnimateFrame(frame, IQM_NextFrame(currententity->frame)); IQM_DrawCasterFrame(); qglPopMatrix(); } void IQM_DrawRagDollCaster ( int RagDollID ) { if ( RGD_CullRagDolls( RagDollID ) ) return; qglPushMatrix (); use_vbo = true; IQM_AnimateRagdoll(RagDollID, false); currentmodel = RagDoll[RagDollID].ragDollMesh; IQM_DrawCasterFrame(); qglPopMatrix(); } alien-arena-7.66+dfsg/source/ref_gl/r_vbo.c0000600000175000017500000002356312161402007017632 0ustar zero79zero79/* Copyright (C) 2011 COR Entertainment This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // r_vbo.c: vertex buffer object managment #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "r_local.h" GLuint vboId = 0; GLuint eboId = 0; int totalVBObufferSize; int totalEBObufferSize; int currVertexNum, currElemNum; size_t vbo_xyz_base, vbo_xyz_pos, vbo_st_base, vbo_st_pos, vbo_lm_base, vbo_lm_pos; GLvoid (APIENTRY * qglBindBufferARB)(GLenum target, GLuint buffer); GLvoid (APIENTRY * qglDeleteBuffersARB)(GLsizei n, const GLuint *buffers); GLvoid (APIENTRY * qglGenBuffersARB)(GLsizei n, GLuint *buffers); GLvoid (APIENTRY * qglBufferDataARB)(GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage); GLvoid (APIENTRY * qglBufferSubDataARB)(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data); void R_LoadVBOSubsystem(void) { gl_state.vbo = false; if(!gl_usevbo->integer) return; if (strstr(gl_config.extensions_string, "GL_ARB_vertex_buffer_object")) { qglBindBufferARB = (void *)qwglGetProcAddress("glBindBufferARB"); qglDeleteBuffersARB = (void *)qwglGetProcAddress("glDeleteBuffersARB"); qglGenBuffersARB = (void *)qwglGetProcAddress("glGenBuffersARB"); qglBufferDataARB = (void *)qwglGetProcAddress("glBufferDataARB"); qglBufferSubDataARB = (void *)qwglGetProcAddress("glBufferSubDataARB"); if (qglGenBuffersARB && qglBindBufferARB && qglBufferDataARB && qglDeleteBuffersARB) { Com_Printf("...using GL_ARB_vertex_buffer_object\n"); gl_state.vbo = true; VB_VCInit(); } } else { Com_Printf(S_COLOR_RED "...GL_ARB_vertex_buffer_object not found\n"); gl_state.vbo = false; } } void VB_BuildSurfaceVBO(msurface_t *surf) { glpoly_t *p = surf->polys; float *v; int i; int l, m, n; int trinum; float map[MAX_VBO_XYZs]; float map2[MAX_VBO_XYZs]; float map3[MAX_VBO_XYZs]; int xyz_size, st_size, lm_size; // XXX: for future reference, the glDrawRangeElements code was last seen // here at revision 3246. if (gl_state.vbo) { for (trinum = 1, l = 0, m = 0, n = 0; trinum < p->numverts-1; trinum++) { v = p->verts[0]; // copy in vertex data map[n++] = v[0]; map[n++] = v[1]; map[n++] = v[2]; // world texture coords map2[l++] = v[3]; map2[l++] = v[4]; // lightmap texture coords map3[m++] = v[5]; map3[m++] = v[6]; for (i = trinum; i < trinum+2; i++) { v = p->verts[i]; // copy in vertex data map[n++] = v[0]; map[n++] = v[1]; map[n++] = v[2]; // world texture coords map2[l++] = v[3]; map2[l++] = v[4]; // lightmap texture coords map3[m++] = v[5]; map3[m++] = v[6]; } } xyz_size = n*sizeof(float); st_size = l*sizeof(float); lm_size = m*sizeof(float); surf->has_vbo = true; surf->vbo_first_vert = currVertexNum; surf->vbo_num_verts = 3*(p->numverts-2); currVertexNum += surf->vbo_num_verts; qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, vbo_xyz_pos, xyz_size, &map); qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, vbo_st_pos, st_size, &map2); qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, vbo_lm_pos, lm_size, &map3); vbo_xyz_pos += xyz_size; vbo_st_pos += st_size; vbo_lm_pos += lm_size; } } void VB_BuildWorldVBO(void) { msurface_t *surf, *surfs; int i, firstsurf, lastsurf; int num_vertexes = totalVBObufferSize/7; currVertexNum = currElemNum = 0; vbo_xyz_base = vbo_xyz_pos = 0; vbo_st_base = vbo_st_pos = num_vertexes*3*sizeof(float); vbo_lm_base = vbo_lm_pos = num_vertexes*5*sizeof(float); qglGenBuffersARB(1, &vboId); qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId); qglBufferDataARB(GL_ARRAY_BUFFER_ARB, totalVBObufferSize*sizeof(float), 0, GL_STATIC_DRAW_ARB); // just to keep the lines of code short surfs = r_worldmodel->surfaces; firstsurf = 0; lastsurf = r_worldmodel->numsurfaces; for (i = 0; i < currentmodel->num_unique_texinfos; i++) { if (currentmodel->unique_texinfo[i]->flags & (SURF_SKY|SURF_NODRAW)) continue; //TODO: use VBO for alpha surfaces? But for now they're just //cluttering up the VBO. if ( TexinfoIsTranslucent(currentmodel->unique_texinfo[i]) && !TexinfoIsAlphaBlended(currentmodel->unique_texinfo[i])) continue; for (surf = &surfs[firstsurf]; surf < &surfs[lastsurf]; surf++) { if ( (currentmodel->unique_texinfo[i] != surf->texinfo->equiv) || (surf->iflags & ISURF_DRAWTURB) || (surf->iflags & ISURF_PLANEBACK)) continue; VB_BuildSurfaceVBO(surf); } for (surf = &surfs[firstsurf]; surf < &surfs[lastsurf]; surf++) { if ( (currentmodel->unique_texinfo[i] != surf->texinfo->equiv) || (surf->iflags & ISURF_DRAWTURB) || !(surf->iflags & ISURF_PLANEBACK)) continue; VB_BuildSurfaceVBO(surf); } } qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); } void VB_BuildVBOBufferSize(msurface_t *surf) { glpoly_t *p = surf->polys; if (!( surf->iflags & ISURF_DRAWTURB ) ) { totalVBObufferSize += 7*3*(p->numverts-2); } } void GL_SetupWorldVBO (void) { qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId); qglVertexPointer(3, GL_FLOAT, 0, (void *)vbo_xyz_base); qglClientActiveTextureARB (GL_TEXTURE0); qglTexCoordPointer(2, GL_FLOAT, 0, (void *)vbo_st_base); qglClientActiveTextureARB (GL_TEXTURE1); qglTexCoordPointer(2, GL_FLOAT, 0, (void *)vbo_lm_base); qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); } void GL_BindVBO(vertCache_t *cache) { if (cache) qglBindBufferARB(GL_ARRAY_BUFFER_ARB, cache->id); else qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); } void GL_BindIBO(vertCache_t *cache) { if (cache) qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, cache->id); else qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0); } vertCache_t *R_VCFindCache(vertStoreMode_t store, model_t *mod) { vertCache_t *cache, *next; for (cache = vcm.activeVertCache.next; cache != &vcm.activeVertCache; cache = next) { next = cache->next; if (cache->store == store && !strcmp(cache->mod->name, mod->name)) { // already cached! return cache; } } return NULL; } vertCache_t *R_VCLoadData(vertCacheMode_t mode, int size, void *buffer, vertStoreMode_t store, model_t *mod) { vertCache_t *cache; if (!vcm.freeVertCache) Com_Error(ERR_FATAL, "VBO cache overflow\n"); cache = vcm.freeVertCache; cache->mode = mode; cache->size = size; cache->pointer = buffer; cache->store = store; cache->mod = mod; // link vcm.freeVertCache = vcm.freeVertCache->next; cache->next = vcm.activeVertCache.next; cache->prev = &vcm.activeVertCache; vcm.activeVertCache.next->prev = cache; vcm.activeVertCache.next = cache; if(store == VBO_STORE_INDICES) GL_BindIBO(cache); else GL_BindVBO(cache); switch (cache->mode) { case VBO_STATIC: if(store == VBO_STORE_INDICES) qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER, cache->size, cache->pointer, GL_STATIC_DRAW_ARB); else qglBufferDataARB(GL_ARRAY_BUFFER_ARB, cache->size, cache->pointer, GL_STATIC_DRAW_ARB); break; case VBO_DYNAMIC: if(store == VBO_STORE_INDICES) qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER, cache->size, cache->pointer, GL_DYNAMIC_DRAW_ARB); else qglBufferDataARB(GL_ARRAY_BUFFER_ARB, cache->size, cache->pointer, GL_DYNAMIC_DRAW_ARB); break; } if(store == VBO_STORE_INDICES) GL_BindIBO(NULL); else GL_BindVBO(NULL); return cache; } void R_VCFree(vertCache_t *cache) { if (!cache) return; // unlink cache->prev->next = cache->next; cache->next->prev = cache->prev; cache->next = vcm.freeVertCache; vcm.freeVertCache = cache; } /* =============== R_VCFreeFrame Deletes all non-STATIC buffers from the previous frame. =============== */ void R_VCFreeFrame() { vertCache_t *cache, *next; if (!gl_state.vbo) return; for (cache = vcm.activeVertCache.next; cache != &vcm.activeVertCache; cache = next) { next = cache->next; if (cache->mode != VBO_STATIC) R_VCFree(cache); } } void VB_VCInit() { int i; if (!gl_state.vbo) return; //clear out previous buffer qglDeleteBuffersARB(1, &vboId); for (i=0; inext; R_VCFree(cache); } } alien-arena-7.66+dfsg/source/ref_gl/r_bloom.c0000600000175000017500000004216412161402007020152 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // r_bloom.c: 2D lighting post process effect #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "r_local.h" /* ============================================================================== LIGHT BLOOMS ============================================================================== */ static float Diamond8x[8][8] = { {0.0f, 0.0f, 0.0f, 0.1f, 0.1f, 0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.2f, 0.3f, 0.3f, 0.2f, 0.0f, 0.0f}, {0.0f, 0.2f, 0.4f, 0.6f, 0.6f, 0.4f, 0.2f, 0.0f}, {0.1f, 0.3f, 0.6f, 0.9f, 0.9f, 0.6f, 0.3f, 0.1f}, {0.1f, 0.3f, 0.6f, 0.9f, 0.9f, 0.6f, 0.3f, 0.1f}, {0.0f, 0.2f, 0.4f, 0.6f, 0.6f, 0.4f, 0.2f, 0.0f}, {0.0f, 0.0f, 0.2f, 0.3f, 0.3f, 0.2f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.1f, 0.1f, 0.0f, 0.0f, 0.0f} }; static float Diamond6x[6][6] = { {0.0f, 0.0f, 0.1f, 0.1f, 0.0f, 0.0f}, {0.0f, 0.3f, 0.5f, 0.5f, 0.3f, 0.0f}, {0.1f, 0.5f, 0.9f, 0.9f, 0.5f, 0.1f}, {0.1f, 0.5f, 0.9f, 0.9f, 0.5f, 0.1f}, {0.0f, 0.3f, 0.5f, 0.5f, 0.3f, 0.0f}, {0.0f, 0.0f, 0.1f, 0.1f, 0.0f, 0.0f} }; static float Diamond4x[4][4] = { {0.3f, 0.4f, 0.4f, 0.3f}, {0.4f, 0.9f, 0.9f, 0.4f}, {0.4f, 0.9f, 0.9f, 0.4f}, {0.3f, 0.4f, 0.4f, 0.3f} }; static int BLOOM_SIZE; cvar_t *r_bloom_alpha; cvar_t *r_bloom_diamond_size; cvar_t *r_bloom_intensity; cvar_t *r_bloom_darken; cvar_t *r_bloom_sample_size; cvar_t *r_bloom_fast_sample; image_t *r_bloomscratchtexture; image_t *r_bloomeffecttexture; image_t *r_midsizetexture; static GLuint bloomscratchFBO, midsizeFBO, bloomeffectFBO; static GLuint bloom_fullsize_downsampling_rbo_FBO; static GLuint bloom_fullsize_downsampling_RBO; static int r_midsizetexture_size; static int screen_texture_width, screen_texture_height; GLint MultiSampleEnabled = 0; //1 if MSAA is enabled //current refdef size: static int curView_x; static int curView_y; static int curView_width; static int curView_height; #define R_Bloom_Quad( x, y, width, height ) \ qglBegin(GL_QUADS); \ qglTexCoord2f( 0, 1.0); \ qglVertex2f( x, y); \ qglTexCoord2f( 0, 0); \ qglVertex2f( x, y+height); \ qglTexCoord2f( 1.0, 0); \ qglVertex2f( x+width, y+height); \ qglTexCoord2f( 1.0, 1.0); \ qglVertex2f( x+width, y); \ qglEnd(); #define R_Bloom_SamplePass( xpos, ypos ) R_Bloom_Quad ( xpos, ypos, BLOOM_SIZE, BLOOM_SIZE) /* ================= R_Bloom_AllocFBOTexture Create a 24-bit square texture with specified size and attach it to an FBO ================= */ image_t *R_Bloom_AllocFBOTexture (char *name, int size_side, GLuint *FBO) { byte *data; int size; image_t *image; size = size_side*size_side*3; data = malloc (size); memset (data, 0, size); // create the texture image = GL_FindFreeImage (name, size_side, size_side, it_pic); GL_Bind (image->texnum); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); qglTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, size_side, size_side, 0, GL_RGB, GL_UNSIGNED_BYTE, (byte*)data); // create up the FBO qglGenFramebuffersEXT(1, FBO); qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,*FBO); // bind the texture to it qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, image->texnum, 0); // clean up free (data); qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0); return image; } /* ================= R_Bloom_AllocRBO Create a 24-bit square RBO with specified size and attach it to an FBO ================= */ void R_Bloom_AllocRBO (int width, int height, GLuint *RBO, GLuint *FBO) { // create the RBO qglGenRenderbuffersEXT(1, RBO); qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, *RBO); qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, width, height); qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); // create up the FBO qglGenFramebuffersEXT(1, FBO); qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, *FBO); // bind the RBO to it qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, *RBO); //clean up qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } /* ================= R_Bloom_InitEffectTexture ================= */ void R_Bloom_InitEffectTexture( void ) { float bloomsizecheck; if( r_bloom_sample_size->integer < 32 ) Cvar_SetValue ("r_bloom_sample_size", 32); //make sure bloom size is a power of 2 BLOOM_SIZE = r_bloom_sample_size->integer; bloomsizecheck = (float)BLOOM_SIZE; while(bloomsizecheck > 1.0f) bloomsizecheck /= 2.0f; if( bloomsizecheck != 1.0f ) { BLOOM_SIZE = 32; while( BLOOM_SIZE < r_bloom_sample_size->integer ) BLOOM_SIZE *= 2; } //make sure bloom size doesn't have stupid values if( BLOOM_SIZE > screen_texture_width || BLOOM_SIZE > screen_texture_height ) BLOOM_SIZE = min( screen_texture_width, screen_texture_height ); if( BLOOM_SIZE != r_bloom_sample_size->integer ) Cvar_SetValue ("r_bloom_sample_size", BLOOM_SIZE); r_bloomeffecttexture = R_Bloom_AllocFBOTexture ("***r_bloomeffecttexture***", BLOOM_SIZE, &bloomeffectFBO); } /* ================= R_Bloom_InitTextures ================= */ void checkFBOExtensions (void); void R_Bloom_InitTextures( void ) { if (!gl_state.fbo || !gl_state.hasFBOblit) { Com_Printf ("FBO Failed, disabling bloom.\n"); Cvar_SetValue ("r_bloom", 0); return; } qglGetError (); qglGetIntegerv(GL_SAMPLE_BUFFERS, &MultiSampleEnabled); //find closer power of 2 to screen size for (screen_texture_width = 1;screen_texture_width < viddef.width;screen_texture_width *= 2); for (screen_texture_height = 1;screen_texture_height < viddef.height;screen_texture_height *= 2); //validate bloom size and init the bloom effect texture R_Bloom_InitEffectTexture(); //init the "scratch" texture r_bloomscratchtexture = R_Bloom_AllocFBOTexture ("***r_bloomscratchtexture***", BLOOM_SIZE, &bloomscratchFBO); //init the screen-size RBO R_Bloom_AllocRBO (viddef.width, viddef.height, &bloom_fullsize_downsampling_RBO, &bloom_fullsize_downsampling_rbo_FBO); //if screensize is more than 2x the bloom effect texture, set up for stepped downsampling r_midsizetexture = NULL; r_midsizetexture_size = 0; if( viddef.width > (BLOOM_SIZE * 2) && !r_bloom_fast_sample->integer ) { r_midsizetexture_size = (int)(BLOOM_SIZE * 2); // mid-size texture r_midsizetexture = R_Bloom_AllocFBOTexture ("***r_midsizetexture***", r_midsizetexture_size, &midsizeFBO); } } /* ================= R_InitBloomTextures ================= */ void R_InitBloomTextures( void ) { r_bloom = Cvar_Get( "r_bloom", "0", CVAR_ARCHIVE ); r_bloom_alpha = Cvar_Get( "r_bloom_alpha", "0.2", CVAR_ARCHIVE ); r_bloom_diamond_size = Cvar_Get( "r_bloom_diamond_size", "8", CVAR_ARCHIVE ); r_bloom_intensity = Cvar_Get( "r_bloom_intensity", "0.5", CVAR_ARCHIVE ); r_bloom_darken = Cvar_Get( "r_bloom_darken", "8", CVAR_ARCHIVE ); r_bloom_sample_size = Cvar_Get( "r_bloom_sample_size", "128", CVAR_ARCHIVE ); r_bloom_fast_sample = Cvar_Get( "r_bloom_fast_sample", "0", CVAR_ARCHIVE ); BLOOM_SIZE = 0; if( !r_bloom->integer ) return; R_Bloom_InitTextures (); } /* ================= R_Bloom_DrawEffect ================= */ void R_Bloom_DrawEffect( void ) { GL_Bind(r_bloomeffecttexture->texnum); qglEnable(GL_BLEND); qglBlendFunc(GL_ONE, GL_ONE); qglColor4f(r_bloom_alpha->value, r_bloom_alpha->value, r_bloom_alpha->value, 1.0f); GL_TexEnv(GL_MODULATE); qglBegin(GL_QUADS); qglTexCoord2f( 0, 1.0 ); qglVertex2f( curView_x, curView_y ); qglTexCoord2f( 0, 0 ); qglVertex2f( curView_x, curView_y + curView_height ); qglTexCoord2f( 1.0, 0 ); qglVertex2f( curView_x + curView_width, curView_y + curView_height ); qglTexCoord2f( 1.0, 1.0 ); qglVertex2f( curView_x + curView_width, curView_y ); qglEnd(); qglDisable(GL_BLEND); } /* ================= R_Bloom_GeneratexDiamonds ================= */ void R_Bloom_GeneratexDiamonds( void ) { int i, j; static float intensity; //set up sample size workspace qglViewport( 0, 0, BLOOM_SIZE, BLOOM_SIZE ); qglMatrixMode( GL_PROJECTION ); qglLoadIdentity (); qglOrtho(0, BLOOM_SIZE, BLOOM_SIZE, 0, -10, 100); qglMatrixMode( GL_MODELVIEW ); qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bloomscratchFBO); GL_Bind(r_bloomeffecttexture->texnum); //start modifying the small scene corner qglColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); qglEnable(GL_BLEND); //darkening passes if( r_bloom_darken->integer ) { qglBlendFunc(GL_DST_COLOR, GL_ZERO); GL_TexEnv(GL_MODULATE); for(i=0; iinteger ;i++) { R_Bloom_SamplePass( 0, 0 ); } qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, BLOOM_SIZE, BLOOM_SIZE); } //bluring passes //qglBlendFunc(GL_ONE, GL_ONE); qglBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR); if( r_bloom_diamond_size->integer > 7 || r_bloom_diamond_size->integer <= 3) { if( r_bloom_diamond_size->integer != 8 ) Cvar_SetValue( "r_bloom_diamond_size", 8 ); for(i=0; iinteger; i++) { for(j=0; jinteger; j++) { intensity = r_bloom_intensity->value * 0.3 * Diamond8x[i][j]; if( intensity < 0.01f ) continue; qglColor4f( intensity, intensity, intensity, 1.0); R_Bloom_SamplePass( i-4, j-4 ); } } } else if( r_bloom_diamond_size->integer > 5 ) { if( r_bloom_diamond_size->integer != 6 ) Cvar_SetValue( "r_bloom_diamond_size", 6 ); for(i=0; iinteger; i++) { for(j=0; jinteger; j++) { intensity = r_bloom_intensity->value * 0.5 * Diamond6x[i][j]; if( intensity < 0.01f ) continue; qglColor4f( intensity, intensity, intensity, 1.0); R_Bloom_SamplePass( i-3, j-3 ); } } } else if( r_bloom_diamond_size->integer > 3 ) { if( r_bloom_diamond_size->integer != 4 ) Cvar_SetValue( "r_bloom_diamond_size", 4 ); for(i=0; iinteger; i++) { for(j=0; jinteger; j++) { intensity = r_bloom_intensity->value * 0.8f * Diamond4x[i][j]; if( intensity < 0.01f ) continue; qglColor4f( intensity, intensity, intensity, 1.0); R_Bloom_SamplePass( i-2, j-2 ); } } } qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, BLOOM_SIZE, BLOOM_SIZE); //restore full screen workspace qglViewport( 0, 0, viddef.width, viddef.height ); qglMatrixMode( GL_PROJECTION ); qglLoadIdentity (); qglOrtho(0, viddef.width, viddef.height, 0, -10, 100); qglMatrixMode( GL_MODELVIEW ); qglLoadIdentity (); qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } /* ================= R_Bloom_FullsizeRBOUpdate This updates the full size RBO from the screen. The whole thing is guaranteed to be updated 60 times a second, but it does it a 1/4 of the screen at a time if the framerate is high enough. It does it in horizontal slices instead of quadrants because that way the GPU doesn't have to skip over part of each row of pixels. Tearing isn't an issue because it'll just be blurred to mush anyway. ================= */ void R_Bloom_FullsizeRBOUpdate (void) { static int cur_section = 0; static int last_time = 0; int i, num_sections, cur_time; int y; cur_time = Sys_Milliseconds(); num_sections = (cur_time-last_time+2)/4; if (num_sections > 4) num_sections = 4; if (num_sections == 0) return; for (i = 0; i < num_sections; i++) { y = cur_section*(vid.height/4); qglBlitFramebufferEXT(0, y, vid.width, y+vid.height/4, 0, y, vid.width, y+vid.height/4, GL_COLOR_BUFFER_BIT, GL_LINEAR); cur_section = (cur_section + 1) % 4; } last_time = cur_time; } /* ================= R_Bloom_DownsampleView Creates a downscaled, blurred version of the screen, leaving it in the "scratch" and "effect" textures (identical in both.) This function is name is a bit confusing, because "downsampling" means two things here: 1) Creating a scaled-down version of an image 2) Converting a multisampled image to a non-multisampled image the same size, which is necessary if MSAA is enabled in the graphics driver settings The function name uses meaning 1. ================= */ void R_Bloom_DownsampleView( void ) { qglDisable( GL_BLEND ); qglColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); GL_SelectTexture (GL_TEXTURE0); // FIXME: OH FFS this is so stupid: tell the GL_Bind batching mechanism // that texture unit 0 has been re-bound, as it most certainly has been. gl_state.currenttextures[gl_state.currenttmu] = -1; if (MultiSampleEnabled != 0) { // If MSAA is enabled, the FBO blitting needs an extra step. // Copy onto full-screen sized RBO first, to go from the multisample // format of the screen to a non-multisampled format. qglBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, bloom_fullsize_downsampling_rbo_FBO); R_Bloom_FullsizeRBOUpdate (); // Set the downsampled RBO as the read framebuffer, then run the rest // of the code as normal. qglBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, bloom_fullsize_downsampling_rbo_FBO); } //stepped downsample if( r_midsizetexture_size ) { // copy into small sized FBO (equivalent to copying into full screen // sized FBO and then drawing that onto the small sized FBO later.) qglBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, bloomscratchFBO); qglBlitFramebufferEXT(0, 0, vid.width, vid.height, 0, 0, BLOOM_SIZE, BLOOM_SIZE, GL_COLOR_BUFFER_BIT, GL_LINEAR); // copy into downsampling (mid-sized) FBO qglBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, midsizeFBO); qglBlitFramebufferEXT(0, 0, vid.width, vid.height, 0, 0, r_midsizetexture_size, r_midsizetexture_size, GL_COLOR_BUFFER_BIT, GL_LINEAR); // create the finished downsampled version of the texture by blending // the small-sized FBO and the mid-sized FBO onto a small-sized FBO, // hoping it adds some blur. // Store first of all in the bloom effect texture, since we don't want // to draw the scratch texture onto itself. qglBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, bloomeffectFBO); // mid-size GL_Bind(r_midsizetexture->texnum); qglColor4f( 0.5f, 0.5f, 0.5f, 1.0f ); R_Bloom_Quad( 0, viddef.height-BLOOM_SIZE, BLOOM_SIZE, BLOOM_SIZE); // small-size qglEnable( GL_BLEND ); qglBlendFunc(GL_ONE, GL_ONE); qglColor4f( 0.5f, 0.5f, 0.5f, 1.0f ); GL_Bind(r_bloomscratchtexture->texnum); R_Bloom_Quad( 0, viddef.height-BLOOM_SIZE, BLOOM_SIZE, BLOOM_SIZE ); qglColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); qglDisable( GL_BLEND ); } else { //downsample simple qglBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, bloomeffectFBO); qglBlitFramebufferEXT(0, 0, vid.width, vid.height, 0, 0, BLOOM_SIZE, BLOOM_SIZE, GL_COLOR_BUFFER_BIT, GL_LINEAR); } // Blit the finished downsampled texture onto a second FBO. We end up with // with two copies, which GenerateDiamonds will take advantage of. qglBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, bloomscratchFBO); qglBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, bloomeffectFBO); qglBlitFramebufferEXT(0, 0, BLOOM_SIZE, BLOOM_SIZE, 0, 0, BLOOM_SIZE, BLOOM_SIZE, GL_COLOR_BUFFER_BIT, GL_NEAREST); qglBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); qglBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); } /* ================= R_BloomBlend ================= */ void R_BloomBlend ( refdef_t *fd ) { if( !(fd->rdflags & RDF_BLOOM) || !r_bloom->integer ) return; if( !BLOOM_SIZE ) R_Bloom_InitTextures(); // previous function can set this if there's no FBO if (!r_bloom->integer) return; if( screen_texture_width < BLOOM_SIZE || screen_texture_height < BLOOM_SIZE ) return; //set up full screen workspace qglViewport( 0, 0, viddef.width, viddef.height ); qglDisable( GL_DEPTH_TEST ); qglMatrixMode( GL_PROJECTION ); qglLoadIdentity (); qglOrtho(0, viddef.width, viddef.height, 0, -10, 100); qglMatrixMode( GL_MODELVIEW ); qglLoadIdentity (); qglDisable(GL_CULL_FACE); qglDisable( GL_BLEND ); qglEnable( GL_TEXTURE_2D ); qglColor4f( 1, 1, 1, 1 ); //set up current sizes // TODO: get rid of these nasty globals curView_x = fd->x; curView_y = fd->y; curView_width = fd->width; curView_height = fd->height; //create the bloom image R_Bloom_DownsampleView(); R_Bloom_GeneratexDiamonds(); R_Bloom_DrawEffect(); qglColor3f (1,1,1); qglDisable (GL_BLEND); qglEnable (GL_TEXTURE_2D); qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); qglDepthMask (1); } alien-arena-7.66+dfsg/source/ref_gl/r_script.h0000600000175000017500000001227512161402007020353 0ustar zero79zero79#ifndef __GL_SCRIPT__ #define __GL_SCRIPT__ //CVARS extern cvar_t *rs_dynamic_time; #define ALPHAFUNC_BASIC 1 #define ALPHAFUNC_GLOSS 2 #define ALPHAFUNC_NORMAL 3 // Animation loop typedef struct anim_stage_s { image_t *texture; // texture char name[MAX_OSPATH]; // texture name struct anim_stage_s *next; // next anim stage } anim_stage_t; typedef struct random_stage_s { image_t *texture; // texture char name[MAX_OSPATH]; // texture name struct random_stage_s *next; // next anim stage } random_stage_t; // Blending typedef struct { int source; // source blend value int dest; // dest blend value qboolean blend; // are we going to blend? } blendfunc_t; // Alpha shifting typedef struct { float min, max; // min/max alpha values float speed; // shifting speed } alphashift_t; // scaling typedef struct { char typeX, typeY; // scale types float scaleX, scaleY; // scaling factors } rs_scale_t; // scrolling typedef struct { char typeX, typeY; // scroll types float speedX, speedY; // speed of scroll } rs_scroll_t; // colormap typedef struct { qboolean enabled; float red, green, blue; // colors - duh! } rs_colormap_t; //conditional operation types typedef enum { rs_cond_none, // no comparison, no subexpressions rs_cond_is, // no comparison, use first subexpresson rs_cond_eq, // == rs_cond_neq, // != rs_cond_gt, // > rs_cond_ngt, // <= rs_cond_lt, // < rs_cond_nlt, // >= rs_cond_and, // && rs_cond_or, // || rs_cond_lnot, // !, use first subexpression } rs_cond_op_t; //conditional operation value typedef struct rs_cond_val_s { rs_cond_op_t optype; //what type of operation struct rs_cond_val_s *subexpr1, *subexpr2; //sub expressions, if applicable cvar_t *val; //value, if applicable cvar_t lval; //for use storing literal values } rs_cond_val_t; // Script stage typedef struct rs_stage_s { image_t *texture; // texture char name[MAX_OSPATH]; // texture name image_t *texture2; // texture for combining(GLSL) char name2[MAX_OSPATH]; // texture name image_t *texture3; // texture for combining(GLSL) char name3[MAX_OSPATH]; // texture name rs_cond_val_t *condv; // conditional expression anim_stage_t *anim_stage; // first animation stage float anim_delay; // Delay between anim frames float last_anim_time; // gametime of last frame change char anim_count; // number of animation frames anim_stage_t *last_anim; // pointer to last anim random_stage_t *rand_stage; // random linked list int rand_count; // number of random pics rs_colormap_t colormap; // color mapping blendfunc_t blendfunc; // image blending alphashift_t alphashift; // alpha shifting rs_scroll_t scroll; // tcmod rs_scale_t scale; // tcmod float rot_speed; // rotate speed (0 for no rotate); qboolean depthhack; // fake zdepth qboolean envmap; // fake envmapping - spheremapping qboolean lightmap; // lightmap this stage? qboolean alphamask; // alpha masking? int alphafunc; // software alpha effects qboolean has_alpha; // for sorting qboolean normalmap; // for normalmaps qboolean lensflare; // for adding lensflares int flaretype; // type of flare qboolean grass; // grass and vegetation int grasstype; // the type of vegetation qboolean beam; // for adding light beams int beamtype; // the type of beam(up vs down) float xang; // beam pitch float yang; // beam roll qboolean rotating; //rotating beams(moving spotlights, etc). qboolean fx; // for glsl effect layer qboolean glow; // for glsl effect layer qboolean cube; // for glsl effect layer struct rs_stage_s *next; // next stage } rs_stage_t; typedef struct rs_stagekey_s { char *stage; void (*func)(rs_stage_t *shader, char **token); } rs_stagekey_t; // Base script typedef struct rscript_s { char name[MAX_OSPATH]; // name of script unsigned int hash_key; // hash key for the script's name qboolean dontflush; // dont flush from memory on map change qboolean ready; // readied by the engine? rs_stage_t *stage; // first rendering stage struct rscript_s *next; // next script in linked list } rscript_t; void RS_SetEnvmap (vec3_t v, float *os, float *ot); void RS_LoadScript(char *script); void RS_FreeAllScripts(void); void RS_ReloadImageScriptLinks (void); void RS_FreeScript(rscript_t *rs); void RS_FreeUnmarked(void); rscript_t *RS_FindScript(char *name); void RS_ReadyScript(rscript_t *rs); void RS_ScanPathForScripts(void); int RS_Animate(rs_stage_t *stage); void RS_UpdateRegistration(void); void RS_DrawSurface (msurface_t *surf, qboolean lightmap); void RS_SetTexcoords (rs_stage_t *stage, float *os, float *ot, msurface_t *fa); void RS_SetTexcoords2D (rs_stage_t *stage, float *os, float *ot); void RS_Surface (msurface_t *surf); void RS_LoadSpecialScripts(void); #define RS_DrawPolyNoLightMap(surf) RS_DrawSurface((surf),false) extern float rs_realtime; #endif // __GL_SCRIPT__ alien-arena-7.66+dfsg/source/ref_gl/r_ragdoll.h0000600000175000017500000001245312161402007020471 0ustar zero79zero79/* Copyright (C) 2010 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #define MAX_RAGDOLLS 64 #define MAX_RAGDOLL_OBJECTS 15 #define MAX_RAGDOLL_JOINTS 15 #define MAX_CONTACTS 32 #define MAX_FORCES 4 #define MAX_ODESTEPS 120 #define MIN_ODESTEPS 20 #define RAGDOLL_DURATION 10000 //10 seconds //body id's #define CHEST 0 #define PELVIS 1 #define HEAD 2 #define RIGHTUPPERLEG 3 #define LEFTUPPERLEG 4 #define RIGHTLOWERLEG 5 #define LEFTLOWERLEG 6 #define RIGHTFOOT 7 #define LEFTFOOT 8 #define RIGHTUPPERARM 9 #define LEFTUPPERARM 10 #define RIGHTFOREARM 11 #define LEFTFOREARM 12 #define RIGHTHAND 13 #define LEFTHAND 14 //joint id's #define MIDSPINE 0 #define LOWSPINE 1 #define NECK 2 #define RIGHTHIP 3 #define LEFTHIP 4 #define RIGHTKNEE 5 #define LEFTKNEE 6 #define RIGHTANKLE 7 #define LEFTANKLE 8 #define RIGHTSHOULDER 9 #define LEFTSHOULDER 10 #define RIGHTELBOW 11 #define LEFTELBOW 12 #define RIGHTWRIST 13 #define LEFTWRIST 14 //ragdoll dimensions #define RAGDOLL_DIMS 56 #define ELBOW_X_OFF 0 //note - we likely want to do something similar for knees and ankles #define ELBOW_Y_OFF 1 #define ELBOW_Z_OFF 2 #define WRIST_X_OFF 3 #define WRIST_Y_OFF 4 #define WRIST_Z_OFF 5 #define FINGERS_X_OFF 6 #define FINGERS_Y_OFF 7 #define FINGERS_Z_OFF 8 #define FOOT_LEN 9 // ankles to base of ball of foot only #define HEEL_LEN 10 #define HEAD_H 11 #define NECK_H 12 #define SHOULDER_H 13 #define CHEST_H 14 #define HIP_H 15 #define HEAD_W 16 #define SHOULDER_W 17 #define CHEST_W 18 // actually wider, but we want narrower than shoulders (esp. with large radius) #define BICEP_W 19 //thickness of bicep #define FOREARM_W 20 //thickness of forearm #define HAND_W 21 //width of hand #define LEG_W 22 // between middles of upper legs #define PELVIS_W 23 // actually wider, but we want smaller than hip width #define THIGH_W 24 //thickness of thigh #define SHIN_W 25 //thickness of shin #define FOOT_W 26 //width of foot #define KNEE_X_OFF 27 #define KNEE_Y_OFF 28 #define KNEE_Z_OFF 29 #define ANKLE_X_OFF 30 #define ANKLE_Y_OFF 31 #define ANKLE_Z_OFF 32 #define GLOBAL_X_OFF 33 #define GLOBAL_Y_OFF 34 #define GLOBAL_Z_OFF 35 //contraint section #define HIP_LOSTOP1 36 #define HIP_HISTOP1 37 #define HIP_LOSTOP2 38 #define HIP_HISTOP2 39 #define KNEE_LOSTOP 40 #define KNEE_HISTOP 41 #define ANKLE_LOSTOP 42 #define ANKLE_HISTOP 43 #define SHOULDER_LOSTOP1 44 #define SHOULDER_HISTOP1 45 #define SHOULDER_LOSTOP2 46 #define SHOULDER_HISTOP2 47 #define ELBOW_LOSTOP 48 #define ELBOW_HISTOP 49 #define WRIST_LOSTOP 50 #define WRIST_HISTOP 51 #define HEAD_LOSTOP1 52 #define HEAD_HISTOP1 53 #define HEAD_LOSTOP2 54 #define HEAD_HISTOP2 55 dWorldID RagDollWorld; dSpaceID RagDollSpace; dJointGroupID contactGroup; int lastODEUpdate; dQuaternion initialQuaternion; typedef struct RagDollBind_s { const char *name; int object; } RagDollBind_t; extern RagDollBind_t RagDollBinds[]; extern int RagDollBindsCount; typedef struct RagDollObject_s { dBodyID body; dMass mass; dGeomID geom; matrix3x4_t initmat; } RagDollObject_t; typedef struct RagDollForce_s { vec3_t org; vec3_t dir; float force; int spawnTime; int destroyed; } RagDollForce_t; #define GROW_ODE_VERTS 16384 #define GROW_ODE_TRIS 16384 typedef struct RagDollWorld_s { dVector3 *ODEVerts; dTriIndex *ODETris; int numODEVerts, maxODEVerts; int numODETris, maxODETris; dTriMeshDataID triMesh; dGeomID geom; } RagDollWorld_t; typedef struct RagDoll_s { char name[MAX_QPATH]; RagDollObject_t RagDollObject[MAX_RAGDOLL_OBJECTS]; dJointID RagDollJoint[MAX_RAGDOLL_JOINTS]; RagDollForce_t RagDollForces[MAX_FORCES]; //mesh information model_t *ragDollMesh; matrix3x4_t *initframe; int texnum; int flags; struct rscript_s *script; float angles[3]; vec3_t origin; vec3_t curPos; int spawnTime; int destroyed; } RagDoll_t; RagDoll_t RagDoll[MAX_RAGDOLLS]; // A few values will be copied into this. It's a bit wasteful, but it allows // us to reuse code that expects them to be in an entity_t struct. entity_t RagDollEntity; //surface for ragdoll to collide RagDollWorld_t RagDollTriWorld; //Funcs extern void R_RenderAllRagdolls ( void ); extern void R_ClearAllRagdolls( void ); extern void RGD_CreateWorldObject( void ); extern void RGD_DestroyWorldObject( void ); extern void RGD_AddNewRagdoll( vec3_t origin, char name[MAX_QPATH] ); extern void RGD_DestroyWorldTrimesh(); extern void RGD_BuildWorldTrimesh (); extern qboolean RGD_CullRagDolls( int RagDollID ); alien-arena-7.66+dfsg/source/ref_gl/r_mesh.c0000600000175000017500000016514612162607462020021 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // r_mesh.c: triangle model functions #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "r_local.h" #include "r_ragdoll.h" #include "r_lodcalc.h" /* ============================================================= ALIAS MODELS ============================================================= */ #define NUMVERTEXNORMALS 162 float r_avertexnormals[NUMVERTEXNORMALS][3] = { #include "anorms.h" }; static vec4_t s_lerped[MAX_VERTS]; static vec3_t VertexArray[MAX_VERTICES]; static vec2_t TexCoordArray[MAX_VERTICES]; static vec3_t NormalsArray[MAX_VERTICES]; static vec4_t TangentsArray[MAX_VERTICES]; static vertCache_t *vbo_st; static vertCache_t *vbo_xyz; static vertCache_t *vbo_normals; static vertCache_t *vbo_tangents; extern vec3_t lightspot; vec3_t shadevector; float shadelight[3]; #define MAX_MODEL_DLIGHTS 128 m_dlight_t model_dlights[MAX_MODEL_DLIGHTS]; int model_dlights_num; extern void MYgluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar); extern rscript_t *rs_glass; extern image_t *r_mirrortexture; extern cvar_t *cl_gun; cvar_t *gl_mirror; // precalculated dot products for quantized angles #define SHADEDOT_QUANT 16 float r_avertexnormal_dots[SHADEDOT_QUANT][256] = #include "anormtab.h" ; float *shadedots = r_avertexnormal_dots[0]; /* ============= MD2 Loading Routines ============= */ /* ============================================================================== ALIAS MODELS ============================================================================== */ /* ======================== MD2_FindTriangleWithEdge ======================== */ static int MD2_FindTriangleWithEdge(neighbors_t * neighbors, dtriangle_t * tris, int numtris, int triIndex, int edgeIndex){ int i, j, found = -1, foundj = 0; dtriangle_t *current = &tris[triIndex]; qboolean dup = false; for (i = 0; i < numtris; i++) { if (i == triIndex) continue; for (j = 0; j < 3; j++) { if (((current->index_xyz[edgeIndex] == tris[i].index_xyz[j]) && (current->index_xyz[(edgeIndex + 1) % 3] == tris[i].index_xyz[(j + 1) % 3])) || ((current->index_xyz[edgeIndex] == tris[i].index_xyz[(j + 1) % 3]) && (current->index_xyz[(edgeIndex + 1) % 3] == tris[i].index_xyz[j]))) { // no edge for this model found yet? if (found == -1) { found = i; foundj = j; } else dup = true; // the three edges story } } } // normal edge, setup neighbor pointers if (!dup && found != -1) { neighbors[found].n[foundj] = triIndex; return found; } // naughty edge let no-one have the neighbor return -1; } /* =============== MD2_BuildTriangleNeighbors =============== */ static void MD2_BuildTriangleNeighbors(neighbors_t * neighbors, dtriangle_t * tris, int numtris) { int i, j; // set neighbors to -1 for (i = 0; i < numtris; i++) { for (j = 0; j < 3; j++) neighbors[i].n[j] = -1; } // generate edges information (for shadow volumes) // NOTE: We do this with the original vertices not the reordered onces // since reordering them // duplicates vertices and we only compare indices for (i = 0; i < numtris; i++) { for (j = 0; j < 3; j++) { if (neighbors[i].n[j] == -1) neighbors[i].n[j] = MD2_FindTriangleWithEdge(neighbors, tris, numtris, i, j); } } } void MD2_LoadVertexArrays(model_t *md2model){ dmdl_t *md2; daliasframe_t *md2frame; dtrivertx_t *md2v; int i; if(md2model->num_frames > 1) return; md2 = (dmdl_t *)md2model->extradata; md2frame = (daliasframe_t *)((byte *)md2 + md2->ofs_frames); if(md2->num_xyz > MAX_VERTS) return; md2model->vertexes = (mvertex_t*)Hunk_Alloc(md2->num_xyz * sizeof(mvertex_t)); for(i = 0, md2v = md2frame->verts; i < md2->num_xyz; i++, md2v++){ // reconstruct the verts VectorSet(md2model->vertexes[i].position, md2v->v[0] * md2frame->scale[0] + md2frame->translate[0], md2v->v[1] * md2frame->scale[1] + md2frame->translate[1], md2v->v[2] * md2frame->scale[2] + md2frame->translate[2]); } } #if 0 byte MD2_Normal2Index(const vec3_t vec) { int i, best; float d, bestd; bestd = best = 0; for (i=0 ; i bestd) { bestd = d; best = i; } } return best; } #else // for MD2 load speedup. Adapted from common.c::MSG_WriteDir() byte MD2_Normal2Index(const vec3_t vec) { int i, best; float d, bestd; float x,y,z; x = vec[0]; y = vec[1]; z = vec[2]; best = 0; // frequently occurring axial cases, use known best index if ( x == 0.0f && y == 0.0f ) { best = ( z >= 0.999f ) ? 5 : 84; } else if ( x == 0.0f && z == 0.0f ) { best = ( y >= 0.999f ) ? 32 : 104; } else if ( y == 0.0f && z == 0.0f ) { best = ( x >= 0.999f ) ? 52 : 143; } else { // general case bestd = 0.0f; for ( i = 0 ; i < NUMVERTEXNORMALS ; i++ ) { // search for closest match d = (x*r_avertexnormals[i][0]) + (y*r_avertexnormals[i][1]) + (z*r_avertexnormals[i][2]); if ( d > 0.998f ) { // no other entry could be a closer match // 0.9679495 is max dot product between anorm.h entries best = i; break; } if ( d > bestd ) { bestd = d; best = i; } } } return best; } #endif void MD2_RecalcVertsLightNormalIdx (dmdl_t *pheader) { int i, j, k, l; daliasframe_t *frame; dtrivertx_t *verts, *v; vec3_t normal, triangle[3], v1, v2; dtriangle_t *tris = (dtriangle_t *) ((byte *)pheader + pheader->ofs_tris); vec3_t normals_[MAX_VERTS]; //for all frames for (i=0; inum_frames; i++) { frame = (daliasframe_t *)((byte *)pheader + pheader->ofs_frames + i * pheader->framesize); verts = frame->verts; memset(normals_, 0, pheader->num_xyz*sizeof(vec3_t)); //for all tris for (j=0; jnum_tris; j++) { //make 3 vec3_t's of this triangle's vertices for (k=0; k<3; k++) { l = tris[j].index_xyz[k]; v = &verts[l]; for (l=0; l<3; l++) triangle[k][l] = v->v[l]; } //calculate normal VectorSubtract(triangle[0], triangle[1], v1); VectorSubtract(triangle[2], triangle[1], v2); CrossProduct(v2,v1, normal); VectorScale(normal, -1.0/VectorLength(normal), normal); for (k=0; k<3; k++) { l = tris[j].index_xyz[k]; VectorAdd(normals_[l], normal, normals_[l]); } } for (j=0; jnum_xyz; j++) for (k=j+1; knum_xyz; k++) if(verts[j].v[0] == verts[k].v[0] && verts[j].v[1] == verts[k].v[1] && verts[j].v[2] == verts[k].v[2]) { float *jnormal = r_avertexnormals[verts[j].lightnormalindex]; float *knormal = r_avertexnormals[verts[k].lightnormalindex]; if(DotProduct(jnormal, knormal)>=cos(DEG2RAD(45))) { VectorAdd(normals_[j], normals_[k], normals_[j]); VectorCopy(normals_[j], normals_[k]); } } //normalize average for (j=0; jnum_xyz; j++) { VectorNormalize(normals_[j]); verts[j].lightnormalindex = MD2_Normal2Index(normals_[j]); } } } #if 0 void MD2_VecsForTris(float *v0, float *v1, float *v2, float *st0, float *st1, float *st2, vec3_t Tangent) { vec3_t vec1, vec2; vec3_t planes[3]; float tmp; int i; for (i=0; i<3; i++) { vec1[0] = v1[i]-v0[i]; vec1[1] = st1[0]-st0[0]; vec1[2] = st1[1]-st0[1]; vec2[0] = v2[i]-v0[i]; vec2[1] = st2[0]-st0[0]; vec2[2] = st2[1]-st0[1]; VectorNormalize(vec1); VectorNormalize(vec2); CrossProduct(vec1,vec2,planes[i]); } for (i=0; i<3; i++) { tmp = 1.0 / planes[i][0]; Tangent[i] = -planes[i][1]*tmp; } VectorNormalize(Tangent); } #else // Math rearrangement for MD2 load speedup static void MD2_VecsForTris( const float *v0, const float *v1, const float *v2, const float *st0, const float *st1, const float *st2, vec3_t Tangent ) { vec3_t vec1, vec2; vec3_t planes[3]; float tmp; float vec1_y, vec1_z, vec1_nrml; float vec2_y, vec2_z, vec2_nrml; int i; vec1_y = st1[0]-st0[0]; vec1_z = st1[1]-st0[1]; vec1_nrml = (vec1_y*vec1_y) + (vec1_z*vec1_z); // partial for normalize vec2_y = st2[0]-st0[0]; vec2_z = st2[1]-st0[1]; vec2_nrml = (vec2_y*vec2_y) + (vec2_z*vec2_z); // partial for normalize for (i=0; i<3; i++) { vec1[0] = v1[i]-v0[i]; // VectorNormalize(vec1); tmp = (vec1[0] * vec1[0]) + vec1_nrml; tmp = sqrt(tmp); if ( tmp > 0.0 ) { tmp = 1.0 / tmp; vec1[0] *= tmp; vec1[1] = vec1_y * tmp; vec1[2] = vec1_z * tmp; } vec2[0] = v2[i]-v0[i]; // --- VectorNormalize(vec2); tmp = (vec2[0] * vec2[0]) + vec2_nrml; tmp = sqrt(tmp); if ( tmp > 0.0 ) { tmp = 1.0 / tmp; vec2[0] *= tmp; vec2[1] = vec2_y * tmp; vec2[2] = vec2_z * tmp; } // --- CrossProduct(vec1,vec2,planes[i]); planes[i][0] = vec1[1]*vec2[2] - vec1[2]*vec2[1]; planes[i][1] = vec1[2]*vec2[0] - vec1[0]*vec2[2]; planes[i][2] = vec1[0]*vec2[1] - vec1[1]*vec2[0]; // --- tmp = 1.0 / planes[i][0]; Tangent[i] = -planes[i][1]*tmp; } VectorNormalize(Tangent); } #endif /* ================= Mod_LoadMD2Model ================= */ void Mod_LoadMD2Model (model_t *mod, void *buffer) { int i, j, k, l; dmdl_t *pinmodel, *pheader, *paliashdr; dstvert_t *pinst, *poutst; dtriangle_t *pintri, *pouttri, *tris; daliasframe_t *pinframe, *poutframe, *pframe; int *pincmd, *poutcmd; int version; int cx; float s, t; float iw, ih; fstvert_t *st; daliasframe_t *frame; dtrivertx_t *verts; byte *tangents; vec3_t tangents_[MAX_VERTS]; char *pstring; int count; image_t *image; pinmodel = (dmdl_t *)buffer; version = LittleLong (pinmodel->version); if (version != ALIAS_VERSION) Com_Printf("%s has wrong version number (%i should be %i)", mod->name, version, ALIAS_VERSION); pheader = Hunk_Alloc (LittleLong(pinmodel->ofs_end)); // byte swap the header fields and sanity check for (i=0 ; iskinheight > MAX_LBM_HEIGHT) Com_Printf("model %s has a skin taller than %d", mod->name, MAX_LBM_HEIGHT); if (pheader->num_xyz <= 0) Com_Printf("model %s has no vertices", mod->name); if (pheader->num_xyz > MAX_VERTS) Com_Printf("model %s has too many vertices", mod->name); if (pheader->num_st <= 0) Com_Printf("model %s has no st vertices", mod->name); if (pheader->num_tris <= 0) Com_Printf("model %s has no triangles", mod->name); if (pheader->num_frames <= 0) Com_Printf("model %s has no frames", mod->name); // // load base s and t vertices // pinst = (dstvert_t *) ((byte *)pinmodel + pheader->ofs_st); poutst = (dstvert_t *) ((byte *)pheader + pheader->ofs_st); for (i=0 ; inum_st ; i++) { poutst[i].s = LittleShort (pinst[i].s); poutst[i].t = LittleShort (pinst[i].t); } // // load triangle lists // pintri = (dtriangle_t *) ((byte *)pinmodel + pheader->ofs_tris); pouttri = (dtriangle_t *) ((byte *)pheader + pheader->ofs_tris); for (i=0 ; inum_tris ; i++) { for (j=0 ; j<3 ; j++) { pouttri[i].index_xyz[j] = LittleShort (pintri[i].index_xyz[j]); pouttri[i].index_st[j] = LittleShort (pintri[i].index_st[j]); } } // // find neighbours // mod->neighbors = Hunk_Alloc(pheader->num_tris * sizeof(neighbors_t)); MD2_BuildTriangleNeighbors(mod->neighbors, pouttri, pheader->num_tris); // // load the frames // for (i=0 ; inum_frames ; i++) { pinframe = (daliasframe_t *) ((byte *)pinmodel + pheader->ofs_frames + i * pheader->framesize); poutframe = (daliasframe_t *) ((byte *)pheader + pheader->ofs_frames + i * pheader->framesize); memcpy (poutframe->name, pinframe->name, sizeof(poutframe->name)); for (j=0 ; j<3 ; j++) { poutframe->scale[j] = LittleFloat (pinframe->scale[j]); poutframe->translate[j] = LittleFloat (pinframe->translate[j]); } // verts are all 8 bit, so no swapping needed memcpy (poutframe->verts, pinframe->verts, pheader->num_xyz*sizeof(dtrivertx_t)); } mod->type = mod_alias; mod->num_frames = pheader->num_frames; // // load the glcmds // pincmd = (int *) ((byte *)pinmodel + pheader->ofs_glcmds); poutcmd = (int *) ((byte *)pheader + pheader->ofs_glcmds); for (i=0 ; inum_glcmds ; i++) poutcmd[i] = LittleLong (pincmd[i]); // skin names are not always valid or file may not exist // do not register skins that cannot be found to eliminate extraneous // file system searching. pstring = &((char*)pheader)[ pheader->ofs_skins ]; count = pheader->num_skins; if ( count ) { // someday .md2's that do not have skins may have zero for num_skins memcpy( pstring, (char *)pinmodel + pheader->ofs_skins, count*MAX_SKINNAME ); i = 0; while ( count-- ) { pstring[MAX_SKINNAME-1] = '\0'; // paranoid image = GL_FindImage( pstring, it_skin); if ( image != NULL ) mod->skins[i++] = image; else pheader->num_skins--; // the important part: adjust skin count pstring += MAX_SKINNAME; } // load script if (mod->skins[0] != NULL) mod->script = mod->skins[0]->script; if (mod->script) RS_ReadyScript( mod->script ); } cx = pheader->num_st * sizeof(fstvert_t); mod->st = st = (fstvert_t*)Hunk_Alloc (cx); // Calculate texcoords for triangles iw = 1.0 / pheader->skinwidth; ih = 1.0 / pheader->skinheight; for (i=0; inum_st ; i++) { s = poutst[i].s; t = poutst[i].t; st[i].s = (s + 1.0) * iw; //tweak by one pixel st[i].t = (t + 1.0) * ih; } MD2_LoadVertexArrays(mod); MD2_RecalcVertsLightNormalIdx(pheader); cx = pheader->num_xyz * pheader->num_frames * sizeof(byte); // Calculate tangents mod->tangents = tangents = (byte*)Hunk_Alloc (cx); tris = (dtriangle_t *) ((byte *)pheader + pheader->ofs_tris); //for all frames for (i=0; inum_frames; i++) { //set temp to zero memset(tangents_, 0, pheader->num_xyz*sizeof(vec3_t)); frame = (daliasframe_t *)((byte *)pheader + pheader->ofs_frames + i * pheader->framesize); verts = frame->verts; //for all tris for (j=0; jnum_tris; j++) { vec3_t vv0,vv1,vv2; vec3_t tangent; vv0[0] = (float)verts[tris[j].index_xyz[0]].v[0]; vv0[1] = (float)verts[tris[j].index_xyz[0]].v[1]; vv0[2] = (float)verts[tris[j].index_xyz[0]].v[2]; vv1[0] = (float)verts[tris[j].index_xyz[1]].v[0]; vv1[1] = (float)verts[tris[j].index_xyz[1]].v[1]; vv1[2] = (float)verts[tris[j].index_xyz[1]].v[2]; vv2[0] = (float)verts[tris[j].index_xyz[2]].v[0]; vv2[1] = (float)verts[tris[j].index_xyz[2]].v[1]; vv2[2] = (float)verts[tris[j].index_xyz[2]].v[2]; MD2_VecsForTris(vv0, vv1, vv2, &st[tris[j].index_st[0]].s, &st[tris[j].index_st[1]].s, &st[tris[j].index_st[2]].s, tangent); for (k=0; k<3; k++) { l = tris[j].index_xyz[k]; VectorAdd(tangents_[l], tangent, tangents_[l]); } } for (j=0; jnum_xyz; j++) for (k=j+1; knum_xyz; k++) if(verts[j].v[0] == verts[k].v[0] && verts[j].v[1] == verts[k].v[1] && verts[j].v[2] == verts[k].v[2]) { float *jnormal = r_avertexnormals[verts[j].lightnormalindex]; float *knormal = r_avertexnormals[verts[k].lightnormalindex]; // if(DotProduct(jnormal, knormal)>=cos(DEG2RAD(45))) if( DotProduct(jnormal, knormal) >= 0.707106781187 ) // cos of 45 degrees. { VectorAdd(tangents_[j], tangents_[k], tangents_[j]); VectorCopy(tangents_[j], tangents_[k]); } } //normalize averages for (j=0; jnum_xyz; j++) { VectorNormalize(tangents_[j]); tangents[i * pheader->num_xyz + j] = MD2_Normal2Index(tangents_[j]); } } mod->num_triangles = pheader->num_tris; paliashdr = (dmdl_t *)mod->extradata; //redo this using max/min from all frames pframe = ( daliasframe_t * ) ( ( byte * ) paliashdr + paliashdr->ofs_frames); /* ** compute axially aligned mins and maxs */ for ( i = 0; i < 3; i++ ) { mod->mins[i] = pframe->translate[i]; mod->maxs[i] = mod->mins[i] + pframe->scale[i]*255; } /* ** compute a full bounding box */ for ( i = 0; i < 8; i++ ) { vec3_t tmp; if ( i & 1 ) tmp[0] = mod->mins[0]; else tmp[0] = mod->maxs[0]; if ( i & 2 ) tmp[1] = mod->mins[1]; else tmp[1] = mod->maxs[1]; if ( i & 4 ) tmp[2] = mod->mins[2]; else tmp[2] = mod->maxs[2]; VectorCopy( tmp, mod->bbox[i] ); } } //============================================================== //Rendering functions /* ============= MD2_VlightModel Vertex lighting for Alias models Contrast has been added by finding a threshold point, and scaling values on either side in opposite directions. This gives the shading a more prounounced, defined look. ============= */ #if 0 void MD2_VlightModel (vec3_t baselight, dtrivertx_t *verts, vec3_t lightOut) { int i; float l; l = shadedots[verts->lightnormalindex]; VectorScale(baselight, l, lightOut); for (i=0; i<3; i++) { //add contrast - lights lighter, darks darker lightOut[i] += (lightOut[i] - 0.25); //keep values sane if (lightOut[i]<0) lightOut[i] = 0; if (lightOut[i]>1) lightOut[i] = 1; } } #else /* Profiling shows this is a "hotspot". Calculation rearranged. * Leave original above for reference. */ void MD2_VlightModel( const vec3_t baselight, dtrivertx_t *verts, vec3_t lightOut ) { float l; float c; l = shadedots[verts->lightnormalindex]; c = baselight[0] * l; c += ( c - 0.25 ); // [0,1] => [-0.25,1.75], then clamp to [0,1] c = c < 0.0f ? 0.0f : ( c > 1.0f ? 1.0f : c ); lightOut[0] = c; c = baselight[1] * l; c += ( c - 0.25 ); c = c < 0.0f ? 0.0f : ( c > 1.0f ? 1.0f : c ); lightOut[1] = c; c = baselight[2] * l; c += ( c - 0.25 ); c = c < 0.0f ? 0.0f : ( c > 1.0f ? 1.0f : c ); lightOut[2] = c; } #endif //This routine bascially finds the average light position, by factoring in all lights and //accounting for their distance, visiblity, and intensity. void R_GetLightVals(vec3_t meshOrigin, qboolean RagDoll) { int i, j, lnum; dlight_t *dl; float dist; vec3_t temp, tempOrg, lightAdd; trace_t r_trace; vec3_t mins, maxs; float numlights, nonweighted_numlights, weight; float bob; qboolean copy; VectorSet(mins, 0, 0, 0); VectorSet(maxs, 0, 0, 0); //light shining down if there are no lights at all VectorCopy(meshOrigin, lightPosition); lightPosition[2] += 128; if((currententity->flags & RF_BOBBING) && !RagDoll) bob = currententity->bob; else bob = 0; VectorCopy(meshOrigin, tempOrg); tempOrg[2] += 24 - bob; //generates more consistent tracing numlights = nonweighted_numlights = 0; VectorClear(lightAdd); statLightIntensity = 0.0; if (!RagDoll) { copy = cl_persistent_ents[currententity->number].setlightstuff; for (i = 0; i < 3; i++) { if (fabs(meshOrigin[i] - cl_persistent_ents[currententity->number].oldorigin[i]) > 0.0001) { copy = false; break; } } } else { copy = false; } if (copy) { numlights = cl_persistent_ents[currententity->number].oldnumlights; VectorCopy ( cl_persistent_ents[currententity->number].oldlightadd, lightAdd); statLightIntensity = cl_persistent_ents[currententity->number].oldlightintens; } else { for (i=0; iflags & RF_WEAPONMODEL) && (LightGroups[i].group_origin[2] > meshOrigin[2])) { r_trace.fraction = 1.0; //don't do traces for lights above weapon models, not smooth enough } else { if (CM_inPVS (tempOrg, LightGroups[i].group_origin)) r_trace = CM_BoxTrace(tempOrg, LightGroups[i].group_origin, mins, maxs, r_worldmodel->firstnode, MASK_OPAQUE); else r_trace.fraction = 0.0; } if(r_trace.fraction == 1.0) { VectorSubtract(meshOrigin, LightGroups[i].group_origin, temp); dist = VectorLength(temp); if(dist == 0) dist = 1; dist = dist*dist; weight = (int)250000/(dist/(LightGroups[i].avg_intensity+1.0f)); for(j = 0; j < 3; j++) { lightAdd[j] += LightGroups[i].group_origin[j]*weight; } statLightIntensity += LightGroups[i].avg_intensity; numlights+=weight; nonweighted_numlights++; } } if (numlights > 0.0) statLightIntensity /= (float)nonweighted_numlights; cl_persistent_ents[currententity->number].oldnumlights = numlights; VectorCopy (lightAdd, cl_persistent_ents[currententity->number].oldlightadd); cl_persistent_ents[currententity->number].setlightstuff = true; VectorCopy (currententity->origin, cl_persistent_ents[currententity->number].oldorigin); cl_persistent_ents[currententity->number].oldlightintens = statLightIntensity; } if(numlights > 0.0) { for(i = 0; i < 3; i++) { statLightPosition[i] = lightAdd[i]/numlights; } } dynFactor = 0; if(gl_dynamic->integer != 0) { dl = r_newrefdef.dlights; //limit to five lights(maybe less)? for (lnum=0; lnum<(r_newrefdef.num_dlights > 5 ? 5: r_newrefdef.num_dlights); lnum++, dl++) { VectorSubtract(meshOrigin, dl->origin, temp); dist = VectorLength(temp); VectorCopy(meshOrigin, temp); temp[2] += 24; //generates more consistent tracing r_trace = CM_BoxTrace(temp, dl->origin, mins, maxs, r_worldmodel->firstnode, MASK_OPAQUE); if(r_trace.fraction == 1.0) { if(dist < dl->intensity) { //make dynamic lights more influential than world for(j = 0; j < 3; j++) lightAdd[j] += dl->origin[j]*10*dl->intensity; numlights+=10*dl->intensity; VectorSubtract (dl->origin, meshOrigin, temp); dynFactor += (dl->intensity/20.0)/VectorLength(temp); } } } } if(numlights > 0.0) { for(i = 0; i < 3; i++) lightPosition[i] = lightAdd[i]/numlights; } } void R_ModelViewTransform(const vec3_t in, vec3_t out){ const float *v = in; const float *m = r_world_matrix; out[0] = m[0] * v[0] + m[4] * v[1] + m[8] * v[2] + m[12]; out[1] = m[1] * v[0] + m[5] * v[1] + m[9] * v[2] + m[13]; out[2] = m[2] * v[0] + m[6] * v[1] + m[10] * v[2] + m[14]; } /* ** MD2_CullModel */ static qboolean MD2_CullModel( vec3_t bbox[8] ) { int i; vec3_t vectors[3]; vec3_t angles; trace_t r_trace; vec3_t dist; if (r_worldmodel ) { //occulusion culling - why draw entities we cannot see? r_trace = CM_BoxTrace(r_origin, currententity->origin, currentmodel->maxs, currentmodel->mins, r_worldmodel->firstnode, MASK_OPAQUE); if(r_trace.fraction != 1.0) return true; } VectorSubtract(r_origin, currententity->origin, dist); /* ** rotate the bounding box */ VectorCopy( currententity->angles, angles ); angles[YAW] = -angles[YAW]; AngleVectors( angles, vectors[0], vectors[1], vectors[2] ); for ( i = 0; i < 8; i++ ) { vec3_t tmp; VectorCopy( currentmodel->bbox[i], tmp ); bbox[i][0] = DotProduct( vectors[0], tmp ); bbox[i][1] = -DotProduct( vectors[1], tmp ); bbox[i][2] = DotProduct( vectors[2], tmp ); VectorAdd( currententity->origin, bbox[i], bbox[i] ); } { int p, f, aggregatemask = ~0; for ( p = 0; p < 8; p++ ) { int mask = 0; for ( f = 0; f < 4; f++ ) { float dp = DotProduct( frustum[f].normal, bbox[p] ); if ( ( dp - frustum[f].dist ) < 0 ) { mask |= ( 1 << f ); } } aggregatemask &= mask; } if ( aggregatemask && (VectorLength(dist) > 150)) //so shadows don't blatantly disappear when out of frustom { return true; } return false; } } void MD2_LerpSelfShadowVerts( int nverts, dtrivertx_t *v, dtrivertx_t *ov, float *lerp, float move[3], float frontv[3], float backv[3] ) { int i; for (i=0 ; i < nverts; i++, v++, ov++, lerp+=4) { lerp[0] = move[0] + ov->v[0]*backv[0] + v->v[0]*frontv[0]; lerp[1] = move[1] + ov->v[1]*backv[1] + v->v[1]*frontv[1]; lerp[2] = move[2] + ov->v[2]*backv[2] + v->v[2]*frontv[2]; } } void R_Mesh_SetupShell (int shell_skinnum, qboolean ragdoll, qboolean using_varray, vec3_t lightcolor) { int i; //shell render if(gl_glsl_shaders->integer && gl_state.glsl_shaders && gl_normalmaps->integer) { vec3_t lightVec, lightVal; if(using_varray) { R_InitVArrays (VERT_NORMAL_COLOURED_TEXTURED); qglNormalPointer(GL_FLOAT, 0, NormalsArray); glEnableVertexAttribArrayARB (1); glVertexAttribPointerARB(1, 4, GL_FLOAT,GL_FALSE, 0, TangentsArray); } //send light level and color to shader, ramp up a bit VectorCopy(lightcolor, lightVal); for(i = 0; i < 3; i++) { if(lightVal[i] < shadelight[i]/2) lightVal[i] = shadelight[i]/2; //never go completely black lightVal[i] *= 5; lightVal[i] += dynFactor; if(lightVal[i] > 1.0+dynFactor) lightVal[i] = 1.0+dynFactor; } //brighten things slightly for (i = 0; i < 3; i++ ) lightVal[i] *= (ragdoll?1.25:2.5); //simple directional(relative light position) VectorSubtract(lightPosition, currententity->origin, lightVec); VectorMA(lightPosition, 1.0, lightVec, lightPosition); R_ModelViewTransform(lightPosition, lightVec); GL_EnableMultitexture( true ); if (ragdoll) qglDepthMask(false); glUseProgramObjectARB( g_meshprogramObj ); glUniform3fARB( g_location_meshlightPosition, lightVec[0], lightVec[1], lightVec[2]); KillFlags |= (KILL_TMU0_POINTER | KILL_TMU1_POINTER); GL_SelectTexture( GL_TEXTURE1); GL_Bind (r_shelltexture2->texnum); glUniform1iARB( g_location_baseTex, 1); GL_SelectTexture( GL_TEXTURE0); GL_Bind (r_shellnormal->texnum); glUniform1iARB( g_location_normTex, 0); glUniform1iARB( g_location_useFX, 0); glUniform1iARB( g_location_useGlow, 0); glUniform1iARB( g_location_useCube, 0); glUniform1iARB( g_location_useShell, 1); glUniform3fARB( g_location_color, lightVal[0], lightVal[1], lightVal[2]); glUniform1fARB( g_location_meshTime, rs_realtime); glUniform1iARB( g_location_meshFog, map_fog); glUniform1iARB(g_location_useGPUanim, 0); } else { GL_Bind(shell_skinnum); R_InitVArrays (VERT_COLOURED_TEXTURED); } } void R_Mesh_SetupGLSL (int skinnum, rscript_t *rs, vec3_t lightcolor) { int i; //render with shaders - assume correct single pass glsl shader struct(let's put some checks in for this) vec3_t lightVec, lightVal; GLSTATE_ENABLE_ALPHATEST //send light level and color to shader, ramp up a bit VectorCopy(lightcolor, lightVal); for(i = 0; i < 3; i++) { if(lightVal[i] < shadelight[i]/2) lightVal[i] = shadelight[i]/2; //never go completely black lightVal[i] *= 5; lightVal[i] += dynFactor; if(r_newrefdef.rdflags & RDF_NOWORLDMODEL) { if(lightVal[i] > 1.5) lightVal[i] = 1.5; } else { if(lightVal[i] > 1.0+dynFactor) lightVal[i] = 1.0+dynFactor; } } if(r_newrefdef.rdflags & RDF_NOWORLDMODEL) //menu model { //fixed light source pointing down, slightly forward and to the left lightPosition[0] = -25.0; lightPosition[1] = 300.0; lightPosition[2] = 400.0; VectorMA(lightPosition, 5.0, lightVec, lightPosition); R_ModelViewTransform(lightPosition, lightVec); for (i = 0; i < 3; i++ ) { lightVal[i] = 1.1; } } else { //simple directional(relative light position) VectorSubtract(lightPosition, currententity->origin, lightVec); VectorMA(lightPosition, 5.0, lightVec, lightPosition); R_ModelViewTransform(lightPosition, lightVec); //brighten things slightly for (i = 0; i < 3; i++ ) { lightVal[i] *= 1.05; } } GL_EnableMultitexture( true ); glUseProgramObjectARB( g_meshprogramObj ); glUniform3fARB( g_location_meshlightPosition, lightVec[0], lightVec[1], lightVec[2]); glUniform3fARB( g_location_color, lightVal[0], lightVal[1], lightVal[2]); KillFlags |= (KILL_TMU0_POINTER | KILL_TMU1_POINTER | KILL_TMU2_POINTER); GL_SelectTexture( GL_TEXTURE1); GL_Bind (skinnum); glUniform1iARB( g_location_baseTex, 1); GL_SelectTexture( GL_TEXTURE0); GL_Bind (rs->stage->texture->texnum); glUniform1iARB( g_location_normTex, 0); GL_SelectTexture( GL_TEXTURE2); GL_Bind (rs->stage->texture2->texnum); glUniform1iARB( g_location_fxTex, 2); qglActiveTextureARB(GL_TEXTURE3); GL_Bind (rs->stage->texture3->texnum); glUniform1iARB( g_location_fx2Tex, 3); GL_SelectTexture( GL_TEXTURE0); if(rs->stage->fx) glUniform1iARB( g_location_useFX, 1); else glUniform1iARB( g_location_useFX, 0); if(rs->stage->glow) glUniform1iARB( g_location_useGlow, 1); else glUniform1iARB( g_location_useGlow, 0); glUniform1iARB( g_location_useShell, 0); if(rs->stage->cube) { glUniform1iARB( g_location_useCube, 1); if(currententity->flags & RF_WEAPONMODEL) glUniform1iARB( g_location_fromView, 1); else glUniform1iARB( g_location_fromView, 0); } else glUniform1iARB( g_location_useCube, 0); glUniform1fARB( g_location_meshTime, rs_realtime); glUniform1iARB( g_location_meshFog, map_fog); } /* ============= MD2_DrawFrame - standard md2 rendering ============= */ void MD2_DrawFrame (dmdl_t *paliashdr, float backlerp, qboolean lerped, int skinnum) { daliasframe_t *frame, *oldframe=NULL; dtrivertx_t *v, *ov=NULL, *verts; dtriangle_t *tris; float frontlerp; float alpha, basealpha; vec3_t move, delta, vectors[3]; vec3_t frontv, backv; int i, j; int index_xyz, index_st; rscript_t *rs = NULL; int va = 0; float shellscale; vec3_t lightcolor; fstvert_t *st; float os, ot, os2, ot2; unsigned offs, offs2; byte *tangents, *oldtangents = NULL; qboolean mirror = false; qboolean glass = false; offs = paliashdr->num_xyz; if(lerped) frame = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames + currententity->frame * paliashdr->framesize); else frame = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames); verts = v = frame->verts; offs2 = offs*currententity->frame; tangents = currentmodel->tangents + offs2; if(lerped) { oldframe = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames + currententity->oldframe * paliashdr->framesize); ov = oldframe->verts; offs2 = offs*currententity->oldframe; oldtangents = currentmodel->tangents + offs2; } tris = (dtriangle_t *) ((byte *)paliashdr + paliashdr->ofs_tris); st = currentmodel->st; if (r_shaders->integer) rs=(rscript_t *)currententity->script; VectorCopy(shadelight, lightcolor); for (i=0;iflags & RF_TRANSLUCENT) { basealpha = alpha = currententity->alpha; if(rs_glass) rs=(rscript_t *)rs_glass; if(!rs) GL_Bind(r_reflecttexture->texnum); else if (!(r_newrefdef.rdflags & RDF_NOWORLDMODEL)) { if(gl_mirror->integer) mirror = true; else glass = true; } } else basealpha = alpha = 1.0; if(lerped) { frontlerp = 1.0 - backlerp; // move should be the delta back to the previous frame * backlerp VectorSubtract (currententity->oldorigin, currententity->origin, delta); } AngleVectors (currententity->angles, vectors[0], vectors[1], vectors[2]); if(lerped) { move[0] = DotProduct (delta, vectors[0]); // forward move[1] = -DotProduct (delta, vectors[1]); // left move[2] = DotProduct (delta, vectors[2]); // up VectorAdd (move, oldframe->translate, move); for (i=0 ; i<3 ; i++) { move[i] = backlerp*move[i] + frontlerp*frame->translate[i]; frontv[i] = frontlerp*frame->scale[i]; backv[i] = backlerp*oldframe->scale[i]; } if(currententity->flags & RF_VIEWERMODEL) { float *lerp; //lerp the vertices for self shadows, and leave if(gl_shadowmaps->integer) { lerp = s_lerped[0]; MD2_LerpSelfShadowVerts( paliashdr->num_xyz, v, ov, lerp, move, frontv, backv); return; } else return; } } if(( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) ) ) { R_Mesh_SetupShell (r_shelltexture->texnum, false, true, lightcolor); qglColor4f( shadelight[0], shadelight[1], shadelight[2], alpha); VArray = &VArrayVerts[0]; if (alpha < 0.0) alpha = 0.0; else if (alpha > 1.0) alpha = 1.0; for (i=0; inum_tris; i++) { for (j=0; j<3; j++) { vec3_t normal; vec4_t tangent; int k; index_xyz = tris[i].index_xyz[j]; index_st = tris[i].index_st[j]; if((currententity->flags & (RF_WEAPONMODEL | RF_SHELL_GREEN)) || (gl_glsl_shaders->integer && gl_state.glsl_shaders && gl_normalmaps->integer)) shellscale = .4; else shellscale = 1.6; if(lerped) { VArray[0] = s_lerped[index_xyz][0] = move[0] + ov[index_xyz].v[0]*backv[0] + v[index_xyz].v[0]*frontv[0] + r_avertexnormals[verts[index_xyz].lightnormalindex][0] * shellscale; VArray[1] = s_lerped[index_xyz][1] = move[1] + ov[index_xyz].v[1]*backv[1] + v[index_xyz].v[1]*frontv[1] + r_avertexnormals[verts[index_xyz].lightnormalindex][1] * shellscale; VArray[2] = s_lerped[index_xyz][2] = move[2] + ov[index_xyz].v[2]*backv[2] + v[index_xyz].v[2]*frontv[2] + r_avertexnormals[verts[index_xyz].lightnormalindex][2] * shellscale; VArray[3] = (s_lerped[index_xyz][1] + s_lerped[index_xyz][0]) * (1.0f / 40.0f); VArray[4] = s_lerped[index_xyz][2] * (1.0f / 40.0f) - r_newrefdef.time * 0.5f; if(gl_glsl_shaders->integer && gl_state.glsl_shaders && gl_normalmaps->integer) { for (k=0; k<3; k++) { normal[k] = r_avertexnormals[verts[index_xyz].lightnormalindex][k] + ( r_avertexnormals[ov[index_xyz].lightnormalindex][k] - r_avertexnormals[verts[index_xyz].lightnormalindex][k] ) * backlerp; tangent[k] = r_avertexnormals[tangents[index_xyz]][k] + ( r_avertexnormals[oldtangents[index_xyz]][k] - r_avertexnormals[tangents[index_xyz]][k] ) * backlerp; } } else { VArray[5] = shadelight[0]; VArray[6] = shadelight[1]; VArray[7] = shadelight[2]; VArray[8] = alpha; } } else { VArray[0] = currentmodel->vertexes[index_xyz].position[0]; VArray[1] = currentmodel->vertexes[index_xyz].position[1]; VArray[2] = currentmodel->vertexes[index_xyz].position[2]; VArray[3] = (currentmodel->vertexes[index_xyz].position[1] + currentmodel->vertexes[index_xyz].position[0]) * (1.0f / 40.0f); VArray[4] = currentmodel->vertexes[index_xyz].position[2] * (1.0f / 40.0f) - r_newrefdef.time * 0.5f; if(gl_glsl_shaders->integer && gl_state.glsl_shaders && gl_normalmaps->integer) { for (k=0;k<3;k++) { normal[k] = r_avertexnormals[verts[index_xyz].lightnormalindex][k]; tangent[k] = r_avertexnormals[tangents[index_xyz]][k]; } } else { VArray[5] = shadelight[0]; VArray[6] = shadelight[1]; VArray[7] = shadelight[2]; VArray[8] = alpha; } } tangent[3] = 1.0; if(gl_glsl_shaders->integer && gl_state.glsl_shaders && gl_normalmaps->integer) { VectorNormalize ( normal ); VectorCopy(normal, NormalsArray[va]); //shader needs normal array Vector4Copy(tangent, TangentsArray[va]); } // increment pointer and counter if(gl_glsl_shaders->integer && gl_state.glsl_shaders && gl_normalmaps->integer) VArray += VertexSizes[VERT_NORMAL_COLOURED_TEXTURED]; else VArray += VertexSizes[VERT_COLOURED_TEXTURED]; va++; } } if (!(!cl_gun->integer && ( currententity->flags & RF_WEAPONMODEL ) ) ) { R_DrawVarrays(GL_TRIANGLES, 0, va); } if(gl_glsl_shaders->integer && gl_state.glsl_shaders && gl_normalmaps->integer) { glUseProgramObjectARB( 0 ); GL_EnableMultitexture( false ); } } else if(mirror || glass) { qboolean mirror_noweap; int vertsize = VertexSizes[VERT_COLOURED_TEXTURED]; mirror_noweap = mirror && !(currententity->flags & RF_WEAPONMODEL); qglDepthMask(false); if(mirror) { if( !(currententity->flags & RF_WEAPONMODEL)) { R_InitVArrays(VERT_COLOURED_MULTI_TEXTURED); vertsize = VertexSizes[VERT_COLOURED_MULTI_TEXTURED]; GL_EnableMultitexture( true ); GL_SelectTexture( GL_TEXTURE0); GL_TexEnv ( GL_COMBINE_EXT ); GL_Bind (r_mirrortexture->texnum); qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE ); GL_SelectTexture( GL_TEXTURE1); GL_TexEnv ( GL_COMBINE_EXT ); GL_Bind (r_mirrorspec->texnum); qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT ); } else { R_InitVArrays (VERT_COLOURED_TEXTURED); GL_SelectTexture( GL_TEXTURE0); GL_Bind (r_mirrortexture->texnum); } } else { R_InitVArrays (VERT_COLOURED_TEXTURED); GL_SelectTexture( GL_TEXTURE0); GL_Bind (r_reflecttexture->texnum); } if (mirror) { rs->stage->scale.scaleX = -1.0; rs->stage->scale.scaleY = 1.0; } else { rs->stage->scale.scaleX = rs->stage->scale.scaleY = 0.5; } for (i=0; inum_tris; i++) { for (j=0; j<3; j++) { vec3_t normal; int k; index_xyz = tris[i].index_xyz[j]; index_st = tris[i].index_st[j]; os = os2 = st[index_st].s; ot = ot2 = st[index_st].t; if(lerped) { VArray[0] = s_lerped[index_xyz][0] = move[0] + ov[index_xyz].v[0]*backv[0] + v[index_xyz].v[0]*frontv[0]; VArray[1] = s_lerped[index_xyz][1] = move[1] + ov[index_xyz].v[1]*backv[1] + v[index_xyz].v[1]*frontv[1]; VArray[2] = s_lerped[index_xyz][2] = move[2] + ov[index_xyz].v[2]*backv[2] + v[index_xyz].v[2]*frontv[2]; for (k=0; k<3; k++) { normal[k] = r_avertexnormals[verts[index_xyz].lightnormalindex][k] + ( r_avertexnormals[ov[index_xyz].lightnormalindex][k] - r_avertexnormals[verts[index_xyz].lightnormalindex][k] ) * backlerp; } // we can safely assume that the contents of // r_avertexnormals need not be converted to unit // vectors, however lerped normals may require this. VectorNormalize ( normal ); } else { VArray[0] = currentmodel->vertexes[index_xyz].position[0]; VArray[1] = currentmodel->vertexes[index_xyz].position[1]; VArray[2] = currentmodel->vertexes[index_xyz].position[2]; for (k=0;k<3;k++) { normal[k] = r_avertexnormals[verts[index_xyz].lightnormalindex][k]; } } if (!mirror || mirror_noweap) { os -= DotProduct (normal, vectors[1]); ot += DotProduct (normal, vectors[2]); } RS_SetTexcoords2D(rs->stage, &os, &ot); VArray[3] = os; VArray[4] = ot; if(mirror_noweap) { os2 -= DotProduct (normal, vectors[1] ); ot2 += DotProduct (normal, vectors[2] ); RS_SetTexcoords2D(rs->stage, &os2, &ot2); VArray[5] = os2; VArray[6] = ot2; VArray[7] = VArray[8] = VArray[9] = 1; VArray[10] = alpha; } else { VArray[5] = VArray[6] = VArray[7] = 1; VArray[8] = alpha; } // increment pointer and counter VArray += vertsize; va++; } } if (!(!cl_gun->integer && ( currententity->flags & RF_WEAPONMODEL ))) { R_DrawVarrays(GL_TRIANGLES, 0, paliashdr->num_tris*3); } if(mirror && !(currententity->flags & RF_WEAPONMODEL)) GL_EnableMultitexture( false ); qglDepthMask(true); } else if(rs && rs->stage->normalmap && gl_normalmaps->integer && gl_glsl_shaders->integer && gl_state.glsl_shaders) { qboolean dovbo; dovbo = gl_state.vbo && !lerped; if(rs->stage->depthhack) qglDepthMask(false); R_Mesh_SetupGLSL (skinnum, rs, lightcolor); if(dovbo) { KillFlags |= (KILL_TMU0_POINTER | KILL_TMU1_POINTER | KILL_TMU2_POINTER | KILL_TMU3_POINTER | KILL_NORMAL_POINTER); } else { R_InitVArrays (VERT_NORMAL_COLOURED_TEXTURED); qglNormalPointer(GL_FLOAT, 0, NormalsArray); glEnableVertexAttribArrayARB (1); glVertexAttribPointerARB(1, 4, GL_FLOAT, GL_FALSE, 0, TangentsArray); KillFlags |= (KILL_TMU0_POINTER | KILL_TMU1_POINTER | KILL_TMU2_POINTER | KILL_TMU3_POINTER | KILL_NORMAL_POINTER); //needed to kill all of these texture units } glUniform1iARB(g_location_useGPUanim, 0); if (dovbo) { vbo_xyz = R_VCFindCache(VBO_STORE_XYZ, currentmodel); vbo_st = R_VCFindCache(VBO_STORE_ST, currentmodel); vbo_normals = R_VCFindCache(VBO_STORE_NORMAL, currentmodel); vbo_tangents = R_VCFindCache(VBO_STORE_TANGENT, currentmodel); if(vbo_xyz && vbo_st && vbo_normals && vbo_tangents) { goto skipLoad; } } for (i=0; inum_tris; i++) { for (j=0; j<3; j++) { vec3_t normal; vec4_t tangent; int k; index_xyz = tris[i].index_xyz[j]; index_st = tris[i].index_st[j]; os = os2 = st[index_st].s; ot = ot2 = st[index_st].t; if(lerped) { VArray[0] = s_lerped[index_xyz][0] = move[0] + ov[index_xyz].v[0]*backv[0] + v[index_xyz].v[0]*frontv[0]; VArray[1] = s_lerped[index_xyz][1] = move[1] + ov[index_xyz].v[1]*backv[1] + v[index_xyz].v[1]*frontv[1]; VArray[2] = s_lerped[index_xyz][2] = move[2] + ov[index_xyz].v[2]*backv[2] + v[index_xyz].v[2]*frontv[2]; for (k=0; k<3; k++) { normal[k] = r_avertexnormals[verts[index_xyz].lightnormalindex][k] + ( r_avertexnormals[ov[index_xyz].lightnormalindex][k] - r_avertexnormals[verts[index_xyz].lightnormalindex][k] ) * backlerp; tangent[k] = r_avertexnormals[tangents[index_xyz]][k] + ( r_avertexnormals[oldtangents[index_xyz]][k] - r_avertexnormals[tangents[index_xyz]][k] ) * backlerp; } // we can safely assume that the contents of // r_avertexnormals need not be converted to unit // vectors, however lerped normals may require this. VectorNormalize ( normal ); } else { VArray[0] = currentmodel->vertexes[index_xyz].position[0]; VArray[1] = currentmodel->vertexes[index_xyz].position[1]; VArray[2] = currentmodel->vertexes[index_xyz].position[2]; for (k=0;k<3;k++) { normal[k] = r_avertexnormals[verts[index_xyz].lightnormalindex][k]; tangent[k] = r_avertexnormals[tangents[index_xyz]][k]; } } tangent[3] = 1.0; VArray[3] = os; VArray[4] = ot; //send tangent to shader VectorCopy(normal, NormalsArray[va]); //shader needs normal array Vector4Copy(tangent, TangentsArray[va]); if (dovbo) { VertexArray[va][0] = VArray[0]; VertexArray[va][1] = VArray[1]; VertexArray[va][2] = VArray[2]; TexCoordArray[va][0] = VArray[3]; TexCoordArray[va][1] = VArray[4]; } // increment pointer and counter VArray += VertexSizes[VERT_NORMAL_COLOURED_TEXTURED]; va++; } } if(dovbo) { vbo_xyz = R_VCLoadData(VBO_STATIC, va*sizeof(vec3_t), VertexArray, VBO_STORE_XYZ, currentmodel); vbo_st = R_VCLoadData(VBO_STATIC, va*sizeof(vec2_t), TexCoordArray, VBO_STORE_ST, currentmodel); vbo_normals = R_VCLoadData(VBO_STATIC, va*sizeof(vec3_t), NormalsArray, VBO_STORE_NORMAL, currentmodel); vbo_tangents = R_VCLoadData(VBO_STATIC, va*sizeof(vec4_t), TangentsArray, VBO_STORE_TANGENT, currentmodel); } skipLoad: if(dovbo) { qglEnableClientState( GL_VERTEX_ARRAY ); GL_BindVBO(vbo_xyz); qglVertexPointer(3, GL_FLOAT, 0, 0); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); GL_BindVBO(vbo_st); qglTexCoordPointer(2, GL_FLOAT, 0, 0); qglEnableClientState( GL_NORMAL_ARRAY ); GL_BindVBO(vbo_normals); qglNormalPointer(GL_FLOAT, 0, 0); glEnableVertexAttribArrayARB (1); GL_BindVBO(vbo_tangents); glVertexAttribPointerARB(1, 4, GL_FLOAT, GL_FALSE, sizeof(vec4_t), 0); } if (!(!cl_gun->integer && ( currententity->flags & RF_WEAPONMODEL ))) R_DrawVarrays(GL_TRIANGLES, 0, paliashdr->num_tris*3); glUseProgramObjectARB( 0 ); GL_EnableMultitexture( false ); if(rs->stage->depthhack) qglDepthMask(true); } else //base render no shaders { va=0; VArray = &VArrayVerts[0]; alpha = basealpha; if (alpha < 0.0) alpha = 0.0; else if (alpha > 1.0) alpha = 1.0; R_InitVArrays (VERT_COLOURED_TEXTURED); GLSTATE_ENABLE_ALPHATEST for (i=0; inum_tris; i++) { for (j=0; j<3; j++) { index_xyz = tris[i].index_xyz[j]; index_st = tris[i].index_st[j]; if(lerped) { MD2_VlightModel (shadelight, &verts[index_xyz], lightcolor); VArray[0] = s_lerped[index_xyz][0] = move[0] + ov[index_xyz].v[0]*backv[0] + v[index_xyz].v[0]*frontv[0]; VArray[1] = s_lerped[index_xyz][1] = move[1] + ov[index_xyz].v[1]*backv[1] + v[index_xyz].v[1]*frontv[1]; VArray[2] = s_lerped[index_xyz][2] = move[2] + ov[index_xyz].v[2]*backv[2] + v[index_xyz].v[2]*frontv[2]; VArray[3] = st[index_st].s; VArray[4] = st[index_st].t; VArray[5] = lightcolor[0]; VArray[6] = lightcolor[1]; VArray[7] = lightcolor[2]; VArray[8] = alpha; } else { MD2_VlightModel (shadelight, &verts[index_xyz], lightcolor); VArray[0] = currentmodel->vertexes[index_xyz].position[0]; VArray[1] = currentmodel->vertexes[index_xyz].position[1]; VArray[2] = currentmodel->vertexes[index_xyz].position[2]; VArray[3] = st[index_st].s; VArray[4] = st[index_st].t; VArray[5] = lightcolor[0] > 0.2 ? lightcolor[0] : 0.2; VArray[6] = lightcolor[1] > 0.2 ? lightcolor[1] : 0.2; VArray[7] = lightcolor[2] > 0.2 ? lightcolor[2] : 0.2; VArray[8] = alpha; } // increment pointer and counter VArray += VertexSizes[VERT_COLOURED_TEXTURED]; va++; } } if (!(!cl_gun->integer && ( currententity->flags & RF_WEAPONMODEL ) ) ) { R_DrawVarrays(GL_TRIANGLES, 0, va); } } GLSTATE_DISABLE_ALPHATEST GLSTATE_DISABLE_BLEND GLSTATE_DISABLE_TEXGEN qglDisableClientState( GL_NORMAL_ARRAY); qglDisableClientState( GL_COLOR_ARRAY ); qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); glDisableVertexAttribArrayARB (1); R_KillVArrays (); if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM ) ) qglEnable( GL_TEXTURE_2D ); } /* ================= R_DrawAliasModel - render alias models(using MD2 format) ================= */ void R_DrawAliasModel ( void ) { int i; dmdl_t *paliashdr; vec3_t bbox[8]; image_t *skin; if((r_newrefdef.rdflags & RDF_NOWORLDMODEL ) && !(currententity->flags & RF_MENUMODEL)) return; if(currententity->team) //don't draw flag models, handled by sprites return; if ( !( currententity->flags & RF_WEAPONMODEL ) ) { if ( MD2_CullModel( bbox ) ) return; } else { if ( r_lefthand->integer == 2 ) return; } R_GetLightVals(currententity->origin, false); //R_GenerateEntityShadow(); //not using this for now, it's generally a bit slower than the stencil volumes at the moment when dealing with static meshes paliashdr = (dmdl_t *)currentmodel->extradata; // // get lighting information // if ( currententity->flags & ( RF_SHELL_HALF_DAM | RF_SHELL_GREEN | RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE) ) { if(!cl_gun->integer && (currententity->flags & RF_WEAPONMODEL)) return; VectorClear (shadelight); if (currententity->flags & RF_SHELL_HALF_DAM) { shadelight[0] = 0.56; shadelight[1] = 0.59; shadelight[2] = 0.45; } if ( currententity->flags & RF_SHELL_DOUBLE ) { shadelight[0] = 0.9; shadelight[1] = 0.7; } if ( currententity->flags & RF_SHELL_RED ) shadelight[0] = 1.0; if ( currententity->flags & RF_SHELL_GREEN ) { shadelight[1] = 1.0; shadelight[2] = 0.6; } if ( currententity->flags & RF_SHELL_BLUE ) { shadelight[2] = 1.0; shadelight[0] = 0.6; } } else if (currententity->flags & RF_FULLBRIGHT) { for (i=0 ; i<3 ; i++) shadelight[i] = 1.0; } else { R_LightPoint (currententity->origin, shadelight, true); } if ( currententity->flags & RF_MINLIGHT ) { float minlight; if(gl_glsl_shaders->integer && gl_state.glsl_shaders && gl_normalmaps->integer) minlight = 0.1; else minlight = 0.2; for (i=0 ; i<3 ; i++) if (shadelight[i] > minlight) break; if (i == 3) { shadelight[0] = minlight; shadelight[1] = minlight; shadelight[2] = minlight; } } if ( currententity->flags & RF_GLOW ) { // bonus items will pulse with time float scale; float minlight; scale = 0.2 * sin(r_newrefdef.time*7); if(gl_glsl_shaders->integer && gl_state.glsl_shaders && gl_normalmaps->integer) minlight = 0.1; else minlight = 0.2; for (i=0 ; i<3 ; i++) { shadelight[i] += scale; if (shadelight[i] < minlight) shadelight[i] = minlight; } } shadedots = r_avertexnormal_dots[((int)(currententity->angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)]; // // locate the proper data // if ( !(currententity->flags & RF_VIEWERMODEL) && !(currententity->flags & RF_WEAPONMODEL) ) { c_alias_polys += paliashdr->num_tris; /* for rspeed_epoly count */ } // // draw all the triangles // if (currententity->flags & RF_DEPTHHACK) // hack the depth range to prevent view model from poking into walls qglDepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin)); if ((currententity->flags & RF_WEAPONMODEL) && r_lefthand->integer != 2) { qglMatrixMode(GL_PROJECTION); qglPushMatrix(); qglLoadIdentity(); if (r_lefthand->integer == 1) { qglScalef(-1, 1, 1); qglCullFace(GL_BACK); } if(r_newrefdef.fov_y < 75.0f) MYgluPerspective(r_newrefdef.fov_y, (float)r_newrefdef.width / (float)r_newrefdef.height, 4.0f, 4096.0f); else MYgluPerspective(75.0f, (float)r_newrefdef.width / (float)r_newrefdef.height, 4.0f, 4096.0f); qglMatrixMode(GL_MODELVIEW); } qglPushMatrix (); currententity->angles[PITCH] = -currententity->angles[PITCH]; // sigh. R_RotateForEntity (currententity); currententity->angles[PITCH] = -currententity->angles[PITCH]; // sigh. // select skin if (currententity->skin) { skin = currententity->skin; // custom player skin } else { if (currententity->skinnum >= MAX_MD2SKINS) skin = currentmodel->skins[0]; else { skin = currentmodel->skins[currententity->skinnum]; if (!skin) skin = currentmodel->skins[0]; } } if (!skin) skin = r_notexture; // fallback... GL_Bind(skin->texnum); // draw it qglShadeModel (GL_SMOOTH); GL_TexEnv( GL_MODULATE ); if ( currententity->flags & ( RF_SHELL_HALF_DAM | RF_SHELL_GREEN | RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE ) ) qglEnable (GL_BLEND); else if ( currententity->flags & RF_TRANSLUCENT ) { qglEnable (GL_BLEND); qglBlendFunc (GL_ONE, GL_ONE); } if (currententity->flags & RF_CUSTOMSKIN) { qglTexGenf(GL_S, GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP); qglTexGenf(GL_T, GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP); qglEnable(GL_TEXTURE_GEN_S); qglEnable(GL_TEXTURE_GEN_T); qglBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } if ( (currententity->frame >= paliashdr->num_frames) || (currententity->frame < 0) ) { currententity->frame = 0; currententity->oldframe = 0; } if ( (currententity->oldframe >= paliashdr->num_frames) || (currententity->oldframe < 0)) { currententity->frame = 0; currententity->oldframe = 0; } if ( !r_lerpmodels->integer ) currententity->backlerp = 0; if(currententity->frame == 0 && currentmodel->num_frames == 1) { if(!(currententity->flags & RF_VIEWERMODEL)) MD2_DrawFrame(paliashdr, 0, false, skin->texnum); } else MD2_DrawFrame(paliashdr, currententity->backlerp, true, skin->texnum); GL_TexEnv( GL_REPLACE ); qglShadeModel (GL_FLAT); qglPopMatrix (); if ( ( currententity->flags & RF_WEAPONMODEL ) && ( r_lefthand->integer != 2 ) ) { qglMatrixMode( GL_PROJECTION ); qglPopMatrix(); qglMatrixMode( GL_MODELVIEW ); qglCullFace( GL_FRONT ); } if ( currententity->flags & ( RF_SHELL_HALF_DAM | RF_SHELL_GREEN | RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE ) ) qglDisable(GL_BLEND); else if ( currententity->flags & RF_TRANSLUCENT ) { qglDisable (GL_BLEND); qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } if( currententity->flags & RF_CUSTOMSKIN ) { qglDisable(GL_TEXTURE_GEN_S); qglDisable(GL_TEXTURE_GEN_T); qglDisable (GL_BLEND); qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); qglColor4f(1,1,1,1); qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } if (currententity->flags & RF_DEPTHHACK) qglDepthRange (gldepthmin, gldepthmax); qglColor4f (1,1,1,1); if(r_minimap->integer) { if ( currententity->flags & RF_MONSTER) { RadarEnts[numRadarEnts].color[0]= 1.0; RadarEnts[numRadarEnts].color[1]= 0.0; RadarEnts[numRadarEnts].color[2]= 2.0; RadarEnts[numRadarEnts].color[3]= 1.0; } else return; VectorCopy(currententity->origin,RadarEnts[numRadarEnts].org); numRadarEnts++; } } void MD2_DrawCasterFrame (dmdl_t *paliashdr, float backlerp, qboolean lerped) { daliasframe_t *frame, *oldframe; dtrivertx_t *v, *ov=NULL, *verts; dtriangle_t *tris; float frontlerp; vec3_t move, delta, vectors[3]; vec3_t frontv, backv; int i, j; int index_xyz, index_st; int va = 0; fstvert_t *st; if(lerped) frame = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames + currententity->frame * paliashdr->framesize); else frame = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames); verts = v = frame->verts; if(lerped) { oldframe = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames + currententity->oldframe * paliashdr->framesize); ov = oldframe->verts; } tris = (dtriangle_t *) ((byte *)paliashdr + paliashdr->ofs_tris); st = currentmodel->st; if(lerped) { frontlerp = 1.0 - backlerp; // move should be the delta back to the previous frame * backlerp VectorSubtract (currententity->oldorigin, currententity->origin, delta); } AngleVectors (currententity->angles, vectors[0], vectors[1], vectors[2]); if(lerped) { move[0] = DotProduct (delta, vectors[0]); // forward move[1] = -DotProduct (delta, vectors[1]); // left move[2] = DotProduct (delta, vectors[2]); // up VectorAdd (move, oldframe->translate, move); for (i=0 ; i<3 ; i++) { move[i] = backlerp*move[i] + frontlerp*frame->translate[i]; frontv[i] = frontlerp*frame->scale[i]; backv[i] = backlerp*oldframe->scale[i]; } } va=0; VArray = &VArrayVerts[0]; R_InitVArrays (VERT_NO_TEXTURE); if (gl_state.vbo && !lerped) { vbo_xyz = R_VCFindCache(VBO_STORE_XYZ, currentmodel); if (vbo_xyz) { goto skipLoad; } } for (i = 0; i < paliashdr->num_tris; i++) { for (j = 0; j < 3; j++) { index_xyz = tris[i].index_xyz[j]; index_st = tris[i].index_st[j]; if(lerped) { VArray[0] = s_lerped[index_xyz][0] = move[0] + ov[index_xyz].v[0]*backv[0] + v[index_xyz].v[0]*frontv[0]; VArray[1] = s_lerped[index_xyz][1] = move[1] + ov[index_xyz].v[1]*backv[1] + v[index_xyz].v[1]*frontv[1]; VArray[2] = s_lerped[index_xyz][2] = move[2] + ov[index_xyz].v[2]*backv[2] + v[index_xyz].v[2]*frontv[2]; } else { VArray[0] = currentmodel->vertexes[index_xyz].position[0]; VArray[1] = currentmodel->vertexes[index_xyz].position[1]; VArray[2] = currentmodel->vertexes[index_xyz].position[2]; if(gl_state.vbo) { VertexArray[va][0] = VArray[0]; VertexArray[va][1] = VArray[1]; VertexArray[va][2] = VArray[2]; } } // increment pointer and counter VArray += VertexSizes[VERT_NO_TEXTURE]; va++; } } if(gl_state.vbo && !lerped) { vbo_xyz = R_VCLoadData(VBO_STATIC, va*sizeof(vec3_t), VertexArray, VBO_STORE_XYZ, currentmodel); } skipLoad: if(gl_state.vbo && !lerped) { qglEnableClientState( GL_VERTEX_ARRAY ); GL_BindVBO(vbo_xyz); qglVertexPointer(3, GL_FLOAT, 0, 0); } R_DrawVarrays(GL_TRIANGLES, 0, paliashdr->num_tris*3); R_KillVArrays (); } //to do - alpha and alphamasks possible? void MD2_DrawCaster ( void ) { vec3_t bbox[8]; dmdl_t *paliashdr; if(currententity->team) //don't draw flag models, handled by sprites return; if ( currententity->flags & RF_WEAPONMODEL ) //don't draw weapon model shadow casters return; if ( currententity->flags & ( RF_SHELL_HALF_DAM | RF_SHELL_GREEN | RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE) ) //no shells return; if ( MD2_CullModel( bbox ) ) return; paliashdr = (dmdl_t *)currentmodel->extradata; // draw it qglPushMatrix (); currententity->angles[PITCH] = -currententity->angles[PITCH]; R_RotateForEntity (currententity); currententity->angles[PITCH] = -currententity->angles[PITCH]; if ( (currententity->frame >= paliashdr->num_frames) || (currententity->frame < 0) ) { currententity->frame = 0; currententity->oldframe = 0; } if ( (currententity->oldframe >= paliashdr->num_frames) || (currententity->oldframe < 0)) { currententity->frame = 0; currententity->oldframe = 0; } if ( !r_lerpmodels->integer ) currententity->backlerp = 0; if(currententity->frame == 0 && currentmodel->num_frames == 1) MD2_DrawCasterFrame(paliashdr, 0, false); else MD2_DrawCasterFrame(paliashdr, currententity->backlerp, true); qglPopMatrix(); } alien-arena-7.66+dfsg/source/ref_gl/r_image.h0000600000175000017500000001007512161402007020125 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Mipmaps are generated for all texture types. If type <= it_wall, brightness and contrast settings are applied to it at load time. If type >= it_bump, the standard mipmapping/anisotropic settings are always used, otherwise they are only used if the entire texture has the same alpha value. If type != it_pic and type != it_particle, picmip settings are applied at load time. */ typedef enum { it_skin, it_sprite, it_wall, it_pic, it_sky, it_bump, it_particle } imagetype_t; typedef struct image_s { char name[MAX_QPATH]; // game path, including extension char bare_name[MAX_QPATH]; // filename only, as called when searching unsigned int hash_key; // hash key used in GL_FindImage imagetype_t type; int width, height; // source image int upload_width, upload_height; // after power of two and picmip int registration_sequence; // 0 = free int texnum; // gl texture binding float sl, tl, sh, th; // 0,0 - 1,1 unless part of the scrap int crop_left, crop_top, crop_width, crop_height; //for cropped 2D drawing float crop_sl, crop_tl, crop_sh, crop_th; // texcoords of cropped corners qboolean scrap; qboolean has_alpha; qboolean paletted; qboolean is_cin; // Heffo - To identify a cin texture's image_t void *script; } image_t; #define TEXNUM_LIGHTMAPS 1024 #define TEXNUM_SCRAPS 1152 #define TEXNUM_IMAGES 1153 #define MAX_GLTEXTURES 4096 //was 1024 //particles extern image_t *r_notexture; extern image_t *r_particletexture; extern image_t *r_smoketexture; extern image_t *r_explosiontexture; extern image_t *r_explosion1texture; extern image_t *r_explosion2texture; extern image_t *r_explosion3texture; extern image_t *r_explosion4texture; extern image_t *r_explosion5texture; extern image_t *r_explosion6texture; extern image_t *r_explosion7texture; extern image_t *r_bloodtexture; extern image_t *r_pufftexture; extern image_t *r_bflashtexture; extern image_t *r_cflashtexture; extern image_t *r_leaderfieldtexture; extern image_t *r_deathfieldtexture; extern image_t *r_deathfieldtexture2; extern image_t *r_shelltexture; extern image_t *r_shelltexture2; extern image_t *r_shellnormal; extern image_t *r_hittexture; extern image_t *r_bubbletexture; extern image_t *r_reflecttexture; extern image_t *r_mirrorspec; extern image_t *r_shottexture; extern image_t *r_bullettexture; extern image_t *r_bulletnormal; extern image_t *r_sayicontexture; extern image_t *r_flaretexture; extern image_t *r_beamtexture; extern image_t *r_beam2texture; extern image_t *r_beam3texture; extern image_t *r_dis1texture; extern image_t *r_dis2texture; extern image_t *r_dis3texture; extern image_t *r_voltagetexture; extern image_t *r_raintexture; extern image_t *r_leaftexture; extern image_t *r_trashtexture; extern image_t *r_splashtexture; extern image_t *r_splash2texture; extern image_t *r_flagtexture; extern image_t *r_logotexture; extern image_t *r_distort; extern image_t *r_mirrortexture; extern image_t gltextures[MAX_GLTEXTURES]; extern int numgltextures; extern image_t *r_flare; extern image_t *r_flare1; extern image_t *sun_object; extern image_t *sun1_object; extern image_t *sun2_object; extern image_t *r_radarmap; extern image_t *r_around; alien-arena-7.66+dfsg/source/ref_gl/r_particle.c0000600000175000017500000013535712162607462020671 0ustar zero79zero79/* Copyright (C) 2010 COR Entertainment, LLC This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // r_particle.c - particle subsystem, renders particles, lightvolumes, lensflares, vegetation, etc #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "r_local.h" particle_t gparticles[MAX_PARTICLES]; int num_gparticles; /* =============== PART_DrawParticles =============== */ static float yawOrRoll; static int compare_particle (const void *_a, const void *_b) { particle_t *a = *(particle_t **)_a; particle_t *b = *(particle_t **)_b; if (a->image != NULL && b->image == NULL) return 1; if (a->image == NULL && b->image != NULL) return -1; if (a->image == NULL && b->image == NULL) return 0; if (a->image->texnum != b->image->texnum) return a->image->texnum-b->image->texnum; if (a->blendsrc != b->blendsrc) return a->blendsrc-b->blendsrc; if (a->blenddst != b->blenddst) return a->blenddst-b->blenddst; return 0; } void PART_DrawParticles( int num_particles, particle_t **particles, const unsigned colortable[768]) { particle_t **p1; particle_t *p; int i, k, j; vec3_t corner[4], up, right, pup, pright, dir; float scale; byte color[4]; int oldblendsrc = -1, oldblenddst = -1; int texnum=0, blenddst, blendsrc; float *corner0 = corner[0]; vec3_t move, delta, v; float sh, th, sl, tl; if ( !num_particles ) return; qglDepthMask( GL_FALSE ); // no z buffering qglEnable( GL_BLEND); GL_TexEnv( GL_MODULATE ); R_InitVArrays (VERT_COLOURED_TEXTURED); qglDisable (GL_CULL_FACE); qsort (particles, num_particles, sizeof (particle_t *), compare_particle); GL_SelectTexture (GL_TEXTURE0); // FIXME: OH FFS this is so stupid: tell the GL_Bind batching mechanism // that texture unit 0 has been re-bound, as it most certainly has been. gl_state.currenttextures[gl_state.currenttmu] = -1; for ( p1 = particles, i=0; i < num_particles ; i++,p1++) { p = *p1; if( p->type == PARTICLE_CHAINED && p->chain_prev) { vec3_t span, beam_org; VectorSubtract (p->current_origin, p->chain_prev->current_origin, span); VectorAdd (p->current_origin, p->chain_prev->current_origin, beam_org); VectorScale (beam_org, 0.5, beam_org); VectorScale (span, 0.5, span); if (R_CullSphere( beam_org, VectorLength (span), 15 ) ) continue; } else if (R_CullSphere( p->current_origin, 64, 15 ) ) continue; if(p->type == PARTICLE_NONE) { blendsrc = GL_SRC_ALPHA; blenddst = GL_ONE; *(int *)color = colortable[p->current_color]; scale = 1; VectorCopy (vup, up); VectorCopy (vright, right); } else { if (p->image != NULL) texnum = p->image->texnum; else texnum = 0; blendsrc = p->blendsrc; blenddst = p->blenddst; scale = p->current_scale; VectorScale (vup, scale, up); VectorScale (vright, scale, right); *(int *)color = colortable[p->current_color]; } color[3] = p->current_alpha*255; GL_Bind (texnum); if (oldblendsrc != blendsrc || oldblenddst != blenddst) { if (oldblendsrc != blendsrc || oldblenddst != blenddst) qglBlendFunc ( blendsrc, blenddst ); oldblendsrc = blendsrc; oldblenddst = blenddst; } if(p->type == PARTICLE_RAISEDDECAL) { for (k = 0; k < 4; k++) color[k] = 255; } if(p->type == PARTICLE_BEAM) { VectorSubtract(p->current_origin, p->angle, move); VectorNormalize(move); VectorCopy(move, pup); VectorSubtract(r_newrefdef.vieworg, p->angle, delta); CrossProduct(pup, delta, pright); VectorNormalize(pright); VectorScale(pright, 5*scale, pright); VectorScale(pup, 5*scale, pup); } else if(p->type == PARTICLE_DECAL || p->type == PARTICLE_RAISEDDECAL) { VectorCopy(p->angle, dir); AngleVectors(dir, NULL, right, up); VectorScale ( right, p->dist, pright ); VectorScale ( up, p->dist, pup ); VectorScale(pright, 5*scale, pright); VectorScale(pup, 5*scale, pup); } else if(p->type == PARTICLE_FLAT) { VectorCopy(r_newrefdef.viewangles, dir); dir[0] = -90; // and splash particles horizontal by setting it AngleVectors(dir, NULL, right, up); if(p->current_origin[2] > r_newrefdef.vieworg[2]){ // it's above us VectorScale(right, 5*scale, pright); VectorScale(up, 5*scale, pup); } else { // it's below us VectorScale(right, 5*scale, pright); VectorScale(up, -5*scale, pup); } } else if(p->type == PARTICLE_FLUTTERWEATHER){ VectorCopy(p->angle, dir); AngleVectors(dir, NULL, right, up); VectorScale(right, 3*scale, pright); VectorScale(up, 3*scale, pup); } else if(p->type == PARTICLE_VERT || p->type == PARTICLE_WEATHER){ // keep it vertical VectorCopy(r_newrefdef.viewangles, v); v[0] = 0; // keep weather particles vertical by removing pitch AngleVectors(v, NULL, right, up); VectorScale(right, 3*scale, pright); VectorScale(up, 3*scale, pup); } else if(p->type == PARTICLE_ROTATINGYAW || p->type == PARTICLE_ROTATINGROLL || p->type == PARTICLE_ROTATINGYAWMINUS){ // keep it vertical, and rotate on axis VectorCopy(r_newrefdef.viewangles, v); v[0] = 0; // keep weather particles vertical by removing pitch yawOrRoll += r_frametime*50; if (yawOrRoll > 360) yawOrRoll = 0; if(p->type == PARTICLE_ROTATINGYAW) v[1] = yawOrRoll; else if(p->type == PARTICLE_ROTATINGROLL) v[2] = yawOrRoll; else v[1] = yawOrRoll+180; AngleVectors(v, NULL, right, up); VectorScale(right, 3*scale, pright); VectorScale(up, 3*scale, pup); } else { VectorScale ( right, p->dist, pright ); VectorScale ( up, p->dist, pup ); } if (p->type == PARTICLE_CHAINED && p->chain_prev) { particle_t *pr; vec3_t pspan, prev_pspan; pr = p->chain_prev; VectorCopy (p->current_pspan, pspan); if (pr->type == PARTICLE_CHAINED && pr->chain_prev) VectorCopy (pr->current_pspan, prev_pspan); else VectorCopy (pspan, prev_pspan); VectorCopy (pspan, pright); VectorSet ( corner[0], p->current_origin[0] + pspan[0]*(0.5), p->current_origin[1] + pspan[1]*(0.5), p->current_origin[2] + pspan[2]*(0.5)); VectorSet ( corner[1], pr->current_origin[0] + prev_pspan[0]*(0.5), pr->current_origin[1] + prev_pspan[1]*(0.5), pr->current_origin[2] + prev_pspan[2]*(0.5)); VectorSet (corner[2], pr->current_origin[0] + prev_pspan[0]*(-0.5), pr->current_origin[1] + prev_pspan[1]*(-0.5), pr->current_origin[2] + prev_pspan[2]*(-0.5)); VectorSet (corner[3], p->current_origin[0] + pspan[0]*(-0.5), p->current_origin[1] + pspan[1]*(-0.5), p->current_origin[2] + pspan[2]*(-0.5)); } else { VectorSet (corner[0], p->current_origin[0] + (pup[0] + pright[0])*(-0.5), p->current_origin[1] + (pup[1] + pright[1])*(-0.5), p->current_origin[2] + (pup[2] + pright[2])*(-0.5)); VectorSet ( corner[1], corner0[0] + pup[0], corner0[1] + pup[1], corner0[2] + pup[2]); VectorSet ( corner[2], corner0[0] + (pup[0]+pright[0]), corner0[1] + (pup[1]+pright[1]), corner0[2] + (pup[2]+pright[2])); VectorSet ( corner[3], corner0[0] + pright[0], corner0[1] + pright[1], corner0[2] + pright[2]); } VArray = &VArrayVerts[0]; if (p->image != NULL) { sh = p->image->sh; th = p->image->th; sl = p->image->sl; tl = p->image->tl; } else { sh = th = 1; sl = tl = 0; } for(k = 0; k < 4; k++) { VArray[0] = corner[k][0]; VArray[1] = corner[k][1]; VArray[2] = corner[k][2]; switch(k) { case 0: VArray[3] = sh; VArray[4] = th; break; case 1: VArray[3] = sl; VArray[4] = th; break; case 2: VArray[3] = sl; VArray[4] = tl; break; case 3: VArray[3] = sh; VArray[4] = tl; break; } for (j = 0; j < 4; j++) VArray[5+j] = (float)color[j]/255.0f; VArray += VertexSizes[VERT_COLOURED_TEXTURED]; } R_DrawVarrays(GL_QUADS, 0, 4); } R_KillVArrays (); qglTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); qglBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); qglColor4f( 1,1,1,1 ); qglDisable(GL_BLEND); qglDepthMask( GL_TRUE ); // back to normal Z buffering GL_TexEnv( GL_REPLACE ); qglEnable (GL_CULL_FACE); } /* =============== R_DrawParticles =============== */ void R_DrawParticles (void) { if ( !r_newrefdef.num_particles ) return; if(map_fog) qglDisable(GL_FOG); PART_DrawParticles( r_newrefdef.num_particles, r_newrefdef.particles, d_8to24table); if(map_fog) qglEnable(GL_FOG); } //lens flares // TODO: flare rendering is actually shockingly slow, and the reason is the // overhead of each glDrawArrays call. It MIGHT be worth using a variation on // this method: http://stackoverflow.com/a/1039082 and batching up all flares // of each texture into a single VArray consisting of vertex and vertex color // data, with a size attribute, one vertex per flare. This would reduce the // usage of the PCI bus. void Mod_AddFlareSurface (msurface_t *surf, int type ) { int i, width, height, intens; glpoly_t *poly; flare_t *light; byte *buffer; byte *p; float *v, surf_bound; vec3_t origin = {0,0,0}, color = {1,1,1}, tmp, rgbSum; vec3_t poly_center, mins, maxs, tmp1; if (surf->iflags & ISURF_DRAWTURB) return; if (surf->texinfo->flags & (SURF_SKY|SURF_TRANS33|SURF_TRANS66|SURF_FLOWING|SURF_WARP)) return; if (!(surf->texinfo->flags & (SURF_LIGHT))) return; if (r_numflares >= MAX_FLARES) return; light = &r_flares[r_numflares++]; intens = surf->texinfo->value; //if (intens < 100) //if not a lighted surf, don't do a flare, right? // return; /* =================== find poligon centre =================== */ VectorSet(mins, 999999, 999999, 999999); VectorSet(maxs, -999999, -999999, -999999); for ( poly = surf->polys; poly; poly = poly->chain ) { for (i=0, v=poly->verts[0] ; i< poly->numverts; i++, v+= VERTEXSIZE) { if(v[0] > maxs[0]) maxs[0] = v[0]; if(v[1] > maxs[1]) maxs[1] = v[1]; if(v[2] > maxs[2]) maxs[2] = v[2]; if(v[0] < mins[0]) mins[0] = v[0]; if(v[1] < mins[1]) mins[1] = v[1]; if(v[2] < mins[2]) mins[2] = v[2]; } } poly_center[0] = (mins[0] + maxs[0]) /2; poly_center[1] = (mins[1] + maxs[1]) /2; poly_center[2] = (mins[2] + maxs[2]) /2; VectorCopy(poly_center, origin); /* ===================================== calc light surf bounds and flare size ===================================== */ VectorSubtract(maxs, mins, tmp1); surf_bound = VectorLength(tmp1); if (surf_bound <=25) light->size = 10; else if (surf_bound <=50) light->size = 15; else if (surf_bound <=100) light->size = 20; else if (surf_bound <=150) light->size = 25; else if (surf_bound <=200) light->size = 30; else if (surf_bound <=250) light->size = 35; /* =================== calc texture color =================== */ GL_Bind( surf->texinfo->image->texnum ); width = surf->texinfo->image->upload_width; height = surf->texinfo->image->upload_height; buffer = malloc(width * height * 3); qglGetTexImage (GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, buffer); VectorClear(rgbSum); for (i=0, p=buffer; ivalue / (width *height), color); for (i=0; i<3; i++) { if (color[i] < 0.5) color[i] = color[i] * 0.5; else color[i] = color[i] * 0.5 + 0.5; } VectorCopy(color, light->color); /* ================================== move flare origin in to map bounds ================================== */ if (surf->iflags & ISURF_PLANEBACK) VectorNegate(surf->plane->normal, tmp); else VectorCopy(surf->plane->normal, tmp); VectorMA(origin, 2, tmp, origin); VectorCopy(origin, light->origin); light->style = type; light->leafnum = CM_PointLeafnum (light->origin); free (buffer); } void PART_RenderFlare (flare_t *light) { vec3_t v, tmp; int j; float dist; float alpha; unsigned flaretex; if(light->style == 0) flaretex = r_flare->texnum; else flaretex = r_flare1->texnum; VectorSubtract (light->origin, r_origin, v); dist = VectorLength(v) * (light->size*0.01); // Flares which are very close are too small to see; fade them out as we // get closer. alpha = light->alpha; if (dist < 2.0*light->size) alpha *= 0.5*(dist-(float)light->size)/(float)light->size; if (alpha < 0.0) return; //limit their size to reasonable. if(dist > 10*light->size) dist = 10*light->size; VectorMA (light->origin, -1-dist, vup, vert_array[1]); VectorMA (vert_array[1], -1-dist, vright, vert_array[1]); VectorMA (light->origin, 1+dist, vup, vert_array[3]); VectorMA (vert_array[3], 1+dist, vright, vert_array[3]); if (R_CullBox (vert_array[1], vert_array[3])) return; VectorMA (light->origin, -1-dist, vup, vert_array[0]); VectorMA (vert_array[0], 1+dist, vright, vert_array[0]); VectorMA (light->origin, 1+dist, vup, vert_array[2]); VectorMA (vert_array[2], -1-dist, vright, vert_array[2]); c_flares++; GL_Bind(flaretex); VectorScale(light->color, alpha, tmp ); for (j=0; j<4; j++) VA_SetElem4(col_array[j], tmp[0],tmp[1],tmp[2], 1); VA_SetElem2(tex_array[0], 0, 1); VA_SetElem2(tex_array[1], 0, 0); VA_SetElem2(tex_array[2], 1, 0); VA_SetElem2(tex_array[3], 1, 1); R_DrawVarrays(GL_QUADS, 0 , 4); } void R_RenderFlares (void) { flare_t *l; int i; qboolean visible; vec3_t mins, maxs; trace_t r_trace; VectorSet(mins, 0, 0, 0); VectorSet(maxs, 0, 0, 0); if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )return; qglDepthMask (0); qglDisable (GL_TEXTURE_2D); qglShadeModel (GL_SMOOTH); qglEnable (GL_BLEND); qglBlendFunc (GL_SRC_ALPHA, GL_ONE); R_InitQuadVarrays(); qglDisable(GL_DEPTH_TEST); qglEnable (GL_TEXTURE_2D); qglEnableClientState( GL_COLOR_ARRAY ); GL_TexEnv( GL_MODULATE ); l = r_flares; for (i=0; itime > 0.02){ if (!CM_inPVS_leafs (r_origin_leafnum, l->leafnum)) continue; r_trace = CM_BoxTrace(r_origin, l->origin, mins, maxs, r_worldmodel->firstnode, MASK_VISIBILILITY); visible = r_trace.fraction == 1.0; l->alpha += (visible ? 0.03 : -0.15); // ramp if(l->alpha > 0.5) // clamp l->alpha = 0.5; else if(l->alpha < 0) l->alpha = 0.0; l->time = rs_realtime; } if (l->alpha > 0) { PART_RenderFlare (l); } } GL_TexEnv( GL_REPLACE ); qglEnable(GL_DEPTH_TEST); qglDisable (GL_TEXTURE_2D); qglDisableClientState(GL_COLOR_ARRAY); R_KillVArrays(); qglColor3f (1,1,1); qglDisable (GL_BLEND); qglEnable (GL_TEXTURE_2D); qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); qglDepthMask (1); } void R_ClearFlares(void) { memset(r_flares, 0, sizeof(r_flares)); r_numflares = 0; } /* ================ Sun Object ================ */ void transform_point(float out[4], const float m[16], const float in[4]) { #define M(row,col) m[col*4+row] out[0] = M(0, 0) * in[0] + M(0, 1) * in[1] + M(0, 2) * in[2] + M(0, 3) * in[3]; out[1] = M(1, 0) * in[0] + M(1, 1) * in[1] + M(1, 2) * in[2] + M(1, 3) * in[3]; out[2] = M(2, 0) * in[0] + M(2, 1) * in[1] + M(2, 2) * in[2] + M(2, 3) * in[3]; out[3] = M(3, 0) * in[0] + M(3, 1) * in[1] + M(3, 2) * in[2] + M(3, 3) * in[3]; #undef M } qboolean gluProject2(float objx, float objy, float objz, const float model[16], const float proj[16], const int viewport[4], float *winx, float *winy) { /* transformation matrix */ float in[4], out[4], temp; /* initialise the matrix and the vector to transform */ in[0] = objx; in[1] = objy; in[2] = objz; in[3] = 1.0; transform_point(out, model, in); transform_point(in, proj, out); /* normalise result to [-1;1] */ if (in[3] == 0.0) return false; temp = 1.0 / in[3]; in[0] *= temp; in[1] *= temp; in[2] *= temp; /* display coordinates */ *winx = viewport[0] + (1 + in[0]) * (float) viewport[2] * 0.5; *winy = viewport[1] + (1 + in[1]) * (float) viewport[3] * 0.5; return true; } void R_InitSun() { draw_sun = false; if (!r_drawsun->value) return; if (spacebox) sun_size = 0.1f; else sun_size = 0.2f; if (R_CullOrigin(sun_origin)) return; draw_sun = true; gluProject2(sun_origin[0], sun_origin[1], sun_origin[2], r_world_matrix, r_project_matrix, (int *) r_viewport, &sun_x, &sun_y); // /, // &sun_z); sun_y = r_newrefdef.height - sun_y; } void PART_RenderSunFlare(image_t * tex, float offset, float radius, float r, float g, float b, float alpha) { float minx, miny, maxx, maxy; float new_x, new_y; float diameter = 2.0*radius; qglColor4f(r, g, b, alpha); GL_Bind(tex->texnum); if (offset) { new_x = offset * (r_newrefdef.width / 2 - sun_x) + sun_x; new_y = offset * (r_newrefdef.height / 2 - sun_y) + sun_y; } else { new_x = sun_x; new_y = sun_y; } minx = new_x - radius; miny = new_y - radius; maxx = new_x + radius; maxy = new_y + radius; if (r_test->integer && false) { // TODO: add an alpha channel to gfx/sun.jpg (will require converting // to TGA) because otherwise this code makes no difference. minx += diameter * (float)tex->crop_left / (float)tex->upload_width; miny += diameter * (float)tex->crop_top / (float)tex->upload_height; maxx = minx + diameter * (float)tex->crop_width / (float)tex->upload_width; maxy = miny + diameter * (float)tex->crop_height / (float)tex->upload_height; qglBegin(GL_QUADS); qglTexCoord2f(tex->crop_sl, tex->crop_tl); qglVertex2f(minx, miny); qglTexCoord2f(tex->crop_sh, tex->crop_tl); qglVertex2f(maxx, miny); qglTexCoord2f(tex->crop_sh, tex->crop_th); qglVertex2f(maxx, maxy); qglTexCoord2f(tex->crop_sl, tex->crop_th); qglVertex2f(minx, maxy); qglEnd(); } else { qglBegin(GL_QUADS); qglTexCoord2f(0, 0); qglVertex2f(minx, miny); qglTexCoord2f(1, 0); qglVertex2f(maxx, miny); qglTexCoord2f(1, 1); qglVertex2f(maxx, maxy); qglTexCoord2f(0, 1); qglVertex2f(minx, maxy); qglEnd(); } } float sun_alpha = 0; void R_RenderSun() { static float l; static float sun_vistest_time = 0; static float sun_ramp_time = 0; float hx, hy; float vec[2]; float size; if (!draw_sun) return; if (r_nosun) return; if (r_newrefdef.rdflags & RDF_NOWORLDMODEL) return; // The sun is only visible if a single pixel at sun_x, sun_y is not // covered by anything. Just like lens flares, we ramp the opacity up and // down linearly to smooth out transitions. Since glReadPixels is // expensive, we only test visibility every SUN_VIS_TEST_PERIOD seconds, // but to keep the opacity animation smooth, we do that every frame. #define SUN_VIS_TEST_PERIOD 0.1 #define SUN_ALPHA_RAMP_PER_SECOND 7.5 #define SUN_ALPHA_RAMP_PER_FRAME (SUN_ALPHA_RAMP_PER_SECOND*(rs_realtime-sun_ramp_time)) // periodically test visibility to ramp alpha if(rs_realtime - sun_vistest_time > SUN_VIS_TEST_PERIOD) { qglReadPixels ( sun_x, r_newrefdef.height - sun_y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &l); sun_vistest_time = rs_realtime; } // ramp opacity up or down each frame sun_alpha += (l == 1.0 ? 1.0 : -1.0)*SUN_ALPHA_RAMP_PER_FRAME; sun_ramp_time = rs_realtime; if(sun_alpha > 1.0) // clamp sun_alpha = 1.0; else if(sun_alpha < 0) sun_alpha = 0.0; if (sun_alpha > 0) { hx = r_newrefdef.width / 2; hy = r_newrefdef.height / 2; vec[0] = 1 - fabs(sun_x - hx) / hx; vec[1] = 1 - fabs(sun_y - hy) / hy; // set 2d qglMatrixMode(GL_PROJECTION); qglPushMatrix(); qglLoadIdentity(); qglOrtho(0, r_newrefdef.width, r_newrefdef.height, 0, -99999, 99999); qglMatrixMode(GL_MODELVIEW); qglPushMatrix(); qglLoadIdentity(); qglEnable(GL_BLEND); qglBlendFunc(GL_SRC_ALPHA, GL_ONE); GL_TexEnv(GL_MODULATE); qglDepthRange(0, 0.3); size = r_newrefdef.width * sun_size; PART_RenderSunFlare(sun_object, 0, size, .75, .75, .75, sun_alpha); if (r_drawsun->value == 2) { PART_RenderSunFlare(sun2_object, -0.9, size * 0.07, 0.1, 0.1, 0, sun_alpha); PART_RenderSunFlare(sun2_object, -0.7, size * 0.15, 0, 0, 0.1, sun_alpha); PART_RenderSunFlare(sun2_object, -0.5, size * 0.085, 0.1, 0, 0, sun_alpha); PART_RenderSunFlare(sun1_object, 0.3, size * 0.25, 0.1, 0.1, 0.1, sun_alpha); PART_RenderSunFlare(sun2_object, 0.5, size * 0.05, 0.1, 0, 0, sun_alpha); PART_RenderSunFlare(sun2_object, 0.64, size * 0.05, 0, 0.1, 0, sun_alpha); PART_RenderSunFlare(sun2_object, 0.7, size * 0.25, 0.1, 0.1, 0, sun_alpha); PART_RenderSunFlare(sun1_object, 0.85, size * 0.5, 0.1, 0.1, 0.1, sun_alpha); PART_RenderSunFlare(sun2_object, 1.1, size * 0.125, 0.1, 0, 0, sun_alpha); PART_RenderSunFlare(sun2_object, 1.25, size * 0.08, 0.1, 0.1, 0, sun_alpha); } qglDepthRange(0, 1); qglColor4f(1, 1, 1, 1); qglDisable(GL_BLEND); qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // set 3d qglPopMatrix(); qglMatrixMode(GL_PROJECTION); qglPopMatrix(); qglMatrixMode(GL_MODELVIEW); } } //Vegetation void Mod_AddVegetationSurface (msurface_t *surf, int texnum, vec3_t color, float size, char name[MAX_QPATH], int type) { glpoly_t *poly; grass_t *grass; image_t *gl; vec3_t origin = {0,0,0}, binormal, tangent, tmp; if (r_numgrasses >= MAX_GRASSES) return; if(size == 0.0) size = 1.0f; poly = surf->polys; VectorCopy(poly->verts[0], origin); AngleVectors(surf->plane->normal, NULL, tangent, binormal); VectorNormalize(tangent); VectorNormalize(binormal); VectorMA(origin, -32*frand(), tangent, origin); if (surf->iflags & ISURF_PLANEBACK) VectorNegate(surf->plane->normal, tmp); else VectorCopy(surf->plane->normal, tmp); VectorMA(origin, 2, tmp, origin); grass = &r_grasses[r_numgrasses++]; VectorCopy(origin, grass->origin); gl = R_RegisterGfxPic (name); if (gl) grass->texsize = gl->height; else grass->texsize = 64; //sane default grass->texnum = texnum; VectorCopy(color, grass->color); grass->size = size; strcpy(grass->name, name); grass->type = type; grass->leafnum = CM_PointLeafnum (grass->origin); if(grass->type == 1) r_hasleaves = true; } // Mark any vegetation sprites that can cast shadows in sunlight, and get // static light levels. void R_FinalizeGrass(model_t *mod) { vec3_t origin, orig2, mins, maxs; trace_t r_trace; grass_t *grass; int i; model_t *old; grass = r_grasses; VectorSet (mins, 0, 0, 0); VectorSet (maxs, 0, 0, 0); old = r_worldmodel; for (i=0; iorigin, origin); if (grass->type == 0) origin[2] += (grass->texsize/32) * grass->size; // XXX: HACK! r_worldmodel = mod; R_StaticLightPoint (origin, grass->static_light); r_worldmodel = old; if (grass->type == 0) { grass->sunVisible = false; continue; //only deal with leaves, grass shadows look kind of bad } //cull for pathline to sunlight VectorCopy (grass->origin, orig2); orig2[2] += (grass->texsize/32) * grass->size; r_trace = CM_BoxTrace(r_sunLight->origin, orig2, maxs, mins, mod->firstnode, MASK_VISIBILILITY); grass->sunVisible = r_trace.fraction == 1.0; } } //rendering int compare_grass (void const *_a, void const *_b) { vec3_t dist; int distA, distB; grass_t a = *(grass_t *)_a; grass_t b = *(grass_t *)_b; VectorSubtract(a.origin, r_origin, dist); distA = VectorLength(dist); VectorSubtract(b.origin, r_origin, dist); distB = VectorLength(dist); if (distA > distB) return -1; else if (distA < distB) return 1; return 0; } static int g_lastGSort = 0; void R_DrawVegetationSurface ( void ) { int i, k; grass_t *grass; float scale; vec3_t origin, mins, maxs, angle, right, up, corner[4]; float *corner0 = corner[0]; qboolean visible; float lightLevel[3]; trace_t r_trace; float sway; int ng; if(r_newrefdef.rdflags & RDF_NOWORLDMODEL) return; //sort the grasses from furthest to closest(we can safely do this every 3/4 second //instead of every frame since our POV shouldn't change that drastically enough //to create artifacts. Grasses must be sorted to prevent major artifacting. if(g_lastGSort < Sys_Milliseconds() - 750) { qsort( r_grasses, r_numgrasses, sizeof( r_grasses[0] ), compare_grass ); g_lastGSort = Sys_Milliseconds(); } grass = r_grasses; VectorSet(mins, 0, 0, 0); VectorSet(maxs, 0, 0, 0); qglDepthMask( GL_FALSE ); qglEnable( GL_BLEND); qglBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); GL_Bind (0); GL_TexEnv( GL_MODULATE ); for (i=0; isize; VectorCopy(grass->origin, origin); if(grass->type) { sway = 3; gCount = 1; visible = true; //leaves tend to use much larger images, culling results in undesired effects } else { sway = 2; qglDisable( GL_CULL_FACE ); // adjust vertical position, scaled origin[2] += (grass->texsize/32) * grass->size; visible = CM_inPVS_leafs (r_origin_leafnum, grass->leafnum); if (visible) { r_trace = CM_BoxTrace(r_origin, origin, maxs, mins, r_worldmodel->firstnode, MASK_VISIBILILITY); visible = r_trace.fraction == 1.0; } } if(visible) { GL_Bind(grass->texnum); if(gl_dynamic->integer) R_DynamicLightPoint (origin, lightLevel); else VectorClear (lightLevel); VectorAdd (grass->static_light, lightLevel, lightLevel); VectorScale(lightLevel, 2.0, lightLevel); qglColor4f( grass->color[0]*(lightLevel[0]+0.1),grass->color[1]*(lightLevel[1]+0.1),grass->color[2]*(lightLevel[2]+0.1), 1 ); if(grass->type) VectorCopy(r_newrefdef.viewangles, angle); else VectorSet(angle, 0, 0, 0); for(ng = 0; ng < gCount; ng ++) { AngleVectors(angle, NULL, right, up); VectorScale(right, scale, right); VectorScale(up, scale, up); //render grass polygon VectorSet (corner[0], origin[0] + (up[0] + right[0])*(-0.5), origin[1] + (up[1] + right[1])*(-0.5), origin[2] + (up[2] + right[2])*(-0.5)); VectorSet ( corner[1], corner0[0] + up[0] + sway*sin (rs_realtime*sway), corner0[1] + up[1] + sway*sin (rs_realtime*sway), corner0[2] + up[2]); VectorSet ( corner[2], corner0[0] + (up[0]+right[0] + sway*sin (rs_realtime*sway)), corner0[1] + (up[1]+right[1] + sway*sin (rs_realtime*sway)), corner0[2] + (up[2]+right[2])); VectorSet ( corner[3], corner0[0] + right[0], corner0[1] + right[1], corner0[2] + right[2]); for(k = 0; k < 4; k++) { VArray[0] = corner[k][0]; VArray[1] = corner[k][1]; VArray[2] = corner[k][2]; switch(k) { case 0: VArray[3] = 1; VArray[4] = 1; break; case 1: VArray[3] = 0; VArray[4] = 1; break; case 2: VArray[3] = 0; VArray[4] = 0; break; case 3: VArray[3] = 1; VArray[4] = 0; break; } VArray += VertexSizes[VERT_SINGLE_TEXTURED]; va++; } angle[1]+=60; } c_grasses++; R_DrawVarrays(GL_QUADS, 0, va); R_KillVArrays (); } } qglColor4f( 1,1,1,1 ); qglDisable(GL_BLEND); qglDepthMask( GL_TRUE ); GL_TexEnv( GL_REPLACE ); qglEnable( GL_CULL_FACE ); } void R_ClearGrasses(void) { memset(r_grasses, 0, sizeof(r_grasses)); r_numgrasses = 0; r_hasleaves = 0; } //Light beams/volumes void Mod_AddBeamSurface (msurface_t *surf, int texnum, vec3_t color, float size, char name[MAX_QPATH], int type, float xang, float yang, qboolean rotating) { glpoly_t *poly; beam_t *beam; image_t *gl; vec3_t poly_center, mins, maxs; float *v; int i; vec3_t origin = {0,0,0}, binormal, tangent, tmp; if (r_numbeams >= MAX_BEAMS) return; if(size == 0.0) size = 1.0f; poly = surf->polys; /* =================== find poligon centre =================== */ VectorSet(mins, 999999, 999999, 999999); VectorSet(maxs, -999999, -999999, -999999); for ( poly = surf->polys; poly; poly = poly->chain ) { for (i=0, v=poly->verts[0] ; i< poly->numverts; i++, v+= VERTEXSIZE) { if(v[0] > maxs[0]) maxs[0] = v[0]; if(v[1] > maxs[1]) maxs[1] = v[1]; if(v[2] > maxs[2]) maxs[2] = v[2]; if(v[0] < mins[0]) mins[0] = v[0]; if(v[1] < mins[1]) mins[1] = v[1]; if(v[2] < mins[2]) mins[2] = v[2]; } } poly_center[0] = (mins[0] + maxs[0]) /2; poly_center[1] = (mins[1] + maxs[1]) /2; poly_center[2] = (mins[2] + maxs[2]) /2; VectorCopy(poly_center, origin); AngleVectors(surf->plane->normal, NULL, tangent, binormal); VectorNormalize(tangent); VectorNormalize(binormal); if (surf->iflags & ISURF_PLANEBACK) VectorNegate(surf->plane->normal, tmp); else VectorCopy(surf->plane->normal, tmp); VectorMA(origin, 2, tmp, origin); beam = &r_beams[r_numbeams++]; VectorCopy(origin, beam->origin); gl = R_RegisterGfxPic (name); if (gl) beam->texsize = gl->height; else beam->texsize = 64; //sane default beam->texnum = texnum; VectorCopy(color, beam->color); beam->size = size; strcpy(beam->name, name); beam->type = type; beam->xang = xang; beam->yang = yang; beam->rotating = rotating; beam->leafnum = 0; if (!beam->rotating) { vec3_t start, end; double maxang; float movdir; if(fabs(beam->xang) > fabs(beam->yang)) maxang = beam->xang; else maxang = beam->yang; if(maxang >= 0.0) movdir = 1.0; else movdir = 0; VectorCopy(beam->origin, start); if(!beam->type) start[2] -= (2.5 - (10.0*maxang))*beam->size*movdir; else start[2] += (2.5 - (10.0*maxang))*beam->size*movdir; VectorCopy(start, end); if(!beam->type) end[2] -= (2.5 + pow(fabs(maxang),2)*10)*beam->size; else end[2] += (2.5 + pow(fabs(maxang),2)*10)*beam->size; end[0] += (pow(fabs(maxang*10), 3)*beam->xang)*beam->size; //angle in rads end[1] += (pow(fabs(maxang*10), 3)*beam->yang)*beam->size; beam->leafnum = CM_PointLeafnum (start); beam->leafnum2 = CM_PointLeafnum (end); if (beam->leafnum == beam->leafnum2) beam->leafnum2 = 0; } } //Rendering void R_DrawBeamSurface ( void ) { int i, j, k; beam_t *beam; double scale, maxang; vec3_t start, end, mins, maxs, angle, right, up, delta, corner[4]; float *corner0 = corner[0]; qboolean visible; trace_t r_trace; vec3_t absmins, absmaxs; if(r_newrefdef.rdflags & RDF_NOWORLDMODEL) return; beam = r_beams; VectorSet(mins, 32, 32, 64); VectorSet(maxs, -32, -32, -64); R_InitVArrays (VERT_SINGLE_TEXTURED); qglDepthMask( GL_FALSE ); qglEnable( GL_BLEND); qglBlendFunc (GL_SRC_ALPHA, GL_ONE); GL_TexEnv( GL_MODULATE ); for (i=0; ileafnum && beam->leafnum2 && !CM_inPVS_leafs (r_origin_leafnum, beam->leafnum) && !CM_inPVS_leafs (r_origin_leafnum, beam->leafnum2)) continue; if ( beam->leafnum && !beam->leafnum2 && !CM_inPVS_leafs (r_origin_leafnum, beam->leafnum)) continue; scale = 10.0*beam->size; if(fabs(beam->xang) > fabs(beam->yang)) maxang = beam->xang; else maxang = beam->yang; if(maxang >= 0.0) movdir = 1.0; else movdir = 0; //to do - this is rather hacky, and really only works for 0 degrees and 45 degree angles(0.25 rads). //will revisit this as needed, for now it works for what I need it for. VectorCopy(beam->origin, start); if(!beam->type) start[2] -= (2.5 - (10.0*maxang))*beam->size*movdir; else start[2] += (2.5 - (10.0*maxang))*beam->size*movdir; VectorCopy(start, end); if(!beam->type) end[2] -= (2.5 + pow(fabs(maxang),2)*10)*beam->size; else end[2] += (2.5 + pow(fabs(maxang),2)*10)*beam->size; if(beam->rotating) { end[0] += sin(rs_realtime)*(pow(fabs(maxang*10), 3)*beam->xang)*beam->size; //angle in rads end[1] += cos(rs_realtime)*(pow(fabs(maxang*10), 3)*beam->yang)*beam->size; } else { end[0] += (pow(fabs(maxang*10), 3)*beam->xang)*beam->size; //angle in rads end[1] += (pow(fabs(maxang*10), 3)*beam->yang)*beam->size; } VectorSubtract(end, start, up); if(!beam->type) VectorScale(up, -beam->size, up); else VectorScale(up, beam->size, up); VectorAdd(start, up, angle); VectorNormalize(up); VectorSubtract(r_newrefdef.vieworg, angle, delta); CrossProduct(up, delta, right); VectorNormalize(right); VectorScale(right, scale, right); VectorScale(up, scale, up); VectorCopy (beam->origin, absmins); VectorCopy (beam->origin, absmaxs); VectorSet (corner[0], end[0] + (up[0] + right[0])*(-0.5), end[1] + (up[1] + right[1])*(-0.5), end[2] + (up[2] + right[2])*(-0.5)); VectorSet ( corner[1], corner0[0] + up[0], corner0[1] + up[1], corner0[2] + up[2]); VectorSet ( corner[2], corner0[0] + (up[0]+right[0]), corner0[1] + (up[1]+right[1]), corner0[2] + (up[2]+right[2])); VectorSet ( corner[3], corner0[0] + right[0], corner0[1] + right[1], corner0[2] + right[2]); for (j = 0; j < 4; j++) { for (k = 0; k < 3; k++) { if (corner[j][k] < absmins[k]) absmins[k] = corner[j][k]; else if (corner[j][k] > absmaxs[k]) absmaxs[k] = corner[j][k]; } } if (R_CullBox (absmins, absmaxs)) continue; // TODO: establish if we should even be using CM_BoxTrace at all-- // performance-wise it's very bad to use it a lot. r_trace = CM_BoxTrace(r_origin, beam->origin, mins, maxs, r_worldmodel->firstnode, MASK_VISIBILILITY); visible = r_trace.fraction == 1.0; if(visible) { //render polygon qglColor4f( beam->color[0],beam->color[1],beam->color[2], 1 ); GL_Bind(beam->texnum); VArray = &VArrayVerts[0]; for(k = 0; k < 4; k++) { VArray[0] = corner[k][0]; VArray[1] = corner[k][1]; VArray[2] = corner[k][2]; switch(k) { case 0: VArray[3] = 1; VArray[4] = 1; break; case 1: VArray[3] = 0; VArray[4] = 1; break; case 2: VArray[3] = 0; VArray[4] = 0; break; case 3: VArray[3] = 1; VArray[4] = 0; break; } VArray += VertexSizes[VERT_SINGLE_TEXTURED]; } R_DrawVarrays(GL_QUADS, 0, 4); c_beams++; } } R_KillVArrays (); qglTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); qglBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); qglColor4f( 1,1,1,1 ); qglDisable(GL_BLEND); qglDepthMask( GL_TRUE ); GL_TexEnv( GL_REPLACE ); } void R_ClearBeams(void) { memset(r_beams, 0, sizeof(r_beams)); r_numbeams = 0; } //Simple items //simple item images image_t *s_item0; image_t *s_item1; image_t *s_item2; image_t *s_item3; image_t *s_item4; image_t *s_item5; image_t *s_item6; image_t *s_item7; image_t *s_item8; image_t *s_item9; image_t *s_item10; image_t *s_item11; image_t *s_item12; image_t *s_item13; image_t *s_item14; image_t *s_item17; image_t *s_item18; image_t *s_item19; image_t *s_item20; image_t *s_item21; image_t *s_item22; image_t *s_item23; image_t *s_item24; extern int gl_filter_max; void R_SI_InitTextures( void ) { byte nullpic[16][16][4]; int x, y; // // blank texture // for (x = 0 ; x < 16 ; x++) { for (y = 0 ; y < 16 ; y++) { nullpic[y][x][0] = 255; nullpic[y][x][1] = 255; nullpic[y][x][2] = 255; nullpic[y][x][3] = 255; } } #define R_SI_InitTexture(itemnum,imgname) \ /* load the texture */ \ s_item ## itemnum = GL_FindImage ("pics/" #imgname ".tga,", it_pic);\ /* load a blank texture if it isn't found */ \ if (!s_item ## itemnum) \ s_item ## itemnum = GL_LoadPic ("***s_item" #itemnum "***", (byte *)nullpic, 16, 16, it_pic, 32); \ /* Disable more than one mipmap level. FIXME: improve mushy mipmap * detection so this isn't necessary. */ \ GL_Bind(s_item ## itemnum ->texnum); \ qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); R_SI_InitTexture (0, w_sshotgun); R_SI_InitTexture (1, w_railgun); R_SI_InitTexture (2, w_chaingun); R_SI_InitTexture (3, w_rlauncher); R_SI_InitTexture (4, w_shotgun); R_SI_InitTexture (5, p_haste); R_SI_InitTexture (6, p_invulnerability); R_SI_InitTexture (7, p_quad); R_SI_InitTexture (8, p_sproing); R_SI_InitTexture (9, p_adrenaline); R_SI_InitTexture (10, p_shard); R_SI_InitTexture (11, p_jacket); R_SI_InitTexture (12, p_combat); R_SI_InitTexture (13, p_body); R_SI_InitTexture (14, p_health); R_SI_InitTexture (17, i_beamgun); R_SI_InitTexture (18, i_vaporizer); R_SI_InitTexture (19, i_disruptor); R_SI_InitTexture (20, i_flamegun); R_SI_InitTexture (21, i_smartgun); R_SI_InitTexture (22, i_chaingun); R_SI_InitTexture (23, i_rocketlauncher); R_SI_InitTexture (24, i_minderaser); } //rendering extern cvar_t *cl_simpleitems; void R_DrawSimpleItems ( void ) { int i, k; float scale; vec3_t origin, mins, maxs, angle, right, up, corner[4]; float *corner0 = corner[0]; qboolean visible; trace_t r_trace; if (!cl_simpleitems->integer) return; if(r_newrefdef.rdflags & RDF_NOWORLDMODEL) return; VectorSet(mins, 0, 0, 0); VectorSet(maxs, 0, 0, 0); qglEnable( GL_BLEND); qglBlendFunc ( GL_ONE, GL_ONE_MINUS_SRC_ALPHA ); GL_Bind (0); qglTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST ); qglTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST ); GL_TexEnv( GL_MODULATE ); qglDepthMask( GL_TRUE ); GLSTATE_ENABLE_ALPHATEST for (i=0 ; imodel || !currententity->model->simple_texnum) continue; currentmodel = currententity->model; R_InitVArrays (VERT_SINGLE_TEXTURED); VArray = &VArrayVerts[0]; VectorCopy(currententity->origin, origin); //PVS checking is not necessary; the server already does that for //entities. r_trace = CM_BoxTrace(r_origin, origin, maxs, mins, r_worldmodel->firstnode, MASK_VISIBILILITY); visible = r_trace.fraction == 1.0; if(visible) { GL_Bind (currentmodel->simple_texnum); switch (currentmodel->simple_color) { case simplecolor_white: qglColor4f( 1, 1, 1, 1 ); //uses texture for color unless specified break; case simplecolor_green: qglColor4f( 0, 1, 0, 1 ); break; case simplecolor_blue: qglColor4f( 0, .3, 1, 1 ); break; case simplecolor_purple: qglColor4f( 1, 0, 1, 1 ); break; } if ( (currentmodel->simple_texnum == s_item17->texnum) || (currentmodel->simple_texnum == s_item18->texnum) || (currentmodel->simple_texnum == s_item19->texnum) || (currentmodel->simple_texnum == s_item20->texnum) || (currentmodel->simple_texnum == s_item21->texnum) || (currentmodel->simple_texnum == s_item22->texnum) || (currentmodel->simple_texnum == s_item23->texnum) || (currentmodel->simple_texnum == s_item24->texnum)) { scale = 40.0; } else { scale = 20.0; } VectorCopy(r_newrefdef.viewangles, angle); angle[0] = 0; // keep vertical by removing pitch AngleVectors(angle, NULL, right, up); VectorScale(right, scale, right); VectorScale(up, scale, up); //render polygon VectorSet (corner[0], origin[0] + (up[0] + right[0])*(-0.5), origin[1] + (up[1] + right[1])*(-0.5), origin[2] + (up[2] + right[2])*(-0.5)); VectorSet ( corner[1], corner0[0] + up[0], corner0[1] + up[1], corner0[2] + up[2]); VectorSet ( corner[2], corner0[0] + (up[0]+right[0]), corner0[1] + (up[1]+right[1]), corner0[2] + (up[2]+right[2])); VectorSet ( corner[3], corner0[0] + right[0], corner0[1] + right[1], corner0[2] + right[2]); for(k = 0; k < 4; k++) { VArray[0] = corner[k][0]; VArray[1] = corner[k][1]; VArray[2] = corner[k][2]; switch(k) { case 0: VArray[3] = 0; VArray[4] = 1; break; case 1: VArray[3] = 0; VArray[4] = 0; break; case 2: VArray[3] = 1; VArray[4] = 0; break; case 3: VArray[3] = 1; VArray[4] = 1; break; } VArray += VertexSizes[VERT_SINGLE_TEXTURED]; va++; } R_DrawVarrays(GL_QUADS, 0, va); R_KillVArrays (); } } qglBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); qglDisable(GL_BLEND); GLSTATE_DISABLE_ALPHATEST qglTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); GL_TexEnv( GL_REPLACE ); } void R_SetSimpleTexnum (model_t *loadmodel, const char *pathname) { loadmodel->simple_texnum = 0; loadmodel->simple_color = simplecolor_white; if (!Q_strcasecmp (pathname, "models/items/ammo/bullets/medium/tris.md2")) { loadmodel->simple_texnum = s_item0->texnum; } else if (!Q_strcasecmp (pathname, "models/items/ammo/cells/medium/tris.md2")) { loadmodel->simple_texnum = s_item1->texnum; } else if (!Q_strcasecmp (pathname, "models/items/ammo/grenades/medium/tris.md2")) { loadmodel->simple_texnum = s_item2->texnum; } else if (!Q_strcasecmp (pathname, "models/items/ammo/rockets/medium/tris.md2")) { loadmodel->simple_texnum = s_item3->texnum; } else if (!Q_strcasecmp (pathname, "models/items/ammo/shells/medium/tris.md2")) { loadmodel->simple_texnum = s_item4->texnum; } //powerups else if (!Q_strcasecmp (pathname, "models/items/haste/tris.md2")) { loadmodel->simple_texnum = s_item5->texnum; } else if (!Q_strcasecmp (pathname, "models/items/invulner/tris.md2")) { loadmodel->simple_texnum = s_item6->texnum; } else if (!Q_strcasecmp (pathname, "models/items/quaddama/tris.md2")) { loadmodel->simple_texnum = s_item7->texnum; } else if (!Q_strcasecmp (pathname, "models/items/sproing/tris.md2")) { loadmodel->simple_texnum = s_item8->texnum; } else if (!Q_strcasecmp (pathname, "models/items/adrenaline/tris.md2")) { loadmodel->simple_texnum = s_item9->texnum; } //armor else if (!Q_strcasecmp (pathname, "models/items/armor/shard/tris.md2")) { loadmodel->simple_texnum = s_item10->texnum; } else if (!Q_strcasecmp (pathname, "models/items/armor/jacket/tris.md2")) { loadmodel->simple_texnum = s_item11->texnum; } else if (!Q_strcasecmp (pathname, "models/items/armor/combat/tris.md2")) { loadmodel->simple_texnum = s_item12->texnum; } else if (!Q_strcasecmp (pathname, "models/items/armor/body/tris.md2")) { loadmodel->simple_texnum = s_item13->texnum; } //health else if (!Q_strcasecmp (pathname, "models/items/healing/small/tris.md2")) { loadmodel->simple_texnum = s_item14->texnum; loadmodel->simple_color = simplecolor_green; } else if (!Q_strcasecmp (pathname, "models/items/healing/medium/tris.md2")) { loadmodel->simple_texnum = s_item14->texnum; loadmodel->simple_color = simplecolor_blue; } else if (!Q_strcasecmp (pathname, "models/items/healing/large/tris.md2")) { loadmodel->simple_texnum = s_item14->texnum; loadmodel->simple_color = simplecolor_purple; } //weapons else if (!Q_strcasecmp (pathname, "models/weapons/g_rail/tris.md2")) { loadmodel->simple_texnum = s_item17->texnum; } else if (!Q_strcasecmp (pathname, "models/weapons/g_bfg/tris.md2")) { loadmodel->simple_texnum = s_item18->texnum; } else if (!Q_strcasecmp (pathname, "models/weapons/g_hyperb/tris.md2")) { loadmodel->simple_texnum = s_item19->texnum; } else if (!Q_strcasecmp (pathname, "models/weapons/g_chain/tris.md2")) { loadmodel->simple_texnum = s_item20->texnum; } else if (!Q_strcasecmp (pathname, "models/weapons/g_shotg/tris.md2")) { loadmodel->simple_texnum = s_item21->texnum; } else if (!Q_strcasecmp (pathname, "models/weapons/g_shotg2/tris.md2")) { loadmodel->simple_texnum = s_item22->texnum; } else if (!Q_strcasecmp (pathname, "models/weapons/g_rocket/tris.md2")) { loadmodel->simple_texnum = s_item23->texnum; } else if (!Q_strcasecmp (pathname, "models/weapons/g_minderaser/tris.md2")) { loadmodel->simple_texnum = s_item24->texnum; } } alien-arena-7.66+dfsg/source/ref_gl/r_text.c0000600000175000017500000003124512161402007020024 0ustar zero79zero79/* Copyright (C) 2010 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* r_text.c * * Generic "front" for text rendering. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include "r_local.h" #include "r_text.h" #include "r_ttf.h" /* Face lookup table. */ static hashtable_t _FNT_LoadedFaces = NULL; /* Font lookup table. */ static hashtable_t _FNT_LoadedFonts = NULL; /* Color table */ float FNT_colors[ 8 ][ 4 ] = { {0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 1.0}, {0.0, 0.0, 1.0, 1.0}, {0.0, 1.0, 1.0, 1.0}, {1.0, 0.0, 1.0, 1.0}, {1.0, 1.0, 1.0, 1.0}, }; /**************************************************************************/ /* NULL FONT */ /**************************************************************************/ /* Null font */ static struct FNT_font_s _FNT_NullFontStruct; static FNT_font_t _FNT_NullFont = NULL; static void _FNT_NullFont_Destroy( FNT_font_t font ) { Com_Error( ERR_FATAL , "FNT_NullFont_Destroy called - this is a bug" ); } static void _FNT_NullFont_RawPrint( FNT_font_t font , const char * text , unsigned int text_length , qboolean r2l , float x , float y , const float color[4] ) { /* EMPTY */ } static void _FNT_NullFont_BoundedPrint( FNT_font_t font , const char * text , unsigned int cmode , unsigned int align , FNT_window_t box , const float * color ) { /* EMPTY */ } static void _FNT_NullFont_WrappedPrint( FNT_font_t font , const char * text , unsigned int cmode , unsigned int align , unsigned int indent , FNT_window_t box , const float * color ) { /* EMPTY */ } static int _FNT_NullFont_PredictSize( FNT_font_t font , const char * text, qboolean color ) { /* EMPTY */ } /**************************************************************************/ /* AUTOMATIC FONT MANAGEMENT */ /**************************************************************************/ /* List head for automated fonts */ static struct FNT_auto_s _FNT_AutoListHead; static FNT_auto_t _FNT_AutoList = NULL; /* Initialise an automatic font structure. */ void FNT_AutoInit( FNT_auto_t auto_font , const char * default_face , int default_size , unsigned int auto_lines , unsigned int min_size , unsigned int max_size ) { assert( auto_font != NULL ); assert( default_face != NULL ); assert( auto_lines > 8 ); assert( min_size != 0 ); assert( max_size > min_size ); assert( default_size == 0 || default_size > min_size ); auto_font->next = auto_font->previous = auto_font; Q_strncpyz2( auto_font->face , default_face , sizeof( auto_font->face ) ); auto_font->faceVar = NULL; auto_font->size = default_size; auto_font->sizeVar = NULL; auto_font->lines = auto_lines; auto_font->minSize = min_size; auto_font->maxSize = max_size; } /* Register an automatic font. */ void FNT_AutoRegister( FNT_auto_t auto_font ) { assert( auto_font != NULL ); if ( _FNT_AutoList == NULL ) { _FNT_AutoListHead.next = _FNT_AutoListHead.previous = _FNT_AutoList = &_FNT_AutoListHead; } if ( auto_font->previous != auto_font->next || auto_font->previous != auto_font ) { return; } auto_font->previous = _FNT_AutoList->previous; auto_font->next = _FNT_AutoList; auto_font->next->previous = auto_font->previous->next = auto_font; auto_font->font = &_FNT_NullFontStruct; } /* Access the font from an automatic font structure. */ FNT_font_t FNT_AutoGet( FNT_auto_t auto_font ) { int size; FNT_face_t face; qboolean fvMod , svMod; assert( _FNT_AutoList != NULL ); assert( auto_font->previous != auto_font ); fvMod = auto_font->faceVar && auto_font->faceVar->modified; svMod = auto_font->sizeVar && auto_font->sizeVar->modified; // Do we need to load a font? if ( auto_font->font != _FNT_NullFont ) { if ( ! ( fvMod || svMod ) ) { return auto_font->font; } FNT_ReleaseFont( auto_font->font ); } // Mark other automatic fonts for reload if we have modified variables if ( fvMod || svMod ) { FNT_auto_t current = auto_font->next; while ( current != auto_font ) { if ( current != _FNT_AutoList && current->font != _FNT_NullFont && ( ( fvMod && auto_font->faceVar == current->faceVar ) || ( svMod && auto_font->sizeVar == current->sizeVar ) ) ) { FNT_ReleaseFont( current->font ); current->font = _FNT_NullFont; } current = current->next; } } // Load face if ( auto_font->faceVar ) { face = FNT_GetFace( auto_font->faceVar->string ); auto_font->faceVar->modified = false; } else { face = NULL; } if ( face == NULL ) { // fallback font face = FNT_GetFace( auto_font->face ); } // Get or compute font size if ( auto_font->sizeVar ) { size = auto_font->sizeVar->integer; auto_font->sizeVar->modified = false; } else { size = auto_font->size; } if ( size <= 0 ) { size = viddef.height / auto_font->lines; } if ( size < auto_font->minSize ) { size = auto_font->minSize; } else if ( size > auto_font->maxSize ) { size = auto_font->maxSize; } return ( auto_font->font = FNT_GetFont( face , size ) ); } /**************************************************************************/ /* FONT FUNCTIONS */ /**************************************************************************/ /* * Initialise lookup tables for the text rendering front-end. */ qboolean FNT_Initialise( ) { if ( _FNT_LoadedFaces != NULL ) return true; // Set up Null font if necessary if ( _FNT_NullFont == NULL ) { _FNT_NullFont = &_FNT_NullFontStruct; memset( _FNT_NullFont , 0 , sizeof( struct FNT_font_s ) ); _FNT_NullFont->Destroy = _FNT_NullFont_Destroy; _FNT_NullFont->RawPrint = _FNT_NullFont_RawPrint; _FNT_NullFont->BoundedPrint = _FNT_NullFont_BoundedPrint; _FNT_NullFont->WrappedPrint = _FNT_NullFont_WrappedPrint; _FNT_NullFont->PredictSize = _FNT_NullFont_PredictSize; } // Create hash tables for both faces and fonts _FNT_LoadedFaces = HT_Create( 100 , HT_FLAG_INTABLE , sizeof( struct FNT_face_s ) , 0 , FNT_FACE_NAME_MAX ); _FNT_LoadedFonts = HT_Create( 400 , HT_FLAG_INTABLE , sizeof( struct FNT_font_s ) , 0 , FNT_FONT_KEY_MAX ); // Initialise TrueType engine if ( ! TTF_Initialise( ) ) { HT_Destroy( _FNT_LoadedFonts ); HT_Destroy( _FNT_LoadedFaces ); return false; } return true; } /* * Function used to destroy fonts */ static qboolean _FNT_DestroyAllFonts( void * item , void * extra ) { FNT_font_t font = (FNT_font_t) item; font->Destroy( font ); return true; } /* * Function used to destroy faces */ static qboolean _FNT_DestroyAllFaces( void * item , void * extra ) { FNT_face_t face = (FNT_face_t) item; face->Destroy( face ); return true; } /* * Destroy the text drawing front-end */ void FNT_Shutdown( ) { FNT_auto_t item; if ( _FNT_LoadedFaces == NULL ) return; // Reset all automatic fonts to the Null font if necessary if ( _FNT_AutoList != NULL ) { item = _FNT_AutoList->next; while ( item != _FNT_AutoList ) { item->font = _FNT_NullFont; item = item->next; } } // Destroy all existing fonts and faces HT_Apply( _FNT_LoadedFonts , _FNT_DestroyAllFonts , NULL ); HT_Destroy( _FNT_LoadedFonts ); _FNT_LoadedFonts = NULL; HT_Apply( _FNT_LoadedFaces , _FNT_DestroyAllFaces , NULL ); HT_Destroy( _FNT_LoadedFaces ); _FNT_LoadedFaces = NULL; // Shutdown TTF engine TTF_Shutdown( ); } /* * Create or access a face. */ FNT_face_t FNT_GetFace( const char * face_name ) { qboolean created; FNT_face_t face; const char * bnStart; const char * bnEnd; const char * bnPtr; size_t bnSize; char baseName[ FNT_FACE_NAME_MAX + 1 ]; // Find the argument's file name bnStart = bnPtr = face_name; while ( *bnPtr ) { if ( *bnPtr == '/' || *bnPtr == '\\' ) bnStart = bnPtr + 1; bnPtr ++; } bnEnd = bnPtr; while ( bnPtr > bnStart && *bnPtr != '.' ) { bnPtr --; } if ( *bnPtr == '.' ) bnEnd = bnPtr; bnSize = bnEnd - bnStart; if ( bnSize > FNT_FACE_NAME_MAX ) { Com_DPrintf( "FNT: face name from '%s' is too long\n" , face_name ); return NULL; } else if ( bnSize == 0 ) { Com_DPrintf( "FNT: face name from '%s' is empty\n" , face_name ); return NULL; } Q_strncpyz2( baseName , bnStart , bnSize + 1 ); // Try looking it up first face = HT_GetItem( _FNT_LoadedFaces , baseName , &created ); if ( created ) { // Changed from 0 to 1. An initial value of 0 was causing face to be // used after being freed. face->used = 1; } else { face->used ++; return face; } // Try loading it as a TrueType font if ( TTF_InitFace( face ) ) return face; // Could not load Com_Printf( "FNT: could not load face '%s'\n" , baseName ); HT_DeleteItem( _FNT_LoadedFaces , baseName , NULL ); return NULL; } /* * Access an actual font */ FNT_font_t FNT_GetFont( FNT_face_t face , unsigned int size ) { char fontId[ FNT_FONT_KEY_MAX + 1 ]; FNT_font_t font; qboolean created; if ( face == NULL ) { return _FNT_NullFont; } // Try looking it up Com_sprintf( fontId , sizeof( fontId ) , "%s|%lu" , face->name , size ); font = HT_GetItem( _FNT_LoadedFonts , fontId , &created ); if ( created ) { // Not found - initialise it. font->used = 1; font->face = face; font->size = size; if ( ! face->GetFont( font ) ) { HT_DeleteItem( _FNT_LoadedFonts , fontId , NULL ); font = _FNT_NullFont; } } else { font->used ++; } return font; } /* * Release a font */ void FNT_ReleaseFont( FNT_font_t font ) { FNT_face_t face; if ( font == NULL || font == _FNT_NullFont ) { return; } font->used --; if ( font->used ) { return; } face = font->face; font->Destroy( font ); HT_DeleteItem( _FNT_LoadedFonts , font->lookup , NULL ); face->used --; if ( face->used ) { return; } face->Destroy( face ); HT_DeleteItem( _FNT_LoadedFaces , face->name , NULL ); } /**************************************************************************/ /* HELPER FUNCTIONS */ /**************************************************************************/ /* * Function that handles color codes in strings. */ qboolean _FNT_HandleColor( const char ** pptr , unsigned int cmode , const float * color , qboolean * expectColor , qboolean * colorChanged , const float ** curColor ) { const char * ptr; char current; if ( cmode == FNT_CMODE_NONE ) { return true; } ptr = *pptr; current = *ptr; if ( cmode == FNT_CMODE_TWO ) { // Two-color mode if ( ( current & 0x80 ) == 0 && *curColor != color ) { *curColor = color; *colorChanged = true; } else if ( ( current & 0x80 ) != 0 && *curColor == color ) { *curColor = &( color[ 4 ] ); *colorChanged = true; } } // Quake color codes current &= 0x7f; if ( *expectColor ) { if ( current == '\n' ) { (*pptr) --; return false; } *expectColor = false; if ( current != '^' ) { if ( cmode != FNT_CMODE_TWO ) { *curColor = FNT_colors[ ( current - '0' ) & 7 ]; *colorChanged = true; } (*pptr) ++; return false; } } else if ( *ptr == '^' ) { *expectColor = true; (*pptr) ++; if ( ! **pptr ) { (*pptr) --; } return false; } else if ( cmode == FNT_CMODE_QUAKE_SRS && *ptr == ' ' ) { *curColor = color; *colorChanged = true; } return true; } /* * Find the next wrapped unit (i.e. line or rest of the string until EOL). */ qboolean _FNT_NextWrappedUnit( const char ** pptr , _FNT_render_info_t renderInfo , unsigned int * unitLength , unsigned int cmode , const float * color ) { const float * curColor = color; qboolean expectColor = false; qboolean colorChanged; char previous = ' '; int index = 0; while ( **pptr && **pptr != '\n' ) { char curChar; // Handle color codes if ( ! _FNT_HandleColor( pptr , cmode , color , &expectColor , &colorChanged , &curColor ) ) { continue; } // Skip extra spaces curChar = *(*pptr) ++; // Add character to info array renderInfo[ index ].toDraw = curChar; renderInfo[ index ].color = curColor; index ++; previous = curChar; } if ( **pptr ) { (*pptr) ++; } *unitLength = index; return ( **pptr != 0 ); } alien-arena-7.66+dfsg/source/ref_gl/r_model.h0000600000175000017500000002432312161402007020144 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. Copyright (C) 2011 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* d*_t structures are on-disk representations m*_t structures are in-memory */ #include "r_iqm.h" /* ============================================================================== WORLD LIGHTS ============================================================================== */ #define MAX_LIGHTS 4096 typedef struct { vec3_t origin; float intensity; void *surf; qboolean grouped; } worldLight_t; worldLight_t r_worldLights[MAX_LIGHTS]; int r_numWorldLights; /* ============================================================================== SUN LIGHTS ============================================================================== */ typedef struct { char targetname[128]; vec3_t origin; vec3_t target; qboolean has_Sun; } sunLight_t; sunLight_t *r_sunLight; /* ============================================================================== ALIAS MODELS ============================================================================== */ typedef struct { byte v[3]; // scaled byte to fit in frame mins/maxs byte lightnormalindex; byte latlong[2]; } mtrivertx_t; typedef struct { float scale[3]; // multiply byte verts by this float translate[3]; // then add this mtrivertx_t *verts; // variable sized } maliasframe_t; typedef struct { char name[MAX_SKINNAME]; } maliasskin_t; typedef struct { int num_skins; maliasskin_t *skins; int num_xyz; int num_tris; int num_glcmds; // dwords in strip/fan command list int *glcmds; int num_frames; maliasframe_t *frames; } maliasmdl_t; //base player models and weapons for prechache typedef struct PModelList_s { char *name; } PModelList_t; extern PModelList_t BasePModels[]; extern int PModelsCount; typedef struct WModelList_s { char *name; } WModelList_t; extern WModelList_t BaseWModels[]; extern int WModelsCount; /* ============================================================================== BRUSH MODELS ============================================================================== */ // // in memory representation // typedef struct mvertex_s { vec3_t position; } mvertex_t; typedef struct { vec3_t dir; } mnormal_t; typedef struct { vec4_t dir; } mtangent_t; typedef struct { vec3_t mins, maxs; float radius; int headnode; int visleafs; // not including the solid leaf 0 int firstface, numfaces; } mmodel_t; #define SIDE_FRONT 0 #define SIDE_BACK 1 #define SIDE_ON 2 //Internal surface flags, applied by the engine #define ISURF_PLANEBACK 0x1 #define ISURF_DRAWTURB 0x2 // same effect as SURF_UNDERWATER, but has to be separate because // SURF_UNDERWATER applies to texinfos, whereas we have to work with // individual surfaces. #define ISURF_UNDERWATER 0x4 #define TexinfoIsTranslucent(texinfo) ((texinfo)->flags & (SURF_TRANS33|SURF_TRANS66)) #define SurfaceIsTranslucent(surf) (TexinfoIsTranslucent((surf)->texinfo)) #define TexinfoIsAlphaBlended(texinfo) ((texinfo)->flags & SURF_TRANS33 && (texinfo)->flags & SURF_TRANS66) #define SurfaceIsAlphaBlended(surf) (TexinfoIsAlphaBlended ((surf)->texinfo)) #define SurfaceHasNoLightmap(surf) ((surf)->texinfo->flags & (SURF_SKY|SURF_TRANS33|SURF_TRANS66|SURF_WARP) && !SurfaceIsAlphaBlended((surf))) // !!! if this is changed, it must be changed in asm_draw.h too !!! typedef struct { unsigned short v[2]; } medge_t; /* ============================================================================== VERTEX ARRAYS ============================================================================== */ typedef struct mtexinfo_s { float vecs[2][4]; int flags; int numframes; struct mtexinfo_s *next; // animation chain struct mtexinfo_s *equiv; // equivalent texinfo image_t *image; image_t *normalMap; image_t *heightMap; qboolean has_normalmap; qboolean has_heightmap; struct rscript_s *script; int value; //for BSP rendering-- not always cleared each frame struct msurface_s *w_glsl_surfaces, *w_glsl_dynamic_surfaces, *w_lightmap_surfaces; //for entity rendering-- cleared for each brush model drawn struct msurface_s *e_glsl_surfaces, *e_glsl_dynamic_surfaces, *e_lightmap_surfaces; } mtexinfo_t; #define VERTEXSIZE 10 typedef struct glpoly_s { struct glpoly_s *next; struct glpoly_s *chain; int numverts; float verts[4][VERTEXSIZE]; // variable sized (xyz s1t1 s2t2) } glpoly_t; // FIXME: We really need a smaller version of this struct with less data in // it, for use by BSP_RecursiveWorldNode. This one is 136 bytes, which is huge // and killing our cache locality. typedef struct msurface_s { int visframe; // should be drawn when node is crossed int iflags; // internal flags, applied by the engine mtexinfo_t *texinfo; cplane_t *plane; //texture chains for batching struct msurface_s *texturechain; struct msurface_s *rscriptchain; //texture chain for lightstyle updating struct msurface_s *flickerchain; vec3_t mins; vec3_t maxs; int texturemins[2]; int extents[2]; glpoly_t *polys; // multiple if warped float c_s, c_t; // lighting info int dlightframe; int dlightbits; int lightmins[2]; int lightmaxs[2]; int lightmaptexturenum; byte styles[MAXLIGHTMAPS]; float cached_light[MAXLIGHTMAPS]; // values currently used in lightmap byte *samples; // [numstyles*surfsize] entity_t *entity; float *tangentSpaceTransform; //vbo int has_vbo; int vbo_first_vert; int vbo_num_verts; // XXX: for future reference, the glDrawRangeElements code was last seen // here at revision 3246. } msurface_t; typedef struct mnode_s { // common with leaf int contents; // -1, to differentiate from leafs int visframe; // node needs to be traversed if current float minmaxs[6]; // for bounding box culling struct mnode_s *parent; // node specific cplane_t *plane; struct mnode_s *children[2]; unsigned short firstsurface; unsigned short numsurfaces; } mnode_t; typedef struct mleaf_s { // common with node int contents; // wil be a negative contents number int visframe; // node needs to be traversed if current float minmaxs[6]; // for bounding box culling struct mnode_s *parent; // leaf specific int cluster; int area; msurface_t **firstmarksurface; int nummarksurfaces; int minPVSleaf, maxPVSleaf; } mleaf_t; //=================================================================== // // Whole model // typedef struct { int n[3]; } neighbors_t; typedef struct { int hasHelmet; float RagDollDims[56]; } mragdoll_t; typedef enum {mod_bad, mod_brush, mod_sprite, mod_alias, mod_iqm } modtype_t; typedef enum { simplecolor_white, simplecolor_green, simplecolor_blue, simplecolor_purple } simplecolor_t; typedef struct model_s { char name[MAX_QPATH]; int registration_sequence; modtype_t type; int flags; // // volume occupied by the model graphics // vec3_t mins, maxs; float radius; vec3_t bbox[8]; // // brush model // int firstmodelsurface, nummodelsurfaces; int numsubmodels; mmodel_t *submodels; int numplanes; cplane_t *planes; int numleafs; // number of visible leafs, not counting 0 mleaf_t *leafs; int numvertexes; mvertex_t *vertexes; int numedges; medge_t *edges; int numnodes; int firstnode; mnode_t *nodes; int numtexinfo; mtexinfo_t *texinfo; int num_unique_texinfos; mtexinfo_t **unique_texinfo; int numsurfaces; msurface_t *surfaces; int numTangentSpaceTransforms; float *tangentSpaceTransforms; int numsurfedges; int *surfedges; int nummarksurfaces; msurface_t **marksurfaces; dvis_t *vis; byte *lightdata; //minimum and maximum leaf indexes for each area int area_min_leaf[MAX_MAP_AREAS]; int area_max_leaf[MAX_MAP_AREAS]; int num_areas; // for alias models and skins image_t *skins[MAX_MD2SKINS]; struct rscript_s *script; int extradatasize; void *extradata; int num_frames; //iqm skeletal model info unsigned int version; mvertex_t *animatevertexes; int num_joints; iqmjoint_t *joints; iqmjoint2_t *joints2; matrix3x4_t *frames; matrix3x4_t *outframe; matrix3x4_t *baseframe; int num_poses; int num_triangles; iqmtriangle_t *tris; mnormal_t *normal; mnormal_t *animatenormal; mtangent_t *tangent; mtangent_t *animatetangent; unsigned char *blendindexes; unsigned char *blendweights; char skinname[MAX_QPATH]; char *jointname; //end iqm //md2 only byte *tangents; fstvert_t *st; neighbors_t *neighbors; //ragdoll info int hasRagDoll; mragdoll_t ragdoll; //simple item texnum int simple_texnum; simplecolor_t simple_color; } model_t; //============================================================================ void Mod_Init (void); void Mod_ClearAll (void); model_t *Mod_ForName (char *name, qboolean crash); mleaf_t *Mod_PointInLeaf (float *p, model_t *model); byte *Mod_ClusterPVS (int cluster, model_t *model); void Mod_Modellist_f (void); void *Hunk_Begin (int maxsize); void *Hunk_Alloc (int size); int Hunk_End (void); void Hunk_Free (void *base); void Mod_Free (model_t *mod); void Mod_FreeAll (void); alien-arena-7.66+dfsg/source/ref_gl/r_vlights.c0000600000175000017500000000536712161402007020526 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "r_local.h" #define VLIGHT_CLAMP_MIN 50.0f #define VLIGHT_CLAMP_MAX 256.0f #define VLIGHT_GRIDSIZE_X 64 #define VLIGHT_GRIDSIZE_Y 64 vec3_t vlightgrid[VLIGHT_GRIDSIZE_X][VLIGHT_GRIDSIZE_Y]; void VLight_InitAnormTable (void) { int x, y; float angle; float sp, sy, cp, cy; for ( x = 0; x < VLIGHT_GRIDSIZE_X; x++ ) { angle = (x * 360 / VLIGHT_GRIDSIZE_X) * ( M_PI / 180.0f ); sy = sin(angle); cy = cos(angle); for ( y = 0; y < VLIGHT_GRIDSIZE_Y; y++ ) { angle = (y * 360 / VLIGHT_GRIDSIZE_X) * ( M_PI / 180.0f ); sp = sin(angle); cp = cos(angle); vlightgrid[x][y][0] = cp*cy; vlightgrid[x][y][1] = cp*sy; vlightgrid[x][y][2] = -sp; } } } float VLight_GetLightValue ( vec3_t normal, vec3_t dir, float apitch, float ayaw ) { int pitchofs, yawofs; float angle1, angle2, light; ayaw += 90; if ( normal[1] == 0 && normal[0] == 0 ) { angle2 = 0; if ( normal[2] > 0 ) angle1 = 90; else angle1 = 270; } else { float forward; angle2 = atan2( normal[1], normal[0] ) * ( 180.0f / M_PI ); if (angle2 < 0) angle2 += 360; forward = sqrt ( normal[0]*normal[0] + normal[1]*normal[1] ); angle1 = atan2( normal[2], forward ) * ( 180.0f / M_PI ); if (angle1 < 0) angle1 += 360; } pitchofs = ( angle1 + apitch ) * VLIGHT_GRIDSIZE_X / 360; yawofs = ( angle2 + ayaw ) * VLIGHT_GRIDSIZE_Y / 360; while (pitchofs > (VLIGHT_GRIDSIZE_X-1)) pitchofs -= VLIGHT_GRIDSIZE_X; while (pitchofs < 0) pitchofs += VLIGHT_GRIDSIZE_X; while (yawofs > (VLIGHT_GRIDSIZE_Y-1)) yawofs -= VLIGHT_GRIDSIZE_Y; while (yawofs < 0) yawofs += VLIGHT_GRIDSIZE_Y; light = ( DotProduct( vlightgrid[pitchofs][yawofs], dir ) + 2.0f ) * 1.5f; if (light > VLIGHT_CLAMP_MAX) light = VLIGHT_CLAMP_MAX; if (light < VLIGHT_CLAMP_MIN) light = VLIGHT_CLAMP_MIN; return light * ( 1.0f / 256.0f ); } void VLight_Init (void) { VLight_InitAnormTable (); } alien-arena-7.66+dfsg/source/ref_gl/r_program.c0000600000175000017500000020652012161402007020507 0ustar zero79zero79/* Copyright (C) 2009 COR Entertainment, LLC This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // r_program.c #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "r_local.h" //ARB fragment program extensions PFNGLGENPROGRAMSARBPROC qglGenProgramsARB = NULL; PFNGLDELETEPROGRAMSARBPROC qglDeleteProgramsARB = NULL; PFNGLBINDPROGRAMARBPROC qglBindProgramARB = NULL; PFNGLPROGRAMSTRINGARBPROC qglProgramStringARB = NULL; PFNGLPROGRAMENVPARAMETER4FARBPROC qglProgramEnvParameter4fARB = NULL; PFNGLPROGRAMLOCALPARAMETER4FARBPROC qglProgramLocalParameter4fARB = NULL; unsigned int g_water_program_id; char *fragment_program_text; //GLSL PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB = NULL; PFNGLDELETEOBJECTARBPROC glDeleteObjectARB = NULL; PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB = NULL; PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB = NULL; PFNGLSHADERSOURCEARBPROC glShaderSourceARB = NULL; PFNGLCOMPILESHADERARBPROC glCompileShaderARB = NULL; PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB = NULL; PFNGLATTACHOBJECTARBPROC glAttachObjectARB = NULL; PFNGLGETINFOLOGARBPROC glGetInfoLogARB = NULL; PFNGLLINKPROGRAMARBPROC glLinkProgramARB = NULL; PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB = NULL; PFNGLUNIFORM3FARBPROC glUniform3fARB = NULL; PFNGLUNIFORM2FARBPROC glUniform2fARB = NULL; PFNGLUNIFORM1IARBPROC glUniform1iARB = NULL; PFNGLUNIFORM1FARBPROC glUniform1fARB = NULL; PFNGLUNIFORMMATRIX3FVARBPROC glUniformMatrix3fvARB = NULL; PFNGLUNIFORMMATRIX3X4FVARBPROC glUniformMatrix3x4fvARB = NULL; PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB = NULL; PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB = NULL; PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB = NULL; PFNGLBINDATTRIBLOCATIONARBPROC glBindAttribLocationARB = NULL; GLhandleARB g_programObj; GLhandleARB g_shadowprogramObj; GLhandleARB g_waterprogramObj; GLhandleARB g_meshprogramObj; GLhandleARB g_glassprogramObj; GLhandleARB g_blankmeshprogramObj; GLhandleARB g_fbprogramObj; GLhandleARB g_blurprogramObj; GLhandleARB g_rblurprogramObj; GLhandleARB g_dropletsprogramObj; GLhandleARB g_godraysprogramObj; GLhandleARB g_vertexShader; GLhandleARB g_fragmentShader; //standard bsp GLuint g_location_surfTexture; GLuint g_location_eyePos; GLuint g_tangentSpaceTransform; GLuint g_location_heightTexture; GLuint g_location_lmTexture; GLuint g_location_normalTexture; GLuint g_location_bspShadowmapTexture; GLuint g_location_bspShadowmapTexture2; GLuint g_location_fog; GLuint g_location_parallax; GLuint g_location_dynamic; GLuint g_location_shadowmap; GLuint g_Location_statshadow; GLuint g_location_xOffs; GLuint g_location_yOffs; GLuint g_location_lightPosition; GLuint g_location_staticLightPosition; GLuint g_location_lightColour; GLuint g_location_lightCutoffSquared; GLuint g_location_liquid; GLuint g_location_shiny; GLuint g_location_rsTime; GLuint g_location_liquidTexture; GLuint g_location_liquidNormTex; GLuint g_location_chromeTex; //shadow on white bsp polys GLuint g_location_entShadow; GLuint g_location_fadeShadow; GLuint g_location_xOffset; GLuint g_location_yOffset; //water GLuint g_location_baseTexture; GLuint g_location_normTexture; GLuint g_location_refTexture; GLuint g_location_waterEyePos; GLuint g_location_tangentSpaceTransform; GLuint g_location_time; GLuint g_location_lightPos; GLuint g_location_reflect; GLuint g_location_trans; GLuint g_location_fogamount; //mesh GLuint g_location_meshlightPosition; GLuint g_location_baseTex; GLuint g_location_normTex; GLuint g_location_fxTex; GLuint g_location_fx2Tex; GLuint g_location_color; GLuint g_location_meshNormal; GLuint g_location_meshTime; GLuint g_location_meshFog; GLuint g_location_useFX; GLuint g_location_useGlow; GLuint g_location_useShell; GLuint g_location_useCube; GLuint g_location_useGPUanim; GLuint g_location_outframe; GLuint g_location_fromView; //glass GLuint g_location_gmirTexture; GLuint g_location_grefTexture; GLuint g_location_gLightPos; GLuint g_location_gFog; GLuint g_location_gOutframe; //blank mesh GLuint g_location_bmOutframe; //fullscreen distortion effects GLuint g_location_framebuffTex; GLuint g_location_distortTex; GLuint g_location_dParams; GLuint g_location_fxPos; //gaussian blur GLuint g_location_scale; GLuint g_location_source; //radial blur GLuint g_location_rscale; GLuint g_location_rsource; GLuint g_location_rparams; //water droplets GLuint g_location_drSource; GLuint g_location_drTex; GLuint g_location_drTime; GLuint g_location_drParams; //god rays GLuint g_location_lightPositionOnScreen; GLuint g_location_sunTex; GLuint g_location_godrayScreenAspect; GLuint g_location_sunRadius; //doesn't work with ARB shaders, unfortunately, due to the #comments #define STRINGIFY(...) #__VA_ARGS__ static char water_ARB_program[] = "!!ARBfp1.0\n" "# Scroll and scale the distortion texture coordinates.\n" "# Scroll coordinates are specified externally.\n" "PARAM scroll1 = program.local[0];\n" "PARAM scroll2 = program.local[1];\n" "PARAM texScale1 = { 0.008, 0.008, 1.0, 1.0 };\n" "PARAM texScale2 = { 0.007, 0.007, 1.0, 1.0 };\n" "TEMP texCoord1;\n" "TEMP texCoord2;\n" "MUL texCoord1, fragment.texcoord[1], texScale1;\n" "MUL texCoord2, fragment.texcoord[1], texScale2;\n" "ADD texCoord1, texCoord1, scroll1;\n" "ADD texCoord2, texCoord2, scroll2;\n" "# Load the distortion textures and add them together.\n" "TEMP distortColor;\n" "TEMP distortColor2;\n" "TXP distortColor, texCoord1, texture[0], 2D;\n" "TXP distortColor2, texCoord2, texture[0], 2D;\n" "ADD distortColor, distortColor, distortColor2;\n" "# Subtract 1.0 and scale by 2.0.\n" "# Textures will be distorted from -2.0 to 2.0 texels.\n" "PARAM scaleFactor = { 2.0, 2.0, 2.0, 2.0 };\n" "PARAM one = { 1.0, 1.0, 1.0, 1.0 };\n" "SUB distortColor, distortColor, one;\n" "MUL distortColor, distortColor, scaleFactor;\n" "# Apply distortion to reflection texture coordinates.\n" "TEMP distortCoord;\n" "TEMP endColor;\n" "ADD distortCoord, distortColor, fragment.texcoord[0];\n" "TXP endColor, distortCoord, texture, 2D;\n" "# Get a vector from the surface to the view origin\n" "PARAM vieworg = program.local[2];\n" "TEMP eyeVec;\n" "TEMP trans;\n" "SUB eyeVec, vieworg, fragment.texcoord[1];\n" "# Normalize the vector to the eye position\n" "TEMP temp;\n" "TEMP invLen;\n" "DP3 temp, eyeVec, eyeVec;\n" "RSQ invLen, temp.x;\n" "MUL eyeVec, eyeVec, invLen;\n" "ABS eyeVec.z, eyeVec.z; # so it works underwater, too\n" "# Load the ripple normal map\n" "TEMP normalColor;\n" "TEMP normalColor2;\n" "# Scale texture\n" "MUL texCoord1, fragment.texcoord[2], texScale2;\n" "MUL texCoord2, fragment.texcoord[2], texScale1;\n" "# Scroll texture\n" "ADD texCoord1, texCoord1, scroll1;\n" "ADD texCoord2, texCoord2, scroll2;\n" "# Get texel color\n" "TXP normalColor, texCoord1, texture[1], 2D;\n" "TXP normalColor2, texCoord2, texture[1], 2D;\n" "# Combine normal maps\n" "ADD normalColor, normalColor, normalColor2;\n" "SUB normalColor, normalColor, 1.0;\n" "# Normalize normal texture\n" "DP3 temp, normalColor, normalColor;\n" "RSQ invLen, temp.x;\n" "MUL normalColor, invLen, normalColor;\n" "# Fresenel approximation\n" "DP3 trans.w, normalColor, eyeVec;\n" "SUB endColor.w, 1.0, trans.w;\n" "MAX endColor.w, endColor.w, 0.4; # MAX sets the min? How odd.\n" "MIN endColor.w, endColor.w, 0.9; # Leave a LITTLE bit of transparency always\n" "# Put the color in the output (TODO: put this in final OP)\n" "MOV result.color, endColor;\n" "END\n"; void R_LoadARBPrograms(void) { if (strstr(gl_config.extensions_string, "GL_ARB_fragment_program")) { gl_state.fragment_program = true; qglGenProgramsARB = (PFNGLGENPROGRAMSARBPROC)qwglGetProcAddress("glGenProgramsARB"); qglDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC)qwglGetProcAddress("glDeleteProgramsARB"); qglBindProgramARB = (PFNGLBINDPROGRAMARBPROC)qwglGetProcAddress("glBindProgramARB"); qglProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC)qwglGetProcAddress("glProgramStringARB"); qglProgramEnvParameter4fARB = (PFNGLPROGRAMENVPARAMETER4FARBPROC)qwglGetProcAddress("glProgramEnvParameter4fARB"); qglProgramLocalParameter4fARB = (PFNGLPROGRAMLOCALPARAMETER4FARBPROC)qwglGetProcAddress("glProgramLocalParameter4fARB"); if (!(qglGenProgramsARB && qglDeleteProgramsARB && qglBindProgramARB && qglProgramStringARB && qglProgramEnvParameter4fARB && qglProgramLocalParameter4fARB)) { gl_state.fragment_program = false; Com_Printf("...GL_ARB_fragment_program not found\n"); } } else { gl_state.fragment_program = false; Com_Printf("...GL_ARB_fragment_program not found\n"); } if (gl_state.fragment_program) { gl_arb_fragment_program = Cvar_Get("gl_arb_fragment_program", "1", CVAR_ARCHIVE); qglGenProgramsARB(1, &g_water_program_id); qglBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, g_water_program_id); qglProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, 1.0f, 0.1f, 0.6f, 0.5f); qglProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(water_ARB_program), water_ARB_program); // Make sure the program loaded correctly { int err = 0; assert((err = qglGetError()) == GL_NO_ERROR); err = err; // for debugging only -- todo, remove } } else gl_arb_fragment_program = Cvar_Get("gl_arb_fragment_program", "0", CVAR_ARCHIVE); } //GLSL Programs //BSP Surfaces static char bsp_vertex_program[] = "#version 120\n" STRINGIFY ( uniform mat3 tangentSpaceTransform; uniform vec3 Eye; uniform vec3 lightPosition; uniform vec3 staticLightPosition; uniform float rsTime; uniform int LIQUID; uniform int FOG; uniform int PARALLAX; uniform int DYNAMIC; uniform int SHINY; const float Eta = 0.66; const float FresnelPower = 5.0; const float F = ((1.0-Eta) * (1.0-Eta))/((1.0+Eta) * (1.0+Eta)); varying float FresRatio; varying vec3 EyeDir; varying vec3 LightDir; varying vec3 StaticLightDir; varying vec4 sPos; varying float fog; void main( void ) { sPos = gl_Vertex; gl_Position = ftransform(); if(SHINY > 0) { vec3 norm = vec3(0, 0, 1); vec4 neyeDir = gl_ModelViewMatrix * gl_Vertex; vec3 refeyeDir = neyeDir.xyz / neyeDir.w; refeyeDir = normalize(refeyeDir); FresRatio = F + (1.0-F) * pow((1.0-dot(refeyeDir,norm)),FresnelPower); } gl_FrontColor = gl_Color; EyeDir = tangentSpaceTransform * ( Eye - gl_Vertex.xyz ); if (DYNAMIC > 0) { LightDir = tangentSpaceTransform * (lightPosition - gl_Vertex.xyz); } if (PARALLAX > 0) { StaticLightDir = tangentSpaceTransform * (staticLightPosition - gl_Vertex.xyz); } // pass any active texunits through gl_TexCoord[0] = gl_MultiTexCoord0; gl_TexCoord[1] = gl_MultiTexCoord1; //fog if(FOG > 0){ fog = (gl_Position.z - gl_Fog.start) / (gl_Fog.end - gl_Fog.start); fog = clamp(fog, 0.0, 1.0); } } ); static char bsp_fragment_program[] = "#version 120\n" STRINGIFY ( uniform sampler2D surfTexture; uniform sampler2D HeightTexture; uniform sampler2D NormalTexture; uniform sampler2D lmTexture; uniform sampler2D liquidTexture; uniform sampler2D liquidNormTex; uniform sampler2D chromeTex; uniform sampler2DShadow ShadowMap; uniform sampler2DShadow StatShadowMap; uniform vec3 lightColour; uniform float lightCutoffSquared; uniform int FOG; uniform int PARALLAX; uniform int DYNAMIC; uniform int STATSHADOW; uniform int SHADOWMAP; uniform int LIQUID; uniform int SHINY; uniform float rsTime; uniform float xPixelOffset; uniform float yPixelOffset; varying float FresRatio; varying vec4 sPos; varying vec3 EyeDir; varying vec3 LightDir; varying vec3 StaticLightDir; varying float fog; vec4 ShadowCoord; float lookup( vec2 offSet, sampler2DShadow Map) { return shadow2DProj(Map, ShadowCoord + vec4(offSet.x * xPixelOffset * ShadowCoord.w, offSet.y * yPixelOffset * ShadowCoord.w, 0.05, 0.0) ).w; } float lookupShadow( sampler2DShadow Map ) { float shadow = 1.0; if(SHADOWMAP > 0) { if (ShadowCoord.w > 1.0) { vec2 o = mod(floor(gl_FragCoord.xy), 2.0); shadow += lookup(vec2(-1.5, 1.5) + o, Map); shadow += lookup(vec2( 0.5, 1.5) + o, Map); shadow += lookup(vec2(-1.5, -0.5) + o, Map); shadow += lookup(vec2( 0.5, -0.5) + o, Map); shadow *= 0.25 ; } shadow += 0.2; if(shadow > 1.0) shadow = 1.0; } return shadow; } void main( void ) { vec4 diffuse; vec4 lightmap; vec4 alphamask; vec4 bloodColor; float distanceSquared; vec3 relativeLightDirection; float diffuseTerm; vec3 halfAngleVector; float specularTerm; float swamp; float attenuation; vec4 litColour; vec3 varyingLightColour; float varyingLightCutoffSquared; float dynshadowval; float statshadowval; vec2 displacement; vec2 displacement2; vec2 displacement3; vec2 displacement4; varyingLightColour = lightColour; varyingLightCutoffSquared = lightCutoffSquared; vec3 relativeEyeDirection = normalize( EyeDir ); vec3 normal = 2.0 * ( texture2D( NormalTexture, gl_TexCoord[0].xy).xyz - vec3( 0.5, 0.5, 0.5 ) ); vec3 textureColour = texture2D( surfTexture, gl_TexCoord[0].xy ).rgb; lightmap = texture2D( lmTexture, gl_TexCoord[1].st ); alphamask = texture2D( surfTexture, gl_TexCoord[0].xy ); //shadows if(DYNAMIC > 0) { ShadowCoord = gl_TextureMatrix[7] * sPos; dynshadowval = lookupShadow(ShadowMap); } else dynshadowval = 0.0; if(STATSHADOW > 0) { ShadowCoord = gl_TextureMatrix[6] * sPos; statshadowval = lookupShadow(StatShadowMap); } else statshadowval = 1.0; bloodColor = vec4(0.0, 0.0, 0.0, 0.0); displacement4 = vec2(0.0, 0.0); if(LIQUID > 0) { vec3 noiseVec; vec3 noiseVec2; vec3 noiseVec3; //for liquid fx scrolling vec4 texco = gl_TexCoord[0]; texco.t = texco.t - rsTime*1.0/LIQUID; vec4 texco2 = gl_TexCoord[0]; texco2.t = texco2.t - rsTime*0.9/LIQUID; //shift the horizontal here a bit texco2.s = texco2.s/1.5; vec4 texco3 = gl_TexCoord[0]; texco3.t = texco3.t - rsTime*0.6/LIQUID; vec4 Offset = texture2D( HeightTexture,gl_TexCoord[0].xy ); Offset = Offset * 0.04 - 0.02; vec2 TexCoords = Offset.xy * relativeEyeDirection.xy + gl_TexCoord[0].xy; displacement = texco.st; noiseVec = normalize(texture2D(liquidNormTex, texco.st)).xyz; noiseVec = (noiseVec * 2.0 - 0.635) * 0.035; displacement2 = texco2.st; noiseVec2 = normalize(texture2D(liquidNormTex, displacement2.xy)).xyz; noiseVec2 = (noiseVec2 * 2.0 - 0.635) * 0.035; if(LIQUID > 2) { displacement3 = texco3.st; noiseVec3 = normalize(texture2D(liquidNormTex, displacement3.xy)).xyz; noiseVec3 = (noiseVec3 * 2.0 - 0.635) * 0.035; } else { //used for water effect only displacement4.x = noiseVec.x + noiseVec2.x; displacement4.y = noiseVec.y + noiseVec2.y; } displacement.x = texco.s + noiseVec.x + TexCoords.x; displacement.y = texco.t + noiseVec.y + TexCoords.y; displacement2.x = texco2.s + noiseVec2.x + TexCoords.x; displacement2.y = texco2.t + noiseVec2.y + TexCoords.y; displacement3.x = texco3.s + noiseVec3.x + TexCoords.x; displacement3.y = texco3.t + noiseVec3.y + TexCoords.y; if(LIQUID > 2) { vec4 diffuse1 = texture2D(liquidTexture, texco.st + displacement.xy); vec4 diffuse2 = texture2D(liquidTexture, texco2.st + displacement2.xy); vec4 diffuse3 = texture2D(liquidTexture, texco3.st + displacement3.xy); vec4 diffuse4 = texture2D(liquidTexture, gl_TexCoord[0].st + displacement4.xy); bloodColor = max(diffuse1, diffuse2); bloodColor = max(bloodColor, diffuse3); } } if(PARALLAX > 0) { //do the parallax mapping vec4 Offset = texture2D( HeightTexture,gl_TexCoord[0].xy ); Offset = Offset * 0.04 - 0.02; vec2 TexCoords = Offset.xy * relativeEyeDirection.xy + gl_TexCoord[0].xy + displacement4.xy; diffuse = texture2D( surfTexture, TexCoords ); relativeLightDirection = normalize (StaticLightDir); diffuseTerm = dot( normal, relativeLightDirection ); if( diffuseTerm > 0.0 ) { halfAngleVector = normalize( relativeLightDirection + relativeEyeDirection ); specularTerm = clamp( dot( normal, halfAngleVector ), 0.0, 1.0 ); specularTerm = pow( specularTerm, 32.0 ); litColour = vec4 (specularTerm + ( 3.0 * diffuseTerm ) * textureColour, 6.0); } else { litColour = vec4( 0.0, 0.0, 0.0, 6.0 ); } gl_FragColor = max(litColour, diffuse * 2.0); gl_FragColor = (gl_FragColor * lightmap) + bloodColor; gl_FragColor = (gl_FragColor * statshadowval); } else { diffuse = texture2D(surfTexture, gl_TexCoord[0].xy); gl_FragColor = (diffuse * lightmap * 2.0); gl_FragColor = (gl_FragColor * statshadowval); } if(DYNAMIC > 0) { lightmap = texture2D(lmTexture, gl_TexCoord[1].st); //now do the dynamic lighting distanceSquared = dot( LightDir, LightDir ); relativeLightDirection = LightDir / sqrt( distanceSquared ); diffuseTerm = clamp( dot( normal, relativeLightDirection ), 0.0, 1.0 ); vec3 colour = vec3( 0.0, 0.0, 0.0 ); if( diffuseTerm > 0.0 ) { halfAngleVector = normalize( relativeLightDirection + relativeEyeDirection ); float specularTerm = clamp( dot( normal, halfAngleVector ), 0.0, 1.0 ); specularTerm = pow( specularTerm, 32.0 ); colour = specularTerm * vec3( 1.0, 1.0, 1.0 ) / 2.0; } attenuation = clamp( 1.0 - ( distanceSquared / varyingLightCutoffSquared ), 0.0, 1.0 ); swamp = attenuation; swamp *= swamp; swamp *= swamp; swamp *= swamp; colour += ( ( ( 0.5 - swamp ) * diffuseTerm ) + swamp ) * textureColour * 3.0; vec4 dynamicColour = vec4( attenuation * colour * dynshadowval * varyingLightColour, 1.0 ); if(PARALLAX > 0) { dynamicColour = max(dynamicColour, gl_FragColor); } else { dynamicColour = max(dynamicColour, vec4(textureColour, 1.0) * lightmap * 2.0); } gl_FragColor = dynamicColour; } gl_FragColor = mix(vec4(0.0, 0.0, 0.0, alphamask.a), gl_FragColor, alphamask.a); if(SHINY > 0) { vec3 reflection = reflect(relativeEyeDirection, normal); vec3 refraction = refract(relativeEyeDirection, normal, 0.66); vec4 Tl = texture2DProj(chromeTex, vec4(reflection.xy, 1.0, 1.0) ); vec4 Tr = texture2DProj(chromeTex, vec4(refraction.xy, 1.0, 1.0) ); vec4 cubemap = mix(Tl,Tr,FresRatio); gl_FragColor = max(gl_FragColor, (cubemap * 0.05 * alphamask.a)); } if(FOG > 0) gl_FragColor = mix(gl_FragColor, gl_Fog.color, fog); } ); static char bsp_fragment_program_ATI[] = "#version 120\n" STRINGIFY ( uniform sampler2D surfTexture; uniform sampler2D HeightTexture; uniform sampler2D NormalTexture; uniform sampler2D lmTexture; uniform sampler2D liquidTexture; uniform sampler2D liquidNormTex; uniform sampler2D chromeTex; uniform sampler2D ShadowMap; uniform sampler2D StatShadowMap; uniform vec3 lightColour; uniform float lightCutoffSquared; uniform int FOG; uniform int PARALLAX; uniform int DYNAMIC; uniform int STATSHADOW; uniform int SHADOWMAP; uniform int LIQUID; uniform int SHINY; uniform float rsTime; uniform float xPixelOffset; uniform float yPixelOffset; varying float FresRatio; varying vec4 sPos; varying vec3 EyeDir; varying vec3 LightDir; varying vec3 StaticLightDir; varying float fog; vec4 ShadowCoord; float lookup( vec2 offSet, sampler2D Map) { float shadow = 1.0; vec4 shadowCoordinateWdivide = (ShadowCoord + vec4(offSet.x * xPixelOffset * ShadowCoord.w, offSet.y * yPixelOffset * ShadowCoord.w, 0.0, 0.0)) / ShadowCoord.w ; // Used to lower moir pattern and self-shadowing shadowCoordinateWdivide.z += 0.0005; float distanceFromLight = texture2D(Map, shadowCoordinateWdivide.xy).z; if (ShadowCoord.w > 0.0) shadow = distanceFromLight < shadowCoordinateWdivide.z ? 0.25 : 1.0 ; return shadow; } float lookupShadow( sampler2D Map ) { float shadow = 1.0; if(SHADOWMAP > 0) { if (ShadowCoord.w > 1.0) { vec2 o = mod(floor(gl_FragCoord.xy), 2.0); shadow += lookup(vec2(-1.5, 1.5) + o, Map); shadow += lookup(vec2( 0.5, 1.5) + o, Map); shadow += lookup(vec2(-1.5, -0.5) + o, Map); shadow += lookup(vec2( 0.5, -0.5) + o, Map); shadow *= 0.25 ; } if(shadow > 1.0) shadow = 1.0; } return shadow; } void main( void ) { vec4 diffuse; vec4 lightmap; vec4 alphamask; vec4 bloodColor; float distanceSquared; vec3 relativeLightDirection; float diffuseTerm; vec3 halfAngleVector; float specularTerm; float swamp; float attenuation; vec4 litColour; vec3 varyingLightColour; float varyingLightCutoffSquared; float dynshadowval; float statshadowval; vec2 displacement; vec2 displacement2; vec2 displacement3; vec2 displacement4; varyingLightColour = lightColour; varyingLightCutoffSquared = lightCutoffSquared; vec3 relativeEyeDirection = normalize( EyeDir ); vec3 normal = 2.0 * ( texture2D( NormalTexture, gl_TexCoord[0].xy).xyz - vec3( 0.5, 0.5, 0.5 ) ); vec3 textureColour = texture2D( surfTexture, gl_TexCoord[0].xy ).rgb; lightmap = texture2D( lmTexture, gl_TexCoord[1].st ); alphamask = texture2D( surfTexture, gl_TexCoord[0].xy ); //shadows if(DYNAMIC > 0) { ShadowCoord = gl_TextureMatrix[7] * sPos; dynshadowval = lookupShadow(ShadowMap); } else dynshadowval = 0.0; if(STATSHADOW > 0) { ShadowCoord = gl_TextureMatrix[6] * sPos; statshadowval = lookupShadow(StatShadowMap); } else statshadowval = 1.0; bloodColor = vec4(0.0, 0.0, 0.0, 0.0); displacement4 = vec2(0.0, 0.0); if(LIQUID > 0) { vec3 noiseVec; vec3 noiseVec2; vec3 noiseVec3; //for liquid fx scrolling vec4 texco = gl_TexCoord[0]; texco.t = texco.t - rsTime*1.0/LIQUID; vec4 texco2 = gl_TexCoord[0]; texco2.t = texco2.t - rsTime*0.9/LIQUID; //shift the horizontal here a bit texco2.s = texco2.s/1.5; vec4 texco3 = gl_TexCoord[0]; texco3.t = texco3.t - rsTime*0.6/LIQUID; vec4 Offset = texture2D( HeightTexture,gl_TexCoord[0].xy ); Offset = Offset * 0.04 - 0.02; vec2 TexCoords = Offset.xy * relativeEyeDirection.xy + gl_TexCoord[0].xy; displacement = texco.st; noiseVec = normalize(texture2D(liquidNormTex, texco.st)).xyz; noiseVec = (noiseVec * 2.0 - 0.635) * 0.035; displacement2 = texco2.st; noiseVec2 = normalize(texture2D(liquidNormTex, displacement2.xy)).xyz; noiseVec2 = (noiseVec2 * 2.0 - 0.635) * 0.035; if(LIQUID > 2) { displacement3 = texco3.st; noiseVec3 = normalize(texture2D(liquidNormTex, displacement3.xy)).xyz; noiseVec3 = (noiseVec3 * 2.0 - 0.635) * 0.035; } else { //used for water effect only displacement4.x = noiseVec.x + noiseVec2.x; displacement4.y = noiseVec.y + noiseVec2.y; } displacement.x = texco.s + noiseVec.x + TexCoords.x; displacement.y = texco.t + noiseVec.y + TexCoords.y; displacement2.x = texco2.s + noiseVec2.x + TexCoords.x; displacement2.y = texco2.t + noiseVec2.y + TexCoords.y; displacement3.x = texco3.s + noiseVec3.x + TexCoords.x; displacement3.y = texco3.t + noiseVec3.y + TexCoords.y; if(LIQUID > 2) { vec4 diffuse1 = texture2D(liquidTexture, texco.st + displacement.xy); vec4 diffuse2 = texture2D(liquidTexture, texco2.st + displacement2.xy); vec4 diffuse3 = texture2D(liquidTexture, texco3.st + displacement3.xy); vec4 diffuse4 = texture2D(liquidTexture, gl_TexCoord[0].st + displacement4.xy); bloodColor = max(diffuse1, diffuse2); bloodColor = max(bloodColor, diffuse3); } } if(PARALLAX > 0) { //do the parallax mapping vec4 Offset = texture2D( HeightTexture,gl_TexCoord[0].xy ); Offset = Offset * 0.04 - 0.02; vec2 TexCoords = Offset.xy * relativeEyeDirection.xy + gl_TexCoord[0].xy + displacement4.xy; diffuse = texture2D( surfTexture, TexCoords ); relativeLightDirection = normalize (StaticLightDir); diffuseTerm = dot( normal, relativeLightDirection ); if( diffuseTerm > 0.0 ) { halfAngleVector = normalize( relativeLightDirection + relativeEyeDirection ); specularTerm = clamp( dot( normal, halfAngleVector ), 0.0, 1.0 ); specularTerm = pow( specularTerm, 32.0 ); litColour = vec4 (specularTerm + ( 3.0 * diffuseTerm ) * textureColour, 6.0); } else { litColour = vec4( 0.0, 0.0, 0.0, 6.0 ); } gl_FragColor = max(litColour, diffuse * 2.0); gl_FragColor = (gl_FragColor * lightmap) + bloodColor; gl_FragColor = (gl_FragColor * statshadowval); } else { diffuse = texture2D(surfTexture, gl_TexCoord[0].xy); gl_FragColor = (diffuse * lightmap * 2.0); gl_FragColor = (gl_FragColor * statshadowval); } if(DYNAMIC > 0) { lightmap = texture2D(lmTexture, gl_TexCoord[1].st); //now do the dynamic lighting distanceSquared = dot( LightDir, LightDir ); relativeLightDirection = LightDir / sqrt( distanceSquared ); diffuseTerm = clamp( dot( normal, relativeLightDirection ), 0.0, 1.0 ); vec3 colour = vec3( 0.0, 0.0, 0.0 ); if( diffuseTerm > 0.0 ) { halfAngleVector = normalize( relativeLightDirection + relativeEyeDirection ); float specularTerm = clamp( dot( normal, halfAngleVector ), 0.0, 1.0 ); specularTerm = pow( specularTerm, 32.0 ); colour = specularTerm * vec3( 1.0, 1.0, 1.0 ) / 2.0; } attenuation = clamp( 1.0 - ( distanceSquared / varyingLightCutoffSquared ), 0.0, 1.0 ); swamp = attenuation; swamp *= swamp; swamp *= swamp; swamp *= swamp; colour += ( ( ( 0.5 - swamp ) * diffuseTerm ) + swamp ) * textureColour * 3.0; vec4 dynamicColour = vec4( attenuation * colour * dynshadowval * varyingLightColour, 1.0 ); if(PARALLAX > 0) { dynamicColour = max(dynamicColour, gl_FragColor); } else { dynamicColour = max(dynamicColour, vec4(textureColour, 1.0) * lightmap * 2.0); } gl_FragColor = dynamicColour; } gl_FragColor = mix(vec4(0.0, 0.0, 0.0, alphamask.a), gl_FragColor, alphamask.a); if(SHINY > 0) { vec3 reflection = reflect(relativeEyeDirection, normal); vec3 refraction = refract(relativeEyeDirection, normal, 0.66); vec4 Tl = texture2DProj(chromeTex, vec4(reflection.xy, 1.0, 1.0) ); vec4 Tr = texture2DProj(chromeTex, vec4(refraction.xy, 1.0, 1.0) ); vec4 cubemap = mix(Tl,Tr,FresRatio); gl_FragColor = max(gl_FragColor, (cubemap * 0.05 * alphamask.a)); } if(FOG > 0) gl_FragColor = mix(gl_FragColor, gl_Fog.color, fog); } ); //SHADOWS static char shadow_vertex_program[] = "#version 120\n" STRINGIFY ( varying vec4 ShadowCoord; void main( void ) { ShadowCoord = gl_TextureMatrix[6] * gl_Vertex; gl_Position = ftransform(); gl_Position.z -= 0.05; //eliminate z-fighting on some drivers } ); static char shadow_fragment_program[] = "#version 120\n" STRINGIFY ( uniform sampler2DShadow StatShadowMap; uniform float fadeShadow; uniform float xPixelOffset; uniform float yPixelOffset; varying vec4 ShadowCoord; float lookup( vec2 offSet) { return shadow2DProj(StatShadowMap, ShadowCoord + vec4(offSet.x * xPixelOffset * ShadowCoord.w, offSet.y * yPixelOffset * ShadowCoord.w, 0.05, 0.0) ).w; } float lookupStatshadow( void ) { float shadow = 1.0; if (ShadowCoord.w > 1.0) { vec2 o = mod(floor(gl_FragCoord.xy), 2.0); shadow += lookup(vec2(-1.5, 1.5) + o); shadow += lookup(vec2( 0.5, 1.5) + o); shadow += lookup(vec2(-1.5, -0.5) + o); shadow += lookup(vec2( 0.5, -0.5) + o); shadow *= 0.25 ; } shadow += 0.3; if(shadow > 1.0) shadow = 1.0; return shadow; } void main( void ) { float statshadowval = 1/fadeShadow * lookupStatshadow(); gl_FragColor = vec4(1.0); gl_FragColor = (gl_FragColor * statshadowval); } ); static char shadow_fragment_program_ATI[] = "#version 120\n" STRINGIFY ( uniform sampler2D StatShadowMap; uniform float fadeShadow; uniform float xPixelOffset; uniform float yPixelOffset; varying vec4 ShadowCoord; float lookup( vec2 offSet) { float shadow = 1.0; vec4 shadowCoordinateWdivide = (ShadowCoord + vec4(offSet.x * xPixelOffset * ShadowCoord.w, offSet.y * yPixelOffset * ShadowCoord.w, 0.0, 0.0)) / ShadowCoord.w ; // Used to lower moir pattern and self-shadowing shadowCoordinateWdivide.z += 0.0005; float distanceFromLight = texture2D(StatShadowMap,shadowCoordinateWdivide.xy).z; if (ShadowCoord.w > 0.0) shadow = distanceFromLight < shadowCoordinateWdivide.z ? 0.25 : 1.0 ; return shadow; } float lookupStatshadow( void ) { float shadow = 1.0; if (ShadowCoord.w > 1.0) { vec2 o = mod(floor(gl_FragCoord.xy), 2.0); shadow += lookup(vec2(-1.5, 1.5) + o); shadow += lookup(vec2( 0.5, 1.5) + o); shadow += lookup(vec2(-1.5, -0.5) + o); shadow += lookup(vec2( 0.5, -0.5) + o); shadow *= 0.25 ; } if(shadow > 1.0) shadow = 1.0; return shadow; } void main( void ) { float statshadowval = 1/fadeShadow * lookupStatshadow(); gl_FragColor = vec4(1.0); gl_FragColor = (gl_FragColor * statshadowval); } ); //MESHES static char mesh_vertex_program[] = "#version 120\n" STRINGIFY ( uniform vec3 lightPos; uniform float time; uniform int FOG; uniform mat3x4 bonemats[70]; uniform int GPUANIM; uniform int useShell; uniform int useCube; attribute vec4 tangent; attribute vec4 weights; attribute vec4 bones; const float Eta = 0.66; const float FresnelPower = 5.0; const float F = ((1.0-Eta) * (1.0-Eta))/((1.0+Eta) * (1.0+Eta)); varying vec3 LightDir; varying vec3 EyeDir; varying float fog; varying float FresRatio; varying vec3 vertPos, lightVec; varying vec3 worldNormal; void subScatterVS(in vec4 ecVert) { if(useShell == 0 && useCube == 0) { lightVec = lightPos - ecVert.xyz; vertPos = ecVert.xyz; } } void main() { vec3 n; vec3 t; vec3 b; vec4 neyeDir; if(GPUANIM > 0) { mat3x4 m = bonemats[int(bones.x)] * weights.x; m += bonemats[int(bones.y)] * weights.y; m += bonemats[int(bones.z)] * weights.z; m += bonemats[int(bones.w)] * weights.w; vec4 mpos = vec4(gl_Vertex * m, gl_Vertex.w); gl_Position = gl_ModelViewProjectionMatrix * mpos; subScatterVS(gl_Position); n = normalize(gl_NormalMatrix * (vec4(gl_Normal, 0.0) * m)); t = normalize(gl_NormalMatrix * (vec4(tangent.xyz, 0.0) * m)); b = normalize(gl_NormalMatrix * (vec4(tangent.w, 0.0, 0.0, 0.0) * m)) * cross(n, t); EyeDir = vec3(gl_ModelViewMatrix * mpos); neyeDir = gl_ModelViewMatrix * mpos; } else { subScatterVS(gl_ModelViewProjectionMatrix * gl_Vertex); gl_Position = ftransform(); n = normalize(gl_NormalMatrix * gl_Normal); t = normalize(gl_NormalMatrix * tangent.xyz); b = tangent.w * cross(n, t); EyeDir = vec3(gl_ModelViewMatrix * gl_Vertex); neyeDir = gl_ModelViewMatrix * gl_Vertex;; } worldNormal = n; gl_TexCoord[0] = gl_MultiTexCoord0; vec3 v; v.x = dot(lightPos, t); v.y = dot(lightPos, b); v.z = dot(lightPos, n); LightDir = normalize(v); v.x = dot(EyeDir, t); v.y = dot(EyeDir, b); v.z = dot(EyeDir, n); EyeDir = normalize(v); //for scrolling fx vec4 texco = gl_MultiTexCoord0; texco.s = texco.s + time*1.0; texco.t = texco.t + time*2.0; gl_TexCoord[1] = texco; if(useShell > 0) gl_TexCoord[0] = texco; if(useCube > 0) { vec3 refeyeDir = neyeDir.xyz / neyeDir.w; refeyeDir = normalize(refeyeDir); FresRatio = F + (1.0-F) * pow((1.0-dot(refeyeDir, n)), FresnelPower); } //fog if(FOG > 0) { fog = (gl_Position.z - gl_Fog.start) / (gl_Fog.end - gl_Fog.start); fog = clamp(fog, 0.0, 0.3); //any higher and meshes disappear } } ); static char mesh_fragment_program[] = "#version 120\n" STRINGIFY ( uniform sampler2D baseTex; uniform sampler2D normalTex; uniform sampler2D fxTex; uniform sampler2D fx2Tex; uniform vec3 baseColor; uniform int GPUANIM; uniform int FOG; uniform int useFX; uniform int useCube; uniform int useGlow; uniform int useShell; uniform int fromView; uniform vec3 lightPos; const float SpecularFactor = 0.5; //next group could be made uniforms if we want to control this const float MaterialThickness = 2.0; //this val seems good for now const vec3 ExtinctionCoefficient = vec3(0.80, 0.12, 0.20); //controls subsurface value const float RimScalar = 10.0; //intensity of the rim effect varying vec3 LightDir; varying vec3 EyeDir; varying float fog; varying float FresRatio; varying vec3 vertPos, lightVec, worldNormal; float halfLambert(in vec3 vect1, in vec3 vect2) { float product = dot(vect1,vect2); return product * 0.5 + 0.5; } float blinnPhongSpecular(in vec3 normalVec, in vec3 lightVec, in float specPower) { vec3 halfAngle = normalize(normalVec + lightVec); return pow(clamp(0.0,1.0,dot(normalVec,halfAngle)),specPower); } void main() { vec3 litColor; vec4 fx; vec4 glow; vec4 scatterCol = vec4(0.0); vec3 textureColour = texture2D( baseTex, gl_TexCoord[0].xy ).rgb; vec3 normal = 2.0 * ( texture2D( normalTex, gl_TexCoord[0].xy).xyz - vec3( 0.5 ) ); vec4 alphamask = texture2D( baseTex, gl_TexCoord[0].xy); vec4 specmask = texture2D( normalTex, gl_TexCoord[0].xy); if(useShell == 0 && useCube == 0 && specmask.a < 1.0) { vec4 SpecColor = vec4(baseColor, 1.0)/2.0; float attenuation = 2.0 * (1.0 / distance(lightPos, vertPos)); vec3 wNorm = worldNormal; vec3 eVec = EyeDir; vec3 lVec = normalize(lightVec); vec4 dotLN = vec4(halfLambert(lVec, wNorm) * attenuation); vec3 indirectLightComponent = vec3(MaterialThickness * max(0.0,dot(-wNorm, lVec))); indirectLightComponent += MaterialThickness * halfLambert(-eVec, lVec); indirectLightComponent *= attenuation; indirectLightComponent.r *= ExtinctionCoefficient.r; indirectLightComponent.g *= ExtinctionCoefficient.g; indirectLightComponent.b *= ExtinctionCoefficient.b; vec3 rim = vec3(1.0 - max(0.0,dot(wNorm, eVec))); rim *= rim; rim *= max(0.0,dot(wNorm, lVec)) * SpecColor.rgb; scatterCol = dotLN + vec4(indirectLightComponent, 1.0); scatterCol.rgb += (rim * RimScalar * attenuation * scatterCol.a); scatterCol.rgb += vec3(blinnPhongSpecular(wNorm, lVec, SpecularFactor*2.0) * attenuation * SpecColor * scatterCol.a * 0.05); scatterCol.rgb *= baseColor; scatterCol.rgb /= (specmask.a*specmask.a);//we use the spec mask for scatter mask, presuming non-spec areas are always soft/skin } //moving fx texture if(useFX > 0) fx = texture2D( fxTex, gl_TexCoord[1].xy ); else fx = vec4(0.0, 0.0, 0.0, 0.0); //glowing fx texture if(useGlow > 0) glow = texture2D(fxTex, gl_TexCoord[0].xy ); litColor = textureColour * max(dot(normal, LightDir), 0.0); vec3 reflectDir = reflect(LightDir, normal); float spec = max(dot(EyeDir, reflectDir), 0.0); if(GPUANIM > 0) spec = pow(spec, 4.0); else spec = pow(spec, 6.0); spec *= (SpecularFactor*specmask.a); litColor = min(litColor + spec, vec3(1.0)); //keep shadows from making meshes completely black litColor = max(litColor, (textureColour * vec3(0.15))); gl_FragColor = vec4(litColor * baseColor, 1.0); gl_FragColor = mix(fx, gl_FragColor + scatterCol, alphamask.a); if(useCube > 0 && specmask.a < 1.0) { vec3 relEyeDir; if(fromView > 0) relEyeDir = normalize(LightDir); else relEyeDir = normalize(EyeDir); vec3 reflection = reflect(relEyeDir, normal); vec3 refraction = refract(relEyeDir, normal, 0.66); vec4 Tl = texture2D(fx2Tex, reflection.xy ); vec4 Tr = texture2D(fx2Tex, refraction.xy ); vec4 cubemap = mix(Tl,Tr,FresRatio); cubemap.rgb = max(gl_FragColor.rgb, cubemap.rgb * litColor); gl_FragColor = mix(cubemap, gl_FragColor, specmask.a); } if(useGlow > 0) gl_FragColor = mix(gl_FragColor, glow, glow.a); if(FOG > 0) gl_FragColor = mix(gl_FragColor, gl_Fog.color, fog); } ); //GLASS static char glass_vertex_program[] = "#version 120\n" STRINGIFY ( uniform mat3x4 bonemats[70]; uniform int FOG; attribute vec4 weights; attribute vec4 bones; varying vec3 r; varying float fog; varying vec3 normal, vert; void main(void) { mat3x4 m = bonemats[int(bones.x)] * weights.x; m += bonemats[int(bones.y)] * weights.y; m += bonemats[int(bones.z)] * weights.z; m += bonemats[int(bones.w)] * weights.w; vec4 mpos = vec4(gl_Vertex * m, gl_Vertex.w); gl_Position = gl_ModelViewProjectionMatrix * mpos; vec3 u = normalize( vec3(gl_ModelViewMatrix * mpos) ); vec3 n = normalize(gl_NormalMatrix * (vec4(gl_Normal, 0.0) * m)); r = reflect( u, n ); normal = n; vert = vec3( gl_ModelViewMatrix * mpos ); //fog if(FOG > 0) { fog = (gl_Position.z - gl_Fog.start) / (gl_Fog.end - gl_Fog.start); fog = clamp(fog, 0.0, 0.3); //any higher and meshes disappear } } ); static char glass_fragment_program[] = "#version 120\n" STRINGIFY ( uniform vec3 LightPos; uniform sampler2D refTexture; uniform sampler2D mirTexture; uniform int FOG; varying vec3 r; varying float fog; varying vec3 normal, vert; void main (void) { vec3 light_dir = normalize( LightPos - vert ); vec3 eye_dir = normalize( -vert.xyz ); vec3 ref = normalize( -reflect( light_dir, normal ) ); float ld = max( dot(normal, light_dir), 0.0 ); float ls = 0.75 * pow( max( dot(ref, eye_dir), 0.0 ), 0.70 ); //0.75 specular, .7 shininess float m = -1.0 * sqrt( r.x*r.x + r.y*r.y + (r.z+1.0)*(r.z+1.0) ); vec2 coord = -vec2(r.x/m + 0.5, r.y/m + 0.5); vec4 t0 = texture2D(refTexture, coord.st); vec4 t1 = texture2D(mirTexture, coord.st); //gl_FragColor = 0.3 * t0 + 0.3 * t1 * (ld + ls); gl_FragColor = 0.3 * t0 + 0.3 * t1 * vec4(ld + ls); if(FOG > 0) gl_FragColor = mix(gl_FragColor, gl_Fog.color, fog); } ); //NO TEXTURE static char blankmesh_vertex_program[] = "#version 120\n" STRINGIFY ( uniform mat3x4 bonemats[70]; attribute vec4 weights; attribute vec4 bones; void main(void) { mat3x4 m = bonemats[int(bones.x)] * weights.x; m += bonemats[int(bones.y)] * weights.y; m += bonemats[int(bones.z)] * weights.z; m += bonemats[int(bones.w)] * weights.w; vec4 mpos = vec4(gl_Vertex * m, gl_Vertex.w); gl_Position = gl_ModelViewProjectionMatrix * mpos; } ); static char blankmesh_fragment_program[] = "#version 120\n" STRINGIFY ( void main (void) { gl_FragColor = vec4(1.0); } ); static char water_vertex_program[] = "#version 120\n" STRINGIFY ( uniform mat3 tangentSpaceTransform; uniform vec3 Eye; uniform vec3 LightPos; uniform float time; uniform int REFLECT; uniform int FOG; const float Eta = 0.66; const float FresnelPower = 2.5; const float F = ((1.0-Eta) * (1.0-Eta))/((1.0+Eta) * (1.0+Eta)); varying float FresRatio; varying vec3 lightDir; varying vec3 eyeDir; varying float fog; void main(void) { gl_Position = ftransform(); lightDir = tangentSpaceTransform * (LightPos - gl_Vertex.xyz); vec4 neyeDir = gl_ModelViewMatrix * gl_Vertex; vec3 refeyeDir = neyeDir.xyz / neyeDir.w; refeyeDir = normalize(refeyeDir); // The normal is always 0, 0, 1 because water is always up. Thus, // dot (refeyeDir,norm) is always refeyeDir.z FresRatio = F + (1.0-F) * pow((1.0-refeyeDir.z),FresnelPower); eyeDir = tangentSpaceTransform * ( Eye - gl_Vertex.xyz ); vec4 texco = gl_MultiTexCoord0; if(REFLECT > 0) { texco.s = texco.s - LightPos.x/256.0; texco.t = texco.t + LightPos.y/256.0; } gl_TexCoord[0] = texco; texco = gl_MultiTexCoord0; texco.s = texco.s + time*0.05; texco.t = texco.t + time*0.05; gl_TexCoord[1] = texco; texco = gl_MultiTexCoord0; texco.s = texco.s - time*0.05; texco.t = texco.t - time*0.05; gl_TexCoord[2] = texco; //fog if(FOG > 0) { fog = (gl_Position.z - gl_Fog.start) / (gl_Fog.end - gl_Fog.start); fog = clamp(fog, 0.0, 1.0); } } ); static char water_fragment_program[] = "#version 120\n" STRINGIFY ( varying vec3 lightDir; varying vec3 eyeDir; varying float FresRatio; varying float fog; uniform sampler2D refTexture; uniform sampler2D normalMap; uniform sampler2D baseTexture; uniform float TRANSPARENT; uniform int FOG; void main (void) { vec4 refColor; vec3 vVec = normalize(eyeDir); refColor = texture2D(refTexture, gl_TexCoord[0].xy); vec3 bump = normalize( texture2D(normalMap, gl_TexCoord[1].xy).xyz - 0.5); vec3 secbump = normalize( texture2D(normalMap, gl_TexCoord[2].xy).xyz - 0.5); vec3 modbump = mix(secbump,bump,0.5); vec3 reflection = reflect(vVec,modbump); vec3 refraction = refract(vVec,modbump,0.66); vec4 Tl = texture2D(baseTexture, reflection.xy); vec4 Tr = texture2D(baseTexture, refraction.xy); vec4 cubemap = mix(Tl,Tr,FresRatio); gl_FragColor = mix(cubemap,refColor,0.5); gl_FragColor.a = TRANSPARENT; if(FOG > 0) gl_FragColor = mix(gl_FragColor, gl_Fog.color, fog); } ); //FRAMEBUFFER DISTORTION EFFECTS static char fb_vertex_program[] = "#version 120\n" STRINGIFY ( void main( void ) { gl_Position = ftransform(); gl_TexCoord[0] = gl_MultiTexCoord0; } ); static char fb_fragment_program[] = "#version 120\n" STRINGIFY ( uniform sampler2D fbtexture; uniform sampler2D distortiontexture; uniform vec2 dParams; uniform vec2 fxPos; void main(void) { vec3 noiseVec; vec2 displacement; float wScissor; float hScissor; displacement = gl_TexCoord[0].st; displacement.x -= fxPos.x; displacement.y -= fxPos.y; noiseVec = normalize(texture2D(distortiontexture, displacement.xy)).xyz; noiseVec = (noiseVec * 2.0 - 0.635) * 0.035; //clamp edges to prevent artifacts wScissor = dParams.x - 0.008; hScissor = dParams.y - 0.008; if(gl_TexCoord[0].s > 0.1 && gl_TexCoord[0].s < wScissor) displacement.x = gl_TexCoord[0].s + noiseVec.x; else displacement.x = gl_TexCoord[0].s; if(gl_TexCoord[0].t > 0.1 && gl_TexCoord[0].t < hScissor) displacement.y = gl_TexCoord[0].t + noiseVec.y; else displacement.y = gl_TexCoord[0].t; gl_FragColor = texture2D(fbtexture, displacement.xy); } ); //GAUSSIAN BLUR EFFECTS static char blur_vertex_program[] = "#version 120\n" STRINGIFY ( varying vec2 texcoord1, texcoord2, texcoord3, texcoord4, texcoord5, texcoord6, texcoord7, texcoord8, texcoord9; uniform vec2 ScaleU; void main() { gl_Position = ftransform(); // If we do all this math here, and let GLSL do its built-in // interpolation of varying variables, the math still comes out right, // but it's faster. texcoord1 = gl_MultiTexCoord0.xy-4.0*ScaleU; texcoord2 = gl_MultiTexCoord0.xy-3.0*ScaleU; texcoord3 = gl_MultiTexCoord0.xy-2.0*ScaleU; texcoord4 = gl_MultiTexCoord0.xy-ScaleU; texcoord5 = gl_MultiTexCoord0.xy; texcoord6 = gl_MultiTexCoord0.xy+ScaleU; texcoord7 = gl_MultiTexCoord0.xy+2.0*ScaleU; texcoord8 = gl_MultiTexCoord0.xy+3.0*ScaleU; texcoord9 = gl_MultiTexCoord0.xy+4.0*ScaleU; } ); static char blur_fragment_program[] = "#version 120\n" STRINGIFY ( varying vec2 texcoord1, texcoord2, texcoord3, texcoord4, texcoord5, texcoord6, texcoord7, texcoord8, texcoord9; uniform sampler2D textureSource; void main() { vec4 sum = vec4(0.0); // take nine samples sum += texture2D(textureSource, texcoord1) * 0.05; sum += texture2D(textureSource, texcoord2) * 0.09; sum += texture2D(textureSource, texcoord3) * 0.12; sum += texture2D(textureSource, texcoord4) * 0.15; sum += texture2D(textureSource, texcoord5) * 0.16; sum += texture2D(textureSource, texcoord6) * 0.15; sum += texture2D(textureSource, texcoord7) * 0.12; sum += texture2D(textureSource, texcoord8) * 0.09; sum += texture2D(textureSource, texcoord9) * 0.05; gl_FragColor = sum; } ); //RADIAL BLUR EFFECTS // xy = radial center screen space position, z = radius attenuation, w = blur strength static char rblur_vertex_program[] = "#version 120\n" STRINGIFY ( void main() { gl_Position = ftransform(); gl_TexCoord[0] = gl_MultiTexCoord0; } ); static char rblur_fragment_program[] = "#version 120\n" STRINGIFY ( uniform sampler2D rtextureSource; uniform vec3 radialBlurParams; uniform vec3 rblurScale; void main(void) { float wScissor; float hScissor; vec2 dir = vec2(radialBlurParams.x - gl_TexCoord[0].x, radialBlurParams.x - gl_TexCoord[0].x); float dist = sqrt(dir.x*dir.x + dir.y*dir.y); dir = dir/dist; vec4 color = texture2D(rtextureSource,gl_TexCoord[0].xy); vec4 sum = color; float strength = radialBlurParams.z; vec2 pDir = vec2(rblurScale.y * 0.5 - gl_TexCoord[0].s, rblurScale.z * 0.5 - gl_TexCoord[0].t); float pDist = sqrt(pDir.x*pDir.x + pDir.y*pDir.y); clamp(pDist, 0.0, 1.0); //the following ugliness is due to ATI's drivers inablity to handle a simple for-loop! sum += texture2D( rtextureSource, gl_TexCoord[0].xy + dir * -0.06 * strength * pDist ); sum += texture2D( rtextureSource, gl_TexCoord[0].xy + dir * -0.05 * strength * pDist ); sum += texture2D( rtextureSource, gl_TexCoord[0].xy + dir * -0.03 * strength * pDist ); sum += texture2D( rtextureSource, gl_TexCoord[0].xy + dir * -0.02 * strength * pDist ); sum += texture2D( rtextureSource, gl_TexCoord[0].xy + dir * -0.01 * strength * pDist ); sum += texture2D( rtextureSource, gl_TexCoord[0].xy + dir * 0.01 * strength * pDist ); sum += texture2D( rtextureSource, gl_TexCoord[0].xy + dir * 0.02 * strength * pDist ); sum += texture2D( rtextureSource, gl_TexCoord[0].xy + dir * 0.03 * strength * pDist ); sum += texture2D( rtextureSource, gl_TexCoord[0].xy + dir * 0.05 * strength * pDist ); sum += texture2D( rtextureSource, gl_TexCoord[0].xy + dir * 0.06 * strength * pDist ); sum *= 1.0/11.0; float t = dist * rblurScale.x; t = clamp( t ,0.0,1.0); vec4 final = mix( color, sum, t ); //clamp edges to prevent artifacts wScissor = rblurScale.y - 0.008; hScissor = rblurScale.z - 0.008; if(gl_TexCoord[0].s > 0.008 && gl_TexCoord[0].s < wScissor && gl_TexCoord[0].t > 0.008 && gl_TexCoord[0].t < hScissor) gl_FragColor = final; else gl_FragColor = color; } ); //WATER DROPLETS static char droplets_vertex_program[] = "#version 120\n" STRINGIFY ( uniform float drTime; void main( void ) { gl_Position = ftransform(); //for vertical scrolling vec4 texco = gl_MultiTexCoord0; texco.t = texco.t + drTime*1.0; gl_TexCoord[1] = texco; texco = gl_MultiTexCoord0; texco.t = texco.t + drTime*0.8; gl_TexCoord[2] = texco; gl_TexCoord[0] = gl_MultiTexCoord0; } ); static char droplets_fragment_program[] = "#version 120\n" STRINGIFY ( uniform sampler2D drSource; uniform sampler2D drTex; uniform vec2 drParams; void main(void) { vec3 noiseVec; vec3 noiseVec2; vec2 displacement; float wScissor; float hScissor; displacement = gl_TexCoord[1].st; noiseVec = normalize(texture2D(drTex, displacement.xy)).xyz; noiseVec = (noiseVec * 2.0 - 0.635) * 0.035; displacement = gl_TexCoord[2].st; noiseVec2 = normalize(texture2D(drTex, displacement.xy)).xyz; noiseVec2 = (noiseVec2 * 2.0 - 0.635) * 0.035; //clamp edges to prevent artifacts wScissor = drParams.x - 0.008; hScissor = drParams.y - 0.028; if(gl_TexCoord[0].s > 0.1 && gl_TexCoord[0].s < wScissor) displacement.x = gl_TexCoord[0].s + noiseVec.x + noiseVec2.x; else displacement.x = gl_TexCoord[0].s; if(gl_TexCoord[0].t > 0.1 && gl_TexCoord[0].t < hScissor) displacement.y = gl_TexCoord[0].t + noiseVec.y + noiseVec2.y; else displacement.y = gl_TexCoord[0].t; gl_FragColor = texture2D(drSource, displacement.xy); } ); static char rgodrays_vertex_program[] = "#version 120\n" STRINGIFY ( void main() { gl_TexCoord[0] = gl_MultiTexCoord0; gl_Position = ftransform(); } ); static char rgodrays_fragment_program[] = "#version 120\n" STRINGIFY ( uniform vec2 lightPositionOnScreen; uniform sampler2D sunTexture; uniform float aspectRatio; //width/height uniform float sunRadius; //note - these could be made uniforms to control externally const float exposure = 0.0034; const float decay = 1.0; const float density = 0.84; const float weight = 5.65; const int NUM_SAMPLES = 75; void main() { vec2 deltaTextCoord = vec2( gl_TexCoord[0].st - lightPositionOnScreen.xy ); vec2 textCoo = gl_TexCoord[0].st; float adjustedLength = length (vec2 (deltaTextCoord.x*aspectRatio, deltaTextCoord.y)); deltaTextCoord *= 1.0 / float(NUM_SAMPLES) * density; float illuminationDecay = 1.0; int lim = NUM_SAMPLES; if (adjustedLength > sunRadius) { //first simulate the part of the loop for which we won't get any //samples anyway float ratio = (adjustedLength-sunRadius)/adjustedLength; lim = int (float(lim)*ratio); textCoo -= deltaTextCoord*lim; illuminationDecay *= pow (decay, lim); //next set up the following loop so it gets the correct number of //samples. lim = NUM_SAMPLES-lim; } gl_FragColor = vec4(0.0); for(int i = 0; i < lim; i++) { textCoo -= deltaTextCoord; vec4 sample = texture2D(sunTexture, textCoo ); sample *= illuminationDecay * weight; gl_FragColor += sample; illuminationDecay *= decay; } gl_FragColor *= exposure; } ); typedef struct { const char *name; int index; } vertex_attribute_t; // add new vertex attributes here #define NO_ATTRIBUTES 0 const vertex_attribute_t standard_attributes[] = { #define ATTRIBUTE_TANGENT (1<<0) {"tangent", 1}, #define ATTRIBUTE_WEIGHTS (1<<1) {"weights", 6}, #define ATTRIBUTE_BONES (1<<2) {"bones", 7} }; const int num_standard_attributes = sizeof(standard_attributes)/sizeof(vertex_attribute_t); void R_LoadGLSLProgram (const char *name, char *vertex, char *fragment, int attributes, GLhandleARB *program) { char str[4096]; const char *shaderStrings[1]; int nResult; int i; *program = glCreateProgramObjectARB(); g_vertexShader = glCreateShaderObjectARB( GL_VERTEX_SHADER_ARB ); shaderStrings[0] = vertex; glShaderSourceARB( g_vertexShader, 1, shaderStrings, NULL ); glCompileShaderARB( g_vertexShader); glGetObjectParameterivARB( g_vertexShader, GL_OBJECT_COMPILE_STATUS_ARB, &nResult ); if( nResult ) glAttachObjectARB( *program, g_vertexShader ); else { Com_Printf("...%s Vertex Shader Compile Error\n", name); } g_fragmentShader = glCreateShaderObjectARB( GL_FRAGMENT_SHADER_ARB ); shaderStrings[0] = fragment; glShaderSourceARB( g_fragmentShader, 1, shaderStrings, NULL ); glCompileShaderARB( g_fragmentShader ); glGetObjectParameterivARB( g_fragmentShader, GL_OBJECT_COMPILE_STATUS_ARB, &nResult ); if( nResult ) glAttachObjectARB( *program, g_fragmentShader ); else { Com_Printf("...%s Fragment Shader Compile Error\n", name); } for (i = 0; i < num_standard_attributes; i++) { if (attributes & (1< #include "r_local.h" static vec3_t modelorg; // relative to viewpoint vec3_t r_worldLightVec; dlight_t *dynLight; #define LIGHTMAP_BYTES 4 //Pretty safe bet most cards support this #define LIGHTMAP_SIZE 2048 #define MAX_LIGHTMAPS 12 int c_visible_lightmaps; int c_visible_textures; // This is supposed to be faster on some older hardware. #define GL_LIGHTMAP_FORMAT GL_BGRA typedef struct { int current_lightmap_texture; // For each column, what is the last row where a pixel is used int allocated[LIGHTMAP_SIZE]; // Lightmap texture data (RGBA, alpha not used) byte lightmap_buffer[4*LIGHTMAP_SIZE*LIGHTMAP_SIZE]; } gllightmapstate_t; // TODO: dynamically allocate this so we can free it for RAM savings? It's // using over 16 megs. static gllightmapstate_t gl_lms; static void LM_InitBlock( void ); static void LM_UploadBlock( ); static qboolean LM_AllocBlock (int w, int h, int *x, int *y); extern void R_SetCacheState( msurface_t *surf ); extern void R_BuildLightMap (msurface_t *surf, byte *dest, int smax, int tmax, int stride); /* =============== BSP_TextureAnimation Returns the proper texture for a given time and base texture XXX: AFAIK this is only used for the old .wal textures, and is a bit redundant with the rscript system, although it is implemented more efficiently. Maybe merge the two systems somehow? =============== */ image_t *BSP_TextureAnimation (mtexinfo_t *tex) { int c; if (!tex->next) return tex->image; c = currententity->frame % tex->numframes; while (c) { tex = tex->next; c--; } return tex->image; } /* ========================================= Textureless Surface Rendering Used by the shadow system ========================================= */ /* ================ BSP_DrawTexturelessPoly ================ */ void BSP_DrawTexturelessPoly (msurface_t *fa) { R_InitVArrays(VERT_NO_TEXTURE); R_AddSurfToVArray (fa); R_KillVArrays(); } void BSP_DrawShadowPoly (msurface_t *fa, vec3_t origin) { R_AddShadowSurfToVArray (fa, origin); } void BSP_DrawTexturelessInlineBModel (entity_t *e) { int i; msurface_t *psurf; // // draw texture // psurf = ¤tmodel->surfaces[currentmodel->firstmodelsurface]; for (i=0 ; inummodelsurfaces ; i++, psurf++) { // draw the polygon BSP_DrawTexturelessPoly( psurf ); psurf->visframe = r_framecount; } qglDisable (GL_BLEND); qglColor4f (1,1,1,1); GL_TexEnv( GL_REPLACE ); } void BSP_DrawTexturelessBrushModel (entity_t *e) { vec3_t mins, maxs; int i; qboolean rotated; if (currentmodel->nummodelsurfaces == 0) return; currententity = e; if (e->angles[0] || e->angles[1] || e->angles[2]) { rotated = true; for (i=0 ; i<3 ; i++) { mins[i] = e->origin[i] - currentmodel->radius; maxs[i] = e->origin[i] + currentmodel->radius; } } else { rotated = false; VectorAdd (e->origin, currentmodel->mins, mins); VectorAdd (e->origin, currentmodel->maxs, maxs); } if (R_CullBox (mins, maxs)) { return; } qglColor3f (1,1,1); VectorSubtract (r_newrefdef.vieworg, e->origin, modelorg); if (rotated) { vec3_t temp; vec3_t forward, right, up; VectorCopy (modelorg, temp); AngleVectors (e->angles, forward, right, up); modelorg[0] = DotProduct (temp, forward); modelorg[1] = -DotProduct (temp, right); modelorg[2] = DotProduct (temp, up); } qglPushMatrix (); e->angles[0] = -e->angles[0]; // stupid quake bug e->angles[2] = -e->angles[2]; // stupid quake bug R_RotateForEntity (e); e->angles[0] = -e->angles[0]; // stupid quake bug e->angles[2] = -e->angles[2]; // stupid quake bug BSP_DrawTexturelessInlineBModel (e); qglPopMatrix (); } /* ========================================= BSP Surface Rendering Common between brush and world models ========================================= */ /* ========================================= Special surfaces - Somewhat less common, require more work to render - Translucent ("alpha") surfaces These are special because they have to be rendered all in one pass, despite consisting of several different types of surfaces, so the code can't make too many assumptions about the surface. - Rscript surfaces (those with material shaders) Rscript surfaces are first rendered through the "ordinary" path, then this one. - Wavy, rippling ("warp") surfaces The code to actually render these is in r_warp.c. ========================================= */ // The "special" surfaces use these for linked lists. // The reason to have linked lists for surfaces from brush model entities // separate from the linked lists for world surfaces is that the world // surface linked lists can be preserved between frames if r_optimize is on, // whereas the entity linked lists must be cleared each time an entity is // drawn. msurface_t *r_alpha_surfaces; msurface_t *r_ent_alpha_surfaces; msurface_t *r_rscript_surfaces; // no brush models can have rscript surfs msurface_t *r_warp_surfaces; msurface_t *r_ent_warp_surfaces; // This is a chain of surfaces that may need to have their lightmaps updated. // They are not rendered in the order of this chain and will be linked into // other chains for rendering. msurface_t *r_flicker_surfaces; /* ================ BSP_DrawWarpSurfaces ================ */ void BSP_DrawWarpSurfaces (qboolean forEnt) { msurface_t *surf; image_t *image; if (forEnt) surf = r_ent_warp_surfaces; else surf = r_warp_surfaces; if (surf == NULL) return; // no lightmaps rendered on these surfaces GL_EnableMultitexture( false ); GL_TexEnv( GL_MODULATE ); qglColor4f( gl_state.inverse_intensity, gl_state.inverse_intensity, gl_state.inverse_intensity, 1.0F ); while (surf) { c_brush_polys++; image = BSP_TextureAnimation (surf->texinfo); GL_Bind (image->texnum); R_RenderWaterPolys(surf, 0, 1, 1); surf = surf->texturechain; } if (forEnt) r_ent_warp_surfaces = NULL; GL_EnableMultitexture( true ); GL_TexEnv( GL_REPLACE ); R_KillVArrays (); } /* ================ BSP_DrawAlphaPoly ================ */ void BSP_DrawAlphaPoly (msurface_t *fa, int flags) { float scroll; scroll = 0; if (flags & SURF_FLOWING) { scroll = -64 * ( (r_newrefdef.time / 40.0) - (int)(r_newrefdef.time / 40.0) ); if (scroll == 0.0) scroll = -64.0; } R_InitVArrays(VERT_SINGLE_TEXTURED); R_AddTexturedSurfToVArray (fa, scroll); R_KillVArrays(); } /* ================ R_DrawAlphaSurfaces Draw water surfaces and windows. Annoyingly, because alpha surfaces have to be drawn from back to front, everything transparent-- water, rscripted surfs, and non-rscripted surfs-- has to be drawn in a single pass. This is an inherently inefficient process. The BSP tree is walked front to back, so unwinding the chain of alpha surfaces will draw back to front, giving proper ordering FOR BSP SURFACES! It's a bit wrong for entity surfaces (i.e. glass doors.) Because they are in separate linked lists, the entity surfaces must be either always behind or always in front of the world surfaces. I chose always in front because that seems to fix all rendering issues, regardless of whether the entity actually is in front. Search me why. NOTE: this bug existed even when it was all one linked list, although at that time entity surfaces were always behind map surfaces (added to the beginning of the linked list after all the BSP rendering code.) ================ */ void R_DrawAlphaSurfaces_chain (msurface_t *chain) { msurface_t *s; float intens; rscript_t *rs_shader; rs_stage_t *stage = NULL; int texnum = 0; float scaleX = 1.0f, scaleY = 1.0f; // the textures are prescaled up for a better lighting range, // so scale it back down intens = gl_state.inverse_intensity; qglDepthMask ( GL_FALSE ); qglEnable (GL_BLEND); GL_TexEnv( GL_MODULATE ); for (s=chain ; s ; s=s->texturechain) { GL_Bind(s->texinfo->image->texnum); c_brush_polys++; if (s->texinfo->flags & SURF_TRANS33) qglColor4f (intens, intens, intens, 0.33); else if (s->texinfo->flags & SURF_TRANS66) qglColor4f (intens, intens, intens, 0.66); else qglColor4f (intens, intens, intens, 1); //moving trans brushes if (s->entity) { qglLoadMatrixf (r_world_matrix); //moving trans brushes s->entity->angles[0] = -s->entity->angles[0]; // stupid quake bug s->entity->angles[2] = -s->entity->angles[2]; // stupid quake bug R_RotateForEntity (s->entity); s->entity->angles[0] = -s->entity->angles[0]; // stupid quake bug s->entity->angles[2] = -s->entity->angles[2]; // stupid quake bug } rs_shader = NULL; if (r_shaders->integer) rs_shader = (rscript_t *)s->texinfo->image->script; if (s->iflags & ISURF_DRAWTURB) { //water shaders scaleX = scaleY = 1.0f; if(rs_shader) { stage = rs_shader->stage; if(stage) { //for now, just map a reflection texture texnum = stage->texture->texnum; //pass this to renderwaterpolys } if(stage->scale.scaleX != 0 && stage->scale.scaleY !=0) { scaleX = stage->scale.scaleX; scaleY = stage->scale.scaleY; } } R_RenderWaterPolys (s, texnum, scaleX, scaleY); qglEnable (GL_BLEND); GL_TexEnv( GL_MODULATE ); } else if(rs_shader && !(s->texinfo->flags & SURF_FLOWING)) { RS_Surface(s); qglEnable (GL_BLEND); GL_TexEnv( GL_MODULATE ); } else BSP_DrawAlphaPoly (s, s->texinfo->flags); } GL_TexEnv( GL_REPLACE ); qglColor4f (1,1,1,1); qglDisable (GL_BLEND); qglDepthMask ( GL_TRUE ); } void R_DrawAlphaSurfaces (void) { R_DrawAlphaSurfaces_chain (r_alpha_surfaces); R_DrawAlphaSurfaces_chain (r_ent_alpha_surfaces); qglLoadMatrixf (r_world_matrix); //moving trans brushes r_ent_alpha_surfaces = NULL; } /* ================ R_DrawRSSurfaces Draw shader surfaces ================ */ void R_DrawRSSurfaces (void) { msurface_t *s = r_rscript_surfaces; if(!s) return; if (!r_shaders->integer) { r_rscript_surfaces = NULL; return; } qglDepthMask(false); qglShadeModel (GL_SMOOTH); qglEnable(GL_POLYGON_OFFSET_FILL); qglPolygonOffset(-3, -2); for (; s; s = s->rscriptchain) RS_Surface(s); qglDisable(GL_POLYGON_OFFSET_FILL); GLSTATE_DISABLE_BLEND GLSTATE_DISABLE_ALPHATEST qglDepthMask(true); } /* ========================================= Ordinary surfaces (fixed-function, normalmapped, and dynamically lit) These are the most commonly used types of surfaces, so the rendering code path for each is more optimized-- surfaces grouped by texinfo, VBOs, VBO batching, etc. ========================================= */ // The "ordinary" surfaces do not use global variables for linked lists. The // linked lists are in the texinfo struct, so the textures can be grouped by // texinfo. Like the "special" surfaces, there are separate linked lists for // entity surfaces and world surfaces. // State variables for detecting changes from one surface to the next. If any // of these change, the current batch of polygons to render is flushed. This // helps minimize GL state change calls and draw calls. int r_currTex = -9999; //only bind a texture if it is not the same as previous surface int r_currLMTex = -9999; //lightmap texture mtexinfo_t *r_currTexInfo = NULL; //texinfo struct float *r_currTangentSpaceTransform; //etc. // VBO batching // This system allows contiguous sequences of polygons to be merged into // batches, even if they are added out of order. // There is a linked list of these, but they are not dynamically allocated. // They are allocated from a static array. This prevents us wasting CPU with // lots of malloc/free calls. Keep this struct small for performance! typedef struct vbobatch_s { int first_vert, last_vert; struct vbobatch_s *next; } vbobatch_t; #define MAX_VBO_BATCHES 100 // 100 ought to be enough. If we run out, we can // always just draw some prematurely. // use a static array and counter to avoid lots of malloc nonsense int num_vbo_batches; vbobatch_t vbobatch_buffer[MAX_VBO_BATCHES]; // never used directly; linked list base only vbobatch_t first_vbobatch[] = {{-1, -1, NULL}}; // if false, flushVBOAccum will set up the VBO GL state qboolean r_vboOn = false; // for the rspeed_vbobatches HUD gauge int c_vbo_batches; // clear all accumulated surfaces without rendering static inline void BSP_ClearVBOAccum (void) { memset (vbobatch_buffer, 0, sizeof(vbobatch_buffer)); num_vbo_batches = 0; first_vbobatch->next = NULL; } // render all accumulated surfaces, then clear them // XXX: assumes that global OpenGL state is correct for whatever surfaces are // in the accumulator, so don't change state until you've called this! static inline void BSP_FlushVBOAccum (void) { vbobatch_t *batch = first_vbobatch->next; if (!batch) return; if (!r_vboOn) { GL_SetupWorldVBO (); r_vboOn = true; } // XXX: for future reference, the glDrawRangeElements code was last seen // here at revision 3246. for (; batch; batch = batch->next) { qglDrawArrays (GL_TRIANGLES, batch->first_vert, batch->last_vert-batch->first_vert); c_vbo_batches++; } BSP_ClearVBOAccum (); } // Add a new surface to the VBO batch accumulator. If its vertex data is next // to any other surfaces within the VBO, opportunistically merge the surfaces // together into a larger "batch," so they can be rendered with one draw call. // Whenever two batches touch each other, they are merged. Hundreds of // surfaces can be rendered with a single call, which is easier on the OpenGL // pipeline. static inline void BSP_AddToVBOAccum (int first_vert, int last_vert) { vbobatch_t *batch = first_vbobatch->next, *prev = first_vbobatch; vbobatch_t *new; if (!batch) { batch = first_vbobatch->next = vbobatch_buffer; batch->first_vert = first_vert; batch->last_vert = last_vert; num_vbo_batches++; return; } // This is optimal. Because of the way the surface linked lists are built // by BSP_AddToTextureChain, they are usually in reverse order, so it's // best to start toward the beginning of the list of VBO batches where // you're more likely to merge something. while (batch->next && batch->next->first_vert < first_vert) { prev = batch; batch = batch->next; } if (batch->first_vert > last_vert) { new = &vbobatch_buffer[num_vbo_batches++]; new->next = batch; prev->next = new; new->first_vert = first_vert; new->last_vert = last_vert; } else if (batch->last_vert == first_vert) { batch->last_vert = last_vert; if (batch->next && batch->next->first_vert == last_vert) { // This is the special case where the new surface bridges the gap // between two existing batches, allowing us to merge them into // the first one. This is the only case where we actually remove a // batch instead of growing one or adding one. batch->last_vert = batch->next->last_vert; if (batch->next == &vbobatch_buffer[num_vbo_batches-1]) num_vbo_batches--; batch->next = batch->next->next; } return; //no need to check for maximum batch count being hit } else if (batch->next && batch->next->first_vert == last_vert) { batch->next->first_vert = first_vert; return; //no need to check for maximum batch count being hit } else if (batch->first_vert == last_vert) { batch->first_vert = first_vert; return; //no need to check for maximum batch count being hit } else //if (batch->last_vert < first_vert) { new = &vbobatch_buffer[num_vbo_batches++]; new->next = batch->next; batch->next = new; new->first_vert = first_vert; new->last_vert = last_vert; } //running out of space if (num_vbo_batches == MAX_VBO_BATCHES) { /* Com_Printf ("MUSTFLUSH\n");*/ BSP_FlushVBOAccum (); } } /* ================ BSP_NonGLSLTexinfoChanged Update GL state as needed so we can draw a new batch of surfaces for the provided texinfo (version for all fixed-function standard surfaces) ================ */ static void BSP_NonGLSLTexinfoChanged (mtexinfo_t *texinfo) { int texnum; BSP_FlushVBOAccum (); if (TexinfoIsAlphaBlended (texinfo)) { if (!r_currTexInfo || !TexinfoIsAlphaBlended(r_currTexInfo)) { qglEnable( GL_ALPHA_TEST ); } } else { if (!r_currTexInfo || TexinfoIsAlphaBlended(r_currTexInfo)) { qglDisable( GL_ALPHA_TEST ); } } // do this here so only have to do it once instead of for each surface texnum = BSP_TextureAnimation( texinfo )->texnum; if(texnum != r_currTex) { qglActiveTextureARB(GL_TEXTURE0); qglBindTexture(GL_TEXTURE_2D, texnum ); r_currTex = texnum; } r_currTexInfo = texinfo; } /* ================ BSP_RenderLightmappedPoly Main polygon rendering routine (all fixed-function standard surfaces) ================ */ static void BSP_RenderLightmappedPoly( msurface_t *surf) { float scroll; unsigned lmtex = surf->lightmaptexturenum; c_brush_polys++; if (lmtex != r_currLMTex) { BSP_FlushVBOAccum (); qglActiveTextureARB(GL_TEXTURE1); qglBindTexture(GL_TEXTURE_2D, gl_state.lightmap_textures + lmtex ); } if(gl_state.vbo && surf->has_vbo && !(surf->texinfo->flags & SURF_FLOWING)) { BSP_AddToVBOAccum (surf->vbo_first_vert, surf->vbo_first_vert+surf->vbo_num_verts); } else { BSP_FlushVBOAccum (); r_vboOn = false; scroll = 0; if (surf->texinfo->flags & SURF_FLOWING) { scroll = -64 * ( (r_newrefdef.time / 40.0) - (int)(r_newrefdef.time / 40.0) ); if (scroll == 0.0) scroll = -64.0; } R_InitVArrays (VERT_MULTI_TEXTURED); R_AddLightMappedSurfToVArray (surf, scroll); } } /* ================ BSP_GLSLTexinfoChanged Update GL state as needed so we can draw a new batch of surfaces for the provided texinfo (version for all normalmapped and/or dynamically lit standard surfaces) ================ */ static void BSP_GLSLTexinfoChanged (mtexinfo_t *texinfo, qboolean dynamic) { int texnum; BSP_FlushVBOAccum (); if (TexinfoIsAlphaBlended (texinfo)) { if (!r_currTexInfo || !TexinfoIsAlphaBlended(r_currTexInfo)) { qglEnable( GL_ALPHA_TEST ); } } else { if (!r_currTexInfo || TexinfoIsAlphaBlended(r_currTexInfo)) { qglDisable( GL_ALPHA_TEST ); } } // no texture animation for normalmapped surfaces, for some reason texnum = texinfo->image->texnum; if(texnum != r_currTex) { r_currTex = texnum; if (!r_currTexInfo) { glUniform1iARB( g_location_surfTexture, 0); glUniform1iARB( g_location_heightTexture, 1); glUniform1iARB( g_location_normalTexture, 2); glUniform1iARB( g_location_lmTexture, 3); } qglActiveTextureARB(GL_TEXTURE0); qglBindTexture(GL_TEXTURE_2D, texnum); qglActiveTextureARB(GL_TEXTURE1); qglBindTexture(GL_TEXTURE_2D, texinfo->heightMap->texnum); qglActiveTextureARB(GL_TEXTURE2); qglBindTexture(GL_TEXTURE_2D, texinfo->normalMap->texnum); KillFlags |= KILL_TMU2_POINTER; } if (dynamic) { if(gl_bspnormalmaps->integer && texinfo->has_heightmap) { if (!r_currTexInfo || !r_currTexInfo->has_heightmap) { glUniform1iARB( g_location_parallax, 1); } } else { if (!r_currTexInfo || r_currTexInfo->has_heightmap) { glUniform1iARB( g_location_parallax, 0); } } } if (!gl_bspnormalmaps->integer) { if (!r_currTexInfo) { glUniform1iARB( g_location_liquid, 0 ); glUniform1iARB( g_location_shiny, 0 ); } } else if (r_currTexInfo && (texinfo->flags & (SURF_BLOOD|SURF_WATER|SURF_SHINY)) == (r_currTexInfo->flags & (SURF_BLOOD|SURF_WATER|SURF_SHINY))) { //no change to GL state is needed } else if (texinfo->flags & SURF_BLOOD) { //need to bind the blood drop normal map, and set flag, and time glUniform1iARB( g_location_liquid, 8 ); //blood type 8, water 1 glUniform1iARB( g_location_shiny, 0 ); glUniform1fARB( g_location_rsTime, rs_realtime); glUniform1iARB( g_location_liquidTexture, 4); //for blood we are going to need to send a diffuse texture with it qglActiveTextureARB(GL_TEXTURE4); qglBindTexture(GL_TEXTURE_2D, r_blooddroplets->texnum); KillFlags |= KILL_TMU4_POINTER; glUniform1iARB( g_location_liquidNormTex, 5); qglActiveTextureARB(GL_TEXTURE5); qglBindTexture(GL_TEXTURE_2D, r_blooddroplets_nm->texnum); KillFlags |= KILL_TMU5_POINTER; } else if (texinfo->flags & SURF_WATER) { //need to bind the water drop normal map, and set flag, and time glUniform1iARB( g_location_liquid, 1 ); glUniform1iARB( g_location_shiny, 0 ); glUniform1fARB( g_location_rsTime, rs_realtime); glUniform1iARB( g_location_liquidNormTex, 4); //for blood we are going to need to send a diffuse texture with it(maybe even height!) qglActiveTextureARB(GL_TEXTURE4); qglBindTexture(GL_TEXTURE_2D, r_droplets->texnum); KillFlags |= KILL_TMU4_POINTER; } else if (texinfo->flags & SURF_SHINY) { glUniform1iARB( g_location_liquid, 0 ); glUniform1iARB( g_location_shiny, 1 ); glUniform1iARB( g_location_chromeTex, 4); qglActiveTextureARB(GL_TEXTURE4); qglBindTexture(GL_TEXTURE_2D, r_mirrorspec->texnum); KillFlags |= KILL_TMU4_POINTER; } else if (!r_currTexInfo || r_currTexInfo->flags & (SURF_BLOOD|SURF_WATER|SURF_SHINY)) { glUniform1iARB( g_location_liquid, 0 ); glUniform1iARB( g_location_shiny, 0 ); } r_currTexInfo = texinfo; } /* ================ BSP_RenderGLSLLightmappedPoly Main polygon rendering routine (all normalmapped and/or dynamically lit standard surfaces) ================ */ static void BSP_RenderGLSLLightmappedPoly( msurface_t *surf) { static float scroll; unsigned lmtex = surf->lightmaptexturenum; c_brush_polys++; scroll = 0; if (lmtex != r_currLMTex) { BSP_FlushVBOAccum (); qglActiveTextureARB(GL_TEXTURE3); qglBindTexture(GL_TEXTURE_2D, gl_state.lightmap_textures + lmtex); KillFlags |= KILL_TMU3_POINTER; } if (r_currTangentSpaceTransform != surf->tangentSpaceTransform) { BSP_FlushVBOAccum (); glUniformMatrix3fvARB( g_tangentSpaceTransform, 1, GL_FALSE, (const GLfloat *) surf->tangentSpaceTransform ); r_currTangentSpaceTransform = (float *)surf->tangentSpaceTransform; } if(gl_state.vbo && surf->has_vbo && !(surf->texinfo->flags & SURF_FLOWING)) { BSP_AddToVBOAccum (surf->vbo_first_vert, surf->vbo_first_vert+surf->vbo_num_verts); } else { BSP_FlushVBOAccum (); r_vboOn = false; scroll = 0; if (surf->texinfo->flags & SURF_FLOWING) { scroll = -64 * ( (r_newrefdef.time / 40.0) - (int)(r_newrefdef.time / 40.0) ); if (scroll == 0.0) scroll = -64.0; } R_InitVArrays (VERT_MULTI_TEXTURED); R_AddLightMappedSurfToVArray (surf, scroll); } } void BSP_DrawNonGLSLSurfaces (qboolean forEnt) { int i; // reset VBO batching state r_currTex = r_currLMTex = -99999; r_currTexInfo = NULL; r_currTangentSpaceTransform = NULL; BSP_FlushVBOAccum (); r_vboOn = false; qglEnableClientState( GL_VERTEX_ARRAY ); qglClientActiveTextureARB (GL_TEXTURE0); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); qglClientActiveTextureARB (GL_TEXTURE1); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); KillFlags |= (KILL_TMU0_POINTER | KILL_TMU1_POINTER); for (i = 0; i < currentmodel->num_unique_texinfos; i++) { msurface_t *s; if (forEnt) { s = currentmodel->unique_texinfo[i]->e_lightmap_surfaces; currentmodel->unique_texinfo[i]->e_lightmap_surfaces = NULL; } else { s = currentmodel->unique_texinfo[i]->w_lightmap_surfaces; } if (!s) continue; BSP_NonGLSLTexinfoChanged (s->texinfo->equiv); for (; s; s = s->texturechain) { BSP_RenderLightmappedPoly(s); r_currLMTex = s->lightmaptexturenum; } } BSP_FlushVBOAccum (); qglActiveTextureARB(GL_TEXTURE1); qglBindTexture(GL_TEXTURE_2D, 0 ); qglDisable (GL_ALPHA_TEST); } void BSP_DrawGLSLSurfaces (qboolean forEnt) { int i; // reset VBO batching state r_currTex = r_currLMTex = -99999; r_currTexInfo = NULL; r_currTangentSpaceTransform = NULL; if (!gl_bspnormalmaps->integer) { return; } BSP_ClearVBOAccum (); if(r_shadowmapcount == 2) { //static vegetation shadow glUniform1iARB( g_location_bspShadowmapTexture2, 6); qglActiveTextureARB(GL_TEXTURE6); qglBindTexture(GL_TEXTURE_2D, r_depthtexture2->texnum); glUniform1iARB( g_location_shadowmap, 1); glUniform1iARB( g_Location_statshadow, 1 ); glUniform1fARB( g_location_xOffs, 1.0/(viddef.width*r_shadowmapscale->value)); glUniform1fARB( g_location_yOffs, 1.0/(viddef.height*r_shadowmapscale->value)); } else { glUniform1iARB( g_location_shadowmap, 0); glUniform1iARB( g_Location_statshadow, 0); } glUniform1iARB( g_location_dynamic, 0); glUniform1iARB( g_location_parallax, 1); r_vboOn = false; qglEnableClientState( GL_VERTEX_ARRAY ); qglClientActiveTextureARB (GL_TEXTURE0); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); qglClientActiveTextureARB (GL_TEXTURE1); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); KillFlags |= (KILL_TMU0_POINTER | KILL_TMU1_POINTER); for (i = 0; i < currentmodel->num_unique_texinfos; i++) { msurface_t *s; if (forEnt) { s = currentmodel->unique_texinfo[i]->e_glsl_surfaces; currentmodel->unique_texinfo[i]->e_glsl_surfaces = NULL; } else { s = currentmodel->unique_texinfo[i]->w_glsl_surfaces; } if (!s) continue; BSP_GLSLTexinfoChanged (s->texinfo->equiv, false); for (; s; s = s->texturechain) { BSP_RenderGLSLLightmappedPoly(s); r_currLMTex = s->lightmaptexturenum; } } BSP_FlushVBOAccum (); qglDisable (GL_ALPHA_TEST); qglActiveTextureARB (GL_TEXTURE1); qglDisable (GL_TEXTURE_2D); } void BSP_DrawGLSLDynamicSurfaces (qboolean forEnt) { int i; dlight_t *dl = NULL; int lnum, sv_lnum = 0; float add, brightest = 0; vec3_t lightVec; float lightCutoffSquared = 0.0f; qboolean foundLight = false; if (gl_dynamic->integer == 0) { return; } dl = r_newrefdef.dlights; for (lnum=0; lnumorigin, lightVec); add = dl->intensity - VectorLength(lightVec)/10; if (add > brightest) //only bother with lights close by { brightest = add; sv_lnum = lnum; //remember the position of most influencial light } } if(brightest > 0) { //we have a light foundLight= true; dynLight = r_newrefdef.dlights; dynLight += sv_lnum; //our most influential light lightCutoffSquared = ( dynLight->intensity - DLIGHT_CUTOFF ); if( lightCutoffSquared <= 0.0f ) lightCutoffSquared = 0.0f; lightCutoffSquared *= 2.0f; lightCutoffSquared *= lightCutoffSquared; // reset VBO batching state r_currTex = r_currLMTex = -99999; r_currTexInfo = NULL; r_currTangentSpaceTransform = NULL; BSP_ClearVBOAccum (); glUniform3fARB( g_location_lightPosition, dynLight->origin[0], dynLight->origin[1], dynLight->origin[2]); glUniform3fARB( g_location_lightColour, dynLight->color[0], dynLight->color[1], dynLight->color[2]); glUniform1fARB( g_location_lightCutoffSquared, lightCutoffSquared); if(gl_shadowmaps->integer) { //dynamic shadow glUniform1iARB( g_location_bspShadowmapTexture, 7); qglActiveTextureARB(GL_TEXTURE7); qglBindTexture(GL_TEXTURE_2D, r_depthtexture->texnum); glUniform1iARB( g_location_shadowmap, 1); glUniform1fARB( g_location_xOffs, 1.0/(viddef.width*r_shadowmapscale->value)); glUniform1fARB( g_location_yOffs, 1.0/(viddef.height*r_shadowmapscale->value)); } else glUniform1iARB( g_location_shadowmap, 0); } glUniform1iARB( g_location_dynamic, foundLight); r_vboOn = false; qglEnableClientState( GL_VERTEX_ARRAY ); qglClientActiveTextureARB (GL_TEXTURE0); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); qglClientActiveTextureARB (GL_TEXTURE1); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); KillFlags |= (KILL_TMU0_POINTER | KILL_TMU1_POINTER); for (i = 0; i < currentmodel->num_unique_texinfos; i++) { msurface_t *s; if (forEnt) { s = currentmodel->unique_texinfo[i]->e_glsl_dynamic_surfaces; currentmodel->unique_texinfo[i]->e_glsl_dynamic_surfaces = NULL; } else { s = currentmodel->unique_texinfo[i]->w_glsl_dynamic_surfaces; } if (!s) continue; BSP_GLSLTexinfoChanged (s->texinfo->equiv, true); for (; s; s = s->texturechain) { BSP_RenderGLSLLightmappedPoly(s); r_currLMTex = s->lightmaptexturenum; } } BSP_FlushVBOAccum (); qglDisable (GL_ALPHA_TEST); qglActiveTextureARB (GL_TEXTURE1); qglDisable (GL_TEXTURE_2D); } /* ========================================= This is the "API" for the BSP surface renderer backend, hiding most of the complexity of the previous functions. ========================================= */ /* ================ BSP_ClearWorldTextureChains Reset linked lists for the world (non-entity/non-brushmodel) surfaces. This need not be called every frame if r_optimize is on. No equivalent function is needed for entity surfaces because they are reset automatically when they are drawn. ================ */ void BSP_ClearWorldTextureChains (void) { int i; for (i = 0; i < currentmodel->num_unique_texinfos; i++) { currentmodel->unique_texinfo[i]->w_lightmap_surfaces = NULL; currentmodel->unique_texinfo[i]->w_glsl_surfaces = NULL; currentmodel->unique_texinfo[i]->w_glsl_dynamic_surfaces = NULL; } r_warp_surfaces = NULL; r_alpha_surfaces = NULL; r_rscript_surfaces = NULL; r_flicker_surfaces = NULL; } /* ================ BSP_AddToTextureChain Call this on a surface (and indicate whether it's an entity surface) and it will figure out which texture chain to add it to; this function is responsible for deciding if the surface is "ordinary" or somehow "special," whether it should be normalmapped and/or dynamically lit, etc. This function will be repeatedly called on all the surfaces in the current brushmodel entity or in the world's static geometry, followed by a single call to BSP_DrawTextureChains to render them all in one fell swoop. ================ */ void BSP_UpdateSurfaceLightmap (msurface_t *surf); void BSP_AddToTextureChain(msurface_t *surf, qboolean forEnt) { int map; rscript_t *rs_shader; qboolean is_dynamic = false; // Special surfaces that need to be handled separately if (surf->texinfo->flags & SURF_SKY) { // just adds to visible sky bounds R_AddSkySurface (surf); return; } if (SurfaceIsTranslucent(surf) && !SurfaceIsAlphaBlended(surf)) { // add to the translucent chain if (forEnt) { surf->texturechain = r_ent_alpha_surfaces; r_ent_alpha_surfaces = surf; } else { surf->texturechain = r_alpha_surfaces; r_alpha_surfaces = surf; } return; } if (surf->iflags & ISURF_DRAWTURB) { // add to the warped surfaces chain if (forEnt) { surf->texturechain = r_ent_warp_surfaces; r_ent_warp_surfaces = surf; } else { surf->texturechain = r_warp_surfaces; r_warp_surfaces = surf; } return; } // The rest of the function handles most ordinary surfaces: normalmapped, // non-normalmapped, and dynamically lit surfaces. As these three cases // are the most common, they are the most optimized-- grouped by texinfo, // etc. // XXX: we could require gl_bspnormalmaps here, but that would result in // weird inconsistency with only meshes lighting up. Better to fall back // on GLSL for dynamically lit surfaces, even with gl_bspnormalmaps 0. if(r_newrefdef.num_dlights && gl_state.glsl_shaders && gl_glsl_shaders->integer && gl_dynamic->integer) { // dynamic this frame or dynamic previously if ( ( surf->dlightframe == r_framecount ) ) { if ( !SurfaceHasNoLightmap(surf) ) is_dynamic = true; } } // reviving the ancient lightstyle system if ( !SurfaceHasNoLightmap(surf) ) { for ( map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++ ) { // Chain of surfaces that may need to have their lightmaps updated // in future frames (for dealing with r_optimize) if (surf->styles[map] != 0) { if (!forEnt) { surf->flickerchain = r_flicker_surfaces; r_flicker_surfaces = surf; break; } if ( r_newrefdef.lightstyles[surf->styles[map]].white != surf->cached_light[map]) { BSP_UpdateSurfaceLightmap (surf); break; } } } } if(is_dynamic && surf->texinfo->has_normalmap && gl_state.glsl_shaders && gl_glsl_shaders->integer) //always glsl for dynamic if it has a normalmap { if (forEnt) { surf->texturechain = surf->texinfo->equiv->e_glsl_dynamic_surfaces; surf->texinfo->equiv->e_glsl_dynamic_surfaces = surf; } else { surf->texturechain = surf->texinfo->equiv->w_glsl_dynamic_surfaces; surf->texinfo->equiv->w_glsl_dynamic_surfaces = surf; } } else if(gl_bspnormalmaps->integer && surf->texinfo->has_heightmap && surf->texinfo->has_normalmap && gl_state.glsl_shaders && gl_glsl_shaders->integer) { if (forEnt) { surf->texturechain = surf->texinfo->equiv->e_glsl_surfaces; surf->texinfo->equiv->e_glsl_surfaces = surf; } else { surf->texturechain = surf->texinfo->equiv->w_glsl_surfaces; surf->texinfo->equiv->w_glsl_surfaces = surf; } } else { if (forEnt) { surf->texturechain = surf->texinfo->equiv->e_lightmap_surfaces; surf->texinfo->equiv->e_lightmap_surfaces = surf; } else { surf->texturechain = surf->texinfo->equiv->w_lightmap_surfaces; surf->texinfo->equiv->w_lightmap_surfaces = surf; } } // Add to the rscript chain if there is actually a shader // TODO: investigate the possibility of doing this for brush models as // well-- might cause problems with caustics and brush models only half // submerged? if(!forEnt && r_shaders->integer) { rs_shader = (rscript_t *)surf->texinfo->image->script; if(rs_shader || (surf->iflags & ISURF_UNDERWATER)) { surf->rscriptchain = r_rscript_surfaces; r_rscript_surfaces = surf; } } } /* ================ BSP_DrawTextureChains Draw ALL surfaces for either the current entity or the world model. If drawing entity surfaces, reset the linked lists afterward. ================ */ void BSP_DrawTextureChains (qboolean forEnt) { msurface_t *flickersurf; int map; if (!forEnt) { R_KillVArrays (); // TODO: check if necessary for (flickersurf = r_flicker_surfaces; flickersurf != NULL; flickersurf = flickersurf->flickerchain) { for ( map = 0; map < MAXLIGHTMAPS && flickersurf->styles[map] != 255; map++ ) { if ( r_newrefdef.lightstyles[flickersurf->styles[map]].white != flickersurf->cached_light[map]) { BSP_UpdateSurfaceLightmap (flickersurf); break; } } } } // Setup GL state for lightmap render // (TODO: only necessary for fixed-function pipeline?) GL_EnableMultitexture( true ); GL_SelectTexture( GL_TEXTURE0); if ( !gl_config.mtexcombine ) { GL_TexEnv( GL_REPLACE ); GL_SelectTexture( GL_TEXTURE1); if ( gl_lightmap->integer ) GL_TexEnv( GL_REPLACE ); else GL_TexEnv( GL_MODULATE ); } else { GL_TexEnv ( GL_COMBINE_EXT ); qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE ); GL_SelectTexture( GL_TEXTURE1 ); GL_TexEnv ( GL_COMBINE_EXT ); if ( gl_lightmap->integer ) { qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE ); } else { qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT ); qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_EXT ); } if ( r_overbrightbits->value ) qglTexEnvi ( GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, r_overbrightbits->value ); } // render all fixed-function surfaces BSP_DrawNonGLSLSurfaces(forEnt); // render all GLSL surfaces, including normalmapped and dynamically lit if(gl_state.glsl_shaders && gl_glsl_shaders->integer) { glUseProgramObjectARB( g_programObj ); glUniform3fARB( g_location_eyePos, r_origin[0], r_origin[1], r_origin[2] ); glUniform1iARB( g_location_fog, map_fog); glUniform3fARB( g_location_staticLightPosition, r_worldLightVec[0], r_worldLightVec[1], r_worldLightVec[2]); BSP_DrawGLSLSurfaces(forEnt); BSP_DrawGLSLDynamicSurfaces(forEnt); glUseProgramObjectARB( 0 ); } // this has to come last because it messes with GL state BSP_DrawWarpSurfaces (forEnt); GL_EnableMultitexture( false ); } /* ============================================================= BRUSH MODELS ============================================================= */ /* ================= BSP_DrawInlineBModel Picks which of the current entity's surfaces face toward the camera, and calls BSP_AddToTextureChain on those. ================= */ void BSP_DrawInlineBModel ( void ) { int i; cplane_t *pplane; float dot; msurface_t *psurf; R_PushDlightsForBModel ( currententity ); if ( currententity->flags & RF_TRANSLUCENT ) { qglEnable (GL_BLEND); qglColor4f (1,1,1,0.25); GL_TexEnv( GL_MODULATE ); } psurf = ¤tmodel->surfaces[currentmodel->firstmodelsurface]; for (i=0 ; inummodelsurfaces ; i++, psurf++) { if (psurf->texinfo->flags & SURF_NODRAW) continue; //can skip dot product stuff // TODO: remove these at load-time for inline models? // find which side of the plane we are on pplane = psurf->plane; dot = DotProduct (modelorg, pplane->normal) - pplane->dist; // draw the polygon if (((psurf->iflags & ISURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) || (!(psurf->iflags & ISURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) { // TODO: do this once at load time psurf->entity = currententity; BSP_AddToTextureChain( psurf, true ); psurf->visframe = r_framecount; } } BSP_DrawTextureChains (true); qglDisable (GL_BLEND); qglColor4f (1,1,1,1); GL_TexEnv( GL_REPLACE ); R_KillVArrays (); } /* ================= R_DrawBrushModel ================= */ void R_DrawBrushModel ( void ) { vec3_t mins, maxs; int i; qboolean rotated; if (currentmodel->nummodelsurfaces == 0) return; gl_state.currenttextures[0] = gl_state.currenttextures[1] = -1; if (currententity->angles[0] || currententity->angles[1] || currententity->angles[2]) { rotated = true; for (i=0 ; i<3 ; i++) { mins[i] = currententity->origin[i] - currentmodel->radius; maxs[i] = currententity->origin[i] + currentmodel->radius; } } else { rotated = false; VectorAdd (currententity->origin, currentmodel->mins, mins); VectorAdd (currententity->origin, currentmodel->maxs, maxs); } if (R_CullBox (mins, maxs)) { return; } qglColor3f (1,1,1); VectorSubtract (r_newrefdef.vieworg, currententity->origin, modelorg); if (rotated) { vec3_t temp; vec3_t forward, right, up; VectorCopy (modelorg, temp); AngleVectors (currententity->angles, forward, right, up); modelorg[0] = DotProduct (temp, forward); modelorg[1] = -DotProduct (temp, right); modelorg[2] = DotProduct (temp, up); } qglPushMatrix (); currententity->angles[0] = -currententity->angles[0]; // stupid quake bug currententity->angles[2] = -currententity->angles[2]; // stupid quake bug R_RotateForEntity (currententity); currententity->angles[0] = -currententity->angles[0]; // stupid quake bug currententity->angles[2] = -currententity->angles[2]; // stupid quake bug BSP_DrawInlineBModel (); qglPopMatrix (); } /* ============================================================= WORLD MODEL ============================================================= */ /* ================= R_CullBox Returns true if the box is completely outside the frustum Variant: uses clipflags ================= */ qboolean R_CullBox_ClipFlags (vec3_t mins, vec3_t maxs, int clipflags) { int i; cplane_t *p; for (i=0,p=frustum ; i<4; i++,p++) { if (!(clipflags & (1<signbits) { case 0: if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist) return true; break; case 1: if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist) return true; break; case 2: if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist) return true; break; case 3: if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist) return true; break; case 4: if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist) return true; break; case 5: if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist) return true; break; case 6: if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist) return true; break; case 7: if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist) return true; break; default: return false; } } return false; } /* ================ BSP_RecursiveWorldNode Goes through the entire world (the BSP tree,) picks out which surfaces should be drawn, and calls BSP_AddToTextureChain on each. node: the BSP node to work on clipflags: indicate which planes of the frustum may intersect the node Since each node is inside its parent in 3D space, if a frustum plane can be shown not to intersect a node at all, then it won't intersect either of its children. ================ */ void BSP_RecursiveWorldNode (mnode_t *node, int clipflags) { int c, side; cplane_t *plane; msurface_t *surf, **mark; mleaf_t *pleaf; float dot; if (node->contents == CONTENTS_SOLID) return; // solid if (node->visframe != r_visframecount) return; // if a leaf node, draw stuff (pt 1) c = 0; if (node->contents != -1) { pleaf = (mleaf_t *)node; if (! (c = pleaf->nummarksurfaces) ) return; // check for door connected areas if (! (r_newrefdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) ) return; // not visible mark = pleaf->firstmarksurface; } if (!r_nocull->integer && clipflags) { int i, clipped; cplane_t *clipplane; for (i=0,clipplane=frustum ; i<4 ; i++,clipplane++) { if (!(clipflags & (1<minmaxs, node->minmaxs+3, clipplane); if (clipped == 1) clipflags &= ~(1<visframe = r_framecount; } while (--c); return; } // node is just a decision point, so go down the apropriate sides // find which side of the node we are on plane = node->plane; switch (plane->type) { case PLANE_X: dot = modelorg[0]; break; case PLANE_Y: dot = modelorg[1]; break; case PLANE_Z: dot = modelorg[2]; break; default: dot = DotProduct (modelorg, plane->normal); break; } side = dot < plane->dist; // recurse down the children, front side first BSP_RecursiveWorldNode (node->children[side], clipflags); // draw stuff for ( c = node->numsurfaces, surf = r_worldmodel->surfaces + node->firstsurface; c ; c--, surf++) { if (surf->visframe != r_framecount) continue; /* XXX: this doesn't seem to cull any surfaces AT ALL when positioned * here! The surf->visframe check seems to catch any back-facing * surfaces, but the back-facing surface check seems to allow some * surfaces which are later caught by the surf->visframe check. So the * visframe check renders the planeback check redundant and useless. * I'm pretty sure it's because the map compiler structures the BSP * tree in such a way as to avoid back-facing surfaces being drawn. * -M if ( (surf->flags & SURF_PLANEBACK) != side ) continue; // wrong side */ if (clipflags != 0 && !( surf->iflags & ISURF_DRAWTURB )) { if (R_CullBox_ClipFlags (surf->mins, surf->maxs, clipflags)) continue; } // the polygon is visible, so add it to the appropriate linked list // list BSP_AddToTextureChain( surf, false ); } // recurse down the back side BSP_RecursiveWorldNode (node->children[!side], clipflags); } /* ============= R_CalcWorldLights - this is the fallback for non deluxmapped bsp's ============= */ void R_CalcWorldLights( void ) { int i, j; vec3_t lightAdd, temp; float dist, weight; int numlights = 0; if(gl_glsl_shaders->integer && gl_state.glsl_shaders) { //get light position relative to player's position VectorClear(lightAdd); for (i = 0; i < r_lightgroups; i++) { VectorSubtract(r_origin, LightGroups[i].group_origin, temp); dist = VectorLength(temp); if(dist == 0) dist = 1; dist = dist*dist; weight = (int)250000/(dist/(LightGroups[i].avg_intensity+1.0f)); for(j = 0; j < 3; j++) lightAdd[j] += LightGroups[i].group_origin[j]*weight; numlights+=weight; } if(numlights > 0.0) { for(i = 0; i < 3; i++) r_worldLightVec[i] = (lightAdd[i]/numlights + r_origin[i])/2.0; } } } /* ============= R_DrawWorldSurfs ============= */ void R_DrawWorldSurfs (void) { if (!r_drawworld->integer) return; if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) return; if (r_newrefdef.areabits == NULL) { Com_Printf ("WARN: No area bits!\n"); return; } qglColor3f (1,1,1); BSP_DrawTextureChains ( false ); R_InitSun(); qglDepthMask(0); R_DrawSkyBox(); qglDepthMask(1); R_DrawRSSurfaces(); } /* =============== R_MarkLeaves Mark the leaves and nodes that are in the PVS for the current cluster =============== */ void R_MarkLeaves (void) { static byte *vis; static byte fatvis[MAX_MAP_LEAFS/8]; mnode_t *node; int i, c; mleaf_t *leaf; int cluster; static int minleaf_allareas, maxleaf_allareas; int minleaf, maxleaf; if ( r_oldviewcluster == r_viewcluster && r_oldviewcluster2 == r_viewcluster2 && !r_novis->integer && r_viewcluster != -1 && !r_newrefdef.areabits_changed) return; r_newrefdef.areabits_changed = false; // development aid to let you run around and see exactly where // the pvs ends if (gl_lockpvs->integer) return; r_oldviewcluster = r_viewcluster; r_oldviewcluster2 = r_viewcluster2; if (r_novis->integer || r_viewcluster == -1 || !r_worldmodel->vis) { r_visframecount++; // mark everything for (i=0 ; inumleafs ; i++) r_worldmodel->leafs[i].visframe = r_visframecount; for (i=0 ; inumnodes ; i++) r_worldmodel->nodes[i].visframe = r_visframecount; return; } vis = Mod_ClusterPVS (r_viewcluster, r_worldmodel); minleaf_allareas = r_viewleaf->minPVSleaf; maxleaf_allareas = r_viewleaf->maxPVSleaf; // may have to combine two clusters because of solid water boundaries if (r_viewcluster2 != r_viewcluster) { if (r_viewleaf2->minPVSleaf < minleaf_allareas) minleaf_allareas = r_viewleaf2->minPVSleaf; if (r_viewleaf2->maxPVSleaf > maxleaf_allareas) maxleaf_allareas = r_viewleaf2->maxPVSleaf; memcpy (fatvis, vis, (r_worldmodel->numleafs+7)/8); vis = Mod_ClusterPVS (r_viewcluster2, r_worldmodel); c = (r_worldmodel->numleafs+31)/32; for (i=0 ; inumleafs; for (i = 0; i < r_worldmodel->num_areas; i++) { if (r_newrefdef.areabits[i>>3] & (1<<(i&7))) { if (r_worldmodel->area_max_leaf[i] > areamax) areamax = r_worldmodel->area_max_leaf[i]; if (r_worldmodel->area_min_leaf[i] < areamin) areamin = r_worldmodel->area_min_leaf[i]; } } if (areamin < areamax) { if (areamin > minleaf) minleaf = areamin; if (areamax < maxleaf) maxleaf = areamax; } } for (i=minleaf,leaf=r_worldmodel->leafs+minleaf ; i<=maxleaf ; i++, leaf++) { cluster = leaf->cluster; if (cluster == -1) continue; if (vis[cluster>>3] & (1<<(cluster&7))) { node = (mnode_t *)leaf; do { if (node->visframe == r_visframecount) break; node->visframe = r_visframecount; node = node->parent; } while (node); } } } /* =============== R_MarkWorldSurfs Mark all surfaces that will need to be drawn this frame =============== */ void R_MarkWorldSurfs (void) { static entity_t ent; static int old_visframecount, old_dlightcount, last_bsp_time; static vec3_t old_origin, old_angle; vec3_t delta_origin, delta_angle; qboolean do_bsp; int cur_ms; if (!r_drawworld->integer) return; if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) return; if (r_newrefdef.areabits == NULL) { Com_Printf ("WARN: No area bits!\n"); return; } R_MarkLeaves (); currentmodel = r_worldmodel; VectorCopy (r_newrefdef.vieworg, modelorg); // auto cycle the world frame for texture animation memset (&ent, 0, sizeof(ent)); ent.frame = (int)(r_newrefdef.time*2); currententity = &ent; gl_state.currenttextures[0] = gl_state.currenttextures[1] = -1; R_CalcWorldLights(); // r_optimize: only re-recurse the BSP tree if the player has moved enough // to matter. VectorSubtract (r_origin, old_origin, delta_origin); VectorSubtract (r_newrefdef.viewangles, old_angle, delta_angle); do_bsp = old_visframecount != r_visframecount || VectorLength (delta_origin) > 5.0 || VectorLength (delta_angle) > 2.0 || r_newrefdef.num_dlights != 0 || old_dlightcount != 0 || !r_optimize->integer || draw_sun; cur_ms = Sys_Milliseconds (); // After a certain amount of time, increase the sensitivity to movement // and angle. If we go too long without re-recursing the BSP tree, it // means the player is either moving very slowly or not moving at all. If // the player is moving slowly enough, it can catch the r_optimize code // napping and cause artefacts, so we should be extra vigilant just in // case. Something you basically have to do on purpose, but we go the // extra mile. if (r_optimize->integer && !do_bsp) { // be sure to handle integer overflow of the millisecond counter if (cur_ms < last_bsp_time || last_bsp_time+100 < cur_ms) do_bsp = VectorLength (delta_origin) > 0.5 || VectorLength (delta_angle) > 0.2; } if (do_bsp) { R_ClearSkyBox (); BSP_ClearWorldTextureChains (); BSP_RecursiveWorldNode (r_worldmodel->nodes, 15); old_visframecount = r_visframecount; VectorCopy (r_origin, old_origin); VectorCopy (r_newrefdef.viewangles, old_angle); last_bsp_time = cur_ms; } old_dlightcount = r_newrefdef.num_dlights; } /* ============================================================================= LIGHTMAP ALLOCATION TODO: move this to another file, this is load-time stuff that doesn't run every frame. ============================================================================= */ static void LM_InitBlock (void) { memset( gl_lms.allocated, 0, sizeof( gl_lms.allocated ) ); } // Upload the current lightmap data to OpenGL, then clear it and prepare for // the next lightmap texture to be filled with data. // TODO: With HD lightmaps, are mipmaps a good idea here? // TODO: Opportunistically make lightmap texture smaller if not all is used? // Will require delaying lightmap texcoords for all surfaces until after // upload. static void LM_UploadBlock (void) { int texture = gl_lms.current_lightmap_texture; GL_SelectTexture (GL_TEXTURE0); // FIXME: OH FFS this is so stupid: tell the GL_Bind batching mechanism // that texture unit 0 has been re-bound, as it most certainly has been. gl_state.currenttextures[gl_state.currenttmu] = -1; GL_Bind( gl_state.lightmap_textures + texture ); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, LIGHTMAP_SIZE, LIGHTMAP_SIZE, 0, GL_LIGHTMAP_FORMAT, GL_UNSIGNED_INT_8_8_8_8_REV, gl_lms.lightmap_buffer ); #if 0 height = 0; for (i = 0; i < LIGHTMAP_SIZE; i++) { if (gl_lms.allocated[i] > height) height = gl_lms.allocated[i]; } Com_Printf (" LIGHTMAP %d HEIGHT %d\n", gl_lms.current_lightmap_texture, height); #endif if ( ++gl_lms.current_lightmap_texture == MAX_LIGHTMAPS ) Com_Error( ERR_DROP, "LM_UploadBlock() - MAX_LIGHTMAPS exceeded\n" ); } // LM_AllocBlock - given a certain size rectangle, allocates space inside the // lightmap texture atlas. // Returns a texture number and the position inside it. // TODO: there are some clever tricks I can think of to pack these more // tightly: opportunistically rotating lightmap textures by 90 degrees, // wrapping the lightmap textures around the edges of the atlas, and even // recognizing that not all surfaces are rectangular. static qboolean LM_AllocBlock (int w, int h, int *x, int *y) { int i, j; int best, best2; best = LIGHTMAP_SIZE; for (i=0 ; i= best) break; if (gl_lms.allocated[i+j] > best2) best2 = gl_lms.allocated[i+j]; } if (j == w) { // this is a valid spot *x = i; *y = best = best2; } } if (best + h > LIGHTMAP_SIZE) return false; for (i=0 ; inext = fa->polys; poly->numverts = lnumverts; fa->polys = poly; for (i=0 ; isurfedges[firstedge + i]; if (lindex > 0) { r_pedge = ¤tmodel->edges[lindex]; vec = currentmodel->vertexes[r_pedge->v[0]].position; } else { r_pedge = ¤tmodel->edges[-lindex]; vec = currentmodel->vertexes[r_pedge->v[1]].position; } s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3]; s /= fa->texinfo->image->width; t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3]; t /= fa->texinfo->image->height; VectorCopy (vec, poly->verts[i]); poly->verts[i][3] = s; poly->verts[i][4] = t; // set bbox for the surf used for culling if (vec[0] > surfmaxs[0]) surfmaxs[0] = vec[0]; if (vec[1] > surfmaxs[1]) surfmaxs[1] = vec[1]; if (vec[2] > surfmaxs[2]) surfmaxs[2] = vec[2]; if (vec[0] < surfmins[0]) surfmins[0] = vec[0]; if (vec[1] < surfmins[1]) surfmins[1] = vec[1]; if (vec[2] < surfmins[2]) surfmins[2] = vec[2]; // // lightmap texture coordinates // s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3]; s -= fa->texturemins[0]; s += light_s*xscale; s += xscale/2.0; s /= LIGHTMAP_SIZE*xscale; t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3]; t -= fa->texturemins[1]; t += light_t*yscale; t += yscale/2.0; t /= LIGHTMAP_SIZE*yscale; poly->verts[i][5] = s; poly->verts[i][6] = t; //to do - check if needed s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3]; s /= 128; t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3]; t /= 128; poly->verts[i][7] = s; poly->verts[i][8] = t; } #if 0 //SO PRETTY and useful for checking how much lightmap data is used up if (lnumverts == 4) { poly->verts[0][5] = 1; poly->verts[0][6] = 1; poly->verts[1][5] = 1; poly->verts[1][6] = 0; poly->verts[2][5] = 0; poly->verts[2][6] = 0; poly->verts[3][5] = 0; poly->verts[3][6] = 1; } #endif // store out the completed bbox VectorCopy (surfmins, fa->mins); VectorCopy (surfmaxs, fa->maxs); } /* ======================== BSP_CreateSurfaceLightmap ======================== */ void BSP_CreateSurfaceLightmap (msurface_t *surf, int smax, int tmax, int *light_s, int *light_t) { byte *base; if (!surf->samples) return; if (surf->texinfo->flags & (SURF_SKY|SURF_WARP)) return; //may not need this? if ( !LM_AllocBlock( smax, tmax, light_s, light_t ) ) { LM_UploadBlock( ); LM_InitBlock(); if ( !LM_AllocBlock( smax, tmax, light_s, light_t ) ) { Com_Error( ERR_FATAL, "Consecutive calls to LM_AllocBlock(%d,%d) failed\n", smax, tmax ); } } surf->lightmaptexturenum = gl_lms.current_lightmap_texture; surf->lightmins[0] = *light_s; surf->lightmins[1] = *light_t; surf->lightmaxs[0] = smax; surf->lightmaxs[1] = tmax; base = gl_lms.lightmap_buffer; base += ((*light_t) * LIGHTMAP_SIZE + *light_s) * LIGHTMAP_BYTES; R_SetCacheState( surf ); R_BuildLightMap (surf, base, smax, tmax, LIGHTMAP_SIZE*LIGHTMAP_BYTES); } void BSP_UpdateSurfaceLightmap (msurface_t *surf) { R_SetCacheState (surf); R_BuildLightMap (surf, gl_lms.lightmap_buffer, surf->lightmaxs[0], surf->lightmaxs[1], surf->lightmaxs[0]*LIGHTMAP_BYTES); GL_SelectTexture (GL_TEXTURE0); // FIXME: OH FFS this is so stupid: tell the GL_Bind batching mechanism // that texture unit 0 has been re-bound, as it most certainly has been. gl_state.currenttextures[gl_state.currenttmu] = -1; GL_Bind( gl_state.lightmap_textures + surf->lightmaptexturenum ); qglTexSubImage2D( GL_TEXTURE_2D, 0, surf->lightmins[0], surf->lightmins[1], surf->lightmaxs[0], surf->lightmaxs[1], GL_LIGHTMAP_FORMAT, GL_UNSIGNED_INT_8_8_8_8_REV, gl_lms.lightmap_buffer ); } /* ================== BSP_BeginBuildingLightmaps ================== */ void BSP_BeginBuildingLightmaps (model_t *m) { static lightstyle_t lightstyles[MAX_LIGHTSTYLES]; int i; memset( gl_lms.allocated, 0, sizeof(gl_lms.allocated) ); r_framecount = 1; // no dlightcache GL_EnableMultitexture( true ); GL_SelectTexture( GL_TEXTURE1); /* ** setup the base lightstyles so the lightmaps won't have to be regenerated ** the first time they're seen */ for (i=0 ; icontents == CONTENTS_SOLID) return; // solid if(r_minimap_zoom->value>=0.1) { distance = 1024.0/r_minimap_zoom->value; } else { distance = 1024.0; } if ( r_origin[0]+distance < node->minmaxs[0] || r_origin[0]-distance > node->minmaxs[3] || r_origin[1]+distance < node->minmaxs[1] || r_origin[1]-distance > node->minmaxs[4] || r_origin[2]+256 < node->minmaxs[2] || r_origin[2]-256 > node->minmaxs[5]) return; // if a leaf node, draw stuff if (node->contents != -1) { pleaf = (mleaf_t *)node; // check for door connected areas if (! (r_newrefdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) ) return; // not visible mark = pleaf->firstmarksurface; c = pleaf->nummarksurfaces; if (c) { do { (*mark)->visframe = r_framecount; mark++; } while (--c); } return; } // node is just a decision point, so go down the apropriate sides // find which side of the node we are on plane = node->plane; switch (plane->type) { case PLANE_X: dot = modelorg[0] - plane->dist; break; case PLANE_Y: dot = modelorg[1] - plane->dist; break; case PLANE_Z: dot = modelorg[2] - plane->dist; break; default: dot = DotProduct (modelorg, plane->normal) - plane->dist; break; } if (dot >= 0) { side = 0; } else { side = 1; } // recurse down the children, front side first R_RecursiveRadarNode (node->children[side]); if(plane->normal[2]) { // draw stuff if(plane->normal[2]>0) for ( c = node->numsurfaces, surf = r_worldmodel->surfaces + node->firstsurface; c ; c--, surf++) { if (surf->texinfo->flags & SURF_SKY){ continue; } } } else { qglDisable(GL_TEXTURE_2D); for ( c = node->numsurfaces, surf = r_worldmodel->surfaces + node->firstsurface; c ; c--, surf++) { float sColor,C[4]; if (surf->texinfo->flags & SURF_SKY) continue; if (surf->texinfo->flags & (SURF_WARP|SURF_FLOWING|SURF_TRANS33|SURF_TRANS66)) { sColor=0.5; } else { sColor=0; } for ( p = surf->polys; p; p = p->chain ) { v = p->verts[0]; qglBegin(GL_LINE_STRIP); for (i=0 ; i< p->numverts; i++, v+= VERTEXSIZE) { C[3]= (v[2]-r_origin[2])/512.0; if (C[3]>0) { C[0]=0.5; C[1]=0.5+sColor; C[2]=0.5; C[3]=1-C[3]; } else { C[0]=0.5; C[1]=sColor; C[2]=0; C[3]+=1; } if(C[3]<0) { C[3]=0; } qglColor4fv(C); qglVertex3fv (v); } qglEnd(); } } qglEnable(GL_TEXTURE_2D); } // recurse down the back side R_RecursiveRadarNode (node->children[!side]); } int numRadarEnts=0; RadarEnt_t RadarEnts[MAX_RADAR_ENTS]; void R_DrawRadar(void) { int i; float fS[4]={0,0,-1.0/512.0,0}; if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) return; if(!r_minimap->integer) return; if (!r_newrefdef.areabits) return; qglViewport ( r_newrefdef.x+r_newrefdef.width-r_minimap_size->value, vid.height-r_newrefdef.y-r_newrefdef.height, r_minimap_size->value, r_minimap_size->value); qglDisable(GL_DEPTH_TEST); qglMatrixMode(GL_PROJECTION); qglPushMatrix(); qglLoadIdentity (); if (r_minimap_style->integer) { qglOrtho(-1024,1024,-1024,1024,-256,256); } else { qglOrtho(-1024,1024,-512,1536,-256,256); } qglMatrixMode(GL_MODELVIEW); qglPushMatrix(); qglLoadIdentity (); { qglStencilMask(255); qglClear(GL_STENCIL_BUFFER_BIT); qglEnable(GL_STENCIL_TEST); qglStencilFunc(GL_ALWAYS,4,4); qglStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE); GLSTATE_ENABLE_ALPHATEST; qglAlphaFunc(GL_LESS,0.1); qglColorMask(0,0,0,0); qglColor4f(1,1,1,1); if(r_around) GL_Bind(r_around->texnum); qglBegin(GL_TRIANGLE_FAN); if (r_minimap_style->integer){ qglTexCoord2f(0,1); qglVertex3f(1024,-1024,1); qglTexCoord2f(1,1); qglVertex3f(-1024,-1024,1); qglTexCoord2f(1,0); qglVertex3f(-1024,1024,1); qglTexCoord2f(0,0); qglVertex3f(1024,1024,1); } else { qglTexCoord2f(0,1); qglVertex3f(1024,-512,1); qglTexCoord2f(1,1); qglVertex3f(-1024,-512,1); qglTexCoord2f(1,0); qglVertex3f(-1024,1536,1); qglTexCoord2f(0,0); qglVertex3f(1024,1536,1); } qglEnd(); qglColorMask(1,1,1,1); GLSTATE_DISABLE_ALPHATEST; qglAlphaFunc(GL_GREATER, 0.5); qglStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE); qglStencilFunc(GL_NOTEQUAL,4,4); } if(r_minimap_zoom->value>=0.1) { qglScalef(r_minimap_zoom->value,r_minimap_zoom->value,r_minimap_zoom->value); } if (r_minimap_style->integer) { qglPushMatrix(); qglRotatef (90-r_newrefdef.viewangles[1], 0, 0, -1); qglDisable(GL_TEXTURE_2D); qglBegin(GL_TRIANGLES); qglColor4f(1,1,1,0.5); qglVertex3f(0,32,0); qglColor4f(1,1,0,0.5); qglVertex3f(24,-32,0); qglVertex3f(-24,-32,0); qglEnd(); qglPopMatrix(); } else { qglDisable(GL_TEXTURE_2D); qglBegin(GL_TRIANGLES); qglColor4f(1,1,1,0.5); qglVertex3f(0,32,0); qglColor4f(1,1,0,0.5); qglVertex3f(24,-32,0); qglVertex3f(-24,-32,0); qglEnd(); qglRotatef (90-r_newrefdef.viewangles[1], 0, 0, 1); } qglTranslatef (-r_newrefdef.vieworg[0], -r_newrefdef.vieworg[1], -r_newrefdef.vieworg[2]); qglBegin(GL_QUADS); for(i=0;itexnum); qglBlendFunc(GL_SRC_ALPHA, GL_ONE); GLSTATE_ENABLE_BLEND; qglColor3f(1,1,1); fS[3]=0.5+ r_newrefdef.vieworg[2]/512.0; qglTexGenf(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); GLSTATE_ENABLE_TEXGEN; qglTexGenfv(GL_S,GL_OBJECT_PLANE,fS); // draw the stuff R_RecursiveRadarNode (r_worldmodel->nodes); qglBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); GLSTATE_DISABLE_TEXGEN; qglPopMatrix(); qglViewport(0,0,vid.width,vid.height); qglMatrixMode(GL_PROJECTION); qglPopMatrix(); qglMatrixMode(GL_MODELVIEW); qglDisable(GL_STENCIL_TEST); GL_TexEnv( GL_REPLACE ); GLSTATE_DISABLE_BLEND; qglEnable(GL_DEPTH_TEST); qglColor4f(1,1,1,1); } alien-arena-7.66+dfsg/source/ref_gl/r_math.h0000600000175000017500000000363112161402007017774 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // r_math.h typedef vec_t mat4x4_t[16]; extern const mat4x4_t mat4x4_identity; void Matrix4_Identity( mat4x4_t m ); void Matrix4_Copy( const mat4x4_t m1, mat4x4_t m2 ); qboolean Matrix4_Compare( const mat4x4_t m1, const mat4x4_t m2 ); void Matrix4_Multiply( const mat4x4_t m1, const mat4x4_t m2, mat4x4_t out ); void Matrix4_MultiplyFast( const mat4x4_t m1, const mat4x4_t m2, mat4x4_t out ); void Matrix4_Rotate( mat4x4_t m, vec_t angle, vec_t x, vec_t y, vec_t z ); void Matrix4_Translate( mat4x4_t m, vec_t x, vec_t y, vec_t z ); void Matrix4_Scale( mat4x4_t m, vec_t x, vec_t y, vec_t z ); void Matrix4_Transpose( const mat4x4_t m, mat4x4_t out ); void Matrix4_Matrix( const mat4x4_t in, vec3_t out[3] ); void Matrix4_Multiply_Vector( const mat4x4_t m, const vec4_t v, vec4_t out ); void Matrix4_Copy2D( const mat4x4_t m1, mat4x4_t m2 ); void Matrix4_Multiply2D( const mat4x4_t m1, const mat4x4_t m2, mat4x4_t out ); void Matrix4_Scale2D( mat4x4_t m, vec_t x, vec_t y ); void Matrix4_Translate2D( mat4x4_t m, vec_t x, vec_t y ); void Matrix4_Stretch2D( mat4x4_t m, vec_t s, vec_t t ); #define nanmask (255<<23) #define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask) alien-arena-7.66+dfsg/source/ref_gl/r_ragdoll.c0000600000175000017500000013772112161402007020472 0ustar zero79zero79/* Copyright (C) 2010 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "r_local.h" #include "r_ragdoll.h" //This file will handle all of the ragdoll calculations, etc. //Notes: //Once a model's frames are at the death stage, the ragdoll takes over. //The world objects are created each time a map is loaded. //We get rotation and location vectors from the //ragdoll, and apply them to the models skeleton. //Ragdolls are batched and drawn just as regular entities, which also means that entities should not be drawn in their normal //batch once in a death animation. When death animations begin, a ragdoll is be generated with the appropriate properties including //position, angles, etc. The ragdoll is timestamped, and is removed from the stack after a certain amount of time has //elapsed. We also take some information from the entity to transfer to the ragdoll, such as the model and skin. cvar_t *r_ragdolls; cvar_t *r_ragdoll_debug; vec3_t rightAxis, leftAxis, upAxis, downAxis, bkwdAxis, fwdAxis; signed int sign(signed int x) { if( x > 0.0 ) return 1.0; else return -1.0; } void norm3(vec3_t v, vec3_t out) { float l = VectorLength(v); if(l > 0.0) { out[0] = v[0] / l; out[1] = v[1] / l; out[2] = v[2] / l; return; } else { VectorClear(out); } } extern void Matrix3x4ForEntity(matrix3x4_t *out, entity_t *ent); extern void Matrix3x4_Invert(matrix3x4_t *out, matrix3x4_t in); extern void Matrix3x4_Multiply(matrix3x4_t *out, matrix3x4_t mat1, matrix3x4_t mat2); extern void Matrix3x4_Add(matrix3x4_t *out, matrix3x4_t mat1, matrix3x4_t mat2); extern void Matrix3x4_Scale(matrix3x4_t *out, matrix3x4_t in, float scale); //routine to create ragdoll body parts between two joints void RGD_addBody(int RagDollID, matrix3x4_t *bindmat, char *name, int objectID, vec3_t p1, vec3_t p2, float radius, float density) { //Adds a capsule body between joint positions p1 and p2 and with given //radius to the ragdoll. int i, nans; float length; vec3_t xa, ya, za, temp; matrix3x4_t initmat; dMatrix3 rot; p1[1] -= RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[GLOBAL_Y_OFF]; p1[2] += RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[GLOBAL_Z_OFF]; p2[1] -= RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[GLOBAL_Y_OFF]; p2[2] += RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[GLOBAL_Z_OFF]; //cylinder length not including endcaps, make capsules overlap by half //radius at joints VectorSubtract(p1, p2, temp); length = VectorLength(temp) - radius; if(length <= 0) length = 0.1f; //create body id RagDoll[RagDollID].RagDollObject[objectID].body = dBodyCreate(RagDollWorld); //creat the geometry and give it a name RagDoll[RagDollID].RagDollObject[objectID].geom = dCreateCapsule (RagDollSpace, radius, length); dGeomSetData(RagDoll[RagDollID].RagDollObject[objectID].geom, name); dGeomSetBody(RagDoll[RagDollID].RagDollObject[objectID].geom, RagDoll[RagDollID].RagDollObject[objectID].body); //set it's mass dMassSetCapsule (&RagDoll[RagDollID].RagDollObject[objectID].mass, density, 3, radius, length); dBodySetMass(RagDoll[RagDollID].RagDollObject[objectID].body, &RagDoll[RagDollID].RagDollObject[objectID].mass); //define body rotation automatically from body axis VectorSubtract(p2, p1, za); norm3(za, za); VectorSet(temp, 1.0, 0.0, 0.0); if (abs(DotProduct(za, temp)) < 0.7) VectorSet(xa, 1.0, 0.0, 0.0); else VectorSet(xa, 0.0, 1.0, 0.0); CrossProduct(za, xa, ya); CrossProduct(ya, za, xa); norm3(xa, xa); CrossProduct(za, xa, ya); Vector4Set(initmat.a, xa[0], ya[0], za[0], 0.5*(p1[0] + p2[0])); Vector4Set(initmat.b, xa[1], ya[1], za[1], 0.5*(p1[1] + p2[1])); Vector4Set(initmat.c, xa[2], ya[2], za[2], 0.5*(p1[2] + p2[2])); nans = 0; for(i = 0; i < 4; i++) { if(IS_NAN(initmat.a[i])) { initmat.a[i] = 0; nans++; } if(IS_NAN(initmat.b[i])) { initmat.b[i] = 0; nans++; } if(IS_NAN(initmat.c[i])) { initmat.c[i] = 0; nans++; } } if(nans > 0) { if(r_ragdoll_debug->integer) Com_Printf("There was a NaN in creating body %i\n", objectID); } Matrix3x4_Invert(&RagDoll[RagDollID].RagDollObject[objectID].initmat, initmat); Matrix3x4_Multiply(&initmat, bindmat[objectID], initmat); Vector4Set(&rot[0], initmat.a[0], initmat.a[1], initmat.a[2], 0); Vector4Set(&rot[4], initmat.b[0], initmat.b[1], initmat.b[2], 0); Vector4Set(&rot[8], initmat.c[0], initmat.c[1], initmat.c[2], 0); dBodySetPosition(RagDoll[RagDollID].RagDollObject[objectID].body, initmat.a[3], initmat.b[3], initmat.c[3]); dBodySetRotation(RagDoll[RagDollID].RagDollObject[objectID].body, rot); dBodySetForce(RagDoll[RagDollID].RagDollObject[objectID].body, 0, 0, 0); dBodySetLinearVel(RagDoll[RagDollID].RagDollObject[objectID].body, 0, 40, 150); //a little initial upward velocity dBodySetAngularVel(RagDoll[RagDollID].RagDollObject[objectID].body, 0, 0, 0); } //joint creation routines void RGD_addFixedJoint(int RagDollID, matrix3x4_t *bindmat, int jointID, int object1, int object2) { dBodyID body1 = RagDoll[RagDollID].RagDollObject[object1].body; dBodyID body2 = RagDoll[RagDollID].RagDollObject[object2].body; RagDoll[RagDollID].RagDollJoint[jointID] = dJointCreateFixed(RagDollWorld, 0); dJointAttach(RagDoll[RagDollID].RagDollJoint[jointID], body1, body2); dJointSetFixed(RagDoll[RagDollID].RagDollJoint[jointID]); } void RGD_addHingeJoint(int RagDollID, matrix3x4_t *bindmat, int jointID, int object1, int object2, vec3_t anchor, vec3_t axis, float loStop, float hiStop) { dBodyID body1 = RagDoll[RagDollID].RagDollObject[object1].body; dBodyID body2 = RagDoll[RagDollID].RagDollObject[object2].body; vec3_t wanchor, waxis; anchor[1] -= RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[GLOBAL_Y_OFF]; anchor[2] += RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[GLOBAL_Z_OFF]; wanchor[0] = 0.5*(DotProduct(bindmat[object1].a, anchor) + bindmat[object1].a[3] + DotProduct(bindmat[object2].a, anchor) + bindmat[object2].a[3]); wanchor[1] = 0.5*(DotProduct(bindmat[object1].b, anchor) + bindmat[object1].b[3] + DotProduct(bindmat[object2].b, anchor) + bindmat[object2].b[3]); wanchor[2] = 0.5*(DotProduct(bindmat[object1].c, anchor) + bindmat[object1].c[3] + DotProduct(bindmat[object2].c, anchor) + bindmat[object2].c[3]); waxis[0] = DotProduct(bindmat[object1].a, axis) + DotProduct(bindmat[object2].a, axis); waxis[1] = DotProduct(bindmat[object1].b, axis) + DotProduct(bindmat[object2].b, axis); waxis[2] = DotProduct(bindmat[object1].c, axis) + DotProduct(bindmat[object2].c, axis); VectorNormalize(waxis); VectorAdd(anchor, RagDoll[RagDollID].origin, anchor); RagDoll[RagDollID].RagDollJoint[jointID] = dJointCreateHinge(RagDollWorld, 0); dJointAttach(RagDoll[RagDollID].RagDollJoint[jointID], body1, body2); dJointSetHingeAnchor(RagDoll[RagDollID].RagDollJoint[jointID], wanchor[0], wanchor[1], wanchor[2]); dJointSetHingeAxis(RagDoll[RagDollID].RagDollJoint[jointID], waxis[0], waxis[1], waxis[2]); dJointSetHingeParam(RagDoll[RagDollID].RagDollJoint[jointID], dParamLoStop, loStop); dJointSetHingeParam(RagDoll[RagDollID].RagDollJoint[jointID], dParamHiStop, hiStop); } void RGD_addBallJoint(int RagDollID, matrix3x4_t *bindmat, int jointID, int object1, int object2, vec3_t anchor) { dBodyID body1 = RagDoll[RagDollID].RagDollObject[object1].body; dBodyID body2 = RagDoll[RagDollID].RagDollObject[object2].body; vec3_t wanchor; anchor[1] -= RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[GLOBAL_Y_OFF]; anchor[2] += RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[GLOBAL_Z_OFF]; wanchor[0] = 0.5*(DotProduct(bindmat[object1].a, anchor) + bindmat[object1].a[3] + DotProduct(bindmat[object2].a, anchor) + bindmat[object2].a[3]); wanchor[1] = 0.5*(DotProduct(bindmat[object1].b, anchor) + bindmat[object1].b[3] + DotProduct(bindmat[object2].b, anchor) + bindmat[object2].b[3]); wanchor[2] = 0.5*(DotProduct(bindmat[object1].c, anchor) + bindmat[object1].c[3] + DotProduct(bindmat[object2].c, anchor) + bindmat[object2].c[3]); RagDoll[RagDollID].RagDollJoint[jointID] = dJointCreateBall(RagDollWorld, 0); dJointAttach(RagDoll[RagDollID].RagDollJoint[jointID], body1, body2); dJointSetBallAnchor(RagDoll[RagDollID].RagDollJoint[jointID], wanchor[0], wanchor[1], wanchor[2]); } void RGD_addUniversalJoint(int RagDollID, matrix3x4_t *bindmat, int jointID, int object1, int object2, vec3_t anchor, vec3_t axis1, vec3_t axis2, float loStop1, float hiStop1, float loStop2, float hiStop2) { vec3_t wanchor, waxis1, waxis2; dBodyID body1 = RagDoll[RagDollID].RagDollObject[object1].body; dBodyID body2 = RagDoll[RagDollID].RagDollObject[object2].body; anchor[1] -= RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[GLOBAL_Y_OFF]; anchor[2] += RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[GLOBAL_Z_OFF]; wanchor[0] = 0.5*(DotProduct(bindmat[object1].a, anchor) + bindmat[object1].a[3] + DotProduct(bindmat[object2].a, anchor) + bindmat[object2].a[3]); wanchor[1] = 0.5*(DotProduct(bindmat[object1].b, anchor) + bindmat[object1].b[3] + DotProduct(bindmat[object2].b, anchor) + bindmat[object2].b[3]); wanchor[2] = 0.5*(DotProduct(bindmat[object1].c, anchor) + bindmat[object1].c[3] + DotProduct(bindmat[object2].c, anchor) + bindmat[object2].c[3]); waxis1[0] = DotProduct(bindmat[object1].a, axis1) + DotProduct(bindmat[object2].a, axis1); waxis1[1] = DotProduct(bindmat[object1].b, axis1) + DotProduct(bindmat[object2].b, axis1); waxis1[2] = DotProduct(bindmat[object1].c, axis1) + DotProduct(bindmat[object2].c, axis1); VectorNormalize(waxis1); waxis2[0] = DotProduct(bindmat[object1].a, axis2) + DotProduct(bindmat[object2].a, axis2); waxis2[1] = DotProduct(bindmat[object1].b, axis2) + DotProduct(bindmat[object2].b, axis2); waxis2[2] = DotProduct(bindmat[object1].c, axis2) + DotProduct(bindmat[object2].c, axis2); VectorNormalize(waxis2); RagDoll[RagDollID].RagDollJoint[jointID] = dJointCreateUniversal(RagDollWorld, 0); dJointAttach(RagDoll[RagDollID].RagDollJoint[jointID], body1, body2); dJointSetUniversalAnchor(RagDoll[RagDollID].RagDollJoint[jointID], wanchor[0], wanchor[1], wanchor[2]); dJointSetUniversalAxis1(RagDoll[RagDollID].RagDollJoint[jointID], waxis1[0], waxis1[1], waxis1[2]); dJointSetUniversalAxis2(RagDoll[RagDollID].RagDollJoint[jointID], waxis2[0], waxis2[1], waxis2[2]); dJointSetUniversalParam(RagDoll[RagDollID].RagDollJoint[jointID], dParamHiStop1, hiStop1); dJointSetUniversalParam(RagDoll[RagDollID].RagDollJoint[jointID], dParamLoStop1, loStop1); dJointSetUniversalParam(RagDoll[RagDollID].RagDollJoint[jointID], dParamHiStop2, hiStop2); dJointSetUniversalParam(RagDoll[RagDollID].RagDollJoint[jointID], dParamLoStop2, loStop2); } #if !defined WIN32_VARIANT /* Constants: * CFM -- "Constraint Force Mixing" * ERP -- "Error Reduction Parameter" * See ODE documentation for more info. * * These are needed to get ragdolls to come to complete rest. * They are determined empirically by observing when the ragdolls on * the floor stop vibrating. * * We will just hard code them, until there is some reason not to. */ const dReal world_cfm_setting = 5.5e-6; const dReal world_erp_setting = 0.3; #endif void RGD_CreateWorldObject( void ) { // Initialize the world RagDollWorld = dWorldCreate(); dWorldSetGravity(RagDollWorld, 0.0, 0.0, -512.0); #if !defined WIN32_VARIANT /* Added to support dWorldQuickStep(), which is needed for ODE v0.12 */ dWorldSetCFM( RagDollWorld, world_cfm_setting ); dWorldSetERP( RagDollWorld, world_erp_setting ); Com_Printf("RagDollWorld Settings: CFM (%.12f) ERP (%.3f)\n", world_cfm_setting, world_erp_setting ); #endif RagDollSpace = dSimpleSpaceCreate(0); contactGroup = dJointGroupCreate(0); //axi used to determine constrained joint rotations VectorSet(rightAxis, 1.0, 0.0, 0.0); VectorSet(leftAxis, -1.0, 0.0, 0.0); VectorSet(upAxis, 0.0, 1.0, 0.0); VectorSet(downAxis, 0.0, -1.0, 0.0); VectorSet(bkwdAxis, 0.0, 0.0, 1.0); VectorSet(fwdAxis, 0.0, 0.0, -1.0); lastODEUpdate = Sys_Milliseconds(); r_DrawingRagDoll = false; } void RGD_DestroyWorldObject( void ) { if(RagDollWorld) { dWorldDestroy(RagDollWorld); RagDollWorld = NULL; } if(RagDollSpace) { dSpaceDestroy (RagDollSpace); RagDollSpace = NULL; } if(contactGroup) { dJointGroupDestroy(contactGroup); contactGroup = NULL; } } RagDollBind_t RagDollBinds[] = { { "hip.l", PELVIS }, { "hip.r", PELVIS }, { "Spine", CHEST }, { "Spine.001", CHEST }, { "Head", HEAD }, { "thigh.r", RIGHTUPPERLEG }, { "thigh.l", LEFTUPPERLEG }, { "shin.r", RIGHTLOWERLEG }, { "shin.l", LEFTLOWERLEG }, { "bicep.r", RIGHTUPPERARM }, { "bicep.l", LEFTUPPERARM }, { "forearm.r", RIGHTFOREARM }, { "forearm.l", LEFTFOREARM }, { "hand01.r", RIGHTHAND }, { "hand01.l", LEFTHAND }, { "hand02.r", RIGHTHAND }, { "hand02.l", LEFTHAND }, { "hand03.r", RIGHTHAND }, { "hand03.l", LEFTHAND }, { "wrist.l", LEFTHAND }, { "wrist.r", RIGHTHAND }, { "foot.r", RIGHTFOOT }, { "toe.r", RIGHTFOOT }, { "foot.l", LEFTFOOT }, { "toe.l", LEFTFOOT } }; int RagDollBindsCount = (int)(sizeof(RagDollBinds)/sizeof(RagDollBinds[0])); //build and set initial position of ragdoll void RGD_RagdollBody_Init( int RagDollID, vec3_t origin, char name[MAX_QPATH] ) { //Ragdoll positions vec3_t R_SHOULDER_POS; vec3_t L_SHOULDER_POS; vec3_t R_ELBOW_POS; vec3_t L_ELBOW_POS; vec3_t R_WRIST_POS; vec3_t L_WRIST_POS; vec3_t R_FINGERS_POS; vec3_t L_FINGERS_POS; vec3_t R_HIP_POS; vec3_t L_HIP_POS; vec3_t R_KNEE_POS; vec3_t L_KNEE_POS; vec3_t R_ANKLE_POS; vec3_t L_ANKLE_POS; vec3_t R_HEEL_POS; vec3_t L_HEEL_POS; vec3_t R_TOES_POS; vec3_t L_TOES_POS; vec3_t p1, p2; float density; matrix3x4_t entmat, temp, bindmat[MAX_RAGDOLL_OBJECTS]; int bindweight[MAX_RAGDOLL_OBJECTS]; int i, j; //we need some information from the current entity strcpy(RagDoll[RagDollID].name, name); RagDoll[RagDollID].ragDollMesh = (model_t *)malloc (sizeof(model_t)); memcpy(RagDoll[RagDollID].ragDollMesh, currententity->model, sizeof(model_t)); RagDoll[RagDollID].initframe = (matrix3x4_t *)malloc (currententity->model->num_joints*sizeof(matrix3x4_t)); memcpy(RagDoll[RagDollID].initframe, currententity->model->outframe, currententity->model->num_joints*sizeof(matrix3x4_t)); if(r_shaders->integer && currententity->script) { RagDoll[RagDollID].script = (rscript_t *)malloc (sizeof(rscript_t)); memcpy(RagDoll[RagDollID].script, currententity->script, sizeof(rscript_t)); if(currententity->script->stage) { RagDoll[RagDollID].script->stage = (rs_stage_t *)malloc ( sizeof(rs_stage_t)); memcpy(RagDoll[RagDollID].script->stage, currententity->script->stage, sizeof(rs_stage_t)); if(currententity->script->stage->next) { RagDoll[RagDollID].script->stage->next = (rs_stage_t *)malloc ( sizeof(rs_stage_t)); memcpy(RagDoll[RagDollID].script->stage->next, currententity->script->stage->next, sizeof(rs_stage_t)); RagDoll[RagDollID].script->stage->next->next = NULL; } else RagDoll[RagDollID].script->stage->next = NULL; } else RagDoll[RagDollID].script->stage = NULL; } else RagDoll[RagDollID].script = NULL; RagDoll[RagDollID].texnum = currententity->skin->texnum; RagDoll[RagDollID].flags = currententity->flags; _VectorCopy(currententity->angles, RagDoll[RagDollID].angles); VectorCopy(origin, RagDoll[RagDollID].origin); VectorCopy(origin, RagDoll[RagDollID].curPos); RagDoll[RagDollID].spawnTime = Sys_Milliseconds(); RagDoll[RagDollID].destroyed = false; memset(bindmat, 0, sizeof(bindmat)); memset(bindweight, 0, sizeof(bindweight)); for(i = 0; i < RagDoll[RagDollID].ragDollMesh->num_joints; i++) { for(j = 0; j < RagDollBindsCount; j++) { if(RagDoll[RagDollID].ragDollMesh->version == 1) { if(!strcmp(&RagDoll[RagDollID].ragDollMesh->jointname[RagDoll[RagDollID].ragDollMesh->joints[i].name], RagDollBinds[j].name)) { int object = RagDollBinds[j].object; if ( ! IS_NAN( RagDoll[RagDollID].initframe[i].a[0] ) ) { Matrix3x4_Add(&bindmat[object], bindmat[object], RagDoll[RagDollID].initframe[i]); } bindweight[object]++; break; } } else { if(!strcmp(&RagDoll[RagDollID].ragDollMesh->jointname[RagDoll[RagDollID].ragDollMesh->joints2[i].name], RagDollBinds[j].name)) { int object = RagDollBinds[j].object; if ( ! IS_NAN( RagDoll[RagDollID].initframe[i].a[0] ) ) { Matrix3x4_Add(&bindmat[object], bindmat[object], RagDoll[RagDollID].initframe[i]); } bindweight[object]++; break; } } } } Matrix3x4ForEntity(&entmat, currententity); for(i = 0; i < MAX_RAGDOLL_OBJECTS; i++) { if(bindweight[i]) { Matrix3x4_Scale(&temp, bindmat[i], 1.0/bindweight[i]); VectorNormalize(temp.a); VectorNormalize(temp.b); VectorNormalize(temp.c); Matrix3x4_Multiply(&bindmat[i], entmat, temp); } else bindmat[i] = entmat; } //set upper body VectorSet(R_SHOULDER_POS, -RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[SHOULDER_W] * 0.5, 0.0, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[SHOULDER_H]); VectorSet(L_SHOULDER_POS, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[SHOULDER_W] * 0.5, 0.0, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[SHOULDER_H]); VectorSet(R_ELBOW_POS, -RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[ELBOW_X_OFF], RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[ELBOW_Y_OFF], RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[ELBOW_Z_OFF]); VectorSet(L_ELBOW_POS, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[ELBOW_X_OFF], RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[ELBOW_Y_OFF], RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[ELBOW_Z_OFF]); VectorSet(R_WRIST_POS, -RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[WRIST_X_OFF], -RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[WRIST_Y_OFF], RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[WRIST_Z_OFF]); VectorSet(L_WRIST_POS, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[WRIST_X_OFF], -RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[WRIST_Y_OFF], RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[WRIST_Z_OFF]); VectorSet(R_FINGERS_POS, -RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[FINGERS_X_OFF], -RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[FINGERS_Y_OFF], RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[FINGERS_Z_OFF]); VectorSet(L_FINGERS_POS, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[FINGERS_X_OFF], -RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[FINGERS_Y_OFF], RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[FINGERS_Z_OFF]); //set lower body VectorSet(R_HIP_POS, -RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[LEG_W] * 0.5, 0.0, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[HIP_H]); VectorSet(L_HIP_POS, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[LEG_W] * 0.5, 0.0, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[HIP_H]); VectorSet(R_KNEE_POS, -RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[KNEE_X_OFF], -RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[KNEE_Y_OFF], RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[KNEE_Z_OFF]); VectorSet(L_KNEE_POS, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[KNEE_X_OFF], -RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[KNEE_Y_OFF], RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[KNEE_Z_OFF]); VectorSet(R_ANKLE_POS, -RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[ANKLE_X_OFF], -RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[ANKLE_Y_OFF], RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[ANKLE_Z_OFF]); VectorSet(L_ANKLE_POS, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[ANKLE_X_OFF], -RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[ANKLE_Y_OFF], RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[ANKLE_Z_OFF]); VectorSet(R_HEEL_POS, R_ANKLE_POS[0], R_ANKLE_POS[1] - RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[HEEL_LEN], R_ANKLE_POS[2]); VectorSet(L_HEEL_POS, L_ANKLE_POS[0], L_ANKLE_POS[1] - RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[HEEL_LEN], L_ANKLE_POS[2]); VectorSet(R_TOES_POS, R_ANKLE_POS[0], R_ANKLE_POS[1] + RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[FOOT_LEN], R_ANKLE_POS[2]); VectorSet(L_TOES_POS, L_ANKLE_POS[0], L_ANKLE_POS[1] + RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[FOOT_LEN], L_ANKLE_POS[2]); //build the ragdoll parts density = 1.0; //for now VectorSet(p1, 0.0, 0.0, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[NECK_H] - 0.1); VectorSet(p2, 0.0, 0.0, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[HIP_H] + 0.1); RGD_addBody(RagDollID, bindmat, "chest", CHEST, p1, p2, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[CHEST_W]/2.0, density); VectorSet(p1, R_HIP_POS[0] + 0.1, R_HIP_POS[1], R_HIP_POS[2] - 0.1); VectorSet(p2, L_HIP_POS[0] - 0.1, L_HIP_POS[1], L_HIP_POS[2] - 0.1); RGD_addBody(RagDollID, bindmat, "pelvis", PELVIS, p1, p2, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[PELVIS_W]/2.0, density); RGD_addFixedJoint(RagDollID, bindmat, LOWSPINE, CHEST, PELVIS); VectorSet(p1, 0.0, 0.0, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[HEAD_H]); VectorSet(p2, 0.0, 0.0, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[NECK_H] + 0.1); RGD_addBody(RagDollID, bindmat, "head", HEAD, p1, p2, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[HEAD_W]/2.0, density); VectorSet(p1, 0.0, 0.0, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[NECK_H]); RGD_addUniversalJoint(RagDollID, bindmat, NECK, CHEST, HEAD, p1, upAxis, rightAxis, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[HEAD_LOSTOP1] * M_PI, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[HEAD_HISTOP1] * M_PI, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[HEAD_LOSTOP2] * M_PI, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[HEAD_HISTOP2] * M_PI); //right leg VectorSet(p1, R_HIP_POS[0] - 0.1, R_HIP_POS[1], R_HIP_POS[2] - 0.1); VectorSet(p2, R_KNEE_POS[0], R_KNEE_POS[1], R_KNEE_POS[2] + 0.1); RGD_addBody(RagDollID, bindmat, "rightupperleg", RIGHTUPPERLEG, p1, p2, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[THIGH_W]/2.0, density); RGD_addUniversalJoint(RagDollID, bindmat, RIGHTHIP, PELVIS, RIGHTUPPERLEG, R_HIP_POS, bkwdAxis, rightAxis, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[HIP_LOSTOP1] * M_PI, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[HIP_HISTOP1] * M_PI, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[HIP_LOSTOP2] * M_PI, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[HIP_HISTOP2] * M_PI); VectorSet(p1, R_KNEE_POS[0], R_KNEE_POS[1], R_KNEE_POS[2] - 0.1); VectorSet(p2, R_ANKLE_POS[0], R_ANKLE_POS[1], R_ANKLE_POS[2]); RGD_addBody(RagDollID, bindmat, "rightlowerleg", RIGHTLOWERLEG, p1, p2, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[SHIN_W]/2.0, density); RGD_addHingeJoint(RagDollID, bindmat, RIGHTKNEE, RIGHTUPPERLEG, RIGHTLOWERLEG, R_KNEE_POS, leftAxis, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[KNEE_LOSTOP] * M_PI, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[KNEE_HISTOP] * M_PI); RGD_addBody(RagDollID, bindmat, "rightfoot", RIGHTFOOT, R_TOES_POS, R_HEEL_POS, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[FOOT_W]/2.0, density); RGD_addHingeJoint(RagDollID, bindmat, RIGHTANKLE, RIGHTLOWERLEG, RIGHTFOOT, R_ANKLE_POS, rightAxis, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[ANKLE_LOSTOP] * M_PI, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[ANKLE_HISTOP] * M_PI); //left leg VectorSet(p1, L_HIP_POS[0] + 0.1, L_HIP_POS[1], L_HIP_POS[2] - 0.1); VectorSet(p2, L_KNEE_POS[0], L_KNEE_POS[1], L_KNEE_POS[2] + 0.1); RGD_addBody(RagDollID, bindmat, "leftupperleg", LEFTUPPERLEG, p1, p2, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[THIGH_W]/2.0, density); RGD_addUniversalJoint(RagDollID, bindmat, LEFTHIP, PELVIS,LEFTUPPERLEG, L_HIP_POS, fwdAxis, rightAxis, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[HIP_LOSTOP1] * M_PI, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[HIP_HISTOP1] * M_PI, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[HIP_LOSTOP2] * M_PI, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[HIP_HISTOP2] * M_PI); VectorSet(p1, L_KNEE_POS[0], L_KNEE_POS[1], L_KNEE_POS[2] - 0.1); VectorSet(p2, L_ANKLE_POS[0], L_ANKLE_POS[1], L_ANKLE_POS[2]); RGD_addBody(RagDollID, bindmat, "leftlowerleg", LEFTLOWERLEG, p1, p2, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[SHIN_W]/2.0, density); RGD_addHingeJoint(RagDollID, bindmat, LEFTKNEE, LEFTUPPERLEG, LEFTLOWERLEG, L_KNEE_POS, leftAxis, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[KNEE_LOSTOP] * M_PI, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[KNEE_HISTOP] * M_PI); RGD_addBody(RagDollID, bindmat, "leftfoot", LEFTFOOT, L_TOES_POS, L_HEEL_POS, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[FOOT_W]/2.0, density); RGD_addHingeJoint(RagDollID, bindmat, LEFTANKLE, LEFTLOWERLEG, LEFTFOOT, L_ANKLE_POS, rightAxis, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[ANKLE_LOSTOP] * M_PI, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[ANKLE_HISTOP] * M_PI); //right arm VectorSet(p1, R_SHOULDER_POS[0] - 0.1, R_SHOULDER_POS[1], R_SHOULDER_POS[2]); VectorSet(p2, R_ELBOW_POS[0], R_ELBOW_POS[1], R_ELBOW_POS[2] + 0.1); RGD_addBody(RagDollID, bindmat, "rightupperarm", RIGHTUPPERARM, p1, p2, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[BICEP_W]/2.0, density); RGD_addUniversalJoint(RagDollID, bindmat, RIGHTSHOULDER, CHEST, RIGHTUPPERARM, R_SHOULDER_POS, bkwdAxis, rightAxis, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[SHOULDER_LOSTOP1] * M_PI, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[SHOULDER_HISTOP1] * M_PI, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[SHOULDER_LOSTOP2] * M_PI, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[SHOULDER_HISTOP2] * M_PI); VectorSet(p1, R_ELBOW_POS[0], R_ELBOW_POS[1], R_ELBOW_POS[2] - 0.1); VectorSet(p2, R_WRIST_POS[0], R_WRIST_POS[1], R_WRIST_POS[2] + 0.1); RGD_addBody(RagDollID, bindmat, "rightforearm", RIGHTFOREARM, p1, p2, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[FOREARM_W]/2.0, density); RGD_addHingeJoint(RagDollID, bindmat, RIGHTELBOW, RIGHTUPPERARM, RIGHTFOREARM, R_ELBOW_POS, downAxis, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[ELBOW_LOSTOP] * M_PI, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[ELBOW_HISTOP] * M_PI); VectorSet(p1, R_WRIST_POS[0], R_WRIST_POS[1], R_WRIST_POS[2] - 0.1); VectorSet(p2, R_FINGERS_POS[0], R_FINGERS_POS[1], R_FINGERS_POS[2]); RGD_addBody(RagDollID, bindmat, "righthand", RIGHTHAND, p1, p2, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[HAND_W]/2.0, density); RGD_addHingeJoint(RagDollID, bindmat, RIGHTWRIST, RIGHTFOREARM, RIGHTHAND, R_WRIST_POS, fwdAxis, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[WRIST_LOSTOP] * M_PI, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[WRIST_HISTOP] * M_PI); //left arm VectorSet(p1, L_SHOULDER_POS[0] + 0.1, L_SHOULDER_POS[1], L_SHOULDER_POS[2]); VectorSet(p2, L_ELBOW_POS[0], L_ELBOW_POS[1], L_ELBOW_POS[2] + 0.1); RGD_addBody(RagDollID, bindmat, "leftupperarm", LEFTUPPERARM, p1, p2, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[BICEP_W]/2.0, density); RGD_addUniversalJoint(RagDollID, bindmat, LEFTSHOULDER, CHEST, LEFTUPPERARM, L_SHOULDER_POS, fwdAxis, rightAxis, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[SHOULDER_LOSTOP1] * M_PI, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[SHOULDER_HISTOP1] * M_PI, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[SHOULDER_LOSTOP2] * M_PI, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[SHOULDER_HISTOP2] * M_PI); VectorSet(p1, L_ELBOW_POS[0], L_ELBOW_POS[1], L_ELBOW_POS[2] - 0.1); VectorSet(p2, L_WRIST_POS[0], L_WRIST_POS[1], L_WRIST_POS[2] + 0.1); RGD_addBody(RagDollID, bindmat, "leftforearm", LEFTFOREARM, p1, p2, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[FOREARM_W]/2.0, density); RGD_addHingeJoint(RagDollID, bindmat, LEFTELBOW, LEFTUPPERARM, LEFTFOREARM, L_ELBOW_POS, upAxis, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[ELBOW_LOSTOP] * M_PI, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[ELBOW_HISTOP] * M_PI); VectorSet(p1, L_WRIST_POS[0], L_WRIST_POS[1], L_WRIST_POS[2] - 0.1); VectorSet(p2, L_FINGERS_POS[0], L_FINGERS_POS[1], L_FINGERS_POS[2]); RGD_addBody(RagDollID, bindmat, "leftthand", LEFTHAND, p1, p2, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[HAND_W]/2.0, density); RGD_addHingeJoint(RagDollID, bindmat, LEFTWRIST, LEFTFOREARM, LEFTHAND, L_WRIST_POS, bkwdAxis, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[WRIST_LOSTOP] * M_PI, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[WRIST_HISTOP] * M_PI); } void R_DrawMark (vec3_t origin, int type) { int i; float scale; if(type) scale = 0.25; else scale = 1.0; qglPushMatrix (); qglTranslatef (origin[0], origin[1], origin[2]); qglDisable (GL_TEXTURE_2D); if(type == 1) qglColor3f (1,0,0); else if(type == 2) qglColor3f (0,1,0); else if(type == 3) qglColor3f (0,0,1); else qglColor3f(1,1,1); qglBegin (GL_TRIANGLE_FAN); qglVertex3f (0, 0, -scale*16); for (i=0 ; i<=4 ; i++) qglVertex3f (scale*16*cos(i*M_PI/2), scale*16*sin(i*M_PI/2), 0); qglEnd (); qglBegin (GL_TRIANGLE_FAN); qglVertex3f (0, 0, scale*16); for (i=4 ; i>=0 ; i--) qglVertex3f (scale*16*cos(i*M_PI/2), scale*16*sin(i*M_PI/2), 0); qglEnd (); qglColor3f (1,1,1); qglPopMatrix (); qglEnable (GL_TEXTURE_2D); } //For creating the surfaces for the ragdoll to collide with void RGD_BuildODEGeoms(msurface_t *surf) { glpoly_t *p; float *v; int i; int polyStart; for ( p = surf->polys; p; p = p->chain ) { if(RagDollTriWorld.numODEVerts + p->numverts > RagDollTriWorld.maxODEVerts) { int growVerts = RagDollTriWorld.maxODEVerts; dVector3 *newVerts; while(RagDollTriWorld.numODEVerts + p->numverts > growVerts) growVerts += GROW_ODE_VERTS; newVerts = (dVector3 *)realloc(RagDollTriWorld.ODEVerts, growVerts*sizeof(dVector3)); if(!newVerts) break; RagDollTriWorld.maxODEVerts = growVerts; RagDollTriWorld.ODEVerts = newVerts; } polyStart = RagDollTriWorld.numODEVerts; for (v = p->verts[0]; v < p->verts[p->numverts]; v += VERTEXSIZE) { RagDollTriWorld.ODEVerts[RagDollTriWorld.numODEVerts][0] = v[0]; RagDollTriWorld.ODEVerts[RagDollTriWorld.numODEVerts][1] = v[1]; RagDollTriWorld.ODEVerts[RagDollTriWorld.numODEVerts][2] = v[2]; RagDollTriWorld.numODEVerts++; } if(RagDollTriWorld.numODETris + p->numverts-2 > RagDollTriWorld.maxODETris) { int growTris = RagDollTriWorld.maxODETris; dTriIndex *newTris; while(RagDollTriWorld.numODETris + p->numverts-2 > growTris) growTris += GROW_ODE_TRIS; newTris = (dTriIndex *)realloc(RagDollTriWorld.ODETris, growTris*sizeof(dTriIndex[3])); if(!newTris) break; RagDollTriWorld.maxODETris = growTris; RagDollTriWorld.ODETris = newTris; } for (i = 2; i < p->numverts; i++) { RagDollTriWorld.ODETris[RagDollTriWorld.numODETris*3+0] = polyStart + i; RagDollTriWorld.ODETris[RagDollTriWorld.numODETris*3+1] = polyStart + i - 1; RagDollTriWorld.ODETris[RagDollTriWorld.numODETris*3+2] = polyStart; RagDollTriWorld.numODETris++; } } } /* ============= R_DrawWorldTrimesh ============= */ void RGD_BuildWorldTrimesh ( void ) { msurface_t *surf; dMatrix3 rot; RagDollTriWorld.numODEVerts = RagDollTriWorld.numODETris = 0; for (surf = &r_worldmodel->surfaces[r_worldmodel->firstmodelsurface]; surf < &r_worldmodel->surfaces[r_worldmodel->firstmodelsurface + r_worldmodel->nummodelsurfaces] ; surf++) { if (surf->texinfo->flags & SURF_SKY) { // no skies here continue; } else { if (!( surf->iflags & ISURF_DRAWTURB ) ) { RGD_BuildODEGeoms(surf); } } } dRSetIdentity(rot); //we need to build the trimesh geometry RagDollTriWorld.triMesh = dGeomTriMeshDataCreate(); // Build the mesh from the data dGeomTriMeshDataBuildSimple(RagDollTriWorld.triMesh, (dReal*)RagDollTriWorld.ODEVerts, RagDollTriWorld.numODEVerts, RagDollTriWorld.ODETris, RagDollTriWorld.numODETris*3); RagDollTriWorld.geom = dCreateTriMesh(RagDollSpace, RagDollTriWorld.triMesh, NULL, NULL, NULL); dGeomSetData(RagDollTriWorld.geom, "surface"); // this geom has no body dGeomSetBody(RagDollTriWorld.geom, 0); dGeomSetPosition(RagDollTriWorld.geom, 0, 0, 0); dGeomSetRotation(RagDollTriWorld.geom, rot); } /* Callback function for the collide() method. This function checks if the given geoms do collide and creates contact joints if they do. */ static void near_callback(void *data, dGeomID geom1, dGeomID geom2) { dContact contact[MAX_CONTACTS]; int i, numc; dJointID j; dBodyID body1 = dGeomGetBody(geom1); dBodyID body2 = dGeomGetBody(geom2); if (dGeomIsSpace(geom1) || dGeomIsSpace(geom2)) { // colliding a space with something dSpaceCollide2(geom1, geom2, data, &near_callback); // now colliding all geoms internal to the space(s) if (dGeomIsSpace(geom1)) { dSpaceID o1_spaceID = (dSpaceID)geom1; dSpaceCollide(o1_spaceID, data, &near_callback); } if (dGeomIsSpace(geom2)) { dSpaceID o2_spaceID = (dSpaceID)geom2; dSpaceCollide(o2_spaceID, data, &near_callback); } } else { if(body1 && body2) { if (dAreConnected(body1, body2)) return; } for(i = 0; i < MAX_CONTACTS; i++) { contact[i].surface.mode = dContactBounce; // Bouncy surface contact[i].surface.bounce = 0.2; contact[i].surface.mu = dInfinity; // Friction contact[i].surface.mu2 = 0; contact[i].surface.bounce_vel = 0.1; } if (( numc = dCollide(geom1, geom2, MAX_CONTACTS, &contact[0].geom, sizeof(dContact))) != 0) { // To add each contact point found to our joint group we call dJointCreateContact which is just one of the many // different joint types available. for (i = 0; i < numc; i++) { // dJointCreateContact needs to know which world and joint group to work with as well as the dContact // object itself. It returns a new dJointID which we then use with dJointAttach to finally create the // temporary contact joint between the two geom bodies. j = dJointCreateContact(RagDollWorld, contactGroup, contact + i); dJointAttach(j, body1, body2); } } } } void R_DestroyRagDoll(int RagDollID, qboolean nuke) { int i; VectorSet(RagDoll[RagDollID].origin, 0, 0, 0); //destroy forces for( i = 0; i < MAX_FORCES; i++) { RagDoll[RagDollID].RagDollForces[i].destroyed = true; } //clear any allocated mem if(RagDoll[RagDollID].ragDollMesh) { free(RagDoll[RagDollID].ragDollMesh); RagDoll[RagDollID].ragDollMesh = NULL; } if(RagDoll[RagDollID].initframe) { free(RagDoll[RagDollID].initframe); RagDoll[RagDollID].initframe = NULL; } if(RagDoll[RagDollID].script) { if(RagDoll[RagDollID].script->stage) { if(RagDoll[RagDollID].script->stage->next) { free(RagDoll[RagDollID].script->stage->next); RagDoll[RagDollID].script->stage->next = NULL; } free(RagDoll[RagDollID].script->stage); RagDoll[RagDollID].script->stage = NULL; } free(RagDoll[RagDollID].script); RagDoll[RagDollID].script = NULL; } if(!nuke) return; //we also want to destroy all ragdoll bodies and joints for this ragdoll for(i = CHEST; i <= LEFTHAND; i++) { if(RagDoll[RagDollID].RagDollObject[i].geom) dGeomDestroy(RagDoll[RagDollID].RagDollObject[i].geom); RagDoll[RagDollID].RagDollObject[i].geom = NULL; if(RagDoll[RagDollID].RagDollObject[i].body) dBodyDestroy(RagDoll[RagDollID].RagDollObject[i].body); RagDoll[RagDollID].RagDollObject[i].body = NULL; } for(i = MIDSPINE; i <= LEFTWRIST; i++) { if(RagDoll[RagDollID].RagDollJoint[i]) dJointDestroy(RagDoll[RagDollID].RagDollJoint[i]); RagDoll[RagDollID].RagDollJoint[i] = NULL; } } void RGD_DestroyWorldTrimesh( void ) { if(RagDollTriWorld.geom) dGeomDestroy(RagDollTriWorld.geom); RagDollTriWorld.geom = NULL; if(RagDollTriWorld.ODEVerts) free(RagDollTriWorld.ODEVerts); RagDollTriWorld.ODEVerts = NULL; RagDollTriWorld.maxODEVerts = 0; if(RagDollTriWorld.ODETris) free(RagDollTriWorld.ODETris); RagDollTriWorld.ODETris = NULL; RagDollTriWorld.maxODETris = 0; } //This is called on every map load void R_ClearAllRagdolls( void ) { int RagDollID; for(RagDollID = 0; RagDollID < MAX_RAGDOLLS; RagDollID++) { R_DestroyRagDoll(RagDollID, true); RagDoll[RagDollID].destroyed = true; } RGD_DestroyWorldTrimesh(); r_DrawingRagDoll = false; } void RGD_AddNewRagdoll( vec3_t origin, char name[MAX_QPATH] ) { int RagDollID, i; vec3_t dist; vec3_t dir; //check to see if we already have spawned a ragdoll for this entity for(RagDollID = 0; RagDollID < MAX_RAGDOLLS; RagDollID++) { if(!RagDoll[RagDollID].destroyed) { VectorSubtract(origin, RagDoll[RagDollID].origin, dist); if(VectorLength(dist) < 64 && !strcmp(RagDoll[RagDollID].name, name)) return; } } VectorSet(dir, 6, 6, 20); //note this is temporary hardcoded value(we should use the velocity of the ragdoll to influence this) r_DrawingRagDoll = true; //we are rendering a Ragdoll somewhere //add a ragdoll, look for first open slot for(RagDollID = 0; RagDollID < MAX_RAGDOLLS; RagDollID++) { if(RagDoll[RagDollID].destroyed) { RGD_RagdollBody_Init(RagDollID, origin, name); if(r_ragdoll_debug->integer == 2) { Com_Printf("RagDoll name: %s Ent name: %s Mesh: %s Ent Mesh: %s\n", RagDoll[RagDollID].name, name, RagDoll[RagDollID].ragDollMesh->name, currentmodel->name); for(i = 0; i < 27; i++) Com_Printf("ragdoll val %i: %4.2f\n", i, RagDoll[RagDollID].ragDollMesh->ragdoll.RagDollDims[i]); } if(r_ragdoll_debug->integer) Com_Printf("Added a ragdoll @ %4.2f,%4.2f,%4.2f\n", RagDoll[RagDollID].origin[0], RagDoll[RagDollID].origin[1], RagDoll[RagDollID].origin[2]); //break glass effect for helmets so we don't need to render them if(RagDoll[RagDollID].ragDollMesh->ragdoll.hasHelmet) CL_GlassShards(RagDoll[RagDollID].origin, dir, 5); break; } } } //Ragdoll rendering routines qboolean RGD_CullRagDolls( int RagDollID ) { int i; vec3_t vectors[3]; vec3_t angles; trace_t r_trace; vec3_t dist; vec3_t bbox[8]; if (r_worldmodel ) { //occulusion culling - why draw entities we cannot see? r_trace = CM_BoxTrace(r_origin, RagDoll[RagDollID].curPos, RagDoll[RagDollID].ragDollMesh->maxs, RagDoll[RagDollID].ragDollMesh->mins, r_worldmodel->firstnode, MASK_OPAQUE); if(r_trace.fraction != 1.0) return true; } VectorSubtract(r_origin, RagDoll[RagDollID].curPos, dist); /* ** rotate the bounding box */ VectorCopy( RagDoll[RagDollID].angles, angles ); angles[YAW] = -angles[YAW]; AngleVectors( angles, vectors[0], vectors[1], vectors[2] ); for ( i = 0; i < 8; i++ ) { vec3_t tmp; VectorCopy( RagDoll[RagDollID].ragDollMesh->bbox[i], tmp ); bbox[i][0] = DotProduct( vectors[0], tmp ); bbox[i][1] = -DotProduct( vectors[1], tmp ); bbox[i][2] = DotProduct( vectors[2], tmp ); VectorAdd( RagDoll[RagDollID].curPos, bbox[i], bbox[i] ); } { int p, f, aggregatemask = ~0; for ( p = 0; p < 8; p++ ) { int mask = 0; for ( f = 0; f < 4; f++ ) { float dp = DotProduct( frustum[f].normal, bbox[p] ); if ( ( dp - frustum[f].dist ) < 0 ) { mask |= ( 1 << f ); } } aggregatemask &= mask; } if ( aggregatemask && (VectorLength(dist) > 150)) { return true; } return false; } } void R_RenderAllRagdolls ( void ) { int RagDollID; int i; if(!r_ragdolls->integer) return; //Iterate though the ragdoll stack, and render each one that is active. //This function is very similar to the iqm/alias entity routine, but will call a //different animation function. This function will keep track of the time as well, and //remove any expired ragdolls off of the stack. for(RagDollID = 0; RagDollID < MAX_RAGDOLLS; RagDollID++) { float dur; if(RagDoll[RagDollID].destroyed) continue; dur = Sys_Milliseconds() - RagDoll[RagDollID].spawnTime; if(dur > RAGDOLL_DURATION) { R_DestroyRagDoll(RagDollID, true); RagDoll[RagDollID].destroyed = true; if(r_ragdoll_debug->integer) Com_Printf("Destroyed a ragdoll"); } else { //we handle the ragdoll's physics, then render the mesh with skeleton adjusted by ragdoll //body object positions const dReal *odePos; int shellEffect = false; float shellAlpha = 1.0f; // quiet warning; is initialized if used. odePos = dBodyGetPosition (RagDoll[RagDollID].RagDollObject[CHEST].body); VectorSet(RagDoll[RagDollID].curPos, odePos[0], odePos[1], odePos[2]); if ( RGD_CullRagDolls( RagDollID ) ) continue; //render the meshes qglShadeModel (GL_SMOOTH); GL_TexEnv( GL_MODULATE ); R_LightPoint (RagDoll[RagDollID].curPos, shadelight, true); if(dur > (RAGDOLL_DURATION - 2500)) { VectorClear (shadelight); shadelight[1] = 1.0; shadelight[2] = 0.6; dBodySetLinearVel(RagDoll[RagDollID].RagDollObject[CHEST].body, 0, 0, 50); //lift into space shellAlpha = (1 - dur/RAGDOLL_DURATION); shellEffect = true; } //check for valid script use_vbo = true; if(RagDoll[RagDollID].script && RagDoll[RagDollID].script->stage) { if(!strcmp("***r_notexture***", RagDoll[RagDollID].script->stage->texture->name) || ((RagDoll[RagDollID].script->stage->fx || RagDoll[RagDollID].script->stage->glow) && !strcmp("***r_notexture***", RagDoll[RagDollID].script->stage->texture2->name)) || (RagDoll[RagDollID].script->stage->cube && !strcmp("***r_notexture***", RagDoll[RagDollID].script->stage->texture3->name))) { RagDoll[RagDollID].script = NULL; //bad shader! use_vbo = false; //cannot use vbo without a valid shader } } R_GetLightVals(RagDoll[RagDollID].curPos, true); R_GenerateRagdollShadow(RagDollID); IQM_AnimateRagdoll(RagDollID, shellEffect); currentmodel = RagDoll[RagDollID].ragDollMesh; // HACK: This is a bit wasteful, but it allows us to reuse code // that expects these values to be in an entity_t struct. VectorCopy (RagDoll[RagDollID].curPos, RagDollEntity.origin); VectorCopy (RagDoll[RagDollID].angles, RagDollEntity.angles); RagDollEntity.script = RagDoll[RagDollID].script; RagDollEntity.flags = shellEffect?RF_SHELL_RED:0; currententity = &RagDollEntity; IQM_DrawFrame (RagDoll[RagDollID].texnum, true, shellAlpha); GL_TexEnv( GL_REPLACE ); qglShadeModel (GL_FLAT); qglColor4f (1,1,1,1); //apply forces from explosions for(i = 0; i < MAX_FORCES; i++) { if(!RagDoll[RagDollID].RagDollForces[i].destroyed) { if(Sys_Milliseconds() - RagDoll[RagDollID].RagDollForces[i].spawnTime < 2000) { VectorSubtract(RagDoll[RagDollID].RagDollForces[i].org, RagDoll[RagDollID].curPos, RagDoll[RagDollID].RagDollForces[i].dir); RagDoll[RagDollID].RagDollForces[i].force /= VectorLength(RagDoll[RagDollID].RagDollForces[i].dir); VectorNormalize(RagDoll[RagDollID].RagDollForces[i].dir); RagDoll[RagDollID].RagDollForces[i].force *= 500; if(RagDoll[RagDollID].RagDollForces[i].force > 10000) RagDoll[RagDollID].RagDollForces[i].force = 10000; //add a force if it's sufficient enough to do anything if(RagDoll[RagDollID].RagDollForces[i].force > 200 || RagDoll[RagDollID].RagDollForces[i].force < -200) { dBodySetLinearVel(RagDoll[RagDollID].RagDollObject[CHEST].body, -RagDoll[RagDollID].RagDollForces[i].dir[0] * RagDoll[RagDollID].RagDollForces[i].force, -RagDoll[RagDollID].RagDollForces[i].dir[1] * RagDoll[RagDollID].RagDollForces[i].force, -RagDoll[RagDollID].RagDollForces[i].dir[2] * RagDoll[RagDollID].RagDollForces[i].force); } RagDoll[RagDollID].RagDollForces[i].destroyed = true; //destroy if used } else RagDoll[RagDollID].RagDollForces[i].destroyed = true; //destroy if expired } } if(r_ragdoll_debug->integer) { //debug - draw ragdoll bodies for(i = CHEST; i <= LEFTHAND; i++) { vec3_t org; const dReal *odePos; if(!RagDoll[RagDollID].RagDollObject[i].body) continue; odePos = dBodyGetPosition (RagDoll[RagDollID].RagDollObject[i].body); VectorSet(org, odePos[0], odePos[1], odePos[2]); if(i == HEAD) R_DrawMark(org, 2); else if (i > LEFTFOOT) R_DrawMark(org, 3); else R_DrawMark(org, 1); } } r_DrawingRagDoll = true; } } #if defined WIN32_VARIANT if(r_DrawingRagDoll) //here we handle the physics { int ODEIterationsPerFrame; int frametime = Sys_Milliseconds() - lastODEUpdate; //iterations need to be adjusted for framerate. ODEIterationsPerFrame = frametime; //clamp it if(ODEIterationsPerFrame > MAX_ODESTEPS) ODEIterationsPerFrame = MAX_ODESTEPS; if(ODEIterationsPerFrame < MIN_ODESTEPS) ODEIterationsPerFrame = MIN_ODESTEPS; dSpaceCollide(RagDollSpace, 0, &near_callback); dWorldStepFast1(RagDollWorld, (float)(frametime/1000.0f), ODEIterationsPerFrame); // Remove all temporary collision joints now that the world has been stepped dJointGroupEmpty(contactGroup); } #else /* ODE library 0.12 does not support dWorldStepFast1. * Using dWorldQuickStep. See RGD_CreateWorldObject(), above. */ if(r_DrawingRagDoll) //here we handle the physics { int frametime = Sys_Milliseconds() - lastODEUpdate; dSpaceCollide(RagDollSpace, 0, &near_callback); dWorldQuickStep( RagDollWorld, ((dReal)frametime)/1000.0 ); // Remove all temporary collision joints now that the world has been stepped dJointGroupEmpty(contactGroup); } #endif lastODEUpdate = Sys_Milliseconds(); r_DrawingRagDoll = false; } void R_ApplyForceToRagdolls(vec3_t origin, float force) { int RagDollID, i; if(!r_ragdolls->integer) return; for(RagDollID = 0; RagDollID < MAX_RAGDOLLS; RagDollID++) { for(i = 0; i < MAX_FORCES; i++) { if(RagDoll[RagDollID].RagDollForces[i].destroyed) { VectorCopy(origin, RagDoll[RagDollID].RagDollForces[i].org); RagDoll[RagDollID].RagDollForces[i].force = force; RagDoll[RagDollID].RagDollForces[i].spawnTime = Sys_Milliseconds(); RagDoll[RagDollID].RagDollForces[i].destroyed = false; break; } } } } alien-arena-7.66+dfsg/source/ref_gl/r_script.c0000600000175000017500000011755012162607462020365 0ustar zero79zero79/* Copyright (C) 2010 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // gl_script.c - scripted texture rendering #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "r_local.h" #if defined WIN32_VARIANT #include #endif extern float r_turbsin[]; #define TOK_DELIMINATORS "\r\n\t " float rs_realtime = 0; rscript_t *rs_rootscript = NULL; int RS_Animate (rs_stage_t *stage) { anim_stage_t *anim = stage->last_anim; /* unused float time = rs_realtime * 1000 - (stage->last_anim_time + stage->anim_delay); */ while (stage->last_anim_time < rs_realtime) { anim = anim->next; if (!anim) anim = stage->anim_stage; stage->last_anim_time += stage->anim_delay; } stage->last_anim = anim; return anim->texture->texnum; } void *RS_AnimateSkin (rs_stage_t *stage) { anim_stage_t *anim = stage->last_anim; /* unused float time = rs_realtime * 1000 - (stage->last_anim_time + stage->anim_delay); */ while (stage->last_anim_time < rs_realtime) { anim = anim->next; if (!anim) anim = stage->anim_stage; stage->last_anim_time += stage->anim_delay; } stage->last_anim = anim; return anim->texture; } float cutDot (vec3_t vec1, vec3_t vec2) { float dot = DotProduct(vec1, vec2); if (dot>1) return 1; if (dot<-1) return -1; return dot; } void RS_ResetScript (rscript_t *rs) { rs_stage_t *stage = rs->stage, *tmp_stage; anim_stage_t *anim, *tmp_anim; random_stage_t *randStage, *tmp_rand; rs->name[0] = 0; while (stage != NULL) { if (stage->anim_count) { anim = stage->anim_stage; while (anim != NULL) { tmp_anim = anim; anim = anim->next; free (tmp_anim); } } if (stage->rand_count) { randStage = stage->rand_stage; while (randStage != NULL) { tmp_rand = randStage; randStage = randStage->next; free (tmp_rand); } } tmp_stage = stage; stage = stage->next; free (tmp_stage); } rs->stage = NULL; rs->dontflush = false; rs->ready = false; } void rs_free_if_subexpr (rs_cond_val_t *expr) { if (expr->lval.string) Z_Free (expr->lval.string); if (expr->subexpr1) rs_free_if_subexpr (expr->subexpr1); if (expr->subexpr2) rs_free_if_subexpr (expr->subexpr2); Z_Free (expr); } void RS_ClearStage (rs_stage_t *stage) { anim_stage_t *anim = stage->anim_stage, *tmp_anim; random_stage_t *randStage = stage->rand_stage, *tmp_rand; if (stage->condv != NULL) { rs_free_if_subexpr (stage->condv); stage->condv = NULL; } while (anim != NULL) { tmp_anim = anim; anim = anim->next; free (tmp_anim); } while (randStage != NULL) { tmp_rand = randStage; randStage = randStage->next; free (tmp_rand); } stage->last_anim = 0; stage->last_anim_time = 0; stage->anim_count = 0; stage->anim_delay = 0; stage->anim_stage = NULL; stage->rand_count = 0; stage->rand_stage = NULL; stage->has_alpha = false; stage->alphamask = false; stage->alphafunc = 0; stage->alphashift.max = 0; stage->alphashift.min = 0; stage->alphashift.speed = 0; stage->blendfunc.blend = false; stage->blendfunc.dest = stage->blendfunc.source = 0; stage->colormap.enabled = false; stage->colormap.red = 0; stage->colormap.green = 0; stage->colormap.blue = 0; stage->scale.scaleX = 0; stage->scale.scaleY = 0; stage->scale.typeX = 0; stage->scale.typeY = 0; stage->scroll.speedX = 0; stage->scroll.speedY = 0; stage->scroll.typeX = 0; stage->scroll.typeY = 0; stage->rot_speed = 0; stage->texture = NULL; stage->texture2 = NULL; stage->texture3 = NULL; stage->depthhack = false; stage->envmap = false; stage->lensflare = false; stage->flaretype = 0; stage->normalmap = false; stage->grass = false; stage->grasstype = 0; stage->beam = false; stage->beamtype = 0; stage->xang = 0; stage->yang = 0; stage->rotating = false; stage->fx = false; stage->glow = false; stage->cube = false; stage->lightmap = true; stage->next = NULL; } // Create a new script with the given name. Reuse the "old" struct if possible // to avoid breaking old pointers. rscript_t *RS_NewScript (char *name, rscript_t *old) { rscript_t *rs; unsigned int i; if (old != NULL) { RS_ResetScript (old); rs = old; } else if (!rs_rootscript) { rs_rootscript = (rscript_t *)malloc(sizeof(rscript_t)); rs = rs_rootscript; rs->next = NULL; } else { rs = rs_rootscript; while (rs->next != NULL) rs = rs->next; rs->next = (rscript_t *)malloc(sizeof(rscript_t)); rs = rs->next; rs->next = NULL; } COMPUTE_HASH_KEY(rs->hash_key, name, i); strncpy (rs->name, name, sizeof(rs->name)); rs->stage = NULL; rs->dontflush = false; rs->ready = false; return rs; } rs_stage_t *RS_NewStage (rscript_t *rs) { rs_stage_t *stage; if (rs->stage == NULL) { rs->stage = (rs_stage_t *)malloc(sizeof(rs_stage_t)); stage = rs->stage; } else { stage = rs->stage; while (stage->next != NULL) stage = stage->next; stage->next = (rs_stage_t *)malloc(sizeof(rs_stage_t)); stage = stage->next; } strncpy (stage->name, "***r_notexture***", sizeof(stage->name)); strncpy (stage->name2, "***r_notexture***", sizeof(stage->name2)); strncpy (stage->name3, "***r_notexture***", sizeof(stage->name3)); stage->rand_stage = NULL; stage->anim_stage = NULL; stage->next = NULL; stage->last_anim = NULL; stage->condv = NULL; RS_ClearStage (stage); return stage; } void RS_FreeAllScripts (void) { rscript_t *rs = rs_rootscript, *tmp_rs; while (rs != NULL) { tmp_rs = rs->next; RS_ResetScript(rs); free (rs); rs = tmp_rs; } } void RS_ReloadImageScriptLinks (void) { image_t *image; int i; char shortname[MAX_QPATH]; for (i=0, image=gltextures ; iname, shortname); image->script = RS_FindScript (shortname); } } void RS_FreeScript(rscript_t *rs) { rscript_t *tmp_rs; if (!rs) return; if (rs_rootscript == rs) { rs_rootscript = rs_rootscript->next; RS_ResetScript(rs); free (rs); return; } tmp_rs = rs_rootscript; while (tmp_rs->next != rs) tmp_rs = tmp_rs->next; tmp_rs->next = rs->next; RS_ResetScript (rs); free (rs); } void RS_FreeUnmarked (void) { image_t *image; int i; rscript_t *rs = rs_rootscript, *tmp_rs; for (i=0, image=gltextures ; iscript && !((rscript_t *)image->script)->dontflush) image->script = NULL; } while (rs != NULL) { tmp_rs = rs->next; if (!rs->dontflush) RS_FreeScript(rs); rs = tmp_rs; } } rscript_t *RS_FindScript(char *name) { rscript_t *rs = rs_rootscript; unsigned int i, hash_key; COMPUTE_HASH_KEY(hash_key, name, i); while (rs != NULL) { if (rs->hash_key == hash_key && !Q_strcasecmp(rs->name, name)) { if (! rs->stage) rs = NULL; break; } rs = rs->next; } return rs; } void RS_ReadyScript (rscript_t *rs) { rs_stage_t *stage; anim_stage_t *anim; random_stage_t *randStage; char mode; if (rs->ready) return; mode = (rs->dontflush) ? it_pic : it_wall; stage = rs->stage; while (stage != NULL) { //if normalmap, set mode if(stage->normalmap) mode = it_bump; //set anim anim = stage->anim_stage; while (anim != NULL) { anim->texture = GL_FindImage (anim->name, mode); if (!anim->texture) anim->texture = r_notexture; anim = anim->next; } //set tiling randStage = stage->rand_stage; while (randStage != NULL) { randStage->texture = GL_FindImage (randStage->name, mode); if (!randStage->texture) randStage->texture = r_notexture; randStage = randStage->next; } //set name if (stage->name[0]) stage->texture = GL_FindImage (stage->name, mode); if (!stage->texture) stage->texture = r_notexture; if (stage->name2[0]) stage->texture2 = GL_FindImage (stage->name2, mode); if (!stage->texture2) stage->texture2 = r_notexture; if (stage->name3[0]) stage->texture3 = GL_FindImage (stage->name3, mode); if (!stage->texture3) stage->texture3 = r_notexture; //check alpha if (stage->blendfunc.blend) stage->has_alpha = true; else stage->has_alpha = false; stage = stage->next; } rs->ready = true; } int RS_BlendID (char *blend) { if (!blend[0]) return 0; if (!Q_strcasecmp (blend, "GL_ZERO")) return GL_ZERO; if (!Q_strcasecmp (blend, "GL_ONE")) return GL_ONE; if (!Q_strcasecmp (blend, "GL_DST_COLOR")) return GL_DST_COLOR; if (!Q_strcasecmp (blend, "GL_ONE_MINUS_DST_COLOR")) return GL_ONE_MINUS_DST_COLOR; if (!Q_strcasecmp (blend, "GL_SRC_ALPHA")) return GL_SRC_ALPHA; if (!Q_strcasecmp (blend, "GL_ONE_MINUS_SRC_ALPHA")) return GL_ONE_MINUS_SRC_ALPHA; if (!Q_strcasecmp (blend, "GL_DST_ALPHA")) return GL_DST_ALPHA; if (!Q_strcasecmp (blend, "GL_ONE_MINUS_DST_ALPHA")) return GL_ONE_MINUS_DST_ALPHA; if (!Q_strcasecmp (blend, "GL_SRC_ALPHA_SATURATE")) return GL_SRC_ALPHA_SATURATE; if (!Q_strcasecmp (blend, "GL_SRC_COLOR")) return GL_SRC_COLOR; if (!Q_strcasecmp (blend, "GL_ONE_MINUS_SRC_COLOR")) return GL_ONE_MINUS_SRC_COLOR; return 0; } int RS_FuncName (char *text) { if (!Q_strcasecmp (text, "static")) // static return 0; else if (!Q_strcasecmp (text, "sine")) // sine wave return 1; else if (!Q_strcasecmp (text, "cosine")) // cosine wave return 2; return 0; } /* scriptname { subdivide vertexwarp safe { map map2 - specific to "fx" map3 - specific to "cube" scroll blendfunc alphashift anim ... end envmap nolightmap alphamask lensflare flaretype normalmap grass grasstype beam beamtype xang yang rotating fx glow cube } } */ void rs_stage_map (rs_stage_t *stage, char **token) { *token = strtok (NULL, TOK_DELIMINATORS); strncpy (stage->name, *token, sizeof(stage->name)); } void rs_stage_map2 (rs_stage_t *stage, char **token) { *token = strtok (NULL, TOK_DELIMINATORS); strncpy (stage->name2, *token, sizeof(stage->name2)); } void rs_stage_map3 (rs_stage_t *stage, char **token) { *token = strtok (NULL, TOK_DELIMINATORS); strncpy (stage->name3, *token, sizeof(stage->name3)); } void rs_stage_colormap (rs_stage_t *stage, char **token) { stage->colormap.enabled = true; *token = strtok (NULL, TOK_DELIMINATORS); stage->colormap.red = atof(*token); *token = strtok (NULL, TOK_DELIMINATORS); stage->colormap.green = atof(*token); *token = strtok (NULL, TOK_DELIMINATORS); stage->colormap.blue = atof(*token); } void rs_stage_scroll (rs_stage_t *stage, char **token) { *token = strtok (NULL, TOK_DELIMINATORS); stage->scroll.typeX = RS_FuncName(*token); *token = strtok (NULL, TOK_DELIMINATORS); stage->scroll.speedX = atof(*token); *token = strtok (NULL, TOK_DELIMINATORS); stage->scroll.typeY = RS_FuncName(*token); *token = strtok (NULL, TOK_DELIMINATORS); stage->scroll.speedY = atof(*token); } void rs_stage_blendfunc (rs_stage_t *stage, char **token) { stage->blendfunc.blend = true; *token = strtok (NULL, TOK_DELIMINATORS); if (!Q_strcasecmp (*token, "add")) { stage->blendfunc.source = GL_ONE; stage->blendfunc.dest = GL_ONE; } else if (!Q_strcasecmp (*token, "blend")) { stage->blendfunc.source = GL_SRC_ALPHA; stage->blendfunc.dest = GL_ONE_MINUS_SRC_ALPHA; } else if (!Q_strcasecmp (*token, "filter")) { stage->blendfunc.source = GL_ZERO; stage->blendfunc.dest = GL_SRC_COLOR; } else { stage->blendfunc.source = RS_BlendID (*token); *token = strtok (NULL, TOK_DELIMINATORS); stage->blendfunc.dest = RS_BlendID (*token); } } void rs_stage_alphashift (rs_stage_t *stage, char **token) { *token = strtok (NULL, TOK_DELIMINATORS); stage->alphashift.speed = (float)atof(*token); *token = strtok (NULL, TOK_DELIMINATORS); stage->alphashift.min = (float)atof(*token); *token = strtok (NULL, TOK_DELIMINATORS); stage->alphashift.max = (float)atof(*token); } void rs_stage_random (rs_stage_t *stage, char **token) { random_stage_t *rand = (random_stage_t *)malloc(sizeof(random_stage_t)); stage->rand_stage = rand; stage->rand_count = 0; *token = strtok(NULL, TOK_DELIMINATORS); while (Q_strcasecmp (*token, "end")) { stage->rand_count++; strncpy (stage->name, *token, sizeof(stage->name)); stage->texture = NULL; *token = strtok(NULL, TOK_DELIMINATORS); if (!Q_strcasecmp (*token, "end")) { rand->next = NULL; break; } rand->next = (random_stage_t *)malloc(sizeof(random_stage_t)); rand = rand->next; } } void rs_stage_anim (rs_stage_t *stage, char **token) { anim_stage_t *anim = (anim_stage_t *)malloc(sizeof(anim_stage_t)); *token = strtok (NULL, TOK_DELIMINATORS); stage->anim_delay = (float)atof(*token); stage->anim_stage = anim; stage->last_anim = anim; *token = strtok(NULL, TOK_DELIMINATORS); while (Q_strcasecmp (*token, "end")) { stage->anim_count++; strncpy (anim->name, *token, sizeof(anim->name)); anim->texture = NULL; *token = strtok(NULL, TOK_DELIMINATORS); if (!Q_strcasecmp (*token, "end")) { anim->next = NULL; break; } anim->next = (anim_stage_t *)malloc(sizeof(anim_stage_t)); anim = anim->next; } } void rs_stage_depthhack (rs_stage_t *stage, char **token) { stage->depthhack = true; } void rs_stage_envmap (rs_stage_t *stage, char **token) { stage->envmap = true; } void rs_stage_nolightmap (rs_stage_t *stage, char **token) { stage->lightmap = false; } void rs_stage_alphamask (rs_stage_t *stage, char **token) { stage->alphamask = true; } void rs_stage_rotate (rs_stage_t *stage, char **token) { *token = strtok (NULL, TOK_DELIMINATORS); stage->rot_speed = (float)atof(*token); } void rs_stage_scale (rs_stage_t *stage, char **token) { *token = strtok (NULL, TOK_DELIMINATORS); stage->scale.typeX = RS_FuncName(*token); *token = strtok (NULL, TOK_DELIMINATORS); stage->scale.scaleX = atof(*token); *token = strtok (NULL, TOK_DELIMINATORS); stage->scale.typeY = RS_FuncName(*token); *token = strtok (NULL, TOK_DELIMINATORS); stage->scale.scaleY = atof(*token); } void rs_stage_alphafunc (rs_stage_t *stage, char **token) { *token = strtok (NULL, TOK_DELIMINATORS); if (!Q_strcasecmp (*token, "normal")) stage->alphafunc = ALPHAFUNC_NORMAL; else if (!Q_strcasecmp (*token, "-normal")) stage->alphafunc = -ALPHAFUNC_NORMAL; else if (!Q_strcasecmp (*token, "gloss")) stage->alphafunc = ALPHAFUNC_GLOSS; else if (!Q_strcasecmp (*token, "-gloss")) stage->alphafunc = -ALPHAFUNC_GLOSS; else if (!Q_strcasecmp (*token, "basic")) stage->alphafunc = ALPHAFUNC_BASIC; else if (!Q_strcasecmp (*token, "-basic")) stage->alphafunc = -ALPHAFUNC_BASIC; } void rs_stage_lensflare (rs_stage_t *stage, char **token) { stage->lensflare = true; } void rs_stage_flaretype (rs_stage_t *stage, char **token) { *token = strtok (NULL, TOK_DELIMINATORS); stage->flaretype = atoi(*token); } void rs_stage_normalmap (rs_stage_t *stage, char **token) { stage->normalmap = true; } void rs_stage_grass (rs_stage_t *stage, char **token) { stage->grass = true; } void rs_stage_grasstype (rs_stage_t *stage, char **token) { *token = strtok (NULL, TOK_DELIMINATORS); stage->grasstype = atoi(*token); } void rs_stage_beam (rs_stage_t *stage, char **token) { stage->beam = true; } void rs_stage_beamtype (rs_stage_t *stage, char **token) { *token = strtok (NULL, TOK_DELIMINATORS); stage->beamtype = atoi(*token); } void rs_stage_xang (rs_stage_t *stage, char **token) { *token = strtok (NULL, TOK_DELIMINATORS); stage->xang = atof(*token); } void rs_stage_yang (rs_stage_t *stage, char **token) { *token = strtok (NULL, TOK_DELIMINATORS); stage->yang = atof(*token); } void rs_stage_rotating (rs_stage_t *stage, char **token) { *token = strtok (NULL, TOK_DELIMINATORS); stage->rotating = atoi(*token); } void rs_stage_fx (rs_stage_t *stage, char **token) { stage->fx = true; } void rs_stage_glow (rs_stage_t *stage, char **token) { stage->glow = true; } void rs_stage_cube (rs_stage_t *stage, char **token) { stage->cube = true; } typedef struct { char *opname; rs_cond_op_t op; } rs_cond_op_key_t; static rs_cond_op_key_t rs_cond_op_keys[] = { { "==", rs_cond_eq }, { "!=", rs_cond_neq }, { ">", rs_cond_gt }, { "<=", rs_cond_ngt }, { "<", rs_cond_lt }, { ">=", rs_cond_nlt }, { "&&", rs_cond_and }, { "||", rs_cond_or }, { NULL, 0 } }; rs_cond_val_t *rs_stage_if_subexpr (char **token) { int i; rs_cond_val_t *res = Z_Malloc (sizeof(rs_cond_val_t)); *token = strtok (NULL, TOK_DELIMINATORS); if (!(*token)) { Z_Free (res); return NULL; } if (!Q_strcasecmp (*token, "(")) { res->subexpr1 = rs_stage_if_subexpr (token); if (!res->subexpr1) //there was an error somewhere { Z_Free (res); return NULL; } *token = strtok (NULL, TOK_DELIMINATORS); if (!(*token)) { Com_Printf ("Ran out of tokens in stage conditional!\n"); rs_free_if_subexpr (res->subexpr1); Z_Free (res); return NULL; } if (!Q_strcasecmp (*token, ")")) { res->optype = rs_cond_is; return res; } for (i = 0; rs_cond_op_keys[i].opname; i++) if (!Q_strcasecmp (*token, rs_cond_op_keys[i].opname)) break; if (!rs_cond_op_keys[i].opname) { Com_Printf ("Invalid stage conditional operation %s\n", *token); rs_free_if_subexpr (res->subexpr1); Z_Free (res); return NULL; } res->optype = rs_cond_op_keys[i].op; res->subexpr2 = rs_stage_if_subexpr (token); if (!res->subexpr2) //there was an error somewhere { rs_free_if_subexpr (res->subexpr1); Z_Free (res); return NULL; } *token = strtok (NULL, TOK_DELIMINATORS); if (!(*token) || Q_strcasecmp (*token, ")")) { Com_Printf ("Missing ) in stage conditional!\n"); if (*token) Com_Printf ("Instead got %s\n", *token); rs_free_if_subexpr (res->subexpr1); rs_free_if_subexpr (res->subexpr2); Z_Free (res); return NULL; } return res; } else if (!Q_strcasecmp (*token, "!")) { res->optype = rs_cond_lnot; res->subexpr1 = rs_stage_if_subexpr (token); if (!res->subexpr1) // there was an error somewhere { Z_Free (res); return NULL; } return res; } else if (!Q_strcasecmp (*token, "$")) { res->optype = rs_cond_none; *token = strtok (NULL, TOK_DELIMINATORS); if (!(*token)) { Com_Printf ("Missing cvar name in stage conditional!\n"); rs_free_if_subexpr (res->subexpr1); Z_Free (res); return NULL; } res->val = Cvar_Get (*token, "0", 0); return res; } else { res->optype = rs_cond_none; res->val = &(res->lval); Anon_Cvar_Set (res->val, *token); return res; } } void rs_stage_if (rs_stage_t *stage, char **token) { stage->condv = rs_stage_if_subexpr (token); if (!stage->condv) Com_Printf ("ERROR in stage conditional!\n"); } // For legacy origin and angle commands that aren't actually used in the code. // Some old rscripts still have the origin command in them, so we should parse // it anyway. Can't find any angle commands, but may as well handle those too. void rs_stage_consume3 (rs_stage_t *stage, char **token) { Com_Printf ("WARN: depreciated Rscript command: %s\n", *token); *token = strtok (NULL, TOK_DELIMINATORS); *token = strtok (NULL, TOK_DELIMINATORS); *token = strtok (NULL, TOK_DELIMINATORS); } // Used for the old "model" command, even though I can't find any rscripts // that have that command. void rs_stage_consume1 (rs_stage_t *stage, char **token) { Com_Printf ("WARN: depreciated Rscript command: %s\n", *token); *token = strtok (NULL, TOK_DELIMINATORS); } // Used for the old "dynamic" command, even though I can't find any rscripts // that have that command. void rs_stage_consume0 (rs_stage_t *stage, char **token) { Com_Printf ("WARN: depreciated Rscript command: %s\n", *token); } static rs_stagekey_t rs_stagekeys[] = { { "colormap", &rs_stage_colormap }, { "map", &rs_stage_map }, { "map2", &rs_stage_map2 }, { "map3", &rs_stage_map3 }, { "scroll", &rs_stage_scroll }, { "blendfunc", &rs_stage_blendfunc }, { "alphashift", &rs_stage_alphashift }, { "rand", &rs_stage_random }, { "anim", &rs_stage_anim }, { "envmap", &rs_stage_envmap }, { "depthhack", &rs_stage_depthhack }, { "nolightmap", &rs_stage_nolightmap }, { "alphamask", &rs_stage_alphamask }, { "rotate", &rs_stage_rotate }, { "scale", &rs_stage_scale }, { "alphafunc", &rs_stage_alphafunc }, { "lensflare", &rs_stage_lensflare }, { "flaretype", &rs_stage_flaretype }, { "normalmap", &rs_stage_normalmap }, { "grass", &rs_stage_grass }, { "grasstype", &rs_stage_grasstype }, { "beam", &rs_stage_beam }, { "beamtype", &rs_stage_beamtype }, { "xang", &rs_stage_xang }, { "yang", &rs_stage_yang }, { "rotating", &rs_stage_rotating }, { "fx", &rs_stage_fx }, { "glow", &rs_stage_glow }, { "cube", &rs_stage_cube }, { "if", &rs_stage_if }, // Depreciated stuff { "model", &rs_stage_consume1 }, { "frames", &rs_stage_consume3 }, { "origin", &rs_stage_consume3 }, { "angle", &rs_stage_consume3 }, { "dynamic", &rs_stage_consume1 }, { NULL, NULL } }; static int num_stagekeys = sizeof (rs_stagekeys) / sizeof(rs_stagekeys[0]) - 1; // ===================================================== void RS_LoadScript(char *script) { qboolean inscript = false, instage = false; char ignored = 0; char *token, *fbuf, *buf; rscript_t *rs = NULL; rs_stage_t *stage = NULL; // unsigned char tcmod = 0; // unused unsigned int len, i; len = FS_LoadFile (script, (void **)&fbuf); if (!fbuf || len < 16) { // Con_Printf (PRINT_ALL, "Could not load script %s\n", script); return; } buf = (char *)malloc(len+1); memcpy (buf, fbuf, len); buf[len] = 0; FS_FreeFile (fbuf); token = strtok (buf, TOK_DELIMINATORS); while (token != NULL) { if (!Q_strcasecmp (token, "/*") || !Q_strcasecmp (token, "[")) ignored++; else if (!Q_strcasecmp (token, "*/") || !Q_strcasecmp (token, "]")) ignored--; if (!Q_strcasecmp (token, "//")) { //IGNORE } else if (!inscript && !ignored) { if (!Q_strcasecmp (token, "{")) { inscript = true; } else { rs = RS_FindScript(token); rs = RS_NewScript (token, rs); } } else if (inscript && !ignored) { if (!Q_strcasecmp(token, "}")) { if (instage) { instage = false; } else { inscript = false; } } else if (!Q_strcasecmp(token, "{")) { if (!instage) { instage = true; stage = RS_NewStage(rs); } } else { if (instage && !ignored) { for (i = 0; i < num_stagekeys; i++) { if (!Q_strcasecmp (rs_stagekeys[i].stage, token)) { rs_stagekeys[i].func (stage, &token); break; } } } } } token = strtok (NULL, TOK_DELIMINATORS); } free(buf); } void RS_ScanPathForScripts (void) { char script[MAX_OSPATH]; char **script_list, *c; int script_count, i; script_list = FS_ListFilesInFS("scripts/*.rscript", &script_count, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM); if(script_list) { for (i = 0; i < script_count; i++) { c = COM_SkipPath(script_list[i]); Com_sprintf(script, MAX_OSPATH, "scripts/%s", c); RS_LoadScript(script); } FS_FreeFileList(script_list, script_count); } script_count = 0; //TODO: gl_interactivescripts cvar script_list = FS_ListFilesInFS("scripts/interactive/*.rscript", &script_count, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM); if(script_list) { for (i = 0; i < script_count; i++) { c = COM_SkipPath(script_list[i]); Com_sprintf(script, MAX_OSPATH, "scripts/interactive/%s", c); RS_LoadScript(script); } FS_FreeFileList(script_list, script_count); } script_count = 0; if(gl_normalmaps->value) { //search for normal map scripts ONLY if we are using normal mapping, do last to overide anything script_list = FS_ListFilesInFS("scripts/normals/*.rscript", &script_count, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM); if(script_list) { for (i = 0; i < script_count; i++) { c = COM_SkipPath(script_list[i]); Com_sprintf(script, MAX_OSPATH, "scripts/normals/%s", c); RS_LoadScript(script); } FS_FreeFileList(script_list, script_count); } } } void RS_SetEnvmap (vec3_t v, float *os, float *ot) { vec3_t vert; vert[0] = v[0]*r_world_matrix[0]+v[1]*r_world_matrix[4]+v[2]*r_world_matrix[8] +r_world_matrix[12]; vert[1] = v[0]*r_world_matrix[1]+v[1]*r_world_matrix[5]+v[2]*r_world_matrix[9] +r_world_matrix[13]; vert[2] = v[0]*r_world_matrix[2]+v[1]*r_world_matrix[6]+v[2]*r_world_matrix[10]+r_world_matrix[14]; VectorNormalize (vert); *os = vert[0]; *ot = vert[1]; } void RS_ScaleTexcoords (rs_stage_t *stage, float *os, float *ot) { // float txm = 0, tym = 0; // unused // scale if (stage->scale.scaleX) { switch (stage->scale.typeX) { case 0: // static *os *= stage->scale.scaleX; break; case 1: // sine *os *= stage->scale.scaleX*sin(rs_realtime*0.05); break; case 2: // cosine *os *= stage->scale.scaleX*cos(rs_realtime*0.05); break; } } if (stage->scale.scaleY) { switch (stage->scale.typeY) { case 0: // static *ot *= stage->scale.scaleY; break; case 1: // sine *ot *= stage->scale.scaleY*sin(rs_realtime*0.05); break; case 2: // cosine *ot *= stage->scale.scaleY*cos(rs_realtime*0.05); break; } } } inline void RS_RotateST (float *os, float *ot, float degrees, msurface_t *fa) { float cost = cos(degrees), sint = sin(degrees); float is = *os, it = *ot, c_s, c_t; c_s = fa->c_s - (int)fa->c_s; c_t = fa->c_t - (int)fa->c_t; *os = cost * (is - c_s) + sint * (c_t - it) + c_s; *ot = cost * (it - c_t) + sint * (is - c_s) + c_t; } inline void RS_RotateST2 (float *os, float *ot, float degrees) { float cost = cos(degrees), sint = sin(degrees); float is = *os, it = *ot; *os = cost * (is - 0.5) + sint * (0.5 - it) + 0.5; *ot = cost * (it - 0.5) + sint * (is - 0.5) + 0.5; } void RS_SetTexcoords (rs_stage_t *stage, float *os, float *ot, msurface_t *fa) { RS_ScaleTexcoords(stage, os, ot); // rotate if (stage->rot_speed) RS_RotateST (os, ot, -stage->rot_speed * rs_realtime * 0.0087266388888888888888888888888889, fa); } void RS_SetTexcoords2D (rs_stage_t *stage, float *os, float *ot) { float txm = 0, tym = 0; // scale if (stage->scale.scaleX) { switch (stage->scale.typeX) { case 0: // static *os *= stage->scale.scaleX; break; case 1: // sine *os *= stage->scale.scaleX*sin(rs_realtime*0.05); break; case 2: // cosine *os *= stage->scale.scaleX*cos(rs_realtime*0.05); break; } } if (stage->scale.scaleY) { switch (stage->scale.typeY) { case 0: // static *ot *= stage->scale.scaleY; break; case 1: // sine *ot *= stage->scale.scaleY*sin(rs_realtime*0.05); break; case 2: // cosine *ot *= stage->scale.scaleY*cos(rs_realtime*0.05); break; } } // rotate if (stage->rot_speed) RS_RotateST2 (os, ot, -stage->rot_speed * rs_realtime * 0.0087266388888888888888888888888889); if (stage->scroll.speedX) { switch(stage->scroll.typeX) { case 0: // static txm=rs_realtime*stage->scroll.speedX; break; case 1: // sine txm=sin(rs_realtime*stage->scroll.speedX); break; case 2: // cosine txm=cos(rs_realtime*stage->scroll.speedX); break; } } else txm=0; if (stage->scroll.speedY) { switch(stage->scroll.typeY) { case 0: // static tym=rs_realtime*stage->scroll.speedY; break; case 1: // sine tym=sin(rs_realtime*stage->scroll.speedY); break; case 2: // cosine tym=cos(rs_realtime*stage->scroll.speedY); break; } } else tym=0; *os += txm; *ot += tym; } float RS_AlphaFunc (int alphafunc, float alpha, vec3_t normal, vec3_t org) { vec3_t dir; if (!abs(alphafunc)) goto endalpha; if (alphafunc == ALPHAFUNC_GLOSS) { //glossmap stuff here... } else if (alphafunc == ALPHAFUNC_NORMAL) { VectorSubtract(org, r_newrefdef.vieworg, dir); VectorNormalize(dir); alpha *= fabs(cutDot(dir, normal)); } endalpha: if (alpha<0) alpha = 0; if (alpha>1) alpha = 1; if (alphafunc<0) alpha = 1-alpha; return alpha; } image_t *BSP_TextureAnimation (mtexinfo_t *tex); rscript_t *surfaceScript(msurface_t *surf) { image_t *image = BSP_TextureAnimation( surf->texinfo ); if (image && image->script) { rscript_t *rs = image->script; RS_ReadyScript(rs); return rs; } return NULL; } void SetVertexOverbrights (qboolean toggle) { if (!r_overbrightbits->value) return; if (toggle)//turn on { qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1); qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE); GL_TexEnv( GL_COMBINE_EXT ); } else //turn off { GL_TexEnv( GL_MODULATE ); qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1); } } void SetLightingMode (void) { GL_SelectTexture( GL_TEXTURE0); if ( !gl_config.mtexcombine ) { GL_TexEnv( GL_REPLACE ); GL_SelectTexture( GL_TEXTURE1); if ( gl_lightmap->value ) GL_TexEnv( GL_REPLACE ); else GL_TexEnv( GL_MODULATE ); } else { GL_TexEnv ( GL_COMBINE_EXT ); qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE ); GL_SelectTexture( GL_TEXTURE1 ); GL_TexEnv ( GL_COMBINE_EXT ); if ( gl_lightmap->value ) { qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE ); } else { qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT ); qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE ); qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_EXT ); } if ( r_overbrightbits->value ) { qglTexEnvi ( GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, r_overbrightbits->value ); } } } qboolean lightmaptoggle; void ToggleLightmap (qboolean toggle) { if (toggle==lightmaptoggle) return; lightmaptoggle = toggle; if (toggle) { SetVertexOverbrights(false); GL_EnableMultitexture( true ); SetLightingMode (); } else { GL_EnableMultitexture( false ); SetVertexOverbrights(true); } } static cvar_t *rs_eval_if_subexpr (rs_cond_val_t *expr) { int resv; switch (expr->optype) { case rs_cond_none: return expr->val; case rs_cond_is: return rs_eval_if_subexpr (expr->subexpr1); case rs_cond_lnot: resv = (rs_eval_if_subexpr (expr->subexpr1)->value == 0); break; case rs_cond_eq: resv = Q_strcasecmp ( rs_eval_if_subexpr (expr->subexpr1)->string, rs_eval_if_subexpr (expr->subexpr2)->string ) == 0; break; case rs_cond_neq: resv = Q_strcasecmp ( rs_eval_if_subexpr (expr->subexpr1)->string, rs_eval_if_subexpr (expr->subexpr2)->string ) != 0; break; case rs_cond_gt: resv = (rs_eval_if_subexpr (expr->subexpr1)->value > rs_eval_if_subexpr (expr->subexpr2)->value ); break; case rs_cond_ngt: resv = (rs_eval_if_subexpr (expr->subexpr1)->value <= rs_eval_if_subexpr (expr->subexpr2)->value ); break; case rs_cond_lt: resv = (rs_eval_if_subexpr (expr->subexpr1)->value < rs_eval_if_subexpr (expr->subexpr2)->value ); break; case rs_cond_nlt: resv = (rs_eval_if_subexpr (expr->subexpr1)->value >= rs_eval_if_subexpr (expr->subexpr2)->value ); break; case rs_cond_and: resv = (rs_eval_if_subexpr (expr->subexpr1)->value && rs_eval_if_subexpr (expr->subexpr2)->value ); break; case rs_cond_or: resv = (rs_eval_if_subexpr (expr->subexpr1)->value || rs_eval_if_subexpr (expr->subexpr2)->value ); break; default: Com_Printf ("Unknown optype %d! (Can't happen)\n", expr->optype); resv = 0; break; } Anon_Cvar_Set (&(expr->lval), va ("%d", resv)); return &(expr->lval); } //This is the shader drawing routine for bsp surfaces - it will draw on top of the //existing texture. void RS_DrawSurfaceTexture (msurface_t *surf, rscript_t *rs) { glpoly_t *p = surf->polys; unsigned lmtex = surf->lightmaptexturenum; float *v; int i, nv; vec3_t vectors[3]; rs_stage_t *stage; float os, ot, alpha; float time, txm=0.0f, tym=0.0f; int VertexCounter; if (!rs) return; nv = surf->polys->numverts; stage = rs->stage; time = rs_realtime; //for envmap by normals AngleVectors (r_newrefdef.viewangles, vectors[0], vectors[1], vectors[2]); lightmaptoggle = true; do { if (stage->lensflare || stage->grass || stage->beam || stage->cube) break; //handled elsewhere if (stage->condv && !(rs_eval_if_subexpr(stage->condv)->value)) continue; //stage should not execute if(stage->lightmap) { ToggleLightmap(true); qglShadeModel (GL_FLAT); GL_MBind (GL_TEXTURE1, gl_state.lightmap_textures + lmtex); if (stage->colormap.enabled) qglDisable (GL_TEXTURE_2D); else if (stage->anim_count){ GL_MBind (GL_TEXTURE0, RS_Animate(stage)); } else { GL_MBind (GL_TEXTURE0, stage->texture->texnum); } } else { ToggleLightmap(false); qglShadeModel (GL_SMOOTH); if (stage->colormap.enabled) qglDisable (GL_TEXTURE_2D); else if (stage->anim_count) { GL_Bind (RS_Animate(stage)); } else { GL_Bind (stage->texture->texnum); } } if (stage->blendfunc.blend) { GL_BlendFunction(stage->blendfunc.source, stage->blendfunc.dest); GLSTATE_ENABLE_BLEND } else if (surf->texinfo->flags & (SURF_TRANS33 | SURF_TRANS66) && !stage->alphamask) { GL_BlendFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GLSTATE_ENABLE_BLEND } else { GLSTATE_DISABLE_BLEND } // sane defaults alpha = 1.0f; if (stage->alphashift.min || stage->alphashift.speed) { if (!stage->alphashift.speed && stage->alphashift.min > 0) { alpha = stage->alphashift.min; } else if (stage->alphashift.speed) { alpha = sin (rs_realtime * stage->alphashift.speed); alpha = (alpha + 1)*0.5f; if (alpha > stage->alphashift.max) alpha = stage->alphashift.max; if (alpha < stage->alphashift.min) alpha = stage->alphashift.min; } } if (stage->scroll.speedX) { switch (stage->scroll.typeX) { case 0: // static txm = rs_realtime*stage->scroll.speedX; break; case 1: // sine txm = sin (rs_realtime*stage->scroll.speedX); break; case 2: // cosine txm = cos (rs_realtime*stage->scroll.speedX); break; } } else txm=0; if (stage->scroll.speedY) { switch (stage->scroll.typeY) { case 0: // static tym = rs_realtime*stage->scroll.speedY; break; case 1: // sine tym = sin (rs_realtime*stage->scroll.speedY); break; case 2: // cosine tym = cos (rs_realtime*stage->scroll.speedY); break; } } else tym=0; qglColor4f (1, 1, 1, alpha); if (stage->alphamask) { GLSTATE_ENABLE_ALPHATEST } else { GLSTATE_DISABLE_ALPHATEST } if(stage->lightmap) R_InitVArrays (VERT_MULTI_TEXTURED); else R_InitVArrays (VERT_SINGLE_TEXTURED); VArray = &VArrayVerts[0]; VertexCounter = 0; for (i = 0, v = p->verts[0]; i < nv; i++, v += VERTEXSIZE) { if (stage->envmap) { RS_SetEnvmap (v, &os, &ot); //move by normal & position os-=DotProduct (surf->plane->normal, vectors[1] ) + (r_newrefdef.vieworg[0]-r_newrefdef.vieworg[1]+r_newrefdef.vieworg[2])*0.0025; ot+=DotProduct (surf->plane->normal, vectors[2] ) + (-r_newrefdef.vieworg[0]+r_newrefdef.vieworg[1]-r_newrefdef.vieworg[2])*0.0025; if (surf->texinfo->flags & SURF_FLOWING) txm = tym = 0; } else { os = v[3]; ot = v[4]; } RS_SetTexcoords (stage, &os, &ot, surf); { float red=255, green=255, blue=255; if (stage->colormap.enabled) { red *= stage->colormap.red/255.0f; green *= stage->colormap.green/255.0f; blue *= stage->colormap.blue/255.0f; } alpha = RS_AlphaFunc(stage->alphafunc, alpha, surf->plane->normal, v); if (red>1)red=1; if (red<0) red = 0; if (green>1)green=1; if (green<0) green = 0; if (blue>1)blue=1; if (blue<0) blue = 0; qglColor4f (red, green, blue, alpha); } // copy in vertex data VArray[0] = v[0]; VArray[1] = v[1]; VArray[2] = v[2]; // world texture coords VArray[3] = os+txm; VArray[4] = ot+tym; // lightmap texture coords VArray[5] = v[5]; VArray[6] = v[6]; if(stage->lightmap) VArray += VertexSizes[VERT_MULTI_TEXTURED]; else VArray += VertexSizes[VERT_SINGLE_TEXTURED]; VertexCounter++; } R_DrawVarrays(GL_POLYGON, 0, VertexCounter); qglColor4f(1,1,1,1); if (stage->colormap.enabled) qglEnable (GL_TEXTURE_2D); } while ( (stage = stage->next) ); qglDisableClientState( GL_COLOR_ARRAY ); qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); R_KillVArrays(); ToggleLightmap(true); GL_EnableMultitexture( false ); // restore the original blend mode qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GLSTATE_DISABLE_BLEND GLSTATE_DISABLE_ALPHATEST GLSTATE_DISABLE_TEXGEN } rscript_t *rs_caustics; rscript_t *rs_glass; void RS_LoadSpecialScripts (void) //the special cases of glass and water caustics { rs_caustics = RS_FindScript("caustics"); if(rs_caustics) RS_ReadyScript(rs_caustics); rs_glass = RS_FindScript("glass"); if(rs_glass) RS_ReadyScript(rs_glass); } void RS_Surface (msurface_t *surf) { rscript_t *rs_shader; //Underwater Caustics if(rs_caustics) if (surf->iflags & ISURF_UNDERWATER ) RS_DrawSurfaceTexture(surf, rs_caustics); //all other textures shaders rs_shader = (rscript_t *)surf->texinfo->image->script; if(rs_shader) RS_DrawSurfaceTexture(surf, rs_shader); } alien-arena-7.66+dfsg/source/ref_gl/r_text.h0000600000175000017500000003607512161402007020037 0ustar zero79zero79/* Copyright (C) 2010 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __R_TEXT_H #define __R_TEXT_H /* Forward-declare the face structure and its pointer type */ struct FNT_face_s; typedef struct FNT_face_s * FNT_face_t; /* Forward-declare the font structure and its pointer type */ struct FNT_font_s; typedef struct FNT_font_s * FNT_font_t; /* Forward-declare the text window structure and its pointer type */ struct FNT_window_s; typedef struct FNT_window_s * FNT_window_t; /**************************************************************************/ /* CONSTANTS */ /**************************************************************************/ /* Maximal length of a font file's base name */ #define FNT_FACE_NAME_MAX 48 /* Maximal length of a font key ("font name!font size") */ #define FNT_FONT_KEY_MAX ( FNT_FACE_NAME_MAX + 11 ) /* Color modes */ #define FNT_CMODE_NONE 0 // Ignore color codes #define FNT_CMODE_QUAKE 1 // Use Quake color codes #define FNT_CMODE_QUAKE_SRS 2 // Use Quake color codes, but // reset to default color when // space is found #define FNT_CMODE_TWO 3 // Use two colors, with bit 7 // of the string's characters // to indicate the second one; // Quake color codes will be // stripped out. /* Text alignment */ #define FNT_ALIGN_LEFT 0 #define FNT_ALIGN_RIGHT 1 #define FNT_ALIGN_CENTER 2 /* Color table for Quake colors */ extern float FNT_colors[ 8 ][ 4 ]; /**************************************************************************/ /* FUNCTION TYPES FOR FACES AND FONTS */ /**************************************************************************/ /* * Face destruction function * * Parameters: * face the face to destroy */ typedef void (* FNT_DestroyFace_funct)( FNT_face_t face ); /* * Font loader function - used by faces when initialising a font. * * Parameters: * font a font structure where everything except the * internal structure pointer has been initialised * * Returns: * true on success, false on failure */ typedef qboolean (* FNT_GetFont_funct )( FNT_font_t font ); /* * Raw printing function. * * Used to draw some text at a specific location using a fixed colour. * * Parameters: * font the font to draw text with * text pointer to the string to draw * text_length length of the string to draw * r2l false for left-to-right, true for right-to-left * x , y coordinates to start from * color (R,G,B,A) colour to apply when drawing * * Notes: * 1/ All control or non-ASCII characters will be skipped. * 2/ No checks will be made regarding the string's end, only the * specified length will be used. * 3/ In right-to-left mode, the string will be read backwards. */ typedef void (* FNT_RawPrint_funct )( FNT_font_t font , const char * text , unsigned int text_length , qboolean r2l , float x , float y , const float color[4] ); /* * Bounded printing function * * Draws a string in a region; does not perform wrapping, everything that is * out of the specified box is ignored. * * Parameters: * font the font to use * text the text to draw * cmode the color coding to use * align the text's alignment * box the text's window * color the color (or colors) to use * * Notes: * 1/ The initial window must include a valid width. * 2/ In "two colors" mode, the "color" parameter should point to an * array of 8 floats; in other modes, only 4 floats are needed. * 3/ The window's width and height will be set to the actual space used * by the text. */ typedef void (* FNT_BoundedPrint_funct)( FNT_font_t font , const char * text , unsigned int cmode , unsigned int align , FNT_window_t box , const float * color ); /* * Printing function that supports word-wrapping. * * Draws a string in a region and performs wrapping as appropriate. If the * region's height is not set to 0, stop printing when it is reached. * * Parameters: * font the font to use * text the text to draw * cmode the color coding to use * align the text's alignment * indent the size of the indent when a line is wrapped * box the text's window * color the color (or colors) to use * * Notes: * 1/ The initial window must include a valid width. * 2/ In "two colors" mode, the "color" parameter should point to an * array of 8 floats; in other modes, only 4 floats are needed. * 3/ The window's width and height will be set to the actual space used * by the text. */ typedef void (* FNT_WrappedPrint_funct)( FNT_font_t font , const char * text , unsigned int cmode , unsigned int align , unsigned int indent , FNT_window_t box , const float * color ); /* * Font destruction function * * Parameters: * font the font to destroy */ typedef void (* FNT_DestroyFont_funct)( FNT_font_t font ); /* * Size prediction function * * Determine how long the given text would be if drawn in the given font. * Assumes no wrapping or boundaries-- it could well return a number greater * than the horizontal resolution of the display. * * Parameters: * font the font to use * text the text to use * color enable ^color code filtering * * Returns: * The width in pixels required to render the text in the font */ typedef int (* FNT_PredictSize_funct)( FNT_font_t font , const char * text, qboolean color ); /**************************************************************************/ /* STRUCTURES FOR FACES AND FONTS */ /**************************************************************************/ /* * This structure corresponds to a "face" - a type of font, with no * specifics such as size. */ struct FNT_face_s { /* The face's name */ char name[ FNT_FACE_NAME_MAX + 1 ]; /* The function that allows fonts to be initialised */ FNT_GetFont_funct GetFont; /* Destructor */ FNT_DestroyFace_funct Destroy; /* Amount of fonts using this face */ unsigned int used; /* Internal data used by the actual font renderer */ void * internal; }; /* * This structure corresponds to a generic font. */ struct FNT_font_s { /* The font's look-up key */ char lookup[ FNT_FONT_KEY_MAX + 1 ]; /* The font's face */ FNT_face_t face; /* The font's height in pixels */ unsigned int size; /* total line height in pixels, including spacing */ unsigned int height; /* theoretical maximum character width in pixels, given current size */ unsigned int width; /* Printing functions */ FNT_RawPrint_funct RawPrint; FNT_BoundedPrint_funct BoundedPrint; FNT_WrappedPrint_funct WrappedPrint; FNT_PredictSize_funct PredictSize; /* Destructor */ FNT_DestroyFont_funct Destroy; /* Amount of "unfreed" GetFont's for this font */ unsigned int used; /* Internal data used by the actual font renderer */ void * internal; }; /* * This structure is used when drawing text, it carries coordinates/region size * between the caller and the text drawing function. */ struct FNT_window_s { int x; int y; unsigned int width; unsigned int height; }; /* * This structure is used by wrapped printing functions, which use * _FNT_NextWrappedUnit() to transform a string into an array of * render information. */ struct _FNT_render_info_s { int toDraw; const float * color; int width; int kerning; }; typedef struct _FNT_render_info_s * _FNT_render_info_t; /* * This structure is used for registration of auto-loaded fonts */ struct FNT_auto_s { /* List pointers */ struct FNT_auto_s * previous; struct FNT_auto_s * next; /* Face to use / default face to use if CVar is set but there is * no such face. */ char face[ FNT_FACE_NAME_MAX + 1 ]; /* CVar that replaces the default face, or NULL if the default * is always used. */ cvar_t * faceVar; /* Default font size. May be <= 0 if the size is to be computed * from the screen's size. */ int size; /* CVar that replaces the default size, or NULL if the default * is always used. */ cvar_t * sizeVar; /* When automatic size computation is used, this indicates the * amount of lines of text on the screen. */ unsigned int lines; /* The minimal size that can be selected, either automatically * or through the variable. */ unsigned int minSize; /* The maximal size that can be selected, either automatically * or through the variable. */ unsigned int maxSize; /* The current font used. May be NULL if unregistered, or may be * the Null Font. */ FNT_font_t font; }; typedef struct FNT_auto_s * FNT_auto_t; /**************************************************************************/ /* FONT FUNCTIONS */ /**************************************************************************/ /* * Initialise the text drawing front-end. * * Returns: * true on success, false on failure. */ qboolean FNT_Initialise( ); /* * Destroy the text drawing front-end. */ void FNT_Shutdown( ); /* * Create or access a face. * * Parameters: * face_name name of the face's definition file * * Returns: * a pointer to the face's structure, or NULL if the face could not * be loaded. * * Notes: * face_name corresponds to a file name; its path and extension are * ignored: faces should be in the "fonts" directory, and they should * be either TrueType fonts or bitmap fonts. If both files exist, the * TrueType font will be used. */ FNT_face_t FNT_GetFace( const char * face_name ); /* * Create or access a font. * * Parameters: * face the face to use to create the font * size the font's desired height in pixels * * Returns: * a pointer to the font's structure, or NULL if the font could not * be initialised. */ FNT_font_t FNT_GetFont( FNT_face_t face , unsigned int size ); /* * Release a font * * This function needs to be called when a font is no longer needed by some * part of the program. * * It will decrease the font's use count and, if necessary, destroy it. * If the face is no longer in use, it will be freed as well. * * Parameters: * font the font to release */ void FNT_ReleaseFont( FNT_font_t font ); /* * Print a raw string. See comment on FNT_RawPrint_funct for more information. */ #define FNT_RawPrint(font,text,text_length,r2l,x,y,color) \ ( font->RawPrint( font,text,text_length,r2l,x,y,color ) ) /* * Print a string bounded by a box. See comment on FNT_BoundedPrint_funct for * more information. */ #define FNT_BoundedPrint(font,text,cmode,align,box,color) \ ( font->BoundedPrint( font , text , cmode , align , box , color ) ) /* * Print a string bounded by a box using word wrapping. See comment on * FNT_WrappedPrint_funct for more information. */ #define FNT_WrappedPrint(font,text,cmode,align,indent,box,color) \ ( font->WrappedPrint( font , text , cmode , align , indent , box , color ) ) /* * Determine how much space is required to print the string. See comment on * FNT_PredictSize_funct for more information. */ #define FNT_PredictSize(font,text,color) \ ( font->PredictSize( font , text , color ) ) /**************************************************************************/ /* AUTOMATIC FONT MANAGEMENT */ /**************************************************************************/ /* * Initialise an automatic font structure. * * Parameters: * auto_font automatic font structure to initialise * default_face name of the default font face * default_size default size of the font * auto_lines amount of lines of text on the screen in automatic * size mode * min_size minimal font size * max_size maximal font size */ void FNT_AutoInit( FNT_auto_t auto_font , const char * default_face , int default_size , unsigned int auto_lines , unsigned int min_size , unsigned int max_size ); /* * Register an automatic font. * * Parameters: * auto_font automatic font structure to register * * Notes: * This function will either ignore the structure or crash, depending * on whatever's in memory, if the structure hasn't been initialised. */ void FNT_AutoRegister( FNT_auto_t auto_font ); /* * Access the font from an automatic font structure. * * If the automatic font uses CVars and one of the variables has been * modified, or if the game went through a video restart, the font * will be reloaded automatically. * * Parameters: * auto_font automatic font structure to access * * Returns: * The font described by the automatic font structure. * * Notes: * This function will probably crash (or at least yield undefined * results) if the automatic font structure hasn't been registered. */ FNT_font_t FNT_AutoGet( FNT_auto_t auto_font ); /**************************************************************************/ /* HELPER FUNCTIONS */ /**************************************************************************/ /* * Handle color codes in strings. * * This function finds color codes, allowing them to be skipped when rendering * strings, while setting the current color vector accordingly. * * Parameters: * pptr pointer to the text pointer, will be updated * depending on what is found * cmode color mode * color default color vector(s) passed to the rendering * function * expectColor pointer to a boolean which is used to keep track * of Quake escape characters * colorChanged pointer to a boolean which will be set to true * if the color has been changed * curColor pointer to a color vector pointer, will be updated * to the new color if needed * * Returns: * true if the next character is to be rendered, false if it must be * skipped */ qboolean _FNT_HandleColor( const char ** pptr , unsigned int cmode , const float * color , qboolean * expectColor , qboolean * colorChanged , const float ** curColor ); /* * Find the next wrapped unit (i.e. line or rest of the string until EOL). * * Parameters: * pptr pointer to the text pointer, will be updated to the * character that follows the wrapped unit (i.e. after * \n or \0) * renderInfo start of the rendering information array * unitLength pointer to an integer which will be updated to the * amount of items in the rendering information array * cmode color mode * color default color vector(s) * * Returns: * false if the end of the string has been reached, false otherwise */ qboolean _FNT_NextWrappedUnit( const char ** pptr , _FNT_render_info_t renderInfo , unsigned int * unitLength , unsigned int cmode , const float * color ); #endif // __R_TEXT_H alien-arena-7.66+dfsg/source/ref_gl/r_iqm.h0000600000175000017500000000534612161402007017636 0ustar zero79zero79#ifndef __MODEL_IQM_H__ #define __MODEL_IQM_H__ //this no worky #define IDINTERQUAKEMODELHEADER (('L'<<40768)+('E'<<20384)+('D'<<10192)+('O'<<5096)+('M'<<2048)+('E'<<1024)+('K'<<512)+('A'<<256)+('U'<<128)+('Q'<<64)+('R'<<32)+('E'<<24)+('T'<<16)+('N'<<8)+'I') typedef struct iqmheader_s { char id[16]; unsigned int version; unsigned int filesize; unsigned int flags; unsigned int num_text, ofs_text; unsigned int num_meshes, ofs_meshes; unsigned int num_vertexarrays, num_vertexes, ofs_vertexarrays; unsigned int num_triangles, ofs_triangles, ofs_neighbors; unsigned int num_joints, ofs_joints; unsigned int num_poses, ofs_poses; unsigned int num_anims, ofs_anims; unsigned int num_frames, num_framechannels, ofs_frames, ofs_bounds; unsigned int num_comment, ofs_comment; unsigned int num_extensions, ofs_extensions; } iqmheader_t; typedef struct iqmmesh_s { unsigned int name; unsigned int material; unsigned int first_vertex, num_vertexes; unsigned int first_triangle, num_triangles; } iqmmesh_t; #define IQM_POSITION 0 #define IQM_TEXCOORD 1 #define IQM_NORMAL 2 #define IQM_TANGENT 3 #define IQM_BLENDINDEXES 4 #define IQM_BLENDWEIGHTS 5 #define IQM_COLOR 6 #define IQM_CUSTOM 0x10 #define IQM_BYTE 0 #define IQM_UBYTE 1 #define IQM_SHORT 2 #define IQM_USHORT 3 #define IQM_INT 4 #define IQM_UINT 5 #define IQM_HALF 6 #define IQM_FLOAT 7 #define IQM_DOUBLE 8 // animflags #define IQM_LOOP 1 typedef struct iqmtriangle_s { unsigned int vertex[3]; } iqmtriangle_t; typedef struct iqmjoint_s { unsigned int name; signed int parent; float origin[3], rotation[3], scale[3]; } iqmjoint_t; typedef struct iqmpose_s { signed int parent; unsigned int channelmask; float channeloffset[9], channelscale[9]; } iqmpose_t; typedef struct iqmjoint2_s { unsigned int name; signed int parent; float origin[3], rotation[4], scale[3]; } iqmjoint2_t; typedef struct iqmpose2_s { signed int parent; unsigned int channelmask; float channeloffset[10], channelscale[10]; } iqmpose2_t; typedef struct iqmanim_s { unsigned int name; unsigned int first_frame, num_frames; float framerate; unsigned int flags; } iqmanim_t; typedef struct iqmvertexarray_s { unsigned int type; unsigned int flags; unsigned int format; unsigned int size; unsigned int offset; } iqmvertexarray_t; typedef struct iqmextension_s { unsigned int name; unsigned int num_data, ofs_data; unsigned int ofs_extensions; // pointer to next extension } iqmextension_t; typedef struct iqmbounds_s { float mins[3], maxs[3]; float xyradius, radius; } iqmbounds_t; #endif alien-arena-7.66+dfsg/source/ref_gl/r_ttf.h0000600000175000017500000000217212161402007017637 0ustar zero79zero79/* Copyright (C) 2010 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __R_TTF_H #define __R_TTF_H #include #include "r_text.h" /* Initialise TTF engine */ qboolean TTF_Initialise( void ); /* Shutdown TTF engine */ void TTF_Shutdown( void ); /* * Initialise a TTF face. * * This function will try loading the face's file and, on success, it will * load and verify the TTF information. */ qboolean TTF_InitFace( FNT_face_t face ); #endif //__R_TTF_H alien-arena-7.66+dfsg/source/ref_gl/r_image.c0000600000175000017500000013612012162607462020135 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif // for jpeglib #define HAVE_PROTOTYPES #include "r_local.h" #if defined HAVE_JPEG_JPEGLIB_H #include "jpeg/jpeglib.h" #else #include "jpeglib.h" #endif image_t gltextures[MAX_GLTEXTURES]; image_t *r_mirrortexture; image_t *r_depthtexture; image_t *r_depthtexture2; int numgltextures; int base_textureid; // gltextures[i] = base_textureid+i extern cvar_t *cl_hudimage1; //custom huds extern cvar_t *cl_hudimage2; unsigned d_8to24table[256]; qboolean GL_Upload8 (byte *data, int width, int height, int picmip, qboolean filter); qboolean GL_Upload32 (byte *data, int width, int height, int picmip, qboolean filter, qboolean force_standard_mipmap); int gl_solid_format = 3; int gl_alpha_format = 4; int gl_tex_solid_format = 3; int gl_tex_alpha_format = 4; int gl_filter_min = GL_LINEAR_MIPMAP_LINEAR; int gl_filter_max = GL_LINEAR; void R_InitImageSubsystem(void) { int max_aniso; if ( strstr( gl_config.extensions_string, "GL_ARB_multitexture" ) ) { Com_Printf ("...using GL_ARB_multitexture\n" ); qglMTexCoord2fARB = ( void * ) qwglGetProcAddress( "glMultiTexCoord2fARB" ); qglMTexCoord3fARB = ( void * ) qwglGetProcAddress( "glMultiTexCoord3fARB" ); qglMultiTexCoord3fvARB = (void*)qwglGetProcAddress("glMultiTexCoord3fvARB"); qglActiveTextureARB = ( void * ) qwglGetProcAddress( "glActiveTextureARB" ); qglClientActiveTextureARB = ( void * ) qwglGetProcAddress( "glClientActiveTextureARB" ); GL_TEXTURE0 = GL_TEXTURE0_ARB; GL_TEXTURE1 = GL_TEXTURE1_ARB; GL_TEXTURE2 = GL_TEXTURE2_ARB; GL_TEXTURE3 = GL_TEXTURE3_ARB; GL_TEXTURE4 = GL_TEXTURE4_ARB; GL_TEXTURE5 = GL_TEXTURE5_ARB; GL_TEXTURE6 = GL_TEXTURE6_ARB; GL_TEXTURE7 = GL_TEXTURE7_ARB; } else { Com_Error (ERR_FATAL, "...GL_ARB_multitexture not found\n" ); } gl_config.mtexcombine = false; if ( strstr( gl_config.extensions_string, "GL_ARB_texture_env_combine" ) ) { Com_Printf( "...using GL_ARB_texture_env_combine\n" ); gl_config.mtexcombine = true; } else { Com_Printf( "...GL_ARB_texture_env_combine not found\n" ); } if ( !gl_config.mtexcombine ) { if ( strstr( gl_config.extensions_string, "GL_EXT_texture_env_combine" ) ) { Com_Printf( "...using GL_EXT_texture_env_combine\n" ); gl_config.mtexcombine = true; } else { Com_Printf( "...GL_EXT_texture_env_combine not found\n" ); } } if (strstr(gl_config.extensions_string, "GL_EXT_texture_filter_anisotropic")) { qglGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_aniso); r_ext_max_anisotropy = Cvar_Get("r_ext_max_anisotropy", "1", CVAR_ARCHIVE ); Cvar_SetValue("r_ext_max_anisotropy", max_aniso); r_anisotropic = Cvar_Get("r_anisotropic", "1", CVAR_ARCHIVE); if (r_anisotropic->integer >= r_ext_max_anisotropy->integer) Cvar_SetValue("r_anisotropic", r_ext_max_anisotropy->integer); if (r_anisotropic->integer <= 0) Cvar_SetValue("r_anisotropic", 1); r_alphamasked_anisotropic = Cvar_Get("r_alphamasked_anisotropic", "1", CVAR_ARCHIVE); if (r_alphamasked_anisotropic->integer >= r_ext_max_anisotropy->integer) Cvar_SetValue("r_alphamasked_anisotropic", r_ext_max_anisotropy->integer); if (r_alphamasked_anisotropic->integer <= 0) Cvar_SetValue("r_alphamasked_anisotropic", 1); if (r_anisotropic->integer == 1 && r_alphamasked_anisotropic->integer == 1) Com_Printf("...ignoring GL_EXT_texture_filter_anisotropic\n"); else Com_Printf("...using GL_EXT_texture_filter_anisotropic\n"); } else { Com_Printf("...GL_EXT_texture_filter_anisotropic not found\n"); r_anisotropic = Cvar_Get("r_anisotropic", "0", CVAR_ARCHIVE); r_alphamasked_anisotropic = Cvar_Get("r_alphamasked_anisotropic", "0", CVAR_ARCHIVE); r_ext_max_anisotropy = Cvar_Get("r_ext_max_anisotropy", "0", CVAR_ARCHIVE); } } GLenum bFunc1 = -1; GLenum bFunc2 = -1; void GL_BlendFunction (GLenum sfactor, GLenum dfactor) { if (sfactor!=bFunc1 || dfactor!=bFunc2) { bFunc1 = sfactor; bFunc2 = dfactor; qglBlendFunc(bFunc1, bFunc2); } } GLenum shadeModelMode = -1; void GL_ShadeModel (GLenum mode) { if (mode!=shadeModelMode) { shadeModelMode = mode; qglShadeModel(mode); } } // FIXME: // This centralized texture bind batching system is a great idea if you use it // *everywhere*. Otherwise you just end up binding a texture elsewhere and // this system doesn't know you've done it, so when you count on this system // to bindanother texture, it doesn't know it has to, and it'll happily let // you use the wrong texture. Anywhere we use glActiveTexture and // glBindTexture directly can potentially screw things up. void GL_EnableMultitexture( qboolean enable ) { if ( !qglActiveTextureARB ) return; if ( enable ) { GL_SelectTexture( GL_TEXTURE1 ); qglEnable( GL_TEXTURE_2D ); GL_TexEnv( GL_REPLACE ); GL_SelectTexture( GL_TEXTURE2 ); qglEnable( GL_TEXTURE_2D ); GL_TexEnv( GL_REPLACE ); GL_SelectTexture( GL_TEXTURE3 ); qglEnable( GL_TEXTURE_2D ); GL_TexEnv( GL_REPLACE ); } else { GL_SelectTexture( GL_TEXTURE1 ); qglDisable( GL_TEXTURE_2D ); GL_TexEnv( GL_REPLACE ); GL_SelectTexture( GL_TEXTURE2 ); qglDisable( GL_TEXTURE_2D ); GL_TexEnv( GL_REPLACE ); GL_SelectTexture( GL_TEXTURE3 ); qglDisable( GL_TEXTURE_2D ); GL_TexEnv( GL_REPLACE ); } GL_SelectTexture( GL_TEXTURE0 ); GL_TexEnv( GL_REPLACE ); } void GL_SelectTexture( GLenum texture ) { int tmu; if ( !qglActiveTextureARB ) return; if ( texture == GL_TEXTURE0 ) { tmu = 0; } else { tmu = 1; } if ( tmu == gl_state.currenttmu ) { return; } gl_state.currenttmu = tmu; if ( qglActiveTextureARB ) { qglActiveTextureARB( texture ); qglClientActiveTextureARB( texture ); } } void GL_TexEnv( GLenum mode ) { static int lastmodes[2] = { -1, -1 }; if ( mode != lastmodes[gl_state.currenttmu] ) { qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode ); lastmodes[gl_state.currenttmu] = mode; } } void GL_Bind (int texnum) { extern image_t *draw_chars; if (gl_nobind->integer && draw_chars) // performance evaluation option texnum = draw_chars->texnum; if ( gl_state.currenttextures[gl_state.currenttmu] == texnum) return; gl_state.currenttextures[gl_state.currenttmu] = texnum; qglBindTexture (GL_TEXTURE_2D, texnum); } void GL_MBind( GLenum target, int texnum ) { GL_SelectTexture( target ); if ( target == GL_TEXTURE0 ) { if ( gl_state.currenttextures[0] == texnum ) return; } else { if ( gl_state.currenttextures[1] == texnum ) return; } GL_Bind( texnum ); } typedef struct { char *name; int minimize, maximize; } glmode_t; glmode_t modes[] = { {"GL_NEAREST", GL_NEAREST, GL_NEAREST}, {"GL_LINEAR", GL_LINEAR, GL_LINEAR}, {"GL_NEAREST_MIPMAP_NEAREST", GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST}, {"GL_LINEAR_MIPMAP_NEAREST", GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR}, {"GL_NEAREST_MIPMAP_LINEAR", GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST}, {"GL_LINEAR_MIPMAP_LINEAR", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR} }; #define NUM_GL_MODES (sizeof(modes) / sizeof (glmode_t)) typedef struct { char *name; int mode; } gltmode_t; gltmode_t gl_alpha_modes[] = { {"default", 4}, {"GL_RGBA", GL_RGBA}, {"GL_RGBA8", GL_RGBA8}, {"GL_RGB5_A1", GL_RGB5_A1}, {"GL_RGBA4", GL_RGBA4}, {"GL_RGBA2", GL_RGBA2}, }; #define NUM_GL_ALPHA_MODES (sizeof(gl_alpha_modes) / sizeof (gltmode_t)) gltmode_t gl_solid_modes[] = { {"default", 3}, {"GL_RGB", GL_RGB}, {"GL_RGB8", GL_RGB8}, {"GL_RGB5", GL_RGB5}, {"GL_RGB4", GL_RGB4}, {"GL_R3_G3_B2", GL_R3_G3_B2}, #ifdef GL_RGB2_EXT {"GL_RGB2", GL_RGB2_EXT}, #endif }; #define NUM_GL_SOLID_MODES (sizeof(gl_solid_modes) / sizeof (gltmode_t)) /* =============== GL_TextureMode =============== */ void GL_TextureMode( char *string ) { int i; image_t *glt; for (i=0 ; i< NUM_GL_MODES ; i++) { if ( !Q_strcasecmp( modes[i].name, string ) ) break; } if (i == NUM_GL_MODES) { Com_Printf ("bad filter name\n"); return; } gl_filter_min = modes[i].minimize; gl_filter_max = modes[i].maximize; // change all the existing mipmap texture objects for (i=0, glt=gltextures ; itype != it_pic && glt->type != it_particle && glt->type != it_sky ) { GL_Bind (glt->texnum); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); } } } /* =============== GL_TextureAlphaMode =============== */ void GL_TextureAlphaMode( char *string ) { int i; for (i=0 ; i< NUM_GL_ALPHA_MODES ; i++) { if ( !Q_strcasecmp( gl_alpha_modes[i].name, string ) ) break; } if (i == NUM_GL_ALPHA_MODES) { Com_Printf ("bad alpha texture mode name\n"); return; } gl_tex_alpha_format = gl_alpha_modes[i].mode; } /* =============== GL_TextureSolidMode =============== */ void GL_TextureSolidMode( char *string ) { int i; for (i=0 ; i< NUM_GL_SOLID_MODES ; i++) { if ( !Q_strcasecmp( gl_solid_modes[i].name, string ) ) break; } if (i == NUM_GL_SOLID_MODES) { Com_Printf ("bad solid texture mode name\n"); return; } gl_tex_solid_format = gl_solid_modes[i].mode; } /* =============== GL_ImageList_f =============== */ void GL_ImageList_f (void) { int i; image_t *image; int texels; const char *palstrings[2] = { "RGB", "PAL" }; Com_Printf ("------------------\n"); texels = 0; for (i=0, image=gltextures ; itexnum <= 0) continue; texels += image->upload_width*image->upload_height; switch (image->type) { case it_skin: Com_Printf ("M"); break; case it_sprite: Com_Printf ("S"); break; case it_wall: Com_Printf ("W"); break; case it_pic: Com_Printf ("P"); break; case it_particle: Com_Printf ("A"); break; default: Com_Printf (" "); break; } Com_Printf (" %3i %3i %s: %s\n", image->upload_width, image->upload_height, palstrings[image->paletted], image->name); } Com_Printf ("Total texel count (not counting mipmaps): %i\n", texels); } /* ============================================================================= scrap allocation Allocate all the little status bar obejcts into a single texture to crutch up inefficient hardware / drivers ============================================================================= */ #define MAX_SCRAPS 1 #define BLOCK_WIDTH 1024 #define BLOCK_HEIGHT 512 int scrap_allocated[MAX_SCRAPS][BLOCK_WIDTH]; byte scrap_texels[MAX_SCRAPS][BLOCK_WIDTH*BLOCK_HEIGHT*4]; qboolean scrap_dirty; // returns a texture number and the position inside it int Scrap_AllocBlock (int w, int h, int *x, int *y) { int i, j; int best, best2; int texnum; for (texnum=0 ; texnum= best) break; if (scrap_allocated[texnum][i+j] > best2) best2 = scrap_allocated[texnum][i+j]; } if (j == w) { // this is a valid spot *x = i; *y = best = best2; } } if (best + h > BLOCK_HEIGHT) continue; for (i=0 ; ixmin = LittleShort(pcx->xmin); pcx->ymin = LittleShort(pcx->ymin); pcx->xmax = LittleShort(pcx->xmax); pcx->ymax = LittleShort(pcx->ymax); pcx->hres = LittleShort(pcx->hres); pcx->vres = LittleShort(pcx->vres); pcx->bytes_per_line = LittleShort(pcx->bytes_per_line); pcx->palette_type = LittleShort(pcx->palette_type); raw = &pcx->data; if (pcx->manufacturer != 0x0a || pcx->version != 5 || pcx->encoding != 1 || pcx->bits_per_pixel != 8 || pcx->xmax >= 1024 || pcx->ymax >= 512) { Com_Printf ("Bad pcx file %s\n", filename); if ((byte *)pcx != static_rawdata) FS_FreeFile (pcx); return; } out = malloc ( (pcx->ymax+1) * (pcx->xmax+1) ); *pic = out; pix = out; if (palette) { *palette = malloc(768); memcpy (*palette, (byte *)pcx + len - 768, 768); } if (width) *width = pcx->xmax+1; if (height) *height = pcx->ymax+1; for (y=0 ; y<=pcx->ymax ; y++, pix += pcx->xmax+1) { for (x=0 ; x<=pcx->xmax ; ) { dataByte = *raw++; if ((dataByte & 0xC0) == 0xC0) { runLength = dataByte & 0x3F; dataByte = *raw++; } else runLength = 1; while (runLength-- > 0) pix[x++] = dataByte; } } if ( raw - (byte *)pcx > len) { Com_DPrintf ("PCX file %s was malformed", filename); free (*pic); *pic = NULL; } if ((byte *)pcx != static_rawdata) FS_FreeFile (pcx); } /* ================================================================= JPEG LOADING By Robert 'Heffo' Heffernan ================================================================= */ static JOCTET eoi_buffer[2] = {(JOCTET)0xFF, (JOCTET)JPEG_EOI}; static qboolean crjpg_corrupted; void crjpg_null(j_decompress_ptr cinfo) { } int crjpg_fill_input_buffer(j_decompress_ptr cinfo) { Com_Printf("Premature end of JPEG data\n"); cinfo->src->next_input_byte = eoi_buffer; cinfo->src->bytes_in_buffer = 2; crjpg_corrupted = true; return 1; } void crjpg_skip_input_data(j_decompress_ptr cinfo, long num_bytes) { cinfo->src->next_input_byte += (size_t) num_bytes; cinfo->src->bytes_in_buffer -= (size_t) num_bytes; if (cinfo->src->bytes_in_buffer < 0) { Com_Printf("Premature end of JPEG data\n"); cinfo->src->next_input_byte = eoi_buffer; cinfo->src->bytes_in_buffer = 2; crjpg_corrupted = true; } } void crjpg_mem_src(j_decompress_ptr cinfo, byte *mem, int len) { cinfo->src = (struct jpeg_source_mgr *)(*cinfo->mem->alloc_small)((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(struct jpeg_source_mgr)); cinfo->src->init_source = crjpg_null; cinfo->src->fill_input_buffer = crjpg_fill_input_buffer; cinfo->src->skip_input_data = crjpg_skip_input_data; cinfo->src->resync_to_restart = jpeg_resync_to_restart; cinfo->src->term_source = crjpg_null; cinfo->src->bytes_in_buffer = len; cinfo->src->next_input_byte = mem; } #define DSTATE_START 200 /* after create_decompress */ #define DSTATE_INHEADER 201 /* reading header markers, no SOS yet */ /* ============== LoadJPG ============== */ #define STATIC_SCANLINE_SIZE (1024*3) byte static_scanline[STATIC_SCANLINE_SIZE]; void LoadJPG (char *filename, byte **pic, int *width, int *height) { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; byte *rawdata, *rgbadata, *scanline, *p, *q; int rawsize, i; crjpg_corrupted = false; // Load JPEG file into memory rawsize = FS_LoadFile_TryStatic ( filename, (void **)&rawdata, static_rawdata, STATIC_RAWDATA_SIZE); if (!rawdata) { return; } // Knightmare- check for bad data if ( rawdata[6] != 'J' || rawdata[7] != 'F' || rawdata[8] != 'I' || rawdata[9] != 'F') { if (rawdata != static_rawdata) FS_FreeFile(rawdata); return; } // Initialise libJpeg Object cinfo.err = jpeg_std_error(&jerr); jpeg_create_decompress(&cinfo); // Feed JPEG memory into the libJpeg Object crjpg_mem_src(&cinfo, rawdata, rawsize); // Process JPEG header jpeg_read_header(&cinfo, true); // bombs out here // Start Decompression jpeg_start_decompress(&cinfo); // Check Color Components if(cinfo.output_components != 3) { jpeg_destroy_decompress(&cinfo); if (rawdata != static_rawdata) FS_FreeFile(rawdata); return; } // Allocate Memory for decompressed image rgbadata = malloc(cinfo.output_width * cinfo.output_height * 4); if(!rgbadata) { jpeg_destroy_decompress(&cinfo); if (rawdata != static_rawdata) FS_FreeFile(rawdata); return; } // Pass sizes to output *width = cinfo.output_width; *height = cinfo.output_height; // Allocate Scanline buffer if (cinfo.output_width * 3 < STATIC_SCANLINE_SIZE) { scanline = &static_scanline[0]; } else { scanline = malloc(cinfo.output_width * 3); if(!scanline) { free(rgbadata); jpeg_destroy_decompress(&cinfo); if (rawdata != static_rawdata) FS_FreeFile(rawdata); return; } } // Read Scanlines, and expand from RGB to RGBA q = rgbadata; while(cinfo.output_scanline < cinfo.output_height) { p = scanline; jpeg_read_scanlines(&cinfo, &scanline, 1); for(i=0; i=0; row--) { pixbuf = targa_rgba + row*columns*4; for(column=0; column=0; row--) { pixbuf = targa_rgba + row*columns*4; for(column=0; column0) row--; else goto breakOut; pixbuf = targa_rgba + row*columns*4; } } } else { // non run-length packet for(j=0;j0) row--; else goto breakOut; pixbuf = targa_rgba + row*columns*4; } } } } breakOut:; } } if (buffer != static_rawdata) FS_FreeFile (buffer); } /* ==================================================================== IMAGE FLOOD FILLING ==================================================================== */ /* ================= Mod_FloodFillSkin Fill background pixels so mipmapping doesn't have haloes ================= */ typedef struct { short x, y; } floodfill_t; // must be a power of 2 #define FLOODFILL_FIFO_SIZE 0x1000 #define FLOODFILL_FIFO_MASK (FLOODFILL_FIFO_SIZE - 1) #define FLOODFILL_STEP( off, dx, dy ) \ { \ if (pos[off] == fillcolor) \ { \ pos[off] = 255; \ fifo[inpt].x = x + (dx), fifo[inpt].y = y + (dy); \ inpt = (inpt + 1) & FLOODFILL_FIFO_MASK; \ } \ else if (pos[off] != 255) fdc = pos[off]; \ } void R_FloodFillSkin( byte *skin, int skinwidth, int skinheight ) { byte fillcolor = *skin; // assume this is the pixel to fill floodfill_t fifo[FLOODFILL_FIFO_SIZE]; int inpt = 0, outpt = 0; int filledcolor = -1; int i; if (filledcolor == -1) { filledcolor = 0; // attempt to find opaque black for (i = 0; i < 256; ++i) if (d_8to24table[i] == (255 << 0)) // alpha 1.0 { filledcolor = i; break; } } // can't fill to filled color or to transparent color (used as visited marker) if ((fillcolor == filledcolor) || (fillcolor == 255)) { //printf( "not filling skin from %d to %d\n", fillcolor, filledcolor ); return; } fifo[inpt].x = 0, fifo[inpt].y = 0; inpt = (inpt + 1) & FLOODFILL_FIFO_MASK; while (outpt != inpt) { int x = fifo[outpt].x, y = fifo[outpt].y; int fdc = filledcolor; byte *pos = &skin[x + skinwidth * y]; outpt = (outpt + 1) & FLOODFILL_FIFO_MASK; if (x > 0) FLOODFILL_STEP( -1, -1, 0 ); if (x < skinwidth - 1) FLOODFILL_STEP( 1, 1, 0 ); if (y > 0) FLOODFILL_STEP( -skinwidth, 0, -1 ); if (y < skinheight - 1) FLOODFILL_STEP( skinwidth, 0, 1 ); skin[x + skinwidth * y] = fdc; } } //======================================================= /* ================ GL_ResampleTexture ================ */ void GL_ResampleTexture (byte *in, int inwidth, int inheight, byte *out, int outwidth, int outheight) { int i, j; byte *inrow, *inrow2; unsigned frac, fracstep; unsigned p1[1024], p2[1024]; byte *pix1, *pix2, *pix3, *pix4; fracstep = inwidth*0x10000/outwidth; frac = fracstep>>2; for (i=0 ; i>16); frac += fracstep; } frac = 3*(fracstep>>2); for (i=0 ; i>16); frac += fracstep; } for (i=0 ; i> 1; for (j=0 ; j>2; *(out+4*j+1) = (pix1[1] + pix2[1] + pix3[1] + pix4[1])>>2; *(out+4*j+2) = (pix1[2] + pix2[2] + pix3[2] + pix4[2])>>2; *(out+4*j+3) = (pix1[3] + pix2[3] + pix3[3] + pix4[3])>>2; } } } /* R_FilterTexture Applies brightness and contrast to the specified image while optionally computing the image's average color. Also handles image inversion and monochrome. This is all munged into one function to reduce loops on level load. */ void R_FilterTexture(byte *in, int width, int height) { int count; float fcb; int ix; static byte lut[256]; static int first_time = 1; static float lut_gamma = 0.0f; static float lut_contrast = 0.0f; if ( lut_gamma != vid_gamma->value || lut_contrast != vid_contrast->value || first_time ) { first_time = 0; lut_gamma = vid_gamma->value; lut_contrast = vid_contrast->value; // build lookup table for ( ix = 0; ix < sizeof(lut); ix++ ) { fcb = (float)ix / 255.0f; fcb *= lut_gamma; if (fcb < 0.0f ) fcb = 0.0f; fcb -= 0.5f; fcb *= lut_contrast; fcb += 0.5f; fcb *= 255.0f; if ( fcb >= 255.0f ) lut[ix] = 255 ; else if (fcb <= 0.0f ) lut[ix] = 0; else lut[ix] = (byte)fcb; } } // apply to image count = width * height; while ( count-- ) { *in = lut[*in]; ++in; *in = lut[*in]; ++in; *in = lut[*in]; ++in; ++in; } } #define ALPHATEST_THRESHOLD 169 // Uses the canonical mipmap generation algorithm, but unlike OpenGL's built- // in mipmapping, it this function knows when to quit-- that is, when the // mipmaps have gotten too "mushy." Mushy mipmaps usually aren't a problem, // but they're a huge one when dealing with alphatest surfaces. int GL_RecursiveGenerateAlphaMipmaps (byte *data, int width, int height, int depth) { int ret; int x, y; int newwidth, newheight; int upper_left_alpha; qboolean uniform = true; byte *mipmap, *scan, *scan2, *out; if (width == 1 && height == 1) return depth; newwidth = width; if (newwidth > 1) newwidth /= 2; newheight = height; if (newheight > 1) newheight /= 2; mipmap = malloc (newwidth*newheight*4); for (y = 0; (y+1) < height; y += 2) { for (x = 0; (x+1) < width; x += 2) { scan = data + (y*width+x)*4; scan2 = data + ((y+1)*width+x)*4; out = mipmap + ((y/2)*(width/2)+(x/2))*4; out[0] = (scan[0]+scan[4]+scan2[0]+scan2[4])/4; out[1] = (scan[1]+scan[5]+scan2[1]+scan2[5])/4; out[2] = (scan[2]+scan[6]+scan2[2]+scan2[6])/4; out[3] = (scan[3]+scan[7]+scan2[3]+scan2[7])/4; if (x == 0 && y == 0) upper_left_alpha = out[3]; else if ((upper_left_alpha > ALPHATEST_THRESHOLD) != (out[3] > ALPHATEST_THRESHOLD)) uniform = false; } } if (uniform) { free (mipmap); return depth; } ret = GL_RecursiveGenerateAlphaMipmaps (mipmap, newwidth, newheight, depth+1); qglTexImage2D (GL_TEXTURE_2D, depth+1, gl_tex_alpha_format, newwidth, newheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipmap); free (mipmap); return ret; } int GL_GenerateAlphaMipmaps (byte *data, int width, int height) { return GL_RecursiveGenerateAlphaMipmaps (data, width, height, 0); } static int powers_of_two[] = {16,32,64,128,256,512,1024,2048,4096}; int upload_width, upload_height; int crop_left, crop_right, crop_top, crop_bottom; qboolean uploaded_paletted; qboolean GL_Upload32 (byte *data, int width, int height, int picmip, qboolean filter, qboolean force_standard_mipmap) { int samples; byte *scaled; int scaled_width, scaled_height; int i, c; byte *scan; int comp; if(filter) R_FilterTexture(data, width, height); uploaded_paletted = false; // scan the texture for any non-255 alpha c = width*height; scan = data + 3; samples = gl_solid_format; for (i=0 ; i= powers_of_two[i] && width < powers_of_two[i+1]) { if (width > ((powers_of_two[i] + powers_of_two[i+1])/2)) scaled_width = powers_of_two[i+1]; else scaled_width = powers_of_two[i]; } else if (width == powers_of_two[i+1]) { scaled_width = powers_of_two[i+1]; } if (scaled_width && scaled_height) break; if (height >= powers_of_two[i] && height < powers_of_two[i+1]) { if (height > ((powers_of_two[i] + powers_of_two[i+1])/2)) scaled_height = powers_of_two[i+1]; else scaled_height = powers_of_two[i]; } else if (height == powers_of_two[i+1]) { scaled_height = powers_of_two[i+1]; } if (scaled_width && scaled_height) break; } // let people sample down the world textures for speed for (i = 0; i < picmip; i++) { if (scaled_width <= 1 || scaled_height <= 1) break; scaled_width >>= 1; scaled_height >>= 1; } if (scaled_width > max_size) scaled_width = max_size; if (scaled_height > max_size) scaled_height = max_size; } if (scaled_width != width || scaled_height != height) { scaled=malloc((scaled_width * scaled_height) * 4); GL_ResampleTexture(data,width,height,scaled,scaled_width,scaled_height); } else { scaled=data; } if (samples != gl_alpha_format || force_standard_mipmap) qglTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE ); qglTexImage2D (GL_TEXTURE_2D, 0, comp, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled); crop_left = crop_right = crop_top = crop_bottom = 0; if (samples == gl_alpha_format) { int x, y; qboolean found; scan = (byte*)scaled+3; for (y = 0; y < scaled_height; y++, crop_top++) { found = false; for (x = 0; x < scaled_width; x++) { scan = ((byte*)scaled + (y*scaled_width+x)*4+3); if (*scan != 0) found = true; } if (found) break; } crop_left = scaled_width; crop_right = scaled_width; for (; y < scaled_height; y++) { for (x = 0; x < scaled_width; x++) { scan = ((byte*)scaled + (y*scaled_width+x)*4+3); if (*scan != 0) { if (x < crop_left) crop_left = x; if (scaled_width-x-1 < crop_right) crop_right = scaled_width-x-1; crop_bottom = scaled_height-y-1; } } } } if (samples == gl_alpha_format && !force_standard_mipmap) { int generated_mipmaps = GL_GenerateAlphaMipmaps (scaled, scaled_width, scaled_height); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, generated_mipmaps); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, r_alphamasked_anisotropic->integer); } else qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, r_anisotropic->integer); if (scaled_width != width || scaled_height != height) free(scaled); upload_width = scaled_width; upload_height = scaled_height; qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); return (samples == gl_alpha_format); } /* =============== GL_Upload8 Returns has_alpha =============== */ qboolean GL_Upload8 (byte *data, int width, int height, int picmip, qboolean filter) { unsigned trans[512*256]; // contains 32 bit RGBA color int i, s; int p; s = width*height; if (s > sizeof(trans)/4) Com_Error (ERR_DROP, "GL_Upload8: too large"); for (i=0 ; i width && data[i-width] != 255) p = data[i-width]; else if (i < s-width && data[i+width] != 255) p = data[i+width]; else if (i > 0 && data[i-1] != 255) p = data[i-1]; else if (i < s-1 && data[i+1] != 255) p = data[i+1]; else p = 0; // copy rgb components ((byte *)&trans[i])[0] = ((byte *)&d_8to24table[p])[0]; ((byte *)&trans[i])[1] = ((byte *)&d_8to24table[p])[1]; ((byte *)&trans[i])[2] = ((byte *)&d_8to24table[p])[2]; } } return GL_Upload32 ((byte*)trans, width, height, picmip, filter, false); } /* ================ GL_ReservePic Find a free image_t ================ */ image_t *GL_FindFreeImage (char *name, int width, int height, imagetype_t type) { image_t *image; int i; // find a free image_t for (i=0, image=gltextures ; itexnum) break; } if (i == numgltextures) { if (numgltextures == MAX_GLTEXTURES) Com_Error (ERR_DROP, "MAX_GLTEXTURES"); numgltextures++; } image = &gltextures[i]; if (strlen(name) >= sizeof(image->name)) Com_Error (ERR_DROP, "Draw_LoadPic: \"%s\" is too long", name); strcpy (image->name, name); if ( name[0] != '*' ) { // not a special name, remove the path part strcpy( image->bare_name, COM_SkipPath( name ) ); } image->registration_sequence = registration_sequence; image->width = width; image->height = height; image->type = type; image->texnum = TEXNUM_IMAGES + (image - gltextures); return image; } /* ================ GL_LoadPic This is also used as an entry point for the generated r_notexture ================ */ image_t *GL_LoadPic (char *name, byte *pic, int width, int height, imagetype_t type, int bits) { image_t *image; int i; int picmip; image = GL_FindFreeImage (name, width, height, type); if (type == it_skin && bits == 8) R_FloodFillSkin(pic, width, height); if (type == it_particle || type == it_pic) picmip = 0; else picmip = gl_picmip->integer; // load little particles into the scrap if (type == it_particle && bits != 8 && image->width <= 128 && image->height <= 128) { int x, y; int i, j, k, l; int texnum; texnum = Scrap_AllocBlock (image->width, image->height, &x, &y); if (texnum == -1) goto nonscrap; scrap_dirty = true; // copy the texels into the scrap block k = 0; for (i=0 ; iheight ; i++) for (j=0 ; jwidth ; j++) for (l = 0; l < 4; l++, k++) scrap_texels[texnum][((y+i)*BLOCK_WIDTH + x + j)*4+l] = pic[k]; image->texnum = TEXNUM_SCRAPS + texnum; // overwrite old texnum image->scrap = true; image->has_alpha = true; image->sl = (double)(x+0.5)/(double)BLOCK_WIDTH; image->sh = (double)(x+image->width-0.5)/(double)BLOCK_WIDTH; image->tl = (double)(y+0.5)/(double)BLOCK_HEIGHT; image->th = (double)(y+image->height-0.5)/(double)BLOCK_HEIGHT; } else { nonscrap: image->scrap = false; GL_Bind(image->texnum); if (bits == 8) { image->has_alpha = GL_Upload8 (pic, width, height, picmip, type <= it_wall); } else { image->has_alpha = GL_Upload32 (pic, width, height, picmip, type <= it_wall, type >= it_bump); } if (type == it_pic) qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); image->paletted = uploaded_paletted; // size in pixels after power of 2 and scales image->upload_width = upload_width; image->upload_height = upload_height; // vertex offset to apply when cropping image->crop_left = crop_left; image->crop_top = crop_top; // size in pixels after cropping image->crop_width = upload_width-crop_left-crop_right; image->crop_height = upload_height-crop_top-crop_bottom; // texcoords to use when not cropping image->sl = 0; image->sh = 1; image->tl = 0; image->th = 1; // texcoords to use when cropping image->crop_sl = 0 + (float)crop_left/(float)upload_width; image->crop_sh = 1 - (float)crop_right/(float)upload_width; image->crop_tl = 0 + (float)crop_top/(float)upload_height; image->crop_th = 1 - (float)crop_bottom/(float)upload_height; } COMPUTE_HASH_KEY( image->hash_key, name, i ); return image; } /* ================ GL_LoadWal ================ */ image_t *GL_LoadWal (char *name) { miptex_t *mt; int width, height, ofs; image_t *image; FS_LoadFile (name, (void **)&mt); if (!mt) { return r_notexture; } width = LittleLong (mt->width); height = LittleLong (mt->height); ofs = LittleLong (mt->offsets[0]); image = GL_LoadPic (name, (byte *)mt + ofs, width, height, it_wall, 8); FS_FreeFile ((void *)mt); return image; } /* =============== GL_GetImage Finds an image, do not attempt to load it =============== */ image_t *GL_GetImage( const char * name ) { image_t * image = NULL; unsigned int hash_key; int i; COMPUTE_HASH_KEY( hash_key, name, i ); for ( i = 0, image=gltextures ; ihash_key && !strcmp(name, image->name)) { image->registration_sequence = registration_sequence; return image; } } return NULL; } /* =============== GL_FreeImage Frees an image slot and deletes the texture =============== */ void GL_FreeImage( image_t * image ) { if ( ! image->texnum ) return; qglDeleteTextures (1, (unsigned *)&image->texnum ); if ( gl_state.currenttextures[gl_state.currenttmu] == image->texnum ) { gl_state.currenttextures[ gl_state.currenttmu ] = 0; } memset (image, 0, sizeof(*image)); } /* =============== GL_FindImage Finds or loads the given image =============== */ image_t *GL_FindImage (char *name, imagetype_t type) { image_t *image = NULL; int len; byte *pic, *palette; int width, height; char shortname[MAX_QPATH]; if (!name) goto ret_image; // Com_Error (ERR_DROP, "GL_FindImage: NULL name"); len = strlen(name); if (len < 5) goto ret_image; // Com_Error (ERR_DROP, "GL_FindImage: bad name: %s", name); //if HUD, then we want to load the one according to what it is set to. if(!strcmp(name, "pics/i_health.pcx")) strcpy(name, cl_hudimage1->string); if(!strcmp(name, "pics/i_score.pcx")) strcpy(name, cl_hudimage2->string); // look for it image = GL_GetImage( name ); if ( image != NULL ) return image; // strip off .pcx, .tga, etc... COM_StripExtension ( name, shortname ); // // load the pic from disk // pic = NULL; palette = NULL; // Try to load the image with different file extensions, in the following // order of decreasing preference: TGA, JPEG, PCX, and WAL. LoadTGA (va("%s.tga", shortname), &pic, &width, &height); if (pic) { image = GL_LoadPic (name, pic, width, height, type, 32); goto done; } LoadJPG (va("%s.jpg", shortname), &pic, &width, &height); if (pic) { image = GL_LoadPic (name, pic, width, height, type, 32); goto done; } // TGA and JPEG are the only file types used for heightmaps and // normalmaps, so if we haven't found it yet, it isn't there, and we can // save ourselves a file lookup. if (type == it_bump) goto done; LoadPCX (va("%s.pcx", shortname), &pic, &palette, &width, &height); if (pic) { image = GL_LoadPic (name, pic, width, height, type, 8); goto done; } if (type == it_wall) image = GL_LoadWal (va("%s.wal", shortname)); done: if (pic) free(pic); if (palette) free(palette); if (image != NULL) image->script = RS_FindScript (shortname); ret_image: return image; } /* =============== R_RegisterSkin =============== */ struct image_s *R_RegisterSkin (char *name) { return GL_FindImage (name, it_skin); } /* ================ GL_FreeUnusedImages Any image that was not touched on this registration sequence will be freed. ================ */ void GL_FreeUnusedImages (void) { int i; image_t *image; // never free r_notexture r_notexture->registration_sequence = registration_sequence; for (i=0, image=gltextures ; iregistration_sequence == registration_sequence) continue; // used this sequence if (!image->registration_sequence) continue; // free image_t slot if (image->type == it_pic || image->type == it_sprite || image->type == it_particle) continue; // don't free pics or particles // free it qglDeleteTextures (1, (unsigned *)&image->texnum ); memset (image, 0, sizeof(*image)); } } /* =============== Draw_GetPalette =============== */ int Draw_GetPalette (void) { int i; int r, g, b; unsigned v; byte *pic, *pal; int width, height; // get the palette LoadPCX ("pics/colormap.pcx", &pic, &pal, &width, &height); if (!pal) { Com_Error (ERR_FATAL, "Couldn't load pics/colormap.pcx\n" "The game executable cannot find its data files. This means\n" "the game is likely not installed correctly." // TODO: automatically generate a list of paths where the data // files should be #if defined UNIX_VARIANT " If you\ninstalled the game from the repository of a Linux\n" "distribution, please report this to ther package\n" "maintainers and have them check the README for packaging\n" "instructions." #endif //UNIX_VARIANT ); } for (i=0 ; i<256 ; i++) { r = pal[i*3+0]; g = pal[i*3+1]; b = pal[i*3+2]; v = (255<<24) + (r<<0) + (g<<8) + (b<<16); d_8to24table[i] = LittleLong(v); } d_8to24table[255] &= LittleLong(0xffffff); // 255 is transparent free (pic); free (pal); return 0; } // TODO: have r_newrefdef available before calling these, put r_mirroretxture // in that struct, base it on the viewport specified in that struct. (Needed // for splitscreen.) void R_InitMirrorTextures( void ) { byte *data; int size; int size_oneside; //init the partial screen texture size_oneside = ceil((512.0f/1080.0f)*(float)viddef.height); size = size_oneside * size_oneside * 4; data = malloc( size ); memset( data, 255, size ); r_mirrortexture = GL_LoadPic( "***r_mirrortexture***", (byte *)data, size_oneside, size_oneside, it_pic, 32 ); free ( data ); } void R_InitDepthTextures( void ) { byte *data; int size, texture_height, texture_width; //find closer power of 2 to screen size for (texture_width = 1;texture_width < viddef.width;texture_width *= 2); for (texture_height = 1;texture_height < viddef.height;texture_height *= 2); //limit to 2048x2048 - anything larger is generally going to cause problems, and AA doesn't support res higher if(texture_width > 2048) texture_width = 2048; if(texture_height > 2048) texture_height = 2048; //init the framebuffer textures size = texture_width * texture_height * 4; data = malloc( size ); memset( data, 255, size ); r_depthtexture = GL_LoadPic( "***r_depthtexture***", (byte *)data, texture_width, texture_height, it_pic, 3 ); r_depthtexture2 = GL_LoadPic( "***r_depthtexture2***", (byte *)data, texture_width, texture_height, it_pic, 3 ); free ( data ); } /* =============== GL_InitImages =============== */ void GL_InitImages (void) { registration_sequence = 1; gl_state.inverse_intensity = 1; Draw_GetPalette (); R_InitMirrorTextures();//MIRRORS R_InitDepthTextures();//DEPTH(SHADOWMAPS) R_FB_InitTextures();//FULLSCREEN EFFECTS R_SI_InitTextures();//SIMPLE ITEMS R_InitBloomTextures();//BLOOMS } /* =============== GL_ShutdownImages =============== */ void GL_ShutdownImages (void) { int i; image_t *image; for (i=0, image=gltextures ; iregistration_sequence) continue; // free image_t slot // free it qglDeleteTextures (1, (unsigned *)&image->texnum); memset (image, 0, sizeof(*image)); } memset (scrap_allocated, 0, sizeof(scrap_allocated)); memset (scrap_texels, 0, sizeof(scrap_texels)); scrap_dirty = false; scrap_uploads = 0; } alien-arena-7.66+dfsg/source/ref_gl/r_ttf.c0000600000175000017500000010052312161402007017631 0ustar zero79zero79/* Copyright (C) 2010 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* r_ttf.c * * Displays text using TrueType fonts, loaded through the FreeType * library. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "r_local.h" #include "r_ttf.h" #include #include FT_FREETYPE_H #ifdef FT_LCD_FILTER_H #include FT_LCD_FILTER_H #endif /***************************************************************************** * LOCAL CONSTANTS * *****************************************************************************/ /* Amount of TTF characters to draw, starting from and including space. */ #define TTF_CHARACTERS 96 /* * Width of the textures used to store TTF fonts. Should be greater than 64 * to prevent TTF textures from being uploaded to the scrap buffer. */ #define TTF_TEXTURE_WIDTH (1 << 9) /***************************************************************************** * LOCAL TYPE DEFINITIONS * *****************************************************************************/ /* Internal structure for TTF faces */ struct _TTF_face_s { /* TTF file data */ FT_Byte * data; /* TTF file size */ unsigned int size; }; typedef struct _TTF_face_s * _TTF_face_t; /* Internal structure for TTF fonts */ struct _TTF_font_s { /* Last flags used to render the font */ unsigned int flags; /* Image used as a texture */ image_t * texture; /* Bitmap containing the font's characters */ unsigned char * bitmap; /* Width of each character */ int widths[ TTF_CHARACTERS ]; /* "Kerning" - specific offset to use for sequences of characters */ int kerning[ TTF_CHARACTERS ][ TTF_CHARACTERS ]; /* Height of the bitmap */ int height; /* GL list identifier */ unsigned int list_id; }; typedef struct _TTF_font_s * _TTF_font_t; /***************************************************************************** * LOCAL FUNCTIONS ENCAPSULATED BY FONT/FACE STRUCTURES * *****************************************************************************/ /* Initialise a TTF font */ static qboolean _TTF_GetFont( FNT_font_t font ); /* Destroy a TTF face */ static void _TTF_DestroyFace( FNT_face_t face ); /* Raw printing function */ static void _TTF_RawPrint( FNT_font_t font , const char * text , unsigned int text_length , qboolean r2l , float x , float y , const float color[4] ); /* Bounded printing function */ static void _TTF_BoundedPrint( FNT_font_t font , const char * text , unsigned int cmode , unsigned int align , FNT_window_t box , const float * color ); /* Wrapped printing function */ static void _TTF_WrappedPrint( FNT_font_t font , const char * text , unsigned int cmode , unsigned int align , unsigned int indent , FNT_window_t box , const float * color ); /* Wrapped printing function */ static int _TTF_PredictSize( FNT_font_t font , const char * text, qboolean color ); /***************************************************************************** * LOCAL VARIABLES * *****************************************************************************/ #if !defined NDEBUG /* * When debugging is not disabled, make sure the library is in the * right state before initialising or shutting down. */ static qboolean _TTF_initialised = false; #endif // !defined NDEBUG /* The TTF library instance. */ static FT_Library _TTF_library; /* CVar to enable/disable sub-pixel rendering. */ static cvar_t * _TTF_subpixel; /* CVar that controls autohinting. */ static cvar_t * _TTF_autohint; /* Macro that computes a font's flags from the TTF control variables */ #define TTF_COMPUTE_FLAGS() ( \ ( (_TTF_autohint && _TTF_autohint->integer ) ? 1 : 0 ) \ | ( _TTF_subpixel ? ( 1 + ( _TTF_subpixel->integer << 1 ) ) : 0) << 1 \ ) /***************************************************************************** * ENGINE INITIALISATION & SHUTDOWN FUNCTIONS * *****************************************************************************/ /* * Initialise the FreeType library */ qboolean TTF_Initialise( ) { FT_Error error; #if !defined NDEBUG if ( _TTF_initialised ) { Com_DPrintf( "TTF: library already initialised\n" ); return false; } #endif // !defined NDEBUG // Initialise FreeType error = FT_Init_FreeType( &_TTF_library ); if ( error != 0 ) { Com_Printf( "TTF: unable to initialise library (error code %d)\n" , error ); return false; } #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING // Access CVar for sub-pixel rendering _TTF_subpixel = Cvar_Get( "ttf_subpixel" , "0" , CVAR_ARCHIVE ); _TTF_subpixel->modified = false; // Attempt to initialise sub-pixel rendering switch ( _TTF_subpixel->integer ) { case 0: break; case 1: FT_Library_SetLcdFilter( _TTF_library , FT_LCD_FILTER_NONE ); break; case 2: FT_Library_SetLcdFilter( _TTF_library , FT_LCD_FILTER_DEFAULT ); break; case 3: FT_Library_SetLcdFilter( _TTF_library , FT_LCD_FILTER_LIGHT ); break; } #else // FT_CONFIG_OPTION_SUBPIXEL_RENDERING _TTF_subpixel = NULL; #endif // FT_CONFIG_OPTION_SUBPIXEL_RENDERING // Access CVar for autohinting _TTF_autohint = Cvar_Get( "ttf_autohint" , "0" , CVAR_ARCHIVE ); _TTF_autohint->modified = false; #if !defined NDEBUG Com_Printf( "...initialised TTF engine\n" ); _TTF_initialised = true; #endif // !defined NDEBUG return true; } /* * Shutdown the FreeType library */ void TTF_Shutdown( ) { #if !defined NDEBUG if ( ! _TTF_initialised ) { Com_DPrintf( "TTF: library is not initialised\n" ); return; } Com_Printf( "...shutting down TTF engine\n" ); _TTF_initialised = false; #endif // !defined NDEBUG FT_Done_FreeType( _TTF_library ); } /***************************************************************************** * FONT FRONT-END INTERFACE FUNCTION * *****************************************************************************/ qboolean TTF_InitFace( FNT_face_t face ) { char fileName[ FNT_FACE_NAME_MAX + 11 ]; FT_Byte * fileData; unsigned int dataSize; FT_Face ftFace; FT_Error error; _TTF_face_t internal; qboolean ok; Com_sprintf( fileName , sizeof( fileName ) , "fonts/%s.ttf" , face->name ); // Attempt to load the font's file dataSize = FS_LoadFile( fileName , (void **)&fileData ); if ( !fileData ) { return false; } // Load TTF face information error = FT_New_Memory_Face( _TTF_library , fileData , dataSize , 0 , &ftFace ); if ( error != 0 ) { Com_Printf( "TTF: failed to load font from '%s' (error code %d)\n" , fileName , error ); FS_FreeFile( fileData ); return false; } // Check font information if ( (ftFace->face_flags & FT_FACE_FLAG_SCALABLE) && (ftFace->face_flags & FT_FACE_FLAG_HORIZONTAL) ) { ok = true; } else { Com_Printf( "TTF: font loaded from '%s' is not scalable\n" , fileName ); ok = false; } FT_Done_Face( ftFace ); if ( ok ) { // Initialise face structure's internal data and function pointers internal = (_TTF_face_t) Z_Malloc( sizeof( struct _TTF_face_s ) ); internal->data = fileData; internal->size = dataSize; face->internal = internal; face->GetFont = _TTF_GetFont; face->Destroy = _TTF_DestroyFace; } else { FS_FreeFile( fileData ); } return ok; } /***************************************************************************** * FONT MANAGEMENT FUNCTIONS * *****************************************************************************/ /* Face destruction function */ static void _TTF_DestroyFace( FNT_face_t face ) { _TTF_face_t faceInt = (_TTF_face_t) face->internal; FS_FreeFile( faceInt->data ); Z_Free( faceInt ); } /* The actual loader function */ static qboolean _TTF_LoadFont( FNT_font_t font ) { _TTF_face_t faceInt = (_TTF_face_t) font->face->internal; _TTF_font_t fontInt = (_TTF_font_t) font->internal; FT_Error error; FT_Face face; unsigned int render_mode; unsigned int glyphs[ TTF_CHARACTERS ]; int max_ascent , max_descent; unsigned int x , y; unsigned int n_lines; unsigned int i; unsigned int texture_height; // Load TTF face information error = FT_New_Memory_Face( _TTF_library , faceInt->data , faceInt->size , 0 , &face ); if ( error != 0 ) { Com_Printf( "TTF: failed to load font face '%s' (error code %d)\n" , font->face->name , error ); return false; } // Sets the font's size error = FT_Set_Pixel_Sizes( face , font->size , 0 ); if ( error != 0 ) { Com_Printf( "TTF: could not set size %lu to font '%s' (error code %d)\n" , font->size , font->face->name , error ); goto _TTF_load_err_0; } // Set rendering mode render_mode = FT_LOAD_RENDER; if ( _TTF_autohint->integer ) render_mode |= FT_LOAD_FORCE_AUTOHINT; if ( _TTF_subpixel && _TTF_subpixel->integer ) { render_mode |= FT_LOAD_TARGET_LCD; } else { render_mode |= FT_LOAD_TARGET_NORMAL; } // Get size information x = TTF_TEXTURE_WIDTH; n_lines = 1; max_ascent = max_descent = 0; for ( i = 0 ; i < TTF_CHARACTERS ; i ++ ) { int temp; // Load the character glyphs[ i ] = FT_Get_Char_Index( face , i + ' ' ); error = FT_Load_Glyph( face , glyphs[ i ] , render_mode ); if ( error != 0 ) { Com_Printf( "TTF: could not load character '%c' from font '%s' (error code %d)\n" , i + ' ' , font->face->name , error ); goto _TTF_load_err_1; } // Get horizontal advance fontInt->widths[ i ] = face->glyph->metrics.horiAdvance >> 6; if ( ( face->glyph->metrics.horiAdvance & 0x3f ) != 0 ) { fontInt->widths[ i ] ++; } // Now get the "real" width and check if the line is full temp = face->glyph->bitmap.width; if ( _TTF_subpixel && _TTF_subpixel->integer ) { temp /= 3; } if ( temp > x ) { n_lines ++; x = TTF_TEXTURE_WIDTH; } x -= temp; // Update max ascent / descent if ( face->glyph->bitmap_top > max_ascent ) max_ascent = face->glyph->bitmap_top; temp = 1 + face->glyph->bitmap.rows - face->glyph->bitmap_top; if ( temp > max_descent ) max_descent = temp; } font->height = fontInt->height = max_ascent + max_descent; // FIXME HACK: some fonts (like freemono) disappear if used as the menu // font if we don't do this, because the menu code ends up calculating // negative margins. if (font->height < font->size) font->height = font->size; font->width = 0; // Get kerning information if ( FT_HAS_KERNING( face ) ) { for ( i = 0 ; i < TTF_CHARACTERS ; i ++ ) { int j; for ( j = 0 ; j < TTF_CHARACTERS ; j ++ ) { FT_Vector kvec; FT_Get_Kerning( face , glyphs[ i ] , glyphs[ j ] , FT_KERNING_DEFAULT , &kvec ); fontInt->kerning[ i ][ j ] = kvec.x >> 6; if (fontInt->kerning[i][j] + fontInt->widths[i] > font->width) font->width = fontInt->kerning[i][j] + fontInt->widths[i]; if (fontInt->kerning[i][j] + fontInt->widths[j] > font->width) font->width = fontInt->kerning[i][j] + fontInt->widths[j]; } } } else { font->width = font->size; memset( fontInt->kerning , 0 , sizeof( fontInt->kerning ) ); } // Compute texture height texture_height = ( max_ascent + max_descent) * n_lines; for ( i = 16 ; i <= 4096 ; i <<= 1 ) { if ( i > texture_height ) { texture_height = i; break; } } // Allocate texture fontInt->bitmap = Z_Malloc( TTF_TEXTURE_WIDTH * texture_height * 4 ); if ( fontInt->bitmap == NULL ) goto _TTF_load_err_0; memset( fontInt->bitmap , 0 , TTF_TEXTURE_WIDTH * texture_height * 4 ); // Initialise GL lists // // XXX: make sure there's no pending error first; this should not be // needed, but since the rest of the GL code doesn't check for errors // that often... qglGetError( ); fontInt->list_id = qglGenLists( TTF_CHARACTERS ); if ( qglGetError( ) != GL_NO_ERROR ) { Com_Printf( "TTF: could not create OpenGL lists\n" ); goto _TTF_load_err_1; } // Draw glyphs on texture x = 0; y = max_ascent; for ( i = 0 ; i < TTF_CHARACTERS ; i ++ ) { unsigned int rWidth , tx , ty; unsigned char * bptr , * fptr; float x1 , x2 , y1 , y2; // Render the character error = FT_Load_Glyph( face , glyphs[ i ] , render_mode ); if ( error != 0 ) { Com_Printf( "TTF: could not load character '%c' from font '%s' (error code %d)\n" , i + ' ' , font->face->name , error ); goto _TTF_load_err_2; } // Compute actual width rWidth = face->glyph->bitmap.width; if ( _TTF_subpixel && _TTF_subpixel->integer ) { rWidth /= 3; } // Wrap current line if needed if ( rWidth > TTF_TEXTURE_WIDTH - x ) { x = 0; y += fontInt->height; } // Compute texture coordinates x1 = (float)x / (float)TTF_TEXTURE_WIDTH; x2 = (float)( x + fontInt->widths[ i ] ) / (float)TTF_TEXTURE_WIDTH; y1 = (float)( y - max_ascent ) / (float)texture_height; y2 = y1 + (float)( fontInt->height ) / (float)texture_height; // Create GL display list qglNewList( fontInt->list_id + i , GL_COMPILE ); qglBegin( GL_QUADS ); qglTexCoord2i( x , y - max_ascent ); qglVertex2i( 0 , 0 ); qglTexCoord2i( x + rWidth , y - max_ascent ); qglVertex2i( rWidth , 0 ); qglTexCoord2i( x + rWidth , y + max_descent ); qglVertex2i( rWidth , fontInt->height ); qglTexCoord2i( x , y + max_descent ); qglVertex2i( 0 , fontInt->height ); qglEnd( ); qglEndList( ); // Copy glyph image to bitmap bptr = fontInt->bitmap + ( x + ( y - face->glyph->bitmap_top ) * TTF_TEXTURE_WIDTH ) * 4; fptr = face->glyph->bitmap.buffer; for ( ty = 0 ; ty < face->glyph->bitmap.rows ; ty ++ ) { unsigned char * rbptr = bptr; if ( _TTF_subpixel && _TTF_subpixel->integer ) { for ( tx = 0 ; tx < face->glyph->bitmap.width / 3 ; tx ++ , rbptr += 4 , fptr += 3 ) { rbptr[0] = fptr[0]; rbptr[1] = fptr[1]; rbptr[2] = fptr[2]; rbptr[3] = fptr[0] / 3 + fptr[1] / 3 + fptr[2] / 3; } } else { for ( tx = 0 ; tx < face->glyph->bitmap.width ; tx ++ , rbptr += 4 , fptr ++ ) { rbptr[0] = 255; rbptr[1] = 255; rbptr[2] = 255; rbptr[3] = *fptr; } } bptr += TTF_TEXTURE_WIDTH * 4; fptr += face->glyph->bitmap.pitch - face->glyph->bitmap.width; } // Update current X x += rWidth; } // Upload the texture // FIXME: if GL_LoadPic fails, we just wasted some memory fontInt->texture = GL_LoadPic( va( "***TTF*%s***" , font->lookup ) , fontInt->bitmap , TTF_TEXTURE_WIDTH , texture_height , it_pic , 32 ); // Set flags fontInt->flags = TTF_COMPUTE_FLAGS( ); FT_Done_Face( face ); return true; _TTF_load_err_2: qglDeleteLists( fontInt->list_id , TTF_CHARACTERS ); _TTF_load_err_1: free( fontInt->bitmap ); _TTF_load_err_0: FT_Done_Face( face ); return false; } /* * Check CVar changes, modify FreeType settings if needed. */ static void _TTF_CheckCVars( ) { #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING if ( _TTF_subpixel->modified ) { switch ( _TTF_subpixel->integer ) { case 0: break; case 1: FT_Library_SetLcdFilter( _TTF_library , FT_LCD_FILTER_NONE ); break; case 2: FT_Library_SetLcdFilter( _TTF_library , FT_LCD_FILTER_DEFAULT ); break; case 3: FT_Library_SetLcdFilter( _TTF_library , FT_LCD_FILTER_LIGHT ); break; } _TTF_subpixel->modified = false; } #endif // FT_CONFIG_OPTION_SUBPIXEL_RENDERING _TTF_autohint->modified = false; } /* * Destroys a font's internal data */ static void _TTF_DestroyData( _TTF_font_t font ) { GL_FreeImage( font->texture ); qglDeleteLists( font->list_id , TTF_CHARACTERS ); Z_Free( font->bitmap ); } /* * Destroys a font's data structure */ static void _TTF_Destroy( FNT_font_t font ) { _TTF_font_t fInternal = (_TTF_font_t) font->internal; _TTF_DestroyData( fInternal ); Z_Free( fInternal ); } /* * Check a font's flags and re-render it if that is necessary. */ static qboolean _TTF_CheckFlags( FNT_font_t font ) { _TTF_font_t fInternal = (_TTF_font_t) font->internal; unsigned int flags = TTF_COMPUTE_FLAGS( ); _TTF_CheckCVars( ); if ( flags != fInternal->flags ) { _TTF_DestroyData( fInternal ); return _TTF_LoadFont( font ); } return true; } static qboolean _TTF_GetFont( FNT_font_t font ) { // Allocate internal memory and load font font->internal = Z_Malloc( sizeof( struct _TTF_font_s ) ); _TTF_CheckCVars( ); if ( ! _TTF_LoadFont( font ) ) { // Failed - free resources Z_Free( font->internal ); font->internal = NULL; return false; } font->RawPrint = _TTF_RawPrint; font->BoundedPrint = _TTF_BoundedPrint; font->WrappedPrint = _TTF_WrappedPrint; font->PredictSize = _TTF_PredictSize; font->Destroy = _TTF_Destroy; return true; } /***************************************************************************** * PRINTING FUNCTIONS: INTERNALS * *****************************************************************************/ /* * Prepares the environment before drawing a string. */ static void _TTF_PrepareToDraw( image_t * texture ) { // Save current context qglPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT | GL_TRANSFORM_BIT | GL_COLOR_BUFFER_BIT ); qglMatrixMode( GL_MODELVIEW ); qglPushMatrix( ); qglMatrixMode( GL_TEXTURE ); qglPushMatrix( ); // Prepare texture GL_Bind( texture->texnum ); GL_TexEnv( GL_MODULATE ); qglLoadIdentity(); qglScaled( 1.0 / texture->width , 1.0 / texture->height , 1 ); qglMatrixMode( GL_MODELVIEW ); // Set blending function qglDisable( GL_ALPHA_TEST ); qglEnable( GL_BLEND ); qglBlendFunc ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ); } /* * Restores the environment as if was before _TTF_PrepareToDraw was called */ static void _TTF_RestoreEnvironment( ) { qglMatrixMode( GL_TEXTURE ); qglPopMatrix( ); qglMatrixMode( GL_MODELVIEW ); qglPopMatrix( ); qglPopAttrib( ); } /* * Internal raw printing function; assumes the GL environment is properly set up. */ static void _TTF_RawPrintInternal( _TTF_font_t font , const char * text , unsigned int text_length , qboolean r2l , float x , float y ) { const unsigned char * ptr = ( const unsigned char *) text; int ptrInc = r2l ? -1 : 1; int previous = -1; if (r2l) ptr += text_length-1; while ( text_length ) { unsigned int i = ( *ptr & 0x7F ) - ' '; if ( i < TTF_CHARACTERS ) { float tx; if ( previous == -1 ) { tx = x; if ( r2l ) { tx -= font->widths[ i ] + font->kerning[ i ][ 0 ]; } } else if ( r2l ) { tx = - ( font->widths[ i ] + font->kerning[ i ][ previous ] ); } else { tx = font->widths[ previous ] + font->kerning[ previous ][ i ]; } qglTranslatef( tx , y , 0 ); qglCallList( font->list_id + i ); y = 0; previous = i; } ptr += ptrInc; text_length --; } } /* * "Fix" an array of wrapped unit by changing characters to TTF font indexes, * computing widths and kernings, and removing non-printable characters. */ static void _TTF_FixWrappedUnit( const _TTF_font_t font , _FNT_render_info_t renderInfo , unsigned int * riLength ) { unsigned int riSkipped , riIndex; // Remove non-printable characters and set width and kerning information for ( riSkipped = riIndex = 0 ; riIndex < *riLength ; riIndex ++ ) { int value = ( renderInfo[ riIndex ].toDraw & 0x7f ) - ' '; // Check for characters to skip if ( value < 0 || value >= TTF_CHARACTERS ) { riSkipped ++; continue; } // If characters were skipped, copy color if ( riSkipped != 0 ) { renderInfo[ riIndex - riSkipped ].color = renderInfo[ riIndex ].color; } // Set modified data for character renderInfo[ riIndex - riSkipped ].toDraw = value; renderInfo[ riIndex - riSkipped ].width = font->widths[ value ]; if ( riIndex - riSkipped == 0 ) { renderInfo[ riIndex - riSkipped ].kerning = 0; } else { renderInfo[ riIndex - riSkipped ].kerning = font->kerning[ renderInfo[ riIndex - riSkipped - 1 ].toDraw ][ value ]; } } *riLength -= riSkipped; } /* * Function that prints a string until either the string ends, a newline is * found or a boundary is reached. */ static void _TTF_PrintUntilEOL( _TTF_font_t font , const char * text , unsigned int cmode , const float * color , unsigned int * width , int * read , const float ** curColor ) { const char * ptr = text; unsigned int cWidth = 0; qboolean expectColor = false; qboolean colorChanged = true; int previous = -1; int txTotal = 0; while ( *ptr ) { int current , charWidth , tx; // Handle color codes if ( ! _FNT_HandleColor( &ptr , cmode , color , &expectColor , &colorChanged , curColor ) ) { continue; } // Found EOL current = ( *ptr & 0x7f ); ptr ++; if ( current == '\n' ) { break; } current -= ' '; if ( current < 0 || current >= TTF_CHARACTERS ) { continue; } // Other character; draw it and update width charWidth = font->widths[ current ]; tx = 0; if ( previous != -1 ) { tx = font->kerning[ previous ][ current ]; charWidth += tx; tx += font->widths[ previous ]; } if ( *width && cWidth + charWidth > *width ) { break; } if ( colorChanged ) { qglColor4fv( *curColor ); colorChanged = false; } if ( tx ) { txTotal += tx; qglTranslatef( tx , 0 , 0 ); } qglCallList( font->list_id + current ); cWidth += charWidth; previous = current; } *read = ptr - text; *width = cWidth; } /* * Internal function for bounded printing when alignment is left. * Assumes the GL environment is ready. */ static void _TTF_BoundedPrintLeft( _TTF_font_t font , const char * text , unsigned int cmode , FNT_window_t box , const float * color ) { const char * ptr = text; unsigned int cHeight = 0; unsigned int maxWidth = 0; qglTranslatef( box->x , box->y , 0 ); while ( *ptr && ( box->height == 0 || cHeight + font->height < box->height ) ) { const float * curColor = color; unsigned int lineWidth = box->width; int read; // Print current line qglPushMatrix( ); qglTranslatef( 0 , (float) cHeight , 0 ); _TTF_PrintUntilEOL( font , ptr , cmode , color , &lineWidth , &read , &curColor ); qglPopMatrix( ); // Update height and maximal width cHeight += font->height; if ( lineWidth > maxWidth ) { maxWidth = lineWidth; } // Find end of line ptr += read - 1; while ( *ptr ) { char c = *ptr; ptr ++; if ( c == '\n' ) { break; } } } box->width = maxWidth; box->height = cHeight; } /* * Draw a set of characters from a render information array. */ static void _TTF_DrawFromInfo( const _TTF_font_t font , const struct _FNT_render_info_s * start , unsigned int length , int lineWidth , int boxX , unsigned int boxW , unsigned int y , unsigned int align , unsigned int indent ) { const float * curColor = NULL; int x = 0; int cx; // Do not draw stuff outside of the screen if ( y + font->height < 0 || y >= viddef.height ) { return; } // Determine starting location switch ( align ) { case FNT_ALIGN_LEFT: x = boxX + indent; break; case FNT_ALIGN_RIGHT: x = boxX + boxW - indent - lineWidth; break; case FNT_ALIGN_CENTER: x = boxX + ( boxW - lineWidth ) / 2; break; } // Do not draw stuff outside of the screen, again if ( x + lineWidth < 0 || x >= viddef.width ) { return; } // Display each character qglPushMatrix( ); cx = 0; while ( length ) { if ( !y ) { x += start->kerning; } qglTranslatef( (float) x , (float) y , 0 ); cx += x; if ( cx >= viddef.width ) { break; } if ( cx + start->width > 0 ) { if ( curColor != start->color ) { qglColor4fv( curColor = start->color ); } qglCallList( font->list_id + start->toDraw ); } x = start->width; y = 0; length --; start ++; } qglPopMatrix( ); } /* * Internal function for bounded printing. * Assumes the GL environment is ready. */ static void _TTF_BoundedPrintInternal( _TTF_font_t font , const char * text , unsigned int cmode , unsigned int align , FNT_window_t box , const float * color ) { qboolean mustQuit = false; const char * ptr = text; unsigned int cHeight = 0; unsigned int nHeight = 0; unsigned int maxWidth = 0; _FNT_render_info_t renderInfo; renderInfo = Z_Malloc( strlen( text ) * sizeof( struct _FNT_render_info_s ) ); while ( ! mustQuit && ( box->height == 0 || cHeight + font->height < box->height ) ) { unsigned int riLength , riIndex; int lWidth , sWidth , eWidth; int sIndex , eIndex; mustQuit = ! _FNT_NextWrappedUnit( &ptr , renderInfo , &riLength , cmode , color ); _TTF_FixWrappedUnit( font , renderInfo , &riLength ); // Skip empty lines if ( riLength == 0 ) { nHeight += font->height; continue; } cHeight += nHeight; nHeight = 0; // Compute total width lWidth = 0; for ( riIndex = 0 ; riIndex < riLength ; riIndex ++ ) { lWidth += renderInfo[ riIndex ].width + renderInfo[ riIndex ].kerning; } // Compute string widths between which characters should be printed if ( lWidth <= box->width ) { sWidth = 0; eWidth = lWidth; sIndex = 0; eIndex = riLength - 1; } else { sWidth = lWidth - box->width; if ( align == FNT_ALIGN_CENTER ) { sWidth /= 2; } eWidth = sWidth + box->width; // Now we need to find the actual width of whatever it is we're going to print lWidth = 0; sIndex = eIndex = -1; for ( riIndex = 0 ; riIndex < riLength ; riIndex ++ ) { int nWidth = renderInfo[ riIndex ].width + renderInfo[ riIndex ].kerning; if ( lWidth >= sWidth && sIndex == -1 ) { sIndex = riIndex; sWidth = lWidth; } if ( lWidth + nWidth > eWidth && eIndex == -1 ) { eIndex = riIndex; eWidth = lWidth; break; } lWidth += nWidth; } if ( sIndex == -1 ) { continue; } if ( eIndex == -1 ) { eIndex = riLength - 1; eWidth = lWidth; } } lWidth = eWidth - sWidth; if ( lWidth > maxWidth ) { maxWidth = lWidth; } _TTF_DrawFromInfo( font , renderInfo + sIndex , 1 + eIndex - sIndex , lWidth , box->x , box->width , box->y + cHeight , align , 0 ); cHeight += font->height; } box->width = maxWidth; box->height = cHeight; Z_Free( renderInfo ); } /* * Draws a line of text from a render information array while performing wrapping. */ static void _TTF_WrapFromInfo( const _TTF_font_t font , const _FNT_render_info_t renderInfo , unsigned int length , unsigned int align , unsigned int indent , const FNT_window_t box , unsigned int * curHeight , unsigned int * maxWidth ) { unsigned int curIndex = 0; qboolean lineStarted = false; unsigned int nLines = 0; unsigned int mlWidth = box->width; int lWidth; int wWidth; unsigned int lsIndex; unsigned int wsIndex; while ( curIndex < length ) { const struct _FNT_render_info_s * current; int cWidth; current = &( renderInfo[ curIndex ++ ] ); // Handle start of lines if ( ! lineStarted ) { lineStarted = true; lWidth = wWidth = 0; wsIndex = lsIndex = curIndex - 1; nLines ++; if ( nLines == 2 ) { mlWidth -= indent; } if ( current->toDraw == 0 ) { wsIndex ++; continue; } } // Compute character width cWidth = current->width; if ( lWidth != 0 ) { cWidth += current->kerning; } if ( lWidth + cWidth > mlWidth ) { // We need to draw if ( lWidth == wWidth ) { // That word fills the whole line _TTF_DrawFromInfo( font , renderInfo + lsIndex , curIndex - ( 1 + lsIndex ) , lWidth , box->x , box->width , box->y + *curHeight , align , ( nLines == 1 ) ? 0 : indent ); curIndex --; } else { // Draw from line start to word start lWidth -= wWidth; _TTF_DrawFromInfo( font , renderInfo + lsIndex , wsIndex - lsIndex , lWidth , box->x , box->width , box->y + *curHeight , align , ( nLines == 1 ) ? 0 : indent ); curIndex = wsIndex; } if ( lWidth > *maxWidth ) { *maxWidth = lWidth; } *curHeight += font->height; lineStarted = false; } else { // Not drawing yet lWidth += cWidth; if ( current->toDraw == 0 ) { wsIndex = curIndex; wWidth = 0; } else { wWidth += cWidth; } } } // Draw rest of the line if required if ( lineStarted && lWidth ) { _TTF_DrawFromInfo( font , renderInfo + lsIndex , curIndex - lsIndex , lWidth , box->x , box->width , box->y + *curHeight , align , ( nLines == 1 ) ? 0 : indent ); *curHeight += font->height; if ( lWidth > *maxWidth ) { *maxWidth = lWidth; } } } /* * Wrapped printing implementation ; assumes OpenGL settings are in place. */ static void _TTF_WrappedPrintInternal( const _TTF_font_t font , const char * text , unsigned int cmode , unsigned int align , unsigned int indent , FNT_window_t box , const float * color ) { qboolean mustQuit = false; const char * curText = text; unsigned int curHeight = 0; unsigned int nextHeight = 0; unsigned int maxWidth = 0; _FNT_render_info_t renderInfo; renderInfo = Z_Malloc( strlen( text ) * sizeof( struct _FNT_render_info_s ) ); assert( box->width > indent ); while ( !mustQuit && ( box->height == 0 || curHeight + font->height < box->height ) ) { unsigned int riLength; mustQuit = ! _FNT_NextWrappedUnit( &curText , renderInfo , &riLength , cmode , color ); _TTF_FixWrappedUnit( font , renderInfo , &riLength ); // Skip empty lines if ( riLength == 0 ) { nextHeight += font->height; continue; } // Print line curHeight += nextHeight; nextHeight = 0; _TTF_WrapFromInfo( font , renderInfo , riLength , align , indent , box , &curHeight , &maxWidth ); } // Update box box->height = curHeight; box->width = maxWidth; Z_Free( renderInfo ); } /***************************************************************************** * PRINTING FUNCTIONS AVAILABLE THROUGH FRONT-END * *****************************************************************************/ /* * Raw printing function for external use */ static void _TTF_RawPrint( FNT_font_t font , const char * text , unsigned int text_length , qboolean r2l , float x , float y , const float color[4] ) { _TTF_font_t fInternal = (_TTF_font_t) font->internal; if ( ! _TTF_CheckFlags( font ) ) return; _TTF_PrepareToDraw( fInternal->texture ); qglColor4fv( color ); _TTF_RawPrintInternal( fInternal , text , text_length , r2l , x , y ); _TTF_RestoreEnvironment( ); } /* * Bounded printing function */ static void _TTF_BoundedPrint( FNT_font_t font , const char * text , unsigned int cmode , unsigned int align , FNT_window_t box , const float * color ) { _TTF_font_t fInternal = (_TTF_font_t) font->internal; if ( ! _TTF_CheckFlags( font ) ) return; _TTF_PrepareToDraw( fInternal->texture ); if ( align == FNT_ALIGN_LEFT || box->width == 0 ) { _TTF_BoundedPrintLeft( fInternal , text , cmode , box , color ); } else { _TTF_BoundedPrintInternal( fInternal , text , cmode , align , box , color ); } _TTF_RestoreEnvironment( ); } /* * Wrapped printing function */ static void _TTF_WrappedPrint( FNT_font_t font , const char * text , unsigned int cmode , unsigned int align , unsigned int indent , FNT_window_t box , const float * color ) { _TTF_font_t fInternal = (_TTF_font_t) font->internal; assert( box->width > 0 ); if ( ! _TTF_CheckFlags( font ) ) return; _TTF_PrepareToDraw( fInternal->texture ); _TTF_WrappedPrintInternal( fInternal , text , cmode , align , indent , box , color ); _TTF_RestoreEnvironment( ); } /* * Size prediction function */ static int _TTF_PredictSize( FNT_font_t font , const char * text, qboolean color ) { _TTF_font_t fInternal; float tx; int ret; unsigned int previous; const unsigned char * ptr; fInternal = (_TTF_font_t) font->internal; ptr = ( const unsigned char *) text; if (*ptr == '\0') return 0; if (*ptr == '^' && color) ptr += 2; previous = ( *ptr & 0x7F ) - ' '; tx = fInternal->widths[ previous ]; while ( *(++ptr) ) { unsigned int i = ( *ptr & 0x7F ) - ' '; if (*ptr == '^' && color) { ptr++; continue; } if ( i < TTF_CHARACTERS ) { tx += fInternal->kerning[ previous ][ i ] + fInternal->widths[ i ]; previous = i; } } // always round up the pixel count ret = (int)tx; if (ret < tx) ret++; return ret; } alien-arena-7.66+dfsg/source/ref_gl/r_local.h0000600000175000017500000006054212161402007020141 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #if defined WIN32_VARIANT # include #endif #include #include #include #include "glext.h" #ifndef GL_COLOR_INDEX8_EXT #define GL_COLOR_INDEX8_EXT GL_COLOR_INDEX #endif #include "client/ref.h" #include "client/vid.h" #include "qgl.h" #include "r_math.h" #if !defined min #define min(a,b) (((a)<(b)) ? (a) : (b)) #endif // up / down #define PITCH 0 // left / right #define YAW 1 // fall over #define ROLL 2 #define DLIGHT_CUTOFF 64 extern viddef_t vid; #include "r_image.h" //=================================================================== typedef enum { rserr_ok, rserr_invalid_fullscreen, rserr_invalid_mode, rserr_unknown } rserr_t; #include "r_model.h" extern float r_frametime; void GL_BeginRendering (int *x, int *y, int *width, int *height); void GL_EndRendering (void); void GL_SetDefaultState( void ); void GL_UpdateSwapInterval( void ); extern float gldepthmin, gldepthmax; #define MAX_LBM_HEIGHT 1024 #define BACKFACE_EPSILON 0.01 extern entity_t *currententity; extern model_t *currentmodel; extern int r_visframecount; extern int r_framecount; extern int r_shadowmapcount; extern cplane_t frustum[4]; extern int c_brush_polys, c_alias_polys; extern int c_flares; extern int c_grasses; extern int c_beams; extern int gl_filter_min, gl_filter_max; // // screen size info // extern refdef_t r_newrefdef; extern int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2; mleaf_t *r_viewleaf, *r_viewleaf2; extern cvar_t *r_norefresh; extern cvar_t *r_lefthand; extern cvar_t *r_drawentities; extern cvar_t *r_drawworld; extern cvar_t *r_fullbright; extern cvar_t *r_novis; extern cvar_t *r_nocull; extern cvar_t *r_lerpmodels; extern cvar_t *r_lightlevel; // FIXME: This is a HACK to get the client's light level extern cvar_t *r_wave; //water waves extern cvar_t *gl_ext_swapinterval; extern cvar_t *gl_ext_pointparameters; extern cvar_t *gl_ext_compiled_vertex_array; extern cvar_t *gl_particle_min_size; extern cvar_t *gl_particle_max_size; extern cvar_t *gl_particle_size; extern cvar_t *gl_particle_att_a; extern cvar_t *gl_particle_att_b; extern cvar_t *gl_particle_att_c; extern cvar_t *gl_bitdepth; extern cvar_t *gl_mode; extern cvar_t *gl_log; extern cvar_t *gl_lightmap; extern cvar_t *gl_dynamic; extern cvar_t *gl_nobind; extern cvar_t *gl_picmip; extern cvar_t *gl_skymip; extern cvar_t *gl_showtris; extern cvar_t *gl_showpolys; extern cvar_t *gl_finish; extern cvar_t *gl_clear; extern cvar_t *gl_cull; extern cvar_t *gl_poly; extern cvar_t *gl_polyblend; extern cvar_t *gl_modulate; extern cvar_t *gl_drawbuffer; extern cvar_t *gl_driver; extern cvar_t *gl_swapinterval; extern cvar_t *gl_texturemode; extern cvar_t *gl_texturealphamode; extern cvar_t *gl_texturesolidmode; extern cvar_t *gl_lockpvs; extern cvar_t *gl_vlights; extern cvar_t *gl_usevbo; extern cvar_t *vid_fullscreen; extern cvar_t *vid_gamma; extern cvar_t *vid_contrast; extern cvar_t *r_anisotropic; extern cvar_t *r_alphamasked_anisotropic; extern cvar_t *r_ext_max_anisotropy; extern cvar_t *r_overbrightbits; extern cvar_t *gl_normalmaps; extern cvar_t *gl_bspnormalmaps; extern cvar_t *gl_shadowmaps; extern cvar_t *gl_fog; extern cvar_t *r_shaders; extern cvar_t *r_bloom; extern cvar_t *r_lensflare; extern cvar_t *r_lensflare_intens; extern cvar_t *r_drawsun; extern cvar_t *r_godrays; extern cvar_t *r_godray_intensity; extern cvar_t *r_optimize; extern cvar_t *r_lightmapfiles; extern cvar_t *r_ragdolls; extern cvar_t *r_ragdoll_debug; extern qboolean map_fog; #if defined WIN32_VARIANT extern char map_music[MAX_PATH]; #else extern char map_music[MAX_OSPATH]; #endif extern unsigned r_weather; extern unsigned r_nosun; extern float r_sunX; extern float r_sunY; extern float r_sunZ; extern cvar_t *r_minimap; extern cvar_t *r_minimap_size; extern cvar_t *r_minimap_zoom; extern cvar_t *r_minimap_style; extern cvar_t *gl_mirror; extern cvar_t *gl_arb_fragment_program; extern cvar_t *gl_glsl_shaders; extern cvar_t *sys_affinity; extern cvar_t *sys_priority; extern cvar_t *gl_screenshot_type; extern cvar_t *gl_screenshot_jpeg_quality; extern cvar_t *r_test; extern int gl_lightmap_format; extern int gl_solid_format; extern int gl_alpha_format; extern int gl_tex_solid_format; extern int gl_tex_alpha_format; extern int c_visible_lightmaps; extern int c_visible_textures; extern float r_world_matrix[16]; extern float r_project_matrix[16]; extern int r_viewport[4]; extern float r_farclip, r_farclip_min, r_farclip_bias; extern int r_origin_leafnum; //Image void R_InitImageSubsystem(void); void GL_Bind (int texnum); void GL_MBind( GLenum target, int texnum ); void GL_TexEnv( GLenum value ); void GL_EnableMultitexture( qboolean enable ); void GL_SelectTexture( GLenum ); void RefreshFont (void); extern void vectoangles (vec3_t value1, vec3_t angles); // dynamic lights void R_StaticLightPoint (vec3_t p, vec3_t color); void R_DynamicLightPoint (vec3_t p, vec3_t color); void R_LightPoint (vec3_t p, vec3_t color, qboolean addDynamic); void R_PushDlights (void); void R_PushDlightsForBModel (entity_t *e); void SetVertexOverbrights (qboolean toggle); //==================================================================== extern model_t *r_worldmodel; extern unsigned d_8to24table[256]; extern int registration_sequence; extern void V_AddBlend (float r, float g, float b, float a, float *v_blend); //Renderer main loop extern int R_Init( void *hinstance, void *hWnd ); extern void R_Shutdown( void ); extern void R_SetupViewport (void); extern void R_RenderView (refdef_t *fd); extern void GL_ScreenShot_f (void); extern void R_DrawAliasModel (void); extern void R_DrawBrushModel (void); extern void R_DrawWorldSurfs (void); extern void R_RenderDlights (void); extern void R_DrawAlphaSurfaces (void); extern void R_InitParticleTexture (void); extern void R_DrawParticles (void); extern void R_DrawRadar(void); extern void R_DrawVehicleHUD (void); extern void R_ClearSkyBox (void); extern void R_DrawSkyBox (void); extern void Draw_InitLocal (void); //Renderer utils extern void R_SubdivideSurface (msurface_t *fa, int firstedge, int numedges); extern qboolean R_CullBox (vec3_t mins, vec3_t maxs); extern qboolean R_CullOrigin(vec3_t origin); extern qboolean R_CullSphere( const vec3_t centre, const float radius, const int clipflags ); extern void R_RotateForEntity (entity_t *e); extern void R_MarkWorldSurfs (void); extern void R_AddSkySurface (msurface_t *fa); extern void R_RenderWaterPolys (msurface_t *fa, int texnum, float scaleX, float scaleY); extern void R_ReadFogScript(char config_file[128]); extern void R_ReadMusicScript(char config_file[128]); //Lights extern dlight_t *dynLight; extern vec3_t lightspot; extern void R_MarkLights (dlight_t *light, int bit, mnode_t *node); extern void VLight_Init (void); extern float VLight_GetLightValue ( vec3_t normal, vec3_t dir, float apitch, float ayaw ); //BSP extern GLuint normalisationCubeMap; extern image_t *r_droplets; extern image_t *r_droplets_nm; extern image_t *r_blooddroplets; extern image_t *r_blooddroplets_nm; extern void BSP_DrawTexturelessPoly (msurface_t *fa); extern void BSP_DrawTexturelessBrushModel (entity_t *e); //Postprocess void R_GLSLPostProcess(void); void R_FB_InitTextures(void); //VBO extern qboolean use_vbo; extern GLuint vboId; extern GLuint eboId; extern int totalVBOsize; extern int vboPosition; extern void R_LoadVBOSubsystem(void); extern void R_VCShutdown(void); extern void VB_VCInit(void); extern void VB_BuildVBOBufferSize(msurface_t *surf); extern void VB_BuildWorldVBO(void); void GL_SetupWorldVBO (void); void GL_BindVBO(vertCache_t *cache); void GL_BindIBO(vertCache_t *cache); vertCache_t *R_VCFindCache(vertStoreMode_t store, model_t *mod); vertCache_t *R_VCLoadData(vertCacheMode_t mode, int size, void *buffer, vertStoreMode_t store, model_t *mod); //Light Bloom extern void R_BloomBlend( refdef_t *fd ); extern void R_InitBloomTextures( void ); //Flares and Sun int r_numflares; extern int c_flares; flare_t r_flares[MAX_FLARES]; extern void Mod_AddFlareSurface (msurface_t *surf, int type ); extern void R_RenderFlares (void); extern void R_ClearFlares(void); vec3_t sun_origin; qboolean spacebox; qboolean draw_sun; float sun_x; float sun_y; float sun_size; extern void R_InitSun(); extern void R_RenderSun(); //Vegetation int r_numgrasses; extern int c_grasses; grass_t r_grasses[MAX_GRASSES]; qboolean r_hasleaves; extern void Mod_AddVegetationSurface (msurface_t *surf, int texnum, vec3_t color, float size, char name[MAX_QPATH], int type); extern void R_DrawVegetationSurface (void); extern void R_ClearGrasses(void); extern void R_FinalizeGrass(model_t *mod); //Simple Items extern void R_SI_InitTextures( void ); extern void R_DrawSimpleItems( void ); void R_SetSimpleTexnum (model_t *loadmodel, const char *pathname); //Light beams/volumes int r_numbeams; extern int c_beams; beam_t r_beams[MAX_BEAMS]; extern void Mod_AddBeamSurface (msurface_t *surf, int texnum, vec3_t color, float size, char name[MAX_QPATH], int type, float xang, float yang, qboolean rotating); extern void R_DrawBeamSurface ( void ); extern void R_ClearBeams(void); //Player icons extern float scr_playericonalpha; //Team colors int r_teamColor; qboolean r_gotFlag; qboolean r_lostFlag; extern void Draw_GetPicSize (int *w, int *h, const char *name); extern void Draw_Pic (float x, float y, const char *name); extern void Draw_ScaledPic (float x, float y, float scale, const char *pic); extern void Draw_StretchPic (float x, float y, float w, float h, const char *name); extern void Draw_FadeScreen (void); extern void R_BeginFrame( float camera_separation ); extern void R_SwapBuffers( int ); extern void R_SetPalette ( const unsigned char *palette); extern int Draw_GetPalette (void); image_t *R_RegisterSkin (char *name); image_t *R_RegisterParticlePic(const char *name); image_t *R_RegisterParticleNormal(const char *name); image_t *R_RegisterGfxPic(const char *name); extern void LoadPCX (char *filename, byte **pic, byte **palette, int *width, int *height); extern image_t *GL_FindFreeImage (char *name, int width, int height, imagetype_t type); extern image_t *GL_LoadPic (char *name, byte *pic, int width, int height, imagetype_t type, int bits); extern image_t *GL_GetImage( const char * name ); extern image_t *GL_FindImage (char *name, imagetype_t type); extern void GL_FreeImage( image_t * image ); extern void GL_TextureMode( char *string ); extern void GL_ImageList_f (void); extern void GL_InitImages (void); extern void GL_ShutdownImages (void); extern void GL_FreeUnusedImages (void); extern void GL_TextureAlphaMode( char *string ); extern void GL_TextureSolidMode( char *string ); /* ** GL config stuff */ #define GL_RENDERER_VOODOO 0x00000001 #define GL_RENDERER_VOODOO2 0x00000002 #define GL_RENDERER_VOODOO_RUSH 0x00000004 #define GL_RENDERER_BANSHEE 0x00000008 #define GL_RENDERER_3DFX 0x0000000F #define GL_RENDERER_PCX1 0x00000010 #define GL_RENDERER_PCX2 0x00000020 #define GL_RENDERER_PMX 0x00000040 #define GL_RENDERER_POWERVR 0x00000070 #define GL_RENDERER_PERMEDIA2 0x00000100 #define GL_RENDERER_GLINT_MX 0x00000200 #define GL_RENDERER_GLINT_TX 0x00000400 #define GL_RENDERER_3DLABS_MISC 0x00000800 #define GL_RENDERER_3DLABS 0x00000F00 #define GL_RENDERER_REALIZM 0x00001000 #define GL_RENDERER_REALIZM2 0x00002000 #define GL_RENDERER_INTERGRAPH 0x00003000 #define GL_RENDERER_3DPRO 0x00004000 #define GL_RENDERER_REAL3D 0x00008000 #define GL_RENDERER_RIVA128 0x00010000 #define GL_RENDERER_DYPIC 0x00020000 #define GL_RENDERER_V1000 0x00040000 #define GL_RENDERER_V2100 0x00080000 #define GL_RENDERER_V2200 0x00100000 #define GL_RENDERER_RENDITION 0x001C0000 #define GL_RENDERER_O2 0x00100000 #define GL_RENDERER_IMPACT 0x00200000 #define GL_RENDERER_RE 0x00400000 #define GL_RENDERER_IR 0x00800000 #define GL_RENDERER_SGI 0x00F00000 #define GL_RENDERER_MCD 0x01000000 #define GL_RENDERER_OTHER 0x80000000 #define GLSTATE_DISABLE_ALPHATEST if (gl_state.alpha_test) { qglDisable(GL_ALPHA_TEST); gl_state.alpha_test=false; } #define GLSTATE_ENABLE_ALPHATEST if (!gl_state.alpha_test) { qglEnable(GL_ALPHA_TEST); gl_state.alpha_test=true; } #define GLSTATE_DISABLE_BLEND if (gl_state.blend) { qglDisable(GL_BLEND); gl_state.blend=false; } #define GLSTATE_ENABLE_BLEND if (!gl_state.blend) { qglEnable(GL_BLEND); gl_state.blend=true; } #define GLSTATE_DISABLE_TEXGEN if (gl_state.texgen) { qglDisable(GL_TEXTURE_GEN_S); qglDisable(GL_TEXTURE_GEN_T); qglDisable(GL_TEXTURE_GEN_R); gl_state.texgen=false; } #define GLSTATE_ENABLE_TEXGEN if (!gl_state.texgen) { qglEnable(GL_TEXTURE_GEN_S); qglEnable(GL_TEXTURE_GEN_T); qglEnable(GL_TEXTURE_GEN_R); gl_state.texgen=true; } #define GL_COMBINE 0x8570 #define GL_DOT3_RGB 0x86AE typedef struct { int renderer; const char *renderer_string; const char *vendor_string; const char *version_string; const char *extensions_string; qboolean allow_cds; qboolean mtexcombine; } glconfig_t; typedef struct { float inverse_intensity; qboolean fullscreen; int prev_mode; unsigned char *d_16to8table; int lightmap_textures; int currenttextures[3]; int currenttmu; float camera_separation; qboolean stereo_enabled; qboolean alpha_test; qboolean blend; qboolean texgen; qboolean fragment_program; qboolean glsl_shaders; qboolean separateStencil; qboolean stencil_wrap; qboolean vbo; qboolean fbo; qboolean hasFBOblit; qboolean ati; } glstate_t; extern glconfig_t gl_config; extern glstate_t gl_state; // vertex arrays extern int KillFlags; #define MAX_ARRAY (MAX_PARTICLES*4) #define VA_SetElem2(v,a,b) ((v)[0]=(a),(v)[1]=(b)) #define VA_SetElem3(v,a,b,c) ((v)[0]=(a),(v)[1]=(b),(v)[2]=(c)) #define VA_SetElem4(v,a,b,c,d) ((v)[0]=(a),(v)[1]=(b),(v)[2]=(c),(v)[3]=(d)) extern float tex_array[MAX_ARRAY][2]; extern float vert_array[MAX_ARRAY][3]; extern float norm_array[MAX_ARRAY][3]; extern float tan_array[MAX_ARRAY][4]; extern float col_array[MAX_ARRAY][4]; #define MAX_VARRAY_VERTS (MAX_VERTS + 2) #define MAX_VARRAY_VERTEX_SIZE 11 #define MAX_VERTICES 16384 #define MAX_INDICES (MAX_VERTICES * 4) #define MAX_SHADOW_VERTS 16384 extern float VArrayVerts[MAX_VARRAY_VERTS * MAX_VARRAY_VERTEX_SIZE]; extern int VertexSizes[]; extern float *VArray; extern vec3_t ShadowArray[MAX_SHADOW_VERTS]; // define our vertex types #define VERT_SINGLE_TEXTURED 0 // verts and st for 1 tmu #define VERT_BUMPMAPPED 1 // verts and st for 1 tmu, but with 2 texcoord pointers #define VERT_MULTI_TEXTURED 2 // verts and st for 2 tmus #define VERT_COLOURED_UNTEXTURED 3 // verts and colour #define VERT_COLOURED_TEXTURED 4 // verts, st for 1 tmu and colour #define VERT_COLOURED_MULTI_TEXTURED 5 // verts, st for 2 tmus and colour #define VERT_DUAL_TEXTURED 6 // verts, st for 2 tmus both with same st #define VERT_NO_TEXTURE 7 // verts only, no textures #define VERT_BUMPMAPPED_COLOURED 8 // verts and st for 1 tmu, 2 texoord pointers and colour #define VERT_NORMAL_COLOURED_TEXTURED 9 // verts and st for 1tmu and color, with normals // looks like these should be bit flags (2010-08) // apparently not - this was not working as bit flags, works fine as ints #define KILL_TMU0_POINTER 1 #define KILL_TMU1_POINTER 2 #define KILL_TMU2_POINTER 3 #define KILL_TMU3_POINTER 4 #define KILL_TMU4_POINTER 5 #define KILL_TMU5_POINTER 6 #define KILL_RGBA_POINTER 7 #define KILL_NORMAL_POINTER 8 // vertex array subsystem void R_InitVArrays (int varraytype); void R_KillVArrays (void); void R_DrawVarrays(GLenum mode, GLint first, GLsizei count); void R_InitQuadVarrays(void); void R_AddSurfToVArray (msurface_t *surf); void R_AddShadowSurfToVArray (msurface_t *surf, vec3_t origin); void R_AddTexturedSurfToVArray (msurface_t *surf, float scroll); void R_AddLightMappedSurfToVArray (msurface_t *surf, float scroll); void R_AddGLSLShadedWarpSurfToVArray (msurface_t *surf, float scroll); void R_KillNormalTMUs(void); //shadows extern void R_InitShadowSubsystem(void); extern void R_CastShadow(void); extern cvar_t *r_shadowmapscale; extern int r_lightgroups; extern image_t *r_depthtexture; extern image_t *r_depthtexture2; extern image_t *r_colorbuffer; extern GLuint fboId[3]; extern GLuint rboId; extern vec3_t r_worldLightVec; typedef struct LightGroup { vec3_t group_origin; vec3_t accum_origin; float avg_intensity; float dist; } LightGroup_t; extern LightGroup_t LightGroups[MAX_LIGHTS]; extern void R_CheckFBOExtensions (void); extern void R_GenerateShadowFBO(void); extern void MD2_DrawCaster (void); extern void IQM_DrawCaster (void); extern void IQM_DrawRagDollCaster (int); extern void R_DrawDynamicCaster(void); extern void R_DrawVegetationCaster(void); extern void R_DrawEntityCaster(entity_t *ent); extern void R_GenerateEntityShadow( void ); extern void R_GenerateRagdollShadow( int RagDollID ); extern void BSP_DrawShadowPoly (msurface_t *fa, vec3_t origin); extern void R_DrawShadowMapWorld(qboolean forEnt, vec3_t origin); int FB_texture_width, FB_texture_height; float fadeShadow; cvar_t *r_shadowcutoff; //shader programs extern void R_LoadARBPrograms(void); extern void R_LoadGLSLPrograms(void); //arb fragment extern unsigned int g_water_program_id; //glsl extern GLhandleARB g_programObj; extern GLhandleARB g_shadowprogramObj; extern GLhandleARB g_waterprogramObj; extern GLhandleARB g_meshprogramObj; extern GLhandleARB g_glassprogramObj; extern GLhandleARB g_blankmeshprogramObj; extern GLhandleARB g_fbprogramObj; extern GLhandleARB g_blurprogramObj; extern GLhandleARB g_rblurprogramObj; extern GLhandleARB g_dropletsprogramObj; extern GLhandleARB g_godraysprogramObj; extern GLhandleARB g_vertexShader; extern GLhandleARB g_fragmentShader; //standard bsp surfaces extern GLuint g_location_surfTexture; extern GLuint g_location_eyePos; extern GLuint g_tangentSpaceTransform; extern GLuint g_location_heightTexture; extern GLuint g_location_lmTexture; extern GLuint g_location_normalTexture; extern GLuint g_location_bspShadowmapTexture; extern GLuint g_location_bspShadowmapTexture2; extern GLuint g_location_bspShadowmapNum; extern GLuint g_location_fog; extern GLuint g_location_parallax; extern GLuint g_location_dynamic; extern GLuint g_location_shadowmap; extern GLuint g_Location_statshadow; extern GLuint g_location_xOffs; extern GLuint g_location_yOffs; extern GLuint g_location_lightPosition; extern GLuint g_location_staticLightPosition; extern GLuint g_location_lightColour; extern GLuint g_location_lightCutoffSquared; extern GLuint g_location_liquid; extern GLuint g_location_shiny; extern GLuint g_location_rsTime; extern GLuint g_location_liquidTexture; extern GLuint g_location_liquidNormTex; extern GLuint g_location_chromeTex; //shadows on white bsp surface extern GLuint g_location_entShadow; extern GLuint g_location_fadeShadow; extern GLuint g_location_xOffset; extern GLuint g_location_yOffset; //water extern GLuint g_location_baseTexture; extern GLuint g_location_normTexture; extern GLuint g_location_refTexture; extern GLuint g_location_waterEyePos; extern GLuint g_location_tangentSpaceTransform; extern GLuint g_location_time; extern GLuint g_location_lightPos; extern GLuint g_location_reflect; extern GLuint g_location_trans; extern GLuint g_location_fogamount; //mesh extern GLuint g_location_meshlightPosition; extern GLuint g_location_baseTex; extern GLuint g_location_normTex; extern GLuint g_location_fxTex; extern GLuint g_location_fx2Tex; extern GLuint g_location_color; extern GLuint g_location_meshNormal; extern GLuint g_location_meshTime; extern GLuint g_location_meshFog; extern GLuint g_location_useFX; extern GLuint g_location_useGlow; extern GLuint g_location_useShell; extern GLuint g_location_useCube; extern GLuint g_location_useGPUanim; extern GLuint g_location_outframe; extern GLuint g_location_fromView; //glass extern GLuint g_location_gmirTexture; extern GLuint g_location_grefTexture; extern GLuint g_location_gLightPos; extern GLuint g_location_gFog; extern GLuint g_location_gOutframe; //blank mesh extern GLuint g_location_bmOutframe; //fullscreen distortion effects extern GLuint g_location_framebuffTex; extern GLuint g_location_distortTex; extern GLuint g_location_dParams; extern GLuint g_location_fxPos; //gaussian blur extern GLuint g_location_scale; extern GLuint g_location_source; //radial blur extern GLuint g_location_rscale; extern GLuint g_location_rsource; extern GLuint g_location_rparams; //water droplets extern GLuint g_location_drSource; extern GLuint g_location_drTex; extern GLuint g_location_drTime; extern GLuint g_location_drParams; //god rays extern GLuint g_location_lightPositionOnScreen; extern GLuint g_location_sunTex; extern GLuint g_location_godrayScreenAspect; extern GLuint g_location_sunRadius; //MD2 extern void Mod_LoadMD2Model (model_t *mod, void *buffer); //Shared mesh items extern vec3_t shadelight; extern vec3_t shadevector; extern int model_dlights_num; extern m_dlight_t model_dlights[128]; extern image_t *r_mirrortexture; extern cvar_t *cl_gun; vec3_t lightPosition; vec3_t statLightPosition; float statLightIntensity; float dynFactor; extern void R_GetLightVals(vec3_t origin, qboolean RagDoll); extern void R_ModelViewTransform(const vec3_t in, vec3_t out); extern void GL_BlendFunction (GLenum sfactor, GLenum dfactor); //iqm #define pi 3.14159265 extern float modelpitch; extern double degreeToRadian(double degree); extern qboolean Mod_INTERQUAKEMODEL_Load(model_t *mod, void *buffer); extern qboolean IQM_ReadSkinFile(char skin_file[MAX_OSPATH], char *skinpath); extern void R_DrawINTERQUAKEMODEL(void); extern void IQM_AnimateFrame(float curframe, int nextframe); extern qboolean IQM_InAnimGroup(int frame, int oldframe); extern int IQM_NextFrame(int frame); extern void IQM_AnimateRagdoll(int RagDollID, int shellEffect); extern void IQM_DrawFrame(int skinnum, qboolean ragdoll, float shellAlpha); extern void IQM_DrawShadow(vec3_t origin); //Ragdoll int r_DrawingRagDoll; int r_SurfaceCount; #define TURBSCALE2 (256.0 / (2 * M_PI)) // reduce runtime calcs #define TURBSCALE 40.743665431525205956834243423364 extern float r_turbsin[]; /* ==================================================================== IMPLEMENTATION SPECIFIC FUNCTIONS ==================================================================== */ extern void GLimp_BeginFrame( float camera_separation ); extern void GLimp_EndFrame( void ); extern qboolean GLimp_Init( void *hinstance, void *hWnd ); extern void GLimp_Shutdown( void ); extern rserr_t GLimp_SetMode( unsigned *pwidth, unsigned *pheight, int mode, qboolean fullscreen ); extern void GLimp_AppActivate( qboolean active ); extern void GLimp_EnableLogging( qboolean enable ); extern void GLimp_LogNewFrame( void ); /* ==================================================================== IMPORTED FUNCTIONS ==================================================================== */ #include "r_script.h" alien-arena-7.66+dfsg/source/ref_gl/r_light.c0000600000175000017500000003223412161402007020146 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // r_light.c #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "r_local.h" int r_dlightframecount; /* ============================================================================= DYNAMIC LIGHTS ============================================================================= */ /* ============= R_MarkLights ============= */ static int num_dlight_surfaces, old_dlightframecount; static qboolean new_dlight; void R_MarkLights (dlight_t *light, int bit, mnode_t *node) { cplane_t *splitplane; float dist; msurface_t *surf; int i, sidebit; if (node->contents != -1) return; splitplane = node->plane; dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist; if (dist > light->intensity-DLIGHT_CUTOFF) { R_MarkLights (light, bit, node->children[0]); return; } if (dist < -light->intensity+DLIGHT_CUTOFF) { R_MarkLights (light, bit, node->children[1]); return; } // mark the polygons surf = r_worldmodel->surfaces + node->firstsurface; for (i=0 ; inumsurfaces ; i++, surf++) { dist = DotProduct (light->origin, surf->plane->normal) - surf->plane->dist; //Discoloda if (dist >= 0) //Discoloda sidebit = 0; //Discoloda else //Discoloda sidebit = ISURF_PLANEBACK; //Discoloda if ( (surf->iflags & ISURF_PLANEBACK) != sidebit ) //Discoloda continue; //Discoloda if (surf->dlightframe != r_dlightframecount) { if (surf->dlightframe != old_dlightframecount) new_dlight = true; num_dlight_surfaces++; surf->dlightbits = bit; surf->dlightframe = r_dlightframecount; } else surf->dlightbits |= bit; } R_MarkLights (light, bit, node->children[0]); R_MarkLights (light, bit, node->children[1]); } /* ============= R_PushDlights ============= */ void R_PushDlights (void) { int i; dlight_t *l; old_dlightframecount = r_dlightframecount; new_dlight = false; num_dlight_surfaces = 0; r_dlightframecount = r_framecount + 1; // because the count hasn't // advanced yet for this frame l = r_newrefdef.dlights; for (i=0 ; inodes ); r_newrefdef.dlights_changed = false; if (num_dlight_surfaces != r_newrefdef.num_dlight_surfaces || new_dlight) r_newrefdef.dlights_changed = true; r_newrefdef.num_dlight_surfaces = num_dlight_surfaces; } /* ============= R_PushDlightsForBModel ============= */ void R_PushDlightsForBModel (entity_t *e) { int k; dlight_t *lt; lt = r_newrefdef.dlights; if (e->angles[0] || e->angles[1] || e->angles[2]) { vec3_t temp; vec3_t forward, right, up; AngleVectors (e->angles, forward, right, up); for (k=0 ; korigin, e->origin, temp); lt->origin[0] = DotProduct (temp, forward); lt->origin[1] = -DotProduct (temp, right); lt->origin[2] = DotProduct (temp, up); R_MarkLights (lt, 1<model->nodes + e->model->firstnode); VectorAdd (temp, e->origin, lt->origin); } } else { for (k=0 ; korigin, e->origin, lt->origin); R_MarkLights (lt, 1<model->nodes + e->model->firstnode); VectorAdd (lt->origin, e->origin, lt->origin); } } } /* ============================================================================= LIGHT SAMPLING ============================================================================= */ vec3_t pointcolor; cplane_t *lightplane; // used as shadow plane vec3_t lightspot; int RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end) { float front, back, frac; int side; cplane_t *plane; vec3_t mid; msurface_t *surf; int s, t, ds, dt; int i; mtexinfo_t *tex; byte *lightmap; int maps; int r; vec3_t scale; if (node->contents != -1) return -1; // didn't hit anything // calculate mid point // FIXME: optimize for axial plane = node->plane; front = DotProduct (start, plane->normal) - plane->dist; back = DotProduct (end, plane->normal) - plane->dist; side = front < 0; if ( (back < 0) == side) return RecursiveLightPoint (node->children[side], start, end); frac = front / (front-back); mid[0] = start[0] + (end[0] - start[0])*frac; mid[1] = start[1] + (end[1] - start[1])*frac; mid[2] = start[2] + (end[2] - start[2])*frac; // go down front side r = RecursiveLightPoint (node->children[side], start, mid); if (r >= 0) return r; // hit something if ( (back < 0) == side ) return -1; // didn't hit anuthing // check for impact on this node VectorCopy (mid, lightspot); lightplane = plane; surf = r_worldmodel->surfaces + node->firstsurface; for (i=0 ; inumsurfaces ; i++, surf++) { tex = surf->texinfo; if (tex->flags & (SURF_WARP|SURF_SKY)) continue; // no lightmaps s = DotProduct (mid, tex->vecs[0]) + tex->vecs[0][3]; if (s < surf->texturemins[0]) continue; ds = s - surf->texturemins[0]; if (ds > surf->extents[0]) continue; t = DotProduct (mid, tex->vecs[1]) + tex->vecs[1][3]; if (t < surf->texturemins[1]) continue; dt = t - surf->texturemins[1]; if (dt > surf->extents[1]) continue; lightmap = surf->samples; if (!surf->samples) return 0; ds >>= 4; dt >>= 4; VectorClear (pointcolor); lightmap += 3*(dt * ((surf->extents[0]>>4)+1) + ds); for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ; maps++) { for (i=0 ; i<3 ; i++) scale[i] = gl_modulate->value*r_newrefdef.lightstyles[surf->styles[maps]].rgb[i]; pointcolor[0] += lightmap[0] * scale[0] * (1.0/255); pointcolor[1] += lightmap[1] * scale[1] * (1.0/255); pointcolor[2] += lightmap[2] * scale[2] * (1.0/255); lightmap += 3*((surf->extents[0]>>4)+1) * ((surf->extents[1]>>4)+1); } return 1; } // go down back side return RecursiveLightPoint (node->children[!side], mid, end); } /* =============== R_LightPoint =============== */ void R_StaticLightPoint (vec3_t p, vec3_t color) { float r; vec3_t end; if (!r_worldmodel->lightdata) { color[0] = color[1] = color[2] = 1.0; return; } end[0] = p[0]; end[1] = p[1]; end[2] = p[2] - 2048; r = RecursiveLightPoint (r_worldmodel->nodes, p, end); if (r == -1) { VectorCopy (vec3_origin, color); } else { VectorCopy (pointcolor, color); } } void R_DynamicLightPoint (vec3_t p, vec3_t color) { int lnum; dlight_t *dl; float light; vec3_t dist, dlightcolor; float add; // // add dynamic lights // light = 0; dl = r_newrefdef.dlights; VectorClear ( dlightcolor ); for (lnum=0 ; lnumorigin, dist); add = dl->intensity - VectorLength(dist); if (add > 0) { add *= (1.0/256); VectorMA (dlightcolor, add, dl->color, dlightcolor); } } VectorScale (dlightcolor, gl_modulate->value, color); } void R_LightPoint (vec3_t p, vec3_t color, qboolean addDynamic) { vec3_t dynamic; R_StaticLightPoint (p, color); if (addDynamic) { R_DynamicLightPoint (p, dynamic); VectorAdd (color, dynamic, color); } } //=================================================================== static float s_blocklights[1024*1024*3]; /* ** R_SetCacheState */ void R_SetCacheState( msurface_t *surf ) { int maps; for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ; maps++) { surf->cached_light[maps] = r_newrefdef.lightstyles[surf->styles[maps]].white; } } /* =============== R_BuildLightMap Combine and scale multiple lightmaps into the floating format in blocklights =============== */ void R_BuildLightMap (msurface_t *surf, byte *dest, int smax, int tmax, int stride) { int r, g, b, a, max; int i, j, size; byte *lightmap, *old_dest; float scale[4]; int nummaps; float *bl; lightstyle_t *style; if ( SurfaceHasNoLightmap( surf ) ) Com_Error (ERR_DROP, "R_BuildLightMap called for non-lit surface"); size = smax*tmax; if (size > (sizeof(s_blocklights)>>4) ) Com_Error (ERR_DROP, "Bad s_blocklights size"); // set to full bright if no light data if (!surf->samples) { int maps; for (i=0 ; istyles[maps] != 255 ; maps++) { style = &r_newrefdef.lightstyles[surf->styles[maps]]; } goto store; } // count the # of maps for ( nummaps = 0 ; nummaps < MAXLIGHTMAPS && surf->styles[nummaps] != 255 ; nummaps++) ; lightmap = surf->samples; // add all the lightmaps if ( nummaps == 1 ) { int maps; for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ; maps++) { bl = s_blocklights; for (i=0 ; i<3 ; i++) scale[i] = gl_modulate->value*r_newrefdef.lightstyles[surf->styles[maps]].rgb[i]; if ( scale[0] == 1.0F && scale[1] == 1.0F && scale[2] == 1.0F ) { for (i=0 ; istyles[maps] != 255 ; maps++) { bl = s_blocklights; for (i=0 ; i<3 ; i++) scale[i] = gl_modulate->value*r_newrefdef.lightstyles[surf->styles[maps]].rgb[i]; if ( scale[0] == 1.0F && scale[1] == 1.0F && scale[2] == 1.0F ) { for (i=0 ; i g) max = r; else max = g; if (b > max) max = b; //255 is best for alpha testing, so textures don't "disapear" in the dark a = 255; /* ** rescale all the color components if the intensity of the greatest ** channel exceeds 1.0 ** NOTE: we used to scale alpha here also, but it caused problems. */ if (max > 255) { float t = 255.0F / max; r = r*t; g = g*t; b = b*t; } // GL_BGRA dest[0] = b; dest[1] = g; dest[2] = r; dest[3] = a; bl += 3; dest += 4; } } #define GET_SAMPLE(x,y) (old_dest+((y*smax+x)*4)+y*stride) #define SAMPLEDIST(a,b) sqrt((float)((a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1])+(a[2]-b[2])*(a[2]-b[2]))) } alien-arena-7.66+dfsg/source/ref_gl/r_main.c0000600000175000017500000014017412204310130017757 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // r_main.c #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "r_local.h" #include "r_script.h" #include "r_ragdoll.h" #include "r_text.h" void R_Clear (void); viddef_t vid; int r_viewport[4]; int GL_TEXTURE0, GL_TEXTURE1, GL_TEXTURE2, GL_TEXTURE3, GL_TEXTURE4, GL_TEXTURE5, GL_TEXTURE6, GL_TEXTURE7; model_t *r_worldmodel; float gldepthmin, gldepthmax; float r_frametime; glconfig_t gl_config; glstate_t gl_state; cvar_t *gl_normalmaps; cvar_t *gl_bspnormalmaps; cvar_t *gl_shadowmaps; cvar_t *gl_arb_fragment_program; cvar_t *gl_glsl_shaders; cvar_t *gl_fog; entity_t *currententity; model_t *currentmodel; cplane_t frustum[4]; int r_visframecount; // bumped when going to a new PVS int r_framecount; // used for dlight push checking int r_shadowmapcount; // number of shadowmaps rendered this frame // performance counters for r_speeds reports int last_c_brush_polys, c_brush_polys; int last_c_alias_polys, c_alias_polys; int c_flares; int c_grasses; int c_beams; extern int c_vbo_batches; extern int c_visible_lightmaps; extern int c_visible_textures; float v_blend[4]; // final blending color float r_farclip, r_farclip_min, r_farclip_bias = 256.0f; void GL_Strings_f( void ); // // view origin // vec3_t vup; vec3_t vpn; vec3_t vright; vec3_t r_origin; int r_origin_leafnum; float r_world_matrix[16]; float r_project_matrix[16]; // // screen size info // refdef_t r_newrefdef; int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2; cvar_t *r_norefresh; cvar_t *r_drawentities; cvar_t *r_drawworld; cvar_t *r_fullbright; cvar_t *r_novis; cvar_t *r_nocull; cvar_t *r_lerpmodels; cvar_t *r_lefthand; cvar_t *r_wave; // Water waves cvar_t *r_shadowmapscale; cvar_t *r_overbrightbits; cvar_t *gl_vlights; cvar_t *gl_nosubimage; cvar_t *gl_usevbo; cvar_t *gl_particle_min_size; cvar_t *gl_particle_max_size; cvar_t *gl_particle_size; cvar_t *gl_particle_att_a; cvar_t *gl_particle_att_b; cvar_t *gl_particle_att_c; cvar_t *gl_ext_pointparameters; cvar_t *gl_log; cvar_t *gl_bitdepth; cvar_t *gl_drawbuffer; cvar_t *gl_driver; cvar_t *gl_lightmap; cvar_t *gl_mode; cvar_t *gl_dynamic; cvar_t *gl_modulate; cvar_t *gl_nobind; cvar_t *gl_picmip; cvar_t *gl_skymip; cvar_t *gl_showtris; cvar_t *gl_showpolys; cvar_t *gl_finish; cvar_t *gl_clear; cvar_t *gl_cull; cvar_t *gl_polyblend; cvar_t *gl_swapinterval; cvar_t *gl_texturemode; cvar_t *gl_texturealphamode; cvar_t *gl_texturesolidmode; cvar_t *gl_lockpvs; cvar_t *vid_fullscreen; cvar_t *vid_gamma; cvar_t *vid_contrast; cvar_t *vid_ref; cvar_t *r_anisotropic; cvar_t *r_alphamasked_anisotropic; cvar_t *r_ext_max_anisotropy; cvar_t *r_shaders; cvar_t *r_bloom; cvar_t *r_lensflare; cvar_t *r_lensflare_intens; cvar_t *r_drawsun; cvar_t *r_lightbeam; cvar_t *r_godrays; cvar_t *r_godray_intensity; cvar_t *r_optimize; cvar_t *r_lightmapfiles; qboolean map_fog; cvar_t *con_font; cvar_t *r_minimap_size; cvar_t *r_minimap_zoom; cvar_t *r_minimap_style; cvar_t *r_minimap; cvar_t *sys_affinity; cvar_t *sys_priority; cvar_t *gl_screenshot_type; cvar_t *gl_screenshot_jpeg_quality; //no blood extern cvar_t *cl_noblood; //first time running game cvar_t *r_firstrun; //for testing cvar_t *r_test; //ODE initialization error check int r_odeinit_success; // 0 if dODEInit2() fails, 1 otherwise. //fog script stuff struct r_fog { float red; float green; float blue; float start; float end; float density; } fog; unsigned r_weather; unsigned r_nosun; float r_sunX; float r_sunY; float r_sunZ; /* ================= R_ReadFogScript ================= */ void R_ReadFogScript( char *config_file ) { FILE *fp; int length; char a_string[128]; char *buffer; char *s; size_t result; if((fp = fopen(config_file, "rb" )) == NULL) { return; } length = FS_filelength( fp ); buffer = malloc( length + 1 ); if ( buffer != NULL ) { buffer[length] = 0; result = fread( buffer, length, 1, fp ); if ( result == 1 ) { s = buffer; strcpy( a_string, COM_Parse( &s ) ); fog.red = atof(a_string); strcpy( a_string, COM_Parse( &s ) ); fog.green = atof(a_string); strcpy( a_string, COM_Parse( &s ) ); fog.blue = atof(a_string); strcpy( a_string, COM_Parse( &s ) ); fog.start = atof(a_string); strcpy( a_string, COM_Parse( &s ) ); fog.end = atof(a_string); strcpy( a_string, COM_Parse( &s ) ); fog.density = atof(a_string); strcpy( a_string, COM_Parse( &s ) ); r_weather = atoi(a_string); strcpy( a_string, COM_Parse( &s ) ); r_nosun = atoi(a_string); strcpy( a_string, COM_Parse( &s ) ); r_sunX = atof(a_string); strcpy( a_string, COM_Parse( &s ) ); r_sunY = atof(a_string); strcpy( a_string, COM_Parse( &s ) ); r_sunZ = atof(a_string); if(fog.density > 0) map_fog = true; } else { Com_DPrintf("R_ReadFogScript: read fail: %s\n", config_file); } free( buffer ); } fclose( fp ); if (gl_fog->integer < 1) { map_fog = false; r_weather = false; } return; } /* ================= R_ReadMusicScript ================= */ //to do - read in secondary music location(for CTF music shift) void R_ReadMusicScript( char *config_file ) { FILE *fp; int length; char *buffer; char *s; size_t result; if((fp = fopen(config_file, "rb" )) == NULL) { return; } length = FS_filelength( fp ); buffer = malloc( length + 1 ); if ( buffer != NULL ) { result = fread( buffer, length, 1, fp ); if ( result == 1 ) { buffer[length] = 0; s = buffer; strcpy( map_music, COM_Parse( &s ) ); map_music[length] = 0; //clear any possible garbage } else { Com_DPrintf("R_ReadMusicScript: read fail: %s\n", config_file); } free( buffer ); } fclose( fp ); return; } /* ================= R_CullBox Returns true if the box is completely outside the frustom ================= */ qboolean R_CullBox (vec3_t mins, vec3_t maxs) { int i; cplane_t *p; if (r_nocull->integer) return false; for (i=0,p=frustum ; i<4; i++,p++) { switch (p->signbits) { case 0: if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist) return true; break; case 1: if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist) return true; break; case 2: if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist) return true; break; case 3: if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist) return true; break; case 4: if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist) return true; break; case 5: if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist) return true; break; case 6: if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist) return true; break; case 7: if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist) return true; break; default: return false; } } return false; } /* ================= R_CullOrigin Returns true if the origin is completely outside the frustom ================= */ qboolean R_CullOrigin(vec3_t origin) { int i; for (i = 0; i < 4; i++) if (BOX_ON_PLANE_SIDE(origin, origin, &frustum[i]) == 2) return true; return false; } qboolean R_CullSphere( const vec3_t centre, const float radius, const int clipflags ) { int i; cplane_t *p; if (r_nocull->value) return false; for (i=0,p=frustum ; i<4; i++,p++) { if ( !(clipflags & (1<normal ) - p->dist <= -radius ) return true; } return false; } void R_RotateForEntity (entity_t *e) { qglTranslatef (e->origin[0], e->origin[1], e->origin[2]); qglRotatef (e->angles[1], 0, 0, 1); qglRotatef (-e->angles[0], 0, 1, 0); qglRotatef (-e->angles[2], 1, 0, 0); } /* ============= R_DrawNullModel ============= */ void R_DrawNullModel (void) { vec3_t shadelight; int i; if ( currententity->flags & RF_FULLBRIGHT ) shadelight[0] = shadelight[1] = shadelight[2] = 1.0F; else R_LightPoint (currententity->origin, shadelight, true); qglPushMatrix (); R_RotateForEntity (currententity); qglDisable (GL_TEXTURE_2D); qglColor3fv (shadelight); qglBegin (GL_TRIANGLE_FAN); qglVertex3f (0, 0, -16); for (i=0 ; i<=4 ; i++) qglVertex3f (16*cos(i*M_PI/2), 16*sin(i*M_PI/2), 0); qglEnd (); qglBegin (GL_TRIANGLE_FAN); qglVertex3f (0, 0, 16); for (i=4 ; i>=0 ; i--) qglVertex3f (16*cos(i*M_PI/2), 16*sin(i*M_PI/2), 0); qglEnd (); qglColor3f (1,1,1); qglPopMatrix (); qglEnable (GL_TEXTURE_2D); } #include "r_lodcalc.h" /* ============= R_DrawEntitiesOnList ============= */ extern cvar_t *cl_simpleitems; void R_DrawEntitiesOnList (void) { int i; rscript_t *rs = NULL; vec3_t dist; if (!r_drawentities->integer) return; if ( !r_odeinit_success ) { // ODE init failed, force ragdolls off r_ragdolls = Cvar_ForceSet("r_ragdolls", "0"); } // draw non-transparent first for (i=0 ; iflags & RF_TRANSLUCENT) continue; // transluscent if (currententity->model && r_shaders->integer) { rs=(rscript_t *)currententity->model->script; //custom player skin (must be done here) if (currententity->skin) { rs = currententity->skin->script; if(rs) RS_ReadyScript(rs); } if (rs) currententity->script = rs; else currententity->script = NULL; } currentmodel = currententity->model; if (cl_simpleitems->integer && currentmodel && currentmodel->simple_texnum) continue; //get distance VectorSubtract(r_origin, currententity->origin, dist); //set lod if available if(VectorLength(dist) > LOD_DIST*2.0) { if(currententity->lod2) currentmodel = currententity->lod2; } else if(VectorLength(dist) > LOD_DIST) { if(currententity->lod1) currentmodel = currententity->lod1; } if (!currentmodel) { R_DrawNullModel (); continue; } switch (currentmodel->type) { case mod_alias: R_DrawAliasModel (); break; case mod_brush: R_DrawBrushModel (); break; case mod_iqm: R_DrawINTERQUAKEMODEL (); break; default: Com_Error(ERR_DROP, "Bad modeltype"); break; } } // draw transparent entities // we could sort these if it ever becomes a problem... qglDepthMask (0); // no z writes for (i=0 ; iflags & RF_TRANSLUCENT)) continue; // solid if (currententity->model && r_shaders->integer) { rs=(rscript_t *)currententity->model->script; //custom player skin (must be done here) if (currententity->skin) { rs = currententity->skin->script; if(rs) RS_ReadyScript(rs); } if (rs) currententity->script = rs; else currententity->script = NULL; } currentmodel = currententity->model; fadeShadow = 1.0; if (!currentmodel) { R_DrawNullModel (); continue; } switch (currentmodel->type) { case mod_alias: R_DrawAliasModel (); break; case mod_brush: R_DrawBrushModel (); break; case mod_iqm: R_DrawINTERQUAKEMODEL (); break; default: Com_Error (ERR_DROP, "Bad modeltype"); break; } } qglDepthMask (1); // back to writing } void R_DrawViewEntitiesOnList (void) { int i; rscript_t *rs = NULL; if (!r_drawentities->integer) return; if(r_newrefdef.rdflags & RDF_NOWORLDMODEL) return; // draw non-transparent first for (i=0 ; iflags & RF_TRANSLUCENT) continue; // transluscent if (currententity->model && r_shaders->integer) { rs=(rscript_t *)currententity->model->script; //custom player skin (must be done here) if (currententity->skin) { rs = currententity->skin->script; if(rs) RS_ReadyScript(rs); } if (rs) currententity->script = rs; else currententity->script = NULL; } currentmodel = currententity->model; if (!currentmodel) { R_DrawNullModel (); continue; } switch (currentmodel->type) { case mod_alias: R_DrawAliasModel (); break; case mod_iqm: R_DrawINTERQUAKEMODEL (); break; default: Com_Error(ERR_DROP, "Bad modeltype"); break; } } // draw transparent entities // we could sort these if it ever becomes a problem... qglDepthMask (0); // no z writes for (i=0 ; iflags & RF_TRANSLUCENT)) continue; // solid if (currententity->model && r_shaders->integer) { rs=(rscript_t *)currententity->model->script; //custom player skin (must be done here) if (currententity->skin) { rs = currententity->skin->script; if(rs) RS_ReadyScript(rs); } if (rs) currententity->script = rs; else currententity->script = NULL; } currentmodel = currententity->model; if (!currentmodel) { R_DrawNullModel (); continue; } switch (currentmodel->type) { case mod_alias: R_DrawAliasModel (); break; case mod_iqm: R_DrawINTERQUAKEMODEL (); break; default: Com_Error (ERR_DROP, "Bad modeltype"); break; } } qglDepthMask (1); // back to writing } extern int r_drawing_fbeffect; extern int r_fbFxType; extern float r_fbeffectTime; extern cvar_t *cl_paindist; /* ============ R_PolyBlend ============ */ void R_PolyBlend (void) { if (!gl_polyblend->integer) return; if (!v_blend[3]) return; if(!r_drawing_fbeffect && cl_paindist->integer) { if(v_blend[0] > 2*v_blend[1] && v_blend[0] > 2*v_blend[2]) { r_drawing_fbeffect = true; r_fbFxType = 2; //FLASH DISTORTION r_fbeffectTime = rs_realtime; } } qglDisable (GL_ALPHA_TEST); qglEnable (GL_BLEND); qglDisable (GL_DEPTH_TEST); qglDisable (GL_TEXTURE_2D); qglMatrixMode(GL_PROJECTION); qglLoadIdentity (); qglOrtho (0, 1, 1, 0, -99999, 99999); qglMatrixMode(GL_MODELVIEW); qglLoadIdentity (); qglColor4fv (v_blend); qglBegin (GL_TRIANGLES); qglVertex2f (-5, -5); qglVertex2f (10, -5); qglVertex2f (-5, 10); qglEnd (); qglDisable (GL_BLEND); qglEnable (GL_TEXTURE_2D); qglEnable (GL_ALPHA_TEST); qglColor4f(1,1,1,1); } //======================================================================= int SignbitsForPlane (cplane_t *out) { int bits, j; // for fast box on planeside test bits = 0; for (j=0 ; j<3 ; j++) { if (out->normal[j] < 0) bits |= 1<cluster; // check above and below so crossing solid water doesn't draw wrong if (!leaf->contents) { // look down a bit vec3_t temp; VectorCopy (r_origin, temp); temp[2] -= 16; r_viewleaf2 = leaf = Mod_PointInLeaf (temp, r_worldmodel); if ( !(leaf->contents & CONTENTS_SOLID) && (leaf->cluster != r_viewcluster2) ) r_viewcluster2 = leaf->cluster; } else { // look up a bit vec3_t temp; VectorCopy (r_origin, temp); temp[2] += 16; r_viewleaf2 = leaf = Mod_PointInLeaf (temp, r_worldmodel); if ( !(leaf->contents & CONTENTS_SOLID) && (leaf->cluster != r_viewcluster2) ) r_viewcluster2 = leaf->cluster; } } for (i=0 ; i<4 ; i++) v_blend[i] = r_newrefdef.blend[i]; c_brush_polys = 0; c_alias_polys = 0; } void MYgluPerspective( GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar ) { GLdouble xmin, xmax, ymin, ymax; ymax = zNear * tan( fovy * M_PI / 360.0 ); ymin = -ymax; xmin = ymin * aspect; xmax = ymax * aspect; xmin += -( 2 * gl_state.camera_separation ) / zNear; xmax += -( 2 * gl_state.camera_separation ) / zNear; qglFrustum( xmin, xmax, ymin, ymax, zNear, zFar ); } /* ============= R_SetupViewport ============= */ void R_SetupViewport (void) { int x, y, w, h; // The viewport info in r_newrefdef is constructed with the upper left // corner as the origin, whereas glViewport treats the lower left corner // as the origin. So we have to do some math to fix the y-coordinates. x = r_newrefdef.x; w = r_newrefdef.width; y = vid.height - r_newrefdef.y - r_newrefdef.height; h = r_newrefdef.height; qglViewport (x, y, w, h); // MPO : note this happens every frame interestingly enough } /* ============= R_SetupGL ============= */ void R_SetupGL (void) { float screenaspect; R_SetupViewport (); // // set up projection matrix // screenaspect = (float)r_newrefdef.width/r_newrefdef.height; qglMatrixMode(GL_PROJECTION); qglLoadIdentity (); if(r_newrefdef.fov_y < 90) MYgluPerspective (r_newrefdef.fov_y, screenaspect, 4, 128000); else MYgluPerspective(r_newrefdef.fov_y, screenaspect, 4 * 74 / r_newrefdef.fov_y, 15000); //Phenax qglCullFace(GL_FRONT); qglMatrixMode(GL_MODELVIEW); qglLoadIdentity (); qglRotatef (-90, 1, 0, 0); // put Z going up qglRotatef (90, 0, 0, 1); // put Z going up qglRotatef (-r_newrefdef.viewangles[2], 1, 0, 0); qglRotatef (-r_newrefdef.viewangles[0], 0, 1, 0); qglRotatef (-r_newrefdef.viewangles[1], 0, 0, 1); qglTranslatef (-r_newrefdef.vieworg[0], -r_newrefdef.vieworg[1], -r_newrefdef.vieworg[2]); qglGetFloatv (GL_MODELVIEW_MATRIX, r_world_matrix); qglGetFloatv(GL_PROJECTION_MATRIX, r_project_matrix); qglGetIntegerv(GL_VIEWPORT, (int *) r_viewport); // // set drawing parms // if (gl_cull->integer) qglEnable(GL_CULL_FACE); qglDisable(GL_BLEND); qglDisable(GL_ALPHA_TEST); qglEnable(GL_DEPTH_TEST); } /* ============= R_Clear ============= */ extern cvar_t *info_spectator; extern cvar_t *cl_add_blend; extern qboolean have_stencil; void R_Clear (void) { qglClearColor(0,0,0,1); if (gl_clear->integer) qglClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); else if (!cl_add_blend->integer && info_spectator->integer && (CM_PointContents(r_newrefdef.vieworg, 0) & CONTENTS_SOLID)) qglClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //out of map else qglClear (GL_DEPTH_BUFFER_BIT); gldepthmin = 0; gldepthmax = 1; qglDepthFunc (GL_LEQUAL); qglDepthRange (gldepthmin, gldepthmax); //our shadow system uses a combo of shadmaps and stencil volumes. if (have_stencil && gl_shadowmaps->integer) { qglClearStencil(0); qglClear(GL_STENCIL_BUFFER_BIT); } } void R_Flash( void ) { R_PolyBlend (); } /* ================ R_RenderView r_newrefdef must be set before the first call ================ */ void R_RenderView (refdef_t *fd) { GLfloat colors[4] = {(GLfloat) fog.red, (GLfloat) fog.green, (GLfloat) fog.blue, (GLfloat) 0.1}; numRadarEnts = 0; if (r_norefresh->integer) return; r_newrefdef = *fd; //shadowmaps if(gl_shadowmaps->integer) { qglEnable(GL_DEPTH_TEST); qglClearColor(0,0,0,1.0f); qglEnable(GL_CULL_FACE); qglHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); R_DrawDynamicCaster(); R_DrawVegetationCaster(); qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0); //Enabling color write (previously disabled for light POV z-buffer rendering) qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } if (!r_worldmodel && !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) ) Com_Error (ERR_DROP, "R_RenderView: NULL worldmodel"); // init r_speeds counters last_c_brush_polys = c_brush_polys; last_c_alias_polys = c_alias_polys; c_brush_polys = 0; c_alias_polys = 0; c_flares = 0; c_grasses = 0; c_beams = 0; c_vbo_batches = 0; R_PushDlights (); R_SetupFrame (); R_SetFrustum (); R_MarkWorldSurfs (); // done here so we know if we're in water if (gl_finish->integer) qglFinish (); // OpenGL calls come after here R_SetupGL (); if(map_fog) { qglFogi(GL_FOG_MODE, GL_LINEAR); qglFogfv(GL_FOG_COLOR, colors); qglFogf(GL_FOG_START, fog.start); qglFogf(GL_FOG_END, fog.end); qglFogf(GL_FOG_DENSITY, fog.density); qglEnable(GL_FOG); } R_DrawWorldSurfs (); if(r_lensflare->integer) R_RenderFlares (); R_DrawEntitiesOnList (); R_DrawVegetationSurface (); R_DrawSimpleItems (); R_CastShadow(); R_RenderAllRagdolls(); //move back ahead of r_castshadow when we figure out shadow jitter bug R_DrawViewEntitiesOnList (); R_DrawAlphaSurfaces (); if (r_lightbeam->integer) R_DrawBeamSurface (); R_DrawParticles (); if(gl_mirror->integer) { int ms = Sys_Milliseconds (); if ( ms < r_newrefdef.last_mirrorupdate_time || (ms-r_newrefdef.last_mirrorupdate_time) >= 16) { GL_SelectTexture (GL_TEXTURE0); GL_Bind (r_mirrortexture->texnum); qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, r_mirrortexture->upload_height/2, r_mirrortexture->upload_width, r_mirrortexture->upload_height); r_newrefdef.last_mirrorupdate_time = ms; } } R_BloomBlend( &r_newrefdef );//BLOOMS R_RenderSun(); R_GLSLPostProcess(); R_DrawVehicleHUD(); R_Flash(); if(map_fog) qglDisable(GL_FOG); R_DrawRadar(); *fd = r_newrefdef; } void R_SetGL2D (void) { // set 2D virtual screen size qglViewport (0,0, vid.width, vid.height); qglMatrixMode(GL_PROJECTION); qglLoadIdentity (); qglOrtho (0, vid.width, vid.height, 0, -99999, 99999); qglMatrixMode(GL_MODELVIEW); qglLoadIdentity (); qglDisable (GL_DEPTH_TEST); qglDisable (GL_CULL_FACE); qglDisable (GL_BLEND); qglEnable (GL_ALPHA_TEST); qglColor4f (1,1,1,1); } /* @@@@@@@@@@@@@@@@@@@@@ R_RenderFrame @@@@@@@@@@@@@@@@@@@@@ */ void R_RenderFrame (refdef_t *fd) { R_RenderView( fd ); R_SetGL2D (); } void R_RenderFramePlayerSetup( refdef_t *rfdf ) { numRadarEnts = 0; r_newrefdef = *rfdf; R_SetupFrame(); R_SetFrustum(); R_SetupGL(); R_DrawEntitiesOnList(); R_SetGL2D(); } void R_Register( void ) { con_font = Cvar_Get ("con_font", "default", CVAR_ARCHIVE); r_lefthand = Cvar_Get( "hand", "0", CVAR_USERINFO | CVAR_ARCHIVE | CVARDOC_INT); Cvar_Describe (r_lefthand, "0 means show gun on the right, 1 means show gun on the left, 2 means hide the gun altogether."); r_norefresh = Cvar_Get ("r_norefresh", "0", 0); r_fullbright = Cvar_Get ("r_fullbright", "0", 0); r_drawentities = Cvar_Get ("r_drawentities", "1", 0); r_drawworld = Cvar_Get ("r_drawworld", "1", 0); r_novis = Cvar_Get ("r_novis", "0", 0); r_nocull = Cvar_Get ("r_nocull", "0", 0); r_lerpmodels = Cvar_Get ("r_lerpmodels", "1", 0); r_wave = Cvar_Get ("r_wave", "2", CVAR_ARCHIVE); // Water waves gl_nosubimage = Cvar_Get( "gl_nosubimage", "0", 0 ); gl_particle_min_size = Cvar_Get( "gl_particle_min_size", ".2", CVAR_ARCHIVE ); gl_particle_max_size = Cvar_Get( "gl_particle_max_size", "40", CVAR_ARCHIVE ); gl_particle_size = Cvar_Get( "gl_particle_size", "40", CVAR_ARCHIVE ); gl_particle_att_a = Cvar_Get( "gl_particle_att_a", "0.01", CVAR_ARCHIVE ); gl_particle_att_b = Cvar_Get( "gl_particle_att_b", "0.0", CVAR_ARCHIVE ); gl_particle_att_c = Cvar_Get( "gl_particle_att_c", "0.01", CVAR_ARCHIVE ); gl_modulate = Cvar_Get ("gl_modulate", "2", CVAR_ARCHIVE|CVARDOC_INT ); Cvar_Describe (gl_modulate, "Brightness setting. Higher means brighter."); gl_log = Cvar_Get( "gl_log", "0", 0 ); gl_bitdepth = Cvar_Get( "gl_bitdepth", "0", 0 ); gl_mode = Cvar_Get( "gl_mode", "3", CVAR_ARCHIVE ); gl_lightmap = Cvar_Get ("gl_lightmap", "0", 0); gl_nobind = Cvar_Get ("gl_nobind", "0", 0); gl_picmip = Cvar_Get ("gl_picmip", "0", CVAR_ARCHIVE|CVARDOC_INT); Cvar_Describe (gl_picmip, "Texture detail. 0 means full detail. Each higher setting has 1/4 less detail."); gl_skymip = Cvar_Get ("gl_skymip", "0", 0); gl_showtris = Cvar_Get ("gl_showtris", "0", 0); gl_showpolys = Cvar_Get ("gl_showpolys", "0", CVARDOC_INT); Cvar_Describe (gl_showpolys, "Useful tool for mappers. 1 means show world polygon outlines for visible surfaces. 2 means show outlines for all surfaces in the PVS, even if they are hidden. Only works with gl_usevbo 0."); gl_finish = Cvar_Get ("gl_finish", "0", CVAR_ARCHIVE|CVARDOC_BOOL); Cvar_Describe (gl_finish, "Waits for graphics driver to finish drawing each frame before drawing the next one. Hurts performance but may improve smoothness on very low-end machines."); gl_clear = Cvar_Get ("gl_clear", "0", CVARDOC_BOOL); gl_cull = Cvar_Get ("gl_cull", "1", CVARDOC_BOOL); Cvar_Describe (gl_cull, "Avoid rendering anything that's off the edge of the screen. Good for performance, recommend leaving it on."); gl_polyblend = Cvar_Get ("gl_polyblend", "1", 0); // OPENGL_DRIVER defined by in config.h gl_driver = Cvar_Get( "gl_driver", OPENGL_DRIVER, 0 ); gl_texturemode = Cvar_Get( "gl_texturemode", "GL_LINEAR_MIPMAP_LINEAR", CVAR_ARCHIVE ); gl_texturealphamode = Cvar_Get( "gl_texturealphamode", "default", CVAR_ARCHIVE ); gl_texturesolidmode = Cvar_Get( "gl_texturesolidmode", "default", CVAR_ARCHIVE ); gl_lockpvs = Cvar_Get( "gl_lockpvs", "0", 0 ); gl_ext_pointparameters = Cvar_Get( "gl_ext_pointparameters", "0", CVAR_ARCHIVE ); gl_drawbuffer = Cvar_Get( "gl_drawbuffer", "GL_BACK", 0 ); gl_swapinterval = Cvar_Get( "gl_swapinterval", "1", CVAR_ARCHIVE|CVARDOC_BOOL ); Cvar_Describe (gl_swapinterval, "Sync to Vblank. Eliminates \"tearing\" effects, but it can hurt framerates."); r_shaders = Cvar_Get ("r_shaders", "1", CVAR_ARCHIVE|CVARDOC_BOOL); r_overbrightbits = Cvar_Get( "r_overbrightbits", "2", CVAR_ARCHIVE ); gl_usevbo = Cvar_Get("gl_usevbo", "1", CVAR_ARCHIVE|CVARDOC_BOOL); Cvar_Describe (gl_usevbo, "Use VBOs for mesh and world geometry. Leave this on unless you've got a very old graphics card."); gl_mirror = Cvar_Get("gl_mirror", "1", CVAR_ARCHIVE|CVARDOC_BOOL); vid_fullscreen = Cvar_Get( "vid_fullscreen", "1", CVAR_ARCHIVE|CVARDOC_BOOL); vid_gamma = Cvar_Get( "vid_gamma", "1.0", CVAR_ARCHIVE ); vid_contrast = Cvar_Get( "vid_contrast", "1.0", CVAR_ARCHIVE); //TODO: remove, unless we decide to add GL ES support or something. vid_ref = Cvar_Get( "vid_ref", "gl", CVAR_ARCHIVE|CVAR_ROM ); gl_vlights = Cvar_Get("gl_vlights", "1", CVAR_ARCHIVE); gl_normalmaps = Cvar_Get("gl_normalmaps", "1", CVAR_ARCHIVE|CVARDOC_BOOL); gl_bspnormalmaps = Cvar_Get("gl_bspnormalmaps", "0", CVAR_ARCHIVE|CVARDOC_BOOL); gl_shadowmaps = Cvar_Get("gl_shadowmaps", "0", CVAR_ARCHIVE|CVARDOC_BOOL); gl_fog = Cvar_Get ("gl_fog", "1", CVAR_ARCHIVE|CVARDOC_BOOL); Cvar_Describe (gl_fog, "Fog and weather effects."); r_shadowmapscale = Cvar_Get( "r_shadowmapscale", "1", CVAR_ARCHIVE ); r_shadowcutoff = Cvar_Get( "r_shadowcutoff", "880", CVAR_ARCHIVE ); r_lensflare = Cvar_Get( "r_lensflare", "1", CVAR_ARCHIVE|CVARDOC_BOOL); r_lensflare_intens = Cvar_Get ("r_lensflare_intens", "3", CVAR_ARCHIVE|CVARDOC_INT); r_drawsun = Cvar_Get("r_drawsun", "2", CVAR_ARCHIVE); r_lightbeam = Cvar_Get ("r_lightbeam", "1", CVAR_ARCHIVE|CVARDOC_BOOL); r_godrays = Cvar_Get ("r_godrays", "0", CVAR_ARCHIVE|CVARDOC_BOOL); r_godray_intensity = Cvar_Get ("r_godray_intensity", "1.0", CVAR_ARCHIVE); r_optimize = Cvar_Get ("r_optimize", "1", CVAR_ARCHIVE|CVARDOC_BOOL); Cvar_Describe (r_optimize, "Skip BSP recursion unless you move. Good for performance, recommend leaving it on."); r_lightmapfiles = Cvar_Get("r_lightmapfiles", "1", CVAR_ARCHIVE|CVARDOC_BOOL); Cvar_Describe (r_lightmapfiles, "Enables the loading of .lightmap files, with more detailed light and shadow. Turn this off if video RAM is limited."); r_minimap_size = Cvar_Get ("r_minimap_size", "256", CVAR_ARCHIVE ); r_minimap_zoom = Cvar_Get ("r_minimap_zoom", "1", CVAR_ARCHIVE ); r_minimap_style = Cvar_Get ("r_minimap_style", "1", CVAR_ARCHIVE ); r_minimap = Cvar_Get ("r_minimap", "0", CVAR_ARCHIVE|CVARDOC_BOOL ); r_ragdolls = Cvar_Get ("r_ragdolls", "1", CVAR_ARCHIVE|CVARDOC_BOOL); r_ragdoll_debug = Cvar_Get("r_ragdoll_debug", "0", CVAR_ARCHIVE|CVARDOC_BOOL); sys_priority = Cvar_Get("sys_priority", "0", CVAR_ARCHIVE); sys_affinity = Cvar_Get("sys_affinity", "1", CVAR_ARCHIVE); gl_screenshot_type = Cvar_Get("gl_screenshot_type", "jpeg", CVAR_ARCHIVE|CVARDOC_STR); gl_screenshot_jpeg_quality = Cvar_Get("gl_screenshot_jpeg_quality", "85", CVAR_ARCHIVE|CVARDOC_INT); r_firstrun = Cvar_Get("r_firstrun", "0", CVAR_ARCHIVE|CVARDOC_BOOL); //first time running the game Cvar_Describe (r_firstrun, "Set this to 0 if you want the game to auto detect your graphics settings next time you run it."); r_test = Cvar_Get("r_test", "0", CVAR_ARCHIVE); //for testing things // FIXME HACK copied over from the video menu code. These are initialized // again elsewhere. TODO: work out any complications that may arise from // deleting these duplicate initializations. Cvar_Get( "r_bloom", "0", CVAR_ARCHIVE ); Cvar_Get( "r_bloom_intensity", "0.5", CVAR_ARCHIVE); Cvar_Get( "r_overbrightbits", "2", CVAR_ARCHIVE); Cvar_Get( "vid_width", "640", CVAR_ARCHIVE); Cvar_Get( "vid_height", "400", CVAR_ARCHIVE); Cvar_Get( "gl_glsl_shaders", "1", CVAR_ARCHIVE); Cmd_AddCommand( "imagelist", GL_ImageList_f ); Cmd_AddCommand( "screenshot", GL_ScreenShot_f ); Cmd_AddCommand( "modellist", Mod_Modellist_f ); Cmd_AddCommand( "gl_strings", GL_Strings_f ); } /* ================== R_SetMode ================== */ qboolean R_SetMode (void) { rserr_t err; qboolean fullscreen; if ( vid_fullscreen->modified && !gl_config.allow_cds ) { Com_Printf ("R_SetMode() - CDS not allowed with this driver\n" ); Cvar_SetValue( "vid_fullscreen", !vid_fullscreen->integer ); vid_fullscreen->modified = false; } fullscreen = vid_fullscreen->integer; vid_fullscreen->modified = false; gl_mode->modified = false; if ( ( err = GLimp_SetMode( &vid.width, &vid.height, gl_mode->integer, fullscreen ) ) == rserr_ok ) { gl_state.prev_mode = gl_mode->integer; } else { if ( err == rserr_invalid_fullscreen ) { Cvar_SetValue( "vid_fullscreen", 0); vid_fullscreen->modified = false; Com_Printf ("ref_gl::R_SetMode() - fullscreen unavailable in this mode\n" ); if ( ( err = GLimp_SetMode( &vid.width, &vid.height, gl_mode->integer, false ) ) == rserr_ok ) return true; } else if ( err == rserr_invalid_mode ) { Cvar_SetValue( "gl_mode", gl_state.prev_mode ); gl_mode->modified = false; Com_Printf ("ref_gl::R_SetMode() - invalid mode\n" ); } // try setting it back to something safe if ( ( err = GLimp_SetMode( &vid.width, &vid.height, gl_state.prev_mode, false ) ) != rserr_ok ) { Com_Printf ("ref_gl::R_SetMode() - could not revert to safe mode\n" ); return false; } } return true; } /* =============== R_SetCompatibility =============== */ void R_SetCompatibility(void) { Cmd_ExecuteString ("exec graphical_presets/compatibility.cfg"); Cbuf_Execute (); Com_Printf("...autodetected MAX COMPATIBILITY game setting\n"); } /* =============== R_SetMaxPerformance =============== */ void R_SetMaxPerformance( void ) { Cmd_ExecuteString ("exec graphical_presets/maxperformance.cfg"); Cbuf_Execute (); Com_Printf("...autodetected MAX PERFORMANCE game setting\n"); } /* =============== R_SetPerformance =============== */ void R_SetPerformance( void ) { Cmd_ExecuteString ("exec graphical_presets/performance.cfg"); Cbuf_Execute (); Com_Printf("...autodetected PERFORMANCE game setting\n"); } /* =============== R_SetQuality =============== */ void R_SetQuality( void ) { Cmd_ExecuteString ("exec graphical_presets/quality.cfg"); Cbuf_Execute (); Com_Printf("...autodetected QUALITY game setting\n"); } /* =============== R_SetMaxQuality =============== */ void R_SetMaxQuality( void ) { Cmd_ExecuteString ("exec graphical_presets/maxquality.cfg"); Cbuf_Execute (); Com_Printf("...autodetected MAX QUALITY game setting\n"); } #if defined WIN32_VARIANT double CPUSpeed() { DWORD BufSize = _MAX_PATH; DWORD dwMHz = _MAX_PATH; HKEY hKey; // open the key where the proc speed is hidden: long lError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, KEY_READ, &hKey); if(lError != ERROR_SUCCESS) return 0; // query the key: RegQueryValueEx(hKey, "~MHz", NULL, NULL, (LPBYTE) &dwMHz, &BufSize); return (double)dwMHz; } #endif /* =============== R_Init =============== */ int R_Init( void *hinstance, void *hWnd ) { int err; int j; extern float r_turbsin[256]; for ( j = 0; j < 256; j++ ) { r_turbsin[j] *= 0.5; } Draw_GetPalette (); R_Register(); // initialize our QGL dynamic bindings if ( !QGL_Init( gl_driver->string ) ) { QGL_Shutdown(); Com_Printf ("ref_gl::R_Init() - could not load \"%s\"\n", gl_driver->string ); return -1; } // initialize OS-specific parts of OpenGL if ( !GLimp_Init( hinstance, hWnd ) ) { QGL_Shutdown(); return -1; } // set our "safe" modes gl_state.prev_mode = 3; // create the window and set up the context if ( !R_SetMode () ) { QGL_Shutdown(); Com_Printf ("ref_gl::R_Init() - could not R_SetMode()\n" ); return -1; } // Initialise TrueType fonts if ( ! FNT_Initialise( ) ) { QGL_Shutdown( ); Com_Printf( "ref_gl::R_Init() - could not initialise text drawing front-end\n" ); return -1; } /* ** get our various GL strings */ gl_config.vendor_string = (const char*)qglGetString (GL_VENDOR); Com_Printf ("GL_VENDOR: %s\n", gl_config.vendor_string ); gl_config.renderer_string = (const char*)qglGetString (GL_RENDERER); Com_Printf ("GL_RENDERER: %s\n", gl_config.renderer_string ); gl_config.version_string = (const char*)qglGetString (GL_VERSION); Com_Printf ("GL_VERSION: %s\n", gl_config.version_string ); gl_config.extensions_string = (const char*)qglGetString (GL_EXTENSIONS); Com_Printf ("GL_EXTENSIONS: %s\n", gl_config.extensions_string ); gl_config.allow_cds = true; Com_Printf ("...allowing CDS\n" ); /* ** grab extensions */ if ( strstr( gl_config.extensions_string, "GL_EXT_compiled_vertex_array" ) || strstr( gl_config.extensions_string, "GL_SGI_compiled_vertex_array" ) ) { Com_Printf ("...enabling GL_EXT_compiled_vertex_array\n" ); qglLockArraysEXT = ( void * ) qwglGetProcAddress( "glLockArraysEXT" ); qglUnlockArraysEXT = ( void * ) qwglGetProcAddress( "glUnlockArraysEXT" ); } else { Com_Printf ("...GL_EXT_compiled_vertex_array not found\n" ); } #if defined WIN32_VARIANT if ( strstr( gl_config.extensions_string, "WGL_EXT_swap_control" ) ) { qwglSwapIntervalEXT = ( BOOL (WINAPI *)(int)) qwglGetProcAddress( "wglSwapIntervalEXT" ); Com_Printf ("...enabling WGL_EXT_swap_control\n" ); } else { Com_Printf ("...WGL_EXT_swap_control not found\n" ); } #endif if (strstr(gl_config.extensions_string, "GL_EXT_point_parameters")) { if(gl_ext_pointparameters->integer) { qglPointParameterfEXT = (void(APIENTRY*)(GLenum, GLfloat))qwglGetProcAddress("glPointParameterfEXT"); qglPointParameterfvEXT = (void(APIENTRY*)(GLenum, const GLfloat*))qwglGetProcAddress("glPointParameterfvEXT"); } else { Com_Printf ("...ignoring GL_EXT_point_parameters\n" ); } } else { Com_Printf ("...GL_EXT_point_parameters not found\n" ); } R_InitImageSubsystem(); R_InitShadowSubsystem(); R_LoadVBOSubsystem(); #if defined DARWIN_SPECIAL_CASE /* * development workaround for Mac OS X / Darwin using X11 * problems seen with 2.1 NVIDIA-1.6.18 when calling * glCreateProgramObjectARB() * For now, just go with low settings. */ gl_state.fragment_program = false; gl_arb_fragment_program = Cvar_Get("gl_arb_fragment_program", "0", CVAR_ARCHIVE); gl_state.glsl_shaders = false; gl_glsl_shaders = Cvar_Get("gl_glsl_shaders", "0", CVAR_ARCHIVE); gl_dynamic = Cvar_Get ("gl_dynamic", "0", CVAR_ARCHIVE); Cvar_SetValue("r_firstrun", 1); R_SetMaxPerformance(); Com_Printf("...Development Workaround. Low game settings forced.\n"); #else //always do this check for ATI drivers - they are somewhat bugged in regards to shadowmapping and use of shadow2dproj command if(!strcmp(gl_config.vendor_string, "ATI Technologies Inc.")) gl_state.ati = true; //load shader programs R_LoadARBPrograms(); R_LoadGLSLPrograms(); //if running for the very first time, automatically set video settings if(!r_firstrun->integer) { qboolean ati_nvidia = false; double CPUTotalSpeed = 4000.0; //default to this double OGLVer = atof(&gl_config.version_string[0]); //int OGLSubVer = atoi(&gl_config.version_string[2]); #if defined WIN32_VARIANT SYSTEM_INFO sysInfo; GetSystemInfo(&sysInfo); Com_Printf("...CPU: %4.2f Cores: %d\n", CPUSpeed(), sysInfo.dwNumberOfProcessors); CPUTotalSpeed = sysInfo.dwNumberOfProcessors * CPUSpeed(); #else FILE *fp; char res[128]; int cores; size_t szrslt; int irslt; fp = popen("/bin/cat /proc/cpuinfo | grep -c '^processor'","r"); if ( fp == NULL ) goto cpuinfo_error; szrslt = fread(res, 1, sizeof(res)-1, fp); res[szrslt] = 0; pclose(fp); if ( !szrslt ) goto cpuinfo_error; cores = atoi( &res[0] ); fp = popen("/bin/cat /proc/cpuinfo | grep '^cpu MHz'","r"); if ( fp == NULL ) goto cpuinfo_error; szrslt = fread(res, 1, sizeof(res)-1, fp); // about 20 bytes/cpu res[szrslt] = 0; pclose(fp); if ( !szrslt ) goto cpuinfo_error; irslt = sscanf( res, "cpu MHz : %lf", &CPUTotalSpeed ); if ( !irslt ) goto cpuinfo_error; Com_Printf("...CPU: %4.2f Cores: %d\n", CPUTotalSpeed, cores); CPUTotalSpeed *= cores; goto cpuinfo_exit; cpuinfo_error: Com_Printf("...Reading /proc/cpuinfo failed.\n"); cpuinfo_exit: #endif //check to see if we are using ATI or NVIDIA, otherwise, we don't want to //deal with high settings on offbrand GPU's like Intel or Unichrome if(!strcmp(gl_config.vendor_string, "ATI Technologies Inc.") || !strcmp(gl_config.vendor_string, "NVIDIA Corporation")) ati_nvidia = true; if(OGLVer < 2.1) { //weak GPU, set to maximum compatibility R_SetCompatibility(); } else if(OGLVer >= 3) { //GPU is modern, check CPU if(CPUTotalSpeed > 3800.0 && ati_nvidia) R_SetMaxQuality(); else R_SetQuality(); } else { if(CPUTotalSpeed > 3800.0 && ati_nvidia) R_SetQuality(); else R_SetPerformance(); } //never run again Cvar_SetValue("r_firstrun", 1); } #endif GL_SetDefaultState(); R_CheckFBOExtensions (); GL_InitImages (); Mod_Init (); R_InitParticleTexture (); Draw_InitLocal (); R_GenerateShadowFBO(); VLight_Init(); //Initialize ODE // ODE assert failures sometimes occur, this may or may not help. r_odeinit_success = dInitODE2(0); //ODE - clear out any ragdolls; if ( r_odeinit_success ) { Com_Printf("...ODE initialized.\n"); R_ClearAllRagdolls(); Com_Printf("...Ragdolls initialized.\n"); } else { Com_Printf("...ODE initialization failed.\n...Ragdolls are disabled.\n"); } scr_playericonalpha = 0.0; err = qglGetError(); if ( err != GL_NO_ERROR ) Com_Printf ("glGetError() = 0x%x\n", err); return 0; } /* =============== R_Shutdown =============== */ void R_Shutdown (void) { Cmd_RemoveCommand ("modellist"); Cmd_RemoveCommand ("screenshot"); Cmd_RemoveCommand ("imagelist"); Cmd_RemoveCommand ("gl_strings"); R_VCShutdown(); Mod_FreeAll (); FNT_Shutdown( ); GL_ShutdownImages (); /* ** shut down OS specific OpenGL stuff like contexts, etc. */ GLimp_Shutdown(); /* ** shutdown our QGL subsystem */ if(gl_state.glsl_shaders) { glDeleteObjectARB( g_vertexShader ); glDeleteObjectARB( g_fragmentShader ); glDeleteObjectARB( g_programObj ); } QGL_Shutdown(); //Shutdown ODE // ODE might fail assert on close when not intialized if ( r_odeinit_success ) { Com_DPrintf("Closing ODE\n"); dCloseODE(); } } /* @@@@@@@@@@@@@@@@@@@@@ R_BeginFrame @@@@@@@@@@@@@@@@@@@@@ */ void R_BeginFrame( float camera_separation ) { gl_state.camera_separation = camera_separation; if (con_font->modified) RefreshFont (); /* ** change modes if necessary */ if ( gl_mode->modified || vid_fullscreen->modified ) { // FIXME: only restart if CDS is required cvar_t *ref; ref = Cvar_Get ("vid_ref", "gl", 0); ref->modified = true; } if ( gl_log->modified ) { GLimp_EnableLogging( gl_log->integer ); gl_log->modified = false; } if ( gl_log->integer ) { GLimp_LogNewFrame(); } GLimp_BeginFrame( camera_separation ); /* ** go into 2D mode */ R_SetGL2D (); /* ** draw buffer stuff */ if ( gl_drawbuffer->modified ) { gl_drawbuffer->modified = false; if ( gl_state.camera_separation == 0 || !gl_state.stereo_enabled ) { if ( Q_strcasecmp( gl_drawbuffer->string, "GL_FRONT" ) == 0 ) qglDrawBuffer( GL_FRONT ); else qglDrawBuffer( GL_BACK ); } } /* ** texturemode stuff */ if ( gl_texturemode->modified ) { GL_TextureMode( gl_texturemode->string ); gl_texturemode->modified = false; } if ( gl_texturealphamode->modified ) { GL_TextureAlphaMode( gl_texturealphamode->string ); gl_texturealphamode->modified = false; } if ( gl_texturesolidmode->modified ) { GL_TextureSolidMode( gl_texturesolidmode->string ); gl_texturesolidmode->modified = false; } /* ** swapinterval stuff */ GL_UpdateSwapInterval(); // // clear screen if desired // R_Clear (); } /* ============= R_AppActivate ============= */ void R_AppActivate( qboolean active ) { GLimp_AppActivate (active); } /* ============= R_EndFrame ============= */ void R_EndFrame (void) { GLimp_EndFrame (); } /* ============= R_SetPalette ============= */ unsigned r_rawpalette[256]; void R_SetPalette ( const unsigned char *palette) { int i; byte *rp = ( byte * ) r_rawpalette; if ( palette ) { for ( i = 0; i < 256; i++ ) { rp[i*4+0] = palette[i*3+0]; rp[i*4+1] = palette[i*3+1]; rp[i*4+2] = palette[i*3+2]; rp[i*4+3] = 0xff; } } else { for ( i = 0; i < 256; i++ ) { rp[i*4+0] = d_8to24table[i] & 0xff; rp[i*4+1] = ( d_8to24table[i] >> 8 ) & 0xff; rp[i*4+2] = ( d_8to24table[i] >> 16 ) & 0xff; rp[i*4+3] = 0xff; } } if ( qglClear && qglClearColor) { // only run this if we haven't uninitialised // OpenGL already qglClearColor (0,0,0,0); qglClear (GL_COLOR_BUFFER_BIT); qglClearColor (1,0, 0.5 , 0.5); } } /* =============== R_FarClip =============== */ float R_FarClip( void ) { float farclip, farclip_dist; int i; vec_t mins[4]; vec_t maxs[4]; vec_t dist; farclip_dist = DotProduct( r_origin, vpn ); if(r_farclip_min > 256.0f) farclip = farclip_dist + r_farclip_min; else farclip = farclip_dist + 256.0f; if( r_worldmodel && !(r_newrefdef.rdflags & RDF_NOWORLDMODEL) ) { for (i = 0; i < 3; i++) { mins[i] = r_worldmodel->nodes[0].minmaxs[i]; maxs[i] = r_worldmodel->nodes[0].minmaxs[3+i]; } dist = (vpn[0] < 0 ? mins[0] : maxs[0]) * vpn[0] + (vpn[1] < 0 ? mins[1] : maxs[1]) * vpn[1] + (vpn[2] < 0 ? mins[2] : maxs[2]) * vpn[2]; if( dist > farclip ) farclip = dist; } if((farclip - farclip_dist + r_farclip_bias) > r_farclip) return ( farclip - farclip_dist + r_farclip_bias); else return r_farclip; } /* ============= R_SetupProjectionMatrix ============= */ void R_SetupProjectionMatrix( refdef_t *rd, mat4x4_t m ) { double xMin, xMax, yMin, yMax, zNear, zFar; r_farclip = R_FarClip (); zNear = 4; zFar = r_farclip; yMax = zNear * tan( rd->fov_y * M_PI / 360.0 ); yMin = -yMax; xMin = yMin * rd->width / rd->height; xMax = yMax * rd->width / rd->height; xMin += -( 2 * gl_state.camera_separation ) / zNear; xMax += -( 2 * gl_state.camera_separation ) / zNear; m[0] = (2.0 * zNear) / (xMax - xMin); m[1] = 0.0f; m[2] = 0.0f; m[3] = 0.0f; m[4] = 0.0f; m[5] = (2.0 * zNear) / (yMax - yMin); m[6] = 0.0f; m[7] = 0.0f; m[8] = (xMax + xMin) / (xMax - xMin); m[9] = (yMax + yMin) / (yMax - yMin); m[10] = -(zFar + zNear) / (zFar - zNear); m[11] = -1.0f; m[12] = 0.0f; m[13] = 0.0f; m[14] = -(2.0 * zFar * zNear) / (zFar - zNear); m[15] = 0.0f; } /* ============= R_SetupModelviewMatrix ============= */ void R_SetupModelviewMatrix( refdef_t *rd, mat4x4_t m ) { Vector4Set( &m[0], 0, 0, -1, 0 ); Vector4Set( &m[4], -1, 0, 0, 0 ); Vector4Set( &m[8], 0, 1, 0, 0 ); Vector4Set( &m[12], 0, 0, 0, 1 ); Matrix4_Rotate( m, -rd->viewangles[2], 1, 0, 0 ); Matrix4_Rotate( m, -rd->viewangles[0], 0, 1, 0 ); Matrix4_Rotate( m, -rd->viewangles[1], 0, 0, 1 ); Matrix4_Translate( m, -rd->vieworg[0], -rd->vieworg[1], -rd->vieworg[2] ); } void R_TransformVectorToScreen( refdef_t *rd, vec3_t in, vec2_t out ) { mat4x4_t p, m; vec4_t temp, temp2; if( !rd || !in || !out ) return; temp[0] = in[0]; temp[1] = in[1]; temp[2] = in[2]; temp[3] = 1.0f; R_SetupProjectionMatrix( rd, p ); R_SetupModelviewMatrix( rd, m ); Matrix4_Multiply_Vector( m, temp, temp2 ); Matrix4_Multiply_Vector( p, temp2, temp ); if( !temp[3] ) return; out[0] = rd->x + (temp[0] / temp[3] + 1.0f) * rd->width * 0.5f; out[1] = rd->y + (temp[1] / temp[3] + 1.0f) * rd->height * 0.5f; } alien-arena-7.66+dfsg/source/ref_gl/r_postprocess.c0000600000175000017500000006131712162607462021444 0ustar zero79zero79/* Copyright (C) 2009 COR Entertainment This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "r_local.h" #define EXPLOSION 1 #define PAIN 2 extern int KillFlags; extern float v_blend[4]; extern void R_TransformVectorToScreen( refdef_t *rd, vec3_t in, vec2_t out ); void R_DrawBloodEffect (void); image_t *r_framebuffer; image_t *r_distortwave; image_t *r_droplets; image_t *r_blooddroplets; image_t *r_blooddroplets_nm; vec3_t r_explosionOrigin; int r_drawing_fbeffect; int r_fbFxType; float r_fbeffectTime; int frames; extern cvar_t *cl_raindist; void R_GLSLDistortion(void) { vec2_t fxScreenPos; int offsetX, offsetY; vec3_t vec; float dot, r_fbeffectLen; vec3_t forward, mins, maxs; trace_t r_trace; float hScissor, wScissor; if(!gl_glsl_shaders->integer || vid.width > 2048 || !gl_state.glsl_shaders) return; if(r_fbFxType == EXPLOSION) { //is it in our view? AngleVectors (r_newrefdef.viewangles, forward, NULL, NULL); VectorSubtract (r_explosionOrigin, r_newrefdef.vieworg, vec); VectorNormalize (vec); dot = DotProduct (vec, forward); if (dot <= 0.3) r_drawing_fbeffect = false; //is anything blocking it from view? VectorSet(mins, 0, 0, 0); VectorSet(maxs, 0, 0, 0); r_trace = CM_BoxTrace(r_origin, r_explosionOrigin, maxs, mins, r_worldmodel->firstnode, MASK_VISIBILILITY); if (r_trace.fraction != 1.0) r_drawing_fbeffect = false; } //if not doing stuff, return if(!r_drawing_fbeffect) return; frames++; if(r_fbFxType == PAIN) { r_fbeffectLen = 0.1; R_DrawBloodEffect(); } else r_fbeffectLen = 0.2; //set up full screen workspace qglViewport( 0, 0, viddef.width, viddef.height ); qglDisable( GL_DEPTH_TEST ); qglMatrixMode( GL_PROJECTION ); qglLoadIdentity (); qglOrtho(0, viddef.width, viddef.height, 0, -10, 100); qglMatrixMode( GL_MODELVIEW ); qglLoadIdentity (); qglDisable(GL_CULL_FACE); qglDisable( GL_BLEND ); qglEnable( GL_TEXTURE_2D ); qglViewport(0,0,FB_texture_width,FB_texture_height); //we need to grab the frame buffer qglBindTexture(GL_TEXTURE_2D, r_framebuffer->texnum); qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, FB_texture_width, FB_texture_height); qglViewport(0,0,viddef.width, viddef.height); //render quad on screen offsetY = viddef.height - FB_texture_height; offsetX = viddef.width - FB_texture_width; hScissor = (float)viddef.height/(float)FB_texture_height; wScissor = (float)viddef.width/(float)FB_texture_width; qglEnableClientState (GL_VERTEX_ARRAY); qglEnableClientState (GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer (2, GL_FLOAT, sizeof(tex_array[0]), tex_array[0]); qglVertexPointer (2, GL_FLOAT, sizeof(vert_array[0]), vert_array[0]); qglColorPointer (4, GL_FLOAT, sizeof(col_array[0]), col_array[0]); VA_SetElem2(vert_array[0],0, viddef.height); VA_SetElem2(vert_array[1],viddef.width-offsetX, viddef.height); VA_SetElem2(vert_array[2],viddef.width-offsetX, offsetY); VA_SetElem2(vert_array[3],0, offsetY); VA_SetElem2(tex_array[0],r_framebuffer->sl, r_framebuffer->tl); VA_SetElem2(tex_array[1],r_framebuffer->sh, r_framebuffer->tl); VA_SetElem2(tex_array[2],r_framebuffer->sh, r_framebuffer->th); VA_SetElem2(tex_array[3],r_framebuffer->sl, r_framebuffer->th); if(r_fbFxType == EXPLOSION) { //create a distortion wave effect at point of explosion glUseProgramObjectARB( g_fbprogramObj ); qglActiveTextureARB(GL_TEXTURE1); qglBindTexture (GL_TEXTURE_2D,r_framebuffer->texnum); glUniform1iARB( g_location_framebuffTex, 1); KillFlags |= KILL_TMU1_POINTER; qglActiveTextureARB(GL_TEXTURE0); if(r_distortwave) qglBindTexture(GL_TEXTURE_2D, r_distortwave->texnum); glUniform1iARB( g_location_distortTex, 0); KillFlags |= KILL_TMU0_POINTER; glUniform2fARB( g_location_dParams, wScissor, hScissor); fxScreenPos[0] = fxScreenPos[1] = 0; //get position of focal point of warp R_TransformVectorToScreen(&r_newrefdef, r_explosionOrigin, fxScreenPos); fxScreenPos[0] /= viddef.width; fxScreenPos[1] /= viddef.height; fxScreenPos[0] -= (0.5 + (abs((float)offsetX)/1024.0)*0.25); fxScreenPos[1] -= (0.5 + (abs((float)offsetY)/1024.0)*0.15); fxScreenPos[0] -= (float)frames*.001; fxScreenPos[1] -= (float)frames*.001; glUniform2fARB( g_location_fxPos, fxScreenPos[0], fxScreenPos[1]); R_DrawVarrays(GL_QUADS, 0, 4); glUseProgramObjectARB( 0 ); } else { //do a radial blur glUseProgramObjectARB( g_rblurprogramObj ); qglActiveTextureARB(GL_TEXTURE0); qglBindTexture(GL_TEXTURE_2D, r_framebuffer->texnum); KillFlags |= KILL_TMU0_POINTER; glUniform1iARB( g_location_rsource, 0); glUniform3fARB( g_location_rscale, 1.0, wScissor, hScissor); glUniform3fARB( g_location_rparams, viddef.width/2.0, viddef.height/2.0, 0.25); R_DrawVarrays(GL_QUADS, 0, 4); glUseProgramObjectARB( 0 ); } R_KillVArrays(); if(rs_realtime > r_fbeffectTime+r_fbeffectLen) { frames = 0; r_drawing_fbeffect = false; //done effect } return; } void R_GLSLWaterDroplets(void) { int offsetX, offsetY; float hScissor, wScissor; trace_t tr; vec3_t end; static float r_drTime; if(!(r_weather == 1) || !cl_raindist->integer || !gl_glsl_shaders->integer || vid.width > 2048 || !gl_state.glsl_shaders) return; VectorCopy(r_newrefdef.vieworg, end); end[2] += 8192; // trace up looking for sky tr = CM_BoxTrace(r_newrefdef.vieworg, end, vec3_origin, vec3_origin, 0, MASK_SHOT); if((tr.surface->flags & SURF_SKY)) { r_drTime = rs_realtime; } if(rs_realtime - r_drTime > 0.5) return; //been out of the rain long enough for effect to dry up //set up full screen workspace qglViewport( 0, 0, viddef.width, viddef.height ); qglDisable( GL_DEPTH_TEST ); qglMatrixMode( GL_PROJECTION ); qglLoadIdentity (); qglOrtho(0, viddef.width, viddef.height, 0, -10, 100); qglMatrixMode( GL_MODELVIEW ); qglLoadIdentity (); qglDisable(GL_CULL_FACE); qglDisable( GL_BLEND ); qglEnable( GL_TEXTURE_2D ); qglViewport(0,0,FB_texture_width,FB_texture_height); //we need to grab the frame buffer qglBindTexture(GL_TEXTURE_2D, r_framebuffer->texnum); qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, FB_texture_width, FB_texture_height); qglViewport(0,0,viddef.width, viddef.height); //render quad on screen offsetY = viddef.height - FB_texture_height; offsetX = viddef.width - FB_texture_width; hScissor = (float)viddef.height/(float)FB_texture_height; wScissor = (float)viddef.width/(float)FB_texture_width; qglEnableClientState (GL_VERTEX_ARRAY); qglEnableClientState (GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer (2, GL_FLOAT, sizeof(tex_array[0]), tex_array[0]); qglVertexPointer (2, GL_FLOAT, sizeof(vert_array[0]), vert_array[0]); qglColorPointer (4, GL_FLOAT, sizeof(col_array[0]), col_array[0]); VA_SetElem2(vert_array[0],0, viddef.height); VA_SetElem2(vert_array[1],viddef.width-offsetX, viddef.height); VA_SetElem2(vert_array[2],viddef.width-offsetX, offsetY); VA_SetElem2(vert_array[3],0, offsetY); VA_SetElem2(tex_array[0],r_framebuffer->sl, r_framebuffer->tl); VA_SetElem2(tex_array[1],r_framebuffer->sh, r_framebuffer->tl); VA_SetElem2(tex_array[2],r_framebuffer->sh, r_framebuffer->th); VA_SetElem2(tex_array[3],r_framebuffer->sl, r_framebuffer->th); //draw water droplets glUseProgramObjectARB( g_dropletsprogramObj ); //this program will have two or three of the normalmap scrolling over the buffer qglActiveTextureARB(GL_TEXTURE1); qglBindTexture (GL_TEXTURE_2D,r_framebuffer->texnum); glUniform1iARB( g_location_drSource, 1); KillFlags |= KILL_TMU1_POINTER; qglActiveTextureARB(GL_TEXTURE0); qglBindTexture(GL_TEXTURE_2D, r_droplets->texnum); glUniform1iARB( g_location_drTex, 0); KillFlags |= KILL_TMU0_POINTER; glUniform1fARB( g_location_drTime, rs_realtime); glUniform2fARB( g_location_drParams, wScissor, hScissor); R_DrawVarrays(GL_QUADS, 0, 4); glUseProgramObjectARB( 0 ); R_KillVArrays(); return; } /* ============== R_ShadowBlend Draws projection shadow(s) from stenciled volume ============== */ image_t *r_colorbuffer; void R_ShadowBlend(float alpha) { if (r_newrefdef.rdflags & RDF_NOWORLDMODEL) return; qglMatrixMode(GL_PROJECTION); qglPushMatrix(); qglLoadIdentity(); qglOrtho(0, 1, 1, 0, -99999, 99999); qglMatrixMode(GL_MODELVIEW); qglPushMatrix(); qglLoadIdentity(); if(gl_state.fbo && gl_state.hasFBOblit && atoi(&gl_config.version_string[0]) >= 3.0) { alpha/=1.5; //necessary because we are blending two quads //blit the stencil mask from main buffer qglBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); qglBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fboId[2]); qglBlitFramebufferEXT(0, 0, vid.width, vid.height, 0, 0, viddef.width, viddef.height, GL_STENCIL_BUFFER_BIT, GL_NEAREST); qglBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); qglBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); //render offscreen qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId[2]); qglDisable(GL_STENCIL_TEST); GLSTATE_DISABLE_ALPHATEST qglEnable( GL_BLEND ); qglDisable (GL_DEPTH_TEST); qglDisable (GL_TEXTURE_2D); qglColor4f (1,1,1, 1); qglBegin(GL_TRIANGLES); qglVertex2f(-5, -5); qglVertex2f(10, -5); qglVertex2f(-5, 10); qglEnd(); } qglColor4f (0,0,0, alpha); GLSTATE_DISABLE_ALPHATEST qglEnable( GL_BLEND ); qglDisable (GL_DEPTH_TEST); qglDisable (GL_TEXTURE_2D); qglEnable(GL_STENCIL_TEST); qglStencilFunc( GL_NOTEQUAL, 0, 0xFF); qglStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); qglBegin(GL_TRIANGLES); qglVertex2f(-5, -5); qglVertex2f(10, -5); qglVertex2f(-5, 10); qglEnd(); if(gl_state.fbo && gl_state.hasFBOblit && atoi(&gl_config.version_string[0]) >= 3.0) { qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); //revert settings qglMatrixMode( GL_PROJECTION ); qglLoadIdentity (); qglOrtho(0, vid.width, vid.height, 0, -10, 100); qglDisable(GL_CULL_FACE); qglEnable( GL_BLEND ); qglEnable( GL_TEXTURE_2D ); qglBlendFunc (GL_ZERO, GL_SRC_COLOR); qglDisable (GL_DEPTH_TEST); qglDisable(GL_STENCIL_TEST); qglColor4f (1,1,1,1); //render quad on screen into FBO //and blur it vertically glUseProgramObjectARB( g_blurprogramObj ); qglActiveTextureARB(GL_TEXTURE0); qglBindTexture(GL_TEXTURE_2D, r_colorbuffer->texnum); glUniform1iARB( g_location_source, 0); glUniform2fARB( g_location_scale, 4.0/vid.width, 2.0/vid.height); qglEnableClientState (GL_VERTEX_ARRAY); qglEnableClientState (GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer (2, GL_FLOAT, sizeof(tex_array[0]), tex_array[0]); qglVertexPointer (2, GL_FLOAT, sizeof(vert_array[0]), vert_array[0]); qglColorPointer (4, GL_FLOAT, sizeof(col_array[0]), col_array[0]); VA_SetElem2(vert_array[0],0, vid.height); VA_SetElem2(vert_array[1],vid.width, vid.height); VA_SetElem2(vert_array[2],vid.width, 0); VA_SetElem2(vert_array[3],0, 0); VA_SetElem2(tex_array[0],r_colorbuffer->sl, r_colorbuffer->tl); VA_SetElem2(tex_array[1],r_colorbuffer->sh, r_colorbuffer->tl); VA_SetElem2(tex_array[2],r_colorbuffer->sh, r_colorbuffer->th); VA_SetElem2(tex_array[3],r_colorbuffer->sl, r_colorbuffer->th); R_DrawVarrays(GL_QUADS, 0, 4); //now blur horizontally glUniform1iARB( g_location_source, 0); glUniform2fARB( g_location_scale, 2.0/vid.width, 4.0/vid.height); qglEnableClientState (GL_VERTEX_ARRAY); qglEnableClientState (GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer (2, GL_FLOAT, sizeof(tex_array[0]), tex_array[0]); qglVertexPointer (2, GL_FLOAT, sizeof(vert_array[0]), vert_array[0]); qglColorPointer (4, GL_FLOAT, sizeof(col_array[0]), col_array[0]); VA_SetElem2(vert_array[0],0, vid.height); VA_SetElem2(vert_array[1],vid.width, vid.height); VA_SetElem2(vert_array[2],vid.width, 0); VA_SetElem2(vert_array[3],0, 0); VA_SetElem2(tex_array[0],r_colorbuffer->sl, r_colorbuffer->tl); VA_SetElem2(tex_array[1],r_colorbuffer->sh, r_colorbuffer->tl); VA_SetElem2(tex_array[2],r_colorbuffer->sh, r_colorbuffer->th); VA_SetElem2(tex_array[3],r_colorbuffer->sl, r_colorbuffer->th); R_DrawVarrays(GL_QUADS, 0, 4); R_KillVArrays(); glUseProgramObjectARB(0); } //revert settings qglMatrixMode(GL_PROJECTION); qglPopMatrix(); qglMatrixMode(GL_MODELVIEW); qglPopMatrix(); qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); qglDisable ( GL_BLEND ); qglEnable (GL_TEXTURE_2D); qglEnable (GL_DEPTH_TEST); qglDisable(GL_STENCIL_TEST); qglEnable(GL_CULL_FACE); qglColor4f(1,1,1,1); } /* ================= R_FB_InitTextures ================= */ void R_FB_InitTextures( void ) { byte *data; int size, x, y; byte nullpic[16][16][4]; // // blank texture // for (x = 0 ; x < 16 ; x++) { for (y = 0 ; y < 16 ; y++) { nullpic[y][x][0] = 255; nullpic[y][x][1] = 255; nullpic[y][x][2] = 255; nullpic[y][x][3] = 255; } } //find closer power of 2 to screen size for (FB_texture_width = 1;FB_texture_width < viddef.width;FB_texture_width *= 2); for (FB_texture_height = 1;FB_texture_height < viddef.height;FB_texture_height *= 2); //limit to 2048x2048 - anything larger is generally going to cause problems, and AA doesn't support res higher if(FB_texture_width > 2048) FB_texture_width = 2048; if(FB_texture_height > 2048) FB_texture_height = 2048; //init the framebuffer texture size = FB_texture_width * FB_texture_height * 4; data = malloc( size ); memset( data, 255, size ); r_framebuffer = GL_LoadPic( "***r_framebuffer***", (byte *)data, FB_texture_width, FB_texture_height, it_pic, 3 ); free ( data ); //init the various FBO textures size = FB_texture_width * FB_texture_height * 4; data = malloc( size ); memset( data, 255, size ); r_colorbuffer = GL_LoadPic( "***r_colorbuffer***", (byte *)data, FB_texture_width, FB_texture_height, it_pic, 3 ); free ( data ); //init the distortion textures r_distortwave = GL_FindImage("gfx/distortwave.jpg", it_pic); if (!r_distortwave) r_distortwave = GL_LoadPic ("***r_distortwave***", (byte *)nullpic, 16, 16, it_pic, 32); r_droplets = GL_FindImage("gfx/droplets.jpg", it_pic); if (!r_droplets) r_droplets = GL_LoadPic ("***r_droplets***", (byte *)nullpic, 16, 16, it_pic, 32); //init gore/blood textures r_blooddroplets = GL_FindImage("gfx/blooddrops.jpg", it_pic); if (!r_blooddroplets) r_blooddroplets = GL_LoadPic ("***r_blooddroplets***", (byte *)nullpic, 16, 16, it_pic, 32); r_blooddroplets_nm = GL_FindImage("gfx/blooddrops_nm.jpg", it_pic); if (!r_blooddroplets_nm) r_blooddroplets_nm = GL_LoadPic ("***r_blooddroplets_nm***", (byte *)nullpic, 16, 16, it_pic, 32); } extern int vehicle_hud; extern cvar_t *cl_vehicle_huds; void R_DrawVehicleHUD (void) { image_t *gl = NULL; rscript_t *rs = NULL; float alpha; rs_stage_t *stage; char shortname[MAX_QPATH]; //draw image over screen if(!cl_vehicle_huds->integer) return; switch(vehicle_hud) { case 1: gl = R_RegisterPic ("hud_bomber"); break; case 2: gl = R_RegisterPic ("hud_strafer"); break; case 3: gl = R_RegisterPic ("hud_hover"); break; case 0: default: break; } if (!gl) { return; } GL_TexEnv(GL_MODULATE); qglEnable (GL_BLEND); qglBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); qglActiveTextureARB(GL_TEXTURE0); qglBindTexture(GL_TEXTURE_2D, gl->texnum); qglEnableClientState (GL_VERTEX_ARRAY); qglEnableClientState (GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer (2, GL_FLOAT, sizeof(tex_array[0]), tex_array[0]); qglVertexPointer (2, GL_FLOAT, sizeof(vert_array[0]), vert_array[0]); qglColorPointer (4, GL_FLOAT, sizeof(col_array[0]), col_array[0]); VA_SetElem2(vert_array[0],0, 0); VA_SetElem2(vert_array[1],vid.width, 0); VA_SetElem2(vert_array[2],vid.width, vid.height); VA_SetElem2(vert_array[3],0, vid.height); VA_SetElem2(tex_array[0],gl->sl, gl->tl); VA_SetElem2(tex_array[1],gl->sh, gl->tl); VA_SetElem2(tex_array[2],gl->sh, gl->th); VA_SetElem2(tex_array[3],gl->sl, gl->th); qglMatrixMode( GL_PROJECTION ); qglLoadIdentity (); qglOrtho(0, viddef.width, viddef.height, 0, -10, 100); qglMatrixMode( GL_MODELVIEW ); qglLoadIdentity (); R_DrawVarrays(GL_QUADS, 0, 4); COM_StripExtension ( gl->name, shortname ); rs = gl->script; if(r_shaders->integer && rs) { RS_ReadyScript(rs); stage=rs->stage; while (stage) { //change to use shader def qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); alpha=1.0f; if (stage->alphashift.min || stage->alphashift.speed) { if (!stage->alphashift.speed && stage->alphashift.min > 0) { alpha=stage->alphashift.min; } else if (stage->alphashift.speed) { alpha=sin(rs_realtime * stage->alphashift.speed); alpha=(alpha+1)*0.5f; if (alpha > stage->alphashift.max) alpha=stage->alphashift.max; if (alpha < stage->alphashift.min) alpha=stage->alphashift.min; } } qglEnableClientState (GL_VERTEX_ARRAY); qglEnableClientState (GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer (2, GL_FLOAT, sizeof(tex_array[0]), tex_array[0]); qglVertexPointer (2, GL_FLOAT, sizeof(vert_array[0]), vert_array[0]); qglColorPointer (4, GL_FLOAT, sizeof(col_array[0]), col_array[0]); VA_SetElem2(vert_array[0],0, 0); VA_SetElem2(vert_array[1],vid.width, 0); VA_SetElem2(vert_array[2],vid.width, vid.height); VA_SetElem2(vert_array[3],0, vid.height); qglColor4f(1,1,1, alpha); VA_SetElem4(col_array[0], 1,1,1, alpha); VA_SetElem4(col_array[1], 1,1,1, alpha); VA_SetElem4(col_array[2], 1,1,1, alpha); VA_SetElem4(col_array[3], 1,1,1, alpha); if (stage->anim_count) GL_Bind(RS_Animate(stage)); else GL_Bind (stage->texture->texnum); VA_SetElem2(tex_array[0],gl->sl, gl->tl); VA_SetElem2(tex_array[1],gl->sh, gl->tl); VA_SetElem2(tex_array[2],gl->sh, gl->th); VA_SetElem2(tex_array[3],gl->sl, gl->th); qglMatrixMode( GL_PROJECTION ); qglLoadIdentity (); qglOrtho(0, viddef.width, viddef.height, 0, -10, 100); qglMatrixMode( GL_MODELVIEW ); qglLoadIdentity (); R_DrawVarrays(GL_QUADS, 0, 4); stage=stage->next; } } qglColor4f(1,1,1,1); qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); qglDisable (GL_BLEND); GL_TexEnv(GL_REPLACE); R_KillVArrays(); } void R_DrawBloodEffect (void) { image_t *gl = NULL; gl = R_RegisterPic ("blood_ring"); if (!gl) { return; } qglEnable (GL_BLEND); qglActiveTextureARB(GL_TEXTURE0); qglBindTexture(GL_TEXTURE_2D, gl->texnum); qglEnableClientState (GL_VERTEX_ARRAY); qglEnableClientState (GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer (2, GL_FLOAT, sizeof(tex_array[0]), tex_array[0]); qglVertexPointer (2, GL_FLOAT, sizeof(vert_array[0]), vert_array[0]); qglColorPointer (4, GL_FLOAT, sizeof(col_array[0]), col_array[0]); VA_SetElem2(vert_array[0],0, 0); VA_SetElem2(vert_array[1],vid.width, 0); VA_SetElem2(vert_array[2],vid.width, vid.height); VA_SetElem2(vert_array[3],0, vid.height); VA_SetElem2(tex_array[0],gl->sl, gl->tl); VA_SetElem2(tex_array[1],gl->sh, gl->tl); VA_SetElem2(tex_array[2],gl->sh, gl->th); VA_SetElem2(tex_array[3],gl->sl, gl->th); qglMatrixMode( GL_PROJECTION ); qglLoadIdentity (); qglOrtho(0, viddef.width, viddef.height, 0, -10, 100); qglMatrixMode( GL_MODELVIEW ); qglLoadIdentity (); R_DrawVarrays(GL_QUADS, 0, 4); qglDisable (GL_BLEND); R_KillVArrays(); } extern void PART_RenderSunFlare(image_t * tex, float offset, float size, float r, float g, float b, float alpha); extern void R_DrawShadowMapWorld (qboolean forEnt, vec3_t origin); extern void R_DrawVegetationCasters( qboolean forShadows ); extern float sun_alpha; extern void MYgluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar); void R_GLSLGodRays(void) { float size, screenaspect; vec2_t fxScreenPos; vec3_t origin = {0, 0, 0}; if(!r_godrays->integer || !r_drawsun->integer) return; if (!draw_sun || sun_alpha <= 0) return; //switch to fbo qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId[2]); //need color buffer qglDisable( GL_DEPTH_TEST ); qglDepthMask (1); qglClear ( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); //render sun object center qglMatrixMode(GL_PROJECTION); qglPushMatrix(); qglLoadIdentity(); qglOrtho(0, r_newrefdef.width, r_newrefdef.height, 0, -99999, 99999); qglMatrixMode(GL_MODELVIEW); qglPushMatrix(); qglLoadIdentity(); size = r_newrefdef.width * sun_size/4.0; PART_RenderSunFlare(sun2_object, 0, size, 1.0, 1.0, 1.0, 1.0); qglPopMatrix(); qglMatrixMode(GL_PROJECTION); qglPopMatrix(); qglLoadIdentity(); //render occuders simple, textureless //need to set up proper matrix for this view! screenaspect = (float)r_newrefdef.width/(float)r_newrefdef.height; if(r_newrefdef.fov_y < 90) MYgluPerspective (r_newrefdef.fov_y, screenaspect, 4, 128000); else MYgluPerspective(r_newrefdef.fov_y, screenaspect, 4 * 74 / r_newrefdef.fov_y, 15000); qglMatrixMode(GL_MODELVIEW); qglLoadIdentity (); qglRotatef (-90, 1, 0, 0); // put Z going up qglRotatef (90, 0, 0, 1); // put Z going up qglRotatef (-r_newrefdef.viewangles[2], 1, 0, 0); qglRotatef (-r_newrefdef.viewangles[0], 0, 1, 0); qglRotatef (-r_newrefdef.viewangles[1], 0, 0, 1); qglTranslatef (-r_newrefdef.vieworg[0], -r_newrefdef.vieworg[1], -r_newrefdef.vieworg[2]); qglCullFace(GL_FRONT); if (gl_cull->integer) qglEnable(GL_CULL_FACE); R_DrawShadowMapWorld(false, origin); //could tweak this to only draw surfaces that are in the sun? R_DrawVegetationCasters(false); qglMatrixMode(GL_PROJECTION); qglPushMatrix(); qglLoadIdentity(); qglOrtho(0, r_newrefdef.width, r_newrefdef.height, 0, -99999, 99999); qglMatrixMode(GL_MODELVIEW); qglPushMatrix(); qglLoadIdentity(); //glsl the fbo with effect qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glUseProgramObjectARB( g_godraysprogramObj ); qglActiveTextureARB(GL_TEXTURE0); qglBindTexture(GL_TEXTURE_2D, r_colorbuffer->texnum); glUniform1iARB( g_location_sunTex, 0); R_TransformVectorToScreen(&r_newrefdef, sun_origin, fxScreenPos); fxScreenPos[0] /= viddef.width; fxScreenPos[1] /= viddef.height; glUniform2fARB( g_location_lightPositionOnScreen, fxScreenPos[0], fxScreenPos[1]); glUniform1fARB( g_location_godrayScreenAspect, screenaspect); glUniform1fARB( g_location_sunRadius, sun_size*r_godray_intensity->value); //render quad qglEnable (GL_BLEND); qglBlendFunc(GL_SRC_ALPHA, GL_ONE); qglDisable(GL_CULL_FACE); qglEnableClientState (GL_VERTEX_ARRAY); qglEnableClientState (GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer (2, GL_FLOAT, sizeof(tex_array[0]), tex_array[0]); qglVertexPointer (2, GL_FLOAT, sizeof(vert_array[0]), vert_array[0]); qglColorPointer (4, GL_FLOAT, sizeof(col_array[0]), col_array[0]); VA_SetElem2(vert_array[0],0, vid.height); VA_SetElem2(vert_array[1],vid.width, vid.height); VA_SetElem2(vert_array[2],vid.width, 0); VA_SetElem2(vert_array[3],0, 0); VA_SetElem2(tex_array[0],r_colorbuffer->sl, r_colorbuffer->tl); VA_SetElem2(tex_array[1],r_colorbuffer->sh, r_colorbuffer->tl); VA_SetElem2(tex_array[2],r_colorbuffer->sh, r_colorbuffer->th); VA_SetElem2(tex_array[3],r_colorbuffer->sl, r_colorbuffer->th); R_DrawVarrays(GL_QUADS, 0, 4); qglDisable (GL_BLEND); qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); R_KillVArrays(); glUseProgramObjectARB( 0 ); qglPopMatrix(); qglMatrixMode(GL_PROJECTION); qglPopMatrix(); qglMatrixMode(GL_MODELVIEW); } void R_GLSLPostProcess(void) { if(gl_glsl_shaders->integer && gl_state.glsl_shaders) { R_GLSLGodRays(); R_GLSLWaterDroplets(); R_GLSLDistortion(); } } alien-arena-7.66+dfsg/source/ref_gl/r_shadows.c0000600000175000017500000004665212161402007020520 0ustar zero79zero79/* Copyright (C) 2009 COR Entertainment, LLC This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Notes on shadow rendering: CRX uses a combination of shadowmapping and stencil volumes for it's shadowing effects. The shadow maps are used for dynamic shadows only, while the stencil volumes are used for static items and vegetation. There are a couple of compelling reaons why we do this. First, the goal is speed. It is slightly faster to create the volumes than it is to render the mesh to create a shadow caster. Another consideration is that the stencil volumes cast on any object without the need for a shader to be present. We are able to create a soft shadow effect by blitting the stencil buffer to an offscreen FBO, blurring it in a GLSL shader, then rendering the image on a single quad overlay with the correct blending. The drawbacks are that we do not have fading penumbras(this could change depending on what the idtech 4 shadow code looks like). Dynamic shadows are handled via shadowmaps since dynamic lighting is handled using GLSL. This allows us to easily create fading penumbras with dynamic lights. While it is slightly slower, it allows for an excellent, and accurate effect. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "r_local.h" #include "r_ragdoll.h" /* =============== SHADOW VOLUMES =============== */ glStencilFuncSeparatePROC qglStencilFuncSeparate = NULL; glStencilOpSeparatePROC qglStencilOpSeparate = NULL; glStencilMaskSeparatePROC qglStencilMaskSeparate = NULL; extern glStencilFuncSeparatePROC qglStencilFuncSeparate; extern glStencilOpSeparatePROC qglStencilOpSeparate; extern glStencilMaskSeparatePROC qglStencilMaskSeparate; extern void R_ShadowBlend(float alpha); vec3_t ShadowArray[MAX_SHADOW_VERTS]; static qboolean triangleFacingLight [MAX_INDICES / 3]; static vec4_t shadow_lerped[MAX_VERTS]; void R_InitShadowSubsystem(void) { // openGL 2.0 Unified Separate Stencil gl_state.stencil_wrap = false; if (strstr(gl_config.extensions_string, "GL_EXT_stencil_wrap")) { Com_Printf("...using GL_EXT_stencil_wrap\n"); gl_state.stencil_wrap = true; } else { Com_Printf("...GL_EXT_stencil_wrap not found\n"); gl_state.stencil_wrap = false; } qglStencilFuncSeparate = (void *)qwglGetProcAddress("glStencilFuncSeparate"); qglStencilOpSeparate = (void *)qwglGetProcAddress("glStencilOpSeparate"); qglStencilMaskSeparate = (void *)qwglGetProcAddress("glStencilMaskSeparate"); gl_state.separateStencil = false; if(qglStencilFuncSeparate && qglStencilOpSeparate && qglStencilMaskSeparate) { Com_Printf("...using GL_EXT_stencil_two_side\n"); gl_state.separateStencil = true; } else Com_Printf("...GL_EXT_stencil_two_side not found\n"); } void SHD_LerpVerts(int nverts, dtrivertx_t *v, dtrivertx_t *ov, float *lerp, float move[3], float frontv[3], float backv[3]) { int i; for (i = 0; i < nverts; i++, v++, ov++, lerp += 4) { lerp[0] = move[0] + ov->v[0]*backv[0] + v->v[0]*frontv[0]; lerp[1] = move[1] + ov->v[1]*backv[1] + v->v[1]*frontv[1]; lerp[2] = move[2] + ov->v[2]*backv[2] + v->v[2]*frontv[2]; } } void SHD_MarkShadowTriangles(dmdl_t *paliashdr, dtriangle_t *tris, vec3_t lightOrg, qboolean lerp) { vec3_t r_triangleNormals[MAX_INDICES / 3]; vec3_t temp, dir0, dir1; int i; float f; float *v0, *v1, *v2; for (i = 0; i < paliashdr->num_tris; i++, tris++) { if(lerp) { v0 = (float*)shadow_lerped[tris->index_xyz[0]]; v1 = (float*)shadow_lerped[tris->index_xyz[1]]; v2 = (float*)shadow_lerped[tris->index_xyz[2]]; } else { v0 = (float*)currentmodel->vertexes[tris->index_xyz[0]].position; v1 = (float*)currentmodel->vertexes[tris->index_xyz[1]].position; v2 = (float*)currentmodel->vertexes[tris->index_xyz[2]].position; } //Calculate shadow volume triangle normals VectorSubtract( v0, v1, dir0 ); VectorSubtract( v2, v1, dir1 ); CrossProduct( dir0, dir1, r_triangleNormals[i] ); // Find front facing triangles VectorSubtract(lightOrg, v0, temp); f = DotProduct(temp, r_triangleNormals[i]); triangleFacingLight[i] = f > 0; } } void SHD_BuildShadowVolume(dmdl_t * hdr, vec3_t light, float projectdistance, qboolean lerp) { dtriangle_t *ot, *tris; neighbors_t *neighbors; int i, j, shadow_vert = 0, index = 0; unsigned ShadowIndex[MAX_INDICES]; vec3_t v0, v1, v2, v3; vec3_t currentShadowLight; daliasframe_t *frame; dtrivertx_t *verts; frame = (daliasframe_t *) ((byte *) hdr + hdr->ofs_frames + currententity->frame * hdr->framesize); verts = frame->verts; ot = tris = (dtriangle_t *) ((unsigned char *) hdr + hdr->ofs_tris); SHD_MarkShadowTriangles(hdr, tris, light, lerp); VectorCopy(light, currentShadowLight); for (i = 0, tris = ot, neighbors = currentmodel->neighbors; i < hdr->num_tris; i++, tris++, neighbors++) { if (!triangleFacingLight[i]) continue; if (neighbors->n[0] < 0 || !triangleFacingLight[neighbors->n[0]]) { for (j = 0; j < 3; j++) { if(lerp) { v0[j] = shadow_lerped[tris->index_xyz[1]][j]; v1[j] = shadow_lerped[tris->index_xyz[0]][j]; } else { v0[j] = currentmodel->vertexes[tris->index_xyz[1]].position[j]; v1[j] = currentmodel->vertexes[tris->index_xyz[0]].position[j]; } v2[j] = v1[j] + ((v1[j] - light[j]) * projectdistance); v3[j] = v0[j] + ((v0[j] - light[j]) * projectdistance); } VA_SetElem3(ShadowArray[shadow_vert+0], v0[0], v0[1], v0[2]); VA_SetElem3(ShadowArray[shadow_vert+1], v1[0], v1[1], v1[2]); VA_SetElem3(ShadowArray[shadow_vert+2], v2[0], v2[1], v2[2]); VA_SetElem3(ShadowArray[shadow_vert+3], v3[0], v3[1], v3[2]); ShadowIndex[index++] = shadow_vert+0; ShadowIndex[index++] = shadow_vert+1; ShadowIndex[index++] = shadow_vert+3; ShadowIndex[index++] = shadow_vert+3; ShadowIndex[index++] = shadow_vert+1; ShadowIndex[index++] = shadow_vert+2; shadow_vert +=4; } if (neighbors->n[1] < 0 || !triangleFacingLight[neighbors->n[1]]) { for (j = 0; j < 3; j++) { if(lerp) { v0[j] = shadow_lerped[tris->index_xyz[2]][j]; v1[j] = shadow_lerped[tris->index_xyz[1]][j]; } else { v0[j] = currentmodel->vertexes[tris->index_xyz[2]].position[j]; v1[j] = currentmodel->vertexes[tris->index_xyz[1]].position[j]; } v2[j] = v1[j] + ((v1[j] - light[j]) * projectdistance); v3[j] = v0[j] + ((v0[j] - light[j]) * projectdistance); } VA_SetElem3(ShadowArray[shadow_vert+0], v0[0], v0[1], v0[2]); VA_SetElem3(ShadowArray[shadow_vert+1], v1[0], v1[1], v1[2]); VA_SetElem3(ShadowArray[shadow_vert+2], v2[0], v2[1], v2[2]); VA_SetElem3(ShadowArray[shadow_vert+3], v3[0], v3[1], v3[2]); ShadowIndex[index++] = shadow_vert+0; ShadowIndex[index++] = shadow_vert+1; ShadowIndex[index++] = shadow_vert+3; ShadowIndex[index++] = shadow_vert+3; ShadowIndex[index++] = shadow_vert+1; ShadowIndex[index++] = shadow_vert+2; shadow_vert +=4; } if (neighbors->n[2] < 0 || !triangleFacingLight[neighbors->n[2]]) { for (j = 0; j < 3; j++) { if(lerp) { v0[j] = shadow_lerped[tris->index_xyz[0]][j]; v1[j] = shadow_lerped[tris->index_xyz[2]][j]; } else { v0[j] = currentmodel->vertexes[tris->index_xyz[0]].position[j]; v1[j] = currentmodel->vertexes[tris->index_xyz[2]].position[j]; } v2[j] = v1[j] + ((v1[j] - light[j]) * projectdistance); v3[j] = v0[j] + ((v0[j] - light[j]) * projectdistance); } VA_SetElem3(ShadowArray[shadow_vert+0], v0[0], v0[1], v0[2]); VA_SetElem3(ShadowArray[shadow_vert+1], v1[0], v1[1], v1[2]); VA_SetElem3(ShadowArray[shadow_vert+2], v2[0], v2[1], v2[2]); VA_SetElem3(ShadowArray[shadow_vert+3], v3[0], v3[1], v3[2]); ShadowIndex[index++] = shadow_vert+0; ShadowIndex[index++] = shadow_vert+1; ShadowIndex[index++] = shadow_vert+3; ShadowIndex[index++] = shadow_vert+3; ShadowIndex[index++] = shadow_vert+1; ShadowIndex[index++] = shadow_vert+2; shadow_vert +=4; } } // triangle is frontface and therefore casts shadow, // output front and back caps for shadow volume front cap for (i = 0, tris = ot; i < hdr->num_tris; i++, tris++) { if (!triangleFacingLight[i]) continue; for (j = 0; j < 3; j++) { if(lerp) { v0[j] = shadow_lerped[tris->index_xyz[0]][j]; v1[j] = shadow_lerped[tris->index_xyz[1]][j]; v2[j] = shadow_lerped[tris->index_xyz[2]][j]; } else { v0[j] = currentmodel->vertexes[tris->index_xyz[0]].position[j]; v1[j] = currentmodel->vertexes[tris->index_xyz[1]].position[j]; v2[j] = currentmodel->vertexes[tris->index_xyz[2]].position[j]; } } VA_SetElem3(ShadowArray[shadow_vert+0], v0[0], v0[1], v0[2]); VA_SetElem3(ShadowArray[shadow_vert+1], v1[0], v1[1], v1[2]); VA_SetElem3(ShadowArray[shadow_vert+2], v2[0], v2[1], v2[2]); ShadowIndex[index++] = shadow_vert+0; ShadowIndex[index++] = shadow_vert+1; ShadowIndex[index++] = shadow_vert+2; shadow_vert +=3; // rear cap (with flipped winding order) for (j = 0; j < 3; j++) { if(lerp) { v0[j] = shadow_lerped[tris->index_xyz[0]][j]; v1[j] = shadow_lerped[tris->index_xyz[1]][j]; v2[j] = shadow_lerped[tris->index_xyz[2]][j]; } else { v0[j] = currentmodel->vertexes[tris->index_xyz[0]].position[j]; v1[j] = currentmodel->vertexes[tris->index_xyz[1]].position[j]; v2[j] = currentmodel->vertexes[tris->index_xyz[2]].position[j]; } v0[j] = v0[j] + ((v0[j] - light[j]) * projectdistance); v1[j] = v1[j] + ((v1[j] - light[j]) * projectdistance); v2[j] = v2[j] + ((v2[j] - light[j]) * projectdistance); } VA_SetElem3(ShadowArray[shadow_vert+0], v0[0], v0[1], v0[2]); VA_SetElem3(ShadowArray[shadow_vert+1], v1[0], v1[1], v1[2]); VA_SetElem3(ShadowArray[shadow_vert+2], v2[0], v2[1], v2[2]); ShadowIndex[index++] = shadow_vert+2; ShadowIndex[index++] = shadow_vert+1; ShadowIndex[index++] = shadow_vert+0; shadow_vert +=3; } if(shadow_vert > 0) { if ( qglLockArraysEXT != 0 ) qglLockArraysEXT( 0, shadow_vert ); qglDrawElements(GL_TRIANGLES, index, GL_UNSIGNED_INT, ShadowIndex); if ( qglUnlockArraysEXT != 0 ) qglUnlockArraysEXT(); } } void SHD_RenderVolumes(dmdl_t * paliashdr, vec3_t lightdir, int projdist, qboolean lerp) { int incr = gl_state.stencil_wrap ? GL_INCR_WRAP_EXT : GL_INCR; int decr = gl_state.stencil_wrap ? GL_DECR_WRAP_EXT : GL_DECR; if(VectorCompare(lightdir, vec3_origin)) return; if(gl_state.separateStencil) { qglDisable(GL_CULL_FACE); qglStencilOpSeparate(GL_BACK, GL_KEEP, incr, GL_KEEP); qglStencilOpSeparate(GL_FRONT, GL_KEEP, decr, GL_KEEP); SHD_BuildShadowVolume(paliashdr, lightdir, projdist, lerp); qglEnable(GL_CULL_FACE); } else { qglEnable(GL_CULL_FACE); qglCullFace(GL_BACK); qglStencilOp(GL_KEEP, incr, GL_KEEP); SHD_BuildShadowVolume(paliashdr, lightdir, projdist, lerp); qglCullFace(GL_FRONT); qglStencilOp(GL_KEEP, decr, GL_KEEP); SHD_BuildShadowVolume(paliashdr, lightdir, projdist, lerp); } } void SHD_DrawAliasShadowVolume(dmdl_t * paliashdr, qboolean lerp) { vec3_t light, temp, tempOrg; int i, j, o; float cost, sint; float is, it, dist; int worldlight = 0; float numlights, weight; float bob, project; trace_t r_trace; vec3_t mins, maxs, lightAdd; VectorSet(mins, 0, 0, 0); VectorSet(maxs, 0, 0, 0); if(currententity->flags & RF_BOBBING) bob = currententity->bob; else bob = 0; VectorCopy(currententity->origin, tempOrg); tempOrg[2] -= bob; VectorClear(light); cost = cos(-currententity->angles[1] / 180 * M_PI), sint = sin(-currententity->angles[1] / 180 * M_PI); numlights = 0; VectorClear(lightAdd); for (i=0; iorigin[2] - bob) continue; //don't bother with world lights below the ent, creates undesirable shadows //need a trace(not for self model, too jerky when lights are blocked and reappear) if(!(currententity->flags & RF_VIEWERMODEL)) { r_trace = CM_BoxTrace(tempOrg, LightGroups[i].group_origin, mins, maxs, r_worldmodel->firstnode, MASK_OPAQUE); if(r_trace.fraction != 1.0) continue; } VectorSubtract(LightGroups[i].group_origin, currententity->origin, temp); dist = VectorLength(temp); //accum and weight weight = (int)250000/(dist/(LightGroups[i].avg_intensity+1.0f)); for(j = 0; j < 3; j++) lightAdd[j] += LightGroups[i].group_origin[j]*weight; numlights+=weight; if(numlights > 0.0) { for(o = 0; o < 3; o++) light[o] = -currententity->origin[o] + lightAdd[o]/numlights; is = light[0], it = light[1]; light[0] = (cost * (is - 0) + sint * (0 - it) + 0); light[1] = (cost * (it - 0) + sint * (is - 0) + 0); light[2] += currententity->model->maxs[2] + 56; } worldlight++; } if(!worldlight) { //no lights found, create light straight down VectorSet(light, 0, 0, 200); is = light[0], it = light[1]; light[0] = (cost * (is - 0) + sint * (0 - it) + 0); light[1] = (cost * (it - 0) + sint * (is - 0) + 0); light[2] += 8; } if(currentmodel->maxs[2] - currentmodel->mins[2] > 200) project = 2.0; else project = 1.5; SHD_RenderVolumes(paliashdr, light, project, lerp); } void SHD_DrawShadowVolume() { dmdl_t *paliashdr=NULL; vec3_t move, delta, vectors[3]; vec3_t frontv, backv; int i; qboolean lerped=false; if(currentmodel->type == mod_alias) { daliasframe_t *frame, *oldframe; dtrivertx_t *v, *ov, *verts; float *lerp; float frontlerp; paliashdr = (dmdl_t *) currentmodel->extradata; if ( (currententity->frame >= paliashdr->num_frames) || (currententity->frame < 0) ) { currententity->frame = 0; currententity->oldframe = 0; } if(currententity->frame == 0 && currentmodel->num_frames == 1) lerped = false; else lerped = true; if(lerped) frame = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames + currententity->frame * paliashdr->framesize); else frame = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames); verts = v = frame->verts; if(lerped) { if ( (currententity->oldframe >= paliashdr->num_frames) || (currententity->oldframe < 0)) { currententity->frame = 0; currententity->oldframe = 0; } oldframe = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames + currententity->oldframe * paliashdr->framesize); ov = oldframe->verts; if ( !r_lerpmodels->value ) currententity->backlerp = 0; frontlerp = 1.0 - currententity->backlerp; // move should be the delta back to the previous frame * backlerp VectorSubtract(currententity->oldorigin, currententity->origin, delta); AngleVectors(currententity->angles, vectors[0], vectors[1], vectors[2]); move[0] = DotProduct(delta, vectors[0]); // forward move[1] = -DotProduct(delta, vectors[1]); // left move[2] = DotProduct(delta, vectors[2]); // up if(oldframe && oldframe->translate) VectorAdd(move, oldframe->translate, move); for (i = 0; i < 3; i++) { move[i] = currententity->backlerp * move[i] + frontlerp * frame->translate[i]; frontv[i] = frontlerp * frame->scale[i]; backv[i] = currententity->backlerp * oldframe->scale[i]; } lerp = shadow_lerped[0]; SHD_LerpVerts(paliashdr->num_xyz, v, ov, lerp, move, frontv, backv); } } qglPushMatrix(); qglDisable(GL_TEXTURE_2D); qglTranslatef(currententity->origin[0], currententity->origin[1], currententity->origin[2]); qglRotatef(currententity->angles[1], 0, 0, 1); if(currentmodel->type == mod_alias) SHD_DrawAliasShadowVolume(paliashdr, lerped); qglEnable(GL_TEXTURE_2D); qglPopMatrix(); } #include "r_lodcalc.h" //to do - all of this will be replaced by shadowmapping extern cvar_t *cl_simpleitems; void R_CastShadow(void) { int i; vec3_t dist, tmp; float rad, thresh; trace_t r_trace; //note - we use a combination of stencil volumes(for world light shadows) and shadowmaps(for dynamic shadows) if (!gl_shadowmaps->value) return; if (r_newrefdef.rdflags & RDF_NOWORLDMODEL) return; qglEnableClientState(GL_VERTEX_ARRAY); qglVertexPointer(3, GL_FLOAT, sizeof(vec3_t), ShadowArray); qglClear(GL_STENCIL_BUFFER_BIT); qglColorMask(0,0,0,0); qglEnable(GL_STENCIL_TEST); qglDepthFunc (GL_LESS); qglDepthMask(0); qglEnable(GL_POLYGON_OFFSET_FILL); qglPolygonOffset(0.0f, 1000.0f); if(gl_state.separateStencil) qglStencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, 0x0, 0xFF); else qglStencilFunc( GL_ALWAYS, 0x0, 0xFF); for (i = 0; i < r_newrefdef.num_entities; i++) { currententity = &r_newrefdef.entities[i]; if (currententity-> flags & (RF_SHELL_HALF_DAM | RF_SHELL_GREEN | RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_WEAPONMODEL | RF_NOSHADOWS | RF_TRANSLUCENT)) continue; currentmodel = currententity->model; if (!currentmodel) continue; if (currentmodel->type != mod_alias) continue; if (cl_simpleitems->integer && currentmodel->simple_texnum != 0) continue; if (r_newrefdef.vieworg[2] < (currententity->origin[2] - 128)) continue; VectorSubtract(currententity->model->maxs, currententity->model->mins, tmp); VectorScale (tmp, 1.666, tmp); rad = VectorLength (tmp); if( R_CullSphere( currententity->origin, rad, 15 ) ) continue; if (r_worldmodel ) { //occulusion culling - why draw shadows of entities we cannot see? r_trace = CM_BoxTrace(r_origin, currententity->origin, currentmodel->maxs, currentmodel->mins, r_worldmodel->firstnode, MASK_OPAQUE); if(r_trace.fraction != 1.0) continue; } //get distance, set lod if available VectorSubtract(r_origin, currententity->origin, dist); //keep some of the truly massive items from having bad disappearing shadow artifacts. thresh = rad*5; if(thresh < 1024) thresh = 1024; //cull by distance if soft shadows if ( VectorLength(dist) > LOD_DIST*(((float)thresh)/500.0) && gl_state.hasFBOblit && atoi(&gl_config.version_string[0]) >= 3.0 ) continue; if(VectorLength(dist) > LOD_DIST*2.0) { if(currententity->lod2) currentmodel = currententity->lod2; } else if(VectorLength(dist) > LOD_DIST) { if(currententity->lod1) currentmodel = currententity->lod1; } SHD_DrawShadowVolume(); } qglDisableClientState(GL_VERTEX_ARRAY); qglColorMask(1,1,1,1); qglDepthMask(1); qglDepthFunc(GL_LEQUAL); qglDisable(GL_POLYGON_OFFSET_FILL); R_ShadowBlend(0.4); } alien-arena-7.66+dfsg/source/ref_gl/r_lodcalc.h0000600000175000017500000000157112161402007020445 0ustar zero79zero79/* ============= LOD calculation The width and height occupied by a model on screen after it's been rendered will scale as the square of the FOV setting, and proportionally to the width/height of the screen itself. Based on the assumption that 500 units is an adequate LOD cutoff distance at 1920*1080 with an FOV of 90, we can scale the LOD cutoff distance to the lowest point where there will be no noticable ugliness. NOTE: Turns out the player's FOV setting goes to fov_x and not fov_y. Go figure. ============= */ #define LOD_BASE_H 1920.0 #define LOD_BASE_W 1080.0 #define LOD_BASE_DIST 500.0 #define LOD_BASE_FOV 90.0 #define LOD_DIST (LOD_BASE_DIST*\ (r_newrefdef.width/LOD_BASE_W)*(r_newrefdef.height/LOD_BASE_H)*\ (LOD_BASE_FOV/r_newrefdef.fov_x)*\ (LOD_BASE_FOV/r_newrefdef.fov_x)) alien-arena-7.66+dfsg/source/ref_gl/r_model.c0000600000175000017500000016323712204310130020140 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. Copyright (C) 2010 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // r_model.c -- model loading and caching #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "r_local.h" #include "r_iqm.h" #include "r_ragdoll.h" #include "client/sound.h" model_t *loadmodel; int modfilelen; void Mod_LoadBrushModel (model_t *mod, void *buffer); model_t *Mod_LoadModel (model_t *mod, qboolean crash); byte mod_novis[MAX_MAP_LEAFS/8]; #define MAX_MOD_KNOWN 512 model_t mod_known[MAX_MOD_KNOWN]; int mod_numknown; // the inline * models from the current map are kept seperate model_t mod_inline[MAX_MOD_KNOWN]; LightGroup_t LightGroups[MAX_LIGHTS]; int r_lightgroups; int registration_sequence; #if defined WIN32_VARIANT char map_music[MAX_PATH]; char map_music_sec[MAX_PATH]; #else char map_music[MAX_OSPATH]; char map_music_sec[MAX_OSPATH]; #endif char map_entitystring[MAX_MAP_ENTSTRING]; int numentitychars; byte *mod_base; /* ================= Mod_LoadEntityString ================= */ void Mod_LoadEntityStrn (lump_t *l) { numentitychars = l->filelen; if (l->filelen > MAX_MAP_ENTSTRING) Sys_Error ("Map has too large entity lump"); memcpy (map_entitystring, mod_base + l->fileofs, l->filelen); } extern char *CM_EntityString (void); void R_RegisterLightGroups (void) { int i; vec3_t dist, mins, maxs; trace_t r_trace; int lnum = 0; qboolean doneShadowGroups = false; qboolean lightWasGrouped = false; VectorSet(mins, 0, 0, 0); VectorSet(maxs, 0, 0, 0); for (i=0; ifirstnode, MASK_OPAQUE); if(!r_worldLights[i].grouped && (lnum < r_numWorldLights) && r_trace.fraction == 1.0f && (VectorLength(dist) < 256.0f)) { r_worldLights[i].grouped = true; VectorAdd(r_worldLights[i].origin, LightGroups[r_lightgroups].accum_origin, LightGroups[r_lightgroups].accum_origin); LightGroups[r_lightgroups].avg_intensity+=(r_worldLights[i].intensity); lnum++; //we grouped an light in this pass lightWasGrouped = true; } } if(!lightWasGrouped) doneShadowGroups = true; else { //we've reach the end, start a new group if(lnum) { VectorScale(LightGroups[r_lightgroups].accum_origin, 1.0/(float)(lnum), LightGroups[r_lightgroups].accum_origin); LightGroups[r_lightgroups].avg_intensity /= (float)lnum; } VectorCopy(LightGroups[r_lightgroups].accum_origin, LightGroups[r_lightgroups].group_origin); r_lightgroups++; if(r_lightgroups > MAX_LIGHTS) doneShadowGroups = true; lnum = 0; } } Com_Printf("Condensed ^2%i worldlights into ^2%i lightgroups\n", r_numWorldLights, r_lightgroups); } /* ================ R_ParseLightEntities parses light entity string ================ */ static void R_ParseLightEntities (void) { int i; char *entString; char *buf, *tok; char block[2048], *bl; vec3_t origin; float intensity; entString = map_entitystring; buf = CM_EntityString(); while (1){ tok = Com_ParseExt(&buf, true); if (!tok[0]) break; // End of data if (Q_strcasecmp(tok, "{")) continue; // Should never happen! // Parse the text inside brackets block[0] = 0; do { tok = Com_ParseExt(&buf, false); if (!Q_strcasecmp(tok, "}")) break; // Done if (!tok[0]) // Newline Q_strcat(block, "\n", sizeof(block)); else { // Token Q_strcat(block, " ", sizeof(block)); Q_strcat(block, tok, sizeof(block)); } } while (buf); // Now look for "classname" tok = strstr(block, "classname"); if (!tok) continue; // Not found // Skip over "classname" and whitespace tok += strlen("classname"); while (*tok && *tok == ' ') tok++; // Next token must be "light" if (Q_strnicmp(tok, "light", 5)) continue; // Not "light" // Finally parse the light entity VectorClear(origin); intensity = 0; bl = block; while (1){ tok = Com_ParseExt(&bl, true); if (!tok[0]) break; // End of data if (!Q_strcasecmp("origin", tok)){ for (i = 0; i < 3; i++){ tok = Com_ParseExt(&bl, false); origin[i] = atof(tok); } } else if (!Q_strcasecmp("light", tok) || !Q_strcasecmp("_light", tok)){ tok = Com_ParseExt(&bl, false); intensity = atof(tok); } else Com_SkipRestOfLine(&bl); } if (!intensity) intensity = 150; // Add it to the list if (r_numWorldLights == MAX_LIGHTS) break; VectorCopy(origin, r_worldLights[r_numWorldLights].origin); r_worldLights[r_numWorldLights].intensity = intensity/2; r_worldLights[r_numWorldLights].surf = NULL; r_numWorldLights++; } } static void R_FindSunTarget (void) { int i; char *entString; char *buf, *tok; char block[2048], *bl; entString = map_entitystring; buf = CM_EntityString(); while (1){ tok = Com_ParseExt(&buf, true); if (!tok[0]) break; // End of data if (Q_strcasecmp(tok, "{")) continue; // Should never happen! // Parse the text inside brackets block[0] = 0; do { tok = Com_ParseExt(&buf, false); if (!Q_strcasecmp(tok, "}")) break; // Done if (!tok[0]) // Newline Q_strcat(block, "\n", sizeof(block)); else { // Token Q_strcat(block, " ", sizeof(block)); Q_strcat(block, tok, sizeof(block)); } } while (buf); // Now look for "targetname" tok = strstr(block, "targetname"); if (!tok) continue; // Not found // Skip over "target" and whitespace tok += strlen("targetname"); while (*tok && *tok == ' ') tok++; // Next token must match the sun targetname if (Q_strnicmp(tok, "moonspot", 8) && Q_strnicmp(tok, "sunspot", 7)) continue; // Finally parse the sun target entity bl = block; while (1){ tok = Com_ParseExt(&bl, true); if (!tok[0]) break; // End of data if (!Q_strcasecmp("origin", tok)){ for (i = 0; i < 3; i++){ tok = Com_ParseExt(&bl, false); r_sunLight->target[i] = atof(tok); } //Com_Printf("Found sun target@ : %4.2f %4.2f %4.2f\n", r_sunLight->target[0], r_sunLight->target[1], r_sunLight->target[2]); } else Com_SkipRestOfLine(&bl); } } } static void R_FindSunEntity (void) { int i; char *entString; char *buf, *tok; char block[2048], *bl; if(r_sunLight) free(r_sunLight); //free at level load r_sunLight = (sunLight_t*)malloc(sizeof(sunLight_t)); r_sunLight->has_Sun = false; entString = map_entitystring; buf = CM_EntityString(); while (1){ tok = Com_ParseExt(&buf, true); if (!tok[0]) break; // End of data if (Q_strcasecmp(tok, "{")) continue; // Should never happen! // Parse the text inside brackets block[0] = 0; do { tok = Com_ParseExt(&buf, false); if (!Q_strcasecmp(tok, "}")) break; // Done if (!tok[0]) // Newline Q_strcat(block, "\n", sizeof(block)); else { // Token Q_strcat(block, " ", sizeof(block)); Q_strcat(block, tok, sizeof(block)); } } while (buf); // Now look for "target" tok = strstr(block, "target"); if (!tok) continue; // Not found // Skip over "target" and whitespace tok += strlen("target"); while (*tok && *tok == ' ') tok++; // Next token must be a valid sun name( to do - maybe read this from the map header if possible?) if (Q_strnicmp(tok, "moonspot", 8) && Q_strnicmp(tok, "sunspot", 7)) continue; strcpy(r_sunLight->targetname, tok); // Finally parse the sun entity bl = block; while (1){ tok = Com_ParseExt(&bl, true); if (!tok[0]) break; // End of data if (!Q_strcasecmp("origin", tok)){ for (i = 0; i < 3; i++){ tok = Com_ParseExt(&bl, false); r_sunLight->origin[i] = atof(tok); r_sunLight->target[i] = 0; //default to this } r_sunLight->has_Sun = true; //Com_Printf("Found sun @ : %4.2f %4.2f %4.2f\n", r_sunLight->origin[0], r_sunLight->origin[1], r_sunLight->origin[2]); } else Com_SkipRestOfLine(&bl); } } if(r_sunLight->has_Sun) R_FindSunTarget(); //find target } /* =============== Mod_PointInLeaf =============== */ mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model) { mnode_t *node; float d; cplane_t *plane; if (!model || !model->nodes) Com_Printf ("Mod_PointInLeaf: bad model"); node = model->nodes; while (1) { if (node->contents != -1) return (mleaf_t *)node; plane = node->plane; d = DotProduct (p,plane->normal) - plane->dist; if (d > 0) node = node->children[0]; else node = node->children[1]; } return NULL; // never reached } /* =================== Mod_DecompressVis =================== */ byte *Mod_DecompressVis (byte *in, model_t *model) { static byte decompressed[MAX_MAP_LEAFS/8]; int c; byte *out; int row; row = (model->vis->numclusters+7)>>3; out = decompressed; if (!in) { // no vis info, so make all visible while (row) { *out++ = 0xff; row--; } return decompressed; } do { if (*in) { *out++ = *in++; continue; } c = in[1]; in += 2; while (c) { *out++ = 0; c--; } } while (out - decompressed < row); return decompressed; } /* ============== Mod_ClusterPVS ============== */ byte *Mod_ClusterPVS (int cluster, model_t *model) { if (cluster == -1 || !model->vis) return mod_novis; return Mod_DecompressVis ( (byte *)model->vis + model->vis->bitofs[cluster][DVIS_PVS], model); } //=============================================================================== /* ================ Mod_Modellist_f ================ */ void Mod_Modellist_f (void) { int i; model_t *mod; int total; total = 0; Com_Printf ("Loaded models:\n"); for (i=0, mod=mod_known ; i < mod_numknown ; i++, mod++) { if (!mod->name[0]) continue; Com_Printf ("%8i : %s\n",mod->extradatasize, mod->name); total += mod->extradatasize; } Com_Printf ("Total resident: %i\n", total); } /* =============== Mod_Init =============== */ void Mod_Init (void) { memset (mod_novis, 0xff, sizeof(mod_novis)); } /* ================== Mod_ForName Loads in a model for the given name ================== */ model_t *Mod_ForName (char *name, qboolean crash) { model_t *mod; unsigned *buf; int i; char shortname[MAX_QPATH], nameShortname[MAX_QPATH]; qboolean is_iqm = false; if (!name[0]) Com_Error (ERR_DROP, "Mod_ForName: NULL name"); // // inline models are grabbed only from worldmodel // if (name[0] == '*') { i = atoi(name+1); if (i < 1 || !r_worldmodel || i >= r_worldmodel->numsubmodels) Com_Error (ERR_DROP, "bad inline model number"); return &mod_inline[i]; } // // search the currently loaded models // for (i=0 , mod=mod_known ; iname[0]) continue; COM_StripExtension(mod->name, shortname); COM_StripExtension(name, nameShortname); if (!strcmp (shortname, nameShortname) ) { if (mod->type == mod_alias || mod->type == mod_iqm) { // Make sure models scripts are definately reloaded between maps image_t *img; img=mod->skins[0]; if (img != NULL) { mod->script = mod->skins[0]->script; if (mod->script) RS_ReadyScript( mod->script ); } } return mod; } } // // find a free model slot spot // for (i=0 , mod=mod_known ; iname[0]) break; // free spot } if (i == mod_numknown) { if (mod_numknown == MAX_MOD_KNOWN) Com_Error (ERR_DROP, "mod_numknown == MAX_MOD_KNOWN"); mod_numknown++; } strcpy (mod->name, name); R_SetSimpleTexnum (mod, name); // // load the file // //if .md2, check for IQM version first COM_StripExtension(mod->name, shortname); strcat(shortname, ".iqm"); modfilelen = FS_LoadFile (shortname, (void*)&buf); if(!buf) //could not find iqm { modfilelen = FS_LoadFile (mod->name, (void*)&buf); if (!buf) { if (crash) Com_Error (ERR_DROP, "Mod_NumForName: %s not found", mod->name); memset (mod->name, 0, sizeof(mod->name)); return NULL; } } else { //we have an .iqm is_iqm = true; strcpy(mod->name, shortname); } loadmodel = mod; if ( developer && developer->integer == 2 ) { // tracing for model loading Com_DPrintf("Mod_ForName: load: %s\n", loadmodel->name ); } // // fill it in // // call the apropriate loader //iqm - try interquake model first if(is_iqm) { if(!Mod_INTERQUAKEMODEL_Load(mod, buf)) Com_Error (ERR_DROP,"Mod_NumForName: wrong fileid for %s", mod->name); } else { switch (LittleLong(*(unsigned *)buf)) { case IDALIASHEADER: loadmodel->extradata = Hunk_Begin (0x300000); Mod_LoadMD2Model (mod, buf); break; case IDBSPHEADER: loadmodel->extradata = Hunk_Begin (0x1500000); Mod_LoadBrushModel (mod, buf); break; default: Com_Error (ERR_DROP,"Mod_NumForName: unknown fileid for %s", mod->name); break; } } loadmodel->extradatasize = Hunk_End (); FS_FreeFile (buf); return mod; } /* =============================================================================== BRUSHMODEL LOADING =============================================================================== */ byte *mod_base; /* ================= Mod_LoadLighting ================= */ void Mod_LoadLighting (lump_t *l) { if (!l->filelen) { loadmodel->lightdata = NULL; return; } loadmodel->lightdata = Hunk_Alloc ( l->filelen); memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen); } /* ================= Mod_LoadVisibility ================= */ void Mod_LoadVisibility (lump_t *l) { int i; if (!l->filelen) { loadmodel->vis = NULL; return; } loadmodel->vis = Hunk_Alloc ( l->filelen); memcpy (loadmodel->vis, mod_base + l->fileofs, l->filelen); loadmodel->vis->numclusters = LittleLong (loadmodel->vis->numclusters); for (i=0 ; ivis->numclusters ; i++) { loadmodel->vis->bitofs[i][0] = LittleLong (loadmodel->vis->bitofs[i][0]); loadmodel->vis->bitofs[i][1] = LittleLong (loadmodel->vis->bitofs[i][1]); } } /* ================= Mod_LoadVertexes ================= */ void Mod_LoadVertexes (lump_t *l) { dvertex_t *in; mvertex_t *out; int i, count; in = (void *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name); count = l->filelen / sizeof(*in); out = Hunk_Alloc ( count*sizeof(*out)); loadmodel->vertexes = out; loadmodel->numvertexes = count; for ( i=0 ; iposition[0] = LittleFloat (in->point[0]); out->position[1] = LittleFloat (in->point[1]); out->position[2] = LittleFloat (in->point[2]); } } /* ================= RadiusFromBounds ================= */ float RadiusFromBounds (vec3_t mins, vec3_t maxs) { int i; vec3_t corner; for (i=0 ; i<3 ; i++) { corner[i] = fabs(mins[i]) > fabs(maxs[i]) ? fabs(mins[i]) : fabs(maxs[i]); } return VectorLength (corner); } /* ================= Mod_LoadSubmodels ================= */ void Mod_LoadSubmodels (lump_t *l) { dmodel_t *in; mmodel_t *out; int i, j, count; in = (void *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name); count = l->filelen / sizeof(*in); out = Hunk_Alloc ( count*sizeof(*out)); loadmodel->submodels = out; loadmodel->numsubmodels = count; for ( i=0 ; imins[j] = LittleFloat (in->mins[j]) - 1; out->maxs[j] = LittleFloat (in->maxs[j]) + 1; } out->radius = RadiusFromBounds (out->mins, out->maxs); out->headnode = LittleLong (in->headnode); out->firstface = LittleLong (in->firstface); out->numfaces = LittleLong (in->numfaces); } } /* ================= Mod_LoadEdges ================= */ void Mod_LoadEdges (lump_t *l) { dedge_t *in; medge_t *out; int i, count; in = (void *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name); count = l->filelen / sizeof(*in); out = Hunk_Alloc ( (count + 1) * sizeof(*out)); loadmodel->edges = out; loadmodel->numedges = count; for ( i=0 ; iv[0] = (unsigned short)LittleShort(in->v[0]); out->v[1] = (unsigned short)LittleShort(in->v[1]); } } /* ================= Mod_LoadTexinfo ================= */ int compare_unique_texinfo (const void *_a, const void *_b) { mtexinfo_t *a = *(mtexinfo_t **)_a, *b = *(mtexinfo_t **)_b; return a->image->texnum-b->image->texnum; } void Mod_LoadTexinfo (lump_t *l) { texinfo_t *in, *in_base; mtexinfo_t *out, *step, **unique_temp; int i, j, count, num_unique; char name[MAX_QPATH]; char sv_name[MAX_QPATH]; int next; in_base = in = (void *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name); count = l->filelen / sizeof(*in); out = Hunk_Alloc ( count*sizeof(*out)); loadmodel->texinfo = out; loadmodel->numtexinfo = count; for ( i=0 ; ivecs[0][j] = LittleFloat (in->vecs[0][j]); out->vecs[1][j] = LittleFloat (in->vecs[1][j]); } out->value = LittleLong (in->value); out->flags = LittleLong (in->flags); next = LittleLong (in->nexttexinfo); if (next > 0 && next < loadmodel->numtexinfo) out->next = loadmodel->texinfo + next; else out->next = NULL; out->equiv = out; Com_sprintf (name, sizeof(name), "textures/%s.wal", in->texture); out->image = GL_FindImage (name, it_wall); Com_sprintf (name, sizeof(name), "textures/%s", in->texture); out->image->script = RS_FindScript(name); if (out->image->script) RS_ReadyScript(out->image->script); //check for normal, height and specular maps strcpy(sv_name, name); if( ( strlen( name ) + 8 ) <= MAX_QPATH ) { strcat( name, "_nm.tga" ); out->normalMap = GL_FindImage( name, it_bump ); if( out->normalMap == NULL ) { out->has_normalmap = false; out->normalMap = out->image; } else out->has_normalmap = true; } else { out->has_normalmap = false; out->normalMap = out->image; } strcpy(name, sv_name); if( ( strlen( name ) + 8 ) <= MAX_QPATH ) { strcat( name, "_hm.tga" ); out->heightMap = GL_FindImage( name, it_bump ); if( out->heightMap == NULL ) { out->has_heightmap = false; out->heightMap = out->image; } else out->has_heightmap = true; } else { out->has_heightmap = false; out->heightMap = out->image; } } // count animation frames for (i=0 ; itexinfo[i]; out->numframes = 1; for (step = out->next ; step && step != out ; step=step->next) out->numframes++; } //find equivalent texinfos num_unique = 0; unique_temp = Z_Malloc (sizeof(mtexinfo_t*)*count); for (i = 0; i < count; i++) { for (j = 0; j < i; j++) { if (in_base[i].flags == in_base[j].flags && in_base[i].nexttexinfo == in_base[j].nexttexinfo && !strcmp (in_base[i].texture, in_base[j].texture)) { loadmodel->texinfo[i].equiv = loadmodel->texinfo[j].equiv; break; } } if (j == i) { unique_temp[num_unique++] = loadmodel->texinfo[i].equiv; } } qsort (unique_temp, num_unique, sizeof(mtexinfo_t*), compare_unique_texinfo); loadmodel->unique_texinfo = Hunk_Alloc (num_unique*sizeof(mtexinfo_t*)); memcpy (loadmodel->unique_texinfo, unique_temp, num_unique*sizeof(mtexinfo_t*)); Z_Free (unique_temp); loadmodel->num_unique_texinfos = num_unique; Com_Printf ("Condensed ^2%i texinfos into ^2%i equivalent texinfos\n", count, num_unique); } /* ================ CalcSurfaceExtents Fills in s->texturemins[] and s->extents[] ================ */ void CalcSurfaceExtents (msurface_t *s, qboolean override, int *smax, int *tmax, float *xscale, float *yscale, int firstedge, int numedges) { float mins[2], maxs[2], val; int i,j, e, vnum; mvertex_t *v; mtexinfo_t *tex; int bmins[2], bmaxs[2]; mins[0] = mins[1] = 999999; maxs[0] = maxs[1] = -99999; tex = s->texinfo; if (firstedge < 0 || firstedge+numedges-1 >= loadmodel->numsurfedges) Com_Error (ERR_DROP, "Map contains invalid value for s->firstedge!\n" "The file is likely corrupted, please obtain a fresh copy."); for (i=0 ; isurfedges[firstedge+i]; if (abs(e) > loadmodel->numedges) Com_Error (ERR_DROP, "Map contains invalid edge offsets!\n" "The file is likely corrupted, please obtain a fresh copy."); if (e >= 0) vnum = loadmodel->edges[e].v[0]; else vnum = loadmodel->edges[-e].v[1]; if (vnum < 0 || vnum >= loadmodel->numvertexes) Com_Error (ERR_DROP, "Map contains invalid vertex offsets!\n" "The file is likely corrupted, please obtain a fresh copy."); v = &loadmodel->vertexes[vnum]; for (j=0 ; j<2 ; j++) { val = v->position[0] * tex->vecs[j][0] + v->position[1] * tex->vecs[j][1] + v->position[2] * tex->vecs[j][2] + tex->vecs[j][3]; if (val < mins[j]) mins[j] = val; if (val > maxs[j]) maxs[j] = val; } } if (!override) { #define DEFAULT_LIGHTMAP_SCALE 16 //each lightmap pixel represents 16x16 units *xscale = *yscale = DEFAULT_LIGHTMAP_SCALE; for (i=0 ; i<2 ; i++) { bmins[i] = floor(mins[i]/DEFAULT_LIGHTMAP_SCALE); bmaxs[i] = ceil(maxs[i]/DEFAULT_LIGHTMAP_SCALE); s->texturemins[i] = bmins[i] * DEFAULT_LIGHTMAP_SCALE; s->extents[i] = (bmaxs[i] - bmins[i]) * DEFAULT_LIGHTMAP_SCALE; } *smax = (s->extents[0]/DEFAULT_LIGHTMAP_SCALE)+1; *tmax = (s->extents[1]/DEFAULT_LIGHTMAP_SCALE)+1; } else { bmins[0] = floor(mins[0]/(*xscale)); bmaxs[0] = ceil(maxs[0]/(*xscale)); s->texturemins[0] = bmins[0] * (*xscale); s->extents[0] = (bmaxs[0] - bmins[0]) * (*xscale); bmins[1] = floor(mins[1]/(*yscale)); bmaxs[1] = ceil(maxs[1]/(*yscale)); s->texturemins[1] = bmins[1] * (*yscale); s->extents[1] = (bmaxs[1] - bmins[1]) * (*yscale); } } void Mod_CalcSurfaceNormals(msurface_t *surf) { glpoly_t *p = surf->polys; float *v; int i; float temp_tangentSpaceTransform[3][3]; for (; p; p = p->chain) { vec3_t v01, v02, temp1, temp2, temp3; vec3_t normal, binormal, tangent; float s = 0; float *vec; _VectorSubtract( p->verts[ 1 ], p->verts[0], v01 ); vec = p->verts[0]; _VectorCopy(surf->plane->normal, normal); // FIXME: on some maps, this code doesn't always initialize v02, // leading to Valgrind complaining about use of uninitialized memory. // dm-infinity and dm-zorn2k11 are two such maps. Probably not a huge // deal, doesn't seem to be causing any issues. for (v = p->verts[0], i = 0 ; i < p->numverts; i++, v += VERTEXSIZE) { float currentLength; vec3_t currentNormal; //do calculations for normal, tangent and binormal if( i > 1) { _VectorSubtract( p->verts[ i ], p->verts[0], temp1 ); CrossProduct( temp1, v01, currentNormal ); currentLength = VectorLength( currentNormal ); if( currentLength > s ) { s = currentLength; _VectorCopy( currentNormal, normal ); vec = p->verts[i]; _VectorCopy( temp1, v02 ); } } } VectorNormalize( normal ); //we have the largest normal temp_tangentSpaceTransform[ 0 ][ 2 ] = normal[ 0 ]; temp_tangentSpaceTransform[ 1 ][ 2 ] = normal[ 1 ]; temp_tangentSpaceTransform[ 2 ][ 2 ] = normal[ 2 ]; //now get the tangent s = ( p->verts[ 1 ][ 3 ] - p->verts[ 0 ][ 3 ] ) * ( vec[ 4 ] - p->verts[ 0 ][ 4 ] ); s -= ( vec[ 3 ] - p->verts[ 0 ][ 3 ] ) * ( p->verts[ 1 ][ 4 ] - p->verts[ 0 ][ 4 ] ); s = 1.0f / s; VectorScale( v01, vec[ 4 ] - p->verts[ 0 ][ 4 ], temp1 ); VectorScale( v02, p->verts[ 1 ][ 4 ] - p->verts[ 0 ][ 4 ], temp2 ); _VectorSubtract( temp1, temp2, temp3 ); VectorScale( temp3, s, tangent ); VectorNormalize( tangent ); temp_tangentSpaceTransform[ 0 ][ 0 ] = tangent[ 0 ]; temp_tangentSpaceTransform[ 1 ][ 0 ] = tangent[ 1 ]; temp_tangentSpaceTransform[ 2 ][ 0 ] = tangent[ 2 ]; //now get the binormal VectorScale( v02, p->verts[ 1 ][ 3 ] - p->verts[ 0 ][ 3 ], temp1 ); VectorScale( v01, vec[ 3 ] - p->verts[ 0 ][ 3 ], temp2 ); _VectorSubtract( temp1, temp2, temp3 ); VectorScale( temp3, s, binormal ); VectorNormalize( binormal ); temp_tangentSpaceTransform[ 0 ][ 1 ] = binormal[ 0 ]; temp_tangentSpaceTransform[ 1 ][ 1 ] = binormal[ 1 ]; temp_tangentSpaceTransform[ 2 ][ 1 ] = binormal[ 2 ]; //Try to find this tangentSpaceTransform in the existing array or else //add it. This is not a RAM-saving measure, it's to allow comparison //of different tangentSpaceTransforms using the == operator, which is //more efficient. { float *tst; int i; int j; for (tst = loadmodel->tangentSpaceTransforms, i = 0; i < loadmodel->numTangentSpaceTransforms; i++, tst += 9) { qboolean match = true; for (j = 0; j < 9; j++) { // If we reduce our precision to just 4 decimal places, // we can cut the number of transforms by a factor of more // than 5. Single-precision floating point is precise to // just 6 places anyway, so we're not loosing too much. // Subjectively, it still looks fine. if (fabs (tst[j]-temp_tangentSpaceTransform[j/3][j%3]) > 0.0001) { match = false; break; } } if (match) break; } surf->tangentSpaceTransform = tst; if (i == loadmodel->numTangentSpaceTransforms) { for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) *(tst++) = temp_tangentSpaceTransform[i][j]; loadmodel->numTangentSpaceTransforms++; } } } } void BSP_BuildPolygonFromSurface(msurface_t *fa, float xscale, float yscale, int light_s, int light_t, int firstedge, int lnumverts); void BSP_CreateSurfaceLightmap (msurface_t *surf, int smax, int tmax, int *light_s, int *light_t); void BSP_EndBuildingLightmaps (void); void BSP_BeginBuildingLightmaps (model_t *m); // FOR REFINE: .lightmap high-detail lightmap override files ltmp_facelookup_t lfacelookups[MAX_MAP_FACES]; int lightdatasize; byte override_lightdata[MAX_OVERRIDE_LIGHTING]; byte *lightmap_header; // choose up to one override for each map face void Mod_LoadRefineFaceLookups (lump_t *l) { int i, count; ltmp_facelookup_t *in; ltmp_facelookup_t *out; if (!l->filelen) return; in = (void *)(lightmap_header+l->fileofs); printf ("%d / %d\n", l->filelen, sizeof(*in)); if (l->filelen % sizeof (*in)) Com_Error (ERR_DROP, "Mod_LoadRefineFaceLookups: funny lump size"); count = l->filelen / sizeof (*in); Com_Printf ("%f\n", in->xscale); for (i = 0; i < count; i++, in++) { int facenum, format, offset, size, width, height; // Silently skip over pixel formats we don't understand. We do this // check first so that in the future it can be used to work around the // following two for backward compatibility. format = LittleLong(in->format); if (format >= LTMP_NUM_SUPPORTED_PIXFMTS) continue; // make a federal case out of bad face offsets facenum = LittleLong(in->facenum); if (facenum >= MAX_MAP_FACES || facenum < 0) Com_Error (ERR_DROP, "Mod_LoadRefineFaceeLookups: bad facenum"); // make a federal case out of bad pixel data offsets offset = LittleLong(in->offset); width = LittleLong(in->width); height = LittleLong(in->height); switch (format) { case LTMP_PIXFMT_RGB24: size = 3*width*height; break; } if (offset < 1 || offset+size > MAX_OVERRIDE_LIGHTING*4) Com_Error (ERR_DROP, "Mod_LoadRefineFaceeLookups: bad offset"); out = &lfacelookups[facenum]; out->offset = offset; out->format = format; out->width = width; out->height = height; out->xscale = LittleFloat(in->xscale); out->yscale = LittleFloat(in->yscale); } } // load only the lightmap data that will actually be used; readjust the // pixel data offsets accordingly void Mod_LoadRefineLighting (lump_t *l) { int i; byte *in_buffer; qboolean overflowed = false; if (!l->filelen) return; if (l->filelen > MAX_OVERRIDE_LIGHTING*4) Com_Error (ERR_DROP, "Mod_LoadRefineLighting: too much light data"); lightdatasize = 0; in_buffer = lightmap_header + l->fileofs; for (i = 0; i < loadmodel->numsurfaces; i++) { int in_offset = lfacelookups[i].offset; if (in_offset) { int size = 0; switch (lfacelookups[i].format) { case LTMP_PIXFMT_RGB24: size = 3*lfacelookups[i].width*lfacelookups[i].height; break; } if (lightdatasize + size >= MAX_OVERRIDE_LIGHTING) { overflowed = true; break; } memcpy (override_lightdata+lightdatasize, in_buffer+in_offset-1, size); lfacelookups[i].offset = lightdatasize+1; lightdatasize += size; } } if (overflowed) { Com_Printf ("Mod_LoadRefineLighting: MAX_OVERRIDE_LIGHTING overflow!\n"); Com_Printf ("Disabling HD lightmaps for this map.\n"); memset (lfacelookups, 0, sizeof(lfacelookups)); } } void Mod_LoadRefineLightmap (char *bsp_name) { byte *buf, *uncompressed_buf; lightmapheader_t header; int length; char name[MAX_OSPATH]; char *extension; int lightmap_file_lump_order[LTMP_LUMPS] = { LTMP_LUMP_FACELOOKUP, LTMP_LUMP_LIGHTING }; sizebuf_t in, out; #ifndef HAVE_ZLIB Com_Printf ("Zlib support must be enabled to use HD lightmaps!\n"); Com_Printf ("Please recompile with Zlib support.\n"); return; #endif strncpy (name, bsp_name, MAX_OSPATH-1-strlen(".lightmap")+strlen(".bsp")); extension = strstr (name, ".bsp"); if (extension) *extension = 0; strcat (name, ".lightmap"); length = FS_LoadFile (name, (void **)&buf); if (!buf) { Com_Printf ("Could not load %s\n", name); return; } else Com_Printf ("Loaded %s\n", name); SZ_Init (&in, buf, length); in.cursize = length; uncompressed_buf = malloc (LTMP_MAX_UNCOMPRESSED_DATA); if (!uncompressed_buf) { Com_Printf ("Mod_LoadRefineLightmap: unable to allocate %d bytes!\n", LTMP_MAX_UNCOMPRESSED_DATA); return; } SZ_Init (&out, (byte *)uncompressed_buf, LTMP_MAX_UNCOMPRESSED_DATA); qdecompress (&in, &out, compression_zlib_header); FS_FreeFile (buf); if (!out.cursize) { Com_Printf ("Mod_LoadRefineLightmap: unable to decompress data in %s!\n",name); free (uncompressed_buf); return; } lightmap_header = (byte *)uncompressed_buf; header = *(lightmapheader_t *)uncompressed_buf; if (header.ident != IDLIGHTMAPHEADER) { Com_Printf ("Mod_LoadRefineLightmap: invalid magic number in %s!\n" "The file is likely corrupt, please obtain a fresh copy.\n", name); free (uncompressed_buf); return; } if (header.version != LTMPVERSION) { Com_Printf ("Mod_LoadRefineLightmap: invalid major version number in %s!\n" "Version %d of the format is not supported. Current major version number is %d\n", name, header.version, LTMPVERSION); free (uncompressed_buf); return; } if (checkLumps (header.lumps, sizeof(int)*3, lightmap_file_lump_order, uncompressed_buf, LTMP_LUMPS, out.cursize)) { Com_Printf ("Mod_LoadRefineLightmap: lumps in %s don't add up right!\n" "The file is likely corrupt, please obtain a fresh copy.\n",name); free (uncompressed_buf); return; } Mod_LoadRefineFaceLookups (&header.lumps[LTMP_LUMP_FACELOOKUP]); Mod_LoadRefineLighting (&header.lumps[LTMP_LUMP_LIGHTING]); free (uncompressed_buf); } /* ================= Mod_LoadFaces ================= */ // We need access to the lighting lump so we can check the bounds of lightmap // offsets. Otherwise, crafted or corrupted BSPs could crash the client. void Mod_LoadFaces (lump_t *l, lump_t *lighting) { dface_t *in; msurface_t *out; int i, count, surfnum; int planenum, side; int ti; int smax, tmax; int light_s, light_t; float xscale, yscale; rscript_t *rs; vec3_t color; in = (void *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name); count = l->filelen / sizeof(*in); out = Hunk_Alloc ( count*sizeof(*out)); loadmodel->surfaces = out; loadmodel->numsurfaces = count; //we are guaranteed not to need more than this loadmodel->tangentSpaceTransforms = Hunk_Alloc (sizeof(float)*9*count); currentmodel = loadmodel; memset (lfacelookups, 0, sizeof(lfacelookups)); if (r_lightmapfiles->integer) Mod_LoadRefineLightmap (loadmodel->name); BSP_BeginBuildingLightmaps (loadmodel); VB_VCInit(); for ( surfnum=0 ; surfnumfirstedge); int numedges = LittleShort(in->numedges); out->iflags = 0; out->polys = NULL; planenum = (unsigned short)LittleShort(in->planenum); side = LittleShort(in->side); if (side) out->iflags |= ISURF_PLANEBACK; if (planenum >= loadmodel->numplanes) Com_Error (ERR_DROP, "Map has invalid plane offsets!\n" "The file is likely corrupted, please obtain a fresh copy."); out->plane = loadmodel->planes + planenum; ti = LittleShort (in->texinfo); if (ti < 0 || ti >= loadmodel->numtexinfo) Com_Error (ERR_DROP, "Map has invalid texinfo offsets!\n" "The file is likely corrupted, please obtain a fresh copy."); out->texinfo = loadmodel->texinfo + ti; if (lfacelookups[surfnum].offset) { smax=lfacelookups[surfnum].width; tmax=lfacelookups[surfnum].height; xscale=lfacelookups[surfnum].xscale; yscale=lfacelookups[surfnum].yscale; CalcSurfaceExtents (out, true, &smax, &tmax, &xscale, &yscale, firstedge, numedges); } else { CalcSurfaceExtents (out, false, &smax, &tmax, &xscale, &yscale, firstedge, numedges); } // lighting info for (i=0 ; istyles[i] = in->styles[i]; i = LittleLong(in->lightofs); if (i < 0 || i >= lighting->filelen) out->samples = NULL; else if (lfacelookups[surfnum].offset > 0 && lfacelookups[surfnum].offset <= lightdatasize) out->samples = override_lightdata + lfacelookups[surfnum].offset-1; else out->samples = loadmodel->lightdata + i; // set the drawing flags if (out->texinfo->flags & SURF_WARP) { out->iflags |= ISURF_DRAWTURB; for (i=0 ; i<2 ; i++) { out->extents[i] = 16384; out->texturemins[i] = -8192; } if(!(gl_state.glsl_shaders && gl_glsl_shaders->value) || !strcmp(out->texinfo->normalMap->name, out->texinfo->image->name)) R_SubdivideSurface (out, firstedge, numedges); // cut up polygon for warps } // create lightmaps and polygons light_s = light_t = 0; if ( !SurfaceHasNoLightmap(out) ) { BSP_CreateSurfaceLightmap (out, smax, tmax, &light_s, &light_t); } if ( (! (out->texinfo->flags & SURF_WARP)) || (gl_state.glsl_shaders && gl_glsl_shaders->value && strcmp(out->texinfo->normalMap->name, out->texinfo->image->name))) BSP_BuildPolygonFromSurface(out, xscale, yscale, light_s, light_t, firstedge, numedges); rs = (rscript_t *)out->texinfo->image->script; if(rs) { rs_stage_t *stage = rs->stage; do { if (stage->lensflare) { if(r_lensflare->value) Mod_AddFlareSurface(out, stage->flaretype); } if (stage->grass && stage->texture) { if(stage->colormap.enabled) { color[0] = stage->colormap.red; color[1] = stage->colormap.green; color[2] = stage->colormap.blue; } Mod_AddVegetationSurface(out, stage->texture->texnum, color, stage->scale.scaleX, stage->texture->bare_name, stage->grasstype); } if (stage->beam && stage->texture) { if(stage->colormap.enabled) { color[0] = stage->colormap.red; color[1] = stage->colormap.green; color[2] = stage->colormap.blue; } Mod_AddBeamSurface(out, stage->texture->texnum, color, stage->scale.scaleX, stage->texture->bare_name, stage->beamtype, stage->xang, stage->yang, stage->rotating); } if (stage->cube) out->texinfo->flags |= SURF_SHINY; } while ( (stage = stage->next) ); } Mod_CalcSurfaceNormals(out); if(gl_state.vbo) { VB_BuildVBOBufferSize(out); out->has_vbo = false; } } BSP_EndBuildingLightmaps (); } /* ================= Mod_SetParent ================= */ void Mod_SetParent (mnode_t *node, mnode_t *parent) { node->parent = parent; if (node->contents != -1) return; Mod_SetParent (node->children[0], node); Mod_SetParent (node->children[1], node); } /* ================= Mod_LoadNodes ================= */ void Mod_LoadNodes (lump_t *l) { int i, j, count, p; dnode_t *in; mnode_t *out; in = (void *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name); count = l->filelen / sizeof(*in); out = Hunk_Alloc ( count*sizeof(*out)); loadmodel->nodes = out; loadmodel->numnodes = count; for ( i=0 ; iminmaxs[j] = LittleShort (in->mins[j]); out->minmaxs[3+j] = LittleShort (in->maxs[j]); } p = LittleLong(in->planenum); if (p < 0 || p >= loadmodel->numplanes) Com_Error (ERR_DROP, "Map has invalid plane offsets!\n" "The file is likely corrupted, please obtain a fresh copy."); out->plane = loadmodel->planes + p; out->firstsurface = (unsigned short)LittleShort (in->firstface); out->numsurfaces = (unsigned short)LittleShort (in->numfaces); out->contents = -1; // differentiate from leafs for (j=0 ; j<2 ; j++) { p = LittleLong (in->children[j]); if (p >= 0) { if (p >= loadmodel->numnodes) Com_Error (ERR_DROP, "Map file has invalid node offsets!\n" "The file is likely corrupted, please obtain a fresh copy."); out->children[j] = loadmodel->nodes + p; } else { if (-1-p >= loadmodel->numleafs) Com_Error (ERR_DROP, "Map file has invalid leaf offsets!\n" "The file is likely corrupted, please obtain a fresh copy."); out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p)); } } } Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs } /* ================= Mod_LoadLeafs ================= */ void Mod_LoadLeafs (lump_t *l) { dleaf_t *in; mleaf_t *out; int i, j, count, p; int to_subtract = 0; //for removing SURF_NODRAW surfaces in = (void *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name); count = l->filelen / sizeof(*in); out = Hunk_Alloc ( count*sizeof(*out)); loadmodel->leafs = out; loadmodel->numleafs = count; for ( i=0 ; iminmaxs[j] = LittleShort (in->mins[j]); out->minmaxs[3+j] = LittleShort (in->maxs[j]); } p = LittleLong(in->contents); out->contents = p; out->cluster = LittleShort(in->cluster); out->area = LittleShort(in->area); out->firstmarksurface = loadmodel->marksurfaces + (unsigned short)(LittleShort(in->firstleafface)); out->nummarksurfaces = (unsigned short)LittleShort(in->numleaffaces); if (out->firstmarksurface < loadmodel->marksurfaces || out->nummarksurfaces < 0 || (unsigned short)LittleShort(in->firstleafface) > loadmodel->nummarksurfaces) Com_Error (ERR_DROP, "Map file has invalid leaf surface offsets!\n" "The file is likely corrupted, please obtain a fresh copy."); out->firstmarksurface -= to_subtract; // Remove SURF_NODRAW surfaces. We do this here instead of in // Mod_LoadMarkSurfaces so we can correct the offsets in each leaf. for (j = 0; j < out->nummarksurfaces; j++) { msurface_t *s; out->firstmarksurface[j] = out->firstmarksurface[j+to_subtract]; s = out->firstmarksurface[j]; if (s->texinfo->flags & SURF_NODRAW) { to_subtract++; j--; out->nummarksurfaces--; } } // gl underwater warp for (j=0 ; jnummarksurfaces ; j++) { msurface_t *s = out->firstmarksurface[j]; if ( (out->contents & MASK_WATER) || (s->texinfo->flags & SURF_UNDERWATER)) out->firstmarksurface[j]->iflags |= ISURF_UNDERWATER; } } loadmodel->nummarksurfaces -= to_subtract; Com_Printf ("Eliminated ^2%i invisible surfaces.\n", to_subtract); } /* ================= Mod_LoadMarksurfaces ================= */ void Mod_LoadMarksurfaces (lump_t *l) { int i, j, count; short *in; msurface_t **out; in = (void *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name); count = l->filelen / sizeof(*in); out = Hunk_Alloc ( count*sizeof(*out)); loadmodel->marksurfaces = out; loadmodel->nummarksurfaces = count; for ( i=0 ; i= loadmodel->numsurfaces) Com_Error (ERR_DROP, "Mod_ParseMarksurfaces: bad surface number"); out[i] = loadmodel->surfaces + j; } } /* ================= Mod_LoadSurfedges ================= */ void Mod_LoadSurfedges (lump_t *l) { int i, count; int *in, *out; in = (void *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name); count = l->filelen / sizeof(*in); if (count < 1 || count >= MAX_MAP_SURFEDGES) Com_Error (ERR_DROP, "MOD_LoadBmodel: bad surfedges count in %s: %i", loadmodel->name, count); out = Hunk_Alloc ( count*sizeof(*out)); loadmodel->surfedges = out; loadmodel->numsurfedges = count; for ( i=0 ; ifileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name); count = l->filelen / sizeof(*in); out = Hunk_Alloc ( count*sizeof(*out)); loadmodel->planes = out; loadmodel->numplanes = count; for ( i=0 ; inormal[j] = LittleFloat (in->normal[j]); if (out->normal[j] < 0) bits |= 1<dist = LittleFloat (in->dist); out->type = LittleLong (in->type); out->signbits = bits; } } /* ================= Mod_SummarizePVS Gather some statistics from the PVS data which allows the renderer to take some shortcuts. ================= */ void Mod_SummarizePVS (void) { byte *vis; mleaf_t *leaf, *leaf2; int cluster; int i; loadmodel->num_areas = 0; for (i = 0; i < MAX_MAP_AREAS; i++) { loadmodel->area_min_leaf[i] = loadmodel->numleafs-1; loadmodel->area_max_leaf[i] = 0; } for (i=0,leaf=loadmodel->leafs ; inumleafs ; i++, leaf++) { cluster = leaf->cluster; if (cluster == -1) continue; vis = Mod_ClusterPVS (cluster, loadmodel); if (loadmodel->area_min_leaf[leaf->area] > i) loadmodel->area_min_leaf[leaf->area] = i; if (loadmodel->area_max_leaf[leaf->area] < i) loadmodel->area_max_leaf[leaf->area] = i; if (leaf->area > loadmodel->num_areas) loadmodel->num_areas = leaf->area; // Two separate loops, one for minPVSleaf and one for maxPVSleaf, // each coming from opposite directions, for greater efficiency. for ( leaf->minPVSleaf = 0, leaf2 = loadmodel->leafs; leaf->minPVSleaf < loadmodel->numleafs; leaf->minPVSleaf++, leaf2++ ) { cluster = leaf2->cluster; if ((leaf2->contents & CONTENTS_SOLID) || cluster == -1) continue; if (leaf2->nummarksurfaces == 0) continue; if (vis[cluster>>3] & (1<<(cluster&7))) break; } for ( leaf->maxPVSleaf = loadmodel->numleafs-1, leaf2 = &loadmodel->leafs[leaf->maxPVSleaf]; leaf->maxPVSleaf >= leaf->minPVSleaf; leaf->maxPVSleaf--, leaf2-- ) { cluster = leaf2->cluster; if ((leaf2->contents & CONTENTS_SOLID) || cluster == -1) continue; if (leaf2->nummarksurfaces == 0) continue; if (vis[cluster>>3] & (1<<(cluster&7))) break; } } loadmodel->num_areas++; } /* ================= Mod_LoadBrushModel ================= */ extern cvar_t *scriptsloaded; void Mod_LoadBrushModel (model_t *mod, void *buffer) { int i; dheader_t *header; mmodel_t *bm; char rs_name[MAX_OSPATH], tmp[MAX_QPATH]; // rscript - MrG if(r_lensflare->value) R_ClearFlares(); R_ClearGrasses(); R_ClearBeams(); RS_FreeUnmarked(); strcpy(tmp,loadmodel->name+5); tmp[strlen(tmp)-4]=0; Com_sprintf(rs_name,MAX_OSPATH,"scripts/maps/%s.rscript",tmp); RS_ScanPathForScripts(); // load all found scripts RS_LoadScript(rs_name); RS_ReloadImageScriptLinks(); RS_LoadSpecialScripts(); Cvar_SetValue("scriptsloaded", 1); //ODE - clear out any ragdolls; R_ClearAllRagdolls(); //ODE - create new world(flush out old first) RGD_DestroyWorldObject(); RGD_CreateWorldObject(); r_numWorldLights = 0; loadmodel->type = mod_brush; if (loadmodel != mod_known) Com_Error (ERR_DROP, "Loaded a brush model after the world"); header = (dheader_t *)buffer; i = LittleLong (header->version); if (i != BSPVERSION) Com_Error (ERR_DROP, "Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION); // swap all the lumps mod_base = (byte *)header; for (i=0 ; ilumps[LUMP_ENTITIES]); Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]); Mod_LoadEdges (&header->lumps[LUMP_EDGES]); Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]); Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]); Mod_LoadPlanes (&header->lumps[LUMP_PLANES]); Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]); Mod_LoadFaces (&header->lumps[LUMP_FACES], &header->lumps[LUMP_LIGHTING]); Mod_LoadMarksurfaces (&header->lumps[LUMP_LEAFFACES]); Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]); Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]); Mod_LoadNodes (&header->lumps[LUMP_NODES]); Mod_SummarizePVS (); Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]); mod->num_frames = 2; // regular and alternate animation // // set up the submodels // for (i=0 ; inumsubmodels ; i++) { model_t *starmod; bm = &mod->submodels[i]; starmod = &mod_inline[i]; *starmod = *loadmodel; starmod->firstmodelsurface = bm->firstface; starmod->nummodelsurfaces = bm->numfaces; starmod->firstnode = bm->headnode; if (starmod->firstnode >= loadmodel->numnodes) Com_Error (ERR_DROP, "Inline model %i has bad firstnode", i); VectorCopy (bm->maxs, starmod->maxs); VectorCopy (bm->mins, starmod->mins); starmod->radius = bm->radius; if (i == 0) *loadmodel = *starmod; starmod->numleafs = bm->visleafs; } R_ParseLightEntities(); R_FindSunEntity(); R_FinalizeGrass(loadmodel); } //============================================================================= /* @@@@@@@@@@@@@@@@@@@@@ R_BeginRegistration Specifies the model that will be used as the world @@@@@@@@@@@@@@@@@@@@@ */ int R_FindFile (char *filename, FILE **file) { *file = fopen (filename, "rb"); if (!*file) { *file = NULL; return -1; } else return 1; } //code to precache all base player models and their w_weapons(note - these are specific to Alien Arena and can be changed for other games) PModelList_t BasePModels[] = { { "martianenforcer" }, { "martiancyborg" }, { "martianoverlord" }, { "martianwarrior" }, { "enforcer" }, { "commander" }, { "lauren" }, { "slashbot" } }; int PModelsCount = (int)(sizeof(BasePModels)/sizeof(BasePModels[0])); WModelList_t BaseWModels[] = { { "w_blaster.md2" }, { "w_shotgun.md2" }, { "w_sshotgun.md2" }, { "w_machinegun.md2" }, { "w_chaingun.md2" }, { "w_glauncher.md2" }, { "w_rlauncher.md2" }, { "w_hyperblaster.md2" }, { "w_railgun.md2" }, { "w_bfg.md2" }, { "w_violator.md2" }, { "weapon.md2" } }; int WModelsCount = (int)(sizeof(BaseWModels)/sizeof(BaseWModels[0])); void R_RegisterBasePlayerModels( void ) { char mod_filename[MAX_QPATH]; char scratch[MAX_QPATH]; int i, j; // int npms = 0; // unused int nskins = 0; char **skinnames; if (is_localhost) { //then the client is also the server so we have this cvar available cvar_t *maxclients = Cvar_Get ("maxclients", 0, 0); if (!maxclients|| maxclients->integer <= 1) return; //don't bother } //precache all player and weapon models(base only, otherwise could take very long loading a map!) for (i = 0; i < PModelsCount; i++) { Com_Printf("Registering models for: %s\n", BasePModels[i].name); Com_sprintf( mod_filename, sizeof(mod_filename), "players/%s/tris.md2", BasePModels[i].name); R_RegisterModel(mod_filename); Com_sprintf( mod_filename, sizeof(mod_filename), "players/%s/lod1.md2", BasePModels[i].name); R_RegisterModel(mod_filename); Com_sprintf( mod_filename, sizeof(mod_filename), "players/%s/lod2.md2", BasePModels[i].name); R_RegisterModel(mod_filename); //register weapon models for (j = 0; j < WModelsCount; j++) { Com_sprintf( mod_filename, sizeof(mod_filename), "players/%s/%s", BasePModels[i].name, BaseWModels[j]); R_RegisterModel(mod_filename); } //register standard sounds S_RegisterSoundsForPlayer (BasePModels[i].name); //register all skins Com_sprintf( scratch, sizeof(scratch), "players/%s/*.jpg", BasePModels[i].name); skinnames = FS_ListFilesInFS( scratch, &nskins, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM ); if(!skinnames) continue; for(j = 0; j < nskins; j++) R_RegisterSkin (skinnames[j]); if(skinnames) free(skinnames); } } void R_RegisterCustomPlayerModels( void ) { char mod_filename[MAX_QPATH]; char scratch[MAX_QPATH]; int i, j; int npms = 0; int nskins = 0; char **dirnames; char **skinnames; dirnames = FS_ListFilesInFS( "players/*.*", &npms, SFF_SUBDIR, 0 ); if ( !dirnames ) return; if ( npms > 1024 ) npms = 1024; for(i = 0; i < npms; i++) { if ( dirnames[i] == 0 ) continue; Com_Printf("Registering custom player model: %s\n", dirnames[i]); Com_sprintf( mod_filename, sizeof(mod_filename), "%s/tris.md2", dirnames[i]); if(FS_FileExists(mod_filename)) R_RegisterModel(mod_filename); else continue; //invalid player model Com_sprintf( mod_filename, sizeof(mod_filename), "%s/lod1.md2", dirnames[i]); if(FS_FileExists(mod_filename)) R_RegisterModel(mod_filename); Com_sprintf( mod_filename, sizeof(mod_filename), "%s/lod2.md2", dirnames[i]); if(FS_FileExists(mod_filename)) R_RegisterModel(mod_filename); //register weapon models for (j = 0; j < WModelsCount; j++) { Com_sprintf( mod_filename, sizeof(mod_filename), "%s/%s", dirnames[i], BaseWModels[j]); if(FS_FileExists(mod_filename)) R_RegisterModel(mod_filename); } //register standard sounds S_RegisterSoundsForPlayer (dirnames[i]); //register all skins strcpy( scratch, dirnames[i] ); strcat( scratch, "/*.jpg" ); skinnames = FS_ListFilesInFS( scratch, &nskins, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM ); if(!skinnames) { // check for .tga, though this is no longer used for current models strcpy( scratch, dirnames[i] ); strcat( scratch, "/*.tga" ); skinnames = FS_ListFilesInFS( scratch, &nskins, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM ); } if(!skinnames) continue; for(j = 0; j < nskins; j++) R_RegisterSkin (skinnames[j]); if(skinnames) free(skinnames); } if(dirnames) free(dirnames); } void R_BeginRegistration (char *model) { char fullname[MAX_OSPATH]; char *path; cvar_t *flushmap; FILE *file; int i; registration_sequence++; r_oldviewcluster = -1; // force markleafs r_weather = 0; //default is 0 r_nosun = 0; // check for fog file, using file system search path path = NULL; map_fog = false; r_weather = false; r_nosun = false; r_sunX = 0; r_sunY = 0; r_sunZ = 0; for(;;) { path = FS_NextPath( path ); if( !path ) { break; } Com_sprintf(fullname, sizeof(fullname), "%s/maps/scripts/%s.fog", path, model); i = 0; R_FindFile( fullname, &file ); //does a fog file exist? if(file) { //read the file, get fog information fclose(file); R_ReadFogScript(fullname); break; } } // check for background music file, , using file system search path //defaults below strcpy(map_music, "music/menumusic.ogg"); strcpy(map_music_sec, "music/adrenaline.ogg"); S_RegisterSound (map_music_sec); path = NULL; for(;;) { path = FS_NextPath( path ); if( !path ) { break; } Com_sprintf(fullname, sizeof(fullname), "%s/maps/scripts/%s.mus", path, model); i = 0; R_FindFile( fullname, &file ); //does a music file exist? if(file) { //read the file, get music information fclose( file ); R_ReadMusicScript( fullname ); break; } } //set ctf flags r_gotFlag = false; r_lostFlag = false; Cvar_Set("rs_hasflag", "0"); Com_sprintf (fullname, sizeof(fullname), "maps/%s.bsp", model); // explicitly free the old map if different // this guarantees that mod_known[0] is the world map flushmap = Cvar_Get ("flushmap", "0", 0); if ( strcmp(mod_known[0].name, fullname) || flushmap->value) Mod_Free (&mod_known[0]); else Mod_Free (&mod_known[0]); //do it every time to fix shader bugs in AA r_worldmodel = Mod_ForName(fullname, true); r_viewcluster = -1; r_teamColor = 0; R_RegisterLightGroups(); //ODE RGD_BuildWorldTrimesh (); //VBO if(gl_state.vbo) VB_BuildWorldVBO(); } /* @@@@@@@@@@@@@@@@@@@@@ R_RegisterModel @@@@@@@@@@@@@@@@@@@@@ */ struct model_s *R_RegisterModel (char *name) { model_t *mod; int i; dmdl_t *pheader; mod = Mod_ForName (name, false); if (mod) { mod->registration_sequence = registration_sequence; // register any images used by the models if (mod->type == mod_alias) { pheader = (dmdl_t *)mod->extradata; for (i=0 ; inum_skins ; i++) mod->skins[i] = GL_FindImage ((char *)pheader + pheader->ofs_skins + i*MAX_SKINNAME, it_skin); //PGM mod->num_frames = pheader->num_frames; //PGM } else if (mod->type == mod_iqm) { mod->skins[0] = GL_FindImage (mod->skinname, it_skin); } else if (mod->type == mod_brush) { for (i=0 ; inumtexinfo ; i++) { mod->texinfo[i].image->registration_sequence = registration_sequence; mod->texinfo[i].normalMap->registration_sequence = registration_sequence; } } } return mod; } /* @@@@@@@@@@@@@@@@@@@@@ R_EndRegistration @@@@@@@@@@@@@@@@@@@@@ */ void R_EndRegistration (void) { int i; model_t *mod; for (i=0, mod=mod_known ; iname[0]) continue; if (mod->registration_sequence != registration_sequence) { // don't need this model Mod_Free (mod); } } GL_FreeUnusedImages (); } //============================================================================= /* ================ Mod_Free ================ */ void Mod_Free (model_t *mod) { Hunk_Free (mod->extradata); memset (mod, 0, sizeof(*mod)); } /* ================ Mod_FreeAll ================ */ void Mod_FreeAll (void) { int i; for (i=0 ; iclient) return value; strcpy(value, Info_ValueForKey (ent->client->pers.userinfo, "skin")); p = strchr(value, '/'); if (!p) return value; return ++p; } qboolean OnSameTeam (edict_t *ent1, edict_t *ent2) { char ent1Team [512]; char ent2Team [512]; if(g_tactical->value) { if(ent1->ctype == ent2->ctype) return true; } if (!((dmflags->integer & DF_SKINTEAMS) || ctf->value || tca->value || cp->value)) return false; strcpy (ent1Team, ClientTeam (ent1)); strcpy (ent2Team, ClientTeam (ent2)); if (strcmp(ent1Team, ent2Team) == 0) return true; return false; } void SelectNextItem (edict_t *ent, int itflags) { gclient_t *cl; int i, index; gitem_t *it; cl = ent->client; if (cl->chase_target) { ChaseNext(ent); return; } // scan for the next valid one for (i=1 ; i<=MAX_ITEMS ; i++) { index = (cl->pers.selected_item + i)%MAX_ITEMS; if (!cl->pers.inventory[index]) continue; it = &itemlist[index]; if (!it->use) continue; if (!(it->flags & itflags)) continue; cl->pers.selected_item = index; return; } cl->pers.selected_item = -1; } void SelectPrevItem (edict_t *ent, int itflags) { gclient_t *cl; int i, index; gitem_t *it; cl = ent->client; if (cl->chase_target) { ChasePrev(ent); return; } // scan for the next valid one for (i=1 ; i<=MAX_ITEMS ; i++) { index = (cl->pers.selected_item + MAX_ITEMS - i)%MAX_ITEMS; if (!cl->pers.inventory[index]) continue; it = &itemlist[index]; if (!it->use) continue; if (!(it->flags & itflags)) continue; cl->pers.selected_item = index; return; } cl->pers.selected_item = -1; } void ValidateSelectedItem (edict_t *ent) { gclient_t *cl; cl = ent->client; if (cl->pers.inventory[cl->pers.selected_item]) return; // valid SelectNextItem (ent, -1); } void DrawChatBubble (edict_t *ent) { if(!ent->client) return; if(ent->client->resp.spectator) return; gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_SAYICON); gi.WritePosition (ent->s.origin); gi.multicast (ent->s.origin, MULTICAST_PVS); } //================================================================================= /* ================== Cmd_Give_f Give items to a client ================== */ void Cmd_Give_f (edict_t *ent) { char *name; gitem_t *it; int index; int i; qboolean give_all; edict_t *it_ent; if (deathmatch->value && !sv_cheats->value) { safe_cprintf (ent, PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n"); return; } name = gi.args(); if (Q_strcasecmp(name, "all") == 0) give_all = true; else give_all = false; if (give_all || Q_strcasecmp(gi.argv(1), "health") == 0) { if (gi.argc() == 3) ent->health = atoi(gi.argv(2)); else ent->health = ent->max_health; if (!give_all) return; } if (give_all || Q_strcasecmp(name, "weapons") == 0) { for (i=0 ; ipickup) continue; if (!(it->flags & IT_WEAPON)) continue; ent->client->pers.inventory[i] += 1; } if (!give_all) return; } if (give_all || Q_strcasecmp(name, "ammo") == 0) { for (i=0 ; ipickup) continue; if (!(it->flags & IT_AMMO)) continue; Add_Ammo (ent, it, 1000, true, true); } if (!give_all) return; } if (give_all || Q_strcasecmp(name, "armor") == 0) { gitem_armor_t *info; it = FindItem("Jacket Armor"); ent->client->pers.inventory[ITEM_INDEX(it)] = 0; it = FindItem("Combat Armor"); ent->client->pers.inventory[ITEM_INDEX(it)] = 0; it = FindItem("Body Armor"); info = (gitem_armor_t *)it->info; ent->client->pers.inventory[ITEM_INDEX(it)] = info->max_count; if (!give_all) return; } if (give_all) { for (i=0 ; ipickup) continue; if (it->flags & (IT_ARMOR|IT_WEAPON|IT_AMMO)) continue; ent->client->pers.inventory[i] = 1; } //don't give vehicles or flags it = FindItem("Bomber"); ent->client->pers.inventory[ITEM_INDEX(it)] = 0; it = FindItem("Strafer"); ent->client->pers.inventory[ITEM_INDEX(it)] = 0; it = FindItem("Hover"); ent->client->pers.inventory[ITEM_INDEX(it)] = 0; it = FindItem("Blue Flag"); ent->client->pers.inventory[ITEM_INDEX(it)] = 0; it = FindItem("Red Flag"); ent->client->pers.inventory[ITEM_INDEX(it)] = 0; return; } it = FindItem (name); if (!it) { name = gi.argv(1); it = FindItem (name); if (!it) { safe_cprintf (ent, PRINT_HIGH, "unknown item\n"); return; } } if (!it->pickup) { safe_cprintf (ent, PRINT_HIGH, "non-pickup item\n"); return; } index = ITEM_INDEX(it); if (it->flags & IT_AMMO) { if (gi.argc() == 3) ent->client->pers.inventory[index] = atoi(gi.argv(2)); else ent->client->pers.inventory[index] += it->quantity; } else { it_ent = G_Spawn(); it_ent->classname = it->classname; SpawnItem (it_ent, it); Touch_Item (it_ent, ent, NULL, NULL); if (it_ent->inuse) G_FreeEdict(it_ent); } } /* ================== Cmd_God_f Sets client to godmode argv(0) god ================== */ void Cmd_God_f (edict_t *ent) { char *msg; if (deathmatch->value && !sv_cheats->value) { safe_cprintf (ent, PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n"); return; } ent->flags ^= FL_GODMODE; if (!(ent->flags & FL_GODMODE) ) msg = "godmode OFF\n"; else msg = "godmode ON\n"; safe_cprintf (ent, PRINT_HIGH, msg); } /* ================== Cmd_Notarget_f Sets client to notarget argv(0) notarget ================== */ void Cmd_Notarget_f (edict_t *ent) { char *msg; if (deathmatch->value && !sv_cheats->value) { safe_cprintf (ent, PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n"); return; } ent->flags ^= FL_NOTARGET; if (!(ent->flags & FL_NOTARGET) ) msg = "notarget OFF\n"; else msg = "notarget ON\n"; safe_cprintf (ent, PRINT_HIGH, msg); } /* ================== Cmd_Noclip_f argv(0) noclip ================== */ void Cmd_Noclip_f (edict_t *ent) { char *msg; if (deathmatch->value && !sv_cheats->value) { safe_cprintf (ent, PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n"); return; } if (ent->movetype == MOVETYPE_NOCLIP) { ent->movetype = MOVETYPE_WALK; msg = "noclip OFF\n"; } else { ent->movetype = MOVETYPE_NOCLIP; msg = "noclip ON\n"; } safe_cprintf (ent, PRINT_HIGH, msg); } /* ================== Cmd_Use_f Use an inventory item ================== */ void Cmd_Use_f (edict_t *ent) { int index; gitem_t *it; char *s; s = gi.args(); it = FindItem (s); if (!it) { safe_cprintf (ent, PRINT_HIGH, "unknown item: %s\n", s); return; } if (!it->use) { safe_cprintf (ent, PRINT_HIGH, "Item is not usable.\n"); return; } index = ITEM_INDEX(it); if (!ent->client->pers.inventory[index]) { safe_cprintf (ent, PRINT_HIGH, "Out of item: %s\n", s); if (it->flags & IT_WEAPON) { ent->client->pers.lastfailedswitch = it; ent->client->pers.failedswitch_framenum = level.framenum; } return; } it->use (ent, it); } /* ================== Cmd_Drop_f Drop an inventory item ================== */ void Cmd_Drop_f (edict_t *ent) { int index; gitem_t *it; char *s; s = gi.args(); it = FindItem (s); if (!it) { safe_cprintf (ent, PRINT_HIGH, "unknown item: %s\n", s); return; } if (!it->drop) { safe_cprintf (ent, PRINT_HIGH, "Item is not dropable.\n"); return; } index = ITEM_INDEX(it); if (!ent->client->pers.inventory[index]) { safe_cprintf (ent, PRINT_HIGH, "Out of item: %s\n", s); return; } it->drop (ent, it); } /* ================= Cmd_Inven_f ================= */ void Cmd_Inven_f (edict_t *ent) { int i; gclient_t *cl; cl = ent->client; cl->showscores = false; cl->showhelp = false; if (cl->showinventory) { cl->showinventory = false; return; } cl->showinventory = true; gi.WriteByte (svc_inventory); for (i=0 ; ipers.inventory[i]); } gi.unicast (ent, true); } /* ================= Cmd_InvUse_f ================= */ void Cmd_InvUse_f (edict_t *ent) { gitem_t *it; ValidateSelectedItem (ent); if (ent->client->pers.selected_item == -1) { safe_cprintf (ent, PRINT_HIGH, "No item to use.\n"); return; } it = &itemlist[ent->client->pers.selected_item]; if (!it->use) { safe_cprintf (ent, PRINT_HIGH, "Item is not usable.\n"); return; } it->use (ent, it); } /* ================= Cmd_WeapPrev_f ================= */ void Cmd_WeapPrev_f (edict_t *ent) { gclient_t *cl; int i, index; gitem_t *it; int selected_weapon; cl = ent->client; if (!cl->pers.weapon) return; selected_weapon = ITEM_INDEX(cl->pers.weapon); // scan for the next valid one for (i=1 ; i<=MAX_ITEMS ; i++) { index = (selected_weapon + i)%MAX_ITEMS; if (!cl->pers.inventory[index]) continue; it = &itemlist[index]; if (!it->use) continue; if (! (it->flags & IT_WEAPON) ) continue; it->use (ent, it); if (cl->pers.weapon == it) return; // successful } } /* ================= Cmd_WeapNext_f ================= */ void Cmd_WeapNext_f (edict_t *ent) { gclient_t *cl; int i, index; gitem_t *it; int selected_weapon; cl = ent->client; if (!cl->pers.weapon) return; selected_weapon = ITEM_INDEX(cl->pers.weapon); // scan for the next valid one for (i=1 ; i<=MAX_ITEMS ; i++) { index = (selected_weapon + MAX_ITEMS - i)%MAX_ITEMS; if (!cl->pers.inventory[index]) continue; it = &itemlist[index]; if (!it->use) continue; if (! (it->flags & IT_WEAPON) ) continue; it->use (ent, it); if (cl->pers.weapon == it) return; // successful } } /* ================= Cmd_WeapLast_f ================= */ void Cmd_WeapLast_f (edict_t *ent) { gclient_t *cl; int index; gitem_t *it; cl = ent->client; if (!cl->pers.weapon || !cl->pers.lastweapon) return; index = ITEM_INDEX(cl->pers.lastweapon); if (!cl->pers.inventory[index]) return; it = &itemlist[index]; if (!it->use) return; if (! (it->flags & IT_WEAPON) ) return; it->use (ent, it); } /* ================= Cmd_InvDrop_f ================= */ void Cmd_InvDrop_f (edict_t *ent) { gitem_t *it; ValidateSelectedItem (ent); if (ent->client->pers.selected_item == -1) { safe_cprintf (ent, PRINT_HIGH, "No item to drop.\n"); return; } it = &itemlist[ent->client->pers.selected_item]; if (!it->drop) { safe_cprintf (ent, PRINT_HIGH, "Item is not dropable.\n"); return; } it->drop (ent, it); } /* ================= Cmd_Kill_f ================= */ void Cmd_Kill_f (edict_t *ent) { if((level.time - ent->client->respawn_time) < 5) return; ent->flags &= ~FL_GODMODE; ent->health = 0; meansOfDeath = MOD_SUICIDE; player_die (ent, ent, ent, 100000, vec3_origin); } /* ================= Cmd_PutAway_f ================= */ void Cmd_PutAway_f (edict_t *ent) { ent->client->showscores = false; ent->client->showhelp = false; ent->client->showinventory = false; } int PlayerSort (void const *a, void const *b) { int anum, bnum; anum = *(int *)a; bnum = *(int *)b; if ( game.clients[anum].ps.stats[STAT_SPECTATOR] == 0 ) anum = game.clients[anum].ps.stats[STAT_FRAGS]; else anum = 0; if ( game.clients[bnum].ps.stats[STAT_SPECTATOR] == 0 ) bnum = game.clients[bnum].ps.stats[STAT_FRAGS]; else bnum = 0; if (anum < bnum) return -1; if (anum > bnum) return 1; return 0; } /* ================= Cmd_Players_f ================= */ void Cmd_Players_f (edict_t *ent) { int i; int count; char small[64]; char large[1280]; int index[256]; count = 0; for (i = 0 ; i < g_maxclients->value ; i++) if (game.clients[i].pers.connected) { index[count] = i; count++; } // sort by frags qsort (index, count, sizeof(index[0]), PlayerSort); // print information large[0] = 0; for (i = 0 ; i < count ; i++) { Com_sprintf (small, sizeof(small), "%3i %s\n", game.clients[index[i]].ps.stats[STAT_FRAGS], game.clients[index[i]].pers.netname); if (strlen (small) + strlen(large) > sizeof(large) - 100 ) { // can't print all of them in one packet strcat (large, "...\n"); break; } strcat (large, small); } safe_cprintf (ent, PRINT_HIGH, "%s\n%i players\n", large, count); } /* ================= Cmd_Wave_f ================= */ void Cmd_Wave_f (edict_t *ent) { int i; i = atoi (gi.argv(1)); // can't wave when ducked if (ent->client->ps.pmove.pm_flags & PMF_DUCKED) return; if (ent->client->anim_priority > ANIM_WAVE) return; ent->client->anim_priority = ANIM_WAVE; switch (i) { case 0: safe_cprintf (ent, PRINT_HIGH, "flipoff\n"); ent->s.frame = FRAME_flip01-1; ent->client->anim_end = FRAME_flip12; break; case 1: safe_cprintf (ent, PRINT_HIGH, "salute\n"); ent->s.frame = FRAME_salute01-1; ent->client->anim_end = FRAME_salute11; break; case 2: safe_cprintf (ent, PRINT_HIGH, "taunt\n"); ent->s.frame = FRAME_taunt01-1; ent->client->anim_end = FRAME_taunt17; break; case 3: safe_cprintf (ent, PRINT_HIGH, "wave\n"); ent->s.frame = FRAME_wave01-1; ent->client->anim_end = FRAME_wave11; break; case 4: default: safe_cprintf (ent, PRINT_HIGH, "point\n"); ent->s.frame = FRAME_point01-1; ent->client->anim_end = FRAME_point12; break; } } /* ================== Cmd_Say_f ================== */ void Cmd_Say_f (edict_t *ent, qboolean team, qboolean arg0) { int i, j; edict_t *other; char *p; char text[2048]; gclient_t *cl; if (gi.argc () < 2 && !arg0) return; if (strlen(gi.args()) < 3) //no text, don't send return; gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_SAYICON); gi.WritePosition (ent->s.origin); gi.multicast (ent->s.origin, MULTICAST_PVS); if (!((dmflags->integer & DF_SKINTEAMS) || ctf->value || tca->value || cp->value)) team = false; if (team) Com_sprintf (text, sizeof(text), "[TEAM] %s: ", ent->client->pers.netname); else Com_sprintf (text, sizeof(text), "%s: ", ent->client->pers.netname); if (arg0) { strcat (text, gi.argv(0)); strcat (text, " "); strcat (text, gi.args()); } else { p = gi.args(); if (*p == '"') { p++; p[strlen(p)-1] = 0; } strcat(text, p); } // don't let text be too long for malicious reasons if (strlen(text) > 150) text[150] = 0; strcat(text, "\n"); if (flood_msgs->value) { cl = ent->client; if (level.time < cl->flood_locktill) { safe_cprintf(ent, PRINT_HIGH, "You can't talk for %d more seconds\n", (int)(cl->flood_locktill - level.time)); return; } i = cl->flood_whenhead - flood_msgs->value + 1; if (i < 0) i = (sizeof(cl->flood_when)/sizeof(cl->flood_when[0])) + i; if (cl->flood_when[i] && level.time - cl->flood_when[i] < flood_persecond->value) { cl->flood_locktill = level.time + flood_waitdelay->value; safe_cprintf(ent, PRINT_CHAT, "Flood protection: You can't talk for %d seconds.\n", (int)flood_waitdelay->value); return; } cl->flood_whenhead = (cl->flood_whenhead + 1) % (sizeof(cl->flood_when)/sizeof(cl->flood_when[0])); cl->flood_when[cl->flood_whenhead] = level.time; } if (g_dedicated->value) safe_cprintf(NULL, PRINT_CHAT, "%s", text); for (j = 1; j <= game.maxclients; j++) { other = &g_edicts[j]; if (!other->inuse) continue; if (!other->client) continue; if(other->is_bot) //JD - security fix continue; if (team) { if (!OnSameTeam(ent, other)) continue; } //safe_cprintf(other, PRINT_CHAT, "%s", text); //JD - security fix gi.cprintf(other, PRINT_CHAT, "%s", text); } } void Cmd_PlayerList_f(edict_t *ent) { int i; char st[80]; char text[1400]; edict_t *e2; // connect time, ping, score, name *text = 0; for (i = 0, e2 = g_edicts + 1; i < g_maxclients->value; i++, e2++) { if (!e2->inuse) continue; Com_sprintf(st, sizeof(st), "%02d:%02d %4d %3d %s%s\n", (level.framenum - e2->client->resp.enterframe) / 600, ((level.framenum - e2->client->resp.enterframe) % 600)/10, e2->client->ping, e2->client->resp.score, e2->client->pers.netname, e2->client->resp.spectator ? " (spectator)" : ""); if (strlen(text) + strlen(st) > sizeof(text) - 50) { sprintf(text+strlen(text), "And more...\n"); safe_cprintf(ent, PRINT_HIGH, "%s", text); return; } strcat(text, st); } safe_cprintf(ent, PRINT_HIGH, "%s", text); } /* ================= Cmd_CallVote_f ================= */ void Cmd_CallVote_f (edict_t *ent) { if(level.time <= warmuptime->value) { safe_bprintf(PRINT_HIGH, "Cannot call a vote during warmup!\n"); return; } if(playervote.called) { safe_bprintf(PRINT_HIGH, "Vote already in progress, please wait.\n"); return; } //start a vote playervote.called = true; playervote.yay = playervote.nay = 0; playervote.starttime = level.time; if(strlen(gi.args()) < 128) { strcpy(playervote.command, gi.args()); safe_bprintf(PRINT_HIGH, "%s called a vote: %s\n", ent->client->pers.netname, playervote.command); } } /* ================= Cmd_Vote_f ================= */ void Cmd_Vote_f (edict_t *ent) { int i, j, mostvotes, winner; int n_candidates; int candidates[4]; char buffer[512]; char buffer2[60]; edict_t *cl_ent; i = atoi (gi.argv(1)); if(g_callvote->value && playervote.called) { switch(i) { //to do - move "voted" to persistant data case 1: if(!ent->client->resp.voted) { ent->client->resp.voted = true; playervote.yay++; safe_bprintf(PRINT_HIGH, "%s voted ^2YES\n", ent->client->pers.netname); } break; case 2: if(!ent->client->resp.voted) { ent->client->resp.voted = true; playervote.nay++; safe_bprintf(PRINT_HIGH, "%s voted ^1NO\n", ent->client->pers.netname); } break; } } if (!level.intermissiontime || ! (g_mapvote && g_mapvote->value && !g_mapvote->modified) ) return; ent->client->mapvote = i; safe_bprintf(PRINT_HIGH, "%s voted for map %i\n", ent->client->pers.netname, i); //update scoreboard mostvotes = 0; winner = 1; //next map in line for(i = 0; i < 4; i++) votedmap[i].tally = 0; for (i=0 ; ivalue ; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || cl_ent->is_bot) continue; for(j = 0; j < 4; j++) { if(cl_ent->client->mapvote-1 == j) votedmap[j].tally++; if(votedmap[j].tally > mostvotes){ mostvotes = votedmap[j].tally; } } } if ( g_voterand && g_voterand->value ) { // random tie resolution n_candidates = 0; for (j = 0; j < 4; j ++) { if ( votedmap[j].tally < mostvotes ) continue; candidates[n_candidates ++] = j; } if ( n_candidates == 1 ) { winner = candidates[0]; sprintf( buffer, "Map %s leads with %i vote%s!", votedmap[winner].mapname, votedmap[winner].tally, (mostvotes > 1) ? "s" : "" ); } else { strcpy( buffer, "It's a tie!\nMaps "); for ( i = 0 ; i < n_candidates ; i ++ ) { j = candidates[i]; if ( i > 0 ) { if ( i == n_candidates - 1 ) strcat( buffer, " and " ); else strcat( buffer, ", " ); } strcat( buffer, votedmap[j].mapname ); } sprintf( buffer2, "\nlead with %i vote%s!" , mostvotes , (mostvotes > 1) ? "s" : "" ); strcat( buffer, buffer2 ); } } else { // "old" voting system, leading map is the first one with enough votes for (j = 0; j < 4; j ++) { i = (j + 1) % 4; if ( votedmap[i].tally < mostvotes ) continue; winner = i; break; } sprintf( buffer, "Map %s leads with %i vote%s!", votedmap[winner].mapname, votedmap[winner].tally, (mostvotes > 1) ? "s" : "" ); } for (i=0 ; ivalue ; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || cl_ent->is_bot) continue; safe_centerprintf(cl_ent, "%s", buffer ); } } void Cmd_VoiceTaunt_f (edict_t *ent) { int index, i; qboolean done; char name[32]; char string[256]; //a small string to send char playermodel[MAX_OSPATH], tauntsound[MAX_OSPATH]; char *info; index = atoi (gi.argv(1)); if(index > 5 || index < 1 || ent->is_bot) { index = (int)(1 + random() * 5); if(index > 5) index = 5; } //get info about this client if(ent->inuse && ent->client) { if((level.time - ent->client->lasttaunttime) > 2) { //prevent flooding ent->client->lasttaunttime = level.time; strcpy(name, ent->client->pers.netname); info = Info_ValueForKey (ent->client->pers.userinfo, "skin"); if ( *info == '\0' ) { /* could not find skin. probable programming error. */ gi.dprintf("Cmd_VoiceTaunt_f: skin not found in userinfo\n"); return; } info[96] = 0; //truncate to prevent bad people from harming the server i = 0; done = false; while(!done) { if((info[i] == '/') || (info[i] == '\\')) done = true; playermodel[i] = info[i]; if(i > 62) done = true; i++; } playermodel[i-1] = 0; sprintf(tauntsound, "taunts/%s/taunt%i.wav", playermodel, index); Com_sprintf(string, sizeof(string), "%s %s %s ", info, tauntsound, name); //send to all clients as a general config string gi.configstring (CS_GENERAL, string); } } } /* ================= ClientCommand ================= */ void ClientCommand (edict_t *ent) { char *cmd; if (!ent->client) return; // not fully in game yet // ACEBOT_ADD if(ACECM_Commands(ent)) return; // ACEBOT_END cmd = gi.argv(0); if (Q_strcasecmp (cmd, "players") == 0) { Cmd_Players_f (ent); return; } if (Q_strcasecmp (cmd, "say") == 0) { Cmd_Say_f (ent, false, false); return; } if (Q_strcasecmp (cmd, "say_team") == 0) { Cmd_Say_f (ent, true, false); return; } if (Q_strcasecmp (cmd, "score") == 0) { Cmd_Score_f (ent); return; } if (Q_strcasecmp (cmd, "callvote") == 0) { Cmd_CallVote_f(ent); return; } if (Q_strcasecmp (cmd, "vote") == 0) { Cmd_Vote_f(ent); return; } if (Q_strcasecmp (cmd, "vtaunt") == 0) { Cmd_VoiceTaunt_f(ent); return; } if (level.intermissiontime) return; if (Q_strcasecmp (cmd, "use") == 0) Cmd_Use_f (ent); else if (Q_strcasecmp (cmd, "drop") == 0) Cmd_Drop_f (ent); else if (Q_strcasecmp (cmd, "give") == 0) Cmd_Give_f (ent); else if (Q_strcasecmp (cmd, "god") == 0) Cmd_God_f (ent); else if (Q_strcasecmp (cmd, "notarget") == 0) Cmd_Notarget_f (ent); else if (Q_strcasecmp (cmd, "noclip") == 0) Cmd_Noclip_f (ent); else if (Q_strcasecmp (cmd, "inven") == 0) Cmd_Inven_f (ent); else if (Q_strcasecmp (cmd, "invnext") == 0) SelectNextItem (ent, -1); else if (Q_strcasecmp (cmd, "invprev") == 0) SelectPrevItem (ent, -1); else if (Q_strcasecmp (cmd, "invnextw") == 0) SelectNextItem (ent, IT_WEAPON); else if (Q_strcasecmp (cmd, "invprevw") == 0) SelectPrevItem (ent, IT_WEAPON); else if (Q_strcasecmp (cmd, "invnextp") == 0) SelectNextItem (ent, IT_POWERUP); else if (Q_strcasecmp (cmd, "invprevp") == 0) SelectPrevItem (ent, IT_POWERUP); else if (Q_strcasecmp (cmd, "invuse") == 0) Cmd_InvUse_f (ent); else if (Q_strcasecmp (cmd, "invdrop") == 0) Cmd_InvDrop_f (ent); else if (Q_strcasecmp (cmd, "weapprev") == 0) Cmd_WeapPrev_f (ent); else if (Q_strcasecmp (cmd, "weapnext") == 0) Cmd_WeapNext_f (ent); else if (Q_strcasecmp (cmd, "weaplast") == 0) Cmd_WeapLast_f (ent); else if (Q_strcasecmp (cmd, "kill") == 0) Cmd_Kill_f (ent); else if (Q_strcasecmp (cmd, "putaway") == 0) Cmd_PutAway_f (ent); else if (Q_strcasecmp (cmd, "wave") == 0) Cmd_Wave_f (ent); else if (Q_strcasecmp(cmd, "playerlist") == 0) Cmd_PlayerList_f(ent); else if (Q_strcasecmp (cmd, "chatbubble") == 0) DrawChatBubble(ent); else // anything that doesn't match a command will be a chat Cmd_Say_f (ent, false, true); } alien-arena-7.66+dfsg/source/game/g_monster.c0000600000175000017500000003463112161402010020163 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. Copyright (C) 20?? COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" void AttackFinished (edict_t *self, float time) { self->monsterinfo.attack_finished = level.time + time; } void M_CheckGround (edict_t *ent) { vec3_t point; trace_t trace; if (ent->flags & (FL_SWIM|FL_FLY)) return; if (ent->velocity[2] > 100) { ent->groundentity = NULL; return; } // if the hull point one-quarter unit down is solid the entity is on ground point[0] = ent->s.origin[0]; point[1] = ent->s.origin[1]; point[2] = ent->s.origin[2] - 0.25; trace = gi.trace (ent->s.origin, ent->mins, ent->maxs, point, ent, MASK_MONSTERSOLID); // check steepness if ( trace.plane.normal[2] < 0.7 && !trace.startsolid) { ent->groundentity = NULL; return; } // ent->groundentity = trace.ent; // ent->groundentity_linkcount = trace.ent->linkcount; // if (!trace.startsolid && !trace.allsolid) // VectorCopy (trace.endpos, ent->s.origin); if (!trace.startsolid && !trace.allsolid) { VectorCopy (trace.endpos, ent->s.origin); ent->groundentity = trace.ent; ent->groundentity_linkcount = trace.ent->linkcount; ent->velocity[2] = 0; } } void M_CatagorizePosition (edict_t *ent) { vec3_t point; int cont; // // get waterlevel // point[0] = ent->s.origin[0]; point[1] = ent->s.origin[1]; point[2] = ent->s.origin[2] + ent->mins[2] + 1; cont = gi.pointcontents (point); if (!(cont & MASK_WATER)) { ent->waterlevel = 0; ent->watertype = 0; return; } ent->watertype = cont; ent->waterlevel = 1; point[2] += 26; cont = gi.pointcontents (point); if (!(cont & MASK_WATER)) return; ent->waterlevel = 2; point[2] += 22; cont = gi.pointcontents (point); if (cont & MASK_WATER) ent->waterlevel = 3; } void M_WorldEffects (edict_t *ent) { int dmg; if (ent->health > 0) { if (!(ent->flags & FL_SWIM)) { if (ent->waterlevel < 3) { ent->air_finished = level.time + 12; } else if (ent->air_finished < level.time) { // drown! if (ent->pain_debounce_time < level.time) { dmg = 2 + 2 * floor(level.time - ent->air_finished); if (dmg > 15) dmg = 15; T_Damage (ent, world, world, vec3_origin, ent->s.origin, vec3_origin, dmg, 0, DAMAGE_NO_ARMOR, MOD_WATER); ent->pain_debounce_time = level.time + 1; } } } else { if (ent->waterlevel > 0) { ent->air_finished = level.time + 9; } else if (ent->air_finished < level.time) { // suffocate! if (ent->pain_debounce_time < level.time) { dmg = 2 + 2 * floor(level.time - ent->air_finished); if (dmg > 15) dmg = 15; T_Damage (ent, world, world, vec3_origin, ent->s.origin, vec3_origin, dmg, 0, DAMAGE_NO_ARMOR, MOD_WATER); ent->pain_debounce_time = level.time + 1; } } } } if (ent->waterlevel == 0) { if (ent->flags & FL_INWATER) { gi.sound (ent, CHAN_BODY, gi.soundindex("player/watr_out.wav"), 1, ATTN_NORM, 0); ent->flags &= ~FL_INWATER; } return; } if ((ent->watertype & CONTENTS_LAVA) && !(ent->flags & FL_IMMUNE_LAVA)) { if (ent->damage_debounce_time < level.time) { ent->damage_debounce_time = level.time + 0.2; T_Damage (ent, world, world, vec3_origin, ent->s.origin, vec3_origin, 10*ent->waterlevel, 0, 0, MOD_LAVA); } } if ((ent->watertype & CONTENTS_SLIME) && !(ent->flags & FL_IMMUNE_SLIME)) { if (ent->damage_debounce_time < level.time) { ent->damage_debounce_time = level.time + 1; T_Damage (ent, world, world, vec3_origin, ent->s.origin, vec3_origin, 4*ent->waterlevel, 0, 0, MOD_SLIME); } } if ( !(ent->flags & FL_INWATER) ) { if (!(ent->svflags & SVF_DEADMONSTER)) { if (ent->watertype & CONTENTS_LAVA) if (random() <= 0.5) gi.sound (ent, CHAN_BODY, gi.soundindex("player/lava1.wav"), 1, ATTN_NORM, 0); else gi.sound (ent, CHAN_BODY, gi.soundindex("player/lava2.wav"), 1, ATTN_NORM, 0); else if (ent->watertype & CONTENTS_SLIME) gi.sound (ent, CHAN_BODY, gi.soundindex("player/watr_in.wav"), 1, ATTN_NORM, 0); else if (ent->watertype & CONTENTS_WATER) gi.sound (ent, CHAN_BODY, gi.soundindex("player/watr_in.wav"), 1, ATTN_NORM, 0); } ent->flags |= FL_INWATER; ent->damage_debounce_time = 0; } } void M_droptofloor (edict_t *ent) { vec3_t end; trace_t trace; ent->s.origin[2] += 1; VectorCopy (ent->s.origin, end); end[2] -= 256; trace = gi.trace (ent->s.origin, ent->mins, ent->maxs, end, ent, MASK_MONSTERSOLID); if (trace.fraction == 1 || trace.allsolid) return; VectorCopy (trace.endpos, ent->s.origin); gi.linkentity (ent); M_CheckGround (ent); M_CatagorizePosition (ent); } void M_SetEffects (edict_t *ent) { ent->s.effects &= ~(EF_COLOR_SHELL|EF_POWERSCREEN); ent->s.renderfx &= ~(RF_SHELL_RED|RF_SHELL_GREEN|RF_SHELL_BLUE); if (ent->monsterinfo.aiflags & AI_RESURRECTING) { ent->s.effects |= EF_COLOR_SHELL; ent->s.renderfx |= RF_SHELL_BLUE; } if (ent->health <= 0) return; } void M_MoveFrame (edict_t *self) { mmove_t *move; int index; move = self->monsterinfo.currentmove; self->nextthink = level.time + FRAMETIME; if ((self->monsterinfo.nextframe) && (self->monsterinfo.nextframe >= move->firstframe) && (self->monsterinfo.nextframe <= move->lastframe)) { self->s.frame = self->monsterinfo.nextframe; self->monsterinfo.nextframe = 0; } else { if (self->s.frame == move->lastframe) { if (move->endfunc) { move->endfunc (self); // regrab move, endfunc is very likely to change it move = self->monsterinfo.currentmove; // check for death if (self->svflags & SVF_DEADMONSTER) return; } } if (self->s.frame < move->firstframe || self->s.frame > move->lastframe) { self->monsterinfo.aiflags &= ~AI_HOLD_FRAME; self->s.frame = move->firstframe; } else { if (!(self->monsterinfo.aiflags & AI_HOLD_FRAME)) { self->s.frame++; if (self->s.frame > move->lastframe) self->s.frame = move->firstframe; } } } index = self->s.frame - move->firstframe; if (move->frame[index].aifunc) { if (!(self->monsterinfo.aiflags & AI_HOLD_FRAME)) move->frame[index].aifunc (self, move->frame[index].dist * self->monsterinfo.scale); else move->frame[index].aifunc (self, 0); } if (move->frame[index].thinkfunc) move->frame[index].thinkfunc (self); } void monster_think (edict_t *self) { M_MoveFrame (self); if (self->linkcount != self->monsterinfo.linkcount) { self->monsterinfo.linkcount = self->linkcount; M_CheckGround (self); } M_CatagorizePosition (self); M_WorldEffects (self); M_SetEffects (self); } /* ================ monster_use Using a monster makes it angry at the current activator ================ */ void monster_use (edict_t *self, edict_t *other, edict_t *activator) { if (self->enemy) return; if (self->health <= 0) return; if (activator->flags & FL_NOTARGET) return; if (!(activator->client) && !(activator->monsterinfo.aiflags & AI_GOOD_GUY)) return; // delay reaction so if the monster is teleported, its sound is still heard self->enemy = activator; FoundTarget (self); } void monster_start_go (edict_t *self); void monster_triggered_spawn (edict_t *self) { self->s.origin[2] += 1; KillBox (self); self->solid = SOLID_BBOX; self->movetype = MOVETYPE_STEP; self->svflags &= ~SVF_NOCLIENT; self->air_finished = level.time + 12; gi.linkentity (self); monster_start_go (self); if (self->enemy && !(self->spawnflags & 1) && !(self->enemy->flags & FL_NOTARGET)) { FoundTarget (self); } else { self->enemy = NULL; } } void monster_triggered_spawn_use (edict_t *self, edict_t *other, edict_t *activator) { // we have a one frame delay here so we don't telefrag the guy who activated us self->think = monster_triggered_spawn; self->nextthink = level.time + FRAMETIME; if (activator->client) self->enemy = activator; self->use = monster_use; } void monster_triggered_start (edict_t *self) { self->solid = SOLID_NOT; self->movetype = MOVETYPE_NONE; self->svflags |= SVF_NOCLIENT; self->nextthink = 0; self->use = monster_triggered_spawn_use; } /* ================ monster_death_use When a monster dies, it fires all of its targets with the current enemy as activator. ================ */ void monster_death_use (edict_t *self) { self->flags &= ~(FL_FLY|FL_SWIM); self->monsterinfo.aiflags &= AI_GOOD_GUY; if (self->item) { Drop_Item (self, self->item); self->item = NULL; } if (self->deathtarget) self->target = self->deathtarget; if (!self->target) return; G_UseTargets (self, self->enemy); } //============================================================================ qboolean monster_start (edict_t *self) { if ((self->spawnflags & 4) && !(self->monsterinfo.aiflags & AI_GOOD_GUY)) { self->spawnflags &= ~4; self->spawnflags |= 1; // gi.dprintf("fixed spawnflags on %s at %s\n", self->classname, vtos(self->s.origin)); } if (!(self->monsterinfo.aiflags & AI_GOOD_GUY)) level.total_monsters++; self->nextthink = level.time + FRAMETIME; self->svflags |= SVF_MONSTER; self->takedamage = DAMAGE_AIM; self->air_finished = level.time + 12; self->use = monster_use; self->max_health = self->health; self->clipmask = MASK_MONSTERSOLID; self->s.skinnum = 0; self->deadflag = DEAD_NO; self->svflags &= ~SVF_DEADMONSTER; if (!self->monsterinfo.checkattack) self->monsterinfo.checkattack = M_CheckAttack; VectorCopy (self->s.origin, self->s.old_origin); if (st.item) { self->item = FindItemByClassname (st.item); if (!self->item) gi.dprintf("%s at %s has bad item: %s\n", self->classname, vtos(self->s.origin), st.item); } // randomize what frame they start on if (self->monsterinfo.currentmove) self->s.frame = self->monsterinfo.currentmove->firstframe + (rand() % (self->monsterinfo.currentmove->lastframe - self->monsterinfo.currentmove->firstframe + 1)); return true; } void monster_start_go (edict_t *self) { vec3_t v; if (self->health <= 0) return; // check for target to combat_point and change to combattarget if (self->target) { qboolean notcombat; qboolean fixup; edict_t *target; target = NULL; notcombat = false; fixup = false; while ((target = G_Find (target, FOFS(targetname), self->target)) != NULL) { if (strcmp(target->classname, "point_combat") == 0) { self->combattarget = self->target; fixup = true; } else { notcombat = true; } } if (notcombat && self->combattarget) gi.dprintf("%s at %s has target with mixed types\n", self->classname, vtos(self->s.origin)); if (fixup) self->target = NULL; } // validate combattarget if (self->combattarget) { edict_t *target; target = NULL; while ((target = G_Find (target, FOFS(targetname), self->combattarget)) != NULL) { if (strcmp(target->classname, "point_combat") != 0) { gi.dprintf("%s at (%i %i %i) has a bad combattarget %s : %s at (%i %i %i)\n", self->classname, (int)self->s.origin[0], (int)self->s.origin[1], (int)self->s.origin[2], self->combattarget, target->classname, (int)target->s.origin[0], (int)target->s.origin[1], (int)target->s.origin[2]); } } } if (self->target) { self->goalentity = self->movetarget = G_PickTarget(self->target); if (!self->movetarget) { gi.dprintf ("%s can't find target %s at %s\n", self->classname, self->target, vtos(self->s.origin)); self->target = NULL; self->monsterinfo.pausetime = 100000000; self->monsterinfo.stand (self); } else if (strcmp (self->movetarget->classname, "path_corner") == 0) { VectorSubtract (self->goalentity->s.origin, self->s.origin, v); self->ideal_yaw = self->s.angles[YAW] = vectoyaw(v); self->monsterinfo.walk (self); self->target = NULL; } else { self->goalentity = self->movetarget = NULL; self->monsterinfo.pausetime = 100000000; self->monsterinfo.stand (self); } } else { self->monsterinfo.pausetime = 100000000; self->monsterinfo.stand (self); } self->think = monster_think; self->nextthink = level.time + FRAMETIME; } void walkmonster_start_go (edict_t *self) { if (!(self->spawnflags & 2) && level.time < 1) { M_droptofloor (self); if (self->groundentity) if (!M_walkmove (self, 0, 0)) gi.dprintf ("%s in solid at %s\n", self->classname, vtos(self->s.origin)); } if (!self->yaw_speed) self->yaw_speed = 20; self->viewheight = 25; monster_start_go (self); if (self->spawnflags & 2) monster_triggered_start (self); } void walkmonster_start (edict_t *self) { self->think = walkmonster_start_go; monster_start (self); } void flymonster_start_go (edict_t *self) { if (!M_walkmove (self, 0, 0)) gi.dprintf ("%s in solid at %s\n", self->classname, vtos(self->s.origin)); if (!self->yaw_speed) self->yaw_speed = 10; self->viewheight = 25; monster_start_go (self); if (self->spawnflags & 2) monster_triggered_start (self); } void flymonster_start (edict_t *self) { self->flags |= FL_FLY; self->think = flymonster_start_go; monster_start (self); } void swimmonster_start_go (edict_t *self) { if (!self->yaw_speed) self->yaw_speed = 10; self->viewheight = 10; monster_start_go (self); if (self->spawnflags & 2) monster_triggered_start (self); } void swimmonster_start (edict_t *self) { self->flags |= FL_SWIM; self->think = swimmonster_start_go; monster_start (self); } alien-arena-7.66+dfsg/source/game/g_weapon.c0000600000175000017500000017215512161402010017771 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. Copyright (C) 20?? COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" #ifdef ALTERIA //add Alteria weapon code void fire_punch(edict_t *self, vec3_t start, vec3_t aimdir, int damage) { vec3_t from; vec3_t end; trace_t tr; edict_t *ignore; if ( g_antilag->integer) G_DoTimeShiftFor( self ); VectorMA (start, 32, aimdir, end); VectorCopy (start, from); ignore = self; tr = gi.trace (from, NULL, NULL, end, ignore, MASK_SHOT); if (tr.ent != self) { if(tr.ent->takedamage || (tr.fraction < 1.0)) { if(tr.ent->takedamage) T_Damage (tr.ent, self, self, aimdir, tr.endpos, tr.plane.normal, damage, 4, 0, MOD_VIOLATOR); //add alteria mod types gi.sound (self, CHAN_VOICE, gi.soundindex("misc/hit.wav"), 1, ATTN_STATIC, 0); //change to impact sound //change this to smoke puffs or similar gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_CHAINGUNSMOKE); //note TE_SMOKE is available and unused if we want better impact effects gi.WritePosition (tr.endpos); gi.multicast (start, MULTICAST_PVS); } } if ( g_antilag->integer) G_UndoTimeShiftFor( self ); } #else /* ================= fire_lead This is an internal support routine used for bullet/pellet based weapons. ================= */ static void fire_lead (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int te_impact, int hspread, int vspread, int mod, int silentHit) { trace_t tr; vec3_t dir; vec3_t forward, right, up; vec3_t end; float r; float u; vec3_t water_start; qboolean water = false; int content_mask = MASK_SHOT | MASK_WATER; if ( g_antilag->integer) G_DoTimeShiftFor( self ); self->client->resp.weapon_shots[3]++; tr = gi.trace (self->s.origin, NULL, NULL, start, self, MASK_SHOT); if (!(tr.fraction < 1.0)) { vectoangles (aimdir, dir); AngleVectors (dir, forward, right, up); r = crandom()*hspread; u = crandom()*vspread; VectorMA (start, 8192, forward, end); VectorMA (end, r, right, end); VectorMA (end, u, up, end); if (gi.pointcontents (start) & MASK_WATER) { water = true; VectorCopy (start, water_start); content_mask &= ~MASK_WATER; } tr = gi.trace (start, NULL, NULL, end, self, content_mask); // see if we hit water if (tr.contents & MASK_WATER) { int color; water = true; VectorCopy (tr.endpos, water_start); if (!VectorCompare (start, tr.endpos)) { if (tr.contents & CONTENTS_WATER) { if (strcmp(tr.surface->name, "*brwater") == 0) color = SPLASH_BROWN_WATER; else color = SPLASH_BLUE_WATER; } else if (tr.contents & CONTENTS_SLIME) color = SPLASH_SLIME; else if (tr.contents & CONTENTS_LAVA) color = SPLASH_LAVA; else color = SPLASH_UNKNOWN; if (color != SPLASH_UNKNOWN) { gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_SPLASH); gi.WriteByte (8); gi.WritePosition (tr.endpos); gi.WriteDir (tr.plane.normal); gi.WriteByte (color); gi.multicast (tr.endpos, MULTICAST_PVS); } // change bullet's course when it enters water VectorSubtract (end, start, dir); vectoangles (dir, dir); AngleVectors (dir, forward, right, up); r = crandom()*hspread*2; u = crandom()*vspread*2; VectorMA (water_start, 8192, forward, end); VectorMA (end, r, right, end); VectorMA (end, u, up, end); } // re-trace ignoring water this time tr = gi.trace (water_start, NULL, NULL, end, self, MASK_SHOT); } } // send gun puff / flash if (!((tr.surface) && (tr.surface->flags & SURF_SKY))) { if (tr.fraction < 1.0) { if (tr.ent->takedamage) { T_Damage (tr.ent, self, self, aimdir, tr.endpos, tr.plane.normal, damage, kick, DAMAGE_BULLET, mod); self->client->resp.weapon_hits[3]++; if(!silentHit) gi.sound (self, CHAN_VOICE, gi.soundindex("misc/hit.wav"), 1, ATTN_STATIC, 0); } else { if (strncmp (tr.surface->name, "sky", 3) != 0) { gi.WriteByte (svc_temp_entity); gi.WriteByte (te_impact); gi.WritePosition (tr.endpos); gi.WriteDir (tr.plane.normal); gi.multicast (tr.endpos, MULTICAST_PVS); if (self->client) PlayerNoise(self, tr.endpos, PNOISE_IMPACT); } } } } // if went through water, determine where the end and make a bubble trail if (water) { vec3_t pos; VectorSubtract (tr.endpos, water_start, dir); VectorNormalize (dir); VectorMA (tr.endpos, -2, dir, pos); if (gi.pointcontents (pos) & MASK_WATER) VectorCopy (pos, tr.endpos); else tr = gi.trace (pos, NULL, NULL, water_start, tr.ent, MASK_WATER); VectorAdd (water_start, tr.endpos, pos); VectorScale (pos, 0.5, pos); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BUBBLETRAIL); gi.WritePosition (water_start); gi.WritePosition (tr.endpos); gi.multicast (pos, MULTICAST_PVS); } if ( g_antilag->integer) G_UndoTimeShiftFor( self ); } /* ================= fire_bullet Fires a single round. Used for machinegun and chaingun. Would be fine for pistols, rifles, etc.... ================= */ void fire_bullet (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, int mod) { fire_lead (self, start, aimdir, damage, kick, TE_GUNSHOT, hspread, vspread, mod, false); } /* ================= fire_shotgun Shoots shotgun pellets. Used by shotgun and super shotgun. ================= */ void fire_shotgun (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, int count, int mod) { int i; for (i = 0; i < count; i++) fire_lead (self, start, aimdir, damage, kick, TE_GUNSHOT, hspread, vspread, mod, i); } /* ================= fire_blaster Fires a single blaster bolt. Used by the blaster and hyper blaster. ================= */ void blaster_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { int mod; if (other == self->owner) return; if (surf && (surf->flags & SURF_SKY)) { G_FreeEdict (self); return; } if (self->owner->client) PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT); if (other->takedamage) { if (self->spawnflags & 1) mod = MOD_BEAMGUN; else mod = MOD_BLASTER; T_Damage (other, self, self->owner, self->velocity, self->s.origin, plane->normal, self->dmg, 1, DAMAGE_ENERGY, mod); self->owner->client->resp.weapon_hits[0]++; gi.sound (self->owner, CHAN_VOICE, gi.soundindex("misc/hit.wav"), 1, ATTN_STATIC, 0); } else { gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BLASTER); //gonna change this badboy gi.WritePosition (self->s.origin); if (!plane) gi.WriteDir (vec3_origin); else gi.WriteDir (plane->normal); gi.multicast (self->s.origin, MULTICAST_PVS); } G_FreeEdict (self); } void blasterball_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { int mod; if (other == self->owner) return; if (surf && (surf->flags & SURF_SKY)) { G_FreeEdict (self); return; } if (self->owner->client) PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT); if (other->takedamage) { if (self->spawnflags & 1) mod = MOD_BEAMGUN; else mod = MOD_BLASTER; T_Damage (other, self, self->owner, self->velocity, self->s.origin, plane->normal, self->dmg, 1, DAMAGE_ENERGY, mod); self->owner->client->resp.weapon_hits[0]++; gi.sound (self->owner, CHAN_VOICE, gi.soundindex("misc/hit.wav"), 1, ATTN_STATIC, 0); } else { gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BLASTER); gi.WritePosition (self->s.origin); if (!plane) gi.WriteDir (vec3_origin); else gi.WriteDir (plane->normal); gi.multicast (self->s.origin, MULTICAST_PVS); } T_RadiusDamage(self, self->owner, 95, other, 150, MOD_PLASMA_SPLASH, 0); G_FreeEdict (self); } void alienblasterball_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { int mod; if (other == self->owner) return; if (surf && (surf->flags & SURF_SKY)) { G_FreeEdict (self); return; } if (self->owner->client) PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT); if (other->takedamage) { if (self->spawnflags & 1) mod = MOD_BEAMGUN; else mod = MOD_BLASTER; T_Damage (other, self, self->owner, self->velocity, self->s.origin, plane->normal, self->dmg, 1, DAMAGE_ENERGY, mod); self->owner->client->resp.weapon_hits[0]++; gi.sound (self->owner, CHAN_VOICE, gi.soundindex("misc/hit.wav"), 1, ATTN_STATIC, 0); } else { gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_SCREEN_SPARKS); gi.WritePosition (self->s.origin); if (!plane) gi.WriteDir (vec3_origin); else gi.WriteDir (plane->normal); gi.multicast (self->s.origin, MULTICAST_PVS); } T_RadiusDamage(self, self->owner, 95, other, 150, MOD_PLASMA_SPLASH, 0); G_FreeEdict (self); } void fire_blasterball (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, int effect, qboolean hyper, qboolean alien) { edict_t *bolt; trace_t tr; self->client->resp.weapon_shots[0]++; VectorNormalize (dir); bolt = G_Spawn(); bolt->svflags = SVF_DEADMONSTER; VectorCopy (start, bolt->s.origin); VectorCopy (start, bolt->s.old_origin); vectoangles (dir, bolt->s.angles); VectorScale (dir, speed, bolt->velocity); bolt->movetype = MOVETYPE_FLYMISSILE; bolt->clipmask = MASK_SHOT; bolt->solid = SOLID_BBOX; if(effect == EF_ROCKET) { //ack, kinda assbackwards, but the past mistakes haunt us bolt->s.effects |= EF_BLASTER; bolt->s.modelindex = gi.modelindex ("models/objects/laser/tris.md2"); } else { bolt->s.effects |= EF_PLASMA; bolt->s.modelindex = gi.modelindex ("models/objects/fireball/tris.md2"); } // All we care about is the effects. However, old clients will refuse to // draw them unless the modelindex is set. To work around this, newer // clients have an RF_NODRAW flag. bolt->s.renderfx |= RF_NODRAW; VectorClear (bolt->mins); VectorClear (bolt->maxs); bolt->s.sound = gi.soundindex ("misc/lasfly.wav"); bolt->owner = self; if(alien) bolt->touch = alienblasterball_touch; else bolt->touch = blasterball_touch; bolt->nextthink = level.time + 2; bolt->think = G_FreeEdict; bolt->dmg = damage; bolt->classname = "bolt"; gi.linkentity (bolt); tr = gi.trace (self->s.origin, NULL, NULL, bolt->s.origin, bolt, MASK_SHOT); if (tr.fraction < 1.0) { VectorMA (bolt->s.origin, -10, dir, bolt->s.origin); bolt->touch (bolt, tr.ent, NULL, NULL); } if ( g_antilag->integer && g_antilagprojectiles->integer) G_AntilagProjectile (bolt); } void fire_blaster (edict_t *self, vec3_t start, vec3_t muzzle, vec3_t aimdir, int damage, int speed, int effect, qboolean hyper) { vec3_t from; vec3_t end; trace_t tr; edict_t *ignore; int mask; qboolean water; if ( g_antilag->integer) G_DoTimeShiftFor( self ); self->client->resp.weapon_shots[6]++; VectorMA (start, 8192, aimdir, end); VectorCopy (start, from); ignore = self; water = false; mask = MASK_SHOT|CONTENTS_SLIME|CONTENTS_LAVA; tr = gi.trace (from, NULL, NULL, end, ignore, mask); if (tr.contents & (CONTENTS_SLIME|CONTENTS_LAVA)) { mask &= ~(CONTENTS_SLIME|CONTENTS_LAVA); water = true; } else { if ((tr.ent != self) && (tr.ent->takedamage)) { T_Damage (tr.ent, self, self, aimdir, tr.endpos, tr.plane.normal, damage, 0, 0, MOD_BLASTER); self->client->resp.weapon_hits[6]++; gi.sound (self, CHAN_VOICE, gi.soundindex("misc/hit.wav"), 1, ATTN_STATIC, 0); } } VectorCopy (tr.endpos, from); VectorMA (start, 8192, aimdir, end); VectorCopy (start, from); // trace for end point of laser beam. // the laser aim is perfect. // no random aim like the machinegun tr = gi.trace (from, NULL, NULL, end, self, MASK_SHOT); // send laser beam temp entity to clients VectorCopy (tr.endpos, from); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_LASERBEAM); gi.WritePosition (muzzle); gi.WritePosition (tr.endpos); gi.multicast (self->s.origin, MULTICAST_PHS); if ((tr.ent != self) && (tr.ent->takedamage)) { T_Damage (tr.ent, self, self, aimdir, tr.endpos, tr.plane.normal, damage, 0, 0, MOD_BEAMGUN); self->client->resp.weapon_hits[6]++; gi.sound (self, CHAN_VOICE, gi.soundindex("misc/hit.wav"), 1, ATTN_STATIC, 0); } else if (!((tr.surface) && (tr.surface->flags & SURF_SKY))) { gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_SCREEN_SPARKS); gi.WritePosition (tr.endpos); gi.WriteDir (tr.plane.normal); gi.multicast (self->s.origin, MULTICAST_PVS); } if ( g_antilag->integer) G_UndoTimeShiftFor( self ); } /* ================= fire_rocket ================= */ void rocket_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { vec3_t origin; if (other == ent->owner) return; if (surf && (surf->flags & SURF_SKY)) { G_FreeEdict (ent); return; } if (ent->owner->client) PlayerNoise(ent->owner, ent->s.origin, PNOISE_IMPACT); // calculate position for the explosion entity VectorMA (ent->s.origin, -0.02, ent->velocity, origin); if (other->takedamage) { T_Damage (other, ent, ent->owner, ent->velocity, ent->s.origin, plane->normal, ent->dmg, 0, 0, MOD_ROCKET); ent->owner->client->resp.weapon_hits[5]++; gi.sound (ent->owner, CHAN_VOICE, gi.soundindex("misc/hit.wav"), 1, ATTN_STATIC, 0); } T_RadiusDamage(ent, ent->owner, ent->radius_dmg, other, ent->dmg_radius, MOD_R_SPLASH, 5); gi.WriteByte (svc_temp_entity); if (ent->waterlevel) gi.WriteByte (TE_ROCKET_EXPLOSION_WATER); else gi.WriteByte (TE_ROCKET_EXPLOSION); gi.WritePosition (origin); gi.multicast (ent->s.origin, MULTICAST_PHS); G_FreeEdict (ent); } void fire_rocket (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage) { edict_t *rocket; self->client->resp.weapon_shots[5]++; rocket = G_Spawn(); VectorCopy (start, rocket->s.origin); VectorCopy (dir, rocket->movedir); vectoangles (dir, rocket->s.angles); VectorScale (dir, speed, rocket->velocity); rocket->movetype = MOVETYPE_FLYMISSILE; rocket->clipmask = MASK_SHOT; rocket->solid = SOLID_BBOX; rocket->s.effects |= EF_ROCKETEXHAUST ; rocket->s.renderfx |= RF_FULLBRIGHT ; if (!excessive->integer && self->client->invincible_framenum <= level.framenum) //With too many rockets, lots of smoke trails hurt performance. rocket->s.effects |= EF_ROCKET; VectorClear (rocket->mins); VectorClear (rocket->maxs); rocket->s.modelindex = gi.modelindex ("models/objects/rocket/tris.md2"); rocket->owner = self; rocket->touch = rocket_touch; rocket->nextthink = level.time + 8000/speed; rocket->think = G_FreeEdict; rocket->dmg = damage; rocket->radius_dmg = radius_damage; rocket->dmg_radius = damage_radius; rocket->s.sound = gi.soundindex ("weapons/rockfly.wav"); rocket->classname = "rocket"; gi.linkentity (rocket); if ( g_antilag->integer && g_antilagprojectiles->integer) G_AntilagProjectile (rocket); } /* ================= fire_stinger ================= */ void stinger_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { vec3_t origin; int n; if (other == ent->owner) return; if (surf && (surf->flags & SURF_SKY)) { G_FreeEdict (ent); return; } if (ent->owner->client) PlayerNoise(ent->owner, ent->s.origin, PNOISE_IMPACT); // calculate position for the explosion entity VectorMA (ent->s.origin, -0.02, ent->velocity, origin); if (other->takedamage) { T_Damage (other, ent, ent->owner, ent->velocity, ent->s.origin, plane->normal, ent->dmg, 0, 0, MOD_ROCKET); ent->owner->client->resp.weapon_hits[5]++; gi.sound (ent->owner, CHAN_VOICE, gi.soundindex("misc/hit.wav"), 1, ATTN_STATIC, 0); } else { // don't throw any debris in net games if (!deathmatch->value) { if ((surf) && !(surf->flags & (SURF_WARP|SURF_TRANS33|SURF_TRANS66|SURF_FLOWING))) { n = rand() % 5; while(n--) ThrowDebris (ent, "models/objects/debris2/tris.md2", 2, ent->s.origin); } } } T_RadiusDamage(ent, ent->owner, ent->radius_dmg, other, ent->dmg_radius, MOD_R_SPLASH, 5); gi.WriteByte (svc_temp_entity); if (ent->waterlevel) gi.WriteByte (TE_ROCKET_EXPLOSION_WATER); else gi.WriteByte (TE_ROCKET_EXPLOSION); gi.WritePosition (origin); gi.multicast (ent->s.origin, MULTICAST_PHS); G_FreeEdict (ent); } void fire_blaster_beam (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, qboolean detonate, qboolean alien) { vec3_t from; vec3_t end; vec3_t dir; trace_t tr; edict_t *ignore, *bomb; int mask; qboolean water; vec3_t water_start; int content_mask = MASK_SHOT | MASK_WATER; if ( g_antilag->integer) G_DoTimeShiftFor( self ); self->client->resp.weapon_shots[0]++; VectorMA (start, 8192, aimdir, end); VectorCopy (start, from); ignore = self; water = false; mask = MASK_SHOT|CONTENTS_SLIME|CONTENTS_LAVA; tr = gi.trace (from, NULL, NULL, end, ignore, mask); if (tr.contents & (CONTENTS_SLIME|CONTENTS_LAVA)) { mask &= ~(CONTENTS_SLIME|CONTENTS_LAVA); water = true; } else { if ((tr.ent != self) && (tr.ent->takedamage)) { T_Damage (tr.ent, self, self, aimdir, tr.endpos, tr.plane.normal, damage, kick, 0, MOD_BLASTER); self->client->resp.weapon_hits[0]++; gi.sound (self, CHAN_VOICE, gi.soundindex("misc/hit.wav"), 1, ATTN_STATIC, 0); } } VectorCopy (tr.endpos, from); VectorMA (start, 8192, aimdir, end); VectorCopy (start, from); // trace for end point of laser beam. // the laser aim is perfect. // no random aim like the machinegun tr = gi.trace (from, NULL, NULL, end, self, MASK_SHOT); // send laser beam temp entity to clients VectorCopy (tr.endpos, from); gi.WriteByte (svc_temp_entity); if(alien) gi.WriteByte (TE_LASERBEAM); else gi.WriteByte (TE_BLASTERBEAM); gi.WritePosition (start); gi.WritePosition (tr.endpos); gi.multicast (self->s.origin, MULTICAST_PHS); gi.WriteByte (svc_temp_entity); if(alien) gi.WriteByte (TE_SCREEN_SPARKS); else gi.WriteByte (TE_BLASTER); gi.WritePosition (tr.endpos); gi.WriteDir (tr.plane.normal); gi.multicast (tr.endpos, MULTICAST_PVS); if(detonate) { //spawn a new ent at end of explosion - and detonate it bomb = G_Spawn(); VectorCopy (tr.endpos, bomb->s.origin); bomb->movetype = MOVETYPE_NONE; bomb->solid = SOLID_NOT; bomb->s.modelindex = 0; bomb->owner = self; bomb->think = G_FreeEdict; bomb->classname = "bomb"; gi.linkentity (bomb); T_RadiusDamage(bomb, self, 50, NULL, 200, MOD_VAPORALTFIRE, 0); G_FreeEdict (bomb); } if (gi.pointcontents (start) & MASK_WATER) { water = true; VectorCopy (start, water_start); content_mask &= ~MASK_WATER; } tr = gi.trace (start, NULL, NULL, end, self, content_mask); // see if we hit water if (tr.contents & MASK_WATER) { int color; water = true; VectorCopy (tr.endpos, water_start); if (!VectorCompare (start, tr.endpos)) { if (tr.contents & CONTENTS_WATER) { if (strcmp(tr.surface->name, "*brwater") == 0) color = SPLASH_BROWN_WATER; else color = SPLASH_BLUE_WATER; } else if (tr.contents & CONTENTS_SLIME) color = SPLASH_SLIME; else if (tr.contents & CONTENTS_LAVA) color = SPLASH_LAVA; else color = SPLASH_UNKNOWN; if (color != SPLASH_UNKNOWN) { gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_SPLASH); gi.WriteByte (8); gi.WritePosition (tr.endpos); gi.WriteDir (tr.plane.normal); gi.WriteByte (color); gi.multicast (tr.endpos, MULTICAST_PVS); } } } // if went through water, determine where the end and make a bubble trail if (water) { vec3_t pos; VectorSubtract (tr.endpos, water_start, dir); VectorNormalize (dir); VectorMA (tr.endpos, -2, dir, pos); if (gi.pointcontents (pos) & MASK_WATER) VectorCopy (pos, tr.endpos); else tr = gi.trace (pos, NULL, NULL, water_start, tr.ent, MASK_WATER); VectorAdd (water_start, tr.endpos, pos); VectorScale (pos, 0.5, pos); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BUBBLETRAIL); gi.WritePosition (water_start); gi.WritePosition (tr.endpos); gi.multicast (pos, MULTICAST_PVS); } if ( g_antilag->integer) G_UndoTimeShiftFor( self ); } void fire_hover_beam (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, qboolean detonate) { vec3_t from; vec3_t end; vec3_t dir; trace_t tr; edict_t *ignore, *bomb; int mask; qboolean water; vec3_t water_start; int content_mask = MASK_SHOT | MASK_WATER; if ( g_antilag->integer) G_DoTimeShiftFor( self ); VectorMA (start, 8192, aimdir, end); VectorCopy (start, from); ignore = self; water = false; mask = MASK_SHOT|CONTENTS_SLIME|CONTENTS_LAVA; tr = gi.trace (from, NULL, NULL, end, ignore, mask); if (tr.contents & (CONTENTS_SLIME|CONTENTS_LAVA)) { mask &= ~(CONTENTS_SLIME|CONTENTS_LAVA); water = true; } else { if ((tr.ent != self) && (tr.ent->takedamage)) T_Damage (tr.ent, self, self, aimdir, tr.endpos, tr.plane.normal, damage, kick, 0, MOD_BLASTER); if (tr.ent->health > 0) { gi.sound (self, CHAN_VOICE, gi.soundindex("misc/hit.wav"), 1, ATTN_STATIC, 0); } } VectorCopy (tr.endpos, from); VectorMA (start, 8192, aimdir, end); VectorCopy (start, from); // trace for end point of laser beam. // the laser aim is perfect. // no random aim like the machinegun tr = gi.trace (from, NULL, NULL, end, self, MASK_SHOT); // send laser beam temp entity to clients VectorCopy (tr.endpos, from); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_REDLASER); gi.WritePosition (start); gi.WritePosition (tr.endpos); gi.multicast (self->s.origin, MULTICAST_PHS); if(detonate) { //spawn a new ent at end of explosion - and detonate it bomb = G_Spawn(); VectorCopy (tr.endpos, bomb->s.origin); bomb->movetype = MOVETYPE_NONE; bomb->solid = SOLID_NOT; bomb->s.modelindex = 0; bomb->owner = self; bomb->think = G_FreeEdict; bomb->classname = "bomb"; gi.linkentity (bomb); T_RadiusDamage(bomb, self, 100, NULL, 200, MOD_VAPORALTFIRE, -1); gi.WriteByte (svc_temp_entity); if (bomb->waterlevel) gi.WriteByte (TE_ROCKET_EXPLOSION_WATER); else gi.WriteByte (TE_ROCKET_EXPLOSION); gi.WritePosition (bomb->s.origin); gi.multicast (bomb->s.origin, MULTICAST_PHS); G_FreeEdict (bomb); } if (gi.pointcontents (start) & MASK_WATER) { water = true; VectorCopy (start, water_start); content_mask &= ~MASK_WATER; } tr = gi.trace (start, NULL, NULL, end, self, content_mask); // see if we hit water if (tr.contents & MASK_WATER) { int color; water = true; VectorCopy (tr.endpos, water_start); if (!VectorCompare (start, tr.endpos)) { if (tr.contents & CONTENTS_WATER) { if (strcmp(tr.surface->name, "*brwater") == 0) color = SPLASH_BROWN_WATER; else color = SPLASH_BLUE_WATER; } else if (tr.contents & CONTENTS_SLIME) color = SPLASH_SLIME; else if (tr.contents & CONTENTS_LAVA) color = SPLASH_LAVA; else color = SPLASH_UNKNOWN; if (color != SPLASH_UNKNOWN) { gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_SPLASH); gi.WriteByte (8); gi.WritePosition (tr.endpos); gi.WriteDir (tr.plane.normal); gi.WriteByte (color); gi.multicast (tr.endpos, MULTICAST_PVS); } } } // if went through water, determine where the end and make a bubble trail if (water) { vec3_t pos; VectorSubtract (tr.endpos, water_start, dir); VectorNormalize (dir); VectorMA (tr.endpos, -2, dir, pos); if (gi.pointcontents (pos) & MASK_WATER) VectorCopy (pos, tr.endpos); else tr = gi.trace (pos, NULL, NULL, water_start, tr.ent, MASK_WATER); VectorAdd (water_start, tr.endpos, pos); VectorScale (pos, 0.5, pos); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BUBBLETRAIL); gi.WritePosition (water_start); gi.WritePosition (tr.endpos); gi.multicast (pos, MULTICAST_PVS); } if ( g_antilag->integer) G_UndoTimeShiftFor( self ); } void fire_disruptor (edict_t *self, vec3_t start, vec3_t muzzle, vec3_t aimdir, int damage, int kick) { vec3_t from; vec3_t end; trace_t tr; edict_t *ignore, *bomb; int mask; qboolean water; if ( g_antilag->integer) G_DoTimeShiftFor( self ); self->client->resp.weapon_shots[1]++; VectorMA (start, 8192, aimdir, end); VectorCopy (start, from); ignore = self; water = false; mask = MASK_SHOT|CONTENTS_SLIME|CONTENTS_LAVA; tr = gi.trace (from, NULL, NULL, end, ignore, mask); if (tr.contents & (CONTENTS_SLIME|CONTENTS_LAVA)) { mask &= ~(CONTENTS_SLIME|CONTENTS_LAVA); water = true; } else { if ((tr.ent != self) && (tr.ent->takedamage)) { T_Damage (tr.ent, self, self, aimdir, tr.endpos, tr.plane.normal, damage, kick, 0, MOD_DISRUPTOR); self->client->resp.weapon_hits[1]++; gi.sound (self, CHAN_VOICE, gi.soundindex("misc/hit.wav"), 1, ATTN_STATIC, 0); } } VectorCopy (tr.endpos, from); VectorMA (start, 8192, aimdir, end); VectorCopy (start, from); // trace for end point of laser beam. // the laser aim is perfect. // no random aim like the machinegun tr = gi.trace (from, NULL, NULL, end, self, MASK_SHOT); // send laser beam temp entity to clients VectorCopy (tr.endpos, from); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_RAILTRAIL); gi.WritePosition (muzzle); gi.WritePosition (tr.endpos); gi.multicast (self->s.origin, MULTICAST_PHS); //spawn a new ent at end and detonate - for trick jumping bomb = G_Spawn(); VectorCopy (tr.endpos, bomb->s.origin); bomb->movetype = MOVETYPE_NONE; bomb->solid = SOLID_NOT; bomb->s.modelindex = 0; bomb->owner = self; bomb->think = G_FreeEdict; bomb->classname = "bomb"; gi.linkentity (bomb); T_RadiusDamage(bomb, self, 95, NULL, 50, MOD_PLASMA_SPLASH, -1); G_FreeEdict (bomb); if (self->client) PlayerNoise(self, tr.endpos, PNOISE_IMPACT); if ( g_antilag->integer) G_UndoTimeShiftFor( self ); } //vaporizer code void fire_vaporizer (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick) { vec3_t from; vec3_t end; trace_t tr; edict_t *ignore; edict_t *bomb; int mask; qboolean water; if ( g_antilag->integer) G_DoTimeShiftFor( self ); self->client->resp.weapon_shots[7]++; VectorMA (start, 8192, aimdir, end); VectorCopy (start, from); ignore = self; water = false; mask = MASK_SHOT|CONTENTS_SLIME|CONTENTS_LAVA; tr = gi.trace (from, NULL, NULL, end, ignore, mask); if (tr.contents & (CONTENTS_SLIME|CONTENTS_LAVA)) { mask &= ~(CONTENTS_SLIME|CONTENTS_LAVA); water = true; } else { if ((tr.ent != self) && (tr.ent->takedamage)) { T_Damage (tr.ent, self, self, aimdir, tr.endpos, tr.plane.normal, damage, kick, 0, MOD_VAPORIZER); self->client->resp.weapon_hits[7]++; gi.sound (self, CHAN_VOICE, gi.soundindex("misc/hit.wav"), 1, ATTN_STATIC, 0); T_RadiusDamage(tr.ent, self, damage, NULL, 120, MOD_VAPORIZER, -1); } } VectorCopy (tr.endpos, from); VectorMA (start, 8192, aimdir, end); VectorCopy (start, from); // trace for end point of laser beam. // the laser aim is perfect. // no random aim like the machinegun tr = gi.trace (from, NULL, NULL, end, self, MASK_SHOT); // send laser beam temp entity to clients VectorCopy (tr.endpos, from); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_VAPORBEAM); gi.WritePosition (start); gi.WritePosition (tr.endpos); gi.multicast (self->s.origin, MULTICAST_PHS); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BFG_BIGEXPLOSION); gi.WritePosition (tr.endpos); gi.multicast (tr.endpos, MULTICAST_PVS); //spawn a new ent at end of explosion - and detonate it bomb = G_Spawn(); VectorCopy (tr.endpos, bomb->s.origin); bomb->movetype = MOVETYPE_NONE; bomb->solid = SOLID_NOT; bomb->s.modelindex = 0; bomb->owner = self; bomb->think = G_FreeEdict; bomb->classname = "bomb"; gi.linkentity (bomb); T_RadiusDamage(bomb, self, 150, NULL, 150, MOD_VAPORIZER, 7); //ridiculously powerful! G_FreeEdict (bomb); if (self->client) PlayerNoise(self, tr.endpos, PNOISE_IMPACT); if ( g_antilag->integer) G_UndoTimeShiftFor( self ); } void homing_think (edict_t *ent) { edict_t *target = NULL; edict_t *blip = NULL; vec3_t targetdir, blipdir; vec_t speed; while ((blip = findradius(blip, ent->s.origin, 1000)) != NULL) { if (!(blip->svflags & SVF_MONSTER) && !blip->client) continue; if (blip == ent->owner) continue; if (!blip->takedamage) continue; if (blip->health <= 0) continue; if (!visible(ent, blip)) continue; if (!infront(ent, blip)) continue; VectorSubtract(blip->s.origin, ent->s.origin, blipdir); blipdir[2] += 16; if ((target == NULL) || (VectorLength(blipdir) < VectorLength(targetdir))) { target = blip; VectorCopy(blipdir, targetdir); } } if (target != NULL) { // target acquired, nudge our direction toward it VectorNormalize(targetdir); VectorScale(targetdir, 0.2, targetdir); VectorAdd(targetdir, ent->movedir, targetdir); VectorNormalize(targetdir); VectorCopy(targetdir, ent->movedir); vectoangles(targetdir, ent->s.angles); speed = VectorLength(ent->velocity); VectorScale(targetdir, speed, ent->velocity); } ent->nextthink = level.time + FRAMETIME; } void fire_homingrocket (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage) { edict_t *rocket; self->client->resp.weapon_shots[5]++; self->client->homing_shots++; rocket = G_Spawn(); VectorCopy (start, rocket->s.origin); VectorCopy (dir, rocket->movedir); vectoangles (dir, rocket->s.angles); VectorScale (dir, speed, rocket->velocity); rocket->movetype = MOVETYPE_FLYMISSILE; rocket->clipmask = MASK_SHOT; rocket->solid = SOLID_BBOX; rocket->s.effects |= EF_ROCKET | EF_ROCKETEXHAUST ; VectorClear (rocket->mins); VectorClear (rocket->maxs); rocket->s.modelindex = gi.modelindex ("models/objects/rocket/tris.md2"); rocket->owner = self; rocket->touch = rocket_touch; // CCH: if they have 5 cells, start homing, otherwise normal rocket think if (self->client->pers.inventory[ITEM_INDEX(FindItem("Cells"))] >= 5) { self->client->pers.inventory[ITEM_INDEX(FindItem("Cells"))] -= 5; rocket->nextthink = level.time + .1; rocket->think = homing_think; } else { safe_cprintf(self, PRINT_HIGH, "No cells for homing missile.\n"); rocket->nextthink = level.time + 8000/speed; rocket->think = G_FreeEdict; } rocket->dmg = damage; rocket->radius_dmg = radius_damage; rocket->dmg_radius = damage_radius; rocket->s.sound = gi.soundindex ("weapons/rockfly.wav"); rocket->classname = "rocket"; gi.linkentity (rocket); } /* ================= fire_minderaser ================= */ void minderaser_think (edict_t *ent) { edict_t *target = NULL; edict_t *blip = NULL; vec3_t targetdir, blipdir; vec_t speed; while ((blip = findradius(blip, ent->s.origin, 1000)) != NULL) { if (!(blip->svflags & SVF_MONSTER) && !blip->client) continue; if (blip == ent->owner) continue; if (!blip->takedamage) continue; if (blip->health <= 0) continue; if (!visible(ent, blip)) continue; VectorSubtract(blip->s.origin, ent->s.origin, blipdir); blipdir[2] += 16; if ((target == NULL) || (VectorLength(blipdir) < VectorLength(targetdir))) { target = blip; VectorCopy(blipdir, targetdir); } } if (target != NULL) { trace_t tr; tr = gi.trace (ent->s.origin, NULL, NULL, target->s.origin, ent, MASK_SOLID); // only move to it if path is not blocked if (tr.fraction == 1.0) { // target acquired, nudge our direction toward it VectorNormalize(targetdir); VectorScale(targetdir, 0.2, targetdir); VectorAdd(targetdir, ent->movedir, targetdir); VectorNormalize(targetdir); VectorCopy(targetdir, ent->movedir); vectoangles(targetdir, ent->s.angles); speed = 450; //speed it up we have a target VectorScale(targetdir, speed, ent->velocity); ent->s.frame = (ent->s.frame + 1) % 24; ent->s.effects = EF_SHIPEXHAUST; ent->s.sound = gi.soundindex ("weapons/seeker_fast.wav"); ent->s.renderfx = 0; } //zap it if close enough and clear if(VectorLength(blipdir) < 128) { //we are close, slow it down speed = 30; VectorScale(targetdir, speed, ent->velocity); ent->s.effects = EF_COLOR_SHELL; ent->s.renderfx = RF_SHELL_BLUE; // hurt it if we can if ((target->takedamage) && (target != ent->owner)) { T_Damage (target, ent, ent->owner, targetdir, target->s.origin, vec3_origin, 35, 1, DAMAGE_ENERGY, MOD_MINDERASER); gi.sound (ent->owner, CHAN_VOICE, gi.soundindex("misc/hit.wav"), 1, ATTN_STATIC, 0); } ent->s.sound = gi.soundindex ("weapons/seeker_zap.wav"); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_LIGHTNING); gi.WritePosition (ent->s.origin); gi.WritePosition (target->s.origin); gi.multicast (ent->s.origin, MULTICAST_PHS); ent->s.frame = 27; } } else { speed = 30; VectorScale(ent->movedir, speed, ent->velocity); ent->s.effects = 0; ent->s.renderfx = 0; ent->s.sound = gi.soundindex ("weapons/seeker.wav"); ent->s.frame = (ent->s.frame + 1) % 24; } ent->nade_timer++; ent->nextthink = level.time + FRAMETIME; if(ent->nade_timer > 300) { //explode gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BFG_BIGEXPLOSION); gi.WritePosition (ent->s.origin); gi.multicast (ent->s.origin, MULTICAST_PHS); gi.sound (ent, CHAN_WEAPON, gi.soundindex("vehicles/explodebomb.wav"), 1, ATTN_NORM, 0); T_RadiusDamage(ent, ent->owner, 400, ent->enemy, 120, MOD_R_SPLASH, 2); G_FreeEdict (ent); } } void minderaser_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { if (other == ent->owner) return; if (surf && (surf->flags & SURF_SKY)) { G_FreeEdict (ent); return; } else if(surf) { //explode gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BFG_BIGEXPLOSION); gi.WritePosition (ent->s.origin); gi.multicast (ent->s.origin, MULTICAST_PHS); gi.sound (ent, CHAN_WEAPON, gi.soundindex("vehicles/explodebomb.wav"), 1, ATTN_NORM, 0); T_RadiusDamage(ent, ent->owner, 400, ent->enemy, 120, MOD_R_SPLASH, 2); G_FreeEdict (ent); return; } //just bounce off of anything else gi.sound (ent, CHAN_VOICE, gi.soundindex ("weapons/clank.wav"), 1, ATTN_NORM, 0); return; } void fire_minderaser (edict_t *self, vec3_t start, vec3_t dir, float timer) { edict_t *spud; float *v; spud = G_Spawn(); VectorCopy (start, spud->s.origin); VectorCopy (dir, spud->movedir); vectoangles (dir, spud->s.angles); VectorScale (dir, 30, spud->velocity); spud->movetype = MOVETYPE_FLYMISSILE; spud->clipmask = MASK_SHOT; spud->solid = SOLID_BBOX; spud->s.effects = 0; spud->s.renderfx = 0; v = tv(-8,-8,-8); VectorCopy (v, spud->mins); v = tv(8,8,8); VectorCopy (v, spud->maxs); spud->s.modelindex = gi.modelindex ("models/objects/spud/tris.md2"); spud->owner = self; spud->touch = minderaser_touch; spud->nade_timer = 0; spud->nextthink = level.time + FRAMETIME; spud->think = minderaser_think; spud->s.sound = gi.soundindex ("weapons/seeker.wav"); spud->classname = "seeker"; //to do - make sure bots know to run like hell away from these things gi.linkentity (spud); } /* ================= fire_smartgrenade ================= */ void smartgrenade_think (edict_t *self) { edict_t *ent; edict_t *target = NULL; edict_t *ignore; vec3_t point; vec3_t dir; vec3_t start; vec3_t end; int dmg; trace_t tr; if (deathmatch->value) { if(excessive->value) dmg = 15; else dmg = 3; } else dmg = 7; ent = NULL; while ((ent = findradius(ent, self->s.origin, 256)) != NULL) { if (ent == self) continue; if (ent == self->owner) continue; if (!ent->takedamage) continue; if (!(ent->svflags & SVF_MONSTER) && (!ent->client) && (strcmp(ent->classname, "misc_explobox") != 0)) continue; VectorMA (ent->absmin, 0.5, ent->size, point); VectorSubtract (point, self->s.origin, dir); VectorNormalize (dir); ignore = self; VectorCopy (self->s.origin, start); VectorMA (start, 2048, dir, end); tr = gi.trace (start, NULL, NULL, end, ignore, CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_DEADMONSTER); // hurt it if we can if ((tr.ent->takedamage) && !(tr.ent->flags & FL_IMMUNE_LASER) && (tr.ent != self->owner)) { T_Damage (tr.ent, self, self->owner, dir, tr.endpos, vec3_origin, dmg, 1, DAMAGE_ENERGY, MOD_SMARTGUN); self->owner->client->resp.weapon_shots[2]++; self->owner->client->resp.weapon_hits[2]++; gi.sound (self->owner, CHAN_VOICE, gi.soundindex("misc/hit.wav"), 1, ATTN_STATIC, 0); } // if we hit something that's not a monster or player we're done if (!(tr.ent->svflags & SVF_MONSTER) && (!tr.ent->client)) { gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_LASER_SPARKS); gi.WriteByte (4); gi.WritePosition (tr.endpos); gi.WriteDir (tr.plane.normal); gi.WriteByte (self->s.skinnum); gi.multicast (tr.endpos, MULTICAST_PVS); } VectorCopy (tr.endpos, start); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_LIGHTNING); gi.WritePosition (self->s.origin); gi.WritePosition (tr.endpos); gi.multicast (self->s.origin, MULTICAST_PHS); target = ent; } self->s.frame = (self->s.frame + 1) % 23; //pulse grotesquely self->nextthink = level.time + FRAMETIME; self->nade_timer++; if(self->nade_timer > 10) { //explode T_RadiusDamage(self, self->owner, self->radius_dmg, self->enemy, self->dmg_radius, MOD_R_SPLASH, 2); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BFG_BIGEXPLOSION); gi.WritePosition (self->s.origin); gi.multicast (self->s.origin, MULTICAST_PHS); G_FreeEdict (self); } } void prox_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point); void prox_think (edict_t *self) { edict_t *ent; ent = NULL; while ((ent = findradius(ent, self->s.origin, 64)) != NULL) { if (ent == self) continue; if (ent == self->owner) continue; if (!ent->takedamage) continue; if (ent->die == prox_die) continue; //avoid infinite recursion self->takedamage = DAMAGE_NO; T_RadiusDamage(self, self->owner, self->radius_dmg, NULL, self->dmg_radius, MOD_R_SPLASH, -1); self->owner->client->resp.weapon_hits[2]++; gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BFG_BIGEXPLOSION); gi.WritePosition (self->s.origin); gi.multicast (self->s.origin, MULTICAST_PHS); G_FreeEdict (self); return; } self->s.frame = (self->s.frame + 1) % 23; //pulse grotesquely self->nextthink = level.time + FRAMETIME; self->nade_timer++; if(self->nade_timer > 300) { //explode //avoid infinite recursion self->takedamage = DAMAGE_NO; T_RadiusDamage(self, self->owner, self->radius_dmg, NULL, self->dmg_radius, MOD_R_SPLASH, 2); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BFG_BIGEXPLOSION); gi.WritePosition (self->s.origin); gi.multicast (self->s.origin, MULTICAST_PHS); G_FreeEdict (self); } } void smartgrenade_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { if (other == ent->owner) return; if (surf && (surf->flags & SURF_SKY)) { G_FreeEdict (ent); return; } //just bounce off of everything gi.sound (ent, CHAN_VOICE, gi.soundindex ("weapons/clank.wav"), 1, ATTN_NORM, 0); return; } void prox_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { //avoid infinite recursion self->takedamage = DAMAGE_NO; //explode T_RadiusDamage(self, self->owner, self->radius_dmg, NULL, self->dmg_radius, MOD_R_SPLASH, 2); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BFG_BIGEXPLOSION); gi.WritePosition (self->s.origin); gi.multicast (self->s.origin, MULTICAST_PHS); G_FreeEdict (self); } void fire_smartgrenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float damage_radius, int radius_damage, float timer) { edict_t *floater; vec3_t dir, forward, right, up; self->client->resp.weapon_shots[2]++; vectoangles(aimdir, dir); AngleVectors(dir, forward, right, up); floater = G_Spawn(); VectorCopy (start, floater->s.origin); VectorScale (aimdir, speed, floater->velocity); VectorMA (floater->velocity, 200 + crandom() * 10.0, up, floater->velocity); VectorMA (floater->velocity, crandom() * 10.0, right, floater->velocity); VectorSet (floater->avelocity, 300, 300, 300); floater->movetype = MOVETYPE_BOUNCE; floater->clipmask = MASK_SHOT; floater->solid = SOLID_BBOX; floater->s.effects |= EF_COLOR_SHELL; floater->s.renderfx |= RF_SHELL_BLUE | RF_GLOW; VectorClear (floater->mins); VectorClear (floater->maxs); floater->s.modelindex = gi.modelindex ("models/objects/electroball/tris.md2"); floater->owner = self; floater->touch = smartgrenade_touch; floater->nextthink = level.time + .1; floater->think = smartgrenade_think; floater->dmg = damage; floater->radius_dmg = radius_damage; floater->dmg_radius = damage_radius; floater->s.sound = gi.soundindex ("weapons/electroball.wav"); floater->classname = "grenade"; floater->nade_timer = 0; gi.linkentity (floater); } void fire_prox (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float damage_radius, int radius_damage, float timer) { edict_t *prox; vec3_t dir, forward, right, up; self->client->resp.weapon_shots[2]++; vectoangles(aimdir, dir); AngleVectors(dir, forward, right, up); prox = G_Spawn(); VectorCopy (start, prox->s.origin); VectorScale (aimdir, speed, prox->velocity); VectorMA (prox->velocity, 20 + crandom() * 10.0, up, prox->velocity); VectorMA (prox->velocity, crandom() * 10.0, right, prox->velocity); VectorSet (prox->avelocity, 20, 20, 20); prox->movetype = MOVETYPE_BOUNCE; prox->clipmask = MASK_SHOT; prox->solid = SOLID_BBOX; VectorClear (prox->mins); VectorClear (prox->maxs); prox->s.modelindex = gi.modelindex ("models/objects/electroball/tris.md2"); prox->owner = self; prox->touch = smartgrenade_touch; prox->nextthink = level.time + .1; prox->think = prox_think; prox->dmg = damage; prox->radius_dmg = radius_damage; prox->dmg_radius = damage_radius; prox->classname = "mine"; prox->takedamage = DAMAGE_YES; prox->health = 20; prox->die = prox_die; prox->nade_timer = 0; gi.linkentity (prox); } //vehicles void bomb_think (edict_t *self) { self->nextthink = level.time + FRAMETIME; } void bomb_blow (edict_t *self) { self->nextthink = level.time + .02; self->s.frame++; G_FreeEdict (self); } void bomb_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { vec3_t origin; int i; edict_t *e; if (other == ent->owner) return; if (surf && (surf->flags & SURF_SKY)) { G_FreeEdict (ent); return; } if (ent->owner->client) PlayerNoise(ent->owner, ent->s.origin, PNOISE_IMPACT); // calculate position for the explosion entity VectorMA (ent->s.origin, -0.02, ent->velocity, origin); if (other->takedamage) { T_Damage (other, ent, ent->owner, ent->velocity, ent->s.origin, plane->normal, ent->dmg, 0, 0, MOD_ROCKET); ent->owner->client->resp.weapon_hits[7]++; gi.sound (ent->owner, CHAN_VOICE, gi.soundindex("misc/hit.wav"), 1, ATTN_STATIC, 0); } T_RadiusDamage(ent, ent->owner, ent->radius_dmg, other, ent->dmg_radius, MOD_R_SPLASH, 7); //advance to expoding frame ent->s.frame++; gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BFG_BIGEXPLOSION); gi.WritePosition (origin); gi.multicast (ent->s.origin, MULTICAST_PHS); gi.sound (ent, CHAN_WEAPON, gi.soundindex("vehicles/explodebomb.wav"), 1, ATTN_NORM, 0); //shake the ground a bit(it's a big ass bomb, right?) for (i=1, e=g_edicts+i; i < globals.num_edicts; i++,e++) { if (!e->inuse) continue; if (!e->client) continue; if (!e->groundentity) continue; e->groundentity = NULL; e->velocity[0] += crandom()* 50; e->velocity[1] += crandom()* 50; e->velocity[2] += 175 + crandom()* 50; } ent->think = bomb_blow; ent->nextthink = level.time + .1; //G_FreeEdict (ent); } void fire_bomb (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float damage_radius, int radius_damage, float timer) { edict_t *bomb; vec3_t dir, forward, right, up; vectoangles(aimdir, dir); AngleVectors(dir, forward, right, up); bomb = G_Spawn(); VectorCopy (start, bomb->s.origin); VectorScale (aimdir, speed, bomb->velocity); VectorMA (bomb->velocity, 200 + crandom() * 10.0, up, bomb->velocity); VectorMA (bomb->velocity, crandom() * 10.0, right, bomb->velocity); VectorSet (bomb->avelocity, 100, 100, 100); bomb->movetype = MOVETYPE_BOUNCE; bomb->clipmask = MASK_SHOT; bomb->solid = SOLID_BBOX; bomb->s.effects |= EF_ROTATE; bomb->s.renderfx |= RF_GLOW; VectorClear (bomb->mins); VectorClear (bomb->maxs); bomb->s.modelindex = gi.modelindex ("vehicles/bomber/bomb.md2"); bomb->owner = self; bomb->touch = bomb_touch; bomb->nextthink = level.time + .1; bomb->think = bomb_think; bomb->dmg = damage; bomb->radius_dmg = radius_damage; bomb->dmg_radius = damage_radius; bomb->s.sound = gi.soundindex ("vehicles/flybomb.wav"); //get a new sound bomb->classname = "grenade"; gi.linkentity (bomb); } /* ======================= Flamethrower ======================= */ void Fire_Think (edict_t *self) { vec3_t dir; int damage; float points; vec3_t v; if (level.time > self->delay || self->owner->deadflag == DEAD_DEAD) { self->owner->Flames--; G_FreeEdict (self); return; } if (!self->owner) { G_FreeEdict (self); return; } if (self->owner->waterlevel) { self->owner->Flames--; G_FreeEdict (self); return; } damage = self->FlameDamage; VectorAdd (self->orb->mins, self->orb->maxs, v); VectorMA (self->orb->s.origin, 0.5, v, v); VectorSubtract (self->s.origin, v, v); points = damage - 0.5 * (VectorLength (v)); VectorSubtract (self->owner->s.origin, self->s.origin, dir); if (self->FlameDelay < level.time) { T_Damage (self->owner, self, self->orb, dir, self->owner->s.origin,vec3_origin, damage, 0, DAMAGE_NO_KNOCKBACK,MOD_FLAME); self->FlameDelay = level.time + 0.8; } VectorCopy(self->owner->s.origin,self->s.origin); self->nextthink = level.time + .2; } void burn_person(edict_t *target, edict_t *owner, int damage) { edict_t *flame; if (target->Flames > 1)//This number sets the allowed amount of flames per person return; target->Flames++; flame = G_Spawn(); flame->movetype = MOVETYPE_NOCLIP; flame->clipmask = MASK_SHOT; flame->solid = SOLID_NOT; flame->s.effects |= EF_SHIPEXHAUST; flame->s.renderfx = RF_TRANSLUCENT; flame->velocity[0] = target->velocity[0]; flame->velocity[1] = target->velocity[1]; flame->velocity[2] = target->velocity[2]; VectorClear (flame->mins); VectorClear (flame->maxs); flame->s.modelindex = gi.modelindex ("models/objects/fireball/tris.md2"); flame->owner = target; flame->orb = owner; flame->delay = level.time + 5;//8;//Jr Shorten it so it goes away faster flame->nextthink = level.time + .8; flame->FlameDelay = level.time + 0.8; flame->think = Fire_Think; flame->FlameDamage = damage+2; flame->classname = "fire"; flame->s.sound = gi.soundindex ("weapons/grenlf1a.wav"); gi.linkentity (flame); VectorCopy(target->s.origin,flame->s.origin); } void flame_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { if (other == self->owner) return; // clean up laser entities if (surf && (surf->flags & SURF_SKY)) { G_FreeEdict (self); return; } if (self->owner->client) PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT); T_Damage (other, self, self->owner, self->velocity, self->s.origin, plane->normal, 6, 0, 0,MOD_FLAME); // core explosion - prevents firing it into the wall/floor if (other->health) { burn_person(other, self->owner, self->FlameDamage); self->owner->client->resp.weapon_hits[4]++; } G_FreeEdict (self); } void fire_flamethrower(edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius) { edict_t *flame; self->client->resp.weapon_shots[4]++; flame = G_Spawn(); VectorCopy (start, flame->s.origin); VectorCopy (dir, flame->movedir); vectoangles (dir, flame->s.angles); VectorScale (dir, speed, flame->velocity); flame->movetype = MOVETYPE_FLYMISSILE; flame->clipmask = MASK_SHOT; flame->solid = SOLID_BBOX; flame->s.effects |= EF_SHIPEXHAUST; flame->s.renderfx = RF_TRANSLUCENT; VectorClear (flame->mins); VectorClear (flame->maxs); flame->s.modelindex = gi.modelindex ("models/objects/fireball/tris.md2"); // All we care about is the effects. However, old clients will refuse to // draw them unless the modelindex is set. To work around this, newer // clients have an RF_NODRAW flag. flame->s.renderfx |= RF_NODRAW; flame->owner = self; flame->touch = flame_touch; flame->nextthink = level.time + 500/speed; flame->think = G_FreeEdict; flame->radius_dmg = damage; flame->FlameDamage = damage; flame->dmg_radius = damage_radius; flame->classname = "flame"; flame->s.sound = gi.soundindex ("weapons/grenlf1a.wav"); gi.linkentity (flame); } void fireball_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { vec3_t origin; if (other == ent->owner) return; if (surf && (surf->flags & SURF_SKY)) { G_FreeEdict (ent); return; } if (ent->owner->client) PlayerNoise(ent->owner, ent->s.origin, PNOISE_IMPACT); // calculate position for the explosion entity VectorMA (ent->s.origin, -0.02, ent->velocity, origin); if (other->takedamage) { T_Damage (other, ent, ent->owner, ent->velocity, ent->s.origin, plane->normal, ent->dmg, 0, 0, MOD_ROCKET); ent->owner->client->resp.weapon_hits[4]++; gi.sound (ent->owner, CHAN_VOICE, gi.soundindex("misc/hit.wav"), 1, ATTN_STATIC, 0); } T_RadiusDamage(ent, ent->owner, ent->radius_dmg, other, ent->dmg_radius, MOD_R_SPLASH, 4); gi.WriteByte (svc_temp_entity); if (ent->waterlevel) gi.WriteByte (TE_ROCKET_EXPLOSION_WATER); else gi.WriteByte (TE_ROCKET_EXPLOSION); gi.WritePosition (origin); gi.multicast (ent->s.origin, MULTICAST_PHS); if (other->health) { burn_person(other, ent->owner, ent->FlameDamage); } G_FreeEdict (ent); } void fire_fireball (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float damage_radius, int radius_damage) { edict_t *fireball; vec3_t dir, forward, right, up; self->client->resp.weapon_shots[4]++; vectoangles(aimdir, dir); AngleVectors(dir, forward, right, up); fireball = G_Spawn(); VectorCopy (start, fireball->s.origin); VectorScale (aimdir, speed, fireball->velocity); VectorMA (fireball->velocity, 200 + crandom() * 10.0, up, fireball->velocity); VectorMA (fireball->velocity, crandom() * 10.0, right, fireball->velocity); VectorSet (fireball->avelocity, 300, 300, 300); fireball->movetype = MOVETYPE_BOUNCE; fireball->clipmask = MASK_SHOT; fireball->solid = SOLID_BBOX; fireball->s.effects |= EF_SHIPEXHAUST; fireball->s.renderfx = RF_TRANSLUCENT; VectorClear (fireball->mins); VectorClear (fireball->maxs); fireball->s.modelindex = gi.modelindex ("models/objects/fireball/tris.md2"); fireball->owner = self; fireball->touch = fireball_touch; fireball->nextthink = level.time + 1500/speed; fireball->think = G_FreeEdict; fireball->dmg = damage; fireball->radius_dmg = radius_damage; fireball->dmg_radius = damage_radius; fireball->FlameDamage = damage; fireball->s.sound = gi.soundindex ("weapons/grenlf1a.wav"); fireball->classname = "flame"; gi.linkentity (fireball); } //deathball static void DeathballTouch(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { //owner (who dropped us) can't touch for two secs // if (other == ent->owner && // ent->nextthink - level.time > 2) // return; Touch_Item (ent, other, plane, surf); } static void DeathballThink(edict_t *ent) { // auto return the ball ResetDeathball(); safe_bprintf(PRINT_HIGH, "The ball has returned!\n"); } void fire_deathball (edict_t *self, vec3_t start, vec3_t aimdir, int speed) { edict_t *ball; vec3_t dir, forward, right, up; gitem_t *deathball_item; float *v; deathball_item = FindItemByClassname("item_deathball"); vectoangles(aimdir, dir); AngleVectors(dir, forward, right, up); ball = Drop_Item(self, deathball_item); VectorCopy (start, ball->s.origin); VectorScale (aimdir, speed, ball->velocity); VectorMA (ball->velocity, 200 + crandom() * 10.0, up, ball->velocity); VectorMA (ball->velocity, crandom() * 10.0, right, ball->velocity); VectorSet (ball->avelocity, 100, 100, 100); ball->movetype = MOVETYPE_BOUNCE; ball->clipmask = MASK_SHOT; ball->solid = SOLID_BBOX; v = tv(-24,-24,-24); VectorCopy (v, ball->mins); v = tv(24,24,24); VectorCopy (v, ball->maxs); ball->s.modelindex = gi.modelindex ("vehicles/deathball/deathball.md2"); ball->owner = self; //important for scoring ball->classname = "item_deathball"; ball->think = DeathballThink; ball->nextthink = level.time + 30; ball->touch = DeathballTouch; ball->s.frame = 229; gi.linkentity (ball); //remove deathball from players inventory //set everything back self->in_deathball = false; if ( instagib->integer || insta_rockets->integer ) { self->client->newweapon = FindItem( "Alien Disruptor" ); } else if ( rocket_arena->integer ) { self->client->newweapon = FindItem( "Rocket Launcher" ); } else { self->client->newweapon = FindItem( "blaster" ); } assert( self->client->newweapon != NULL ); self->client->pers.inventory[ITEM_INDEX(deathball_item)] = 0; self->s.modelindex4 = 0; } void fire_violator(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int alt) { vec3_t from; vec3_t end; trace_t tr; edict_t *ignore; if ( g_antilag->integer) G_DoTimeShiftFor( self ); if(alt) VectorMA (start, 6.4, aimdir, end); else VectorMA (start, 6.4, aimdir, end); VectorCopy (start, from); ignore = self; tr = gi.trace (from, NULL, NULL, end, ignore, MASK_PLAYERSOLID); if ((tr.ent != self) && (tr.ent->takedamage)) { T_Damage (tr.ent, self, self, aimdir, tr.endpos, tr.plane.normal, damage, kick, 0, MOD_VIOLATOR); self->client->resp.weapon_hits[8]++; gi.sound (self, CHAN_VOICE, gi.soundindex("misc/hit.wav"), 1, ATTN_STATIC, 0); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_LASER_SPARKS); gi.WriteByte (4); gi.WritePosition (tr.endpos); gi.WriteDir (tr.plane.normal); // skinnum is sometimes larger, why?, but does it matter? gi.WriteByte( ((self->s.skinnum > 255) ? 0 : self->s.skinnum) ); gi.multicast (tr.endpos, MULTICAST_PVS); } VectorCopy (tr.endpos, from); if ( g_antilag->integer) G_UndoTimeShiftFor( self ); } //Tactical - bombs void tactical_bomb_think (edict_t *self) { self->nextthink = level.time + FRAMETIME; if(self->armed) { self->s.frame++; if(self->s.frame > 10) self->s.frame = 10; self->nade_timer++; //this should only start after armed } else //in cases of being disarmed { self->s.frame--; if(self->s.frame < 0) self->s.frame = 0; self->nade_timer = 0; } if(self->nade_timer > 100) //10 seconds { //explode //avoid infinite recursion self->takedamage = DAMAGE_NO; T_RadiusDamage(self, self->owner, self->radius_dmg, NULL, self->dmg_radius, MOD_R_SPLASH, 0); //just send this bad boy to whole level, make it sound BIG gi.sound( &g_edicts[1], CHAN_AUTO, gi.soundindex( "world/explosion1.wav" ), 1, ATTN_NONE, 0 ); gi.WriteByte (svc_temp_entity); if(self->classname == "abomb") gi.WriteByte (TE_BFG_BIGEXPLOSION); else gi.WriteByte (TE_ROCKET_EXPLOSION); //might want different, massive effect here gi.WritePosition (self->s.origin); gi.multicast (self->s.origin, MULTICAST_PHS); G_FreeEdict (self); } } void abomb_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { if (other == ent->owner) return; //detonator will set arming if (surf && (surf->flags & SURF_SKY)) { G_FreeEdict (ent); return; } //do we just want players with detonators to just touch them? Touch for now...maybe actually fire one off in future? if(other->has_detonator && other->ctype == 0) { ent->armed = true; other->has_detonator = false; //only get one safe_bprintf(PRINT_HIGH, "Alien bomb is armed!\n"); gi.sound( &g_edicts[1], CHAN_AUTO, gi.soundindex( "weapons/adetonatorup.wav" ), 1, ATTN_NONE, 0 ); } else if((other->has_minderaser || other->has_vaporizor) && ent->armed) { ent->armed = false; safe_bprintf(PRINT_HIGH, "Alien bomb is disarmed!\n"); gi.sound( &g_edicts[1], CHAN_AUTO, gi.soundindex( "weapons/adetonatordown.wav" ), 1, ATTN_NONE, 0 ); } return; } void hbomb_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { if (other == ent->owner) return; //detonator will set arming if (surf && (surf->flags & SURF_SKY)) { G_FreeEdict (ent); return; } //do we just want players with detonators to just touch them? Touch for now...maybe actually fire one off in future? if(other->has_detonator && other->ctype == 1) { ent->armed = true; other->has_detonator = false; //only get one safe_bprintf(PRINT_HIGH, "Bomb is armed!\n"); gi.sound( &g_edicts[1], CHAN_AUTO, gi.soundindex( "weapons/hdetonatorup.wav" ), 1, ATTN_NONE, 0 ); } else if((other->has_minderaser || other->has_vaporizor) && ent->armed) { ent->armed = false; safe_bprintf(PRINT_HIGH, "Bomb is disarmed!\n"); gi.sound( &g_edicts[1], CHAN_AUTO, gi.soundindex( "weapons/hdetonatordown.wav" ), 1, ATTN_NONE, 0 ); } return; } void bomb_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { float div; //blowing up an armed bomb is still pretty bad, but it would be smarter to get it prior to being armed. if(self->armed) div = 2; else div = 10; //avoid infinite recursion self->takedamage = DAMAGE_NO; //explode - much smaller explosion. T_RadiusDamage(self, self->owner, self->radius_dmg/div, NULL, self->dmg_radius/div, MOD_R_SPLASH, 0); gi.WriteByte (svc_temp_entity); if(self->classname == "abomb") gi.WriteByte (TE_BFG_BIGEXPLOSION); else gi.WriteByte (TE_ROCKET_EXPLOSION); gi.WritePosition (self->s.origin); gi.multicast (self->s.origin, MULTICAST_PHS); G_FreeEdict (self); } void fire_tacticalbomb (edict_t *self, vec3_t start, vec3_t aimdir, int speed) { edict_t *bomb; vec3_t dir, forward, right, up; float *v; vectoangles(aimdir, dir); AngleVectors(dir, forward, right, up); bomb = G_Spawn(); VectorCopy (start, bomb->s.origin); VectorScale (aimdir, speed, bomb->velocity); VectorMA (bomb->velocity, 20 + crandom() * 10.0, up, bomb->velocity); VectorMA (bomb->velocity, crandom() * 10.0, right, bomb->velocity); VectorSet (bomb->avelocity, 20, 20, 20); bomb->movetype = MOVETYPE_BOUNCE; bomb->clipmask = MASK_SHOT; bomb->solid = SOLID_BBOX; v = tv(-8,-8,0); VectorCopy (v, bomb->mins); v = tv(8,8,16); VectorCopy (v, bomb->maxs); if(self->ctype) { bomb->s.modelindex = gi.modelindex ("models/tactical/human_bomb.iqm"); bomb->touch = hbomb_touch; bomb->classname = "hbomb"; } else { bomb->s.modelindex = gi.modelindex ("models/tactical/alien_bomb.iqm"); bomb->touch = abomb_touch; bomb->classname = "abomb"; } bomb->owner = self; bomb->think = tactical_bomb_think; bomb->nextthink = level.time + .1; bomb->dmg = 1000; //insane amount of damage power bomb->radius_dmg = 1000; bomb->dmg_radius = 512; bomb->takedamage = DAMAGE_YES; bomb->health = 500; //make it somewhat hard to destroy bomb->die = bomb_die; bomb->armed = false; bomb->nade_timer = 0; gi.linkentity (bomb); } #endif alien-arena-7.66+dfsg/source/game/q_shared.h0000600000175000017500000007646312161402010017772 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // q_shared.h -- included first by ALL program modules #if !defined Q_SHARED_H_ #define Q_SHARED_H_ #include #include #include #include #include #include #include #include #include typedef unsigned char byte; // TODO: check for implementation defined boolean // typedef enum {false, true} qboolean; #ifndef true # define false 0 # define true 1 #endif typedef int qboolean; #ifndef NULL #define NULL ((void *)0) #endif // angle indexes #define PITCH 0 // up / down #define YAW 1 // left / right #define ROLL 2 // fall over #define MAX_STRING_CHARS 1024 // max length of a string passed to Cmd_TokenizeString #define MAX_STRING_TOKENS 80 // max tokens resulting from Cmd_TokenizeString #define MAX_TOKEN_CHARS 1024 // max length of an individual token // MAX_QPATH must be 64 for Alien Arena client/server protocol. #define MAX_QPATH 64 // max length of a quake game pathname #if defined UNIX_VARIANT #define MAX_OSPATH 256 // max length of a filesystem pathname #else #define MAX_OSPATH 128 // max length of a filesystem pathname #endif #define PLAYERNAME_GLYPHS 15 // maximum visible characters in a player name #define PLAYERNAME_SIZE 32 // maximum bytes in player name string including color escapes // // per-level limits // #define MAX_CLIENTS 256 // absolute limit #define MAX_EDICTS 1024 // must change protocol to increase more #define MAX_LIGHTSTYLES 256 #define MAX_MODELS 256 // these are sent over the net as bytes #define MAX_SOUNDS 256 // so they cannot be blindly increased #define MAX_IMAGES 256 #define MAX_ITEMS 256 #define MAX_GENERAL (MAX_CLIENTS*2) // general config strings // game print flags #define PRINT_LOW 0 // pickup messages #define PRINT_MEDIUM 1 // death messages #define PRINT_HIGH 2 // critical messages #define PRINT_CHAT 3 // chat messages #define ERR_FATAL 0 // exit the entire game with a popup window #define ERR_DROP 1 // print to console and disconnect from game #define ERR_DISCONNECT 2 // don't kill server #define PRINT_ALL 0 #define PRINT_DEVELOPER 1 // only print when "developer 1" #define PRINT_ALERT 2 // destination class for gi.multicast() typedef enum { MULTICAST_ALL, MULTICAST_PHS, MULTICAST_PVS, MULTICAST_ALL_R, MULTICAST_PHS_R, MULTICAST_PVS_R } multicast_t; /* ============================================================== MATHLIB ============================================================== */ typedef float vec_t; typedef vec_t vec2_t[2]; typedef vec_t vec3_t[3]; typedef vec_t vec4_t[4]; typedef vec_t vec5_t[5]; typedef int fixed4_t; typedef int fixed8_t; typedef int fixed16_t; typedef struct matrix3x3_s { vec3_t a; vec3_t b; vec3_t c; } matrix3x3_t; typedef struct matrix3x4_s { vec4_t a; vec4_t b; vec4_t c; } matrix3x4_t; typedef struct matrix4x4_s { vec4_t a; vec4_t b; vec4_t c; vec4_t d; } matrix4x4_t; #ifndef M_PI #define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h #endif struct cplane_s; extern vec3_t vec3_origin; #define nanmask (255<<23) #define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask) #define Q_ftol( f ) ( long ) (f) #define DotProduct(x,y) (x[0]*y[0]+x[1]*y[1]+x[2]*y[2]) #define VectorSubtract(a,b,c) (c[0]=a[0]-b[0],c[1]=a[1]-b[1],c[2]=a[2]-b[2]) #define VectorAdd(a,b,c) (c[0]=a[0]+b[0],c[1]=a[1]+b[1],c[2]=a[2]+b[2]) #define VectorCopy(a,b) (b[0]=a[0],b[1]=a[1],b[2]=a[2]) #define VectorClear(a) (a[0]=a[1]=a[2]=0) #define VectorNegate(a,b) (b[0]=-a[0],b[1]=-a[1],b[2]=-a[2]) #define VectorSet(v, x, y, z) (v[0]=(x), v[1]=(y), v[2]=(z)) #define SnapVector(v) {v[0]=((int)(v[0]));v[1]=((int)(v[1]));v[2]=((int)(v[2]));} void VectorMA (vec3_t veca, float scale, vec3_t vecb, vec3_t vecc); #define Vector4Set(v, a, b, c, d) ((v)[0]=(a),(v)[1]=(b),(v)[2]=(c),(v)[3] = (d)) #define Vector4Copy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3]) #define Vector4Scale(in,scale,out) ((out)[0]=(in)[0]*scale,(out)[1]=(in)[1]*scale,(out)[2]=(in)[2]*scale,(out)[3]=(in)[3]*scale) #define Vector4Add(a,b,c) ((c)[0]=(((a[0])+(b[0]))),(c)[1]=(((a[1])+(b[1]))),(c)[2]=(((a[2])+(b[2]))),(c)[3]=(((a[3])+(b[3])))) #define Vector4Sub(a,b,c) ((c)[0]=(((a[0])-(b[0]))),(c)[1]=(((a[1])-(b[1]))),(c)[2]=(((a[2])-(b[2]))),(c)[3]=(((a[3])-(b[3])))) #define Vector4Avg(a,b,c) ((c)[0]=(((a[0])+(b[0]))*0.5f),(c)[1]=(((a[1])+(b[1]))*0.5f),(c)[2]=(((a[2])+(b[2]))*0.5f),(c)[3]=(((a[3])+(b[3]))*0.5f)) #define Vector4Clear(a) ((a)[0]=(a)[1]=(a)[2]=(a)[3]=0) #define DEG2RAD( a ) (( (a) * M_PI ) / 180.0F) #define RAD2DEG( a ) (( (a) * 180.0F ) / M_PI) // just in case you do't want to use the macros vec_t _DotProduct (vec3_t v1, vec3_t v2); void _VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out); void _VectorAdd (vec3_t veca, vec3_t vecb, vec3_t out); void _VectorCopy (vec3_t in, vec3_t out); void ClearBounds (vec3_t mins, vec3_t maxs); void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs); int VectorCompare (vec3_t v1, vec3_t v2); vec_t VectorLength (vec3_t v); void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross); vec_t VectorNormalize (vec3_t v); // returns vector length vec_t VectorNormalize2 (vec3_t v, vec3_t out); void VectorInverse (vec3_t v); void VectorScale (vec3_t in, vec_t scale, vec3_t out); int Q_log2(int val); void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]); void R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4]); void NormalToLatLong( const vec3_t normal, byte latlong[2] ); void LatLongToNormal( byte latlong[2], vec3_t normal ); void fast_sincosf( float angle, float *sina, float *cosa ); void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up); void vectoangles (vec3_t value1, vec3_t angles); int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct cplane_s *plane); float anglemod(float a); float LerpAngle (float a1, float a2, float frac); #define BOX_ON_PLANE_SIDE(emins, emaxs, p) \ (((p)->type < 3)? \ ( \ ((p)->dist <= (emins)[(p)->type])? \ 1 \ : \ ( \ ((p)->dist >= (emaxs)[(p)->type])?\ 2 \ : \ 3 \ ) \ ) \ : \ BoxOnPlaneSide( (emins), (emaxs), (p))) void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal ); void PerpendicularVector( vec3_t dst, const vec3_t src ); void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees ); //============================================= /* FIXME: Beware - _vsnprintf does not end with \0 - vsnprintf (*nix) does */ #if defined WIN32_VARIANT #define vsnprintf _vsnprintf #endif char *COM_SkipPath (char *pathname); void COM_StripExtension (char *in, char *out); void COM_FileBase (char *in, char *out); void COM_FilePath (char *in, char *out); void COM_DefaultExtension (char *path, char *extension); char *COM_Parse (char **data_p); // data is an in/out parm, returns a parsed out token char *Com_ParseExt (char **data_p, qboolean allowNewLines); char *Com_SkipWhiteSpace (char *data_p, qboolean *hasNewLines); void Com_SkipRestOfLine (char **data_p); int com_parseLine; void Com_sprintf (char *dest, int size, char *fmt, ...); void Com_PageInMemory (byte *buffer, int size); //============================================= // portable case insensitive compare int Q_strcasecmp (const char *s1, const char *s2); int Q_strncasecmp (const char *s1, const char *s2, int n); void Q_strcat (char *dst, const char *src, int dstSize); int Q_strnicmp (const char *string1, const char *string2, int n); char *Q_strlwr(char *s); // void Q_strncpyz2 (char *dst, const char *src, int dstSize); //============================================= short BigShort(short l); short LittleShort(short l); int BigLong (int l); int LittleLong (int l); float BigFloat (float l); float LittleFloat (float l); void Swap_Init (void); char *va(char *format, ...); //============================================= // // key / value info strings // #define MAX_INFO_KEY 64 #define MAX_INFO_VALUE 64 #define MAX_INFO_STRING 512 char *Info_ValueForKey (char *s, char *key); qboolean Info_KeyExists (const char *s, const char *key); void Info_RemoveKey (char *s, char *key); void Info_SetValueForKey (char *s, char *key, char *value); qboolean Info_Validate (char *s); size_t ValidatePlayerName( char *player_name, size_t player_name_size ); /* ============================================================== SYSTEM SPECIFIC ============================================================== */ extern int curtime; // time returned by last Sys_Milliseconds int Sys_Milliseconds (void); void Sys_Mkdir (char *path); // large block stack allocation routines void *Hunk_Begin (int maxsize); void *Hunk_Alloc (int size); void Hunk_Free (void *buf); int Hunk_End (void); // directory searching #define SFF_ARCH 0x01 #define SFF_HIDDEN 0x02 #define SFF_RDONLY 0x04 #define SFF_SUBDIR 0x08 #define SFF_SYSTEM 0x10 /* ** pass in an attribute mask of things you wish to REJECT */ char *Sys_FindFirst (char *path, unsigned musthave, unsigned canthave ); char *Sys_FindNext ( unsigned musthave, unsigned canthave ); void Sys_FindClose (void); // this is only here so the functions in q_shared.c and q_shwin.c can link void Sys_Error (char *error, ...); void Com_Printf (char *msg, ...); /* ========================================================== CVARS (console variables) ========================================================== */ #ifndef CVAR #define CVAR // These are all the flags that actually do anything. // NOTE: there is no need to maintain any kind of compatibility, we can change // these if we want to. #define CVAR_ARCHIVE 1 // set to cause it to be saved to vars.rc #define CVAR_USERINFO 2 // added to userinfo when changed #define CVAR_SERVERINFO 4 // added to serverinfo when changed #define CVAR_NOSET 8 // don't allow change from console at all, // but can be set from the command line #define CVAR_LATCH 16 // save changes until server restart #define CVAR_ROM 32 // cannot be set by user at all #define CVAR_GAMEINFO 64 // added to the 'mods' field of the serverinfo // string when changed #define CVAR_PROFILE 128 // profile information // These flags are purely for documentation (used by the "help" command.) // Usually, at most one of these will be set. They are not "enforced" by the // code in any way. // TODO: go through and add all these flags for cvars as appropriate. // TODO: others like address, path, IP address, etc? #define CVARDOC_BOOL 512 #define CVARDOC_STR 1024 #define CVARDOC_FLOAT 2048 #define CVARDOC_INT 4096 // nothing outside the Cvar_*() functions should modify these fields! typedef struct cvar_s { char *name; unsigned int hash_key; char *string; char *latched_string; // for CVAR_LATCH vars int flags; qboolean modified; // set each time the cvar is changed float value; float default_value; int integer; char *description; // Optional (may be NULL) struct cvar_s *next; } cvar_t; #endif // CVAR /* ============================================================== COLLISION DETECTION ============================================================== */ // lower bits are stronger, and will eat weaker brushes completely #define CONTENTS_SOLID 1 // an eye is never valid in a solid #define CONTENTS_WINDOW 2 // translucent, but not watery #define CONTENTS_AUX 4 #define CONTENTS_LAVA 8 #define CONTENTS_SLIME 16 #define CONTENTS_WATER 32 #define CONTENTS_MIST 64 #define LAST_VISIBLE_CONTENTS 64 // remaining contents are non-visible, and don't eat brushes #define CONTENTS_AREAPORTAL 0x8000 #define CONTENTS_PLAYERCLIP 0x10000 #define CONTENTS_MONSTERCLIP 0x20000 // currents can be added to any other contents, and may be mixed #define CONTENTS_CURRENT_0 0x40000 #define CONTENTS_CURRENT_90 0x80000 #define CONTENTS_CURRENT_180 0x100000 #define CONTENTS_CURRENT_270 0x200000 #define CONTENTS_CURRENT_UP 0x400000 #define CONTENTS_CURRENT_DOWN 0x800000 #define CONTENTS_ORIGIN 0x1000000 // removed before bsping an entity #define CONTENTS_MONSTER 0x2000000 // should never be on a brush, only in game #define CONTENTS_DEADMONSTER 0x4000000 #define CONTENTS_DETAIL 0x8000000 // brushes to be added after vis leafs #define CONTENTS_TRANSLUCENT 0x10000000 // auto set if any surface has trans #define CONTENTS_LADDER 0x20000000 #define SURF_LIGHT 0x1 // value will hold the light strength #define SURF_SLICK 0x2 // effects game physics #define SURF_SKY 0x4 // don't draw, but add to skybox #define SURF_WARP 0x8 // turbulent water warp #define SURF_TRANS33 0x10 #define SURF_TRANS66 0x20 #define SURF_FLOWING 0x40 // scroll towards angle #define SURF_NODRAW 0x80 // don't bother referencing the texture #define SURF_BLOOD 0x400 // dripping blood surface #define SURF_WATER 0x800 // dripping water surface #define SURF_UNDERWATER 0x2000 // reflecting ripples; applied automatically // to underwater surfs but could be applied // manually as well // content masks #define MASK_ALL (-1) #define MASK_SOLID (CONTENTS_SOLID|CONTENTS_WINDOW) #define MASK_PLAYERSOLID (CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER) #define MASK_DEADSOLID (CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW) #define MASK_MONSTERSOLID (CONTENTS_SOLID|CONTENTS_MONSTERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER) #define MASK_WATER (CONTENTS_WATER|CONTENTS_LAVA|CONTENTS_SLIME) #define MASK_OPAQUE (CONTENTS_SOLID|CONTENTS_SLIME|CONTENTS_LAVA) #define MASK_SHOT (CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEADMONSTER) #define MASK_CURRENT (CONTENTS_CURRENT_0|CONTENTS_CURRENT_90|CONTENTS_CURRENT_180|CONTENTS_CURRENT_270|CONTENTS_CURRENT_UP|CONTENTS_CURRENT_DOWN) #define MASK_VISIBILILITY (CONTENTS_SOLID/*|CONTENTS_WINDOW*/|CONTENTS_WATER|CONTENTS_LAVA|CONTENTS_SLIME) // gi.BoxEdicts() can return a list of either solid or trigger entities // FIXME: eliminate AREA_ distinction? #define AREA_SOLID 1 #define AREA_TRIGGERS 2 // plane_t structure // !!! if this is changed, it must be changed in asm code too !!! typedef struct cplane_s { vec3_t normal; float dist; byte type; // for fast side tests byte signbits; // signx + (signy<<1) + (signz<<1) byte pad[2]; } cplane_t; // structure offset for asm code #define CPLANE_NORMAL_X 0 #define CPLANE_NORMAL_Y 4 #define CPLANE_NORMAL_Z 8 #define CPLANE_DIST 12 #define CPLANE_TYPE 16 #define CPLANE_SIGNBITS 17 #define CPLANE_PAD0 18 #define CPLANE_PAD1 19 typedef struct cmodel_s { vec3_t mins, maxs; vec3_t origin; // for sounds or lights int headnode; } cmodel_t; typedef struct csurface_s { char name[16]; int flags; int value; } csurface_t; typedef struct mapsurface_s // used internally due to name len probs //ZOID { csurface_t c; char rname[32]; } mapsurface_t; // a trace is returned when a box is swept through the world typedef struct { qboolean allsolid; // if true, plane is not valid qboolean startsolid; // if true, the initial point was in a solid area float fraction; // time completed, 1.0 = didn't hit anything vec3_t endpos; // final position cplane_t plane; // surface normal at impact csurface_t *surface; // surface hit int contents; // contents on other side of surface hit struct edict_s *ent; // not set by CM_*() functions } trace_t; // pmove_state_t is the information necessary for client side movement // prediction typedef enum { // can accelerate and turn PM_NORMAL, PM_SPECTATOR, // no acceleration or turning PM_DEAD, PM_GIB, // different bounding box PM_FREEZE } pmtype_t; // pmove->pm_flags #define PMF_DUCKED 1 #define PMF_JUMP_HELD 2 #define PMF_ON_GROUND 4 #define PMF_TIME_WATERJUMP 8 // pm_time is waterjump #define PMF_TIME_LAND 16 // pm_time is time before rejump #define PMF_TIME_TELEPORT 32 // pm_time is non-moving time #define PMF_NO_PREDICTION 64 // temporarily disables prediction (used for grappling hook) // this structure needs to be communicated bit-accurate // from the server to the client to guarantee that // prediction stays in sync, so no floats are used. // if any part of the game code modifies this struct, it // will result in a prediction error of some degree. typedef struct { pmtype_t pm_type; int origin[3]; // 12.3 short velocity[3]; // 12.3 byte pm_flags; // ducked, jump_held, etc byte pm_time; // each unit = 8 ms short gravity; short delta_angles[3]; // add to command angles to get view direction // changed by spawns, rotating objects, and teleporters } pmove_state_t; // // button bits // #define BUTTON_ATTACK 1 #define BUTTON_USE 2 #define BUTTON_ATTACK2 4 #define BUTTON_ANY 128 // any key whatsoever // usercmd_t is sent to the server each client frame typedef struct usercmd_s { byte msec; byte buttons; short angles[3]; short forwardmove, sidemove, upmove; byte impulse; // remove? byte lightlevel; // light level the player is standing on } usercmd_t; #define MAXTOUCH 32 typedef struct { // state (in / out) pmove_state_t s; // command (in) usercmd_t cmd; qboolean snapinitial; // if s has been changed outside pmove // results (out) int numtouch; struct edict_s *touchents[MAXTOUCH]; vec3_t viewangles; // clamped float viewheight; vec3_t mins, maxs; // bounding box size struct edict_s *groundentity; int watertype; int waterlevel; int joustattempts; // callbacks to test the world trace_t (*trace) (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end); int (*pointcontents) (vec3_t point); } pmove_t; // entity_state_t->effects // Effects are things handled on the client side (lights, particles, frame animations) // that happen constantly on the given entity. // An entity that has effects will be sent to the client // even if it has a zero index model. #define EF_ROTATE 0x00000001 // rotate (bonus items) #define EF_GIB 0x00000002 // leave a trail #define EF_BLASTER 0x00000008 // redlight + trail #define EF_ROCKET 0x00000010 // redlight + trail #define EF_GRENADE 0x00000020 #define EF_HYPERBLASTER 0x00000040 #define EF_BFG 0x00000080 #define EF_COLOR_SHELL 0x00000100 #define EF_POWERSCREEN 0x00000200 #define EF_ANIM01 0x00000400 // automatically cycle between frames 0 and 1 at 2 hz #define EF_ANIM23 0x00000800 // automatically cycle between frames 2 and 3 at 2 hz #define EF_ANIM_ALL 0x00001000 // automatically cycle through all frames at 2hz #define EF_ANIM_ALLFAST 0x00002000 // automatically cycle through all frames at 10hz #define EF_BUBBLES 0x00004000 #define EF_QUAD 0x00008000 #define EF_PENT 0x00010000 #define EF_TELEPORTER 0x00020000 // particle fountain #define EF_TEAM1 0x00040000 #define EF_TEAM2 0x00080000 #define EF_GREENGIB 0x00200000 #define EF_PLASMA 0x01000000 #define EF_SHIPEXHAUST 0x02000000 #define EF_ROCKETEXHAUST 0x80000000 // entity_state_t->renderfx flags #define RF_MINLIGHT 1 // allways have some light (viewmodel) #define RF_VIEWERMODEL 2 // don't draw through eyes, only mirrors #define RF_WEAPONMODEL 4 // only draw through eyes #define RF_FULLBRIGHT 8 // allways draw full intensity #define RF_DEPTHHACK 16 // for view weapon Z crunching #define RF_TRANSLUCENT 32 #define RF_FRAMELERP 64 #define RF_BEAM 128 // unused #define RF_CUSTOMSKIN 256 // skin is an index in image_precache #define RF_GLOW 512 // pulse lighting for bonus items #define RF_SHELL_RED 1024 #define RF_SHELL_GREEN 2048 #define RF_SHELL_BLUE 4096 #define RF_BOBBING 0x00008000 // 32768 #define RF_SHELL_DOUBLE 0x00010000 // 65536 #define RF_SHELL_HALF_DAM 0x00020000 #define RF_NOSHADOWS 0x00040000 //use this one for turning off shadows, etc. #define RF_MONSTER 0x00080000 #define RF_NODRAW 0x00100000 //use this instead of a 0 modelindex for compatibility. #define RF_MENUMODEL 0x01280000 //for player menu // player_state_t->refdef flags #define RDF_UNDERWATER 1 // warp the screen as apropriate #define RDF_NOWORLDMODEL 2 // used for player configuration screen #define RDF_IRGOGGLES 4 #define RDF_UVGOGGLES 8 // // muzzle flashes / player effects // #define MZ_BLASTER 0 #define MZ_MACHINEGUN 1 #define MZ_SHOTGUN 2 #define MZ_CHAINGUN1 3 #define MZ_CHAINGUN2 4 #define MZ_CHAINGUN3 5 #define MZ_RAILGUN 6 #define MZ_ROCKET 7 #define MZ_GRENADE 8 #define MZ_LOGIN 9 #define MZ_LOGOUT 10 #define MZ_RESPAWN 11 #define MZ_BFG 12 #define MZ_SSHOTGUN 13 #define MZ_HYPERBLASTER 14 #define MZ_ITEMRESPAWN 15 #define MZ_SILENCED 128 // bit flag ORed with one of the above numbers // temp entity events // // Temp entity events are for things that happen // at a location seperate from any existing entity. // Temporary entity messages are explicitly constructed // and broadcast. #define TE_GUNSHOT 0 #define TE_BLOOD 1 #define TE_BLASTER 2 #define TE_RAILTRAIL 3 #define TE_LASERBEAM 4 #define TE_EXPLOSION1 5 #define TE_EXPLOSION2 6 #define TE_ROCKET_EXPLOSION 7 #define TE_SPARKS 9 #define TE_SPLASH 10 #define TE_BUBBLETRAIL 11 #define TE_SCREEN_SPARKS 12 #define TE_DEATHFIELD2 13 #define TE_BULLET_SPARKS 14 #define TE_LASER_SPARKS 15 #define TE_DONTUSE 16 #define TE_ROCKET_EXPLOSION_WATER 17 #define TE_REDLASER 19 #define TE_BFG_BIGEXPLOSION 21 #define TE_BOSSTPORT 22 #define TE_DONTUSE2 23 #define TE_GREENBLOOD 26 #define TE_LIGHTNING 33 #define TE_VAPORBEAM 38 #define TE_STEAM 40 #define TE_SAYICON 45 #define TE_TELEPORT_EFFECT 48 #define TE_LEADERBLASTER 56 #define TE_CHAINGUNSMOKE 57 #define TE_BLUE_MUZZLEFLASH 58 #define TE_SMART_MUZZLEFLASH 59 #define TE_VOLTAGE 60 #define TE_DEATHFIELD 61 #define TE_BLASTERBEAM 62 #define TE_STAIN 63 #define TE_FIRE 64 #define TE_SMOKE 66 #define SPLASH_UNKNOWN 0 #define SPLASH_SPARKS 1 #define SPLASH_BLUE_WATER 2 #define SPLASH_BROWN_WATER 3 #define SPLASH_SLIME 4 #define SPLASH_LAVA 5 #define SPLASH_BLOOD 6 // sound channels // channel 0 never willingly overrides // other channels (1-7) allways override a playing sound on that channel #define CHAN_AUTO 0 #define CHAN_WEAPON 1 #define CHAN_VOICE 2 #define CHAN_ITEM 3 #define CHAN_BODY 4 // modifier flags #define CHAN_NO_PHS_ADD 8 // send to all clients, not just ones in PHS (ATTN 0 will also do this) #define CHAN_RELIABLE 16 // send by reliable message, not datagram // sound attenuation values #define ATTN_NONE 0 // full volume the entire level #define ATTN_NORM 1 #define ATTN_IDLE 2 #define ATTN_STATIC 3 // diminish very rapidly with distance // player_state->stats[] indexes #define STAT_HEALTH_ICON 0 #define STAT_HEALTH 1 #define STAT_AMMO_ICON 2 #define STAT_AMMO 3 #define STAT_ARMOR_ICON 4 #define STAT_ARMOR 5 #define STAT_RED_MATCHES 6 #define STAT_BLUE_MATCHES 7 #define STAT_TACTICAL_SCORE 8 #define STAT_TIMER_ICON 9 #define STAT_TIMER 10 #define STAT_HELPICON 11 #define STAT_SELECTED_ITEM 12 #define STAT_LAYOUTS 13 #define STAT_FRAGS 14 #define STAT_FLASHES 15 // cleared each frame, 1 = health, 2 = armor #define STAT_FLAGS 15 // misc boolean values, use only bits 3-16 #define STAT_CHASE 16 #define STAT_SPECTATOR 17 #define STAT_SCOREBOARD 18 #define STAT_DEATHS 19 #define STAT_HIGHSCORE 20 #define STAT_REDSCORE 21 #define STAT_BLUESCORE 22 #define STAT_FLAG_ICON 23 #define STAT_ZOOMED 24 #define STAT_WEAPN1 25 #define STAT_WEAPN2 26 #define STAT_WEAPN3 27 #define STAT_WEAPN4 28 #define STAT_WEAPN5 29 #define STAT_WEAPN6 30 #define STAT_WEAPN7 31 #define MAX_STATS 32 // bit flags for use in STAT_FLAGS #define STAT_FLAGS_CROSSHAIRPOSITION (4|8) #define STAT_FLAGS_CROSSHAIRPOS1 0 //default #define STAT_FLAGS_CROSSHAIRCENTER 4 #define STAT_FLAGS_CROSSHAIRPOS2 8 #define STAT_FLAGS_CROSSHAIRPOS3 12 // dmflags->value flags #define DF_NO_HEALTH 0x00000001 // 1 #define DF_NO_ITEMS 0x00000002 // 2 #define DF_WEAPONS_STAY 0x00000004 // 4 #define DF_NO_FALLING 0x00000008 // 8 #define DF_INSTANT_ITEMS 0x00000010 // 16 #define DF_SAME_LEVEL 0x00000020 // 32 #define DF_SKINTEAMS 0x00000040 // 64 #define DF_NO_FRIENDLY_FIRE 0x00000100 // 256 #define DF_SPAWN_FARTHEST 0x00000200 // 512 #define DF_FORCE_RESPAWN 0x00000400 // 1024 #define DF_NO_ARMOR 0x00000800 // 2048 #define DF_ALLOW_EXIT 0x00001000 // 4096 #define DF_INFINITE_AMMO 0x00002000 // 8192 #define DF_QUAD_DROP 0x00004000 // 16384 // RAFAEL #define DF_QUADFIRE_DROP 0x00010000 // 65536 //CODERED #define DF_BOT_AUTOSAVENODES 0x00020000 //131072 #define DF_BOTCHAT 0x00040000 //262144 #define DF_BOT_FUZZYAIM 0x00080000 //524288 #define DF_BOTS 0x00100000 //1048576 #define DF_BOT_LEVELAD 0x00200000 //2097152 /* ========================================================== ELEMENTS COMMUNICATED ACROSS THE NET ========================================================== */ #define ANGLE2SHORT(x) ((int)((x)*65536/360) & 65535) #define SHORT2ANGLE(x) ((x)*(360.0/65536)) // Number of bytes per axis of world coordinates in the net protocol. // 2 is the default, backward-compatible number. // TODO: make this a variable, have it set based on the map size, server kicks // clients that don't support big maps. #define coord_bytes 2 // // config strings are a general means of communication from // the server to all connected clients. // Each config string can be at most MAX_QPATH characters. // Alien Arena client/server protocol depends on MAX_QPATH being 64 // #define CS_NAME 0 #define CS_SKY 2 #define CS_SKYAXIS 3 // %f %f %f format #define CS_SKYROTATE 4 #define CS_STATUSBAR 5 // display program string #define CS_AIRACCEL 29 // air acceleration control #define CS_MAXCLIENTS 30 #define CS_MAPCHECKSUM 31 // for catching cheater maps #define CS_MODELS 32 #define CS_SOUNDS (CS_MODELS+MAX_MODELS) #define CS_IMAGES (CS_SOUNDS+MAX_SOUNDS) #define CS_LIGHTS (CS_IMAGES+MAX_IMAGES) #define CS_ITEMS (CS_LIGHTS+MAX_LIGHTSTYLES) #define CS_PLAYERSKINS (CS_ITEMS+MAX_ITEMS) #define CS_GENERAL (CS_PLAYERSKINS+MAX_CLIENTS) #define MAX_CONFIGSTRINGS (CS_GENERAL+MAX_GENERAL) //============================================== // entity_state_t->event values // ertity events are for effects that take place reletive // to an existing entities origin. Very network efficient. // All muzzle flashes really should be converted to events... typedef enum { EV_NONE, EV_ITEM_RESPAWN, EV_FOOTSTEP, EV_FALLSHORT, EV_FALL, EV_FALLFAR, EV_PLAYER_TELEPORT, EV_OTHER_TELEPORT, EV_WADE } entity_event_t; // entity_state_t is the information conveyed from the server // in an update message about entities that the client will // need to render in some way typedef struct entity_state_s { int number; // edict index vec3_t origin; vec3_t angles; vec3_t old_origin; // for lerping int modelindex; int modelindex2, modelindex3, modelindex4; // weapons, CTF flags, etc int frame; int skinnum; unsigned int effects; // PGM - we're filling it, so it needs to be unsigned int renderfx; int solid; // for client side prediction, 8*(bits 0-4) is x/y radius // 8*(bits 5-9) is z down distance, 8(bits10-15) is z up // gi.linkentity sets this properly int sound; // for looping sounds, to guarantee shutoff int event; // impulse events -- muzzle flashes, footsteps, etc // events only go out for a single frame, they // are automatically cleared each frame vec3_t spawn_pos; //used for remembering the original spawn position of an entity } entity_state_t; //============================================== //bot score info //data used to track bot scores for server status strings typedef struct { char name[MAX_INFO_STRING]; int score; } bot_t; // player_state_t is the information needed in addition to pmove_state_t // to rendered a view. There will only be 10 player_state_t sent each second, // but the number of pmove_state_t changes will be reletive to client // frame rates typedef struct { pmove_state_t pmove; // for prediction // these fields do not need to be communicated bit-precise vec3_t viewangles; // for fixed views vec3_t viewoffset; // add to pmovestate->origin vec3_t kick_angles; // add to view direction to get render angles // set by weapon kicks, pain effects, etc vec3_t gunangles; vec3_t gunoffset; int gunindex; int gunframe; float blend[4]; // rgba full screen effect float fov; // horizontal field of view int rdflags; // refdef flags short stats[MAX_STATS]; // fast status bar updates //bot score info int botnum; bot_t bots[100]; } player_state_t; //colored text //============================================= #define Q_COLOR_ESCAPE '^' #define Q_IsColorString(p) ( p && *(p) == Q_COLOR_ESCAPE && *((p)+1) && *((p)+1) != Q_COLOR_ESCAPE ) #define COLOR_BLACK '0' #define COLOR_RED '1' #define COLOR_GREEN '2' #define COLOR_YELLOW '3' #define COLOR_BLUE '4' #define COLOR_CYAN '5' #define COLOR_MAGENTA '6' #define COLOR_WHITE '7' #define ColorIndex(c) ( ( (c) - '0' ) & 7 ) #define COLOR_R(rgba) ((rgba) & 0xFF) #define COLOR_G(rgba) (((rgba) >> 8) & 0xFF) #define COLOR_B(rgba) (((rgba) >> 16) & 0xFF) #define COLOR_A(rgba) (((rgba) >> 24) & 0xFF) #define COLOR_RGB(r,g,b) (((r) << 0)|((g) << 8)|((b) << 16)) #define COLOR_RGBA(r,g,b,a) (((r) << 0)|((g) << 8)|((b) << 16)|((a) << 24)) #define S_COLOR_BLACK "^0" #define S_COLOR_RED "^1" #define S_COLOR_GREEN "^2" #define S_COLOR_YELLOW "^3" #define S_COLOR_BLUE "^4" #define S_COLOR_CYAN "^5" #define S_COLOR_MAGENTA "^6" #define S_COLOR_WHITE "^7" //unlagged - lag simulation #2 #define MAX_LATENT_CMDS 64 //unlagged - lag simulation #2 // // types of compression // enum compressiontypes_e { compression_zlib_raw, compression_lzo, compression_zlib_header, last_compressiontype_known }; #endif /* Q_SHARED_H_ */ alien-arena-7.66+dfsg/source/game/cow.h0000600000175000017500000000235312161402010016757 0ustar zero79zero79#define FRAME_walk01 0 #define FRAME_walk02 1 #define FRAME_walk03 2 #define FRAME_walk04 3 #define FRAME_walk05 4 #define FRAME_walk06 5 #define FRAME_walk07 6 #define FRAME_walk08 7 #define FRAME_walk09 8 #define FRAME_walk10 9 #define FRAME_walk11 10 #define FRAME_walk12 11 #define FRAME_stand01 12 #define FRAME_stand02 13 #define FRAME_stand03 14 #define FRAME_stand04 15 #define FRAME_stand05 16 #define FRAME_stand06 17 #define FRAME_stand07 18 #define FRAME_stand08 19 #define FRAME_stand09 20 #define FRAME_stand10 21 #define FRAME_stand11 22 #define FRAME_stand12 23 #define FRAME_stand13 24 #define FRAME_stand14 25 #define FRAME_stand15 26 #define FRAME_stand16 27 #define FRAME_stand17 28 #define FRAME_stand18 29 #define FRAME_stand19 30 #define FRAME_stand20 31 #define FRAME_pain01 32 #define FRAME_pain02 33 #define FRAME_pain03 34 #define FRAME_pain04 35 #define FRAME_pain05 36 #define FRAME_pain06 37 #define FRAME_pain07 38 #define FRAME_pain08 39 #define FRAME_pain09 40 #define FRAME_pain10 41 #define FRAME_pain11 42 #define MODEL_SCALE 1.000000 alien-arena-7.66+dfsg/source/game/g_spider.c0000600000175000017500000002162612161402010017762 0ustar zero79zero79/* Copyright (C) 2012 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* ============================================================================== Spider projectile bot ============================================================================== */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" #include "g_spider.h" static int sound_pain; static int sound_die; static int sound_walk; static int sound_punch; static int sound_sight; static int sound_search; void spider_search (edict_t *self) { gi.sound (self, CHAN_VOICE, sound_search, 1, ATTN_NORM, 0); } mframe_t spider_frames_stand [] = { {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL} }; mmove_t spider_move_stand = {FRAME_stand01, FRAME_stand13, spider_frames_stand, NULL}; void spider_stand (edict_t *self) { self->monsterinfo.currentmove = &spider_move_stand; } void spider_step(edict_t *self) { gi.sound (self, CHAN_VOICE, sound_walk, 1, ATTN_NORM, 0); } mframe_t spider_frames_walk1 [] = { {ai_run, 4, NULL}, {ai_run, 8, spider_step}, {ai_run, 12, NULL}, {ai_run, 12, spider_step}, {ai_run, 8, NULL}, {ai_run, 12, spider_step} }; mmove_t spider_move_walk1 = {FRAME_walk01, FRAME_walk06, spider_frames_walk1, NULL}; void spider_walk (edict_t *self) { if (self->monsterinfo.aiflags & AI_STAND_GROUND) self->monsterinfo.currentmove = &spider_move_stand; else self->monsterinfo.currentmove = &spider_move_walk1; } void spiderShot (edict_t *self) //same as deathray shot { vec3_t forward, right; vec3_t start; vec3_t end; vec3_t dir; vec3_t from; vec3_t offset; int damage = 50; trace_t tr; AngleVectors (self->s.angles, forward, right, NULL); VectorSet(offset, 16, 0, 16); G_ProjectSource (self->s.origin, offset, forward, right, start); VectorCopy (self->s.origin, start); VectorCopy (self->enemy->s.origin, end); end[2] += self->enemy->viewheight; VectorSubtract (end, start, dir); right[0] = forward[0] * 32; right[1] = forward[1] * 32; VectorAdd(start, right, start); start[2] += 16; VectorCopy (start, from); tr = gi.trace (from, NULL, NULL, end, self, MASK_SHOT); VectorCopy (tr.endpos, from); // send muzzle flash gi.WriteByte (svc_muzzleflash); gi.WriteShort (self-g_edicts); gi.WriteByte (MZ_RAILGUN); gi.multicast (self->s.origin, MULTICAST_PVS); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_VAPORBEAM); gi.WritePosition (start); gi.WritePosition (end); gi.multicast (self->s.origin, MULTICAST_PHS); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BFG_BIGEXPLOSION); gi.WritePosition (end); gi.multicast (end, MULTICAST_PVS); gi.sound (self, CHAN_VOICE, sound_punch, 1, ATTN_NORM, 0); if ((tr.ent != self) && (tr.ent->takedamage)) T_Damage (tr.ent, self, self, dir, tr.endpos, tr.plane.normal, damage, 0, 0, MOD_SPIDER); else if (!((tr.surface) && (tr.surface->flags & SURF_SKY))) { gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_SCREEN_SPARKS); gi.WritePosition (tr.endpos); gi.WriteDir (tr.plane.normal); gi.multicast (self->s.origin, MULTICAST_PVS); } } mframe_t spider_frames_attack_shoot [] = { {ai_charge, 0, NULL}, {ai_charge, 0, spiderShot}, {ai_charge, 0, NULL}, {ai_charge, 0, NULL}, {ai_charge, 0, NULL}, {ai_charge, 0, NULL} }; mmove_t spider_move_attack_shoot = {FRAME_shoot01, FRAME_shoot06, spider_frames_attack_shoot, spider_walk}; void spider_sight (edict_t *self, edict_t *other) { gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); self->monsterinfo.currentmove = &spider_move_walk1; } void spider_attack (edict_t *self) { self->monsterinfo.currentmove = &spider_move_attack_shoot; } mframe_t spider_frames_pain1 [] = { {ai_move, 0, NULL}, {ai_move, 0, NULL}, {ai_move, 0, NULL}, {ai_move, 0, NULL}, {ai_move, 0, NULL} }; mmove_t spider_move_pain1 = {FRAME_pain01, FRAME_pain05, spider_frames_pain1, spider_walk}; void spider_pain (edict_t *self, edict_t *other, float kick, int damage) { if (level.time < self->pain_debounce_time) return; self->pain_debounce_time = level.time + 3; gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0); self->monsterinfo.currentmove = &spider_move_pain1; } void spider_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { gi.sound (self, CHAN_VOICE, sound_die, 1, ATTN_NORM, 0); self->movetype = MOVETYPE_TOSS; self->svflags |= SVF_DEADMONSTER; gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_EXPLOSION1); gi.WritePosition (self->s.origin); gi.multicast (self->s.origin, MULTICAST_PVS); self->deadflag = DEAD_DEAD; self->think = G_FreeEdict; gi.linkentity (self); G_FreeEdict(self); } void spawn_spider (edict_t *owner, vec3_t origin, vec3_t angle) { edict_t *self = G_Spawn(); VectorCopy(origin, self->s.origin); VectorCopy(angle, self->s.angles); self->s.origin[2] += 16; sound_pain = gi.soundindex ("misc/deathray/fizz.wav"); sound_die = gi.soundindex ("misc/deathray/fizz.wav"); sound_walk = gi.soundindex ("weapons/spidermov.wav"); sound_punch = gi.soundindex ("misc/deathray/shoot.wav"); sound_search = gi.soundindex ("weapons/seeker.wav"); sound_sight = gi.soundindex ("misc/deathray/weird2.wav"); self->s.modelindex = gi.modelindex("models/objects/spider/tris.md2"); self->s.modelindex3 = gi.modelindex("models/objects/spider/helmet.md2"); self->classname = "proj_spider"; VectorSet (self->mins, -16, -16, 0); VectorSet (self->maxs, 16, 16, 32); self->movetype = MOVETYPE_STEP; self->solid = SOLID_BBOX; self->takedamage = DAMAGE_YES; self->max_health = 100; self->health = self->max_health; self->gib_health = 0; self->mass = 100; self->pain = spider_pain; self->die = spider_die; self->monsterinfo.stand = spider_stand; self->monsterinfo.walk = spider_walk; self->monsterinfo.run = spider_walk; self->monsterinfo.dodge = NULL; self->monsterinfo.attack = spider_attack; self->monsterinfo.melee = spider_attack; self->monsterinfo.sight = spider_sight; self->monsterinfo.search = spider_search; self->s.renderfx |= RF_MONSTER; self->monsterinfo.currentmove = &spider_move_stand; self->monsterinfo.scale = MODEL_SCALE; self->enemy = NULL; self->owner = owner; gi.linkentity (self); walkmonster_start (self); } void spider_think (edict_t *self) { self->nextthink = level.time + FRAMETIME; } void spider_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { if (other == ent->owner) return; if (surf && (surf->flags & SURF_SKY)) { G_FreeEdict (ent); return; } else if(surf) { spawn_spider(ent->owner, ent->s.origin, ent->s.angles); G_FreeEdict (ent); return; } //just bounce off of anything else gi.sound (ent, CHAN_VOICE, gi.soundindex ("weapons/clank.wav"), 1, ATTN_NORM, 0); return; } void fire_spider (edict_t *self, vec3_t start, vec3_t aimdir, int speed) { edict_t *spider; vec3_t dir, forward, right, up; self->client->resp.weapon_shots[2]++; vectoangles(aimdir, dir); AngleVectors(dir, forward, right, up); spider = G_Spawn(); VectorCopy (start, spider->s.origin); VectorScale (aimdir, speed, spider->velocity); VectorMA (spider->velocity, 200 + crandom() * 10.0, up, spider->velocity); VectorMA (spider->velocity, crandom() * 10.0, right, spider->velocity); VectorSet (spider->avelocity, 300, 300, 300); spider->movetype = MOVETYPE_BOUNCE; spider->clipmask = MASK_SHOT; spider->solid = SOLID_BBOX; VectorClear (spider->mins); VectorClear (spider->maxs); spider->s.modelindex = gi.modelindex("models/objects/spider/tris.md2"); spider->s.modelindex3 = gi.modelindex("models/objects/spider/helmet.md2"); spider->s.frame = 31; spider->owner = self; spider->touch = spider_touch; spider->nextthink = level.time + .1; spider->think = spider_think; spider->s.sound = gi.soundindex ("weapons/electroball.wav"); spider->classname = "proj_spider"; gi.linkentity (spider); }alien-arena-7.66+dfsg/source/game/acesrc/0000700000175000017500000000000012207204656017272 5ustar zero79zero79alien-arena-7.66+dfsg/source/game/acesrc/acebot_items.c0000600000175000017500000004214612161402010022064 0ustar zero79zero79/////////////////////////////////////////////////////////////////////// // // ACE - Quake II Bot Base Code // // Version 1.0 // // This file is Copyright(c), Steve Yeager 1998, All Rights Reserved // // // All other files are Copyright(c) Id Software, Inc. // // Please see liscense.txt in the source directory for the copyright // information regarding those files belonging to Id Software, Inc. // // Should you decide to release a modified version of ACE, you MUST // include the following text (minus the BEGIN and END lines) in the // documentation for your modification. // // --- BEGIN --- // // The ACE Bot is a product of Steve Yeager, and is available from // the ACE Bot homepage, at http://www.axionfx.com/ace. // // This program is a modification of the ACE Bot, and is therefore // in NO WAY supported by Steve Yeager. // This program MUST NOT be sold in ANY form. If you have paid for // this product, you should contact Steve Yeager immediately, via // the ACE Bot homepage. // // --- END --- // // I, Steve Yeager, hold no responsibility for any harm caused by the // use of this source code, especially to small children and animals. // It is provided as-is with no implied warranty or support. // // I also wish to thank and acknowledge the great work of others // that has helped me to develop this code. // // John Cricket - For ideas and swapping code. // Ryan Feltrin - For ideas and swapping code. // SABIN - For showing how to do true client based movement. // BotEpidemic - For keeping us up to date. // Telefragged.com - For giving ACE a home. // Microsoft - For giving us such a wonderful crash free OS. // id - Need I say more. // // And to all the other testers, pathers, and players and people // who I can't remember who the heck they were, but helped out. // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // acebot_items.c - This file contains all of the // item handling routines for the // ACE bot, including fact table support // /////////////////////////////////////////////////////////////////////// #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "game/g_local.h" #include "acebot.h" int num_items = 0; item_table_t item_table[MAX_EDICTS]; static gitem_t *redflag; static gitem_t *blueflag; void ACEAI_InitKnownCTFItems(void) { //int i; //define gitem_t pointers commonly used for comparisons inside this archive. redflag = FindItemByClassname("item_flag_red"); blueflag = FindItemByClassname("item_flag_blue"); } /////////////////////////////////////////////////////////////////////// // Can we get there? /////////////////////////////////////////////////////////////////////// qboolean ACEIT_IsReachable(edict_t *self, vec3_t goal) { trace_t trace; vec3_t v; VectorCopy(self->mins,v); v[2] += 18; // Stepsize trace = gi.trace (self->s.origin, v, self->maxs, goal, self, BOTMASK_OPAQUE); // Yes we can see it if (trace.fraction == 1.0) return true; else return false; } /////////////////////////////////////////////////////////////////////// // Visiblilty check /////////////////////////////////////////////////////////////////////// qboolean ACEIT_IsVisible(edict_t *self, vec3_t goal) { trace_t trace; trace = gi.trace (self->s.origin, vec3_origin, vec3_origin, goal, self, BOTMASK_OPAQUE); // Yes we can see it if (trace.fraction == 1.0) return true; else return false; } /////////////////////////////////////////////////////////////////////// // Weapon changing support /////////////////////////////////////////////////////////////////////// qboolean ACEIT_ChangeWeapon (edict_t *ent, gitem_t *item) { int ammo_index; gitem_t *ammo_item; // see if we're already using it if (item == ent->client->pers.weapon) return true; // Has not picked up weapon yet if(!ent->client->pers.inventory[ITEM_INDEX(item)]) return false; // Do we have ammo for it? if (item->ammo) { ammo_item = FindItem(item->ammo); ammo_index = ITEM_INDEX(ammo_item); if (!ent->client->pers.inventory[ammo_index] && !g_select_empty->value) return false; } // Change to this weapon ent->client->newweapon = item; // Make weapon swap visible. ChangeWeapon( ent ); return true; } extern gitem_armor_t jacketarmor_info; extern gitem_armor_t combatarmor_info; extern gitem_armor_t bodyarmor_info; /////////////////////////////////////////////////////////////////////// // Check if we can use the armor /////////////////////////////////////////////////////////////////////// qboolean ACEIT_CanUseArmor (gitem_t *item, edict_t *other) { int old_armor_index; gitem_armor_t *oldinfo; gitem_armor_t *newinfo; int newcount; float salvage; int salvagecount; // get info on new armor newinfo = (gitem_armor_t *)item->info; old_armor_index = ArmorIndex (other); // handle armor shards specially if (item->tag == ARMOR_SHARD) return true; // get info on old armor if (old_armor_index == ITEM_INDEX(FindItem("Jacket Armor"))) oldinfo = &jacketarmor_info; else if (old_armor_index == ITEM_INDEX(FindItem("Combat Armor"))) oldinfo = &combatarmor_info; else // (old_armor_index == body_armor_index) oldinfo = &bodyarmor_info; if (newinfo->normal_protection <= oldinfo->normal_protection) { // calc new armor values salvage = newinfo->normal_protection / oldinfo->normal_protection; salvagecount = salvage * newinfo->base_count; newcount = other->client->pers.inventory[old_armor_index] + salvagecount; if (newcount > oldinfo->max_count) newcount = oldinfo->max_count; // if we're already maxed out then we don't need the new armor if (other->client->pers.inventory[old_armor_index] >= newcount) return false; } return true; } //========================================== // find needed flag // //========================================== gitem_t *ACEIT_WantedFlag (edict_t *self) { qboolean hasflag; if (!ctf->value) return NULL; //find out if the player has a flag, and what flag is it if (redflag && self->client->pers.inventory[ITEM_INDEX(redflag)]) hasflag = true; else if (blueflag && self->client->pers.inventory[ITEM_INDEX(blueflag)]) hasflag = true; else hasflag = false; //jalToDo: see if our flag is at base if (!hasflag)//if we don't have a flag we want other's team flag { if (self->dmteam == RED_TEAM) return blueflag; else return redflag; } else //we have a flag { if (self->dmteam == BLUE_TEAM) return redflag; else return blueflag; } return NULL; } /////////////////////////////////////////////////////////////////////// // Determins the NEED for an item // // This function can be modified to support new items to pick up // Any other logic that needs to be added for custom decision making // can be added here. For now it is very simple. /////////////////////////////////////////////////////////////////////// float ACEIT_ItemNeed(edict_t *self, int item) { gitem_t *wantedFlag; // Make sure item is at least close to being valid if(item < 0 || item > 100) return 0.0; switch(item) { // Health case ITEMLIST_HEALTH_SMALL: case ITEMLIST_HEALTH_MEDIUM: case ITEMLIST_HEALTH_LARGE: case ITEMLIST_HEALTH_MEGA: if(self->health < 100) return 1.0 - (float)self->health/100.0f; // worse off, higher priority else return 0.0; case ITEMLIST_QUADDAMAGE: case ITEMLIST_INVULNERABILITY: case ITEMLIST_HASTE: case ITEMLIST_SPROING: case ITEMLIST_ADRENALINE: return 0.6; // Weapons case ITEMLIST_ROCKETLAUNCHER: case ITEMLIST_CHAINGUN: case ITEMLIST_SUPERSHOTGUN: case ITEMLIST_BFG10K: if(g_tactical->integer && self->ctype == 0) return 0.0; else if(g_tactical->integer && self->ctype == 1) { if(!self->client->pers.inventory[item]) return 0.9; else return 0.0; } case ITEMLIST_SHOTGUN: case ITEMLIST_HYPERBLASTER: case ITEMLIST_RAILGUN: case ITEMLIST_MINDERASER: if(g_tactical->integer && self->ctype == 1) return 0.0; else if(g_tactical->integer && self->ctype == 0) { if(!self->client->pers.inventory[item]) return 0.9; else return 0.0; } //normal game mode if(!self->client->pers.inventory[item]) return 0.9; //was .7 else return 0.0; // Ammo case ITEMLIST_SLUGS: if(self->client->pers.inventory[ITEMLIST_SLUGS] < self->client->pers.max_slugs) return 0.4; else return 0.0; case ITEMLIST_BULLETS: if(self->client->pers.inventory[ITEMLIST_BULLETS] < self->client->pers.max_bullets) return 0.3; else return 0.0; case ITEMLIST_SHELLS: if(self->client->pers.inventory[ITEMLIST_SHELLS] < self->client->pers.max_shells) return 0.3; else return 0.0; case ITEMLIST_CELLS: if(self->client->pers.inventory[ITEMLIST_CELLS] < self->client->pers.max_cells) return 0.3; else return 0.0; case ITEMLIST_ROCKETS: if(self->client->pers.inventory[ITEMLIST_ROCKETS] < self->client->pers.max_rockets) return 1.5; else return 0.0; case ITEMLIST_GRENADES: if(self->client->pers.inventory[ITEMLIST_GRENADES] < self->client->pers.max_grenades) return 0.3; else return 0.0; case ITEMLIST_BODYARMOR: if(ACEIT_CanUseArmor (FindItem("Body Armor"), self)) return 0.6; else return 0.0; case ITEMLIST_COMBATARMOR: if(ACEIT_CanUseArmor (FindItem("Combat Armor"), self)) return 0.6; else return 0.0; case ITEMLIST_JACKETARMOR: if(ACEIT_CanUseArmor (FindItem("Jacket Armor"), self)) return 0.6; else return 0.0; //flags case ITEMLIST_FLAG1: wantedFlag = ACEIT_WantedFlag (self); //Returns the flag gitem_t if (redflag != wantedFlag) return 0.0; else return 3.0; case ITEMLIST_FLAG2: wantedFlag = ACEIT_WantedFlag (self); //Returns the flag gitem_t if (blueflag != wantedFlag) return 0.0; else return 3.0; //vehicles case ITEMLIST_BOMBER: case ITEMLIST_STRAFER: case ITEMLIST_HOVER: if(!self->client->pers.inventory[item]) return 0.9; else return 0.0; //deathball case ITEMLIST_DEATHBALL: return 3.0; default: return 0.0; } } /////////////////////////////////////////////////////////////////////// // Convert a classname to its index value // // I prefer to use integers/defines for simplicity sake. This routine // can lead to some slowdowns I guess, but makes the rest of the code // easier to deal with. /////////////////////////////////////////////////////////////////////// int ACEIT_ClassnameToIndex(char *classname) { if(strcmp(classname,"item_armor_body")==0) return ITEMLIST_BODYARMOR; if(strcmp(classname,"item_armor_combat")==0) return ITEMLIST_COMBATARMOR; if(strcmp(classname,"item_armor_jacket")==0) return ITEMLIST_JACKETARMOR; if(strcmp(classname,"item_armor_shard")==0) return ITEMLIST_ARMORSHARD; if(strcmp(classname,"weapon_blaster")==0) return ITEMLIST_BLASTER; if(strcmp(classname,"weapon_shotgun")==0) return ITEMLIST_SHOTGUN; if(strcmp(classname,"weapon_supershotgun")==0) return ITEMLIST_SUPERSHOTGUN; if(strcmp(classname,"weapon_chaingun")==0) return ITEMLIST_CHAINGUN; if(strcmp(classname,"ammo_grenades")==0) return ITEMLIST_GRENADES; if(strcmp(classname,"weapon_rocketlauncher")==0) return ITEMLIST_ROCKETLAUNCHER; if(strcmp(classname,"weapon_hyperblaster")==0) return ITEMLIST_HYPERBLASTER; if(strcmp(classname,"weapon_railgun")==0) return ITEMLIST_RAILGUN; if(strcmp(classname,"weapon_bfg")==0) return ITEMLIST_BFG10K; if(strcmp(classname, "weapon_minderaser") == 0) return ITEMLIST_MINDERASER; if(strcmp(classname,"ammo_shells")==0) return ITEMLIST_SHELLS; if(strcmp(classname,"ammo_bullets")==0) return ITEMLIST_BULLETS; if(strcmp(classname,"ammo_cells")==0) return ITEMLIST_CELLS; if(strcmp(classname,"ammo_rockets")==0) return ITEMLIST_ROCKETS; if(strcmp(classname,"ammo_slugs")==0) return ITEMLIST_SLUGS; if(strcmp(classname,"item_quad")==0) return ITEMLIST_QUADDAMAGE; if(strcmp(classname,"item_invunerability")==0) return ITEMLIST_INVULNERABILITY; if(strcmp(classname,"item_haste")==0) return ITEMLIST_HASTE; if(strcmp(classname,"item_sproing")==0) return ITEMLIST_SPROING; if(strcmp(classname,"item_adrenaline")==0) return ITEMLIST_ADRENALINE; if(strcmp(classname,"item_health")==0) // ?? return ITEMLIST_HEALTH; if(strcmp(classname,"item_health_small")==0) return ITEMLIST_HEALTH_SMALL; if(strcmp(classname,"item_health_medium")==0) return ITEMLIST_HEALTH_MEDIUM; if(strcmp(classname,"item_health_large")==0) return ITEMLIST_HEALTH_LARGE; if(strcmp(classname,"item_health_mega")==0) return ITEMLIST_HEALTH_MEGA; if(strcmp(classname, "item_flag_red") == 0) return ITEMLIST_FLAG1; if(strcmp(classname, "item_flag_blue") == 0) return ITEMLIST_FLAG2; if(strcmp(classname, "item_bomber") == 0) return ITEMLIST_BOMBER; if(strcmp(classname, "item_strafer") == 0) return ITEMLIST_STRAFER; if(strcmp(classname, "item_deathball") == 0) return ITEMLIST_DEATHBALL; return INVALID; } /////////////////////////////////////////////////////////////////////// // Only called once per level, when saved will not be called again // // Downside of the routine is that items can not move about. If the level // has been saved before and reloaded, it could cause a problem if there // are items that spawn at random locations. // //#define DEBUG // uncomment to write out items to a file. /////////////////////////////////////////////////////////////////////// void ACEIT_BuildItemNodeTable (qboolean rebuild) { edict_t *items; int i,item_index; vec3_t v,v1,v2; #ifdef DEBUG FILE *pOut; // for testing if((pOut = fopen("items.txt","wt"))==NULL) return; #endif num_items = 0; // Add game items for(items = g_edicts; items < &g_edicts[globals.num_edicts]; items++) { // filter out crap if(items->solid == SOLID_NOT) continue; if(!items->classname) continue; ///////////////////////////////////////////////////////////////// // Items ///////////////////////////////////////////////////////////////// item_index = ACEIT_ClassnameToIndex(items->classname); //////////////////////////////////////////////////////////////// // SPECIAL NAV NODE DROPPING CODE //////////////////////////////////////////////////////////////// // Special node dropping for platforms if(strcmp(items->classname,"func_plat")==0) { if(!rebuild) ACEND_AddNode(items,NODE_PLATFORM); item_index = 99; // to allow to pass the item index test } // Special node dropping for teleporters if(strcmp(items->classname,"misc_teleporter_dest")==0 || strcmp(items->classname,"misc_teleporter")==0) { if(!rebuild) ACEND_AddNode(items,NODE_TELEPORTER); item_index = 99; } #ifdef DEBUG if(item_index == INVALID) fprintf(pOut,"Rejected item: %s node: %d pos: %f %f %f\n",items->classname,item_table[num_items].node,items->s.origin[0],items->s.origin[1],items->s.origin[2]); else fprintf(pOut,"item: %s node: %d pos: %f %f %f\n",items->classname,item_table[num_items].node,items->s.origin[0],items->s.origin[1],items->s.origin[2]); #endif if(item_index == INVALID) continue; // add a pointer to the item entity item_table[num_items].ent = items; item_table[num_items].item = item_index; // If new, add nodes for items if(!rebuild) { // Add a new node at the item's location. item_table[num_items].node = ACEND_AddNode(items,NODE_ITEM); num_items++; } else // Now if rebuilding, just relink ent structures { // Find stored location for(i=0;is.origin,v); // Add 16 to item type nodes if(nodes[i].type == NODE_ITEM) v[2] += 16; // Add 32 to teleporter if(nodes[i].type == NODE_TELEPORTER) v[2] += 32; if(nodes[i].type == NODE_PLATFORM) { VectorCopy(items->maxs,v1); VectorCopy(items->mins,v2); // To get the center v[0] = (v1[0] - v2[0]) / 2 + v2[0]; v[1] = (v1[1] - v2[1]) / 2 + v2[1]; v[2] = items->mins[2]+64; } if(v[0] == nodes[i].origin[0] && v[1] == nodes[i].origin[1] && v[2] == nodes[i].origin[2]) { // found a match now link to facts item_table[num_items].node = i; #ifdef DEBUG fprintf(pOut,"Relink item: %s node: %d pos: %f %f %f\n",items->classname,item_table[num_items].node,items->s.origin[0],items->s.origin[1],items->s.origin[2]); #endif num_items++; } } } } } #ifdef DEBUG fclose(pOut); #endif } alien-arena-7.66+dfsg/source/game/acesrc/acebot_cmds.c0000600000175000017500000001627512161402010021675 0ustar zero79zero79/////////////////////////////////////////////////////////////////////// // // ACE - Quake II Bot Base Code // // Version 1.0 // // This file is Copyright(c), Steve Yeager 1998, All Rights Reserved // // // All other files are Copyright(c) Id Software, Inc. // // Please see liscense.txt in the source directory for the copyright // information regarding those files belonging to Id Software, Inc. // // Should you decide to release a modified version of ACE, you MUST // include the following text (minus the BEGIN and END lines) in the // documentation for your modification. // // --- BEGIN --- // // The ACE Bot is a product of Steve Yeager, and is available from // the ACE Bot homepage, at http://www.axionfx.com/ace. // // This program is a modification of the ACE Bot, and is therefore // in NO WAY supported by Steve Yeager. // This program MUST NOT be sold in ANY form. If you have paid for // this product, you should contact Steve Yeager immediately, via // the ACE Bot homepage. // // --- END --- // // I, Steve Yeager, hold no responsibility for any harm caused by the // use of this source code, especially to small children and animals. // It is provided as-is with no implied warranty or support. // // I also wish to thank and acknowledge the great work of others // that has helped me to develop this code. // // John Cricket - For ideas and swapping code. // Ryan Feltrin - For ideas and swapping code. // SABIN - For showing how to do true client based movement. // BotEpidemic - For keeping us up to date. // Telefragged.com - For giving ACE a home. // Microsoft - For giving us such a wonderful crash free OS. // id - Need I say more. // // And to all the other testers, pathers, and players and people // who I can't remember who the heck they were, but helped out. // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // acebot_cmds.c - Main internal command processor // /////////////////////////////////////////////////////////////////////// #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "game/g_local.h" #include "acebot.h" qboolean debug_mode=false; /////////////////////////////////////////////////////////////////////// // Special command processor /////////////////////////////////////////////////////////////////////// qboolean ACECM_Commands(edict_t *ent) { char *cmd; int node; cmd = gi.argv(0); if(Q_strcasecmp (cmd, "addnode") == 0 && debug_mode) ent->last_node = ACEND_AddNode(ent,atoi(gi.argv(1))); else if(Q_strcasecmp (cmd, "removelink") == 0 && debug_mode) ACEND_RemoveNodeEdge(ent,atoi(gi.argv(1)), atoi(gi.argv(2))); else if(Q_strcasecmp (cmd, "addlink") == 0 && debug_mode) ACEND_UpdateNodeEdge(atoi(gi.argv(1)), atoi(gi.argv(2))); else if(Q_strcasecmp (cmd, "showpath") == 0 && debug_mode) ACEND_ShowPath(ent,atoi(gi.argv(1))); else if(Q_strcasecmp (cmd, "shownode") == 0 && debug_mode) ACEND_ShowNode(atoi(gi.argv(1))); else if(Q_strcasecmp (cmd, "hidenode") == 0 && debug_mode) { node = atoi(gi.argv(1)); if (node_showents[node]) { G_FreeEdict(node_showents[node]); node_showents[node] = NULL; } } else if(Q_strcasecmp (cmd, "findnode") == 0 && debug_mode) { if (gi.argc() == 2) node = atoi(gi.argv(1)); else node = ACEND_FindClosestReachableNode(ent,NODE_DENSITY, NODE_ALL); safe_bprintf(PRINT_MEDIUM,"node: %d type: %d x: %f y: %f z %f\n",node,nodes[node].type,nodes[node].origin[0],nodes[node].origin[1],nodes[node].origin[2]); } else if(Q_strcasecmp (cmd, "movenode") == 0 && debug_mode) { node = atoi(gi.argv(1)); nodes[node].origin[0] = atof(gi.argv(2)); nodes[node].origin[1] = atof(gi.argv(3)); nodes[node].origin[2] = atof(gi.argv(4)); safe_bprintf(PRINT_MEDIUM,"node: %d moved to x: %f y: %f z %f\n",node, nodes[node].origin[0],nodes[node].origin[1],nodes[node].origin[2]); } else return false; return true; } /////////////////////////////////////////////////////////////////////// // Called when the level changes, store maps and bots (disconnected) /////////////////////////////////////////////////////////////////////// void ACECM_Store() { ACEND_SaveNodes(); } /////////////////////////////////////////////////////////////////////// // These routines are bot safe print routines, all id code needs to be // changed to these so the bots do not blow up on messages sent to them. // Do a find and replace on all code that matches the below criteria. // // (Got the basic idea from Ridah) // // change: gi.cprintf to safe_cprintf // change: gi.bprintf to safe_bprintf // change: gi.centerprintf to safe_centerprintf // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Debug print, could add a "logging" feature to print to a file /////////////////////////////////////////////////////////////////////// void debug_printf(char *fmt, ...) { int i; char bigbuffer[0x10000]; int len; va_list argptr; edict_t *cl_ent; va_start (argptr,fmt); len = vsnprintf (bigbuffer,sizeof(bigbuffer),fmt,argptr); va_end (argptr); if (g_dedicated->value) gi.cprintf(NULL, PRINT_MEDIUM, "%s", bigbuffer); for (i=0 ; ivalue ; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || cl_ent->is_bot) continue; gi.cprintf(cl_ent, PRINT_MEDIUM, "%s", bigbuffer); } } /////////////////////////////////////////////////////////////////////// // botsafe cprintf /////////////////////////////////////////////////////////////////////// void safe_cprintf (edict_t *ent, int printlevel, char *fmt, ...) { char bigbuffer[0x10000]; va_list argptr; int len; if (ent && (!ent->inuse || ent->is_bot)) return; va_start (argptr,fmt); len = vsnprintf (bigbuffer,sizeof(bigbuffer),fmt,argptr); va_end (argptr); gi.cprintf(ent, printlevel, "%s", bigbuffer); } /////////////////////////////////////////////////////////////////////// // botsafe centerprintf /////////////////////////////////////////////////////////////////////// void safe_centerprintf (edict_t *ent, char *fmt, ...) { char bigbuffer[0x10000]; va_list argptr; int len; if (!ent->inuse || ent->is_bot) return; // If the MOTD was displayed and is being "protected" from overwrite, // ignore the call. if ( ent->client && ent->client->motd_frames ) { return; } va_start (argptr,fmt); len = vsnprintf (bigbuffer,sizeof(bigbuffer),fmt,argptr); va_end (argptr); gi.centerprintf(ent,"%s", bigbuffer); } /////////////////////////////////////////////////////////////////////// // botsafe bprintf /////////////////////////////////////////////////////////////////////// void safe_bprintf (int printlevel, char *fmt, ...) { int i; char bigbuffer[0x10000]; int len; va_list argptr; edict_t *cl_ent; va_start (argptr,fmt); len = vsnprintf (bigbuffer,sizeof(bigbuffer),fmt,argptr); va_end (argptr); if (g_dedicated->value) gi.cprintf(NULL, printlevel, "%s", bigbuffer); for (i=0 ; ivalue ; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || cl_ent->is_bot) continue; gi.cprintf(cl_ent, printlevel, "%s", bigbuffer); } } alien-arena-7.66+dfsg/source/game/acesrc/acebot.h0000600000175000017500000002124112161402010020661 0ustar zero79zero79/////////////////////////////////////////////////////////////////////// // // ACE - Quake II Bot Base Code // // Version 1.0 // // This file is Copyright(c), Steve Yeager 1998, All Rights Reserved // // // All other files are Copyright(c) Id Software, Inc. // // Please see liscense.txt in the source directory for the copyright // information regarding those files belonging to Id Software, Inc. // // Should you decide to release a modified version of ACE, you MUST // include the following text (minus the BEGIN and END lines) in the // documentation for your modification. // // --- BEGIN --- // // The ACE Bot is a product of Steve Yeager, and is available from // the ACE Bot homepage, at http://www.axionfx.com/ace. // // This program is a modification of the ACE Bot, and is therefore // in NO WAY supported by Steve Yeager. // This program MUST NOT be sold in ANY form. If you have paid for // this product, you should contact Steve Yeager immediately, via // the ACE Bot homepage. // // --- END --- // // I, Steve Yeager, hold no responsibility for any harm caused by the // use of this source code, especially to small children and animals. // It is provided as-is with no implied warranty or support. // // I also wish to thank and acknowledge the great work of others // that has helped me to develop this code. // // John Cricket - For ideas and swapping code. // Ryan Feltrin - For ideas and swapping code. // SABIN - For showing how to do true client based movement. // BotEpidemic - For keeping us up to date. // Telefragged.com - For giving ACE a home. // Microsoft - For giving us such a wonderful crash free OS. // id - Need I say more. // // And to all the other testers, pathers, and players and people // who I can't remember who the heck they were, but helped out. // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // acebot.h - Main header file for ACEBOT // // /////////////////////////////////////////////////////////////////////// #ifndef _ACEBOT_H #define _ACEBOT_H #if !defined BOT_GAMEDATA #define BOT_GAMEDATA "botinfo" #endif // Only 100 allowed for now (probably never be enough edicts for 'em #define MAX_BOTS 100 // Platform states #define STATE_TOP 0 #define STATE_BOTTOM 1 #define STATE_UP 2 #define STATE_DOWN 3 // Maximum nodes #define MAX_NODES 1000 // Link types #define INVALID -1 // Node types #define NODE_MOVE 0 #define NODE_LADDER 1 #define NODE_PLATFORM 2 #define NODE_TELEPORTER 3 #define NODE_ITEM 4 #define NODE_WATER 5 #define NODE_GRAPPLE 6 #define NODE_JUMP 7 #define NODE_REDBASE 8 #define NODE_BLUEBASE 9 #define NODE_DEFEND 10 #define NODE_ALL 99 // For selecting all nodes // Density setting for nodes #define NODE_DENSITY 256 // Bot state types #define STATE_STAND 0 #define STATE_MOVE 1 #define STATE_ATTACK 2 #define STATE_WANDER 3 #define STATE_FLEE 4 #define MOVE_LEFT 0 #define MOVE_RIGHT 1 #define MOVE_FORWARD 2 #define MOVE_BACK 3 // Item defines (got this list from somewhere??....so thanks to whoever created it) #define ITEMLIST_NULLINDEX 0 #define ITEMLIST_BODYARMOR 1 #define ITEMLIST_COMBATARMOR 2 #define ITEMLIST_JACKETARMOR 3 #define ITEMLIST_ARMORSHARD 4 #define ITEMLIST_GRAPPLE 7 #define ITEMLIST_BLASTER 8 #define ITEMLIST_SHOTGUN 9 #define ITEMLIST_SUPERSHOTGUN 10 #define ITEMLIST_CHAINGUN 11 #define ITEMLIST_GRENADES 12 #define ITEMLIST_ROCKETLAUNCHER 13 #define ITEMLIST_HYPERBLASTER 14 #define ITEMLIST_RAILGUN 15 #define ITEMLIST_BFG10K 16 #define ITEMLIST_SHELLS 17 #define ITEMLIST_BULLETS 18 #define ITEMLIST_CELLS 19 #define ITEMLIST_ROCKETS 20 #define ITEMLIST_SLUGS 21 #define ITEMLIST_QUADDAMAGE 22 #define ITEMLIST_INVULNERABILITY 23 #define ITEMLIST_ADRENALINE 24 #define ITEMLIST_HEALTH 25 // new for ctf #define ITEMLIST_FLAG1 26 #define ITEMLIST_FLAG2 27 #define ITEMLIST_HASTE 28 #define ITEMLIST_SPROING 29 // my additions #define ITEMLIST_HEALTH_SMALL 30 #define ITEMLIST_HEALTH_MEDIUM 31 #define ITEMLIST_HEALTH_LARGE 32 #define ITEMLIST_BOT 33 #define ITEMLIST_PLAYER 34 #define ITEMLIST_HEALTH_MEGA 35 //vehicles #define ITEMLIST_BOMBER 36 #define ITEMLIST_STRAFER 37 #define ITEMLIST_DEATHBALL 38 #define ITEMLIST_HOVER 39 //mind eraser #define ITEMLIST_MINDERASER 40 // Special CONTENT mask for acebots, so they can detect and climb ladders // replaces MASK_OPAQUE defined in game/q_shared.h #define BOTMASK_OPAQUE (CONTENTS_SOLID|CONTENTS_SLIME|CONTENTS_LAVA|CONTENTS_LADDER) // Node structure typedef struct node_s { vec3_t origin; // Using Id's representation int type; // type of node } node_t; typedef struct item_table_s { int item; float weight; edict_t *ent; int node; } item_table_t; // Bot config structure struct botvals_s { int skill; char faveweap[64]; float weapacc[10]; float awareness; char chatmsg1[128]; char chatmsg2[128]; char chatmsg3[128]; char chatmsg4[128]; char chatmsg5[128]; char chatmsg6[128]; char chatmsg7[128]; char chatmsg8[128]; } botvals; extern edict_t *players[MAX_CLIENTS]; // pointers to all players in the game // extern decs edict_t *node_showents[MAX_NODES]; //ents created by shownode extern node_t nodes[MAX_NODES]; extern item_table_t item_table[MAX_EDICTS]; extern qboolean debug_mode; extern int bot_numnodes; extern int num_items; extern int num_bots; // id Function Protos I need void LookAtKiller (edict_t *self, edict_t *inflictor, edict_t *attacker); void ClientObituary (edict_t *self, edict_t *inflictor, edict_t *attacker); void TossClientWeapon (edict_t *self); void ClientThink (edict_t *ent, usercmd_t *ucmd); void SelectSpawnPoint (edict_t *ent, vec3_t origin, vec3_t angles); void ClientUserinfoChanged (edict_t *ent, char *userinfo, int whereFrom); void CopyToBodyQue (edict_t *ent); qboolean ClientConnect (edict_t *ent, char *userinfo); void Use_Plat (edict_t *ent, edict_t *other, edict_t *activator); // acebot_ai.c protos void ACEAI_Think (edict_t *self); void ACEAI_PickLongRangeGoal(edict_t *self); void ACEAI_PickShortRangeGoal(edict_t *self); qboolean ACEAI_FindEnemy(edict_t *self); void ACEAI_ChooseWeapon(edict_t *self); qboolean ACEAI_CheckShot(edict_t *self); // acebot_cmds.c protos qboolean ACECM_Commands(edict_t *ent); void ACECM_Store(); // acebot_items.c protos qboolean ACEIT_IsVisible(edict_t *self, vec3_t goal); qboolean ACEIT_IsReachable(edict_t *self,vec3_t goal); qboolean ACEIT_ChangeWeapon (edict_t *ent, gitem_t *item); qboolean ACEIT_CanUseArmor (gitem_t *item, edict_t *other); float ACEIT_ItemNeed(edict_t *self, int item); int ACEIT_ClassnameToIndex(char *classname); void ACEIT_BuildItemNodeTable (qboolean rebuild); // acebot_movement.c protos qboolean ACEMV_SpecialMove(edict_t *self,usercmd_t *ucmd); void ACEMV_Move(edict_t *self, usercmd_t *ucmd); void ACEMV_Attack (edict_t *self, usercmd_t *ucmd); void ACEMV_Wander (edict_t *self, usercmd_t *ucmd); // acebot_nodes.c protos int ACEND_FindCost(int from, int to); int ACEND_FindCloseReachableNode(edict_t *self, int dist, int type); int ACEND_FindClosestReachableNode(edict_t *self, int range, int type); void ACEND_SetGoal(edict_t *self, int goal_node); qboolean ACEND_FollowPath(edict_t *self); void ACEND_GrapFired(edict_t *self); qboolean ACEND_CheckForLadder(edict_t *self); void ACEND_PathMap(edict_t *self); void ACEND_InitNodes(void); void ACEND_ShowNode(int node); void ACEND_DrawPath(); void ACEND_ShowPath(edict_t *self, int goal_node); int ACEND_AddNode(edict_t *self, int type); void ACEND_UpdateNodeEdge(int from, int to); void ACEND_RemoveNodeEdge(edict_t *self, int from, int to); void ACEND_ResolveAllPaths(); void ACEND_SaveNodes(); void ACEND_LoadNodes(); // acebot_spawn.c protos void ACESP_UpdateBots(void); void ACESP_SaveBots(); void ACESP_LoadBots(edict_t *ent); int ACESP_FindBotNum(void); edict_t *ACESP_FindBot(const char *name); void ACESP_KickBot(edict_t *bot); void ACESP_HoldSpawn(edict_t *self); void ACESP_PutClientInServer (edict_t *bot, qboolean respawn); void ACESP_Respawn (edict_t *self); edict_t *ACESP_FindFreeClient (void); void ACESP_SetName(edict_t *bot, char *name, char *skin, char *userinfo ); qboolean ACESP_SpawnBot (char *name, char *skin, char *userinfo); void ACESP_ReAddBots(); void ACESP_RemoveBot(char *name); void safe_cprintf (edict_t *ent, int printlevel, char *fmt, ...); void safe_centerprintf (edict_t *ent, char *fmt, ...); void safe_bprintf (int printlevel, char *fmt, ...); void debug_printf (char *fmt, ...); #endif alien-arena-7.66+dfsg/source/game/acesrc/acebot_nodes.c0000600000175000017500000005037712161402010022060 0ustar zero79zero79/////////////////////////////////////////////////////////////////////// // // ACE - Quake II Bot Base Code // // Version 1.0 // // This file is Copyright(c), Steve Yeager 1998, All Rights Reserved // // // All other files are Copyright(c) Id Software, Inc. // // Please see liscense.txt in the source directory for the copyright // information regarding those files belonging to Id Software, Inc. // // Should you decide to release a modified version of ACE, you MUST // include the following text (minus the BEGIN and END lines) in the // documentation for your modification. // // --- BEGIN --- // // The ACE Bot is a product of Steve Yeager, and is available from // the ACE Bot homepage, at http://www.axionfx.com/ace. // // This program is a modification of the ACE Bot, and is therefore // in NO WAY supported by Steve Yeager. // This program MUST NOT be sold in ANY form. If you have paid for // this product, you should contact Steve Yeager immediately, via // the ACE Bot homepage. // // --- END --- // // I, Steve Yeager, hold no responsibility for any harm caused by the // use of this source code, especially to small children and animals. // It is provided as-is with no implied warranty or support. // // I also wish to thank and acknowledge the great work of others // that has helped me to develop this code. // // John Cricket - For ideas and swapping code. // Ryan Feltrin - For ideas and swapping code. // SABIN - For showing how to do true client based movement. // BotEpidemic - For keeping us up to date. // Telefragged.com - For giving ACE a home. // Microsoft - For giving us such a wonderful crash free OS. // id - Need I say more. // // And to all the other testers, pathers, and players and people // who I can't remember who the heck they were, but helped out. // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // acebot_nodes.c - This file contains all of the // pathing routines for the ACE bot. // /////////////////////////////////////////////////////////////////////// #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "game/g_local.h" #include "acebot.h" // flags qboolean newmap=true; // Total number of nodes that are items int numitemnodes; // Total number of nodes int bot_numnodes; // For debugging paths int show_path_from = -1; int show_path_to = -1; // array for node data node_t nodes[MAX_NODES]; edict_t *node_showents[MAX_NODES]; short int path_table[MAX_NODES][MAX_NODES]; /////////////////////////////////////////////////////////////////////// // NODE INFORMATION FUNCTIONS /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Determine cost of moving from one node to another /////////////////////////////////////////////////////////////////////// int ACEND_FindCost(int from, int to) { int curnode; int cost=1; // Shortest possible is 1 // If we can not get there then return invalid if (path_table[from][to] == INVALID) { //if(debug_mode) // debug_printf("Found invalid path!"); return INVALID; } // Otherwise check the path and return the cost curnode = path_table[from][to]; // Find a path (linear time, very fast) while(curnode != to) { curnode = path_table[curnode][to]; if(curnode == INVALID) // something has corrupted the path abort { //if(debug_mode) // debug_printf("Found invalid path!"); return INVALID; } cost++; if(cost > 500) { if(debug_mode) debug_printf("Cost exceeded maximum!\n"); break; } } return cost; } /////////////////////////////////////////////////////////////////////// // Find the closest node to the player within a certain range /////////////////////////////////////////////////////////////////////// int ACEND_FindClosestReachableNode(edict_t *self, int range, int type) { int i; float closest = 99999; float dist; int node=-1; vec3_t v; trace_t tr; float rng; vec3_t maxs,mins; VectorCopy(self->mins,mins); VectorCopy(self->maxs,maxs); // For Ladders, do not worry so much about reachability if(type == NODE_LADDER) { VectorCopy(vec3_origin,maxs); VectorCopy(vec3_origin,mins); } else mins[2] += 18; // Stepsize rng = (float)(range); // square range for distance comparison (eliminate sqrt) for(i=0;is.origin, v); // subtract first dist = VectorLength(v); if(self->current_node != -1) { dist = dist + abs(self->current_node - i); //try to keep the bot on the current path(i.e - nodes in sequence are weighted over those out) } if(dist < closest && dist < rng) { // make sure it is visible tr = gi.trace (self->s.origin, mins, maxs, nodes[i].origin, self, MASK_SOLID); if(tr.fraction == 1.0) { node = i; closest = dist; } } } } return node; } /////////////////////////////////////////////////////////////////////// // BOT NAVIGATION ROUTINES /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Set up the goal /////////////////////////////////////////////////////////////////////// void ACEND_SetGoal(edict_t *self, int goal_node) { int node; gitem_t *flag1_item, *flag2_item; self->goal_node = goal_node; //if flag in possession only use base nodes if(ctf->value) { flag1_item = FindItemByClassname("item_flag_red"); flag2_item = FindItemByClassname("item_flag_blue"); if (self->client->pers.inventory[ITEM_INDEX(flag1_item)]) { node = ACEND_FindClosestReachableNode(self,NODE_DENSITY*3,NODE_BLUEBASE); if(node == -1) node = ACEND_FindClosestReachableNode(self,NODE_DENSITY*3,NODE_ALL); } else if (self->client->pers.inventory[ITEM_INDEX(flag2_item)]) { node = ACEND_FindClosestReachableNode(self,NODE_DENSITY*3,NODE_REDBASE); if(node == -1) node = ACEND_FindClosestReachableNode(self,NODE_DENSITY*3,NODE_ALL); } else node = ACEND_FindClosestReachableNode(self,NODE_DENSITY*3,NODE_ALL); } else if(g_tactical->value) //when a base's laser barriers shut off, go into a more direct attack route { if (self->ctype == 1 && (!tacticalScore.alienComputer || !tacticalScore.alienPowerSource)) { node = ACEND_FindClosestReachableNode(self,NODE_DENSITY*3,NODE_BLUEBASE); if(node == -1) node = ACEND_FindClosestReachableNode(self,NODE_DENSITY*3,NODE_ALL); } else if (self->ctype == 0 && (!tacticalScore.humanComputer || !tacticalScore.humanPowerSource)) { node = ACEND_FindClosestReachableNode(self,NODE_DENSITY*3,NODE_REDBASE); if(node == -1) node = ACEND_FindClosestReachableNode(self,NODE_DENSITY*3,NODE_ALL); } else node = ACEND_FindClosestReachableNode(self,NODE_DENSITY*3,NODE_ALL); } else node = ACEND_FindClosestReachableNode(self, NODE_DENSITY*3, NODE_ALL); if(node == -1) return; if(debug_mode) debug_printf("%s new start node (type: %i) selected %d\n",self->client->pers.netname, nodes[node].type, node); self->current_node = node; self->next_node = self->current_node; // make sure we get to the nearest node first self->node_timeout = 0; } /////////////////////////////////////////////////////////////////////// // Move closer to goal by pointing the bot to the next node // that is closer to the goal /////////////////////////////////////////////////////////////////////// qboolean ACEND_FollowPath(edict_t *self) { vec3_t v; ////////////////////////////////////////// // Show the path if(debug_mode) { show_path_from = self->current_node; show_path_to = self->goal_node; } ////////////////////////////////////////// // Try again? if(self->node_timeout ++ > 30) { if(self->tries++ > 3) return false; else ACEND_SetGoal(self,self->goal_node); } // Are we there yet? VectorSubtract(self->s.origin,nodes[self->next_node].origin,v); if(VectorLength(v) < 32) { // reset timeout self->node_timeout = 0; if(self->next_node == self->goal_node) { if(debug_mode) debug_printf("%s reached goal!\n",self->client->pers.netname); ACEAI_PickLongRangeGoal(self); // Pick a new goal } else { self->current_node = self->next_node; self->next_node = path_table[self->current_node][self->goal_node]; } } if(self->current_node == -1 || self->next_node ==-1) return false; // Set bot's movement vector VectorSubtract (nodes[self->next_node].origin, self->s.origin , self->move_vector); return true; } /////////////////////////////////////////////////////////////////////// // Init node array (set all to INVALID) /////////////////////////////////////////////////////////////////////// void ACEND_InitNodes(void) { bot_numnodes = 1; numitemnodes = 1; memset(nodes,0,sizeof(node_t) * MAX_NODES); memset(path_table,INVALID,sizeof(short int)*MAX_NODES*MAX_NODES); memset(node_showents,0,sizeof(edict_t *)*MAX_NODES); } /////////////////////////////////////////////////////////////////////// // Show the node for debugging (utility function) // Previously there was a warning comment here about overflows, however it // seems to be just fine on a private server. /////////////////////////////////////////////////////////////////////// void ACEND_ShowNode(int node) { edict_t *ent; if (node_showents[node]) { safe_bprintf(PRINT_MEDIUM, "node %d already being shown\n", node); return; } ent = G_Spawn(); ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_NOT; if(nodes[node].type == NODE_MOVE) ent->s.renderfx = RF_SHELL_BLUE; else if (nodes[node].type == NODE_WATER) ent->s.renderfx = RF_SHELL_RED; else ent->s.renderfx = RF_SHELL_GREEN; // action nodes ent->s.modelindex = gi.modelindex ("models/items/ammo/grenades/medium/tris.md2"); ent->owner = ent; ent->nextthink = level.time + 200000.0; ent->think = G_FreeEdict; ent->dmg = 0; VectorCopy(nodes[node].origin,ent->s.origin); gi.linkentity (ent); node_showents[node] = ent; } /////////////////////////////////////////////////////////////////////// // Draws the current path (utility function) /////////////////////////////////////////////////////////////////////// void ACEND_DrawPath() { int current_node, goal_node, next_node; if (!debug_mode) return; current_node = show_path_from; goal_node = show_path_to; next_node = path_table[current_node][goal_node]; // Now set up and display the path while(current_node != goal_node && current_node != -1) { gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_REDLASER); gi.WritePosition (nodes[current_node].origin); gi.WritePosition (nodes[next_node].origin); gi.multicast (nodes[current_node].origin, MULTICAST_PVS); current_node = next_node; next_node = path_table[current_node][goal_node]; } } /////////////////////////////////////////////////////////////////////// // Turns on showing of the path, set goal to -1 to // shut off. (utility function) /////////////////////////////////////////////////////////////////////// void ACEND_ShowPath(edict_t *self, int goal_node) { show_path_from = ACEND_FindClosestReachableNode(self, NODE_DENSITY, NODE_ALL); show_path_to = goal_node; } /////////////////////////////////////////////////////////////////////// // Add a node of type ? /////////////////////////////////////////////////////////////////////// int ACEND_AddNode(edict_t *self, int type) { vec3_t v1,v2; // Block if we exceed maximum if (bot_numnodes + 1 > MAX_NODES) return false; // Set location VectorCopy(self->s.origin,nodes[bot_numnodes].origin); // Set type nodes[bot_numnodes].type = type; ///////////////////////////////////////////////////// // ITEMS // Move the z location up just a bit. if(type == NODE_ITEM) { nodes[bot_numnodes].origin[2] += 16; numitemnodes++; } // Teleporters if(type == NODE_TELEPORTER) { // Up 32 nodes[bot_numnodes].origin[2] += 32; } if(type == NODE_LADDER) { nodes[bot_numnodes].type = NODE_LADDER; if(debug_mode) { debug_printf("Node added %d type: Ladder\n",bot_numnodes); ACEND_ShowNode(bot_numnodes); } bot_numnodes++; return bot_numnodes-1; // return the node added } // For platforms drop two nodes one at top, one at bottom if(type == NODE_PLATFORM) { VectorCopy(self->maxs,v1); VectorCopy(self->mins,v2); // To get the center nodes[bot_numnodes].origin[0] = (v1[0] - v2[0]) / 2 + v2[0]; nodes[bot_numnodes].origin[1] = (v1[1] - v2[1]) / 2 + v2[1]; nodes[bot_numnodes].origin[2] = self->maxs[2]; if(debug_mode) ACEND_ShowNode(bot_numnodes); bot_numnodes++; nodes[bot_numnodes].origin[0] = nodes[bot_numnodes-1].origin[0]; nodes[bot_numnodes].origin[1] = nodes[bot_numnodes-1].origin[1]; nodes[bot_numnodes].origin[2] = self->mins[2]+64; nodes[bot_numnodes].type = NODE_PLATFORM; // Add a link ACEND_UpdateNodeEdge(bot_numnodes,bot_numnodes-1); if(debug_mode) { debug_printf("Node added %d type: Platform\n",bot_numnodes); ACEND_ShowNode(bot_numnodes); } bot_numnodes++; return bot_numnodes -1; } if(debug_mode) { if(nodes[bot_numnodes].type == NODE_MOVE) debug_printf("Node added %d type: Move\n",bot_numnodes); else if(nodes[bot_numnodes].type == NODE_TELEPORTER) debug_printf("Node added %d type: Teleporter\n",bot_numnodes); else if(nodes[bot_numnodes].type == NODE_ITEM) debug_printf("Node added %d type: Item\n",bot_numnodes); else if(nodes[bot_numnodes].type == NODE_WATER) debug_printf("Node added %d type: Water\n",bot_numnodes); else if(nodes[bot_numnodes].type == NODE_GRAPPLE) debug_printf("Node added %d type: Grapple\n",bot_numnodes); else if(nodes[bot_numnodes].type == NODE_REDBASE) debug_printf("Node added %d type: Red Base\n",bot_numnodes); else if(nodes[bot_numnodes].type == NODE_BLUEBASE) debug_printf("Node added %d type: Blue Base\n",bot_numnodes); else if(nodes[bot_numnodes].type == NODE_DEFEND) debug_printf("Node added %d type: Defend Base\n",bot_numnodes); ACEND_ShowNode(bot_numnodes); } bot_numnodes++; return bot_numnodes-1; // return the node added } /////////////////////////////////////////////////////////////////////// // Add/Update node connections (paths) /////////////////////////////////////////////////////////////////////// void ACEND_UpdateNodeEdge(int from, int to) { int i; if(from == -1 || to == -1 || from == to) return; // safety // Add the link path_table[from][to] = to; // Now for the self-referencing part, linear time for each link added for(i=0;i %d\n", from, to); } /////////////////////////////////////////////////////////////////////// // Remove a node edge /////////////////////////////////////////////////////////////////////// void ACEND_RemoveNodeEdge(edict_t *self, int from, int to) { int i; if(debug_mode) debug_printf("%s: Removing Edge %d -> %d\n", self->client->pers.netname, from, to); path_table[from][to] = INVALID; // set to invalid // Make sure this gets updated in our path array for(i=0;iinuse || !self->is_bot ) { gi.dprintf("ACEAI_Think: bad call program error\n"); return; } // Set up client movement VectorCopy(self->client->ps.viewangles,self->s.angles); VectorSet (self->client->ps.pmove.delta_angles, 0, 0, 0); memset (&ucmd, 0, sizeof (ucmd)); self->enemy = NULL; self->movetarget = NULL; // Force respawn if (self->deadflag) { self->client->buttons = 0; ucmd.buttons = BUTTON_ATTACK; /* * do nothing else until respawned. */ ClientThink (self, &ucmd); self->nextthink = level.time + FRAMETIME; return; } if(self->state == STATE_WANDER && self->wander_timeout < level.time) ACEAI_PickLongRangeGoal(self); // pick a new long range goal // Kill the bot if completely stuck somewhere if(VectorLength(self->velocity) > 37) self->suicide_timeout = level.time + 10.0; if(self->suicide_timeout < level.time && self->takedamage == DAMAGE_AIM && !level.intermissiontime) { self->health = 0; player_die (self, self, self, 100000, vec3_origin); // bot suicide, branch around irrelevant stuff. goto clientthink; } //reset the state from pauses for taunting if(self->suicide_timeout < level.time + 8) self->state = STATE_WANDER; //times up on spawn protection if(level.time > self->client->spawnprotecttime + g_spawnprotect->integer) self->client->spawnprotected = false; // Find any short range goal - but not if in air(ie, jumping a jumppad) if (self->groundentity) ACEAI_PickShortRangeGoal(self); // Look for enemies if ( ACEAI_FindEnemy( self ) ) { ACEAI_ChooseWeapon( self ); ACEMV_Attack( self, &ucmd ); } else { // Execute the move, or wander ACEAI_ChooseWeapon( self ); // for deselecting violator if ( self->state == STATE_WANDER ) { ACEMV_Wander( self, &ucmd ); } else if ( self->state == STATE_MOVE ) { ACEMV_Move( self, &ucmd ); } } clientthink: // debug_printf("State: %d\n",self->state); ucmd.msec = 100; // bots "client loop" runs at server frame rate self->client->ping = 0; //show in scoreboard ping of 0 // set bot's view angle ucmd.angles[PITCH] = ANGLE2SHORT( self->s.angles[PITCH] ); ucmd.angles[YAW] = ANGLE2SHORT( self->s.angles[YAW] ); ucmd.angles[ROLL] = ANGLE2SHORT( self->s.angles[ROLL] ); // send command through id's code ClientThink (self, &ucmd); self->nextthink = level.time + FRAMETIME; } /////////////////////////////////////////////////////////////////////// // Evaluate the best long range goal and send the bot on // its way. This is a good time waster, so use it sparingly. // Do not call it for every think cycle. /////////////////////////////////////////////////////////////////////// void ACEAI_PickLongRangeGoal(edict_t *self) { int i; int node; float weight,best_weight=0.0; int current_node,goal_node=0; edict_t *goal_ent=NULL, *ent; float cost; gitem_t *flag1_item, *flag2_item; qboolean hasFlag = false; // look for a target flag1_item = FindItemByClassname("item_flag_red"); flag2_item = FindItemByClassname("item_flag_blue"); //if flag in possession, try to find base nodes if(ctf->value) { if (self->client->pers.inventory[ITEM_INDEX(flag1_item)]) { current_node = ACEND_FindClosestReachableNode(self,NODE_DENSITY,NODE_BLUEBASE); if(current_node == -1) current_node = ACEND_FindClosestReachableNode(self,NODE_DENSITY,NODE_ALL); else hasFlag = true; } else if (self->client->pers.inventory[ITEM_INDEX(flag2_item)]) { current_node = ACEND_FindClosestReachableNode(self,NODE_DENSITY,NODE_REDBASE); if(current_node == -1) current_node = ACEND_FindClosestReachableNode(self,NODE_DENSITY,NODE_ALL); else hasFlag = true; } else current_node = ACEND_FindClosestReachableNode(self,NODE_DENSITY,NODE_ALL); } else if(g_tactical->value) //when a base's laser barriers shut off, go into a more direct attack route { if (self->ctype == 1 && (!tacticalScore.alienComputer || !tacticalScore.alienPowerSource)) { current_node = ACEND_FindClosestReachableNode(self,NODE_DENSITY,NODE_BLUEBASE); if(current_node == -1) current_node = ACEND_FindClosestReachableNode(self,NODE_DENSITY,NODE_ALL); else hasFlag = true; //we can use this from CTF - bots will ignore most anything and attack base components } else if (self->ctype == 0 && (!tacticalScore.humanComputer || !tacticalScore.humanPowerSource)) { current_node = ACEND_FindClosestReachableNode(self,NODE_DENSITY,NODE_REDBASE); if(current_node == -1) current_node = ACEND_FindClosestReachableNode(self,NODE_DENSITY,NODE_ALL); else hasFlag = true; } else current_node = ACEND_FindClosestReachableNode(self,NODE_DENSITY,NODE_ALL); } else current_node = ACEND_FindClosestReachableNode(self,NODE_DENSITY,NODE_ALL); self->current_node = current_node; if(current_node == -1) { self->state = STATE_WANDER; self->wander_timeout = level.time + 1.0; self->goal_node = -1; return; } if(!hasFlag) { /////////////////////////////////////////////////////// // Items /////////////////////////////////////////////////////// for(i=0;isolid == SOLID_NOT) // ignore items that are not there. continue; cost = ACEND_FindCost(current_node,item_table[i].node); if(cost == INVALID || cost < 2) // ignore invalid and very short hops continue; weight = ACEIT_ItemNeed(self, item_table[i].item); weight *= random(); // Allow random variations weight /= cost; // Check against cost of getting there if(weight > best_weight) { best_weight = weight; goal_node = item_table[i].node; goal_ent = item_table[i].ent; } } /////////////////////////////////////////////////////// // Players /////////////////////////////////////////////////////// // This should be its own function and is for now just // finds a player to set as the goal. for(i = 0; i < game.maxclients; i++) { ent = g_edicts + i + 1; if(ent == self || !ent->inuse || (ent->client->invis_framenum > level.framenum)) continue; node = ACEND_FindClosestReachableNode(ent,NODE_DENSITY,NODE_ALL); cost = ACEND_FindCost(current_node, node); if(cost == INVALID || cost < 3) // ignore invalid and very short hops continue; weight = 0.3; weight *= random(); // Allow random variations weight /= cost; // Check against cost of getting there //to do - check for flag, and if enemy has the flag, up the weight. if(weight > best_weight) { best_weight = weight; goal_node = node; goal_ent = ent; } } } else { qboolean hadCTFnode = false; //we need to get node at the end of the path //We can walk the node table and get the last linked node of this type further down the list than this node for(i = 0;i < bot_numnodes; i++) { if (self->client->pers.inventory[ITEM_INDEX(flag1_item)] || (g_tactical->value && self->ctype == 1)) { if(nodes[i].type == NODE_BLUEBASE) { goal_node = i; hadCTFnode = true; } } if (self->client->pers.inventory[ITEM_INDEX(flag2_item)] || (g_tactical->value && self->ctype == 0)) { if(nodes[i].type == NODE_REDBASE) { goal_node = i; hadCTFnode = true; } } } if(!hadCTFnode) { self->state = STATE_WANDER; self->wander_timeout = level.time + 1.0; self->goal_node = -1; return; } best_weight = 1.0; } // If do not find a goal, go wandering.... if(best_weight == 0.0 || goal_node == INVALID) { self->goal_node = INVALID; self->state = STATE_WANDER; self->wander_timeout = level.time + 1.0; if(debug_mode) debug_printf("%s did not find a LR goal, wandering.\n",self->client->pers.netname); return; // no path? } // OK, everything valid, let's start moving to our goal. self->state = STATE_MOVE; self->tries = 0; // Reset the count of how many times we tried this goal if(goal_ent != NULL && debug_mode) debug_printf("%s selected a %s at node %d (type: %i) for LR goal.\n",self->client->pers.netname, goal_ent->classname, goal_node, nodes[goal_node].type); else if(debug_mode) debug_printf("%s selected node %d (type: %i) for LR goal.\n",self->client->pers.netname, goal_node, nodes[goal_node].type); ACEND_SetGoal(self,goal_node); } /////////////////////////////////////////////////////////////////////// // Pick best goal based on importance and range. This function // overrides the long range goal selection for items that // are very close to the bot and are reachable. /////////////////////////////////////////////////////////////////////// //use this so that bots aren't trying to get to an enemy or item that is behind grating or glass. qboolean ACEIT_IsVisibleSolid(edict_t *self, edict_t *other) { trace_t tr; if(other->client) { if(other->client->invis_framenum > level.framenum) return false; } tr = gi.trace (self->s.origin, vec3_origin, vec3_origin, other->s.origin, self, MASK_SOLID); // Blocked, do not shoot if (tr.fraction != 1.0) return false; return true; } void ACEAI_PickShortRangeGoal(edict_t *self) { edict_t *target; float weight,best_weight=0.0; edict_t *best = NULL; int index; // look for a target (should make more efficent later) target = findradius(NULL, self->s.origin, 200); while(target) { if(target->classname == NULL) return; // Missle avoidance code // Set our movetarget to be the rocket or grenade fired at us. if(strcmp(target->classname,"rocket") == 0 || strcmp(target->classname,"grenade") == 0 || strcmp(target->classname,"seeker") == 0) { if(debug_mode) debug_printf("PROJECTILE ALERT!\n"); self->movetarget = target; return; } if (strcmp(target->classname, "player") == 0) //so players can't sneak RIGHT up on a bot { if(!target->deadflag && !self->in_deathball && !OnSameTeam(self, target) && !(target->client->invis_framenum > level.framenum)) { self->movetarget = target; } } if (ACEIT_IsReachable(self,target->s.origin)) { if (infront(self, target) && ACEIT_IsVisibleSolid(self, target)) { index = ACEIT_ClassnameToIndex(target->classname); weight = ACEIT_ItemNeed(self, index); if(weight > best_weight) { best_weight = weight; best = target; } } } // next target target = findradius(target, self->s.origin, 200); //was 200 } if(best_weight) { self->movetarget = best; if(debug_mode && self->goalentity != self->movetarget) debug_printf("%s selected a %s for SR goal.\n",self->client->pers.netname, self->movetarget->classname); self->goalentity = best; } } /////////////////////////////////////////////////////////////////////// // Scan for enemy /////////////////////////////////////////////////////////////////////// qboolean ACEAI_infront (edict_t *self, edict_t *other) { vec3_t vec; float dot; vec3_t forward; gitem_t *vehicle; vehicle = FindItemByClassname("item_bomber"); if (self->client->pers.inventory[ITEM_INDEX(vehicle)]) { return true; //do this so that they aren't getting lost and just flying off } vehicle = FindItemByClassname("item_strafer"); if (self->client->pers.inventory[ITEM_INDEX(vehicle)]) { return true; //do this so that they aren't getting lost and just flying off } AngleVectors (self->s.angles, forward, NULL, NULL); VectorSubtract (other->s.origin, self->s.origin, vec); VectorNormalize (vec); dot = DotProduct (vec, forward); if (dot > (1.0 - self->awareness)) return true; return false; } qboolean ACEAI_FindEnemy(edict_t *self) { int i; vec3_t dist; edict_t *bestenemy = NULL; float bestweight = 99999; float weight; gitem_t *flag1_item=NULL, *flag2_item=NULL; edict_t *target; edict_t *ent; if(ctf->value) { flag1_item = FindItemByClassname("item_flag_red"); flag2_item = FindItemByClassname("item_flag_blue"); } if(self->in_deathball && (self->health > 25)) { //cannot, or should not, fire at players when in a deathball //look for goal - if health is too low, drop the ball and fight back target = findradius(NULL, self->s.origin, 200); self->enemy = NULL; while(target) { if(target->classname == NULL) { self->enemy = NULL; return false; } if(self->dmteam == RED_TEAM && target->classname == "item_blue_dbtarget") self->enemy = target; else if(self->dmteam == BLUE_TEAM && target->classname == "item_red_dbtarget") self->enemy = target; else if(self->dmteam == NO_TEAM && target->classname == "item_dbtarget") self->enemy = target; target = findradius(target, self->s.origin, 200); } if(self->enemy) { //safe_bprintf(PRINT_MEDIUM, "Target Aquired!\n"); self->movetarget = self->enemy; self->goalentity= self->enemy; //face it, and fire return true; } else return false; } //only look for these if your team's spider is vulnerable if(tca->value && ((self->dmteam == RED_TEAM && red_team_score < 2) || (self->dmteam == BLUE_TEAM && blue_team_score < 2))) { target = findradius(NULL, self->s.origin, 300); self->enemy = NULL; while(target) { if(target->classname == NULL) { self->enemy = NULL; return false; } if(self->dmteam == RED_TEAM) { if(target->classname == "misc_bluespidernode") self->enemy = target; } else if(self->dmteam == BLUE_TEAM) { if(target->classname == "misc_redspidernode") self->enemy = target; } target = findradius(target, self->s.origin, 300); if(self->enemy) { //safe_bprintf(PRINT_MEDIUM, "Target Aquired!\n"); self->movetarget = self->enemy; self->goalentity= self->enemy; //face it, and fire return true; } else return false; } } if(g_tactical->value) { target = findradius(NULL, self->s.origin, 200); self->enemy = NULL; while(target) { if(target->classname == NULL) { self->enemy = NULL; return false; } if(self->ctype == 1) { if(target->classname == "hbomb") return false; //prevents them from accidently destorying a planted bomb else if(target->classname == "alien computer") self->enemy = target; else if(target->classname == "alien powersrc") self->enemy = target; else if(target->classname == "alien ammodepot") self->enemy = target; else if(target->classname == "alien backupgen") self->enemy = target; } else if(self->ctype == 0) { if(target->classname == "abomb") return false; else if(target->classname == "human computer") self->enemy = target; else if(target->classname == "human powersrc") self->enemy = target; else if(target->classname == "human ammodepot") self->enemy = target; else if(target->classname == "human backupgen") self->enemy = target; } target = findradius(target, self->s.origin, 200); if(self->enemy) { self->movetarget = self->enemy; self->goalentity= self->enemy; //face it, and fire return true; } } } if(self->oldenemy != NULL) //(was shot from behind) { if(!OnSameTeam(self, self->oldenemy)) { //to do - add code to ask for help if carrying the flag self->enemy = self->oldenemy; self->oldenemy = NULL; return true; } } for(i=0;iinuse || ent->solid == SOLID_NOT) continue; if(!ent->deadflag && ACEAI_infront(self, ent) && ACEIT_IsVisibleSolid(self, ent) && gi.inPVS (self->s.origin, ent->s.origin) && (!OnSameTeam(self, ent))) { VectorSubtract(self->s.origin, ent->s.origin, dist); weight = VectorLength( dist ); //add some more checks here, for health and armor, just slight, but enough to make them favor going for the weaker player // Check if best target, or better than current target if (weight < bestweight) { bestweight = weight; bestenemy = ent; } } } if(bestenemy) { self->enemy = bestenemy; //if using a blaster, and it's far away, don't fire, it's pointless if((self->client->pers.weapon == FindItem("Blaster") || self->client->pers.weapon == FindItem("Alien Blaster")) && (bestweight > 1500)) { self->enemy = NULL; return false; } //if carrying a flag, and not close to an enemy, continue running to goal if(ctf->value) { if (((self->client->pers.inventory[ITEM_INDEX(flag1_item)]) || (self->client->pers.inventory[ITEM_INDEX(flag2_item)])) && bestweight > 300) { self->enemy = NULL; return false; } } return true; } return false; } /////////////////////////////////////////////////////////////////////// // Hold fire with RL/BFG? /////////////////////////////////////////////////////////////////////// qboolean ACEAI_CheckShot(edict_t *self) { trace_t tr; assert( self->enemy != NULL ); tr = gi.trace (self->s.origin, tv(-8,-8,-8), tv(8,8,8), self->enemy->s.origin, self, MASK_SOLID); // Blocked, do not shoot - JKD 4/25/2013 - changed the threshold from 1.0 to 0.6 - this seemed to work much better and solved problems where bots // would not fire at items even though they had an obviously clear shot. if ( tr.fraction < 0.6f ) return false; return true; } void ACEAI_Use_Invisibility (edict_t *ent) { gitem_t *it; it = FindItem("Invisibility"); ent->client->pers.inventory[ITEM_INDEX(it)]--; ValidateSelectedItem (ent); it = FindItem("Sproing"); ent->client->pers.inventory[ITEM_INDEX(it)] = 0; it = FindItem("Haste"); ent->client->pers.inventory[ITEM_INDEX(it)] = 0; ent->client->resp.reward_pts = 0; ent->client->resp.powered = false; if (ent->client->invis_framenum > level.framenum) ent->client->invis_framenum += 300; else ent->client->invis_framenum = level.framenum + 300; gi.sound(ent, CHAN_ITEM, gi.soundindex("items/powerup.wav"), 1, ATTN_NORM, 0); } void ACEAI_Use_Haste (edict_t *ent) { gitem_t *it; it = FindItem("Haste"); ent->client->pers.inventory[ITEM_INDEX(it)]--; ValidateSelectedItem (ent); it = FindItem("Sproing"); ent->client->pers.inventory[ITEM_INDEX(it)] = 0; it = FindItem("Invisibility"); ent->client->pers.inventory[ITEM_INDEX(it)] = 0; ent->client->resp.reward_pts = 0; ent->client->resp.powered = false; if (ent->client->haste_framenum > level.framenum) ent->client->haste_framenum += 300; else ent->client->haste_framenum = level.framenum + 300; gi.sound(ent, CHAN_ITEM, gi.soundindex("items/powerup.wav"), 1, ATTN_NORM, 0); } void ACEAI_Use_Sproing (edict_t *ent) { gitem_t *it; it = FindItem("Sproing"); ent->client->pers.inventory[ITEM_INDEX(it)]--; ValidateSelectedItem (ent); it = FindItem("Haste"); ent->client->pers.inventory[ITEM_INDEX(it)] = 0; it = FindItem("Invisibility"); ent->client->pers.inventory[ITEM_INDEX(it)] = 0; ent->client->resp.reward_pts = 0; ent->client->resp.powered = false; if (ent->client->sproing_framenum > level.framenum) ent->client->sproing_framenum += 300; else ent->client->sproing_framenum = level.framenum + 300; gi.sound(ent, CHAN_ITEM, gi.soundindex("items/powerup.wav"), 1, ATTN_NORM, 0); } /////////////////////////////////////////////////////////////////////// // Choose the best weapon for bot /////////////////////////////////////////////////////////////////////// /* 1 : 1.0 //blaster accuracy 2 : 1.0 //alien disruptor accuracy 3 : 1.0 //pulse rifle accuracy 4 : 1.0 //flame thrower accuracy 5 : 1.0 //homing rocket launcher accuracy 6 : 1.0 //rocket launcher accuracy 7 : 1.0 //alien smartgun accuracy 8 : 1.0 //alien beamgun accuracy 9 : 1.0 //alien vaporizer accuracy */ #define ACCURACY_BLASTER 1 #define ACCURACY_DISRUPTOR 2 #define ACCURACY_CHAINGUN 3 #define ACCURACY_FLAMETHROWER 4 #define ACCURACY_NOTUSED 5 #define ACCURACY_ROCKETLAUNCHER 6 #define ACCURACY_SMARTGUN 7 #define ACCURACY_BEAMGUN 8 #define ACCURACY_VAPORIZER 9 void ACEAI_ChooseWeapon(edict_t *self) { float range; vec3_t v; float c; qboolean selected; qboolean clear_shot; if (self->in_vehicle || self->in_deathball) { return; } if(self->client->resp.powered) { //got enough reward points, use something c = random(); if( c < 0.5) ACEAI_Use_Invisibility(self); else if (c < 0.7) ACEAI_Use_Haste(self); else ACEAI_Use_Sproing(self); } // calculate distance to enemy target for range-based weapon selection clear_shot = true; if ( self->enemy != NULL ) { VectorSubtract( self->s.origin, self->enemy->s.origin, v ); range = VectorLength( v ); clear_shot = ACEAI_CheckShot( self ); } else if ( self->client->pers.weapon->weapmodel == WEAP_VIOLATOR ) { // put away the violator, and select something else // using a fake range. range = 500.0F; } else { // otherwise, keep current weapon when there is no target. return; } //mutators /* * Unconditionally choose for insta and rockets. */ if ( instagib->integer ) { // TODO: consider whether this prevents using violator // and whether or not that is a good thing. if ( self->client->pers.weapon->weapmodel != WEAP_DISRUPTOR ) { self->client->newweapon = FindItem( "Alien Disruptor" ); assert( self->client->newweapon != NULL ); ChangeWeapon( self ); } self->accuracy = self->weapacc[ACCURACY_DISRUPTOR]; return; } if ( rocket_arena->integer ) { if ( self->client->pers.weapon->weapmodel != WEAP_ROCKETLAUNCHER ) { self->client->newweapon = FindItem( "Rocket Launcher" ); assert( self->client->newweapon != NULL ); ChangeWeapon( self ); } self->accuracy = self->weapacc[ACCURACY_ROCKETLAUNCHER]; return; } // insta/rockets hybrid if ( insta_rockets->integer ) { if ( self->skill > 0 && range < 170.0F ) // Little closer than usual (normally 200) { if ( self->client->pers.weapon->weapmodel != WEAP_VIOLATOR ) { self->client->newweapon = FindItem( "Violator" ); assert( self->client->newweapon != NULL ); ChangeWeapon( self ); } self->accuracy = 1.0; return; } if ( clear_shot && range > 169.0F && range < 450.0F ) // Medium Range, use Rockets { if ( self->client->pers.weapon->weapmodel != WEAP_ROCKETLAUNCHER ) { self->client->newweapon = FindItem( "Rocket Launcher" ); assert( self->client->newweapon != NULL ); ChangeWeapon( self ); } self->accuracy = self->weapacc[ACCURACY_ROCKETLAUNCHER]; return; } // Long range (or possibly short range for skill 0 bots) if ( self->client->pers.weapon->weapmodel != WEAP_DISRUPTOR ) { self->client->newweapon = FindItem( "Alien Disruptor" ); assert( self->client->newweapon != NULL ); ChangeWeapon( self ); } self->accuracy = self->weapacc[ACCURACY_DISRUPTOR]; return; } //drop bombs if they have one, and the target is something that we want to plant a bomb near if(g_tactical->integer) { if(self->has_bomb && self->ctype == 0 && (self->enemy->classname == "human computer" || self->enemy->classname == "human powersrc" || self->enemy->classname == "human ammodepot")) { if(range < 300.0f) { if(ACEIT_ChangeWeapon( self, FindItem( "Alien Bomb" ))) return; } } else if(self->has_bomb && self->ctype == 1 && (self->enemy->classname == "alien computer" || self->enemy->classname == "alien powersrc" || self->enemy->classname == "alien ammodepot")) { if(range < 300.0f) { if(ACEIT_ChangeWeapon( self, FindItem( "Human Bomb" ))) return; } } } // what is the bot's favorite weapon? // The bot will always check for it's favorite weapon first, // which is set in the bot's config file, // unless it has a minderaser if ( clear_shot ) { if ( ACEIT_ChangeWeapon( self, FindItem( "Minderaser" ) ) ) { //keep same accurace as if firing a rocket self->accuracy = self->weapacc[ACCURACY_ROCKETLAUNCHER]; return; } } if ( !strcmp( self->faveweap, "Alien Vaporizer" ) && self->skill > 1 ) { if ( ACEIT_ChangeWeapon( self, FindItem( self->faveweap ) ) ) { self->accuracy = self->weapacc[ACCURACY_VAPORIZER]; return; } } if ( !strcmp( self->faveweap, "Alien Disruptor" ) ) { if ( ACEIT_ChangeWeapon( self, FindItem( self->faveweap ) ) ) { self->accuracy = self->weapacc[ACCURACY_DISRUPTOR]; return; } } if ( !strcmp( self->faveweap, "Disruptor" ) ) { if ( ACEIT_ChangeWeapon( self, FindItem( self->faveweap ) ) ) { self->accuracy = self->weapacc[ACCURACY_BEAMGUN]; return; } } if ( !strcmp( self->faveweap, "Pulse Rifle" ) ) { if ( ACEIT_ChangeWeapon( self, FindItem( self->faveweap ) ) ) { self->accuracy = self->weapacc[ACCURACY_CHAINGUN]; return; } } if ( !strcmp( self->faveweap, "Alien Smartgun" ) ) { if ( clear_shot && ACEIT_ChangeWeapon( self, FindItem( "Alien Smartgun" ))) { self->accuracy = self->weapacc[ACCURACY_SMARTGUN]; return; } } if ( !strcmp( self->faveweap, "Rocket Launcher" ) ) { if ( range > 200.0f ) { if ( clear_shot && ACEIT_ChangeWeapon( self, FindItem( "Rocket Launcher" ))) { self->accuracy = self->weapacc[ACCURACY_ROCKETLAUNCHER]; return; } } } if ( !strcmp( self->faveweap, "Flame Thrower" ) ) { if ( range < 500.0f || (range < 800.0f && self->skill == 3) ) { if ( ACEIT_ChangeWeapon( self, FindItem( "Flame Thrower" ) ) ) { self->accuracy = self->weapacc[ACCURACY_FLAMETHROWER]; return; } } } if ( !strcmp( self->faveweap, "Violator" ) && self->skill > 0 ) { if ( range < 300.0f ) { //because it's a fav weap, we want them to really try and use it if ( ACEIT_ChangeWeapon( self, FindItem( "Violator" ) ) ) { self->accuracy = 1.0; return; } } } // now go through normal weapon favoring routine // always favor the Vaporizor, unless close, then use the violator #ifndef TACTICAL if ( range < 200.0f && self->skill > 0 ) { selected = ACEIT_ChangeWeapon( self, FindItem( "Violator" )); assert( selected ); self->accuracy = 1.0f; return; } #endif if ( self->skill > 1 ) { if ( ACEIT_ChangeWeapon( self, FindItem( "Alien Vaporizer" ))) { self->accuracy = self->weapacc[ACCURACY_VAPORIZER]; return; } } if ( clear_shot && ACEIT_ChangeWeapon( self, FindItem( "Alien Smartgun" ))) { self->accuracy = self->weapacc[ACCURACY_SMARTGUN]; return; } // Longer range so the bot doesn't blow himself up! if ( clear_shot && range > 200.0f ) { if ( ACEIT_ChangeWeapon( self, FindItem( "Rocket Launcher" ))) { self->accuracy = self->weapacc[ACCURACY_ROCKETLAUNCHER]; return; } } // Only use FT in certain ranges if ( range < 500.0f || (range < 800.0f && self->skill == 3) ) { if ( ACEIT_ChangeWeapon( self, FindItem( "Flame Thrower" ) )) { self->accuracy = self->weapacc[ACCURACY_FLAMETHROWER]; return; } } if ( ACEIT_ChangeWeapon( self, FindItem( "Disruptor" ) )) { self->accuracy = self->weapacc[ACCURACY_BEAMGUN]; return; } if ( ACEIT_ChangeWeapon( self, FindItem( "Pulse Rifle" ) )) { self->accuracy = self->weapacc[ACCURACY_CHAINGUN]; return; } if ( ACEIT_ChangeWeapon( self, FindItem( "Alien Disruptor" ) )) { self->accuracy = self->weapacc[ACCURACY_DISRUPTOR]; return; } if(g_tactical->integer && self->ctype == 0) selected = ACEIT_ChangeWeapon( self, FindItem( "Alien Blaster" ) ); else selected = ACEIT_ChangeWeapon( self, FindItem( "Blaster" ) ); assert( selected ); self->accuracy = self->weapacc[ACCURACY_BLASTER]; } alien-arena-7.66+dfsg/source/game/acesrc/acebot_movement.c0000600000175000017500000010136312161402010022572 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. Copyright (C) 1998 Steve Yeager Copyright (C) 2010 COR Entertainment, LLC. See below for Steve Yeager's original copyright notice. Modified to GPL in 2002. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /////////////////////////////////////////////////////////////////////// // // ACE - Quake II Bot Base Code // // Version 1.0 // // This file is Copyright(c), Steve Yeager 1998, All Rights Reserved // // // All other files are Copyright(c) Id Software, Inc. // // Please see liscense.txt in the source directory for the copyright // information regarding those files belonging to Id Software, Inc. // // Should you decide to release a modified version of ACE, you MUST // include the following text (minus the BEGIN and END lines) in the // documentation for your modification. // // --- BEGIN --- // // The ACE Bot is a product of Steve Yeager, and is available from // the ACE Bot homepage, at http://www.axionfx.com/ace. // // This program is a modification of the ACE Bot, and is therefore // in NO WAY supported by Steve Yeager. // This program MUST NOT be sold in ANY form. If you have paid for // this product, you should contact Steve Yeager immediately, via // the ACE Bot homepage. // // --- END --- // // I, Steve Yeager, hold no responsibility for any harm caused by the // use of this source code, especially to small children and animals. // It is provided as-is with no implied warranty or support. // // I also wish to thank and acknowledge the great work of others // that has helped me to develop this code. // // John Cricket - For ideas and swapping code. // Ryan Feltrin - For ideas and swapping code. // SABIN - For showing how to do true client based movement. // BotEpidemic - For keeping us up to date. // Telefragged.com - For giving ACE a home. // Microsoft - For giving us such a wonderful crash free OS. // id - Need I say more. // // And to all the other testers, pathers, and players and people // who I can't remember who the heck they were, but helped out. // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // acebot_movement.c - This file contains all of the // movement routines for the ACE bot // /////////////////////////////////////////////////////////////////////// #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "game/g_local.h" #include "acebot.h" /////////////////////////////////////////////////////////////////////// // Checks if bot can move (really just checking the ground) // Also, this is not a real accurate check, but does a // pretty good job and looks for lava/slime. /////////////////////////////////////////////////////////////////////// qboolean ACEMV_CanMove(edict_t *self, int direction) { vec3_t forward, right; vec3_t offset,start,end; vec3_t angles; trace_t tr; gitem_t *vehicle; vehicle = FindItemByClassname("item_bomber"); if (self->client->pers.inventory[ITEM_INDEX(vehicle)]) { return true; // yup, can move, we are in an air vehicle } vehicle = FindItemByClassname("item_strafer"); if (self->client->pers.inventory[ITEM_INDEX(vehicle)]) { return true; // yup, can move, we are in an air vehicle } // Now check to see if move will move us off an edge VectorCopy(self->s.angles,angles); if(direction == MOVE_LEFT) angles[1] += 90; else if(direction == MOVE_RIGHT) angles[1] -= 90; else if(direction == MOVE_BACK) angles[1] -=180; // Set up the vectors AngleVectors (angles, forward, right, NULL); VectorSet(offset, 36, 0, 24); G_ProjectSource (self->s.origin, offset, forward, right, start); VectorSet(offset, 36, 0, -400); G_ProjectSource (self->s.origin, offset, forward, right, end); tr = gi.trace(start, NULL, NULL, end, self, (CONTENTS_SOLID|CONTENTS_SLIME|CONTENTS_MIST|CONTENTS_LAVA|CONTENTS_WINDOW)); if(tr.fraction > 0.3 || (tr.contents & (CONTENTS_LAVA|CONTENTS_SLIME|CONTENTS_MIST)) ) { if(debug_mode) debug_printf("%s: move blocked\n",self->client->pers.netname); if(self->groundentity) self->s.angles[YAW] += random() * 180 - 90; //blocked, so try something else return false; } return true; // yup, can move } /////////////////////////////////////////////////////////////////////// // Handle special cases of crouch/jump // // If the move is resolved here, this function returns // true. /////////////////////////////////////////////////////////////////////// qboolean ACEMV_SpecialMove(edict_t *self, usercmd_t *ucmd) { vec3_t dir,forward,right,start,end,offset; vec3_t top; trace_t tr; short mSpeed; if(g_tactical->integer) mSpeed = 200; else mSpeed = 400; // Get current direction VectorCopy(self->client->ps.viewangles,dir); dir[YAW] = self->s.angles[YAW]; AngleVectors (dir, forward, right, NULL); VectorSet(offset, 18, 0, 0); G_ProjectSource (self->s.origin, offset, forward, right, start); offset[0] += 18; G_ProjectSource (self->s.origin, offset, forward, right, end); // trace it start[2] += 18; // so they are not jumping all the time end[2] += 18; tr = gi.trace (start, self->mins, self->maxs, end, self, MASK_MONSTERSOLID); if(tr.allsolid) { // Check for crouching start[2] -= 14; end[2] -= 14; // Set up for crouching check VectorCopy(self->maxs,top); top[2] = 0.0; // crouching height tr = gi.trace (start, self->mins, top, end, self, MASK_PLAYERSOLID); // Crouch if(!tr.allsolid) { if(ACEMV_CanMove(self, MOVE_FORWARD)) ucmd->forwardmove = mSpeed; else if(ACEMV_CanMove(self, MOVE_BACK)) ucmd->forwardmove = -mSpeed; ucmd->upmove = -400; return true; } // Check for jump start[2] += 32; end[2] += 32; tr = gi.trace (start, self->mins, self->maxs, end, self, MASK_MONSTERSOLID); if(!tr.allsolid) { if(ACEMV_CanMove(self, MOVE_FORWARD)) ucmd->forwardmove = mSpeed; else if(ACEMV_CanMove(self, MOVE_BACK)) ucmd->forwardmove = -mSpeed; ucmd->upmove = 400; return true; } } return false; // We did not resolve a move here } /////////////////////////////////////////////////////////////////////// // Checks for obstructions in front of bot // // This is a function I created origianlly for ACE that // tries to help steer the bot around obstructions. // // If the move is resolved here, this function returns true. /////////////////////////////////////////////////////////////////////// qboolean ACEMV_CheckEyes(edict_t *self, usercmd_t *ucmd) { vec3_t forward, right; vec3_t leftstart, rightstart,focalpoint; vec3_t upstart,upend; vec3_t dir,offset; short mSpeed; trace_t traceRight,traceLeft,traceUp, traceFront; // for eyesight if(g_tactical->integer) mSpeed = 200; else mSpeed = 400; // Get current angle and set up "eyes" /* make sure bot's "eyes" are straight ahead * something is going wrong after rocket jump, and "eyes" are always down * and bot runs in circle. */ self->s.angles[PITCH] = 0.0f; VectorCopy(self->s.angles,dir); AngleVectors (dir, forward, right, NULL); // Let them move to targets by walls if(!self->movetarget) VectorSet(offset,200,0,4); // focalpoint else VectorSet(offset,36,0,4); // focalpoint G_ProjectSource (self->s.origin, offset, forward, right, focalpoint); // Check from self to focalpoint // Ladder code VectorSet(offset,36,0,0); // set as high as possible G_ProjectSource (self->s.origin, offset, forward, right, upend); traceFront = gi.trace(self->s.origin, self->mins, self->maxs, upend, self, BOTMASK_OPAQUE); if ( traceFront.contents & CONTENTS_LADDER ) { ucmd->upmove = 400; if(ACEMV_CanMove(self, MOVE_FORWARD)) ucmd->forwardmove = mSpeed; return true; } // If this check fails we need to continue on with more detailed checks if ( traceFront.fraction >= 1.0f ) { if ( ACEMV_CanMove( self, MOVE_FORWARD ) ) ucmd->forwardmove = mSpeed; //only try forward, bot should be looking to move in direction of eyes return true; } VectorSet(offset, 0, 18, 4); G_ProjectSource (self->s.origin, offset, forward, right, leftstart); offset[1] -= 36; // want to make sure this is correct //VectorSet(offset, 0, -18, 4); G_ProjectSource (self->s.origin, offset, forward, right, rightstart); traceRight = gi.trace(rightstart, NULL, NULL, focalpoint, self, BOTMASK_OPAQUE); traceLeft = gi.trace(leftstart, NULL, NULL, focalpoint, self, BOTMASK_OPAQUE); // Wall checking code, this will degenerate progressivly so the least cost // check will be done first. // If open space move ok if(traceRight.fraction != 1 || traceLeft.fraction != 1 || strcmp(traceLeft.ent->classname,"func_door")!=0) { // Special uppoint logic to check for slopes/stairs/jumping etc. VectorSet(offset, 0, 18, 24); G_ProjectSource (self->s.origin, offset, forward, right, upstart); VectorSet(offset,0,0,200); // scan for height above head G_ProjectSource (self->s.origin, offset, forward, right, upend); traceUp = gi.trace(upstart, NULL, NULL, upend, self, BOTMASK_OPAQUE); VectorSet(offset,200,0,200*traceUp.fraction-5); // set as high as possible G_ProjectSource (self->s.origin, offset, forward, right, upend); traceUp = gi.trace(upstart, NULL, NULL, upend, self, BOTMASK_OPAQUE); // If the upper trace is not open, we need to turn. if(traceUp.fraction < 1.0f ) { if(traceRight.fraction > traceLeft.fraction) self->s.angles[YAW] += (1.0 - traceLeft.fraction) * 45.0; else self->s.angles[YAW] += -(1.0 - traceRight.fraction) * 45.0; if(ACEMV_CanMove(self, MOVE_FORWARD)) ucmd->forwardmove = mSpeed; return true; } } return false; } /////////////////////////////////////////////////////////////////////// // Make the change in angles a little more gradual, not so snappy // Subtle, but noticeable. // // Modified from the original id ChangeYaw code... /////////////////////////////////////////////////////////////////////// void ACEMV_ChangeBotAngle (edict_t *ent) { float ideal_yaw; float ideal_pitch; float current_yaw; float current_pitch; float move; float speed; vec3_t ideal_angle; // Normalize the move angle first VectorNormalize(ent->move_vector); current_yaw = anglemod(ent->s.angles[YAW]); current_pitch = anglemod(ent->s.angles[PITCH]); vectoangles (ent->move_vector, ideal_angle); ideal_yaw = anglemod(ideal_angle[YAW]); ideal_pitch = anglemod(ideal_angle[PITCH]); // Yaw if (current_yaw != ideal_yaw) { move = ideal_yaw - current_yaw; speed = ent->yaw_speed; if (ideal_yaw > current_yaw) { if (move >= 180.0f) move = move - 360.0f; } else { if (move <= -180.0f) move = move + 360.0f; } if (move > 0.0f) { if (move > speed) move = speed; } else { if (move < -speed) move = -speed; } ent->s.angles[YAW] = anglemod (current_yaw + move); } // Pitch if (current_pitch != ideal_pitch) { move = ideal_pitch - current_pitch; speed = ent->yaw_speed; if (ideal_pitch > current_pitch) { if (move >= 180.0f) move = move - 360.0f; } else { if (move <= -180.0f) move = move + 360.0f; } if (move > 0.0f) { if (move > speed) move = speed; } else { if (move < -speed) move = -speed; } ent->s.angles[PITCH] = anglemod (current_pitch + move); } } /////////////////////////////////////////////////////////////////////// // Set bot to move to it's movetarget. (following node path) /////////////////////////////////////////////////////////////////////// void ACEMV_MoveToGoal(edict_t *self, usercmd_t *ucmd) { short mSpeed; if(g_tactical->integer) mSpeed = 200; else mSpeed = 400; // If a rocket or grenade is around deal with it // Simple, but effective (could be rewritten to be more accurate) if(strcmp(self->movetarget->classname,"rocket") == 0 || strcmp(self->movetarget->classname,"grenade") == 0 || strcmp(self->movetarget->classname,"seeker") == 0 ) { if(debug_mode) debug_printf("%s: Oh crap a rocket!\n",self->client->pers.netname); if(strcmp(self->movetarget->classname,"seeker") == 0) { VectorSubtract (self->s.origin, self->movetarget->s.origin, self->move_vector); ACEMV_ChangeBotAngle(self); //turn and run like hell away from it //to do - needs improvement - bot should run when getting hit by seeker as well if(ACEMV_CanMove(self, MOVE_FORWARD)) ucmd->forwardmove = mSpeed; } else { VectorSubtract (self->movetarget->s.origin, self->s.origin, self->move_vector); ACEMV_ChangeBotAngle(self); // strafe left/right if(rand()%1 && ACEMV_CanMove(self, MOVE_LEFT)) ucmd->sidemove = -mSpeed; else if(ACEMV_CanMove(self, MOVE_RIGHT)) ucmd->sidemove = mSpeed; } return; } else { // Set bot's movement direction VectorSubtract (self->movetarget->s.origin, self->s.origin, self->move_vector); ACEMV_ChangeBotAngle(self); //try moving forward, if blocked, strafe around it if possible. if(ACEMV_CanMove(self, MOVE_FORWARD)) ucmd->forwardmove = mSpeed; else if(ACEMV_CanMove(self, MOVE_BACK)) ucmd->forwardmove = -mSpeed; else if(ACEMV_CanMove(self, MOVE_RIGHT)) ucmd->sidemove = mSpeed; else if(ACEMV_CanMove(self, MOVE_LEFT)) ucmd->sidemove = -mSpeed; return; } } /////////////////////////////////////////////////////////////////////// // Main movement code. (following node path) /////////////////////////////////////////////////////////////////////// void ACEMV_Move(edict_t *self, usercmd_t *ucmd) { vec3_t dist; int current_node_type=-1; int next_node_type=-1; int i; float c; short mSpeed; if(g_tactical->integer) mSpeed = 200; else mSpeed = 400; // Get current and next node back from nav code. if(!ACEND_FollowPath(self)) { self->state = STATE_WANDER; self->wander_timeout = level.time + 1.0; return; } if(!self->groundentity) return; current_node_type = nodes[self->current_node].type; next_node_type = nodes[self->next_node].type; /////////////////////////// // Move To Goal /////////////////////////// if (self->movetarget) ACEMV_MoveToGoal(self,ucmd); //////////////////////////////////////////////////////// // Platforms /////////////////////////////////////////////////////// if(current_node_type != NODE_PLATFORM && next_node_type == NODE_PLATFORM) { // check to see if lift is down? for(i=0;inext_node) if(item_table[i].ent->moveinfo.state != STATE_BOTTOM) return; // Wait for elevator } if(current_node_type == NODE_PLATFORM && next_node_type == NODE_PLATFORM) { // Move to the center self->move_vector[2] = 0; // kill z movement if(VectorLength(self->move_vector) > 10) ucmd->forwardmove = 200; // walk to center ACEMV_ChangeBotAngle(self); return; // No move, riding elevator } //////////////////////////////////////////////////////// // Jumpto Nodes /////////////////////////////////////////////////////// if(next_node_type == NODE_JUMP || (current_node_type == NODE_JUMP && next_node_type != NODE_ITEM && nodes[self->next_node].origin[2] > self->s.origin[2])) { // Set up a jump move ucmd->forwardmove = mSpeed; ucmd->upmove = 400; ACEMV_ChangeBotAngle(self); VectorCopy(self->move_vector, dist); VectorScale(dist, 440, self->velocity); return; } //////////////////////////////////////////////////////// // Ladder Nodes /////////////////////////////////////////////////////// if(next_node_type == NODE_LADDER && nodes[self->next_node].origin[2] > self->s.origin[2]) { // Otherwise move as fast as we can ucmd->forwardmove = mSpeed; self->velocity[2] = 320; ACEMV_ChangeBotAngle(self); return; } // If getting off the ladder if(current_node_type == NODE_LADDER && next_node_type != NODE_LADDER && nodes[self->next_node].origin[2] > self->s.origin[2]) { ucmd->forwardmove = mSpeed; ucmd->upmove = 200; self->velocity[2] = 200; ACEMV_ChangeBotAngle(self); return; } //////////////////////////////////////////////////////// // Water Nodes /////////////////////////////////////////////////////// if(current_node_type == NODE_WATER) { // We need to be pointed up/down ACEMV_ChangeBotAngle(self); // If the next node is not in the water, then move up to get out. if(next_node_type != NODE_WATER && !(gi.pointcontents(nodes[self->next_node].origin) & MASK_WATER)) // Exit water ucmd->upmove = 400; ucmd->forwardmove = 300; return; } // Falling off ledge? if(!self->groundentity) { ACEMV_ChangeBotAngle(self); self->velocity[0] = self->move_vector[0] * 360; self->velocity[1] = self->move_vector[1] * 360; return; } // Check to see if stuck, and if so try to free us // Also handles crouching if(VectorLength(self->velocity) < 37) { // Keep a random factor just in case.... if(random() > 0.1 && ACEMV_SpecialMove(self, ucmd)) return; self->s.angles[YAW] += random() * 180 - 90; // Try moving foward, if not, try to strafe around obstacle if(ACEMV_CanMove(self, MOVE_FORWARD)) ucmd->forwardmove = mSpeed; else if(ACEMV_CanMove(self, MOVE_BACK)) ucmd->forwardmove = -mSpeed; else if(ACEMV_CanMove(self, MOVE_RIGHT)) ucmd->sidemove = mSpeed; else if(ACEMV_CanMove(self, MOVE_LEFT)) ucmd->sidemove = -mSpeed; return; } // Otherwise move as fast as we can if(ACEMV_CanMove(self, MOVE_FORWARD)) ucmd->forwardmove = mSpeed; if(self->skill == 3) { //ultra skill level(will be 3) c = random(); if(!self->in_deathball && grapple->value && c <= .7) { //use the grapple once in awhile to pull itself around if(self->client->ctf_grapplestate == CTF_GRAPPLE_STATE_HANG) { CTFPlayerResetGrapple(self); ACEMV_ChangeBotAngle(self); return; } ACEMV_ChangeBotAngle(self); ACEIT_ChangeWeapon(self,FindItem("grapple")); ucmd->buttons = BUTTON_ATTACK; ACEMV_ChangeBotAngle(self); return; } else if(self->client->ctf_grapplestate != CTF_GRAPPLE_STATE_PULL && self->client->ctf_grapplestate != CTF_GRAPPLE_STATE_HANG) { //don't interrupt a pull float weight; int strafeJump = false; //Strafejumping should only occur now if a bot is far enough from a node //and not wandering. We really don't want them to jump around when wandering //as it seems to hinder locating a goal. VectorSubtract(self->s.origin, nodes[self->current_node].origin, dist); weight = VectorLength( dist ); if(weight > 300) strafeJump = true; if(strafeJump) { if(c > .7) ucmd->upmove = 400; //jump around the level if(c > 0.9 && ACEMV_CanMove(self, MOVE_LEFT)) ucmd->sidemove = -200; //strafejump left(was -400) else if(c > 0.8 && ACEMV_CanMove(self, MOVE_RIGHT)) ucmd->sidemove = 200; //strafejump right(was 400) } } //Now if we have the Alien Smartgun, drop some prox mines :) if (self->client->pers.weapon == FindItem("alien smartgun") && c < 0.2) ucmd->buttons = BUTTON_ATTACK2; } ACEMV_ChangeBotAngle(self); } /////////////////////////////////////////////////////////////////////// // Wandering code (based on old ACE movement code) /////////////////////////////////////////////////////////////////////// void ACEMV_Wander(edict_t *self, usercmd_t *ucmd) { vec3_t temp; float c; short mSpeed; if(g_tactical->integer) mSpeed = 200; else mSpeed = 400; // Do not move if(self->next_move_time > level.time) return; // Special check for elevators, stand still until the ride comes to a complete stop. if(self->groundentity != NULL && self->groundentity->use == Use_Plat) if(self->groundentity->moveinfo.state == STATE_UP || self->groundentity->moveinfo.state == STATE_DOWN) // only move when platform not { self->velocity[0] = 0; self->velocity[1] = 0; self->velocity[2] = 0; self->next_move_time = level.time + 0.5; return; } // Is there a target to move to if (self->movetarget) ACEMV_MoveToGoal(self,ucmd); //////////////////////////////// // Swimming? //////////////////////////////// VectorCopy(self->s.origin,temp); temp[2]+=24; if(gi.pointcontents (temp) & MASK_WATER) { // If drowning and no node, move up if(self->client->next_drown_time > 0) { ucmd->upmove = 1; self->s.angles[PITCH] = -45; } else ucmd->upmove = 15; ucmd->forwardmove = 300; } else self->client->next_drown_time = 0; // probably shound not be messing with this, but //////////////////////////////// // Lava? //////////////////////////////// temp[2]-=48; if(gi.pointcontents(temp) & (CONTENTS_LAVA|CONTENTS_SLIME)) { // safe_bprintf(PRINT_MEDIUM,"lava jump\n"); self->s.angles[YAW] += random() * 360 - 180; ucmd->forwardmove = mSpeed; ucmd->upmove = 400; return; } if(ACEMV_CheckEyes(self,ucmd)) return; // Check for special movement if we have a normal move (have to test) if(VectorLength(self->velocity) < 37) { /*if(random() > 0.1 && ACEMV_SpecialMove(self,ucmd)) return;*/ //removed this because when wandering, the last thing you want is bots jumping //over things and going off ledges. It's better for them to just bounce around the map. self->s.angles[YAW] += random() * 180 - 90; // Try to move forward, if blocked, try to strafe around obstacle if(ACEMV_CanMove(self, MOVE_FORWARD)) ucmd->forwardmove = mSpeed; else if(ACEMV_CanMove(self, MOVE_BACK)) ucmd->forwardmove = -mSpeed; else if(ACEMV_CanMove(self, MOVE_RIGHT)) ucmd->sidemove = mSpeed; else if(ACEMV_CanMove(self, MOVE_LEFT)) ucmd->sidemove = -mSpeed; if(!M_CheckBottom(self) || !self->groundentity) // if there is ground continue, otherwise wait for next move. { if(ACEMV_CanMove(self, MOVE_FORWARD)) ucmd->forwardmove = mSpeed; } return; } if(ACEMV_CanMove(self, MOVE_FORWARD)) ucmd->forwardmove = mSpeed; if(self->skill == 3) { //ultra skill level(will be 3) c = random(); //If we have the Alien Smartgun, drop some prox mines :) if (self->client->pers.weapon == FindItem("alien smartgun") && c < 0.2) ucmd->buttons = BUTTON_ATTACK2; } } /** * @brief Apply some imprecision to an attacking bot's aim * * @detail Uses a randomly oriented X,Y vector with a random length * plus an offset, which leaves a hole in the center of the * target area. * * @param self entity for the bot * @param pdx x for targeted enemy's origin * @param pdy y for targeted enemy's origin * * @return *pdx and *pdy altered */ /* * constants for target fuzzification */ static const float ktgt_scale = 250.0f; //scaling factor static const float ktgt_ofs = 20.0f; //radius of hole /* scaling for weap skill for bot cfg skill 0, 1, 2 & 3 */ static const float ktgt_skill[4] = { 0.7f, 0.8f, 0.9f, 1.0f }; //accuracy scaling by skill //accuracy factor = ktgt_skill[0] * self->accuracy minimum clamp static const float ktgt_acc = 0.35; static void fuzzy_target( edict_t *self, float *pdx, float *pdy ) { float accuracy; float random_r; float radius; float angle; float ca,sa; float dx,dy; /* * self->accuracy is weapon specific accuracy from bot .cfg file */ accuracy = self->accuracy; if ( accuracy < 0.5f ) accuracy = 0.5f; else if ( accuracy > 1.0f ) accuracy = 1.0f; //calc weap accuracy factor with scaling on bot skill switch ( self->skill ) { case 0: accuracy *= ktgt_skill[0]; break; case 1: default: accuracy *= ktgt_skill[1]; break; case 2: accuracy *= ktgt_skill[2]; break; case 3: //override 3->2 for CTF accuracy *= (ctf->integer) ? ktgt_skill[2] : ktgt_skill[3]; break; } //radius calc random_r = ktgt_scale * crandom(); radius = (random_r * ( ktgt_acc / accuracy)) + ktgt_ofs; //angle calc angle = random() * 2.0f * M_PI; fast_sincosf( angle, &sa, &ca ); //apply delta to target *pdx += dx = ca * radius; *pdy += dy = sa * radius; // if ( debug_mode ) // { // gi.dprintf("{\t%0.2f\t%0.2f\tacc%0.1f\t%i}\n", // dx, dy, accuracy, self->skill ); // } } /////////////////////////////////////////////////////////////////////// // Attack movement routine /////////////////////////////////////////////////////////////////////// void ACEMV_Attack (edict_t *self, usercmd_t *ucmd) { float c, d; vec3_t target; vec3_t angles; vec3_t down; int strafespeed; float jump_thresh; float crouch_thresh; gitem_t *vehicle; float range = 0.0f; vec3_t v; qboolean use_fuzzy_aim; short mSpeed; if(g_tactical->integer) mSpeed = 200; else mSpeed = 400; ucmd->buttons = 0; use_fuzzy_aim = true; // unless overridden by special cases if ( dmflags->integer & DF_BOT_FUZZYAIM ) { // when bit is set it means fuzzy aim is disabled. for testing mostly. use_fuzzy_aim = false; } vehicle = FindItemByClassname("item_bomber"); if (self->client->pers.inventory[ITEM_INDEX(vehicle)]) { //if we are too low, don't shoot, and move up. Should be fairly simple, right? if(self->enemy->s.origin[2] >= self->s.origin[2] - 128) { //we want to be well above our target ucmd->upmove += 400; // face the enemy while moving up VectorCopy(self->enemy->s.origin,target); VectorSubtract (target, self->s.origin, self->move_vector); vectoangles (self->move_vector, angles); VectorCopy(angles,self->s.angles); return; } } switch ( self->skill ) { // set up the skill levels case 0: strafespeed = 300; jump_thresh = 1.0f; // never jump crouch_thresh = 0.0f; // never crouch break; case 1: default: strafespeed = 400; jump_thresh = 0.95f; crouch_thresh = 0.85f; // crouch much break; case 2: case 3: strafespeed = 800; if ( !joustmode->integer ) { jump_thresh = 0.8f; crouch_thresh = 0.7f; } else { jump_thresh = 0.5f; // want to jump a whole lot more in joust mode crouch_thresh = 0.4f; // and crouch less } break; } d = random(); // for skill 0 movement c = random(); // for strafing, jumping, crouching // violator attack if ( self->client->pers.weapon == FindItem( "Violator" ) ) { use_fuzzy_aim = false; // avoid potential odd melee attack behaviour if ( ACEMV_CanMove( self, MOVE_FORWARD ) ) ucmd->forwardmove += 400; //lunge at enemy goto attack; } //machinegun/blaster/beamgun strafing for level 2/3 bots if ( !joustmode->value && self->skill >= 2 && (self->client->pers.weapon == FindItem( "Blaster" ) || self->client->pers.weapon == FindItem( "Alien Blaster" ) || self->client->pers.weapon == FindItem( "Pulse Rifle" ) || self->client->pers.weapon == FindItem( "Disruptor" ))) { //strafe no matter what if ( c < 0.5f && ACEMV_CanMove( self, MOVE_LEFT ) ) { ucmd->sidemove -= mSpeed; } else if ( c < 1.0f && ACEMV_CanMove( self, MOVE_RIGHT ) ) { ucmd->sidemove += mSpeed; } else { //don't want high skill level bots just standing around goto standardmove; } //allow for some circle strafing if ( self->health < 50 && ACEMV_CanMove( self, MOVE_BACK ) ) { ucmd->forwardmove -= mSpeed; } else if ( c < 0.6f && ACEMV_CanMove( self, MOVE_FORWARD ) ) { //keep this at default, not make them TOO hard ucmd->forwardmove += mSpeed; } else if ( c < 0.8f && ACEMV_CanMove( self, MOVE_BACK ) ) { ucmd->forwardmove -= mSpeed; } goto attack; //skip any jumping or crouching } if ( self->skill == 0 && d < 0.9f ) goto attack; //skill 0 bots will barely move while firing standardmove: if ( c < 0.2f && ACEMV_CanMove( self, MOVE_LEFT ) ) { ucmd->sidemove -= strafespeed; //300 for low skill 800 for hardest(3 levels?) } else if ( c < 0.4f && ACEMV_CanMove( self, MOVE_RIGHT ) ) { ucmd->sidemove += strafespeed; } if ( self->health < 50 && ACEMV_CanMove( self, MOVE_BACK ) ) { //run away if wounded ucmd->forwardmove -= mSpeed; } else if ( c < 0.6f && ACEMV_CanMove( self, MOVE_FORWARD ) ) { //keep this at default, not make them TOO hard ucmd->forwardmove += mSpeed; } else if ( c < 0.8f && ACEMV_CanMove( self, MOVE_BACK ) ) { ucmd->forwardmove -= mSpeed; } c = random(); //really mix this up some if ( self->health >= 50 && c < crouch_thresh ) { ucmd->upmove -= 200; } else if ( c > jump_thresh ) { #ifndef ALTERIA c = random(); if ( self->health >= 70 && self->skill >= 2 && !self->in_vehicle && !self->in_deathball && ACEIT_ChangeWeapon( self, FindItem( "Rocket Launcher" ) ) && c < 0.6f ) { // Rocket Jump self->s.angles[PITCH] = 90.0f; AngleVectors( self->s.angles, down, NULL, NULL ); fire_rocket( self, self->s.origin, down, 200, 650, 120, 120 ); ucmd->upmove += 200; self->s.angles[PITCH] = 0.0f; if ( (!(dmflags->integer & DF_INFINITE_AMMO)) && !rocket_arena->integer && !insta_rockets->integer ) { self->client->pers.inventory[self->client->ammo_index]--; } return; } else #endif { // Normal Jump ucmd->upmove += 200; } } attack: // Set the attack if(ACEAI_CheckShot(self)) { //bot is taking a shot, lose spawn protection // and calculate distance to enemy range = 0.0f; if(self->enemy) { self->client->spawnprotected = false; VectorSubtract (self->s.origin, self->enemy->s.origin, v); range = VectorLength(v); if ( range < 32.0f ) { // point blank range, avoid potentially odd behaviour use_fuzzy_aim = false; } } if(self->skill >= 2) { //skill 2/3 bots can use alt-fires! // Base selection on distance. ucmd->buttons = BUTTON_ATTACK; if (self->client->pers.weapon == FindItem("Blaster") || self->client->pers.weapon == FindItem("Alien Blaster")) { if( range > 500) ucmd->buttons = BUTTON_ATTACK2; else ucmd->buttons = BUTTON_ATTACK; } if (self->client->pers.weapon == FindItem("Alien Disruptor")) { if(range > 1000) { ucmd->buttons = BUTTON_ATTACK2; use_fuzzy_aim = false; //make it more accurate, since he's sniping } else ucmd->buttons = BUTTON_ATTACK; } if (self->client->pers.weapon == FindItem("Flame Thrower")) { if(range < 500) ucmd->buttons = BUTTON_ATTACK; else ucmd->buttons = BUTTON_ATTACK2; } if (self->client->pers.weapon == FindItem("Pulse Rifle")) { if(range < 200) ucmd->buttons = BUTTON_ATTACK2; else ucmd->buttons = BUTTON_ATTACK; } if (self->client->pers.weapon == FindItem("Disruptor")) { if(range < 300) ucmd->buttons = BUTTON_ATTACK2; else ucmd->buttons = BUTTON_ATTACK; } if (self->client->pers.weapon == FindItem("Alien Vaporizer")) { if(range < 300) ucmd->buttons = BUTTON_ATTACK2; else ucmd->buttons = BUTTON_ATTACK; } if (self->client->pers.weapon == FindItem("Minderaser")) { if(range < 400) ucmd->buttons = BUTTON_ATTACK; else ucmd->buttons = BUTTON_ATTACK2; } //vehicle alt-fires if (self->client->pers.weapon == FindItem("bomber") || self->client->pers.weapon == FindItem("strafer")) { if(range > 500) ucmd->buttons = BUTTON_ATTACK2; else ucmd->buttons = BUTTON_ATTACK; } if (self->client->pers.weapon == FindItem("hover")) { if(range < 300) ucmd->buttons = BUTTON_ATTACK2; else ucmd->buttons = BUTTON_ATTACK; } } else { ucmd->buttons = BUTTON_ATTACK; } } else { // not taking a shot ucmd->buttons = 0; use_fuzzy_aim = false; } // Aim VectorCopy(self->enemy->s.origin,target); if ( use_fuzzy_aim ) { fuzzy_target( self, &target[0], &target[1] ); } // Set movement direction toward targeted enemy VectorSubtract (target, self->s.origin, self->move_vector); vectoangles (self->move_vector, angles); VectorCopy(angles,self->s.angles); } alien-arena-7.66+dfsg/source/game/acesrc/acebot_spawn.c0000600000175000017500000012556712161402010022104 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. Copyright (C) 1998 Steve Yeager Copyright (C) 2010 COR Entertainment, LLC. See below for Steve Yeager's original copyright notice. Modified to GPL in 2002. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /////////////////////////////////////////////////////////////////////// // // ACE - Quake II Bot Base Code // // Version 1.0 // // This file is Copyright(c), Steve Yeager 1998, All Rights Reserved // // // All other files are Copyright(c) Id Software, Inc. // // Please see liscense.txt in the source directory for the copyright // information regarding those files belonging to Id Software, Inc. // // Should you decide to release a modified version of ACE, you MUST // include the following text (minus the BEGIN and END lines) in the // documentation for your modification. // // --- BEGIN --- // // The ACE Bot is a product of Steve Yeager, and is available from // the ACE Bot homepage, at http://www.axionfx.com/ace. // // This program is a modification of the ACE Bot, and is therefore // in NO WAY supported by Steve Yeager. // This program MUST NOT be sold in ANY form. If you have paid for // this product, you should contact Steve Yeager immediately, via // the ACE Bot homepage. // // --- END --- // // I, Steve Yeager, hold no responsibility for any harm caused by the // use of this source code, especially to small children and animals. // It is provided as-is with no implied warranty or support. // // I also wish to thank and acknowledge the great work of others // that has helped me to develop this code. // // John Cricket - For ideas and swapping code. // Ryan Feltrin - For ideas and swapping code. // SABIN - For showing how to do true client based movement. // BotEpidemic - For keeping us up to date. // Telefragged.com - For giving ACE a home. // Microsoft - For giving us such a wonderful crash free OS. // id - Need I say more. // // And to all the other testers, pathers, and players and people // who I can't remember who the heck they were, but helped out. // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // acebot_spawn.c - This file contains all of the // spawing support routines for the ACE bot. // /////////////////////////////////////////////////////////////////////// #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "game/g_local.h" #include "game/m_player.h" #include "acebot.h" #define MAX_BOTTMPFILE_COUNT 64 // arbitrary limit for bot .tmp files // mostly just for checking validity of the count field in the file. static size_t szr; // just for unused result warnings /* * Bot File Functions * * for loading bots from custom.cfg, team.cfg, and .cfg */ static struct loadbots_file_s { FILE *pfile; int record_count; } loadbots_file; static void loadbots_openfile( void ) { char bot_filename[MAX_OSPATH]; char stem[MAX_QPATH]; int tmpcount; FILE *tmppfile; size_t result; loadbots_file.pfile = NULL; loadbots_file.record_count = 0; // custom.cfg has priority over team.cfg if ( sv_custombots && sv_custombots->integer ) { sprintf( stem, BOT_GAMEDATA"/custom%i.tmp", sv_custombots->integer ); } else if ( TEAM_GAME ) { strcpy(stem, BOT_GAMEDATA"/team.tmp"); } else { sprintf(stem, BOT_GAMEDATA"/%s.tmp", level.mapname); } if ( !gi.FullPath( bot_filename, sizeof(bot_filename), stem ) ) { gi.dprintf("ACESP_LoadBots: not found: %s\n", stem); } else if ( (tmppfile = fopen(bot_filename, "rb")) == NULL ) { gi.dprintf("ACESP_LoadBots: failed fopen for read: %s\n", bot_filename); } else { // read the count result = fread( &tmpcount, sizeof(int), 1, tmppfile ); if (result != 1 || tmpcount < 0 || tmpcount > MAX_BOTTMPFILE_COUNT) { gi.dprintf("ACESP_LoadBots: failed fread or invalid count in %s\n", bot_filename); fclose( tmppfile ); } else if ( tmpcount == 0 ) { gi.dprintf("ACESP_LoadBots: %s is empty\n", bot_filename); fclose( tmppfile ); } else { loadbots_file.pfile = tmppfile; loadbots_file.record_count = tmpcount; } } } static void loadbots_closefile( void ) { if ( loadbots_file.pfile != NULL ) { fclose( loadbots_file.pfile ); loadbots_file.record_count = 0; } } static size_t loadbots_readnext( char *p_userinfo_bfr ) { size_t result; char botname[PLAYERNAME_SIZE]; if ( loadbots_file.pfile == NULL || loadbots_file.record_count == 0 ) { result = 0 ; } else { result = fread( p_userinfo_bfr, sizeof(char) * MAX_INFO_STRING, 1, loadbots_file.pfile ); if ( result ) { // make sure name from file is valid Q_strncpyz2( botname, Info_ValueForKey( p_userinfo_bfr, "name" ), sizeof(botname) ); ValidatePlayerName( botname, sizeof(botname) ); Info_SetValueForKey( p_userinfo_bfr, "name", botname ); } } return result; // 1 if ok, 0 if not } /* * client_botupdate * * count bots and update bot information in clients * * see: * p_hud.c::G_UpdateStats() * sv_main.c::SV_StatusString() * */ static int client_botupdate( void ) { int botnum; int botidx; char *botname; edict_t *pbot; int bots; edict_t *pclient; int clients; qboolean firstclient; // count bots botnum = 0; clients = game.maxclients; for ( pbot=&g_edicts[clients]; clients--; --pbot ) { if ( pbot->inuse && pbot->is_bot ) { ++botnum; } } // update clients if ( botnum == 0 ) { // clear bot count for ( pclient = &g_edicts[1], clients=game.maxclients ; clients--; ++pclient ) { // in every active client if ( pclient->inuse ) { pclient->client->ps.botnum = pclient->client->resp.botnum = 0; } } return 0; } botidx = 0; bots = botnum; for ( pbot = &g_edicts[game.maxclients]; bots ; --pbot ) { // process each bot if ( pbot->inuse && pbot->is_bot ) { botname = Info_ValueForKey( pbot->client->pers.userinfo, "name" ); firstclient = true; for ( pclient = &g_edicts[1], clients=game.maxclients ; clients--; ++pclient ) { // for every active client, plus always update first client for server if ( pclient->inuse || firstclient ) { pclient->client->ps.botnum = pclient->client->resp.botnum = botnum; strcpy( pclient->client->resp.bots[botidx].name, botname ); strcpy( pclient->client->ps.bots[botidx].name, botname ); pclient->client->resp.bots[botidx].score = pbot->client->resp.score; pclient->client->ps.bots[botidx].score = pbot->client->resp.score; firstclient = false; } } ++botidx; --bots; } } return botnum; } /** * @brief Update bot info in client records * * @detail Intended to be called once per frame, in RunFrame. First client * record should always have current bot info, so that server status * shows bots even when in intermission. * In ACE debug mode, reports when bot count changes. ACE debug mode * is controlled with "sv acedebug on","sv acedebug off" * */ void ACESP_UpdateBots( void ) { static int prev_count = 0; int count; /* count bots, and, in debug mode, output changes. */ count = client_botupdate(); if ( debug_mode ) { if ( count != prev_count ) debug_printf("Bot count %i to %i\n", prev_count, count ); } prev_count = count; } /* ====== ACESP_SaveBots Save current bots to bots.tmp file, which is used for creating custom.tmp, team.tmp and .tmp files also update bot information in client records ====== */ void ACESP_SaveBots( void ) { edict_t *bot; FILE *pOut; int i,count; char full_path[MAX_OSPATH]; count = client_botupdate(); // count bots and update clients gi.FullWritePath( full_path, sizeof(full_path), BOT_GAMEDATA"/bots.tmp" ); if ( ( pOut = fopen( full_path, "wb" )) == NULL ) { gi.dprintf("ACESP_SaveBots: fopen for write failed: %s\n", full_path ); return; } if ( count > MAX_BOTTMPFILE_COUNT ) { // record count limit mostly just for file error checking count = MAX_BOTTMPFILE_COUNT; gi.dprintf("ACESP_SaveBots: count limited to (%i)\n, ", count ); } szr = fwrite(&count,sizeof (int),1,pOut); // Write number of bots for (i = game.maxclients; i > 0 && count ; i--) { // write all current bots to bots.tmp bot = &g_edicts[i]; if (bot->inuse && bot->is_bot) { szr = fwrite(bot->client->pers.userinfo,sizeof (char) * MAX_INFO_STRING,1,pOut); --count; } } fclose(pOut); } /* ====== ACESP_FindBot find bot by name ====== */ edict_t *ACESP_FindBot( const char *name ) { edict_t *pbot; edict_t *found_bot = NULL; int clients = game.maxclients; for ( pbot=&g_edicts[clients]; clients-- ; --pbot ) { if ( pbot->inuse && pbot->is_bot && !strcmp( pbot->client->pers.netname, name ) ) { found_bot = pbot; break; } } return found_bot; } /* * game_census * * simple census, for non team. * team games use p_client.c::TeamCensus() */ typedef struct gamecensus_s { int real; int bots; } gamecensus_t; static void game_census( gamecensus_t *gamecensus ) { edict_t *pentity; int clients; int real = 0; int bots = 0; clients = game.maxclients; for ( pentity = &g_edicts[1]; clients--; ++pentity ) { if ( pentity->inuse ) { if ( pentity->is_bot ) { ++bots; } else { if ( g_duel->integer ) { // in duel, spectators count as being ingame ++real; } else if ( pentity->client->pers.spectator == 0 ) { ++real; } } } } gamecensus->real = real; gamecensus->bots = bots; } /* ====== ACESP_LoadBots Called for a client on connect or disconnect or for every client on ResetLevel() Also "unloads" bots for auto bot kick ====== */ /* * LoadBots sub-functions * * Team and Non-Team, With and Without Auto Bot Kick * * On entry: * '*.tmp' file has been opened, caller will close file * record count has been read and is known to be >0 * file read position is at first bot record */ static void loadbots_team_botkick( edict_t *ent ) { char userinfo[MAX_INFO_STRING]; char *name; char *skin; int rec_count; teamcensus_t teamcensus; int spawnkicknum; int ingame_players; int ingame_bots; qboolean bot_spawned; qboolean replace_bot; int botreplace_team; edict_t *pbot; int result; // count the ingame players and bots TeamCensus( &teamcensus ); if ( ent->client->pers.spectator && teamcensus.bots > 0 ) { // "spectator" is player who has not yet joined a team // nothing to do, unless bots have not been loaded. return; } ingame_players = teamcensus.real; ingame_bots = teamcensus.bots; spawnkicknum = sv_botkickthreshold->integer; if ( ingame_players >= spawnkicknum ) { // do not need any bots, kick any that are on server for ( pbot=&g_edicts[game.maxclients]; ingame_bots ; --pbot ) { if ( pbot->inuse && pbot->is_bot ) { ACESP_KickBot( pbot ); --ingame_bots; } } return; } replace_bot = false; botreplace_team = NO_TEAM; // default, either team. if ( teamcensus.total > spawnkicknum && ingame_bots > 0 ) { // a bot will be replaced replace_bot = true; if ( teamcensus.bots_blue > 0 && teamcensus.bots_red > 0 ) { // bots on both teams, botreplace_team = ent->dmteam; // replace same team, unless... if ( ent->dmteam == RED_TEAM && teamcensus.red < teamcensus.blue ) { botreplace_team = BLUE_TEAM; } else if ( ent->dmteam == BLUE_TEAM && teamcensus.blue < teamcensus.red ) { botreplace_team = RED_TEAM; } } } // bot team assignment is done in ACESP_SetName(), called from ACESP_SpawnBot() rec_count = loadbots_file.record_count; while ( rec_count-- ) { result = loadbots_readnext( userinfo ); if ( result == 0 ) { // file error break; } name = Info_ValueForKey( userinfo, "name" ); pbot = ACESP_FindBot( name ); if ( pbot == NULL ) { // not on server if ( !replace_bot ) { // not benching a bot, so ok to spawn if limit allows if ( (ingame_players + ingame_bots) < spawnkicknum ) { // spawn a team bot skin = Info_ValueForKey( userinfo, "skin" ); bot_spawned = ACESP_SpawnBot( name, skin, NULL); if ( bot_spawned ) { ++ingame_bots; } } } } else { // already on server if ( replace_bot ) { if ( botreplace_team == NO_TEAM || botreplace_team == pbot->dmteam ) { // on either team (NO_TEAM) or on specified team only ACESP_KickBot( pbot ); --ingame_bots; replace_bot = false; // one time only } } else if ( (ingame_players + ingame_bots) > spawnkicknum ) { // apply bot kick threshold ACESP_KickBot( pbot ); --ingame_bots; } } } } static void loadbots_team( void ) { char userinfo[MAX_INFO_STRING]; char *name; char *skin; int rec_count; qboolean bot_spawned; edict_t *bot; int result; // bot team assignment is done in ACESP_SetName(), called from ACESP_SpawnBot() rec_count = loadbots_file.record_count; while ( rec_count-- ) { // load all bots in the file result = loadbots_readnext( userinfo ); if (!result) { // file read error break; } name = Info_ValueForKey(userinfo, "name"); bot = ACESP_FindBot( name ); if (bot == NULL) { // not on server, spawn a team bot skin = Info_ValueForKey(userinfo, "skin"); bot_spawned = ACESP_SpawnBot( name, skin, NULL ); } } } static void loadbots_nonteam_botkick( void ) { char userinfo[MAX_INFO_STRING]; char *name; int rec_count; int spawnkicknum; int ingame_players; int ingame_bots; qboolean bot_spawned; edict_t *pbot; int result; gamecensus_t gamecensus; game_census( &gamecensus ); ingame_players = gamecensus.real; ingame_bots = gamecensus.bots; if ( g_duel->integer ) { // duel mode can have 1 and only 1 bot if ( ingame_players > 0 ) { // 1 or 0 bots and 1 or more real players spawnkicknum = 2; } else { // 1 bot or 0 bots, 0 real players spawnkicknum = 1; } } else { spawnkicknum = sv_botkickthreshold->integer; } if ( ingame_players >= spawnkicknum ) { // do not need any bots, kick any that are on server for ( pbot=&g_edicts[game.maxclients]; ingame_bots ; pbot-- ) { if ( pbot->inuse && pbot->is_bot ) { ACESP_KickBot( pbot ); --ingame_bots; } } return; } rec_count = loadbots_file.record_count; while ( rec_count-- ) { result = loadbots_readnext( userinfo ); if ( result == 0 ) { // file error break; } name = Info_ValueForKey( userinfo, "name" ); pbot = ACESP_FindBot( name ); if ( pbot == NULL ) { // not on server, spawn a bot if bot kick threshold allows if ( (ingame_players + ingame_bots) < spawnkicknum ) { // spawn a non-team bot bot_spawned = ACESP_SpawnBot (NULL, NULL, userinfo); if ( bot_spawned ) { ++ingame_bots; } } } else { // already on server if ( (ingame_players + ingame_bots) > spawnkicknum ) { // bot kick threshold ACESP_KickBot( pbot ); --ingame_bots; } } } } static void loadbots_nonteam( void ) { char userinfo[MAX_INFO_STRING]; char *name; int rec_count; qboolean bot_spawned; edict_t *pbot; int result; rec_count = loadbots_file.record_count; while ( rec_count-- ) { result = loadbots_readnext( userinfo ); if ( !result ) { // file read error break; } name = Info_ValueForKey( userinfo, "name" ); pbot = ACESP_FindBot( name ); if ( pbot == NULL ) { // not found on server, spawn a non-team bot bot_spawned = ACESP_SpawnBot (NULL, NULL, userinfo); } } } void ACESP_LoadBots( edict_t *ent ) { if ( dmflags->integer & DF_BOTS ) { // bots disabled. // result of setting the dmflag to disable bots when there are // bots in the game is undefined. return; } loadbots_openfile(); if ( loadbots_file.record_count == 0 ) { // no bots to load loadbots_closefile(); return; } if ( (sv_botkickthreshold && sv_botkickthreshold->integer) || g_duel->integer ) { // auto botkick, duel mode allows only 1 bot if ( TEAM_GAME ) { loadbots_team_botkick( ent ); } else { loadbots_nonteam_botkick(); } } else { // no auto botkick /* * TODO: see if it is possible to disable bot loading here * if there have been any callvote bot kicks in a game. * Because, if a new player enters, kicked bots will be reloaded. */ if ( TEAM_GAME ) { loadbots_team(); } else { loadbots_nonteam(); } } loadbots_closefile(); } /* ====== ACESP_FindBotNum called by server to determine bot kick threshold ====== */ int ACESP_FindBotNum(void) { int count; if ( dmflags->integer & DF_BOTS ) { // bots disabled by dmflag bit return 0; } loadbots_openfile(); count = loadbots_file.record_count; loadbots_closefile(); return count; } /////////////////////////////////////////////////////////////////////// // Called by PutClient in Server to actually release the bot into the game // Keep from killin' each other when all spawned at once /////////////////////////////////////////////////////////////////////// void ACESP_HoldSpawn(edict_t *self) { if ( !self->inuse || !self->is_bot ) { gi.dprintf("ACEAI_HoldSpawn: bad call program error\n"); return; } if (!KillBox (self)) { // could't spawn in? } gi.linkentity (self); self->think = ACEAI_Think; self->nextthink = level.time + FRAMETIME; // send effect gi.WriteByte (svc_muzzleflash); gi.WriteShort (self-g_edicts); gi.WriteByte (MZ_LOGIN); gi.multicast (self->s.origin, MULTICAST_PVS); safe_bprintf (PRINT_MEDIUM, "%s entered the game\n", self->client->pers.netname); } /*=== ACECO_ReadConfig() System-independent bot configuration file reader. 2010-08: Replaces function in acebot_config.cpp for Windows To be called with relative path to the .cfg file. ===*/ void ACECO_ReadConfig( char *config_file ) { char full_path[ MAX_OSPATH]; FILE *fp; int k; size_t length, result; char *buffer; char *s; const char *delim = "\r\n"; float tmpf; //set bot defaults(in case no bot config file is present for that bot) botvals.skill = 1; //medium strcpy(botvals.faveweap, "None"); for ( k = 1; k < 10; k++ ) botvals.weapacc[k] = 0.75; botvals.awareness = 0.7; // 0.7 is 145 degree FOV strcpy( botvals.chatmsg1, "%s: You are a real jerk %s!" ); strcpy( botvals.chatmsg2, "%s: Wait till next time %s." ); strcpy( botvals.chatmsg3, "%s: Life was better alive, %s!" ); strcpy( botvals.chatmsg4, "%s: You will pay for this %s!" ); strcpy( botvals.chatmsg5, "%s: You're using a bot %s!" ); strcpy( botvals.chatmsg6, "%s: I will be hunting you %s!" ); strcpy( botvals.chatmsg7, "%s: It hurts %s...it hurts..." ); strcpy( botvals.chatmsg8, "%s: Just a lucky shot %s!" ); if ( !gi.FullPath( full_path, sizeof(full_path), config_file ) ) { // bot not configured, use defaults return; } if ( (fp = fopen( full_path, "rb" )) == NULL ) { gi.dprintf("ACECO_ReadConfig: failed open for read: %s\n", full_path ); return; } if ( fseek(fp, 0, SEEK_END) ) { // seek error fclose( fp ); return; } if ( (length = ftell(fp)) == (size_t)-1L ) { // tell error fclose( fp ); return; } if ( fseek(fp, 0, SEEK_SET) ) { // seek error fclose( fp ); return; } buffer = malloc( length + 1); if ( buffer == NULL ) { // memory allocation error fclose( fp ); return; } result = fread( buffer, 1, length, fp ); fclose( fp ); if ( result != length ) { // read error free( buffer ); return; } buffer[length] = 0; // note: malloc'd buffer is modified by strtok if ( (s = strtok( buffer, delim )) != NULL ) botvals.skill = atoi( s ); if ( botvals.skill < 0 ) botvals.skill = 0; if ( s && ((s = strtok( NULL, delim )) != NULL) ) strncpy( botvals.faveweap, s, sizeof(botvals.faveweap)-1 ); for(k = 1; k < 10; k++) { if ( s && ((s = strtok( NULL, delim )) != NULL ) ) { tmpf = atof( s ); if ( tmpf < 0.5f ) tmpf = 0.5f; else if (tmpf > 1.0f ) tmpf = 1.0f; botvals.weapacc[k] = tmpf; } } if ( s && ((s = strtok( NULL, delim)) != NULL) ) { tmpf = atof( s ); if ( tmpf < 0.1f ) tmpf = 0.1f; else if ( tmpf > 1.0f ) tmpf = 1.0f; botvals.awareness = tmpf; } if ( s && ((s = strtok( NULL, delim)) != NULL) ) strncpy( botvals.chatmsg1, s, sizeof(botvals.chatmsg1)-1 ); if ( s && ((s = strtok( NULL, delim)) != NULL) ) strncpy( botvals.chatmsg2, s, sizeof(botvals.chatmsg2)-1 ); if ( s && ((s = strtok( NULL, delim)) != NULL) ) strncpy( botvals.chatmsg3, s, sizeof(botvals.chatmsg3)-1 ); if ( s && ((s = strtok( NULL, delim)) != NULL) ) strncpy( botvals.chatmsg4, s, sizeof(botvals.chatmsg4)-1 ); if ( s && ((s = strtok( NULL, delim)) != NULL) ) strncpy( botvals.chatmsg5, s, sizeof(botvals.chatmsg5)-1 ); if ( s && ((s = strtok( NULL, delim)) != NULL) ) strncpy( botvals.chatmsg6, s, sizeof(botvals.chatmsg6)-1 ); if ( s && ((s = strtok( NULL, delim)) != NULL) ) strncpy( botvals.chatmsg7, s, sizeof(botvals.chatmsg7)-1 ); if ( s && ((s = strtok( NULL, delim)) != NULL) ) strncpy( botvals.chatmsg8, s, sizeof(botvals.chatmsg8)-1 ); free( buffer ); } /* ====== ACESP_PutClientInServer Bot version of p_client.c:PutClientInServer() Also see: ClientUserinfoChanged() and ClientChangeSkin() ====== */ void ACESP_PutClientInServer (edict_t *bot, qboolean respawn ) { vec3_t mins = {-16, -16, -24}; vec3_t maxs = {16, 16, 32}; int index, armor_index; vec3_t spawn_origin, spawn_angles; gclient_t *client; gitem_t *item; int i, k, done; client_persistant_t saved; client_respawn_t resp; char *info; char playermodel[MAX_OSPATH] = " "; char modelpath[MAX_OSPATH] = " "; FILE *file; char userinfo[MAX_INFO_STRING]; char bot_configfilename[MAX_OSPATH]; // find a spawn point // do it before setting health back up, so farthest // ranging doesn't count this client if(!g_tactical->integer) SelectSpawnPoint (bot, spawn_origin, spawn_angles); index = bot - g_edicts - 1; client = bot->client; resp = bot->client->resp; // init pers.* variables, save and restore userinfo variables (name, skin) memcpy(userinfo, client->pers.userinfo, MAX_INFO_STRING ); InitClientPersistant (client); memcpy(client->pers.userinfo, userinfo, MAX_INFO_STRING ); // set netname from userinfo strncpy( bot->client->pers.netname, (Info_ValueForKey( client->pers.userinfo, "name")), sizeof(bot->client->pers.netname)-1); // combine name and skin into a configstring gi.configstring( CS_PLAYERSKINS+index, va("%s\\%s", bot->client->pers.netname, (Info_ValueForKey( client->pers.userinfo, "skin")))); // clear everything but the persistant data ( pers.* and resp.*) saved = client->pers; memset (client, 0, sizeof(*client)); client->pers = saved; client->resp = resp; // match p_client.c., all do not necessarily apply to bots client->is_bot = 1; // this is a bot client->kill_streak = 0; client->homing_shots = 0; client->mapvote = 0; client->lasttaunttime = 0; client->rayImmunity = false; // copy some data from the client to the entity FetchClientEntData (bot); // clear entity values bot->groundentity = NULL; bot->client = &game.clients[index]; if(g_spawnprotect->value) bot->client->spawnprotected = true; bot->takedamage = DAMAGE_AIM; bot->movetype = MOVETYPE_WALK; bot->viewheight = 24; bot->classname = "bot"; bot->mass = 200; bot->solid = SOLID_BBOX; bot->deadflag = DEAD_NO; bot->air_finished = level.time + 12; bot->clipmask = MASK_PLAYERSOLID; bot->model = "players/martianenforcer/tris.md2"; bot->pain = player_pain; bot->die = player_die; bot->waterlevel = 0; bot->watertype = 0; bot->flags &= ~FL_NO_KNOCKBACK; bot->svflags &= ~SVF_DEADMONSTER; bot->is_jumping = false; //vehicles bot->in_vehicle = false; //deathball bot->in_deathball = false; VectorCopy (mins, bot->mins); VectorCopy (maxs, bot->maxs); VectorClear (bot->velocity); // clear playerstate values memset (&bot->client->ps, 0, sizeof(client->ps)); //ZOID client->ps.pmove.pm_flags &= ~PMF_NO_PREDICTION; //ZOID client->ps.fov = 90; client->ps.gunindex = gi.modelindex(client->pers.weapon->view_model); // clear entity state values bot->s.effects = 0; bot->s.skinnum = bot - g_edicts - 1; bot->s.modelindex = 255; // will use the skin specified model bot->s.modelindex2 = 255; // custom gun model info = Info_ValueForKey (bot->client->pers.userinfo, "skin"); i = 0; done = false; strcpy(playermodel, " "); while(!done) { if((info[i] == '/') || (info[i] == '\\')) done = true; playermodel[i] = info[i]; if(i > 62) done = true; i++; } playermodel[i-1] = 0; sprintf(modelpath, "players/%s/helmet.md2", playermodel); Q2_FindFile (modelpath, &file); //does a helmet exist? if(file) { sprintf(modelpath, "players/%s/helmet.md2", playermodel); bot->s.modelindex3 = gi.modelindex(modelpath); fclose(file); } else bot->s.modelindex3 = 0; bot->s.modelindex4 = 0; //check for gib file bot->usegibs = 0; //alien is default sprintf(modelpath, "players/%s/usegibs", playermodel); Q2_FindFile (modelpath, &file); if(file) { //use model specific gibs bot->usegibs = 1; sprintf(bot->head, "players/%s/head.md2", playermodel); sprintf(bot->body, "players/%s/body.md2", playermodel); sprintf(bot->leg, "players/%s/leg.md2", playermodel); sprintf(bot->arm, "players/%s/arm.md2", playermodel); fclose(file); } //check for class file bot->ctype = 0; sprintf(modelpath, "players/%s/human", playermodel); Q2_FindFile (modelpath, &file); if(file) { fclose(file); //human bot->ctype = 1; if(g_tactical->integer || (classbased->value && !(rocket_arena->integer || instagib->integer || insta_rockets->value || excessive->value))) { if(g_tactical->integer) { //read class file(tactical only) //example: //100-150 (health) //0-3 (armor type) //0-1 (has bomb) //0-1 (has detonator) //0-1 (has mind eraser) //0-1 (has vaporizor) ParseClassFile(modelpath, bot); if(bot->has_bomb) { bot->client->pers.inventory[ITEM_INDEX(FindItem("Human Bomb"))] = 1; bot->client->pers.inventory[ITEM_INDEX(FindItem("bombs"))] = 1; //tactical note - humans will use same ammo, etc, just different weapons } item = FindItem("Blaster"); } else { bot->health = bot->max_health = client->pers.max_health = client->pers.health = 100; armor_index = ITEM_INDEX(FindItem("Jacket Armor")); client->pers.inventory[armor_index] += 30; client->pers.inventory[ITEM_INDEX(FindItem("Rocket Launcher"))] = 1; client->pers.inventory[ITEM_INDEX(FindItem("rockets"))] = 10; item = FindItem("Rocket Launcher"); } client->pers.selected_item = ITEM_INDEX(item); client->pers.inventory[client->pers.selected_item] = 1; client->pers.weapon = item; } } else { sprintf(modelpath, "players/%s/robot", playermodel); Q2_FindFile (modelpath, &file); if(file && !g_tactical->integer) { //robot - not used in tactical bot->ctype = 2; if(classbased->value && !(rocket_arena->integer || instagib->integer || insta_rockets->value || excessive->value)) { bot->health = bot->max_health = client->pers.max_health = client->pers.health = 85; armor_index = ITEM_INDEX(FindItem("Jacket Armor")); client->pers.inventory[armor_index] += 175; } fclose(file); } else { //alien bot->ctype = 0; if(g_tactical->integer || (classbased->value && !(rocket_arena->integer || instagib->integer || insta_rockets->value || excessive->value))) { bot->health = bot->max_health = client->pers.max_health = client->pers.health = 150; if(g_tactical->integer) { sprintf(modelpath, "players/%s/alien", playermodel); Q2_FindFile (modelpath, &file); if(file) { ParseClassFile(modelpath, bot); if(bot->has_bomb) { bot->client->pers.inventory[ITEM_INDEX(FindItem("Alien Bomb"))] = 1; bot->client->pers.inventory[ITEM_INDEX(FindItem("bombs"))] = 1; //tactical note - humans will use same ammo, etc, just different weapons } } item = FindItem("Blaster"); client->pers.selected_item = ITEM_INDEX(item); client->pers.inventory[client->pers.selected_item] = 0; item = FindItem("Alien Blaster"); } else { client->pers.inventory[ITEM_INDEX(FindItem("Alien Disruptor"))] = 1; client->pers.inventory[ITEM_INDEX(FindItem("cells"))] = 100; item = FindItem("Alien Disruptor"); } client->pers.selected_item = ITEM_INDEX(item); client->pers.inventory[client->pers.selected_item] = 1; client->pers.weapon = item; } } } //has to be done after determining the class/team - note - we don't care about spawn distances in tactical if(g_tactical->integer) SelectSpawnPoint (bot, spawn_origin, spawn_angles); client->ps.pmove.origin[0] = spawn_origin[0]*8; client->ps.pmove.origin[1] = spawn_origin[1]*8; client->ps.pmove.origin[2] = spawn_origin[2]*8; bot->s.frame = 0; VectorCopy (spawn_origin, bot->s.origin); bot->s.origin[2] += 1; // make sure off ground // set the delta angle for (i=0 ; i<3 ; i++) client->ps.pmove.delta_angles[i] = ANGLE2SHORT(spawn_angles[i] - client->resp.cmd_angles[i]); bot->s.angles[PITCH] = 0; bot->s.angles[YAW] = spawn_angles[YAW]; bot->s.angles[ROLL] = 0; VectorCopy (bot->s.angles, client->ps.viewangles); VectorCopy (bot->s.angles, client->v_angle); // force the current weapon up client->newweapon = client->pers.weapon; ChangeWeapon (bot); bot->enemy = NULL; bot->movetarget = NULL; bot->yaw_speed = 37; // bot turning speed. angle in degrees bot->state = STATE_MOVE; // Set the current node bot->current_node = ACEND_FindClosestReachableNode(bot,NODE_DENSITY, NODE_ALL); bot->goal_node = bot->current_node; bot->next_node = bot->current_node; bot->next_move_time = level.time; bot->suicide_timeout = level.time + 15.0; if ( !respawn ) { /* * on initial spawn, load bot configuration * from botinfo/.cfg file * ReadConfig sets defaults if there is no such file. */ info = Info_ValueForKey (bot->client->pers.userinfo, "name"); sprintf( bot_configfilename, BOT_GAMEDATA"/%s.cfg", info ); ACECO_ReadConfig(bot_configfilename); //set config items bot->skill = botvals.skill; strcpy(bot->faveweap, botvals.faveweap); for(k = 1; k < 10; k++) bot->weapacc[k] = botvals.weapacc[k]; bot->accuracy = 0.75; //start with this(changes when bot selects a weapon bot->awareness = botvals.awareness; strcpy(bot->chatmsg1, botvals.chatmsg1); strcpy(bot->chatmsg2, botvals.chatmsg2); strcpy(bot->chatmsg3, botvals.chatmsg3); strcpy(bot->chatmsg4, botvals.chatmsg4); strcpy(bot->chatmsg5, botvals.chatmsg5); strcpy(bot->chatmsg6, botvals.chatmsg6); strcpy(bot->chatmsg7, botvals.chatmsg7); strcpy(bot->chatmsg8, botvals.chatmsg8); /* * adjust skill according to cvar. Single Player menu selections * force the cvar. * 0 : forces all to 0 skill (single player easy) * 1 : skill is cfg setting (single player medium) * 2 : skill is cfg setting setting plus 1 (single player hard) * 3 : forces all to skill 3 (single player ultra) */ if( skill->integer == 0 ) { bot->skill = 0; //dumb as a box of rocks } else if ( skill->integer == 2 ) { bot->skill += 1; if(bot->skill > 3) bot->skill = 3; } else if ( skill->integer >= 3 ) { bot->skill = 3; } /* * clear the weapon accuracy statistics. * for testing aim related settings. */ for(i = 0; i < 9; i++) { client->resp.weapon_shots[i] = 0; client->resp.weapon_hits[i] = 0; } } // If we are not respawning hold off for up to three seconds before releasing into game if(!respawn) { bot->think = ACESP_HoldSpawn; bot->nextthink = level.time + random()*3.0; // up to three seconds } else { if (!KillBox (bot)) { // could't spawn in? } bot->s.event = EV_OTHER_TELEPORT; //fix "player flash" bug gi.linkentity (bot); bot->think = ACEAI_Think; bot->nextthink = level.time + FRAMETIME; // send effect gi.WriteByte (svc_muzzleflash); gi.WriteShort (bot-g_edicts); gi.WriteByte (MZ_LOGIN); gi.multicast (bot->s.origin, MULTICAST_PVS); } client->spawnprotecttime = level.time; //unlagged if ( g_antilag->integer) { G_ResetHistory( bot ); // and this is as good a time as any to clear the saved state bot->client->saved.leveltime = 0; } } /////////////////////////////////////////////////////////////////////// // Respawn the bot /////////////////////////////////////////////////////////////////////// void ACESP_Respawn (edict_t *self) { CopyToBodyQue (self); ACESP_PutClientInServer( self, true ); // respawn // add a teleportation effect self->s.event = EV_PLAYER_TELEPORT; // hold in place briefly self->client->ps.pmove.pm_flags = PMF_TIME_TELEPORT; self->client->ps.pmove.pm_time = 14; self->client->respawn_time = level.time; } /////////////////////////////////////////////////////////////////////// // Find a free client spot /////////////////////////////////////////////////////////////////////// edict_t *ACESP_FindFreeClient (void) { int clients; edict_t *pbot = NULL; edict_t *found_bot = NULL; int maxcount = 0; // find current maximum count field, used for bot naming clients = game.maxclients; for ( pbot=&g_edicts[clients]; clients--; --pbot ) { if ( pbot->is_bot && (pbot->count > maxcount) ) { maxcount = pbot->count; } } // find a free slot for new bot clients = game.maxclients; for ( pbot=&g_edicts[clients]; clients--; --pbot ) { // reverse search, bots are assigned from end of list if ( !pbot->inuse ) { pbot->count = maxcount + 1; // for new bot's generic name found_bot = pbot; break; } } return found_bot; } /* * ACESP_SetName() * * determine bot name and skin * for team games, select the team */ void ACESP_SetName(edict_t *bot, char *name, char *skin, char *userinfo ) { char bot_skin[MAX_INFO_STRING]; char bot_name[MAX_INFO_STRING]; char playerskin[MAX_INFO_STRING]; char playermodel[MAX_INFO_STRING]; int i, j, k, copychar; teamcensus_t teamcensus; char *skin2; if(strlen(name) == 0) { // generate generic name, set model/skin to default sprintf(bot_name,"ACEBot_%d",bot->count); sprintf(bot_skin,"martianenforcer/default"); skin2 = bot_skin; } else { // name and skin from args strcpy(bot_name,name); skin2 = skin; } bot->dmteam = NO_TEAM; bot->teamset = false; if ( TEAM_GAME ) { // extract model from info record copychar = false; strcpy(playerskin, " "); strcpy(playermodel, " "); j = k = 0; for(i = 0; i <= (int)strlen(skin2) && i < MAX_INFO_STRING; i++) { if(copychar){ playerskin[k] = skin2[i]; k++; } else { playermodel[j] = skin2[i]; j++; } if(skin2[i] == '/') copychar = true; } playermodel[j] = 0; // assign bot to a team and set skin TeamCensus( &teamcensus ); // apply team balancing rules bot->dmteam = teamcensus.team_for_bot; if ( bot->dmteam == BLUE_TEAM ) { strcpy(playerskin, "blue"); bot->teamset = true; } else if ( bot->dmteam == RED_TEAM ) { strcpy(playerskin, "red"); bot->teamset = true; } else { // not expected. probably a program error. gi.dprintf("ACESP_SetName: bot team skin program error.\n"); strcpy( playerskin, "default" ); } // concatenate model and new skin strcpy(bot_skin, playermodel); strcat(bot_skin, playerskin); } else { // non-team if ( strlen(skin2) == 0 ) { // if no skin yet, choose model/skin randomly if ( rand() & 1 ) sprintf(bot_skin,"martianenforcer/red"); else sprintf(bot_skin,"martianenforcer/blue"); } else strcpy(bot_skin,skin2); } // initialise userinfo memset( userinfo, 0, MAX_INFO_STRING ); // add bot's name\model/skin\hand to userinfo Info_SetValueForKey (userinfo, "name", bot_name); Info_SetValueForKey (userinfo, "skin", bot_skin); Info_SetValueForKey (userinfo, "hand", "2"); // bot is center handed for now! } /* * ACESP_ClientConnect * * bot version of p_client.c::ClientConnect() * */ qboolean ACESP_ClientConnect( edict_t *pbot ) { edict_t *pclient; int clients; char *name = pbot->client->pers.netname; // check for collison with a player name clients = game.maxclients; for ( pclient = &g_edicts[1]; clients--; pclient++ ) { if ( pclient->inuse && pclient != pbot && !strcmp( pclient->client->pers.netname, name ) ) { // return false; } } return true; } /* * ACESP_SpawnBot * * initial spawn from LoadBots() or server command * */ qboolean ACESP_SpawnBot (char *name, char *skin, char *userinfo) { char new_userinfo[MAX_INFO_STRING]; edict_t *pbot; qboolean connect_allowed = false; pbot = ACESP_FindFreeClient (); if (!pbot) { // no free client record gi.dprintf("Server is full, maxclients is %d\n", game.maxclients); return false; } // there is a free client record, use it pbot->inuse = true; pbot->is_bot = true; if ( userinfo == NULL ) { // team bot or "sv addbot", generate userinfo. // for team games, select team ACESP_SetName( pbot, name, skin, new_userinfo ); } else { // non-team bot , userinfo from *.tmp file // copy to local userinfo record memcpy( new_userinfo, userinfo, MAX_INFO_STRING ); } // store userinfo in client memcpy( pbot->client->pers.userinfo, new_userinfo, MAX_INFO_STRING ); // set name from userinfo memcpy( pbot->client->pers.netname, Info_ValueForKey( new_userinfo, "name"), sizeof( pbot->client->pers.netname ) ); // attempt connection to server connect_allowed = ACESP_ClientConnect( pbot ); if( !connect_allowed ) { /* Tony: Sometimes bots are refused entry to servers - give up gracefully */ // safe_bprintf (PRINT_MEDIUM, "Bot was refused entry to server.\n"); gi.dprintf("%s (bot) failed connection to server\n", pbot->client->pers.netname ); // release client record and exit pbot->inuse = false; pbot->is_bot = false; return false; } pbot->client->pers.connected = true; gi.dprintf("%s (bot) connected\n", pbot->client->pers.netname ); // some basic initial value setting G_InitEdict( pbot ); InitClientResp( pbot->client); // initial spawn ACESP_PutClientInServer( pbot, false ); ACESP_SaveBots(); // update bots.tmp and clients bot information if ( g_duel->integer ) { ClientPlaceInQueue( pbot ); ClientCheckQueue( pbot ); } // make sure all view stuff is valid ClientEndServerFrame( pbot ); ACEAI_PickLongRangeGoal( pbot ); // pick a new goal return true; } /////////////////////////////////////////////////////////////////////// // Remove/Kick Bots /////////////////////////////////////////////////////////////////////// /*=== remove_bot() common routine for removal or kick of a bot adapted from player_die(), and previous ACESP_RemoveBot(), ACESP_KickBot() === */ static void remove_bot( edict_t *bot ) { VectorClear( bot->avelocity ); if ( bot->in_vehicle ) { VehicleDeadDrop( bot ); } if(ctf->value) { CTFDeadDropFlag(bot, NULL); } if ( bot->in_deathball ) { DeadDropDeathball(bot); } if ( g_duel->integer ) {// duel mode, we need to bump people down the queue if its the player in game leaving MoveClientsDownQueue(bot); if( !bot->client->resp.spectator ) { // bot was in duel int j; for ( j = 1; j <= game.maxclients; j++) { // clear scores of other players if ( g_edicts[j].inuse && g_edicts[j].client ) g_edicts[j].client->resp.score = 0; } } } bot->inuse = false; bot->solid = SOLID_NOT; bot->classname = "disconnected"; bot->s.modelindex = 0; bot->s.modelindex2= 0; bot->s.modelindex3 = 0; bot->s.modelindex4 = 0; bot->s.angles[0] = 0; // ? bot->s.angles[2] = 0; // ? bot->s.sound = 0; bot->client->weapon_sound = 0; bot->s.effects = 0; // remove powerups bot->client->quad_framenum = 0; bot->client->invincible_framenum = 0; bot->client->haste_framenum = 0; bot->client->sproing_framenum = 0; bot->client->invis_framenum = 0; // clear inventory memset( bot->client->pers.inventory, 0, sizeof(bot->client->pers.inventory)); bot->client->pers.connected = false; // particle effect for exit from game gi.WriteByte (svc_muzzleflash); gi.WriteShort (bot-g_edicts); gi.WriteByte (MZ_LOGOUT); gi.multicast (bot->s.origin, MULTICAST_PVS); gi.configstring( CS_PLAYERSKINS + ( ((ptrdiff_t)(bot - g_edicts))-1 ), ""); // unlink from world gi.unlinkentity (bot); } /* ====== ACESP_RemoveBot remove by server command "sv removebot |all" ====== */ void ACESP_RemoveBot(char *name) { edict_t *pbot; int clients; qboolean allbots; qboolean freed = false; allbots = strcmp( name, "all" ) == 0; clients = game.maxclients; for ( pbot = &g_edicts[1]; clients--; pbot++ ) { if ( pbot->inuse && pbot->is_bot && (allbots || G_NameMatch( pbot->client->pers.netname, name ))) { remove_bot( pbot ); safe_cprintf( NULL, PRINT_HIGH, "%s removed\n", pbot->client->pers.netname ); freed = true; } } if ( !allbots && !freed ) { safe_cprintf( NULL, PRINT_HIGH, "%s not found, not removed\n", name ); } // update bots.tmp and client bot information ACESP_SaveBots(); } /* ====== ACESP_KickBot remove by auto bot kick (cvar:sv_botkickthreshold) or by "callvote kick " ====== */ void ACESP_KickBot( edict_t *bot ) { remove_bot( bot ); safe_bprintf (PRINT_MEDIUM, "%s (bot) kicked\n", bot->client->pers.netname); // update bots.tmp and client bot information ACESP_SaveBots(); } alien-arena-7.66+dfsg/source/game/g_local.h0000600000175000017500000013552612161402010017600 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // g_local.h -- local definitions for game module #include "q_shared.h" // define GAME_INCLUDE so that game.h does not define the // short, server-visible gclient_t and edict_t structures, // because we define the full size ones in this file #define GAME_INCLUDE #include "game.h" // the "gameversion" client command will print this plus compile date #define GAMEVERSION "data1" // protocol bytes that can be directly added to messages #define svc_muzzleflash 1 #define svc_muzzleflash2 2 #define svc_temp_entity 3 #define svc_layout 4 #define svc_inventory 5 #define svc_nop 6 #define svc_stufftext 11 //================================================================== // view pitching times #define DAMAGE_TIME 0.5 #define FALL_TIME 0.3 // edict->spawnflags // these are set with checkboxes on each entity in the map editor #define SPAWNFLAG_NOT_EASY 0x00000100 #define SPAWNFLAG_NOT_MEDIUM 0x00000200 #define SPAWNFLAG_NOT_HARD 0x00000400 #define SPAWNFLAG_NOT_DEATHMATCH 0x00000800 // edict->flags #define FL_FLY 0x00000001 #define FL_SWIM 0x00000002 // implied immunity to drowining #define FL_IMMUNE_LASER 0x00000004 #define FL_INWATER 0x00000008 #define FL_GODMODE 0x00000010 #define FL_NOTARGET 0x00000020 #define FL_IMMUNE_SLIME 0x00000040 #define FL_IMMUNE_LAVA 0x00000080 #define FL_PARTIALGROUND 0x00000100 // not all corners are valid #define FL_WATERJUMP 0x00000200 // player jumping out of water #define FL_TEAMSLAVE 0x00000400 // not the first on the team #define FL_NO_KNOCKBACK 0x00000800 #define FL_POWER_ARMOR 0x00001000 // power armor (if any) is active #define FL_RESPAWN 0x80000000 // used for item respawning #define FRAMETIME 0.1 //unlagged - true ping #define NUM_PING_SAMPLES 64 //unlagged - true ping // memory tags to allow dynamic memory to be cleaned up #define TAG_GAME 765 // clear when unloading the dll #define TAG_LEVEL 766 // clear when loading a new level #define MELEE_DISTANCE 80 // Anti-camp defaults /** @brief Default anti-camp frames * * Default value for the ac_frames anti-camp CVar. */ #define G_ANTICAMP_FRAMES 30 /** @brief Default anti-camp threshold * * Default value for the ac_threshold anti-camp CVar. */ #define G_ANTICAMP_THRESHOLD 100 #define BODY_QUEUE_SIZE 8 typedef enum { DAMAGE_NO, DAMAGE_YES, // will take damage if hit DAMAGE_AIM // auto targeting recognizes this } damage_t; typedef enum { WEAPON_READY, WEAPON_ACTIVATING, WEAPON_DROPPING, WEAPON_FIRING } weaponstate_t; typedef enum { AMMO_BULLETS, AMMO_SHELLS, AMMO_ROCKETS, AMMO_GRENADES, AMMO_CELLS, AMMO_SLUGS, AMMO_SEEKERS, AMMO_BOMBS } ammo_t; //teams typedef struct teamcensus_s { // see p_client.c::TeamCensus() int total; int real; int bots; int red; int blue; int real_red; int real_blue; int bots_red; int bots_blue; int team_for_real; int team_for_bot; } teamcensus_t; #define TEAM_GAME ( (dmflags->integer & (DF_SKINTEAMS)) \ || ctf->integer || tca->integer || cp->integer ) //clientinfo origins #define INGAME 0 #define SPAWN 1 #define CONNECT 2 //deadflag #define DEAD_NO 0 #define DEAD_DYING 1 #define DEAD_DEAD 2 #define DEAD_RESPAWNABLE 3 //range #define RANGE_MELEE 0 #define RANGE_NEAR 1 #define RANGE_MID 2 #define RANGE_FAR 3 //gib types #define GIB_ORGANIC 0 #define GIB_METALLIC 1 //monster ai flags #define AI_STAND_GROUND 0x00000001 #define AI_TEMP_STAND_GROUND 0x00000002 #define AI_SOUND_TARGET 0x00000004 #define AI_LOST_SIGHT 0x00000008 #define AI_PURSUIT_LAST_SEEN 0x00000010 #define AI_PURSUE_NEXT 0x00000020 #define AI_PURSUE_TEMP 0x00000040 #define AI_HOLD_FRAME 0x00000080 #define AI_GOOD_GUY 0x00000100 #define AI_BRUTAL 0x00000200 #define AI_NOSTEP 0x00000400 #define AI_DUCKED 0x00000800 #define AI_COMBAT_POINT 0x00001000 #define AI_MEDIC 0x00002000 #define AI_RESURRECTING 0x00004000 #define AI_NPC 0x00008000 // FIXME: use AI_GOOD_GUY instead? //monster attack state #define AS_STRAIGHT 1 #define AS_SLIDING 2 #define AS_MELEE 3 #define AS_MISSILE 4 // armor types #define ARMOR_NONE 0 #define ARMOR_JACKET 1 #define ARMOR_COMBAT 2 #define ARMOR_BODY 3 #define ARMOR_SHARD 4 // handedness values #define RIGHT_HANDED 0 #define LEFT_HANDED 1 #define CENTER_HANDED 2 // game.serverflags values #define SFL_CROSS_TRIGGER_1 0x00000001 #define SFL_CROSS_TRIGGER_2 0x00000002 #define SFL_CROSS_TRIGGER_3 0x00000004 #define SFL_CROSS_TRIGGER_4 0x00000008 #define SFL_CROSS_TRIGGER_5 0x00000010 #define SFL_CROSS_TRIGGER_6 0x00000020 #define SFL_CROSS_TRIGGER_7 0x00000040 #define SFL_CROSS_TRIGGER_8 0x00000080 #define SFL_CROSS_TRIGGER_MASK 0x000000ff // noise types for PlayerNoise #define PNOISE_SELF 0 #define PNOISE_WEAPON 1 #define PNOISE_IMPACT 2 // edict->movetype values typedef enum { MOVETYPE_NONE, // never moves MOVETYPE_NOCLIP, // origin and angles change with no interaction MOVETYPE_PUSH, // no clip to world, push on box contact MOVETYPE_STOP, // no clip to world, stops on box contact MOVETYPE_WALK, // gravity MOVETYPE_STEP, // gravity, special edge handling MOVETYPE_FLY, MOVETYPE_TOSS, // gravity MOVETYPE_FLYMISSILE, // extra size to monsters MOVETYPE_BOUNCE } movetype_t; typedef struct { char command[128]; //limit to prevent malicious buffer overflows int yay; int nay; float starttime; float time; qboolean called; } g_vote_t; typedef struct { int base_count; int max_count; float normal_protection; float energy_protection; int armor; } gitem_armor_t; // gitem_t->flags #define IT_WEAPON 1 // use makes active weapon #define IT_AMMO 2 #define IT_ARMOR 4 #define IT_KEY 8 #define IT_POWERUP 16 #define IT_HEALTH 32 //to do - add alteria items - will require a number of other changes, particularly in bot code as well // gitem_t->weapmodel for weapons indicates model index #define WEAP_BLASTER 1 #define WEAP_SMARTGUN 2 #define WEAP_CHAINGUN 3 #define WEAP_GRAPPLE 4 #define WEAP_FLAMETHROWER 5 #define WEAP_ROCKETLAUNCHER 8 #define WEAP_DISRUPTOR 9 #define WEAP_BEAMGUN 10 #define WEAP_VAPORIZER 11 #define WEAP_VIOLATOR 12 #define WEAP_MINDERASER 13 #define WEAP_BOMBER 14 #define WEAP_STRAFER 15 #define WEAP_DEATHBALL 16 #define WEAP_HOVER 17 #define WEAP_ABOMB 18 #define WEAP_HBOMB 19 typedef struct gitem_s { char *classname; // spawning name qboolean (*pickup)(struct edict_s *ent, struct edict_s *other); void (*use)(struct edict_s *ent, struct gitem_s *item); void (*drop)(struct edict_s *ent, struct gitem_s *item); void (*weaponthink)(struct edict_s *ent); char *pickup_sound; char *world_model; int world_model_flags; char *view_model; // client side info char *icon; char *pickup_name; // for printing on pickup int count_width; // number of digits to display by icon int quantity; // for ammo how much, for weapons how much is used per shot char *ammo; // for weapons int flags; // IT_* flags int weapmodel; // weapon model index (for weapons) void *info; int tag; char *precaches; // string of all models, sounds, and images this item will use } gitem_t; // // this structure is left intact through an entire game // it should be initialized at dll load time, and read/written to // the server.ssv file for savegames // typedef struct { char helpmessage1[512]; char helpmessage2[512]; int helpchanged; // flash F1 icon if non 0, play sound // and increment only if 1, 2, or 3 gclient_t *clients; // [maxclients] // store latched cvars here that we want to get at often int maxclients; int maxentities; // cross level triggers int serverflags; // items int num_items; qboolean autosaved; } game_locals_t; // // this structure is cleared as each map is entered // it is read/written to the level.sav file for savegames // typedef struct { int framenum; float time; int previousTime; //in milleseconds char level_name[MAX_QPATH]; // the descriptive name (Outer Base, etc) char mapname[MAX_QPATH]; // the server name (base1, etc) char nextmap[MAX_QPATH]; // go here when fraglimit is hit // intermission state float intermissiontime; // time the intermission was started char *changemap; int exitintermission; vec3_t intermission_origin; vec3_t intermission_angle; edict_t *sight_client; // changed once each frame for coop games edict_t *sight_entity; int sight_entity_framenum; edict_t *sound_entity; int sound_entity_framenum; edict_t *sound2_entity; int sound2_entity_framenum; int pic_health; int total_secrets; int found_secrets; int total_goals; int found_goals; int total_monsters; int killed_monsters; edict_t *current_entity; // entity running from G_RunFrame int body_que; // dead bodies //unlagged - backward reconciliation #4 // actual time this server frame started float frameStartTime; //unlagged - backward reconciliation #4 } level_locals_t; // spawn_temp_t is only used to hold entity field values that // can be set from the editor, but aren't actualy present // in edict_t during gameplay typedef struct { // world vars char *sky; float skyrotate; vec3_t skyaxis; char *nextmap; int lip; int distance; int height; char *noise; float pausetime; char *item; char *gravity; float minyaw; float maxyaw; float minpitch; float maxpitch; } spawn_temp_t; typedef struct { // fixed data vec3_t start_origin; vec3_t start_angles; vec3_t end_origin; vec3_t end_angles; int sound_start; int sound_middle; int sound_end; float accel; float speed; float decel; float distance; float wait; // state data int state; vec3_t dir; float current_speed; float move_speed; float next_speed; float remaining_distance; float decel_distance; void (*endfunc)(edict_t *); } moveinfo_t; typedef struct { void (*aifunc)(edict_t *self, float dist); float dist; void (*thinkfunc)(edict_t *self); } mframe_t; typedef struct { int firstframe; int lastframe; mframe_t *frame; void (*endfunc)(edict_t *self); } mmove_t; typedef struct { mmove_t *currentmove; int aiflags; int nextframe; float scale; void (*stand)(edict_t *self); void (*idle)(edict_t *self); void (*search)(edict_t *self); void (*walk)(edict_t *self); void (*run)(edict_t *self); void (*dodge)(edict_t *self, edict_t *other, float eta); void (*attack)(edict_t *self); void (*melee)(edict_t *self); void (*sight)(edict_t *self, edict_t *other); qboolean (*checkattack)(edict_t *self); float pausetime; float attack_finished; vec3_t saved_goal; float search_time; float trail_time; vec3_t last_sighting; int attack_state; int lefty; float idle_time; int linkcount; } monsterinfo_t; //tactical typedef struct { qboolean alienComputer; int alienComputerHealth; qboolean alienPowerSource; int alienPowerSourceHealth; qboolean alienAmmoDepot; int alienAmmoDepotHealth; qboolean alienBackupGen; qboolean humanComputer; int humanComputerHealth; qboolean humanPowerSource; int humanPowerSourceHealth; qboolean humanAmmoDepot; int humanAmmoDepotHealth; qboolean humanBackupGen; } tactical_t; extern game_locals_t game; extern level_locals_t level; extern game_import_t gi; extern game_export_t globals; extern spawn_temp_t st; extern g_vote_t playervote; extern tactical_t tacticalScore; extern int sm_meat_index; extern int red_team_score; extern int blue_team_score; extern int red_team_matches; //for tca extern int blue_team_matches; //for tca extern int reddiff; extern int bluediff; extern int redwinning; extern int print1; extern int print2; extern int print3; // means of death #define MOD_UNKNOWN 0 #define MOD_BLASTER 1 #define MOD_VIOLATOR 2 #define MOD_CGALTFIRE 3 #define MOD_CHAINGUN 5 #define MOD_FLAME 6 #define MOD_ROCKET 8 #define MOD_R_SPLASH 9 #define MOD_BEAMGUN 10 #define MOD_DISRUPTOR 11 #define MOD_SMARTGUN 12 #define MOD_VAPORIZER 13 #define MOD_VAPORALTFIRE 14 #define MOD_PLASMA_SPLASH 16 #define MOD_WATER 17 #define MOD_SLIME 18 #define MOD_LAVA 19 #define MOD_CRUSH 20 #define MOD_TELEFRAG 21 #define MOD_FALLING 22 #define MOD_SUICIDE 23 #define MOD_CAMPING 24 #define MOD_EXPLOSIVE 25 #define MOD_BARREL 26 #define MOD_BOMB 27 #define MOD_EXIT 28 #define MOD_SPLASH 29 #define MOD_TARGET_LASER 30 #define MOD_TRIGGER_HURT 31 #define MOD_DEATHRAY 32 #define MOD_TARGET_BLASTER 33 #define MOD_GRAPPLE 34 #define MOD_HEADSHOT 35 #define MOD_MINDERASER 36 #define MOD_SPIDER 37 #define MOD_FRIENDLY_FIRE 0x8000000 extern int meansOfDeath; extern edict_t *g_edicts; #define FOFS(x)(ptrdiff_t)&(((edict_t *)0)->x) #define STOFS(x)(ptrdiff_t)&(((spawn_temp_t *)0)->x) #define LLOFS(x)(ptrdiff_t)&(((level_locals_t *)0)->x) #define CLOFS(x)(ptrdiff_t)&(((gclient_t *)0)->x) #define random() ((rand() & 0x7fff) / ((float)0x7fff)) #define crandom() (2.0 * (random() - 0.5)) extern cvar_t *maxentities; extern cvar_t *deathmatch; extern cvar_t *ctf; extern cvar_t *tca; extern cvar_t *cp; extern cvar_t *dmflags; extern cvar_t *skill; extern cvar_t *fraglimit; extern cvar_t *timelimit; extern cvar_t *password; extern cvar_t *spectator_password; extern cvar_t *needpass; extern cvar_t *g_select_empty; extern cvar_t *g_dedicated; extern cvar_t *motdfile; extern cvar_t *motdforce; extern cvar_t *filterban; extern cvar_t *sv_gravity; extern cvar_t *sv_maxvelocity; extern cvar_t *gun_x, *gun_y, *gun_z; extern cvar_t *sv_rollspeed; extern cvar_t *sv_rollangle; extern cvar_t *run_pitch; extern cvar_t *run_roll; extern cvar_t *bob_up; extern cvar_t *bob_pitch; extern cvar_t *bob_roll; extern cvar_t *sv_cheats; extern cvar_t *g_maxclients; extern cvar_t *maxspectators; extern cvar_t *flood_msgs; extern cvar_t *flood_persecond; extern cvar_t *flood_waitdelay; extern cvar_t *sv_maplist; extern cvar_t *g_background_music; extern cvar_t *sv_botkickthreshold; extern cvar_t *sv_custombots; //mutators extern cvar_t *instagib; extern cvar_t *rocket_arena; extern cvar_t *insta_rockets; extern cvar_t *low_grav; extern cvar_t *regeneration; extern cvar_t *vampire; extern cvar_t *excessive; extern cvar_t *grapple; extern cvar_t *classbased; //duel mode extern cvar_t *g_duel; //tactical mode extern cvar_t *g_tactical; extern cvar_t *g_losehealth; extern cvar_t *g_losehealth_num; //weapons extern cvar_t *wep_selfdmgmulti; //health/max health/max ammo extern cvar_t *g_spawnhealth; extern cvar_t *g_maxhealth; extern cvar_t *g_maxbullets; extern cvar_t *g_maxshells; extern cvar_t *g_maxrockets; extern cvar_t *g_maxgrenades; extern cvar_t *g_maxcells; extern cvar_t *g_maxslugs; extern cvar_t *g_maxseekers; extern cvar_t *g_maxbombs; //quick weapon change extern cvar_t *quickweap; //anti-camp extern cvar_t *anticamp; extern cvar_t *camptime; extern cvar_t *ac_frames; extern cvar_t *ac_threshold; extern cvar_t *g_randomquad; //warmup time extern cvar_t *warmuptime; //spawn protection extern cvar_t *g_spawnprotect; //jousting extern cvar_t *joustmode; //map voting extern cvar_t *g_mapvote; extern cvar_t *g_voterand; extern cvar_t *g_votemode; extern cvar_t *g_votesame; //call voting extern cvar_t *g_callvote; //forced autobalanced teams extern cvar_t *g_autobalance; //reward point threshold extern cvar_t *g_reward; //show player lights for visibility even in non-team games extern cvar_t *g_dmlights; #define world (&g_edicts[0]) // item spawnflags #define ITEM_TRIGGER_SPAWN 0x00000001 #define ITEM_NO_TOUCH 0x00000002 // 6 bits reserved for editor flags // 8 bits used as power cube id bits for coop games #define DROPPED_ITEM 0x00010000 #define DROPPED_PLAYER_ITEM 0x00020000 #define ITEM_TARGETS_USED 0x00040000 // // fields are needed for spawning from the entity string // and saving / loading games // #define FFL_SPAWNTEMP 1 #define FFL_NOSPAWN 2 typedef enum { F_INT, F_FLOAT, F_LSTRING, // string on disk, pointer in memory, TAG_LEVEL F_GSTRING, // string on disk, pointer in memory, TAG_GAME F_VECTOR, F_ANGLEHACK, F_EDICT, // index on disk, pointer in memory F_ITEM, // index on disk, pointer in memory F_CLIENT, // index on disk, pointer in memory F_FUNCTION, F_MMOVE, F_IGNORE } fieldtype_t; typedef struct { char *name; int ofs; fieldtype_t type; int flags; } field_t; extern field_t fields[]; extern gitem_t itemlist[]; //mind eraser globals extern float mindEraserTime; // // g_cmds.c // void Cmd_Score_f (edict_t *ent); void Cmd_VoiceTaunt_f (edict_t *ent); // // g_items.c // void PrecacheItem (gitem_t *it); void InitItems (void); void SetItemNames (void); gitem_t *FindItem (char *pickup_name); gitem_t *FindItemByClassname (char *classname); #define ITEM_INDEX(x) ((x)-itemlist) edict_t *Drop_Item (edict_t *ent, gitem_t *item); void SetRespawn (edict_t *ent, float delay); void ChangeWeapon (edict_t *ent); void SpawnItem (edict_t *ent, gitem_t *item); void DoRespawn (edict_t *ent); void Think_Weapon (edict_t *ent); int ArmorIndex (edict_t *ent); gitem_t *GetItemByIndex (int index); qboolean Add_Ammo (edict_t *ent, gitem_t *item, int count, qboolean weapon, qboolean dropped); void Touch_Item (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf); //CTF void CTFDeadDropFlag(edict_t *self, edict_t *other); void CTFResetFlag(int team); void CTFEffects(edict_t *player); void CTFScoreboardMessage (edict_t *ent, edict_t *killer, int mapvote); void CTFPrecache(void); void CTFFlagSetup (edict_t *ent); qboolean CTFPickup_Flag (edict_t *ent, edict_t *other); void CTFDrop_Flag(edict_t *ent, gitem_t *item); //Vehicles void Reset_player(edict_t *ent); void Jet_Explosion(edict_t *ent); qboolean Jet_Active(edict_t *ent); void Jet_ApplyJet( edict_t *ent, usercmd_t *ucmd ); qboolean Jet_AvoidGround( edict_t *ent ); void VehicleDeadDrop(edict_t *self); void VehicleSetup (edict_t *ent); qboolean Get_in_vehicle (edict_t *ent, edict_t *other); void Leave_vehicle(edict_t *ent, gitem_t *item); //deathball void ResetDeathball(); void DeadDropDeathball(edict_t *self); void DeathballSetup (edict_t *ent); qboolean Pickup_deathball (edict_t *ent, edict_t *other); void DeathballDrop(edict_t *ent, gitem_t *item); // // g_utils.c // qboolean KillBox (edict_t *ent); void G_ProjectSource (vec3_t point, vec3_t distance, vec3_t forward, vec3_t right, vec3_t result); edict_t *G_Find (edict_t *from, int fieldofs, char *match); edict_t *findradius (edict_t *from, vec3_t org, float rad); edict_t *G_PickTarget (char *targetname); void G_UseTargets (edict_t *ent, edict_t *activator); void G_SetMovedir (vec3_t angles, vec3_t movedir); void G_InitEdict (edict_t *e); edict_t *G_Spawn (void); void G_FreeEdict (edict_t *e); void G_TouchTriggers (edict_t *ent); void G_TouchSolids (edict_t *ent); char *G_CopyString (const char *in); void G_CleanPlayerName ( const char *source, char *dest ); float *tv (float x, float y, float z); char *vtos (vec3_t v); float vectoyaw (vec3_t vec); // void vectoangles (vec3_t vec, vec3_t angles); // // g_combat.c // qboolean OnSameTeam (edict_t *ent1, edict_t *ent2); qboolean CanDamage (edict_t *targ, edict_t *inflictor); void T_Damage (edict_t *targ, edict_t *inflictor, edict_t *attacker, vec3_t dir, vec3_t point, vec3_t normal, int damage, int knockback, int dflags, int mod); void T_RadiusDamage (edict_t *inflictor, edict_t *attacker, float damage, edict_t *ignore, float radius, int mod, int weapon); // damage flags #define DAMAGE_RADIUS 0x00000001 // damage was indirect #define DAMAGE_NO_ARMOR 0x00000002 // armour does not protect from this damage #define DAMAGE_ENERGY 0x00000004 // damage is from an energy based weapon #define DAMAGE_NO_KNOCKBACK 0x00000008 // do not affect velocity, just view angles #define DAMAGE_BULLET 0x00000010 // damage is from a bullet (used for ricochets) #define DAMAGE_NO_PROTECTION 0x00000020 // armor, shields, invulnerability, and godmode have no effect #define DEFAULT_BULLET_HSPREAD 300 #define DEFAULT_BULLET_VSPREAD 300 #define DEFAULT_SHOTGUN_HSPREAD 1000 #define DEFAULT_SHOTGUN_VSPREAD 500 #define DEFAULT_DEATHMATCH_SHOTGUN_COUNT 12 #define DEFAULT_SHOTGUN_COUNT 12 #define DEFAULT_SSHOTGUN_COUNT 15 // // g_monster.c // void M_droptofloor (edict_t *ent); void monster_think (edict_t *self); void walkmonster_start (edict_t *self); void swimmonster_start (edict_t *self); void flymonster_start (edict_t *self); void AttackFinished (edict_t *self, float time); void monster_death_use (edict_t *self); void M_CatagorizePosition (edict_t *ent); qboolean M_CheckAttack (edict_t *self); void M_FlyCheck (edict_t *self); void M_CheckGround (edict_t *ent); void M_SetEffects (edict_t *ent); // // g_misc.c // void ThrowClientHead (edict_t *self, int damage); void ThrowGib (edict_t *self, char *gibname, int damage, int type, int effects); void BecomeExplosion1 (edict_t *self); // // g_ai.c // void AI_SetSightClient (void); void ai_stand (edict_t *self, float dist); void ai_move (edict_t *self, float dist); void ai_walk (edict_t *self, float dist); void ai_turn (edict_t *self, float dist); void ai_still (edict_t *self, float dist); void ai_run (edict_t *self, float dist); void ai_charge (edict_t *self, float dist); int range (edict_t *self, edict_t *other); void FoundTarget (edict_t *self); qboolean infront (edict_t *self, edict_t *other); qboolean visible (edict_t *self, edict_t *other); qboolean FacingIdeal(edict_t *self); // // g_weapon.c // void ThrowDebris (edict_t *self, char *modelname, float speed, vec3_t origin); void ThrowDebris2 (edict_t *self, char *modelname, float speed, vec3_t origin); #ifdef ALTERIA void fire_punch(edict_t *self, vec3_t start, vec3_t aimdir, int damage); #else void fire_bullet (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, int mod); void fire_shotgun (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, int count, int mod); void fire_blaster (edict_t *self, vec3_t start, vec3_t muzzle, vec3_t aimdir, int damage, int speed, int effect, qboolean hyper); void fire_rocket (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage); void fire_homingrocket (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage); void fire_disruptor (edict_t *self, vec3_t start, vec3_t muzzle, vec3_t aimdir, int damage, int kick); void fire_bomb (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage, float timer); void fire_blaster_beam (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, qboolean detonate, qboolean alien); void fire_smartgrenade (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage, float timer); void fire_smartgrenade_alien (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage, float timer); void fire_flamethrower(edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius); void fire_hover_beam (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, qboolean detonate); void fire_minderaser (edict_t *self, vec3_t start, vec3_t dir, float timer); void fire_spider (edict_t *self, vec3_t start, vec3_t aimdir, int speed); void fire_vaporizer (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick); void fire_blasterball (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, int effect, qboolean hyper, qboolean alien); void fire_prox (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage, float timer); void fire_fireball (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float damage_radius, int radius_damage); void fire_violator(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int alt); void fire_tacticalbomb (edict_t *self, vec3_t start, vec3_t aimdir, int speed); #endif //deathball void fire_deathball (edict_t *self, vec3_t start, vec3_t dir, int speed); //grapple typedef enum { CTF_GRAPPLE_STATE_FLY, CTF_GRAPPLE_STATE_PULL, CTF_GRAPPLE_STATE_HANG } ctfgrapplestate_t; #define CTF_GRAPPLE_SPEED 1650 // speed of grapple in flight #define CTF_GRAPPLE_PULL_SPEED 1650 // speed player is pulled at // GRAPPLE void CTFWeapon_Grapple (edict_t *ent); void CTFPlayerResetGrapple(edict_t *ent); void CTFGrapplePull(edict_t *self); void CTFResetGrapple(edict_t *self); // // g_ptrail.c // void PlayerTrail_Init (void); void PlayerTrail_Add (vec3_t spot); void PlayerTrail_New (vec3_t spot); edict_t *PlayerTrail_PickFirst (edict_t *self); edict_t *PlayerTrail_PickNext (edict_t *self); edict_t *PlayerTrail_LastSpot (void); // // p_client.c // void respawn (edict_t *ent); void BeginIntermission (edict_t *targ); void EndIntermission (void); void PutClientInServer (edict_t *ent); void InitClientPersistant (gclient_t *client); void InitClientResp (gclient_t *client); void InitBodyQue (void); void ClientBeginServerFrame (edict_t *ent); void Q2_FindFile (char *filename, FILE **file); void ClientPlaceInQueue(edict_t *ent); void ClientCheckQueue(edict_t *ent); void MoveClientsDownQueue(edict_t *ent); void SaveClientData (void); void FetchClientEntData (edict_t *ent); void TeamCensus( teamcensus_t* team_census ); void ParseClassFile( char *config_file, edict_t *ent ); //unlagged - g_unlagged.c void G_ResetHistory( edict_t *ent ); void G_StoreHistory( edict_t *ent ); void G_TimeShiftAllClients( int time, edict_t *skip ); void G_UnTimeShiftAllClients( edict_t *skip ); void G_DoTimeShiftFor( edict_t *ent ); void G_UndoTimeShiftFor( edict_t *ent ); void G_UnTimeShiftClient( edict_t *ent ); void G_AntilagProjectile( edict_t *ent ); //unlagged - g_unlagged.c // // g_player.c // void player_pain (edict_t *self, edict_t *other, float kick, int damage); void player_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point); // // g_svcmds.c // void ServerCommand (void); qboolean SV_FilterPacket (char *from); // // p_view.c // void ClientEndServerFrame (edict_t *ent); // // p_hud.c // void MoveClientToIntermission (edict_t *client); void G_UpdateStats (edict_t *ent); void ValidateSelectedItem (edict_t *ent); void DeathmatchScoreboardMessage (edict_t *client, edict_t *killer, int mapvote); // // p_weapon.c // void P_ProjectSource (gclient_t *client, vec3_t point, vec3_t distance, vec3_t forward, vec3_t right, vec3_t result); void Weapon_Generic (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int FRAME_IDLE_LAST, int FRAME_DEACTIVATE_LAST, int *pause_frames, int *fire_frames, void (*fire)(edict_t *ent)); void PlayerNoise(edict_t *who, vec3_t where, int type); // // m_move.c // qboolean M_CheckBottom (edict_t *ent); qboolean M_walkmove (edict_t *ent, float yaw, float dist); void M_MoveToGoal (edict_t *ent, float dist); void M_ChangeYaw (edict_t *ent); // // g_phys.c // void G_RunEntity (edict_t *ent, float timespan); void SV_CheckVelocity (edict_t *ent); // // g_chase.c // void UpdateChaseCam(edict_t *ent); void ChaseNext(edict_t *ent); void ChasePrev(edict_t *ent); void GetChaseTarget(edict_t *ent); // // g_main.c // qboolean G_NameMatch( const char* netname, const char *kickname ); // // Spawn functions // extern void SP_item_health (edict_t *self); extern void SP_item_health_small (edict_t *self); extern void SP_item_health_large (edict_t *self); extern void SP_item_health_mega (edict_t *self); extern void SP_info_player_start (edict_t *ent); extern void SP_info_player_deathmatch (edict_t *ent); extern void SP_info_player_intermission (edict_t *ent); extern void SP_info_player_red (edict_t *ent); extern void SP_info_player_blue(edict_t *ent); extern void SP_func_plat (edict_t *ent); extern void SP_func_rotating (edict_t *ent); extern void SP_func_button (edict_t *ent); extern void SP_func_door (edict_t *ent); extern void SP_func_door_secret (edict_t *ent); extern void SP_func_door_rotating (edict_t *ent); extern void SP_func_water (edict_t *ent); extern void SP_func_train (edict_t *ent); extern void SP_func_conveyor (edict_t *self); extern void SP_func_wall (edict_t *self); extern void SP_func_object (edict_t *self); extern void SP_func_explosive (edict_t *self); extern void SP_func_timer (edict_t *self); extern void SP_func_areaportal (edict_t *ent); extern void SP_func_killbox (edict_t *ent); extern void SP_trigger_always (edict_t *ent); extern void SP_trigger_once (edict_t *ent); extern void SP_trigger_multiple (edict_t *ent); extern void SP_trigger_relay (edict_t *ent); extern void SP_trigger_push (edict_t *ent); extern void SP_trigger_hurt (edict_t *ent); extern void SP_trigger_key (edict_t *ent); extern void SP_trigger_counter (edict_t *ent); extern void SP_trigger_elevator (edict_t *ent); extern void SP_trigger_gravity (edict_t *ent); extern void SP_trigger_monsterjump (edict_t *ent); extern void SP_trigger_deathballtarget (edict_t *ent); extern void SP_trigger_reddeathballtarget (edict_t *ent); extern void SP_trigger_bluedeathballtarget (edict_t *ent); extern void SP_trigger_redcowtarget ( edict_t *ent); extern void SP_trigger_bluecowtarget (edict_t *ent); extern void SP_target_temp_entity (edict_t *ent); extern void SP_target_speaker (edict_t *ent); extern void SP_target_explosion (edict_t *ent); extern void SP_target_secret (edict_t *ent); extern void SP_target_splash (edict_t *ent); extern void SP_target_steam (edict_t *ent); extern void SP_target_spawner (edict_t *ent); extern void SP_target_blaster (edict_t *ent); extern void SP_target_laser (edict_t *self); extern void SP_target_lightramp (edict_t *self); extern void SP_target_earthquake (edict_t *ent); extern void SP_target_fire (edict_t *ent); extern void SP_target_changelevel (edict_t *ent); extern void SP_worldspawn (edict_t *ent); extern void SP_light (edict_t *self); extern void SP_info_null (edict_t *self); extern void SP_info_notnull (edict_t *self); extern void SP_path_corner (edict_t *self); extern void SP_point_combat (edict_t *self); extern void SP_misc_teleporter (edict_t *self); extern void SP_misc_teleporter_dest (edict_t *self); extern void SP_npc_cow (edict_t *self); extern void SP_npc_deathray(edict_t *self); //TCA extern void SP_misc_spiderpod (edict_t *self); extern void SP_misc_rednode (edict_t *self); extern void SP_misc_bluenode (edict_t *self); extern void SP_misc_bluespidernode (edict_t *self); extern void SP_misc_redspidernode (edict_t *self); //Tactical extern void SP_misc_aliencomputer (edict_t *self); extern void SP_misc_humancomputer (edict_t *self); extern void SP_misc_alienpowersrc (edict_t *self); extern void SP_misc_humanpowersrc (edict_t *self); extern void SP_misc_alienammodepot (edict_t *self); extern void SP_misc_humanammodepot (edict_t *self); extern void SP_misc_alienbackupgen (edict_t *self); extern void SP_misc_humanbackupgen (edict_t *self); extern void SP_misc_deathray (edict_t *self); extern void SP_misc_laser (edict_t *self); extern void SP_misc_mapmodel (edict_t *self); extern void SP_misc_watersplash (edict_t *ent); extern void SP_misc_electroflash (edict_t *ent); //============================================================================ // client_t->anim_priority #define ANIM_BASIC 0 // stand / run #define ANIM_WAVE 1 #define ANIM_JUMP 2 #define ANIM_PAIN 3 #define ANIM_ATTACK 4 #define ANIM_DEATH 5 #define ANIM_REVERSE 6 #define BASE_ROCKETS 10 #define BASE_SHELLS 10 #define BASE_CELLS 50 #define BASE_SLUGS 10 #define BASE_GRENADES 50 #define BASE_BULLETS 50 #define BASE_SEEKERS 1 #define BASE_BOMBS 1 // client data that stays across multiple level loads typedef struct { char userinfo[MAX_INFO_STRING]; char netname[(PLAYERNAME_GLYPHS*3)+1]; // name from cvar // room for "rainbow" name, but is truncated to PLAYERNAME_SIZE int hand; qboolean connected; // a loadgame will leave valid entities that // just don't have a connection yet // values saved and restored from edicts when changing levels int health; int max_health; int savedFlags; int selected_item; int inventory[MAX_ITEMS]; // ammo capacities int max_bullets; int max_shells; int max_rockets; int max_grenades; int max_cells; int max_slugs; int max_seekers; int max_bombs; gitem_t *weapon; gitem_t *lastweapon; gitem_t *lastfailedswitch; float failedswitch_framenum; int game_helpchanged; int helpchanged; int spectator; // client is a spectator int queue; // client queue position for duel mode //unlagged - client options // these correspond with variables in the userinfo string int delag; int debugDelag; int cmdTimeNudge; //unlagged - client options //unlagged - lag simulation #2 int latentSnaps; int latentCmds; int plOut; usercmd_t cmdqueue[MAX_LATENT_CMDS]; int cmdhead; //unlagged - lag simulation #2 //unlagged - true ping int realPing; int pingsamples[NUM_PING_SAMPLES]; int samplehead; //unlagged - true ping } client_persistant_t; //unlagged - backward reconciliation #1 // the size of history we'll keep #define NUM_CLIENT_HISTORY 17 // everything we need to know to backward reconcile typedef struct { vec3_t mins, maxs; vec3_t currentOrigin; int leveltime; } clientHistory_t; //unlagged - backward reconciliation #1 // client data that stays across deathmatch respawns typedef struct { int enterframe; // level.framenum the client entered the game int score; // frags, etc int deaths; // deaths, etc vec3_t cmd_angles; // angles sent over in the last command //bot score info int botnum; bot_t bots[100]; //weapon accuracy info int weapon_shots[9]; int weapon_hits[9]; //reward points int reward_pts; qboolean powered; //voting qboolean voted; int spectator; // client is a spectator } client_respawn_t; // this structure is cleared on each PutClientInServer(), // except for 'client->pers' struct gclient_s { // known to server player_state_t ps; // communicated by server to clients int ping; // private to game client_persistant_t pers; client_respawn_t resp; pmove_state_t old_pmove; // for detecting out-of-pmove changes qboolean showscores; // set layout stat qboolean showinventory; // set layout stat qboolean showhelp; qboolean showhelpicon; /** @brief "Message of the day" frames left * * Prevent centerprinting until the MOTD has been displayed * for some time. This makes sure players can actually read * the MOTD. */ int motd_frames; //stuff for bots qboolean is_bot; /* --------------------------*/ /* * this is identical to declarations in edict_t * it appears this data in gclient_s is not used. */ int skill; char faveweap[64]; float weapacc[10]; float accuracy; float awareness; char chatmsg1[128]; char chatmsg2[128]; char chatmsg3[128]; char chatmsg4[128]; char chatmsg5[128]; char chatmsg6[128]; char chatmsg7[128]; char chatmsg8[128]; /*----------------------------*/ int ammo_index; int buttons; int oldbuttons; int latched_buttons; qboolean weapon_thunk; gitem_t *newweapon; // sum up damage over an entire frame, so // shotgun blasts give a single big kick int damage_armor; // damage absorbed by armor int damage_blood; // damage taken out of health int damage_knockback; // impact damage vec3_t damage_from; // origin for vector calculation float killer_yaw; // when dead, look at killer weaponstate_t weaponstate; vec3_t kick_angles; // weapon kicks vec3_t kick_origin; float v_dmg_roll, v_dmg_pitch, v_dmg_time; // damage kicks float fall_time, fall_value; // for view drop on fall float damage_alpha; float bonus_alpha; vec3_t damage_blend; vec3_t v_angle; // aiming direction float bobtime; // so off-ground doesn't change it vec3_t oldviewangles; vec3_t oldvelocity; float next_drown_time; int old_waterlevel; int breather_sound; int machinegun_shots; // for weapon raising // animation vars int anim_end; int anim_priority; qboolean anim_duck; qboolean anim_run; // powerup timers float quad_framenum; float invincible_framenum; float haste_framenum; float sproing_framenum; float regen_framenum; float invis_framenum; float losehealth_framenum; qboolean grenade_blew_up; float grenade_time; int silencer_shots; int weapon_sound; float pickup_msg_time; float flood_locktill; // locked from talking float flood_when[10]; // when messages were said int flood_whenhead; // head pointer for when said float respawn_time; // can respawn when time > this edict_t *chase_target; // player we are chasing qboolean update_chase; // need to update chase info? //team int dmteam; //chasecam int chasetoggle; edict_t *chasecam; edict_t *oldplayer; //vehicles qboolean in_vehicle; float Jet_framenum; /*burn out time when jet is activated*/ float Jet_remaining; /*remaining fuel time*/ float Jet_next_think; //deathball qboolean in_deathball; //grapple void *ctf_grapple; // entity of grapple int ctf_grapplestate; // true if pulling float ctf_grapplereleasetime; // time of grapple release //kill streaks int kill_streak; //obviously this *will* get cleared at each respawn in most cases //joust attempts - for limiting how many times you can joust at a time int joustattempts; //homing rocket limits int homing_shots; //movetime - used for special moves float lastmovetime; int lastsidemove; int lastforwardmove; int dodge; int moved; int keydown; float lastdodge; float spawnprotecttime; qboolean spawnprotected; //map voting int mapvote; //taunt message float lasttaunttime; //deathray immunity qboolean rayImmunity; float rayTime; //unlagged - backward reconciliation #1 // the serverTime the button was pressed // (stored before pmove_fixed changes serverTime) int attackTime; // the head of the history queue int historyHead; // the history queue clientHistory_t history[NUM_CLIENT_HISTORY]; // the client's saved position clientHistory_t saved; // used to restore after time shift // an approximation of the actual server time we received this // command (not in 50ms increments) int frameOffset; //unlagged - backward reconciliation #1 //unlagged - smooth clients #1 // the last frame number we got an update from this client int lastUpdateFrame; //unlagged - smooth clients #1 }; struct edict_s { entity_state_t s; struct gclient_s *client; // NULL if not a player // the server expects the first part // of gclient_s to be a player_state_t // but the rest of it is opaque qboolean inuse; int linkcount; // FIXME: move these fields to a server private sv_entity_t link_t area; // linked to a division node or leaf int num_clusters; // if -1, use headnode instead int clusternums[MAX_ENT_CLUSTERS]; int headnode; // unused if num_clusters != -1 int areanum, areanum2; //================================ int svflags; vec3_t mins, maxs; vec3_t absmin, absmax, size; solid_t solid; int clipmask; edict_t *owner; int redirect_number; //for ghost mode // must be accessible to server code for collision detection int dmteam; int teamset; #define RED_TEAM 0 #define BLUE_TEAM 1 #define NO_TEAM 2 // DO NOT MODIFY ANYTHING ABOVE THIS, THE SERVER // EXPECTS THE FIELDS IN THAT ORDER! //================================ int movetype; int flags; char *model; float freetime; // sv.time when the object was freed // // only used locally in game, not by server // char *message; char *classname; int spawnflags; float timestamp; float angle; // set in qe3, -1 = up, -2 = down char *target; char *targetname; char *killtarget; char *team; char *pathtarget; char *deathtarget; char *combattarget; edict_t *target_ent; float speed, accel, decel; vec3_t movedir; vec3_t pos1, pos2; vec3_t velocity; vec3_t avelocity; int mass; float air_finished; float gravity; // per entity gravity multiplier (1.0 is normal) // use for lowgrav artifact, flares edict_t *goalentity; edict_t *movetarget; float yaw_speed; float ideal_yaw; float nextthink; void (*prethink) (edict_t *ent); void (*think)(edict_t *self); void (*blocked)(edict_t *self, edict_t *other); //move to moveinfo? void (*touch)(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf); void (*use)(edict_t *self, edict_t *other, edict_t *activator); void (*pain)(edict_t *self, edict_t *other, float kick, int damage); void (*die)(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point); float touch_debounce_time; // are all these legit? do we need more/less of them? float pain_debounce_time; float damage_debounce_time; float fly_sound_debounce_time; //move to clientinfo float last_move_time; int health; int max_health; int gib_health; int deadflag; qboolean show_hostile; char *map; // target_changelevel int viewheight; // height above origin where eyesight is determined int takedamage; int dmg; int radius_dmg; float dmg_radius; int sounds; //make this a spawntemp var? int count; edict_t *chain; edict_t *enemy; edict_t *oldenemy; edict_t *activator; edict_t *groundentity; int groundentity_linkcount; edict_t *teamchain; edict_t *teammaster; edict_t *mynoise; // can go in client only edict_t *mynoise2; int noise_index; int noise_index2; float volume; float attenuation; // timing variables float wait; float delay; // before firing targets float random; float teleport_time; int watertype; int waterlevel; vec3_t move_origin; vec3_t move_angles; // move this to clientinfo? int light_level; int style; // also used as areaportal number gitem_t *item; // for bonus items // common data blocks moveinfo_t moveinfo; monsterinfo_t monsterinfo; edict_t *flashlight; edict_t *replaced_weapon; // ACEBOT_ADD qboolean is_bot; qboolean is_jumping; // For movement vec3_t move_vector; float next_move_time; float wander_timeout; float suicide_timeout; // For node code int current_node; // current node int goal_node; // current goal node int next_node; // the node that will take us one step closer to our goal int node_timeout; int last_node; int tries; int state; //for config int skill; char faveweap[64]; float weapacc[10]; float accuracy; float awareness; char chatmsg1[128]; char chatmsg2[128]; char chatmsg3[128]; char chatmsg4[128]; char chatmsg5[128]; char chatmsg6[128]; char chatmsg7[128]; char chatmsg8[128]; // ACEBOT_END //chasecam int chasedist1; int chasedist2; // for deathcam to remember position of player's death vec3_t death_origin; //vehicles qboolean in_vehicle; //deathball qboolean in_deathball; //Flamethrower and fire vars float FlameDelay; int Flames; int FlameDamage; edict_t *orb; //Prox mines and grenades int nade_timer; //bombs int armed; //alt-fires qboolean altfire; //power nodes qboolean powered; //class(human = 0; alien = 1; robot = 2;) int ctype; //tactical mode qboolean has_bomb; qboolean has_detonator; qboolean has_vaporizor; qboolean has_minderaser; int armor_type; char charModel[128]; //model specific gibs int usegibs; char head[64]; char leg[64]; char arm[64]; char body[64]; // Anti-camp velocity accumulation /** @brief Velocities history * * At each server frame, a client's velocity will be stored inside * this array. While the array may contain up to 100 vectors, the * ac_frames CVar will determine how many of these vectors will be * used. */ vec3_t old_velocities[ 100 ]; /** @brief Velocity accumulator * * This vector contains the sum of velocities for the past frames. * The amount of frames that are indeed accumulated depends on the * value of the ac_frames CVar. */ vec3_t velocity_accum; /** @brief Velocities history index * * The last updated vector in the old_velocities array. */ int old_velocities_current; /** @brief Stored velocity vectors * * The actual amount of vectors currently stored in the old_velocities * array. */ int old_velocities_count; }; struct gmapvote_s { char mapname[32]; //ugg, end the pointer madness int tally; } votedmap[4]; extern char *winningmap; extern void CheckDeathcam_Viewent(edict_t *ent); extern void DeathcamRemove (edict_t *ent, char *opt); extern void DeathcamStart (edict_t *ent); extern void DeathcamTrack (edict_t *ent); //IP information typedef struct { unsigned mask; unsigned compare; } ipfilter_t; #define MAX_IPFILTERS 1024 ipfilter_t ipfilters[MAX_IPFILTERS]; int numipfilters; extern qboolean StringToFilter (char *s, ipfilter_t *f); //unlagged extern cvar_t *g_antilag; extern cvar_t *g_antilagdebug; extern cvar_t *g_antilagprojectiles; // ACEBOT_ADD #include "acesrc/acebot.h" // ACEBOT_END alien-arena-7.66+dfsg/source/game/p_hud.c0000600000175000017500000007534112161402010017270 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" /* ====================================================================== INTERMISSION ====================================================================== */ void MoveClientToIntermission (edict_t *ent) { if (deathmatch->integer) ent->client->showscores = true; VectorCopy (level.intermission_origin, ent->s.origin); ent->client->ps.pmove.origin[0] = level.intermission_origin[0]*8; ent->client->ps.pmove.origin[1] = level.intermission_origin[1]*8; ent->client->ps.pmove.origin[2] = level.intermission_origin[2]*8; VectorCopy (level.intermission_angle, ent->client->ps.viewangles); // 2011-05 stop spectator from drifting, // and, possibly, other intermission bogus movement. VectorClear( ent->velocity ); VectorClear( ent->avelocity); ent->client->ps.pmove.pm_type = PM_FREEZE; ent->client->ps.gunindex = 0; ent->client->ps.blend[3] = 0; ent->client->ps.rdflags &= ~RDF_UNDERWATER; // clean up powerup info ent->client->quad_framenum = 0; ent->client->invincible_framenum = 0; ent->client->haste_framenum = 0; ent->client->sproing_framenum = 0; ent->client->invis_framenum = 0; ent->client->grenade_blew_up = false; ent->client->grenade_time = 0; ent->viewheight = 0; ent->s.modelindex = 0; ent->s.modelindex2 = 0; ent->s.modelindex3 = 0; ent->s.modelindex4 = 0; ent->s.effects = 0; ent->s.sound = 0; ent->solid = SOLID_NOT; // add the layout if (deathmatch->integer) { DeathmatchScoreboardMessage (ent, NULL, g_mapvote->integer); gi.unicast (ent, true); } } void dumb_think(edict_t *ent) { //just a generic think ent->nextthink = level.time + 0.100; } void PlaceWinnerOnVictoryPad(edict_t *winner, int offset) { edict_t *pad; edict_t *chasecam; gclient_t *cl; vec3_t forward, right, movedir, origin; if(winner->in_vehicle) Reset_player(winner); VectorCopy (level.intermission_angle, winner->s.angles); //move it infront of everyone AngleVectors (level.intermission_angle, forward, right, NULL); VectorMA (level.intermission_origin, 100+abs(offset), forward, winner->s.origin); VectorMA (winner->s.origin, offset, right, winner->s.origin); winner->s.origin[2] +=8; winner->client->ps.pmove.origin[0] = winner->s.origin[0]; winner->client->ps.pmove.origin[1] = winner->s.origin[1]; winner->client->ps.pmove.origin[2] = winner->s.origin[2]; VectorClear( winner->velocity ); VectorClear( winner->avelocity ); if (deathmatch->integer) winner->client->showscores = true; winner->client->ps.gunindex = 0; winner->client->ps.pmove.pm_type = PM_FREEZE; winner->client->ps.blend[3] = 0; winner->client->ps.rdflags &= ~RDF_UNDERWATER; // clean up powerup info winner->client->quad_framenum = 0; winner->client->invincible_framenum = 0; winner->client->haste_framenum = 0; winner->client->sproing_framenum = 0; winner->client->invis_framenum = 0; winner->client->grenade_blew_up = false; winner->client->grenade_time = 0; winner->s.effects = EF_ROTATE; winner->s.renderfx = (RF_FULLBRIGHT | RF_GLOW | RF_NOSHADOWS); winner->s.sound = 0; winner->solid = SOLID_NOT; // add the layout if (deathmatch->integer) { DeathmatchScoreboardMessage (winner, NULL, g_mapvote->integer); gi.unicast (winner, true); } //create a new entity for the pad pad = G_Spawn(); VectorMA (winner->s.origin, 8, right, pad->s.origin); VectorCopy (level.intermission_angle, pad->s.angles); pad->s.origin[2] -= 8; pad->movetype = MOVETYPE_NONE; pad->solid = SOLID_NOT; pad->s.renderfx = (RF_FULLBRIGHT | RF_GLOW | RF_NOSHADOWS); pad->s.modelindex = gi.modelindex("models/objects/dmspot/tris.md2"); pad->think = NULL; pad->classname = "pad"; gi.linkentity (pad); movedir[0] = movedir[1] = 0; movedir[2] = -1; VectorCopy(pad->s.origin, origin); origin[2] -= 24; //if map is going to repeat - don't put these here as we have no way to remove them //if map is not reloaded if(strcmp(level.mapname, level.changemap)) { gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_STEAM); gi.WriteByte (100); gi.WritePosition (origin); gi.WriteDir (movedir); gi.WriteByte (0); gi.multicast (origin, MULTICAST_PVS); } //now we want to allow the winners to actually see themselves on the podium, creating a //simple chasecam if(winner->is_bot) { //who cares if bots can not see themselves! winner->takedamage = DAMAGE_NO; //so they stop burning and suiciding gi.linkentity(winner); //link because we changed position! return; } winner->client->chasetoggle = 1; chasecam = G_Spawn (); chasecam->owner = winner; chasecam->solid = SOLID_NOT; chasecam->movetype = MOVETYPE_FLYMISSILE; VectorCopy (level.intermission_angle, chasecam->s.angles); VectorClear (chasecam->mins); VectorClear (chasecam->maxs); VectorCopy (level.intermission_origin, chasecam->s.origin); chasecam->classname = "chasecam"; chasecam->think = NULL; winner->client->chasecam = chasecam; winner->client->oldplayer = G_Spawn(); if (!winner->client->oldplayer->client) { cl = (gclient_t *) malloc(sizeof(gclient_t)); winner->client->oldplayer->client = cl; /* printf("+++ Podiumcam = %p\n", winner->client->oldplayer->client); */ } if (winner->client->oldplayer) { winner->client->oldplayer->s.frame = winner->s.frame; VectorCopy (winner->s.origin, winner->client->oldplayer->s.origin); VectorCopy (winner->s.angles, winner->client->oldplayer->s.angles); } winner->client->oldplayer->s = winner->s; gi.linkentity (winner->client->oldplayer); //move the winner back to the intermission point VectorCopy (level.intermission_origin, winner->s.origin); winner->client->ps.pmove.origin[0] = level.intermission_origin[0]*8; winner->client->ps.pmove.origin[1] = level.intermission_origin[1]*8; winner->client->ps.pmove.origin[2] = level.intermission_origin[2]*8; VectorCopy (level.intermission_angle, winner->client->ps.viewangles); winner->s.modelindex = 0; winner->s.modelindex2 = 0; winner->s.modelindex3 = 0; winner->s.modelindex = 0; winner->s.effects = 0; winner->s.sound = 0; winner->solid = SOLID_NOT; } void BeginIntermission (edict_t *targ) { int i; edict_t *ent, *client=NULL; edict_t *winner = NULL; edict_t *firstrunnerup = NULL; edict_t *secondrunnerup = NULL; edict_t *cl_ent; int high_score, low_score; winner = NULL; firstrunnerup = NULL; secondrunnerup = NULL; if (level.intermissiontime) return; // already activated if ((dmflags->integer & DF_BOT_AUTOSAVENODES)) ACECM_Store(); //store the nodes automatically when changing levels. game.autosaved = false; for (i=0 ; iinteger ; i++) { client = g_edicts + 1 + i; if (!client->inuse) continue; // remove from vehicle. // note: vehicle hud is client-side, so may remain in view if (client->in_vehicle) { Reset_player( client ); } // respawn the dead if (client->health <= 0) { respawn(client); } client->s.frame = 0; // disconnect spectators from target to prevent point-of-view errors if ( client->client && client->client->resp.spectator ) { if ( client->client->chase_target != NULL ) { client->client->chase_target = NULL; client->client->ps.pmove.pm_flags &= ~PMF_NO_PREDICTION; } } if(!client->is_bot && g_mapvote->integer) safe_centerprintf(client, "Use F1-F4 to vote for next map!"); } level.intermissiontime = level.time; level.changemap = targ->map; level.exitintermission = 0; // find an intermission spot ent = G_Find (NULL, FOFS(classname), "info_player_intermission"); if (!ent) { // the map creator forgot to put in an intermission point... ent = G_Find (NULL, FOFS(classname), "info_player_start"); if (!ent) ent = G_Find(NULL, FOFS(classname), "info_player_blue"); if (!ent) ent = G_Find (NULL, FOFS(classname), "info_player_deathmatch"); } else { // chose one of four spots i = rand() & 3; while (i--) { ent = G_Find (ent, FOFS(classname), "info_player_intermission"); if (!ent) // wrap around the list ent = G_Find (ent, FOFS(classname), "info_player_intermission"); } } if ( ent == NULL ) { /* can occur when running a demo .dm2 file */ return; } VectorCopy (ent->s.origin, level.intermission_origin); VectorCopy (ent->s.angles, level.intermission_angle); low_score = 0; //get the lowest score in the game, and use that as the base high score to start for (i=0; iinuse || game.clients[i].resp.spectator) continue; if(game.clients[i].resp.score <= low_score) low_score = game.clients[i].resp.score; } //get the winning player's info high_score = low_score; for (i=0 ; iinuse || game.clients[i].resp.spectator) continue; if(game.clients[i].resp.score >= high_score) { winner = cl_ent; high_score = game.clients[i].resp.score; } } //get the first runner up's info high_score = low_score; for (i=0 ; iinuse || game.clients[i].resp.spectator || (cl_ent == winner)) continue; if(game.clients[i].resp.score >= high_score) { firstrunnerup = cl_ent; high_score = game.clients[i].resp.score; } } //get the second runner up's info high_score = low_score; for (i=0 ; iinuse || game.clients[i].resp.spectator || (cl_ent == winner) || (cl_ent == firstrunnerup)) continue; if(game.clients[i].resp.score >= high_score) { secondrunnerup = cl_ent; high_score = game.clients[i].resp.score; } } if(!winner) winner = g_edicts; if(!firstrunnerup) firstrunnerup = g_edicts; if(!secondrunnerup) secondrunnerup = g_edicts; // move all clients but the winners to the intermission point for (i=0 ; iinteger ; i++) { client = g_edicts + 1 + i; if (!client->inuse) continue; if((client != winner) && (client != firstrunnerup) && (client != secondrunnerup)) MoveClientToIntermission (client); } if ((dmflags->integer & DF_SKINTEAMS) || ctf->integer || tca->integer || cp->integer) //team stuff { if ( blue_team_score > red_team_score ) { if(ctf->integer || tca->integer || cp->integer) gi.sound (client, CHAN_AUTO, gi.soundindex("misc/blue_wins_ctf.wav"), 1, ATTN_NONE, 0); else gi.sound (client, CHAN_AUTO, gi.soundindex("misc/blue_wins.wav"), 1, ATTN_NONE, 0); } else if ( blue_team_score < red_team_score ) { if(ctf->integer || tca->integer || cp->integer) gi.sound (client, CHAN_AUTO, gi.soundindex("misc/red_wins_ctf.wav"), 1, ATTN_NONE, 0); else gi.sound (client, CHAN_AUTO, gi.soundindex("misc/red_wins.wav"), 1, ATTN_NONE, 0); } else { if ( ctf->integer ) { gi.sound( client, CHAN_AUTO, gi.soundindex("misc/game_tied_ctf.wav"), 1, ATTN_NONE, 0); } else { gi.sound( client, CHAN_AUTO, gi.soundindex("misc/game_tied.wav"), 1, ATTN_NONE, 0); } } } else if ( !(dmflags->integer & DF_BOT_LEVELAD) ) { if(winner->is_bot) gi.sound (ent, CHAN_AUTO, gi.soundindex("world/botwon.wav"), 1, ATTN_NONE, 0); else gi.sound (winner, CHAN_AUTO, gi.soundindex("world/youwin.wav"), 1, ATTN_STATIC, 0); } //place winner on victory pads, ala Q3 if(winner && winner->client && winner->inuse) PlaceWinnerOnVictoryPad(winner, 0); if(firstrunnerup && firstrunnerup->client && firstrunnerup->inuse) PlaceWinnerOnVictoryPad(firstrunnerup, 32); if(secondrunnerup && secondrunnerup->client && secondrunnerup->inuse) PlaceWinnerOnVictoryPad(secondrunnerup, -32); } //duel code int highestpos, numplayers; void MoveEveryoneDownQueue(void) { int i, induel = 0; for (i = 0; i < g_maxclients->integer; i++) { if(g_edicts[i+1].inuse && g_edicts[i+1].client) { //move everyone else down a notch(never less than 0) if(induel > 1 && g_edicts[i+1].client->pers.queue <= 3) //houston, we have a problem return; //abort, stop moving people if(g_edicts[i+1].client->pers.queue > 1) g_edicts[i+1].client->pers.queue-=1; if(g_edicts[i+1].client->pers.queue < 3) induel++; } } } void CheckDuelWinner(void) { int i; int highscore, induel; highscore = 0; numplayers = 0; highestpos = 0; induel = 0; for (i = 0; i < g_maxclients->integer; i++) { if(g_edicts[i+1].inuse && g_edicts[i+1].client) { if(g_edicts[i+1].client->resp.score > highscore) highscore = g_edicts[i+1].client->resp.score; if(g_edicts[i+1].client->pers.queue > highestpos) highestpos = g_edicts[i+1].client->pers.queue; numplayers++; } } if(highestpos < numplayers) highestpos = numplayers; for (i = 0; i < g_maxclients->integer; i++) { if(g_edicts[i+1].inuse && g_edicts[i+1].client) { if((g_edicts[i+1].client->resp.score < highscore) && g_edicts[i+1].client->pers.queue < 3) { g_edicts[i+1].client->pers.queue = highestpos+1; //loser, kicked to the back of the line highestpos++; } } } MoveEveryoneDownQueue(); //last resort checking after positions have changed //check for any screwups and correct the queue while(induel < 2 && numplayers > 1) { induel = 0; for (i = 0; i < g_maxclients->integer; i++) { if(g_edicts[i+1].inuse && g_edicts[i+1].client) { if(g_edicts[i+1].client->pers.queue < 3 && g_edicts[i+1].client->pers.queue) induel++; } } if(induel < 2) //something is wrong(i.e winner left), move everyone down. MoveEveryoneDownQueue(); } } void EndIntermission(void) { int i; edict_t *ent; if(g_duel->integer) CheckDuelWinner(); for (i=0 ; iinteger; i++) { ent = g_edicts + 1 + i; if (!ent->inuse || ent->client->resp.spectator) continue; if(!ent->is_bot && ent->client->chasetoggle > 0) { ent->client->chasetoggle = 0; /* Stop the chasecam from moving */ VectorClear (ent->client->chasecam->velocity); if(ent->client->oldplayer->client != NULL) { /* printf("--- Podiumcam = %p\n", ent->client->oldplayer->client);*/ free(ent->client->oldplayer->client); } G_FreeEdict (ent->client->oldplayer); G_FreeEdict (ent->client->chasecam); } } } /* ================== DeathmatchScoreboardMessage ================== */ void DeathmatchScoreboardMessage (edict_t *ent, edict_t *killer, int mapvote) { char entry[1024]; char string[1400]; int stringlength; int i, j, k; int sorted[MAX_CLIENTS]; int sortedscores[MAX_CLIENTS]; int score, total; int x, y; gclient_t *cl; edict_t *cl_ent; #if 0 // 2010-12 unused. see below char acc[16]; char weapname[16]; #endif if (ent->is_bot) return; if (g_tactical->integer) return; //no scoreboard in tactical mode if ((dmflags->integer & DF_SKINTEAMS) || ctf->value || tca->value || cp->value) { CTFScoreboardMessage (ent, killer, mapvote); return; } // sort the clients by score total = 0; for (i=0 ; iinuse || (!g_duel->integer && game.clients[i].resp.spectator)) continue; score = game.clients[i].resp.score; for (j=0 ; j sortedscores[j]) break; } for (k=total ; k>j ; k--) { sorted[k] = sorted[k-1]; sortedscores[k] = sortedscores[k-1]; } sorted[j] = i; sortedscores[j] = score; total++; } // print level name and exit rules string[0] = 0; stringlength = strlen(string); Com_sprintf (entry, sizeof(entry), "newsb "); j = strlen(entry); strcpy (string + stringlength, entry); stringlength += j; // add the clients in sorted order if (total > 12) total = 12; for (i=0 ; i 1024) break; strcpy (string + stringlength, entry); stringlength += j; // send the layout if(!cl->resp.spectator) Com_sprintf (entry, sizeof(entry), "client %i %i %i %i %i %i ", x, y, sorted[i], cl->resp.score, cl->ping, (level.framenum - cl->resp.enterframe)/600); else //duel mode will have queued spectators Com_sprintf (entry, sizeof(entry), "queued %i %i %i %i %i %i ", x, y, sorted[i], cl->resp.score, cl->ping, cl->pers.queue-2); j = strlen(entry); if (stringlength + j > 1024) break; strcpy (string + stringlength, entry); stringlength += j; } #if 0 /* * 2010-12 Def'd out. Probable major contributer to net comm * server->client overflow and dropped message errors. */ //weapon accuracy(don't do if map voting) if(!mapvote) { //add a background x = 96; y = 16*(total+1); Com_sprintf (entry, sizeof(entry), "xv %i yv %i picn %s ", x-4, y+48, "statbox"); j = strlen(entry); if(stringlength + j < 1024) { strcpy(string + stringlength, entry); stringlength +=j; } Com_sprintf(entry, sizeof(entry), "xv %i yv %i string Accuracy ", x, y+56); j = strlen(entry); if(stringlength + j < 1024) { strcpy(string + stringlength, entry); stringlength +=j; } for(i = 0; i < 9; i++) { //in case of scenarios where a weapon is scoring multiple hits per shot(ie smartgun) if(ent->client->resp.weapon_hits[i] > ent->client->resp.weapon_shots[i]) ent->client->resp.weapon_hits[i] = ent->client->resp.weapon_shots[i]; if(ent->client->resp.weapon_shots[i] == 0) strcpy(acc, "0%"); else { sprintf(acc, "%i", (100*ent->client->resp.weapon_hits[i]/ent->client->resp.weapon_shots[i])); strcat(acc, "%"); } switch (i) { case 0: strcpy(weapname, "blaster"); break; case 1: strcpy(weapname, "disruptor"); break; case 2: strcpy(weapname, "smartgun"); break; case 3: strcpy(weapname, "chaingun"); break; case 4: strcpy(weapname, "flame"); break; case 5: strcpy(weapname, "rocket"); break; case 6: strcpy(weapname, "beamgun"); break; case 7: strcpy(weapname, "vaporizer"); break; case 8: strcpy(weapname, "violator"); break; } Com_sprintf(entry, sizeof(entry), "xv %i yv %i string %s xv %i string %s ", x, y+((i+1)*9)+64, weapname, x+96, acc); j = strlen(entry); if(stringlength + j < 1024) { strcpy(string + stringlength, entry); stringlength +=j; } } } #endif //map voting if(mapvote) { y = 64; x = 96; Com_sprintf(entry, sizeof(entry), "xv %i yt %i string Vote ", x, y); j = strlen(entry); if(stringlength + j < 1024) { strcpy(string + stringlength, entry); stringlength +=j; } x = 136; Com_sprintf(entry, sizeof(entry), "xv %i yt %i string for ", x, y); j = strlen(entry); if(stringlength + j < 1024) { strcpy(string + stringlength, entry); stringlength +=j; } x = 168; Com_sprintf(entry, sizeof(entry), "xv %i yt %i string next ", x, y); j = strlen(entry); if(stringlength + j < 1024) { strcpy(string + stringlength, entry); stringlength +=j; } x = 208; Com_sprintf(entry, sizeof(entry), "xv %i yt %i string map: ", x, y); j = strlen(entry); if(stringlength + j < 1024) { strcpy(string + stringlength, entry); stringlength +=j; } x = 96; for(i=0; i<4; i++) { Com_sprintf(entry, sizeof(entry), "xv %i yt %i string F%i.%s ", x, y+((i+1)*9)+9, i+1, votedmap[i].mapname); j = strlen(entry); if(stringlength + j < 1024) { strcpy(string + stringlength, entry); stringlength +=j; } } } gi.WriteByte (svc_layout); gi.WriteString (string); } /* ================== DeathmatchScoreboard Draw instead of help message. Note that it isn't that hard to overflow the 1400 byte message limit! ================== */ void DeathmatchScoreboard (edict_t *ent) { if (ent->is_bot) return; DeathmatchScoreboardMessage (ent, ent->enemy, false); gi.unicast (ent, true); } /* ================== Cmd_Score_f Display the scoreboard ================== */ void Cmd_Score_f (edict_t *ent) { ent->client->showinventory = false; ent->client->showhelp = false; if (!deathmatch->integer) // Should we ever wish to do a singleplayer game, we could bring the // "help computer" back here. return; if (ent->client->showscores) { ent->client->showscores = false; return; } ent->client->showscores = true; DeathmatchScoreboard (ent); } //======================================================================= /* =============== G_SetScoreStats Common with G_SetStats and G_SetSpectatorStats =============== */ void G_SetScoreStats (edict_t *ent) { edict_t *e2; int i; int high_score = 0; // highest scorer for (i = 0, e2 = g_edicts + 1; i < g_maxclients->integer; i++, e2++) { if (!e2->inuse) continue; if(e2->client->resp.score > high_score) high_score = e2->client->resp.score; } ent->client->ps.stats[STAT_HIGHSCORE] = high_score; ent->client->ps.stats[STAT_SCOREBOARD] = gi.imageindex ("i_score"); //team ent->client->ps.stats[STAT_REDSCORE] = red_team_score; ent->client->ps.stats[STAT_BLUESCORE] = blue_team_score; if (tca->integer) { ent->client->ps.stats[STAT_RED_MATCHES] = red_team_matches; ent->client->ps.stats[STAT_BLUE_MATCHES] = blue_team_matches; } if (g_tactical->integer) //just use the weapon slots since these aren't displayed in tactical anyway { ent->client->ps.stats[STAT_TACTICAL_SCORE] = gi.imageindex ("i_tactical"); ent->client->ps.stats[STAT_WEAPN1] = tacticalScore.humanComputerHealth; ent->client->ps.stats[STAT_WEAPN2] = tacticalScore.humanPowerSourceHealth; ent->client->ps.stats[STAT_WEAPN3] = tacticalScore.humanAmmoDepotHealth; ent->client->ps.stats[STAT_WEAPN4] = tacticalScore.alienComputerHealth; ent->client->ps.stats[STAT_WEAPN5] = tacticalScore.alienPowerSourceHealth; ent->client->ps.stats[STAT_WEAPN6] = tacticalScore.alienAmmoDepotHealth; } } /* =============== G_SetStats =============== */ void G_SetStats (edict_t *ent) { gitem_t *item; int index; int i; gitem_t *flag1_item, *flag2_item; flag1_item = FindItemByClassname("item_flag_red"); flag2_item = FindItemByClassname("item_flag_blue"); // // health // ent->client->ps.stats[STAT_HEALTH_ICON] = level.pic_health; ent->client->ps.stats[STAT_HEALTH] = ent->health; // // ammo // if (!ent->client->ammo_index /* || !ent->client->pers.inventory[ent->client->ammo_index] */) { ent->client->ps.stats[STAT_AMMO_ICON] = 0; ent->client->ps.stats[STAT_AMMO] = 0; } else { item = &itemlist[ent->client->ammo_index]; ent->client->ps.stats[STAT_AMMO_ICON] = gi.imageindex (item->icon); ent->client->ps.stats[STAT_AMMO] = ent->client->pers.inventory[ent->client->ammo_index]; } // // armor // index = ArmorIndex (ent); if (index) { item = GetItemByIndex (index); ent->client->ps.stats[STAT_ARMOR_ICON] = 0; ent->client->ps.stats[STAT_ARMOR] = ent->client->pers.inventory[index]; } else { ent->client->ps.stats[STAT_ARMOR_ICON] = 0; ent->client->ps.stats[STAT_ARMOR] = 0; } // // timers // if (ent->client->quad_framenum > level.framenum) { ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_quad"); ent->client->ps.stats[STAT_TIMER] = (ent->client->quad_framenum - level.framenum)/10; } else if (ent->client->invincible_framenum > level.framenum) { ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_invulnerability"); ent->client->ps.stats[STAT_TIMER] = (ent->client->invincible_framenum - level.framenum)/10; } else if (ent->client->haste_framenum > level.framenum) { ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_haste"); ent->client->ps.stats[STAT_TIMER] = (ent->client->haste_framenum - level.framenum)/10; } else if (ent->client->sproing_framenum > level.framenum) { ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_sproing"); ent->client->ps.stats[STAT_TIMER] = (ent->client->sproing_framenum - level.framenum)/10; } else if (ent->client->invis_framenum > level.framenum) { ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_invis"); ent->client->ps.stats[STAT_TIMER] = (ent->client->invis_framenum - level.framenum)/10; } else if (ent->client->resp.powered) { ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_powered"); ent->client->ps.stats[STAT_TIMER] = ent->client->resp.reward_pts; } else { ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_rewardpts"); ent->client->ps.stats[STAT_TIMER] = ent->client->resp.reward_pts; } // // selected item // ent->client->ps.stats[STAT_SELECTED_ITEM] = ent->client->pers.selected_item; //ctf if(ctf->integer) { if (ent->client->pers.inventory[ITEM_INDEX(flag1_item)]) ent->client->ps.stats[STAT_FLAG_ICON] = gi.imageindex ("i_flag1"); else if (ent->client->pers.inventory[ITEM_INDEX(flag2_item)]) ent->client->ps.stats[STAT_FLAG_ICON] = gi.imageindex ("i_flag2"); else { //do teams if(ent->dmteam == RED_TEAM) ent->client->ps.stats[STAT_FLAG_ICON] = gi.imageindex ( "i_team1"); else if(ent->dmteam == BLUE_TEAM) ent->client->ps.stats[STAT_FLAG_ICON] = gi.imageindex ( "i_team2"); else ent->client->ps.stats[STAT_FLAG_ICON] = gi.imageindex ( "bar_loading"); } } else { //do teams if(ent->dmteam == RED_TEAM) ent->client->ps.stats[STAT_FLAG_ICON] = gi.imageindex ( "i_team1"); else if(ent->dmteam == BLUE_TEAM) ent->client->ps.stats[STAT_FLAG_ICON] = gi.imageindex ( "i_team2"); else ent->client->ps.stats[STAT_FLAG_ICON] = gi.imageindex ( "bar_loading"); } // // layouts // ent->client->ps.stats[STAT_LAYOUTS] = 0; if (deathmatch->integer) { if (ent->client->pers.health <= 0 || level.intermissiontime || ent->client->showscores) ent->client->ps.stats[STAT_LAYOUTS] |= 1; if (ent->client->showinventory && ent->client->pers.health > 0) ent->client->ps.stats[STAT_LAYOUTS] |= 2; } else { if (ent->client->showscores || ent->client->showhelp) ent->client->ps.stats[STAT_LAYOUTS] |= 1; if (ent->client->showinventory && ent->client->pers.health > 0) ent->client->ps.stats[STAT_LAYOUTS] |= 2; } // // frags and deaths // ent->client->ps.stats[STAT_FRAGS] = ent->client->resp.score; ent->client->ps.stats[STAT_DEATHS] = ent->client->resp.deaths; G_SetScoreStats (ent); #ifndef ALTERIA if(!g_tactical->integer) { //weapon/ammo inventories for(i = 0; i < 7; i++) ent->client->ps.stats[STAT_WEAPN1+i] = 0; i = 0; if(ent->client->pers.inventory[ITEM_INDEX(FindItem("Alien Disruptor"))] && ent->client->pers.weapon != (FindItem("Alien Disruptor"))) { ent->client->ps.stats[STAT_WEAPN1] = gi.imageindex ("disruptor"); i++; } if(ent->client->pers.inventory[ITEM_INDEX(FindItem("Alien Smartgun"))] && ent->client->pers.weapon != (FindItem("Alien Smartgun"))) { ent->client->ps.stats[STAT_WEAPN1+i] = gi.imageindex ("smartgun"); i++; } if(ent->client->pers.inventory[ITEM_INDEX(FindItem("Pulse Rifle"))] && ent->client->pers.weapon != (FindItem("Pulse Rifle"))) { ent->client->ps.stats[STAT_WEAPN1+i] = gi.imageindex ("chaingun"); i++; } if(ent->client->pers.inventory[ITEM_INDEX(FindItem("Flame Thrower"))] && ent->client->pers.weapon != (FindItem("Flame Thrower"))) { ent->client->ps.stats[STAT_WEAPN1+i] = gi.imageindex ("flamethrower"); i++; } if(ent->client->pers.inventory[ITEM_INDEX(FindItem("Rocket Launcher"))] && ent->client->pers.weapon != (FindItem("Rocket Launcher"))) { ent->client->ps.stats[STAT_WEAPN1+i] = gi.imageindex ("rocketlauncher"); i++; } if(ent->client->pers.inventory[ITEM_INDEX(FindItem("Disruptor"))] && ent->client->pers.weapon != (FindItem("Disruptor"))) { ent->client->ps.stats[STAT_WEAPN1+i] = gi.imageindex ("beamgun"); i++; } if(ent->client->pers.inventory[ITEM_INDEX(FindItem("Alien Vaporizer"))] && ent->client->pers.weapon != (FindItem("Alien Vaporizer"))) { ent->client->ps.stats[STAT_WEAPN1+i] = gi.imageindex ("vaporizor"); } } #endif // // current weapon // if (ent->client->pers.weapon) ent->client->ps.stats[STAT_HELPICON] = gi.imageindex (ent->client->pers.weapon->icon); else ent->client->ps.stats[STAT_HELPICON] = 0; ent->client->ps.stats[STAT_FLAGS] &= ~STAT_FLAGS_CROSSHAIRPOSITION; if ( ent->client->pers.weapon == FindItem ("Alien Disruptor") || ent->client->pers.weapon == FindItem ("Violator") || ent->client->pers.weapon == FindItem ("Disruptor") || ent->client->pers.weapon == FindItem ("Pulse Rifle")) ent->client->ps.stats[STAT_FLAGS] |= STAT_FLAGS_CROSSHAIRCENTER; else if (ent->client->pers.weapon == FindItem ("Rocket Launcher")) ent->client->ps.stats[STAT_FLAGS] |= STAT_FLAGS_CROSSHAIRPOS2; } /* =============== G_SetSpectatorStats =============== */ void G_SetSpectatorStats (edict_t *ent) { gclient_t *cl = ent->client; if (ent->client->showscores) cl->ps.stats[STAT_LAYOUTS] = 1; else cl->ps.stats[STAT_LAYOUTS] = 0; if (cl->chase_target && cl->chase_target->inuse) { // XXX: is this code ever active? cl->ps.stats[STAT_CHASE] = CS_PLAYERSKINS + (cl->chase_target - g_edicts) - 1; } else { cl->ps.stats[STAT_CHASE] = 0; G_SetScoreStats (ent); } } /** * @brief Update stats for scoreboard display on * * @detail Spectator issues complicate things. Spectator sees chase target's * HUD information. But spectator needs to show zeroed scoring * data in status responses, player lists, etc. Real player clients * contain bot scoring info, which is updated by * acebot_spawn.c::ACESP_UpdateBots(), called for every server frame * and would be redundant if updated here. The server expects to see * the bot info in the first client, regardless of it being in use * or being a spectator. * * @param ent entity for player or bot */ void G_UpdateStats( edict_t *ent ) { gclient_t *gcl = ent->client; if ( gcl->resp.spectator && !ent->is_bot ) { if ( gcl->chase_target != NULL && level.intermissiontime <= 0.0f ) { // clone chase target's stats for hud memcpy( gcl->ps.stats, gcl->chase_target->client->ps.stats, sizeof( gcl->ps.stats ) ); } else { memset( gcl->ps.stats, 0, sizeof(gcl->ps.stats)); G_SetSpectatorStats( ent); } gcl->ps.stats[STAT_SPECTATOR] = 1; } else { ent->client->ps.stats[STAT_SPECTATOR] = 0; G_SetStats( ent ); } } alien-arena-7.66+dfsg/source/game/game.h0000600000175000017500000002004112161402010017072 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // game.h -- game module information visible to server #define GAME_API_VERSION 3 // edict->svflags #define SVF_NOCLIENT 0x00000001 // don't send entity to clients, even if it has effects #define SVF_DEADMONSTER 0x00000002 // treat as CONTENTS_DEADMONSTER for collision #define SVF_MONSTER 0x00000004 // treat as CONTENTS_MONSTER for collision #define SVF_FAKECLIENT 0x00000020 // do not try to send anything to this client // edict->solid values typedef enum { SOLID_NOT, // no interaction with other objects SOLID_TRIGGER, // only touch when inside, after moving SOLID_BBOX, // touch on edge SOLID_BSP // bsp clip, touch on edge } solid_t; //=============================================================== // link_t is only used for entity area links now typedef struct link_s { struct link_s *prev, *next; } link_t; #define MAX_ENT_CLUSTERS 16 typedef struct edict_s edict_t; typedef struct gclient_s gclient_t; #ifndef GAME_INCLUDE struct gclient_s { player_state_t ps; // communicated by server to clients int ping; // the game dll can add anything it wants after // this point in the structure }; struct edict_s { entity_state_t s; struct gclient_s *client; qboolean inuse; int linkcount; // FIXME: move these fields to a server private sv_entity_t link_t area; // linked to a division node or leaf int num_clusters; // if -1, use headnode instead int clusternums[MAX_ENT_CLUSTERS]; int headnode; // unused if num_clusters != -1 int areanum, areanum2; //================================ int svflags; // SVF_NOCLIENT, SVF_DEADMONSTER, SVF_MONSTER, etc vec3_t mins, maxs; vec3_t absmin, absmax, size; solid_t solid; int clipmask; edict_t *owner; int redirect_number; //for ghost mode // must be accessible to server code for collision detection int dmteam; int teamset; #define RED_TEAM 0 #define BLUE_TEAM 1 #define NO_TEAM 2 // the game dll can add anything it wants after // this point in the structure }; #endif // GAME_INCLUDE //=============================================================== // // functions provided by the main engine // typedef struct { // special messages void (*bprintf) (int printlevel, char *fmt, ...); void (*dprintf) (char *fmt, ...); void (*cprintf) (edict_t *ent, int printlevel, char *fmt, ...); void (*centerprintf) (edict_t *ent, char *fmt, ...); void (*sound) (edict_t *ent, int channel, int soundindex, float volume, float attenuation, float timeofs); void (*positioned_sound) (vec3_t origin, edict_t *ent, int channel, int soundinedex, float volume, float attenuation, float timeofs); // config strings hold all the index strings, the lightstyles, // and misc data like the sky definition and cdtrack. // All of the current configstrings are sent to clients when // they connect, and changes are sent to all connected clients. void (*configstring) (int num, char *string); void (*error) (char *fmt, ...); // the *index functions create configstrings and some internal server state int (*modelindex) (char *name); int (*soundindex) (char *name); int (*imageindex) (char *name); // for checking if assets are already loaded - return 0 if they are not int (*checkmodelindex) (char *name); int (*checksoundindex) (char *name); int (*checkimageindex) (char *name); void (*setmodel) (edict_t *ent, char *name); // collision detection trace_t (*trace) (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passent, int contentmask); int (*pointcontents) (vec3_t point); qboolean (*inPVS) (vec3_t p1, vec3_t p2); qboolean (*inPHS) (vec3_t p1, vec3_t p2); void (*SetAreaPortalState) (int portalnum, qboolean open); qboolean (*AreasConnected) (int area1, int area2); // an entity will never be sent to a client or used for collision // if it is not passed to linkentity. If the size, position, or // solidity changes, it must be relinked. void (*linkentity) (edict_t *ent); void (*unlinkentity) (edict_t *ent); // call before removing an interactive edict int (*BoxEdicts) (vec3_t mins, vec3_t maxs, edict_t **list, int maxcount, int areatype); void (*Pmove) (pmove_t *pmove); // player movement code common with client prediction // network messaging void (*multicast) (vec3_t origin, multicast_t to); void (*unicast) (edict_t *ent, qboolean reliable); void (*WriteChar) (int c); void (*WriteByte) (int c); void (*WriteShort) (int c); void (*WriteLong) (int c); void (*WriteFloat) (float f); void (*WriteString) (char *s); void (*WritePosition) (vec3_t pos); // some fractional bits void (*WriteDir) (vec3_t pos); // single byte encoded, very coarse void (*WriteAngle) (float f); // managed memory allocation void *(*TagMalloc) (int size, int tag); void (*TagFree) (void *block); void (*FreeTags) (int tag); // console variable interaction cvar_t *(*cvar) (char *var_name, char *value, int flags); void (*cvar_set) (char *var_name, char *value); cvar_t *(*cvar_forceset) (char *var_name, char *value); void (*cvar_describe) (cvar_t *var, char *description_string); // ClientCommand and ServerCommand parameter access int (*argc) (void); char *(*argv) (int n); char *(*args) (void); // concatenation of all argv >= 1 // add commands to the server console as if they were typed in // for map changing, etc void (*AddCommandString) (char *text); void (*DebugGraph) (float value, const float color[]); int (*Sys_Milliseconds) (void); // File System path from relative path (added 2010-08) qboolean (*FullPath)(char *full_path, size_t pathsize, const char *relative_path); void (*FullWritePath)(char *full_path, size_t pathsize, const char *relative_path); } game_import_t; // // functions exported by the game subsystem // typedef struct { int apiversion; // the init function will only be called when a game starts, // not each time a level is loaded. Persistant data for clients // and the server can be allocated in init void (*Init) (void); void (*Shutdown) (void); // each new level entered will cause a call to SpawnEntities void (*SpawnEntities) (char *mapname, char *entstring, char *spawnpoint); qboolean (*ClientConnect)( edict_t *ent, char *userinfo); void (*ClientBegin) (edict_t *ent); void (*ClientUserinfoChanged) (edict_t *ent, char *userinfo, int whereFrom); void (*ClientDisconnect) (edict_t *ent); void (*ClientCommand) (edict_t *ent); void (*ClientThink) (edict_t *ent, usercmd_t *cmd); int (*ACESP_FindBotNum) (void); void (*RunFrame) (void); void (*ForceExitIntermission) (void); // ServerCommand will be called when an "sv " command is issued on the // server console. // The game can issue gi.argc() / gi.argv() commands to get the rest // of the parameters void (*ServerCommand) (void); // // global variables shared between game and server // // The edict array is allocated in the game dll so it // can vary in size from one game to another. // // The size will be fixed when ge->Init() is called struct edict_s *edicts; int edict_size; int num_edicts; // current number, <= max_edicts int max_edicts; } game_export_t; game_export_t *GetGameApi (game_import_t *import); alien-arena-7.66+dfsg/source/game/c_cam.c0000600000175000017500000001236712161402010017232 0ustar zero79zero79/* Copyright (C) 20?? COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" /*#define DEBUG_DEATHCAM*/ /* Uncomment this or set as a CFLAG at build time */ void DeathcamTrack (edict_t *ent); /* The ent is the owner of the chasecam */ void DeathcamStart (edict_t *ent) { /* This creates a tempory entity we can manipulate within this * function */ edict_t *chasecam; /* Tell everything that looks at the toggle that our chasecam is on * and working */ ent->client->chasetoggle = 1; /* Make out gun model "non-existent" so it's more realistic to the * player using the chasecam */ ent->client->ps.gunindex = 0; chasecam = G_Spawn (); chasecam->owner = ent; chasecam->solid = SOLID_NOT; chasecam->movetype = MOVETYPE_FLYMISSILE; /* Stop movement prediction */ ent->client->ps.pmove.pm_flags |= PMF_NO_PREDICTION; /* Don't send camera info to other players */ ent->svflags |= SVF_NOCLIENT; /* Now, make the angles of the player model, (!NOT THE HUMAN VIEW!) be * copied to the same angle of the chasecam entity */ VectorCopy (ent->s.angles, chasecam->s.angles); /*alt fire of zoom weapons-- reset some things.*/ ent->client->ps.fov = atoi(Info_ValueForKey(ent->client->pers.userinfo, "fov")); //alt fire - reset the fov; ent->client->ps.stats[STAT_ZOOMED] = 0; /* Clear the size of the entity, so it DOES technically have a size, * but that of '0 0 0'-'0 0 0'. (xyz, xyz). mins = Minimum size, * maxs = Maximum size */ VectorClear (chasecam->mins); VectorClear (chasecam->maxs); VectorClear (chasecam->velocity); /* Make the chasecam's origin (position) be the same as the player * entity's because as the camera starts, it will force itself out * slowly backwards from the player model */ VectorCopy (ent->s.origin, chasecam->s.origin); VectorCopy (ent->s.origin, chasecam->death_origin); chasecam->classname = "chasecam"; chasecam->nextthink = level.time + 0.100; chasecam->think = DeathcamTrack; ent->client->chasecam = chasecam; ent->client->oldplayer = G_Spawn(); } void DeathcamRemove (edict_t *ent, char *opt) { if(ent->client->chasetoggle == 1) /* Safety check */ { ent->client->chasetoggle = 0; /* Stop the chasecam from moving */ VectorClear (ent->client->chasecam->velocity); /* Re-enable sending entity info to other clients */ ent->svflags &= ~SVF_NOCLIENT; if(ent->client->oldplayer->client != NULL) { #ifdef DEBUG_DEATHCAM printf("--- Deathcam = %p\n", ent->client->oldplayer->client); #endif free(ent->client->oldplayer->client); } G_FreeEdict (ent->client->oldplayer); G_FreeEdict (ent->client->chasecam); } } /* The "ent" is the chasecam */ void DeathcamTrack (edict_t *ent) { trace_t tr; vec3_t spot1, spot2; vec3_t forward, right, up; ent->nextthink = level.time + 0.100; AngleVectors (ent->s.angles, forward, right, up); //JKD - 7/16/06 - tweaked this slightly so that it's a little closer to the body /* find position for camera to end up */ VectorMA (ent->death_origin, -150, forward, spot1); /* Move camera destination up slightly too */ spot1[2] += 30; /* Make sure we don't go outside the level */ tr = gi.trace (ent->s.origin, NULL, NULL, spot1, ent, false); /* subtract the endpoint from the start point for length and * direction manipulation */ VectorSubtract (tr.endpos, ent->s.origin, spot2); /* Use this to modify camera velocity */ VectorCopy(spot2, ent->velocity); } void CheckDeathcam_Viewent (edict_t *ent) { gclient_t *cl; int tmp; if (!ent->client->oldplayer->client) { cl = (gclient_t *) malloc(sizeof(gclient_t)); ent->client->oldplayer->client = cl; #ifdef DEBUG_DEATHCAM printf("+++ Deathcam = %p\n", cl); #endif } if (ent->client->oldplayer) { ent->client->oldplayer->s.frame = ent->s.frame; /* Copy the origin, the speed, and the model angle, NOT * literal angle to the display entity */ VectorCopy (ent->s.origin, ent->client->oldplayer->s.origin); VectorCopy (ent->velocity, ent->client->oldplayer->velocity); VectorCopy (ent->s.angles, ent->client->oldplayer->s.angles); } tmp = ent->client->oldplayer->s.number; ent->client->oldplayer->s = ent->s; ent->client->oldplayer->s.number = tmp; // keep same s.number, not client's gi.linkentity (ent->client->oldplayer); } alien-arena-7.66+dfsg/source/game/g_cow.c0000600000175000017500000001364312161402010017264 0ustar zero79zero79/* Copyright (C) 2007 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* ============================================================================== Cow NPC - an NPC that respawns after dying, and will follow players until being caught by their team's tractor beam or "cow trap" devices. These NPC's are very basic, very dumb creatures that will just walk towards whatever client they might see. The goal is for the players to lure them into traps, and without them getting "killed", in which case they would respawn at their original position. When a cow walks into a trap, the team who owns the trap will get rewarded with points, and that cow will be respawned. ============================================================================== */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" #include "cow.h" static int sound_moo; static int sound_groan; static int sound_step1; int kick = 0; void cow_pain (edict_t *self, edict_t *other, float kick, int damage); void cow_search (edict_t *self) { gi.sound (self, CHAN_VOICE, sound_moo, 1, ATTN_NORM, 0); } mframe_t cow_frames_stand [] = { {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL} }; mmove_t cow_move_stand = {FRAME_stand01, FRAME_stand20, cow_frames_stand, NULL}; void cow_stand (edict_t *self) { self->monsterinfo.currentmove = &cow_move_stand; } void cow_step (edict_t *self) { gi.sound (self, CHAN_VOICE, sound_step1, 1, ATTN_NORM, 0); //perhaps draw a beam to the player that is leading it? if(self->enemy) { if(self->enemy->dmteam == BLUE_TEAM) { gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BLASTERBEAM); gi.WritePosition (self->s.origin); gi.WritePosition (self->enemy->s.origin); gi.multicast (self->s.origin, MULTICAST_PHS); } else { gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_REDLASER); gi.WritePosition (self->s.origin); gi.WritePosition (self->enemy->s.origin); gi.multicast (self->s.origin, MULTICAST_PHS); } } } mframe_t cow_frames_walk [] = { {ai_run, 42.0, NULL}, {ai_run, 22.0, NULL}, {ai_run, 5.0, NULL}, {ai_run, 3.0, NULL}, {ai_run, 0.0, NULL}, {ai_run, 0.0, cow_step}, {ai_run, 0.0, NULL}, {ai_run, 17.0, NULL}, {ai_run, 42.0, NULL}, {ai_run, 14.0, NULL}, {ai_run, 5.0, cow_step}, {ai_run, 0.0, NULL} }; mmove_t cow_move_walk = {FRAME_walk01, FRAME_walk12, cow_frames_walk, NULL}; void cow_walk (edict_t *self) { self->monsterinfo.currentmove = &cow_move_walk; } void cow_run (edict_t *self) { if ((self->monsterinfo.aiflags & AI_STAND_GROUND)) self->monsterinfo.currentmove = &cow_move_stand; else self->monsterinfo.currentmove = &cow_move_walk; } void cow_sight (edict_t *self, edict_t *other) { gi.sound (self, CHAN_VOICE, sound_moo, 1, ATTN_IDLE, 0); self->monsterinfo.currentmove = &cow_move_walk; } mframe_t cow_frames_pain [] = { {ai_move, 0, NULL}, {ai_move, 0, NULL}, {ai_move, 0, NULL}, {ai_move, 0, NULL}, {ai_move, 0, NULL}, {ai_move, 0, NULL}, {ai_move, 0, NULL}, {ai_move, 0, NULL}, {ai_move, 0, NULL}, {ai_move, 0, NULL}, {ai_move, 0, NULL} }; mmove_t cow_move_pain = {FRAME_pain01, FRAME_pain11, cow_frames_pain, cow_walk}; void cow_pain (edict_t *self, edict_t *other, float kick, int damage) { if (level.time < self->pain_debounce_time) return; self->pain_debounce_time = level.time + 3; gi.sound (self, CHAN_VOICE, sound_groan, 1, ATTN_NORM, 0); self->monsterinfo.currentmove = &cow_move_pain; } void SP_npc_cow (edict_t *self) { if(!cp->value) return; //not in cp mode, no cows needed // pre-caches sound_moo = gi.soundindex ("misc/cow/moo.wav"); sound_groan = gi.soundindex ("misc/cow/groan.wav"); sound_step1 = gi.soundindex ("misc/cow/step1.wav"); self->s.modelindex = gi.modelindex("models/cow/tris.md2"); self->s.modelindex3 = gi.modelindex("models/cow/helmet.md2"); VectorSet (self->mins, -32, -32, -2); VectorSet (self->maxs, 32, 32, 56); self->movetype = MOVETYPE_STEP; self->solid = SOLID_BBOX; self->classname = "cow"; self->max_health = 250; self->health = self->max_health; self->gib_health = -40; self->mass = 250; self->pain = cow_pain; self->die = NULL; self->monsterinfo.stand = cow_stand; self->monsterinfo.walk = cow_walk; self->monsterinfo.run = cow_walk; self->monsterinfo.dodge = NULL; self->monsterinfo.attack = cow_walk; self->monsterinfo.melee = cow_walk; self->monsterinfo.sight = cow_sight; self->monsterinfo.search = cow_search; self->s.renderfx |= RF_MONSTER; self->monsterinfo.currentmove = &cow_move_stand; self->monsterinfo.scale = MODEL_SCALE; self->monsterinfo.aiflags = AI_NPC; self->dmteam = NO_TEAM; self->enemy = NULL; gi.linkentity (self); walkmonster_start (self); VectorCopy(self->s.origin, self->s.spawn_pos); //remember where the cow began } alien-arena-7.66+dfsg/source/game/g_ctf.c0000600000175000017500000006016012161402010017244 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" int imageindex_sbfctf1; int imageindex_sbfctf2; /* ================== CTFScoreboardMessage ================== */ void CTFScoreboardMessage (edict_t *ent, edict_t *killer, int mapvote) { char entry[1024]; char string[1400]; int len; int i, j, k, x, y; int sorted[2][MAX_CLIENTS]; int sortedscores[2][MAX_CLIENTS]; int score, total[2], totalscore[2]; gclient_t *cl; edict_t *cl_ent; int team; int maxsize = 1024; gitem_t *flag1_item, *flag2_item; flag1_item = FindItemByClassname("item_flag_red"); flag2_item = FindItemByClassname("item_flag_blue"); // sort the clients by team and score total[0] = total[1] = 0; totalscore[0] = totalscore[1] = 0; for (i=0 ; iinuse) continue; if (cl_ent->dmteam == RED_TEAM) team = 0; else if (cl_ent->dmteam == BLUE_TEAM) team = 1; else continue; // unknown team? score = game.clients[i].resp.score; for (j=0 ; j sortedscores[team][j]) break; } for (k=total[team] ; k>j ; k--) { sorted[team][k] = sorted[team][k-1]; sortedscores[team][k] = sortedscores[team][k-1]; } sorted[team][j] = i; sortedscores[team][j] = score; totalscore[team] += score; total[team]++; } // print level name and exit rules // add the clients in sorted order *string = 0; len = 0; if(ctf->value) { //do ctf sprintf(string, "newctfsb xv -16 yv -8 picn ctf1 " "xv +12 yv 4 num 3 21 " "xv 238 yv -8 picn ctf2 " "xv 264 yv 4 num 3 22 "); len = strlen(string); } else { //regular team games sprintf(string, "newctfsb xv -16 yv -8 picn team1 " "xv +12 yv 4 num 3 21 " "xv 238 yv -8 picn team2 " "xv 264 yv 4 num 3 22 "); len = strlen(string); } for (i=0 ; i<16 ; i++) { if (i >= total[0] && i >= total[1]) break; // we're done *entry = 0; // left side if (i < total[0]) { cl = &game.clients[sorted[0][i]]; cl_ent = g_edicts + 1 + sorted[0][i]; sprintf(entry+strlen(entry), "ctf -96 %d %d %d %d ", 42 + i * 16, sorted[0][i], cl->resp.score, cl->ping > 999 ? 999 : cl->ping); if (cl_ent->client->pers.inventory[ITEM_INDEX(flag2_item)]) sprintf(entry + strlen(entry), "xv -92 yv %d picn sbfctf2 ", 43 + i * 16); if (maxsize - len > strlen(entry)) { strcat(string, entry); len = strlen(string); } } // right side if (i < total[1]) { cl = &game.clients[sorted[1][i]]; cl_ent = g_edicts + 1 + sorted[1][i]; sprintf(entry+strlen(entry), "ctf 160 %d %d %d %d ", 42 + i * 16, sorted[1][i], cl->resp.score, cl->ping > 999 ? 999 : cl->ping); if (cl_ent->client->pers.inventory[ITEM_INDEX(flag1_item)]) sprintf(entry + strlen(entry), "xv 164 yv %d picn sbfctf1 ", 43 + i * 16); if (maxsize - len > strlen(entry)) { strcat(string, entry); len = strlen(string); } } } if(mapvote) { y = 64; x = 96; Com_sprintf(entry, sizeof(entry), "xv %i yt %i string Vote ", x, y); if(maxsize - len > strlen(entry)) { strcat(string, entry); len = strlen(string); } x = 136; Com_sprintf(entry, sizeof(entry), "xv %i yt %i string for ", x, y); if(maxsize - len > strlen(entry)) { strcat(string, entry); len = strlen(string); } x = 168; Com_sprintf(entry, sizeof(entry), "xv %i yt %i string next ", x, y); if(maxsize - len > strlen(entry)) { strcat(string, entry); len = strlen(string); } x = 208; Com_sprintf(entry, sizeof(entry), "xv %i yt %i string map: ", x, y); if(maxsize - len > strlen(entry)) { strcat(string, entry); len = strlen(string); } x = 96; for(i=0; i<4; i++) { Com_sprintf(entry, sizeof(entry), "xv %i yt %i string %i.%s ", x, y+((i+1)*9)+9, i+1, votedmap[i].mapname); if(maxsize - len > strlen(entry)) { strcat(string, entry); len = strlen(string); } } } gi.WriteByte (svc_layout); gi.WriteString (string); } /* * Precache CTF items */ void CTFPrecache(void) { imageindex_sbfctf1 = gi.imageindex("sbfctf1"); imageindex_sbfctf2 = gi.imageindex("sbfctf2"); } /*------------------------------------------------------------------------*/ /* GRAPPLE */ /*------------------------------------------------------------------------*/ // ent is player void CTFPlayerResetGrapple(edict_t *ent) { if (ent->client && ent->client->ctf_grapple) CTFResetGrapple(ent->client->ctf_grapple); } // self is grapple, not player void CTFResetGrapple(edict_t *self) { if (self->owner->client->ctf_grapple) { float volume = 1.0; gclient_t *cl; if (self->owner->client->silencer_shots) volume = 0.2; cl = self->owner->client; cl->ctf_grapple = NULL; cl->ctf_grapplereleasetime = level.time; cl->ctf_grapplestate = CTF_GRAPPLE_STATE_FLY; // we're firing, not on hook cl->ps.pmove.pm_flags &= ~PMF_NO_PREDICTION; G_FreeEdict(self); } } void CTFGrappleTouch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { // float volume = 1.0; if (other == self->owner) return; if (self->owner->client->ctf_grapplestate != CTF_GRAPPLE_STATE_FLY) return; if (surf && (surf->flags & SURF_SKY)) { CTFResetGrapple(self); return; } VectorCopy(vec3_origin, self->velocity); PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT); if (other->takedamage) { T_Damage (other, self, self->owner, self->velocity, self->s.origin, plane->normal, self->dmg, 1, 0, MOD_GRAPPLE); } self->owner->client->ctf_grapplestate = CTF_GRAPPLE_STATE_PULL; // we're on hook self->enemy = other; self->solid = SOLID_NOT; } // draw beam between grapple and self void CTFGrappleDrawCable(edict_t *self) { vec3_t offset, start, end, f, r; vec3_t dir; float distance; AngleVectors (self->owner->client->v_angle, f, r, NULL); VectorSet(offset, 32, 6, self->owner->viewheight-5); P_ProjectSource (self->owner->client, self->owner->s.origin, offset, f, r, start); VectorSubtract(start, self->owner->s.origin, offset); VectorSubtract (start, self->s.origin, dir); distance = VectorLength(dir); // don't draw cable if close if (distance < 64) return; #if 0 if (distance > 256) return; // check for min/max pitch vectoangles (dir, angles); if (angles[0] < -180) angles[0] += 360; if (fabs(angles[0]) > 45) return; trace_t tr; //!! tr = gi.trace (start, NULL, NULL, self->s.origin, self, MASK_SHOT); if (tr.ent != self) { CTFResetGrapple(self); return; } #endif VectorCopy (self->s.origin, end); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BLASTERBEAM); gi.WritePosition (start); gi.WritePosition (end); gi.multicast (self->s.origin, MULTICAST_PVS); } void SV_AddGravity (edict_t *ent, float timespan); // pull the player toward the grapple void CTFGrapplePull(edict_t *self) { vec3_t hookdir, v; float vlen; if (strcmp(self->owner->client->pers.weapon->classname, "weapon_grapple") == 0 && !self->owner->client->newweapon && self->owner->client->weaponstate != WEAPON_FIRING && self->owner->client->weaponstate != WEAPON_ACTIVATING) { CTFResetGrapple(self); return; } if (self->enemy) { if (self->enemy->solid == SOLID_NOT) { CTFResetGrapple(self); return; } if (self->enemy->solid == SOLID_BBOX) { VectorScale(self->enemy->size, 0.5, v); VectorAdd(v, self->enemy->s.origin, v); VectorAdd(v, self->enemy->mins, self->s.origin); gi.linkentity (self); } else VectorCopy(self->enemy->velocity, self->velocity); if (self->enemy->takedamage) { float volume = 1.0; if (self->owner->client->silencer_shots) volume = 0.2; T_Damage (self->enemy, self, self->owner, self->velocity, self->s.origin, vec3_origin, 1, 1, 0, MOD_GRAPPLE); } if (self->enemy->deadflag) { // he died CTFResetGrapple(self); return; } } CTFGrappleDrawCable(self); if (self->owner->client->ctf_grapplestate > CTF_GRAPPLE_STATE_FLY) { // pull player toward grapple // this causes icky stuff with prediction, we need to extend // the prediction layer to include two new fields in the player // move stuff: a point and a velocity. The client should add // that velociy in the direction of the point vec3_t forward, up; AngleVectors (self->owner->client->v_angle, forward, NULL, up); VectorCopy(self->owner->s.origin, v); v[2] += self->owner->viewheight; VectorSubtract (self->s.origin, v, hookdir); vlen = VectorLength(hookdir); if (self->owner->client->ctf_grapplestate == CTF_GRAPPLE_STATE_PULL && vlen < 64) { float volume = 1.0; if (self->owner->client->silencer_shots) volume = 0.2; self->owner->client->ps.pmove.pm_flags |= PMF_NO_PREDICTION; gi.sound (self->owner, CHAN_RELIABLE+CHAN_WEAPON, gi.soundindex("weapons/electroball.wav"), volume, ATTN_NORM, 0); self->owner->client->ctf_grapplestate = CTF_GRAPPLE_STATE_HANG; } VectorNormalize (hookdir); VectorScale(hookdir, CTF_GRAPPLE_PULL_SPEED, hookdir); VectorCopy(hookdir, self->owner->velocity); SV_AddGravity(self->owner, FRAMETIME); } } void CTFFireGrapple (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, int effect) { edict_t *grapple; trace_t tr; VectorNormalize (dir); grapple = G_Spawn(); VectorCopy (start, grapple->s.origin); VectorCopy (start, grapple->s.old_origin); vectoangles (dir, grapple->s.angles); VectorScale (dir, speed, grapple->velocity); grapple->movetype = MOVETYPE_FLYMISSILE; grapple->clipmask = MASK_SHOT; grapple->solid = SOLID_BBOX; grapple->s.effects |= effect; VectorClear (grapple->mins); VectorClear (grapple->maxs); grapple->s.modelindex = 0; grapple->owner = self; grapple->touch = CTFGrappleTouch; grapple->dmg = damage; self->client->ctf_grapple = grapple; self->client->ctf_grapplestate = CTF_GRAPPLE_STATE_FLY; // we're firing, not on hook gi.linkentity (grapple); tr = gi.trace (self->s.origin, NULL, NULL, grapple->s.origin, grapple, MASK_SHOT); if (tr.fraction < 1.0) { VectorMA (grapple->s.origin, -10, dir, grapple->s.origin); grapple->touch (grapple, tr.ent, NULL, NULL); } } void CTFGrappleFire (edict_t *ent, vec3_t g_offset, int damage, int effect) { vec3_t forward, right; vec3_t start; vec3_t offset; // float volume = 1.0; if (ent->client->ctf_grapplestate > CTF_GRAPPLE_STATE_FLY) return; // it's already out AngleVectors (ent->client->v_angle, forward, right, NULL); // VectorSet(offset, 24, 16, ent->viewheight-8+2); VectorSet(offset, 24, 8, ent->viewheight-8+2); VectorAdd (offset, g_offset, offset); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); VectorScale (forward, -2, ent->client->kick_origin); ent->client->kick_angles[0] = -1; CTFFireGrapple (ent, start, forward, damage, CTF_GRAPPLE_SPEED, effect); PlayerNoise(ent, start, PNOISE_WEAPON); } void CTFWeapon_Grapple_Fire (edict_t *ent) { int damage; damage = 15; CTFGrappleFire (ent, vec3_origin, damage, 0); ent->client->ps.gunframe++; } void CTFWeapon_Grapple (edict_t *ent) { static int pause_frames[] = {10, 18, 27, 0}; static int fire_frames[] = {6, 0}; int prevstate; // if the the attack button is still down, stay in the firing frame if ((ent->client->buttons & BUTTON_ATTACK) && ent->client->weaponstate == WEAPON_FIRING && ent->client->ctf_grapple) ent->client->ps.gunframe = 9; if (!(ent->client->buttons & BUTTON_ATTACK) && ent->client->ctf_grapple) { CTFResetGrapple(ent->client->ctf_grapple); if (ent->client->weaponstate == WEAPON_FIRING) ent->client->weaponstate = WEAPON_READY; } if (ent->client->newweapon && ent->client->ctf_grapplestate > CTF_GRAPPLE_STATE_FLY && ent->client->weaponstate == WEAPON_FIRING) { // he wants to change weapons while grappled ent->client->weaponstate = WEAPON_DROPPING; ent->client->ps.gunframe = 32; } prevstate = ent->client->weaponstate; Weapon_Generic (ent, 5, 9, 31, 36, pause_frames, fire_frames, CTFWeapon_Grapple_Fire); // if we just switched back to grapple, immediately go to fire frame if (prevstate == WEAPON_ACTIVATING && ent->client->weaponstate == WEAPON_READY && ent->client->ctf_grapplestate > CTF_GRAPPLE_STATE_FLY) { if (!(ent->client->buttons & BUTTON_ATTACK)) ent->client->ps.gunframe = 9; else ent->client->ps.gunframe = 5; ent->client->weaponstate = WEAPON_FIRING; } } static void CTFFlagThink(edict_t *ent) { if (ent->solid != SOLID_NOT) ent->s.frame = 173 + (((ent->s.frame - 173) + 1) % 16); ent->nextthink = level.time + FRAMETIME; } void CTFFlagSetup (edict_t *ent) { trace_t tr; vec3_t dest; float *v; v = tv(-15,-15,-15); VectorCopy (v, ent->mins); v = tv(15,15,15); VectorCopy (v, ent->maxs); if (ent->model) gi.setmodel (ent, ent->model); else gi.setmodel (ent, ent->item->world_model); ent->solid = SOLID_TRIGGER; ent->movetype = MOVETYPE_TOSS; ent->touch = Touch_Item; v = tv(0,0,-128); VectorAdd (ent->s.origin, v, dest); tr = gi.trace (ent->s.origin, ent->mins, ent->maxs, dest, ent, MASK_SOLID); if (tr.startsolid) { gi.dprintf ("CTFFlagSetup: %s startsolid at %s\n", ent->classname, vtos(ent->s.origin)); G_FreeEdict (ent); return; } VectorCopy (tr.endpos, ent->s.origin); gi.linkentity (ent); ent->nextthink = level.time + FRAMETIME; ent->think = CTFFlagThink; } void CTFEffects(edict_t *player) { gitem_t *flag1_item, *flag2_item; flag1_item = FindItemByClassname("item_flag_red"); flag2_item = FindItemByClassname("item_flag_blue"); if (player->client->pers.inventory[ITEM_INDEX(flag1_item)]) player->s.modelindex4 = gi.modelindex("models/items/flags/flag1.md2"); else if (player->client->pers.inventory[ITEM_INDEX(flag2_item)]) player->s.modelindex4 = gi.modelindex("models/items/flags/flag2.md2"); else player->s.modelindex4 = 0; } void CTFDrop_Flag(edict_t *ent, gitem_t *item) { if (rand() & 1) safe_cprintf(ent, PRINT_HIGH, "Only lusers drop flags.\n"); else safe_cprintf(ent, PRINT_HIGH, "Winners don't drop flags.\n"); } void CTFResetFlag(int ctf_team) { char *c; edict_t *ent; switch (ctf_team) { case RED_TEAM: c = "item_flag_red"; break; case BLUE_TEAM: c = "item_flag_blue"; break; default: return; } ent = NULL; while ((ent = G_Find (ent, FOFS(classname), c)) != NULL) { if (ent->spawnflags & DROPPED_ITEM) G_FreeEdict(ent); else { ent->svflags &= ~SVF_NOCLIENT; ent->solid = SOLID_TRIGGER; gi.linkentity(ent); ent->s.event = EV_ITEM_RESPAWN; } } } void CTFResetFlags(void) { CTFResetFlag(RED_TEAM); CTFResetFlag(BLUE_TEAM); } static void CTFDropFlagTouch(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { //owner (who dropped us) can't touch for two secs if (other == ent->owner && ent->nextthink - level.time > 28) return; Touch_Item (ent, other, plane, surf); } static void CTFDropFlagThink(edict_t *ent) { // auto return the flag // reset flag will remove ourselves if (strcmp(ent->classname, "item_flag_red") == 0) { CTFResetFlag(RED_TEAM); safe_bprintf(PRINT_HIGH, "The %s flag has returned!\n", "Red"); } else if (strcmp(ent->classname, "item_flag_blue") == 0) { CTFResetFlag(BLUE_TEAM); safe_bprintf(PRINT_HIGH, "The %s flag has returned!\n", "Blue"); } } void CTFDeadDropFlag(edict_t *self, edict_t *other) { edict_t *dropped = NULL; gitem_t *flag1_item, *flag2_item; dropped = NULL; flag1_item = flag2_item = NULL; flag1_item = FindItemByClassname("item_flag_red"); flag2_item = FindItemByClassname("item_flag_blue"); /* notes on assist bonus: * other can be NULL, if self is disconnecting, or self is a bot being kicked. * other can be self for suicides, but that is handled with team check. */ if (self->client->pers.inventory[ITEM_INDEX(flag1_item)]) { if ( other != NULL && other->client && ( (other->dmteam == RED_TEAM && self->dmteam == BLUE_TEAM) || (other->dmteam == BLUE_TEAM && self->dmteam == RED_TEAM) )) {//kill enemy w flag; assist bonus (1 for frag + 4 = 5 total) other->client->resp.score += 4; } dropped = Drop_Item(self, flag1_item); self->client->pers.inventory[ITEM_INDEX(flag1_item)] = 0; safe_bprintf(PRINT_HIGH, "%s lost the %s flag!\n", self->client->pers.netname, "Red"); } else if (self->client->pers.inventory[ITEM_INDEX(flag2_item)]) { if ( other != NULL && other->client && ( (other->dmteam == RED_TEAM && self->dmteam == BLUE_TEAM) || (other->dmteam == BLUE_TEAM && self->dmteam == RED_TEAM ) )) { //kill enemy w flag; assist bonus (1 for frag + 4 = 5 total) other->client->resp.score += 4; } dropped = Drop_Item(self, flag2_item); self->client->pers.inventory[ITEM_INDEX(flag2_item)] = 0; safe_bprintf(PRINT_HIGH, "%s lost the %s flag!\n", self->client->pers.netname, "Blue"); } if (dropped) { dropped->think = CTFDropFlagThink; dropped->nextthink = level.time + 30; dropped->touch = CTFDropFlagTouch; dropped->s.frame = 175; dropped->s.effects = EF_ROTATE; } } qboolean CTFPickup_Flag (edict_t *ent, edict_t *other) { int ctf_team; char team_name[16] = " "; char enemy_team_name[16] = " "; gitem_t *flag_item, *enemy_flag_item, *it; // figure out what team this flag is if (strcmp(ent->classname, "item_flag_red") == 0) ctf_team = RED_TEAM; else if (strcmp(ent->classname, "item_flag_blue") == 0) ctf_team = BLUE_TEAM; else { safe_cprintf(ent, PRINT_HIGH, "Don't know what team the flag is on.\n"); return false; } // same team, if the flag at base, check to he has the enemy flag if (ctf_team == RED_TEAM) { flag_item = FindItemByClassname("item_flag_red"); enemy_flag_item = FindItemByClassname("item_flag_blue"); strcpy(team_name, "Red"); strcpy(enemy_team_name, "Blue"); } else { flag_item = FindItemByClassname("item_flag_blue"); enemy_flag_item = FindItemByClassname("item_flag_red"); strcpy(team_name, "Blue"); strcpy(enemy_team_name, "Red"); } if (ctf_team == other->dmteam) { if (!(ent->spawnflags & DROPPED_ITEM)) { // the flag is at home base. if the player has the enemy // flag, he's just won! if (other->client->pers.inventory[ITEM_INDEX(enemy_flag_item)]) { safe_bprintf(PRINT_HIGH, "%s captured the %s flag!\n", other->client->pers.netname, enemy_team_name); other->client->pers.inventory[ITEM_INDEX(enemy_flag_item)] = 0; if (ctf_team == RED_TEAM) { red_team_score++; if(red_team_score > blue_team_score){ reddiff = red_team_score - blue_team_score; if(reddiff == 1){ gi.sound (ent, CHAN_AUTO, gi.soundindex("misc/red_takes.wav"), 1, ATTN_NONE, 0); } else { gi.sound (ent, CHAN_AUTO, gi.soundindex("misc/red_increases.wav"), 1, ATTN_NONE, 0); } } else { if(red_team_score == blue_team_score){ gi.sound (ent, CHAN_AUTO, gi.soundindex("misc/scores_tied.wav"), 1, ATTN_NONE, 0); } else { gi.sound (ent, CHAN_AUTO, gi.soundindex("misc/red_scores.wav"), 1, ATTN_NONE, 0); } } } else { blue_team_score++; if(blue_team_score > red_team_score){ bluediff = blue_team_score - red_team_score; if(bluediff == 1){ gi.sound (ent, CHAN_AUTO, gi.soundindex("misc/blue_takes.wav"), 1, ATTN_NONE, 0); } else { gi.sound (ent, CHAN_AUTO, gi.soundindex("misc/blue_increases.wav"), 1, ATTN_NONE, 0); } } else { if(red_team_score == blue_team_score){ gi.sound (ent, CHAN_AUTO, gi.soundindex("misc/scores_tied.wav"), 1, ATTN_NONE, 0); } else { gi.sound (ent, CHAN_AUTO, gi.soundindex("misc/blue_scores.wav"), 1, ATTN_NONE, 0); } } } // other gets another 10 frag bonus other->client->resp.score += 10;//CTF_CAPTURE_BONUS; //reward points bonus other->client->resp.reward_pts+=5; if(other->client->resp.reward_pts >= g_reward->integer && !other->client->resp.powered) { //give them speed and invis powerups it = FindItem("Invisibility"); other->client->pers.inventory[ITEM_INDEX(it)] += 1; it = FindItem("Sproing"); other->client->pers.inventory[ITEM_INDEX(it)] += 1; it = FindItem("Haste"); other->client->pers.inventory[ITEM_INDEX(it)] += 1; other->client->resp.powered = true; gi.sound (other, CHAN_AUTO, gi.soundindex("misc/pc_up.wav"), 1, ATTN_STATIC, 0); } CTFResetFlags(); return false; } return false; // its at home base already } // hey, its not home. return it by teleporting it back safe_bprintf(PRINT_HIGH, "%s returned the %s flag!\n", other->client->pers.netname, team_name); other->client->resp.score += 5;//CTF_RECOVERY_BONUS; if(!strcmp("Red", team_name)) gi.sound (ent, CHAN_AUTO, gi.soundindex("misc/red_returned.wav"), 1, ATTN_NONE, 0); else gi.sound (ent, CHAN_AUTO, gi.soundindex("misc/blue_returned.wav"), 1, ATTN_NONE, 0); //reward points bonus other->client->resp.reward_pts+=2; if(other->client->resp.reward_pts >= g_reward->integer && !other->client->resp.powered) { //give them speed and invis powerups it = FindItem("Invisibility"); other->client->pers.inventory[ITEM_INDEX(it)] += 1; it = FindItem("Sproing"); other->client->pers.inventory[ITEM_INDEX(it)] += 1; it = FindItem("Haste"); other->client->pers.inventory[ITEM_INDEX(it)] += 1; other->client->resp.powered = true; gi.sound (other, CHAN_AUTO, gi.soundindex("misc/pc_up.wav"), 1, ATTN_STATIC, 0); } //CTFResetFlag will remove this entity! We must return false CTFResetFlag(ctf_team); return false; } // hey, its not our flag, pick it up safe_bprintf(PRINT_HIGH, "%s got the %s flag!\n", other->client->pers.netname, team_name); other->client->resp.score += 10;//CTF_FLAG_BONUS; if(!strcmp("Red", team_name)) gi.sound (ent, CHAN_AUTO, gi.soundindex("misc/red_picked.wav"), 1, ATTN_NONE, 0); else gi.sound (ent, CHAN_AUTO, gi.soundindex("misc/blue_picked.wav"), 1, ATTN_NONE, 0); other->client->resp.reward_pts+=2; //if a bot, break off of path, so we can find base path if(other->is_bot) { other->state = STATE_WANDER; other->wander_timeout = level.time + 1.0; } if(other->client->resp.reward_pts >= g_reward->integer && !other->client->resp.powered) { //give them speed and invis powerups it = FindItem("Invisibility"); other->client->pers.inventory[ITEM_INDEX(it)] += 1; it = FindItem("Sproing"); other->client->pers.inventory[ITEM_INDEX(it)] += 1; it = FindItem("Haste"); other->client->pers.inventory[ITEM_INDEX(it)] += 1; other->client->resp.powered = true; gi.sound (other, CHAN_AUTO, gi.soundindex("misc/pc_up.wav"), 1, ATTN_STATIC, 0); } other->client->pers.inventory[ITEM_INDEX(flag_item)] = 1; // pick up the flag // if it's not a dropped flag, we just make is disappear // if it's dropped, it will be removed by the pickup caller if (!(ent->spawnflags & DROPPED_ITEM)) { ent->flags |= FL_RESPAWN; ent->svflags |= SVF_NOCLIENT; ent->solid = SOLID_NOT; } return true; } alien-arena-7.66+dfsg/source/game/g_unlagged.c0000600000175000017500000002250512161402010020257 0ustar zero79zero79/* Copyright (C) 2009 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" /* ============ G_ResetHistory Clear out the given client's history (should be called when the teleport bit is flipped) ============ */ void G_ResetHistory( edict_t *ent ) { int i; int time; time = gi.Sys_Milliseconds(); // fill up the history with data (assume the current position) ent->client->historyHead = NUM_CLIENT_HISTORY - 1; for ( i = ent->client->historyHead; i >= 0; i--, time -= 100 ) { VectorCopy( ent->mins, ent->client->history[i].mins ); VectorCopy( ent->maxs, ent->client->history[i].maxs ); VectorCopy( ent->s.origin, ent->client->history[i].currentOrigin ); ent->client->history[i].leveltime = time; } } /* ============ G_StoreHistory Keep track of where the client's been ============ */ void G_StoreHistory( edict_t *ent ) { int head; ent->client->historyHead++; if ( ent->client->historyHead >= NUM_CLIENT_HISTORY ) { ent->client->historyHead = 0; } head = ent->client->historyHead; // store all the collision-detection info and the time VectorCopy( ent->mins, ent->client->history[head].mins ); VectorCopy( ent->maxs, ent->client->history[head].maxs ); VectorCopy( ent->s.origin, ent->client->history[head].currentOrigin ); SnapVector( ent->client->history[head].currentOrigin ); ent->client->history[head].leveltime = gi.Sys_Milliseconds(); } /* ============= TimeShiftLerp Used below to interpolate between two previous vectors Returns a vector "frac" times the distance between "start" and "end" ============= */ static void TimeShiftLerp( float frac, vec3_t start, vec3_t end, vec3_t result ) { result[0] = start[0] + frac * ( end[0] - start[0] ); result[1] = start[1] + frac * ( end[1] - start[1] ); result[2] = start[2] + frac * ( end[2] - start[2] ); } /* ================= G_TimeShiftClient Move a client back to where he was at the specified time ================= */ void G_TimeShiftClient( edict_t *ent, int time, qboolean debug, edict_t *debugger ) { int j, k; char str[MAX_STRING_CHARS]; VectorCopy( ent->mins, ent->client->saved.mins ); VectorCopy( ent->maxs, ent->client->saved.maxs ); VectorCopy( ent->s.origin, ent->client->saved.currentOrigin ); ent->client->saved.leveltime = gi.Sys_Milliseconds(); if(g_antilagdebug->integer > 1) { //debug Com_sprintf(str, sizeof(str), "head: %i, %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i time: %i\n", ent->client->historyHead, ent->client->history[0].leveltime, ent->client->history[1].leveltime, ent->client->history[2].leveltime, ent->client->history[3].leveltime, ent->client->history[4].leveltime, ent->client->history[5].leveltime, ent->client->history[6].leveltime, ent->client->history[7].leveltime, ent->client->history[8].leveltime, ent->client->history[9].leveltime, ent->client->history[10].leveltime, ent->client->history[11].leveltime, ent->client->history[12].leveltime, ent->client->history[13].leveltime, ent->client->history[14].leveltime, ent->client->history[15].leveltime, ent->client->history[16].leveltime, time ); safe_cprintf(debugger, PRINT_HIGH, "%s\n", str); } // find two entries in the history whose times sandwich "time" // assumes no two adjacent records have the same timestamp j = k = ent->client->historyHead; do { if ( ent->client->history[j].leveltime <= time ) break; k = j; j--; if ( j < 0 ) { j = NUM_CLIENT_HISTORY - 1; } } while ( j != ent->client->historyHead ); if(g_antilagdebug->value) safe_cprintf(debugger, PRINT_HIGH, "reconciled time at: %i\n", k); // if we got past the first iteration above, we've sandwiched (or wrapped) if ( j != k ) { // if we haven't wrapped back to the head, we've sandwiched, so // we shift the client's position back to where he was at "time" if ( j != ent->client->historyHead ) { float frac = (float)(time - ent->client->history[j].leveltime) / (float)(ent->client->history[k].leveltime - ent->client->history[j].leveltime); // interpolate between the two origins to give position at time index "time" TimeShiftLerp( frac, ent->client->history[j].currentOrigin, ent->client->history[k].currentOrigin, ent->s.origin ); // lerp these too, just for fun (and ducking) TimeShiftLerp( frac, ent->client->history[j].mins, ent->client->history[k].mins, ent->mins ); TimeShiftLerp( frac, ent->client->history[j].maxs, ent->client->history[k].maxs, ent->maxs ); // this will recalculate absmin and absmax gi.linkentity( ent ); } else { // we wrapped, so grab the earliest VectorCopy( ent->client->history[k].currentOrigin, ent->s.origin ); VectorCopy( ent->client->history[k].mins, ent->mins ); VectorCopy( ent->client->history[k].maxs, ent->maxs ); // this will recalculate absmin and absmax gi.linkentity( ent ); } } } /* ===================== G_TimeShiftAllClients Move ALL clients back to where they were at the specified "time", except for "skip" ===================== */ void G_TimeShiftAllClients( int time, edict_t *skip ) { int i; edict_t *ent; for (i=0 ; ivalue ; i++) { ent = g_edicts + 1 + i; if (!ent->inuse || !ent->client) continue; if ( ent->client && ent->inuse && !ent->client->resp.spectator && ent != skip ) { G_TimeShiftClient( ent, time, false, skip ); } } } /* ================ G_DoTimeShiftFor Decide what time to shift everyone back to, and do it ================ */ void G_DoTimeShiftFor( edict_t *ent ) { //check this, because this will be different for alien arena for sure. // int wpflags[10] = { 0, 0, 2, 4, 0, 0, 8, 16, 0, 0 }; // int wpflag = wpflags[ent->client->ps.weapon]; int time; // don't time shift for mistakes or bots if ( !ent->inuse || !ent->client || ent->is_bot ) { return; } // do the full lag compensation time = ent->client->attackTime - ent->client->ping - 100; //100 ms is our "built-in" lag due to the 10fps server frame G_TimeShiftAllClients( time, ent ); } /* =================== G_UnTimeShiftClient Move a client back to where he was before the time shift =================== */ void G_UnTimeShiftClient( edict_t *ent ) { // move it back VectorCopy( ent->client->saved.mins, ent->mins ); VectorCopy( ent->client->saved.maxs, ent->maxs ); VectorCopy( ent->client->saved.currentOrigin, ent->s.origin ); ent->client->saved.leveltime = 0; // this will recalculate absmin and absmax gi.linkentity( ent ); } /* ======================= G_UnTimeShiftAllClients Move ALL the clients back to where they were before the time shift, except for "skip" ======================= */ void G_UnTimeShiftAllClients( edict_t *skip ) { int i; edict_t *ent; for (i=0 ; ivalue ; i++) { ent = g_edicts + 1 + i; if (!ent->inuse || !ent->client) continue; if ( ent->client && ent->inuse && !ent->client->resp.spectator && ent != skip ) { G_UnTimeShiftClient( ent ); } } } /* ================== G_UndoTimeShiftFor Put everyone except for this client back where they were ================== */ void G_UndoTimeShiftFor( edict_t *ent ) { // don't un-time shift for mistakes or bots if ( !ent->inuse || !ent->client || (ent->is_bot) ) { return; } G_UnTimeShiftAllClients( ent ); } /* ================== G_AntilagProjectile Simulate any extra frames to get the projectile "caught up" on the current state of the game. ================== */ void G_AntilagProjectile( edict_t *ent ) { int ping, time; edict_t *owner; // Save a copy of the player who fired the shot. The reason not to refer // to ent->owner directly is because if the projectile hits something, // its contents will be cleared during the call to G_RunEntity. owner = ent->owner; // don't antilag mistakes or bots if ( !ent || !ent->inuse || !owner || !owner->inuse || !owner->client || owner->is_bot ) { return; } for (ping = owner->client->ping; ping > FRAMETIME*1000; ping -= FRAMETIME*1000) { // do the full lag compensation, without the "built in" lag time = owner->client->attackTime - ping; G_TimeShiftAllClients( time, owner ); G_RunEntity (ent, FRAMETIME); G_UnTimeShiftAllClients( owner ); if ( !ent->inuse ) return; } time = owner->client->attackTime - ping; G_TimeShiftAllClients( time, owner ); G_RunEntity (ent, (float)ping/1000.0f); G_UnTimeShiftAllClients( owner ); } alien-arena-7.66+dfsg/source/game/p_trail.c0000600000175000017500000000572712161402010017624 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" /* ============================================================================== PLAYER TRAIL ============================================================================== This is a circular list containing the a list of points of where the player has been recently. It is used by monsters for pursuit. .origin the spot .owner forward link .aiment backward link */ #define TRAIL_LENGTH 8 edict_t *trail[TRAIL_LENGTH]; int trail_head; qboolean trail_active = false; #define NEXT(n) (((n) + 1) & (TRAIL_LENGTH - 1)) #define PREV(n) (((n) - 1) & (TRAIL_LENGTH - 1)) void PlayerTrail_Init (void) { int n; if (deathmatch->value) return; for (n = 0; n < TRAIL_LENGTH; n++) { trail[n] = G_Spawn(); trail[n]->classname = "player_trail"; } trail_head = 0; trail_active = true; } void PlayerTrail_Add (vec3_t spot) { vec3_t temp; if (!trail_active) return; VectorCopy (spot, trail[trail_head]->s.origin); trail[trail_head]->timestamp = level.time; VectorSubtract (spot, trail[PREV(trail_head)]->s.origin, temp); trail[trail_head]->s.angles[1] = vectoyaw (temp); trail_head = NEXT(trail_head); } void PlayerTrail_New (vec3_t spot) { if (!trail_active) return; PlayerTrail_Init (); PlayerTrail_Add (spot); } edict_t *PlayerTrail_PickFirst (edict_t *self) { int marker; int n; if (!trail_active) return NULL; for (marker = trail_head, n = TRAIL_LENGTH; n; n--) { if(trail[marker]->timestamp <= self->monsterinfo.trail_time) marker = NEXT(marker); else break; } if (visible(self, trail[marker])) { return trail[marker]; } if (visible(self, trail[PREV(marker)])) { return trail[PREV(marker)]; } return trail[marker]; } edict_t *PlayerTrail_PickNext (edict_t *self) { int marker; int n; if (!trail_active) return NULL; for (marker = trail_head, n = TRAIL_LENGTH; n; n--) { if(trail[marker]->timestamp <= self->monsterinfo.trail_time) marker = NEXT(marker); else break; } return trail[marker]; } edict_t *PlayerTrail_LastSpot (void) { return trail[PREV(trail_head)]; } alien-arena-7.66+dfsg/source/game/g_func.c0000600000175000017500000015126312161402010017430 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" /* ========================================================= PLATS movement options: linear smooth start, hard stop smooth start, smooth stop start end acceleration speed deceleration begin sound end sound target fired when reaching end wait at end object characteristics that use move segments --------------------------------------------- movetype_push, or movetype_stop action when touched action when blocked action when used disabled? auto trigger spawning ========================================================= */ #define PLAT_LOW_TRIGGER 1 #define STATE_TOP 0 #define STATE_BOTTOM 1 #define STATE_UP 2 #define STATE_DOWN 3 #define DOOR_START_OPEN 1 #define DOOR_REVERSE 2 #define DOOR_CRUSHER 4 #define DOOR_NOMONSTER 8 #define DOOR_TOGGLE 32 #define DOOR_X_AXIS 64 #define DOOR_Y_AXIS 128 // // Support routines for movement (changes in origin using velocity) // void Move_Done (edict_t *ent) { VectorClear (ent->velocity); ent->moveinfo.endfunc (ent); } void Move_Final (edict_t *ent) { if (ent->moveinfo.remaining_distance == 0) { Move_Done (ent); return; } VectorScale (ent->moveinfo.dir, ent->moveinfo.remaining_distance / FRAMETIME, ent->velocity); ent->think = Move_Done; ent->nextthink = level.time + FRAMETIME; } void Move_Begin (edict_t *ent) { float frames; if ((ent->moveinfo.speed * FRAMETIME) >= ent->moveinfo.remaining_distance) { Move_Final (ent); return; } VectorScale (ent->moveinfo.dir, ent->moveinfo.speed, ent->velocity); frames = floor((ent->moveinfo.remaining_distance / ent->moveinfo.speed) / FRAMETIME); ent->moveinfo.remaining_distance -= frames * ent->moveinfo.speed * FRAMETIME; ent->nextthink = level.time + (frames * FRAMETIME); ent->think = Move_Final; } void Think_AccelMove (edict_t *ent); void Move_Calc (edict_t *ent, vec3_t dest, void(*func)(edict_t*)) { VectorClear (ent->velocity); VectorSubtract (dest, ent->s.origin, ent->moveinfo.dir); ent->moveinfo.remaining_distance = VectorNormalize (ent->moveinfo.dir); ent->moveinfo.endfunc = func; if (ent->moveinfo.speed == ent->moveinfo.accel && ent->moveinfo.speed == ent->moveinfo.decel) { if (level.current_entity == ((ent->flags & FL_TEAMSLAVE) ? ent->teammaster : ent)) { Move_Begin (ent); } else { ent->nextthink = level.time + FRAMETIME; ent->think = Move_Begin; } } else { // accelerative ent->moveinfo.current_speed = 0; ent->think = Think_AccelMove; ent->nextthink = level.time + FRAMETIME; } } // // Support routines for angular movement (changes in angle using avelocity) // void AngleMove_Done (edict_t *ent) { VectorClear (ent->avelocity); ent->moveinfo.endfunc (ent); } void AngleMove_Final (edict_t *ent) { vec3_t move; if (ent->moveinfo.state == STATE_UP) VectorSubtract (ent->moveinfo.end_angles, ent->s.angles, move); else VectorSubtract (ent->moveinfo.start_angles, ent->s.angles, move); if (VectorCompare (move, vec3_origin)) { AngleMove_Done (ent); return; } VectorScale (move, 1.0/FRAMETIME, ent->avelocity); ent->think = AngleMove_Done; ent->nextthink = level.time + FRAMETIME; } void AngleMove_Begin (edict_t *ent) { vec3_t destdelta; float len; float traveltime; float frames; // set destdelta to the vector needed to move if (ent->moveinfo.state == STATE_UP) VectorSubtract (ent->moveinfo.end_angles, ent->s.angles, destdelta); else VectorSubtract (ent->moveinfo.start_angles, ent->s.angles, destdelta); // calculate length of vector len = VectorLength (destdelta); // divide by speed to get time to reach dest traveltime = len / ent->moveinfo.speed; if (traveltime < FRAMETIME) { AngleMove_Final (ent); return; } frames = floor(traveltime / FRAMETIME); // scale the destdelta vector by the time spent traveling to get velocity VectorScale (destdelta, 1.0 / traveltime, ent->avelocity); // set nextthink to trigger a think when dest is reached ent->nextthink = level.time + frames * FRAMETIME; ent->think = AngleMove_Final; } void AngleMove_Calc (edict_t *ent, void(*func)(edict_t*)) { VectorClear (ent->avelocity); ent->moveinfo.endfunc = func; if (level.current_entity == ((ent->flags & FL_TEAMSLAVE) ? ent->teammaster : ent)) { AngleMove_Begin (ent); } else { ent->nextthink = level.time + FRAMETIME; ent->think = AngleMove_Begin; } } /* ============== Think_AccelMove The team has completed a frame of movement, so change the speed for the next frame ============== */ #define AccelerationDistance(target, rate) (target * ((target / rate) + 1) / 2) void plat_CalcAcceleratedMove(moveinfo_t *moveinfo) { float accel_dist; float decel_dist; moveinfo->move_speed = moveinfo->speed; if (moveinfo->remaining_distance < moveinfo->accel) { moveinfo->current_speed = moveinfo->remaining_distance; return; } accel_dist = AccelerationDistance (moveinfo->speed, moveinfo->accel); decel_dist = AccelerationDistance (moveinfo->speed, moveinfo->decel); if ((moveinfo->remaining_distance - accel_dist - decel_dist) < 0) { float f; f = (moveinfo->accel + moveinfo->decel) / (moveinfo->accel * moveinfo->decel); moveinfo->move_speed = (-2 + sqrt(4 - 4 * f * (-2 * moveinfo->remaining_distance))) / (2 * f); decel_dist = AccelerationDistance (moveinfo->move_speed, moveinfo->decel); } moveinfo->decel_distance = decel_dist; }; void plat_Accelerate (moveinfo_t *moveinfo) { // are we decelerating? if (moveinfo->remaining_distance <= moveinfo->decel_distance) { if (moveinfo->remaining_distance < moveinfo->decel_distance) { if (moveinfo->next_speed) { moveinfo->current_speed = moveinfo->next_speed; moveinfo->next_speed = 0; return; } if (moveinfo->current_speed > moveinfo->decel) moveinfo->current_speed -= moveinfo->decel; } return; } // are we at full speed and need to start decelerating during this move? if (moveinfo->current_speed == moveinfo->move_speed) if ((moveinfo->remaining_distance - moveinfo->current_speed) < moveinfo->decel_distance) { float p1_distance; float p2_distance; float distance; p1_distance = moveinfo->remaining_distance - moveinfo->decel_distance; p2_distance = moveinfo->move_speed * (1.0 - (p1_distance / moveinfo->move_speed)); distance = p1_distance + p2_distance; moveinfo->current_speed = moveinfo->move_speed; moveinfo->next_speed = moveinfo->move_speed - moveinfo->decel * (p2_distance / distance); return; } // are we accelerating? if (moveinfo->current_speed < moveinfo->speed) { float old_speed; float p1_distance; float p1_speed; float p2_distance; float distance; old_speed = moveinfo->current_speed; // figure simple acceleration up to move_speed moveinfo->current_speed += moveinfo->accel; if (moveinfo->current_speed > moveinfo->speed) moveinfo->current_speed = moveinfo->speed; // are we accelerating throughout this entire move? if ((moveinfo->remaining_distance - moveinfo->current_speed) >= moveinfo->decel_distance) return; // during this move we will accelrate from current_speed to move_speed // and cross over the decel_distance; figure the average speed for the // entire move p1_distance = moveinfo->remaining_distance - moveinfo->decel_distance; p1_speed = (old_speed + moveinfo->move_speed) / 2.0; p2_distance = moveinfo->move_speed * (1.0 - (p1_distance / p1_speed)); distance = p1_distance + p2_distance; moveinfo->current_speed = (p1_speed * (p1_distance / distance)) + (moveinfo->move_speed * (p2_distance / distance)); moveinfo->next_speed = moveinfo->move_speed - moveinfo->decel * (p2_distance / distance); return; } // we are at constant velocity (move_speed) return; }; void Think_AccelMove (edict_t *ent) { ent->moveinfo.remaining_distance -= ent->moveinfo.current_speed; if (ent->moveinfo.current_speed == 0) // starting or blocked plat_CalcAcceleratedMove(&ent->moveinfo); plat_Accelerate (&ent->moveinfo); // will the entire move complete on next frame? if (ent->moveinfo.remaining_distance <= ent->moveinfo.current_speed) { Move_Final (ent); return; } VectorScale (ent->moveinfo.dir, ent->moveinfo.current_speed*10, ent->velocity); ent->nextthink = level.time + FRAMETIME; ent->think = Think_AccelMove; } void plat_go_down (edict_t *ent); void plat_hit_top (edict_t *ent) { if (!(ent->flags & FL_TEAMSLAVE)) { if (ent->moveinfo.sound_end) gi.sound (ent, CHAN_NO_PHS_ADD+CHAN_VOICE, ent->moveinfo.sound_end, 1, ATTN_STATIC, 0); ent->s.sound = 0; } ent->moveinfo.state = STATE_TOP; ent->think = plat_go_down; ent->nextthink = level.time + 3; } void plat_hit_bottom (edict_t *ent) { if (!(ent->flags & FL_TEAMSLAVE)) { if (ent->moveinfo.sound_end) gi.sound (ent, CHAN_NO_PHS_ADD+CHAN_VOICE, ent->moveinfo.sound_end, 1, ATTN_STATIC, 0); ent->s.sound = 0; } ent->moveinfo.state = STATE_BOTTOM; } void plat_go_down (edict_t *ent) { if (!(ent->flags & FL_TEAMSLAVE)) { if (ent->moveinfo.sound_start) gi.sound (ent, CHAN_NO_PHS_ADD+CHAN_VOICE, ent->moveinfo.sound_start, 1, ATTN_STATIC, 0); ent->s.sound = gi.soundindex ("world/turbine1.wav"); } ent->moveinfo.state = STATE_DOWN; Move_Calc (ent, ent->moveinfo.end_origin, plat_hit_bottom); } void plat_go_up (edict_t *ent) { if (!(ent->flags & FL_TEAMSLAVE)) { if (ent->moveinfo.sound_start) gi.sound (ent, CHAN_NO_PHS_ADD+CHAN_VOICE, ent->moveinfo.sound_start, 1, ATTN_STATIC, 0); ent->s.sound = gi.soundindex ("world/turbine1.wav"); } ent->moveinfo.state = STATE_UP; Move_Calc (ent, ent->moveinfo.start_origin, plat_hit_top); } void plat_blocked (edict_t *self, edict_t *other) { if (!(other->svflags & SVF_MONSTER) && (!other->client) ) { // give it a chance to go away on it's own terms (like gibs) T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH); return; } T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH); if (self->moveinfo.state == STATE_UP) plat_go_down (self); else if (self->moveinfo.state == STATE_DOWN) plat_go_up (self); } void Use_Plat (edict_t *ent, edict_t *other, edict_t *activator) { if (ent->think) return; // already down plat_go_down (ent); } void Touch_Plat_Center (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { if (!other->client) return; if (other->health <= 0) return; ent = ent->enemy; // now point at the plat, not the trigger if (ent->moveinfo.state == STATE_BOTTOM) plat_go_up (ent); else if (ent->moveinfo.state == STATE_TOP) ent->nextthink = level.time + 1; // the player is still on the plat, so delay going down } void plat_spawn_inside_trigger (edict_t *ent) { edict_t *trigger; vec3_t tmin, tmax; // // middle trigger // trigger = G_Spawn(); trigger->touch = Touch_Plat_Center; trigger->movetype = MOVETYPE_NONE; trigger->solid = SOLID_TRIGGER; trigger->enemy = ent; tmin[0] = ent->mins[0] + 25; tmin[1] = ent->mins[1] + 25; tmin[2] = ent->mins[2]; tmax[0] = ent->maxs[0] - 25; tmax[1] = ent->maxs[1] - 25; tmax[2] = ent->maxs[2] + 8; tmin[2] = tmax[2] - (ent->pos1[2] - ent->pos2[2] + st.lip); if (ent->spawnflags & PLAT_LOW_TRIGGER) tmax[2] = tmin[2] + 8; if (tmax[0] - tmin[0] <= 0) { tmin[0] = (ent->mins[0] + ent->maxs[0]) *0.5; tmax[0] = tmin[0] + 1; } if (tmax[1] - tmin[1] <= 0) { tmin[1] = (ent->mins[1] + ent->maxs[1]) *0.5; tmax[1] = tmin[1] + 1; } VectorCopy (tmin, trigger->mins); VectorCopy (tmax, trigger->maxs); gi.linkentity (trigger); } /*QUAKED func_plat (0 .5 .8) ? PLAT_LOW_TRIGGER speed default 150 Plats are always drawn in the extended position, so they will light correctly. If the plat is the target of another trigger or button, it will start out disabled in the extended position until it is trigger, when it will lower and become a normal plat. "speed" overrides default 200. "accel" overrides default 500 "lip" overrides default 8 pixel lip If the "height" key is set, that will determine the amount the plat moves, instead of being implicitly determoveinfoned by the model's height. Set "sounds" to one of the following: 1) base fast 2) chain slow */ void SP_func_plat (edict_t *ent) { VectorClear (ent->s.angles); ent->solid = SOLID_BSP; ent->movetype = MOVETYPE_PUSH; gi.setmodel (ent, ent->model); ent->blocked = plat_blocked; if (!ent->speed) ent->speed = 20; else ent->speed *= 0.1; if (!ent->accel) ent->accel = 5; else ent->accel *= 0.1; if (!ent->decel) ent->decel = 5; else ent->decel *= 0.1; if (!ent->dmg) ent->dmg = 2; if (!st.lip) st.lip = 8; // pos1 is the top position, pos2 is the bottom VectorCopy (ent->s.origin, ent->pos1); VectorCopy (ent->s.origin, ent->pos2); if (st.height) ent->pos2[2] -= st.height; else ent->pos2[2] -= (ent->maxs[2] - ent->mins[2]) - st.lip; ent->use = Use_Plat; plat_spawn_inside_trigger (ent); // the "start moving" trigger if (ent->targetname) { ent->moveinfo.state = STATE_UP; } else { VectorCopy (ent->pos2, ent->s.origin); gi.linkentity (ent); ent->moveinfo.state = STATE_BOTTOM; } ent->moveinfo.speed = ent->speed; ent->moveinfo.accel = ent->accel; ent->moveinfo.decel = ent->decel; ent->moveinfo.wait = ent->wait; VectorCopy (ent->pos1, ent->moveinfo.start_origin); VectorCopy (ent->s.angles, ent->moveinfo.start_angles); VectorCopy (ent->pos2, ent->moveinfo.end_origin); VectorCopy (ent->s.angles, ent->moveinfo.end_angles); ent->moveinfo.sound_start = gi.soundindex ("world/turbine1.wav"); ent->moveinfo.sound_middle = gi.soundindex ("world/turbine1.wav"); ent->moveinfo.sound_end = gi.soundindex ("world/platstop.wav"); } //==================================================================== /*QUAKED func_rotating (0 .5 .8) ? START_ON REVERSE X_AXIS Y_AXIS TOUCH_PAIN STOP ANIMATED ANIMATED_FAST You need to have an origin brush as part of this entity. The center of that brush will be the point around which it is rotated. It will rotate around the Z axis by default. You can check either the X_AXIS or Y_AXIS box to change that. "speed" determines how fast it moves; default value is 100. "dmg" damage to inflict when blocked (2 default) REVERSE will cause the it to rotate in the opposite direction. STOP mean it will stop moving instead of pushing entities */ void rotating_blocked (edict_t *self, edict_t *other) { T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH); } void rotating_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { if (self->avelocity[0] || self->avelocity[1] || self->avelocity[2]) T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH); } void rotating_use (edict_t *self, edict_t *other, edict_t *activator) { if (!VectorCompare (self->avelocity, vec3_origin)) { self->s.sound = 0; VectorClear (self->avelocity); self->touch = NULL; } else { self->s.sound = self->moveinfo.sound_middle; VectorScale (self->movedir, self->speed, self->avelocity); if (self->spawnflags & 16) self->touch = rotating_touch; } } void SP_func_rotating (edict_t *ent) { if (ent->spawnflags & 32) ent->movetype = MOVETYPE_STOP; else ent->movetype = MOVETYPE_PUSH; // set the axis of rotation VectorClear(ent->movedir); if (ent->spawnflags & 4) ent->movedir[2] = 1.0; else if (ent->spawnflags & 8) ent->movedir[0] = 1.0; else // Z_AXIS ent->movedir[1] = 1.0; // check for reverse rotation if (ent->spawnflags & 2) VectorNegate (ent->movedir, ent->movedir); if (!ent->speed) ent->speed = 100; if (!ent->dmg) ent->dmg = 2; // ent->moveinfo.sound_middle = "doors/hydro1.wav"; ent->use = rotating_use; if (ent->dmg) ent->blocked = rotating_blocked; if (ent->spawnflags & 1) ent->use (ent, NULL, NULL); if(ent->spawnflags & 64) ent->solid = SOLID_NOT; else ent->solid = SOLID_BSP; if(!(ent->spawnflags & 128)) ent->s.renderfx = (RF_NOSHADOWS | RF_MINLIGHT); gi.setmodel (ent, ent->model); gi.linkentity (ent); } /* ====================================================================== BUTTONS ====================================================================== */ /*QUAKED func_button (0 .5 .8) ? When a button is touched, it moves some distance in the direction of it's angle, triggers all of it's targets, waits some time, then returns to it's original position where it can be triggered again. "angle" determines the opening direction "target" all entities with a matching targetname will be used "speed" override the default 40 speed "wait" override the default 1 second wait (-1 = never return) "lip" override the default 4 pixel lip remaining at end of move "health" if set, the button must be killed instead of touched "sounds" 1) silent 2) steam metal 3) wooden clunk 4) metallic click 5) in-out */ void button_done (edict_t *self) { self->moveinfo.state = STATE_BOTTOM; self->s.effects &= ~EF_ANIM23; self->s.effects |= EF_ANIM01; } void button_return (edict_t *self) { self->moveinfo.state = STATE_DOWN; Move_Calc (self, self->moveinfo.start_origin, button_done); self->s.frame = 0; if (self->health) self->takedamage = DAMAGE_YES; } void button_wait (edict_t *self) { self->moveinfo.state = STATE_TOP; self->s.effects &= ~EF_ANIM01; self->s.effects |= EF_ANIM23; G_UseTargets (self, self->activator); self->s.frame = 1; if (self->moveinfo.wait >= 0) { self->nextthink = level.time + self->moveinfo.wait; self->think = button_return; } } void button_fire (edict_t *self) { if (self->moveinfo.state == STATE_UP || self->moveinfo.state == STATE_TOP) return; self->moveinfo.state = STATE_UP; if (self->moveinfo.sound_start && !(self->flags & FL_TEAMSLAVE)) gi.sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self->moveinfo.sound_start, 1, ATTN_STATIC, 0); Move_Calc (self, self->moveinfo.end_origin, button_wait); } void button_use (edict_t *self, edict_t *other, edict_t *activator) { self->activator = activator; button_fire (self); } void button_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { //do not allow buttons to be activated in warmup if(level.time <= warmuptime->value) return; if (!other->client) return; if (other->health <= 0) return; self->activator = other; button_fire (self); //button pusher is immune to death rays - use spawn flags if(self->spawnflags & 1) { other->client->rayImmunity = true; other->client->rayTime = level.time; } } void button_killed (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { self->activator = attacker; self->health = self->max_health; self->takedamage = DAMAGE_NO; button_fire (self); } void SP_func_button (edict_t *ent) { vec3_t abs_movedir; float dist; G_SetMovedir (ent->s.angles, ent->movedir); ent->movetype = MOVETYPE_STOP; ent->solid = SOLID_BSP; gi.setmodel (ent, ent->model); if (ent->sounds != 1) ent->moveinfo.sound_start = gi.soundindex ("world/button2.wav"); if (!ent->speed) ent->speed = 40; if (!ent->accel) ent->accel = ent->speed; if (!ent->decel) ent->decel = ent->speed; if (!ent->wait) ent->wait = 3; if (!st.lip) st.lip = 4; VectorCopy (ent->s.origin, ent->pos1); abs_movedir[0] = fabs(ent->movedir[0]); abs_movedir[1] = fabs(ent->movedir[1]); abs_movedir[2] = fabs(ent->movedir[2]); dist = abs_movedir[0] * ent->size[0] + abs_movedir[1] * ent->size[1] + abs_movedir[2] * ent->size[2] - st.lip; VectorMA (ent->pos1, dist, ent->movedir, ent->pos2); ent->use = button_use; ent->s.effects |= EF_ANIM01; if (ent->health) { ent->max_health = ent->health; ent->die = button_killed; ent->takedamage = DAMAGE_YES; } else if (! ent->targetname) ent->touch = button_touch; ent->moveinfo.state = STATE_BOTTOM; ent->moveinfo.speed = ent->speed; ent->moveinfo.accel = ent->accel; ent->moveinfo.decel = ent->decel; ent->moveinfo.wait = ent->wait; VectorCopy (ent->pos1, ent->moveinfo.start_origin); VectorCopy (ent->s.angles, ent->moveinfo.start_angles); VectorCopy (ent->pos2, ent->moveinfo.end_origin); VectorCopy (ent->s.angles, ent->moveinfo.end_angles); gi.linkentity (ent); } /* ====================================================================== DOORS spawn a trigger surrounding the entire team unless it is already targeted by another ====================================================================== */ /*QUAKED func_door (0 .5 .8) ? START_OPEN x CRUSHER NOMONSTER ANIMATED TOGGLE ANIMATED_FAST TOGGLE wait in both the start and end states for a trigger event. START_OPEN the door to moves to its destination when spawned, and operate in reverse. It is used to temporarily or permanently close off an area when triggered (not useful for touch or takedamage doors). NOMONSTER monsters will not trigger this door "message" is printed when the door is touched if it is a trigger door and it hasn't been fired yet "angle" determines the opening direction "targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door. "health" if set, door must be shot open "speed" movement speed (100 default) "wait" wait before returning (3 default, -1 = never return) "lip" lip remaining at end of move (8 default) "dmg" damage to inflict when blocked (2 default) "sounds" 1) silent 2) light 3) medium 4) heavy */ void door_use_areaportals (edict_t *self, qboolean open) { edict_t *t = NULL; if (!self->target) return; while ((t = G_Find (t, FOFS(targetname), self->target))) { if (Q_strcasecmp(t->classname, "func_areaportal") == 0) { gi.SetAreaPortalState (t->style, open); } } } void door_go_down (edict_t *self); void door_hit_top (edict_t *self) { if (!(self->flags & FL_TEAMSLAVE)) { if (self->moveinfo.sound_end) gi.sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self->moveinfo.sound_end, 1, ATTN_STATIC, 0); self->s.sound = 0; } self->moveinfo.state = STATE_TOP; if (self->spawnflags & DOOR_TOGGLE) return; if (self->moveinfo.wait >= 0) { self->think = door_go_down; self->nextthink = level.time + self->moveinfo.wait; } } void door_hit_bottom (edict_t *self) { if (!(self->flags & FL_TEAMSLAVE)) { if (self->moveinfo.sound_end) gi.sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self->moveinfo.sound_end, 1, ATTN_STATIC, 0); self->s.sound = 0; } self->moveinfo.state = STATE_BOTTOM; door_use_areaportals (self, false); } void door_go_down (edict_t *self) { if (!(self->flags & FL_TEAMSLAVE)) { if (self->moveinfo.sound_start) gi.sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self->moveinfo.sound_start, 1, ATTN_STATIC, 0); self->s.sound = self->moveinfo.sound_middle; } if (self->max_health) { self->takedamage = DAMAGE_YES; self->health = self->max_health; } self->moveinfo.state = STATE_DOWN; if (strcmp(self->classname, "func_door") == 0) Move_Calc (self, self->moveinfo.start_origin, door_hit_bottom); else if (strcmp(self->classname, "func_door_rotating") == 0) AngleMove_Calc (self, door_hit_bottom); } void door_go_up (edict_t *self, edict_t *activator) { if (self->moveinfo.state == STATE_UP) return; // already going up if (self->moveinfo.state == STATE_TOP) { // reset top wait time if (self->moveinfo.wait >= 0) self->nextthink = level.time + self->moveinfo.wait; return; } if (!(self->flags & FL_TEAMSLAVE)) { if (self->moveinfo.sound_start) gi.sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self->moveinfo.sound_start, 1, ATTN_STATIC, 0); self->s.sound = self->moveinfo.sound_middle; } self->moveinfo.state = STATE_UP; if (strcmp(self->classname, "func_door") == 0) Move_Calc (self, self->moveinfo.end_origin, door_hit_top); else if (strcmp(self->classname, "func_door_rotating") == 0) AngleMove_Calc (self, door_hit_top); G_UseTargets (self, activator); door_use_areaportals (self, true); } void door_use (edict_t *self, edict_t *other, edict_t *activator) { edict_t *ent; if (self->flags & FL_TEAMSLAVE) return; if (self->spawnflags & DOOR_TOGGLE) { if (self->moveinfo.state == STATE_UP || self->moveinfo.state == STATE_TOP) { // trigger all paired doors for (ent = self ; ent ; ent = ent->teamchain) { ent->message = NULL; ent->touch = NULL; door_go_down (ent); } return; } } // trigger all paired doors for (ent = self ; ent ; ent = ent->teamchain) { ent->message = NULL; ent->touch = NULL; door_go_up (ent, activator); } }; void Touch_DoorTrigger (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { if (other->health <= 0) return; if (!(other->svflags & SVF_MONSTER) && (!other->client)) return; if ((self->owner->spawnflags & DOOR_NOMONSTER) && (other->svflags & SVF_MONSTER)) return; if (level.time < self->touch_debounce_time) return; self->touch_debounce_time = level.time + 1.0; door_use (self->owner, other, other); } void Think_CalcMoveSpeed (edict_t *self) { edict_t *ent; float min; float time; float newspeed; float ratio; float dist; if (self->flags & FL_TEAMSLAVE) return; // only the team master does this // find the smallest distance any member of the team will be moving min = fabs(self->moveinfo.distance); for (ent = self->teamchain; ent; ent = ent->teamchain) { dist = fabs(ent->moveinfo.distance); if (dist < min) min = dist; } time = min / self->moveinfo.speed; // adjust speeds so they will all complete at the same time for (ent = self; ent; ent = ent->teamchain) { newspeed = fabs(ent->moveinfo.distance) / time; ratio = newspeed / ent->moveinfo.speed; if (ent->moveinfo.accel == ent->moveinfo.speed) ent->moveinfo.accel = newspeed; else ent->moveinfo.accel *= ratio; if (ent->moveinfo.decel == ent->moveinfo.speed) ent->moveinfo.decel = newspeed; else ent->moveinfo.decel *= ratio; ent->moveinfo.speed = newspeed; } } void Think_SpawnDoorTrigger (edict_t *ent) { edict_t *other; vec3_t mins, maxs; if (ent->flags & FL_TEAMSLAVE) return; // only the team leader spawns a trigger VectorCopy (ent->absmin, mins); VectorCopy (ent->absmax, maxs); for (other = ent->teamchain ; other ; other=other->teamchain) { AddPointToBounds (other->absmin, mins, maxs); AddPointToBounds (other->absmax, mins, maxs); } // expand mins[0] -= 60; mins[1] -= 60; maxs[0] += 60; maxs[1] += 60; other = G_Spawn (); VectorCopy (mins, other->mins); VectorCopy (maxs, other->maxs); other->owner = ent; other->solid = SOLID_TRIGGER; other->movetype = MOVETYPE_NONE; other->touch = Touch_DoorTrigger; gi.linkentity (other); if (ent->spawnflags & DOOR_START_OPEN) door_use_areaportals (ent, true); Think_CalcMoveSpeed (ent); } void door_blocked (edict_t *self, edict_t *other) { edict_t *ent; if (!(other->svflags & SVF_MONSTER) && (!other->client) ) { // give it a chance to go away on it's own terms (like gibs) T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH); return; } T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH); if (self->spawnflags & DOOR_CRUSHER) return; // if a door has a negative wait, it would never come back if blocked, // so let it just squash the object to death real fast if (self->moveinfo.wait >= 0) { if (self->moveinfo.state == STATE_DOWN) { for (ent = self->teammaster ; ent ; ent = ent->teamchain) door_go_up (ent, ent->activator); } else { for (ent = self->teammaster ; ent ; ent = ent->teamchain) door_go_down (ent); } } } void door_killed (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { edict_t *ent; for (ent = self->teammaster ; ent ; ent = ent->teamchain) { ent->health = ent->max_health; ent->takedamage = DAMAGE_NO; } door_use (self->teammaster, attacker, attacker); } void door_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { if (!other->client) return; if (level.time < self->touch_debounce_time) return; self->touch_debounce_time = level.time + 5.0; safe_centerprintf (other, "%s", self->message); gi.sound (other, CHAN_AUTO, gi.soundindex ("misc/talk1.wav"), 1, ATTN_NORM, 0); } void SP_func_door (edict_t *ent) { vec3_t abs_movedir; if (ent->sounds != 1) { ent->moveinfo.sound_start = gi.soundindex ("doors/dr1_strt.wav"); ent->moveinfo.sound_middle = gi.soundindex ("doors/dr1_mid.wav"); ent->moveinfo.sound_end = gi.soundindex ("doors/dr1_end.wav"); } G_SetMovedir (ent->s.angles, ent->movedir); ent->movetype = MOVETYPE_PUSH; ent->solid = SOLID_BSP; gi.setmodel (ent, ent->model); ent->blocked = door_blocked; ent->use = door_use; if (!ent->speed) ent->speed = 100; if (deathmatch->value) ent->speed *= 2; if (!ent->accel) ent->accel = ent->speed; if (!ent->decel) ent->decel = ent->speed; if (!ent->wait) ent->wait = 3; if (!st.lip) st.lip = 8; if (!ent->dmg) ent->dmg = 2; // calculate second position VectorCopy (ent->s.origin, ent->pos1); abs_movedir[0] = fabs(ent->movedir[0]); abs_movedir[1] = fabs(ent->movedir[1]); abs_movedir[2] = fabs(ent->movedir[2]); ent->moveinfo.distance = abs_movedir[0] * ent->size[0] + abs_movedir[1] * ent->size[1] + abs_movedir[2] * ent->size[2] - st.lip; VectorMA (ent->pos1, ent->moveinfo.distance, ent->movedir, ent->pos2); // if it starts open, switch the positions if (ent->spawnflags & DOOR_START_OPEN) { VectorCopy (ent->pos2, ent->s.origin); VectorCopy (ent->pos1, ent->pos2); VectorCopy (ent->s.origin, ent->pos1); } ent->moveinfo.state = STATE_BOTTOM; if (!ent->targetname && (!ent->health || ent->health > 8)) ent->health = 1; if (ent->health) { ent->takedamage = DAMAGE_YES; ent->die = door_killed; ent->max_health = ent->health; } if (ent->targetname && ent->message) { gi.soundindex ("misc/talk.wav"); ent->touch = door_touch; } ent->moveinfo.speed = ent->speed; ent->moveinfo.accel = ent->accel; ent->moveinfo.decel = ent->decel; ent->moveinfo.wait = ent->wait; VectorCopy (ent->pos1, ent->moveinfo.start_origin); VectorCopy (ent->s.angles, ent->moveinfo.start_angles); VectorCopy (ent->pos2, ent->moveinfo.end_origin); VectorCopy (ent->s.angles, ent->moveinfo.end_angles); if (ent->spawnflags & 16) ent->s.effects |= EF_ANIM_ALL; if (ent->spawnflags & 64) ent->s.effects |= EF_ANIM_ALLFAST; // to simplify logic elsewhere, make non-teamed doors into a team of one if (!ent->team) ent->teammaster = ent; gi.linkentity (ent); ent->nextthink = level.time + FRAMETIME; if (ent->targetname) ent->think = Think_CalcMoveSpeed; else ent->think = Think_SpawnDoorTrigger; } /*QUAKED func_door_rotating (0 .5 .8) ? START_OPEN REVERSE CRUSHER NOMONSTER ANIMATED TOGGLE X_AXIS Y_AXIS TOGGLE causes the door to wait in both the start and end states for a trigger event. START_OPEN the door to moves to its destination when spawned, and operate in reverse. It is used to temporarily or permanently close off an area when triggered (not useful for touch or takedamage doors). NOMONSTER monsters will not trigger this door You need to have an origin brush as part of this entity. The center of that brush will be the point around which it is rotated. It will rotate around the Z axis by default. You can check either the X_AXIS or Y_AXIS box to change that. "distance" is how many degrees the door will be rotated. "speed" determines how fast the door moves; default value is 100. REVERSE will cause the door to rotate in the opposite direction. "message" is printed when the door is touched if it is a trigger door and it hasn't been fired yet "angle" determines the opening direction "targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door. "health" if set, door must be shot open "speed" movement speed (100 default) "wait" wait before returning (3 default, -1 = never return) "dmg" damage to inflict when blocked (2 default) "sounds" 1) silent 2) light 3) medium 4) heavy */ void SP_func_door_rotating (edict_t *ent) { VectorClear (ent->s.angles); // set the axis of rotation VectorClear(ent->movedir); if (ent->spawnflags & DOOR_X_AXIS) ent->movedir[2] = 1.0; else if (ent->spawnflags & DOOR_Y_AXIS) ent->movedir[0] = 1.0; else // Z_AXIS ent->movedir[1] = 1.0; // check for reverse rotation if (ent->spawnflags & DOOR_REVERSE) VectorNegate (ent->movedir, ent->movedir); if (!st.distance) { gi.dprintf("%s at %s with no distance set\n", ent->classname, vtos(ent->s.origin)); st.distance = 90; } VectorCopy (ent->s.angles, ent->pos1); VectorMA (ent->s.angles, st.distance, ent->movedir, ent->pos2); ent->moveinfo.distance = st.distance; ent->movetype = MOVETYPE_PUSH; ent->solid = SOLID_BSP; gi.setmodel (ent, ent->model); ent->blocked = door_blocked; ent->use = door_use; if (!ent->speed) ent->speed = 100; if (!ent->accel) ent->accel = ent->speed; if (!ent->decel) ent->decel = ent->speed; if (!ent->wait) ent->wait = 3; if (!ent->dmg) ent->dmg = 2; if (ent->sounds != 1) { ent->moveinfo.sound_start = gi.soundindex ("doors/dr1_strt.wav"); ent->moveinfo.sound_middle = gi.soundindex ("doors/dr1_mid.wav"); ent->moveinfo.sound_end = gi.soundindex ("doors/dr1_end.wav"); } // if it starts open, switch the positions if (ent->spawnflags & DOOR_START_OPEN) { VectorCopy (ent->pos2, ent->s.angles); VectorCopy (ent->pos1, ent->pos2); VectorCopy (ent->s.angles, ent->pos1); VectorNegate (ent->movedir, ent->movedir); } if (ent->health) { ent->takedamage = DAMAGE_YES; ent->die = door_killed; ent->max_health = ent->health; } if (ent->targetname && ent->message) { gi.soundindex ("misc/talk.wav"); ent->touch = door_touch; } ent->moveinfo.state = STATE_BOTTOM; ent->moveinfo.speed = ent->speed; ent->moveinfo.accel = ent->accel; ent->moveinfo.decel = ent->decel; ent->moveinfo.wait = ent->wait; VectorCopy (ent->s.origin, ent->moveinfo.start_origin); VectorCopy (ent->pos1, ent->moveinfo.start_angles); VectorCopy (ent->s.origin, ent->moveinfo.end_origin); VectorCopy (ent->pos2, ent->moveinfo.end_angles); if (ent->spawnflags & 16) ent->s.effects |= EF_ANIM_ALL; // to simplify logic elsewhere, make non-teamed doors into a team of one if (!ent->team) ent->teammaster = ent; gi.linkentity (ent); ent->nextthink = level.time + FRAMETIME; if (ent->health || ent->targetname) ent->think = Think_CalcMoveSpeed; else ent->think = Think_SpawnDoorTrigger; } /*QUAKED func_water (0 .5 .8) ? START_OPEN func_water is a moveable water brush. It must be targeted to operate. Use a non-water texture at your own risk. START_OPEN causes the water to move to its destination when spawned and operate in reverse. "angle" determines the opening direction (up or down only) "speed" movement speed (25 default) "wait" wait before returning (-1 default, -1 = TOGGLE) "lip" lip remaining at end of move (0 default) "sounds" (yes, these need to be changed) 0) no sound 1) water 2) lava */ void SP_func_water (edict_t *self) { vec3_t abs_movedir; G_SetMovedir (self->s.angles, self->movedir); self->movetype = MOVETYPE_PUSH; self->solid = SOLID_BSP; gi.setmodel (self, self->model); switch (self->sounds) { default: break; case 1: // water self->moveinfo.sound_start = gi.soundindex ("world/mov_watr.wav"); self->moveinfo.sound_end = gi.soundindex ("world/stp_watr.wav"); break; case 2: // lava self->moveinfo.sound_start = gi.soundindex ("world/mov_watr.wav"); self->moveinfo.sound_end = gi.soundindex ("world/stp_watr.wav"); break; } // calculate second position VectorCopy (self->s.origin, self->pos1); abs_movedir[0] = fabs(self->movedir[0]); abs_movedir[1] = fabs(self->movedir[1]); abs_movedir[2] = fabs(self->movedir[2]); self->moveinfo.distance = abs_movedir[0] * self->size[0] + abs_movedir[1] * self->size[1] + abs_movedir[2] * self->size[2] - st.lip; VectorMA (self->pos1, self->moveinfo.distance, self->movedir, self->pos2); // if it starts open, switch the positions if (self->spawnflags & DOOR_START_OPEN) { VectorCopy (self->pos2, self->s.origin); VectorCopy (self->pos1, self->pos2); VectorCopy (self->s.origin, self->pos1); } VectorCopy (self->pos1, self->moveinfo.start_origin); VectorCopy (self->s.angles, self->moveinfo.start_angles); VectorCopy (self->pos2, self->moveinfo.end_origin); VectorCopy (self->s.angles, self->moveinfo.end_angles); self->moveinfo.state = STATE_BOTTOM; if (!self->speed) self->speed = 25; self->moveinfo.accel = self->moveinfo.decel = self->moveinfo.speed = self->speed; if (!self->wait) self->wait = -1; self->moveinfo.wait = self->wait; self->use = door_use; if (self->wait == -1) self->spawnflags |= DOOR_TOGGLE; self->classname = "func_door"; gi.linkentity (self); } #define TRAIN_START_ON 1 #define TRAIN_TOGGLE 2 #define TRAIN_BLOCK_STOPS 4 /*QUAKED func_train (0 .5 .8) ? START_ON TOGGLE BLOCK_STOPS Trains are moving platforms that players can ride. The targets origin specifies the min point of the train at each corner. The train spawns at the first target it is pointing at. If the train is the target of a button or trigger, it will not begin moving until activated. speed default 100 dmg default 2 noise looping sound to play when the train is in motion */ void train_next (edict_t *self); void train_blocked (edict_t *self, edict_t *other) { if (!(other->svflags & SVF_MONSTER) && (!other->client) ) { // give it a chance to go away on it's own terms (like gibs) T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH); return; } if (level.time < self->touch_debounce_time) return; if (!self->dmg) return; self->touch_debounce_time = level.time + 0.5; T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH); } void train_wait (edict_t *self) { if (self->target_ent->pathtarget) { char *savetarget; edict_t *ent; ent = self->target_ent; savetarget = ent->target; ent->target = ent->pathtarget; G_UseTargets (ent, self->activator); ent->target = savetarget; // make sure we didn't get killed by a killtarget if (!self->inuse) return; } if (self->moveinfo.wait) { if (self->moveinfo.wait > 0) { self->nextthink = level.time + self->moveinfo.wait; self->think = train_next; } else if (self->spawnflags & TRAIN_TOGGLE) // && wait < 0 { train_next (self); self->spawnflags &= ~TRAIN_START_ON; VectorClear (self->velocity); self->nextthink = 0; } if (!(self->flags & FL_TEAMSLAVE)) { if (self->moveinfo.sound_end) gi.sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self->moveinfo.sound_end, 1, ATTN_STATIC, 0); self->s.sound = 0; } } else { train_next (self); } } void train_next (edict_t *self) { edict_t *ent; vec3_t dest; qboolean first; first = true; again: if (!self->target) { // gi.dprintf ("train_next: no next target\n"); return; } ent = G_PickTarget (self->target); if (!ent) { gi.dprintf ("train_next: bad target %s\n", self->target); return; } self->target = ent->target; // check for a teleport path_corner if (ent->spawnflags & 1) { if (!first) { gi.dprintf ("connected teleport path_corners, see %s at %s\n", ent->classname, vtos(ent->s.origin)); return; } first = false; VectorSubtract (ent->s.origin, self->mins, self->s.origin); VectorCopy (self->s.origin, self->s.old_origin); self->s.event = EV_OTHER_TELEPORT; gi.linkentity (self); goto again; } self->moveinfo.wait = ent->wait; self->target_ent = ent; if (!(self->flags & FL_TEAMSLAVE)) { if (self->moveinfo.sound_start) gi.sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self->moveinfo.sound_start, 1, ATTN_STATIC, 0); if(self->spawnflags & 64) self->s.sound = gi.soundindex("world/electricity.wav"); else self->s.sound = gi.soundindex ("world/turbine1.wav"); } VectorSubtract (ent->s.origin, self->mins, dest); self->moveinfo.state = STATE_TOP; VectorCopy (self->s.origin, self->moveinfo.start_origin); VectorCopy (dest, self->moveinfo.end_origin); Move_Calc (self, dest, train_wait); VectorCopy (ent->s.angles, self->s.angles); self->spawnflags |= TRAIN_START_ON; } void train_resume (edict_t *self) { edict_t *ent; vec3_t dest; ent = self->target_ent; VectorSubtract (ent->s.origin, self->mins, dest); self->moveinfo.state = STATE_TOP; VectorCopy (self->s.origin, self->moveinfo.start_origin); VectorCopy (dest, self->moveinfo.end_origin); Move_Calc (self, dest, train_wait); self->spawnflags |= TRAIN_START_ON; } void func_train_find (edict_t *self) { edict_t *ent; if (!self->target) { gi.dprintf ("train_find: no target\n"); return; } ent = G_PickTarget (self->target); if (!ent) { gi.dprintf ("train_find: target %s not found\n", self->target); return; } self->target = ent->target; VectorSubtract (ent->s.origin, self->mins, self->s.origin); gi.linkentity (self); // if not triggered, start immediately if (!self->targetname) self->spawnflags |= TRAIN_START_ON; if (self->spawnflags & TRAIN_START_ON) { self->nextthink = level.time + FRAMETIME; self->think = train_next; self->activator = self; } } void train_use (edict_t *self, edict_t *other, edict_t *activator) { self->activator = activator; if (self->spawnflags & TRAIN_START_ON) { if (!(self->spawnflags & TRAIN_TOGGLE)) return; self->spawnflags &= ~TRAIN_START_ON; VectorClear (self->velocity); self->nextthink = 0; } else { if (self->target_ent) train_resume(self); else train_next(self); } } void SP_func_train (edict_t *self) { self->movetype = MOVETYPE_PUSH; VectorClear (self->s.angles); self->blocked = train_blocked; if (self->spawnflags & TRAIN_BLOCK_STOPS) self->dmg = 0; else { if (!self->dmg) self->dmg = 100; } if(self->spawnflags & 8) self->solid = SOLID_NOT; else self->solid = SOLID_BSP; gi.setmodel (self, self->model); self->s.frame = 0; //in case of mesh if(self->spawnflags & 16) self->s.renderfx = RF_TRANSLUCENT; self->s.renderfx |= RF_NOSHADOWS; //just too unpredictable and odd if(self->spawnflags & 64) self->s.effects |= EF_HYPERBLASTER; //teleporter type effect self->moveinfo.sound_middle = gi.soundindex ("world/turbine1.wav"); if (!self->speed) self->speed = 100; self->moveinfo.speed = self->speed; self->moveinfo.accel = self->moveinfo.decel = self->moveinfo.speed; self->use = train_use; gi.linkentity (self); if (self->target) { // start trains on the second frame, to make sure their targets have had // a chance to spawn self->nextthink = level.time + FRAMETIME; self->think = func_train_find; } else { gi.dprintf ("func_train without a target at %s\n", vtos(self->absmin)); } } /*QUAKED trigger_elevator (0.3 0.1 0.6) (-8 -8 -8) (8 8 8) */ void trigger_elevator_use (edict_t *self, edict_t *other, edict_t *activator) { edict_t *target; if (self->movetarget->nextthink) { // gi.dprintf("elevator busy\n"); return; } if (!other->pathtarget) { gi.dprintf("elevator used with no pathtarget\n"); return; } target = G_PickTarget (other->pathtarget); if (!target) { gi.dprintf("elevator used with bad pathtarget: %s\n", other->pathtarget); return; } self->movetarget->target_ent = target; train_resume (self->movetarget); } void trigger_elevator_init (edict_t *self) { if (!self->target) { gi.dprintf("trigger_elevator has no target\n"); return; } self->movetarget = G_PickTarget (self->target); if (!self->movetarget) { gi.dprintf("trigger_elevator unable to find target %s\n", self->target); return; } if (strcmp(self->movetarget->classname, "func_train") != 0) { gi.dprintf("trigger_elevator target %s is not a train\n", self->target); return; } self->use = trigger_elevator_use; self->svflags = SVF_NOCLIENT; } void SP_trigger_elevator (edict_t *self) { self->think = trigger_elevator_init; self->nextthink = level.time + FRAMETIME; } /*QUAKED func_timer (0.3 0.1 0.6) (-8 -8 -8) (8 8 8) START_ON "wait" base time between triggering all targets, default is 1 "random" wait variance, default is 0 so, the basic time between firing is a random time between (wait - random) and (wait + random) "delay" delay before first firing when turned on, default is 0 "pausetime" additional delay used only the very first time and only if spawned with START_ON These can used but not touched. */ void func_timer_think (edict_t *self) { G_UseTargets (self, self->activator); self->nextthink = level.time + self->wait + crandom() * self->random; } void func_timer_use (edict_t *self, edict_t *other, edict_t *activator) { self->activator = activator; // if on, turn it off if (self->nextthink) { self->nextthink = 0; return; } // turn it on if (self->delay) self->nextthink = level.time + self->delay; else func_timer_think (self); } void SP_func_timer (edict_t *self) { if (!self->wait) self->wait = 1.0; self->use = func_timer_use; self->think = func_timer_think; if (self->random >= self->wait) { self->random = self->wait - FRAMETIME; gi.dprintf("func_timer at %s has random >= wait\n", vtos(self->s.origin)); } if (self->spawnflags & 1) { self->nextthink = level.time + 1.0 + st.pausetime + self->delay + self->wait + crandom() * self->random; self->activator = self; } self->svflags = SVF_NOCLIENT; } /*QUAKED func_conveyor (0 .5 .8) ? START_ON TOGGLE Conveyors are stationary brushes that move what's on them. The brush should be have a surface with at least one current content enabled. speed default 100 */ void func_conveyor_use (edict_t *self, edict_t *other, edict_t *activator) { if (self->spawnflags & 1) { self->speed = 0; self->spawnflags &= ~1; } else { self->speed = self->count; self->spawnflags |= 1; } if (!(self->spawnflags & 2)) self->count = 0; } void SP_func_conveyor (edict_t *self) { if (!self->speed) self->speed = 100; if (!(self->spawnflags & 1)) { self->count = self->speed; self->speed = 0; } self->use = func_conveyor_use; gi.setmodel (self, self->model); self->solid = SOLID_BSP; gi.linkentity (self); } /*QUAKED func_door_secret (0 .5 .8) ? always_shoot 1st_left 1st_down A secret door. Slide back and then to the side. open_once doors never closes 1st_left 1st move is left of arrow 1st_down 1st move is down from arrow always_shoot door is shootebale even if targeted "angle" determines the direction "dmg" damage to inflic when blocked (default 2) "wait" how long to hold in the open position (default 5, -1 means hold) */ #define SECRET_ALWAYS_SHOOT 1 #define SECRET_1ST_LEFT 2 #define SECRET_1ST_DOWN 4 void door_secret_move1 (edict_t *self); void door_secret_move2 (edict_t *self); void door_secret_move3 (edict_t *self); void door_secret_move4 (edict_t *self); void door_secret_move5 (edict_t *self); void door_secret_move6 (edict_t *self); void door_secret_done (edict_t *self); void door_secret_use (edict_t *self, edict_t *other, edict_t *activator) { // make sure we're not already moving if (!VectorCompare(self->s.origin, vec3_origin)) return; Move_Calc (self, self->pos1, door_secret_move1); door_use_areaportals (self, true); } void door_secret_move1 (edict_t *self) { self->nextthink = level.time + 1.0; self->think = door_secret_move2; } void door_secret_move2 (edict_t *self) { Move_Calc (self, self->pos2, door_secret_move3); } void door_secret_move3 (edict_t *self) { if (self->wait == -1) return; self->nextthink = level.time + self->wait; self->think = door_secret_move4; } void door_secret_move4 (edict_t *self) { Move_Calc (self, self->pos1, door_secret_move5); } void door_secret_move5 (edict_t *self) { self->nextthink = level.time + 1.0; self->think = door_secret_move6; } void door_secret_move6 (edict_t *self) { Move_Calc (self, vec3_origin, door_secret_done); } void door_secret_done (edict_t *self) { if (!(self->targetname) || (self->spawnflags & SECRET_ALWAYS_SHOOT)) { self->health = 0; self->takedamage = DAMAGE_YES; } door_use_areaportals (self, false); } void door_secret_blocked (edict_t *self, edict_t *other) { if (!(other->svflags & SVF_MONSTER) && (!other->client) ) { // give it a chance to go away on it's own terms (like gibs) T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH); // if it's still there, nuke it if (other->inuse) BecomeExplosion1 (other); return; } if (level.time < self->touch_debounce_time) return; self->touch_debounce_time = level.time + 0.5; T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH); } void door_secret_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { self->takedamage = DAMAGE_NO; door_secret_use (self, attacker, attacker); } void SP_func_door_secret (edict_t *ent) { vec3_t forward, right, up; float side; float width; float length; ent->moveinfo.sound_start = gi.soundindex ("doors/dr1_strt.wav"); ent->moveinfo.sound_middle = gi.soundindex ("doors/dr1_mid.wav"); ent->moveinfo.sound_end = gi.soundindex ("doors/dr1_end.wav"); ent->movetype = MOVETYPE_PUSH; ent->solid = SOLID_BSP; gi.setmodel (ent, ent->model); ent->blocked = door_secret_blocked; ent->use = door_secret_use; if (!(ent->targetname) || (ent->spawnflags & SECRET_ALWAYS_SHOOT)) { ent->health = 0; ent->takedamage = DAMAGE_YES; ent->die = door_secret_die; } if (!ent->dmg) ent->dmg = 2; if (!ent->wait) ent->wait = 5; ent->moveinfo.accel = ent->moveinfo.decel = ent->moveinfo.speed = 50; // calculate positions AngleVectors (ent->s.angles, forward, right, up); VectorClear (ent->s.angles); side = 1.0 - (ent->spawnflags & SECRET_1ST_LEFT); if (ent->spawnflags & SECRET_1ST_DOWN) width = fabs(DotProduct(up, ent->size)); else width = fabs(DotProduct(right, ent->size)); length = fabs(DotProduct(forward, ent->size)); if (ent->spawnflags & SECRET_1ST_DOWN) VectorMA (ent->s.origin, -1 * width, up, ent->pos1); else VectorMA (ent->s.origin, side * width, right, ent->pos1); VectorMA (ent->pos1, length, forward, ent->pos2); if (ent->health) { ent->takedamage = DAMAGE_YES; ent->die = door_killed; ent->max_health = ent->health; } else if (ent->targetname && ent->message) { gi.soundindex ("misc/talk.wav"); ent->touch = door_touch; } ent->classname = "func_door"; gi.linkentity (ent); } /*QUAKED func_killbox (1 0 0) ? Kills everything inside when fired, irrespective of protection. */ void use_killbox (edict_t *self, edict_t *other, edict_t *activator) { KillBox (self); } void SP_func_killbox (edict_t *ent) { gi.setmodel (ent, ent->model); ent->use = use_killbox; ent->svflags = SVF_NOCLIENT; } alien-arena-7.66+dfsg/source/game/g_spawn.c0000600000175000017500000007664212161402010017634 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. Copyright (C) 20?? COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" typedef struct { char *name; void (*spawn)(edict_t *ent); } spawn_t; spawn_t spawns[] = { {"item_health", SP_item_health}, {"item_health_small", SP_item_health_small}, {"item_health_large", SP_item_health_large}, {"item_health_mega", SP_item_health_mega}, {"info_player_start", SP_info_player_start}, {"info_player_deathmatch", SP_info_player_deathmatch}, {"info_player_intermission", SP_info_player_intermission}, {"info_player_red", SP_info_player_red}, {"info_player_blue", SP_info_player_blue}, {"func_plat", SP_func_plat}, {"func_button", SP_func_button}, {"func_door", SP_func_door}, {"func_door_secret", SP_func_door_secret}, {"func_door_rotating", SP_func_door_rotating}, {"func_rotating", SP_func_rotating}, {"func_train", SP_func_train}, {"func_water", SP_func_water}, {"func_conveyor", SP_func_conveyor}, {"func_areaportal", SP_func_areaportal}, {"func_wall", SP_func_wall}, {"func_object", SP_func_object}, {"func_timer", SP_func_timer}, {"func_explosive", SP_func_explosive}, {"func_killbox", SP_func_killbox}, {"trigger_always", SP_trigger_always}, {"trigger_once", SP_trigger_once}, {"trigger_multiple", SP_trigger_multiple}, {"trigger_relay", SP_trigger_relay}, {"trigger_push", SP_trigger_push}, {"trigger_hurt", SP_trigger_hurt}, {"trigger_key", SP_trigger_key}, {"trigger_counter", SP_trigger_counter}, {"trigger_elevator", SP_trigger_elevator}, {"trigger_gravity", SP_trigger_gravity}, {"trigger_monsterjump", SP_trigger_monsterjump}, {"trigger_deathballtarget", SP_trigger_deathballtarget}, {"trigger_reddeathballtarget", SP_trigger_reddeathballtarget}, {"trigger_bluedeathballtarget", SP_trigger_bluedeathballtarget}, {"trigger_bluecowtarget", SP_trigger_bluecowtarget}, {"trigger_redcowtarget", SP_trigger_redcowtarget}, {"target_temp_entity", SP_target_temp_entity}, {"target_speaker", SP_target_speaker}, {"target_explosion", SP_target_explosion}, {"target_secret", SP_target_secret}, {"target_splash", SP_target_splash}, {"target_steam", SP_target_steam}, {"target_spawner", SP_target_spawner}, #ifndef ALTERIA {"target_blaster", SP_target_blaster}, {"target_laser", SP_target_laser}, #endif {"target_lightramp", SP_target_lightramp}, {"target_earthquake", SP_target_earthquake}, {"target_fire", SP_target_fire}, {"target_changelevel", SP_target_changelevel}, {"worldspawn", SP_worldspawn}, {"light", SP_light}, {"info_null", SP_info_null}, {"func_group", SP_info_null}, {"info_notnull", SP_info_notnull}, {"path_corner", SP_path_corner}, {"point_combat", SP_point_combat}, {"misc_teleporter", SP_misc_teleporter}, {"misc_teleporter_dest", SP_misc_teleporter_dest}, {"npc_cow", SP_npc_cow}, {"npc_deathray", SP_npc_deathray}, //TCA {"misc_spiderpod", SP_misc_spiderpod}, {"misc_rednode", SP_misc_rednode}, {"misc_bluenode", SP_misc_bluenode}, {"misc_redspidernode", SP_misc_redspidernode}, {"misc_bluespidernode", SP_misc_bluespidernode}, //Tactical {"misc_aliencomputer", SP_misc_aliencomputer}, {"misc_humancomputer", SP_misc_humancomputer}, {"misc_alienpowersrc", SP_misc_alienpowersrc}, {"misc_humanpowersrc", SP_misc_humanpowersrc}, {"misc_alienammodepot", SP_misc_alienammodepot}, {"misc_humanammodepot", SP_misc_humanammodepot}, {"misc_alienbackupgen", SP_misc_alienbackupgen}, {"misc_humanbackupgen", SP_misc_humanbackupgen}, {"misc_deathray", SP_misc_deathray}, //note - spawnflags determine team for this item(1 for human) {"misc_laser", SP_misc_laser}, //spawnflag 1 for human {"misc_mapmodel", SP_misc_mapmodel}, {"misc_watersplash", SP_misc_watersplash}, {"misc_electroflash", SP_misc_electroflash}, {NULL, NULL} }; /* =============== ED_CallSpawn Finds the spawn function for the entity and calls it =============== */ void ED_CallSpawn (edict_t *ent) { spawn_t *s; gitem_t *item; int i; if (!ent->classname) { gi.dprintf ("ED_CallSpawn: NULL classname\n"); return; } // check item spawn functions for (i=0,item=itemlist ; iclassname) continue; //-JD - removing old weapons, and in the case of the vaporizer, duplicates. if(!Q_strcasecmp(ent->classname, "weapon_grenadelauncher")) ent->classname = "weapon_rocketlauncher"; //hack to remove old weapons if(!Q_strcasecmp(ent->classname, "weapon_machinegun")) ent->classname = "weapon_bfg"; //hack to remove old weapons if(!Q_strcasecmp(ent->classname, "weapon_minderaser")) continue; //never place one of these traditionally if (!strcmp(item->classname, ent->classname)) { // found it SpawnItem (ent, item); return; } } gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_TELEPORT_EFFECT); gi.WritePosition (ent->s.origin); gi.multicast (ent->s.origin, MULTICAST_PVS); // check normal spawn functions for (s=spawns ; s->name ; s++) { if (!strcmp(s->name, ent->classname)) { // found it s->spawn (ent); return; } } gi.dprintf ("%s doesn't have a spawn function\n", ent->classname); } /* ============= ED_NewString ============= */ char *ED_NewString (char *string) { char *newb, *new_p; int i,l; l = strlen(string) + 1; newb = gi.TagMalloc (l, TAG_LEVEL); new_p = newb; for (i=0 ; i< l ; i++) { if (string[i] == '\\' && i < l-1) { i++; if (string[i] == 'n') *new_p++ = '\n'; else *new_p++ = '\\'; } else *new_p++ = string[i]; } return newb; } /* =============== ED_ParseField Takes a key/value pair and sets the binary values in an edict =============== */ void ED_ParseField (char *key, char *value, edict_t *ent) { field_t *f; byte *b; float v; vec3_t vec; for (f=fields ; f->name ; f++) { if (!Q_strcasecmp(f->name, key)) { // found it if (f->flags & FFL_SPAWNTEMP) b = (byte *)&st; else b = (byte *)ent; switch (f->type) { case F_LSTRING: *(char **)(b+f->ofs) = ED_NewString (value); break; case F_VECTOR: sscanf (value, "%f %f %f", &vec[0], &vec[1], &vec[2]); ((float *)(b+f->ofs))[0] = vec[0]; ((float *)(b+f->ofs))[1] = vec[1]; ((float *)(b+f->ofs))[2] = vec[2]; break; case F_INT: *(int *)(b+f->ofs) = atoi(value); break; case F_FLOAT: *(float *)(b+f->ofs) = atof(value); break; case F_ANGLEHACK: v = atof(value); ((float *)(b+f->ofs))[0] = 0; ((float *)(b+f->ofs))[1] = v; ((float *)(b+f->ofs))[2] = 0; break; case F_IGNORE: default: break; } return; } } gi.dprintf ("%s is not a field\n", key); } /* ==================== ED_ParseEdict Parses an edict out of the given string, returning the new position ed should be a properly initialized empty edict. ==================== */ char *ED_ParseEdict (char *data, edict_t *ent) { qboolean init; char keyname[256]; char *com_token; init = false; memset (&st, 0, sizeof(st)); // go through all the dictionary pairs while (1) { // parse key com_token = COM_Parse (&data); if (com_token[0] == '}') break; if (!data) gi.error ("ED_ParseEntity: EOF without closing brace"); strncpy (keyname, com_token, sizeof(keyname)-1); // parse value com_token = COM_Parse (&data); if (!data) gi.error ("ED_ParseEntity: EOF without closing brace"); if (com_token[0] == '}') gi.error ("ED_ParseEntity: closing brace without data"); init = true; // keynames with a leading underscore are used for utility comments, // and are immediately discarded by quake if (keyname[0] == '_') continue; ED_ParseField (keyname, com_token, ent); } if (!init) memset (ent, 0, sizeof(*ent)); return data; } /* ================ G_FindTeams Chain together all entities with a matching team field. All but the first will have the FL_TEAMSLAVE flag set. All but the last will have the teamchain field set to the next one ================ */ void G_FindTeams (void) { edict_t *e, *e2, *chain; int i, j; int c, c2; c = 0; c2 = 0; for (i=1, e=g_edicts+i ; i < globals.num_edicts ; i++,e++) { if (!e->inuse) continue; if (!e->team) continue; if (e->flags & FL_TEAMSLAVE) continue; chain = e; e->teammaster = e; c++; c2++; for (j=i+1, e2=e+1 ; j < globals.num_edicts ; j++,e2++) { if (!e2->inuse) continue; if (!e2->team) continue; if (e2->flags & FL_TEAMSLAVE) continue; if (!strcmp(e->team, e2->team)) { c2++; chain->teamchain = e2; e2->teammaster = e; chain = e2; e2->flags |= FL_TEAMSLAVE; } } } gi.dprintf ("%i teams with %i entities\n", c, c2); } /* ============== SpawnEntities Creates a server's entity / program execution context by parsing textual entity definitions out of an ent file. ============== */ int levelnum; void SpawnEntities (char *mapname, char *entities, char *spawnpoint) { edict_t *ent; int inhibit; char *com_token; int i; float skill_level; skill_level = floor (skill->value); if (skill_level < 0) skill_level = 0; if (skill_level > 3) skill_level = 3; if (skill->value != skill_level) gi.cvar_forceset("skill", va("%f", skill_level)); SaveClientData (); gi.FreeTags (TAG_LEVEL); memset (&level, 0, sizeof(level)); memset (g_edicts, 0, game.maxentities * sizeof (g_edicts[0])); strncpy (level.mapname, mapname, sizeof(level.mapname)-1); // set client fields on player ents for (i=0 ; iclassname, "trigger_once") && !Q_strcasecmp(ent->model, "*27")) ent->spawnflags &= ~SPAWNFLAG_NOT_HARD; // remove things (except the world) from different skill levels or deathmatch if (ent != g_edicts) { if (deathmatch->value) { if ( ent->spawnflags & SPAWNFLAG_NOT_DEATHMATCH ) { G_FreeEdict (ent); inhibit++; continue; } } else { if ( ((skill->value == 0) && (ent->spawnflags & SPAWNFLAG_NOT_EASY)) || ((skill->value == 1) && (ent->spawnflags & SPAWNFLAG_NOT_MEDIUM)) || (((skill->value == 2) || (skill->value == 3)) && (ent->spawnflags & SPAWNFLAG_NOT_HARD)) ) { G_FreeEdict (ent); inhibit++; continue; } } ent->spawnflags &= ~(SPAWNFLAG_NOT_EASY|SPAWNFLAG_NOT_MEDIUM|SPAWNFLAG_NOT_HARD|SPAWNFLAG_NOT_DEATHMATCH); } ED_CallSpawn (ent); } gi.dprintf ("%i entities inhibited\n", inhibit); //reset minderaser mindEraserTime = level.time; ACEND_InitNodes(); ACEND_LoadNodes(); G_FindTeams (); PlayerTrail_Init (); } //=================================================================== #if 0 // cursor positioning xl xr yb yt xv yv // drawing statpic pic num string // control if ifeq ifbit endif #endif char *dm_statusbar = //background "yb -256 " "xl 0 " "pic 0 " "xr -130 " "yt 2 " "pic 18 " // health "yb -29 " "xl 11 " "hnum " // ammo "if 2 " " xl 76 " " anum " "endif " // armor " xl 142 " " rnum " // timer "if 9 " " xv 262 " " yb -24 " " num 2 10 " " xv 296 " " yb -32 " " pic 9 " "endif " // weapon icon "if 11 " " xr -72 " " yt 196 " " pic 11 " "endif " // frags "xr -67 " "yt 16 " "num 3 14" // deaths "xr -67 " "yt 48 " "num 3 19 " // high scorer "yt 80 " "num 3 20 " // weapon stats "if 25 " "xr -72 " "yt 227 " "pic 25 " "endif" "if 26 " "yt 258 " "pic 26 " "endif " "if 27 " "yt 289 " "pic 27 " "endif " "if 28 " "yt 320 " "pic 28 " "endif " "if 29 " "yt 351 " "pic 29 " "endif " "if 30 " "yt 382 " "pic 30 " "endif " "if 31 " "yt 413 " "pic 31 " "endif " ; char *team_statusbar = // background "yb -256 " "xl 0 " "pic 0 " "xr -130 " "yt 2 " "pic 18 " // health "yb -29 " "xl 11 " "hnum " // ammo "if 2 " " xl 76 " " anum " "endif " // armor " xl 142 " " rnum " // timer "if 9 " " xv 324 " " yb -24 " " num 2 10 " " xv 358 " " yb -32 " " pic 9 " "endif " // weapon icon "if 11 " " xr -72 " " yt 196 " " pic 11 " "endif " // frags "xr -67 " "yt 16 " "num 3 14" // deaths "xr -67 " "yt 48 " "num 3 19 " // high scorer "yt 80 " "num 3 20 " // red team "yt 132 " "num 3 21 " // blue team "yt 166 " "num 3 22 " // flag " xv 128 " " yb -64 " " pic 23 " // weapon stats "if 25 " "xr -72 " "yt 227 " "pic 25 " "endif" "if 26 " "yt 258 " "pic 26 " "endif " "if 27 " "yt 289 " "pic 27 " "endif " "if 28 " "yt 320 " "pic 28 " "endif " "if 29 " "yt 351 " "pic 29 " "endif " "if 30 " "yt 382 " "pic 30 " "endif " "if 31 " "yt 413 " "pic 31 " "endif " ; char *tca_statusbar = // background "yb -256 " "xl 0 " "pic 0 " "xr -130 " "yt 2 " "pic 18 " // health "yb -29 " "xl 11 " "hnum " // ammo "if 2 " " xl 76 " " anum " "endif " // armor " xl 142 " " rnum " // timer "if 9 " " xv 324 " " yb -24 " " num 2 10 " " xv 358 " " yb -32 " " pic 9 " "endif " // weapon icon "if 11 " " xr -72 " " yt 196 " " pic 11 " "endif " // frags "xr -67 " "yt 16 " "num 3 14" // deaths "xr -67 " "yt 48 " "num 3 19 " // high scorer "yt 80 " "num 3 20 " // red team "yt 132 " "num 1 6 " "xr -27 " "num 1 21 " // blue team "yt 166 " "num 1 22 " "xr -67 " "num 1 7 " // red label "yt 124 " "xr -30 " "string nodes " "xr -70 " "string matches " // blue label "yt 158 " "xr -30 " "string nodes " "xr -70 " "string matches " // flag " xv 128 " " yb -64 " " pic 23 " // weapon stats "if 25 " "xr -72 " "yt 227 " "pic 25 " "endif" "if 26 " "yt 258 " "pic 26 " "endif " "if 27 " "yt 289 " "pic 27 " "endif " "if 28 " "yt 320 " "pic 28 " "endif " "if 29 " "yt 351 " "pic 29 " "endif " "if 30 " "yt 382 " "pic 30 " "endif " "if 31 " "yt 413 " "pic 31 " "endif " ; char *tactical_statusbar = // background "yb -256 " "xl 0 " "pic 0 " "xr -130 " "yt 2 " "pic 8 " // health "yb -29 " "xl 11 " "hnum " // ammo "if 2 " " xl 76 " " anum " "endif " // armor " xl 142 " " rnum " // Human Computer "xr -67 " "yt 16 " "num 3 25 " // Human Power "yt 48 " "num 3 26 " // Human Ammo Depot "yt 80 " "num 3 27 " // Alien Computer "yt 122 " "num 3 28 " // Alien Power "yt 154 " "num 3 29 " // Alien Ammo Depot "yt 186 " "num 3 30 " // timer "if 9 " " xv 324 " " yb -24 " " num 2 10 " " xv 358 " " yb -32 " " pic 9 " "endif " // weapon icon "if 11 " " xr -72 " " yt 196 " " pic 11 " "endif " ; /*QUAKED worldspawn (0 0 0) ? Only used for the world. "sky" environment map name "skyaxis" vector axis for rotating sky "skyrotate" speed of rotation in degrees/second "sounds" music cd track number "gravity" 800 is default gravity "message" text to print at user logon */ void SP_worldspawn (edict_t *ent) { ent->movetype = MOVETYPE_PUSH; ent->solid = SOLID_BSP; ent->inuse = true; // since the world doesn't use G_Spawn() ent->s.modelindex = 1; // world model is always index 1 //--------------- // reserve some spots for dead player bodies for coop / deathmatch InitBodyQue (); // set configstrings for items SetItemNames (); if (st.nextmap) strcpy (level.nextmap, st.nextmap); // make some data visible to the server if (ent->message && ent->message[0]) { gi.configstring (CS_NAME, ent->message); strncpy (level.level_name, ent->message, sizeof(level.level_name)); } else strncpy (level.level_name, level.mapname, sizeof(level.level_name)); if (st.sky && st.sky[0]) gi.configstring (CS_SKY, st.sky); else gi.configstring (CS_SKY, "space1"); gi.configstring (CS_SKYROTATE, va("%f", st.skyrotate) ); gi.configstring (CS_SKYAXIS, va("%f %f %f", st.skyaxis[0], st.skyaxis[1], st.skyaxis[2]) ); gi.configstring (CS_MAXCLIENTS, va("%i", g_maxclients->integer ) ); // status bar program if ((dmflags->integer & DF_SKINTEAMS) || ctf->integer || cp->integer) { gi.configstring (CS_STATUSBAR, team_statusbar); if(ctf->value) CTFPrecache(); } else if (tca->integer) gi.configstring (CS_STATUSBAR, tca_statusbar); else if (g_tactical->integer) gi.configstring (CS_STATUSBAR, tactical_statusbar); else gi.configstring (CS_STATUSBAR, dm_statusbar); //--------------- // help icon for statusbar level.pic_health = gi.imageindex ("i_health"); gi.imageindex ("help"); if (!st.gravity) { if(low_grav->value) gi.cvar_set("sv_gravity", "300"); else gi.cvar_set("sv_gravity", "800"); } else gi.cvar_set("sv_gravity", st.gravity); //prechaches PrecacheItem (FindItem ("Blaster")); PrecacheItem (FindItem ("Violator")); gi.soundindex ("player/lava1.wav"); gi.soundindex ("player/lava2.wav"); gi.soundindex ("misc/pc_up.wav"); gi.soundindex ("misc/talk1.wav"); gi.soundindex ("items/respawn1.wav"); // sexed sounds gi.soundindex ("*death1.wav"); gi.soundindex ("*death2.wav"); gi.soundindex ("*death3.wav"); gi.soundindex ("*death4.wav"); gi.soundindex ("*fall1.wav"); gi.soundindex ("*fall2.wav"); gi.soundindex ("*gurp1.wav"); // drowning damage gi.soundindex ("*gurp2.wav"); gi.soundindex ("*jump1.wav"); // player jump gi.soundindex ("*pain25_1.wav"); gi.soundindex ("*pain25_2.wav"); gi.soundindex ("*pain50_1.wav"); gi.soundindex ("*pain50_2.wav"); gi.soundindex ("*pain75_1.wav"); gi.soundindex ("*pain75_2.wav"); gi.soundindex ("*pain100_1.wav"); gi.soundindex ("*pain100_2.wav"); //------------------- gi.soundindex ("player/gasp1.wav"); // gasping for air gi.soundindex ("player/gasp2.wav"); // head breaking surface, not gasping gi.soundindex ("player/watr_in.wav"); // feet hitting water gi.soundindex ("player/watr_out.wav"); // feet leaving water gi.soundindex ("player/watr_un.wav"); // head going underwater gi.soundindex ("items/damage.wav"); gi.soundindex ("items/protect.wav"); gi.soundindex ("items/protect4.wav"); gi.soundindex ("weapons/noammo.wav"); gi.soundindex ("weapons/whoosh.wav"); gi.soundindex ("misc/1frags.wav"); gi.soundindex ("misc/2frags.wav"); gi.soundindex ("misc/3frags.wav"); gi.soundindex ("misc/one.wav"); gi.soundindex ("misc/two.wav"); gi.soundindex ("misc/three.wav"); gi.soundindex ("misc/godlike.wav"); gi.soundindex ("misc/rampage.wav"); gi.soundindex ("misc/fight.wav"); gi.soundindex ("misc/minderaser.wav"); //if maxclients is 0 or 1, it means someone is probably just testing a map //or testing some code, so we really don't need to precache all this crap if (game.maxclients > 1) { //precache all base player taunts gi.soundindex ("taunts/martianenforcer/taunt1.wav"); gi.soundindex ("taunts/martianenforcer/taunt2.wav"); gi.soundindex ("taunts/martianenforcer/taunt3.wav"); gi.soundindex ("taunts/martianenforcer/taunt4.wav"); gi.soundindex ("taunts/martianenforcer/taunt5.wav"); gi.soundindex ("taunts/martiancyborg/taunt1.wav"); gi.soundindex ("taunts/martiancyborg/taunt2.wav"); gi.soundindex ("taunts/martiancyborg/taunt3.wav"); gi.soundindex ("taunts/martiancyborg/taunt4.wav"); gi.soundindex ("taunts/martiancyborg/taunt5.wav"); gi.soundindex ("taunts/commander/taunt1.wav"); gi.soundindex ("taunts/commander/taunt2.wav"); gi.soundindex ("taunts/commander/taunt3.wav"); gi.soundindex ("taunts/commander/taunt4.wav"); gi.soundindex ("taunts/commander/taunt5.wav"); gi.soundindex ("taunts/enforcer/taunt1.wav"); gi.soundindex ("taunts/enforcer/taunt2.wav"); gi.soundindex ("taunts/enforcer/taunt3.wav"); gi.soundindex ("taunts/enforcer/taunt4.wav"); gi.soundindex ("taunts/enforcer/taunt5.wav"); gi.soundindex ("taunts/slashbot/taunt1.wav"); gi.soundindex ("taunts/slashbot/taunt2.wav"); gi.soundindex ("taunts/slashbot/taunt3.wav"); gi.soundindex ("taunts/slashbot/taunt4.wav"); gi.soundindex ("taunts/slashbot/taunt5.wav"); gi.soundindex ("taunts/lauren/taunt1.wav"); gi.soundindex ("taunts/lauren/taunt2.wav"); gi.soundindex ("taunts/lauren/taunt3.wav"); gi.soundindex ("taunts/lauren/taunt4.wav"); gi.soundindex ("taunts/lauren/taunt5.wav"); gi.soundindex ("taunts/martiancyborg/taunt1.wav"); gi.soundindex ("taunts/martiancyborg/taunt2.wav"); gi.soundindex ("taunts/martiancyborg/taunt3.wav"); gi.soundindex ("taunts/martiancyborg/taunt4.wav"); gi.soundindex ("taunts/martiancyborg/taunt5.wav"); gi.soundindex ("taunts/martianoverlord/taunt1.wav"); gi.soundindex ("taunts/martianoverlord/taunt2.wav"); gi.soundindex ("taunts/martianoverlord/taunt3.wav"); gi.soundindex ("taunts/martianoverlord/taunt4.wav"); gi.soundindex ("taunts/martianoverlord/taunt5.wav"); gi.soundindex ("taunts/martianwarrior/taunt1.wav"); gi.soundindex ("taunts/martianwarrior/taunt2.wav"); gi.soundindex ("taunts/martianwarrior/taunt3.wav"); gi.soundindex ("taunts/martianwarrior/taunt4.wav"); gi.soundindex ("taunts/martianwarrior/taunt5.wav"); //precache any gibs sm_meat_index = gi.modelindex ("models/objects/gibs/sm_meat/tris.md2"); gi.modelindex ("models/objects/gibs/mart_gut/tris.md2"); gi.modelindex ("models/objects/debris1/tris.md2"); gi.modelindex ("models/objects/debris3/tris.md2"); //precache all base player models. this eliminates "stutter" when a player joins the game //this should be here for the cases of 7.45 clients and older gi.modelindex ("players/martianenforcer/tris.md2"); gi.modelindex ("players/martiancyborg/tris.md2"); gi.modelindex ("players/martianoverlord/tris.md2"); gi.modelindex ("players/martianwarrior/tris.md2"); gi.modelindex ("players/enforcer/tris.md2"); gi.modelindex ("players/lauren/tris.md2"); gi.modelindex ("players/slashbot/tris.md2"); gi.modelindex ("players/commander/tris.md2"); //do the w_weps gi.modelindex ("players/martianenforcer/weapon.md2"); gi.modelindex ("players/martianenforcer/w_blaster.md2"); gi.modelindex ("players/martianenforcer/w_shotgun.md2"); gi.modelindex ("players/martianenforcer/w_sshotgun.md2"); gi.modelindex ("players/martianenforcer/w_machinegun.md2"); gi.modelindex ("players/martianenforcer/w_chaingun.md2"); gi.modelindex ("players/martianenforcer/w_rlauncher.md2"); gi.modelindex ("players/martianenforcer/w_hyperblaster.md2"); gi.modelindex ("players/martianenforcer/w_railgun.md2"); gi.modelindex ("players/martianenforcer/w_bfg.md2"); gi.modelindex ("players/martianenforcer/w_violator.md2"); gi.modelindex ("players/martianenforcer/w_minderaser.md2"); gi.modelindex ("players/martiancyborg/weapon.md2"); gi.modelindex ("players/martiancyborg/w_blaster.md2"); gi.modelindex ("players/martiancyborg/w_shotgun.md2"); gi.modelindex ("players/martiancyborg/w_sshotgun.md2"); gi.modelindex ("players/martiancyborg/w_machinegun.md2"); gi.modelindex ("players/martiancyborg/w_chaingun.md2"); gi.modelindex ("players/martiancyborg/w_rlauncher.md2"); gi.modelindex ("players/martiancyborg/w_hyperblaster.md2"); gi.modelindex ("players/martiancyborg/w_railgun.md2"); gi.modelindex ("players/martiancyborg/w_bfg.md2"); gi.modelindex ("players/martiancyborg/w_violator.md2"); gi.modelindex ("players/martiancyborg/w_minderaser.md2"); gi.modelindex ("players/enforcer/weapon.md2"); gi.modelindex ("players/enforcer/w_blaster.md2"); gi.modelindex ("players/enforcer/w_shotgun.md2"); gi.modelindex ("players/enforcer/w_sshotgun.md2"); gi.modelindex ("players/enforcer/w_machinegun.md2"); gi.modelindex ("players/enforcer/w_chaingun.md2"); gi.modelindex ("players/enforcer/w_rlauncher.md2"); gi.modelindex ("players/enforcer/w_hyperblaster.md2"); gi.modelindex ("players/enforcer/w_railgun.md2"); gi.modelindex ("players/enforcer/w_bfg.md2"); gi.modelindex ("players/enforcer/w_violator.md2"); gi.modelindex ("players/enforcer/w_minderaser.md2"); gi.modelindex ("players/lauren/weapon.md2"); gi.modelindex ("players/lauren/w_blaster.md2"); gi.modelindex ("players/lauren/w_shotgun.md2"); gi.modelindex ("players/lauren/w_sshotgun.md2"); gi.modelindex ("players/lauren/w_machinegun.md2"); gi.modelindex ("players/lauren/w_chaingun.md2"); gi.modelindex ("players/lauren/w_rlauncher.md2"); gi.modelindex ("players/lauren/w_hyperblaster.md2"); gi.modelindex ("players/lauren/w_railgun.md2"); gi.modelindex ("players/lauren/w_bfg.md2"); gi.modelindex ("players/lauren/w_violator.md2"); gi.modelindex ("players/lauren/w_minderaser.md2"); gi.modelindex ("players/slashbot/weapon.md2"); gi.modelindex ("players/slashbot/w_blaster.md2"); gi.modelindex ("players/slashbot/w_shotgun.md2"); gi.modelindex ("players/slashbot/w_sshotgun.md2"); gi.modelindex ("players/slashbot/w_machinegun.md2"); gi.modelindex ("players/slashbot/w_chaingun.md2"); gi.modelindex ("players/slashbot/w_rlauncher.md2"); gi.modelindex ("players/slashbot/w_hyperblaster.md2"); gi.modelindex ("players/slashbot/w_railgun.md2"); gi.modelindex ("players/slashbot/w_bfg.md2"); gi.modelindex ("players/slashbot/w_violator.md2"); gi.modelindex ("players/slashbot/w_minderaser.md2"); gi.modelindex ("players/commander/weapon.md2"); gi.modelindex ("players/commander/w_blaster.md2"); gi.modelindex ("players/commander/w_shotgun.md2"); gi.modelindex ("players/commander/w_sshotgun.md2"); gi.modelindex ("players/commander/w_machinegun.md2"); gi.modelindex ("players/commander/w_chaingun.md2"); gi.modelindex ("players/commander/w_rlauncher.md2"); gi.modelindex ("players/commander/w_hyperblaster.md2"); gi.modelindex ("players/commander/w_railgun.md2"); gi.modelindex ("players/commander/w_bfg.md2"); gi.modelindex ("players/commander/w_violator.md2"); gi.modelindex ("players/commander/w_minderaser.md2"); gi.modelindex ("players/martianoverlord/weapon.md2"); gi.modelindex ("players/martianoverlord/w_blaster.md2"); gi.modelindex ("players/martianoverlord/w_shotgun.md2"); gi.modelindex ("players/martianoverlord/w_sshotgun.md2"); gi.modelindex ("players/martianoverlord/w_machinegun.md2"); gi.modelindex ("players/martianoverlord/w_chaingun.md2"); gi.modelindex ("players/martianoverlord/w_rlauncher.md2"); gi.modelindex ("players/martianoverlord/w_hyperblaster.md2"); gi.modelindex ("players/martianoverlord/w_railgun.md2"); gi.modelindex ("players/martianoverlord/w_bfg.md2"); gi.modelindex ("players/martianoverlord/w_violator.md2"); gi.modelindex ("players/martianoverlord/w_minderaser.md2"); gi.modelindex ("players/martianwarrior/weapon.md2"); gi.modelindex ("players/martianwarrior/w_blaster.md2"); gi.modelindex ("players/martianwarrior/w_shotgun.md2"); gi.modelindex ("players/martianwarrior/w_sshotgun.md2"); gi.modelindex ("players/martianwarrior/w_machinegun.md2"); gi.modelindex ("players/martianwarrior/w_chaingun.md2"); gi.modelindex ("players/martianwarrior/w_rlauncher.md2"); gi.modelindex ("players/martianwarrior/w_hyperblaster.md2"); gi.modelindex ("players/martianwarrior/w_railgun.md2"); gi.modelindex ("players/martianwarrior/w_bfg.md2"); gi.modelindex ("players/martianwarrior/w_violator.md2"); gi.modelindex ("players/martianwarrior/w_minderaser.md2"); //weapon models that aren't placed in levels gi.modelindex ("models/weapons/v_minderaser/tris.md2"); gi.modelindex ("models/weapons/g_minderaser/tris.md2"); gi.modelindex ("models/objects/spud/tris.md2"); gi.modelindex ("models/weapons/v_blast/tris.md2"); gi.modelindex ("models/weapons/v_violator/tris.md2"); } //these are needed for custom player models for when they enter a game gi.modelindex ("#w_blaster.md2"); gi.modelindex ("#w_shotgun.md2"); gi.modelindex ("#w_sshotgun.md2"); gi.modelindex ("#w_machinegun.md2"); gi.modelindex ("#w_chaingun.md2"); gi.modelindex ("#a_grenades.md2"); gi.modelindex ("#w_glauncher.md2"); gi.modelindex ("#w_rlauncher.md2"); gi.modelindex ("#w_hyperblaster.md2"); gi.modelindex ("#w_railgun.md2"); gi.modelindex ("#w_bfg.md2"); gi.modelindex ("#w_violator.md2"); gi.modelindex ("#w_minderaser.md2"); // // Setup light animation tables. 'a' is total darkness, 'z' is doublebright. // // 0 normal gi.configstring(CS_LIGHTS+0, "m"); // 1 FLICKER (first variety) gi.configstring(CS_LIGHTS+1, "mmnmmommommnonmmonqnmmo"); // 2 SLOW STRONG PULSE gi.configstring(CS_LIGHTS+2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba"); // 3 CANDLE (first variety) gi.configstring(CS_LIGHTS+3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg"); // 4 FAST STROBE gi.configstring(CS_LIGHTS+4, "mamamamamama"); // 5 GENTLE PULSE 1 gi.configstring(CS_LIGHTS+5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj"); // 6 FLICKER (second variety) gi.configstring(CS_LIGHTS+6, "nmonqnmomnmomomno"); // 7 CANDLE (second variety) gi.configstring(CS_LIGHTS+7, "mmmaaaabcdefgmmmmaaaammmaamm"); // 8 CANDLE (third variety) gi.configstring(CS_LIGHTS+8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa"); // 9 SLOW STROBE (fourth variety) gi.configstring(CS_LIGHTS+9, "aaaaaaaazzzzzzzz"); // 10 FLUORESCENT FLICKER gi.configstring(CS_LIGHTS+10, "mmamammmmammamamaaamammma"); // 11 SLOW PULSE NOT FADE TO BLACK gi.configstring(CS_LIGHTS+11, "abcdefghijklmnopqrrqponmlkjihgfedcba"); // styles 32-62 are assigned by the light program for switchable lights // 63 testing gi.configstring(CS_LIGHTS+63, "a"); //call voting(we've started a new level, clear it) if(g_callvote->value) { playervote.called = false; playervote.yay = 0; playervote.nay = 0; playervote.command[0] = 0; } } alien-arena-7.66+dfsg/source/game/g_spider.h0000600000175000017500000000164712161402010017770 0ustar zero79zero79 #define FRAME_stand01 0 #define FRAME_stand02 1 #define FRAME_stand03 2 #define FRAME_stand04 3 #define FRAME_stand05 4 #define FRAME_stand06 5 #define FRAME_stand07 6 #define FRAME_stand08 7 #define FRAME_stand09 8 #define FRAME_stand10 9 #define FRAME_stand11 10 #define FRAME_stand12 11 #define FRAME_stand13 12 #define FRAME_stand14 13 #define FRAME_walk01 14 #define FRAME_walk02 15 #define FRAME_walk03 16 #define FRAME_walk04 17 #define FRAME_walk05 18 #define FRAME_walk06 19 #define FRAME_shoot01 20 #define FRAME_shoot02 21 #define FRAME_shoot03 22 #define FRAME_shoot04 23 #define FRAME_shoot05 24 #define FRAME_shoot06 25 #define FRAME_pain01 26 #define FRAME_pain02 27 #define FRAME_pain03 28 #define FRAME_pain04 29 #define FRAME_pain05 30 #define MODEL_SCALE 1.000000 alien-arena-7.66+dfsg/source/game/g_target.c0000600000175000017500000005051112161402010017755 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" /*QUAKED target_temp_entity (1 0 0) (-8 -8 -8) (8 8 8) Fire an origin based temp entity event to the clients. "style" type byte */ void Use_Target_Tent (edict_t *ent, edict_t *other, edict_t *activator) { gi.WriteByte (svc_temp_entity); gi.WriteByte (ent->style); gi.WritePosition (ent->s.origin); gi.multicast (ent->s.origin, MULTICAST_PVS); } void SP_target_temp_entity (edict_t *ent) { ent->use = Use_Target_Tent; } //========================================================== //========================================================== /*QUAKED target_speaker (1 0 0) (-8 -8 -8) (8 8 8) looped-on looped-off reliable "noise" wav file to play "attenuation" -1 = none, send to whole level 1 = normal fighting sounds 2 = idle sound level 3 = ambient sound level "volume" 0.0 to 1.0 Normal sounds play each time the target is used. The reliable flag can be set for crucial voiceovers. Looped sounds are always atten 3 / vol 1, and the use function toggles it on/off. Multiple identical looping sounds will just increase volume without any speed cost. */ void Use_Target_Speaker (edict_t *ent, edict_t *other, edict_t *activator) { int chan; if (ent->spawnflags & 3) { // looping sound toggles if (ent->s.sound) ent->s.sound = 0; // turn it off else ent->s.sound = ent->noise_index; // start it } else { // normal sound if (ent->spawnflags & 4) chan = CHAN_VOICE|CHAN_RELIABLE; else chan = CHAN_VOICE; // use a positioned_sound, because this entity won't normally be // sent to any clients because it is invisible gi.positioned_sound (ent->s.origin, ent, chan, ent->noise_index, ent->volume, ent->attenuation, 0); } } void Target_Speaker_Think (edict_t *ent) { ent->s.sound = ent->noise_index; ent->nextthink = level.time + 1; } extern int levelnum; void SP_target_speaker (edict_t *ent) { char buffer[MAX_QPATH]; static int prev_levelnum; if(!st.noise) { gi.dprintf("target_speaker with no noise set at %s\n", vtos(ent->s.origin)); return; } if (strstr (st.noise, "music")) { if (levelnum != prev_levelnum) //only warn once per level { prev_levelnum = levelnum; gi.dprintf("SHUT UP SHUT UP SHUT UP YOU INFERNAL BONGO DRUMS!\n"); gi.dprintf("Map contains one or more target_speakers with \"music\" in its sound file name.\n"); gi.dprintf("These have been disabled.\n"); } return; } if (!strstr (st.noise, ".wav")) Com_sprintf (buffer, sizeof(buffer), "%s.wav", st.noise); else strncpy (buffer, st.noise, sizeof(buffer)); ent->noise_index = gi.soundindex (buffer); if (!ent->volume) ent->volume = 1.0; if (!ent->attenuation) ent->attenuation = 1.0; else if (ent->attenuation == -1) // use -1 so 0 defaults to 1 ent->attenuation = 0; // check for prestarted looping sound if (ent->spawnflags & 1) ent->s.sound = ent->noise_index; ent->use = Use_Target_Speaker; if(ent->spawnflags & 3) { //only looped sounds ent->think = Target_Speaker_Think; //added for turning sound off in menu ent->nextthink = level.time + 1; } // must link the entity so we get areas and clusters so // the server can determine who to send updates to gi.linkentity (ent); } //========================================================== /*QUAKED target_secret (1 0 1) (-8 -8 -8) (8 8 8) Counts a secret found. These are single use targets. */ void use_target_secret (edict_t *ent, edict_t *other, edict_t *activator) { gi.sound (ent, CHAN_VOICE, ent->noise_index, 1, ATTN_NORM, 0); level.found_secrets++; G_UseTargets (ent, activator); G_FreeEdict (ent); } void SP_target_secret (edict_t *ent) { if (deathmatch->value) { // auto-remove for deathmatch G_FreeEdict (ent); return; } ent->use = use_target_secret; if (!st.noise) st.noise = "misc/secret.wav"; ent->noise_index = gi.soundindex (st.noise); ent->svflags = SVF_NOCLIENT; level.total_secrets++; // map bug hack if (!Q_strcasecmp(level.mapname, "mine3") && ent->s.origin[0] == 280 && ent->s.origin[1] == -2048 && ent->s.origin[2] == -624) ent->message = "You have found a secret area."; } //========================================================== /*QUAKED target_explosion (1 0 0) (-8 -8 -8) (8 8 8) Spawns an explosion temporary entity when used. "delay" wait this long before going off "dmg" how much radius damage should be done, defaults to 0 */ void target_explosion_explode (edict_t *self) { float save; gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_EXPLOSION1); gi.WritePosition (self->s.origin); gi.multicast (self->s.origin, MULTICAST_PHS); T_RadiusDamage (self, self->activator, self->dmg, NULL, self->dmg+40, MOD_EXPLOSIVE, -1); save = self->delay; self->delay = 0; G_UseTargets (self, self->activator); self->delay = save; } void use_target_explosion (edict_t *self, edict_t *other, edict_t *activator) { self->activator = activator; if (!self->delay) { target_explosion_explode (self); return; } self->think = target_explosion_explode; self->nextthink = level.time + self->delay; } void SP_target_explosion (edict_t *ent) { ent->use = use_target_explosion; ent->svflags = SVF_NOCLIENT; } //========================================================== /*QUAKED target_splash (1 0 0) (-8 -8 -8) (8 8 8) Creates a particle splash effect when used. Set "sounds" to one of the following: 1) sparks 2) blue water 3) brown water 4) slime 5) lava 6) blood "count" how many pixels in the splash "dmg" if set, does a radius damage at this location when it splashes useful for lava/sparks */ void use_target_splash (edict_t *self, edict_t *other, edict_t *activator) { gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_SPLASH); gi.WriteByte (self->count); gi.WritePosition (self->s.origin); gi.WriteDir (self->movedir); gi.WriteByte (self->sounds); gi.multicast (self->s.origin, MULTICAST_PVS); if (self->dmg) T_RadiusDamage (self, activator, self->dmg, NULL, self->dmg+40, MOD_SPLASH, -1); } void SP_target_splash (edict_t *self) { self->use = use_target_splash; G_SetMovedir (self->s.angles, self->movedir); if (!self->count) self->count = 32; self->svflags = SVF_NOCLIENT; } void use_target_steam (edict_t *self, edict_t *other, edict_t *activator) { gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_STEAM); gi.WriteByte (self->count); gi.WritePosition (self->s.origin); gi.WriteDir (self->movedir); gi.WriteByte (self->sounds); gi.multicast (self->s.origin, MULTICAST_ALL); } void SP_target_steam (edict_t *self) { self->use = use_target_steam; G_SetMovedir (self->s.angles, self->movedir); if (!self->count) self->count = 32; self->svflags = SVF_NOCLIENT; } void use_target_fire (edict_t *self, edict_t *other, edict_t *activator) { gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_FIRE); gi.WriteByte (self->count); gi.WritePosition (self->s.origin); gi.WriteDir (self->movedir); gi.WriteByte (self->sounds); gi.multicast (self->s.origin, MULTICAST_ALL); } void SP_target_fire (edict_t *self) { self->use = use_target_fire; G_SetMovedir (self->s.angles, self->movedir); // if (!self->count) self->count = 32; self->s.effects = EF_HYPERBLASTER;//give it a glow self->svflags = SVF_NOCLIENT; } //========================================================== /*QUAKED target_spawner (1 0 0) (-8 -8 -8) (8 8 8) Set target to the type of entity you want spawned. Useful for spawning monsters and gibs in the factory levels. For monsters: Set direction to the facing you want it to have. For gibs: Set direction if you want it moving and speed how fast it should be moving otherwise it will just be dropped */ void ED_CallSpawn (edict_t *ent); void use_target_spawner (edict_t *self, edict_t *other, edict_t *activator) { edict_t *ent; ent = G_Spawn(); ent->classname = self->target; ent->spawnflags = self->spawnflags; ent->deathtarget = self->deathtarget; VectorCopy (self->s.origin, ent->s.origin); VectorCopy (self->s.angles, ent->s.angles); ED_CallSpawn (ent); gi.unlinkentity (ent); KillBox (ent); gi.linkentity (ent); if (self->speed) VectorCopy (self->movedir, ent->velocity); } void SP_target_spawner (edict_t *self) { self->use = use_target_spawner; self->svflags = SVF_NOCLIENT; if (self->speed) { G_SetMovedir (self->s.angles, self->movedir); VectorScale (self->movedir, self->speed, self->movedir); } } //========================================================== /*QUAKED target_blaster (1 0 0) (-8 -8 -8) (8 8 8) NOTRAIL NOEFFECTS Fires a blaster bolt in the set direction when triggered. dmg default is 15 speed default is 1000 */ #ifndef ALTERIA void use_target_blaster (edict_t *self, edict_t *other, edict_t *activator) { int effect; if (self->spawnflags & 2) effect = 0; else if (self->spawnflags & 1) effect = EF_HYPERBLASTER; else effect = EF_BLASTER; fire_blaster (self, self->s.origin, self->s.origin, self->movedir, self->dmg, self->speed, EF_BLASTER, MOD_TARGET_BLASTER); gi.sound (self, CHAN_VOICE, self->noise_index, 1, ATTN_NORM, 0); } void SP_target_blaster (edict_t *self) { self->use = use_target_blaster; G_SetMovedir (self->s.angles, self->movedir); self->noise_index = gi.soundindex ("weapons/laser2.wav"); if (!self->dmg) self->dmg = 15; if (!self->speed) self->speed = 1000; self->svflags = SVF_NOCLIENT; } #endif //========================================================== /*QUAKED target_laser (0 .5 .8) (-8 -8 -8) (8 8 8) START_ON RED GREEN BLUE YELLOW ORANGE FAT When triggered, fires a laser. You can either set a target or a direction. */ void target_laser_think (edict_t *self) { edict_t *ignore; vec3_t start; vec3_t end; trace_t tr; vec3_t point; vec3_t last_movedir; int count; if (self->spawnflags & 0x80000000) count = 8; else count = 4; if (self->enemy) { VectorCopy (self->movedir, last_movedir); VectorMA (self->enemy->absmin, 0.5, self->enemy->size, point); VectorSubtract (point, self->s.origin, self->movedir); VectorNormalize (self->movedir); if (!VectorCompare(self->movedir, last_movedir)) self->spawnflags |= 0x80000000; } ignore = self; VectorCopy (self->s.origin, start); VectorMA (start, 2048, self->movedir, end); while(1) { tr = gi.trace (start, NULL, NULL, end, ignore, CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_DEADMONSTER); gi.WriteByte (svc_temp_entity); if (self->spawnflags & 8) gi.WriteByte (TE_LIGHTNING); else if (self->spawnflags & 16) gi.WriteByte (TE_VAPORBEAM); else gi.WriteByte (TE_LASERBEAM); gi.WritePosition (start); gi.WritePosition (end); gi.multicast (start, MULTICAST_PHS); if (!tr.ent) break; // hurt it if we can if ((tr.ent->takedamage) && !(tr.ent->flags & FL_IMMUNE_LASER)) T_Damage (tr.ent, self, self->activator, self->movedir, tr.endpos, vec3_origin, self->dmg, 1, DAMAGE_ENERGY, MOD_TARGET_LASER); // if we hit something that's not a monster or player or is immune to lasers, we're done if (!(tr.ent->svflags & SVF_MONSTER) && (!tr.ent->client)) { if (self->spawnflags & 0x80000000) { self->spawnflags &= ~0x80000000; gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_LASER_SPARKS); gi.WriteByte (count); gi.WritePosition (tr.endpos); gi.WriteDir (tr.plane.normal); gi.WriteByte (self->s.skinnum); gi.multicast (tr.endpos, MULTICAST_PVS); } break; } ignore = tr.ent; VectorCopy (tr.endpos, start); } VectorCopy (tr.endpos, self->s.old_origin); if ((self->spawnflags & 2) || (self->spawnflags & 64)) { self->nextthink = level.time + 2; gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_EXPLOSION1); gi.WritePosition (tr.endpos); gi.multicast (tr.endpos, MULTICAST_PVS); T_RadiusDamage(self, self->owner, 500, self->owner, 300, MOD_R_SPLASH, -1); gi.sound (self, CHAN_AUTO, gi.soundindex("martian/saucer.wav"), 1, ATTN_NORM, 0); self->nextthink = 0; } else self->nextthink = level.time + FRAMETIME; } void target_laser_on (edict_t *self) { if(self->spawnflags & 64) { self->nextthink = 0; } else { if (!self->activator) self->activator = self; self->spawnflags |= 0x80000001; self->svflags &= ~SVF_NOCLIENT; target_laser_think (self); } } void target_laser_off (edict_t *self) { if(self->spawnflags & 64) { if (!self->activator) self->activator = self; // self->spawnflags |= 0x80000001; // self->svflags &= ~SVF_NOCLIENT; self->spawnflags &= ~1; self->svflags |= SVF_NOCLIENT; target_laser_think (self); } else { self->spawnflags &= ~1; self->svflags |= SVF_NOCLIENT; self->nextthink = 0; } } void target_laser_use (edict_t *self, edict_t *other, edict_t *activator) { self->activator = activator; if (self->spawnflags & 1) target_laser_off (self); else target_laser_on (self); } void target_laser_start (edict_t *self) { edict_t *ent; self->movetype = MOVETYPE_NONE; self->solid = SOLID_NOT; // set the color - I will need to fix this later if (self->spawnflags & 2) self->s.skinnum = 0xf2f2f0f0; else if (self->spawnflags & 4) self->s.skinnum = 0xd0d1d2d3; else if (self->spawnflags & 8) self->s.skinnum = 0xf3f3f1f1; else if (self->spawnflags & 16) self->s.skinnum = 0xdcdddedf; else if (self->spawnflags & 32) self->s.skinnum = 0xe0e1e2e3; if (!self->enemy) { if (self->target) { ent = G_Find (NULL, FOFS(targetname), self->target); if (!ent) gi.dprintf ("%s at %s: %s is a bad target\n", self->classname, vtos(self->s.origin), self->target); self->enemy = ent; } else { G_SetMovedir (self->s.angles, self->movedir); } } self->use = target_laser_use; self->think = target_laser_think; if (!self->dmg) self->dmg = 1; VectorSet (self->mins, -16, -16, -16); VectorSet (self->maxs, 16, 16, 16); gi.linkentity (self); if (self->spawnflags & 1) target_laser_on (self); else target_laser_off (self); } void SP_target_laser (edict_t *self) { // let everything else get spawned before we start firing self->think = target_laser_start; self->nextthink = level.time + 1; } /*QUAKED target_changelevel (1 0 0) (-8 -8 -8) (8 8 8) Changes level to "map" when fired */ void use_target_changelevel (edict_t *self, edict_t *other, edict_t *activator) { if (level.intermissiontime) return; // already activated if (!deathmatch->value) { if (g_edicts[1].health <= 0) return; } // if noexit, do a ton of damage to other if (deathmatch->value && !( dmflags->integer & DF_ALLOW_EXIT) && other != world) { T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 10 * other->max_health, 1000, 0, MOD_EXIT); return; } // if multiplayer, let everyone know who hit the exit if (deathmatch->value) { if (activator && activator->client) safe_bprintf (PRINT_HIGH, "%s exited the level.\n", activator->client->pers.netname); } // if going to a new unit, clear cross triggers if (strstr(self->map, "*")) game.serverflags &= ~(SFL_CROSS_TRIGGER_MASK); BeginIntermission (self); } void SP_target_changelevel (edict_t *ent) { if (!ent->map) { gi.dprintf("target_changelevel with no map at %s\n", vtos(ent->s.origin)); G_FreeEdict (ent); return; } ent->use = use_target_changelevel; ent->svflags = SVF_NOCLIENT; } //========================================================== /*QUAKED target_lightramp (0 .5 .8) (-8 -8 -8) (8 8 8) TOGGLE speed How many seconds the ramping will take message two letters; starting lightlevel and ending lightlevel */ void target_lightramp_think (edict_t *self) { char style[2]; style[0] = 'a' + self->movedir[0] + (level.time - self->timestamp) / FRAMETIME * self->movedir[2]; style[1] = 0; gi.configstring (CS_LIGHTS+self->enemy->style, style); if ((level.time - self->timestamp) < self->speed) { self->nextthink = level.time + FRAMETIME; } else if (self->spawnflags & 1) { char temp; temp = self->movedir[0]; self->movedir[0] = self->movedir[1]; self->movedir[1] = temp; self->movedir[2] *= -1; } } void target_lightramp_use (edict_t *self, edict_t *other, edict_t *activator) { if (!self->enemy) { edict_t *e; // check all the targets e = NULL; while (1) { e = G_Find (e, FOFS(targetname), self->target); if (!e) break; if (strcmp(e->classname, "light") != 0) { gi.dprintf("%s at %s ", self->classname, vtos(self->s.origin)); gi.dprintf("target %s (%s at %s) is not a light\n", self->target, e->classname, vtos(e->s.origin)); } else { self->enemy = e; } } if (!self->enemy) { gi.dprintf("%s target %s not found at %s\n", self->classname, self->target, vtos(self->s.origin)); G_FreeEdict (self); return; } } self->timestamp = level.time; target_lightramp_think (self); } void SP_target_lightramp (edict_t *self) { if (!self->message || strlen(self->message) != 2 || self->message[0] < 'a' || self->message[0] > 'z' || self->message[1] < 'a' || self->message[1] > 'z' || self->message[0] == self->message[1]) { gi.dprintf("target_lightramp has bad ramp (%s) at %s\n", self->message, vtos(self->s.origin)); G_FreeEdict (self); return; } if (deathmatch->value) { G_FreeEdict (self); return; } if (!self->target) { gi.dprintf("%s with no target at %s\n", self->classname, vtos(self->s.origin)); G_FreeEdict (self); return; } self->svflags |= SVF_NOCLIENT; self->use = target_lightramp_use; self->think = target_lightramp_think; self->movedir[0] = self->message[0] - 'a'; self->movedir[1] = self->message[1] - 'a'; self->movedir[2] = (self->movedir[1] - self->movedir[0]) / (self->speed / FRAMETIME); } //========================================================== /*QUAKED target_earthquake (1 0 0) (-8 -8 -8) (8 8 8) When triggered, this initiates a level-wide earthquake. All players and monsters are affected. "speed" severity of the quake (default:200) "count" duration of the quake (default:5) */ void target_earthquake_think (edict_t *self) { int i; edict_t *e; if (self->last_move_time < level.time) { gi.positioned_sound (self->s.origin, self, CHAN_AUTO, self->noise_index, 1.0, ATTN_NONE, 0); self->last_move_time = level.time + 0.5; } for (i=1, e=g_edicts+i; i < globals.num_edicts; i++,e++) { if (!e->inuse) continue; if (!e->client) continue; if (!e->groundentity) continue; e->groundentity = NULL; e->velocity[0] += crandom()* 150; e->velocity[1] += crandom()* 150; e->velocity[2] = self->speed * (100.0 / e->mass); } if (level.time < self->timestamp) self->nextthink = level.time + FRAMETIME; } void target_earthquake_use (edict_t *self, edict_t *other, edict_t *activator) { self->timestamp = level.time + self->count; self->nextthink = level.time + FRAMETIME; self->activator = activator; self->last_move_time = 0; } void SP_target_earthquake (edict_t *self) { if (!self->targetname) gi.dprintf("untargeted %s at %s\n", self->classname, vtos(self->s.origin)); if (!self->count) self->count = 5; if (!self->speed) self->speed = 200; self->svflags |= SVF_NOCLIENT; self->think = target_earthquake_think; self->use = target_earthquake_use; self->noise_index = gi.soundindex ("world/explosion2.wav"); } alien-arena-7.66+dfsg/source/game/g_deathball.c0000600000175000017500000001307212161402010020410 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" //Deathball static void DeathballThink(edict_t *ent) { ent->nextthink = level.time + FRAMETIME; } void DeathballSetup (edict_t *ent) { trace_t tr; vec3_t dest; float *v; v = tv(-32,-32,-32); VectorCopy (v, ent->mins); v = tv(32,32,32); VectorCopy (v, ent->maxs); if (ent->model) gi.setmodel (ent, ent->model); else gi.setmodel (ent, ent->item->world_model); ent->solid = SOLID_TRIGGER; ent->movetype = MOVETYPE_TOSS; ent->touch = Touch_Item; v = tv(0,0,-128); VectorAdd (ent->s.origin, v, dest); tr = gi.trace (ent->s.origin, ent->mins, ent->maxs, dest, ent, MASK_SOLID); if (tr.startsolid) { gi.dprintf ("DeathballSetup: %s startsolid at %s\n", ent->classname, vtos(ent->s.origin)); G_FreeEdict (ent); return; } VectorCopy (tr.endpos, ent->s.origin); gi.linkentity (ent); ent->s.frame = 229; ent->nextthink = level.time + FRAMETIME; ent->think = DeathballThink; } void DeathballDrop(edict_t *ent, gitem_t *item) { if (rand() & 1) safe_cprintf(ent, PRINT_HIGH, "Only lusers drop the ball!\n"); else safe_cprintf(ent, PRINT_HIGH, "Winners don't drop their balls!\n"); } void ResetDeathball() { char *c; edict_t *ent; ent = NULL; c = "item_deathball"; while ((ent = G_Find (ent, FOFS(classname), c)) != NULL) { if (ent->spawnflags & DROPPED_ITEM) G_FreeEdict(ent); else { ent->svflags &= ~SVF_NOCLIENT; ent->solid = SOLID_TRIGGER; gi.linkentity(ent); ent->s.frame = 229; ent->s.event = EV_ITEM_RESPAWN; } } } static void DropDeathballTouch(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { //owner (who dropped us) can't touch for two secs if (other == ent->owner && ent->nextthink - level.time > 2) return; other->in_deathball = true; Touch_Item (ent, other, plane, surf); } static void DropDeathballThink(edict_t *ent) { // auto return the ball // reset ball will remove ourselves ResetDeathball(); safe_bprintf(PRINT_HIGH, "The ball has returned!\n"); } void DeadDropDeathball(edict_t *self) { edict_t *dropped = NULL; gitem_t *deathball_item; dropped = NULL; deathball_item = NULL; deathball_item = FindItemByClassname("item_deathball"); if (self->client->pers.inventory[ITEM_INDEX(deathball_item)]) { dropped = Drop_Item(self, deathball_item); self->client->pers.inventory[ITEM_INDEX(deathball_item)] = 0; safe_bprintf(PRINT_HIGH, "%s lost the ball!\n", self->client->pers.netname); self->s.modelindex4 = 0; self->in_deathball = false; } if (dropped) { dropped->think = DropDeathballThink; dropped->nextthink = level.time + 30; dropped->touch = DropDeathballTouch; dropped->s.frame = 229; } } qboolean Pickup_deathball (edict_t *ent, edict_t *other) { gitem_t *bomber; gitem_t *strafer; gitem_t *hover; gitem_t *deathball; char cleanname[PLAYERNAME_SIZE]; int i; edict_t *cl_ent; //check for any vehicles, if we have one, don't get in a deathball! bomber = FindItemByClassname("item_bomber"); strafer = FindItemByClassname("item_strafer"); hover = FindItemByClassname("item_hover"); if((other->client->pers.inventory[ITEM_INDEX(bomber)] == 1) || (other->client->pers.inventory[ITEM_INDEX(strafer)] == 1) || (other->client->pers.inventory[ITEM_INDEX(hover)] == 1)) return false; deathball = FindItemByClassname(ent->classname); // get in the ball if(other->client->pers.inventory[ITEM_INDEX(deathball)] == 1) return false; //can't get in a deathball if you're already in one! (would never happen) //put him in the ball(weapon model replaced with this) other->s.modelindex4 = gi.modelindex("vehicles/deathball/deathball.md2"); other->in_deathball = true; other->client->pers.inventory[ITEM_INDEX(deathball)] = 1; other->client->newweapon = ent->item; if (!(ent->spawnflags & DROPPED_ITEM)) { ent->flags |= FL_RESPAWN; ent->svflags |= SVF_NOCLIENT; ent->solid = SOLID_NOT; } G_CleanPlayerName( other->client->pers.netname, cleanname ); if(dmflags->integer & DF_SKINTEAMS) { for (i=0 ; ivalue ; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || cl_ent->is_bot) continue; safe_centerprintf(cl_ent, "%s got the ball!\n", cleanname); } safe_centerprintf(other, "You've got the ball!\nShoot the ball\ninto your enemy's goal!"); } else { for (i=0 ; ivalue ; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || cl_ent->is_bot) continue; safe_centerprintf(cl_ent, "%s got the ball!\n", cleanname); } safe_centerprintf(other, "You've got the ball!\nShoot the ball\ninto any goal!"); } //play a sound here too gi.sound (ent, CHAN_AUTO, gi.soundindex("misc/db_pickup.wav"), 1, ATTN_NONE, 0); return true; } alien-arena-7.66+dfsg/source/game/p_view.c0000600000175000017500000010215112161402010017450 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" #include "m_player.h" static edict_t *current_player; static gclient_t *current_client; static vec3_t forward, right, up; float xyspeed; float bobmove; int bobcycle; // odd cycles are right foot going forward float bobfracsin; // sin(bobfrac*M_PI) /* =============== SV_CalcRoll =============== */ float SV_CalcRoll (vec3_t angles, vec3_t velocity) { float sign; float side; float value; side = DotProduct (velocity, right); sign = side < 0 ? -1 : 1; side = fabs(side); value = sv_rollangle->value; if (side < sv_rollspeed->value) side = side * value / sv_rollspeed->value; else side = value; return side*sign; } /* =============== P_DamageFeedback Handles color blends and view kicks =============== */ void P_DamageFeedback (edict_t *player) { gclient_t *client; float side; float realcount, count, kick; vec3_t v; int r, l; static vec3_t acolor = {1.0, 1.0, 1.0}; static vec3_t bcolor = {1.0, 0.0, 0.0}; client = player->client; // flash the backgrounds behind the status numbers client->ps.stats[STAT_FLASHES] &= ~(1|2); if (client->damage_blood) client->ps.stats[STAT_FLASHES] |= 1; if (client->damage_armor && !(player->flags & FL_GODMODE) && (client->invincible_framenum <= level.framenum)) client->ps.stats[STAT_FLASHES] |= 2; // total points of damage shot at the player this frame count = (client->damage_blood + client->damage_armor); if (count == 0) return; // didn't take any damage // start a pain animation if still in the player model if (client->anim_priority < ANIM_PAIN && player->s.modelindex == 255) { static int i; client->anim_priority = ANIM_PAIN; if (client->ps.pmove.pm_flags & PMF_DUCKED) { player->s.frame = FRAME_crpain1-1; client->anim_end = FRAME_crpain4; } else { i = (i+1)%3; switch (i) { case 0: player->s.frame = FRAME_pain101-1; client->anim_end = FRAME_pain104; break; case 1: player->s.frame = FRAME_pain201-1; client->anim_end = FRAME_pain204; break; case 2: player->s.frame = FRAME_pain301-1; client->anim_end = FRAME_pain304; break; } } } realcount = count; if (count < 10) count = 10; // always make a visible effect // play an apropriate pain sound if ((level.time > player->pain_debounce_time) && !(player->flags & FL_GODMODE) && (client->invincible_framenum <= level.framenum)) { r = 1 + (rand()&1); player->pain_debounce_time = level.time + 0.7; if (player->health < 25) l = 25; else if (player->health < 50) l = 50; else if (player->health < 75) l = 75; else l = 100; gi.sound (player, CHAN_VOICE, gi.soundindex(va("*pain%i_%i.wav", l, r)), 1, ATTN_NORM, 0); } // the total alpha of the blend is always proportional to count if (client->damage_alpha < 0) client->damage_alpha = 0; client->damage_alpha += count*0.01; if (client->damage_alpha < 0.2) client->damage_alpha = 0.2; if (client->damage_alpha > 0.6) client->damage_alpha = 0.6; // don't go too saturated // the color of the blend will vary based on how much was absorbed // by different armors VectorClear (v); if (client->damage_armor) VectorMA (v, (float)client->damage_armor/realcount, acolor, v); if (client->damage_blood) VectorMA (v, (float)client->damage_blood/realcount, bcolor, v); VectorCopy (v, client->damage_blend); // // calculate view angle kicks // kick = abs(client->damage_knockback); if (kick && player->health > 0) // kick of 0 means no view adjust at all { kick = kick * 100 / player->health; if (kick < count*0.5) kick = count*0.5; if (kick > 50) kick = 50; VectorSubtract (client->damage_from, player->s.origin, v); VectorNormalize (v); side = DotProduct (v, right); client->v_dmg_roll = kick*side*0.3; side = -DotProduct (v, forward); client->v_dmg_pitch = kick*side*0.3; client->v_dmg_time = level.time + DAMAGE_TIME; } // // clear totals // client->damage_blood = 0; client->damage_armor = 0; client->damage_knockback = 0; } /* =============== SV_CalcViewOffset Auto pitching on slopes? fall from 128: 400 = 160000 fall from 256: 580 = 336400 fall from 384: 720 = 518400 fall from 512: 800 = 640000 fall from 640: 960 = damage = deltavelocity*deltavelocity * 0.0001 =============== */ void SV_CalcViewOffset (edict_t *ent) { float *angles; float bob; float ratio; float delta; vec3_t v; // base angles angles = ent->client->ps.kick_angles; // if dead, fix the angle and don't add any kick if (ent->deadflag) { VectorClear (angles); ent->client->ps.viewangles[ROLL] = 40; ent->client->ps.viewangles[PITCH] = -15; ent->client->ps.viewangles[YAW] = ent->client->killer_yaw; } else { // add angles based on weapon kick VectorCopy (ent->client->kick_angles, angles); // add angles based on damage kick ratio = (ent->client->v_dmg_time - level.time) / DAMAGE_TIME; if (ratio < 0) { ratio = 0; ent->client->v_dmg_pitch = 0; ent->client->v_dmg_roll = 0; } angles[PITCH] += ratio * ent->client->v_dmg_pitch; angles[ROLL] += ratio * ent->client->v_dmg_roll; // add pitch based on fall kick // ratio = (ent->client->fall_time - level.time) / FALL_TIME; // if (ratio < 0) // ratio = 0; // angles[PITCH] += ratio * ent->client->fall_value; // add angles based on velocity delta = DotProduct (ent->velocity, forward); angles[PITCH] += delta*run_pitch->value; delta = DotProduct (ent->velocity, right); angles[ROLL] += delta*run_roll->value; // add angles based on bob delta = bobfracsin * bob_pitch->value * xyspeed; if (ent->client->ps.pmove.pm_flags & PMF_DUCKED) delta *= 6; // crouching angles[PITCH] += delta; delta = bobfracsin * bob_roll->value * xyspeed; if (ent->client->ps.pmove.pm_flags & PMF_DUCKED) delta *= 6; // crouching if (bobcycle & 1) delta = -delta; angles[ROLL] += delta; } // base origin VectorClear (v); // add view height v[2] += ent->viewheight; // add fall height ratio = (ent->client->fall_time - level.time) / FALL_TIME; if (ratio < 0) ratio = 0; v[2] -= ratio * ent->client->fall_value; // add bob height bob = bobfracsin * xyspeed * bob_up->value; if (bob > 6) bob = 6; v[2] += bob; // add kick offset VectorAdd (v, ent->client->kick_origin, v); // absolutely bound offsets // so the view can never be outside the player box if (!ent->client->chasetoggle) { if (v[0] < -14) v[0] = -14; else if (v[0] > 14) v[0] = 14; if (v[1] < -14) v[1] = -14; else if (v[1] > 14) v[1] = 14; if (v[2] < -22) v[2] = -22; else if (v[2] > 30) v[2] = 30; } else { VectorSet (v, 0, 0, 0); if (ent->client->chasecam != NULL) { ent->client->ps.pmove.origin[0] = ent->client->chasecam->s.origin[0]*8; ent->client->ps.pmove.origin[1] = ent->client->chasecam->s.origin[1]*8; ent->client->ps.pmove.origin[2] = ent->client->chasecam->s.origin[2]*8; VectorCopy (ent->client->chasecam->s.angles, ent->client->ps.viewangles); } } VectorCopy (v, ent->client->ps.viewoffset); } /* ============== SV_CalcGunOffset ============== */ void SV_CalcGunOffset (edict_t *ent) { int i; // gun angles from bobbing ent->client->ps.gunangles[ROLL] = xyspeed * bobfracsin * 0.005; ent->client->ps.gunangles[YAW] = xyspeed * bobfracsin * 0.01; if (bobcycle & 1) { ent->client->ps.gunangles[ROLL] = -ent->client->ps.gunangles[ROLL]; ent->client->ps.gunangles[YAW] = -ent->client->ps.gunangles[YAW]; } ent->client->ps.gunangles[PITCH] = xyspeed * bobfracsin * 0.005; VectorClear (ent->client->ps.gunoffset); // gun_x / gun_y / gun_z are development tools for (i=0 ; i<3 ; i++) { ent->client->ps.gunoffset[i] += forward[i]*(gun_y->value); ent->client->ps.gunoffset[i] += right[i]*gun_x->value; ent->client->ps.gunoffset[i] += up[i]* (-gun_z->value); } //landing on jumps if(ent->s.event == EV_FALLSHORT || ent->s.event == EV_FALL || ent->s.event == EV_FALLFAR) { ent->client->ps.gunoffset[2] -=1.5; ent->client->ps.gunangles[PITCH] -= 1; ent->client->ps.gunangles[ROLL] -= 1; } } /* ============= SV_AddBlend ============= */ void SV_AddBlend (float r, float g, float b, float a, float *v_blend) { float a2, a3; if (a <= 0) return; a2 = v_blend[3] + (1-v_blend[3])*a; // new total alpha a3 = v_blend[3]/a2; // fraction of color from old v_blend[0] = v_blend[0]*a3 + r*(1-a3); v_blend[1] = v_blend[1]*a3 + g*(1-a3); v_blend[2] = v_blend[2]*a3 + b*(1-a3); v_blend[3] = a2; } void ResetWeaponModel (edict_t *ent) { char *info; char weaponame[64] = " "; char weaponmodel[MAX_OSPATH] = " "; int i; int done; char weaponpath[MAX_OSPATH] = " "; FILE *file; if (ent->in_vehicle) { return; } //set up code to set player world weapon model info = Info_ValueForKey (ent->client->pers.userinfo, "skin"); i = 0; done = 0; strcpy(weaponame, " "); weaponame[0] = 0; while(!done) { if((info[i] == '/') || (info[i] == '\\')) done = 1; weaponame[i] = info[i]; if(i > 63) done = 1; i++; } strcpy(weaponmodel, " "); weaponmodel[0] = 0; sprintf(weaponmodel, "players/%s%s", weaponame, "weapon.md2"); //default if( !Q_strcasecmp( ent->client->pers.weapon->view_model, "models/weapons/v_violator/tris.md2" )) sprintf(weaponmodel, "players/%s%s", weaponame, "w_violator.md2"); else if( !Q_strcasecmp( ent->client->pers.weapon->view_model, "models/weapons/v_rocket/tris.md2")) sprintf(weaponmodel, "players/%s%s", weaponame, "w_rlauncher.md2"); else if( !Q_strcasecmp(ent->client->pers.weapon->view_model,"models/weapons/v_blast/tris.md2")) sprintf(weaponmodel, "players/%s%s", weaponame, "w_blaster.md2"); else if( !Q_strcasecmp(ent->client->pers.weapon->view_model,"models/weapons/v_alienblast/tris.md2")) sprintf(weaponmodel, "players/%s%s", weaponame, "w_alienblaster.md2"); else if( !Q_strcasecmp(ent->client->pers.weapon->view_model,"models/weapons/v_bfg/tris.md2")) sprintf(weaponmodel, "players/%s%s", weaponame, "w_bfg.md2"); else if( !Q_strcasecmp(ent->client->pers.weapon->view_model, "models/weapons/v_rail/tris.md2")) sprintf(weaponmodel, "players/%s%s", weaponame, "w_railgun.md2"); else if( !Q_strcasecmp(ent->client->pers.weapon->view_model, "models/weapons/v_shotg2/tris.md2")) sprintf(weaponmodel, "players/%s%s", weaponame, "w_sshotgun.md2"); else if( !Q_strcasecmp(ent->client->pers.weapon->view_model, "models/weapons/v_shotg/tris.md2")) sprintf(weaponmodel, "players/%s%s", weaponame, "w_shotgun.md2"); else if( !Q_strcasecmp(ent->client->pers.weapon->view_model, "models/weapons/v_hyperb/tris.md2")) sprintf(weaponmodel, "players/%s%s", weaponame, "w_hyperblaster.md2"); else if( !Q_strcasecmp(ent->client->pers.weapon->view_model, "models/weapons/v_chain/tris.md2")) sprintf(weaponmodel, "players/%s%s", weaponame, "w_chaingun.md2"); else if( !Q_strcasecmp(ent->client->pers.weapon->view_model, "models/weapons/v_minderaser/tris.md2")) sprintf(weaponmodel, "players/%s%s", weaponame, "w_minderaser.md2"); else if( !Q_strcasecmp(ent->client->pers.weapon->view_model, "vehicles/deathball/v_wep.md2")) sprintf(weaponmodel, "players/%s%s", weaponame, "w_machinegun.md2"); sprintf(weaponpath, "%s", weaponmodel); Q2_FindFile (weaponpath, &file); //does it really exist? if(!file) { sprintf(weaponpath, "%s%s", weaponame, "weapon.md2"); //no w_weaps, do we have this model? Q2_FindFile (weaponpath, &file); if(!file) //server does not have this player model sprintf(weaponmodel, "players/martianenforcer/weapon.md2");//default player(martian) else { //have the model, but it has no w_weaps sprintf(weaponmodel, "players/%s%s", weaponame, "weapon.md2"); //custom weapon fclose(file); } } else fclose(file); ent->s.modelindex2 = gi.modelindex(weaponmodel); } /* ============= SV_CalcBlend ============= */ void SV_CalcBlend (edict_t *ent) { int contents; vec3_t vieworg; int remaining; ent->client->ps.blend[0] = ent->client->ps.blend[1] = ent->client->ps.blend[2] = ent->client->ps.blend[3] = 0; // add for contents VectorAdd (ent->s.origin, ent->client->ps.viewoffset, vieworg); contents = gi.pointcontents (vieworg); if (contents & (CONTENTS_LAVA|CONTENTS_SLIME|CONTENTS_WATER) ) ent->client->ps.rdflags |= RDF_UNDERWATER; else ent->client->ps.rdflags &= ~RDF_UNDERWATER; if (contents & (CONTENTS_SOLID|CONTENTS_LAVA)) SV_AddBlend (1.0, 0.3, 0.0, 0.6, ent->client->ps.blend); else if (contents & CONTENTS_SLIME) SV_AddBlend (0.0, 0.1, 0.05, 0.6, ent->client->ps.blend); else if (contents & CONTENTS_WATER) SV_AddBlend (0.5, 0.3, 0.2, 0.4, ent->client->ps.blend); // add for powerups //vehicles(flying) if ( Jet_Active(ent) ) { /*update the fuel time*/ ent->client->Jet_remaining = ent->client->Jet_framenum - level.framenum; /*if no fuel remaining, remove vehicle from inventory*/ if ( ent->client->Jet_remaining == 0 ) { ent->client->pers.inventory[ITEM_INDEX(FindItem("bomber"))] = 0; ent->client->pers.inventory[ITEM_INDEX(FindItem("strafer"))] = 0; ent->client->pers.inventory[ITEM_INDEX(FindItem("hover"))] = 0; //set everything back Reset_player(ent); } /*Play jetting sound every 0.6 secs (sound of monster icarus)*/ if ( ((int)ent->client->Jet_remaining % 6) == 0 ) { gi.sound (ent, CHAN_AUTO, gi.soundindex("vehicles/bomberidle.wav"), 0.9, ATTN_NORM, 0); // send muzzle flash gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_RAILGUN | MZ_SILENCED); gi.multicast (ent->s.origin, MULTICAST_PVS); } /*beginning to fade if 4 secs or less*/ if (ent->client->Jet_remaining <= 40) /*play on/off sound every sec*/ if ( ((int)ent->client->Jet_remaining % 10) == 0 ) gi.sound(ent, CHAN_ITEM, gi.soundindex("vehicles/warning.wav"), 1, ATTN_NORM, 0); if (ent->client->Jet_remaining > 40 || ( (int)ent->client->Jet_remaining & 4) ) SV_AddBlend (0, 0, 1, 0.08, ent->client->ps.blend); } else if (ent->client->quad_framenum > level.framenum) { remaining = ent->client->quad_framenum - level.framenum; if (remaining == 30) // beginning to fade gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage2.wav"), 1, ATTN_NORM, 0); if (remaining > 30 || (remaining & 4) ) SV_AddBlend (0, 0, 1, 0.08, ent->client->ps.blend); } else if (ent->client->invincible_framenum > level.framenum || ent->client->spawnprotected) { remaining = ent->client->invincible_framenum - level.framenum; if (remaining == 30) // beginning to fade gi.sound(ent, CHAN_ITEM, gi.soundindex("items/protect2.wav"), 1, ATTN_NORM, 0); if (remaining > 30 || (remaining & 4) ) SV_AddBlend (1, 1, 0, 0.08, ent->client->ps.blend); } else if (ent->client->haste_framenum > level.framenum) { remaining = ent->client->haste_framenum - level.framenum; if (remaining == 30) // beginning to fade gi.sound(ent, CHAN_ITEM, gi.soundindex("items/hasteout.wav"), 1, ATTN_NORM, 0); if (remaining > 30 || (remaining & 4) ) SV_AddBlend (0.4, 1, 0.4, 0.04, ent->client->ps.blend); } else if (ent->client->sproing_framenum > level.framenum) { remaining = ent->client->sproing_framenum - level.framenum; if (remaining == 30) // beginning to fade gi.sound(ent, CHAN_ITEM, gi.soundindex("items/sproingout.wav"), 1, ATTN_NORM, 0); if (remaining > 30 || (remaining & 4) ) SV_AddBlend (0.4, 1, 0.4, 0.04, ent->client->ps.blend); } else if (ent->client->invis_framenum > level.framenum) { remaining = ent->client->invis_framenum - level.framenum; if (remaining == 30) // beginning to fade gi.sound(ent, CHAN_ITEM, gi.soundindex("items/protect2.wav"), 1, ATTN_NORM, 0); if (remaining > 30 || (remaining & 4) ) SV_AddBlend (0.4, 1, 0.4, 0.04, ent->client->ps.blend); if (remaining == 1) { //put weapon model back ResetWeaponModel(ent); } } // add for damage if (ent->client->damage_alpha > 0) SV_AddBlend (ent->client->damage_blend[0],ent->client->damage_blend[1] ,ent->client->damage_blend[2], ent->client->damage_alpha, ent->client->ps.blend); if (ent->client->bonus_alpha > 0) SV_AddBlend (0.85, 0.7, 0.3, ent->client->bonus_alpha, ent->client->ps.blend); // drop the damage value ent->client->damage_alpha -= 0.06; if (ent->client->damage_alpha < 0) ent->client->damage_alpha = 0; // drop the bonus value ent->client->bonus_alpha -= 0.1; if (ent->client->bonus_alpha < 0) ent->client->bonus_alpha = 0; } /* ================= P_FallingDamage ================= */ void P_FallingDamage (edict_t *ent) { float delta; int damage; vec3_t dir; if (ent->s.modelindex != 255) return; // not in the player model if (ent->movetype == MOVETYPE_NOCLIP) return; if(joustmode->value) return; if ((ent->client->oldvelocity[2] < 0) && (ent->velocity[2] > ent->client->oldvelocity[2]) && (!ent->groundentity)) { delta = ent->client->oldvelocity[2]; } else { if (!ent->groundentity) return; delta = ent->velocity[2] - ent->client->oldvelocity[2]; } delta = delta*delta * 0.0001; // never take damage if just release grapple or on grapple if (level.time - ent->client->ctf_grapplereleasetime <= FRAMETIME * 2 || (ent->client->ctf_grapple && ent->client->ctf_grapplestate > CTF_GRAPPLE_STATE_FLY)) return; // never take falling damage if completely underwater if (ent->waterlevel == 3) return; if (ent->waterlevel == 2) delta *= 0.25; if (ent->waterlevel == 1) delta *= 0.5; if (delta < 3) return; // if (delta < 15) // { // ent->s.event = EV_FOOTSTEP; // return; // } ent->client->fall_value = delta; if (ent->client->fall_value > 20) ent->client->fall_value = 20; ent->client->fall_time = level.time + FALL_TIME; if (delta > 30) { if (ent->health > 0) { if (delta >= 55) ent->s.event = EV_FALLFAR; else ent->s.event = EV_FALL; } ent->pain_debounce_time = level.time; // no normal pain sound damage = (delta-30)/2; if (damage < 1) damage = 1; if (damage > 10) damage = 10; VectorSet (dir, 0, 0, 1); if (!deathmatch->value || !(dmflags->integer & DF_NO_FALLING) ) T_Damage (ent, world, world, dir, ent->s.origin, vec3_origin, damage, 0, 0, MOD_FALLING); } else { ent->s.event = EV_FALLSHORT; return; } } /* ============= P_WorldEffects ============= */ void P_WorldEffects (void) { int waterlevel, old_waterlevel; if (current_player->movetype == MOVETYPE_NOCLIP) { current_player->air_finished = level.time + 12; // don't need air return; } waterlevel = current_player->waterlevel; old_waterlevel = current_client->old_waterlevel; current_client->old_waterlevel = waterlevel; // // if just entered a water volume, play a sound // if (!old_waterlevel && waterlevel) { PlayerNoise(current_player, current_player->s.origin, PNOISE_SELF); if (current_player->watertype & CONTENTS_LAVA) gi.sound (current_player, CHAN_BODY, gi.soundindex("player/lava_in.wav"), 1, ATTN_NORM, 0); else if (current_player->watertype & CONTENTS_SLIME) gi.sound (current_player, CHAN_BODY, gi.soundindex("player/watr_in.wav"), 1, ATTN_NORM, 0); else if (current_player->watertype & CONTENTS_WATER) gi.sound (current_player, CHAN_BODY, gi.soundindex("player/watr_in.wav"), 1, ATTN_NORM, 0); current_player->flags |= FL_INWATER; // clear damage_debounce, so the pain sound will play immediately current_player->damage_debounce_time = level.time - 1; } // // if just completely exited a water volume, play a sound // if (old_waterlevel && ! waterlevel) { PlayerNoise(current_player, current_player->s.origin, PNOISE_SELF); gi.sound (current_player, CHAN_BODY, gi.soundindex("player/watr_out.wav"), 1, ATTN_NORM, 0); current_player->flags &= ~FL_INWATER; } // // check for head just going under water // if (old_waterlevel != 3 && waterlevel == 3) { gi.sound (current_player, CHAN_BODY, gi.soundindex("player/watr_un.wav"), 1, ATTN_NORM, 0); } // // check for head just coming out of water // if (old_waterlevel == 3 && waterlevel != 3) { if (current_player->air_finished < level.time) { // gasp for air gi.sound (current_player, CHAN_VOICE, gi.soundindex("player/gasp1.wav"), 1, ATTN_NORM, 0); PlayerNoise(current_player, current_player->s.origin, PNOISE_SELF); } else if (current_player->air_finished < level.time + 11) { // just break surface gi.sound (current_player, CHAN_VOICE, gi.soundindex("player/gasp2.wav"), 1, ATTN_NORM, 0); } } // // check for drowning // if (waterlevel == 3) { // if out of air, start drowning if (current_player->air_finished < level.time) { // drown! if (current_player->client->next_drown_time < level.time && current_player->health > 0) { current_player->client->next_drown_time = level.time + 1; // take more damage the longer underwater current_player->dmg += 2; if (current_player->dmg > 15) current_player->dmg = 15; // play a gurp sound instead of a normal pain sound if (current_player->health <= current_player->dmg) gi.sound (current_player, CHAN_VOICE, gi.soundindex("player/drown1.wav"), 1, ATTN_NORM, 0); else if (rand()&1) gi.sound (current_player, CHAN_VOICE, gi.soundindex("*gurp1.wav"), 1, ATTN_NORM, 0); else gi.sound (current_player, CHAN_VOICE, gi.soundindex("*gurp2.wav"), 1, ATTN_NORM, 0); current_player->pain_debounce_time = level.time; T_Damage (current_player, world, world, vec3_origin, current_player->s.origin, vec3_origin, current_player->dmg, 0, DAMAGE_NO_ARMOR, MOD_WATER); } } } else { current_player->air_finished = level.time + 12; current_player->dmg = 2; } // // check for sizzle damage // if (waterlevel && (current_player->watertype&(CONTENTS_LAVA|CONTENTS_SLIME)) ) { if (current_player->watertype & CONTENTS_LAVA) { if (current_player->health > 0 && current_player->pain_debounce_time <= level.time && current_client->invincible_framenum < level.framenum) { if (rand()&1) gi.sound (current_player, CHAN_VOICE, gi.soundindex("player/burn1.wav"), 1, ATTN_NORM, 0); else gi.sound (current_player, CHAN_VOICE, gi.soundindex("player/burn2.wav"), 1, ATTN_NORM, 0); current_player->pain_debounce_time = level.time + 1; } T_Damage (current_player, world, world, vec3_origin, current_player->s.origin, vec3_origin, 3*waterlevel, 0, 0, MOD_LAVA); } if (current_player->watertype & CONTENTS_SLIME) { T_Damage (current_player, world, world, vec3_origin, current_player->s.origin, vec3_origin, 1*waterlevel, 0, 0, MOD_SLIME); } } } /* =============== TeamEffects =============== */ void TeamEffects(edict_t *player) { if(g_tactical->integer) return; if(player->dmteam == RED_TEAM) player->s.effects |= EF_TEAM1; else if(player->dmteam == BLUE_TEAM) player->s.effects |= EF_TEAM2; } /* =============== G_SetClientEffects =============== */ void G_SetClientEffects (edict_t *ent) { int remaining; ent->s.effects = 0; ent->s.renderfx = 0; if (ent->health <= 0 || level.intermissiontime) return; if(ctf->value) CTFEffects(ent); if ((dmflags->integer & DF_SKINTEAMS) || ctf->value || tca->value || cp->value ) TeamEffects(ent); else if (g_dmlights->integer && !g_tactical->integer) ent->s.effects |= EF_TEAM2; if (ent->client->quad_framenum > level.framenum) { remaining = ent->client->quad_framenum - level.framenum; if (remaining > 30 || (remaining & 4) ) ent->s.effects |= EF_QUAD; } if (ent->client->invincible_framenum > level.framenum) { remaining = ent->client->invincible_framenum - level.framenum; if (remaining > 30 || (remaining & 4) ) ent->s.effects |= EF_PENT; } // show cheaters!!! if (ent->flags & FL_GODMODE) { ent->s.effects |= EF_COLOR_SHELL; ent->s.renderfx |= (RF_SHELL_RED|RF_SHELL_GREEN|RF_SHELL_BLUE); } if(ent->client->spawnprotected) ent->s.effects |= EF_PENT; if(ent->client->kill_streak >= 8) ent->s.effects |= EF_BUBBLES; //invisibility if(ent->client->invis_framenum > level.framenum) { ent->s.renderfx |= RF_TRANSLUCENT; ent->s.modelindex2 = 0; } } /* =============== G_SetClientEvent =============== */ void G_SetClientEvent (edict_t *ent) { if (ent->s.event) return; if ( ent->groundentity && xyspeed > 225) { if ( (int)(current_client->bobtime+bobmove) != bobcycle ) ent->s.event = EV_FOOTSTEP; if ( ((ent->waterlevel == 1) || (ent->waterlevel == 2)) && (xyspeed > 100) ) { if ( (int)(current_client->bobtime+bobmove) != bobcycle ) { ent->s.event = EV_WADE; } } } } /* =============== G_SetClientSound =============== */ void G_SetClientSound (edict_t *ent) { char *weap; if (ent->client->pers.game_helpchanged != game.helpchanged) { ent->client->pers.game_helpchanged = game.helpchanged; ent->client->pers.helpchanged = 1; } // help beep (no more than three times) if (ent->client->pers.helpchanged && ent->client->pers.helpchanged <= 3 && !(level.framenum&63) ) { ent->client->pers.helpchanged++; gi.sound (ent, CHAN_VOICE, gi.soundindex ("misc/pc_up.wav"), 1, ATTN_STATIC, 0); safe_centerprintf (ent, "Journal Entry - Press F1"); } if (ent->client->pers.weapon) weap = ent->client->pers.weapon->classname; else weap = ""; if (strcmp(weap, "weapon_bfg") == 0) ent->s.sound = gi.soundindex("weapons/vaporizer_hum.wav"); else if (strcmp(weap, "weapon_shotgun") == 0) ent->s.sound = gi.soundindex("weapons/smartgun_hum.wav"); else if (ent->client->weapon_sound) ent->s.sound = ent->client->weapon_sound; else ent->s.sound = 0; } /* =============== G_SetClientFrame =============== */ void G_SetClientFrame (edict_t *ent) { gclient_t *client; qboolean duck, run; //vehicles if (ent->in_vehicle) { //don't animate the vehicle(yet!) ent->s.frame = 0; return; } if (ent->s.modelindex != 255) return; // not in the player model client = ent->client; if (client->ps.pmove.pm_flags & PMF_DUCKED) duck = true; else duck = false; if (xyspeed) run = true; else run = false; // check for stand/duck and stop/go transitions if (duck != client->anim_duck && client->anim_priority < ANIM_DEATH) goto newanim; if (run != client->anim_run && client->anim_priority == ANIM_BASIC) goto newanim; if (!ent->groundentity && client->anim_priority <= ANIM_WAVE) goto newanim; //check for running while shooting if (run && client->anim_priority == ANIM_ATTACK) goto newanim; if(client->anim_priority == ANIM_REVERSE) { if(ent->s.frame > client->anim_end) { ent->s.frame--; return; } } else if (ent->s.frame < client->anim_end) { // continue an animation ent->s.frame++; return; } if (client->anim_priority == ANIM_DEATH) return; // stay there if (client->anim_priority == ANIM_JUMP) { if (!ent->groundentity) return; // stay there ent->client->anim_priority = ANIM_WAVE; ent->s.frame = FRAME_jump3; ent->client->anim_end = FRAME_jump6; return; } newanim: // return to either a running or standing frame client->anim_priority = ANIM_BASIC; client->anim_duck = duck; client->anim_run = run; if (!ent->groundentity) { //ZOID: if on grapple, don't go into jump frame, go into standing //frame if (client->ctf_grapple) { ent->s.frame = FRAME_stand01; client->anim_end = FRAME_stand40; } else { //ZOID client->anim_priority = ANIM_JUMP; if (ent->s.frame != FRAME_jump2) ent->s.frame = FRAME_jump1; client->anim_end = FRAME_jump2; } } else if (run) { // running if (duck) { ent->s.frame = FRAME_crwalk1; client->anim_end = FRAME_crwalk6; } else { ent->s.frame = FRAME_run1; client->anim_end = FRAME_run6; } } else { // standing if (duck) { ent->s.frame = FRAME_crstnd01; client->anim_end = FRAME_crstnd19; } else { ent->s.frame = FRAME_stand01; client->anim_end = FRAME_stand40; } } } /* ================= ClientEndServerFrame Called for each player at the end of the server frame and right after spawning ================= */ void ClientEndServerFrame (edict_t *ent) { float bobtime; int i; current_player = ent; current_client = ent->client; if (ent->client->chase_target != NULL && ent->client->resp.spectator != 0) { ent->redirect_number = ent->client->chase_target->s.number; // This isn't needed to make spectators follow the chase target // around; the server code does that already. This is so that when you // un-follow someone, you're dropped off right where they were. Due to // the weird way bots are done, there's no easy way to copy view // angles over. VectorCopy (ent->client->chase_target->s.origin, ent->s.origin); ent->s.origin[2] += 24; // a little above the target } else ent->redirect_number = ent->s.number; // // If the origin or velocity have changed since ClientThink(), // update the pmove values. This will happen when the client // is pushed by a bmodel or kicked by an explosion. // // If it wasn't updated here, the view position would lag a frame // behind the body position when pushed -- "sinking into plats" // for (i=0 ; i<3 ; i++) { current_client->ps.pmove.origin[i] = ent->s.origin[i]*8.0; current_client->ps.pmove.velocity[i] = ent->velocity[i]*8.0; } // // If the end of unit layout is displayed, don't give // the player any normal movement attributes // if (level.intermissiontime) { current_client->ps.blend[3] = 0; current_client->ps.fov = 90; G_UpdateStats (ent); return; } AngleVectors (ent->client->v_angle, forward, right, up); // burn from lava, etc P_WorldEffects (); // // set model angles from view angles so other things in // the world can tell which direction you are looking // if (ent->client->v_angle[PITCH] > 180) ent->s.angles[PITCH] = (-360 + ent->client->v_angle[PITCH])/3; else ent->s.angles[PITCH] = ent->client->v_angle[PITCH]/3; ent->s.angles[YAW] = ent->client->v_angle[YAW]; ent->s.angles[ROLL] = 0; ent->s.angles[ROLL] = SV_CalcRoll (ent->s.angles, ent->velocity)*4; // // calculate speed and cycle to be used for // all cyclic walking effects // xyspeed = sqrt(ent->velocity[0]*ent->velocity[0] + ent->velocity[1]*ent->velocity[1]); if (xyspeed < 5 || !ent->groundentity) { bobmove = 0; current_client->bobtime = 0; // start at beginning of cycle again } else { // so bobbing only cycles when on ground if (xyspeed > 210) bobmove = 0.25; else if (xyspeed > 100) bobmove = 0.125; else bobmove = 0.0625; } bobtime = (current_client->bobtime += bobmove); if (current_client->ps.pmove.pm_flags & PMF_DUCKED) bobtime *= 4; bobcycle = (int)bobtime; bobfracsin = fabs(sin(bobtime*M_PI)); // detect hitting the floor P_FallingDamage (ent); // apply all the damage taken this frame P_DamageFeedback (ent); // determine the view offsets SV_CalcViewOffset (ent); // determine the gun offsets SV_CalcGunOffset (ent); // determine the full screen color blend // must be after viewoffset, so eye contents can be // accurately determined // FIXME: with client prediction, the contents // should be determined by the client SV_CalcBlend (ent); G_UpdateStats (ent); G_SetClientEvent (ent); G_SetClientEffects (ent); G_SetClientSound (ent); G_SetClientFrame (ent); VectorCopy (ent->velocity, ent->client->oldvelocity); VectorCopy (ent->client->ps.viewangles, ent->client->oldviewangles); // clear weapon kicks VectorClear (ent->client->kick_origin); VectorClear (ent->client->kick_angles); // if the scoreboard is up, update it if (ent->client->showscores && !(level.framenum & 31) ) { if (ent->is_bot) return; DeathmatchScoreboardMessage (ent, ent->enemy, false); gi.unicast (ent, false); } if (ent->client->chasetoggle == 1) CheckDeathcam_Viewent(ent); if ( g_antilag->integer) G_StoreHistory( ent ); } alien-arena-7.66+dfsg/source/game/g_items.c0000600000175000017500000014225112161402010017613 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" qboolean Pickup_Weapon (edict_t *ent, edict_t *other); void Use_Weapon (edict_t *ent, gitem_t *inv); void Drop_Weapon (edict_t *ent, gitem_t *inv); #ifdef ALTERIA void Weapon_Punch ( edict_t *ent); #else void Weapon_Blaster (edict_t *ent); void Weapon_AlienBlaster (edict_t *ent); void Weapon_Violator (edict_t *ent); void Weapon_Smartgun (edict_t *ent); void Weapon_Chain (edict_t *ent); void Weapon_Flame (edict_t *ent); void Weapon_Disruptor (edict_t *ent); void Weapon_RocketLauncher (edict_t *ent); void Weapon_Beamgun (edict_t *ent); void Weapon_Vaporizer (edict_t *ent); void Weapon_Minderaser (edict_t *ent); void Weapon_Bomber (edict_t *ent); void Weapon_Strafer (edict_t *ent); void Weapon_Deathball (edict_t *ent); void Weapon_Hover (edict_t *ent); void Weapon_TacticalBomb ( edict_t *ent); #endif gitem_armor_t jacketarmor_info = { 25, 50, .30, .00, ARMOR_JACKET}; gitem_armor_t combatarmor_info = { 50, 100, .60, .30, ARMOR_COMBAT}; gitem_armor_t bodyarmor_info = {100, 200, .80, .60, ARMOR_BODY}; static int jacket_armor_index; static int combat_armor_index; static int body_armor_index; #define HEALTH_IGNORE_MAX 1 #define HEALTH_TIMED 2 void Use_Quad (edict_t *ent, gitem_t *item); static int quad_drop_timeout_hack; //====================================================================== /* =============== GetItemByIndex =============== */ gitem_t *GetItemByIndex (int index) { if (index == 0 || index >= game.num_items) return NULL; return &itemlist[index]; } /* =============== FindItemByClassname =============== */ gitem_t *FindItemByClassname (char *classname) { int i; gitem_t *it; it = itemlist; for (i=0 ; iclassname) continue; if (!Q_strcasecmp(it->classname, classname)) return it; } return NULL; } /* =============== FindItem =============== */ gitem_t *FindItem (char *pickup_name) { int i; gitem_t *it; it = itemlist; for (i=0 ; ipickup_name) continue; if (!Q_strcasecmp(it->pickup_name, pickup_name)) return it; } return NULL; } //====================================================================== static void drop_temp_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { if (other == ent->owner) return; Touch_Item (ent, other, plane, surf); } static void drop_make_touchable (edict_t *ent) { ent->touch = Touch_Item; if (deathmatch->integer) { if(!g_tactical->integer) //in tactical mode, we don't remove dropped items { ent->nextthink = level.time + 29; ent->think = G_FreeEdict; } } } float mindEraserTime; void SpawnMinderaser(edict_t *ent) { edict_t *minderaser, *cl_ent; int i; for (i = 0; i < g_maxclients->integer; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || cl_ent->is_bot) continue; safe_centerprintf(cl_ent, "A Mind Eraser has spawned!\n"); } //to do - play level wide klaxxon gi.sound( &g_edicts[1], CHAN_AUTO, gi.soundindex( "misc/minderaser.wav" ), 1, ATTN_NONE, 0 ); minderaser = G_Spawn(); VectorCopy(ent->s.origin, minderaser->s.origin); minderaser->spawnflags = DROPPED_PLAYER_ITEM; minderaser->model = "models/weapons/g_minderaser/tris.md2"; minderaser->classname = "weapon_minderaser"; minderaser->item = FindItem ("Minderaser"); minderaser->s.effects = minderaser->item->world_model_flags; minderaser->s.renderfx = RF_GLOW; VectorSet (minderaser->mins, -15, -15, -15); VectorSet (minderaser->maxs, 15, 15, 15); gi.setmodel (minderaser, minderaser->item->world_model); minderaser->solid = SOLID_TRIGGER; minderaser->health = 100; minderaser->movetype = MOVETYPE_TOSS; minderaser->touch = drop_temp_touch; minderaser->owner = NULL; SetRespawn (ent, 1000000); //huge delay until ME is picked up from pad. minderaser->replaced_weapon = ent; //remember this entity mindEraserTime = level.time; } void DoRespawn (edict_t *ent) { char szTmp[64]; //Add mind eraser spawn here, if it's been two minutes since last respawn of it, //go ahead and set the next weapon spawned to be the mind eraser //need to check if first part of name is weapon if(level.time > mindEraserTime + 120.0) { strcpy(szTmp, ent->classname); szTmp[6] = 0; if(!Q_strcasecmp(szTmp, "weapon")) { SpawnMinderaser(ent); return; } } if (ent->team) { edict_t *master; int count; int choice; master = ent->teammaster; for (count = 0, ent = master; ent; ent = ent->chain, count++) ; choice = rand() % count; for (count = 0, ent = master; count < choice; ent = ent->chain, count++) ; } ent->svflags &= ~SVF_NOCLIENT; ent->solid = SOLID_TRIGGER; gi.linkentity (ent); // send an effect ent->s.event = EV_ITEM_RESPAWN; } void SetRespawn (edict_t *ent, float delay) { if ( ent->item && g_duel->integer && ent->item->weapmodel != WEAP_MINDERASER ) { switch (ent->item->flags) { //TODO: playtest this and adjust the scaling factors. case IT_WEAPON: delay *= 3.0; break; case IT_POWERUP: case IT_AMMO: //intentional fallthrough delay *= 2.0; break; case IT_ARMOR: case IT_HEALTH: //intentional fallthrough delay *= 1.5; break; default: break; } } ent->flags |= FL_RESPAWN; ent->svflags |= SVF_NOCLIENT; ent->solid = SOLID_NOT; ent->nextthink = level.time + delay; ent->think = DoRespawn; gi.linkentity (ent); } //====================================================================== qboolean Pickup_Powerup (edict_t *ent, edict_t *other) { int quantity; quantity = other->client->pers.inventory[ITEM_INDEX(ent->item)]; if ((skill->value == 1 && quantity >= 2) || (skill->value >= 2 && quantity >= 1)) return false; other->client->pers.inventory[ITEM_INDEX(ent->item)]++; if (deathmatch->integer) { int randomSpawn; //Phenax - Add random time to quad spawn if(ent->item->use == Use_Quad && g_randomquad->integer) randomSpawn = 10 + rand() % (30 - 10); //10 to 30 seconds randomness else randomSpawn = 0; if (!(ent->spawnflags & DROPPED_ITEM) ) SetRespawn (ent, ent->item->quantity + randomSpawn); if ((dmflags->integer & DF_INSTANT_ITEMS) || (ent->item->use == Use_Quad && (ent->spawnflags & DROPPED_PLAYER_ITEM))) { if ((ent->item->use == Use_Quad) && (ent->spawnflags & DROPPED_PLAYER_ITEM)) quad_drop_timeout_hack = (ent->nextthink - level.time) / FRAMETIME; ent->item->use (other, ent->item); } } return true; } void Drop_General (edict_t *ent, gitem_t *item) { Drop_Item (ent, item); ent->client->pers.inventory[ITEM_INDEX(item)]--; ValidateSelectedItem (ent); } //====================================================================== qboolean Pickup_Adrenaline (edict_t *ent, edict_t *other) { if (!deathmatch->integer) other->max_health += 1; if (other->health < other->max_health) other->health = other->max_health; if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->integer)) SetRespawn (ent, ent->item->quantity); return true; } //====================================================================== void Use_Quad (edict_t *ent, gitem_t *item) { int timeout; ent->client->pers.inventory[ITEM_INDEX(item)]--; ValidateSelectedItem (ent); if (quad_drop_timeout_hack) { timeout = quad_drop_timeout_hack; quad_drop_timeout_hack = 0; } else { timeout = 300; } if (ent->client->quad_framenum > level.framenum) ent->client->quad_framenum += timeout; else ent->client->quad_framenum = level.framenum + timeout; gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0); } //====================================================================== void Use_Invulnerability (edict_t *ent, gitem_t *item) { ent->client->pers.inventory[ITEM_INDEX(item)]--; ValidateSelectedItem (ent); if (ent->client->invincible_framenum > level.framenum) ent->client->invincible_framenum += 300; else ent->client->invincible_framenum = level.framenum + 300; //add full armor ent->client->pers.inventory[combat_armor_index] = 200; gi.sound(ent, CHAN_ITEM, gi.soundindex("items/protect.wav"), 1, ATTN_NORM, 0); } void Use_Haste (edict_t *ent, gitem_t *item) { gitem_t *it; ent->client->pers.inventory[ITEM_INDEX(item)]--; ValidateSelectedItem (ent); if(ent->client->resp.powered) { it = FindItem("Sproing"); ent->client->pers.inventory[ITEM_INDEX(it)] = 0; it = FindItem("Invisibility"); ent->client->pers.inventory[ITEM_INDEX(it)] = 0; ent->client->resp.reward_pts = 0; ent->client->resp.powered = false; } if (ent->client->haste_framenum > level.framenum) ent->client->haste_framenum += 300; else ent->client->haste_framenum = level.framenum + 300; gi.sound(ent, CHAN_ITEM, gi.soundindex("items/powerup.wav"), 1, ATTN_NORM, 0); } //====================================================================== void Use_Sproing (edict_t *ent, gitem_t *item) { gitem_t *it; ent->client->pers.inventory[ITEM_INDEX(item)]--; ValidateSelectedItem (ent); if(ent->client->resp.powered) { it = FindItem("Invisibility"); ent->client->pers.inventory[ITEM_INDEX(it)] = 0; it = FindItem("Haste"); ent->client->pers.inventory[ITEM_INDEX(it)] = 0; ent->client->resp.reward_pts = 0; ent->client->resp.powered = false; } if (ent->client->sproing_framenum > level.framenum) ent->client->sproing_framenum += 300; else ent->client->sproing_framenum = level.framenum + 300; gi.sound(ent, CHAN_ITEM, gi.soundindex("items/powerup.wav"), 1, ATTN_NORM, 0); } void Use_Invisibility (edict_t *ent, gitem_t *item) { gitem_t *it; ent->client->pers.inventory[ITEM_INDEX(item)]--; ValidateSelectedItem (ent); if(ent->client->resp.powered) { it = FindItem("Sproing"); ent->client->pers.inventory[ITEM_INDEX(it)] = 0; it = FindItem("Haste"); ent->client->pers.inventory[ITEM_INDEX(it)] = 0; ent->client->resp.reward_pts = 0; ent->client->resp.powered = false; } if (ent->client->invis_framenum > level.framenum) ent->client->invis_framenum += 300; else ent->client->invis_framenum = level.framenum + 300; gi.sound(ent, CHAN_ITEM, gi.soundindex("items/powerup.wav"), 1, ATTN_NORM, 0); } //====================================================================== qboolean Pickup_Key (edict_t *ent, edict_t *other) { other->client->pers.inventory[ITEM_INDEX(ent->item)]++; return true; } //====================================================================== qboolean Add_Ammo (edict_t *ent, gitem_t *item, int count, qboolean weapon, qboolean dropped) { int index; int max, base; gitem_t *failedswitch; if (!ent->client) return false; if (item->tag == AMMO_BULLETS) { max = ent->client->pers.max_bullets; base = BASE_BULLETS; } else if (item->tag == AMMO_SHELLS) { max = ent->client->pers.max_shells; base = BASE_SHELLS; } else if (item->tag == AMMO_ROCKETS) { max = ent->client->pers.max_rockets; base = BASE_ROCKETS; } else if (item->tag == AMMO_GRENADES) { max = ent->client->pers.max_grenades; base = BASE_GRENADES; } else if (item->tag == AMMO_CELLS) { max = ent->client->pers.max_cells; base = BASE_CELLS; } else if (item->tag == AMMO_SLUGS) { max = ent->client->pers.max_slugs; base = BASE_SLUGS; } else if (item->tag == AMMO_SEEKERS) { max = ent->client->pers.max_seekers; base = BASE_SEEKERS; } else if (item->tag == AMMO_BOMBS) { max = ent->client->pers.max_bombs; base = BASE_BOMBS; } else return false; index = ITEM_INDEX(item); if (ent->client->pers.inventory[index] == max) return false; if (weapon && !dropped && (ent->client->pers.inventory[index] > 0)) count = 1; //already has weapon -- not dropped. Give him 1 ammo. //if less than base ammo, restock ammo fully if(ent->client->pers.inventory[index] < base) //less than base ammount ent->client->pers.inventory[index] = base; else ent->client->pers.inventory[index] += count; if (ent->client->pers.inventory[index] > max) ent->client->pers.inventory[index] = max; failedswitch = ent->client->pers.lastfailedswitch; if (failedswitch && failedswitch->ammo && (FindItem(failedswitch->ammo) == item) && (level.framenum - ent->client->pers.failedswitch_framenum) < 5) ent->client->newweapon = failedswitch; return true; } qboolean Pickup_Ammo (edict_t *ent, edict_t *other) { int oldcount; int count; qboolean weapon; weapon = (ent->item->flags & IT_WEAPON); if ( weapon && ( dmflags->integer & DF_INFINITE_AMMO ) ) count = 1000; else if (ent->count) count = ent->count; else count = ent->item->quantity; oldcount = other->client->pers.inventory[ITEM_INDEX(ent->item)]; if (!Add_Ammo (other, ent->item, count, false, true)) //Not 'dropped' but give full ammo even if ammo > 0 return false; if (weapon && !oldcount) { if (other->client->pers.weapon != ent->item && ( !deathmatch->integer || other->client->pers.weapon == FindItem("Blaster") || other->client->pers.weapon == FindItem("Alien Blaster")) ) other->client->newweapon = ent->item; } if (!(ent->spawnflags & (DROPPED_ITEM | DROPPED_PLAYER_ITEM)) && (deathmatch->integer)) { if(g_tactical->integer) { if(!strcmp(ent->classname, "ammo_cells") || !strcmp(ent->classname, "ammo_shells")) { if(!tacticalScore.alienPowerSource) { if(tacticalScore.alienBackupGen) SetRespawn (ent, 20); //on backup power, generate ammo much slower else SetRespawn (ent, 40); //for the most part, dead } else SetRespawn (ent, 5); } else if(!strcmp(ent->classname, "ammo_rockets") || !strcmp(ent->classname, "ammo_bullets") || !strcmp(ent->classname, "ammo_grenades")) { if(!tacticalScore.humanPowerSource) { if(tacticalScore.humanBackupGen) SetRespawn (ent, 20); else SetRespawn (ent, 40); } else SetRespawn (ent, 5); } } else SetRespawn (ent, 30); } return true; } void Drop_Ammo (edict_t *ent, gitem_t *item) { edict_t *dropped; int index; index = ITEM_INDEX(item); dropped = Drop_Item (ent, item); if (ent->client->pers.inventory[index] >= item->quantity) dropped->count = item->quantity; else dropped->count = ent->client->pers.inventory[index]; if (ent->client->pers.weapon && ent->client->pers.weapon->tag == AMMO_GRENADES && item->tag == AMMO_GRENADES && ent->client->pers.inventory[index] - dropped->count <= 0) { safe_cprintf (ent, PRINT_HIGH, "Can't drop current weapon\n"); G_FreeEdict(dropped); return; } ent->client->pers.inventory[index] -= dropped->count; ValidateSelectedItem (ent); } //====================================================================== void MegaHealth_think (edict_t *self) { if (self->owner->health > self->owner->max_health) { self->nextthink = level.time + 1; self->owner->health -= 1; return; } if (!(self->spawnflags & DROPPED_ITEM) && (deathmatch->integer)) SetRespawn (self, 20); else G_FreeEdict (self); } void Healthbox_think (edict_t *self) { self->nextthink = level.time + 7; self->s.effects = EF_ROTATE; self->s.renderfx = RF_GLOW; return; } qboolean Pickup_Health (edict_t *ent, edict_t *other) { if (!(ent->style & HEALTH_IGNORE_MAX)) if (other->health >= other->max_health) { ent->s.effects |= EF_ROTATE; ent->think = Healthbox_think; ent->nextthink = level.time + 7; return false; } other->health += ent->count; if (!(ent->style & HEALTH_IGNORE_MAX)) { if (other->health > other->max_health) other->health = other->max_health; } if (ent->style & HEALTH_TIMED) { ent->think = MegaHealth_think; ent->nextthink = level.time + 5; ent->owner = other; ent->flags |= FL_RESPAWN; ent->svflags |= SVF_NOCLIENT; ent->solid = SOLID_NOT; } else { if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->integer)) SetRespawn (ent, 30); } return true; } //====================================================================== int ArmorIndex (edict_t *ent) { if (!ent->client) return 0; if (ent->client->pers.inventory[jacket_armor_index] > 0) return jacket_armor_index; if (ent->client->pers.inventory[combat_armor_index] > 0) return combat_armor_index; if (ent->client->pers.inventory[body_armor_index] > 0) return body_armor_index; return 0; } qboolean Pickup_Armor (edict_t *ent, edict_t *other) { int old_armor_index; gitem_armor_t *oldinfo; gitem_armor_t *newinfo; int newcount; float salvage; int salvagecount; // get info on new armor newinfo = (gitem_armor_t *)ent->item->info; old_armor_index = ArmorIndex (other); // handle armor shards specially if (ent->item->tag == ARMOR_SHARD) { if (!old_armor_index) other->client->pers.inventory[jacket_armor_index] = 5; else other->client->pers.inventory[old_armor_index] += 5; } // if player has no armor, just use it else if (!old_armor_index) { other->client->pers.inventory[ITEM_INDEX(ent->item)] = newinfo->base_count; } // use the better armor else { // get info on old armor if (old_armor_index == jacket_armor_index) oldinfo = &jacketarmor_info; else if (old_armor_index == combat_armor_index) oldinfo = &combatarmor_info; else // (old_armor_index == body_armor_index) oldinfo = &bodyarmor_info; if (newinfo->normal_protection > oldinfo->normal_protection) { // calc new armor values salvage = oldinfo->normal_protection / newinfo->normal_protection; salvagecount = salvage * other->client->pers.inventory[old_armor_index]; newcount = newinfo->base_count + salvagecount; if (newcount > newinfo->max_count) newcount = newinfo->max_count; // zero count of old armor so it goes away other->client->pers.inventory[old_armor_index] = 0; // change armor to new item with computed value other->client->pers.inventory[ITEM_INDEX(ent->item)] = newcount; } else { // calc new armor values salvage = newinfo->normal_protection / oldinfo->normal_protection; salvagecount = salvage * newinfo->base_count; newcount = other->client->pers.inventory[old_armor_index] + salvagecount; if (newcount > oldinfo->max_count) newcount = oldinfo->max_count; // if we're already maxed out then we don't need the new armor if (other->client->pers.inventory[old_armor_index] >= newcount) return false; // update current armor value other->client->pers.inventory[old_armor_index] = newcount; } } if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->integer)) SetRespawn (ent, 20); return true; } //====================================================================== /* =============== Touch_Item =============== */ void Touch_Item (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { qboolean taken; if (!other->client) return; if (other->health < 1) return; // dead people can't pickup if (!ent->item->pickup) return; // not a grabbable item? taken = ent->item->pickup(ent, other); if (taken) { // flash the screen other->client->bonus_alpha = 0.25; // show icon and name on status bar other->client->pickup_msg_time = level.time + 3.0; // change selected item if (ent->item->use) other->client->pers.selected_item = other->client->ps.stats[STAT_SELECTED_ITEM] = ITEM_INDEX(ent->item); if (ent->item->pickup == Pickup_Health) { if (ent->count == 5) gi.sound(other, CHAN_ITEM, gi.soundindex("items/s_health.wav"), 1, ATTN_NORM, 0); else if (ent->count == 10) gi.sound(other, CHAN_ITEM, gi.soundindex("items/n_health.wav"), 1, ATTN_NORM, 0); else if (ent->count == 25) gi.sound(other, CHAN_ITEM, gi.soundindex("items/l_health.wav"), 1, ATTN_NORM, 0); else // (ent->count == 100) gi.sound(other, CHAN_ITEM, gi.soundindex("items/m_health.wav"), 1, ATTN_NORM, 0); } else if (ent->item->pickup_sound) { gi.sound(other, CHAN_ITEM, gi.soundindex(ent->item->pickup_sound), 1, ATTN_NORM, 0); } } if (!(ent->spawnflags & ITEM_TARGETS_USED)) { G_UseTargets (ent, other); ent->spawnflags |= ITEM_TARGETS_USED; } if (!taken) return; if(g_tactical->integer) //items do not respawn in tactical mode(except ammo when ammo depots are running) { if((!strcmp(ent->classname, "ammo_cells") || !strcmp(ent->classname, "ammo_shells")) && tacticalScore.alienAmmoDepot) return; else if((!strcmp(ent->classname, "ammo_rockets") || !strcmp(ent->classname, "ammo_bullets") || !strcmp(ent->classname, "ammo_grenades")) && tacticalScore.humanAmmoDepot) return; G_FreeEdict (ent); return; } if (ent->spawnflags & (DROPPED_ITEM | DROPPED_PLAYER_ITEM)) { if (ent->flags & FL_RESPAWN) ent->flags &= ~FL_RESPAWN; else G_FreeEdict (ent); } } //====================================================================== edict_t *Drop_Item (edict_t *ent, gitem_t *item) { edict_t *dropped; vec3_t forward, right; vec3_t offset; dropped = G_Spawn(); dropped->classname = item->classname; dropped->item = item; dropped->spawnflags = DROPPED_ITEM; dropped->s.effects = item->world_model_flags; dropped->s.renderfx = RF_GLOW; VectorSet (dropped->mins, -15, -15, -15); VectorSet (dropped->maxs, 15, 15, 15); gi.setmodel (dropped, dropped->item->world_model); if(!strcmp(item->classname, "item_bomber")) dropped->s.modelindex3 = gi.modelindex("vehicles/bomber/helmet.md2"); dropped->solid = SOLID_TRIGGER; dropped->movetype = MOVETYPE_TOSS; dropped->touch = drop_temp_touch; dropped->owner = ent; if (ent->client) { trace_t trace; AngleVectors (ent->client->v_angle, forward, right, NULL); VectorSet(offset, 24, 0, -16); G_ProjectSource (ent->s.origin, offset, forward, right, dropped->s.origin); trace = gi.trace (ent->s.origin, dropped->mins, dropped->maxs, dropped->s.origin, ent, CONTENTS_SOLID); VectorCopy (trace.endpos, dropped->s.origin); } else { AngleVectors (ent->s.angles, forward, right, NULL); VectorCopy (ent->s.origin, dropped->s.origin); } VectorScale (forward, 100, dropped->velocity); dropped->velocity[2] = 300; dropped->think = drop_make_touchable; dropped->nextthink = level.time + 1; gi.linkentity (dropped); return dropped; } void Use_Item (edict_t *ent, edict_t *other, edict_t *activator) { ent->svflags &= ~SVF_NOCLIENT; ent->use = NULL; if (ent->spawnflags & ITEM_NO_TOUCH) { ent->solid = SOLID_BBOX; ent->touch = NULL; } else { ent->solid = SOLID_TRIGGER; ent->touch = Touch_Item; } gi.linkentity (ent); } //====================================================================== /* ================ droptofloor ================ */ void droptofloor (edict_t *ent) { trace_t tr; vec3_t dest; float *v; v = tv(-15,-15,-15); VectorCopy (v, ent->mins); v = tv(15,15,15); VectorCopy (v, ent->maxs); if (ent->model) gi.setmodel (ent, ent->model); else gi.setmodel (ent, ent->item->world_model); ent->solid = SOLID_TRIGGER; ent->movetype = MOVETYPE_TOSS; ent->touch = Touch_Item; v = tv(0,0,-128); VectorAdd (ent->s.origin, v, dest); tr = gi.trace (ent->s.origin, ent->mins, ent->maxs, dest, ent, MASK_SOLID); if (tr.startsolid) { gi.dprintf ("droptofloor: %s startsolid at %s\n", ent->classname, vtos(ent->s.origin)); G_FreeEdict (ent); return; } VectorCopy (tr.endpos, ent->s.origin); if (ent->team) { ent->flags &= ~FL_TEAMSLAVE; ent->chain = ent->teamchain; ent->teamchain = NULL; ent->svflags |= SVF_NOCLIENT; ent->solid = SOLID_NOT; if (ent == ent->teammaster) { ent->nextthink = level.time + FRAMETIME; ent->think = DoRespawn; } } if (ent->spawnflags & ITEM_NO_TOUCH) { ent->solid = SOLID_BBOX; ent->touch = NULL; ent->s.effects &= ~EF_ROTATE; ent->s.renderfx &= ~RF_GLOW; } if (ent->spawnflags & ITEM_TRIGGER_SPAWN) { ent->svflags |= SVF_NOCLIENT; ent->solid = SOLID_NOT; ent->use = Use_Item; } gi.linkentity (ent); } /* =============== PrecacheItem Precaches all data needed for a given item. This will be called for each item spawned in a level, and for each item in each client's inventory. =============== */ void PrecacheItem (gitem_t *it) { char *s, *start; char data[MAX_QPATH]; int len; gitem_t *ammo; if (!it) return; if (it->pickup_sound) gi.soundindex (it->pickup_sound); if (it->world_model) gi.modelindex (it->world_model); if (it->view_model) gi.modelindex (it->view_model); if (it->icon) gi.imageindex (it->icon); // parse everything for its ammo if (it->ammo && it->ammo[0]) { ammo = FindItem (it->ammo); if (ammo != it) PrecacheItem (ammo); } // parse the space seperated precache string for other items s = it->precaches; if (!s || !s[0]) return; while (*s) { start = s; while (*s && *s != ' ') s++; len = s-start; if (len >= MAX_QPATH || len < 5) gi.error ("PrecacheItem: %s has bad precache string", it->classname); memcpy (data, start, len); data[len] = 0; if (*s) s++; // determine type based on extension if (!strcmp(data+len-3, "md2")) gi.modelindex (data); else if (!strcmp(data+len-3, "sp2")) gi.modelindex (data); else if (!strcmp(data+len-3, "wav")) gi.soundindex (data); if (!strcmp(data+len-3, "pcx")) gi.imageindex (data); } } /* ============ SpawnItem Sets the clipping size and plants the object on the floor. Items can't be immediately dropped to floor, because they might be on an entity that hasn't spawned yet. ============ */ void SpawnItem (edict_t *ent, gitem_t *item) { PrecacheItem (item); if (ent->spawnflags) { if (strcmp(ent->classname, "key_power_cube") != 0) { ent->spawnflags = 0; gi.dprintf("%s at %s has invalid spawnflags set\n", ent->classname, vtos(ent->s.origin)); } } // some items will be prevented in deathmatch if (deathmatch->integer) { if ( dmflags->integer & DF_NO_ARMOR ) { if (item->pickup == Pickup_Armor) { G_FreeEdict (ent); return; } } if ( dmflags->integer & DF_NO_ITEMS ) { if (item->pickup == Pickup_Powerup) { G_FreeEdict (ent); return; } } if ( dmflags->integer & DF_NO_HEALTH ) { if (item->pickup == Pickup_Health || item->pickup == Pickup_Adrenaline) { G_FreeEdict (ent); return; } } if ( dmflags->integer & DF_INFINITE_AMMO ) { if ( (item->flags == IT_AMMO) || (strcmp(ent->classname, "weapon_bfg") == 0) ) { G_FreeEdict (ent); return; } } if(excessive->integer || instagib->integer || rocket_arena->integer || insta_rockets->integer ) { if (item->flags == IT_AMMO || (strcmp(ent->classname, "weapon_bfg") == 0) || (strcmp(ent->classname, "weapon_hyperblaster") == 0) || (strcmp(ent->classname, "weapon_railgun") == 0) || (strcmp(ent->classname, "weapon_rocketlauncher") == 0) || (strcmp(ent->classname, "weapon_grenadelauncher") == 0) || (strcmp(ent->classname, "weapon_chaingun") == 0) || (strcmp(ent->classname, "weapon_supershotgun") == 0) || (strcmp(ent->classname, "weapon_shotgun") == 0)) { G_FreeEdict (ent); return; } } } //CTF //Don't spawn the flags unless enabled if (!ctf->integer && (strcmp(ent->classname, "item_flag_red") == 0 || strcmp(ent->classname, "item_flag_blue") == 0)) { G_FreeEdict(ent); return; } ent->item = item; ent->nextthink = level.time + 2 * FRAMETIME; // items start after other solids ent->think = droptofloor; if (strcmp(ent->classname, "item_flag_red") && //flags are special and don't get this strcmp(ent->classname, "item_flag_blue")) { ent->s.effects = EF_ROTATE; } ent->s.renderfx = RF_GLOW; if((strcmp(ent->classname, "Health") == 0)) { ent->s.modelindex2 = gi.modelindex("models/items/healing/globe/tris.md2"); } else if((strcmp(ent->classname, "item_quad") == 0)) { ent->s.modelindex2 = gi.modelindex("models/items/quaddama/unit.md2"); } if (ent->model) gi.modelindex (ent->model); //flags are server animated and have special handling if (strcmp(ent->classname, "item_flag_red") == 0 || strcmp(ent->classname, "item_flag_blue") == 0) { ent->think = CTFFlagSetup; } //vehicles have special handling if((strcmp(ent->classname, "item_bomber") == 0) || (strcmp(ent->classname, "item_strafer") == 0) || (strcmp(ent->classname, "item_hover") == 0)) ent->think = VehicleSetup; //ditto for deathball if(strcmp(ent->classname, "item_deathball") == 0) ent->think = DeathballSetup; } //====================================================================== gitem_t itemlist[] = { { NULL }, // leave index 0 alone // // ARMOR // /*QUAKED item_armor_body (.3 .3 1) (-16 -16 -16) (16 16 16) */ { "item_armor_body", Pickup_Armor, NULL, NULL, NULL, "misc/ar1_pkup.wav", "models/items/armor/body/tris.md2", EF_ROTATE, NULL, /* icon */ "i_bodyarmor", /* pickup */ "Body Armor", /* width */ 3, 0, NULL, IT_ARMOR, 0, &bodyarmor_info, ARMOR_BODY, /* precache */ "" }, /*QUAKED item_armor_combat (.3 .3 1) (-16 -16 -16) (16 16 16) */ { "item_armor_combat", Pickup_Armor, NULL, NULL, NULL, "misc/ar1_pkup.wav", "models/items/armor/combat/tris.md2", EF_ROTATE, NULL, /* icon */ "i_combatarmor", /* pickup */ "Combat Armor", /* width */ 3, 0, NULL, IT_ARMOR, 0, &combatarmor_info, ARMOR_COMBAT, /* precache */ "" }, /*QUAKED item_armor_jacket (.3 .3 1) (-16 -16 -16) (16 16 16) */ { "item_armor_jacket", Pickup_Armor, NULL, NULL, NULL, "misc/ar1_pkup.wav", "models/items/armor/jacket/tris.md2", EF_ROTATE, NULL, /* icon */ "i_jacketarmor", /* pickup */ "Jacket Armor", /* width */ 3, 0, NULL, IT_ARMOR, 0, &jacketarmor_info, ARMOR_JACKET, /* precache */ "" }, /*QUAKED item_armor_shard (.3 .3 1) (-16 -16 -16) (16 16 16) */ { "item_armor_shard", Pickup_Armor, NULL, NULL, NULL, "misc/ar2_pkup.wav", "models/items/armor/shard/tris.md2", EF_ROTATE, NULL, /* icon */ "i_jacketarmor", /* pickup */ "Armor Shard", /* width */ 3, 0, NULL, IT_ARMOR, 0, NULL, ARMOR_SHARD, /* precache */ "" }, //CTF /*QUAKED item_flag_team1 (1 0.2 0) (-16 -16 -24) (16 16 32) */ { "item_flag_red", CTFPickup_Flag, NULL, CTFDrop_Flag, //Should this be null if we don't want players to drop it manually? NULL, NULL, "models/items/flags/flag1.md2", EF_TEAM1, NULL, /* icon */ "i_flag1", /* pickup */ "Red Flag", /* width */ 2, 0, NULL, 0, 0, NULL, 0, /* precache */ "misc/red_scores.wav misc/red_takes.wav misc/red_increases.wav misc/red_wins.wav misc/scores_tied.wav misc/red_picked.wav" }, /*QUAKED item_flag_team2 (1 0.2 0) (-16 -16 -24) (16 16 32) */ { "item_flag_blue", CTFPickup_Flag, NULL, CTFDrop_Flag, //Should this be null if we don't want players to drop it manually? NULL, NULL, "models/items/flags/flag2.md2", EF_TEAM2, NULL, /* icon */ "i_flag2", /* pickup */ "Blue Flag", /* width */ 2, 0, NULL, 0, 0, NULL, 0, /* precache */ "misc/blue_scores.wav misc/blue_takes.wav misc/blue_increases.wav misc/blue_wins.wav misc/blue_picked.wav" }, #ifndef ALTERIA /*QUAKED item_bomber (1 0.2 0) (-16 -16 -24) (16 16 32) */ { "item_bomber", Get_in_vehicle, NULL, Leave_vehicle, Weapon_Bomber, NULL, "vehicles/bomber/tris.md2", 0, "vehicles/bomber/v_wep.md2", /* icon */ "bomber", /* pickup */ "Bomber", 0, 0, NULL, IT_WEAPON, WEAP_BOMBER, NULL, 0, NULL }, /*QUAKED item_stafer (1 0.2 0) (-16 -16 -24) (16 16 32) */ { "item_strafer", Get_in_vehicle, NULL, Leave_vehicle, Weapon_Strafer, NULL, "vehicles/strafer/tris.md2", 0, "vehicles/strafer/v_wep.md2", /* icon */ "strafer", /* pickup */ "Strafer", 0, 0, NULL, IT_WEAPON, WEAP_STRAFER, NULL, 0, NULL }, /*QUAKED item_hover (1 0.2 0) (-16 -16 -24) (16 16 32) */ { "item_hover", Get_in_vehicle, NULL, Leave_vehicle, Weapon_Hover, NULL, "vehicles/hover/tris.md2", 0, "vehicles/hover/v_wep.md2", /* icon */ "hover", /* pickup */ "Hover", 0, 0, NULL, IT_WEAPON, WEAP_HOVER, NULL, 0, NULL }, //Tactical bombs { "item_alien_bomb", NULL, //Pickup_alienBomb, //only owner will be able to pick this item back up Use_Weapon, NULL, Weapon_TacticalBomb, //fire out bomb, not too far, like prox mines NULL, "models/tactical/alien_bomb.iqm", 0, "vehicles/deathball/v_wep.md2", //will use db's vweap for bombs and detonators /* icon */ "abomb", /* pickup */ "Alien Bomb", 0, 1, "bombs", IT_WEAPON, WEAP_ABOMB, NULL, 0, NULL }, { "item_human_bomb", NULL, //Pickup_humanBomb, //only owner will be able to pick this item back up Use_Weapon, NULL, Weapon_TacticalBomb, //fire out bomb, not too far, like prox mines NULL, "models/tactical/human_bomb.iqm", 0, "vehicles/deathball/v_wep.md2", //will use db's vweap for bombs and detonators /* icon */ "abomb", /* pickup */ "Human Bomb", 0, 1, "bombs", IT_WEAPON, WEAP_HBOMB, NULL, 0, NULL }, /*QUAKED item_deathball (1 0.2 0) (-16 -16 -24) (16 16 32) */ { "item_deathball", Pickup_deathball, NULL, DeathballDrop, Weapon_Deathball, NULL, "vehicles/deathball/deathball.md2", 0, "vehicles/deathball/v_wep.md2", /* icon */ "grapple", /* pickup */ "Deathball", 0, 0, NULL, IT_WEAPON, WEAP_DEATHBALL, NULL, 0, NULL }, //a fake item for bots to use as a target for throwing a deathball at. { "item_dbtarget", NULL, NULL, NULL, NULL, NULL, "models/objects/blank/tris.md2", 0, NULL, NULL, NULL, 0, 0, NULL, IT_POWERUP, WEAP_DEATHBALL, NULL, 0, NULL }, { "item_red_dbtarget", NULL, NULL, NULL, NULL, NULL, "models/objects/blank/tris.md2", 0, NULL, NULL, NULL, 0, 0, NULL, IT_POWERUP, WEAP_DEATHBALL, NULL, 0, NULL }, { "item_blue_dbtarget", NULL, NULL, NULL, NULL, NULL, "models/objects/blank/tris.md2", 0, NULL, NULL, NULL, 0, 0, NULL, IT_POWERUP, WEAP_DEATHBALL, NULL, 0, NULL }, #endif // // WEAPONS // /* weapon_grapple (.3 .3 1) (-16 -16 -16) (16 16 16) always owned, never in the world */ { "weapon_grapple", NULL, Use_Weapon, NULL, CTFWeapon_Grapple, "misc/w_pkup.wav", NULL, 0, "models/weapons/v_machn/tris.md2", /* icon */ "grapple", /* pickup */ "Grapple", 0, 0, NULL, IT_WEAPON, WEAP_GRAPPLE, NULL, 0, /* precache */ "weapons/electroball.wav" }, #ifdef ALTERIA //note some of this is clearly temporary placeholder { "weapon_warrior_punch", NULL, Use_Weapon, NULL, Weapon_Punch, "misc/w_pkup.wav", NULL, 0, "models/weapons/v_warriorhands/tris.md2", /* icon */ "warriorpunch", /* pickup */ "Warriorpunch", 0, 0, NULL, IT_WEAPON, WEAP_VIOLATOR, NULL, 0, /* precache */ "weapons/viofire1.wav weapons/viofire2.wav" }, { "weapon_wizard_punch", NULL, Use_Weapon, NULL, Weapon_Punch, "misc/w_pkup.wav", NULL, 0, "models/weapons/v_wizardhands/tris.md2", /* icon */ "wizardpunch", /* pickup */ "Wizardpunch", 0, 0, NULL, IT_WEAPON, WEAP_VIOLATOR, NULL, 0, /* precache */ "weapons/viofire1.wav weapons/viofire2.wav" }, #else /* weapon_blaster (.3 .3 1) (-16 -16 -16) (16 16 16) always owned, never in the world */ { "weapon_blaster", NULL, Use_Weapon, NULL, Weapon_Blaster, "misc/w_pkup.wav", NULL, 0, "models/weapons/v_blast/tris.md2", /* icon */ "blaster", /* pickup */ "Blaster", 0, 0, NULL, IT_WEAPON, WEAP_BLASTER, NULL, 0, /* precache */ "weapons/blastf1a.wav misc/lasfly.wav" }, /* weapon_blaster (.3 .3 1) (-16 -16 -16) (16 16 16) always owned, never in the world */ { "weapon_alienblaster", NULL, Use_Weapon, NULL, Weapon_AlienBlaster, "misc/w_pkup.wav", NULL, 0, "models/weapons/v_alienblast/tris.md2", /* icon */ "alienblaster", /* pickup */ "Alien Blaster", 0, 0, NULL, IT_WEAPON, WEAP_BLASTER, NULL, 0, /* precache */ "weapons/blastf1a.wav misc/lasfly.wav" //to do tactical - change sound }, { "weapon_violator", NULL, Use_Weapon, NULL, Weapon_Violator, "misc/w_pkup.wav", NULL, 0, "models/weapons/v_violator/tris.md2", /* icon */ "violator", /* pickup */ "Violator", 0, 0, NULL, IT_WEAPON, WEAP_VIOLATOR, NULL, 0, /* precache */ "weapons/viofire1.wav weapons/viofire2.wav" }, /*QUAKED weapon_shotgun (.3 .3 1) (-16 -16 -16) (16 16 16) */ { "weapon_shotgun", Pickup_Weapon, Use_Weapon, Drop_Weapon, Weapon_Smartgun, "misc/w_pkup.wav", "models/weapons/g_shotg/tris.md2", EF_ROTATE, "models/weapons/v_shotg/tris.md2", /* icon */ "smartgun", /* pickup */ "Alien Smartgun", 0, 1, "Alien Smart Grenade", IT_WEAPON, WEAP_SMARTGUN, NULL, 0, /* precache */ "weapons/clank.wav weapons/shotgf1b.wav weapons/smartgun_hum.wav" }, /*QUAKED weapon_supershotgun (.3 .3 1) (-16 -16 -16) (16 16 16) */ { "weapon_supershotgun", Pickup_Weapon, Use_Weapon, Drop_Weapon, Weapon_Chain, "misc/w_pkup.wav", "models/weapons/g_shotg2/tris.md2", EF_ROTATE, "models/weapons/v_shotg2/tris.md2", /* icon */ "chaingun", /* pickup */ "Pulse Rifle", 0, 2, "Bullets", IT_WEAPON, WEAP_CHAINGUN, NULL, 0, /* precache */ "weapons/machgf1b.wav weapons/machgf2b.wav weapons/machgf3b.wav weapons/machgf4b.wav" }, /*QUAKED weapon_chaingun (.3 .3 1) (-16 -16 -16) (16 16 16) */ { "weapon_chaingun", Pickup_Weapon, Use_Weapon, Drop_Weapon, Weapon_Flame, "misc/w_pkup.wav", "models/weapons/g_chain/tris.md2", EF_ROTATE, "models/weapons/v_chain/tris.md2", /* icon */ "flamethrower", /* pickup */ "Flame Thrower", 0, 1, "Napalm", IT_WEAPON, WEAP_FLAMETHROWER, NULL, 0, /* precache */ "weapons/grenlb1b.wav weapons/grenlf1a.wav" }, /*QUAKED weapon_rocketlauncher (.3 .3 1) (-16 -16 -16) (16 16 16) */ { "weapon_rocketlauncher", Pickup_Weapon, Use_Weapon, Drop_Weapon, Weapon_RocketLauncher, "misc/w_pkup.wav", "models/weapons/g_rocket/tris.md2", EF_ROTATE, "models/weapons/v_rocket/tris.md2", /* icon */ "rocketlauncher", /* pickup */ "Rocket Launcher", 0, 1, "Rockets", IT_WEAPON, WEAP_ROCKETLAUNCHER, NULL, 0, /* precache */ "models/objects/rocket/tris.md2 weapons/rockfly.wav weapons/rocklf1a.wav models/objects/debris2/tris.md2" }, /*QUAKED weapon_hyperblaster (.3 .3 1) (-16 -16 -16) (16 16 16) */ { "weapon_hyperblaster", Pickup_Weapon, Use_Weapon, Drop_Weapon, Weapon_Disruptor, "misc/w_pkup.wav", "models/weapons/g_hyperb/tris.md2", EF_ROTATE, "models/weapons/v_hyperb/tris.md2", /* icon */ "disruptor", /* pickup */ "Alien Disruptor", 0, 1, "Cells", IT_WEAPON, WEAP_DISRUPTOR, NULL, 0, /* precache */ "weapons/railgf1a.wav" }, /*QUAKED weapon_railgun (.3 .3 1) (-16 -16 -16) (16 16 16) */ { "weapon_railgun", Pickup_Weapon, Use_Weapon, Drop_Weapon, Weapon_Beamgun, "misc/w_pkup.wav", "models/weapons/g_rail/tris.md2", EF_ROTATE, "models/weapons/v_rail/tris.md2", /* icon */ "beamgun", /* pickup */ "Disruptor", 0, 1, "Cells", IT_WEAPON, WEAP_BEAMGUN, NULL, 0, /* precache */ "weapons/hyprbf1a.wav" }, /*QUAKED weapon_bfg (.3 .3 1) (-16 -16 -16) (16 16 16) */ { "weapon_bfg", Pickup_Weapon, Use_Weapon, Drop_Weapon, Weapon_Vaporizer, "misc/w_pkup.wav", "models/weapons/g_bfg/tris.md2", EF_ROTATE, "models/weapons/v_bfg/tris.md2", /* icon */ "vaporizor", /* pickup */ "Alien Vaporizer", 0, 1, "Slugs", IT_WEAPON, WEAP_VAPORIZER, NULL, 0, /* precache */ "weapons/energyfield.wav smallmech/sight.wav weapons/vaporizer_hum.wav" }, { "weapon_minderaser", Pickup_Weapon, Use_Weapon, NULL, //never drop Weapon_Minderaser, "misc/w_pkup.wav", "models/weapons/g_minderaser/tris.md2", EF_ROTATE, "models/weapons/v_minderaser/tris.md2", /* icon */ "minderaser", /* pickup */ "Minderaser", 0, 1, "Seekers", IT_WEAPON, WEAP_MINDERASER, NULL, 0, /* precache */ "weapons/clank.wav weapons/minderaserfire.wav weapons/shotgf1b.wav weapons/smartgun_hum.wav" }, #endif // // AMMO ITEMS // /*QUAKED ammo_shells (.3 .3 1) (-16 -16 -16) (16 16 16) */ { "ammo_shells", Pickup_Ammo, NULL, Drop_Ammo, NULL, "misc/am_pkup.wav", "models/items/ammo/shells/medium/tris.md2", 0, NULL, /* icon */ "a_shells", /* pickup */ "Alien Smart Grenade", /* width */ 3, 10, NULL, IT_AMMO, 0, NULL, AMMO_SHELLS, /* precache */ "" }, /*QUAKED ammo_shells (.3 .3 1) (-16 -16 -16) (16 16 16) */ { "ammo_grenades", Pickup_Ammo, NULL, Drop_Ammo, NULL, "misc/am_pkup.wav", "models/items/ammo/grenades/medium/tris.md2", 0, NULL, /* icon */ "a_grenades", /* pickup */ "Napalm", /* width */ 3, 50, NULL, IT_AMMO, 0, NULL, AMMO_GRENADES, /* precache */ "" }, /*QUAKED ammo_bullets (.3 .3 1) (-16 -16 -16) (16 16 16) */ { "ammo_bullets", Pickup_Ammo, NULL, Drop_Ammo, NULL, "misc/am_pkup.wav", "models/items/ammo/bullets/medium/tris.md2", 0, NULL, /* icon */ "a_bullets", /* pickup */ "Bullets", /* width */ 3, 50, NULL, IT_AMMO, 0, NULL, AMMO_BULLETS, /* precache */ "" }, /*QUAKED ammo_cells (.3 .3 1) (-16 -16 -16) (16 16 16) */ { "ammo_cells", Pickup_Ammo, NULL, Drop_Ammo, NULL, "misc/am_pkup.wav", "models/items/ammo/cells/medium/tris.md2", 0, NULL, /* icon */ "a_cells", /* pickup */ "Cells", /* width */ 3, 50, NULL, IT_AMMO, 0, NULL, AMMO_CELLS, /* precache */ "" }, /*QUAKED ammo_rockets (.3 .3 1) (-16 -16 -16) (16 16 16) */ { "ammo_rockets", Pickup_Ammo, NULL, Drop_Ammo, NULL, "misc/am_pkup.wav", "models/items/ammo/rockets/medium/tris.md2", 0, NULL, /* icon */ "a_rockets", /* pickup */ "Rockets", /* width */ 3, 5, NULL, IT_AMMO, 0, NULL, AMMO_ROCKETS, /* precache */ "" }, /*QUAKED ammo_slugs (.3 .3 1) (-16 -16 -16) (16 16 16) */ { "ammo_slugs", Pickup_Ammo, NULL, Drop_Ammo, NULL, "misc/am_pkup.wav", NULL, 0, NULL, /* icon */ "a_slugs", /* pickup */ "Slugs", /* width */ 3, 10, NULL, IT_AMMO, 0, NULL, AMMO_SLUGS, /* precache */ "" }, { "ammo_seekers", Pickup_Ammo, //set to null NULL, Drop_Ammo, //set to null NULL, "misc/am_pkup.wav", NULL, 0, NULL, /* icon */ "a_seekers", /* pickup */ "Seekers", /* width */ 3, 1, NULL, IT_AMMO, 0, NULL, AMMO_SEEKERS, /* precache */ "" }, { "ammo_bombs", Pickup_Ammo, //set to null NULL, Drop_Ammo, //set to null NULL, "misc/am_pkup.wav", NULL, 0, NULL, /* icon */ "a_bombs", /* pickup */ "Bombs", /* width */ 3, 1, NULL, IT_AMMO, 0, NULL, AMMO_BOMBS, /* precache */ "" }, // // POWERUP ITEMS // /*QUAKED item_quad (.3 .3 1) (-16 -16 -16) (16 16 16) */ { "item_quad", Pickup_Powerup, Use_Quad, Drop_General, NULL, "items/powerup.wav", "models/items/quaddama/tris.md2", EF_ROTATE, NULL, /* icon */ "p_quad", /* pickup */ "Double Damage", //now double damage, rather than quad /* width */ 2, 150, NULL, IT_POWERUP, 0, NULL, 0, /* precache */ "items/damage.wav items/damage2.wav items/damage3.wav" }, /*QUAKED item_invulnerability (.3 .3 1) (-16 -16 -16) (16 16 16) */ { "item_invulnerability", Pickup_Powerup, Use_Invulnerability, Drop_General, NULL, "items/powerup.wav", "models/items/invulner/tris.md2", EF_ROTATE, NULL, /* icon */ "p_invulnerability", /* pickup */ "Alien Force", //now "Alien Force" - Damage reduced to 1/3, max armor added /* width */ 2, 300, NULL, IT_POWERUP, 0, NULL, 0, /* precache */ "items/protect.wav items/protect2.wav items/protect4.wav" }, /*QUAKED item_adrenaline (.3 .3 1) (-16 -16 -16) (16 16 16) gives +1 to maximum health */ { "item_adrenaline", Pickup_Adrenaline, NULL, NULL, NULL, "items/n_health.wav", "models/items/adrenaline/tris.md2", EF_ROTATE, NULL, /* icon */ "p_adrenaline", /* pickup */ "Adrenaline", /* width */ 2, 60, NULL, IT_HEALTH, 0, NULL, 0, /* precache */ "" }, { NULL, Pickup_Health, NULL, NULL, NULL, "items/l_health.wav", NULL, 0, NULL, /* icon */ "i_health", /* pickup */ "Health", /* width */ 3, 0, NULL, IT_HEALTH, 0, NULL, 0, /* precache */ "items/s_health.wav items/n_health.wav items/l_health.wav items/m_health.wav" }, { "item_haste", Pickup_Powerup, Use_Haste, Drop_General, NULL, "items/powerup.wav", "models/items/haste/tris.md2", EF_ROTATE, NULL, /* icon */ "p_haste", /* pickup */ "Haste", /* width */ 2, 60, NULL, IT_POWERUP, 0, NULL, 0, /* precache */ "items/hasteout.wav" }, { "item_sproing", Pickup_Powerup, Use_Sproing, Drop_General, NULL, "items/powerup.wav", "models/items/sproing/tris.md2", EF_ROTATE, NULL, /* icon */ "p_sproing", /* pickup */ "Sproing", /* width */ 2, 60, NULL, IT_POWERUP, 0, NULL, 0, /* precache */ "items/sproingout.wav" }, //these next two powerups are never placed in maps { "item_invisibility", Pickup_Powerup, Use_Invisibility, NULL, NULL, "items/powerup.wav", NULL, EF_ROTATE, NULL, NULL, "Invisibility", 2, 60, NULL, IT_POWERUP, 0, NULL, 0, /* precache */ "items/protect2.wav" }, // end of list marker {NULL} }; /*QUAKED item_health (.3 .3 1) (-16 -16 -16) (16 16 16) */ void SP_item_health (edict_t *self) { if ( deathmatch->integer && (dmflags->integer & DF_NO_HEALTH) ) { G_FreeEdict (self); return; } self->model = "models/items/healing/medium/tris.md2"; self->classname = "Health"; self->count = 10; SpawnItem (self, FindItem ("Health")); gi.soundindex ("items/n_health.wav"); } /*QUAKED item_health_small (.3 .3 1) (-16 -16 -16) (16 16 16) */ void SP_item_health_small (edict_t *self) { if ( deathmatch->integer && (dmflags->integer & DF_NO_HEALTH) ) { G_FreeEdict (self); return; } self->model = "models/items/healing/small/tris.md2"; self->count = 5; self->classname = "Health"; SpawnItem (self, FindItem ("Health")); self->style = HEALTH_IGNORE_MAX; gi.soundindex ("items/s_health.wav"); } /*QUAKED item_health_large (.3 .3 1) (-16 -16 -16) (16 16 16) */ void SP_item_health_large (edict_t *self) { if ( deathmatch->integer && (dmflags->integer & DF_NO_HEALTH) ) { G_FreeEdict (self); return; } self->model = "models/items/healing/large/tris.md2"; self->classname = "Health"; self->count = 25; SpawnItem (self, FindItem ("Health")); gi.soundindex ("items/l_health.wav"); } /*QUAKED item_health_mega (.3 .3 1) (-16 -16 -16) (16 16 16) */ void SP_item_health_mega (edict_t *self) { if ( deathmatch->integer && (dmflags->integer & DF_NO_HEALTH) ) { G_FreeEdict (self); return; } self->model = "models/items/mega_h/tris.md2"; self->count = 100; SpawnItem (self, FindItem ("Health")); gi.soundindex ("items/m_health.wav"); self->style = HEALTH_IGNORE_MAX|HEALTH_TIMED; } void InitItems (void) { game.num_items = sizeof(itemlist)/sizeof(itemlist[0]) - 1; } /* =============== SetItemNames Called by worldspawn =============== */ void SetItemNames (void) { int i; gitem_t *it; for (i=0 ; ipickup_name); } jacket_armor_index = ITEM_INDEX(FindItem("Jacket Armor")); combat_armor_index = ITEM_INDEX(FindItem("Combat Armor")); body_armor_index = ITEM_INDEX(FindItem("Body Armor")); } alien-arena-7.66+dfsg/source/game/p_client.c0000600000175000017500000031377612161402010017775 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. Copyright (C) 2010 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" #include "m_player.h" /* Number of gibs to throw on death with lots of damage (including Client Head, where applicable) */ #define DEATH_GIBS_TO_THROW 5 void ClientUserinfoChanged (edict_t *ent, char *userinfo, int whereFrom); void ClientDisconnect (edict_t *ent); void SP_misc_teleporter_dest (edict_t *ent); /*QUAKED info_player_start (1 0 0) (-16 -16 -24) (16 16 32) The normal starting point for a level. */ void SP_info_player_start(edict_t *self) { return; } /*QUAKED info_player_deathmatch (1 0 1) (-16 -16 -24) (16 16 32) potential spawning position for deathmatch games */ void SP_info_player_deathmatch(edict_t *self) { if (!deathmatch->value) { G_FreeEdict (self); return; } //SP_misc_teleporter_dest (self); } void SP_info_player_red(edict_t *self) { if (!deathmatch->value) { G_FreeEdict (self); return; } //SP_misc_teleporter_dest (self); } void SP_info_player_blue(edict_t *self) { if (!deathmatch->value) { G_FreeEdict (self); return; } //SP_misc_teleporter_dest (self); } /*QUAKED info_player_intermission (1 0 1) (-16 -16 -24) (16 16 32) The deathmatch intermission point will be at one of these Use 'angles' instead of 'angle', so you can set pitch or roll as well as yaw. 'pitch yaw roll' */ void SP_info_player_intermission(edict_t *ent) { } //======================================================================= void player_pain (edict_t *self, edict_t *other, float kick, int damage) { // player pain is handled at the end of the frame in P_DamageFeedback if(self->is_bot) self->oldenemy = other; } qboolean IsFemale (edict_t *ent) { char *info; if (!ent->client) return false; info = Info_ValueForKey (ent->client->pers.userinfo, "skin"); if (info[0] == 'f' || info[0] == 'F') return true; return false; } void ClientObituary (edict_t *self, edict_t *inflictor, edict_t *attacker) { int mod=0, msg; char *message; char *message2; qboolean ff; char *chatmsg; char *tauntmsg; char cleanname[PLAYERNAME_SIZE]; char cleanname2[PLAYERNAME_SIZE]; int i, pos, total, place; edict_t *cl_ent; gitem_t *it; if (deathmatch->value) { ff = meansOfDeath & MOD_FRIENDLY_FIRE; mod = meansOfDeath & ~MOD_FRIENDLY_FIRE; message = NULL; chatmsg = NULL; tauntmsg = NULL; message2 = ""; switch (mod) { case MOD_SUICIDE: message = "suicides"; break; case MOD_FALLING: message = "cratered"; break; case MOD_CRUSH: message = "was squished"; break; case MOD_WATER: message = "sank like a rock"; break; case MOD_SLIME: message = "melted"; break; case MOD_LAVA: message = "does a back flip into the lava"; break; case MOD_EXPLOSIVE: case MOD_BARREL: message = "blew up"; break; case MOD_EXIT: message = "found a way out"; break; case MOD_TARGET_LASER: message = "saw the light"; break; case MOD_TARGET_BLASTER: message = "got blasted"; break; case MOD_BOMB: case MOD_SPLASH: case MOD_TRIGGER_HURT: message = "was in the wrong place"; break; } if (attacker == self) { switch (mod) { case MOD_CAMPING: message = "was killed for camping"; break; case MOD_PLASMA_SPLASH: if (IsFemale(self)) message = "melted herself"; else message = "melted himself"; break; case MOD_R_SPLASH: if (IsFemale(self)) message = "blew herself up"; else message = "blew himself up"; break; case MOD_VAPORIZER: message = "should have used a smaller gun"; break; default: if (IsFemale(self)) message = "killed herself"; else message = "killed himself"; break; } } if (message) { safe_bprintf (PRINT_MEDIUM, "%s %s.\n", self->client->pers.netname, message); if (deathmatch->value) { self->client->resp.score--; self->client->resp.deaths++; } self->enemy = NULL; self->client->kill_streak = 0; //reset, you are dead return; } self->enemy = attacker; if (attacker && attacker->client) { //clean up names, get rid of escape chars G_CleanPlayerName ( self->client->pers.netname , cleanname ); G_CleanPlayerName ( attacker->client->pers.netname , cleanname2 ); if(!attacker->is_bot) { pos = 0; total = 0; for (i=0 ; iinuse || game.clients[i].resp.spectator) continue; if(attacker->client->resp.score+1 >= game.clients[i].resp.score) pos++; total++; } place = total - pos; if(place < 3) { switch(place) { case 0: safe_centerprintf(attacker, "You fragged %s\n1st place with %i frags\n", cleanname, attacker->client->resp.score+1); break; case 1: safe_centerprintf(attacker, "You fragged %s\n2nd place with %i frags\n", cleanname, attacker->client->resp.score+1); break; case 2: safe_centerprintf(attacker, "You fragged %s\n3rd place with %i frags\n", cleanname, attacker->client->resp.score+1); break; default: break; } } else safe_centerprintf(attacker, "You fragged %s\n", cleanname); } switch (mod) { case MOD_BLASTER: message = "was blasted by"; break; case MOD_VIOLATOR: message = "was probed by"; break; case MOD_CGALTFIRE: message = "was blown away by"; message2 = "'s chaingun burst"; break; case MOD_CHAINGUN: message = "was cut in half by"; message2 = "'s chaingun"; break; case MOD_FLAME: message = "was burned by"; message2 = "'s napalm"; break; case MOD_ROCKET: message = "ate"; message2 = "'s rocket"; break; case MOD_R_SPLASH: message = "almost dodged"; message2 = "'s rocket"; break; case MOD_BEAMGUN: message = "was melted by"; message2 = "'s beamgun"; break; case MOD_DISRUPTOR: message = "was disrupted by"; break; case MOD_SMARTGUN: message = "saw the pretty lights from"; message2 = "'s smartgun"; break; case MOD_VAPORIZER: message = "was disintegrated by"; message2 = "'s vaporizer blast"; break; case MOD_VAPORALTFIRE: message = "couldn't hide from"; message2 = "'s vaporizer"; break; case MOD_MINDERASER: message = "had it's mind erased by"; message2 = "'s alien seeker"; break; case MOD_PLASMA_SPLASH: //blaster splash damage message = "was melted"; message2 = "'s plasma"; break; case MOD_TELEFRAG: message = "tried to invade"; message2 = "'s personal space"; break; case MOD_GRAPPLE: message = "was caught by"; message2 = "'s grapple"; break; case MOD_HEADSHOT: message = "had its head blown off by"; } //here is where the bot chat features will be added. //default is on. Setting to 1 turns it off. if ( !(dmflags->integer & DF_BOTCHAT) && self->is_bot) { msg = random() * 9; switch(msg){ case 1: chatmsg = self->chatmsg1; break; case 2: chatmsg = self->chatmsg2; break; case 3: chatmsg = self->chatmsg3; break; case 4: chatmsg = self->chatmsg4; break; case 5: chatmsg = self->chatmsg5; break; case 6: chatmsg = self->chatmsg6; break; case 7: chatmsg = self->chatmsg7; break; case 8: chatmsg = self->chatmsg8; break; default: chatmsg = "%s: Stop it %s, you punk!"; break; } if(chatmsg) { safe_bprintf (PRINT_CHAT, chatmsg, self->client->pers.netname, attacker->client->pers.netname); safe_bprintf (PRINT_CHAT, "\n"); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_SAYICON); gi.WritePosition (self->s.origin); gi.multicast (self->s.origin, MULTICAST_PVS); } } //bot taunts if(!(dmflags->integer & DF_BOTCHAT) && attacker->is_bot) { if(!(attacker->client->ps.pmove.pm_flags & PMF_DUCKED)) { attacker->state = STATE_STAND; attacker->s.frame = FRAME_taunt01-1; attacker->client->anim_end = FRAME_taunt17; //print a taunt, or send taunt sound msg = random() * 24; switch(msg){ case 1: tauntmsg = "%s: You should have used a bigger gun %s.\n"; break; case 2: tauntmsg = "%s: You fight like your mom %s.\n"; break; case 3: tauntmsg = "%s: And stay down %s!\n"; break; case 4: tauntmsg = "%s: %s = pwned!\n"; break; case 5: tauntmsg = "%s: All too easy, %s, all too easy.\n"; break; case 6: tauntmsg = "%s: Ack! %s Ack! Ack!\n"; break; case 7: tauntmsg = "%s: What a loser you are %s!\n"; break; case 8: tauntmsg = "%s: %s, could you BE any more dead?\n"; break; case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: Cmd_VoiceTaunt_f(attacker); break; default: tauntmsg = "%s: You are useless to me, %s\n"; break; } if(tauntmsg) { safe_bprintf (PRINT_CHAT, tauntmsg, attacker->client->pers.netname, self->client->pers.netname); //send an effect to show that the bot is taunting gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_SAYICON); gi.WritePosition (attacker->s.origin); gi.multicast (attacker->s.origin, MULTICAST_PVS); } } } if (message) { safe_bprintf (PRINT_MEDIUM,"%s %s %s%s\n", self->client->pers.netname, message, attacker->client->pers.netname, message2); if (deathmatch->value) { if(mod == MOD_MINDERASER) { self->client->resp.reward_pts = 0; self->client->resp.powered = false; } if (ff) { attacker->client->resp.score--; attacker->client->resp.deaths++; if ((dmflags->integer & DF_SKINTEAMS) && !ctf->value) { if(attacker->dmteam == RED_TEAM) red_team_score--; else blue_team_score--; } } else { attacker->client->resp.score++; if(!self->groundentity) { attacker->client->resp.reward_pts+=3; safe_centerprintf(attacker, "Midair shot!\n"); } else attacker->client->resp.reward_pts++; if(mod == MOD_HEADSHOT) { //3 more pts for a headshot attacker->client->resp.reward_pts+=3; safe_centerprintf(attacker, "HEADSHOT!\n"); gi.sound(attacker, CHAN_AUTO, gi.soundindex("misc/headshot.wav"), 1, ATTN_STATIC, 0); } //mutators if(vampire->value) { attacker->health+=20; if(attacker->health > attacker->max_health) attacker->health = attacker->max_health; } self->client->resp.deaths++; if ((dmflags->integer & DF_SKINTEAMS) && !ctf->value) { if(attacker->dmteam == RED_TEAM) { red_team_score++; safe_bprintf(PRINT_MEDIUM, "Red Team scores!\n"); gi.sound (self, CHAN_AUTO, gi.soundindex("misc/red_scores.wav"), 1, ATTN_NONE, 0); } else { blue_team_score++; safe_bprintf(PRINT_MEDIUM, "Blue Team scores!\n"); gi.sound (self, CHAN_AUTO, gi.soundindex("misc/blue_scores.wav"), 1, ATTN_NONE, 0); } } //kill streaks attacker->client->kill_streak++; switch(attacker->client->kill_streak) { case 3: for (i=0 ; ivalue ; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || cl_ent->is_bot) continue; safe_centerprintf(cl_ent, "%s is on a killing spree!\n", cleanname2); } break; case 5: for (i=0 ; ivalue ; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || cl_ent->is_bot) continue; safe_centerprintf(cl_ent, "%s is on a rampage!\n", cleanname2); } gi.sound (self, CHAN_AUTO, gi.soundindex("misc/rampage.wav"), 1, ATTN_NONE, 0); attacker->client->resp.reward_pts+=10; break; case 8: for (i=0 ; ivalue ; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || cl_ent->is_bot) continue; safe_centerprintf(cl_ent, "%s is unstoppable!\n", cleanname2); } break; case 10: for (i=0 ; ivalue ; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || cl_ent->is_bot) continue; safe_centerprintf(cl_ent, "%s is a god!\n", cleanname2); } gi.sound (self, CHAN_AUTO, gi.soundindex("misc/godlike.wav"), 1, ATTN_NONE, 0); attacker->client->resp.reward_pts+=20; break; default: break; } if(self->client->kill_streak >=3) { for (i=0 ; ivalue ; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || cl_ent->is_bot) continue; safe_centerprintf(cl_ent, "%s's killing spree\nended by %s!\n", cleanname, cleanname2); } } } } if(attacker->client->resp.reward_pts >= g_reward->integer && !attacker->client->resp.powered) { //give them speed and invis powerups it = FindItem("Invisibility"); attacker->client->pers.inventory[ITEM_INDEX(it)] += 1; it = FindItem("Sproing"); attacker->client->pers.inventory[ITEM_INDEX(it)] += 1; it = FindItem("Haste"); attacker->client->pers.inventory[ITEM_INDEX(it)] += 1; attacker->client->resp.powered = true; gi.sound (attacker, CHAN_AUTO, gi.soundindex("misc/pc_up.wav"), 1, ATTN_STATIC, 0); } self->client->kill_streak = 0; //reset, you are dead return; } } } if(mod == MOD_DEATHRAY) { safe_bprintf(PRINT_MEDIUM, "%s killed by Deathray!\n", self->client->pers.netname); //immune player (activator) gets score increase for (i=0 ; ivalue ; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || cl_ent->is_bot) continue; if(cl_ent->client) if(cl_ent->client->rayImmunity) cl_ent->client->resp.score++; } return; } if(mod == MOD_SPIDER) { safe_bprintf(PRINT_MEDIUM, "%s killed by Spiderbot!\n", self->client->pers.netname); self->client->resp.reward_pts = 0; self->client->resp.powered = false; if(inflictor->owner->client) inflictor->owner->client->resp.score++; return; } safe_bprintf (PRINT_MEDIUM,"%s died.\n", self->client->pers.netname); if (deathmatch->value) { self->client->resp.score--; self->client->resp.deaths++; } } void Touch_Item (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf); void TossClientWeapon (edict_t *self) { gitem_t *item; edict_t *drop; qboolean quad; qboolean sproing; qboolean haste; float spread; if ((!deathmatch->value) || instagib->integer || rocket_arena->integer || insta_rockets->value) { return; } item = self->client->pers.weapon; if (!self->client->pers.inventory[self->client->ammo_index] ) item = NULL; #ifdef ALTERIA if (item && (strcmp (item->pickup_name, "Warriorpunch") == 0)) item = NULL; if (item && (strcmp (item->pickup_name, "Wizardpunch") == 0)) item = NULL; #else if (item && (strcmp (item->pickup_name, "Blaster") == 0)) item = NULL; if (item && (strcmp (item->pickup_name, "Alien Blaster") == 0)) item = NULL; if (item && (strcmp (item->pickup_name, "Violator") == 0)) item = NULL; if (item && (strcmp (item->pickup_name, "Minderaser") == 0)) item = NULL; if (g_tactical->integer && item && (strcmp (item->pickup_name, "Alien Vaporizer") == 0)) item = NULL; #endif if(g_tactical->integer) { //always drop your weapon on death, even if it isn't the current held item. if(self->client->pers.inventory[ITEM_INDEX(FindItem("Flame Thrower"))] == 1) { item = FindItem( "Flame Thrower" ); if(item) { spread = 0; self->client->v_angle[YAW] -= spread; drop = Drop_Item (self, item); self->client->v_angle[YAW] += spread; drop->spawnflags = DROPPED_PLAYER_ITEM; } } if(self->client->pers.inventory[ITEM_INDEX(FindItem("Rocket Launcher"))] == 1) { item = FindItem( "Rocket Launcher" ); if(item) { spread = 35; self->client->v_angle[YAW] -= spread; drop = Drop_Item (self, item); self->client->v_angle[YAW] += spread; drop->spawnflags = DROPPED_PLAYER_ITEM; } } if(self->client->pers.inventory[ITEM_INDEX(FindItem("Pulse Rifle"))] == 1) { item = FindItem( "Pulse Rifle" ); if(item) { spread = 70; self->client->v_angle[YAW] -= spread; drop = Drop_Item (self, item); self->client->v_angle[YAW] += spread; drop->spawnflags = DROPPED_PLAYER_ITEM; } } if(self->client->pers.inventory[ITEM_INDEX(FindItem("Disruptor"))] == 1) { item = FindItem( "Disruptor" ); if(item) { spread = 105; self->client->v_angle[YAW] -= spread; drop = Drop_Item (self, item); self->client->v_angle[YAW] += spread; drop->spawnflags = DROPPED_PLAYER_ITEM; } } if(self->client->pers.inventory[ITEM_INDEX(FindItem("Alien Disruptor"))] == 1) { item = FindItem( "Alien Disruptor" ); if(item) { spread = 140; self->client->v_angle[YAW] -= spread; drop = Drop_Item (self, item); self->client->v_angle[YAW] += spread; drop->spawnflags = DROPPED_PLAYER_ITEM; } } if(self->client->pers.inventory[ITEM_INDEX(FindItem("Alien Smartgun"))] == 1) { item = FindItem( "Alien Smartgun" ); if(item) { spread = 175; self->client->v_angle[YAW] -= spread; drop = Drop_Item (self, item); self->client->v_angle[YAW] += spread; drop->spawnflags = DROPPED_PLAYER_ITEM; } } } else { if (!(dmflags->integer & DF_QUAD_DROP)) quad = false; else quad = (self->client->quad_framenum > (level.framenum + 10)); sproing = (self->client->sproing_framenum > (level.framenum + 10)); haste = (self->client->haste_framenum > (level.framenum + 10)); if ((item && quad) || (item && haste) || (item && sproing)) spread = 22.5; else spread = 0.0; if (item) { self->client->v_angle[YAW] -= spread; drop = Drop_Item (self, item); self->client->v_angle[YAW] += spread; drop->spawnflags = DROPPED_PLAYER_ITEM; } if (quad) { self->client->v_angle[YAW] += spread; drop = Drop_Item (self, FindItemByClassname ("item_quad")); self->client->v_angle[YAW] -= spread; drop->spawnflags |= DROPPED_PLAYER_ITEM; drop->touch = Touch_Item; drop->nextthink = level.time + (self->client->quad_framenum - level.framenum) * FRAMETIME; drop->think = G_FreeEdict; } if (sproing && !self->client->resp.powered) { self->client->v_angle[YAW] += spread; drop = Drop_Item (self, FindItemByClassname ("item_sproing")); self->client->v_angle[YAW] -= spread; drop->spawnflags |= DROPPED_PLAYER_ITEM; drop->touch = Touch_Item; drop->nextthink = level.time + (self->client->sproing_framenum - level.framenum) * FRAMETIME; drop->think = G_FreeEdict; } if (haste && !self->client->resp.powered) { self->client->v_angle[YAW] += spread; drop = Drop_Item (self, FindItemByClassname ("item_haste")); self->client->v_angle[YAW] -= spread; drop->spawnflags |= DROPPED_PLAYER_ITEM; drop->touch = Touch_Item; drop->nextthink = level.time + (self->client->haste_framenum - level.framenum) * FRAMETIME; drop->think = G_FreeEdict; } } } /* ================== LookAtKiller ================== */ void LookAtKiller (edict_t *self, edict_t *inflictor, edict_t *attacker) { vec3_t dir; if (attacker && attacker != world && attacker != self) { VectorSubtract (attacker->s.origin, self->s.origin, dir); } else if (inflictor && inflictor != world && inflictor != self) { VectorSubtract (inflictor->s.origin, self->s.origin, dir); } else { self->client->killer_yaw = self->s.angles[YAW]; return; } self->client->killer_yaw = 180/M_PI*atan2(dir[1], dir[0]); } /* ================== player_die ================== */ void player_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { int n; char *info; int got_vehicle = 0; int number_of_gibs = 0; int gib_effect = EF_GREENGIB; int hasFlag = false; gitem_t *it, *flag1_item, *flag2_item; int mod; mod = meansOfDeath & ~MOD_FRIENDLY_FIRE; if (self->in_vehicle) { Reset_player(self); //get the player out of the vehicle Jet_Explosion(self); //blow that bitch up! got_vehicle = 1; //so we know how to handle dropping it } VectorClear (self->avelocity); self->takedamage = DAMAGE_YES; self->movetype = MOVETYPE_TOSS; info = Info_ValueForKey (self->client->pers.userinfo, "skin"); self->s.modelindex2 = 0; // remove linked weapon model if(ctf->value) self->s.modelindex4 = 0; // remove linked ctf flag self->s.angles[0] = 0; self->s.angles[2] = 0; self->s.sound = 0; self->client->weapon_sound = 0; self->maxs[2] = -8; self->svflags |= SVF_DEADMONSTER; if (!self->deadflag) { self->client->respawn_time = level.time + 3.8; //go into 3rd person view if (deathmatch->value) if(!self->is_bot) DeathcamStart(self); self->client->ps.pmove.pm_type = PM_DEAD; ClientObituary (self, inflictor, attacker); if(got_vehicle) //special for vehicles VehicleDeadDrop(self); else { if(!excessive->value) TossClientWeapon (self); } if(ctf->value) { //check to see if they had a flag flag1_item = flag2_item = NULL; flag1_item = FindItemByClassname("item_flag_red"); flag2_item = FindItemByClassname("item_flag_blue"); if (self->client->pers.inventory[ITEM_INDEX(flag1_item)] || self->client->pers.inventory[ITEM_INDEX(flag1_item)]) hasFlag = true; CTFDeadDropFlag(self, attacker); if(anticamp->value && meansOfDeath == MOD_SUICIDE && hasFlag) { //make campers really pay for hiding flags if(self->dmteam == BLUE_TEAM) CTFResetFlag(RED_TEAM); else CTFResetFlag(BLUE_TEAM); } } if(self->in_deathball) DeadDropDeathball(self); CTFPlayerResetGrapple(self); if (deathmatch->integer && !self->is_bot) { ACESP_UpdateBots(); self->client->showscores = false; // override toggle Cmd_Score_f( self ); } if(attacker) { if(self->health < -40 && attacker->client) { attacker->client->resp.reward_pts++; if(attacker->client->resp.reward_pts >= g_reward->integer && !attacker->client->resp.powered) { //give them speed and invis powerups it = FindItem("Invisibility"); attacker->client->pers.inventory[ITEM_INDEX(it)] += 1; it = FindItem("Sproing"); attacker->client->pers.inventory[ITEM_INDEX(it)] += 1; it = FindItem("Haste"); attacker->client->pers.inventory[ITEM_INDEX(it)] += 1; attacker->client->resp.powered = true; gi.sound (attacker, CHAN_VOICE, gi.soundindex("misc/pc_up.wav"), 1, ATTN_STATIC, 0); } } } } // remove powerups self->client->quad_framenum = 0; self->client->invincible_framenum = 0; self->client->haste_framenum = 0; self->client->sproing_framenum = 0; self->client->invis_framenum = 0; // clear inventory memset(self->client->pers.inventory, 0, sizeof(self->client->pers.inventory)); if (self->health < -40) { // gib self->takedamage = DAMAGE_NO; self->s.modelindex3 = 0; //remove helmet, if a martian if(self->client->chasetoggle == 1) { /* If deathcam is active, switch client model to nothing */ self->s.modelindex = 0; self->s.effects = 0; self->solid = SOLID_NOT; number_of_gibs = DEATH_GIBS_TO_THROW; } else { /* No deathcam, handle player's view and model with ThrowClientHead() */ ThrowClientHead (self, damage); number_of_gibs = DEATH_GIBS_TO_THROW - 1; } if(self->ctype == 0) { //alien gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_DEATHFIELD); gi.WritePosition (self->s.origin); gi.multicast (self->s.origin, MULTICAST_PVS); for (n= 0; n < number_of_gibs; n++) { if(mod == MOD_R_SPLASH || mod == MOD_ROCKET) ThrowGib (self, "models/objects/gibs/mart_gut/tris.md2", damage, GIB_METALLIC, EF_SHIPEXHAUST); else ThrowGib (self, "models/objects/gibs/mart_gut/tris.md2", damage, GIB_METALLIC, EF_GREENGIB); ThrowGib (self, "models/objects/debris2/tris.md2", damage, GIB_METALLIC, 0); } } else if(self->ctype == 2) { //robot gib_effect = 0; for (n= 0; n < number_of_gibs; n++) { ThrowGib (self, "models/objects/debris3/tris.md2", damage, GIB_METALLIC, 0); ThrowGib (self, "models/objects/debris1/tris.md2", damage, GIB_METALLIC, 0); } //blow up too :) gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_ROCKET_EXPLOSION); gi.WritePosition (self->s.origin); gi.multicast (self->s.origin, MULTICAST_PHS); } else { //human gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_DEATHFIELD2); gi.WritePosition (self->s.origin); gi.WriteDir (self->s.angles); gi.multicast (self->s.origin, MULTICAST_PVS); gib_effect = EF_GIB; for (n= 0; n < number_of_gibs; n++) { if(mod == MOD_R_SPLASH || mod == MOD_ROCKET) ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_METALLIC, EF_SHIPEXHAUST); else ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_METALLIC, EF_GIB); } } if(self->usegibs) { if(mod == MOD_R_SPLASH || mod == MOD_ROCKET) gib_effect = EF_SHIPEXHAUST; ThrowGib (self, self->head, damage, GIB_ORGANIC, gib_effect); ThrowGib (self, self->leg, damage, GIB_ORGANIC, gib_effect); ThrowGib (self, self->leg, damage, GIB_ORGANIC, gib_effect); ThrowGib (self, self->body, damage, GIB_ORGANIC, gib_effect); ThrowGib (self, self->arm, damage, GIB_ORGANIC, gib_effect); ThrowGib (self, self->arm, damage, GIB_ORGANIC, gib_effect); } } else { // normal death if (!self->deadflag) { static int i; i = (i+1)%3; // start a death animation self->client->anim_priority = ANIM_DEATH; switch (i) { //all player models are now using the longer set of death frames only case 0: self->s.frame = FRAME_death501-1; self->client->anim_end = FRAME_death518; break; case 1: self->s.frame = FRAME_death601-1; self->client->anim_end = FRAME_death620; break; case 2: self->s.frame = FRAME_death401-1; self->client->anim_end = FRAME_death422; break; } gi.sound (self, CHAN_VOICE, gi.soundindex(va("*death%i.wav", (rand()%4)+1)), 1, ATTN_NORM, 0); } } gi.sound (self, CHAN_VOICE, gi.soundindex("misc/death.wav"), 1, ATTN_STATIC, 0); self->deadflag = DEAD_DEAD; self->takedamage = DAMAGE_NO; gi.linkentity (self); } //======================================================================= /* ============== InitClientPersistant This is only called when the game first initializes in single player, but is called after each death and level change in deathmatch ============== */ void InitClientPersistant (gclient_t *client) { gitem_t *item; int queue=0; if(g_duel->integer) //need to save this off in duel mode. Potentially dangerous? queue = client->pers.queue; memset (&client->pers, 0, sizeof(client->pers)); if(g_duel->integer) client->pers.queue = queue; #ifdef ALTERIA item = FindItem("Warriorpunch"); #else if(!rocket_arena->integer && !g_tactical->integer) { //gets a violator, unless RA or Tactical item = FindItem("Violator"); client->pers.selected_item = ITEM_INDEX(item); client->pers.inventory[client->pers.selected_item] = 1; client->pers.weapon = item; } //mutator - will need to have item if(instagib->integer) { client->pers.inventory[ITEM_INDEX(FindItem("Alien Disruptor"))] = 1; client->pers.inventory[ITEM_INDEX(FindItem("cells"))] = g_maxcells->value; item = FindItem("Alien Disruptor"); } else if(rocket_arena->integer) { client->pers.inventory[ITEM_INDEX(FindItem("Rocket Launcher"))] = 1; client->pers.inventory[ITEM_INDEX(FindItem("rockets"))] = g_maxrockets->value; item = FindItem("Rocket Launcher"); } else if (insta_rockets->integer ) { client->pers.inventory[ITEM_INDEX(FindItem("Rocket Launcher"))] = 1; client->pers.inventory[ITEM_INDEX(FindItem("rockets"))] = g_maxrockets->value; item = FindItem("Rocket Launcher"); client->pers.inventory[ITEM_INDEX(FindItem("Alien Disruptor"))] = 1; client->pers.inventory[ITEM_INDEX(FindItem("cells"))] = g_maxcells->value; item = FindItem("Alien Disruptor"); } else item = FindItem("Blaster"); #endif client->pers.selected_item = ITEM_INDEX(item); client->pers.inventory[client->pers.selected_item] = 1; client->pers.weapon = item; if(excessive->value) { //Allow custom health, even in excessive. client->pers.health = g_spawnhealth->value * 3; client->pers.max_bullets = g_maxbullets->value * 2.5; client->pers.max_shells = g_maxshells->value * 5; client->pers.max_rockets = g_maxrockets->value * 10; client->pers.max_grenades = g_maxgrenades->value * 10; client->pers.max_cells = g_maxcells->value * 2.5; client->pers.max_slugs = g_maxslugs->value * 10; client->pers.max_seekers = g_maxseekers->value * 2; client->pers.max_bombs = g_maxbombs->value * 2; client->pers.inventory[ITEM_INDEX(FindItem("Rocket Launcher"))] = 1; client->pers.inventory[ITEM_INDEX(FindItem("rockets"))] = g_maxrockets->value * 10; client->pers.inventory[ITEM_INDEX(FindItem("Pulse Rifle"))] = 1; client->pers.inventory[ITEM_INDEX(FindItem("bullets"))] = g_maxbullets->value * 2.5; client->pers.inventory[ITEM_INDEX(FindItem("Alien Disruptor"))] = 1; client->pers.inventory[ITEM_INDEX(FindItem("Disruptor"))] = 1; client->pers.inventory[ITEM_INDEX(FindItem("cells"))] = g_maxcells->value * 2.5; client->pers.inventory[ITEM_INDEX(FindItem("Alien Smartgun"))] = 1; client->pers.inventory[ITEM_INDEX(FindItem("alien smart grenade"))] = g_maxshells->value * 5; client->pers.inventory[ITEM_INDEX(FindItem("Alien Vaporizer"))] = 1; client->pers.inventory[ITEM_INDEX(FindItem("slugs"))] = g_maxslugs->value * 10; client->pers.inventory[ITEM_INDEX(FindItem("Flame Thrower"))] = 1; client->pers.inventory[ITEM_INDEX(FindItem("napalm"))] = g_maxgrenades->value * 10; client->pers.inventory[ITEM_INDEX(FindItem("Minderaser"))] = 1; client->pers.inventory[ITEM_INDEX(FindItem("seekers"))] = g_maxseekers->value * 2; client->pers.inventory[ITEM_INDEX(FindItem("bombs"))] = g_maxbombs->value * 2; } else { client->pers.health = g_spawnhealth->value; client->pers.max_bullets = g_maxbullets->value; client->pers.max_shells = g_maxshells->value; client->pers.max_rockets = g_maxrockets->value; client->pers.max_grenades = g_maxgrenades->value; client->pers.max_cells = g_maxcells->value; client->pers.max_slugs = g_maxslugs->value; client->pers.max_seekers = g_maxseekers->value; client->pers.max_bombs = g_maxbombs->value; } if(vampire->value) client->pers.max_health = g_maxhealth->value * 2; else if(excessive->value) client->pers.max_health = g_maxhealth->value * 3; else client->pers.max_health = g_maxhealth->value; if(grapple->value) { item = FindItem("Grapple"); client->pers.inventory[ITEM_INDEX(item)] = 1; } //if powered up, give back powerups if(client->resp.powered) { item = FindItem("Invisibility"); client->pers.inventory[ITEM_INDEX(item)] += 1; item = FindItem("Sproing"); client->pers.inventory[ITEM_INDEX(item)] += 1; item = FindItem("Haste"); client->pers.inventory[ITEM_INDEX(item)] += 1; } client->pers.connected = true; } void InitClientResp (gclient_t *client) { memset (&client->resp, 0, sizeof(client->resp)); client->resp.enterframe = level.framenum; } /* ================== SaveClientData Some information that should be persistant, like health, is still stored in the edict structure, so it needs to be mirrored out to the client structure before all the edicts are wiped. ================== */ void SaveClientData (void) { int i; edict_t *ent; for (i=0 ; iinuse) continue; game.clients[i].pers.health = ent->health; game.clients[i].pers.max_health = ent->max_health; } } void FetchClientEntData (edict_t *ent) { ent->health = ent->client->pers.health; ent->max_health = ent->client->pers.max_health; } /* ======================================================================= SelectSpawnPoint ======================================================================= */ /* ================ PlayersRangeFromSpot Returns the distance to the nearest player from the given spot ================ */ float PlayersRangeFromSpot (edict_t *spot) { edict_t *player; float bestplayerdistance; vec3_t v; int n; float playerdistance; bestplayerdistance = 9999999; for (n = 1; n <= g_maxclients->value; n++) { player = &g_edicts[n]; if (!player->inuse) continue; if (player->health <= 0) continue; VectorSubtract (spot->s.origin, player->s.origin, v); playerdistance = VectorLength (v); if (playerdistance < bestplayerdistance) bestplayerdistance = playerdistance; } return bestplayerdistance; } /* ================ SelectRandomDeathmatchSpawnPoint go to a random point, but NOT the two points closest to other players ================ */ edict_t *SelectRandomDeathmatchSpawnPoint (void) { edict_t *spot, *spot1, *spot2; int count = 0; int selection; float range, range1, range2; spot = NULL; range1 = range2 = 99999; spot1 = spot2 = NULL; while ((spot = G_Find (spot, FOFS(classname), "info_player_deathmatch")) != NULL) { count++; range = PlayersRangeFromSpot(spot); if (range < range1) { range1 = range; spot1 = spot; } else if (range < range2) { range2 = range; spot2 = spot; } } if (!count) return NULL; if (count <= 2) { spot1 = spot2 = NULL; } else { if ( spot1 ) { count--; } if ( spot2 ) { count--; } } selection = rand() % count; spot = NULL; do { spot = G_Find (spot, FOFS(classname), "info_player_deathmatch"); if (spot == spot1 || spot == spot2) selection++; } while(selection--); return spot; } /* ================ SelectRandomDeathmatchSpawnPoint go to a random point, but NOT the two points closest to other players ================ */ edict_t *SelectRandomCTFSpawnPoint (void) { edict_t *spot, *spot1, *spot2; int count = 0; int selection; float range, range1, range2; char whichteam[32]; spot = NULL; range1 = range2 = 99999; spot1 = spot2 = NULL; if(random() < 0.5) strcpy(whichteam, "info_player_red"); else strcpy(whichteam, "info_player_blue"); while ((spot = G_Find (spot, FOFS(classname), whichteam)) != NULL) { count++; range = PlayersRangeFromSpot(spot); if (range < range1) { range1 = range; spot1 = spot; } else if (range < range2) { range2 = range; spot2 = spot; } } if (!count) return NULL; if (count <= 2) { spot1 = spot2 = NULL; } else { if ( spot1 ) { count--; } if ( spot2 ) { count--; } } selection = rand() % count; spot = NULL; do { spot = G_Find (spot, FOFS(classname), whichteam); if (spot == spot1 || spot == spot2) selection++; } while(selection--); return spot; } /* ================ SelectFarthestDeathmatchSpawnPoint ================ */ edict_t *SelectFarthestDeathmatchSpawnPoint (void) { edict_t *bestspot; float bestdistance, bestplayerdistance; edict_t *spot; spot = NULL; bestspot = NULL; bestdistance = 0; while ((spot = G_Find (spot, FOFS(classname), "info_player_deathmatch")) != NULL) { bestplayerdistance = PlayersRangeFromSpot (spot); if (bestplayerdistance > bestdistance) { bestspot = spot; bestdistance = bestplayerdistance; } } if (bestspot) { return bestspot; } // if there is a player just spawned on each and every start spot // we have no choice to turn one into a telefrag meltdown spot = G_Find (NULL, FOFS(classname), "info_player_deathmatch"); return spot; } edict_t *SelectDeathmatchSpawnPoint (void) { if ( dmflags->integer & DF_SPAWN_FARTHEST) return SelectFarthestDeathmatchSpawnPoint (); else return SelectRandomDeathmatchSpawnPoint (); } /* ================ SelectCTFSpawnPoint go to a ctf point, but NOT the two points closest to other players ================ */ edict_t *SelectCTFSpawnPoint (edict_t *ent) { edict_t *spot, *spot1, *spot2; int count = 0; int selection; float range, range1, range2; char *cname; if(g_tactical->value) { if(ent->ctype == 1) cname = "info_player_red"; else cname = "info_player_blue"; } else { switch (ent->dmteam) { case RED_TEAM: cname = "info_player_red"; break; case BLUE_TEAM: cname = "info_player_blue"; break; case NO_TEAM: default: return SelectRandomCTFSpawnPoint(); } } spot = NULL; range1 = range2 = 99999; spot1 = spot2 = NULL; while ((spot = G_Find (spot, FOFS(classname), cname)) != NULL) { count++; range = PlayersRangeFromSpot(spot); if (range < range1) { range1 = range; spot1 = spot; } else if (range < range2) { range2 = range; spot2 = spot; } } if (!count) return SelectRandomDeathmatchSpawnPoint(); if (count <= 2) { spot1 = spot2 = NULL; } else count -= 2; selection = rand() % count; spot = NULL; do { spot = G_Find (spot, FOFS(classname), cname); if (spot == spot1 || spot == spot2) selection++; } while(selection--); return spot; } /* =========== SelectSpawnPoint Chooses a player start, deathmatch start, coop start, etc ============ */ void SelectSpawnPoint (edict_t *ent, vec3_t origin, vec3_t angles) { edict_t *spot = NULL; if (deathmatch->value) { if (g_tactical->value || ctf->value || tca->value || cp->value || (dmflags->integer & DF_SKINTEAMS)) { spot = SelectCTFSpawnPoint(ent); if(!spot) spot = SelectDeathmatchSpawnPoint (); } else { spot = SelectDeathmatchSpawnPoint (); if(!spot) spot = SelectCTFSpawnPoint(ent); //dm on team based maps } } // find a single player start spot if (!spot) { spot = G_Find (spot, FOFS(classname), "info_player_start"); if (!spot) gi.error ("Couldn't find spawn point!"); } VectorCopy (spot->s.origin, origin); origin[2] += 9; VectorCopy (spot->s.angles, angles); } //====================================================================== void InitBodyQue (void) { int i; edict_t *ent; level.body_que = 0; for (i=0; iclassname = "bodyque"; } } /* ============= BodySink After sitting around for five seconds, fall into the ground and dissapear ============= */ void BodySink( edict_t *ent ) { if ( level.time - ent->timestamp > 10.5 ) { // the body ques are never actually freed, they are just unlinked gi.unlinkentity( ent ); ent->s.modelindex = 0; //for good measure ent->s.modelindex2 = 0; ent->s.modelindex3 = 0; ent->s.modelindex4 = 0; ent->s.effects = 0; return; } ent->nextthink = level.time + .1; ent->s.origin[2] -= 1; ent->s.effects |= EF_COLOR_SHELL; ent->s.renderfx |= RF_SHELL_GREEN; ent->solid = SOLID_NOT; //don't gib sinking bodies } void body_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { self->s.modelindex3 = 0; self->s.modelindex4 = 0; self->takedamage = DAMAGE_NO; self->solid = SOLID_NOT; self->s.effects = EF_GIB; self->s.sound = 0; self->flags |= FL_NO_KNOCKBACK; if (self->client) // bodies in the queue don't have a client anymore { self->client->anim_priority = ANIM_DEATH; self->client->anim_end = self->s.frame; } else { self->think = NULL; self->nextthink = 0; } gi.linkentity (self); } void CopyToBodyQue (edict_t *ent) { edict_t *body; // grab a body que and cycle to the next one body = &g_edicts[g_maxclients->integer + level.body_que + 1]; level.body_que = (level.body_que + 1) % BODY_QUEUE_SIZE; gi.unlinkentity (ent); gi.unlinkentity (body); body->s = ent->s; body->s.number = body - g_edicts; body->svflags = ent->svflags; VectorCopy (ent->mins, body->mins); VectorCopy (ent->maxs, body->maxs); VectorCopy (ent->absmin, body->absmin); VectorCopy (ent->absmax, body->absmax); VectorCopy (ent->size, body->size); body->solid = SOLID_NOT; body->clipmask = ent->clipmask; body->owner = ent->owner; body->movetype = ent->movetype; body->die = body_die; body->takedamage = DAMAGE_YES; body->ctype = ent->ctype; body->timestamp = level.time; body->nextthink = level.time + 5; body->think = BodySink; gi.linkentity (body); } void respawn (edict_t *self) { if (deathmatch->value) { // ACEBOT_ADD special respawning code if (self->is_bot) { ACESP_Respawn (self); return; } // ACEBOT_END //spectator mode // spectator's don't leave bodies if (self->movetype != MOVETYPE_NOCLIP) CopyToBodyQue (self); //end spectator mode self->svflags &= ~SVF_NOCLIENT; PutClientInServer (self); // add a teleportation effect self->s.event = EV_PLAYER_TELEPORT; // hold in place briefly self->client->ps.pmove.pm_flags = PMF_TIME_TELEPORT; self->client->ps.pmove.pm_time = 14; self->client->respawn_time = level.time; return; } // restart the entire server gi.AddCommandString ("menu_loadgame\n"); } //spectator mode void spectator_respawn (edict_t *ent) { int i, numspec; // if the user wants to become a spectator, make sure he doesn't // exceed max_spectators if (ent->client->pers.spectator) { char *value = Info_ValueForKey (ent->client->pers.userinfo, "spectator_password"); if (*spectator_password->string && strcmp(spectator_password->string, "none") && strcmp(spectator_password->string, value)) { gi.cprintf(ent, PRINT_HIGH, "%s", "Spectator password incorrect.\n"); ent->client->pers.spectator = 0; gi.WriteByte (svc_stufftext); gi.WriteString ("spectator 0\n"); gi.unicast(ent, true); return; } // count spectators for (i = 1, numspec = 0; i <= g_maxclients->value; i++) if (g_edicts[i].inuse && g_edicts[i].client->pers.spectator) numspec++; if (numspec >= maxspectators->value) { gi.cprintf(ent, PRINT_HIGH, "%s", "Server spectator limit is full."); ent->client->pers.spectator = 0; // reset his spectator var gi.WriteByte (svc_stufftext); gi.WriteString ("spectator 0\n"); gi.unicast(ent, true); return; } } else { // he was a spectator and wants to join the game // he must have the right password char *value = Info_ValueForKey (ent->client->pers.userinfo, "password"); if (*password->string && strcmp(password->string, "none") && strcmp(password->string, value)) { gi.cprintf(ent, PRINT_HIGH, "%s", "Password incorrect.\n"); ent->client->pers.spectator = 1; gi.WriteByte (svc_stufftext); gi.WriteString ("spectator 1\n"); gi.unicast(ent, true); return; } } /* Remove deathcam if changed to spectator after death */ if (ent->client->pers.spectator && ent->deadflag) DeathcamRemove (ent, "off"); // clear client on respawn ent->client->resp.score = 0; ent->svflags &= ~SVF_NOCLIENT; PutClientInServer (ent); // add a teleportation effect if (!ent->client->pers.spectator) { // send effect gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_LOGIN); gi.multicast (ent->s.origin, MULTICAST_PVS); // hold in place briefly ent->client->ps.pmove.pm_flags = PMF_TIME_TELEPORT; ent->client->ps.pmove.pm_time = 14; } ent->client->respawn_time = level.time; if (ent->client->pers.spectator) { // pers.spectator > 0, entering spectator mode safe_bprintf (PRINT_HIGH, "%s has moved to the sidelines\n", ent->client->pers.netname); } else { // pers.spectator==0, leaving spectator mode safe_bprintf (PRINT_HIGH, "%s joined the game\n", ent->client->pers.netname); } if ( sv_botkickthreshold && sv_botkickthreshold->integer ) { // player entered or left playing field, update for auto botkick ACESP_LoadBots( ent ); } } //end spectator mode //============================================================== /* =========== ParseClassFile Used in tactical mode for setting class items =========== */ void ParseClassFile( char *config_file, edict_t *ent ) { char full_path[MAX_OSPATH]; FILE *fp; int length; char a_string[128]; char *buffer; char *s; size_t result; if ( gi.FullPath( full_path, sizeof(full_path), config_file ) ) { if((fp = fopen(full_path, "rb" )) == NULL) { return; } if ( fseek(fp, 0, SEEK_END) ) { // seek error fclose( fp ); return; } if ( (length = ftell(fp)) == (size_t)-1L ) { // tell error fclose( fp ); return; } if ( fseek(fp, 0, SEEK_SET) ) { // seek error fclose( fp ); return; } buffer = malloc( length + 1 ); if ( buffer != NULL ) { buffer[length] = 0; result = fread( buffer, length, 1, fp ); if ( result == 1 ) { s = buffer; strcpy( a_string, COM_Parse( &s ) ); ent->max_health = atoi(a_string); strcpy( a_string, COM_Parse( &s ) ); ent->armor_type = atoi(a_string); strcpy( a_string, COM_Parse( &s ) ); ent->has_bomb = atoi(a_string); strcpy( a_string, COM_Parse( &s ) ); ent->has_detonator = atoi(a_string); strcpy( a_string, COM_Parse( &s ) ); ent->has_minderaser = atoi(a_string); strcpy( a_string, COM_Parse( &s ) ); ent->has_vaporizor = atoi(a_string); //note - we may or may not need the ent vars, for now keep them if(ent->max_health > 0) ent->health = ent->client->pers.max_health = ent->client->pers.health = ent->max_health; else ent->max_health = 100; switch(ent->armor_type) { default: case 0: break; case 1: ent->client->pers.inventory[ITEM_INDEX(FindItem("Jacket Armor"))] += 30; break; case 2: ent->client->pers.inventory[ITEM_INDEX(FindItem("Body Armor"))] += 50; break; case 3: ent->client->pers.inventory[ITEM_INDEX(FindItem("Jacket Armor"))] += 30; break; } if(ent->has_minderaser) { ent->client->pers.inventory[ITEM_INDEX(FindItem("Minderaser"))] = 1; ent->client->pers.inventory[ITEM_INDEX(FindItem("seekers"))] = 1; } if(ent->has_vaporizor) { ent->client->pers.inventory[ITEM_INDEX(FindItem("Alien Vaporizer"))] = 1; ent->client->pers.inventory[ITEM_INDEX(FindItem("slugs"))] = 4; } } free( buffer ); } fclose( fp ); } return; } /* =========== PutClientInServer Called when a player connects to a server or respawns in a deathmatch. ============ */ void PutClientInServer (edict_t *ent) { vec3_t mins = {-16, -16, -24}; vec3_t maxs = {16, 16, 32}; int index, armor_index; vec3_t spawn_origin, spawn_angles; gclient_t *client; gitem_t *item; int i, done; client_persistant_t saved; client_respawn_t resp; char *info; char playermodel[MAX_OSPATH] = " "; char modelpath[MAX_OSPATH] = " "; FILE *file; char userinfo[MAX_INFO_STRING]; // find a spawn point // do it before setting health back up, so farthest // ranging doesn't count this client if(!g_tactical->integer) SelectSpawnPoint (ent, spawn_origin, spawn_angles); index = ent-g_edicts-1; client = ent->client; client->is_bot = 0; client->kill_streak = 0; client->homing_shots = 0; client->mapvote = 0; client->lasttaunttime = 0; client->rayImmunity = false; resp = client->resp; memcpy (userinfo, client->pers.userinfo, sizeof(userinfo)); InitClientPersistant (client); ClientUserinfoChanged (ent, userinfo, SPAWN); // clear everything but the persistant data saved = client->pers; memset (client, 0, sizeof(*client)); client->pers = saved; if (client->pers.health <= 0) InitClientPersistant(client); client->resp = resp; // copy some data from the client to the entity FetchClientEntData (ent); // clear entity values ent->groundentity = NULL; ent->client = &game.clients[index]; if(g_spawnprotect->value) ent->client->spawnprotected = true; ent->takedamage = DAMAGE_AIM; ent->movetype = MOVETYPE_WALK; ent->viewheight = 22; ent->inuse = true; ent->classname = "player"; ent->mass = 200; ent->solid = SOLID_BBOX; ent->deadflag = DEAD_NO; ent->air_finished = level.time + 12; ent->clipmask = MASK_PLAYERSOLID; ent->model = "players/martianenforcer/tris.md2"; ent->pain = player_pain; ent->die = player_die; ent->waterlevel = 0; ent->watertype = 0; ent->flags &= ~FL_NO_KNOCKBACK; ent->svflags &= ~SVF_DEADMONSTER; // ACEBOT_ADD ent->is_bot = false; ent->last_node = -1; ent->is_jumping = false; // ACEBOT_END //vehicles ent->in_vehicle = false; //deathball ent->in_deathball = false; //anti-camp ent->suicide_timeout = level.time + 10.0; VectorClear (ent->velocity_accum); ent->old_velocities_current = -1; ent->old_velocities_count = 0; VectorCopy (mins, ent->mins); VectorCopy (maxs, ent->maxs); VectorClear (ent->velocity); // clear playerstate values memset (&ent->client->ps, 0, sizeof(client->ps)); //remove these if there are there if(ent->client->oldplayer) G_FreeEdict (ent->client->oldplayer); if(ent->client->chasecam) G_FreeEdict (ent->client->chasecam); client->ps.fov = atoi(Info_ValueForKey(client->pers.userinfo, "fov")); if (client->ps.fov < 1) client->ps.fov = 90; else if (client->ps.fov > 160) client->ps.fov = 160; client->ps.gunindex = gi.modelindex(client->pers.weapon->view_model); // clear entity state values ent->s.effects = 0; ent->s.skinnum = ent - g_edicts - 1; ent->s.modelindex = 255; // will use the skin specified model ent->s.modelindex2 = 255; // custom gun model info = Info_ValueForKey (ent->client->pers.userinfo, "skin"); i = 0; done = false; strcpy(playermodel, " "); while(!done) { if((info[i] == '/') || (info[i] == '\\')) done = true; playermodel[i] = info[i]; if(i > 62) done = true; i++; } playermodel[i-1] = 0; sprintf(modelpath, "players/%s/helmet.md2", playermodel); Q2_FindFile (modelpath, &file); //does a helmet exist? if(file) { sprintf(modelpath, "players/%s/helmet.md2", playermodel); ent->s.modelindex3 = gi.modelindex(modelpath); fclose(file); } else ent->s.modelindex3 = 0; ent->s.modelindex4 = 0; //check for class file #ifdef ALTERIA ent->ctype = 0; //wizard is default sprintf(modelpath, "players/%s/human", playermodel); Q2_FindFile (modelpath, &file); if(file) { //warrior ent->ctype = 1; ent->health = ent->max_health = client->pers.max_health = client->pers.health = 100; armor_index = ITEM_INDEX(FindItem("Jacket Armor")); client->pers.inventory[armor_index] += 30; client->pers.inventory[ITEM_INDEX(FindItem("Warriorpunch"))] = 1; item = FindItem("Warriorpunch"); client->pers.selected_item = ITEM_INDEX(item); client->pers.inventory[client->pers.selected_item] = 1; client->pers.weapon = item; fclose(file); } else { //wizard ent->health = ent->max_health = client->pers.max_health = client->pers.health = 150; client->pers.inventory[ITEM_INDEX(FindItem("Wizardpunch"))] = 1; //client->pers.inventory[ITEM_INDEX(FindItem("cells"))] = 100; //to to - blue or yellow mana item = FindItem("Wizardpunch"); client->pers.selected_item = ITEM_INDEX(item); client->pers.inventory[client->pers.selected_item] = 1; client->pers.weapon = item; } #else ent->ctype = 0; //alien is default sprintf(modelpath, "players/%s/human", playermodel); sprintf(ent->charModel, playermodel); Q2_FindFile (modelpath, &file); if(file) { fclose(file); //human ent->ctype = 1; if(g_tactical->integer || (classbased->value && !(rocket_arena->integer || instagib->integer || insta_rockets->value || excessive->value))) { if(g_tactical->integer) { //read class file(tactical only) //example: //100-150 (health) //0-3 (armor type) //0-1 (has bomb) //0-1 (has detonator) //0-1 (has mind eraser) //0-1 (has vaporizor) ParseClassFile(modelpath, ent); if(ent->has_bomb) { ent->client->pers.inventory[ITEM_INDEX(FindItem("Human Bomb"))] = 1; ent->client->pers.inventory[ITEM_INDEX(FindItem("bombs"))] = 1; //tactical note - humans will use same ammo, etc, just different weapons } item = FindItem("Blaster"); } else { ent->health = ent->max_health = client->pers.max_health = client->pers.health = 100; armor_index = ITEM_INDEX(FindItem("Jacket Armor")); client->pers.inventory[armor_index] += 30; client->pers.inventory[ITEM_INDEX(FindItem("Rocket Launcher"))] = 1; client->pers.inventory[ITEM_INDEX(FindItem("rockets"))] = 10; item = FindItem("Rocket Launcher"); } client->pers.selected_item = ITEM_INDEX(item); client->pers.inventory[client->pers.selected_item] = 1; client->pers.weapon = item; } } else { //robot - not used in tactical - should we kick them out at this point, or just let them continue on the alien team? sprintf(modelpath, "players/%s/robot", playermodel); Q2_FindFile (modelpath, &file); if(file && !g_tactical->integer) { ent->ctype = 2; if(classbased->value && !(rocket_arena->integer || instagib->integer || insta_rockets->value || excessive->value)) { ent->health = ent->max_health = client->pers.max_health = client->pers.health = 85; armor_index = ITEM_INDEX(FindItem("Combat Armor")); client->pers.inventory[armor_index] += 175; } fclose(file); } else { //alien ent->ctype = 0; if(g_tactical->integer || (classbased->value && !(rocket_arena->integer || instagib->integer || insta_rockets->value || excessive->value))) { ent->health = ent->max_health = client->pers.max_health = client->pers.health = 150; if(g_tactical->integer) { sprintf(modelpath, "players/%s/alien", playermodel); Q2_FindFile (modelpath, &file); if(file) { ParseClassFile(modelpath, ent); if(ent->has_bomb) { ent->client->pers.inventory[ITEM_INDEX(FindItem("Alien Bomb"))] = 1; ent->client->pers.inventory[ITEM_INDEX(FindItem("bombs"))] = 1; //tactical note - humans will use same ammo, etc, just different weapons } } item = FindItem("Blaster"); client->pers.selected_item = ITEM_INDEX(item); client->pers.inventory[client->pers.selected_item] = 0; item = FindItem("Alien Blaster"); } else { client->pers.inventory[ITEM_INDEX(FindItem("Alien Disruptor"))] = 1; client->pers.inventory[ITEM_INDEX(FindItem("cells"))] = 100; item = FindItem("Alien Disruptor"); } client->pers.selected_item = ITEM_INDEX(item); client->pers.inventory[client->pers.selected_item] = 1; client->pers.weapon = item; } } } #endif //has to be done after determining the class/team - note - we don't care about spawn distances in tactical if(g_tactical->integer) SelectSpawnPoint (ent, spawn_origin, spawn_angles); client->ps.pmove.origin[0] = spawn_origin[0]*8; client->ps.pmove.origin[1] = spawn_origin[1]*8; client->ps.pmove.origin[2] = spawn_origin[2]*8; ent->s.frame = 0; VectorCopy (spawn_origin, ent->s.origin); ent->s.origin[2] += 1; // make sure off ground VectorCopy (ent->s.origin, ent->s.old_origin); // set the delta angle for (i=0 ; i<3 ; i++) client->ps.pmove.delta_angles[i] = ANGLE2SHORT(spawn_angles[i] - client->resp.cmd_angles[i]); ent->s.angles[PITCH] = 0; ent->s.angles[YAW] = spawn_angles[YAW]; ent->s.angles[ROLL] = 0; VectorCopy (ent->s.angles, client->ps.viewangles); VectorCopy (ent->s.angles, client->v_angle); //spectator mode // spawn a spectator if ( client->pers.spectator != 0 ) { client->chase_target = NULL; client->resp.spectator = client->pers.spectator; ent->movetype = MOVETYPE_NOCLIP; ent->solid = SOLID_NOT; ent->svflags |= SVF_NOCLIENT; ent->client->ps.gunindex = 0; gi.linkentity (ent); return; } else if ( !g_duel->integer ) client->resp.spectator = 0; //end spectator mode if (!KillBox (ent)) { // could't spawn in? } ent->s.event = EV_OTHER_TELEPORT; //to fix "player flash" bug gi.linkentity (ent); // force the current weapon up client->newweapon = client->pers.weapon; ChangeWeapon (ent); client->spawnprotecttime = level.time; //unlagged if ( g_antilag->integer) { G_ResetHistory( ent ); // and this is as good a time as any to clear the saved state client->saved.leveltime = 0; } } //DUEL MODE void ClientPlaceInQueue(edict_t *ent) { int i; int highestpos, induel, numplayers; highestpos = induel = numplayers = 0; for (i = 0; i < g_maxclients->value; i++) { if(g_edicts[i+1].inuse && g_edicts[i+1].client) { if(g_edicts[i+1].client->pers.queue > highestpos) //only count players that are actually in highestpos = g_edicts[i+1].client->pers.queue; if(g_edicts[i+1].client->pers.queue && g_edicts[i+1].client->pers.queue < 3) induel++; if(g_edicts[i+1].client->pers.queue) //only count players that are actually in numplayers++; } } if(induel > 1) //make sure no more than two are in the duel at once if(highestpos < 2) highestpos = 2; //in case two people somehow managed to have pos 1 if(highestpos < numplayers) highestpos = numplayers; if(!ent->client->pers.queue) ent->client->pers.queue = highestpos+1; } void ClientCheckQueue(edict_t *ent) { int i; int numplayers = 0; if(ent->client->pers.queue > 2) { //everyone in line remains a spectator ent->client->pers.spectator = ent->client->resp.spectator = 1; ent->client->chase_target = NULL; ent->movetype = MOVETYPE_NOCLIP; ent->solid = SOLID_NOT; ent->svflags |= SVF_NOCLIENT; ent->client->ps.gunindex = 0; gi.linkentity (ent); } else { for (i = 0; i < g_maxclients->value; i++) { if(g_edicts[i+1].inuse && g_edicts[i+1].client) { if(!g_edicts[i+1].client->pers.spectator && g_edicts[i+1].client->pers.queue) numplayers++; } } if(numplayers < 3) //only put him in if there are less than two ent->client->pers.spectator = ent->client->resp.spectator = 0; } } void MoveClientsDownQueue(edict_t *ent) { int i; qboolean putonein = false; for (i = 0; i < g_maxclients->value; i++) { //move everyone down if(g_edicts[i+1].inuse && g_edicts[i+1].client) { if(g_edicts[i+1].client->pers.queue > ent->client->pers.queue) g_edicts[i+1].client->pers.queue--; if(!putonein && g_edicts[i+1].client->pers.queue == 2 && g_edicts[i+1].client->resp.spectator) { //make sure those who should be in game are g_edicts[i+1].client->pers.spectator = g_edicts[i+1].client->resp.spectator = false; g_edicts[i+1].svflags &= ~SVF_NOCLIENT; g_edicts[i+1].movetype = MOVETYPE_WALK; g_edicts[i+1].solid = SOLID_BBOX; if(!g_edicts[i+1].is_bot) PutClientInServer(g_edicts+i+1); else ACESP_PutClientInServer( g_edicts+i+1, true ); // respawn safe_bprintf(PRINT_HIGH, "%s has entered the duel!\n", g_edicts[i+1].client->pers.netname); putonein = true; } } } if(ent->client) ent->client->pers.queue = 0; } //END DUEL MODE #define MAX_MOTD_SIZE 500 /** @brief Read the MOTD file and send it to the client * * Try to open the MOTD file (first from the CVar setting, then from the * default location). If it is found, read it and send it to the client. * * @param ent the entity to send to * * @return true if the message was found and sent */ static qboolean SendMessageOfTheDay( edict_t * ent ) { FILE *file; char name[ MAX_OSPATH ]; qboolean found; int size; char motd[ MAX_MOTD_SIZE ]; found = false; if ( motdfile && motdfile->string && motdfile->string[0] ) { // look for custom message of the day file found = gi.FullPath( name, sizeof( name ), motdfile->string ); } if ( !found ) { // look for default message of the day file found = gi.FullPath( name, sizeof( name ), "motd.txt" ); } if ( !found || (file = fopen( name, "rb" )) == NULL ) { // No MOTD at all, or we can't read it return false; } // We successfully opened the file "motd.txt" - read it and close it size = fread( motd , 1 , MAX_MOTD_SIZE - 1 , file ); fclose( file ); // Make sure what we read is NULL-terminated motd[ size ] = 0; // If the file did contain data, print to the client if ( size ) { gi.centerprintf( ent , "%s" , motd ); } return ( size > 0 ); } /* ===================== ClientBeginDeathmatch A client has just connected to the server in deathmatch mode, so clear everything out before starting them. ===================== */ void ClientBeginDeathmatch (edict_t *ent) { G_InitEdict (ent); InitClientResp (ent->client); ent->dmteam = NO_TEAM; // locate ent at a spawn point if(!ent->client->pers.spectator) //fixes invisible player bugs caused by leftover svf_noclients ent->svflags &= ~SVF_NOCLIENT; PutClientInServer (ent); //kick and blackhole a player in tactical that is not using an authorized character! if(g_tactical->integer) { //we want to actually check their model to be one of the valid ones we use if(strcmp("martianenforcer", ent->charModel) && strcmp("martianwarrior", ent->charModel) && strcmp("martianoverlord", ent->charModel) && strcmp("lauren", ent->charModel) && strcmp("enforcer", ent->charModel) && strcmp("commander", ent->charModel)) { if ( ent->is_bot ) { ACESP_KickBot( ent ); } else { safe_bprintf(PRINT_HIGH, "%s was kicked for using invalid character class!\n", ent->client->pers.netname); ClientDisconnect (ent); } } } //in ctf, initially start in chase mode, and allow them to choose a team if( TEAM_GAME ) { ent->client->pers.spectator = 1; ent->client->chase_target = NULL; ent->client->resp.spectator = 1; ent->movetype = MOVETYPE_NOCLIP; ent->solid = SOLID_NOT; ent->svflags |= SVF_NOCLIENT; ent->client->ps.gunindex = 0; gi.linkentity (ent); //bring up scoreboard if not on a team if(ent->dmteam == NO_TEAM) { ent->client->showscores = true; CTFScoreboardMessage (ent, NULL, false); gi.unicast (ent, true); ent->teamset = true; // used to error check team skin } } //if duel mode, then check number of existing players. If more there are already two in the game, force //this player to spectator mode, and assign a queue position(we can use the spectator cvar for this) else if(g_duel->integer) { ClientPlaceInQueue(ent); ClientCheckQueue(ent); } // send effect gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_LOGIN); gi.multicast (ent->s.origin, MULTICAST_PVS); safe_bprintf (PRINT_HIGH, "%s entered the game\n", ent->client->pers.netname); // Send MOTD and enable MOTD protection if necessary if ( SendMessageOfTheDay( ent ) ) { ent->client->motd_frames = motdforce->integer; if ( ent->client->motd_frames < 0 ) { ent->client->motd_frames = 0; } } else { ent->client->motd_frames = 0; } if(g_callvote->value) safe_cprintf(ent, PRINT_HIGH, "Call voting is ^2ENABLED\n"); else safe_cprintf(ent, PRINT_HIGH, "Call voting is ^1DISABLED\n"); if(g_antilag->value) safe_cprintf(ent, PRINT_HIGH, "Antilag is ^2ENABLED\n"); else safe_cprintf(ent, PRINT_HIGH, "Antilag is ^1DISABLED\n"); //check bots with each player connect ACESP_LoadBots( ent ); // make sure all view stuff is valid ClientEndServerFrame (ent); } /* =========== ClientBegin called when a client has finished connecting, and is ready to be placed into the game. This will happen every level load. ============ */ void ClientBegin (edict_t *ent) { int i; ent->client = game.clients + (ent - g_edicts - 1); for(i = 0; i < 9; i++) { ent->client->resp.weapon_shots[i] = 0; ent->client->resp.weapon_hits[i] = 0; } ent->client->kill_streak = 0; ent->client->homing_shots = 0; ClientBeginDeathmatch (ent); } /* =========== ClientUserInfoChanged called whenever the player updates a userinfo variable. The game can override any of the settings in place (forcing skins or names, etc) before copying it off. ============ */ void ClientUserinfoChanged (edict_t *ent, char *userinfo, int whereFrom) { char *s; edict_t *cl_ent; int playernum; int i, j, k; qboolean duplicate, done, copychar; char playermodel[MAX_OSPATH] = " "; char playerskin[MAX_INFO_STRING] = " "; char modelpath[MAX_OSPATH] = " "; char slot[4]; char tmp_playername[PLAYERNAME_SIZE]; FILE *file; teamcensus_t teamcensus; // check for malformed or illegal info strings if (!Info_Validate(userinfo)) { if(ent->dmteam == RED_TEAM) strcpy (userinfo, "\\name\\badinfo\\skin\\martianenforcer/red"); else if(ent->dmteam == BLUE_TEAM) strcpy (userinfo, "\\name\\badinfo\\skin\\martianenforcer/blue"); else strcpy (userinfo, "\\name\\badinfo\\skin\\martianenforcer/default"); ent->s.modelindex3 = gi.modelindex("players/martianenforcer/helmet.md2"); } if(whereFrom != SPAWN && whereFrom != CONNECT) whereFrom = INGAME; if((playervote.called || g_tactical->integer ) && whereFrom == INGAME) return; //do not allow people to change info during votes or in tactical mode(yet) /*if(((dmflags->integer & DF_SKINTEAMS) || ctf->value || tca->value || cp->value) && !whereFrom && (ent->dmteam != NO_TEAM)) { safe_bprintf (PRINT_MEDIUM, "Changing settings not allowed during a team game\n"); return; }*/ // validate and set name s = Info_ValueForKey (userinfo, "name"); if ( s == NULL || *s == 0 ) s = "Player"; Q_strncpyz2( tmp_playername, s , sizeof(tmp_playername) ); ValidatePlayerName( tmp_playername, sizeof(tmp_playername) ); Q_strncpyz2( ent->client->pers.netname, tmp_playername, sizeof(ent->client->pers.netname)); // end name validate //spectator mode if ( !g_duel->integer ) { // never fool with spectating in duel mode // set spectator s = Info_ValueForKey (userinfo, "spectator"); if ( TEAM_GAME ) { // if ( strcmp( s, "2" ) ) { // not special team game spectate // so make sure it stays 0 Info_SetValueForKey( userinfo, "spectator", "0"); } else { ent->client->pers.spectator = 2; } } else { if ( deathmatch->value && *s && strcmp(s, "0") ) ent->client->pers.spectator = atoi(s); else ent->client->pers.spectator = 0; } } //end spectator mode // set skin s = Info_ValueForKey (userinfo, "skin"); // do the team skin check if ( TEAM_GAME && ent->client->pers.spectator != 2 && ent->client->resp.spectator != 2 ) { copychar = false; strcpy( playerskin, " " ); strcpy( playermodel, " " ); j = k = 0; for ( i = 0; i <= strlen( s ) && i < MAX_OSPATH; i++ ) { if(copychar){ playerskin[k] = s[i]; k++; } else { playermodel[j] = s[i]; j++; } if ( s[i] == '/' ) copychar = true; } playermodel[j] = 0; if ( whereFrom != SPAWN && whereFrom != CONNECT && ent->teamset ) { // ingame and team is supposed to be set, error check skin if ( strcmp( playerskin, "red" ) && strcmp( playerskin, "blue" ) ) { // skin error, fix team assignment ent->dmteam = NO_TEAM; TeamCensus( &teamcensus ); // apply team balancing rules ent->dmteam = teamcensus.team_for_real; safe_bprintf( PRINT_MEDIUM, "Invalid Team Skin! Assigning to %s Team...\n", (ent->dmteam == RED_TEAM ? "Red" : "Blue") ); ClientBegin( ent ); // this might work } } strcpy( playerskin, (ent->dmteam == RED_TEAM ? "red" : "blue") ); if(strlen(playermodel) > 32) //something went wrong, or somebody is being malicious strcpy(playermodel, "martianenforcer/"); strcpy(s, playermodel); strcat(s, playerskin); Info_SetValueForKey (userinfo, "skin", s); } // end skin check playernum = ent-g_edicts-1; //check for duplicates(but not on respawns) duplicate = false; if(whereFrom != SPAWN) { for (j=0; jvalue ; j++) { cl_ent = g_edicts + 1 + j; if (!cl_ent->inuse) continue; if(!strcmp(ent->client->pers.netname, cl_ent->client->pers.netname)) { if(playernum != j) duplicate = true; } } if(duplicate && playernum < 100) { //just paranoia, should never be more than 64 #if defined WIN32_VARIANT i = sprintf_s(slot, sizeof(slot), "%i", playernum); #else i = snprintf(slot, sizeof(slot), "%i", playernum); #endif if ( strlen(ent->client->pers.netname) < (PLAYERNAME_SIZE - i) ) { //small enough, just add to end strcat(ent->client->pers.netname, slot); } else { //need to lop off end first TODO: technically, should look for color escapes ent->client->pers.netname[ (PLAYERNAME_SIZE-1) - i ] = 0; strcat(ent->client->pers.netname, slot); } Info_SetValueForKey (userinfo, "name", ent->client->pers.netname); safe_bprintf(PRINT_HIGH, "Was a duplicate, changing name to %s\n", ent->client->pers.netname); } } // end duplicate check // combine name and skin into a configstring gi.configstring (CS_PLAYERSKINS+playernum, va("%s\\%s", ent->client->pers.netname, s) ); s = Info_ValueForKey (userinfo, "skin"); i = 0; done = false; strcpy(playermodel, " "); while(!done) { if((s[i] == '/') || (s[i] == '\\')) done = true; playermodel[i] = s[i]; if(i > 62) done = true; i++; } playermodel[i-1] = 0; sprintf(modelpath, "players/%s/helmet.md2", playermodel); Q2_FindFile (modelpath, &file); //does a helmet exist? if(file) { sprintf(modelpath, "players/%s/helmet.md2", playermodel); ent->s.modelindex3 = gi.modelindex(modelpath); fclose(file); } else ent->s.modelindex3 = 0; ent->s.modelindex4 = 0; //do gib checking here - to do - let's replace these model specific gibs with class type specific(alien/robot/human) //check for gib file ent->usegibs = 0; //alien is default sprintf(modelpath, "players/%s/usegibs", playermodel); Q2_FindFile (modelpath, &file); if(file) { //use model specific gibs ent->usegibs = 1; sprintf(ent->head, "players/%s/head.md2", playermodel); sprintf(ent->body, "players/%s/body.md2", playermodel); sprintf(ent->leg, "players/%s/leg.md2", playermodel); sprintf(ent->arm, "players/%s/arm.md2", playermodel); fclose(file); } // fov ent->client->ps.fov = atoi(Info_ValueForKey(userinfo, "fov")); if (ent->client->ps.fov < 1) ent->client->ps.fov = 90; else if (ent->client->ps.fov > 160) ent->client->ps.fov = 160; // handedness s = Info_ValueForKey (userinfo, "hand"); if (strlen(s)) { ent->client->pers.hand = atoi(s); } // save off the userinfo in case we want to check something later Q_strncpyz2( ent->client->pers.userinfo, userinfo, sizeof(ent->client->pers.userinfo) ); } void ClientChangeSkin (edict_t *ent) { char *s; int playernum; int i, j, k, copychar; char playermodel[MAX_OSPATH] = " "; char playerskin[MAX_INFO_STRING] = " "; char userinfo[MAX_INFO_STRING]; char tmp_playername[PLAYERNAME_SIZE]; //get the userinfo memcpy (userinfo, ent->client->pers.userinfo, sizeof(userinfo)); // check for malformed or illegal info strings if (!Info_Validate(userinfo)) { if(ent->dmteam == RED_TEAM) strcpy (userinfo, "\\name\\badinfo\\skin\\martianenforcer/red"); else if(ent->dmteam == BLUE_TEAM) strcpy (userinfo, "\\name\\badinfo\\skin\\martianenforcer/blue"); else strcpy (userinfo, "\\name\\badinfo\\skin\\martianenforcer/default"); ent->s.modelindex3 = gi.modelindex("players/martianenforcer/helmet.md2"); } // set name s = Info_ValueForKey (userinfo, "name"); // fix player name if corrupted if ( s != NULL && s[0] ) { Q_strncpyz2( tmp_playername, s, sizeof(tmp_playername ) ); ValidatePlayerName( tmp_playername, sizeof(tmp_playername ) ); Q_strncpyz2(ent->client->pers.netname, tmp_playername, sizeof(ent->client->pers.netname) ); } // set skin s = Info_ValueForKey (userinfo, "skin"); copychar = false; strcpy(playerskin, " "); strcpy(playermodel, " "); j = k = 0; for(i = 0; i <= strlen(s) && i < MAX_OSPATH; i++) { if(copychar){ playerskin[k] = s[i]; k++; } else { playermodel[j] = s[i]; j++; } if(s[i] == '/') copychar = true; } playermodel[j] = 0; if( ent->dmteam == BLUE_TEAM) { if ( !ent->is_bot ) safe_bprintf (PRINT_MEDIUM, "Joined Blue Team...\n"); strcpy(playerskin, "blue"); } else { if ( !ent->is_bot ) safe_bprintf (PRINT_MEDIUM, "Joined Red Team...\n"); strcpy(playerskin, "red"); } if(strlen(playermodel) > 32) //something went wrong, or somebody is being malicious strcpy(playermodel, "martianenforcer/"); strcpy(s, playermodel); strcat(s, playerskin); Info_SetValueForKey (userinfo, "skin", s); playernum = ent-g_edicts-1; // combine name and skin into a configstring gi.configstring (CS_PLAYERSKINS+playernum, va("%s\\%s", ent->client->pers.netname, s) ); // fov ent->client->ps.fov = atoi(Info_ValueForKey(userinfo, "fov")); if (ent->client->ps.fov < 1) ent->client->ps.fov = 90; else if (ent->client->ps.fov > 160) ent->client->ps.fov = 160; // handedness s = Info_ValueForKey (userinfo, "hand"); if (strlen(s)) { ent->client->pers.hand = atoi(s); } // save off the userinfo in case we want to check something later strncpy (ent->client->pers.userinfo, userinfo, sizeof(ent->client->pers.userinfo)-1); } /* =========== ClientConnect Called when a player begins connecting to the server. The game can refuse entrance to a client by returning false. If the client is allowed, the connection process will continue and eventually get to ClientBegin() Changing levels will NOT cause this to be called again, but loadgames will. ============ */ qboolean ClientConnect (edict_t *ent, char *userinfo) { char *value; int i, numspec; // check to see if they are on the banned IP list value = Info_ValueForKey (userinfo, "ip"); if (SV_FilterPacket(value)) { Info_SetValueForKey(userinfo, "rejmsg", "Banned."); return false; } //spectator mode // check for a spectator value = Info_ValueForKey (userinfo, "spectator"); if ( TEAM_GAME && strcmp(value, "0") ) { // for team game, force spectator off Info_SetValueForKey( userinfo, "spectator", "0" ); ent->client->pers.spectator = 0; } if (deathmatch->value && *value && strcmp(value, "0")) { value = Info_ValueForKey( userinfo, "spectator_password" ); if (*spectator_password->string && strcmp(spectator_password->string, "none") && strcmp(spectator_password->string, value)) { Info_SetValueForKey(userinfo, "rejmsg", "Spectator password required or incorrect."); return false; } // count spectators for (i = numspec = 0; i < g_maxclients->value; i++) if (g_edicts[i+1].inuse && g_edicts[i+1].client->pers.spectator) numspec++; if (numspec >= maxspectators->value) { Info_SetValueForKey(userinfo, "rejmsg", "Server spectator limit is full."); return false; } } else if(!ent->is_bot){ // check for a password value = Info_ValueForKey (userinfo, "password"); if (*password->string && strcmp(password->string, "none") && strcmp(password->string, value)) { Info_SetValueForKey(userinfo, "rejmsg", "Password required or incorrect."); return false; } } //end specator mode // they can connect ent->client = game.clients + (ent - g_edicts - 1); // if there is already a body waiting for us (a loadgame), just // take it, otherwise spawn one from scratch if (ent->inuse == false) { // clear the respawning variables InitClientResp (ent->client); if (!game.autosaved || !ent->client->pers.weapon) InitClientPersistant (ent->client); } // for real players in team games, team is to be selected ent->dmteam = NO_TEAM; ent->teamset = false; ClientUserinfoChanged (ent, userinfo, CONNECT); if (game.maxclients > 1) gi.dprintf ("%s connected\n", ent->client->pers.netname); ent->client->pers.connected = true; return true; } /* =========== ClientDisconnect Called when a player drops from the server. Will not be called between levels. ============ */ void ClientDisconnect (edict_t *ent) { int playernum, i; if (!ent->client) return; safe_bprintf (PRINT_HIGH, "%s disconnected\n", ent->client->pers.netname); if(ctf->value) { //if carrying flag, don't take it with you! no attacker points. CTFDeadDropFlag(ent, NULL); } DeadDropDeathball(ent); if(ent->deadflag && ent->client->chasetoggle == 1) DeathcamRemove(ent, "off"); //if in duel mode, we need to bump people down the queue if its the player in game leaving if(g_duel->integer) { MoveClientsDownQueue(ent); if(!ent->client->resp.spectator) { for (i = 0; i < g_maxclients->value; i++) //clear scores if player was in duel if(g_edicts[i+1].inuse && g_edicts[i+1].client && !g_edicts[i+1].is_bot) g_edicts[i+1].client->resp.score = 0; } } // send effect gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_LOGOUT); gi.multicast (ent->s.origin, MULTICAST_PVS); gi.unlinkentity (ent); ent->s.modelindex = 0; ent->s.effects = 0; ent->s.sound = 0; ent->solid = SOLID_NOT; ent->inuse = false; ent->classname = "disconnected"; ent->client->pers.connected = false; playernum = ent-g_edicts-1; gi.configstring (CS_PLAYERSKINS+playernum, ""); // if using bot thresholds, put the bot back in(duel always uses them) if ( sv_botkickthreshold->integer || g_duel->integer ) { ACESP_LoadBots( ent ); } } //============================================================== edict_t *pm_passent; // pmove doesn't need to know about passent and contentmask trace_t PM_trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end) { if (pm_passent->health > 0) return gi.trace (start, mins, maxs, end, pm_passent, MASK_PLAYERSOLID); else return gi.trace (start, mins, maxs, end, pm_passent, MASK_DEADSOLID); } unsigned CheckBlock (void *b, int c) { int v,i; v = 0; for (i=0 ; is, sizeof(pm->s)); c2 = CheckBlock (&pm->cmd, sizeof(pm->cmd)); Com_Printf ("sv %3i:%i %i\n", pm->cmd.impulse, c1, c2); } /* ====== TeamCensus tallies up players and bots in game used by auto bot kick, and auto team selection implements team balancing rules ====== */ void TeamCensus( teamcensus_t *teamcensus ) { int i; int diff; int dmteam; int red_sum; int blue_sum; int real_red = 0; int real_blue = 0; int bots_red = 0; int bots_blue = 0; int team_for_real = NO_TEAM; int team_for_bot = NO_TEAM; for ( i = 1; i <= game.maxclients; i++ ) { // count only clients that have joined teams if ( g_edicts[i].inuse ) { dmteam = g_edicts[i].dmteam; if ( g_edicts[i].is_bot ) { if ( dmteam == RED_TEAM ) { ++bots_red; } else if ( dmteam == BLUE_TEAM ) { ++bots_blue; } } else { if ( dmteam == RED_TEAM ) { ++real_red; } else if ( dmteam == BLUE_TEAM ) { ++real_blue; } } } } red_sum = real_red + bots_red; blue_sum = real_blue + bots_blue; // team balancing rules if ( red_sum == blue_sum ) { // teams are of equal size if ( bots_blue == bots_red ) { // with equal number of both real players and bots // assign by scoring or random selection if ( red_team_score > blue_team_score ) { // leader gets the bot // real player being a good sport joins the team that is behind if ( tca->integer ) { team_for_bot = BLUE_TEAM; team_for_real = RED_TEAM; } else { team_for_bot = RED_TEAM; team_for_real = BLUE_TEAM; } } else if ( blue_team_score > red_team_score ) { if ( tca->integer ) { team_for_bot = RED_TEAM; team_for_real = BLUE_TEAM; } else { team_for_bot = BLUE_TEAM; team_for_real = RED_TEAM; } } else if ( rand() & 1 ) { team_for_real = team_for_bot = RED_TEAM; } else { team_for_real = team_for_bot = BLUE_TEAM; } } else if ( bots_blue > bots_red ) { // with more blue bots than red // put bot on team with fewer bots (red) // real player on team with fewer real players (blue) team_for_bot = RED_TEAM; team_for_real = BLUE_TEAM; } else { // with more red bots than blue // put bot on team with fewer bots (blue) // real player on team with fewer real players (red) team_for_bot = BLUE_TEAM; team_for_real = RED_TEAM; } } else { // teams are of unequal size diff = red_sum - blue_sum; if ( diff > 1 ) { // red is 2 or more larger team_for_real = team_for_bot = BLUE_TEAM; } else if ( diff < -1 ) { // blue is 2 or more larger team_for_real = team_for_bot = RED_TEAM; } else if ( real_blue == real_red ) { // with equal numbers of real players if ( bots_blue > bots_red ) { // blue team is larger by 1 bot team_for_real = team_for_bot = RED_TEAM; } else { // red_team is larger by 1 bot team_for_real = team_for_bot = BLUE_TEAM; } } else { // with equal numbers of bots if ( real_blue > real_red ) { // blue team is larger by 1 real player team_for_real = team_for_bot = RED_TEAM; } else { // red team is larger by 1 real player team_for_real = team_for_bot = BLUE_TEAM; } } } teamcensus->total = red_sum + blue_sum; // sum of all teamcensus->real = real_red + real_blue; // sum of real players teamcensus->bots = bots_red + bots_blue; // sum of bots teamcensus->red = real_red + bots_red; // sum of red team members teamcensus->blue = real_blue + bots_blue; // sum of blue team members teamcensus->real_red = real_red; // red team players in game teamcensus->real_blue = real_blue; // blue team players in game teamcensus->bots_red = bots_red; // red team bots in game teamcensus->bots_blue = bots_blue; // blue team bots in game teamcensus->team_for_real = team_for_real; // team for real player to join teamcensus->team_for_bot = team_for_bot; // team for bot to join } /** @brief Handle clients that are in "team selection" mode * * @todo this function needs cleaning up - if we set spectator mode to 0, we * can return from the function; if that is done, then we no longer need * to make sure that the client is not in a team in the rest of the * function. * * @param ent entity of the client * @param client the client itself * @param ucmd user command from the client */ static inline void ClientTeamSelection( edict_t * ent , gclient_t * client , usercmd_t * ucmd ) { teamcensus_t teamcensus; if ( client->pers.spectator == 2 ) { // entered with special team spectator mode on // force it off, does not appear to help much. (?) ent->dmteam = NO_TEAM; client->pers.spectator = 0; } if ( ent->dmteam == RED_TEAM || ent->dmteam == BLUE_TEAM ) { client->pers.spectator = 0; } if ( level.time / 2 == ceil( level.time / 2 ) && client->pers.spectator == 1 && ent->dmteam == NO_TEAM ) { // send "how to join" message if ( g_autobalance->integer ) { safe_centerprintf( ent, "\n\n\nPress to join\n" "autobalanced team\n" ); } else { safe_centerprintf( ent, "\n\n\nPress to autojoin\n" "or to join BLUE\n" "or to join RED\n" ); } } if ( client->latched_buttons & BUTTON_ATTACK ) { // to auto join client->latched_buttons = 0; if ( client->pers.spectator == 1 && ent->dmteam == NO_TEAM) { TeamCensus( &teamcensus ); // apply team balance rules ent->dmteam = teamcensus.team_for_real; client->pers.spectator = 0; ClientChangeSkin( ent ); } } if ( ucmd->upmove >= 10 && ent->dmteam == NO_TEAM ) { if ( !g_autobalance->integer ) { // jump to join blue ent->dmteam = BLUE_TEAM; client->pers.spectator = 0; ClientChangeSkin( ent ); } } else if ( ucmd->upmove < 0 && ent->dmteam == NO_TEAM ) { if ( !g_autobalance->integer ) { // crouch to join red ent->dmteam = RED_TEAM; client->pers.spectator = 0; ClientChangeSkin( ent ); } } else { client->ps.pmove.pm_flags &= ~PMF_JUMP_HELD; } } /* ============== ClientThink This will be called once for each client frame, which will usually be a couple times for each server frame. ============== */ void ClientThink (edict_t *ent, usercmd_t *ucmd) { gclient_t *client; edict_t *other; int i, j, mostvotes, n_candidates; int map_candidates[4]; pmove_t pm; qboolean sproing, haste; vec3_t addspeed, forward, up, right; level.current_entity = ent; client = ent->client; // If the MOTD is being forced on, decrease frame counter // and re-send the file if necessary if ( client->motd_frames ) { if ( level.time - floor( level.time ) != 0 ) { SendMessageOfTheDay( ent ); } client->motd_frames --; } //unlagged if ( g_antilag->integer) client->attackTime = gi.Sys_Milliseconds(); if (level.intermissiontime) { client->ps.pmove.pm_type = PM_FREEZE; // can exit intermission after 10 seconds, or 20 if map voting enables // (voting will only work if g_mapvote wasn't modified during intermission) if (g_mapvote->value && ! g_mapvote->modified) { //print out results, track winning map mostvotes = 0; for (j = 0; j < 4; j++) { if (votedmap[j].tally > mostvotes) mostvotes = votedmap[j].tally; } if ( g_voterand && g_voterand->value ) { // we're using a random value for the next map // if a choice needs to be done n_candidates = 0; for ( j = 0 ; j < 4 ; j ++ ) { if ( votedmap[j].tally < mostvotes ) continue; map_candidates[n_candidates ++] = j; } j = random() * (n_candidates - 1); level.changemap = votedmap[map_candidates[j]].mapname; } else { // "old" voting system, take the first map that // has enough votes for ( j = 0 ; j < 4 ; j ++ ) { i = (j + 1) % 4; if ( votedmap[i].tally < mostvotes ) continue; level.changemap = votedmap[i].mapname; break; } } if (level.time > level.intermissiontime + 20.0 && (ucmd->buttons & BUTTON_ANY) ) level.exitintermission = true; } else { if (level.time > level.intermissiontime + 10.0 && (ucmd->buttons & BUTTON_ANY) ) level.exitintermission = true; } return; } else if ( g_mapvote && g_mapvote->modified ) { g_mapvote->modified = false; } pm_passent = ent; if (ent->client->chase_target) { client->resp.cmd_angles[0] = SHORT2ANGLE(ucmd->angles[0]); client->resp.cmd_angles[1] = SHORT2ANGLE(ucmd->angles[1]); client->resp.cmd_angles[2] = SHORT2ANGLE(ucmd->angles[2]); } else { // set up for pmove memset (&pm, 0, sizeof(pm)); if (ent->movetype == MOVETYPE_NOCLIP) client->ps.pmove.pm_type = PM_SPECTATOR; else if (ent->s.modelindex != 255 && !(ent->in_vehicle) && !(client->chasetoggle)) //for vehicles or deathcam client->ps.pmove.pm_type = PM_GIB; else if (ent->deadflag) client->ps.pmove.pm_type = PM_DEAD; else client->ps.pmove.pm_type = PM_NORMAL; if(!client->chasetoggle) { client->ps.pmove.gravity = sv_gravity->value; } else { /* No gravity to move the deathcam */ client->ps.pmove.gravity = 0; } //vehicles if ( Jet_Active(ent) ) Jet_ApplyJet( ent, ucmd ); pm.s = client->ps.pmove; for (i=0 ; i<3 ; i++) { pm.s.origin[i] = ent->s.origin[i]*8; pm.s.velocity[i] = ent->velocity[i]*8; } if (memcmp(&client->old_pmove, &pm.s, sizeof(pm.s))) { pm.snapinitial = true; } if(g_tactical->integer) { //limit acceleration if(ucmd->forwardmove > 200) ucmd->forwardmove = 200; if(ucmd->forwardmove < -200) ucmd->forwardmove = -200; if(ucmd->sidemove > 200) ucmd->sidemove = 200; if(ucmd->sidemove < -200) ucmd->sidemove = -200; } ucmd->forwardmove *= 1.3; //tactical if(g_tactical->integer) { client->dodge = false; } else { //dodging client->dodge = false; if((level.time - client->lastdodge) > 1.0 && ent->groundentity && ucmd->forwardmove == 0 && ucmd->sidemove != 0 && client->moved == false && client->keydown < 10 && ((level.time - client->lastmovetime) < .15)) { if((ucmd->sidemove < 0 && client->lastsidemove < 0) || (ucmd->sidemove > 0 && client->lastsidemove > 0)) { if(ucmd->sidemove > 0) client->dodge = 1; else client->dodge = -1; ucmd->upmove += 100; } } if((level.time - client->lastdodge) > 1.0 && ent->groundentity && ucmd->forwardmove != 0 && ucmd->sidemove == 0 && client->moved == false && client->keydown < 10 && ((level.time - client->lastmovetime) < .15)) { if((ucmd->forwardmove < 0 && client->lastforwardmove < 0) || (ucmd->forwardmove > 0 && client->lastforwardmove > 0)) { if(ucmd->forwardmove > 0) client->dodge = 2; else client->dodge = -2; ucmd->upmove += 100; } } } //checking previous frame's movement if(client->moved == true && (ucmd->buttons & BUTTON_ANY)) { client->keydown++; } else if (ucmd->sidemove != 0 || ucmd->forwardmove != 0) { client->keydown = 0; } if(ucmd->sidemove != 0 || ucmd->forwardmove != 0) { client->lastmovetime = level.time; client->lastsidemove = ucmd->sidemove; client->lastforwardmove = ucmd->forwardmove; client->moved = true; } else //we had a frame with no movement client->moved = false; pm.cmd = *ucmd; pm.trace = PM_trace; // adds default parms pm.pointcontents = gi.pointcontents; //joust mode if(joustmode->value) { if(ent->groundentity) client->joustattempts = 0; if(pm.cmd.upmove >= 10) { client->joustattempts++; pm.joustattempts = client->joustattempts; if(pm.joustattempts == 10 || pm.joustattempts == 20) { gi.sound(ent, CHAN_VOICE, gi.soundindex("*jump1.wav"), 1, ATTN_NORM, 0); PlayerNoise(ent, ent->s.origin, PNOISE_SELF); } } } // perform a pmove gi.Pmove (&pm); // save results of pmove client->ps.pmove = pm.s; client->old_pmove = pm.s; for (i=0 ; i<3 ; i++) { ent->s.origin[i] = pm.s.origin[i]*0.125; ent->velocity[i] = pm.s.velocity[i]*0.125; } //check for a dodge, and peform if true if(client->dodge != 0) { //check for dodge direction if(client->dodge == 2 || client->dodge == -2) { //was forward or backward AngleVectors (ent->s.angles, addspeed, right, up); client->dodge /= 2; } else { //was sideways AngleVectors (ent->s.angles, forward, addspeed, up); } addspeed[0] *= 300*client->dodge; addspeed[1] *= 300*client->dodge; VectorAdd(ent->velocity, addspeed, ent->velocity); //check velocity SV_CheckVelocity(ent); client->dodge = false; client->lastdodge = client->lastmovetime = level.time; } VectorCopy (pm.mins, ent->mins); VectorCopy (pm.maxs, ent->maxs); client->resp.cmd_angles[0] = SHORT2ANGLE(ucmd->angles[0]); client->resp.cmd_angles[1] = SHORT2ANGLE(ucmd->angles[1]); client->resp.cmd_angles[2] = SHORT2ANGLE(ucmd->angles[2]); //vehicles if ( Jet_Active(ent) ) if( pm.groundentity ) /*are we on ground*/ if ( Jet_AvoidGround(ent) ) /*then lift us if possible*/ pm.groundentity = NULL; /*now we are no longer on ground*/ if (ent->groundentity && !pm.groundentity && (pm.cmd.upmove >= 10) && (pm.waterlevel == 0)) { sproing = client->sproing_framenum > level.framenum; haste = client->haste_framenum > level.framenum; if(sproing) { gi.sound(ent, CHAN_VOICE, gi.soundindex("items/sproing.wav"), 1, ATTN_NORM, 0); ent->velocity[2] += 400; } if(haste && ucmd->forwardmove > 0) { AngleVectors (ent->s.angles, addspeed, right, up); addspeed[0] *= 400; addspeed[1] *= 400; for(i = 0; i < 2; i++) { if(addspeed[i] > 200) addspeed[i] = 200; } VectorAdd(ent->velocity, addspeed, ent->velocity); gi.sound(ent, CHAN_VOICE, gi.soundindex("items/haste.wav"), 1, ATTN_NORM, 0); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_EXPLOSION2); gi.WritePosition (ent->s.origin); gi.multicast (ent->s.origin, MULTICAST_PVS); } else gi.sound(ent, CHAN_VOICE, gi.soundindex("*jump1.wav"), 1, ATTN_NORM, 0); PlayerNoise(ent, ent->s.origin, PNOISE_SELF); } ent->viewheight = pm.viewheight; ent->waterlevel = pm.waterlevel; ent->watertype = pm.watertype; ent->groundentity = pm.groundentity; if (pm.groundentity) ent->groundentity_linkcount = pm.groundentity->linkcount; if (ent->deadflag) { client->ps.viewangles[ROLL] = 40; client->ps.viewangles[PITCH] = -15; client->ps.viewangles[YAW] = client->killer_yaw; } else { VectorCopy (pm.viewangles, client->v_angle); VectorCopy (pm.viewangles, client->ps.viewangles); } if (client->ctf_grapple) CTFGrapplePull(client->ctf_grapple); gi.linkentity (ent); if (ent->movetype != MOVETYPE_NOCLIP) G_TouchTriggers (ent); // touch other objects for (i=0 ; itouch) continue; other->touch (other, ent, NULL, NULL); } } client->oldbuttons = client->buttons; client->buttons = ucmd->buttons; client->latched_buttons |= client->buttons & ~client->oldbuttons; // save light level the player is standing on for // monster sighting AI ent->light_level = ucmd->lightlevel; if ( client->resp.spectator == 0 ) { // regular (non-spectator) mode if (client->latched_buttons & BUTTON_ATTACK) { if (!client->weapon_thunk) { client->weapon_thunk = true; Think_Weapon (ent); } } } else { // spectator mode if ( TEAM_GAME && client->resp.spectator < 2 ) { // team selection state ClientTeamSelection( ent , client , ucmd ); } /* team selection state */ else { // regular spectator if ( client->latched_buttons & BUTTON_ATTACK ) { client->latched_buttons = 0; if ( client->chase_target ) { client->chase_target = NULL; client->ps.pmove.pm_flags &= ~PMF_NO_PREDICTION; } else { GetChaseTarget( ent ); } } if ( ucmd->upmove >= 10 ) { if ( !(client->ps.pmove.pm_flags & PMF_JUMP_HELD) ) { client->ps.pmove.pm_flags |= PMF_JUMP_HELD; if ( client->chase_target ) ChaseNext( ent ); else GetChaseTarget( ent ); } } else { client->ps.pmove.pm_flags &= ~PMF_JUMP_HELD; } } /* regular spectator */ } /* spectator mode */ // update chase cam if being followed for (i = 1; i <= g_maxclients->value; i++) { other = g_edicts + i; if (other->inuse && other->client->chase_target == ent) UpdateChaseCam(other); } //mutators if((regeneration->value || excessive->value) && !ent->deadflag) { if((ent->health < ent->max_health) && (client->regen_framenum < level.framenum)) { client->regen_framenum = level.framenum + 5; ent->health+=2; } } //spawn protection has run out if(level.time > ent->client->spawnprotecttime + g_spawnprotect->integer) ent->client->spawnprotected = false; //lose one health every second if(g_losehealth->value && !ent->deadflag) { if(regeneration->value || excessive->value || vampire->value) return; if((ent->health > g_losehealth_num->value) && (client->losehealth_framenum < level.framenum)) { client->losehealth_framenum = level.framenum + 10; ent->health-=1; } } } /** @brief Update the anti-camp timeout * * The anti-camp computation accumulates players' velocities, averages them * and updates the "suicide_timeout" field if the length of that average * vector is above some threshold. * * It is controlled by the camptime, ac_frames and ac_threshold CVars. */ static inline void _UpdateAntiCamp( edict_t * ent ) { int n_frames = ac_frames->integer; float thresh; vec3_t avg; // Make sure we have a valid ac_frames if ( n_frames < 1 || n_frames > 100 ) { n_frames = G_ANTICAMP_FRAMES; } if ( ent->old_velocities_count < n_frames ) { // Not enough frames yet ent->old_velocities_count ++; ent->old_velocities_current ++; } else { // Enough frames - remove oldest known velocity from // accumulator ent->old_velocities_current = ( ent->old_velocities_current + 1 ) % n_frames; VectorSubtract( ent->velocity_accum , ent->old_velocities[ ent->old_velocities_current ] , ent->velocity_accum ); } // Store current velocity into history and add its value to the // accumulator VectorCopy( ent->velocity , ent->old_velocities[ ent->old_velocities_current ] ); VectorAdd( ent->velocity_accum , ent->velocity , ent->velocity_accum ); if ( ent->old_velocities_count < n_frames ) { return; } // Get and adjust speed threshold thresh = ac_threshold->value; if ( thresh <= 0 || thresh > 500 ) { thresh = G_ANTICAMP_THRESHOLD; } if ( excessive->integer ) { thresh *= 1.5; } // Check average velocity lengths against threshold VectorCopy( ent->velocity_accum , avg ); avg[0] /= n_frames; avg[1] /= n_frames; avg[2] /= n_frames; if ( VectorLength( avg ) > thresh ) { ent->suicide_timeout = level.time + camptime->integer; } // Inflict anti-camp damage if ( ent->suicide_timeout < level.time && ent->takedamage == DAMAGE_AIM && ! ent->client->resp.spectator) { T_Damage (ent, world, world, vec3_origin, ent->s.origin, vec3_origin, ent->dmg, 0, DAMAGE_NO_ARMOR, MOD_SUICIDE); safe_centerprintf(ent, "Anticamp: move or die!\n"); } } /* ============== ClientBeginServerFrame This will be called once for each server frame, before running any other entities in the world. ============== */ void ClientBeginServerFrame (edict_t *ent) { gclient_t *client; int buttonMask; if (level.intermissiontime) return; client = ent->client; //spectator mode if ( deathmatch->value && client->pers.spectator != client->resp.spectator && (level.time - client->respawn_time) >= 5 ) { if ( TEAM_GAME && client->pers.spectator == 2 ) { // special team game spectator mode (has problems) if ( client->resp.spectator == 1 ) { // special team spectator mode spectator_respawn( ent ); client->resp.spectator = 2; } } else if ( TEAM_GAME && client->resp.spectator == 2 ) { // pers != resp, exit spectator mode not allowed client->pers.spectator = 2; } else { // enter or exit spectator mode spectator_respawn( ent ); } return; } //end spectator mode //anti-camp // do not apply to godmode cheat or bots. // bots have other suicidal tendencies which may (or may not) conflict. if ( anticamp->integer && !(ent->flags & FL_GODMODE) && !(ent->is_bot) ) { _UpdateAntiCamp( ent ); } //spectator mode if (!client->weapon_thunk && !client->resp.spectator) //end spectator mode Think_Weapon (ent); else client->weapon_thunk = false; if (ent->deadflag) { // wait for any button just going down if ( level.time > client->respawn_time) { // in deathmatch, only wait for attack button if (deathmatch->value) buttonMask = BUTTON_ATTACK | BUTTON_ATTACK2; else buttonMask = -1; //should probably add in a force respawn option if (( client->latched_buttons & buttonMask ) || (deathmatch->value && (dmflags->integer & DF_FORCE_RESPAWN) ) ) { if(!ent->is_bot) DeathcamRemove (ent, "off"); respawn(ent); client->latched_buttons = 0; } } return; } // add player trail so monsters can follow if (!deathmatch->value) if (!visible (ent, PlayerTrail_LastSpot() ) ) PlayerTrail_Add (ent->s.old_origin); client->latched_buttons = 0; } alien-arena-7.66+dfsg/source/game/g_main.c0000600000175000017500000011617112204310130017417 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. Copyright (C) 2010 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #if defined HAVE_UNISTD_H #include #endif #if defined HAVE_SYS_STAT_H #include #endif #if !defined HAVE__STRDUP #define _strdup strdup #endif #include "g_local.h" game_locals_t game; level_locals_t level; game_import_t gi; game_export_t globals; spawn_temp_t st; g_vote_t playervote; tactical_t tacticalScore; int sm_meat_index; int meansOfDeath; int bot_won; char *winningmap; edict_t *g_edicts; cvar_t *deathmatch; cvar_t *ctf; cvar_t *tca; cvar_t *cp; //mutators cvar_t *instagib; cvar_t *rocket_arena; cvar_t *insta_rockets; cvar_t *low_grav; cvar_t *regeneration; cvar_t *vampire; cvar_t *excessive; cvar_t *grapple; cvar_t *classbased; //duel mode cvar_t *g_duel; //tactical mode cvar_t *g_tactical; cvar_t *g_losehealth; cvar_t *g_losehealth_num; //weapons cvar_t *wep_selfdmgmulti; //health/max health/max ammo cvar_t *g_spawnhealth; cvar_t *g_maxhealth; cvar_t *g_maxbullets; cvar_t *g_maxshells; cvar_t *g_maxrockets; cvar_t *g_maxgrenades; cvar_t *g_maxcells; cvar_t *g_maxslugs; cvar_t *g_maxseekers; cvar_t *g_maxbombs; //quick weapon change cvar_t *quickweap; //anti-camp cvar_t *anticamp; cvar_t *camptime; //show player lights for visibility even in non-team games cvar_t *g_dmlights; /** @brief Anti-camp frames * * This CVar controls the amount of frames velocity is accumulated for when * trying to determine if a player is camping. Its valid range is 1-100, * anything outside this range will default it to the value of the * G_ANTICAMP_FRAMES constant. * * @note If the value is 1, the anti-camp will work exactly as it used to. * * @note This CVar's value should be high enough for the anti-camp to work * correctly (the higher it is, the more the system "remembers" about * players' previous velocities), but low enough and for it not to * punish players for camping long after they've resumed moving. */ cvar_t *ac_frames; /** @brief Anti-camp threshold * * This CVar contains the speed below which the timeout to "suicide" is no * longer updated. It will default to G_ANTICAMP_THRESHOLD if its value is * not in the ]0;500] range. * * @note In excessive mode, this value is multiplied by 1.5 */ cvar_t *ac_threshold; //random quad cvar_t *g_randomquad; //warmup cvar_t *warmuptime; //spawn protection cvar_t *g_spawnprotect; //joust mode cvar_t *joustmode; //map voting cvar_t *g_mapvote; cvar_t *g_voterand; cvar_t *g_votemode; cvar_t *g_votesame; //call voting cvar_t *g_callvote; //reward point threshold cvar_t *g_reward; //force autobalanced teams cvar_t *g_autobalance; cvar_t *dmflags; cvar_t *skill; cvar_t *fraglimit; cvar_t *timelimit; cvar_t *password; cvar_t *spectator_password; cvar_t *needpass; cvar_t *g_maxclients; cvar_t *maxspectators; cvar_t *maxentities; cvar_t *g_select_empty; cvar_t *g_dedicated; cvar_t *motdfile; /** @brief CVar that forces MOTD display * * This CVar should contain an integer, which will indicate how client frames * the MOTD should be forced on for. If it is 0, then the MOTD will not be * forced on. */ cvar_t *motdforce; cvar_t *filterban; cvar_t *sv_maxvelocity; cvar_t *sv_gravity; cvar_t *sv_rollspeed; cvar_t *sv_rollangle; cvar_t *gun_x; cvar_t *gun_y; cvar_t *gun_z; cvar_t *run_pitch; cvar_t *run_roll; cvar_t *bob_up; cvar_t *bob_pitch; cvar_t *bob_roll; cvar_t *sv_cheats; cvar_t *flood_msgs; cvar_t *flood_persecond; cvar_t *flood_waitdelay; cvar_t *sv_maplist; cvar_t *g_background_music; cvar_t *sv_botkickthreshold; cvar_t *sv_custombots; //unlagged cvar_t *g_antilag; cvar_t *g_antilagdebug; cvar_t *g_antilagprojectiles; void SpawnEntities (char *mapname, char *entities, char *spawnpoint); void ClientThink (edict_t *ent, usercmd_t *cmd); qboolean ClientConnect (edict_t *ent, char *userinfo); void ClientUserinfoChanged (edict_t *ent, char *userinfo, int whereFrom); void ClientDisconnect (edict_t *ent); void ClientBegin (edict_t *ent); void ClientCommand (edict_t *ent); void RunEntity (edict_t *ent); void InitGame (void); void G_RunFrame (void); int ACESP_FindBotNum(void); extern long filelength(int); extern void ED_CallSpawn (edict_t *ent); static size_t szr; static int g_filelength( FILE *f ) { int length = -1; #if defined HAVE_FILELENGTH length = filelength( fileno( f ) ); #elif defined HAVE_FSTAT struct stat statbfr; int result; result = fstat( fileno(f), &statbfr ); if ( result != -1 ) { length = (int)statbfr.st_size; } #else long int pos; pos = ftell( f ); fseek( f, 0L, SEEK_END ); length = ftell( f ); fseek( f, pos, SEEK_SET ); #endif return length; } //=================================================================== void ShutdownGame (void) { gi.dprintf ("==== ShutdownGame ====\n"); gi.FreeTags (TAG_LEVEL); gi.FreeTags (TAG_GAME); } /* ============= G_ForceExitIntermission To prevent those annoying occurrences when you join a server which has been idling at intermission for a long time, then it instantly switches maps as soon as the old one is done loading. Now new player joins will force intermission to end after twenty seconds, even if there are still players in the server. ============= */ void ExitLevel (void); void G_ForceExitIntermission (void) { if (level.time < level.intermissiontime + 20.0 || !level.intermissiontime) return; ExitLevel(); } /* ================= GetGameAPI Returns a pointer to the structure with all entry points and global variables ================= */ game_export_t *GetGameAPI (game_import_t *import) { gi = *import; globals.apiversion = GAME_API_VERSION; globals.Init = InitGame; globals.Shutdown = ShutdownGame; globals.SpawnEntities = SpawnEntities; globals.ClientThink = ClientThink; globals.ClientConnect = ClientConnect; globals.ClientUserinfoChanged = ClientUserinfoChanged; globals.ClientDisconnect = ClientDisconnect; globals.ClientBegin = ClientBegin; globals.ClientCommand = ClientCommand; globals.ACESP_FindBotNum = ACESP_FindBotNum; globals.RunFrame = G_RunFrame; globals.ForceExitIntermission = G_ForceExitIntermission; globals.ServerCommand = ServerCommand; globals.edict_size = sizeof(edict_t); return &globals; } #define Z_MAGIC 0x1d1d typedef struct zhead_s { struct zhead_s *prev, *next; short magic; short tag; int size; } zhead_t; zhead_t z_chain; int z_count, z_bytes; /* ================= ClientEndServerFrames ================= */ void ClientEndServerFrames (void) { int i; edict_t *ent; /* make sure bot info in first client is up to date */ ACESP_UpdateBots(); // calc the player views now that all pushing // and damage has been added for (i=0 ; ivalue ; i++) { ent = g_edicts + 1 + i; if (!ent->inuse || !ent->client) continue; ClientEndServerFrame (ent); } } /* ================= CreateTargetChangeLevel Returns the created target changelevel ================= */ edict_t *CreateTargetChangeLevel(char *map) { edict_t *ent; ent = G_Spawn (); ent->classname = "target_changelevel"; Com_sprintf(level.nextmap, sizeof(level.nextmap), "%s", map); ent->map = level.nextmap; return ent; } /** * \brief Log scores and stats * * \detail This is a somewhat crude formatted dump of game information to * the server console and log file. This version is mostly intended * to collect some data about bot targeting accuracy. * * The odds that the array indexes for the weapon hit data and weapon * accuracy data are correctly cross-referenced are slim. * * --- from hud stat report (p_hud.c) --- * --- currently def'd out --- * 0: "blaster" * 1: "disruptor" * 2: "smartgun" * 3: "chaingun" * 4: "flame" * 5: "rocket" * 6: "beamgun" * 7: "vaporizer" * 8: "violator" * *--- weapon_hit[] incremented --- * 0 : blasterball_touch : Weapon_Beamgun, Weapon_Blaster, Weapon_Hover * 0 : fire_blaster_beam : Weapon_Beamgun, Weapon_Blaster, Weapon_Alienblaster, Weapon_Strafer * 1 : fire_disruptor : Weapon_Disruptor * 2 : smartgrenade_think : Weapon_Smartgun * 3 : fire_lead : Weapon_Chain * 4 : fireball_touch : Weapon_Flame * 4 : flame_touch : Weapon_Flame * 5 : rocket_touch : Weapon_RocketLauncher, Weapon_Bomber, Weapon_Strafer * 6 : fire_blaster : Weapon_Beamgun, Weapon_Blaster * 7 : bomb_touch : Weapon_Bomber, Weapon_Vaporizer * 7 : fire_vaporizer : Weapon_Vaporizer * 8 : fire_violator : Weapon_Violator * --- from sample.cfg accuracy * weapon_hit[] :to: bot weapacc[] * 0: 1: blaster * 1: 2: alien disruptor * 3: 3: pulse rifle (chaingun) * 4: 4: flame thrower * x: 5: homing rocket launcher (not implemented) * 5: 6: rocket launcher * 2: 7: alien smartgun * 6: 8: alien beamgun * 7: 9: alien vaporizer * 8: x: violator */ static void game_report( void ) { static const char* weapname[] = { " blaster", // 0 blaster, hover " disruptor", // 1 " smartgun", // 2 " chaingun", // 3 " flame", // 4 " rocket", // 5 rocketlauncher, bomber, strafer " beamgun", // 6 beamgun " vaporizer", // 7 +bomber's bomb " violator" // 8 }; /* cross-reference from weapon_hit to weapacc[] */ static const int accxref[] = { 1, /* 0 blaster */ 2, /* 1 disruptor */ 7, /* 2 smartgun */ 3, /* 3 chaingun */ 4, /* 4 flame */ 6, /* 5 rocket */ 8, /* 6 beamgun */ 9, /* 7 vaporizer */ 0 /* 8 violator */ /* no weapacc[] for this */ }; edict_t *pclient; int i; char *client_name; gi.dprintf( "\n" ); for ( i = 0, pclient = &g_edicts[1] ; i < game.maxclients ; ++pclient, i++ ) { // for each possible client, human or bot if ( pclient->inuse && game.clients[i].resp.spectator == 0 ) { int weap; /* scoring - UNSORTED */ client_name = Info_ValueForKey( pclient->client->pers.userinfo, "name" ); if ( pclient->is_bot ) { gi.dprintf( "%s (%i,%0.2f): %i\n", client_name, pclient->skill, pclient->awareness, game.clients[i].resp.score ); } else { gi.dprintf( "%s: %i\n", client_name, game.clients[i].resp.score ); } /* weapon skill */ for ( weap = 0; weap < 9; weap++ ) { if ( pclient->client->resp.weapon_shots[weap] != 0 ) { int hits = pclient->client->resp.weapon_hits[weap]; int shots = pclient->client->resp.weapon_shots[weap]; int percent = (100 * hits) / shots; if ( pclient->is_bot ) { if ( weap == 8 ) { /* violator - no weapacc[], accuracy always 1.0 */ gi.dprintf( " %s (1.0): %i/%i = %i%%\n", weapname[weap], hits, shots, percent ); } else { gi.dprintf( " %s (%0.2f): %i/%i = %i%%\n", weapname[weap], pclient->weapacc[accxref[weap]], hits, shots, percent ); } } else { gi.dprintf( " %s : %i/%i = %i%%\n", weapname[weap], hits, shots, percent ); } } } } } gi.dprintf("\n"); } /* ================= EndDMLevel The timelimit or fraglimit has been exceeded ================= */ void EndDMLevel (void) { edict_t *ent; char *s, *t, *f; static const char *seps = " ,\n\r"; char *buffer; char mapsname[MAX_OSPATH]; int length; static char **mapnames; static int nummaps; int i; FILE *fp; // log game scoring, statistics. currently crude for bot testing mostly. if ( g_dedicated && g_dedicated->integer != 0 ) { game_report(); } /* Search for dead players in order to remove DeathCam and free mem */ for (i=0 ; ivalue ; i++) { ent = g_edicts + i + 1; if (!ent->inuse || ent->client->resp.spectator) continue; if(!ent->is_bot && ent->deadflag) DeathcamRemove (ent, "off"); } //call voting if(g_callvote->value) { playervote.called = false; playervote.yay = 0; playervote.nay = 0; playervote.command[0] = 0; } //map voting if(g_mapvote->value) { level.changemap = level.mapname; // initialise map list using the current map's name // this is done in all modes just in case for ( i = 0 ; i < 4 ; i ++ ) { strcpy(votedmap[i].mapname, level.mapname); votedmap[i].tally = 0; } // if there is a map list, time to choose if ( sv_maplist && sv_maplist->string && *(sv_maplist->string) ) { char * names[200]; // 200 map names should be fine int n_maps = 0; int same_index = -1; int mode = ( g_votemode ? g_votemode->value : 0 ); qboolean same = ( g_votesame ? (g_votesame->value == 1) : 1 ); memset( names, 0 , sizeof(names) ); s = _strdup( sv_maplist->string ); t = strtok( s, seps ); do { // if using the same map is disallowed, skip it if ( !Q_strcasecmp(t, level.mapname) ) { if ( same_index == -1 ) same_index = n_maps; if ( !same ) continue; } // avoid duplicates for ( i = 0 ; i < n_maps ; i ++ ) { if ( ! Q_strcasecmp( t , names[i] ) ) break; } if ( i < n_maps ) continue; names[n_maps ++] = t; } while ( (t = strtok( NULL, seps)) != NULL ); if ( n_maps > 0 ) { // if the map list has been changed and the // current map is no longer in it, prevent // screw-ups if ( same_index == -1 ) same_index = 0; if ( mode == 0 ) { // standard vote mode, take the next // 4 maps from the list for ( i = 0 ; i < 4 ; i ++ ) strcpy( votedmap[i].mapname, names[(same_index + i) % n_maps] ); } else { // random selection for ( i = 0 ; i < 4 && n_maps > 0 ; i ++ ) { int map = random() * (n_maps - 1); strcpy( votedmap[i].mapname, names[map] ); names[map] = names[n_maps - 1]; n_maps --; } } } free(s); } } // stay on same level flag if (dmflags->integer & DF_SAME_LEVEL) { BeginIntermission (CreateTargetChangeLevel (level.mapname) ); return; } if (bot_won && !(dmflags->integer & DF_BOT_LEVELAD) && !ctf->value) { BeginIntermission (CreateTargetChangeLevel (level.mapname) ); return; } if( ( ctf->integer || cp->integer ) && ! g_dedicated->integer ) { //ctf will just stay on same level unless specified by dedicated list BeginIntermission (CreateTargetChangeLevel (level.mapname)); return; } // see if it's in the map list if (*sv_maplist->string) { s = _strdup(sv_maplist->string); f = NULL; t = strtok(s, seps); while (t != NULL) { if (Q_strcasecmp(t, level.mapname) == 0) { // it's in the list, go to the next one t = strtok(NULL, seps); if (t == NULL) { // end of list, go to first one if (f == NULL) // there isn't a first one, same level BeginIntermission (CreateTargetChangeLevel (level.mapname) ); else BeginIntermission (CreateTargetChangeLevel (f) ); } else BeginIntermission (CreateTargetChangeLevel (t) ); free(s); return; } if (!f) f = t; t = strtok(NULL, seps); } free(s); } if(ctf->integer) { //wasn't in the dedicated list BeginIntermission (CreateTargetChangeLevel (level.mapname)); return; } //check the maps.lst file and read in those, which will overide anything in the level //write this code here /* ** load the list of map names */ if ( !gi.FullPath( mapsname, sizeof(mapsname), "maps.lst" ) ) { // no maps.lst. // note: originally this was looked for in "./data1/" only // hope it is ok to use FullPath() search path. BeginIntermission (CreateTargetChangeLevel (level.mapname) ); return; } if ( ( fp = fopen( mapsname, "rb" ) ) == 0 ) { BeginIntermission (CreateTargetChangeLevel (level.mapname) ); return; } length = g_filelength( fp ); buffer = malloc( length + 1 ); szr = fread( buffer, length, 1, fp ); buffer[length] = 0; s = buffer; i = 0; while ( i < length ) { if ( s[i] == '\r' ) nummaps++; i++; } mapnames = malloc( sizeof( char * ) * ( nummaps + 1 ) ); memset( mapnames, 0, sizeof( char * ) * ( nummaps + 1 ) ); s = buffer; for ( i = 0; i < nummaps; i++ ) { char shortname[MAX_TOKEN_CHARS]; char longname[MAX_TOKEN_CHARS]; char scratch[200]; #if defined WIN32_VARIANT int j; #endif int l; strcpy( shortname, COM_Parse( &s ) ); l = strlen(shortname); #if defined WIN32_VARIANT for (j=0 ; jmodified || spectator_password->modified) { password->modified = spectator_password->modified = false; need = 0; if (*password->string && Q_strcasecmp(password->string, "none")) need |= 1; if (*spectator_password->string && Q_strcasecmp(spectator_password->string, "none")) need |= 2; gi.cvar_set("needpass", va("%d", need)); } } /* ================= ResetLevel ================= */ void ResetLevel (qboolean keepscores) //for resetting players and items after warmup { int i, backup_score = 0; //initialize to shut gcc up edict_t *ent; gitem_t *item; for (i=0 ; ivalue ; i++) { ent = g_edicts + i + 1; if (!ent->inuse || ent->client->resp.spectator) continue; if (keepscores) backup_score = ent->client->resp.score; // locate ent at a spawn point and reset everything InitClientResp (ent->client); if(ent->is_bot) { // respawn bots after warmup ACESP_PutClientInServer( ent, true ); } else { if(ent->deadflag) DeathcamRemove (ent, "off"); PutClientInServer (ent); } ent->client->homing_shots = 0; if (keepscores) ent->client->resp.score = backup_score; } ACESP_SaveBots(); // update bots.tmp and client bot information blue_team_score = 0; red_team_score = 0; if(g_tactical->integer) { tacticalScore.alienAmmoDepot = tacticalScore.alienComputer = tacticalScore.alienPowerSource = tacticalScore.alienBackupGen = tacticalScore.humanAmmoDepot = tacticalScore.humanComputer = tacticalScore.humanPowerSource = tacticalScore.humanBackupGen = true; } mindEraserTime = level.time; //reset level items for (i=1, ent=g_edicts+i ; i < globals.num_edicts ; i++,ent++) { if (!ent->inuse) continue; if(ent->client) //not players continue; //only items, not triggers, trains, etc for (i=0,item=itemlist ; iclassname) continue; if (!strcmp(item->classname, ent->classname)) { // found it DoRespawn(ent); break; } } if (!strcmp(ent->classname, "misc_bluenode") || !strcmp(ent->classname, "misc_rednode")) ent->powered = true; if (!strcmp(ent->classname, "misc_redspidernode")) { gi.unlinkentity (ent); SP_misc_redspidernode (ent); } if (!strcmp(ent->classname, "misc_bluespidernode")) { gi.unlinkentity (ent); SP_misc_bluespidernode (ent); } } if(g_callvote->integer) safe_bprintf(PRINT_HIGH, "Call voting is ^2ENABLED\n"); else safe_bprintf(PRINT_HIGH, "Call voting is ^1DISABLED\n"); if(g_antilag->integer) safe_bprintf(PRINT_HIGH, "Antilag is ^2ENABLED\n"); else safe_bprintf(PRINT_HIGH, "Antilag is ^1DISABLED\n"); return; } /* ================= CheckDMRules ================= */ void CheckDMRules (void) { int i, top_score; gclient_t *cl; edict_t *cl_ent; float countdown_time; static int warmup_state = 0; gi.cvar_set ("g_teamgame", va("%d", TEAM_GAME)); if ( !g_tactical->integer && !tca->integer && !ctf->integer && !cp->integer && !(dmflags->integer & DF_SKINTEAMS) ) { /*--- non-team game warmup ---*/ /* * note: broadcast sounds require first client to have sound info * whether or not first client is inuse (bot or not, also not important) */ if ( (warmup_state == 0) && (level.time <= warmuptime->value) ) { /* start warmup countdown */ countdown_time = warmuptime->value - level.time; warmup_state = (int)(ceil( countdown_time )); } if ( warmup_state > 0 ) { /* warmup in progress */ countdown_time = warmuptime->value - level.time; if ( (float)warmup_state > ceil( countdown_time ) ) { /* next state of countdown */ --warmup_state; switch ( warmup_state ) { case 3: gi.sound( &g_edicts[1], CHAN_AUTO, gi.soundindex( "misc/three.wav" ), 1, ATTN_NONE, 0 ); break; case 2: gi.sound( &g_edicts[1], CHAN_AUTO, gi.soundindex( "misc/two.wav" ), 1, ATTN_NONE, 0 ); break; case 1: gi.sound( &g_edicts[1], CHAN_AUTO, gi.soundindex( "misc/one.wav" ), 1, ATTN_NONE, 0 ); break; case 0: gi.sound( &g_edicts[1], CHAN_AUTO, gi.soundindex( "misc/fight.wav" ), 1, ATTN_NONE, 0 ); break; default: break; } if ( warmup_state > 0 ) { for ( i = 1; i <= g_maxclients->integer; i++ ) { safe_centerprintf( &g_edicts[i], "%i...\n", warmup_state ); } } else { /* end of warmup */ for ( i = 1; i <= g_maxclients->integer; i++ ) { safe_centerprintf( &g_edicts[i], "FIGHT!\n" ); } ResetLevel(false); } } } } if (level.intermissiontime) return; if (!deathmatch->integer) return; if (timelimit->value) { if (level.time >= timelimit->value*60.0 && ((tca->integer || ctf->integer || cp->integer || (dmflags->integer & DF_SKINTEAMS)) || level.time > warmuptime->value)) { safe_bprintf (PRINT_HIGH, "Timelimit hit.\n"); EndDMLevel (); return; } } if (fraglimit->integer && ((tca->integer || ctf->integer || cp->integer || (dmflags->integer & DF_SKINTEAMS)) || level.time > warmuptime->value)) { //team scores if ((dmflags->integer & DF_SKINTEAMS) || ctf->integer || cp->integer) //it's all about the team! { if(blue_team_score >= fraglimit->integer) { safe_bprintf(PRINT_HIGH, "Blue Team wins!\n"); bot_won = 0; //we don't care if it's a bot that wins EndDMLevel(); return; } if(red_team_score >= fraglimit->integer) { safe_bprintf(PRINT_HIGH, "Red Team wins!\n"); bot_won = 0; //we don't care if it's a bot that wins EndDMLevel(); return; } } else { top_score = 0; for (i=0 ; iinteger ; i++) { cl = game.clients + i; if (!g_edicts[i+1].inuse) continue; if(cl->resp.score > top_score) top_score = cl->resp.score; //grab the top score if (cl->resp.score >= fraglimit->integer) { if(cl->is_bot) { bot_won = 1; //a bot has won the match safe_bprintf (PRINT_HIGH, "Fraglimit hit by bot.\n"); } else { bot_won = 0; safe_bprintf (PRINT_HIGH, "Fraglimit hit.\n"); } EndDMLevel (); return; } } if(!tca->integer && !ctf->integer && !cp->integer) { i = fraglimit->integer - top_score; switch(i) { case 3: if(!print3) { for (i=0 ; iinteger ; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || cl_ent->is_bot) continue; if(i == 0) gi.sound (cl_ent, CHAN_AUTO, gi.soundindex("misc/3frags.wav"), 1, ATTN_NONE, 0); safe_centerprintf(cl_ent, "3 frags remain!\n"); } print3 = true; } break; case 2: if(!print2) { for (i=0 ; iinteger ; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || cl_ent->is_bot) continue; if(i == 0) gi.sound (cl_ent, CHAN_AUTO, gi.soundindex("misc/2frags.wav"), 1, ATTN_NONE, 0); safe_centerprintf(cl_ent, "2 frags remain!\n"); } print2 = true; } break; case 1: if(!print1) { for (i=0 ; iinteger ; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || cl_ent->is_bot) continue; if(i == 0) gi.sound (cl_ent, CHAN_AUTO, gi.soundindex("misc/1frags.wav"), 1, ATTN_NONE, 0); safe_centerprintf(cl_ent, "1 frag remains!\n"); } print1 = true; } break; default: break; } } } } if(tca->integer) { if(red_team_matches == 2) { safe_bprintf(PRINT_HIGH, "Red Team wins!\n"); bot_won = 0; //we don't care if it's a bot that wins EndDMLevel(); return; } if(blue_team_matches == 2) { safe_bprintf(PRINT_HIGH, "Blue Team wins!\n"); bot_won = 0; //we don't care if it's a bot that wins EndDMLevel(); return; } if (blue_team_score == 0) { safe_bprintf(PRINT_HIGH, "Red Team wins match %d out of 3!\n", red_team_matches); bot_won = 0; ResetLevel(true); blue_team_score = red_team_score = 4; return; } if (red_team_score == 0) { safe_bprintf(PRINT_HIGH, "Blue Team wins match %d out of 3!\n", blue_team_matches); bot_won = 0; ResetLevel(true); blue_team_score = red_team_score = 4; return; } } if(g_tactical->integer) { if(!tacticalScore.alienAmmoDepot && !tacticalScore.alienComputer && !tacticalScore.alienPowerSource) { safe_bprintf(PRINT_HIGH, "The Humans have defeated the Aliens!\n"); bot_won = 0; //we don't care if it's a bot that wins EndDMLevel(); return; } if(!tacticalScore.humanAmmoDepot && !tacticalScore.humanComputer && !tacticalScore.humanPowerSource) { safe_bprintf(PRINT_HIGH, "The Aliens have defeated the Humans!\n"); bot_won = 0; //we don't care if it's a bot that wins EndDMLevel(); return; } } } /* ============= ExitLevel ============= */ void ExitLevel (void) { int i; edict_t *ent; char command [256]; if(strcmp(level.mapname, level.changemap) || timelimit->value || g_tactical->value) { Com_sprintf( command, sizeof(command), "map \"%s\"\n", level.changemap ); gi.AddCommandString( command ); } //Note-- whenever the map command fails (for instance, misspelled bsp name //in the server cfg,) it will just play another game on the same map. As //of right here in the code, there is no way to detect if that is going to //happen, so we initialize another game on this map just in case. This //fixes many longstanding bugs where misspelled map names in the cfg would //cause servers to glitch out. // -Max level.changemap = NULL; level.exitintermission = 0; level.intermissiontime = 0; ClientEndServerFrames (); EndIntermission(); // clear some things before going to next level for (i=0 ; iinteger ; i++) { ent = g_edicts + 1 + i; if (!ent->inuse) continue; if (ent->health > ent->client->pers.max_health) ent->health = ent->client->pers.max_health; ent->client->resp.score = 0; ent->client->resp.deaths = 0; ent->client->resp.reward_pts = 0; ent->client->homing_shots = 0; ent->takedamage = DAMAGE_AIM; ent->solid = SOLID_BBOX; ent->deadflag = DEAD_NO; if(ent->is_bot) { ACESP_PutClientInServer( ent, true ); } else { PutClientInServer (ent); } if(g_duel->integer) { ClientPlaceInQueue(ent); ClientCheckQueue(ent); } } for (i=1, ent=g_edicts+i ; i < globals.num_edicts ; i++,ent++) { if (!ent->inuse || ent->client) continue; //remove podiums if(!strcmp(ent->classname, "pad")) G_FreeEdict(ent); if(tca->integer) { if(strstr(ent->classname, "spidernode")) ED_CallSpawn (ent); ent->powered = true; } } if(tca->integer) { blue_team_score = red_team_score = 4; red_team_matches = blue_team_matches = 0; } else { red_team_score = 0; blue_team_score = 0; } if(g_tactical->integer) { tacticalScore.alienAmmoDepot = tacticalScore.alienComputer = tacticalScore.alienPowerSource = tacticalScore.alienBackupGen = tacticalScore.humanAmmoDepot = tacticalScore.humanComputer = tacticalScore.humanPowerSource = tacticalScore.humanBackupGen = true; tacticalScore.alienAmmoDepotHealth = tacticalScore.alienComputerHealth = tacticalScore.alienPowerSourceHealth = tacticalScore.humanAmmoDepotHealth = tacticalScore.humanComputerHealth = tacticalScore.humanPowerSourceHealth = 100; } print1 = print2 = print3 = false; } /* ================ G_Ban Ban player ================ */ /* ================= SV_WriteIP_f ================= */ void G_Ban (char *ip) { FILE *f; char name[MAX_OSPATH]; cvar_t *game; int i; //add to banlist file game = gi.cvar("game", "", 0); if (!*game->string) sprintf (name, "%s/listip.cfg", GAMEVERSION); else sprintf (name, "%s/listip.cfg", game->string); safe_cprintf (NULL, PRINT_HIGH, "Writing %s.\n", name); f = fopen (name, "ab"); if (!f) { safe_cprintf (NULL, PRINT_HIGH, "Couldn't open %s\n", name); return; } fprintf (f, "sv addip %s\n", ip); fclose (f); //add to current ban list for (i=0 ; i and callvote kicks ================ */ qboolean G_NameMatch( const char* netname, const char *kickname ) { const char* p_netname = netname; const char* p_kickname = kickname; int char_count = 16; int len_count = 49; // maximum length of 16 char color name (16 * 3 + nul) qboolean matched = false; while ( len_count > 0 && char_count > 0) { if ( *p_netname != *p_kickname ) { if ( Q_IsColorString( p_netname ) ) { // netname has color code, kickname does not, match still possible p_netname += 2; len_count -= 2; } else if ( Q_IsColorString( p_kickname )) { // kickname has color code, netname does not, match still possible p_kickname += 2; len_count -= 2; } else { // no match. mismatched chars, or end of one or the other break; } } else if ( !*p_netname && !*p_kickname ) { // end of both strings, matched = true; break; } else { // chars matched if ( Q_IsColorString( p_netname ) && Q_IsColorString( p_kickname ) ) { // color does not have to match p_netname += 2; p_kickname += 2; len_count -= 2; } else { ++p_netname; ++p_kickname; --len_count; --char_count; } } } return matched; } /* ================ G_ParseVoteCommand Parse and execute command ================ */ // helper function static edict_t* find_kick_target( const char *name ) { edict_t* kick_target = NULL; edict_t* ent; int i; for ( i = 1 ; i <= g_maxclients->integer ; i++ ) { ent = &g_edicts[i]; if ( !ent->inuse ) continue; if ( ent->client ) { if ( G_NameMatch( ent->client->pers.netname, name ) ) { kick_target = ent; break; } } } return kick_target; } void G_ParseVoteCommand (void) { int i, j; char command[128]; char args[128]; edict_t *ent; qboolean donearg = false; char *value; //separate command from args i = j = 0; while(i < 128) { if(playervote.command[i] == ' ') donearg = true; if(!donearg) command[i] = playervote.command[i]; else command[i] = 0; if(donearg && i < 127) { //skip the space between command and arg args[j] = playervote.command[i+1]; j++; } i++; } if ( !strcmp(command, "kick") ) { // kick player or bot ent = find_kick_target( args ); if ( ent ) { if ( ent->is_bot ) { if ( sv_botkickthreshold && sv_botkickthreshold->integer ) { safe_bprintf(PRINT_HIGH, "Auto bot kick enabled, callvote kick disabled.\n%s not kicked.\n", ent->client->pers.netname); } else { ACESP_KickBot( ent ); } } else { safe_bprintf(PRINT_HIGH, "%s was kicked\n", args); ClientDisconnect (ent); } } else { safe_bprintf( PRINT_HIGH, "Did not find %s here.\n", args ); } } else if ( !strcmp( command, "kickban") ) { // kickban player ent = find_kick_target( args ); if ( ent ) { if ( ent->is_bot ) { // safe_bprintf(PRINT_HIGH, "%s is a bot, use \"kick\", not \"kickban.\"\n", ent->client->pers.netname); } else { safe_bprintf(PRINT_HIGH, "%s was kickbanned\n", args); ClientDisconnect (ent); value = Info_ValueForKey (ent->client->pers.userinfo, "ip"); G_Ban(value); } } else { safe_bprintf( PRINT_HIGH, "Did not find %s here.\n", args ); } } else if(!strcmp(command, "fraglimit")) { //change fraglimit gi.cvar_set("fraglimit", args); safe_bprintf(PRINT_HIGH, "Fraglimit changed to %s\n", args); } else if(!strcmp(command, "timelimit")) { //change timelimit gi.cvar_set("timelimit", args); safe_bprintf(PRINT_HIGH, "Timelimit changed to %s\n", args); } else if(!strcmp(command, "map")) { //change map Com_sprintf (command, sizeof(command), "map \"%s\"\n", args); gi.AddCommandString (command); } else safe_bprintf(PRINT_HIGH, "Invalid command!"); } /* ================ G_RunFrame Advances the world by 0.1 seconds ================ */ extern void ACEND_DrawPath(void); void G_RunFrame (void) { int i, numActiveClients = 0; edict_t *ent; level.previousTime = gi.Sys_Milliseconds() - 100; level.framenum++; level.time = level.framenum*FRAMETIME; /* * update bot info in first client always, and in other active clients */ ACESP_UpdateBots(); // choose a client for monsters to target this frame AI_SetSightClient (); // exit intermissions if (level.exitintermission) { ExitLevel (); return; } // // treat each object in turn // even the world gets a chance to think // ent = &g_edicts[0]; for (i=0 ; iinuse) continue; level.current_entity = ent; VectorCopy (ent->s.origin, ent->s.old_origin); // if the ground entity moved, make sure we are still on it if ((ent->groundentity) && (ent->groundentity->linkcount != ent->groundentity_linkcount)) { ent->groundentity = NULL; if ( !(ent->flags & (FL_SWIM|FL_FLY)) && (ent->svflags & SVF_MONSTER) ) { M_CheckGround (ent); } } if (i > 0 && i <= g_maxclients->integer) { ClientBeginServerFrame (ent); } if(ent->inuse && ent->client && !ent->is_bot) { if ( ent->s.number <= g_maxclients->integer ) { // count actual players, not deathcam entities numActiveClients++; } } //this next block of code may not be practical for a server running at 10fps /* if(ent->movetype & MOVETYPE_FLYMISSILE) { //unlagged if ( g_antilag->integer) G_TimeShiftAllClients( level.previousTime, NULL ); G_RunEntity (ent); //unlagged if ( g_antilag->integer) G_UnTimeShiftAllClients( NULL ); } else*/ G_RunEntity (ent, FRAMETIME); } // see if it is time to end a deathmatch CheckDMRules (); // see if needpass needs updated CheckNeedPass (); // build the playerstate_t structures for all players ClientEndServerFrames (); // For bot debugging ACEND_DrawPath(); //unlagged if ( g_antilag->integer) level.frameStartTime = level.time; //call voting if(g_callvote->integer && playervote.called) { playervote.time = level.time; if(playervote.time-playervote.starttime > 15 ){ //15 seconds //execute command if votes are sufficient if(numActiveClients <= 2 && playervote.yay > playervote.nay+1) { //minimum of 2 votes to pass safe_bprintf(PRINT_HIGH, "Vote ^2Passed\n"); //parse command(we will allow kick, map, fraglimit, timelimit). G_ParseVoteCommand(); } else if(playervote.yay > 2 && playervote.yay > playervote.nay+1) { //3-1 minimum to pass safe_bprintf(PRINT_HIGH, "Vote ^2Passed\n"); //parse command(we will allow kick, map, fraglimit, timelimit). G_ParseVoteCommand(); } else safe_bprintf(PRINT_HIGH, "Vote ^1Failed\n"); //clear playervote.called = false; playervote.yay = playervote.nay = 0; playervote.command[0] = 0; //do each ent for (i=0 ; iinteger ; i++) { ent = g_edicts + 1 + i; if (!ent->inuse || ent->is_bot) continue; ent->client->resp.voted = false; } } } } alien-arena-7.66+dfsg/source/game/m_move.c0000600000175000017500000002742312161402010017451 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // m_move.c -- monster movement #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" #define STEPSIZE 18 /* ============= M_CheckBottom Returns false if any part of the bottom of the entity is off an edge that is not a staircase. ============= */ int c_yes, c_no; qboolean M_CheckBottom (edict_t *ent) { vec3_t mins, maxs, start, stop; trace_t trace; int x, y; float mid, bottom; VectorAdd (ent->s.origin, ent->mins, mins); VectorAdd (ent->s.origin, ent->maxs, maxs); // if all of the points under the corners are solid world, don't bother // with the tougher checks // the corners must be within 16 of the midpoint start[2] = mins[2] - 1; for (x=0 ; x<=1 ; x++) for (y=0 ; y<=1 ; y++) { start[0] = x ? maxs[0] : mins[0]; start[1] = y ? maxs[1] : mins[1]; if (gi.pointcontents (start) != CONTENTS_SOLID) goto realcheck; } c_yes++; return true; // we got out easy realcheck: c_no++; // // check it for real... // start[2] = mins[2]; // the midpoint must be within 16 of the bottom start[0] = stop[0] = (mins[0] + maxs[0])*0.5; start[1] = stop[1] = (mins[1] + maxs[1])*0.5; stop[2] = start[2] - 2*STEPSIZE; trace = gi.trace (start, vec3_origin, vec3_origin, stop, ent, MASK_MONSTERSOLID); if (trace.fraction == 1.0) return false; mid = bottom = trace.endpos[2]; // the corners must be within 16 of the midpoint for (x=0 ; x<=1 ; x++) for (y=0 ; y<=1 ; y++) { start[0] = stop[0] = x ? maxs[0] : mins[0]; start[1] = stop[1] = y ? maxs[1] : mins[1]; trace = gi.trace (start, vec3_origin, vec3_origin, stop, ent, MASK_MONSTERSOLID); if (trace.fraction != 1.0 && trace.endpos[2] > bottom) bottom = trace.endpos[2]; if (trace.fraction == 1.0 || mid - trace.endpos[2] > STEPSIZE) return false; } c_yes++; return true; } /* ============= SV_movestep Called by monster program code. The move will be adjusted for slopes and stairs, but if the move isn't possible, no move is done, false is returned, and pr_global_struct->trace_normal is set to the normal of the blocking wall ============= */ //FIXME since we need to test end position contents here, can we avoid doing //it again later in catagorize position? qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink) { float dz; vec3_t oldorg, neworg, end; trace_t trace; int i; float stepsize; vec3_t test; int contents; // try the move VectorCopy (ent->s.origin, oldorg); VectorAdd (ent->s.origin, move, neworg); // flying monsters don't step up if ( ent->flags & (FL_SWIM | FL_FLY) ) { // try one move with vertical motion, then one without for (i=0 ; i<2 ; i++) { VectorAdd (ent->s.origin, move, neworg); if (i == 0 && ent->enemy) { if (!ent->goalentity) ent->goalentity = ent->enemy; dz = ent->s.origin[2] - ent->goalentity->s.origin[2]; if (ent->goalentity->client) { if (dz > 40) neworg[2] -= 8; if (!((ent->flags & FL_SWIM) && (ent->waterlevel < 2))) if (dz < 30) neworg[2] += 8; } else { if (dz > 8) neworg[2] -= 8; else if (dz > 0) neworg[2] -= dz; else if (dz < -8) neworg[2] += 8; else neworg[2] += dz; } } trace = gi.trace (ent->s.origin, ent->mins, ent->maxs, neworg, ent, MASK_MONSTERSOLID); // fly monsters don't enter water voluntarily if (ent->flags & FL_FLY) { if (!ent->waterlevel) { test[0] = trace.endpos[0]; test[1] = trace.endpos[1]; test[2] = trace.endpos[2] + ent->mins[2] + 1; contents = gi.pointcontents(test); if (contents & MASK_WATER) return false; } } // swim monsters don't exit water voluntarily if (ent->flags & FL_SWIM) { if (ent->waterlevel < 2) { test[0] = trace.endpos[0]; test[1] = trace.endpos[1]; test[2] = trace.endpos[2] + ent->mins[2] + 1; contents = gi.pointcontents(test); if (!(contents & MASK_WATER)) return false; } } if (trace.fraction == 1) { VectorCopy (trace.endpos, ent->s.origin); if (relink) { gi.linkentity (ent); G_TouchTriggers (ent); } return true; } if (!ent->enemy) break; } return false; } // push down from a step height above the wished position if (!(ent->monsterinfo.aiflags & AI_NOSTEP)) stepsize = STEPSIZE; else stepsize = 1; neworg[2] += stepsize; VectorCopy (neworg, end); end[2] -= stepsize*2; trace = gi.trace (neworg, ent->mins, ent->maxs, end, ent, MASK_MONSTERSOLID); if (trace.allsolid) return false; if (trace.startsolid) { neworg[2] -= stepsize; trace = gi.trace (neworg, ent->mins, ent->maxs, end, ent, MASK_MONSTERSOLID); if (trace.allsolid || trace.startsolid) return false; } // don't go in to water if (ent->waterlevel == 0) { test[0] = trace.endpos[0]; test[1] = trace.endpos[1]; test[2] = trace.endpos[2] + ent->mins[2] + 1; contents = gi.pointcontents(test); if (contents & MASK_WATER) return false; } if (trace.fraction == 1) { // if monster had the ground pulled out, go ahead and fall if ( ent->flags & FL_PARTIALGROUND ) { VectorAdd (ent->s.origin, move, ent->s.origin); if (relink) { gi.linkentity (ent); G_TouchTriggers (ent); } ent->groundentity = NULL; return true; } return false; // walked off an edge } // check point traces down for dangling corners VectorCopy (trace.endpos, ent->s.origin); if (!M_CheckBottom (ent)) { if ( ent->flags & FL_PARTIALGROUND ) { // entity had floor mostly pulled out from underneath it // and is trying to correct if (relink) { gi.linkentity (ent); G_TouchTriggers (ent); } return true; } VectorCopy (oldorg, ent->s.origin); return false; } if ( ent->flags & FL_PARTIALGROUND ) { ent->flags &= ~FL_PARTIALGROUND; } ent->groundentity = trace.ent; ent->groundentity_linkcount = trace.ent->linkcount; // the move is ok if (relink) { gi.linkentity (ent); G_TouchTriggers (ent); } return true; } //============================================================================ /* =============== M_ChangeYaw =============== */ void M_ChangeYaw (edict_t *ent) { float ideal; float current; float move; float speed; current = anglemod(ent->s.angles[YAW]); ideal = ent->ideal_yaw; if (current == ideal) return; move = ideal - current; speed = ent->yaw_speed; if (ideal > current) { if (move >= 180) move = move - 360; } else { if (move <= -180) move = move + 360; } if (move > 0) { if (move > speed) move = speed; } else { if (move < -speed) move = -speed; } ent->s.angles[YAW] = anglemod (current + move); } /* ====================== SV_StepDirection Turns to the movement direction, and walks the current distance if facing it. ====================== */ qboolean SV_StepDirection (edict_t *ent, float yaw, float dist) { vec3_t move, oldorigin; float delta; ent->ideal_yaw = yaw; M_ChangeYaw (ent); yaw = yaw*M_PI*2 / 360; move[0] = cos(yaw)*dist; move[1] = sin(yaw)*dist; move[2] = 0; VectorCopy (ent->s.origin, oldorigin); if (SV_movestep (ent, move, false)) { delta = ent->s.angles[YAW] - ent->ideal_yaw; if (delta > 45 && delta < 315) { // not turned far enough, so don't take the step VectorCopy (oldorigin, ent->s.origin); } gi.linkentity (ent); G_TouchTriggers (ent); return true; } gi.linkentity (ent); G_TouchTriggers (ent); return false; } /* ====================== SV_FixCheckBottom ====================== */ void SV_FixCheckBottom (edict_t *ent) { ent->flags |= FL_PARTIALGROUND; } /* ================ SV_NewChaseDir ================ */ #define DI_NODIR -1 void SV_NewChaseDir (edict_t *actor, edict_t *enemy, float dist) { float deltax,deltay; float d[3]; float tdir, olddir, turnaround; //FIXME: how did we get here with no enemy if (!enemy) return; olddir = anglemod( (int)(actor->ideal_yaw/45)*45 ); turnaround = anglemod(olddir - 180); deltax = enemy->s.origin[0] - actor->s.origin[0]; deltay = enemy->s.origin[1] - actor->s.origin[1]; if (deltax>10) d[1]= 0; else if (deltax<-10) d[1]= 180; else d[1]= DI_NODIR; if (deltay<-10) d[2]= 270; else if (deltay>10) d[2]= 90; else d[2]= DI_NODIR; // try direct route if (d[1] != DI_NODIR && d[2] != DI_NODIR) { if (d[1] == 0) tdir = d[2] == 90 ? 45 : 315; else tdir = d[2] == 90 ? 135 : 215; if (tdir != turnaround && SV_StepDirection(actor, tdir, dist)) return; } // try other directions if ( ((rand()&3) & 1) || abs(deltay)>abs(deltax)) { tdir=d[1]; d[1]=d[2]; d[2]=tdir; } if (d[1]!=DI_NODIR && d[1]!=turnaround && SV_StepDirection(actor, d[1], dist)) return; if (d[2]!=DI_NODIR && d[2]!=turnaround && SV_StepDirection(actor, d[2], dist)) return; /* there is no direct path to the player, so pick another direction */ if (olddir!=DI_NODIR && SV_StepDirection(actor, olddir, dist)) return; if (rand()&1) /*randomly determine direction of search*/ { for (tdir=0 ; tdir<=315 ; tdir += 45) if (tdir!=turnaround && SV_StepDirection(actor, tdir, dist) ) return; } else { for (tdir=315 ; tdir >=0 ; tdir -= 45) if (tdir!=turnaround && SV_StepDirection(actor, tdir, dist) ) return; } if (turnaround != DI_NODIR && SV_StepDirection(actor, turnaround, dist) ) return; actor->ideal_yaw = olddir; // can't move // if a bridge was pulled out from underneath a monster, it may not have // a valid standing position at all if (!M_CheckBottom (actor)) SV_FixCheckBottom (actor); } /* ====================== SV_CloseEnough ====================== */ qboolean SV_CloseEnough (edict_t *ent, edict_t *goal, float dist) { int i; for (i=0 ; i<3 ; i++) { if (goal->absmin[i] > ent->absmax[i] + dist) return false; if (goal->absmax[i] < ent->absmin[i] - dist) return false; } return true; } /* ====================== M_MoveToGoal ====================== */ void M_MoveToGoal (edict_t *ent, float dist) { edict_t *goal; goal = ent->goalentity; if (!ent->groundentity && !(ent->flags & (FL_FLY|FL_SWIM))) return; // if the next step hits the enemy, return immediately if (ent->enemy && SV_CloseEnough (ent, ent->enemy, dist) ) return; // bump around... if ( (rand()&3)==1 || !SV_StepDirection (ent, ent->ideal_yaw, dist)) { if (ent->inuse) SV_NewChaseDir (ent, goal, dist); } } /* =============== M_walkmove =============== */ qboolean M_walkmove (edict_t *ent, float yaw, float dist) { vec3_t move; if (!ent->groundentity && !(ent->flags & (FL_FLY|FL_SWIM))) return false; yaw = yaw*M_PI*2 / 360; move[0] = cos(yaw)*dist; move[1] = sin(yaw)*dist; move[2] = 0; return SV_movestep(ent, move, true); } alien-arena-7.66+dfsg/source/game/g_utils.c0000600000175000017500000002711612161402010017634 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // g_utils.c -- misc utility functions for game module #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" void G_ProjectSource (vec3_t point, vec3_t distance, vec3_t forward, vec3_t right, vec3_t result) { result[0] = point[0] + forward[0] * distance[0] + right[0] * distance[1]; result[1] = point[1] + forward[1] * distance[0] + right[1] * distance[1]; result[2] = point[2] + forward[2] * distance[0] + right[2] * distance[1] + distance[2]; } /* ============= G_Find Searches all active entities for the next one that holds the matching string at fieldofs (use the FOFS() macro) in the structure. Searches beginning at the edict after from, or the beginning if NULL NULL will be returned if the end of the list is reached. ============= */ edict_t *G_Find (edict_t *from, int fieldofs, char *match) { char *s; if (!from) from = g_edicts; else from++; for ( ; from < &g_edicts[globals.num_edicts] ; from++) { if (!from->inuse) continue; s = *(char **) ((byte *)from + fieldofs); if (!s) continue; if (!Q_strcasecmp (s, match)) return from; } return NULL; } /* ================= findradius Returns entities that have origins within a spherical area findradius (origin, radius) ================= */ edict_t *findradius (edict_t *from, vec3_t org, float rad) { vec3_t eorg; int j; if (!from) from = g_edicts; else from++; for ( ; from < &g_edicts[globals.num_edicts]; from++) { if (!from->inuse) continue; if (from->solid == SOLID_NOT) continue; for (j=0 ; j<3 ; j++) eorg[j] = org[j] - (from->s.origin[j] + (from->mins[j] + from->maxs[j])*0.5); if (VectorLength(eorg) > rad) continue; return from; } return NULL; } /* ============= G_PickTarget Searches all active entities for the next one that holds the matching string at fieldofs (use the FOFS() macro) in the structure. Searches beginning at the edict after from, or the beginning if NULL NULL will be returned if the end of the list is reached. ============= */ #define MAXCHOICES 8 edict_t *G_PickTarget (char *targetname) { edict_t *ent = NULL; int num_choices = 0; edict_t *choice[MAXCHOICES]; if (!targetname) { gi.dprintf("G_PickTarget called with NULL targetname\n"); return NULL; } while(1) { ent = G_Find (ent, FOFS(targetname), targetname); if (!ent) break; choice[num_choices++] = ent; if (num_choices == MAXCHOICES) break; } if (!num_choices) { gi.dprintf("G_PickTarget: target %s not found\n", targetname); return NULL; } return choice[rand() % num_choices]; } void Think_Delay (edict_t *ent) { G_UseTargets (ent, ent->activator); G_FreeEdict (ent); } /* ============================== G_UseTargets the global "activator" should be set to the entity that initiated the firing. If self.delay is set, a DelayedUse entity will be created that will actually do the SUB_UseTargets after that many seconds have passed. Centerprints any self.message to the activator. Search for (string)targetname in all entities that match (string)self.target and call their .use function ============================== */ void G_UseTargets (edict_t *ent, edict_t *activator) { edict_t *t; // // check for a delay // if (ent->delay) { // create a temp object to fire at a later time t = G_Spawn(); t->classname = "DelayedUse"; t->nextthink = level.time + ent->delay; t->think = Think_Delay; t->activator = activator; if (!activator) gi.dprintf ("Think_Delay with no activator\n"); t->message = ent->message; t->target = ent->target; t->killtarget = ent->killtarget; return; } // // print the message // if ((ent->message) && !(activator->svflags & SVF_MONSTER)) { safe_centerprintf (activator, "%s", ent->message); if (ent->noise_index) gi.sound (activator, CHAN_AUTO, ent->noise_index, 1, ATTN_NORM, 0); else gi.sound (activator, CHAN_AUTO, gi.soundindex ("misc/talk1.wav"), 1, ATTN_NORM, 0); } // // kill killtargets // if (ent->killtarget) { t = NULL; while ((t = G_Find (t, FOFS(targetname), ent->killtarget))) { G_FreeEdict (t); if (!ent->inuse) { gi.dprintf("entity was removed while using killtargets\n"); return; } } } // // fire targets // if (ent->target) { t = NULL; while ((t = G_Find (t, FOFS(targetname), ent->target))) { // doors fire area portals in a specific way if (!Q_strcasecmp(t->classname, "func_areaportal") && (!Q_strcasecmp(ent->classname, "func_door") || !Q_strcasecmp(ent->classname, "func_door_rotating"))) continue; if (t == ent) { gi.dprintf ("WARNING: Entity used itself.\n"); } else { if (t->use) t->use (t, ent, activator); } if (!ent->inuse) { gi.dprintf("entity was removed while using targets\n"); return; } } } } /* ============= TempVector This is just a convenience function for making temporary vectors for function calls ============= */ float *tv (float x, float y, float z) { static int index; static vec3_t vecs[8]; float *v; // use an array so that multiple tempvectors won't collide // for a while v = vecs[index]; index = (index + 1)&7; v[0] = x; v[1] = y; v[2] = z; return v; } /* ============= VectorToString This is just a convenience function for printing vectors ============= */ char *vtos (vec3_t v) { static int index; static char str[8][32]; char *s; // use an array so that multiple vtos won't collide s = str[index]; index = (index + 1)&7; Com_sprintf (s, 32, "(%i %i %i)", (int)v[0], (int)v[1], (int)v[2]); return s; } vec3_t VEC_UP = {0, -1, 0}; vec3_t MOVEDIR_UP = {0, 0, 1}; vec3_t VEC_DOWN = {0, -2, 0}; vec3_t MOVEDIR_DOWN = {0, 0, -1}; void G_SetMovedir (vec3_t angles, vec3_t movedir) { if (VectorCompare (angles, VEC_UP)) { VectorCopy (MOVEDIR_UP, movedir); } else if (VectorCompare (angles, VEC_DOWN)) { VectorCopy (MOVEDIR_DOWN, movedir); } else { AngleVectors (angles, movedir, NULL, NULL); } VectorClear (angles); } float vectoyaw (vec3_t vec) { float yaw; if (/*vec[YAW] == 0 &&*/ vec[PITCH] == 0) { yaw = 0; if (vec[YAW] > 0) yaw = 90; else if (vec[YAW] < 0) yaw = -90; } else { yaw = (int) (atan2(vec[YAW], vec[PITCH]) * 180 / M_PI); if (yaw < 0) yaw += 360; } return yaw; } // void vectoangles (vec3_t value1, vec3_t angles) Moved to q_shared.c char *G_CopyString (const char *in) { char *out; out = gi.TagMalloc (strlen(in)+1, TAG_LEVEL); strcpy (out, in); return out; } void G_InitEdict (edict_t *e) { e->inuse = true; e->classname = "noclass"; e->gravity = 1.0; e->s.number = e - g_edicts; } /* ================= G_Spawn Either finds a free edict, or allocates a new one. Try to avoid reusing an entity that was recently freed, because it can cause the client to think the entity morphed into something else instead of being removed and recreated, which can cause interpolated angles and bad trails. ================= */ edict_t *G_Spawn (void) { int i; edict_t *e; e = &g_edicts[g_maxclients->integer+1]; for ( i=g_maxclients->integer+1 ; iinuse && ( e->freetime < 2 || level.time - e->freetime > 0.5 ) ) { G_InitEdict (e); return e; } } if (i == game.maxentities) gi.error ("ED_Alloc: no free edicts"); globals.num_edicts++; G_InitEdict (e); return e; } /* ================= G_FreeEdict Marks the edict as free ================= */ void G_FreeEdict (edict_t *ed) { gi.unlinkentity (ed); // unlink from world if ((ed - g_edicts) <= (g_maxclients->value + BODY_QUEUE_SIZE)) { // gi.dprintf("tried to free special edict\n"); return; } memset (ed, 0, sizeof(*ed)); ed->classname = "freed"; ed->freetime = level.time; ed->inuse = false; } /* ============ G_TouchTriggers ============ */ void G_TouchTriggers (edict_t *ent) { int i, num; edict_t *touch[MAX_EDICTS], *hit; // dead things don't activate triggers! if ((ent->client || (ent->svflags & SVF_MONSTER)) && (ent->health <= 0)) return; num = gi.BoxEdicts (ent->absmin, ent->absmax, touch , MAX_EDICTS, AREA_TRIGGERS); // be careful, it is possible to have an entity in this // list removed before we get to it (killtriggered) for (i=0 ; iinuse) continue; if (!hit->touch) continue; hit->touch (hit, ent, NULL, NULL); } } /* ============ G_TouchSolids Call after linking a new trigger in during gameplay to force all entities it covers to immediately touch it ============ */ void G_TouchSolids (edict_t *ent) { int i, num; edict_t *touch[MAX_EDICTS], *hit; num = gi.BoxEdicts (ent->absmin, ent->absmax, touch , MAX_EDICTS, AREA_SOLID); // be careful, it is possible to have an entity in this // list removed before we get to it (killtriggered) for (i=0 ; iinuse) continue; if (ent->touch) ent->touch (hit, ent, NULL, NULL); if (!ent->inuse) break; } } /* ============================================================================== Kill box ============================================================================== */ /* ================= KillBox Kills all entities that would touch the proposed new positioning of ent. Ent should be unlinked before calling this! ================= */ qboolean KillBox (edict_t *ent) { trace_t tr; while (1) { tr = gi.trace (ent->s.origin, ent->mins, ent->maxs, ent->s.origin, NULL, MASK_PLAYERSOLID); if (!tr.ent) break; // nail it T_Damage (tr.ent, ent, ent, vec3_origin, ent->s.origin, vec3_origin, 100000, 0, DAMAGE_NO_PROTECTION, MOD_TELEFRAG); // if we didn't kill it, fail if (tr.ent->solid) return false; } return true; // all clear } /* ============= G_CleanPlayerName Removes escape characters from a player's name and prepares it to be displayed in green through safe_centerprintf. !Note!: dest must be at least PLAYERNAME_SIZE bytes long. (could be PLAYERNAME_GLYPHS + 1 long, but safer to use max. string length) ============= */ void G_CleanPlayerName ( const char *source, char *dest ) { const char *pch_src = source; char *pch_dst = dest; int count = strlen( pch_src ); memset( pch_dst, 0, PLAYERNAME_SIZE ); while ( count > 0 ) { if ( Q_IsColorString( pch_src ) ) { pch_src += 2; count -= 2; } else { *pch_dst++ = *pch_src | 0x80; ++pch_src; --count; } } } alien-arena-7.66+dfsg/source/game/q_shared.c0000600000175000017500000011235012161402010017747 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "q_shared.h" vec3_t vec3_origin = {0,0,0}; //============================================================================ void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees ) { float m[3][3]; float im[3][3]; float zrot[3][3]; float tmpmat[3][3]; float rot[3][3]; int i; vec3_t vr, vup, vf; vf[0] = dir[0]; vf[1] = dir[1]; vf[2] = dir[2]; PerpendicularVector( vr, dir ); CrossProduct( vr, vf, vup ); m[0][0] = vr[0]; m[1][0] = vr[1]; m[2][0] = vr[2]; m[0][1] = vup[0]; m[1][1] = vup[1]; m[2][1] = vup[2]; m[0][2] = vf[0]; m[1][2] = vf[1]; m[2][2] = vf[2]; memcpy( im, m, sizeof( im ) ); im[0][1] = m[1][0]; im[0][2] = m[2][0]; im[1][0] = m[0][1]; im[1][2] = m[2][1]; im[2][0] = m[0][2]; im[2][1] = m[1][2]; memset( zrot, 0, sizeof( zrot ) ); zrot[0][0] = zrot[1][1] = zrot[2][2] = 1.0F; zrot[0][0] = cos( DEG2RAD( degrees ) ); zrot[0][1] = sin( DEG2RAD( degrees ) ); zrot[1][0] = -sin( DEG2RAD( degrees ) ); zrot[1][1] = cos( DEG2RAD( degrees ) ); R_ConcatRotations( m, zrot, tmpmat ); R_ConcatRotations( tmpmat, im, rot ); for ( i = 0; i < 3; i++ ) { dst[i] = rot[i][0] * point[0] + rot[i][1] * point[1] + rot[i][2] * point[2]; } } /* ** Fast sincos function using polynomial approximation ** ** Profiling indicates that AngleVectors() is heavily used, which justifies ** (i hope) doing some "heroic" optimization. ** Testing indicates that maximum variation from original calculation is ** is around 0.000006 ** ** sin(a) ~= a - (0.16666 * a**3) + (0.0083143 a**5) - (0.00018542 * a**7) ** ** Reference: ** Essential Mathematics for Games and Interactive Applications, Second Edition. ** by James M. Van Verth and Lars M. Bishop, Morgan-Kaufman Publishing. ** which bases this technique on: ** Robin Green's GDC 2003 session, "Faster Math Functions" ** ** Arguments: ** angle : in radians */ #define kPI 3.1415926535897932384626433832795f #define kHalfPI 1.5707963267948966192313216916398f #define kTwoPI 2.0f*kPI static const float kTwoOverPI = 1.0f / kHalfPI; static const float kRationalHalfPI = 201.0f / 128.0f; static const float kRemainderHalfPI = 4.8382679e-4f; static const float kpoly3 = -0.16666f; static const float kpoly5 = 0.0083143f; static const float kpoly7 = -0.00018542f; float fast_sincosf_calc( float angle ) { float result; float anglesq; anglesq = angle * angle; result = angle * ( 1.0f + anglesq * (kpoly3 + anglesq * (kpoly5 + ( anglesq * kpoly7 )))); return result; } void fast_sincosf( float angle, float *sina, float *cosa ) { qboolean negate; float angle_radians; float angle_float_part; float angle_float_part_minus_halfpi; int angle_int_part; // make negative angle non-negative for purposes of calculation negate = false; angle_radians = angle; if( angle_radians < 0.0f ) { negate = true; angle_radians = -angle_radians; } // this is tricky. to prevent "catastophic cancelation" when subtracting // near equal floating point numbers, the calculation is broken down // into 2 parts. angle_float_part = kTwoOverPI * angle_radians; angle_int_part = (int)angle_float_part; angle_float_part = (angle_radians - (kRationalHalfPI * angle_int_part)) - (kRemainderHalfPI * angle_int_part); angle_float_part_minus_halfpi = (angle_float_part - kRationalHalfPI) - kRemainderHalfPI; switch( angle_int_part & 0x03 ) // mod 4 to get quadrant { case 0: // 0..PI/2 *sina = fast_sincosf_calc( angle_float_part ); *cosa = fast_sincosf_calc( -angle_float_part_minus_halfpi ); break; case 1: // PI/2..PI *sina = fast_sincosf_calc( -angle_float_part_minus_halfpi ); *cosa = fast_sincosf_calc( -angle_float_part ); break; case 2: // PI..3/2 PI *sina = fast_sincosf_calc( -angle_float_part ); *cosa = fast_sincosf_calc( angle_float_part_minus_halfpi ); break; case 3: // 3/2 PI..2 PI *sina = fast_sincosf_calc( angle_float_part_minus_halfpi ); *cosa = fast_sincosf_calc( angle_float_part ); break; } if( negate ) { *sina = -(*sina); } } void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up) { float angle; float sr, sp, sy, cr, cp, cy; angle = angles[YAW] * (kTwoPI / 360.0f); fast_sincosf( angle, &sy, &cy ); angle = angles[PITCH] * (kTwoPI / 360.0f ); fast_sincosf( angle, &sp, &cp ); if( right || up ) { // if forward only, this is not used angle = angles[ROLL] * (kTwoPI / 360.0f); fast_sincosf( angle, &sr, &cr ); } if (forward) { forward[0] = cp*cy; forward[1] = cp*sy; forward[2] = -sp; } if (right) { right[0] = (-1*sr*sp*cy+-1*cr*-sy); right[1] = (-1*sr*sp*sy+-1*cr*cy); right[2] = -1*sr*cp; } if (up) { up[0] = (cr*sp*cy+-sr*-sy); up[1] = (cr*sp*sy+-sr*cy); up[2] = cr*cp; } } void vectoangles (vec3_t value1, vec3_t angles) { float forward; float yaw, pitch; if (value1[1] == 0.0f && value1[0] == 0.0f ) { yaw = 0.0f; if (value1[2] > 0.0f) pitch = 90.0f; else pitch = 270.0f; } else { // PMM - fixed to correct for pitch of 0 if (value1[0]) yaw = (atan2(value1[1], value1[0]) * 180.0f / M_PI); else if (value1[1] > 0) yaw = 90.0f; else yaw = 270.0f; if (yaw < 0.0f) yaw += 360.0f; forward = sqrt (value1[0]*value1[0] + value1[1]*value1[1]); pitch = (atan2(value1[2], forward) * 180.0f / M_PI); if (pitch < 0.0f) pitch += 360.0f; } angles[PITCH] = -pitch; angles[YAW] = yaw; angles[ROLL] = 0.0f; } void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal ) { float d; vec3_t n; float inv_denom; inv_denom = 1.0F / DotProduct( normal, normal ); d = DotProduct( normal, p ) * inv_denom; n[0] = normal[0] * inv_denom; n[1] = normal[1] * inv_denom; n[2] = normal[2] * inv_denom; dst[0] = p[0] - d * n[0]; dst[1] = p[1] - d * n[1]; dst[2] = p[2] - d * n[2]; } /* ** assumes "src" is normalized */ void PerpendicularVector( vec3_t dst, const vec3_t src ) { int pos; int i; float minelem = 1.0F; vec3_t tempvec; /* ** find the smallest magnitude axially aligned vector */ for ( pos = 0, i = 0; i < 3; i++ ) { if ( fabs( src[i] ) < minelem ) { pos = i; minelem = fabs( src[i] ); } } tempvec[0] = tempvec[1] = tempvec[2] = 0.0F; tempvec[pos] = 1.0F; /* ** project the point onto the plane defined by src */ ProjectPointOnPlane( dst, tempvec, src ); /* ** normalize the result */ VectorNormalize( dst ); } /* ================ R_ConcatRotations ================ */ void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]) { out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + in1[0][2] * in2[2][0]; out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + in1[0][2] * in2[2][1]; out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + in1[0][2] * in2[2][2]; out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + in1[1][2] * in2[2][0]; out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + in1[1][2] * in2[2][1]; out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + in1[1][2] * in2[2][2]; out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + in1[2][2] * in2[2][0]; out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + in1[2][2] * in2[2][1]; out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + in1[2][2] * in2[2][2]; } /* ================ R_ConcatTransforms ================ */ void R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4]) { out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + in1[0][2] * in2[2][0]; out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + in1[0][2] * in2[2][1]; out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + in1[0][2] * in2[2][2]; out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] + in1[0][2] * in2[2][3] + in1[0][3]; out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + in1[1][2] * in2[2][0]; out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + in1[1][2] * in2[2][1]; out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + in1[1][2] * in2[2][2]; out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] + in1[1][2] * in2[2][3] + in1[1][3]; out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + in1[2][2] * in2[2][0]; out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + in1[2][2] * in2[2][1]; out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + in1[2][2] * in2[2][2]; out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + in1[2][2] * in2[2][3] + in1[2][3]; } //============================================================================ // these are probably obsolete (2010-06-13) /* float Q_fabs (float f) { #if 0 if (f >= 0) return f; return -f; #else int tmp = * ( int * ) &f; tmp &= 0x7FFFFFFF; return * ( float * ) &tmp; #endif } #if defined _M_IX86 && !defined C_ONLY #pragma warning (disable:4035) __declspec( naked ) long Q_ftol( float f ) { static int tmp; __asm fld dword ptr [esp+4] __asm fistp tmp __asm mov eax, tmp __asm ret } #pragma warning (default:4035) #endif */ /* =============== LerpAngle =============== */ float LerpAngle (float a2, float a1, float frac) { if (a1 - a2 > 180) a1 -= 360; if (a1 - a2 < -180) a1 += 360; return a2 + frac * (a1 - a2); } float anglemod(float a) { #if 0 if (a >= 0) a -= 360*(int)(a/360); else a += 360*( 1 + (int)(-a/360) ); #endif a = (360.0f/65536.0f) * ((int)(a*(65536.0f/360.0f)) & 65535); return a; } int i; vec3_t corners[2]; // this is the slow, general version int BoxOnPlaneSide2 (vec3_t emins, vec3_t emaxs, struct cplane_s *p) { int i; float dist1, dist2; int sides; vec3_t corners[2]; for (i=0 ; i<3 ; i++) { if (p->normal[i] < 0) { corners[0][i] = emins[i]; corners[1][i] = emaxs[i]; } else { corners[1][i] = emins[i]; corners[0][i] = emaxs[i]; } } dist1 = DotProduct (p->normal, corners[0]) - p->dist; dist2 = DotProduct (p->normal, corners[1]) - p->dist; sides = 0; if (dist1 >= 0) sides = 1; if (dist2 < 0) sides |= 2; return sides; } /* ================== BoxOnPlaneSide Returns 1, 2, or 1 + 2 ================== */ int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct cplane_s *p) { float dist1, dist2; int sides; // fast axial cases if (p->type < 3) { if (p->dist <= emins[p->type]) return 1; if (p->dist >= emaxs[p->type]) return 2; return 3; } // general case switch (p->signbits) { case 0: dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; break; case 1: dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; break; case 2: dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; break; case 3: dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; break; case 4: dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; break; case 5: dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; break; case 6: dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; break; case 7: dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; break; default: dist1 = dist2 = 0; // shut up compiler assert( 0 ); break; } sides = 0; if (dist1 >= p->dist) sides = 1; if (dist2 < p->dist) sides |= 2; return sides; } /* probably obsolete (2010-08) #pragma warning( disable: 4035 ) __declspec( naked ) int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct cplane_s *p) { static int bops_initialized; static int Ljmptab[8]; __asm { push ebx cmp bops_initialized, 1 je initialized mov bops_initialized, 1 mov Ljmptab[0*4], offset Lcase0 mov Ljmptab[1*4], offset Lcase1 mov Ljmptab[2*4], offset Lcase2 mov Ljmptab[3*4], offset Lcase3 mov Ljmptab[4*4], offset Lcase4 mov Ljmptab[5*4], offset Lcase5 mov Ljmptab[6*4], offset Lcase6 mov Ljmptab[7*4], offset Lcase7 initialized: mov edx,ds:dword ptr[4+12+esp] mov ecx,ds:dword ptr[4+4+esp] xor eax,eax mov ebx,ds:dword ptr[4+8+esp] mov al,ds:byte ptr[17+edx] cmp al,8 jge Lerror fld ds:dword ptr[0+edx] fld st(0) jmp dword ptr[Ljmptab+eax*4] Lcase0: fmul ds:dword ptr[ebx] fld ds:dword ptr[0+4+edx] fxch st(2) fmul ds:dword ptr[ecx] fxch st(2) fld st(0) fmul ds:dword ptr[4+ebx] fld ds:dword ptr[0+8+edx] fxch st(2) fmul ds:dword ptr[4+ecx] fxch st(2) fld st(0) fmul ds:dword ptr[8+ebx] fxch st(5) faddp st(3),st(0) fmul ds:dword ptr[8+ecx] fxch st(1) faddp st(3),st(0) fxch st(3) faddp st(2),st(0) jmp LSetSides Lcase1: fmul ds:dword ptr[ecx] fld ds:dword ptr[0+4+edx] fxch st(2) fmul ds:dword ptr[ebx] fxch st(2) fld st(0) fmul ds:dword ptr[4+ebx] fld ds:dword ptr[0+8+edx] fxch st(2) fmul ds:dword ptr[4+ecx] fxch st(2) fld st(0) fmul ds:dword ptr[8+ebx] fxch st(5) faddp st(3),st(0) fmul ds:dword ptr[8+ecx] fxch st(1) faddp st(3),st(0) fxch st(3) faddp st(2),st(0) jmp LSetSides Lcase2: fmul ds:dword ptr[ebx] fld ds:dword ptr[0+4+edx] fxch st(2) fmul ds:dword ptr[ecx] fxch st(2) fld st(0) fmul ds:dword ptr[4+ecx] fld ds:dword ptr[0+8+edx] fxch st(2) fmul ds:dword ptr[4+ebx] fxch st(2) fld st(0) fmul ds:dword ptr[8+ebx] fxch st(5) faddp st(3),st(0) fmul ds:dword ptr[8+ecx] fxch st(1) faddp st(3),st(0) fxch st(3) faddp st(2),st(0) jmp LSetSides Lcase3: fmul ds:dword ptr[ecx] fld ds:dword ptr[0+4+edx] fxch st(2) fmul ds:dword ptr[ebx] fxch st(2) fld st(0) fmul ds:dword ptr[4+ecx] fld ds:dword ptr[0+8+edx] fxch st(2) fmul ds:dword ptr[4+ebx] fxch st(2) fld st(0) fmul ds:dword ptr[8+ebx] fxch st(5) faddp st(3),st(0) fmul ds:dword ptr[8+ecx] fxch st(1) faddp st(3),st(0) fxch st(3) faddp st(2),st(0) jmp LSetSides Lcase4: fmul ds:dword ptr[ebx] fld ds:dword ptr[0+4+edx] fxch st(2) fmul ds:dword ptr[ecx] fxch st(2) fld st(0) fmul ds:dword ptr[4+ebx] fld ds:dword ptr[0+8+edx] fxch st(2) fmul ds:dword ptr[4+ecx] fxch st(2) fld st(0) fmul ds:dword ptr[8+ecx] fxch st(5) faddp st(3),st(0) fmul ds:dword ptr[8+ebx] fxch st(1) faddp st(3),st(0) fxch st(3) faddp st(2),st(0) jmp LSetSides Lcase5: fmul ds:dword ptr[ecx] fld ds:dword ptr[0+4+edx] fxch st(2) fmul ds:dword ptr[ebx] fxch st(2) fld st(0) fmul ds:dword ptr[4+ebx] fld ds:dword ptr[0+8+edx] fxch st(2) fmul ds:dword ptr[4+ecx] fxch st(2) fld st(0) fmul ds:dword ptr[8+ecx] fxch st(5) faddp st(3),st(0) fmul ds:dword ptr[8+ebx] fxch st(1) faddp st(3),st(0) fxch st(3) faddp st(2),st(0) jmp LSetSides Lcase6: fmul ds:dword ptr[ebx] fld ds:dword ptr[0+4+edx] fxch st(2) fmul ds:dword ptr[ecx] fxch st(2) fld st(0) fmul ds:dword ptr[4+ecx] fld ds:dword ptr[0+8+edx] fxch st(2) fmul ds:dword ptr[4+ebx] fxch st(2) fld st(0) fmul ds:dword ptr[8+ecx] fxch st(5) faddp st(3),st(0) fmul ds:dword ptr[8+ebx] fxch st(1) faddp st(3),st(0) fxch st(3) faddp st(2),st(0) jmp LSetSides Lcase7: fmul ds:dword ptr[ecx] fld ds:dword ptr[0+4+edx] fxch st(2) fmul ds:dword ptr[ebx] fxch st(2) fld st(0) fmul ds:dword ptr[4+ecx] fld ds:dword ptr[0+8+edx] fxch st(2) fmul ds:dword ptr[4+ebx] fxch st(2) fld st(0) fmul ds:dword ptr[8+ecx] fxch st(5) faddp st(3),st(0) fmul ds:dword ptr[8+ebx] fxch st(1) faddp st(3),st(0) fxch st(3) faddp st(2),st(0) LSetSides: faddp st(2),st(0) fcomp ds:dword ptr[12+edx] xor ecx,ecx fnstsw ax fcomp ds:dword ptr[12+edx] and ah,1 xor ah,1 add cl,ah fnstsw ax and ah,1 add ah,ah add cl,ah pop ebx mov eax,ecx ret Lerror: int 3 } } #pragma warning( default: 4035 ) #endif */ void ClearBounds (vec3_t mins, vec3_t maxs) { mins[0] = mins[1] = mins[2] = 99999; maxs[0] = maxs[1] = maxs[2] = -99999; } void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs) { int i; vec_t val; for (i=0 ; i<3 ; i++) { val = v[i]; if (val < mins[i]) mins[i] = val; if (val > maxs[i]) maxs[i] = val; } } int VectorCompare (vec3_t v1, vec3_t v2) { if (v1[0] != v2[0] || v1[1] != v2[1] || v1[2] != v2[2]) return 0; return 1; } vec_t VectorNormalize (vec3_t v) { float length, ilength; length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; length = sqrt (length); // FIXME if (length) { ilength = 1/length; v[0] *= ilength; v[1] *= ilength; v[2] *= ilength; } return length; } vec_t VectorNormalize2 (vec3_t v, vec3_t out) { float length, ilength; length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; length = sqrt (length); if (length) { ilength = 1/length; out[0] = v[0]*ilength; out[1] = v[1]*ilength; out[2] = v[2]*ilength; } return length; } void VectorMA (vec3_t veca, float scale, vec3_t vecb, vec3_t vecc) { vecc[0] = veca[0] + scale*vecb[0]; vecc[1] = veca[1] + scale*vecb[1]; vecc[2] = veca[2] + scale*vecb[2]; } void NormalToLatLong( const vec3_t normal, byte latlong[2] ) { // can't do atan2 (normal[1], normal[0]) if ( normal[0] == 0 && normal[1] == 0 ) { if ( normal[2] > 0 ) { latlong[0] = 0; // acos ( 1 ) latlong[1] = 0; } else { latlong[0] = 128; // acos ( -1 ) latlong[1] = 0; } } else { int angle; angle = (int)( acos (normal[2]) * 255.0 / (M_PI * 2) ) & 255; latlong[0] = angle; angle = (int)( atan2 (normal[1], normal[0]) * 255.0 / (M_PI * 2) ) & 255; latlong[1] = angle; } } void LatLongToNormal( byte latlong[2], vec3_t normal ) { float sin_a, sin_b, cos_a, cos_b; sin_a = (float)latlong[0] * (1.0 / 255.0) * M_PI * 2; cos_a = cos ( sin_a ); sin_a = sin ( sin_a ); sin_b = (float)latlong[1] * (1.0 / 255.0) * M_PI * 2; cos_b = cos ( sin_b ); sin_b = sin ( sin_b ); VectorSet ( normal, cos_b * sin_a, sin_b * sin_a, cos_a ); } vec_t _DotProduct (vec3_t v1, vec3_t v2) { return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; } void _VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out) { out[0] = veca[0]-vecb[0]; out[1] = veca[1]-vecb[1]; out[2] = veca[2]-vecb[2]; } void _VectorAdd (vec3_t veca, vec3_t vecb, vec3_t out) { out[0] = veca[0]+vecb[0]; out[1] = veca[1]+vecb[1]; out[2] = veca[2]+vecb[2]; } void _VectorCopy (vec3_t in, vec3_t out) { out[0] = in[0]; out[1] = in[1]; out[2] = in[2]; } void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross) { cross[0] = v1[1]*v2[2] - v1[2]*v2[1]; cross[1] = v1[2]*v2[0] - v1[0]*v2[2]; cross[2] = v1[0]*v2[1] - v1[1]*v2[0]; } vec_t VectorLength(vec3_t v) { int i; float length; length = 0; for (i=0 ; i< 3 ; i++) length += v[i]*v[i]; length = sqrt (length); return length; } void VectorInverse (vec3_t v) { v[0] = -v[0]; v[1] = -v[1]; v[2] = -v[2]; } void VectorScale (vec3_t in, vec_t scale, vec3_t out) { out[0] = in[0]*scale; out[1] = in[1]*scale; out[2] = in[2]*scale; } int Q_log2(int val) { int answer=0; while (val>>=1) answer++; return answer; } //==================================================================================== /* ============ COM_SkipPath ============ */ char *COM_SkipPath (char *pathname) { char *last; last = pathname; while (*pathname) { if (*pathname=='/') last = pathname+1; pathname++; } return last; } /* ============ COM_StripExtension ============ */ void COM_StripExtension (char *in, char *out) { while (*in && *in != '.') *out++ = *in++; *out = 0; } /* ============ COM_FileExtension ============ */ #if 0 // not used char *COM_FileExtension (char *in) { static char exten[8]; int i; while (*in && *in != '.') in++; if (!*in) return ""; in++; for (i=0 ; i<7 && *in ; i++,in++) exten[i] = *in; exten[i] = 0; return exten; } #endif /* ============ COM_FileBase ============ */ void COM_FileBase (char *in, char *out) { char *s, *s2; s = in + strlen(in) - 1; while (s != in && *s != '.') s--; for (s2 = s ; s2 != in && *s2 != '/' ; s2--) ; if (s-s2 < 2) out[0] = 0; else { s--; strncpy (out,s2+1, s-s2); out[s-s2] = 0; } } /* ============ COM_FilePath Returns the path up to, but not including the last / ============ */ void COM_FilePath (char *in, char *out) { char *s; s = in + strlen(in) - 1; while (s != in && *s != '/') s--; strncpy (out,in, s-in); out[s-in] = 0; } /* ================== COM_DefaultExtension ================== */ void COM_DefaultExtension (char *path, char *extension) { char *src; // // if path doesn't have a .EXT, append extension // (extension should include the .) // src = path + strlen(path) - 1; while (*src != '/' && src != path) { if (*src == '.') return; // it has an extension src--; } strcat (path, extension); } /* ============================================================================ BYTE ORDER FUNCTIONS ============================================================================ */ qboolean bigendien; // can't just use function pointers, or dll linkage can // mess up when qcommon is included in multiple places short (*_BigShort) (short l); short (*_LittleShort) (short l); int (*_BigLong) (int l); int (*_LittleLong) (int l); float (*_BigFloat) (float l); float (*_LittleFloat) (float l); short BigShort(short l){return _BigShort(l);} short LittleShort(short l) {return _LittleShort(l);} int BigLong (int l) {return _BigLong(l);} int LittleLong (int l) {return _LittleLong(l);} float BigFloat (float l) {return _BigFloat(l);} float LittleFloat (float l) {return _LittleFloat(l);} short ShortSwap (short l) { byte b1,b2; b1 = l&255; b2 = (l>>8)&255; return (b1<<8) + b2; } short ShortNoSwap (short l) { return l; } int LongSwap (int l) { byte b1,b2,b3,b4; b1 = l&255; b2 = (l>>8)&255; b3 = (l>>16)&255; b4 = (l>>24)&255; return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; } int LongNoSwap (int l) { return l; } float FloatSwap (float f) { union { float f; byte b[4]; } dat1, dat2; dat1.f = f; dat2.b[0] = dat1.b[3]; dat2.b[1] = dat1.b[2]; dat2.b[2] = dat1.b[1]; dat2.b[3] = dat1.b[0]; return dat2.f; } float FloatNoSwap (float f) { return f; } /* ================ Swap_Init ================ */ void Swap_Init (void) { byte swaptest[2] = {1,0}; // set the byte swapping variables in a portable manner if ( *(short *)swaptest == 1) { bigendien = false; _BigShort = ShortSwap; _LittleShort = ShortNoSwap; _BigLong = LongSwap; _LittleLong = LongNoSwap; _BigFloat = FloatSwap; _LittleFloat = FloatNoSwap; } else { bigendien = true; _BigShort = ShortNoSwap; _LittleShort = ShortSwap; _BigLong = LongNoSwap; _LittleLong = LongSwap; _BigFloat = FloatNoSwap; _LittleFloat = FloatSwap; } } /* ============ va does a varargs printf into a temp buffer, so I don't need to have varargs versions of all text functions. FIXME: make this buffer size safe someday ============ */ /* * 2010-11 Use multiple static buffers to avoid collisions. * Like g_utils::tv(),vtos() */ char *va(char *format, ...) { va_list argptr; static int index = 0; static char string[8][1024]; index = (index + 1) & 0x07; va_start (argptr, format); vsnprintf(string[index], sizeof(string[0]), format, argptr); va_end (argptr); return string[index]; } char com_token[MAX_TOKEN_CHARS]; /* ============== COM_Parse Parse a token out of a string ============== */ char *COM_Parse (char **data_p) { int c; int len; char *data; data = *data_p; len = 0; com_token[0] = 0; if (!data) { *data_p = NULL; return ""; } // skip whitespace skipwhite: while ( (c = *data) <= ' ') { if (c == 0) { *data_p = NULL; return ""; } data++; } // skip // comments if (c=='/' && data[1] == '/') { while (*data && *data != '\n') data++; goto skipwhite; } // handle quoted strings specially if (c == '\"') { data++; while (1) { c = *data++; if (c=='\"' || !c) { com_token[len] = 0; *data_p = data; return com_token; } if (len < MAX_TOKEN_CHARS) { com_token[len] = c; len++; } } } // parse a regular word do { if (len < MAX_TOKEN_CHARS) { com_token[len] = c; len++; } data++; c = *data; } while (c>32); if (len == MAX_TOKEN_CHARS) { // Com_Printf ("Token exceeded %i chars, discarded.\n", MAX_TOKEN_CHARS); len = 0; } com_token[len] = 0; *data_p = data; return com_token; } int Q_strnicmp (const char *string1, const char *string2, int n) { int c1, c2; if (string1 == NULL) { if (string2 == NULL) return 0; else return -1; } else if (string2 == NULL) return 1; do { c1 = *string1++; c2 = *string2++; if (!n--) return 0;// Strings are equal until end point if (c1 != c2) { if (c1 >= 'a' && c1 <= 'z') c1 -= ('a' - 'A'); if (c2 >= 'a' && c2 <= 'z') c2 -= ('a' - 'A'); if (c1 != c2) return c1 < c2 ? -1 : 1; } } while (c1); return 0;// Strings are equal } void Q_strncpyz2 (char *dst, const char *src, int dstSize) { if (!dst) Sys_Error(ERR_FATAL, "Q_strncpyz: NULL dst"); if (!src) Sys_Error(ERR_FATAL, "Q_strncpyz: NULL src"); if (dstSize < 1) Sys_Error(ERR_FATAL, "Q_strncpyz: dstSize < 1"); strncpy(dst, src, dstSize-1); dst[dstSize-1] = 0; } void Q_strcat (char *dst, const char *src, int dstSize) { int len; len = strlen(dst); if (len >= dstSize) Sys_Error(ERR_FATAL, "Q_strcat: already overflowed"); Q_strncpyz2(dst + len, src, dstSize - len); } char *Com_SkipWhiteSpace (char *data_p, qboolean *hasNewLines) { int c; while ((c = *data_p) <= ' ') { if (!c) return NULL; if (c == '\n') { com_parseLine++; *hasNewLines = true; } data_p++; } return data_p; } void Com_SkipRestOfLine (char **data_p) { char*data; int c; data = *data_p; while ((c = *data++) != 0) { if (c == '\n') { com_parseLine++; break; } } *data_p = data; } char *Com_ParseExt (char **data_p, qboolean allowNewLines) { int c, len = 0; char *data; qboolean hasNewLines = false; data = *data_p; com_token[0] = 0; // Make sure incoming data is valid if (!data) { *data_p = NULL; return com_token; } // Backup the session data so we can unget easily // Com_BackupParseSession(data_p); while (1) { // Skip whitespace data = Com_SkipWhiteSpace(data, &hasNewLines); if (!data) { *data_p = NULL; return com_token; } if (hasNewLines && !allowNewLines) { *data_p = data; return com_token; } c = *data; // Skip // comments if (c == '/' && data[1] == '/') { while (*data && *data != '\n') data++; } // Skip /* */ comments else if (c == '/' && data[1] == '*') { data += 2; while (*data && (*data != '*' || data[1] != '/')) { if (*data == '\n') com_parseLine++; data++; } if (*data) data += 2; } // An actual token else break; } // Handle quoted strings specially if (c == '\"') { data++; while (1) { c = *data++; if (c == '\n') com_parseLine++; if (c == '\"' || !c) { *data_p = data; com_token[len] = 0; return com_token; } if (len < MAX_TOKEN_CHARS) com_token[len++] = c; } } // Parse a regular word do { if (len < MAX_TOKEN_CHARS) com_token[len++] = c; data++; c = *data; } while (c > 32); if (len == MAX_TOKEN_CHARS) len = 0; com_token[len] = 0; *data_p = data; return com_token; } /* =============== Com_PageInMemory =============== */ int paged_total; void Com_PageInMemory (byte *buffer, int size) { int i; for (i=size-1 ; i>0 ; i-=4096) paged_total += buffer[i]; } /* ============================================================================ LIBRARY REPLACEMENT FUNCTIONS ============================================================================ */ int Q_strncasecmp (const char *s1, const char *s2, int n) { int c1, c2; do { c1 = *s1++; c2 = *s2++; if (!n--) return 0; // strings are equal until end point if (c1 != c2) { if (c1 >= 'a' && c1 <= 'z') c1 -= ('a' - 'A'); if (c2 >= 'a' && c2 <= 'z') c2 -= ('a' - 'A'); if (c1 != c2) return -1; // strings not equal } } while (c1); return 0; // strings are equal } int Q_strcasecmp (const char *s1, const char *s2) { return Q_strncasecmp (s1, s2, 99999); } void Com_sprintf (char *dest, int size, char *fmt, ...) { int len; va_list argptr; char bigbuffer[0x10000]; va_start (argptr,fmt); len = vsnprintf (bigbuffer,sizeof(bigbuffer), fmt,argptr); va_end (argptr); if (len >= size) Com_Printf ("Com_sprintf: overflow of %i in %i\n", len, size); //JD - Fix for potential server crashes. bigbuffer[size-1] = '\0'; //strcpy (dest, bigbuffer); strncpy (dest, bigbuffer, size-1); } /* ============================================================================ MORE LIBRARY REPLACEMENT FUNCTIONS ============================================================================ */ // not used, may be obsolete (2010-08) /* ============== Q_strncpyz ============== */ /* void Q_strncpyz( char *dest, const char *src, size_t size ) { #ifdef HAVE_STRLCPY strlcpy( dest, src, size ); #else if( size ) { while( --size && (*dest++ = *src++) ); *dest = '\0'; } #endif } */ /* ============== Q_strncatz ============== */ /* void Q_strncatz( char *dest, const char *src, size_t size ) { #ifdef HAVE_STRLCAT strlcat( dest, src, size ); #else if( size ) { while( --size && *dest++ ); if( size ) { dest--; while( --size && (*dest++ = *src++) ); } *dest = '\0'; } #endif } */ /* ============== Q_strlwr ============== */ char *Q_strlwr( char *s ) { char *p; if( s ) { for( p = s; *s; s++ ) *s = tolower( *s ); return p; } return NULL; } /* ===================================================================== INFO STRINGS ===================================================================== */ /* =============== Info_ValueForKey Searches the string for the given key and returns the associated value, or an empty string. =============== */ char *Info_ValueForKey (char *s, char *key) { /* * 2010-11 Increase static buffers from 2 to 8 to avoid collisions * Like g_utils.c::tv(),vtos() */ char pkey[512]; static char value[8][512]; static int valueindex = 0; char *o; valueindex = (valueindex + 1) & 0x07; if (*s == '\\') s++; while (1) { o = pkey; while (*s != '\\') { if (!*s) return ""; *o++ = *s++; } *o = 0; s++; o = value[valueindex]; while (*s != '\\' && *s) { if (!*s) return ""; *o++ = *s++; } *o = 0; if (!strcmp (key, pkey) ) return value[valueindex]; if (!*s) return ""; s++; } } void Info_RemoveKey (char *s, char *key) { char *start; char pkey[512]; char value[512]; char *o; if (strstr (key, "\\")) { // Com_Printf ("Can't use a key with a \\\n"); return; } while (1) { start = s; if (*s == '\\') s++; o = pkey; while (*s != '\\') { if (!*s) return; *o++ = *s++; } *o = 0; s++; o = value; while (*s != '\\' && *s) { if (!*s) return; *o++ = *s++; } *o = 0; if (!strcmp (key, pkey) ) { /* Two strcpy's instead of one - this was messing up * on modern, 64-bit Linux system due to "s" being modified * while it is being copied. * - E.B. */ strcpy( value , s ); strcpy( start , value ); return; } if (!*s) return; } } /* ================== Info_Validate Some characters are illegal in info strings because they can mess up the server's parsing ================== */ qboolean Info_Validate (char *s) { if (strstr (s, "\"")) return false; if (strstr (s, ";")) return false; return true; } void Info_SetValueForKey (char *s, char *key, char *value) { char newi[MAX_INFO_STRING], *v; int c; int maxsize = MAX_INFO_STRING; if (strstr (key, "\\") || strstr (value, "\\") ) { Com_Printf ("Can't use keys or values with a \\\n"); return; } if (strstr (key, ";") ) { Com_Printf ("Can't use keys or values with a semicolon\n"); return; } if (strstr (key, "\"") || strstr (value, "\"") ) { Com_Printf ("Can't use keys or values with a \"\n"); return; } if (strlen(key) > MAX_INFO_KEY-1 || strlen(value) > MAX_INFO_KEY-1) { Com_Printf ("Keys and values must be < 64 characters.\n"); return; } Info_RemoveKey (s, key); if (!value || !strlen(value)) return; Com_sprintf (newi, sizeof(newi), "\\%s\\%s", key, value); if (strlen(newi) + strlen(s) > maxsize) { Com_Printf ("Info string length exceeded\n"); return; } // only copy ascii values s += strlen(s); v = newi; while (*v) { c = *v++; c &= 127; // strip high bits if (c >= 32 && c < 127) *s++ = c; } *s = 0; } qboolean Info_KeyExists (const char *s, const char *key) { char pkey[512]; char *o; if (*s == '\\') s++; for (;;) { o = pkey; while (*s != '\\') { if (!*s) return false; *o++ = *s++; } *o = 0; s++; while (*s != '\\' && *s) s++; if (!strcmp (key, pkey) ) return true; if (!*s) return false; s++; } } //==================================================================== /* * ValidatePlayerName() * * checks validity of a player name string. * may modify the string: * - player_name must NOT be const. * - player_name_size passes size of caller's char array * * returns: the number of glyphs (visible chars) in the player's name */ size_t ValidatePlayerName( char *player_name, size_t player_name_size ) { char *pch; size_t count; size_t char_count; size_t glyph_count; size_t char_count_limit; assert( player_name != NULL ); assert( player_name_size > 0); assert( strlen( player_name ) < 127 ); for ( pch = player_name, count = strlen( player_name); count--; pch++ ) { // translate bad chars to space if ( !isascii( *pch ) || !isgraph( *pch ) ) *pch = ' '; } if ( player_name_size < PLAYERNAME_SIZE ) { char_count_limit = player_name_size - 1; } else { char_count_limit = PLAYERNAME_SIZE - 1; } char_count = glyph_count = 0; pch = player_name; while ( *pch && glyph_count < PLAYERNAME_GLYPHS && char_count < char_count_limit ) { // while chars and 1+ glyphs possible and 1+ chars possible. if ( Q_IsColorString( pch ) ) { if ( char_count < (char_count_limit-3) ) { // room for 3 chars is available char_count += 2; pch += 2; } else { // no room for color escape and glyph, done break; } } else { ++char_count; ++glyph_count; ++pch; } } assert( char_count <= char_count_limit ); assert( glyph_count <= PLAYERNAME_GLYPHS ); player_name[ char_count ] = '\0'; // possible truncation return glyph_count; } alien-arena-7.66+dfsg/source/game/g_chase.c0000600000175000017500000000601312161402010017550 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. JKD - 032207 - removed some very heinous things like bumping up the view during jumps, and using the old "look at player" angles upon dying. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" void UpdateChaseCam(edict_t *ent) { // is our chase target gone? if (!ent->client->chase_target->inuse || ent->client->chase_target->client->resp.spectator) { edict_t *old = ent->client->chase_target; ChaseNext(ent); if (ent->client->chase_target == old) { ent->client->chase_target = NULL; ent->client->ps.pmove.pm_flags &= ~PMF_NO_PREDICTION; return; } } gi.linkentity(ent); } void ChaseNext(edict_t *ent) { int i; char clean_name[PLAYERNAME_SIZE]; edict_t *e; if (!ent->client->chase_target) return; i = ent->client->chase_target - g_edicts; do { i++; if (i > g_maxclients->value) i = 1; e = g_edicts + i; if (!e->inuse) continue; if (!e->client->resp.spectator) break; } while (e != ent->client->chase_target); ent->client->chase_target = e; ent->client->update_chase = true; G_CleanPlayerName( e->client->pers.netname, clean_name ); safe_centerprintf(ent, "Following %s", clean_name); } void ChasePrev(edict_t *ent) { int i; char clean_name[PLAYERNAME_SIZE]; edict_t *e; if (!ent->client->chase_target) return; i = ent->client->chase_target - g_edicts; do { i--; if (i < 1) i = g_maxclients->value; e = g_edicts + i; if (!e->inuse) continue; if (!e->client->resp.spectator) break; } while (e != ent->client->chase_target); ent->client->chase_target = e; ent->client->update_chase = true; G_CleanPlayerName( e->client->pers.netname, clean_name ); safe_centerprintf(ent, "Following %s", clean_name); } void GetChaseTarget(edict_t *ent) { int i; char clean_name[PLAYERNAME_SIZE]; edict_t *other; for (i = 1; i <= g_maxclients->value; i++) { other = g_edicts + i; if (other->inuse && !other->client->resp.spectator) { ent->client->chase_target = other; ent->client->update_chase = true; G_CleanPlayerName( other->client->pers.netname, clean_name ); safe_centerprintf(ent, "Following %s", clean_name); UpdateChaseCam(ent); return; } } safe_centerprintf(ent, "No other players to chase."); } alien-arena-7.66+dfsg/source/game/g_deathray.h0000600000175000017500000000036612161402010020300 0ustar zero79zero79 #define FRAME_stand01 0 #define FRAME_stand02 1 #define FRAME_stand03 2 #define FRAME_stand04 3 #define FRAME_stand05 4 #define FRAME_stand06 5 #define MODEL_SCALE 1.000000 alien-arena-7.66+dfsg/source/game/p_weapon.c0000600000175000017500000017327212161402010020003 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. Copyright (C) 20?? COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // p_weapon.c #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" #include "m_player.h" static qboolean is_quad; static byte is_silenced; // static qboolean altfire; float damage_buildup = 1.0; void P_ProjectSource (gclient_t *client, vec3_t point, vec3_t distance, vec3_t forward, vec3_t right, vec3_t result) { vec3_t _distance; VectorCopy (distance, _distance); if (client->pers.hand == LEFT_HANDED) _distance[1] *= -1; else if (client->pers.hand == CENTER_HANDED) _distance[1] = 0; G_ProjectSource (point, _distance, forward, right, result); } /* =============== PlayerNoise Each player can have two noise objects associated with it: a personal noise (jumping, pain, weapon firing), and a weapon target noise (bullet wall impacts) Monsters that don't directly see the player can move to a noise in hopes of seeing the player from there. =============== */ void PlayerNoise(edict_t *who, vec3_t where, int type) { edict_t *noise; if (type == PNOISE_WEAPON) { if (who->client->silencer_shots) { who->client->silencer_shots--; return; } } if (deathmatch->value) return; if (who->flags & FL_NOTARGET) return; if (!who->mynoise) { noise = G_Spawn(); noise->classname = "player_noise"; VectorSet (noise->mins, -8, -8, -8); VectorSet (noise->maxs, 8, 8, 8); noise->owner = who; noise->svflags = SVF_NOCLIENT; who->mynoise = noise; noise = G_Spawn(); noise->classname = "player_noise"; VectorSet (noise->mins, -8, -8, -8); VectorSet (noise->maxs, 8, 8, 8); noise->owner = who; noise->svflags = SVF_NOCLIENT; who->mynoise2 = noise; } if (type == PNOISE_SELF || type == PNOISE_WEAPON) { noise = who->mynoise; level.sound_entity = noise; level.sound_entity_framenum = level.framenum; } else // type == PNOISE_IMPACT { noise = who->mynoise2; level.sound2_entity = noise; level.sound2_entity_framenum = level.framenum; } VectorCopy (where, noise->s.origin); VectorSubtract (where, noise->maxs, noise->absmin); VectorAdd (where, noise->maxs, noise->absmax); noise->teleport_time = level.time; gi.linkentity (noise); } qboolean Pickup_Weapon (edict_t *ent, edict_t *other) { int index; gitem_t *ammo; if (other->in_vehicle) { return false; } index = ITEM_INDEX(ent->item); //mutators if ( instagib->integer || rocket_arena->integer || insta_rockets->integer ) { return false; //why pick them up in these modes? } if( g_tactical->integer) { //certain classes can only use certain weapons if(other->ctype == 0) { if(!strcmp(ent->classname, "weapon_rocketlauncher") || !strcmp(ent->classname, "weapon_chaingun") || !strcmp(ent->classname, "weapon_bfg") || !strcmp(ent->classname, "weapon_supershotgun")) return false; } else if (!strcmp(ent->classname, "weapon_shotgun") || !strcmp(ent->classname, "weapon_hyperblaster") || !strcmp(ent->classname, "weapon_railgun") || !strcmp(ent->classname, "weapon_minderaser")) return false; //do not pick up a weapon if you already have one - the premise behind this is that it will give others opportunities to pick up weapons since they do not respawn if(other->client->pers.inventory[ITEM_INDEX(FindItem("Alien Disruptor"))] || other->client->pers.inventory[ITEM_INDEX(FindItem("Alien Smartgun"))] || other->client->pers.inventory[ITEM_INDEX(FindItem("Rocket Launcher"))] || other->client->pers.inventory[ITEM_INDEX(FindItem("Disruptor"))] || other->client->pers.inventory[ITEM_INDEX(FindItem("Pulse Rifle"))] || other->client->pers.inventory[ITEM_INDEX(FindItem("Flame Thrower"))] ) { safe_centerprintf(other, "Cannot pick up weapon, you already have a weapon"); return false; } } if ( ( (dmflags->integer & DF_WEAPONS_STAY)) && other->client->pers.inventory[index]) { if (!(ent->spawnflags & (DROPPED_ITEM | DROPPED_PLAYER_ITEM) ) ) return false; // leave the weapon for others to pickup } other->client->pers.inventory[index]++; if (!(ent->spawnflags & DROPPED_ITEM) ) { // give them some ammo with it ammo = FindItem (ent->item->ammo); if ( dmflags->integer & DF_INFINITE_AMMO ) Add_Ammo (other, ammo, 1000, true, true); else if (ent->spawnflags & DROPPED_PLAYER_ITEM) Add_Ammo (other, ammo, ammo->quantity, true, true); //DROPPED WEAPON give full ammo else Add_Ammo (other, ammo, ammo->quantity, true, false); //if ME, make sure original weapon gets respawned if(!strcmp(ent->classname, "weapon_minderaser")) { if(ent->replaced_weapon != NULL) SetRespawn(ent->replaced_weapon, 5); } if ( !(ent->spawnflags & DROPPED_PLAYER_ITEM) ) { if (deathmatch->value) { if (dmflags->integer & DF_WEAPONS_STAY) ent->flags |= FL_RESPAWN; else { //weapon = FindItem (ent->item->weapon); if(ent->item->weapmodel == WEAP_VAPORIZER) SetRespawn (ent, 10); else SetRespawn (ent, 5); } } } } if (other->client->pers.weapon != ent->item && (other->client->pers.inventory[index] == 1) && ( !deathmatch->value || other->client->pers.weapon == FindItem("blaster") || other->client->pers.weapon == FindItem("Alien Blaster")) ) other->client->newweapon = ent->item; if (other->client->pers.lastfailedswitch == ent->item && (level.framenum - other->client->pers.failedswitch_framenum) < 5) other->client->newweapon = ent->item; return true; } /* =========== Q2_FindFile Finds the file in the search path. Given a relative path, returns an open FILE* for reading =========== */ void Q2_FindFile (char *filename, FILE **file) { char full_path[MAX_OSPATH]; cvar_t *dbg_developer; *file = NULL; dbg_developer = gi.cvar("developer", "0", 0 ); if ( dbg_developer && dbg_developer->integer == 2 ) { // A prefix for FS_FullPath Com_DPrintf() tracing to show a call from game. gi.dprintf("G: "); } if ( gi.FullPath( full_path, sizeof(full_path), filename ) ) { *file = fopen( full_path, "rb" ); if( *file == NULL ) { gi.dprintf("Q2_FindFile: failed fopen for read: %s", full_path ); } } } /* =============== ChangeWeapon The old weapon has been dropped all the way, so make the new one current =============== */ void ChangeWeapon (edict_t *ent) { char *info; char weaponame[64] = " "; char weaponmodel[MAX_OSPATH] = " "; int i; int done; char weaponpath[MAX_OSPATH] = " "; FILE *file; ent->client->pers.lastweapon = ent->client->pers.weapon; ent->client->pers.weapon = ent->client->newweapon; ent->client->newweapon = NULL; ent->client->machinegun_shots = 0; // set visible model if (ent->s.modelindex == 255) { if (ent->client->pers.weapon) i = ((ent->client->pers.weapon->weapmodel & 0xff) << 8); else i = 0; ent->s.skinnum = (ent - g_edicts - 1) | i; } if (ent->client->pers.weapon && ent->client->pers.weapon->ammo) ent->client->ammo_index = ITEM_INDEX(FindItem(ent->client->pers.weapon->ammo)); else ent->client->ammo_index = 0; if (!ent->client->pers.weapon) { // dead ent->client->ps.gunindex = 0; return; } ent->client->weaponstate = WEAPON_ACTIVATING; ent->client->ps.gunframe = 0; ent->client->ps.gunindex = gi.modelindex(ent->client->pers.weapon->view_model); if (ent->in_vehicle) { return; } //set up code to set player world weapon model, as well as some hacks :( info = Info_ValueForKey (ent->client->pers.userinfo, "skin"); i = 0; done = 0; strcpy(weaponame, " "); weaponame[0] = 0; while(!done) { if((info[i] == '/') || (info[i] == '\\')) done = 1; weaponame[i] = info[i]; if(i > 63) done = 1; i++; } strcpy(weaponmodel, " "); weaponmodel[0] = 0; sprintf(weaponmodel, "players/%s%s", weaponame, "weapon.md2"); //default #ifdef ALTERIA //add in Alteria definitions #else if( !Q_strcasecmp(ent->client->pers.weapon->view_model,"models/weapons/v_violator/tris.md2")) sprintf(weaponmodel, "players/%s%s", weaponame, "w_violator.md2"); else if( !Q_strcasecmp( ent->client->pers.weapon->view_model,"models/weapons/v_rocket/tris.md2")) sprintf(weaponmodel, "players/%s%s", weaponame, "w_rlauncher.md2"); else if( !Q_strcasecmp(ent->client->pers.weapon->view_model,"models/weapons/v_blast/tris.md2")) sprintf(weaponmodel, "players/%s%s", weaponame, "w_blaster.md2"); else if( !Q_strcasecmp(ent->client->pers.weapon->view_model,"models/weapons/v_alienblast/tris.md2")) sprintf(weaponmodel, "players/%s%s", weaponame, "w_alienblaster.md2"); else if( !Q_strcasecmp(ent->client->pers.weapon->view_model,"models/weapons/v_bfg/tris.md2")) sprintf(weaponmodel, "players/%s%s", weaponame, "w_bfg.md2"); else if( !Q_strcasecmp(ent->client->pers.weapon->view_model,"models/weapons/v_rail/tris.md2")) sprintf(weaponmodel, "players/%s%s", weaponame, "w_railgun.md2"); else if( !Q_strcasecmp(ent->client->pers.weapon->view_model,"models/weapons/v_shotg2/tris.md2")) sprintf(weaponmodel, "players/%s%s", weaponame, "w_sshotgun.md2"); else if( !Q_strcasecmp(ent->client->pers.weapon->view_model,"models/weapons/v_shotg/tris.md2")) sprintf(weaponmodel, "players/%s%s", weaponame, "w_shotgun.md2"); else if( !Q_strcasecmp(ent->client->pers.weapon->view_model,"models/weapons/v_hyperb/tris.md2")) sprintf(weaponmodel, "players/%s%s", weaponame, "w_hyperblaster.md2"); else if( !Q_strcasecmp(ent->client->pers.weapon->view_model,"models/weapons/v_chain/tris.md2")) sprintf(weaponmodel, "players/%s%s", weaponame, "w_chaingun.md2"); else if( !Q_strcasecmp(ent->client->pers.weapon->view_model, "models/weapons/v_minderaser/tris.md2")) sprintf(weaponmodel, "players/%s%s", weaponame, "w_minderaser.md2"); else if( !Q_strcasecmp(ent->client->pers.weapon->view_model,"vehicles/deathball/v_wep.md2")) sprintf(weaponmodel, "players/%s%s", weaponame, "w_machinegun.md2"); #endif sprintf(weaponpath, "%s", weaponmodel); ent->s.modelindex2 = gi.checkmodelindex(weaponmodel); if (ent->s.modelindex2 == 0) // check if hasn't already been loaded { Q2_FindFile (weaponpath, &file); //does it really exist? if(!file) { sprintf(weaponpath, "%s%s", weaponame, "weapon.md2"); //no w_weaps, do we have this model? Q2_FindFile (weaponpath, &file); if(!file) //server does not have this player model sprintf(weaponmodel, "players/martianenforcer/weapon.md2");//default player(martian) else { //have the model, but it has no w_weaps sprintf(weaponmodel, "players/%s%s", weaponame, "weapon.md2"); //custom weapon fclose(file); } } else fclose(file); ent->s.modelindex2 = gi.modelindex(weaponmodel); } //play a sound like in Q3, except for blaster, so it doesn't do it on spawn. if( Q_strcasecmp( ent->client->pers.weapon->view_model,"models/weapons/v_blast/tris.md2") ) gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/whoosh.wav"), 1, ATTN_NORM, 0); ent->client->anim_priority = ANIM_PAIN; if(ent->client->ps.pmove.pm_flags & PMF_DUCKED) { ent->s.frame = FRAME_crpain1; ent->client->anim_end = FRAME_crpain4; } else { ent->s.frame = FRAME_pain301; ent->client->anim_end = FRAME_pain304; } } /* ================= NoAmmoWeaponChange ================= */ void NoAmmoWeaponChange (edict_t *ent) { if ( ent->client->pers.inventory[ITEM_INDEX(FindItem("cells"))] && ent->client->pers.inventory[ITEM_INDEX(FindItem("Disruptor"))] ) { ent->client->newweapon = FindItem ("Disruptor"); return; } if ( ent->client->pers.inventory[ITEM_INDEX(FindItem("rockets"))] && ent->client->pers.inventory[ITEM_INDEX(FindItem("Rocket Launcher"))] ) { ent->client->newweapon = FindItem ("Rocket Launcher"); return; } if ( ent->client->pers.inventory[ITEM_INDEX(FindItem("napalm"))] && ent->client->pers.inventory[ITEM_INDEX(FindItem("Flame Thrower"))] ) { ent->client->newweapon = FindItem ("Flame Thrower"); return; } if ( ent->client->pers.inventory[ITEM_INDEX(FindItem("bullets"))] > 1 && ent->client->pers.inventory[ITEM_INDEX(FindItem("Pulse Rifle"))] ) { ent->client->newweapon = FindItem ("Pulse Rifle"); return; } if ( ent->client->pers.inventory[ITEM_INDEX(FindItem("alien smart grenade"))] && ent->client->pers.inventory[ITEM_INDEX(FindItem("Alien Smartgun"))] ) { ent->client->newweapon = FindItem ("Alien Smartgun"); return; } if ( ent->client->pers.inventory[ITEM_INDEX(FindItem("cells"))] > 4 && ent->client->pers.inventory[ITEM_INDEX(FindItem("Alien Disruptor"))] ) { ent->client->newweapon = FindItem ("Alien Disruptor"); return; } if(g_tactical->integer && ent->ctype == 0) ent->client->newweapon = FindItem ("Alien Blaster"); else ent->client->newweapon = FindItem ("Blaster"); } /* ================= Think_Weapon Called by ClientBeginServerFrame and ClientThink ================= */ void Think_Weapon (edict_t *ent) { // if just died, put the weapon away if (ent->health < 1) { ent->client->newweapon = NULL; ChangeWeapon (ent); } // call active weapon think routine if (ent->client->pers.weapon && ent->client->pers.weapon->weaponthink) { is_quad = (ent->client->quad_framenum > level.framenum); if (ent->client->silencer_shots) is_silenced = MZ_SILENCED; else is_silenced = 0; ent->client->pers.weapon->weaponthink (ent); } } /* ================ Use_Weapon Make the weapon ready if there is ammo ================ */ void Use_Weapon (edict_t *ent, gitem_t *item) { int ammo_index; gitem_t *ammo_item; if (ent->in_vehicle || ent->in_deathball) { return; } // see if we're already using it if (item == ent->client->pers.weapon) return; if (item->ammo && !g_select_empty->value && !(item->flags & IT_AMMO)) { ammo_item = FindItem(item->ammo); ammo_index = ITEM_INDEX(ammo_item); if (!ent->client->pers.inventory[ammo_index]) { safe_cprintf (ent, PRINT_HIGH, "No %s for %s.\n", ammo_item->pickup_name, item->pickup_name); ent->client->pers.lastfailedswitch = item; ent->client->pers.failedswitch_framenum = level.framenum; return; } if (ent->client->pers.inventory[ammo_index] < item->quantity) { safe_cprintf (ent, PRINT_HIGH, "Not enough %s for %s.\n", ammo_item->pickup_name, item->pickup_name); ent->client->pers.lastfailedswitch = item; ent->client->pers.failedswitch_framenum = level.framenum; return; } } // change to this weapon when down ent->client->newweapon = item; } /* ================ Drop_Weapon ================ */ void Drop_Weapon (edict_t *ent, gitem_t *item) { int index; if ((dmflags->integer & DF_WEAPONS_STAY) || instagib->integer || rocket_arena->integer || insta_rockets->integer ) { return; } index = ITEM_INDEX(item); // see if we're already using it if ( ((item == ent->client->pers.weapon) || (item == ent->client->newweapon))&& (ent->client->pers.inventory[index] == 1) ) { safe_cprintf (ent, PRINT_HIGH, "Can't drop current weapon\n"); return; } Drop_Item (ent, item); ent->client->pers.inventory[index]--; } /* ================ Weapon_Generic A generic function to handle the basics of weapon thinking ================ */ #define FRAME_FIRE_FIRST (FRAME_ACTIVATE_LAST + 1) #define FRAME_IDLE_FIRST (FRAME_FIRE_LAST + 1) void Weapon_Generic (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int FRAME_IDLE_LAST, int FRAME_DEACTIVATE, int *pause_frames, int *fire_frames, void (*fire)(edict_t *ent)) { int n; #define gunframe ent->client->ps.gunframe if (ent->client->weaponstate == WEAPON_DROPPING) { ChangeWeapon (ent); return; } if (ent->client->weaponstate == WEAPON_ACTIVATING) { if(excessive->value || quickweap->value || ent->client->invincible_framenum > level.framenum) { ent->client->weaponstate = WEAPON_READY; gunframe = FRAME_IDLE_FIRST; goto fire_begin; //velociraptors be damned } else if ((ent->client->latched_buttons|ent->client->buttons) & (BUTTON_ATTACK|BUTTON_ATTACK2)) { if (gunframe >= FRAME_ACTIVATE_LAST-3) { ent->client->weaponstate = WEAPON_READY; gunframe = FRAME_IDLE_FIRST; goto fire_begin; //velociraptors be damned } } else if (gunframe == FRAME_ACTIVATE_LAST) { ent->client->weaponstate = WEAPON_READY; gunframe = FRAME_IDLE_FIRST; return; } gunframe++; return; } if ((ent->client->newweapon) && (ent->client->weaponstate != WEAPON_FIRING || gunframe == FRAME_FIRE_FIRST || gunframe == FRAME_FIRE_LAST)) { if(excessive->value || quickweap->value || ent->client->invincible_framenum > level.framenum) { ChangeWeapon (ent); return; } ent->client->weaponstate = WEAPON_DROPPING; gunframe = FRAME_DEACTIVATE-1; return; } if (ent->client->weaponstate == WEAPON_READY) { fire_begin: if ( ((ent->client->latched_buttons|ent->client->buttons) & BUTTON_ATTACK) ) { ent->client->spawnprotected = false; ent->client->latched_buttons &= ~BUTTON_ATTACK; if ((!ent->client->ammo_index) || ( ent->client->pers.inventory[ent->client->ammo_index] >= ent->client->pers.weapon->quantity)) { gunframe = FRAME_FIRE_FIRST; ent->client->weaponstate = WEAPON_FIRING; // start the animation if(!ent->client->anim_run) { //looks better than skating, eh? ent->client->anim_priority = ANIM_ATTACK; if (ent->client->ps.pmove.pm_flags & PMF_DUCKED) { ent->s.frame = FRAME_crattak1-1; ent->client->anim_end = FRAME_crattak9; } else { ent->s.frame = FRAME_attack1-1; ent->client->anim_end = FRAME_attack8; } } } else { if (level.time >= ent->pain_debounce_time) { gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0); ent->pain_debounce_time = level.time + 1; } NoAmmoWeaponChange (ent); } } //alt fire else if ( ((ent->client->latched_buttons|ent->client->buttons) & BUTTON_ATTACK2) ) { ent->client->spawnprotected = false; ent->client->latched_buttons &= ~BUTTON_ATTACK2; if ((!ent->client->ammo_index) || ( ent->client->pers.inventory[ent->client->ammo_index] >= ent->client->pers.weapon->quantity)) { gunframe = FRAME_FIRE_FIRST; ent->client->weaponstate = WEAPON_FIRING; // start the animation if(!ent->client->anim_run) { //looks better than skating, eh? ent->client->anim_priority = ANIM_ATTACK; if (ent->client->ps.pmove.pm_flags & PMF_DUCKED) { ent->s.frame = FRAME_crattak1-1; ent->client->anim_end = FRAME_crattak9; } else { ent->s.frame = FRAME_attack1-1; ent->client->anim_end = FRAME_attack8; } } } else { if (level.time >= ent->pain_debounce_time) { gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0); ent->pain_debounce_time = level.time + 1; } NoAmmoWeaponChange (ent); } } else { if (gunframe == FRAME_IDLE_LAST) { #ifdef ALTERIA gunframe = FRAME_IDLE_FIRST; //we can return this to alien arena if we ever decide to have idle animations again for weapons #endif return; } if (pause_frames) { for (n = 0; pause_frames[n]; n++) { if (gunframe == pause_frames[n]) { if (rand()&15) return; } } } gunframe++; return; } } if (ent->client->weaponstate == WEAPON_FIRING) { for (n = 0; fire_frames[n]; n++) { if (gunframe == fire_frames[n]) { if (ent->client->quad_framenum > level.framenum) gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage3.wav"), 1, ATTN_NORM, 0); fire (ent); break; } } if (!fire_frames[n]) gunframe++; if (gunframe == FRAME_IDLE_FIRST+1) ent->client->weaponstate = WEAPON_READY; } #undef gunframe } #ifdef ALTERIA //add Alteria weapons here /* ====================================================================== VIOALATOR ====================================================================== */ void punch_fire (edict_t *ent) { vec3_t offset, start; vec3_t forward, right; int damage; damage = 30; AngleVectors (ent->client->v_angle, forward, right, NULL); VectorScale (forward, 2, ent->client->kick_origin); ent->client->kick_angles[0] = -1; VectorSet(offset, 4, 4, ent->viewheight-2); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); fire_punch (ent, start, forward, damage); ent->client->ps.gunframe++; PlayerNoise(ent, start, PNOISE_WEAPON); //punch does not use ammo } void Weapon_Punch (edict_t *ent) { static int pause_frames[] = {52, 0}; static int fire_frames[] = {9, 0}; Weapon_Generic (ent, 5, 14, 52, 56, pause_frames, fire_frames, punch_fire); } void Weapon_Wizard_Punch (edict_t *ent) { static int pause_frames[] = {52, 0}; static int fire_frames[] = {9, 0}; Weapon_Generic (ent, 5, 14, 52, 56, pause_frames, fire_frames, punch_fire); } #else void weapon_disruptor_fire (edict_t *ent) { vec3_t start, muzzle; vec3_t forward, right; vec3_t offset; int damage; int kick; int buildup; if ( instagib->integer || insta_rockets->integer ) { damage = 200; kick = 200; } else { damage = 60; kick = 60; } if (is_quad) { damage *= 2; kick *= 2; } //alt fire if (ent->client->buttons & BUTTON_ATTACK2) { ent->client->ps.fov = 20; buildup = damage_buildup; //int, for the pic flag ent->client->ps.stats[STAT_ZOOMED] = buildup; damage_buildup += 0.1; //the longer you hold the key, the stronger the blast if(damage_buildup > 3.0) damage_buildup = 3.0; if(damage_buildup < 3.0) //play a sound gi.sound(ent, CHAN_AUTO, gi.soundindex("world/laser1.wav"), 1, ATTN_NORM, 0); return; } AngleVectors (ent->client->v_angle, forward, right, NULL); VectorScale (forward, -3, ent->client->kick_origin); ent->client->kick_angles[0] = -3; VectorSet(offset, 32, 5, ent->viewheight-5); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, muzzle); VectorSet(offset, 32, 0, ent->viewheight); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); fire_disruptor (ent, start, muzzle, forward, damage*damage_buildup, kick); //alt fire - reset some things ent->client->ps.fov = atoi(Info_ValueForKey(ent->client->pers.userinfo, "fov")); //alt fire - reset the fov; ent->client->ps.stats[STAT_ZOOMED] = 0; damage_buildup = 1.0; // send muzzle flash gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_RAILGUN | is_silenced); gi.multicast (ent->s.origin, MULTICAST_PVS); ent->client->ps.gunframe++; PlayerNoise(ent, start, PNOISE_WEAPON); if ( !( (dmflags->integer & DF_INFINITE_AMMO) || instagib->integer || insta_rockets->integer ) ) { ent->client->pers.inventory[ent->client->ammo_index] = ent->client->pers.inventory[ent->client->ammo_index]-5; } } void Weapon_Disruptor (edict_t *ent) { static int pause_frames[] = {42, 0}; static int fire_frames[] = {5, 0}; static int excessive_fire_frames[] = {5,7,9,11,0}; if(excessive->value || ent->client->invincible_framenum > level.framenum) Weapon_Generic (ent, 4, 12, 42, 46, pause_frames, excessive_fire_frames, weapon_disruptor_fire); else Weapon_Generic (ent, 4, 12, 42, 46, pause_frames, fire_frames, weapon_disruptor_fire); } void weapon_vaporizer_fire (edict_t *ent) { vec3_t start; vec3_t forward, right; vec3_t offset; int damage = 100; int radius_damage = 100; int damage_radius = 150; int kick = 200; if (is_quad) { radius_damage *=2; damage *= 2; kick *= 4; } if(ent->client->buttons & BUTTON_ATTACK2) ent->altfire = true; else if(ent->client->buttons & BUTTON_ATTACK) { ent->altfire = false; if (ent->client->pers.inventory[ent->client->ammo_index] < 2) { ent->client->ps.gunframe = 19; NoAmmoWeaponChange(ent); } } if(ent->client->ps.gunframe == 7) gi.sound(ent, CHAN_AUTO, gi.soundindex("smallmech/sight.wav"), 1, ATTN_NORM, 0); AngleVectors (ent->client->v_angle, forward, right, NULL); VectorScale (forward, -3, ent->client->kick_origin); ent->client->kick_angles[0] = -3; VectorSet(offset, 32, 5, ent->viewheight-5); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); if(ent->client->ps.gunframe == 12) { VectorAdd(start, forward, start); start[2]+=6; gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BLUE_MUZZLEFLASH); gi.WritePosition (start); gi.multicast (start, MULTICAST_PVS); } if(ent->client->ps.gunframe == 13) { if(ent->altfire) {//alt fire AngleVectors (ent->client->v_angle, forward, right, NULL); VectorScale (forward, -2, ent->client->kick_origin); ent->client->kick_angles[0] = -1; VectorSet(offset, 32, 5, ent->viewheight-4); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); forward[0] = forward[0] * 4.6; forward[1] = forward[1] * 4.6; forward[2] = forward[2] * 4.6; fire_bomb (ent, start, forward, damage, 250, damage_radius, radius_damage, 8); if (! ( dmflags->integer & DF_INFINITE_AMMO ) ) ent->client->pers.inventory[ent->client->ammo_index]= ent->client->pers.inventory[ent->client->ammo_index]-1; } else { fire_vaporizer (ent, start, forward, damage, kick); if (! ( dmflags->integer & DF_INFINITE_AMMO ) ) ent->client->pers.inventory[ent->client->ammo_index]= ent->client->pers.inventory[ent->client->ammo_index]-2; } // send muzzle flash gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_RAILGUN | is_silenced); gi.multicast (ent->s.origin, MULTICAST_PVS); VectorAdd(start, forward, start); start[2]+=6; gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BLUE_MUZZLEFLASH); gi.WritePosition (start); gi.multicast (start, MULTICAST_PVS); gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/energyfield.wav"), 1, ATTN_NORM, 0); ent->client->weapon_sound = 0; } ent->client->ps.gunframe++; } void Weapon_Vaporizer (edict_t *ent) { static int pause_frames[] = {48, 0}; static int fire_frames[] = {6, 7, 12, 13, 0}; Weapon_Generic (ent, 5, 18, 48, 52, pause_frames, fire_frames, weapon_vaporizer_fire); } /* ====================================================================== Flame Thrower ====================================================================== */ void weapon_flamethrower_fire (edict_t *ent) { vec3_t offset, start; vec3_t forward, right; int damage = 25; float damage_radius = 200; if((ent->client->buttons & BUTTON_ATTACK2) && ent->client->ps.gunframe == 6) { //shoot a fireball AngleVectors (ent->client->v_angle, forward, right, NULL); VectorSet(offset, 8, 8, ent->viewheight-8); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); fire_fireball (ent, start, forward, damage, 1500, damage_radius, 75); // send muzzle flash gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_GRENADE | is_silenced); gi.multicast (ent->s.origin, MULTICAST_PVS); ent->client->ps.gunframe++; PlayerNoise(ent, start, PNOISE_WEAPON); if (! ( dmflags->integer & DF_INFINITE_AMMO ) ) { ent->client->pers.inventory[ent->client->ammo_index] -= ent->client->pers.weapon->quantity*10; if(ent->client->pers.inventory[ent->client->ammo_index] < 0) ent->client->pers.inventory[ent->client->ammo_index] = 0; } return; } if (!(ent->client->buttons & BUTTON_ATTACK) || (!ent->is_bot && ent->client->newweapon)) { ent->client->ps.gunframe = 17; return; } // send muzzle flash gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_GRENADE | is_silenced); gi.multicast (ent->s.origin, MULTICAST_PVS); PlayerNoise(ent, start, PNOISE_WEAPON); if (is_quad) damage *= 2; AngleVectors (ent->client->v_angle, forward, right, NULL); VectorSet(offset, 8, 8, ent->viewheight-8); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); fire_flamethrower (ent, start, forward, damage, 500, damage_radius); ent->client->ps.gunframe++; PlayerNoise(ent, start, PNOISE_WEAPON); if (! ( dmflags->integer & DF_INFINITE_AMMO ) ) { ent->client->pers.inventory[ent->client->ammo_index] -= ent->client->pers.weapon->quantity; if(ent->client->pers.inventory[ent->client->ammo_index] < 0) ent->client->pers.inventory[ent->client->ammo_index] = 0; } } void Weapon_Flame (edict_t *ent) { static int pause_frames[] = {36, 0}; static int fire_frames[] = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0}; Weapon_Generic (ent, 5, 16, 36, 40, pause_frames, fire_frames, weapon_flamethrower_fire); } /* ====================================================================== ROCKET ====================================================================== */ void Weapon_RocketLauncher_Fire (edict_t *ent) { vec3_t offset, start; vec3_t forward, right; int damage; float damage_radius; int radius_damage; // damage = 100 + (int)(random() * 20.0); damage = 110; // median of formerly random 100..120 radius_damage = 120; damage_radius = 120; if (is_quad) { damage *= 2; radius_damage *= 2; } AngleVectors (ent->client->v_angle, forward, right, NULL); VectorScale (forward, 2, ent->client->kick_origin); ent->client->kick_angles[0] = -1; VectorSet(offset, 4, 4, ent->viewheight-2); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); if(ent->client->buttons & BUTTON_ATTACK2) //alt fire { if(ent->client->homing_shots < 5) { if(excessive->value) //no homers in excessive! fire_rocket (ent, start, forward, damage, 900, damage_radius, radius_damage); else fire_homingrocket (ent, start, forward, damage, 250, damage_radius, radius_damage); } else { safe_cprintf(ent, PRINT_HIGH, "Exceeded max number of homing missiles for this life!\n"); fire_rocket (ent, start, forward, damage, 900, damage_radius, radius_damage); } } else fire_rocket (ent, start, forward, damage, 900, damage_radius, radius_damage); // send muzzle flash gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_ROCKET | is_silenced); gi.multicast (ent->s.origin, MULTICAST_PVS); ent->client->ps.gunframe++; PlayerNoise(ent, start, PNOISE_WEAPON); if ( (!( dmflags->integer & DF_INFINITE_AMMO )) && !rocket_arena->integer && !insta_rockets->integer ) { ent->client->pers.inventory[ent->client->ammo_index]--; } } void Weapon_RocketLauncher (edict_t *ent) { static int pause_frames[] = {52, 0}; static int fire_frames[] = {6, 0}; static int excessive_fire_frames[] = {5,7,9,11,13, 0}; if(excessive->value || ent->client->invincible_framenum > level.framenum) Weapon_Generic (ent, 5, 14, 52, 56, pause_frames, excessive_fire_frames, Weapon_RocketLauncher_Fire); else Weapon_Generic (ent, 5, 14, 52, 56, pause_frames, fire_frames, Weapon_RocketLauncher_Fire); } /* ====================================================================== BLASTER ====================================================================== */ void Blaster_Fire (edict_t *ent, vec3_t g_offset, int damage, qboolean hyper, qboolean alien, int effect) { vec3_t forward, right; vec3_t start, muzzle; vec3_t offset; if (is_quad) damage *= 2; AngleVectors (ent->client->v_angle, forward, right, NULL); if(!hyper) { VectorScale (forward, -3, ent->client->kick_origin); ent->client->kick_angles[0] = -3; } if(hyper && (ent->client->buttons & BUTTON_ATTACK)) VectorSet(offset, 32, 6, ent->viewheight-8); else if(hyper && (ent->client->buttons & BUTTON_ATTACK2)) VectorSet(offset, 32, 6, ent->viewheight-10); else VectorSet(offset, 30, 6, ent->viewheight-5); VectorAdd (offset, g_offset, offset); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, muzzle); if (hyper && (ent->client->buttons & BUTTON_ATTACK)) { VectorSet(offset, 32, 0, ent->viewheight); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); } else VectorCopy (muzzle, start); if(hyper) { if(ent->client->buttons & BUTTON_ATTACK2) { //alt fire ent->altfire = !ent->altfire; if(ent->altfire) { gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/blastf1a.wav"), 1, ATTN_NORM, 0); fire_blasterball (ent, start, forward, damage*3, 1000, effect, hyper, false); } } else { // [no file]gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/hyprbd1a.wav"), 1, ATTN_NORM, 0); fire_blaster (ent, start, muzzle, forward, damage, 2800, effect, hyper); } } else { if(ent->client->buttons & BUTTON_ATTACK2) { //alt fire fire_blaster_beam (ent, start, forward, (int)((float)damage/1.4), 0, false, alien); gi.sound(ent, CHAN_AUTO, gi.soundindex("vehicles/shootlaser.wav"), 1, ATTN_NORM, 0); } else fire_blasterball (ent, start, forward, damage, 1200, effect, hyper, alien); } // send muzzle flash gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); if (hyper) gi.WriteByte (MZ_HYPERBLASTER | is_silenced); else if (ent->client->buttons & BUTTON_ATTACK2) gi.WriteByte (MZ_RAILGUN | is_silenced); else gi.WriteByte (MZ_BLASTER | is_silenced); gi.multicast (ent->s.origin, MULTICAST_PVS); PlayerNoise(ent, start, PNOISE_WEAPON); //create visual muzzle flash sprite! if(!hyper || (ent->client->buttons & BUTTON_ATTACK2)) { VectorAdd(muzzle, forward, muzzle); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BLUE_MUZZLEFLASH); gi.WritePosition (muzzle); gi.multicast (muzzle, MULTICAST_PVS); } } void Weapon_Blaster_Fire (edict_t *ent) { int damage; damage = 30; Blaster_Fire (ent, vec3_origin, damage, false, false, EF_BLASTER); ent->client->ps.gunframe++; } void Weapon_Blaster (edict_t *ent) { static int pause_frames[] = {52, 0}; static int fire_frames[] = {5,0}; static int excessive_fire_frames[] = {5,6,7,8,0}; if(excessive->value || ent->client->invincible_framenum > level.framenum) Weapon_Generic (ent, 4, 8, 52, 55, pause_frames, excessive_fire_frames, Weapon_Blaster_Fire); else Weapon_Generic (ent, 4, 8, 52, 55, pause_frames, fire_frames, Weapon_Blaster_Fire); } //to do - tactical - create different effect(i think same damage and behavior though). void Weapon_AlienBlaster_Fire (edict_t *ent) { int damage; damage = 30; Blaster_Fire (ent, vec3_origin, damage, false, true, EF_ROCKET); ent->client->ps.gunframe++; } void Weapon_AlienBlaster (edict_t *ent) { static int pause_frames[] = {52, 0}; static int fire_frames[] = {5,0}; static int excessive_fire_frames[] = {5,6,7,8,0}; if(excessive->value || ent->client->invincible_framenum > level.framenum) Weapon_Generic (ent, 4, 8, 52, 55, pause_frames, excessive_fire_frames, Weapon_AlienBlaster_Fire); else Weapon_Generic (ent, 4, 8, 52, 55, pause_frames, fire_frames, Weapon_AlienBlaster_Fire); } //vehicles void Weapon_Bomber_Fire (edict_t *ent) { vec3_t offset, start; vec3_t forward, right; int damage; float damage_radius; int radius_damage; damage = 150; radius_damage = 175; damage_radius = 250; if (is_quad) { damage *= 2; radius_damage *= 2; } AngleVectors (ent->client->v_angle, forward, right, NULL); VectorScale (forward, -2, ent->client->kick_origin); ent->client->kick_angles[0] = -1; VectorSet(offset, 8, 8, ent->viewheight-4); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); if(ent->client->buttons & BUTTON_ATTACK2 && ent->client->ps.gunframe != 12) { fire_rocket (ent, start, forward, damage/3, 1400, damage_radius/2, radius_damage/2); gi.sound (ent, CHAN_WEAPON, gi.soundindex("weapons/rocklr1b.wav"), 1, ATTN_NORM, 0); ent->client->ps.gunframe = 12; } else if(ent->client->ps.gunframe != 6){ forward[0] = forward[0] * 2.6; forward[1] = forward[1] * 2.6; fire_bomb (ent, start, forward, damage, 250, damage_radius, radius_damage, 8); gi.sound (ent, CHAN_WEAPON, gi.soundindex("vehicles/shootbomb.wav"), 1, ATTN_NORM, 0); } // send muzzle flash gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_BFG | is_silenced); gi.multicast (ent->s.origin, MULTICAST_PVS); ent->client->ps.gunframe++; //might want to work with this some if (! ( dmflags->integer & DF_INFINITE_AMMO ) ) ent->client->pers.inventory[ent->client->ammo_index]--; } void Weapon_Bomber (edict_t *ent) { static int pause_frames[] = {30, 0}; static int fire_frames[] = {6,12,0}; static int excessive_fire_frames[] = {6,8,10,12,0}; if(excessive->value || ent->client->invincible_framenum > level.framenum) Weapon_Generic (ent, 5, 16, 39, 45, pause_frames, excessive_fire_frames, Weapon_Bomber_Fire); else Weapon_Generic (ent, 5, 16, 39, 45, pause_frames, fire_frames, Weapon_Bomber_Fire); } void Weapon_Strafer_Fire (edict_t *ent) { vec3_t forward, right; vec3_t start; vec3_t offset; int damage; float damage_radius; int radius_damage; radius_damage = 100; damage_radius = 100; if(excessive->value) damage = 60; else damage = 20; if (is_quad) damage *= 2; AngleVectors (ent->client->v_angle, forward, right, NULL); VectorScale (forward, -3, ent->client->kick_origin); ent->client->kick_angles[0] = -3; VectorSet(offset, 40, 6, ent->viewheight-5); right[0] = right[0] * 5; right[1] = right[1] * 5; P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); if(ent->client->buttons & BUTTON_ATTACK2) fire_rocket (ent, start, forward, damage, 1200, damage_radius, radius_damage); else fire_blaster_beam (ent, start, forward, damage, 0, true, false); // send muzzle flash gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_BFG | is_silenced); gi.multicast (ent->s.origin, MULTICAST_PVS); VectorAdd(start, forward, start); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BLUE_MUZZLEFLASH); gi.WritePosition (start); gi.multicast (start, MULTICAST_PVS); //now do the other side AngleVectors (ent->client->v_angle, forward, right, NULL); VectorScale (forward, -3, ent->client->kick_origin); ent->client->kick_angles[0] = -3; VectorSet(offset, 40, 6, ent->viewheight-5); right[0] = right[0] * -5; right[1] = right[1] * -5; P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); if(ent->client->buttons & BUTTON_ATTACK2) { fire_rocket (ent, start, forward, damage, 1200, damage_radius, radius_damage); gi.sound (ent, CHAN_WEAPON, gi.soundindex("weapons/rocklr1b.wav"), 1, ATTN_NORM, 0); } else { fire_blaster_beam (ent, start, forward, damage, 0, true, false); gi.sound (ent, CHAN_WEAPON, gi.soundindex("vehicles/shootlaser.wav"), 1, ATTN_NORM, 0); } // send muzzle flash gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_BFG | is_silenced); gi.multicast (ent->s.origin, MULTICAST_PVS); VectorAdd(start, forward, start); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BLUE_MUZZLEFLASH); gi.WritePosition (start); gi.multicast (start, MULTICAST_PVS); ent->client->ps.gunframe++; } void Weapon_Strafer (edict_t *ent) //for now { static int pause_frames[] = {30, 0}; static int fire_frames[] = {6,0}; static int excessive_fire_frames[] = {6,8,10,0}; if(excessive->value || ent->client->invincible_framenum > level.framenum) Weapon_Generic (ent, 5, 11, 33, 39, pause_frames, excessive_fire_frames, Weapon_Strafer_Fire); else Weapon_Generic (ent, 5, 11, 33, 39, pause_frames, fire_frames, Weapon_Strafer_Fire); } void Weapon_Hover_Fire (edict_t *ent) { vec3_t forward, right; vec3_t start; vec3_t offset; int damage; if(excessive->value) damage = 200; else damage = 20; if (is_quad) damage *= 2; AngleVectors (ent->client->v_angle, forward, right, NULL); VectorScale (forward, -3, ent->client->kick_origin); ent->client->kick_angles[0] = -3; VectorSet(offset, 40, 0, ent->viewheight-5); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); if(ent->client->buttons & BUTTON_ATTACK2) { fire_blasterball (ent, start, forward, damage*3, 1500, EF_ROCKET, false, false); gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/hypbrl1a.wav"), 1, ATTN_NORM, 0); } else if(ent->client->ps.gunframe == 6) { fire_hover_beam (ent, start, forward, damage, 0, true); gi.sound (ent, CHAN_WEAPON, gi.soundindex("weapons/biglaser.wav"), 1, ATTN_NORM, 0); VectorAdd(start, forward, start); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_CHAINGUNSMOKE); gi.WritePosition (start); gi.multicast (start, MULTICAST_PVS); } // send muzzle flash gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_BFG | is_silenced); gi.multicast (ent->s.origin, MULTICAST_PVS); if(ent->client->buttons & BUTTON_ATTACK2) { forward[0] = forward[0] * 10; forward[1] = forward[1] * 10; VectorAdd(start, forward, start); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_SMART_MUZZLEFLASH); gi.WritePosition (start); gi.multicast (start, MULTICAST_PVS); } ent->client->ps.gunframe++; } void Weapon_Hover (edict_t *ent) //for now { static int pause_frames[] = {30, 0}; static int fire_frames[] = {6,8,10,0}; static int excessive_fire_frames[] = {6,8,10,0}; if(excessive->value || ent->client->invincible_framenum > level.framenum) Weapon_Generic (ent, 5, 11, 33, 39, pause_frames, excessive_fire_frames, Weapon_Hover_Fire); else Weapon_Generic (ent, 5, 11, 33, 39, pause_frames, fire_frames, Weapon_Hover_Fire); } void Weapon_Beamgun_Fire (edict_t *ent) { vec3_t offset; int effect; int damage; if (!(ent->client->buttons & (BUTTON_ATTACK|BUTTON_ATTACK2)) || (!ent->is_bot && ent->client->newweapon)) { ent->client->ps.gunframe = 25; } else { if (! ent->client->pers.inventory[ent->client->ammo_index] ) { if (level.time >= ent->pain_debounce_time) { gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0); ent->pain_debounce_time = level.time + 1; } NoAmmoWeaponChange (ent); } else { offset[0] = 0; offset[1] = 0; offset[2] = 3; if ((ent->client->ps.gunframe == 6) || (ent->client->ps.gunframe == 9)) effect = EF_HYPERBLASTER; else effect = 0; if(excessive->value) damage = 20; else damage = 7; Blaster_Fire (ent, offset, damage, true, false, effect); if (! ( dmflags->integer & DF_INFINITE_AMMO ) ) ent->client->pers.inventory[ent->client->ammo_index]--; } ent->client->ps.gunframe++; if (ent->client->ps.gunframe == 24 && ent->client->pers.inventory[ent->client->ammo_index]) ent->client->ps.gunframe = 6; } } void Weapon_Beamgun (edict_t *ent) { static int pause_frames[] = {53, 0}; static int fire_frames[] = {6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 0}; Weapon_Generic (ent, 5, 24, 53, 57, pause_frames, fire_frames, Weapon_Beamgun_Fire); } /* ====================================================================== MACHINEGUN / CHAINGUN ====================================================================== */ void Machinegun_Fire (edict_t *ent) { int i; int shots; vec3_t start; vec3_t forward, right; vec3_t offset; int damage; int kick = 2; if(excessive->value) damage = 60; else damage = 18; if ((ent->client->ps.gunframe == 5) && !(ent->client->buttons & BUTTON_ATTACK || ent->client->buttons & BUTTON_ATTACK2)) { ent->client->ps.gunframe = 14; ent->client->weapon_sound = 0; return; } else if ((ent->client->ps.gunframe == 13) && (ent->client->buttons & BUTTON_ATTACK || ent->client->buttons & BUTTON_ATTACK2) && ent->client->pers.inventory[ent->client->ammo_index]) { ent->client->ps.gunframe = 5; } else if (ent->client->buttons & BUTTON_ATTACK2 && ent->client->ps.gunframe > 6) { if(ent->client->ps.gunframe == 7 || ent->client->ps.gunframe == 12) { ent->client->ps.gunframe = 14; return; } ent->altfire = true; ent->client->ps.gunframe++; } else if (ent->client->buttons & BUTTON_ATTACK2) { ent->client->ps.gunframe++; ent->altfire = true; } else if (ent->client->buttons & BUTTON_ATTACK){ ent->client->ps.gunframe++; ent->altfire = false; } else ent->client->ps.gunframe++; shots = 1; if (ent->client->pers.inventory[ent->client->ammo_index] < 0) ent->client->pers.inventory[ent->client->ammo_index]= 0; if (ent->client->pers.inventory[ent->client->ammo_index] < shots) shots = ent->client->pers.inventory[ent->client->ammo_index]; if (!shots) { if (level.time >= ent->pain_debounce_time) { gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0); ent->pain_debounce_time = level.time + 1; } NoAmmoWeaponChange (ent); return; } if (is_quad) { damage *= 2; kick *= 2; } AngleVectors (ent->client->v_angle, forward, right, NULL);//was up if(ent->client->ps.gunframe == 6 || ent->client->ps.gunframe == 8 || ent->client->ps.gunframe == 10 || ent->client->ps.gunframe == 12) { if(ent->altfire) ent->client->kick_angles[0] = -3; /* Kick view up */ else { ent->client->kick_angles[2] = (random() - 0.5)*3; /* Twist the view around a bit */ ent->client->kick_angles[0] = -1; /* tiny kick for pulsing effect */ } } if(ent->client->ps.gunframe == 6 && ent->client->buttons & BUTTON_ATTACK2) { int bullet_count = DEFAULT_SSHOTGUN_COUNT; /* If we're low on ammo, fire less shots */ if(ent->client->pers.inventory[ent->client->ammo_index] < DEFAULT_SSHOTGUN_COUNT/2) bullet_count = ent->client->pers.inventory[ent->client->ammo_index] * 2; VectorSet(offset, 1, 1, ent->viewheight-0.5); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); fire_shotgun (ent, start, forward, damage/2, kick, DEFAULT_SHOTGUN_HSPREAD, DEFAULT_SHOTGUN_VSPREAD, bullet_count, MOD_CGALTFIRE); //play a booming sound gi.sound(ent, CHAN_AUTO, gi.soundindex("world/rocket.wav"), 1, ATTN_NORM, 0); // send muzzle flash gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte ((MZ_CHAINGUN1 + shots - 1) | is_silenced); gi.multicast (ent->s.origin, MULTICAST_PVS); //create smoke effect forward[0] = forward[0] * 24; forward[1] = forward[1] * 24; right[0] = right[0] * 3; right[1] = right[1] * 3; start[2] -= 2; VectorAdd(start, forward, start); VectorAdd(start, right, start); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_CHAINGUNSMOKE); gi.WritePosition (start); gi.multicast (start, MULTICAST_PVS); if (! ( dmflags->integer & DF_INFINITE_AMMO ) ) ent->client->pers.inventory[ent->client->ammo_index] -= 10; //kick it ahead, we don't want spinning ent->client->ps.gunframe = 12; } else if(!ent->altfire){ if (!(ent->client->buttons & BUTTON_ATTACK) && ent->client->ps.gunframe > 6) { // Make it easier to escape from the animation while not firing. // Since this is a rapid-fire weapon, there's no reason not to do // this. (If it wasn't, allowing this would make it be possible to // cheat the maximum fire rate.) if (!ent->is_bot && ent->client->newweapon) ent->client->ps.gunframe = 14; return; //Don't waste ammo } for (i=0 ; iviewheight-0.5); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); fire_bullet (ent, start, forward, damage, kick, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MOD_CHAINGUN); } // send muzzle flash gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte ((MZ_CHAINGUN1 + shots - 1) | is_silenced); gi.multicast (ent->s.origin, MULTICAST_PVS); //create visual muzzle flash sprite! forward[0] = forward[0] * 24; forward[1] = forward[1] * 24; right[0] = right[0] * 3; right[1] = right[1] * 3; start[2] -= 2; VectorAdd(start, forward, start); VectorAdd(start, right, start); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_CHAINGUNSMOKE); gi.WritePosition (start); gi.multicast (start, MULTICAST_PVS); if (! ( dmflags->integer & DF_INFINITE_AMMO ) ) ent->client->pers.inventory[ent->client->ammo_index] -= shots; // Make it easier to escape from the animation while firing. Since // this is a rapid-fire weapon, there's no reason not to do this. (If // it wasn't, allowing this would make it be possible to cheat the // maximum fire rate.) if (!ent->is_bot && ent->client->newweapon) ent->client->ps.gunframe = 14; } } void Weapon_Chain (edict_t *ent) { static int pause_frames[] = {43, 0}; static int fire_frames[] = {5, 6, 7, 8, 9, 10, 11, 12, 13}; Weapon_Generic (ent, 4, 14, 43, 46, pause_frames, fire_frames, Machinegun_Fire); } void weapon_smartgun_fire (edict_t *ent) { vec3_t offset, start; vec3_t forward, right; int damage; float damage_radius; int radius_damage; // damage = 100 + (int)(random() * 20.0); damage = 110; // median of formerly random damage of 100..120 radius_damage = 120; damage_radius = 120; if (is_quad || excessive->value) { damage *= 2; radius_damage *= 2; } AngleVectors (ent->client->v_angle, forward, right, NULL); VectorScale (forward, -2, ent->client->kick_origin); ent->client->kick_angles[0] = -1; VectorSet(offset, 8, 8, ent->viewheight-4); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); forward[0] = forward[0] * 2.6; forward[1] = forward[1] * 2.6; forward[2] = forward[2] * 2.6; if(ent->altfire) { if(excessive->value) fire_smartgrenade (ent, start, forward, damage, 400, damage_radius, radius_damage, 8); else fire_prox (ent, start, forward, damage-50, 200, damage_radius, radius_damage-50, 8); } else fire_smartgrenade (ent, start, forward, damage, 500, damage_radius, radius_damage, 8); // send muzzle flash gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_SHOTGUN | is_silenced); gi.multicast (ent->s.origin, MULTICAST_PVS); ent->client->ps.gunframe++; PlayerNoise(ent, start, PNOISE_WEAPON); //create visual muzzle flash sprite! forward[0] = forward[0] * 10; forward[1] = forward[1] * 10; VectorAdd(start, forward, start); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_SMART_MUZZLEFLASH); gi.WritePosition (start); gi.multicast (start, MULTICAST_PVS); if (! ( dmflags->integer & DF_INFINITE_AMMO ) ) ent->client->pers.inventory[ent->client->ammo_index]--; } void Weapon_Smartgun (edict_t *ent) { static int pause_frames[] = {31, 0}; static int fire_frames[] = {6, 0}; if(ent->client->buttons & BUTTON_ATTACK2) ent->altfire = true; else if(ent->client->buttons & BUTTON_ATTACK) ent->altfire = false; Weapon_Generic (ent, 3, 11, 31, 35, pause_frames, fire_frames, weapon_smartgun_fire); } void weapon_minderaser_fire (edict_t *ent) { vec3_t offset, start; vec3_t forward, right; int damage; float damage_radius; int radius_damage; damage = 110; radius_damage = 120; damage_radius = 120; if (is_quad || excessive->value) { damage *= 2; radius_damage *= 2; } AngleVectors (ent->client->v_angle, forward, right, NULL); VectorScale (forward, 2, ent->client->kick_origin); ent->client->kick_angles[0] = -1; VectorSet(offset, 8, 8, ent->viewheight-4); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); forward[0] = forward[0] * 12.0; forward[1] = forward[1] * 12.0; forward[2] = forward[2] * 12.0; if(ent->altfire) fire_spider (ent, start, forward, 25); else fire_minderaser (ent, start, forward, 30); gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/minderaserfire.wav"), 1, ATTN_NORM, 0); // send muzzle flash gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_RAILGUN | is_silenced); gi.multicast (ent->s.origin, MULTICAST_PVS); ent->client->ps.gunframe++; PlayerNoise(ent, start, PNOISE_WEAPON); //create visual muzzle flash sprite! forward[0] = forward[0] * 2; forward[1] = forward[1] * 2; VectorAdd(start, forward, start); start[2]+=6; gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BOSSTPORT); gi.WritePosition (start); gi.multicast (start, MULTICAST_PVS); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BLUE_MUZZLEFLASH); gi.WritePosition (start); gi.multicast (start, MULTICAST_PVS); ent->client->pers.inventory[ent->client->ammo_index]--; } void Weapon_Minderaser (edict_t *ent) { static int pause_frames[] = {31, 0}; static int fire_frames[] = {6, 0}; if(ent->client->buttons & BUTTON_ATTACK2) ent->altfire = true; else if(ent->client->buttons & BUTTON_ATTACK) ent->altfire = false; Weapon_Generic (ent, 3, 11, 31, 35, pause_frames, fire_frames, weapon_minderaser_fire); } void Weapon_Deathball_Fire (edict_t *ent) { vec3_t start; vec3_t forward, right; vec3_t offset; AngleVectors (ent->client->v_angle, forward, right, NULL); VectorScale (forward, -3, ent->client->kick_origin); ent->client->kick_angles[0] = -3; VectorSet(offset, 32, 5, ent->viewheight-5); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); if(ent->client->ps.gunframe == 7) { fire_deathball (ent, start, forward, 550); // send muzzle flash gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_RAILGUN | is_silenced); gi.multicast (ent->s.origin, MULTICAST_PVS); VectorAdd(start, forward, start); start[2]+=6; gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BLUE_MUZZLEFLASH); gi.WritePosition (start); gi.multicast (start, MULTICAST_PVS); gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/energyfield.wav"), 1, ATTN_NORM, 0); ent->client->weapon_sound = 0; } ent->client->ps.gunframe++; } void Weapon_Deathball (edict_t *ent) { static int pause_frames[] = {33, 0}; static int fire_frames[] = {7,0}; Weapon_Generic (ent, 5, 11, 33, 39, pause_frames, fire_frames, Weapon_Deathball_Fire); } /* ====================================================================== VIOLATOR ====================================================================== */ void Violator_Fire (edict_t *ent) { vec3_t start; vec3_t forward, right, left, back; vec3_t offset; int damage; int kick = 4; if(excessive->value || instagib->integer) damage = 200; else damage = 40; if ((ent->client->ps.gunframe == 6) && !(ent->client->buttons & (BUTTON_ATTACK|BUTTON_ATTACK2))) { ent->client->ps.gunframe = 14; ent->client->weapon_sound = 0; return; } else if (!ent->altfire && ent->client->ps.gunframe > 6 && !(ent->client->buttons & (BUTTON_ATTACK|BUTTON_ATTACK2))) { //Fast-forward through firing animation if not firing anymore. //This is purely cosmetic, the player can resume firing at any point //point in this animation. //TODO: special sound effect here? ent->client->ps.gunframe+=1; ent->client->weapon_sound = 0; // Make it easier to escape from the animation while not firing. Since // this is a rapid-fire weapon, there's no reason not to do this. (If // it wasn't, allowing this would make it be possible to cheat the // maximum fire rate.) if (!ent->is_bot && ent->client->newweapon) ent->client->ps.gunframe = 14; return; } else if (ent->client->ps.gunframe == 14 && (ent->client->buttons & (BUTTON_ATTACK|BUTTON_ATTACK2))) { ent->client->ps.gunframe = 6; } else if (ent->client->buttons & BUTTON_ATTACK2 && ent->client->ps.gunframe > 6) { if(ent->client->ps.gunframe == 7 || ent->client->ps.gunframe == 13) { ent->client->ps.gunframe = 14; return; } ent->altfire = true; ent->client->ps.gunframe = 14; } else if (ent->client->buttons & BUTTON_ATTACK2) { ent->client->ps.gunframe++; ent->altfire = true; } else if (ent->client->buttons & BUTTON_ATTACK){ ent->client->ps.gunframe++; ent->altfire = false; } else ent->client->ps.gunframe++; if (is_quad) { damage *= 2; kick *=2; } AngleVectors (ent->client->v_angle, forward, right, NULL); VectorScale (forward, -6 * random(), ent->client->kick_origin); ent->client->kick_angles[0] = -6 * random(); VectorScale(forward, 10, forward); VectorScale(right, 10, right); VectorScale (right, -10, left); VectorScale (forward, -10, back); if(ent->client->ps.gunframe == 6 && ent->client->buttons & BUTTON_ATTACK2) { VectorSet(offset, 1, 1, ent->viewheight-0.5); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); fire_violator(ent, start, forward, damage/2, kick*20, 1); fire_violator(ent, start, right, damage/2, kick*20, 1); fire_violator(ent, start, left, damage/2, kick*20, 1); fire_violator(ent, start, back, damage/2, kick*20, 1); ent->client->resp.weapon_shots[8]++; gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/viofire2.wav"), 1, ATTN_NORM, 0); // send muzzle flash and effects gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_RAILGUN | is_silenced); gi.multicast (ent->s.origin, MULTICAST_PVS); VectorScale(forward, 1.4, forward); VectorAdd(start, forward, start); VectorScale(right, -0.5, right); VectorAdd(start, right, start); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BOSSTPORT); gi.WritePosition (start); gi.multicast (start, MULTICAST_PVS); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BLUE_MUZZLEFLASH); gi.WritePosition (start); gi.multicast (start, MULTICAST_PVS); //kick it ahead, we don't want it continuing to pump ent->client->ps.gunframe = 12; } else if(!ent->altfire) { VectorSet(offset, 1, 1, ent->viewheight-0.5); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); fire_violator(ent, start, forward, damage, kick, 0); gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/viofire1.wav"), 1, ATTN_NORM, 0); ent->client->resp.weapon_shots[8]++; // send muzzle flash gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_RAILGUN | is_silenced); gi.multicast (ent->s.origin, MULTICAST_PVS); VectorScale(forward, 1.4, forward); VectorAdd(start, forward, start); VectorScale(right, -0.5, right); VectorAdd(start, right, start); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_VOLTAGE); gi.WritePosition (start); gi.WriteDir(forward); gi.multicast (start, MULTICAST_PVS); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BLUE_MUZZLEFLASH); gi.WritePosition (start); gi.multicast (start, MULTICAST_PVS); // Make it easier to escape from the animation while firing. Since // this is a rapid-fire weapon, there's no reason not to do this. (If // it wasn't, allowing this would make it be possible to cheat the // maximum fire rate.) if (!ent->is_bot && ent->client->newweapon) ent->client->ps.gunframe = 14; } } void Weapon_Violator (edict_t *ent) { static int pause_frames[] = {43, 0}; static int fire_frames[] = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; static int bot_fire_frames[] = {5, 6, 7, 8, 9, 10, 11, 12, 13}; if(ent->is_bot) //done because bots need one frame in which to "escape" from firing Weapon_Generic (ent, 4, 14, 43, 46, pause_frames, bot_fire_frames, Violator_Fire); else Weapon_Generic (ent, 4, 14, 43, 46, pause_frames, fire_frames, Violator_Fire); } //Tactical weapons - bombs, detonators, etc void Weapon_TacticalBomb_Fire (edict_t *ent) { vec3_t start; vec3_t forward, right; vec3_t offset; AngleVectors (ent->client->v_angle, forward, right, NULL); VectorScale (forward, -3, ent->client->kick_origin); ent->client->kick_angles[0] = -3; VectorSet(offset, 32, 5, ent->viewheight-5); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); if(ent->client->ps.gunframe == 7) { fire_tacticalbomb (ent, start, forward, 100); // send muzzle flash gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_RAILGUN | is_silenced); gi.multicast (ent->s.origin, MULTICAST_PVS); VectorAdd(start, forward, start); start[2]+=6; gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BLUE_MUZZLEFLASH); gi.WritePosition (start); gi.multicast (start, MULTICAST_PVS); gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/energyfield.wav"), 1, ATTN_NORM, 0); // to do - change me ent->client->weapon_sound = 0; } ent->client->ps.gunframe++; ent->client->pers.inventory[ent->client->ammo_index]--; } void Weapon_TacticalBomb (edict_t *ent) { static int pause_frames[] = {33, 0}; static int fire_frames[] = {7,0}; Weapon_Generic (ent, 5, 11, 33, 39, pause_frames, fire_frames, Weapon_TacticalBomb_Fire); } #endif alien-arena-7.66+dfsg/source/game/g_vehicles.c0000600000175000017500000003531712161402010020300 0ustar zero79zero79/* Copyright (C) 20?? COR Entertainment, LLC. Copyright (C) 1998 by "Attila." Based on the email address provided, Attila is likely the pseudonym of Jens Bohnwagner, but this isn't certain. Original code: http://www.quakewiki.net/archives/qdevels/quake2/1_2_98.html This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" /*we get silly velocity-effects when we are on ground and try to accelerate, so lift us a little bit if possible*/ qboolean Jet_AvoidGround( edict_t *ent ) { vec3_t new_origin; trace_t trace; qboolean success; /*Check if there is enough room above us before we change origin[2]*/ new_origin[0] = ent->s.origin[0]; new_origin[1] = ent->s.origin[1]; new_origin[2] = ent->s.origin[2] + 0.5; trace = gi.trace( ent->s.origin, ent->mins, ent->maxs, new_origin, ent, MASK_MONSTERSOLID ); if ( (success=(trace.plane.normal[2]) == 0 ) ) /*no ceiling?*/ ent->s.origin[2] += 0.5; /*then make sure off ground*/ return success; } /*This function returns true if the jet is activated (surprise, surprise)*/ qboolean Jet_Active( edict_t *ent ) { return ( ent->client->Jet_framenum >= level.framenum ); } /*If a player dies with activated jetpack this function will be called and produces a little explosion*/ void Jet_Explosion( edict_t *ent ) { gi.WriteByte( svc_temp_entity ); gi.WriteByte( TE_EXPLOSION1 ); /*TE_EXPLOSION2 is possible too*/ gi.WritePosition( ent->s.origin ); gi.multicast( ent->s.origin, MULTICAST_PVS ); } /*The lifting effect is done through changing the origin, it gives the best results. Of course its a little dangerous because if we dont take care, we can move into solid*/ void Jet_ApplyLifting( edict_t *ent ) { float delta; vec3_t new_origin; trace_t trace; int time = 24; /*must be >0, time/10 = time in sec for a complete cycle (up/down)*/ float amplitude = 2.0; /*calculate the z-distance to lift in this step*/ delta = sin( (float)((level.framenum%time)*(360/time))/180*M_PI ) * amplitude; delta = (float)((int)(delta*8))/8; /*round to multiples of 0.125*/ VectorCopy( ent->s.origin, new_origin ); new_origin[2] += delta; if( VectorLength(ent->velocity) == 0 ) { /*i dont know the reason yet, but there is some floating so we have to compensate that here (only if there is no velocity left)*/ new_origin[0] -= 0.125; new_origin[1] -= 0.125; new_origin[2] -= 0.125; } /*before we change origin, its important to check that we dont go into solid*/ trace = gi.trace( ent->s.origin, ent->mins, ent->maxs, new_origin, ent, MASK_MONSTERSOLID ); if ( trace.plane.normal[2] == 0 ) VectorCopy( new_origin, ent->s.origin ); } /*if the angle of the velocity vector is different to the viewing angle (flying curves or stepping left/right) we get a dotproduct which is here used for rolling*/ void Jet_ApplyRolling( edict_t *ent, vec3_t right ) { float roll, value = 0.05, sign = -1; /*set this to +1 if you want to roll contrariwise*/ roll = DotProduct( ent->velocity, right ) * value * sign; ent->client->kick_angles[ROLL] = roll; } /*Now for the main movement code. The steering is a lot like in water, that means your viewing direction is your moving direction. You have three direction Boosters: the big Main Booster and the smaller up-down and left-right Boosters. There are only 2 adds to the code of the first tutorial: the Jet_next_think and the rolling. The other modifications results in the use of the built-in quake functions, there is no change in moving behavior (reinventing the wheel is a lot of "fun" and a BIG waste of time ;-))*/ void Jet_ApplyJet( edict_t *ent, usercmd_t *ucmd ) { float direction; vec3_t acc; vec3_t forward, right; int i; gitem_t *vehicle; vehicle = FindItemByClassname("item_hover"); /*clear gravity so we dont have to compensate it with the Boosters*/ if(!(ent->client->pers.inventory[ITEM_INDEX(vehicle)])) ent->client->ps.pmove.gravity = 0; else //make hovercraft fall quicker ent->client->ps.pmove.gravity = sv_gravity->value * 4; /*calculate the direction vectors dependent on viewing direction (length of the vectors forward/right is always 1, the coordinates of the vectors are values of how much youre looking in a specific direction [if youre looking up to the top, the x/y values are nearly 0 the z value is nearly 1])*/ AngleVectors( ent->client->v_angle, forward, right, NULL ); /*Run jet only 10 times a second so movement dont depends on fps because ClientThink is called as often as possible (fps<10 still is a problem ?)*/ if ( ent->client->Jet_next_think <= level.framenum ) { ent->client->Jet_next_think = level.framenum + 1; /*clear acceleration-vector*/ VectorClear( acc ); /*if we are moving forward or backward add MainBooster acceleration (60)*/ if ( ucmd->forwardmove ) { /*are we accelerating backward or forward?*/ direction = (ucmd->forwardmove<0) ? -1.0 : 1.0; /*add the acceleration for each direction*/ if(!(ent->client->pers.inventory[ITEM_INDEX(vehicle)])) { acc[0] += direction * forward[0] * 60; acc[1] += direction * forward[1] * 60; acc[2] += direction * forward[2] * 60; } else { acc[0] += direction * forward[0] * 120; acc[1] += direction * forward[1] * 120; } } /*if we sidestep add Left-Right-Booster acceleration (40)*/ if ( ucmd->sidemove ) { /*are we accelerating left or right*/ direction = (ucmd->sidemove<0) ? -1.0 : 1.0; /*add only to x and y acceleration*/ acc[0] += right[0] * direction * 40; acc[1] += right[1] * direction * 40; } /*if we crouch or jump add Up-Down-Booster acceleration (30)*/ /*if we are in a hovercraft, we won't do this */ // if(!(ent->client->pers.inventory[ITEM_INDEX(vehicle)])) { if ( ucmd->upmove ) acc[2] += ucmd->upmove > 0 ? 30 : -30; // } /*now apply some friction dependent on velocity (higher velocity results in higher friction), without acceleration this will reduce the velocity to 0 in a few steps*/ ent->velocity[0] += -(ent->velocity[0]/6.0); ent->velocity[1] += -(ent->velocity[1]/6.0); ent->velocity[2] += -(ent->velocity[2]/7.0); /*then accelerate with the calculated values. If the new acceleration for a direction is smaller than an earlier, the friction will reduce the speed in that direction to the new value in a few steps, so if youre flying curves or around corners youre floating a little bit in the old direction*/ VectorAdd( ent->velocity, acc, ent->velocity ); /*round velocitys (is this necessary?)*/ ent->velocity[0] = (float)((int)(ent->velocity[0]*8))/8; ent->velocity[1] = (float)((int)(ent->velocity[1]*8))/8; ent->velocity[2] = (float)((int)(ent->velocity[2]*8))/8; /*Bound velocitys so that friction and acceleration dont need to be synced on maxvelocitys*/ for ( i=0 ; i<2 ; i++) /*allow z-velocity to be greater*/ { if(!(ent->client->pers.inventory[ITEM_INDEX(vehicle)])) { if (ent->velocity[i] > 300) ent->velocity[i] = 300; else if (ent->velocity[i] < -300) ent->velocity[i] = -300; } else { if (ent->velocity[i] > 600) ent->velocity[i] = 600; else if (ent->velocity[i] < -600) ent->velocity[i] = -600; } } /*add some gentle up and down when idle (not accelerating)*/ if( VectorLength(acc) == 0 ) Jet_ApplyLifting( ent ); }//if ( ent->client->Jet_next_think... /*add rolling when we fly curves or boost left/right*/ Jet_ApplyRolling( ent, right ); } void Use_Jet ( edict_t *ent) { /*jetpack in inventory but no fuel time? must be one of the give all/give jetpack cheats, so put fuel in*/ if ( ent->client->Jet_remaining == 0 ) ent->client->Jet_remaining = 700; if ( Jet_Active(ent) ) ent->client->Jet_framenum = 0; else ent->client->Jet_framenum = level.framenum + ent->client->Jet_remaining; gi.sound( ent, CHAN_ITEM, gi.soundindex("vehicles/got_in.wav"), 0.8, ATTN_NORM, 0 ); } static void VehicleThink(edict_t *ent) { ent->nextthink = level.time + FRAMETIME; } void VehicleSetup (edict_t *ent) { trace_t tr; vec3_t dest; float *v; v = tv(-64,-64,-24); VectorCopy (v, ent->mins); v = tv(64,64,64); VectorCopy (v, ent->maxs); if (ent->model) gi.setmodel (ent, ent->model); else gi.setmodel (ent, ent->item->world_model); if(!strcmp(ent->classname, "item_bomber")) ent->s.modelindex3 = gi.modelindex("vehicles/bomber/helmet.md2"); ent->solid = SOLID_TRIGGER; ent->movetype = MOVETYPE_TOSS; ent->touch = Touch_Item; v = tv(0,0,-128); VectorAdd (ent->s.origin, v, dest); tr = gi.trace (ent->s.origin, ent->mins, ent->maxs, dest, ent, MASK_SOLID); if (tr.startsolid) { gi.dprintf ("VehicleSetup: %s startsolid at %s\n", ent->classname, vtos(ent->s.origin)); G_FreeEdict (ent); return; } VectorCopy (tr.endpos, ent->s.origin); gi.linkentity (ent); ent->nextthink = level.time + FRAMETIME; ent->think = VehicleThink; } static void VehicleDropTouch(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { //owner (who dropped us) can't touch for two secs if (other == ent->owner && ent->nextthink - level.time > 2) return; Touch_Item (ent, other, plane, surf); } static void VehicleDropThink(edict_t *ent) { //let it hang around for awhile ent->nextthink = level.time + 20; ent->think = G_FreeEdict; } void VehicleDeadDrop(edict_t *self) { edict_t *dropped; gitem_t *vehicle; dropped = NULL; vehicle = FindItemByClassname("item_bomber"); if (self->client->pers.inventory[ITEM_INDEX(vehicle)]) { dropped = Drop_Item(self, vehicle); self->client->pers.inventory[ITEM_INDEX(vehicle)] = 0; safe_bprintf(PRINT_HIGH, "Bomber is abandoned!\n"); } if (dropped) { dropped->think = VehicleDropThink; dropped->nextthink = level.time + 5; dropped->touch = VehicleDropTouch; dropped->s.frame = 0; return; } //didn't find a bomber, try a strafer vehicle = FindItemByClassname("item_strafer"); if (self->client->pers.inventory[ITEM_INDEX(vehicle)]) { dropped = Drop_Item(self, vehicle); self->client->pers.inventory[ITEM_INDEX(vehicle)] = 0; safe_bprintf(PRINT_HIGH, "Strafer is abandoned!\n"); } if (dropped) { dropped->think = VehicleDropThink; dropped->nextthink = level.time + 5; dropped->touch = VehicleDropTouch; dropped->s.frame = 0; return; } //didn't find a strafer, try a hovercraft vehicle = FindItemByClassname("item_hover"); if (self->client->pers.inventory[ITEM_INDEX(vehicle)]) { dropped = Drop_Item(self, vehicle); self->client->pers.inventory[ITEM_INDEX(vehicle)] = 0; safe_bprintf(PRINT_HIGH, "Hovercraft is abandoned!\n"); } if (dropped) { dropped->think = VehicleDropThink; dropped->nextthink = level.time + 5; dropped->touch = VehicleDropTouch; dropped->s.frame = 0; return; } } void Reset_player(edict_t *ent) { char userinfo[MAX_INFO_STRING]; int i, done; char playermodel[MAX_OSPATH] = " "; char modelpath[MAX_OSPATH] = " "; FILE *file; char *s; //set everything back if ( instagib->integer || insta_rockets->integer ) { ent->client->newweapon = FindItem("Alien Disruptor"); } else if( rocket_arena->integer ) { ent->client->newweapon = FindItem("Rocket Launcher"); } else { ent->client->newweapon = FindItem("blaster"); } assert( ent->client->newweapon != NULL ); memcpy (userinfo, ent->client->pers.userinfo, sizeof(userinfo)); s = Info_ValueForKey (userinfo, "skin"); ent->client->Jet_framenum = 0; i = 0; done = false; strcpy(playermodel, " "); while(!done) { if((s[i] == '/') || (s[i] == '\\')) done = true; playermodel[i] = s[i]; if(i > 62) done = true; i++; } playermodel[i-1] = 0; ent->s.modelindex = 255; sprintf(modelpath, "players/%s/helmet.md2", playermodel); Q2_FindFile (modelpath, &file); //does a helmet exist? if(file) { sprintf(modelpath, "players/%s/helmet.md2", playermodel); ent->s.modelindex3 = gi.modelindex(modelpath); fclose(file); } else ent->s.modelindex3 = 0; ent->s.modelindex4 = 0; ent->in_vehicle = false; } void Leave_vehicle(edict_t *ent, gitem_t *item) { Reset_player(ent); ent->client->pers.inventory[ITEM_INDEX(item)] = 0; gi.sound( ent, CHAN_ITEM, gi.soundindex("vehicles/got_in.wav"), 0.8, ATTN_NORM, 0 ); Drop_Item (ent, item); safe_bprintf(PRINT_HIGH, "Vehicle has been dropped!\n"); } qboolean Get_in_vehicle (edict_t *ent, edict_t *other) { gitem_t *vehicle; float *v; vehicle = NULL; if(other->in_vehicle) //already in a vehicle return false; vehicle = FindItemByClassname(ent->classname); //put him in the vehicle if(!strcmp(ent->classname, "item_bomber")) { other->s.modelindex = gi.modelindex("vehicles/bomber/tris.md2"); other->s.modelindex2 = 0; other->s.modelindex3 = gi.modelindex("vehicles/bomber/helmet.md2"); other->s.modelindex4 = 0; } else if(!strcmp(ent->classname, "item_hover")) { other->s.modelindex = gi.modelindex("vehicles/hover/tris.md2"); other->s.modelindex2 = 0; other->s.modelindex3 = 0; other->s.modelindex4 = 0; } else { other->s.modelindex = gi.modelindex("vehicles/strafer/tris.md2"); other->s.modelindex2 = 0; other->s.modelindex3 = 0; other->s.modelindex4 = 0; } other->in_vehicle = true; other->client->Jet_remaining = 500; v = tv(-64,-64,-24); VectorCopy (v,other->mins); v = tv(64,64,64); VectorCopy (v, other->maxs); other->s.origin[2] +=24; other->client->pers.inventory[ITEM_INDEX(vehicle)] = 1; other->client->newweapon = ent->item; if (!(ent->spawnflags & DROPPED_ITEM)) { SetRespawn (ent, 60); } Use_Jet(other); ent->owner = other; return true; } alien-arena-7.66+dfsg/source/game/g_combat.c0000600000175000017500000003446012161402010017741 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // g_combat.c #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" /* ============ CanDamage Returns true if the inflictor can directly damage the target. Used for explosions and melee attacks. ============ */ qboolean CanDamage (edict_t *targ, edict_t *inflictor) { vec3_t dest; trace_t trace; // bmodels need special checking because their origin is 0,0,0 if (targ->movetype == MOVETYPE_PUSH) { VectorAdd (targ->absmin, targ->absmax, dest); VectorScale (dest, 0.5, dest); trace = gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID); if (trace.fraction == 1.0) return true; if (trace.ent == targ) return true; return false; } trace = gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, targ->s.origin, inflictor, MASK_SOLID); if (trace.fraction == 1.0) return true; VectorCopy (targ->s.origin, dest); dest[0] += 15.0; dest[1] += 15.0; trace = gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID); if (trace.fraction == 1.0) return true; VectorCopy (targ->s.origin, dest); dest[0] += 15.0; dest[1] -= 15.0; trace = gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID); if (trace.fraction == 1.0) return true; VectorCopy (targ->s.origin, dest); dest[0] -= 15.0; dest[1] += 15.0; trace = gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID); if (trace.fraction == 1.0) return true; VectorCopy (targ->s.origin, dest); dest[0] -= 15.0; dest[1] -= 15.0; trace = gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID); if (trace.fraction == 1.0) return true; return false; } /* ============ Killed ============ */ void Killed (edict_t *targ, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { if (targ->health < -999) targ->health = -999; if (targ->monsterinfo.aiflags & AI_NPC) { //cows never really die, they just return to their //original spawn points //send an effect gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BFG_BIGEXPLOSION); gi.WritePosition (targ->s.origin); gi.multicast (targ->s.origin, MULTICAST_PHS); targ->health = targ->max_health; targ->s.event = EV_PLAYER_TELEPORT; targ->enemy = NULL; VectorCopy(targ->s.spawn_pos, targ->s.origin); return; } targ->enemy = attacker; if ((targ->svflags & SVF_MONSTER) && (targ->deadflag != DEAD_DEAD)) { // targ->svflags |= SVF_DEADMONSTER; // now treat as a different content type if (!(targ->monsterinfo.aiflags & AI_GOOD_GUY)) { level.killed_monsters++; // medics won't heal monsters that they kill themselves if (strcmp(attacker->classname, "monster_medic") == 0) targ->owner = attacker; } } if (targ->movetype == MOVETYPE_PUSH || targ->movetype == MOVETYPE_STOP || targ->movetype == MOVETYPE_NONE) { // doors, triggers, etc targ->die (targ, inflictor, attacker, damage, point); return; } if ((targ->svflags & SVF_MONSTER) && (targ->deadflag != DEAD_DEAD)) { targ->touch = NULL; monster_death_use (targ); } targ->die (targ, inflictor, attacker, damage, point); } /* ================ SpawnDamage ================ */ void SpawnDamage (int type, vec3_t origin, vec3_t normal, int damage) { if (damage > 255) damage = 255; gi.WriteByte (svc_temp_entity); gi.WriteByte (type); // gi.WriteByte (damage); gi.WritePosition (origin); gi.WriteDir (normal); gi.multicast (origin, MULTICAST_PVS); } /* ============ T_Damage targ entity that is being damaged inflictor entity that is causing the damage attacker entity that caused the inflictor to damage targ example: targ=monster, inflictor=rocket, attacker=player dir direction of the attack point point at which the damage is being inflicted normal normal vector from that point damage amount of damage being inflicted knockback force to be applied against targ as a result of the damage dflags these flags are used to control how T_Damage works DAMAGE_RADIUS damage was indirect (from a nearby explosion) DAMAGE_NO_ARMOR armor does not protect from this damage DAMAGE_ENERGY damage is from an energy based weapon DAMAGE_NO_KNOCKBACK do not affect velocity, just view angles DAMAGE_BULLET damage is from a bullet (used for ricochets) DAMAGE_NO_PROTECTION kills godmode, armor, everything ============ */ static int CheckArmor (edict_t *ent, vec3_t point, vec3_t normal, int damage, int te_sparks, int dflags) { gclient_t *client; int save; int index; gitem_t *armor; if (!damage) return 0; client = ent->client; if (!client) return 0; if (dflags & DAMAGE_NO_ARMOR) return 0; index = ArmorIndex (ent); if (!index) return 0; armor = GetItemByIndex (index); if (dflags & DAMAGE_ENERGY) save = ceil(((gitem_armor_t *)armor->info)->energy_protection*damage); else save = ceil(((gitem_armor_t *)armor->info)->normal_protection*damage); if (save >= client->pers.inventory[index]) save = client->pers.inventory[index]; if (!save) return 0; client->pers.inventory[index] -= save; SpawnDamage (te_sparks, point, normal, save); return save; } qboolean CheckTeamDamage (edict_t *targ, edict_t *attacker) { //FIXME make the next line real and uncomment this block // if ((ability to damage a teammate == OFF) && (targ's team == attacker's team)) return false; } void VerifyHeadShot( vec3_t point, vec3_t dir, float height, vec3_t newpoint) { vec3_t normdir; vec3_t normdir2; VectorNormalize2(dir, normdir); VectorScale( normdir, height, normdir2 ); VectorAdd( point, normdir2, newpoint ); } #define HEAD_HEIGHT 12.0 #define CROUCHING_MAXS2 16 void T_Damage (edict_t *targ, edict_t *inflictor, edict_t *attacker, vec3_t dir, vec3_t point, vec3_t normal, int damage, int knockback, int dflags, int mod) { gclient_t *client; int take; int save; int asave; int te_sparks; int head_success = 0; float z_rel; int height; float from_top; float targ_maxs2; if (!targ->takedamage) return; if(mod != MOD_TELEFRAG) if(targ->inuse && targ->client) if(targ->client->spawnprotected) return; //headshots for disruptors targ_maxs2 = targ->maxs[2]; if (targ_maxs2 == 4) targ_maxs2 = CROUCHING_MAXS2; height = abs(targ->mins[2]) + targ_maxs2; if (targ->client && mod == MOD_DISRUPTOR) { z_rel = point[2] - targ->s.origin[2]; from_top = targ_maxs2 - z_rel; if (from_top < 0.0) from_top = 0.0; if ( from_top < 2*HEAD_HEIGHT ) { vec3_t new_point; VerifyHeadShot( point, dir, HEAD_HEIGHT, new_point ); VectorSubtract( new_point, targ->s.origin, new_point ); if ( (targ_maxs2 - new_point[2]) < HEAD_HEIGHT && (abs(new_point[1])) < HEAD_HEIGHT*.8 && (abs(new_point[0])) < HEAD_HEIGHT*.8 ) { head_success = 1; } } if ( head_success ) { damage = damage*1.8 + 1; if (attacker->client) mod = MOD_HEADSHOT; } } // friendly fire avoidance // if enabled you can't hurt teammates (but you can hurt yourself) // knockback still occurs if ((targ != attacker) && ((deathmatch->value && (dmflags->integer & (DF_SKINTEAMS))) || ctf->value || tca->value || cp->value)) { if (OnSameTeam (targ, attacker) && mod != MOD_TELEFRAG) //telefrag kills no matter what { if (dmflags->integer & DF_NO_FRIENDLY_FIRE) damage = 0; else mod |= MOD_FRIENDLY_FIRE; //educate the noobs.... safe_centerprintf(attacker, "Stop shooting your teammates!!!"); } } if (targ == attacker) { damage *= wep_selfdmgmulti->value; } meansOfDeath = mod; // easy mode takes half damage if (skill->value == 0 && deathmatch->value == 0 && targ->client) { damage *= 0.5; if (!damage) damage = 1; } client = targ->client; if (dflags & DAMAGE_BULLET) te_sparks = TE_BULLET_SPARKS; else te_sparks = TE_SPARKS; VectorNormalize(dir); if (targ->flags & FL_NO_KNOCKBACK) knockback = 0; // figure momentum add if (!(dflags & DAMAGE_NO_KNOCKBACK)) { if ((knockback) && (targ->movetype != MOVETYPE_NONE) && (targ->movetype != MOVETYPE_BOUNCE) && (targ->movetype != MOVETYPE_PUSH) && (targ->movetype != MOVETYPE_STOP)) { vec3_t kvel; float mass; if (targ->mass < 50) mass = 50; else mass = targ->mass; if (targ->client && attacker == targ) VectorScale (dir, 1600.0 * (float)knockback / mass, kvel); // the rocket jump hack... else VectorScale (dir, 500.0 * (float)knockback / mass, kvel); VectorAdd (targ->velocity, kvel, targ->velocity); } } //diminish plasma splash, as we want this to be minimal, as it's more used for tricks if(mod == MOD_PLASMA_SPLASH) { // damage /= (1+ (int)(random() * 10.0)); damage /= 6; // median of formerly random 1..11 } take = damage; save = 0; // check for godmode if ( (targ->flags & FL_GODMODE) && !(dflags & DAMAGE_NO_PROTECTION) ) { take = 0; save = damage; SpawnDamage (te_sparks, point, normal, save); } // check for invincibility if ((client && client->invincible_framenum > level.framenum ) && !(dflags & DAMAGE_NO_PROTECTION)) { if (targ->pain_debounce_time < level.time) { gi.sound(targ, CHAN_ITEM, gi.soundindex("items/protect4.wav"), 1, ATTN_NORM, 0); targ->pain_debounce_time = level.time + 2; } if(mod == MOD_TRIGGER_HURT) { take = 0; save = damage; } else { take = damage/3; save = 0; } } asave = CheckArmor (targ, point, normal, take, te_sparks, dflags); take -= asave; //treat cheat/powerup savings the same as armor asave += save; // team damage avoidance if (!(dflags & DAMAGE_NO_PROTECTION) && CheckTeamDamage (targ, attacker)) return; // do the damage if (take) { if (client) { if (targ->ctype == 0) //alien, robot, human SpawnDamage (TE_GREENBLOOD, point, normal, take); else if (targ->ctype == 2) SpawnDamage (TE_GUNSHOT, point, normal, take); else SpawnDamage (TE_BLOOD, point, normal, take); } else { if (targ->ctype == 0) //alien, robot, human SpawnDamage (TE_GREENBLOOD, point, normal, take); else if (targ->ctype == 2) SpawnDamage (TE_GUNSHOT, point, normal, take); else SpawnDamage (TE_BLOOD, point, normal, take); if(tca->value) { if(!(strcmp(targ->classname, "misc_redspidernode")) || !(strcmp(targ->classname, "misc_bluespidernode"))) safe_centerprintf(attacker, "Spider health at %i percent", 100*(targ->health-take)/600); } if(g_tactical->value) { if(!strcmp(targ->classname, "alien computer")) safe_centerprintf(attacker, "Alien Computer health at %i percent", 100*(targ->health-take)/1500); else if(!strcmp(targ->classname, "human computer")) safe_centerprintf(attacker, "Human Computer health at %i percent", 100*(targ->health-take)/1500); else if(!strcmp(targ->classname, "alien powersrc")) safe_centerprintf(attacker, "Alien Power Source health at %i percent", 100*(targ->health-take)/1500); else if(!strcmp(targ->classname, "human powersrc")) safe_centerprintf(attacker, "Human Power Source health at %i percent", 100*(targ->health-take)/1500); else if(!strcmp(targ->classname, "alien ammodepot")) safe_centerprintf(attacker, "Alien Ammo Depot health at %i percent", 100*(targ->health-take)/1500); else if(!strcmp(targ->classname, "human ammodepot")) safe_centerprintf(attacker, "Human Ammo Depot health at %i percent", 100*(targ->health-take)/1500); } } targ->health = targ->health - take; if (targ->health <= 0) { if (client) targ->flags |= FL_NO_KNOCKBACK; Killed (targ, inflictor, attacker, take, point); return; } } if (client) { if (!(targ->flags & FL_GODMODE) && (take) && (targ->pain)) targ->pain (targ, attacker, knockback, take); } else if (take) { if (targ->pain) targ->pain (targ, attacker, knockback, take); } // add to the damage inflicted on a player this frame // the total will be turned into screen blends and view angle kicks // at the end of the frame if (client) { client->damage_armor += asave; client->damage_blood += take; client->damage_knockback += knockback; VectorCopy (point, client->damage_from); } } /* ============ T_RadiusDamage ============ */ void T_RadiusDamage (edict_t *inflictor, edict_t *attacker, float damage, edict_t *ignore, float radius, int mod, int weapon) { float points; edict_t *ent = NULL; vec3_t v; vec3_t dir; while ((ent = findradius(ent, inflictor->s.origin, radius)) != NULL) { if (ent == ignore) continue; if (!ent->takedamage) continue; VectorAdd (ent->mins, ent->maxs, v); VectorMA (ent->s.origin, 0.5, v, v); VectorSubtract (inflictor->s.origin, v, v); points = damage - 0.5 * VectorLength (v); if (ent == attacker) points = points * 0.5; if (points > 0) { if (CanDamage (ent, inflictor)) { VectorSubtract (ent->s.origin, inflictor->s.origin, dir); T_Damage (ent, inflictor, attacker, dir, inflictor->s.origin, vec3_origin, (int)points, (int)points, DAMAGE_RADIUS, mod); if (ent != attacker) gi.sound (attacker, CHAN_VOICE, gi.soundindex("misc/hit.wav"), 1, ATTN_STATIC, 0); if(weapon >=0) attacker->client->resp.weapon_hits[weapon]++; } } } } alien-arena-7.66+dfsg/source/game/g_deathray.c0000600000175000017500000002370712161402010020277 0ustar zero79zero79/* Copyright (C) 2009 COR Entertainment, LLC. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* ============================================================================== Death Ray Gun ============================================================================== */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" #include "g_deathray.h" static int sound_pain; static int sound_die; static int sound_idle; static int sound_punch; static int sound_sight; static int sound_search; void deathray_search (edict_t *self) { gi.sound (self, CHAN_VOICE, sound_search, 1, ATTN_NORM, 0); } mframe_t deathray_frames_stand [] = { {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL} }; mmove_t deathray_move_stand = {FRAME_stand01, FRAME_stand06, deathray_frames_stand, NULL}; void deathray_stand (edict_t *self) { self->monsterinfo.currentmove = &deathray_move_stand; } mframe_t deathray_frames_run1 [] = { {ai_run, 0, NULL}, {ai_run, 0, NULL}, {ai_run, 0, NULL}, {ai_run, 0, NULL}, {ai_run, 0, NULL}, {ai_run, 0, NULL} }; mmove_t deathray_move_run1 = {FRAME_stand01, FRAME_stand06, deathray_frames_run1, NULL}; void deathray_run (edict_t *self) { self->monsterinfo.currentmove = &deathray_move_run1; } void deathrayShot (edict_t *self) { vec3_t forward, right; vec3_t start; vec3_t end; vec3_t dir; vec3_t from; vec3_t offset; int damage = 50; trace_t tr; //tactical if(g_tactical->value) { if(self->spawnflags & 1) { //if power source is down, and backup gen is on, get erratic if(!tacticalScore.humanPowerSource) { if(!tacticalScore.humanBackupGen) return; if(random() < 0.5) { if(self->enemy->ctype == 1) { if(random() < 0.5) return; } else return; } } else if(!tacticalScore.humanComputer) //we have power, but no computer, so behave erratically { if(random() < 0.5) { if(self->enemy->ctype == 1) { if(random() < 0.5) return; } else return; } } //do not fire on humans if(self->enemy->ctype == 1) return; } else { if(!tacticalScore.alienPowerSource) { if(!tacticalScore.alienBackupGen) return; if(random() < 0.5) { if(self->enemy->ctype == 0) { if(random() < 0.5) return; } else return; } } else if(!tacticalScore.alienComputer) { if(random() < 0.5) { if(self->enemy->ctype == 0) { if(random() < 0.5) return; } else return; } } //do not fire on aliens if(self->enemy->ctype == 0) return; } } AngleVectors (self->s.angles, forward, right, NULL); VectorSet(offset, 32, 0, 48); G_ProjectSource (self->s.origin, offset, forward, right, start); VectorCopy (self->s.origin, start); VectorCopy (self->enemy->s.origin, end); end[2] += self->enemy->viewheight; VectorSubtract (end, start, dir); right[0] = forward[0] * 64; right[1] = forward[1] * 64; VectorAdd(start, right, start); end[2] -= 32; start[2] += 64; VectorCopy (start, from); tr = gi.trace (from, NULL, NULL, end, self, MASK_SHOT); VectorCopy (tr.endpos, from); // send muzzle flash gi.WriteByte (svc_muzzleflash); gi.WriteShort (self-g_edicts); gi.WriteByte (MZ_RAILGUN); gi.multicast (self->s.origin, MULTICAST_PVS); gi.WriteByte (svc_temp_entity); //tactical if(self->spawnflags & 1) gi.WriteByte (TE_REDLASER); else gi.WriteByte (TE_VAPORBEAM); gi.WritePosition (start); gi.WritePosition (end); gi.multicast (self->s.origin, MULTICAST_PHS); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BFG_BIGEXPLOSION); gi.WritePosition (end); gi.multicast (end, MULTICAST_PVS); gi.sound (self, CHAN_VOICE, sound_punch, 1, ATTN_NORM, 0); if ((tr.ent != self) && (tr.ent->takedamage)) T_Damage (tr.ent, self, self, dir, tr.endpos, tr.plane.normal, damage, 0, 0, MOD_DEATHRAY); else if (!((tr.surface) && (tr.surface->flags & SURF_SKY))) { gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_SCREEN_SPARKS); gi.WritePosition (tr.endpos); gi.WriteDir (tr.plane.normal); gi.multicast (self->s.origin, MULTICAST_PVS); } } mframe_t deathray_frames_attack_shoot [] = { {ai_charge, 0, NULL}, {ai_charge, 0, deathrayShot}, {ai_charge, 0, NULL}, {ai_charge, 0, NULL}, {ai_charge, 0, deathrayShot}, {ai_charge, 0, NULL}, {ai_charge, 0, deathrayShot} }; mmove_t deathray_move_attack_shoot = {FRAME_stand01, FRAME_stand06, deathray_frames_attack_shoot, deathray_run}; void deathray_sight (edict_t *self, edict_t *other) { gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); self->monsterinfo.currentmove = &deathray_move_run1; } void deathray_attack (edict_t *self) { self->monsterinfo.currentmove = &deathray_move_attack_shoot; } mframe_t deathray_frames_pain1 [] = { {ai_move, 0, NULL}, {ai_move, 0, NULL}, {ai_move, 0, NULL}, {ai_move, 0, NULL}, {ai_move, 0, NULL}, {ai_move, 0, NULL} }; mmove_t deathray_move_pain1 = {FRAME_stand01, FRAME_stand06, deathray_frames_pain1, deathray_run}; void deathray_pain (edict_t *self, edict_t *other, float kick, int damage) { if (self->health < (self->max_health / 2)) self->s.skinnum = 1; if (level.time < self->pain_debounce_time) return; self->pain_debounce_time = level.time + 3; gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0); self->monsterinfo.currentmove = &deathray_move_pain1; } void deathray_dead (edict_t *self) { VectorSet (self->mins, -16, -16, -42); VectorSet (self->maxs, 16, 16, -8); self->movetype = MOVETYPE_TOSS; self->svflags |= SVF_DEADMONSTER; self->nextthink = 0; gi.linkentity (self); } mframe_t deathray_frames_death1 [] = { {ai_move, 0, NULL}, {ai_move, 0, NULL}, {ai_move, 0, NULL}, {ai_move, 0, NULL}, {ai_move, 0, NULL} }; mmove_t deathray_move_death1 = {FRAME_stand01, FRAME_stand05, deathray_frames_death1, deathray_dead}; void deathray_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_EXPLOSION1); gi.WritePosition (self->s.origin); gi.multicast (self->s.origin, MULTICAST_PVS); self->deadflag = DEAD_DEAD; gi.sound( &g_edicts[1], CHAN_AUTO, gi.soundindex( "world/explosion1.wav" ), 1, ATTN_NONE, 0 ); G_FreeEdict (self); } void SP_npc_deathray (edict_t *self) { // pre-caches sound_pain = gi.soundindex ("misc/deathray/fizz.wav"); sound_die = gi.soundindex ("misc/deathray/fizz.wav"); sound_idle = gi.soundindex ("misc/deathray/weird2.wav"); sound_punch = gi.soundindex ("misc/deathray/shoot.wav"); sound_search = gi.soundindex ("misc/deathray/weird2.wav"); sound_sight = gi.soundindex ("misc/deathray/weird2.wav"); self->s.modelindex = gi.modelindex("models/misc/deathray/deathray.md2"); VectorSet (self->mins, -16, -16, 0); VectorSet (self->maxs, 16, 16, 48); self->movetype = MOVETYPE_STEP; self->solid = SOLID_BBOX; self->takedamage = DAMAGE_NO; //invincible self->max_health = 5000; self->health = self->max_health; self->gib_health = 0; self->mass = 5000; self->pain = deathray_pain; self->die = deathray_die; self->monsterinfo.stand = deathray_stand; self->monsterinfo.walk = deathray_run; self->monsterinfo.run = deathray_run; self->monsterinfo.dodge = NULL; self->monsterinfo.attack = deathray_attack; self->monsterinfo.melee = deathray_attack; self->monsterinfo.sight = deathray_sight; self->monsterinfo.search = deathray_search; self->s.renderfx |= RF_MONSTER; self->monsterinfo.currentmove = &deathray_move_stand; self->monsterinfo.scale = MODEL_SCALE; gi.linkentity (self); walkmonster_start (self); } void SP_misc_deathray (edict_t *self) { // pre-caches sound_pain = gi.soundindex ("misc/deathray/fizz.wav"); sound_die = gi.soundindex ("misc/deathray/fizz.wav"); sound_idle = gi.soundindex ("misc/deathray/weird2.wav"); sound_punch = gi.soundindex ("misc/deathray/shoot.wav"); sound_search = gi.soundindex ("misc/deathray/weird2.wav"); sound_sight = gi.soundindex ("misc/deathray/weird2.wav"); //to do - make different mesh for human weapon self->s.modelindex = gi.modelindex("models/misc/deathray/deathray.md2"); VectorSet (self->mins, -16, -16, 0); VectorSet (self->maxs, 16, 16, 48); self->movetype = MOVETYPE_STEP; self->solid = SOLID_BBOX; self->takedamage = DAMAGE_YES; self->max_health = 300; self->health = self->max_health; self->gib_health = 0; self->mass = 5000; self->pain = deathray_pain; self->die = deathray_die; self->monsterinfo.stand = deathray_stand; self->monsterinfo.walk = deathray_run; self->monsterinfo.run = deathray_run; self->monsterinfo.dodge = NULL; self->monsterinfo.attack = deathray_attack; self->monsterinfo.melee = deathray_attack; self->monsterinfo.sight = deathray_sight; self->monsterinfo.search = deathray_search; self->s.renderfx |= RF_MONSTER; self->monsterinfo.currentmove = &deathray_move_stand; self->monsterinfo.scale = MODEL_SCALE; gi.linkentity (self); walkmonster_start (self); } alien-arena-7.66+dfsg/source/game/g_save.c0000600000175000017500000003443312161402010017432 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" #define Function(f) {#f, f} int red_team_score; int blue_team_score; int red_team_matches; //for tca int blue_team_matches; //for tca int reddiff; int bluediff; int redwinning; int print1, print2, print3; mmove_t mmove_reloc; field_t fields[] = { {"classname", FOFS(classname), F_LSTRING}, {"model", FOFS(model), F_LSTRING}, {"spawnflags", FOFS(spawnflags), F_INT}, {"speed", FOFS(speed), F_FLOAT}, {"accel", FOFS(accel), F_FLOAT}, {"decel", FOFS(decel), F_FLOAT}, {"target", FOFS(target), F_LSTRING}, {"targetname", FOFS(targetname), F_LSTRING}, {"pathtarget", FOFS(pathtarget), F_LSTRING}, {"deathtarget", FOFS(deathtarget), F_LSTRING}, {"killtarget", FOFS(killtarget), F_LSTRING}, {"combattarget", FOFS(combattarget), F_LSTRING}, {"message", FOFS(message), F_LSTRING}, {"team", FOFS(team), F_LSTRING}, {"wait", FOFS(wait), F_FLOAT}, {"delay", FOFS(delay), F_FLOAT}, {"random", FOFS(random), F_FLOAT}, {"move_origin", FOFS(move_origin), F_VECTOR}, {"move_angles", FOFS(move_angles), F_VECTOR}, {"style", FOFS(style), F_INT}, {"count", FOFS(count), F_INT}, {"health", FOFS(health), F_INT}, {"sounds", FOFS(sounds), F_INT}, {"light", 0, F_IGNORE}, {"dmg", FOFS(dmg), F_INT}, {"mass", FOFS(mass), F_INT}, {"volume", FOFS(volume), F_FLOAT}, {"attenuation", FOFS(attenuation), F_FLOAT}, {"map", FOFS(map), F_LSTRING}, {"origin", FOFS(s.origin), F_VECTOR}, {"angles", FOFS(s.angles), F_VECTOR}, {"angle", FOFS(s.angles), F_ANGLEHACK}, {"goalentity", FOFS(goalentity), F_EDICT, FFL_NOSPAWN}, {"movetarget", FOFS(movetarget), F_EDICT, FFL_NOSPAWN}, {"enemy", FOFS(enemy), F_EDICT, FFL_NOSPAWN}, {"oldenemy", FOFS(oldenemy), F_EDICT, FFL_NOSPAWN}, {"activator", FOFS(activator), F_EDICT, FFL_NOSPAWN}, {"groundentity", FOFS(groundentity), F_EDICT, FFL_NOSPAWN}, {"teamchain", FOFS(teamchain), F_EDICT, FFL_NOSPAWN}, {"teammaster", FOFS(teammaster), F_EDICT, FFL_NOSPAWN}, {"owner", FOFS(owner), F_EDICT, FFL_NOSPAWN}, {"mynoise", FOFS(mynoise), F_EDICT, FFL_NOSPAWN}, {"mynoise2", FOFS(mynoise2), F_EDICT, FFL_NOSPAWN}, {"target_ent", FOFS(target_ent), F_EDICT, FFL_NOSPAWN}, {"chain", FOFS(chain), F_EDICT, FFL_NOSPAWN}, {"flashlight", FOFS(flashlight), F_EDICT, FFL_NOSPAWN}, // Knightmare- fixed save pointer! {"prethink", FOFS(prethink), F_FUNCTION, FFL_NOSPAWN}, {"think", FOFS(think), F_FUNCTION, FFL_NOSPAWN}, {"blocked", FOFS(blocked), F_FUNCTION, FFL_NOSPAWN}, {"touch", FOFS(touch), F_FUNCTION, FFL_NOSPAWN}, {"use", FOFS(use), F_FUNCTION, FFL_NOSPAWN}, {"pain", FOFS(pain), F_FUNCTION, FFL_NOSPAWN}, {"die", FOFS(die), F_FUNCTION, FFL_NOSPAWN}, {"stand", FOFS(monsterinfo.stand), F_FUNCTION, FFL_NOSPAWN}, {"idle", FOFS(monsterinfo.idle), F_FUNCTION, FFL_NOSPAWN}, {"search", FOFS(monsterinfo.search), F_FUNCTION, FFL_NOSPAWN}, {"walk", FOFS(monsterinfo.walk), F_FUNCTION, FFL_NOSPAWN}, {"run", FOFS(monsterinfo.run), F_FUNCTION, FFL_NOSPAWN}, {"dodge", FOFS(monsterinfo.dodge), F_FUNCTION, FFL_NOSPAWN}, {"attack", FOFS(monsterinfo.attack), F_FUNCTION, FFL_NOSPAWN}, {"melee", FOFS(monsterinfo.melee), F_FUNCTION, FFL_NOSPAWN}, {"sight", FOFS(monsterinfo.sight), F_FUNCTION, FFL_NOSPAWN}, {"checkattack", FOFS(monsterinfo.checkattack), F_FUNCTION, FFL_NOSPAWN}, {"currentmove", FOFS(monsterinfo.currentmove), F_MMOVE, FFL_NOSPAWN}, {"endfunc", FOFS(moveinfo.endfunc), F_FUNCTION, FFL_NOSPAWN}, // temp spawn vars -- only valid when the spawn function is called {"lip", STOFS(lip), F_INT, FFL_SPAWNTEMP}, {"distance", STOFS(distance), F_INT, FFL_SPAWNTEMP}, {"height", STOFS(height), F_INT, FFL_SPAWNTEMP}, {"noise", STOFS(noise), F_LSTRING, FFL_SPAWNTEMP}, {"pausetime", STOFS(pausetime), F_FLOAT, FFL_SPAWNTEMP}, {"item", STOFS(item), F_LSTRING, FFL_SPAWNTEMP}, //need for item field in edict struct, FFL_SPAWNTEMP item will be skipped on saves {"item", FOFS(item), F_ITEM}, {"gravity", STOFS(gravity), F_LSTRING, FFL_SPAWNTEMP}, {"sky", STOFS(sky), F_LSTRING, FFL_SPAWNTEMP}, {"skyrotate", STOFS(skyrotate), F_FLOAT, FFL_SPAWNTEMP}, {"skyaxis", STOFS(skyaxis), F_VECTOR, FFL_SPAWNTEMP}, {"minyaw", STOFS(minyaw), F_FLOAT, FFL_SPAWNTEMP}, {"maxyaw", STOFS(maxyaw), F_FLOAT, FFL_SPAWNTEMP}, {"minpitch", STOFS(minpitch), F_FLOAT, FFL_SPAWNTEMP}, {"maxpitch", STOFS(maxpitch), F_FLOAT, FFL_SPAWNTEMP}, {"nextmap", STOFS(nextmap), F_LSTRING, FFL_SPAWNTEMP}, {0, 0, 0, 0} }; field_t levelfields[] = { {"changemap", LLOFS(changemap), F_LSTRING}, {"sight_client", LLOFS(sight_client), F_EDICT}, {"sight_entity", LLOFS(sight_entity), F_EDICT}, {"sound_entity", LLOFS(sound_entity), F_EDICT}, {"sound2_entity", LLOFS(sound2_entity), F_EDICT}, {NULL, 0, F_INT} }; field_t clientfields[] = { {"pers.weapon", CLOFS(pers.weapon), F_ITEM}, {"pers.lastweapon", CLOFS(pers.lastweapon), F_ITEM}, {"newweapon", CLOFS(newweapon), F_ITEM}, {NULL, 0, F_INT} }; /* ============ InitGame This will be called when the dll is first loaded, which only happens when a new game is started or a save game is loaded. ============ */ void InitGame (void) { gi.dprintf ("==== InitGame ====\n"); gun_x = gi.cvar ("gun_x", "0", 0); gun_y = gi.cvar ("gun_y", "0", 0); gun_z = gi.cvar ("gun_z", "0", 0); //FIXME: sv_ prefix is wrong for these sv_rollspeed = gi.cvar ("sv_rollspeed", "200", 0); sv_rollangle = gi.cvar ("sv_rollangle", "2", 0); sv_maxvelocity = gi.cvar ("sv_maxvelocity", "2000", 0); sv_gravity = gi.cvar ("sv_gravity", "800", 0); // noset vars g_dedicated = gi.cvar ("dedicated", "0", CVAR_NOSET); // latched vars sv_cheats = gi.cvar ("cheats", "0", CVAR_SERVERINFO | CVAR_LATCH); gi.cvar ("gamename", GAMEVERSION , CVAR_SERVERINFO | CVAR_LATCH); gi.cvar ("gamedate", __DATE__ , CVAR_SERVERINFO | CVAR_LATCH); g_maxclients = gi.cvar ("maxclients", "1", CVAR_SERVERINFO | CVAR_LATCH | CVARDOC_INT); maxspectators = gi.cvar ("maxspectators", "4", CVAR_SERVERINFO | CVARDOC_INT); deathmatch = gi.cvar ("deathmatch", "0", CVAR_LATCH | CVARDOC_BOOL); ctf = gi.cvar ("ctf", "0", CVAR_LATCH | CVAR_GAMEINFO | CVARDOC_BOOL); tca = gi.cvar ("tca", "0", CVAR_LATCH | CVAR_GAMEINFO | CVARDOC_BOOL); cp = gi.cvar ("cp", "0", CVAR_LATCH | CVAR_GAMEINFO | CVARDOC_BOOL); skill = gi.cvar ("skill", "1", CVAR_LATCH | CVARDOC_INT); maxentities = gi.cvar ("maxentities", "1024", CVAR_LATCH | CVARDOC_INT); sv_botkickthreshold = gi.cvar("sv_botkickthreshold", "0", CVAR_LATCH | CVARDOC_INT); sv_custombots = gi.cvar("sv_custombots", "0", CVAR_LATCH | CVARDOC_INT); gi.cvar_describe (sv_custombots, "0 uses default botfile. Any other value selects a botfile of the form botinfo/custom.tmp."); //mutator instagib = gi.cvar ("instagib", "0", CVAR_LATCH | CVAR_GAMEINFO | CVARDOC_BOOL); rocket_arena = gi.cvar ("rocket_arena", "0", CVAR_LATCH | CVAR_GAMEINFO | CVARDOC_BOOL); insta_rockets = gi.cvar ("insta_rockets", "0", CVAR_LATCH | CVAR_GAMEINFO | CVARDOC_BOOL); low_grav = gi.cvar ("low_grav", "0", CVAR_LATCH | CVAR_GAMEINFO | CVARDOC_BOOL); regeneration = gi.cvar ("regeneration", "0", CVAR_LATCH | CVAR_GAMEINFO | CVARDOC_BOOL); vampire = gi.cvar ("vampire", "0", CVAR_LATCH | CVAR_GAMEINFO | CVARDOC_BOOL); excessive = gi.cvar ("excessive", "0", CVAR_LATCH | CVAR_GAMEINFO | CVARDOC_BOOL); grapple = gi.cvar ("grapple", "0", CVAR_LATCH | CVAR_GAMEINFO | CVARDOC_BOOL); classbased = gi.cvar ("classbased", "0", CVAR_LATCH | CVAR_GAMEINFO | CVARDOC_BOOL); //duel mode g_duel = gi.cvar ("g_duel", "0", CVAR_LATCH | CVAR_GAMEINFO | CVARDOC_BOOL); //tactical mode g_tactical = gi.cvar ("g_tactical", "0", CVAR_LATCH | CVAR_GAMEINFO | CVARDOC_BOOL); g_losehealth = gi.cvar ("g_losehealth", "1", CVAR_LATCH | CVARDOC_BOOL); g_losehealth_num = gi.cvar ("g_losehealth_num", "100", CVAR_LATCH | CVARDOC_INT); //weapons wep_selfdmgmulti = gi.cvar("wep_selfdmgmulti", "1.0", CVARDOC_FLOAT); //health/max health/max ammo g_spawnhealth = gi.cvar("g_spawnhealth", "125", CVARDOC_INT); g_maxhealth = gi.cvar("g_maxhealth", "100", CVARDOC_INT); g_maxbullets = gi.cvar("g_maxbullets", "200", CVARDOC_INT); g_maxshells = gi.cvar("g_maxshells", "100", CVARDOC_INT); g_maxrockets = gi.cvar("g_maxrockets", "50", CVARDOC_INT); g_maxgrenades = gi.cvar("g_maxgrenades", "50", CVARDOC_INT); g_maxcells = gi.cvar("g_maxcells", "200", CVARDOC_INT); g_maxslugs = gi.cvar("g_maxslugs", "50", CVARDOC_INT); g_maxseekers = gi.cvar("g_maxseekers", "1", CVARDOC_INT); g_maxbombs = gi.cvar("g_maxbombs", "1", CVARDOC_INT); //quick weapon change quickweap = gi.cvar ("quickweap", "0", CVAR_LATCH | CVAR_GAMEINFO | CVARDOC_INT); gi.cvar_describe (quickweap, "fast weapon switching."); //anti-camp anticamp = gi.cvar("anticamp", "0", CVAR_LATCH | CVAR_GAMEINFO | CVARDOC_BOOL); camptime = gi.cvar("camptime", "10", CVAR_LATCH | CVARDOC_INT); ac_frames = gi.cvar("ac_frames", "0", CVAR_LATCH | CVARDOC_INT); ac_threshold = gi.cvar("ac_threshold", "0", CVAR_LATCH | CVARDOC_INT); //random quad g_randomquad = gi.cvar("g_randomquad", "0", CVAR_LATCH | CVARDOC_BOOL); //warmup time if (g_maxclients->integer > 1) warmuptime = gi.cvar("warmuptime", "30", CVAR_LATCH | CVARDOC_INT); else // You can override this default if you want to, but a default of 0 is // nice if you're just loading a map to test code or to test the map // itself, over and over again. warmuptime = gi.cvar("warmuptime", "0", CVAR_LATCH | CVARDOC_INT); //spawn protection g_spawnprotect = gi.cvar("g_spawnprotect", "2", CVAR_SERVERINFO | CVARDOC_INT); gi.cvar_describe (g_spawnprotect, "number of seconds of spawn protection."); //joust mode joustmode = gi.cvar("sv_joustmode", "0", CVAR_SERVERINFO | CVAR_GAMEINFO | CVARDOC_BOOL); gi.cvar_describe (joustmode, "players can jump in midair."); //map voting g_mapvote = gi.cvar("g_mapvote", "0", CVAR_SERVERINFO); g_voterand = gi.cvar("g_voterand", "0", 0); g_votemode = gi.cvar("g_votemode", "0", 0); g_votesame = gi.cvar("g_votesame", "1", 0); //call voting g_callvote = gi.cvar("g_callvote", "1", CVAR_SERVERINFO | CVARDOC_BOOL); //change after testing //forced autobalanced teams g_autobalance = gi.cvar("g_autobalance", "0", 0); //reward points threshold g_reward = gi.cvar("g_reward", "20", CVAR_SERVERINFO); //antilag g_antilag = gi.cvar("g_antilag", "1", CVAR_SERVERINFO | CVARDOC_BOOL); g_antilagprojectiles = gi.cvar ("g_antilagprojectiles", "0", CVAR_GAMEINFO | CVARDOC_BOOL); g_antilagdebug = gi.cvar("g_antilagdebug", "0", 0 /*CVAR_SERVERINFO*/); // change anytime vars dmflags = gi.cvar ("dmflags", "0", CVAR_SERVERINFO); fraglimit = gi.cvar ("fraglimit", "0", CVAR_SERVERINFO); timelimit = gi.cvar ("timelimit", "0", CVAR_SERVERINFO); password = gi.cvar ("password", "", CVAR_USERINFO); spectator_password = gi.cvar ("spectator_password", "", CVAR_USERINFO); needpass = gi.cvar ("needpass", "0", CVAR_SERVERINFO); filterban = gi.cvar ("filterban", "1", 0); motdfile = gi.cvar ("motdfile", "motd.txt", 0); motdforce = gi.cvar ("motdforce", "0", 0); g_select_empty = gi.cvar ("g_select_empty", "0", CVAR_ARCHIVE); g_dmlights = gi.cvar ("g_dm_lights", "0", CVAR_ARCHIVE | CVAR_GAMEINFO); run_pitch = gi.cvar ("run_pitch", "0.002", 0); run_roll = gi.cvar ("run_roll", "0.005", 0); bob_up = gi.cvar ("bob_up", "0.005", 0); bob_pitch = gi.cvar ("bob_pitch", "0.002", 0); bob_roll = gi.cvar ("bob_roll", "0.002", 0); g_background_music = gi.cvar ("background_music", "1", CVAR_ARCHIVE); // flood control flood_msgs = gi.cvar ("flood_msgs", "4", 0); flood_persecond = gi.cvar ("flood_persecond", "4", 0); flood_waitdelay = gi.cvar ("flood_waitdelay", "10", 0); // dm map list sv_maplist = gi.cvar ("sv_maplist", "", 0); //throwaway cvars gi.cvar ("g_teamgame", va("%d", TEAM_GAME), CVAR_SERVERINFO); // items InitItems (); //set this if you're running experimental code on your server gi.cvar("testcode", "0", CVAR_GAMEINFO | CVAR_ROM); //set this in your config if you're testing an unfinished map gi.cvar("testmap", "0", CVAR_GAMEINFO); Com_sprintf (game.helpmessage1, sizeof(game.helpmessage1), ""); Com_sprintf (game.helpmessage2, sizeof(game.helpmessage2), ""); // initialize all entities for this game game.maxentities = maxentities->integer; g_edicts = gi.TagMalloc (game.maxentities * sizeof(g_edicts[0]), TAG_GAME); globals.edicts = g_edicts; globals.max_edicts = game.maxentities; // initialize all clients for this game game.maxclients = g_maxclients->integer; game.clients = gi.TagMalloc (game.maxclients * sizeof(game.clients[0]), TAG_GAME); globals.num_edicts = game.maxclients+1; //clear out team scores and player counts if(tca->integer) { blue_team_score = red_team_score = 4; blue_team_matches = red_team_matches = 0; } else { red_team_score = 0; blue_team_score = 0; } if(g_tactical->integer) { tacticalScore.alienAmmoDepot = tacticalScore.alienComputer = tacticalScore.alienPowerSource = tacticalScore.alienBackupGen = tacticalScore.humanAmmoDepot = tacticalScore.humanComputer = tacticalScore.humanPowerSource = tacticalScore.humanBackupGen = true; tacticalScore.alienAmmoDepotHealth = tacticalScore.alienComputerHealth = tacticalScore.alienPowerSourceHealth = tacticalScore.humanAmmoDepotHealth = tacticalScore.humanComputerHealth = tacticalScore.humanPowerSourceHealth = 100; } //reset minderaser mindEraserTime = level.time; print1 = print2 = print3 = false; } alien-arena-7.66+dfsg/source/game/g_ai.c0000600000175000017500000005730612161402010017071 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // g_ai.c #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" qboolean FindTarget (edict_t *self); extern cvar_t *g_maxclients; qboolean ai_checkattack (edict_t *self, float dist); qboolean enemy_vis; qboolean enemy_infront; int enemy_range; float enemy_yaw; //============================================================================ /* ================= AI_SetSightClient Called once each frame to set level.sight_client to the player to be checked for in findtarget. If all clients are either dead or in notarget, sight_client will be null. In coop games, sight_client will cycle between the clients. ================= */ void AI_SetSightClient (void) { edict_t *ent; int start, check; if (level.sight_client == NULL) start = 1; else start = level.sight_client - g_edicts; check = start; while (1) { check++; if (check > game.maxclients) check = 1; ent = &g_edicts[check]; if (ent->inuse && ent->health > 0 && !(ent->flags & FL_NOTARGET) ) { level.sight_client = ent; return; // got one } if (check == start) { level.sight_client = NULL; return; // nobody to see } } } //============================================================================ /* ============= ai_move Move the specified distance at current facing. This replaces the QC functions: ai_forward, ai_back, ai_pain, and ai_painforward ============== */ void ai_move (edict_t *self, float dist) { M_walkmove (self, self->s.angles[YAW], dist); } /* ============= ai_stand Used for standing around and looking for players Distance is for slight position adjustments needed by the animations ============== */ void ai_stand (edict_t *self, float dist) { vec3_t v; if (dist) M_walkmove (self, self->s.angles[YAW], dist); if (self->monsterinfo.aiflags & AI_STAND_GROUND) { if (self->enemy) { VectorSubtract (self->enemy->s.origin, self->s.origin, v); self->ideal_yaw = vectoyaw(v); if (self->s.angles[YAW] != self->ideal_yaw && self->monsterinfo.aiflags & AI_TEMP_STAND_GROUND) { self->monsterinfo.aiflags &= ~(AI_STAND_GROUND | AI_TEMP_STAND_GROUND); self->monsterinfo.run (self); } M_ChangeYaw (self); ai_checkattack (self, 0); } else FindTarget (self); return; } if (FindTarget (self)) return; if (level.time > self->monsterinfo.pausetime) { self->monsterinfo.walk (self); return; } if (!(self->spawnflags & 1) && (self->monsterinfo.idle) && (level.time > self->monsterinfo.idle_time)) { if (self->monsterinfo.idle_time) { self->monsterinfo.idle (self); self->monsterinfo.idle_time = level.time + 15 + random() * 15; } else { self->monsterinfo.idle_time = level.time + random() * 15; } } } /* ============= ai_walk The monster is walking it's beat ============= */ void ai_walk (edict_t *self, float dist) { M_MoveToGoal (self, dist); // check for noticing a player if (FindTarget (self)) return; if ((self->monsterinfo.search) && (level.time > self->monsterinfo.idle_time)) { if (self->monsterinfo.idle_time) { self->monsterinfo.search (self); self->monsterinfo.idle_time = level.time + 15 + random() * 15; } else { self->monsterinfo.idle_time = level.time + random() * 15; } } } /* ============= ai_charge Turns towards target and advances Use this call with a distnace of 0 to replace ai_face ============== */ void ai_charge (edict_t *self, float dist) { vec3_t v; VectorSubtract (self->enemy->s.origin, self->s.origin, v); self->ideal_yaw = vectoyaw(v); M_ChangeYaw (self); if (dist) M_walkmove (self, self->s.angles[YAW], dist); } /* ============= ai_turn don't move, but turn towards ideal_yaw Distance is for slight position adjustments needed by the animations ============= */ void ai_turn (edict_t *self, float dist) { if (dist) M_walkmove (self, self->s.angles[YAW], dist); if (FindTarget (self)) return; M_ChangeYaw (self); } void ai_still (edict_t *self, float dist) { if (dist) M_walkmove (self, self->s.angles[YAW], dist); M_ChangeYaw (self); } /* .enemy Will be world if not currently angry at anyone. .movetarget The next path spot to walk toward. If .enemy, ignore .movetarget. When an enemy is killed, the monster will try to return to it's path. .hunt_time Set to time + something when the player is in sight, but movement straight for him is blocked. This causes the monster to use wall following code for movement direction instead of sighting on the player. .ideal_yaw A yaw angle of the intended direction, which will be turned towards at up to 45 deg / state. If the enemy is in view and hunt_time is not active, this will be the exact line towards the enemy. .pausetime A monster will leave it's stand state and head towards it's .movetarget when time > .pausetime. walkmove(angle, speed) primitive is all or nothing */ /* ============= range returns the range catagorization of an entity reletive to self 0 melee range, will become hostile even if back is turned 1 visibility and infront, or visibility and show hostile 2 infront and show hostile 3 only triggered by damage ============= */ int range (edict_t *self, edict_t *other) { vec3_t v; float len; VectorSubtract (self->s.origin, other->s.origin, v); len = VectorLength (v); if (len < MELEE_DISTANCE) return RANGE_MELEE; if (len < 500) return RANGE_NEAR; if (len < 1000) return RANGE_MID; return RANGE_FAR; } /* ============= visible returns 1 if the entity is visible to self, even if not infront () ============= */ qboolean visible (edict_t *self, edict_t *other) { vec3_t spot1; vec3_t spot2; trace_t trace; VectorCopy (self->s.origin, spot1); spot1[2] += self->viewheight; VectorCopy (other->s.origin, spot2); spot2[2] += other->viewheight; trace = gi.trace (spot1, vec3_origin, vec3_origin, spot2, self, MASK_OPAQUE); if (trace.fraction == 1.0) return true; return false; } /* ============= infront returns 1 if the entity is in front (in sight) of self ============= */ qboolean infront (edict_t *self, edict_t *other) { vec3_t vec; float dot; vec3_t forward; AngleVectors (self->s.angles, forward, NULL, NULL); VectorSubtract (other->s.origin, self->s.origin, vec); VectorNormalize (vec); dot = DotProduct (vec, forward); if (dot > 0.3) return true; return false; } //============================================================================ void HuntTarget (edict_t *self) { vec3_t vec; if (self->monsterinfo.aiflags & AI_DUCKED) return; self->goalentity = self->enemy; if (self->monsterinfo.aiflags & AI_STAND_GROUND) self->monsterinfo.stand (self); else self->monsterinfo.run (self); VectorSubtract (self->enemy->s.origin, self->s.origin, vec); self->ideal_yaw = vectoyaw(vec); // wait a while before first attack if (!(self->monsterinfo.aiflags & AI_STAND_GROUND)) AttackFinished (self, 1); } void FoundTarget (edict_t *self) { if (self->monsterinfo.aiflags & AI_DUCKED) return; // let other monsters see this monster for a while if (self->enemy->client) { level.sight_entity = self; level.sight_entity_framenum = level.framenum; level.sight_entity->light_level = 128; } self->show_hostile = level.time + 1; // wake up other monsters VectorCopy(self->enemy->s.origin, self->monsterinfo.last_sighting); self->monsterinfo.trail_time = level.time; if (!self->combattarget) { HuntTarget (self); return; } //if(self->classname != "monster_mech") // self->goalentity = self->movetarget = G_PickTarget(self->combattarget); if (!self->movetarget) { self->goalentity = self->movetarget = self->enemy; HuntTarget (self); gi.dprintf("%s at %s, combattarget %s not found\n", self->classname, vtos(self->s.origin), self->combattarget); return; } // clear out our combattarget, these are a one shot deal self->combattarget = NULL; self->monsterinfo.aiflags |= AI_COMBAT_POINT; // clear the targetname, that point is ours! self->movetarget->targetname = NULL; self->monsterinfo.pausetime = 0; // run for it self->monsterinfo.run (self); } /* =========== FindTarget Self is currently not attacking anything, so try to find a target Returns TRUE if an enemy was sighted When a player fires a missile, the point of impact becomes a fakeplayer so that monsters that see the impact will respond as if they had seen the player. To avoid spending too much time, only a single client (or fakeclient) is checked each frame. This means multi player games will have slightly slower noticing monsters. ============ */ qboolean FindTarget (edict_t *self) { int i; vec3_t dist; edict_t *bestenemy = NULL; float bestweight = 99999; float weight; edict_t *ent; for(i=0;iinuse || ent->solid == SOLID_NOT) continue; if(!ent->deadflag && infront(self, ent) && gi.inPVS (self->s.origin, ent->s.origin)) { VectorSubtract(self->s.origin, ent->s.origin, dist); weight = VectorLength( dist ); // Check if best target, or better than current target if (weight < bestweight) { bestweight = weight; bestenemy = ent; } } } if(bestenemy) { self->enemy = bestenemy; // // got one // FoundTarget (self); //tell player that he needs to move his cows to his team's goal! if(self->enemy && !self->enemy->is_bot && !strcmp(self->classname, "npc_cow")) safe_centerprintf(self->enemy, "Lead this cow to your team's goal!"); if (!(self->monsterinfo.aiflags & AI_SOUND_TARGET) && (self->monsterinfo.sight)) self->monsterinfo.sight (self, self->enemy); return true; } return false; } //============================================================================= /* ============ FacingIdeal ============ */ qboolean FacingIdeal(edict_t *self) { float delta; delta = anglemod(self->s.angles[YAW] - self->ideal_yaw); if (delta > 45 && delta < 315) return false; return true; } //============================================================================= qboolean M_CheckAttack (edict_t *self) { vec3_t spot1, spot2; float chance; trace_t tr; if (self->enemy->health > 0) { // see if any entities are in the way of the shot VectorCopy (self->s.origin, spot1); spot1[2] += self->viewheight; VectorCopy (self->enemy->s.origin, spot2); spot2[2] += self->enemy->viewheight; tr = gi.trace (spot1, NULL, NULL, spot2, self, CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_SLIME|CONTENTS_LAVA|CONTENTS_WINDOW); // do we have a clear shot? if (tr.ent != self->enemy) return false; } // melee attack if (enemy_range == RANGE_MELEE) { // don't always melee in easy mode if (skill->value == 0 && (rand()&3) ) return false; if (self->monsterinfo.melee) self->monsterinfo.attack_state = AS_MELEE; else self->monsterinfo.attack_state = AS_MISSILE; return true; } // missile attack if (!self->monsterinfo.attack) return false; if (level.time < self->monsterinfo.attack_finished) return false; if(strcmp(self->classname, "npc_deathray")) if (enemy_range == RANGE_FAR) return false; if(strcmp(self->classname, "proj_spider")) { chance = 0.8; } else if (self->monsterinfo.aiflags & AI_STAND_GROUND) { chance = 0.4; } else if (enemy_range == RANGE_MELEE) { chance = 0.2; } else if (enemy_range == RANGE_NEAR) { chance = 0.1; } else if (enemy_range == RANGE_MID) { chance = 0.02; } else if (enemy_range == RANGE_FAR && !strcmp(self->classname, "npc_deathray")) { chance = 0.02; } else { return false; } if (skill->value == 0) chance *= 0.5; else if (skill->value >= 2) chance *= 2; if (random () < chance) { self->monsterinfo.attack_state = AS_MISSILE; self->monsterinfo.attack_finished = level.time + 2*random(); return true; } if (self->flags & FL_FLY) { if (random() < 0.3) self->monsterinfo.attack_state = AS_SLIDING; else self->monsterinfo.attack_state = AS_STRAIGHT; } return false; } /* ============= ai_run_melee Turn and close until within an angle to launch a melee attack ============= */ void ai_run_melee(edict_t *self) { self->ideal_yaw = enemy_yaw; M_ChangeYaw (self); if (FacingIdeal(self)) { self->monsterinfo.melee (self); self->monsterinfo.attack_state = AS_STRAIGHT; } } /* ============= ai_run_missile Turn in place until within an angle to launch a missile attack ============= */ void ai_run_missile (edict_t *self) { self->ideal_yaw = enemy_yaw; M_ChangeYaw (self); if (FacingIdeal(self)) { self->monsterinfo.attack (self); self->monsterinfo.attack_state = AS_STRAIGHT; } }; /* ============= ai_run_slide Strafe sideways, but stay at aproximately the same range ============= */ void ai_run_slide(edict_t *self, float distance) { float ofs; self->ideal_yaw = enemy_yaw; M_ChangeYaw (self); if (self->monsterinfo.lefty) ofs = 90; else ofs = -90; if (M_walkmove (self, self->ideal_yaw + ofs, distance)) return; self->monsterinfo.lefty = 1 - self->monsterinfo.lefty; M_walkmove (self, self->ideal_yaw - ofs, distance); } /* ============= ai_checkattack Decides if we're going to attack or do something else used by ai_run and ai_stand ============= */ qboolean ai_checkattack (edict_t *self, float dist) { vec3_t temp; qboolean hesDeadJim; // this causes monsters to run blindly to the combat point w/o firing if (self->goalentity) { if (self->monsterinfo.aiflags & AI_COMBAT_POINT) return false; if (self->monsterinfo.aiflags & AI_SOUND_TARGET) { if ((level.time - self->enemy->teleport_time) > 5.0) { if (self->goalentity == self->enemy) { if (self->movetarget) self->goalentity = self->movetarget; else self->goalentity = NULL; } self->monsterinfo.aiflags &= ~AI_SOUND_TARGET; if (self->monsterinfo.aiflags & AI_TEMP_STAND_GROUND) self->monsterinfo.aiflags &= ~(AI_STAND_GROUND | AI_TEMP_STAND_GROUND); } else { self->show_hostile = level.time + 1; return false; } } } enemy_vis = false; // see if the enemy is dead hesDeadJim = false; if ((!self->enemy) || (!self->enemy->inuse)) { hesDeadJim = true; } else if (self->monsterinfo.aiflags & AI_MEDIC) { if (self->enemy->health > 0) { hesDeadJim = true; self->monsterinfo.aiflags &= ~AI_MEDIC; } } else { if (self->monsterinfo.aiflags & AI_BRUTAL) { if (self->enemy->health <= -self->enemy->gib_health) hesDeadJim = true; } else { if (self->enemy->health <= 0) hesDeadJim = true; } } if (hesDeadJim) { self->enemy = NULL; // FIXME: look all around for other targets if (self->oldenemy && self->oldenemy->health > 0) { self->enemy = self->oldenemy; self->oldenemy = NULL; HuntTarget (self); } else { if (self->movetarget) { self->goalentity = self->movetarget; self->monsterinfo.walk (self); } else { // we need the pausetime otherwise the stand code // will just revert to walking with no target and // the monsters will wonder around aimlessly trying // to hunt the world entity self->monsterinfo.pausetime = level.time + 100000000; self->monsterinfo.stand (self); } return true; } } self->show_hostile = level.time + 1; // wake up other monsters // check knowledge of enemy enemy_vis = visible(self, self->enemy); if (enemy_vis) { self->monsterinfo.search_time = level.time + 5; VectorCopy (self->enemy->s.origin, self->monsterinfo.last_sighting); } enemy_infront = infront(self, self->enemy); enemy_range = range(self, self->enemy); VectorSubtract (self->enemy->s.origin, self->s.origin, temp); enemy_yaw = vectoyaw(temp); if(!strcmp(self->classname, "npc_deathray")) if(self->enemy->client && self->enemy->inuse) if(self->enemy->client->rayImmunity && ((level.time - self->enemy->client->rayTime) < 60)) return false; if(!strcmp(self->classname, "proj_spider")) if(self->enemy->client && self->enemy->inuse) if(self->enemy == self->owner) return false; // JDC self->ideal_yaw = enemy_yaw; if (self->monsterinfo.attack_state == AS_MISSILE) { ai_run_missile (self); return true; } if (self->monsterinfo.attack_state == AS_MELEE) { ai_run_melee (self); return true; } // if enemy is not currently visible, we will never attack if (!enemy_vis) return false; return self->monsterinfo.checkattack (self); } /* ============= ai_run The monster has an enemy it is trying to kill ============= */ void ai_run (edict_t *self, float dist) { vec3_t v; edict_t *tempgoal; edict_t *save; qboolean new; edict_t *marker; float d1, d2; trace_t tr; vec3_t v_forward, v_right; float left, center, right; vec3_t left_target, right_target; // if we're going to a combat point, just proceed if (self->monsterinfo.aiflags & AI_COMBAT_POINT) { M_MoveToGoal (self, dist); return; } if (self->monsterinfo.aiflags & AI_SOUND_TARGET) { VectorSubtract (self->s.origin, self->enemy->s.origin, v); if (VectorLength(v) < 64) { self->monsterinfo.aiflags |= (AI_STAND_GROUND | AI_TEMP_STAND_GROUND); self->monsterinfo.stand (self); return; } M_MoveToGoal (self, dist); if (!FindTarget (self)) return; } if (ai_checkattack (self, dist)) return; if (self->monsterinfo.attack_state == AS_SLIDING) { ai_run_slide (self, dist); return; } if(!strcmp(self->classname, "proj_spider")) if(self->goalentity == self->owner) return; if (enemy_vis) { // if (self.aiflags & AI_LOST_SIGHT) // dprint("regained sight\n"); M_MoveToGoal (self, dist); self->monsterinfo.aiflags &= ~AI_LOST_SIGHT; VectorCopy (self->enemy->s.origin, self->monsterinfo.last_sighting); self->monsterinfo.trail_time = level.time; return; } if ((self->monsterinfo.search_time) && (level.time > (self->monsterinfo.search_time + 20))) { M_MoveToGoal (self, dist); self->monsterinfo.search_time = 0; // dprint("search timeout\n"); return; } save = self->goalentity; tempgoal = G_Spawn(); self->goalentity = tempgoal; new = false; if (!(self->monsterinfo.aiflags & AI_LOST_SIGHT)) { // just lost sight of the player, decide where to go first // dprint("lost sight of player, last seen at "); dprint(vtos(self.last_sighting)); dprint("\n"); self->monsterinfo.aiflags |= (AI_LOST_SIGHT | AI_PURSUIT_LAST_SEEN); self->monsterinfo.aiflags &= ~(AI_PURSUE_NEXT | AI_PURSUE_TEMP); new = true; } if (self->monsterinfo.aiflags & AI_PURSUE_NEXT) { self->monsterinfo.aiflags &= ~AI_PURSUE_NEXT; // dprint("reached current goal: "); dprint(vtos(self.origin)); dprint(" "); dprint(vtos(self.last_sighting)); dprint(" "); dprint(ftos(vlen(self.origin - self.last_sighting))); dprint("\n"); // give ourself more time since we got this far self->monsterinfo.search_time = level.time + 5; if (self->monsterinfo.aiflags & AI_PURSUE_TEMP) { // dprint("was temp goal; retrying original\n"); self->monsterinfo.aiflags &= ~AI_PURSUE_TEMP; marker = NULL; VectorCopy (self->monsterinfo.saved_goal, self->monsterinfo.last_sighting); new = true; } else if (self->monsterinfo.aiflags & AI_PURSUIT_LAST_SEEN) { self->monsterinfo.aiflags &= ~AI_PURSUIT_LAST_SEEN; marker = PlayerTrail_PickFirst (self); } else { marker = PlayerTrail_PickNext (self); } if (marker) { VectorCopy (marker->s.origin, self->monsterinfo.last_sighting); self->monsterinfo.trail_time = marker->timestamp; self->s.angles[YAW] = self->ideal_yaw = marker->s.angles[YAW]; // dprint("heading is "); dprint(ftos(self.ideal_yaw)); dprint("\n"); // debug_drawline(self.origin, self.last_sighting, 52); new = true; } } VectorSubtract (self->s.origin, self->monsterinfo.last_sighting, v); d1 = VectorLength(v); if (d1 <= dist) { self->monsterinfo.aiflags |= AI_PURSUE_NEXT; dist = d1; } VectorCopy (self->monsterinfo.last_sighting, self->goalentity->s.origin); if (new) { // gi.dprintf("checking for course correction\n"); tr = gi.trace(self->s.origin, self->mins, self->maxs, self->monsterinfo.last_sighting, self, MASK_PLAYERSOLID); if (tr.fraction < 1) { VectorSubtract (self->goalentity->s.origin, self->s.origin, v); d1 = VectorLength(v); center = tr.fraction; d2 = d1 * ((center+1)/2); self->s.angles[YAW] = self->ideal_yaw = vectoyaw(v); AngleVectors(self->s.angles, v_forward, v_right, NULL); VectorSet(v, d2, -16, 0); G_ProjectSource (self->s.origin, v, v_forward, v_right, left_target); tr = gi.trace(self->s.origin, self->mins, self->maxs, left_target, self, MASK_PLAYERSOLID); left = tr.fraction; VectorSet(v, d2, 16, 0); G_ProjectSource (self->s.origin, v, v_forward, v_right, right_target); tr = gi.trace(self->s.origin, self->mins, self->maxs, right_target, self, MASK_PLAYERSOLID); right = tr.fraction; center = (d1*center)/d2; if (left >= center && left > right) { if (left < 1) { VectorSet(v, d2 * left * 0.5, -16, 0); G_ProjectSource (self->s.origin, v, v_forward, v_right, left_target); // gi.dprintf("incomplete path, go part way and adjust again\n"); } VectorCopy (self->monsterinfo.last_sighting, self->monsterinfo.saved_goal); self->monsterinfo.aiflags |= AI_PURSUE_TEMP; VectorCopy (left_target, self->goalentity->s.origin); VectorCopy (left_target, self->monsterinfo.last_sighting); VectorSubtract (self->goalentity->s.origin, self->s.origin, v); self->s.angles[YAW] = self->ideal_yaw = vectoyaw(v); // gi.dprintf("adjusted left\n"); // debug_drawline(self.origin, self.last_sighting, 152); } else if (right >= center && right > left) { if (right < 1) { VectorSet(v, d2 * right * 0.5, 16, 0); G_ProjectSource (self->s.origin, v, v_forward, v_right, right_target); // gi.dprintf("incomplete path, go part way and adjust again\n"); } VectorCopy (self->monsterinfo.last_sighting, self->monsterinfo.saved_goal); self->monsterinfo.aiflags |= AI_PURSUE_TEMP; VectorCopy (right_target, self->goalentity->s.origin); VectorCopy (right_target, self->monsterinfo.last_sighting); VectorSubtract (self->goalentity->s.origin, self->s.origin, v); self->s.angles[YAW] = self->ideal_yaw = vectoyaw(v); // gi.dprintf("adjusted right\n"); // debug_drawline(self.origin, self.last_sighting, 152); } } // else gi.dprintf("course was fine\n"); } M_MoveToGoal (self, dist); G_FreeEdict(tempgoal); self->goalentity = save; } alien-arena-7.66+dfsg/source/game/g_misc.c0000600000175000017500000014722612161402010017434 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // g_misc.c #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" /*QUAKED func_group (0 0 0) ? Used to group brushes together just for editor convenience. */ //===================================================== void Use_Areaportal (edict_t *ent, edict_t *other, edict_t *activator) { ent->count ^= 1; // toggle state // gi.dprintf ("portalstate: %i = %i\n", ent->style, ent->count); gi.SetAreaPortalState (ent->style, ent->count); } /*QUAKED func_areaportal (0 0 0) ? This is a non-visible object that divides the world into areas that are seperated when this portal is not activated. Usually enclosed in the middle of a door. */ void SP_func_areaportal (edict_t *ent) { ent->use = Use_Areaportal; ent->count = 0; // always start closed; } //===================================================== /* ================= Misc functions ================= */ void VelocityForDamage (int damage, vec3_t v) { v[0] = 100.0 * crandom(); v[1] = 100.0 * crandom(); v[2] = 200.0 + 100.0 * random(); if (damage < 50) VectorScale (v, 0.7, v); else VectorScale (v, 1.2, v); } void ClipGibVelocity (edict_t *ent) { if (ent->velocity[0] < -300) ent->velocity[0] = -300; else if (ent->velocity[0] > 300) ent->velocity[0] = 300; if (ent->velocity[1] < -300) ent->velocity[1] = -300; else if (ent->velocity[1] > 300) ent->velocity[1] = 300; if (ent->velocity[2] < 200) ent->velocity[2] = 200; // always some upwards else if (ent->velocity[2] > 500) ent->velocity[2] = 500; } /* ================= gibs ================= */ void gib_think (edict_t *self) { self->s.frame++; self->nextthink = level.time + FRAMETIME; if (self->s.frame > 9) { self->think = G_FreeEdict; self->nextthink = level.time + 2 + random()*2; } } void gib_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { vec3_t normal_angles, right; if (!self->groundentity) return; self->touch = NULL; if (plane) { gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/fhit3.wav"), 1, ATTN_NORM, 0); vectoangles (plane->normal, normal_angles); AngleVectors (normal_angles, NULL, right, NULL); vectoangles (right, self->s.angles); if (self->s.modelindex == sm_meat_index) { self->s.frame = 0;//++; self->think = gib_think; self->nextthink = level.time + FRAMETIME; } } } void gib_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { G_FreeEdict (self); } void ThrowGib (edict_t *self, char *gibname, int damage, int type, int effects) { edict_t *gib; vec3_t vd; vec3_t origin; vec3_t size; float vscale; gib = G_Spawn(); VectorScale (self->size, 1, size); VectorAdd (self->absmin, size, origin); gib->s.origin[0] = origin[0] + crandom() * size[0]; gib->s.origin[1] = origin[1] + crandom() * size[1]; gib->s.origin[2] = origin[2] + crandom() * size[2]; gi.setmodel (gib, gibname); gib->solid = SOLID_NOT; gib->s.effects = effects; gib->flags |= FL_NO_KNOCKBACK; gib->takedamage = DAMAGE_YES; gib->die = gib_die; if (type == GIB_ORGANIC) { gib->movetype = MOVETYPE_BOUNCE; gib->touch = gib_touch; vscale = 0.2; } else { gib->movetype = MOVETYPE_BOUNCE; vscale = 1.0; } VelocityForDamage (damage, vd); VectorMA (self->velocity, vscale, vd, gib->velocity); ClipGibVelocity (gib); gib->avelocity[0] = random()*600; gib->avelocity[1] = random()*600; gib->avelocity[2] = random()*600; gib->think = G_FreeEdict; gib->nextthink = level.time + 2 + random()*2; gi.linkentity (gib); } void ThrowClientHead (edict_t *self, int damage) { vec3_t vd; char *gibname; gibname = "models/objects/gibs/sm_meat/tris.md2"; self->s.skinnum = 0; self->s.origin[2] += 32; self->s.frame = 0; gi.setmodel (self, gibname); VectorSet (self->mins, -16, -16, 0); VectorSet (self->maxs, 16, 16, 16); self->takedamage = DAMAGE_NO; self->solid = SOLID_NOT; self->s.effects = EF_GIB; self->s.sound = 0; self->flags |= FL_NO_KNOCKBACK; self->movetype = MOVETYPE_TOSS; VelocityForDamage (damage, vd); VectorAdd (self->velocity, vd, self->velocity); if (self->client) // bodies in the queue don't have a client anymore { self->client->anim_priority = ANIM_DEATH; self->client->anim_end = self->s.frame; } else { self->think = NULL; self->nextthink = 0; } gi.linkentity (self); } /* ================= debris ================= */ void debris_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { G_FreeEdict (self); } void ThrowDebris (edict_t *self, char *modelname, float speed, vec3_t origin) { edict_t *chunk; vec3_t v; chunk = G_Spawn(); VectorCopy (origin, chunk->s.origin); gi.setmodel (chunk, modelname); v[0] = 100 * crandom(); v[1] = 100 * crandom(); v[2] = 100 + 100 * crandom(); VectorMA (self->velocity, speed, v, chunk->velocity); chunk->movetype = MOVETYPE_BOUNCE; chunk->solid = SOLID_NOT; chunk->avelocity[0] = random()*600; chunk->avelocity[1] = random()*600; chunk->avelocity[2] = random()*600; chunk->s.effects |= EF_ROCKET; chunk->think = G_FreeEdict; chunk->nextthink = level.time + 5 + random()*5; chunk->s.frame = 0; chunk->flags = 0; chunk->classname = "debris"; chunk->takedamage = DAMAGE_YES; chunk->die = debris_die; gi.linkentity (chunk); } void ThrowDebris2 (edict_t *self, char *modelname, float speed, vec3_t origin) { edict_t *chunk; vec3_t v; chunk = G_Spawn(); VectorCopy (origin, chunk->s.origin); gi.setmodel (chunk, modelname); v[0] = 100 * crandom(); v[1] = 100 * crandom(); v[2] = 100 + 100 * crandom(); VectorMA (self->velocity, speed, v, chunk->velocity); chunk->movetype = MOVETYPE_BOUNCE; chunk->solid = SOLID_NOT; chunk->avelocity[0] = random()*600; chunk->avelocity[1] = random()*600; chunk->avelocity[2] = random()*600; chunk->think = G_FreeEdict; chunk->nextthink = level.time + 5 + random()*5; chunk->s.frame = 0; chunk->flags = 0; chunk->classname = "debris"; chunk->takedamage = DAMAGE_YES; chunk->die = debris_die; gi.linkentity (chunk); } void BecomeExplosion1 (edict_t *self) { gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_EXPLOSION1); gi.WritePosition (self->s.origin); gi.multicast (self->s.origin, MULTICAST_PVS); G_FreeEdict (self); } void BecomeExplosion2 (edict_t *self) { gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_EXPLOSION2); gi.WritePosition (self->s.origin); gi.multicast (self->s.origin, MULTICAST_PVS); G_FreeEdict (self); } /*QUAKED path_corner (.5 .3 0) (-8 -8 -8) (8 8 8) TELEPORT Target: next path corner Pathtarget: gets used when an entity that has this path_corner targeted touches it */ void path_corner_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { vec3_t v; edict_t *next; if (other->movetarget != self) return; if (other->enemy) return; if (self->pathtarget) { char *savetarget; savetarget = self->target; self->target = self->pathtarget; G_UseTargets (self, other); self->target = savetarget; } if (self->target) next = G_PickTarget(self->target); else next = NULL; if ((next) && (next->spawnflags & 1)) { VectorCopy (next->s.origin, v); v[2] += next->mins[2]; v[2] -= other->mins[2]; VectorCopy (v, other->s.origin); next = G_PickTarget(next->target); other->s.event = EV_OTHER_TELEPORT; } other->goalentity = other->movetarget = next; if (self->wait) { other->monsterinfo.pausetime = level.time + self->wait; other->monsterinfo.stand (other); return; } if (!other->movetarget) { other->monsterinfo.pausetime = level.time + 100000000; other->monsterinfo.stand (other); } else { VectorSubtract (other->goalentity->s.origin, other->s.origin, v); other->ideal_yaw = vectoyaw (v); } } void SP_path_corner (edict_t *self) { if (!self->targetname) { gi.dprintf ("path_corner with no targetname at %s\n", vtos(self->s.origin)); G_FreeEdict (self); return; } self->solid = SOLID_TRIGGER; self->touch = path_corner_touch; VectorSet (self->mins, -8, -8, -8); VectorSet (self->maxs, 8, 8, 8); self->svflags |= SVF_NOCLIENT; gi.linkentity (self); } /*QUAKED point_combat (0.5 0.3 0) (-8 -8 -8) (8 8 8) Hold Makes this the target of a monster and it will head here when first activated before going after the activator. If hold is selected, it will stay here. */ void point_combat_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { edict_t *activator; if (other->movetarget != self) return; if (self->target) { other->target = self->target; other->goalentity = other->movetarget = G_PickTarget(other->target); if (!other->goalentity) { gi.dprintf("%s at %s target %s does not exist\n", self->classname, vtos(self->s.origin), self->target); other->movetarget = self; } self->target = NULL; } else if ((self->spawnflags & 1) && !(other->flags & (FL_SWIM|FL_FLY))) { other->monsterinfo.pausetime = level.time + 100000000; other->monsterinfo.aiflags |= AI_STAND_GROUND; other->monsterinfo.stand (other); } if (other->movetarget == self) { other->target = NULL; other->movetarget = NULL; other->goalentity = other->enemy; other->monsterinfo.aiflags &= ~AI_COMBAT_POINT; } if (self->pathtarget) { char *savetarget; savetarget = self->target; self->target = self->pathtarget; if (other->enemy && other->enemy->client) activator = other->enemy; else if (other->oldenemy && other->oldenemy->client) activator = other->oldenemy; else if (other->activator && other->activator->client) activator = other->activator; else activator = other; G_UseTargets (self, activator); self->target = savetarget; } } void SP_point_combat (edict_t *self) { if (deathmatch->value) { G_FreeEdict (self); return; } self->solid = SOLID_TRIGGER; self->touch = point_combat_touch; VectorSet (self->mins, -8, -8, -16); VectorSet (self->maxs, 8, 8, 16); self->svflags = SVF_NOCLIENT; gi.linkentity (self); }; /*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4) Used as a positional target for spotlights, etc. */ void SP_info_null (edict_t *self) { G_FreeEdict (self); }; /*QUAKED info_notnull (0 0.5 0) (-4 -4 -4) (4 4 4) Used as a positional target for lightning. */ void SP_info_notnull (edict_t *self) { VectorCopy (self->s.origin, self->absmin); VectorCopy (self->s.origin, self->absmax); }; /*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) START_OFF Non-displayed light. Default light value is 300. Default style is 0. If targeted, will toggle between on and off. Default _cone value is 10 (used to set size of light for spotlights) */ #define START_OFF 1 static void light_use (edict_t *self, edict_t *other, edict_t *activator) { if (self->spawnflags & START_OFF) { gi.configstring (CS_LIGHTS+self->style, "m"); self->spawnflags &= ~START_OFF; } else { gi.configstring (CS_LIGHTS+self->style, "a"); self->spawnflags |= START_OFF; } } void SP_light (edict_t *self) { // no targeted lights in deathmatch, because they cause global messages if (!self->targetname || deathmatch->value) { G_FreeEdict (self); return; } if (self->style >= 32) { self->use = light_use; if (self->spawnflags & START_OFF) gi.configstring (CS_LIGHTS+self->style, "a"); else gi.configstring (CS_LIGHTS+self->style, "m"); } } /*QUAKED func_wall (0 .5 .8) ? TRIGGER_SPAWN TOGGLE START_ON ANIMATED ANIMATED_FAST This is just a solid wall if not inhibited TRIGGER_SPAWN the wall will not be present until triggered it will then blink in to existance; it will kill anything that was in it's way TOGGLE only valid for TRIGGER_SPAWN walls this allows the wall to be turned on and off START_ON only valid for TRIGGER_SPAWN walls the wall will initially be present */ void func_wall_use (edict_t *self, edict_t *other, edict_t *activator) { if (self->solid == SOLID_NOT) { self->solid = SOLID_BSP; self->svflags &= ~SVF_NOCLIENT; KillBox (self); } else { self->solid = SOLID_NOT; self->svflags |= SVF_NOCLIENT; } gi.linkentity (self); if (!(self->spawnflags & 2)) self->use = NULL; } void SP_func_wall (edict_t *self) { self->movetype = MOVETYPE_PUSH; gi.setmodel (self, self->model); if (self->spawnflags & 8) self->s.effects |= EF_ANIM_ALL; if (self->spawnflags & 16) self->s.effects |= EF_ANIM_ALLFAST; // just a wall if ((self->spawnflags & 7) == 0) { self->solid = SOLID_BSP; gi.linkentity (self); return; } // it must be TRIGGER_SPAWN if (!(self->spawnflags & 1)) { // gi.dprintf("func_wall missing TRIGGER_SPAWN\n"); self->spawnflags |= 1; } // yell if the spawnflags are odd if (self->spawnflags & 4) { if (!(self->spawnflags & 2)) { gi.dprintf("func_wall START_ON without TOGGLE\n"); self->spawnflags |= 2; } } self->use = func_wall_use; if (self->spawnflags & 4) { self->solid = SOLID_BSP; } else { self->solid = SOLID_NOT; self->svflags |= SVF_NOCLIENT; } gi.linkentity (self); } /*QUAKED func_object (0 .5 .8) ? TRIGGER_SPAWN ANIMATED ANIMATED_FAST This is solid bmodel that will fall if it's support it removed. */ void func_object_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { // only squash thing we fall on top of if (!plane) return; if (plane->normal[2] < 1.0) return; if (other->takedamage == DAMAGE_NO) return; T_Damage (other, self, self, vec3_origin, self->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH); } void func_object_release (edict_t *self) { self->movetype = MOVETYPE_TOSS; self->touch = func_object_touch; } void func_object_use (edict_t *self, edict_t *other, edict_t *activator) { self->solid = SOLID_BSP; self->svflags &= ~SVF_NOCLIENT; self->use = NULL; KillBox (self); func_object_release (self); } void SP_func_object (edict_t *self) { gi.setmodel (self, self->model); self->mins[0] += 1; self->mins[1] += 1; self->mins[2] += 1; self->maxs[0] -= 1; self->maxs[1] -= 1; self->maxs[2] -= 1; if (!self->dmg) self->dmg = 100; if (self->spawnflags == 0) { self->solid = SOLID_BSP; self->movetype = MOVETYPE_PUSH; self->think = func_object_release; self->nextthink = level.time + 2 * FRAMETIME; } else { self->solid = SOLID_NOT; self->movetype = MOVETYPE_PUSH; self->use = func_object_use; self->svflags |= SVF_NOCLIENT; } if (self->spawnflags & 2) self->s.effects |= EF_ANIM_ALL; if (self->spawnflags & 4) self->s.effects |= EF_ANIM_ALLFAST; self->clipmask = MASK_MONSTERSOLID; gi.linkentity (self); } /*QUAKED func_explosive (0 .5 .8) ? Trigger_Spawn ANIMATED ANIMATED_FAST Any brush that you want to explode or break apart. If you want an ex0plosion, set dmg and it will do a radius explosion of that amount at the center of the bursh. If targeted it will not be shootable. health defaults to 100. mass defaults to 75. This determines how much debris is emitted when it explodes. You get one large chunk per 100 of mass (up to 8) and one small chunk per 25 of mass (up to 16). So 800 gives the most. */ void func_explosive_explode (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { vec3_t origin; vec3_t chunkorigin; vec3_t size; int count; int mass; // bmodel origins are (0 0 0), we need to adjust that here VectorScale (self->size, 0.5, size); VectorAdd (self->absmin, size, origin); VectorCopy (origin, self->s.origin); self->takedamage = DAMAGE_NO; if (self->dmg) T_RadiusDamage (self, attacker, self->dmg, NULL, self->dmg+40, MOD_EXPLOSIVE, -1); VectorSubtract (self->s.origin, inflictor->s.origin, self->velocity); VectorNormalize (self->velocity); VectorScale (self->velocity, 150, self->velocity); // start chunks towards the center VectorScale (size, 0.5, size); mass = self->mass; if (!mass) mass = 75; // big chunks if (mass >= 100) { count = mass / 100; if (count > 8) count = 8; while(count--) { chunkorigin[0] = origin[0] + crandom() * size[0]; chunkorigin[1] = origin[1] + crandom() * size[1]; chunkorigin[2] = origin[2] + crandom() * size[2]; ThrowDebris (self, "models/objects/debris1/tris.md2", 1, chunkorigin); } } // small chunks count = mass / 25; if (count > 16) count = 16; while(count--) { chunkorigin[0] = origin[0] + crandom() * size[0]; chunkorigin[1] = origin[1] + crandom() * size[1]; chunkorigin[2] = origin[2] + crandom() * size[2]; ThrowDebris (self, "models/objects/debris2/tris.md2", 2, chunkorigin); } G_UseTargets (self, attacker); if (self->dmg) BecomeExplosion1 (self); else G_FreeEdict (self); } void func_explosive_use(edict_t *self, edict_t *other, edict_t *activator) { func_explosive_explode (self, self, other, self->health, vec3_origin); } void func_explosive_spawn (edict_t *self, edict_t *other, edict_t *activator) { self->solid = SOLID_BSP; self->svflags &= ~SVF_NOCLIENT; self->use = NULL; KillBox (self); gi.linkentity (self); } void SP_func_explosive (edict_t *self) { self->movetype = MOVETYPE_PUSH; gi.modelindex ("models/objects/debris1/tris.md2"); gi.modelindex ("models/objects/debris2/tris.md2"); gi.setmodel (self, self->model); if (self->spawnflags & 1) { self->svflags |= SVF_NOCLIENT; self->solid = SOLID_NOT; self->use = func_explosive_spawn; } else { self->solid = SOLID_BSP; if (self->targetname) self->use = func_explosive_use; } if (self->spawnflags & 2) self->s.effects |= EF_ANIM_ALL; if (self->spawnflags & 4) self->s.effects |= EF_ANIM_ALLFAST; if (self->use != func_explosive_use) { if (!self->health) self->health = 100; self->die = func_explosive_explode; self->takedamage = DAMAGE_YES; } gi.linkentity (self); } /*QUAKED misc_explobox (0 .5 .8) (-16 -16 0) (16 16 40) Large exploding box. You can override its mass (100), health (80), and dmg (150). */ void barrel_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { float ratio; vec3_t v; if ((!other->groundentity) || (other->groundentity == self)) return; ratio = (float)other->mass / (float)self->mass; VectorSubtract (self->s.origin, other->s.origin, v); M_walkmove (self, vectoyaw(v), 20 * ratio * FRAMETIME); } void barrel_explode (edict_t *self) { vec3_t org; float spd; vec3_t save, size; T_RadiusDamage (self, self->activator, self->dmg, NULL, self->dmg+40, MOD_BARREL, -1); VectorCopy (self->s.origin, save); VectorMA (self->absmin, 0.5, self->size, self->s.origin); VectorScale (self->size, 0.5, size); // a few big chunks spd = 1.5 * (float)self->dmg / 200.0; org[0] = self->s.origin[0] + crandom() * size[0]; org[1] = self->s.origin[1] + crandom() * size[1]; org[2] = self->s.origin[2] + crandom() * size[2]; ThrowDebris (self, "models/objects/debris1/tris.md2", spd, org); org[0] = self->s.origin[0] + crandom() * size[0]; org[1] = self->s.origin[1] + crandom() * size[1]; org[2] = self->s.origin[2] + crandom() * size[2]; ThrowDebris (self, "models/objects/debris1/tris.md2", spd, org); // bottom corners spd = 1.75 * (float)self->dmg / 200.0; VectorCopy (self->absmin, org); ThrowDebris (self, "models/objects/debris3/tris.md2", spd, org); VectorCopy (self->absmin, org); org[0] += self->size[0]; ThrowDebris (self, "models/objects/debris3/tris.md2", spd, org); VectorCopy (self->absmin, org); org[1] += self->size[1]; ThrowDebris (self, "models/objects/debris3/tris.md2", spd, org); VectorCopy (self->absmin, org); org[0] += self->size[0]; org[1] += self->size[1]; ThrowDebris (self, "models/objects/debris3/tris.md2", spd, org); // a bunch of little chunks spd = 2 * self->dmg / 200; org[0] = self->s.origin[0] + crandom() * size[0]; org[1] = self->s.origin[1] + crandom() * size[1]; org[2] = self->s.origin[2] + crandom() * size[2]; ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org); org[0] = self->s.origin[0] + crandom() * size[0]; org[1] = self->s.origin[1] + crandom() * size[1]; org[2] = self->s.origin[2] + crandom() * size[2]; ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org); org[0] = self->s.origin[0] + crandom() * size[0]; org[1] = self->s.origin[1] + crandom() * size[1]; org[2] = self->s.origin[2] + crandom() * size[2]; ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org); org[0] = self->s.origin[0] + crandom() * size[0]; org[1] = self->s.origin[1] + crandom() * size[1]; org[2] = self->s.origin[2] + crandom() * size[2]; ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org); org[0] = self->s.origin[0] + crandom() * size[0]; org[1] = self->s.origin[1] + crandom() * size[1]; org[2] = self->s.origin[2] + crandom() * size[2]; ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org); org[0] = self->s.origin[0] + crandom() * size[0]; org[1] = self->s.origin[1] + crandom() * size[1]; org[2] = self->s.origin[2] + crandom() * size[2]; ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org); org[0] = self->s.origin[0] + crandom() * size[0]; org[1] = self->s.origin[1] + crandom() * size[1]; org[2] = self->s.origin[2] + crandom() * size[2]; ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org); org[0] = self->s.origin[0] + crandom() * size[0]; org[1] = self->s.origin[1] + crandom() * size[1]; org[2] = self->s.origin[2] + crandom() * size[2]; ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org); VectorCopy (save, self->s.origin); if (self->groundentity) BecomeExplosion2 (self); else BecomeExplosion1 (self); } void barrel_delay (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { self->takedamage = DAMAGE_NO; self->nextthink = level.time + 2 * FRAMETIME; self->think = barrel_explode; self->activator = attacker; } //================================================================================= void teleporter_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { edict_t *dest; int i; if (!other->client) return; dest = G_Find (NULL, FOFS(targetname), self->target); if (!dest) { gi.dprintf ("Couldn't find destination\n"); return; } //ZOID CTFPlayerResetGrapple(other); //ZOID // unlink to make sure it can't possibly interfere with KillBox gi.unlinkentity (other); VectorCopy (dest->s.origin, other->s.origin); VectorCopy (dest->s.origin, other->s.old_origin); other->s.origin[2] += 10; // clear the velocity and hold them in place briefly VectorClear (other->velocity); other->client->ps.pmove.pm_time = 160>>3; // hold time other->client->ps.pmove.pm_flags |= PMF_TIME_TELEPORT; // draw the teleport splash at source and on the player self->owner->s.event = EV_PLAYER_TELEPORT; other->s.event = EV_PLAYER_TELEPORT; // set angles for (i=0 ; i<3 ; i++) { other->client->ps.pmove.delta_angles[i] = ANGLE2SHORT(dest->s.angles[i] - other->client->resp.cmd_angles[i]); } VectorClear (other->s.angles); VectorClear (other->client->ps.viewangles); VectorClear (other->client->v_angle); // kill anything at the destination KillBox (other); gi.linkentity (other); } /*QUAKED misc_teleporter (1 0 0) (-32 -32 -24) (32 32 -16) Stepping onto this disc will teleport players to the targeted misc_teleporter_dest object. */ void SP_misc_teleporter (edict_t *ent) { edict_t *trig; if (!ent->target) { gi.dprintf ("teleporter without a target.\n"); G_FreeEdict (ent); return; } // The actual misc_teleporter is converted into a cosmetic object for the // glowing effect, while a new entity is spawned to act as the functioning // teleporter. gi.setmodel (ent, "models/objects/blank/tris.md2"); ent->s.skinnum = 1; ent->s.effects = EF_TELEPORTER; ent->solid = SOLID_BBOX; VectorSet (ent->mins, -32, -32, -24); VectorSet (ent->maxs, 32, 32, -16); gi.linkentity (ent); trig = G_Spawn (); trig->touch = teleporter_touch; trig->solid = SOLID_TRIGGER; trig->target = ent->target; trig->owner = ent; VectorCopy (ent->s.origin, trig->s.origin); VectorSet (trig->mins, -8, -8, 8); VectorSet (trig->maxs, 8, 8, 24); gi.linkentity (trig); } /*QUAKED misc_teleporter_dest (1 0 0) (-32 -32 -24) (32 32 -16) Point teleporters at these. */ void SP_misc_teleporter_dest (edict_t *ent) { ent->s.modelindex = 0; ent->s.skinnum = 0; ent->solid = SOLID_NOT; VectorSet (ent->mins, -32, -32, -24); VectorSet (ent->maxs, 32, 32, -16); gi.linkentity (ent); } void misc_mapmodel_think (edict_t *ent) { if(ent->spawnflags & 2) ent->s.frame = (ent->s.frame + 1) % 39; else ent->s.frame = (ent->s.frame + 1) % 24; ent->nextthink = level.time + FRAMETIME; } void SP_misc_mapmodel (edict_t *ent) //random .md2 map models { gi.setmodel (ent, ent->model); ent->solid = SOLID_NOT; //will need clipping brushes around it //disable shadows(also disables per-pixel dynamic lighting unless minlight set if(ent->spawnflags & 1) ent->s.renderfx = RF_NOSHADOWS; if(ent->spawnflags & 16) ent->s.renderfx = RF_TRANSLUCENT; if(ent->spawnflags & 32) { //animated mesh if(ent->spawnflags & 128) ent->s.frame = 0; else ent->s.frame = rand()%24; ent->think = misc_mapmodel_think; ent->nextthink = level.time + FRAMETIME; } else //static mesh ent->s.frame = 0; //allow dynamic per-pixel lighting if(ent->spawnflags & 64) ent->s.renderfx |= RF_MINLIGHT; gi.linkentity (ent); } void watersplash_think (edict_t *ent) { vec3_t up; up[0] = 0; up[1] = 0; up[2] = 1; //write effect gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_SPLASH); gi.WriteByte (8); gi.WritePosition (ent->s.origin); gi.WriteDir (up); gi.WriteByte (SPLASH_BLUE_WATER); //we should allow spawnflags to change this gi.multicast (ent->s.origin, MULTICAST_PVS); ent->nextthink = level.time + 1.0; } void SP_misc_watersplash (edict_t *ent) { gi.setmodel(ent, NULL); ent->solid = SOLID_NOT; ent->movetype = MOVETYPE_NONE; ent->takedamage = DAMAGE_NO; ent->think = watersplash_think; ent->nextthink = level.time + 0.5 + random(); gi.linkentity (ent); } void misc_electroflash_think (edict_t *ent) { gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_RAILGUN); gi.multicast (ent->s.origin, MULTICAST_PVS); ent->nextthink = level.time + 0.05 + random(); } void SP_misc_electroflash (edict_t *ent) //random electrical pulses { gi.setmodel (ent, NULL); ent->solid = SOLID_NOT; ent->movetype = MOVETYPE_NONE; ent->takedamage = DAMAGE_NO; ent->s.sound = gi.soundindex("world/electricity.wav"); ent->think = misc_electroflash_think; ent->nextthink = level.time + 0.05 + random(); gi.linkentity (ent); } //Team Core Assault void spidervolts (edict_t *self) { vec3_t start; vec3_t end; // int damage = 30; int x; int aim; VectorCopy (self->s.origin, start); VectorCopy (start, end); start[2] = start[2] + 128; for(x = 0; x<20; x++) { if(random() < .5) aim = -1000; else aim = 1000; end[0] = end[0] + random()*aim; if(random() < .5) aim = -1000; else aim = 1000; end[1] = end[1] + random()*aim; if(random() < .5) aim = 0; else aim = 1000; end[2] = end[2] + random()*aim; gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_LIGHTNING); gi.WritePosition (start); gi.WritePosition (end); gi.multicast (start, MULTICAST_PHS); T_RadiusDamage(self, self, 300, NULL, 800, MOD_R_SPLASH, -1); } gi.sound (self, CHAN_AUTO, gi.soundindex("weapons/electroball.wav"), 1, ATTN_NONE, 0); } void misc_spiderpod_think (edict_t *ent) { ent->s.frame = (ent->s.frame + 1) % 13; //fire random bursts of electricicy if(ent->s.frame == 10) if(random() > 0.7) spidervolts(ent); ent->nextthink = level.time + FRAMETIME; } void SP_misc_spiderpod (edict_t *ent) { ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_BBOX; ent->s.modelindex = gi.modelindex ("models/misc/spiderpod/tris.md2"); ent->s.renderfx = (RF_FULLBRIGHT | RF_GLOW | RF_NOSHADOWS); VectorSet (ent->mins, -64, -64, 0); VectorSet (ent->maxs, 64, 64, 128); ent->think = misc_spiderpod_think; ent->nextthink = level.time + FRAMETIME; gi.linkentity (ent); M_droptofloor (ent); } //items for Team Core Assault mode void rednode_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { if(other->dmteam == NO_TEAM || other->movetype == MOVETYPE_FLYMISSILE) return; //do not allow projectiles to turn anything off //if off, and red player, turn on if(!ent->powered && other->client && other->dmteam == RED_TEAM) { ent->powered = true; red_team_score++; if(other->client) other->client->resp.score+=2; //play sound, print message gi.sound (other, CHAN_AUTO, gi.soundindex("misc/redpnenabled.wav"), 1, ATTN_NONE, 0); safe_centerprintf(other, "Red Powernode Enabled!\n"); } //if on, and blue player, turn off if(ent->powered && other->client && other->dmteam == BLUE_TEAM) { ent->powered = false; red_team_score--; if(other->client) other->client->resp.score+=5; if(red_team_score == 1) { gi.sound (other, CHAN_AUTO, gi.soundindex("misc/redvulnerable.wav"), 1, ATTN_NONE, 0); safe_centerprintf(other, "Red Spider Node Vulnerable!"); } else { gi.sound (other, CHAN_AUTO, gi.soundindex("misc/redpndisabled.wav"), 1, ATTN_NONE, 0); safe_centerprintf(other, "Red Powernode Disabled!\n"); } } //if off, and blue player, nothing //if on, and red player, nothing } void rednode_think (edict_t *ent) { vec3_t start, end; if(ent->powered){ VectorCopy(ent->s.origin, start); start[2] -= 24; VectorCopy(ent->s.origin, end); end[2] += 256; //draw a beam into the sky gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_REDLASER); gi.WritePosition (start); gi.WritePosition (end); gi.multicast (start, MULTICAST_PHS); } ent->nextthink = level.time + FRAMETIME; } void SP_misc_rednode (edict_t *ent) { if (!tca->integer) { G_FreeEdict (ent); return; } ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_BBOX; ent->takedamage = DAMAGE_NO; ent->s.modelindex = gi.modelindex ("models/objects/dmspot/tris.md2"); ent->s.renderfx = (RF_FULLBRIGHT | RF_GLOW | RF_NOSHADOWS); VectorSet (ent->mins, -32, -32, -24); VectorSet (ent->maxs, 32, 32, -8); ent->s.frame = 0; ent->powered = true; //start on ent->touch = rednode_touch; ent->think = rednode_think; ent->nextthink = level.time + FRAMETIME; gi.linkentity (ent); M_droptofloor (ent); } void bluenode_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { if(other->dmteam == NO_TEAM || other->movetype == MOVETYPE_FLYMISSILE) return; //do not allow projectiles to turn anything off //if off, and blue player, turn on if(!ent->powered && other->client && other->dmteam == BLUE_TEAM) { ent->powered = true; blue_team_score++; if(other->client) other->client->resp.score+=2; gi.sound (other, CHAN_AUTO, gi.soundindex("misc/bluepnenabled.wav"), 1, ATTN_NONE, 0); safe_centerprintf(other, "Blue Powernode Enabled!\n"); } //if on, and red player, turn off if(ent->powered && other->client && other->dmteam == RED_TEAM) { ent->powered = false; blue_team_score--; if(other->client) other->client->resp.score+=5; if(blue_team_score == 1) { gi.sound (other, CHAN_AUTO, gi.soundindex("misc/bluevulnerable.wav"), 1, ATTN_NONE, 0); safe_centerprintf(other, "Blue Spider Node Vulnerable!\n"); } else { gi.sound (other, CHAN_AUTO, gi.soundindex("misc/bluepndisabled.wav"), 1, ATTN_NONE, 0); safe_centerprintf(other, "Blue Powernode Disabled!\n"); } } } void bluenode_think (edict_t *ent) { vec3_t start, end; if(ent->powered){ VectorCopy(ent->s.origin, start); start[2] -= 24; VectorCopy(ent->s.origin, end); end[2] += 256; //draw a beam into the sky gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BLASTERBEAM); gi.WritePosition (start); gi.WritePosition (end); gi.multicast (start, MULTICAST_PHS); } ent->nextthink = level.time + FRAMETIME; } void SP_misc_bluenode (edict_t *ent) { if (!tca->integer) { G_FreeEdict (ent); return; } ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_BBOX; ent->takedamage = DAMAGE_NO; ent->s.modelindex = gi.modelindex ("models/objects/dmspot/tris.md2"); ent->s.renderfx = (RF_FULLBRIGHT | RF_GLOW | RF_NOSHADOWS); VectorSet (ent->mins, -32, -32, -24); VectorSet (ent->maxs, 32, 32, -8); ent->s.frame = 0; ent->powered = true; //start on gi.linkentity (ent); ent->touch = bluenode_touch; ent->think = bluenode_think; ent->nextthink = level.time + FRAMETIME; M_droptofloor (ent); } void redspidernode_think (edict_t *ent) { //just sits there pulsing if(red_team_score < 2) //now it can take damage ent->takedamage = DAMAGE_YES; else ent->takedamage = DAMAGE_NO; ent->s.frame = (ent->s.frame + 1) % 13; ent->nextthink = level.time + FRAMETIME; } void red_roundend(edict_t *ent) { red_team_score = 0; blue_team_matches++; } void redspidernode_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { self->takedamage = DAMAGE_NO; self->activator = attacker; gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BFG_BIGEXPLOSION); gi.WritePosition (self->s.origin); gi.multicast (self->s.origin, MULTICAST_PHS); if(attacker->dmteam == BLUE_TEAM && attacker->client) attacker->client->resp.score+=50; gi.sound (self, CHAN_AUTO, gi.soundindex("players/martiancyborg/death1.wav"), 1, ATTN_NONE, 0); self->think = red_roundend; self->nextthink = level.time + 2; } void SP_misc_redspidernode (edict_t *ent) { if (!tca->integer) { G_FreeEdict (ent); return; } ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_BBOX; ent->takedamage = DAMAGE_NO; ent->s.modelindex = gi.modelindex ("models/misc/spiderpod/tris.md2"); ent->s.modelindex3 = gi.modelindex ("models/misc/spiderpod/helmet.md2"); ent->s.renderfx = (RF_FULLBRIGHT | RF_GLOW); VectorSet (ent->mins, -64, -64, 0); VectorSet (ent->maxs, 64, 64, 128); ent->health = 600; ent->die = redspidernode_die; ent->think = redspidernode_think; ent->nextthink = level.time + FRAMETIME; gi.linkentity (ent); M_droptofloor (ent); } void bluespidernode_think (edict_t *ent) { //just sits there pulsing if(blue_team_score < 2) //now it can take damage ent->takedamage = DAMAGE_YES; else ent->takedamage = DAMAGE_NO; ent->s.frame = (ent->s.frame + 1) % 13; ent->nextthink = level.time + FRAMETIME; } void blue_roundend(edict_t *self) { blue_team_score = 0; red_team_matches++; } void bluespidernode_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { self->takedamage = DAMAGE_NO; self->activator = attacker; gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BFG_BIGEXPLOSION); gi.WritePosition (self->s.origin); gi.multicast (self->s.origin, MULTICAST_PHS); if(attacker->dmteam == RED_TEAM && attacker->client) attacker->client->resp.score+=50; gi.sound (self, CHAN_AUTO, gi.soundindex("players/martiancyborg/death1.wav"), 1, ATTN_NONE, 0); self->think = blue_roundend; self->nextthink = level.time + 2; } void SP_misc_bluespidernode (edict_t *ent) { if (!tca->integer) { G_FreeEdict (ent); return; } ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_BBOX; ent->takedamage = DAMAGE_NO; ent->s.modelindex = gi.modelindex ("models/misc/spiderpod/tris.md2"); ent->s.modelindex3 = gi.modelindex ("models/misc/spiderpod/helmet.md2"); ent->s.renderfx = (RF_FULLBRIGHT | RF_GLOW); VectorSet (ent->mins, -64, -64, 0); VectorSet (ent->maxs, 64, 64, 128); ent->health = 600; ent->die = bluespidernode_die; ent->think = bluespidernode_think; ent->nextthink = level.time + FRAMETIME; gi.linkentity (ent); M_droptofloor (ent); } //Tactical base items //Rules: When a computer is destroyed, that base's turrents/deathrays will behave eratically, even firing on it's own team on occasion. Laser barriers shut off. //When a powersource is destroyed, the backup generators(if not already destroyed) for the computer and ammo generator turn on(generator models will animate, emit sound). Ammo will generate from depot at half speed. //Laser barriers shut off, turrets and deathrays are weak. //When an ammo depot is destroyed, ammo stops being produced. //When all three are disabled, the other team wins. //lasers void misc_laser_think (edict_t *self) { edict_t *ent; edict_t *ignore; vec3_t start; vec3_t end; trace_t tr; vec3_t point; vec3_t last_movedir; int count; if(self->spawnflags & 1) { if(!tacticalScore.humanComputer || !tacticalScore.humanPowerSource) { self->nextthink = 0; return; } } else if(!tacticalScore.alienComputer || !tacticalScore.alienPowerSource) { self->nextthink = 0; return; } count = 8; if (!self->enemy) { if (self->target) { ent = G_Find (NULL, FOFS(targetname), self->target); if (!ent) gi.dprintf ("%s at %s: %s is a bad target\n", self->classname, vtos(self->s.origin), self->target); self->enemy = ent; } else { G_SetMovedir (self->s.angles, self->movedir); } } else { VectorCopy (self->movedir, last_movedir); VectorMA (self->enemy->absmin, 0.5, self->enemy->size, point); VectorSubtract (point, self->s.origin, self->movedir); VectorNormalize (self->movedir); } ignore = self; VectorCopy (self->s.origin, start); VectorCopy (self->enemy->s.origin, end); while(1) { tr = gi.trace (start, NULL, NULL, end, ignore, CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_DEADMONSTER); gi.WriteByte (svc_temp_entity); if (self->spawnflags & 1) gi.WriteByte (TE_REDLASER); else gi.WriteByte (TE_LASERBEAM); gi.WritePosition (start); gi.WritePosition (end); gi.multicast (start, MULTICAST_PHS); if (!tr.ent) break; //don't hurt anyone on the same team as the laser - spawnflag 1 = human if(self->spawnflags & 1) { if(tr.ent->ctype == 1) break; } else if(!tr.ent->ctype) break; // hurt it if we can if (tr.ent->takedamage) T_Damage (tr.ent, self, self->activator, self->movedir, tr.endpos, vec3_origin, self->dmg, 1, DAMAGE_ENERGY, MOD_TARGET_LASER); // if we hit something that's not a player, we're done if (!tr.ent->client) { break; } ignore = tr.ent; VectorCopy (tr.endpos, start); } VectorCopy (tr.endpos, self->s.old_origin); self->nextthink = level.time + FRAMETIME; } void misc_laser_start (edict_t *self) { self->think = misc_laser_think; } void laser_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { self->takedamage = DAMAGE_NO; self->activator = attacker; gi.WriteByte (svc_temp_entity); if(self->spawnflags & 1) { gi.WriteByte (TE_ROCKET_EXPLOSION); } else { gi.WriteByte (TE_BFG_BIGEXPLOSION); } gi.WritePosition (self->s.origin); gi.multicast (self->s.origin, MULTICAST_PHS); gi.sound( &g_edicts[1], CHAN_AUTO, gi.soundindex( "world/explosion1.wav" ), 1, ATTN_NONE, 0 ); G_FreeEdict (self); } void SP_misc_laser (edict_t *ent) { if (!g_tactical->integer) { G_FreeEdict (ent); return; } ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_BBOX; ent->takedamage = DAMAGE_YES; ent->health = 1000; ent->die = laser_die; ent->dmg = 500; //cause severe damage, especially if multiples(most cases) if(ent->spawnflags & 1) ent->s.modelindex = gi.modelindex ("models/tactical/human_laser.iqm"); else ent->s.modelindex = gi.modelindex ("models/tactical/alien_laser.iqm"); VectorSet (ent->mins, -16, -16, -16); VectorSet (ent->maxs, 16, 16, 16); // let everything else get spawned before we start firing ent->think = misc_laser_think; ent->nextthink = level.time + 1; gi.linkentity (ent); } //computers void computer_think (edict_t *ent) { if(ent->classname == "alien computer") tacticalScore.alienComputerHealth = ent->health/15; else tacticalScore.humanComputerHealth = ent->health/15; ent->s.frame = (ent->s.frame + 1) % 24; ent->nextthink = level.time + FRAMETIME; } void computer_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { edict_t *cl_ent; int i; self->takedamage = DAMAGE_NO; self->activator = attacker; gi.WriteByte (svc_temp_entity); if(self->classname == "alien computer") { tacticalScore.alienComputer = false; tacticalScore.alienComputerHealth = 0; gi.WriteByte (TE_BFG_BIGEXPLOSION); } else { tacticalScore.humanComputer = false; tacticalScore.humanComputerHealth = 0; gi.WriteByte (TE_ROCKET_EXPLOSION); } gi.WritePosition (self->s.origin); gi.multicast (self->s.origin, MULTICAST_PHS); if(self->classname == "alien computer") { for (i=0 ; ivalue ; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || cl_ent->is_bot) continue; safe_centerprintf(cl_ent, "Alien Central Computer has been destroyed!"); } } else { for (i=0 ; ivalue ; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || cl_ent->is_bot) continue; safe_centerprintf(cl_ent, "Human Central Computer has been destroyed!"); } } gi.sound( &g_edicts[1], CHAN_AUTO, gi.soundindex( "world/explosion1.wav" ), 1, ATTN_NONE, 0 ); G_FreeEdict (self); } void SP_misc_aliencomputer (edict_t *ent) { if (!g_tactical->integer) { G_FreeEdict (ent); return; } ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_BBOX; ent->takedamage = DAMAGE_YES; ent->s.modelindex = gi.modelindex ("models/tactical/alien_computer.iqm"); VectorSet (ent->mins, -64, -64, 0); VectorSet (ent->maxs, 64, 64, 64); ent->health = 1500; ent->die = computer_die; ent->think = computer_think; ent->nextthink = level.time + FRAMETIME; ent->classname = "alien computer"; gi.linkentity (ent); M_droptofloor (ent); } void SP_misc_humancomputer (edict_t *ent) { if (!g_tactical->integer) { G_FreeEdict (ent); return; } ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_BBOX; ent->takedamage = DAMAGE_YES; ent->s.modelindex = gi.modelindex ("models/tactical/human_computer.iqm"); VectorSet (ent->mins, -64, -64, 0); VectorSet (ent->maxs, 64, 64, 64); ent->health = 1500; ent->die = computer_die; ent->think = computer_think; ent->nextthink = level.time + FRAMETIME; ent->classname = "human computer"; gi.linkentity (ent); M_droptofloor (ent); } //power sources void powersrc_think (edict_t *ent) { if(ent->classname == "alien powersrc") tacticalScore.alienPowerSourceHealth = ent->health/15; else tacticalScore.humanPowerSourceHealth = ent->health/15; ent->s.frame = (ent->s.frame + 1) % 24; ent->nextthink = level.time + FRAMETIME; } void powersrc_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { edict_t *cl_ent; int i; self->takedamage = DAMAGE_NO; self->activator = attacker; gi.WriteByte (svc_temp_entity); if(self->classname == "alien powersrc") { tacticalScore.alienPowerSource = false; tacticalScore.alienPowerSourceHealth = 0; gi.WriteByte (TE_BFG_BIGEXPLOSION); } else { tacticalScore.humanPowerSource = false; tacticalScore.humanPowerSourceHealth = 0; gi.WriteByte (TE_ROCKET_EXPLOSION); } gi.WritePosition (self->s.origin); gi.multicast (self->s.origin, MULTICAST_PHS); if(self->classname == "alien powersrc") { for (i=0 ; ivalue ; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || cl_ent->is_bot) continue; safe_centerprintf(cl_ent, "Alien Power Source has been destroyed!"); } } else { for (i=0 ; ivalue ; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || cl_ent->is_bot) continue; safe_centerprintf(cl_ent, "Human Power Source has been destroyed!"); } } gi.sound( &g_edicts[1], CHAN_AUTO, gi.soundindex( "world/explosion1.wav" ), 1, ATTN_NONE, 0 ); G_FreeEdict (self); } void SP_misc_alienpowersrc (edict_t *ent) { if (!g_tactical->integer) { G_FreeEdict (ent); return; } ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_BBOX; ent->takedamage = DAMAGE_YES; ent->s.modelindex = gi.modelindex ("models/tactical/alien_powersrc.iqm"); VectorSet (ent->mins, -64, -64, 0); VectorSet (ent->maxs, 64, 64, 72); ent->health = 1500; ent->die = powersrc_die; ent->think = powersrc_think; ent->nextthink = level.time + FRAMETIME; ent->classname = "alien powersrc"; gi.linkentity (ent); M_droptofloor (ent); } void SP_misc_humanpowersrc (edict_t *ent) { if (!g_tactical->integer) { G_FreeEdict (ent); return; } ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_BBOX; ent->takedamage = DAMAGE_YES; ent->s.modelindex = gi.modelindex ("models/tactical/human_powersrc.iqm"); VectorSet (ent->mins, -32, -32, 0); VectorSet (ent->maxs, 32, 32, 72); ent->health = 1500; ent->die = powersrc_die; ent->think = powersrc_think; ent->nextthink = level.time + FRAMETIME; ent->classname = "human powersrc"; gi.linkentity (ent); M_droptofloor (ent); } //ammo depots void ammodepot_think (edict_t *ent) { if(ent->classname == "alien ammodepot") tacticalScore.alienAmmoDepotHealth = ent->health/15; else tacticalScore.humanAmmoDepotHealth = ent->health/15; ent->nextthink = level.time + FRAMETIME; } void ammodepot_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { edict_t *cl_ent; int i; self->takedamage = DAMAGE_NO; self->activator = attacker; gi.WriteByte (svc_temp_entity); if(self->classname == "alien ammodepot") { tacticalScore.alienAmmoDepot = false; tacticalScore.alienAmmoDepotHealth = 0; gi.WriteByte (TE_BFG_BIGEXPLOSION); } else { tacticalScore.humanAmmoDepot = false; tacticalScore.humanAmmoDepotHealth = 0; gi.WriteByte (TE_ROCKET_EXPLOSION); } gi.WritePosition (self->s.origin); gi.multicast (self->s.origin, MULTICAST_PHS); if(self->classname == "alien ammodepot") { for (i=0 ; ivalue ; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || cl_ent->is_bot) continue; safe_centerprintf(cl_ent, "Alien Ammo Depot has been destroyed!"); } } else { for (i=0 ; ivalue ; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || cl_ent->is_bot) continue; safe_centerprintf(cl_ent, "Human Ammo Depot has been destroyed!"); } } gi.sound( &g_edicts[1], CHAN_AUTO, gi.soundindex( "world/explosion1.wav" ), 1, ATTN_NONE, 0 ); G_FreeEdict (self); } void SP_misc_alienammodepot (edict_t *ent) { if (!g_tactical->integer) { G_FreeEdict (ent); return; } ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_BBOX; ent->takedamage = DAMAGE_YES; ent->s.modelindex = gi.modelindex ("models/tactical/ammopad.md2"); VectorSet (ent->mins, -32, -32, 0); VectorSet (ent->maxs, 32, 32, 16); ent->health = 1500; ent->die = ammodepot_die; ent->think = ammodepot_think; ent->nextthink = level.time + FRAMETIME; ent->classname = "alien ammodepot"; gi.linkentity (ent); M_droptofloor (ent); } void SP_misc_humanammodepot (edict_t *ent) { if (!g_tactical->integer) { G_FreeEdict (ent); return; } ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_BBOX; ent->takedamage = DAMAGE_YES; ent->s.modelindex = gi.modelindex ("maps/meshes/flagpad.md2"); VectorSet (ent->mins, -32, -32, 0); VectorSet (ent->maxs, 32, 32, 16); ent->health = 1500; ent->die = ammodepot_die; ent->think = ammodepot_think; ent->nextthink = level.time + FRAMETIME; ent->classname = "human ammodepot"; gi.linkentity (ent); M_droptofloor (ent); } //Backup generators void backupgen_think (edict_t *ent) { if(ent->classname == "alien backupgen") { if(!tacticalScore.alienPowerSource) { //animate ent->s.frame = (ent->s.frame + 1) % 24; gi.sound (ent, CHAN_AUTO, gi.soundindex("misc/reject.wav"), 1, ATTN_STATIC, 0); } } else { if(!tacticalScore.humanPowerSource) { ent->s.frame = (ent->s.frame + 1) % 24; gi.sound (ent, CHAN_AUTO, gi.soundindex("misc/reject.wav"), 1, ATTN_STATIC, 0); } } ent->nextthink = level.time + FRAMETIME; } void backupgen_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { edict_t *cl_ent; int i; self->takedamage = DAMAGE_NO; self->activator = attacker; gi.WriteByte (svc_temp_entity); if(self->classname == "alien backupgen") { tacticalScore.alienBackupGen = false; gi.WriteByte (TE_BFG_BIGEXPLOSION); } else { tacticalScore.humanBackupGen = false; gi.WriteByte (TE_ROCKET_EXPLOSION); } gi.WritePosition (self->s.origin); gi.multicast (self->s.origin, MULTICAST_PHS); if(self->classname == "alien backupgen") { for (i=0 ; ivalue ; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || cl_ent->is_bot) continue; safe_centerprintf(cl_ent, "Alien Backup Generator has been destroyed!"); } } else { for (i=0 ; ivalue ; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || cl_ent->is_bot) continue; safe_centerprintf(cl_ent, "Human Backup Generator has been destroyed!"); } } gi.sound( &g_edicts[1], CHAN_AUTO, gi.soundindex( "world/explosion1.wav" ), 1, ATTN_NONE, 0 ); G_FreeEdict (self); } void SP_misc_alienbackupgen (edict_t *ent) { if (!g_tactical->integer) { G_FreeEdict (ent); return; } ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_BBOX; ent->takedamage = DAMAGE_YES; ent->s.modelindex = gi.modelindex ("models/tactical/alien_backupgen.iqm"); VectorSet (ent->mins, -24, -24, 0); VectorSet (ent->maxs, 24, 24, 48); ent->health = 300; ent->die = backupgen_die; ent->think = backupgen_think; ent->nextthink = level.time + FRAMETIME; ent->classname = "alien backupgen"; gi.linkentity (ent); M_droptofloor (ent); } void SP_misc_humanbackupgen (edict_t *ent) { if (!g_tactical->integer) { G_FreeEdict (ent); return; } ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_BBOX; ent->takedamage = DAMAGE_YES; ent->s.modelindex = gi.modelindex ("models/tactical/human_backupgen.iqm"); VectorSet (ent->mins, -24, -24, 0); VectorSet (ent->maxs, 24, 24, 48); ent->health = 300; ent->die = backupgen_die; ent->think = backupgen_think; ent->nextthink = level.time + FRAMETIME; ent->classname = "human backupgen"; gi.linkentity (ent); M_droptofloor (ent); } alien-arena-7.66+dfsg/source/game/g_phys.c0000600000175000017500000005407712161402010017465 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // g_phys.c #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" /* pushmove objects do not obey gravity, and do not interact with each other or trigger fields, but block normal movement and push normal objects when they move. onground is set for toss objects when they come to a complete rest. it is set for steping or walking objects doors, plats, etc are SOLID_BSP, and MOVETYPE_PUSH bonus items are SOLID_TRIGGER touch, and MOVETYPE_TOSS corpses are SOLID_NOT and MOVETYPE_TOSS crates are SOLID_BBOX and MOVETYPE_TOSS walking monsters are SOLID_SLIDEBOX and MOVETYPE_STEP flying/floating monsters are SOLID_SLIDEBOX and MOVETYPE_FLY solid_edge items only clip against bsp models. */ /* ============ SV_TestEntityPosition ============ */ edict_t *SV_TestEntityPosition (edict_t *ent) { trace_t trace; int mask; if (ent->clipmask) mask = ent->clipmask; else mask = MASK_SOLID; trace = gi.trace (ent->s.origin, ent->mins, ent->maxs, ent->s.origin, ent, mask); if (trace.startsolid) return g_edicts; return NULL; } /* ================ SV_CheckVelocity ================ */ void SV_CheckVelocity (edict_t *ent) { int i; // // bound velocity // for (i=0 ; i<3 ; i++) { if (ent->velocity[i] > sv_maxvelocity->value) ent->velocity[i] = sv_maxvelocity->value; else if (ent->velocity[i] < -sv_maxvelocity->value) ent->velocity[i] = -sv_maxvelocity->value; } } /* ============= SV_RunThink Runs thinking code for this frame if necessary ============= */ qboolean SV_RunThink (edict_t *ent) { float thinktime; if(!strcmp(ent->classname, "func_train")) { //if animated mesh, animate at this target if (ent->spawnflags & 32) ent->s.frame = (ent->s.frame + 1)%24; } thinktime = ent->nextthink; if (thinktime <= 0) return true; if (thinktime > level.time+0.001) return true; ent->nextthink = 0; if (!ent->think) gi.error ("NULL ent->think"); ent->think (ent); return false; } /* ================== SV_Impact Two entities have touched, so run their touch functions ================== */ void SV_Impact (edict_t *e1, trace_t *trace) { edict_t *e2; // cplane_t backplane; e2 = trace->ent; if (e1->touch && e1->solid != SOLID_NOT) e1->touch (e1, e2, &trace->plane, trace->surface); if (e2->touch && e2->solid != SOLID_NOT) e2->touch (e2, e1, NULL, NULL); } /* ================== ClipVelocity Slide off of the impacting object returns the blocked flags (1 = floor, 2 = step / wall) ================== */ #define STOP_EPSILON 0.1 int ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce) { float backoff; float change; int i, blocked; blocked = 0; if (normal[2] > 0) blocked |= 1; // floor if (!normal[2]) blocked |= 2; // step backoff = DotProduct (in, normal) * overbounce; for (i=0 ; i<3 ; i++) { change = normal[i]*backoff; out[i] = in[i] - change; if (out[i] > -STOP_EPSILON && out[i] < STOP_EPSILON) out[i] = 0; } return blocked; } /* ============ SV_FlyMove The basic solid body movement clip that slides along multiple planes Returns the clipflags if the velocity was modified (hit something solid) 1 = floor 2 = wall / step 4 = dead stop ============ */ #define MAX_CLIP_PLANES 5 int SV_FlyMove (edict_t *ent, float timespan, int mask) { edict_t *hit; int bumpcount, numbumps; vec3_t dir; float d; int numplanes; vec3_t planes[MAX_CLIP_PLANES]; vec3_t primal_velocity, original_velocity, new_velocity; int i, j; trace_t trace; vec3_t end; float time_left; int blocked; numbumps = 4; blocked = 0; VectorCopy (ent->velocity, original_velocity); VectorCopy (ent->velocity, primal_velocity); numplanes = 0; time_left = timespan; ent->groundentity = NULL; for (bumpcount=0 ; bumpcounts.origin[i] + time_left * ent->velocity[i]; trace = gi.trace (ent->s.origin, ent->mins, ent->maxs, end, ent, mask); if (trace.allsolid) { // entity is trapped in another solid VectorCopy (vec3_origin, ent->velocity); return 3; } if (trace.fraction > 0) { // actually covered some distance VectorCopy (trace.endpos, ent->s.origin); VectorCopy (ent->velocity, original_velocity); numplanes = 0; } if (trace.fraction == 1) break; // moved the entire distance hit = trace.ent; if (trace.plane.normal[2] > 0.7) { blocked |= 1; // floor if ( hit->solid == SOLID_BSP) { ent->groundentity = hit; ent->groundentity_linkcount = hit->linkcount; } } if (!trace.plane.normal[2]) { blocked |= 2; // step } // // run the impact function // SV_Impact (ent, &trace); if (!ent->inuse) break; // removed by the impact function time_left -= time_left * trace.fraction; // cliped to another plane if (numplanes >= MAX_CLIP_PLANES) { // this shouldn't really happen VectorCopy (vec3_origin, ent->velocity); return 3; } VectorCopy (trace.plane.normal, planes[numplanes]); numplanes++; // // modify original_velocity so it parallels all of the clip planes // for (i=0 ; ivelocity); } else { // go along the crease if (numplanes != 2) { // gi.dprintf ("clip velocity, numplanes == %i\n",numplanes); VectorCopy (vec3_origin, ent->velocity); return 7; } CrossProduct (planes[0], planes[1], dir); d = DotProduct (dir, ent->velocity); VectorScale (dir, d, ent->velocity); } // // if original velocity is against the original velocity, stop dead // to avoid tiny occilations in sloping corners // if (DotProduct (ent->velocity, primal_velocity) <= 0) { VectorCopy (vec3_origin, ent->velocity); return blocked; } } return blocked; } /* ============ SV_AddGravity ============ */ void SV_AddGravity (edict_t *ent, float timespan) { ent->velocity[2] -= ent->gravity * sv_gravity->value * timespan; } /* =============================================================================== PUSHMOVE =============================================================================== */ /* ============ SV_PushEntity Does not change the entities velocity at all ============ */ trace_t SV_PushEntity (edict_t *ent, vec3_t push) { trace_t trace; vec3_t start; vec3_t end; int mask; VectorCopy (ent->s.origin, start); VectorAdd (start, push, end); retry: if (ent->clipmask) mask = ent->clipmask; else mask = MASK_SOLID; trace = gi.trace (start, ent->mins, ent->maxs, end, ent, mask); if (trace.startsolid || trace.allsolid) { mask ^= CONTENTS_DEADMONSTER; trace = gi.trace (start, ent->mins, ent->maxs, end, ent, mask); } VectorCopy (trace.endpos, ent->s.origin); gi.linkentity (ent); if (trace.fraction != 1.0) { SV_Impact (ent, &trace); // if the pushed entity went away and the pusher is still there if (!trace.ent->inuse && ent->inuse) { // move the pusher back and try again VectorCopy (start, ent->s.origin); gi.linkentity (ent); goto retry; } } if (ent->inuse) G_TouchTriggers (ent); return trace; } typedef struct { edict_t *ent; vec3_t origin; vec3_t angles; float deltayaw; } pushed_t; pushed_t pushed[MAX_EDICTS], *pushed_p; edict_t *obstacle; /* ============ SV_Push Objects need to be moved back on a failed push, otherwise riders would continue to slide. ============ */ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove) { int i, e; edict_t *check, *block; vec3_t mins, maxs; pushed_t *p; vec3_t org, org2, move2, forward, right, up; // clamp the move to 1/8 units, so the position will // be accurate for client side prediction for (i=0 ; i<3 ; i++) { float temp; temp = move[i]*8.0; if (temp > 0.0) temp += 0.5; else temp -= 0.5; move[i] = 0.125 * (int)temp; } // find the bounding box for (i=0 ; i<3 ; i++) { mins[i] = pusher->absmin[i] + move[i]; maxs[i] = pusher->absmax[i] + move[i]; } // we need this for pushing things later VectorSubtract (vec3_origin, amove, org); AngleVectors (org, forward, right, up); // save the pusher's original position pushed_p->ent = pusher; VectorCopy (pusher->s.origin, pushed_p->origin); VectorCopy (pusher->s.angles, pushed_p->angles); if (pusher->client) pushed_p->deltayaw = pusher->client->ps.pmove.delta_angles[YAW]; pushed_p++; // move the pusher to it's final position VectorAdd (pusher->s.origin, move, pusher->s.origin); VectorAdd (pusher->s.angles, amove, pusher->s.angles); gi.linkentity (pusher); // see if any solid entities are inside the final position check = g_edicts+1; for (e = 1; e < globals.num_edicts; e++, check++) { if (!check->inuse) continue; if (check->movetype == MOVETYPE_PUSH || check->movetype == MOVETYPE_STOP || check->movetype == MOVETYPE_NONE || check->movetype == MOVETYPE_NOCLIP) continue; if (!check->area.prev) continue; // not linked in anywhere // if the entity is standing on the pusher, it will definitely be moved if (check->groundentity != pusher) { // see if the ent needs to be tested if ( check->absmin[0] >= maxs[0] || check->absmin[1] >= maxs[1] || check->absmin[2] >= maxs[2] || check->absmax[0] <= mins[0] || check->absmax[1] <= mins[1] || check->absmax[2] <= mins[2] ) continue; // see if the ent's bbox is inside the pusher's final position if (!SV_TestEntityPosition (check)) continue; } if ((pusher->movetype == MOVETYPE_PUSH) || (check->groundentity == pusher)) { // move this entity pushed_p->ent = check; VectorCopy (check->s.origin, pushed_p->origin); VectorCopy (check->s.angles, pushed_p->angles); pushed_p++; // try moving the contacted entity VectorAdd (check->s.origin, move, check->s.origin); if (check->client) { // FIXME: doesn't rotate monsters? check->client->ps.pmove.delta_angles[YAW] += amove[YAW]; } // figure movement due to the pusher's amove VectorSubtract (check->s.origin, pusher->s.origin, org); org2[0] = DotProduct (org, forward); org2[1] = -DotProduct (org, right); org2[2] = DotProduct (org, up); VectorSubtract (org2, org, move2); VectorAdd (check->s.origin, move2, check->s.origin); // may have pushed them off an edge if (check->groundentity != pusher) check->groundentity = NULL; block = SV_TestEntityPosition (check); if (!block) { // pushed ok gi.linkentity (check); // impact? continue; } // if it is ok to leave in the old position, do it // this is only relevent for riding entities, not pushed // FIXME: this doesn't acount for rotation VectorSubtract (check->s.origin, move, check->s.origin); block = SV_TestEntityPosition (check); if (!block) { pushed_p--; continue; } } // save off the obstacle so we can call the block function obstacle = check; // move back any entities we already moved // go backwards, so if the same entity was pushed // twice, it goes back to the original position for (p=pushed_p-1 ; p>=pushed ; p--) { VectorCopy (p->origin, p->ent->s.origin); VectorCopy (p->angles, p->ent->s.angles); if (p->ent->client) { p->ent->client->ps.pmove.delta_angles[YAW] = p->deltayaw; } gi.linkentity (p->ent); } return false; } //FIXME: is there a better way to handle this? // see if anything we moved has touched a trigger for (p=pushed_p-1 ; p>=pushed ; p--) G_TouchTriggers (p->ent); return true; } /* ================ SV_Physics_Pusher Bmodel objects don't interact with each other, but push all box objects ================ */ void SV_Physics_Pusher (edict_t *ent, float timespan) { vec3_t move, amove; edict_t *part, *mv; // if not a team captain, so movement will be handled elsewhere if ( ent->flags & FL_TEAMSLAVE) return; // make sure all team slaves can move before commiting // any moves or calling any think functions // if the move is blocked, all moved objects will be backed out //retry: pushed_p = pushed; for (part = ent ; part ; part=part->teamchain) { if (part->velocity[0] || part->velocity[1] || part->velocity[2] || part->avelocity[0] || part->avelocity[1] || part->avelocity[2] ) { // object is moving VectorScale (part->velocity, timespan, move); VectorScale (part->avelocity, timespan, amove); if (!SV_Push (part, move, amove)) break; // move was blocked } } if (pushed_p > &pushed[MAX_EDICTS]) gi.error (ERR_FATAL, "pushed_p > &pushed[MAX_EDICTS], memory corrupted"); if (part) { // the move failed, bump all nextthink times and back out moves for (mv = ent ; mv ; mv=mv->teamchain) { if (mv->nextthink > 0) mv->nextthink += timespan; } // if the pusher has a "blocked" function, call it // otherwise, just stay in place until the obstacle is gone if (part->blocked) part->blocked (part, obstacle); #if 0 // if the pushed entity went away and the pusher is still there if (!obstacle->inuse && part->inuse) goto retry; #endif } else { // the move succeeded, so call all think functions for (part = ent ; part ; part=part->teamchain) { SV_RunThink (part); } } } //================================================================== /* ============= SV_Physics_None Non moving objects can only think ============= */ void SV_Physics_None (edict_t *ent) { // regular thinking SV_RunThink (ent); } /* ============= SV_Physics_Noclip A moving object that doesn't obey physics ============= */ void SV_Physics_Noclip (edict_t *ent, float timespan) { // regular thinking if (!SV_RunThink (ent)) return; VectorMA (ent->s.angles, timespan, ent->avelocity, ent->s.angles); VectorMA (ent->s.origin, timespan, ent->velocity, ent->s.origin); gi.linkentity (ent); } /* ============================================================================== TOSS / BOUNCE ============================================================================== */ /* ============= SV_Physics_Toss Toss, bounce, and fly movement. When onground, do nothing. ============= */ void SV_Physics_Toss (edict_t *ent, float timespan) { trace_t trace; vec3_t move; float backoff; edict_t *slave; qboolean wasinwater; qboolean isinwater; vec3_t old_origin; // regular thinking SV_RunThink (ent); // if not a team captain, so movement will be handled elsewhere if ( ent->flags & FL_TEAMSLAVE) return; if (ent->velocity[2] > 0) ent->groundentity = NULL; // check for the groundentity going away if (ent->groundentity) if (!ent->groundentity->inuse) ent->groundentity = NULL; // if onground, return without moving if ( ent->groundentity ) return; VectorCopy (ent->s.origin, old_origin); SV_CheckVelocity (ent); // add gravity if (ent->movetype != MOVETYPE_FLY && ent->movetype != MOVETYPE_FLYMISSILE) SV_AddGravity (ent, timespan); // move angles VectorMA (ent->s.angles, timespan, ent->avelocity, ent->s.angles); // move origin VectorScale (ent->velocity, timespan, move); trace = SV_PushEntity (ent, move); if (!ent->inuse) return; if (trace.fraction < 1) { if (ent->movetype == MOVETYPE_BOUNCE) backoff = 1.5; else backoff = 1; ClipVelocity (ent->velocity, trace.plane.normal, ent->velocity, backoff); // stop if on ground if (trace.plane.normal[2] > 0.7) { if (ent->velocity[2] < 60 || ent->movetype != MOVETYPE_BOUNCE ) { ent->groundentity = trace.ent; ent->groundentity_linkcount = trace.ent->linkcount; VectorCopy (vec3_origin, ent->velocity); VectorCopy (vec3_origin, ent->avelocity); } } // if (ent->touch) // ent->touch (ent, trace.ent, &trace.plane, trace.surface); } // check for water transition wasinwater = (ent->watertype & MASK_WATER); ent->watertype = gi.pointcontents (ent->s.origin); isinwater = ent->watertype & MASK_WATER; if (isinwater) ent->waterlevel = 1; else ent->waterlevel = 0; // move teamslaves for (slave = ent->teamchain; slave; slave = slave->teamchain) { VectorCopy (ent->s.origin, slave->s.origin); gi.linkentity (slave); } } /* =============================================================================== STEPPING MOVEMENT =============================================================================== */ /* ============= SV_Physics_Step Monsters freefall when they don't have a ground entity, otherwise all movement is done with discrete steps. This is also used for objects that have become still on the ground, but will fall if the floor is pulled out from under them. FIXME: is this true? ============= */ //FIXME: hacked in for E3 demo #define sv_stopspeed 100 #define sv_friction 6 #define sv_waterfriction 1 void SV_AddRotationalFriction (edict_t *ent, float timespan) { int n; float adjustment; VectorMA (ent->s.angles, timespan, ent->avelocity, ent->s.angles); adjustment = timespan * sv_stopspeed * sv_friction; for (n = 0; n < 3; n++) { if (ent->avelocity[n] > 0) { ent->avelocity[n] -= adjustment; if (ent->avelocity[n] < 0) ent->avelocity[n] = 0; } else { ent->avelocity[n] += adjustment; if (ent->avelocity[n] > 0) ent->avelocity[n] = 0; } } } void SV_Physics_Step (edict_t *ent, float timespan) { qboolean wasonground; qboolean hitsound = false; float *vel; float speed, newspeed, control; float friction; edict_t *groundentity; int mask; // airborn monsters should always check for ground if (!ent->groundentity) M_CheckGround (ent); groundentity = ent->groundentity; SV_CheckVelocity (ent); if (groundentity) wasonground = true; else wasonground = false; if (ent->avelocity[0] || ent->avelocity[1] || ent->avelocity[2]) SV_AddRotationalFriction (ent, timespan); // add gravity except: // flying monsters // swimming monsters who are in the water if (! wasonground) if (!(ent->flags & FL_FLY)) if (!((ent->flags & FL_SWIM) && (ent->waterlevel > 2))) { if (ent->velocity[2] < sv_gravity->value*-0.1) hitsound = true; if (ent->waterlevel == 0) SV_AddGravity (ent, timespan); } // friction for flying monsters that have been given vertical velocity if ((ent->flags & FL_FLY) && (ent->velocity[2] != 0)) { speed = fabs(ent->velocity[2]); control = speed < sv_stopspeed ? sv_stopspeed : speed; friction = sv_friction/3; newspeed = speed - (timespan * control * friction); if (newspeed < 0) newspeed = 0; newspeed /= speed; ent->velocity[2] *= newspeed; } // friction for flying monsters that have been given vertical velocity if ((ent->flags & FL_SWIM) && (ent->velocity[2] != 0)) { speed = fabs(ent->velocity[2]); control = speed < sv_stopspeed ? sv_stopspeed : speed; newspeed = speed - (timespan * control * sv_waterfriction * ent->waterlevel); if (newspeed < 0) newspeed = 0; newspeed /= speed; ent->velocity[2] *= newspeed; } if (ent->velocity[2] || ent->velocity[1] || ent->velocity[0]) { // apply friction // let dead monsters who aren't completely onground slide if ((wasonground) || (ent->flags & (FL_SWIM|FL_FLY))) if (!(ent->health <= 0.0 && !M_CheckBottom(ent))) { vel = ent->velocity; speed = sqrt(vel[0]*vel[0] +vel[1]*vel[1]); if (speed) { friction = sv_friction; control = speed < sv_stopspeed ? sv_stopspeed : speed; newspeed = speed - timespan*control*friction; if (newspeed < 0) newspeed = 0; newspeed /= speed; vel[0] *= newspeed; vel[1] *= newspeed; } } if (ent->svflags & SVF_MONSTER) mask = MASK_MONSTERSOLID; else mask = MASK_SOLID; SV_FlyMove (ent, timespan, mask); gi.linkentity (ent); G_TouchTriggers (ent); if (!ent->inuse) return; } // regular thinking SV_RunThink (ent); } //============================================================================ /* ================ G_RunEntity ================ */ void G_RunEntity (edict_t *ent, float timespan) { if (ent->prethink) ent->prethink (ent); switch ( (int)ent->movetype) { // ACEBOT_ADD case MOVETYPE_WALK: SV_RunThink (ent); break; // ACEBOT_END case MOVETYPE_PUSH: case MOVETYPE_STOP: SV_Physics_Pusher (ent, timespan); break; case MOVETYPE_NONE: SV_Physics_None (ent); break; case MOVETYPE_NOCLIP: SV_Physics_Noclip (ent, timespan); break; case MOVETYPE_STEP: SV_Physics_Step (ent, timespan); break; case MOVETYPE_TOSS: case MOVETYPE_BOUNCE: case MOVETYPE_FLY: case MOVETYPE_FLYMISSILE: SV_Physics_Toss (ent, timespan); break; default: gi.error ("SV_Physics: bad movetype %i", (int)ent->movetype); } } alien-arena-7.66+dfsg/source/game/g_svcmds.c0000600000175000017500000001733512161402010017775 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" void Svcmd_Test_f (void) { safe_cprintf (NULL, PRINT_HIGH, "Svcmd_Test_f()\n"); } /* ============================================================================== PACKET FILTERING You can add or remove addresses from the filter list with: addip removeip The ip address is specified in dot format, and any unspecified digits will match any value, so you can specify an entire class C network with "addip 192.246.40". Removeip will only remove an address specified exactly the same way. You cannot addip a subnet, then removeip a single host. listip Prints the current list of filters. writeip Dumps "addip " commands to listip.cfg so it can be execed at a later date. The filter lists are not saved and restored by default, because I beleive it would cause too much confusion. filterban <0 or 1> If 1 (the default), then ip addresses matching the current list will be prohibited from entering the game. This is the default setting. If 0, then only addresses matching the list will be allowed. This lets you easily set up a private game, or a game that only allows players from your local network. ============================================================================== */ /* ================= StringToFilter ================= */ qboolean StringToFilter (char *s, ipfilter_t *f) { char num[128]; int i, j; byte b[4]; byte m[4]; for (i=0 ; i<4 ; i++) { b[i] = 0; m[i] = 0; } for (i=0 ; i<4 ; i++) { if (*s < '0' || *s > '9') { safe_cprintf(NULL, PRINT_HIGH, "Bad filter address: %s\n", s); return false; } j = 0; while (*s >= '0' && *s <= '9') { num[j++] = *s++; } num[j] = 0; b[i] = atoi(num); if (b[i] != 0) m[i] = 255; if (!*s) break; s++; } f->mask = *(unsigned *)m; f->compare = *(unsigned *)b; return true; } /* ================= SV_FilterPacket ================= */ qboolean SV_FilterPacket (char *from) { int i; unsigned in; byte m[4]; char *p; i = 0; p = from; while (*p && i < 4) { m[i] = 0; while (*p >= '0' && *p <= '9') { m[i] = m[i]*10 + (*p - '0'); p++; } if (!*p || *p == ':') break; i++, p++; } in = *(unsigned *)m; for (i=0 ; iinteger; return !filterban->integer; } /* ================= SV_AddIP_f ================= */ void SVCmd_AddIP_f (void) { int i; if (gi.argc() < 3) { safe_cprintf(NULL, PRINT_HIGH, "Usage: addip \n"); return; } for (i=0 ; i\n"); return; } if (!StringToFilter (gi.argv(2), &f)) return; for (i=0 ; istring) sprintf (name, "%s/listip.cfg", GAMEVERSION); else sprintf (name, "%s/listip.cfg", game->string); safe_cprintf (NULL, PRINT_HIGH, "Writing %s.\n", name); f = fopen (name, "wb"); if (!f) { safe_cprintf (NULL, PRINT_HIGH, "Couldn't open %s\n", name); return; } fprintf(f, "set filterban %d\n", filterban->integer); for (i=0 ; iinteger & DF_BOTS ) { safe_cprintf( NULL, PRINT_HIGH, "Bots disabled in dmflags, sv addbot disabled.\n"); } else if ( (sv_botkickthreshold && sv_botkickthreshold->integer) || (g_duel && g_duel-> integer) ) { // duel mode forces bot kick threshold safe_cprintf( NULL, PRINT_HIGH, "Auto bot kick enabled, sv addbot disabled.\n"); } else { // can become a team bot with assigned skin color Q_strncpyz2( botname, gi.argv(2), sizeof(botname) ); ValidatePlayerName( botname, sizeof(botname) ); ACESP_SpawnBot( botname, gi.argv(3), NULL ); } } // removebot else if(Q_strcasecmp (cmd, "removebot") == 0) { if ( dmflags->integer & DF_BOTS ) { safe_cprintf( NULL, PRINT_HIGH, "Bots disabled in dmflags, sv removebot disabled.\n"); } else if ( (sv_botkickthreshold && sv_botkickthreshold->integer) || ( g_duel && g_duel->integer ) ) { // duel mode forces bot kick threshold safe_cprintf( NULL, PRINT_HIGH, "Auto bot kick enabled, sv removebot disabled.\n"); } else { ACESP_RemoveBot(gi.argv(2)); } } // Node saving else if(Q_strcasecmp (cmd, "savenodes") == 0) ACEND_SaveNodes(); // ACEBOT_END else safe_cprintf (NULL, PRINT_HIGH, "Unknown server command \"%s\"\n", cmd); } alien-arena-7.66+dfsg/source/game/m_player.h0000600000175000017500000002274312161402010020004 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // G:\quake2\baseq2\models/player_x/frames // This file generated by qdata - Do NOT Modify #define FRAME_stand01 0 #define FRAME_stand02 1 #define FRAME_stand03 2 #define FRAME_stand04 3 #define FRAME_stand05 4 #define FRAME_stand06 5 #define FRAME_stand07 6 #define FRAME_stand08 7 #define FRAME_stand09 8 #define FRAME_stand10 9 #define FRAME_stand11 10 #define FRAME_stand12 11 #define FRAME_stand13 12 #define FRAME_stand14 13 #define FRAME_stand15 14 #define FRAME_stand16 15 #define FRAME_stand17 16 #define FRAME_stand18 17 #define FRAME_stand19 18 #define FRAME_stand20 19 #define FRAME_stand21 20 #define FRAME_stand22 21 #define FRAME_stand23 22 #define FRAME_stand24 23 #define FRAME_stand25 24 #define FRAME_stand26 25 #define FRAME_stand27 26 #define FRAME_stand28 27 #define FRAME_stand29 28 #define FRAME_stand30 29 #define FRAME_stand31 30 #define FRAME_stand32 31 #define FRAME_stand33 32 #define FRAME_stand34 33 #define FRAME_stand35 34 #define FRAME_stand36 35 #define FRAME_stand37 36 #define FRAME_stand38 37 #define FRAME_stand39 38 #define FRAME_stand40 39 #define FRAME_run1 40 #define FRAME_run2 41 #define FRAME_run3 42 #define FRAME_run4 43 #define FRAME_run5 44 #define FRAME_run6 45 #define FRAME_attack1 46 #define FRAME_attack2 47 #define FRAME_attack3 48 #define FRAME_attack4 49 #define FRAME_attack5 50 #define FRAME_attack6 51 #define FRAME_attack7 52 #define FRAME_attack8 53 #define FRAME_pain101 54 #define FRAME_pain102 55 #define FRAME_pain103 56 #define FRAME_pain104 57 #define FRAME_pain201 58 #define FRAME_pain202 59 #define FRAME_pain203 60 #define FRAME_pain204 61 #define FRAME_pain301 62 #define FRAME_pain302 63 #define FRAME_pain303 64 #define FRAME_pain304 65 #define FRAME_jump1 66 #define FRAME_jump2 67 #define FRAME_jump3 68 #define FRAME_jump4 69 #define FRAME_jump5 70 #define FRAME_jump6 71 #define FRAME_flip01 72 #define FRAME_flip02 73 #define FRAME_flip03 74 #define FRAME_flip04 75 #define FRAME_flip05 76 #define FRAME_flip06 77 #define FRAME_flip07 78 #define FRAME_flip08 79 #define FRAME_flip09 80 #define FRAME_flip10 81 #define FRAME_flip11 82 #define FRAME_flip12 83 #define FRAME_salute01 84 #define FRAME_salute02 85 #define FRAME_salute03 86 #define FRAME_salute04 87 #define FRAME_salute05 88 #define FRAME_salute06 89 #define FRAME_salute07 90 #define FRAME_salute08 91 #define FRAME_salute09 92 #define FRAME_salute10 93 #define FRAME_salute11 94 #define FRAME_taunt01 95 #define FRAME_taunt02 96 #define FRAME_taunt03 97 #define FRAME_taunt04 98 #define FRAME_taunt05 99 #define FRAME_taunt06 100 #define FRAME_taunt07 101 #define FRAME_taunt08 102 #define FRAME_taunt09 103 #define FRAME_taunt10 104 #define FRAME_taunt11 105 #define FRAME_taunt12 106 #define FRAME_taunt13 107 #define FRAME_taunt14 108 #define FRAME_taunt15 109 #define FRAME_taunt16 110 #define FRAME_taunt17 111 #define FRAME_wave01 112 #define FRAME_wave02 113 #define FRAME_wave03 114 #define FRAME_wave04 115 #define FRAME_wave05 116 #define FRAME_wave06 117 #define FRAME_wave07 118 #define FRAME_wave08 119 #define FRAME_wave09 120 #define FRAME_wave10 121 #define FRAME_wave11 122 #define FRAME_point01 123 #define FRAME_point02 124 #define FRAME_point03 125 #define FRAME_point04 126 #define FRAME_point05 127 #define FRAME_point06 128 #define FRAME_point07 129 #define FRAME_point08 130 #define FRAME_point09 131 #define FRAME_point10 132 #define FRAME_point11 133 #define FRAME_point12 134 #define FRAME_crstnd01 135 #define FRAME_crstnd02 136 #define FRAME_crstnd03 137 #define FRAME_crstnd04 138 #define FRAME_crstnd05 139 #define FRAME_crstnd06 140 #define FRAME_crstnd07 141 #define FRAME_crstnd08 142 #define FRAME_crstnd09 143 #define FRAME_crstnd10 144 #define FRAME_crstnd11 145 #define FRAME_crstnd12 146 #define FRAME_crstnd13 147 #define FRAME_crstnd14 148 #define FRAME_crstnd15 149 #define FRAME_crstnd16 150 #define FRAME_crstnd17 151 #define FRAME_crstnd18 152 #define FRAME_crstnd19 153 #define FRAME_crwalk1 154 #define FRAME_crwalk2 155 #define FRAME_crwalk3 156 #define FRAME_crwalk4 157 #define FRAME_crwalk5 158 #define FRAME_crwalk6 159 #define FRAME_crattak1 160 #define FRAME_crattak2 161 #define FRAME_crattak3 162 #define FRAME_crattak4 163 #define FRAME_crattak5 164 #define FRAME_crattak6 165 #define FRAME_crattak7 166 #define FRAME_crattak8 167 #define FRAME_crattak9 168 #define FRAME_crpain1 169 #define FRAME_crpain2 170 #define FRAME_crpain3 171 #define FRAME_crpain4 172 #define FRAME_crdeath1 173 #define FRAME_crdeath2 174 #define FRAME_crdeath3 175 #define FRAME_crdeath4 176 #define FRAME_crdeath5 177 #define FRAME_death101 178 #define FRAME_death102 179 #define FRAME_death103 180 #define FRAME_death104 181 #define FRAME_death105 182 #define FRAME_death106 183 #define FRAME_death201 184 #define FRAME_death202 185 #define FRAME_death203 186 #define FRAME_death204 187 #define FRAME_death205 188 #define FRAME_death206 189 #define FRAME_death301 190 #define FRAME_death302 191 #define FRAME_death303 192 #define FRAME_death304 193 #define FRAME_death305 194 #define FRAME_death306 195 #define FRAME_death307 196 #define FRAME_death308 197 #define FRAME_death401 198 #define FRAME_death402 199 #define FRAME_death403 200 #define FRAME_death404 201 #define FRAME_death405 202 #define FRAME_death406 203 #define FRAME_death407 204 #define FRAME_death408 205 #define FRAME_death409 206 #define FRAME_death410 207 #define FRAME_death411 208 #define FRAME_death412 209 #define FRAME_death413 210 #define FRAME_death414 211 #define FRAME_death415 212 #define FRAME_death416 213 #define FRAME_death417 214 #define FRAME_death418 215 #define FRAME_death419 216 #define FRAME_death420 217 #define FRAME_death421 218 #define FRAME_death422 219 #define FRAME_death501 220 #define FRAME_death502 221 #define FRAME_death503 222 #define FRAME_death504 223 #define FRAME_death505 224 #define FRAME_death506 225 #define FRAME_death507 226 #define FRAME_death508 227 #define FRAME_death509 228 #define FRAME_death510 229 #define FRAME_death511 230 #define FRAME_death512 231 #define FRAME_death513 232 #define FRAME_death514 233 #define FRAME_death515 234 #define FRAME_death516 235 #define FRAME_death517 236 #define FRAME_death518 237 #define FRAME_death601 238 #define FRAME_death602 239 #define FRAME_death603 240 #define FRAME_death604 241 #define FRAME_death605 242 #define FRAME_death606 243 #define FRAME_death607 244 #define FRAME_death608 245 #define FRAME_death609 246 #define FRAME_death610 247 #define FRAME_death611 248 #define FRAME_death612 249 #define FRAME_death613 250 #define FRAME_death614 251 #define FRAME_death615 252 #define FRAME_death616 253 #define FRAME_death617 254 #define FRAME_death618 255 #define FRAME_death619 256 #define FRAME_death620 257 #define MODEL_SCALE 1.000000 alien-arena-7.66+dfsg/source/game/g_trigger.c0000600000175000017500000004227012161402010020135 0ustar zero79zero79/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "g_local.h" void InitTrigger (edict_t *self) { if (!VectorCompare (self->s.angles, vec3_origin)) G_SetMovedir (self->s.angles, self->movedir); self->solid = SOLID_TRIGGER; self->movetype = MOVETYPE_NONE; gi.setmodel (self, self->model); self->svflags = SVF_NOCLIENT; } // the wait time has passed, so set back up for another activation void multi_wait (edict_t *ent) { ent->nextthink = 0; } // the trigger was just activated // ent->activator should be set to the activator so it can be held through a delay // so wait for the delay time before firing void multi_trigger (edict_t *ent) { if (ent->nextthink) return; // already been triggered G_UseTargets (ent, ent->activator); if (ent->wait > 0) { ent->think = multi_wait; ent->nextthink = level.time + ent->wait; } else { // we can't just remove (self) here, because this is a touch function // called while looping through area links... ent->touch = NULL; ent->nextthink = level.time + FRAMETIME; ent->think = G_FreeEdict; } } void Use_Multi (edict_t *ent, edict_t *other, edict_t *activator) { ent->activator = activator; multi_trigger (ent); } void Touch_Multi (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { //not during warmup if (self->spawnflags & 32) { if(level.time <= warmuptime->value) return; } if(other->client) { if (self->spawnflags & 2) return; } else if (other->svflags & SVF_MONSTER) { if (!(self->spawnflags & 1)) return; } else return; if (!VectorCompare(self->movedir, vec3_origin)) { vec3_t forward; AngleVectors(other->s.angles, forward, NULL, NULL); if (_DotProduct(forward, self->movedir) < 0) return; } self->activator = other; multi_trigger (self); } /*QUAKED trigger_multiple (.5 .5 .5) ? MONSTER NOT_PLAYER TRIGGERED Variable sized repeatable trigger. Must be targeted at one or more entities. If "delay" is set, the trigger waits some time after activating before firing. "wait" : Seconds between triggerings. (.2 default) sounds 1) secret 2) beep beep 3) large switch 4) set "message" to text string */ void trigger_enable (edict_t *self, edict_t *other, edict_t *activator) { self->solid = SOLID_TRIGGER; self->use = Use_Multi; gi.linkentity (self); } void SP_trigger_multiple (edict_t *ent) { if (ent->sounds == 1) ent->noise_index = gi.soundindex ("misc/secret.wav"); else if (ent->sounds == 2) ent->noise_index = gi.soundindex ("misc/talk.wav"); else if (ent->sounds == 3) ent->noise_index = gi.soundindex ("misc/trigger1.wav"); if (!ent->wait) ent->wait = 0.2; ent->touch = Touch_Multi; ent->movetype = MOVETYPE_NONE; ent->svflags |= SVF_NOCLIENT; if (ent->spawnflags & 4) { ent->solid = SOLID_NOT; ent->use = trigger_enable; } else { ent->solid = SOLID_TRIGGER; ent->use = Use_Multi; } if (!VectorCompare(ent->s.angles, vec3_origin)) G_SetMovedir (ent->s.angles, ent->movedir); gi.setmodel (ent, ent->model); gi.linkentity (ent); } /*QUAKED trigger_once (.5 .5 .5) ? x x TRIGGERED Triggers once, then removes itself. You must set the key "target" to the name of another object in the level that has a matching "targetname". If TRIGGERED, this trigger must be triggered before it is live. sounds 1) secret 2) beep beep 3) large switch 4) "message" string to be displayed when triggered */ void SP_trigger_once(edict_t *ent) { // make old maps work because I messed up on flag assignments here // triggered was on bit 1 when it should have been on bit 4 if (ent->spawnflags & 1) { vec3_t v; VectorMA (ent->mins, 0.5, ent->size, v); ent->spawnflags &= ~1; ent->spawnflags |= 4; gi.dprintf("fixed TRIGGERED flag on %s at %s\n", ent->classname, vtos(v)); } ent->wait = -1; SP_trigger_multiple (ent); } /*QUAKED trigger_relay (.5 .5 .5) (-8 -8 -8) (8 8 8) This fixed size trigger cannot be touched, it can only be fired by other events. */ void trigger_relay_use (edict_t *self, edict_t *other, edict_t *activator) { G_UseTargets (self, activator); } void SP_trigger_relay (edict_t *self) { self->use = trigger_relay_use; } /* ============================================================================== trigger_key ============================================================================== */ /*QUAKED trigger_key (.5 .5 .5) (-8 -8 -8) (8 8 8) A relay trigger that only fires it's targets if player has the proper key. Use "item" to specify the required key, for example "key_data_cd" */ void trigger_key_use (edict_t *self, edict_t *other, edict_t *activator) { int index; if (!self->item) return; if (!activator->client) return; index = ITEM_INDEX(self->item); if (!activator->client->pers.inventory[index]) { if (level.time < self->touch_debounce_time) return; self->touch_debounce_time = level.time + 5.0; safe_centerprintf (activator, "You need the %s", self->item->pickup_name); gi.sound (activator, CHAN_AUTO, gi.soundindex ("misc/keytry.wav"), 1, ATTN_NORM, 0); return; } gi.sound (activator, CHAN_AUTO, gi.soundindex ("misc/keyuse.wav"), 1, ATTN_NORM, 0); activator->client->pers.inventory[index]--; G_UseTargets (self, activator); self->use = NULL; } void SP_trigger_key (edict_t *self) { if (!st.item) { gi.dprintf("no key item for trigger_key at %s\n", vtos(self->s.origin)); return; } self->item = FindItemByClassname (st.item); if (!self->item) { gi.dprintf("item %s not found for trigger_key at %s\n", st.item, vtos(self->s.origin)); return; } if (!self->target) { gi.dprintf("%s at %s has no target\n", self->classname, vtos(self->s.origin)); return; } gi.soundindex ("misc/keytry.wav"); gi.soundindex ("misc/keyuse.wav"); self->use = trigger_key_use; } /* ============================================================================== trigger_counter ============================================================================== */ /*QUAKED trigger_counter (.5 .5 .5) ? nomessage Acts as an intermediary for an action that takes multiple inputs. If nomessage is not set, t will print "1 more.. " etc when triggered and "sequence complete" when finished. After the counter has been triggered "count" times (default 2), it will fire all of it's targets and remove itself. */ void trigger_counter_use(edict_t *self, edict_t *other, edict_t *activator) { if (self->count == 0) return; self->count--; if (self->count) { if (! (self->spawnflags & 1)) { safe_centerprintf(activator, "%i more to go...", self->count); gi.sound (activator, CHAN_AUTO, gi.soundindex ("misc/talk1.wav"), 1, ATTN_NORM, 0); } return; } if (! (self->spawnflags & 1)) { safe_centerprintf(activator, "Sequence completed!"); gi.sound (activator, CHAN_AUTO, gi.soundindex ("misc/talk1.wav"), 1, ATTN_NORM, 0); } self->activator = activator; multi_trigger (self); } void SP_trigger_counter (edict_t *self) { self->wait = -1; if (!self->count) self->count = 2; self->use = trigger_counter_use; } /* ============================================================================== trigger_always ============================================================================== */ /*QUAKED trigger_always (.5 .5 .5) (-8 -8 -8) (8 8 8) This trigger will always fire. It is activated by the world. */ void SP_trigger_always (edict_t *ent) { // we must have some delay to make sure our use targets are present if (ent->delay < 0.2) ent->delay = 0.2; G_UseTargets(ent, ent); } /* ============================================================================== trigger_push ============================================================================== */ #define PUSH_ONCE 1 static int windsound; void trigger_push_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { if (strcmp(other->classname, "grenade") == 0) { VectorScale (self->movedir, self->speed * 10, other->velocity); } else if (other->health > 0) { VectorScale (self->movedir, self->speed * 10, other->velocity); if (other->client) { // don't take falling damage immediately from this VectorCopy (other->velocity, other->client->oldvelocity); if (other->fly_sound_debounce_time < level.time) { other->fly_sound_debounce_time = level.time + 1.5; gi.sound (other, CHAN_AUTO, windsound, 1, ATTN_NORM, 0); } } } if (self->spawnflags & PUSH_ONCE) G_FreeEdict (self); } /*QUAKED trigger_push (.5 .5 .5) ? PUSH_ONCE Pushes the player "speed" defaults to 1000 */ void SP_trigger_push (edict_t *self) { InitTrigger (self); windsound = gi.soundindex ("misc/windfly.wav"); self->touch = trigger_push_touch; if (!self->speed) self->speed = 1000; gi.linkentity (self); } /* ============================================================================== trigger_hurt ============================================================================== */ /*QUAKED trigger_hurt (.5 .5 .5) ? START_OFF TOGGLE SILENT NO_PROTECTION SLOW Any entity that touches this will be hurt. It does dmg points of damage each server frame SILENT supresses playing the sound SLOW changes the damage rate to once per second NO_PROTECTION *nothing* stops the damage "dmg" default 5 (whole numbers only) */ void hurt_use (edict_t *self, edict_t *other, edict_t *activator) { if (self->solid == SOLID_NOT) self->solid = SOLID_TRIGGER; else self->solid = SOLID_NOT; gi.linkentity (self); if (!(self->spawnflags & 2)) self->use = NULL; } void hurt_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { int dflags; if (!other->takedamage) return; if (self->timestamp > level.time) return; if (self->spawnflags & 16) self->timestamp = level.time + 1; else self->timestamp = level.time + FRAMETIME; if (!(self->spawnflags & 4)) { if ((level.framenum % 10) == 0) gi.sound (other, CHAN_AUTO, self->noise_index, 1, ATTN_NORM, 0); } if (self->spawnflags & 8) dflags = DAMAGE_NO_PROTECTION; else dflags = 0; T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, self->dmg, dflags, MOD_TRIGGER_HURT); } void SP_trigger_hurt (edict_t *self) { InitTrigger (self); self->touch = hurt_touch; if (!self->dmg) self->dmg = 5; if (self->spawnflags & 1) self->solid = SOLID_NOT; else self->solid = SOLID_TRIGGER; if (self->spawnflags & 2) self->use = hurt_use; gi.linkentity (self); } /* ============================================================================== trigger_gravity ============================================================================== */ /*QUAKED trigger_gravity (.5 .5 .5) ? Changes the touching entites gravity to the value of "gravity". 1.0 is standard gravity for the level. */ void trigger_gravity_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { other->gravity = self->gravity; } void SP_trigger_gravity (edict_t *self) { if (st.gravity == 0) { gi.dprintf("trigger_gravity without gravity set at %s\n", vtos(self->s.origin)); G_FreeEdict (self); return; } InitTrigger (self); self->gravity = atoi(st.gravity); self->touch = trigger_gravity_touch; } /* ============================================================================== trigger_monsterjump ============================================================================== */ /*QUAKED trigger_monsterjump (.5 .5 .5) ? Walking monsters that touch this will jump in the direction of the trigger's angle "speed" default to 200, the speed thrown forward "height" default to 200, the speed thrown upwards */ void trigger_monsterjump_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { if (self->nextthink) return; // already been triggered if (other->flags & (FL_FLY | FL_SWIM) ) return; if (other->svflags & SVF_DEADMONSTER) return; // set XY even if not on ground, so the jump will clear lips other->velocity[0] = self->movedir[0] * self->speed; other->velocity[1] = self->movedir[1] * self->speed; other->groundentity = NULL; other->velocity[2] = self->movedir[2]; //play a sound gi.sound (other, CHAN_AUTO, gi.soundindex("world/button2.wav"), 1, ATTN_NORM, 0); self->nextthink = level.time + .1; } void SP_trigger_monsterjump (edict_t *self) { if (!self->speed) self->speed = 200; if (!st.height) st.height = 200; if (self->s.angles[YAW] == 0) self->s.angles[YAW] = 360; InitTrigger (self); self->touch = trigger_monsterjump_touch; self->movedir[2] = st.height; self->think = multi_wait; } //trigger_deathballtarget - a "goal" used for scoring in deathball void deathballtarget_use (edict_t *self, edict_t *other, edict_t *activator) { if (self->solid == SOLID_NOT) self->solid = SOLID_TRIGGER; else self->solid = SOLID_NOT; gi.linkentity (self); if (!(self->spawnflags & 2)) self->use = NULL; } void deathballtarget_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { if (self->timestamp > level.time) return; self->timestamp = level.time + FRAMETIME; if(strcmp(other->classname, "item_deathball") == 0) { if (!(dmflags->integer & DF_SKINTEAMS)) other->owner->client->resp.score += 10; if ((dmflags->integer & DF_SKINTEAMS)) { if(other->owner->dmteam == RED_TEAM && strcmp(self->classname, "trigger_bluedeathballtarget") == 0) { red_team_score+=10; other->owner->client->resp.score += 10; } else if(other->owner->dmteam == BLUE_TEAM && strcmp(self->classname, "trigger_reddeathballtarget") == 0) { blue_team_score+=10; other->owner->client->resp.score += 10; } else return; //shot at wrong goal in a team game, loser! } //send an effect gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BFG_BIGEXPLOSION); gi.WritePosition (other->s.origin); gi.multicast (other->s.origin, MULTICAST_PHS); gi.sound (other, CHAN_AUTO, gi.soundindex("misc/db_score.wav"), 1, ATTN_NONE, 0); ResetDeathball(); } } void SP_trigger_deathballtarget (edict_t *self) { InitTrigger (self); self->touch = deathballtarget_touch; if (self->spawnflags & 1) self->solid = SOLID_NOT; else self->solid = SOLID_TRIGGER; if (self->spawnflags & 2) self->use = deathballtarget_use; gi.linkentity (self); } void SP_trigger_reddeathballtarget (edict_t *self) { InitTrigger (self); self->touch = deathballtarget_touch; if (self->spawnflags & 1) self->solid = SOLID_NOT; else self->solid = SOLID_TRIGGER; if (self->spawnflags & 2) self->use = deathballtarget_use; gi.linkentity (self); } void SP_trigger_bluedeathballtarget (edict_t *self) { InitTrigger (self); self->touch = deathballtarget_touch; if (self->spawnflags & 1) self->solid = SOLID_NOT; else self->solid = SOLID_TRIGGER; if (self->spawnflags & 2) self->use = deathballtarget_use; gi.linkentity (self); } void cowtarget_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { if (self->timestamp > level.time) return; self->timestamp = level.time + FRAMETIME; if(strcmp(other->classname, "cow") == 0) { if(strcmp(self->classname, "trigger_bluecowtarget") == 0) blue_team_score++; if(strcmp(self->classname, "trigger_redcowtarget") == 0) red_team_score++; //send an effect gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BFG_BIGEXPLOSION); gi.WritePosition (other->s.origin); gi.multicast (other->s.origin, MULTICAST_PHS); gi.sound (other, CHAN_AUTO, gi.soundindex("misc/db_score.wav"), 1, ATTN_NONE, 0); //get rid of the cow, it's been beamed into the void....(back to pasture) other->health = other->max_health; other->s.event = EV_PLAYER_TELEPORT; VectorCopy(other->s.spawn_pos, other->s.origin); //reward the player who was controlling the cow if(other->enemy) other->enemy->client->resp.score += 10; } } void SP_trigger_redcowtarget (edict_t *self) { InitTrigger(self); self->solid = SOLID_TRIGGER; self->touch = cowtarget_touch; gi.linkentity (self); } void SP_trigger_bluecowtarget (edict_t *self) { InitTrigger(self); self->solid = SOLID_TRIGGER; self->touch = cowtarget_touch; gi.linkentity (self); } alien-arena-7.66+dfsg/alienarena.png0000600000175000017500000001354512161402016016425 0ustar zero79zero79PNG  IHDR00  pHYsod tEXtComment*IDATxZipTו}jvZ@BHE,6I9ql'8L%S$q%kLT2?2l'N*) dnzs=|wDۮ.1joƫ! !<D y }OO5"~: M\ FmD^Ҙ Ene$2`_ a~iCae4/mFhCzE*g`M3d]<aI(=Jxtu.D`h헋5b3ؾ8rb _;Qn^ 7+Yxr>+AoEb!,A6Y-44E'$rVÅ9G7`  ]N n4AEΉE*_J Лd0L0PxPqJix_2ȻLkAh DncA-+ =zc(ys&|pS҉q<ad0 ;n|vcp5ф5hk|tcPY8}.#1ʅ$b[8xC^~z!֦ŦHO# + TYb"7EUVD'n ~2 %ݤ*> 栚L*s#Kqt,xHc1 vx^m2[ *7xHC\fl#KV_'tPkERm2T!3Nۇ7M>$SuP%Q 7e0 x 䛌 PDem$e#$|^_H$2"`. >FYwZ b[jdj\Þ'Wh/u4~C=㭴`svL}sgu&l>:0%J֢~L?3+?],*5 ϲNΕ;_vk ҃ך1ڈ}uh^B~kidZM4eQV]*:*0 .v  dRݜ=B֎F|*»ݔv8`j@W.ުJ9L0ًQ2+G/Rl"4䊚߾_ 3HޛFdZeP%)MüA S!hyٯC:*!_ibBF9GuԳ:Y```dƠ-ܲ!)ߢA( }GrK~!?:ւ!$+`L7GBe)Nl K$JJ(jYf/HSwz3Aqh"M@F i;AIx\ R+>}]Ǧ\E'-Q,^]snyiҏ_zuY?--_8n:h)`꾭8a,}(#W_;mjFCṤ[;۰VL،c8ڎS߹{ u`0~CkAvL]0݈moC=X:|a^8"zK8 lT`:9aRF`~ ̯F+v_VN}&VP*k _ߋ"3G ,%O."JD/;A2y r0rT B eUԮs()`\u^{g<~{~~j$N7"0P(?Gjgjޔ"QQXD# =|3ԋDH!Fx<;o.#,0x`@k$.4FHI*gfk@t{ĉ4bqýdu^1p\HJ|NsNvsSNFHF59V=Cz =ȖP6/."2HiDkֵشcӕ6s:C !/~4Iz# 4J *.hF UMO\k}u@+^GxeJn{ @ vAO݀K@Qmv ##,!'pލj w±6z&r£/i]mtW} :B]G.r ^jGpiZ;V/`#O hhxr E\#NF{چH-D#b[n"uYwXE0Y)ŝ6XQAZFRdtCd3X-׈pn0.8g"VA&6]EC!#Tbx9!kH= z{VƉì٫Abx6VR~vw'RNT`/&xyU09J4r*D!rEK 7:Ye+MPB$K!w&phGZʨzk7\txh|eAĆ<7yZ#eF PPA^hҢt0Y ͕(OYU =$ɻbB.![O^7 N4yԳ@mz)]J7,Y*\hW;>tEsxRkf܆Yn3AO"'fM^XB%f߼"715 s:C LgTP족~&aOF{-0s5-t^;}16>D*@Scy>y{y /as۱9,>A=KpK2ξS:]O.cr%qe65 ϙ{c-˭;`ŊM#p{i+<3ٿ0uh[l!==1F0&1ON1Kbx1tƻYpl!LDp X*Q +1䶦P6CYoY2,2 e?bKvl%.gU6س4v8B8v8dprN|.a0^^9;T,X?,vh&L!<uA;@ZJ";jA^L4[g haTB+j* I"!)d,D@SK8#R2PEzĤx >#l 6X'R$esOcUxG1AR1bNG!(#'q4<v,:ksTuD "HrdDa,d7m&Ke,A,b X*PPOvbCsuV>7:v>; oցض($c$vRH-!y'BSDftr`7v`v` 5D[HiWfQ3$1ĥ;!.-(!!ch&Jeo #bEe}i'Q:F6REyؗ 2$NN'?'vpb{.Z^ U$Hp FB_r@[|q&]2^arC@'1<ϛ B}$:Bxg-mbn"C5ԥ2$h7"G1D췂5ѭ@ܱB҈)*$ VZt<9zw #+ ğ6Վh<򁨩PX͂>NYj9`QhkDjR(w \5Fc$P8n*h(AA(Zt@/I^]icл.%ed¼f ZVIwĽť9Iu?قi'|;mݸPyre*i'mNZ.-YK: y`RJrꠒ_Jo3~HY@J*@n5RPgk6؉ "}B^@<~{6̥1yGNA$G,E}uHmOXCJhFmBB:5RBnVZGu@5KsPR_cqX-6T,TF!*$80F>MD0~3LK KQQT9ZҲ^7Z!NJpjid7~/U0Ve~ Td:PN_\C2I`i7{X' pKK3M3b`?I'/nJ465v_N_NwϮI/ȴn!` !B-su>`(ځfz*}-E {ĥ>O+jjN% >jVG- l;4a@NxB$twZvTV޵;upq R;QJ$}z[*G} oyjVV"# @ƒY, YRMh큦"(]P)w3dj{3@+_0)EI z[܉,dvTKh Z"T_KEL`Bv fV Q M:9d#T\1&JU@)L 5R*&M_~.rNlWobmp!1G&%|Nr0QbL3m?Px^!5dVͿِ|ߢ$L)v?_o2__롼P :7 ԉ|;pTq4P !2‚aZwy+*#O OTr f?~ȉW$%&A 1H~P~x&mp4 C@Ω2A+Rr ^s["t[+-7M&S6n/db4{/v!cH#"J}&#Hqč+jtt¹V=˱W]2?t.!_q۹;l/t/t]/oYUye.1IENDB`alien-arena-7.66+dfsg/tactical/0000700000175000017500000000000012207204665015405 5ustar zero79zero79alien-arena-7.66+dfsg/tactical/default.cfg0000600000175000017500000000610012204310130017467 0ustar zero79zero79// // KEY BINDINGS // unbindall bind ' "inven_drop" bind 1 "use Blaster" bind 2 "use Alien Disruptor" bind 3 "use Pulse Rifle" bind 4 "use Flame Thrower" bind 5 "use Rocket Launcher" bind 6 "use Alien Smartgun" bind 7 "use Disruptor" bind 8 "use Alien Vaporizer" bind 9 "use Violator" bind 0 "use Minderaser" bind MWHEELDOWN "weapprev" bind MWHEELUP "weapnext" // // CHARACTER CONTROLS // bind CTRL +attack bind MOUSE1 +attack bind MOUSE2 +attack2 bind ALT +strafe bind , +moveleft bind . +moveright bind DEL +lookdown bind PGDN +lookup bind END centerview bind c +movedown bind i inven bind ENTER invuse bind [ invprev bind ] invnext bind ' invdrop bind BACKSPACE invdrop bind TAB "score" bind / weapnext bind q use quad damage bind i use invulnerability //waves bind h "wave 0" bind j "wave 1" bind k "wave 2" bind l "wave 3" bind g "wave 4" bind SHIFT +speed bind UPARROW +forward bind DOWNARROW +back bind LEFTARROW +left bind RIGHTARROW +right bind w +forward bind s +back bind a +moveleft bind d +moveright bind SPACE +moveup bind x "drop strafer; drop bomber; drop hover" // // MOUSE OPTIONS // bind \ +mlook // // CLIENT ENVIRONMENT COMMANDS // bind PAUSE "pause" bind ESCAPE "togglemenu" bind ~ "toggleconsole" bind ` "toggleconsole" bind F1 "vote 1" bind F2 "vote 2" bind F3 "vote 3" bind F4 "vote 4" bind F10 "menu_quit" bind F12 "screenshot" bind t "messagemode" bind y "messagemode2" bind u "messagemode3" bind + "sizeup" bind = "sizeup" bind - "sizedown" bind INS +klook // // DEFAULT CVARS // //set viewsize 100 //set vid_fullscreen 1 set win_noalttab 0 set sensitivity 3 set crosshair ch1 set con_font "default" set freelook 1 set cl_run 1 set hand 0 set m_pitch 0.022 set m_yaw 0.022 set m_forward 1 set m_side 0.8 set m_smoothing 0 set lookspring 1 set lookstrafe 0 set background_music 1 set background_music_vol 0.8 set s_volume 0.1 set s_doppler 0 set cl_noskins 0 set cl_showplayernames 0 //---------------------------------------------- // // userinfo // set name Player set skin martianenforcer/default //---------------------------------------------- // // DEMO STUFF // alias d1 "skill 1; deathmatch 1; fraglimit 0; maxclients 8; g_tactical 1; map tac-extermination" // // newgame command // alias newgame " killserver ; deathmatch 1; fraglimit 0; maxclients 8; g_tactical 1; map tac-extermination" // // quake2 +set dedicated 1 // will run this command if no other +map is included // alias dedicated_start "map tac-extermination" alien-arena-7.66+dfsg/tactical/maps.lst0000600000175000017500000000005212204310130017046 0ustar zero79zero79tac-extermination "Final Extermination" 0alien-arena-7.66+dfsg/tactical/motd.txt0000600000175000017500000000011712204310130017070 0ustar zero79zero79Welcome to Alien Arena Tactical Demo Alpha! http://red.planetarena.org/ alien-arena-7.66+dfsg/tactical/server.cfg0000600000175000017500000000072612204310130017361 0ustar zero79zero79// Generic dedicated server config set dmflags 2359312 set hostname "Alien Arena Tactical Demo Server" set website "http://red.planetarena.org" s set Admin "admin" s set deathmatch 1 set sv_botkickthreshold 4 set maxclients 24 set fraglimit 0 set timelimit 0 set sv_maplist "tac-extermination" set sv_public 1 set logfile 1 set g_tactical 1 set rcon_password "rconpw" setmaster master.corservers.com master2.corservers.com map tac-extermination alien-arena-7.66+dfsg/configure.ac0000600000175000017500000004453612206717367016134 0ustar zero79zero79# Process this file with autoconf to produce a configure script. # # Alien Arena auto configuration source # # Copyright (C) 2010 COR Entertainment, LLC. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # # configure.ac for # GNU/Linux, Unix # Windows (32-bit) using MinGW - Experimental # Mac OS X / Darwin using X11 - Experimental AC_PREREQ([2.69]) AC_INIT([alienarena],[7.66],[alienrace@comcast.net]) AC_CONFIG_SRCDIR([source/ref_gl/r_image.h]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_AUX_DIR([config]) AC_CONFIG_HEADERS([config/config.h]) dnl insure default prefix AX_EXPAND_PREFIX dnl 1.14 = require automake 1.14 or greater dnl foreign = do not apply GNU doc requirements dnl subdir-objects = compile objects into their sub directories dnl silent-rules = less output (--disable-silent-rules for more output) dnl add dist-zip, dist-bzip2 for other distributions besides tar.gz AM_INIT_AUTOMAKE([ 1.14 foreign subdir-objects silent-rules ]) AM_SILENT_RULES([yes]) dnl use --enable-maintainer-mode to get full set of make targets. dnl autotools generated files will not be updated otherwise. dnl without --enable-maintainer-mode, autotools programs are not needed dnl to build the program, which is better for non-developers. AM_MAINTAINER_MODE AC_CANONICAL_HOST # # Checks for programs. # AC_PROG_CXX AC_PROG_AWK AC_PROG_CC AC_PROG_CPP AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_MAKE_SET AC_PROG_RANLIB AC_PROG_MKDIR_P AM_PROG_CC_C_O PKG_PROG_PKG_CONFIG # # check host environment # cond_build_win32=no cond_build_unix=no unix_host=generic AS_CASE([ ${host} ], [ *-*-mingw* ],[ cond_build_win32=yes ], [ *-*-darwin*], [ cond_build_unix=yes unix_host=darwin ], [ *-*-linux* ], [ cond_build_unix=yes unix_host=linux ], [ cond_build_unix=yes ]) AM_CONDITIONAL([BUILD_WIN32],[ test "x${cond_build_win32}" = xyes ]) AM_CONDITIONAL([BUILD_UNIX],[ test "x${cond_build_unix}" = xyes ]) # # Environment variable for specifying libGL.dylib path for Darwin when it # is not in the dlopen() search path. see dlopen (3) for Mac OS X. # Either export or in command line: GL_LIBDIR=/usr/Xll/lib, for example. # If this GL_LIBDIR is not given, use the shell variable x_libraries from # the AC_PATH_X macro (which may be empty) # gl_dlopen_path=default AS_IF([ test x"${unix_host}" = xdarwin ], [ AC_PATH_X AC_MSG_CHECKING([for GL_LIBDIR (location of libGL.dylib)]) AC_ARG_VAR( GL_LIBDIR, [directory containing libGL.dylib]) AC_MSG_RESULT([${GL_LIBDIR}]) AS_IF([ test x"${GL_LIBDIR}" = x ], [gl_dlopen_path=${x_libraries}], [gl_dlopen_path=${GL_LIBDIR}]) ]) # # Unix/Linux/Darwin dedicated server only build option # AC_MSG_CHECKING([whether to build the client]) AM_COND_IF([BUILD_UNIX], [ AC_ARG_ENABLE( [client], [AS_HELP_STRING([--disable-client], [build dedicated server only, not the client (default:no)])], [build_client=${enableval}], [build_client=yes]) ], [build_client=yes]) AC_MSG_RESULT([${build_client}]) AM_CONDITIONAL([BUILD_CLIENT],[ test "x${build_client}" = xyes ]) # # Alternate Install. Install in the traditional single directory way. # Might be required for map making tools to work. Also, good when updating # from SVN regularly. Affects how Makefile sets DATADIR and does make-install. # for now, win32/mingw is always alternate install # AM_COND_IF([BUILD_WIN32], [alternate_install=yes], [ AC_MSG_CHECKING([for traditional single directory, in place installation]) AC_ARG_ENABLE( [alternate_install], [AS_HELP_STRING([--enable-alternate-install], [traditional single directory, in-place installation (default:no)])], [alternate_install=${enableval}], [alternate_install=no]) AC_MSG_RESULT([${alternate_install}]) ]) AM_CONDITIONAL([ALTERNATE_INSTALL],[ test "x${alternate_install}" = xyes ]) dnl dnl symbols for config.h dnl AM_COND_IF([BUILD_UNIX], [ AC_DEFINE([UNIX_VARIANT],1,[unix-specific conditional compile]) AS_CASE([ ${unix_host} ], [ darwin ], [ AC_DEFINE([DARWIN_SPECIAL_CASE],1,[darwin-specific conditional compile]) dnl dnl possible error from select() in unix/net_udp.c::Net_Sleep() dnl AC_DEFINE([_DARWIN_UNLIMITED_SELECT],1,[see select (2) man page for Mac OS X]) ], [ linux ], [AC_DEFINE([LINUX_SPECIAL_CASE],1,[linux-specific conditional compile])], [ generic ] [AC_DEFINE([GENERIC_UNIX],1,[non-specific unix conditional compile])]) AC_ARG_ENABLE([ansi-color], [AS_HELP_STRING([--enable-ansi-color],[ANSI terminal color (default: no)])], [ansi_color=${enableval}],[ansi_color=no]) AS_IF([ test "x$ansi_color" = "xyes" ],[ AC_DEFINE([ANSI_COLOR],1,[Enable ANSI terminal color codes in stdout]) ]) ]) AM_COND_IF([BUILD_WIN32], [AC_DEFINE([WIN32_VARIANT],1,[win32-specific conditional compile])]) AC_DEFINE_UNQUOTED(CPUSTRING, "${host_cpu}", [Canonical CPU identification]) AC_DEFINE_UNQUOTED(BUILDSTRING, "${host_os}", [Canonical OS identification]) # # ODE (Open Dynamic Engine) Library # # if no option or "--without-system-libode" is specified, use the recommended # integrated ODE. # if "--with-system-libode" is specified, check. look under BUILD_CLIENT # for details. # AC_ARG_WITH([system-libode], [AS_HELP_STRING([--with(out)-system-libode], [use system-supplied libode (default:without)])], [system_ode=${withval}], [system_ode=no]) # # Option for disabling installation of documents to allow for custom # documentation installation. Normally only useful for distro packagers. # Do not put in status message, because documents probably are being # installed in a custom way. # AC_ARG_ENABLE([documents], [AS_HELP_STRING([--disable-documents], [Disable document installation (default: no)])], [no_docs=${documents}], [no_docs=no]) AM_CONDITIONAL([INSTALL_DOCS],[ test "x${no_docs}" = "xno" ]) # # Option for specifying where icon is installed. # AC_ARG_WITH(icondir, [AS_HELP_STRING([--with-icondir=DIR], [icon install directory (default:DATADIR/icons)])], [ with_icondir=${withval} ], [ with_icondir=${datadir}/icons ]) AC_SUBST([icondir], [${with_icondir}]) # # User writable data and configuration subdirectory in $HOME # normally this is a hidden subdirectory # default is .codered. but distros modify this # can be overridden by environment variable, COR_GAME # # (These also are #defined in qcommon.h, but changing them is not a good idea # BASE_GAMEDATA "data1", GAME_GAMEDATA "arena", BOT_GAMEDATA "botinfo") # # AC_ARG_VAR creates ALIENARENA_HOMEDIR entry for ./configure --help # AC_DEFINE_UNQUOTED adds the setting to config.h, # overriding the define in qcommon.h # and # using the default, if not specified in the commandline # (Note: could also be specified in enviroment. That is not recommended # but is the reason for the package specific variable name.) # alienarena_homedir=".codered" AC_ARG_VAR([ALIENARENA_HOMEDIR],[User data and cfg subdirectory in $HOME]) AS_IF([ test "x${ALIENARENA_HOMEDIR}" = "x" ], [ALIENARENA_HOMEDIR=${alienarena_homedir}], [alienarena_homedir=${ALIENARENA_HOMEDIR}]) AC_DEFINE_UNQUOTED([USER_GAMEDATA],["${alienarena_homedir}"], [User data and cfg subdirectory in $HOME]) # # Checks for libraries. # AC_SEARCH_LIBS([acos],[m]) AC_SEARCH_LIBS([dlopen],[dl]) AC_SEARCH_LIBS([clock_gettime],[rt]) dnl dnl start of client-only library requirements dnl AM_COND_IF([BUILD_CLIENT], [ AX_PTHREAD([],[AC_MSG_ERROR(["Required pthreads support not found."])]) # # This might be a workaround for DSO missing pthread library error # AS_IF([ test "x$PTHREAD_LIBS" = "x" ],[PTHREAD_LIBS="-pthread"]) dnl dnl zlib support dnl dnl If no option is specified, then check for the library and act accordingly. dnl If "--without-zlib" is specified, do not check, and disable the library. dnl If "--with-zlib" is specified, check and bail out if it cannot be found. dnl AC_ARG_WITH([zlib], [AS_HELP_STRING([--with(out)-zlib],[include Zlib compression support (default: check)])], [], [with_zlib=check]) have_zlib=no AS_IF([ test "x$with_zlib" != "xno" ],[ PKG_CHECK_MODULES([ZLIB],[zlib],[ have_zlib=yes AC_DEFINE([HAVE_ZLIB],1,[Enable ZLib support]) ],[ have_zlib=no AS_IF([ test "x$with_zlib" = "xyes" ],[ AC_MSG_FAILURE([--with-zlib specified, but the library or headers could not be found]) ]) ]) ]) dnl IJG libjpeg required AC_SEARCH_LIBS([jpeg_read_header],[jpeg],, [AC_MSG_ERROR(["Required jpeg library not found."])]) AM_COND_IF([BUILD_UNIX], [ dnl dnl XF86 dnl PKG_CHECK_MODULES([X11],[x11]) dnl dnl XF86 VidMode extension dnl Note: supports full-screen display. if it is not installed, the dnl build will succeed but full-screen will not work. dnl dnl If no option is specified, then check for the library and act accordingly. dnl If "--without-xf86vm" is specified, do not check, and disable the library. dnl If "--with-xf86vm" is specified, check and bail out if it cannot be found. dnl AC_ARG_WITH([xf86vm], [AS_HELP_STRING([--with(out)-xf86vm],[include XF86 VidMode support (default: check)])], [], [with_xf86vm=check]) have_Xxf86vm=no AS_IF([ test "x$with_xf86vm" != "xno" ],[ PKG_CHECK_MODULES([XXF86VM],[xxf86vm],[ have_Xxf86vm=yes AC_DEFINE([HAVE_XXF86VM],1,[Enable X86 VidMode support]) ],[ have_Xxf86vm=no AS_IF([ test "x$with_xf86vm" = "xyes" ],[ AC_MSG_FAILURE([--with-xf86vm specified, but the library or headers could not be found]) ]) ]) ]) dnl dnl XF86 DGA extension dnl Note: this is changed to default to "without", dnl so "--with-xf86dga" must be specified to use this library dnl dnl If no option is specified, disable the library. dnl If "--without-xf86dga" is specified, do not check, and disable the library. dnl If "--with-xf86dga" is specified, check and bail out if it cannot be found. dnl AC_ARG_WITH([xf86dga], [AS_HELP_STRING([--with(out)-xf86dga],[include XF86 DGA support (default: without)])], [], [with_xf86dga=no]) have_Xxf86dga=no AS_IF([ test "x$with_xf86dga" != "xno" ],[ PKG_CHECK_MODULES([XXF86DGA],[xxf86dga],[ have_Xxf86dga=yes AC_DEFINE([HAVE_XXF86DGA],1,[Enable X86 DGA support]) AC_CHECK_HEADERS([X11/extensions/Xxf86dga.h],[],[],[ #include #include ]) ],[ have_Xxf86dga=no AS_IF([ test "x$with_xf86dga" = "xyes" ],[ AC_MSG_FAILURE([--with-xf86dga specified, but the library or headers could not be found]) ]) ]) ]) ]) # # if option to use system libode, rather than integrated ODE, is selected # use pkg-config to get cflags and libs. do not default to # integrated ODE on failure, as that is probably not what is wanted. # # for recommended integrated ODE build, setup client dependencies, # and configuration. Double precision math is "hardwired" here and # is not considered to be a user-specifiable option. # AS_IF([ test "x$system_ode" = "xyes" ],[ PKG_CHECK_MODULES([ODE],[ode],,[ AC_MSG_FAILURE( [--with-system-libode specified, but the library or headers could not be found]) ]) ],[ AC_SUBST([ODE_CFLAGS],[-DdDOUBLE]) AC_DEFINE([dEpsilon],[DBL_EPSILON],[Define to DBL_EPSILON for ODE]) ]) dnl dnl Check common client dependencies: dnl Curl, Ogg/Vorbis and vorbisfile dnl PKG_CHECK_MODULES([DEPS],[libcurl ogg vorbis vorbisfile freetype2]) dnl Hack in the extras for Win32 dnl TODO: this may not be the best way to do this win32_syslibs="" AM_COND_IF([BUILD_WIN32], [ win32_syslibs="-lmingw32 -lwinmm -lwsock32 -lws2_32 -lgdi32 -luser32"]) AC_SUBST([WIN32_LIBS],[$win32_syslibs]) ]) AM_CONDITIONAL([USE_SYSTEM_LIBODE],[ test "x$system_ode" = "xyes" ]) dnl dnl end of client-only library requirements dnl # # Checks for header files # AC_CHECK_HEADERS( [inttypes.h stdint.h stddef.h stdlib.h unistd.h], [],[],[]) AC_CHECK_HEADERS( [float.h limits.h], [],[],[]) AC_CHECK_HEADERS( [arpa/inet.h netinet/in.h sys/ioctl.h sys/socket.h netdb.h termios.h sys/select.h] [],[],[]) AC_CHECK_HEADERS( [dlfcn.h fcntl.h malloc.h string.h sys/param.h sys/stat.h] [],[],[]) AC_CHECK_HEADERS( [time.h sys/time.h] [],[],[]) AC_CHECK_HEADERS([windows.h winsock.h winsock2.h]) dnl dnl start of client-only header requirements dnl AM_COND_IF([BUILD_CLIENT],[ jpeglib_h_found=no AC_CHECK_HEADERS([jpeglib.h jpeg/jpeglib.h],[ jpeglib_h_found=yes ]) AS_IF([ test "x${jpeglib_h_found}" = xno ], [AC_MSG_ERROR("Required JPEG header file not found.")]) openal_h_found=no AC_CHECK_HEADERS([AL/al.h al.h OpenAL/al.h],[ openal_h_found=yes ]) AS_IF([ test "x${openal_h_found}" = xno ], [AC_MSG_ERROR("Required OpenAL header file not found.")]) openalc_h_found=no AC_CHECK_HEADERS([AL/alc.h alc.h OpenAL/alc.h],[ openalc_h_found=yes ]) AS_IF([ test "x${openalc_h_found}" = xno ], [AC_MSG_ERROR("Required OpenAL header file not found.")]) AC_CHECK_HEADERS([GL/gl.h],, [AC_MSG_ERROR("Required OpenGL header files not found.")]) AM_COND_IF([BUILD_UNIX], [AC_CHECK_HEADERS([GL/glx.h],, [AC_MSG_ERROR("Required OpenGL header files not found.") ]) ]) ]) dnl dnl end of client-only header requirements dnl # # Checks for typedefs, structures, and compiler characteristics. # AC_HEADER_STDBOOL AC_C_INLINE AC_TYPE_SIZE_T AC_TYPE_UID_T AC_TYPE_INT32_T AC_TYPE_INT64_T AC_TYPE_UINT64_T AC_CHECK_TYPES([ptrdiff_t]) AC_CHECK_TYPES([uintptr_t]) # # Checks for library functions. # AC_FUNC_ERROR_AT_LINE AC_FUNC_ALLOCA AC_FUNC_MALLOC AC_FUNC_MMAP AC_FUNC_REALLOC AC_FUNC_OBSTACK dnl network functions AC_CHECK_FUNCS([closesocket socket gethostbyname select]) dnl thread functions AC_CHECK_FUNCS([pthread_create _begin_thread]) dnl string functions AC_CHECK_FUNCS([strchr strerror strrchr strstr strlcpy isascii]) AC_CHECK_FUNCS([strcasecmp strncasecmp ]) AC_CHECK_FUNCS([strdup _strdup stricmp _stricmp strnicmp _strnicmp]) dnl file system functions AC_CHECK_FUNCS([filelength stat fstat getcwd _getcwd unlink _unlink mkdir _mkdir]) dnl math functions AC_CHECK_FUNCS([pow sqrt floor]) dnl mem mgmt functions AC_CHECK_FUNCS([memmove memset munmap mremap]) dnl time functions AC_CHECK_FUNCS([gettimeofday clock_gettime]) dnl other functions AC_CHECK_FUNCS([ putenv _putenv]) dnl dnl Set names of dlopened libraries for config.h dnl AM_COND_IF([BUILD_UNIX], [AS_CASE([ ${unix_host} ], [ darwin ], [AS_IF([ test x"${gl_dlopen_path}" = xdefault ], [AC_DEFINE([OPENGL_DRIVER], ["libGL.dylib"], [OpenAL dynamic lib name]) ], [AC_DEFINE_UNQUOTED([OPENGL_DRIVER], ["${gl_dlopen_path}/libGL.dylib"], [OpenGL dynamic lib path]) ]) AC_DEFINE([OPENAL_DRIVER], ["/System/Library/Frameworks/OpenAL.framework/OpenAL"], [OpenAl dynamic lib path]) ], [ AC_DEFINE([OPENGL_DRIVER], ["libGL.so.1"],[OpenGL shared lib name]) AC_DEFINE([OPENAL_DRIVER], ["libopenal.so.1"],[OpenAL shared lib name]) ]) ]) AM_COND_IF([BUILD_WIN32], [ AC_DEFINE([OPENGL_DRIVER],["opengl32"],[OpenGL DLL name]) AC_DEFINE([OPENAL_DRIVER],["OpenAL32.dll"],[OpenAL dll name]) ]) # # required gcc/g++ options. # fast-math because strict adherence to IEEE standard is not needed. # no-strict-aliasing because strict aliasing is not adhered to in places. # AX_APPEND_FLAG([-ffast-math],[CFLAGS]) AX_APPEND_FLAG([-ffast-math],[CXXFLAGS]) AX_APPEND_FLAG([-fno-strict-aliasing],[CFLAGS]) AX_APPEND_FLAG([-fno-strict-aliasing],[CXXFLAGS]) # outputs AC_CONFIG_FILES([ Makefile source/Makefile ]) AC_OUTPUT dnl Option to disable this message. AC_ARG_ENABLE([build-status],[AS_HELP_STRING([--disable-build-status], [hide the status message at the end of the configuration script (default:no)])], [hide_status=${enableval}],[hide_status=no]) AS_IF([test "x$hide_status" = "xno"],[ AS_ECHO() AS_ECHO(["-------------------------------------------"]) AS_ECHO(["Package: ${PACKAGE_NAME} Version: ${PACKAGE_VERSION}"]) AS_ECHO([" OS: .................... ${host_os}"]) AS_ECHO([" CPU: ................... ${host_cpu}"]) AM_COND_IF([BUILD_WIN32],,[ AS_IF([ test "x$build_client" = "xyes" ],[dedicated_only=no],[dedicated_only=yes]) AS_ECHO([" Dedicated Only: ........ ${dedicated_only}"]) AS_ECHO([" Server terminal color: . ${ansi_color}"]) ]) AS_ECHO([" Alternate install: ..... ${alternate_install}"]) AM_COND_IF([ALTERNATE_INSTALL],[ AM_COND_IF([BUILD_CLIENT],[ AS_ECHO([" System ODE library ..... ${system_ode}"]) AS_ECHO([" XF86 DGA support: ...... ${have_Xxf86dga}"]) AS_ECHO([" XF86 VidMode support: .. ${have_Xxf86vm}"]) AS_ECHO([" Zlib support: .......... ${have_zlib}"]) ]) AS_ECHO([" Shared Data ............ ${srcdir}"]) AS_ECHO([" note: with alternate install, data is located relative to CWD."]) AS_ECHO([" User Home R/W Data ..... ${alienarena_homedir}"]) ],[ dnl dnl try to generate the full path for automake pkgdatadir dnl which determines DATADIR that locates data1, arena, and botinfo dnl game_data=${datadir}/${PACKAGE_NAME} game_data_a=`eval "echo ${game_data}"` game_data=`eval "echo ${game_data_a}"` AM_COND_IF([BUILD_CLIENT],[ AS_ECHO([" System ODE library ..... ${system_ode}"]) AS_ECHO([" XF86 DGA support: ...... ${have_Xxf86dga}"]) AS_ECHO([" XF86 VidMode support: .. ${have_Xxf86vm}"]) AS_ECHO([" Zlib support: .......... ${have_zlib}"]) AS_IF([ test x"${unix_host}" = xdarwin ],[ AS_ECHO([" GL_LIBDIR: ............. ${gl_dlopen_path}"]) ]) ]) AS_ECHO([" Prefix ................. ${prefix}"]) AS_ECHO([" Shared RO Data: ........ ${game_data}"]) AS_ECHO([" User Home R/W Data ..... ${alienarena_homedir}"]) ]) AS_ECHO() AM_COND_IF([ALTERNATE_INSTALL], [AS_ECHO(["Run \"make\" to build, then \"make install-alternate\" to install."])], [AS_ECHO(["Run \"make\" to build, then \"sudo make install\" to install."])]) AS_ECHO() AS_ECHO(["Advanced Build Information:"]) AS_ECHO([" See README for information and recommendations."]) AS_ECHO([" Run ./configure --help for configure options."]) AS_ECHO([" Compiler options:"]) AS_ECHO([" CFLAGS:.... ${CFLAGS}"]) AS_ECHO([" CXXFLAGS:.. ${CXXFLAGS}"]) AS_ECHO() AS_ECHO(["--------------------------------------------"]) ]) alien-arena-7.66+dfsg/docs/0000700000175000017500000000000012207204656014551 5ustar zero79zero79alien-arena-7.66+dfsg/docs/README.txt0000600000175000017500000003165712161401602016252 0ustar zero79zero79ALIEN ARENA 1. Introduction 2. System Requirements 3. Getting Started * Installation * Basic Commands * Completing Levels * Connecting to a server 4. The CodeRED ACE Bot 5. The Rewards System 6. How to uninstall 7. Credits 8. Copyright Information 1. INTRODUCTION ALIEN ARENA is a standalone 3D first person online deathmatch shooter crafted from the original source code of Quake II and Quake III, released by id Software under the GPL license. With features including 32 bit graphics, new particle engine and effects, light blooms, reflective water, hi resolution textures and skins, hi poly models, stain maps, ALIEN ARENA pushes the envelope of graphical beauty rivaling today's top games. The game features 37 levels, which can be played online against other players, or against the built in CodeRED bots. Alien Arena offers CTF, AOA (All Out Assault) mode, in which players can climb into vehicles to do battle, Deathball, Team Core Assault, where teams disable enemy power nodes to eventually destroy the enemy power core, and Cattle Prod, where teams guide cows into goal areas. Simply go into the multiplayer menu to start a server, change the game rules , and choose a map to play on. You can also select from five different mutators(instagib, rocket arena, excessive, low grav, regen, and vampire) to further customize your game experience. Alien Arena : Many are called, only one will reign supreme. Eternal war ravaged the vastness of infinite space. For as far back into the ages as the memories of the galaxies oldest races could reach, it had been this way. Planet at war with planet, conflicts ending with a burned cinder orbiting a dead sun and countless billions sent screaming into oblivion. War, endless and eternal, embracing all the peoples of the cosmos. Scientific triumphs heralded the creation of ever more deadly weapons until the very fabric of the universe itself was threatened. Then came the call. Some said it was sent by an elder race, legendary beings of terrifying power who had existed since the birth of the stars and who now made their home beyond the fringes of known creation, others whispered fearfully and looked to the skies for the coming of their gods. Perhaps it didn't matter who had sent the call, for all the people of the stars could at least agree that the call was there. The wars were to end - or they would be ended. In a demonstration of power whoever had sent the call snuffed out the homeworld of the XXXX, the greatest empire of all the stars, in a heartbeat. One moment it was there, the next it was dust carried on the solar winds. All races had no choice but to heed the call. For most the call was a distant tug, a whispered warning that the wars were over, but for the greatest hero of each people it was more, it was a fire raging through their blood, a call to a new war, to the battle to end all battles. That fire burns in your blood, compelling you, the greatest warrior of your people, to fight in a distant and unknown arena, your honor and the future of your race at stake. Across the stars you traveled in search of this arena where the mightiest of the mighty would do battle, where you would stand face to face with your enemies in a duel to the death. Strange new weapons awaited you, weapons which you would have to master if you were to survive and emerge victorious from the complex and deadly arenas in which you were summoned to fight. The call to battle beats through your heart and soul like the drums of war. Will you be the one to rise through the ranks and conquer all others, the one who stands proud as the undefeated champion of the Alien Arena? 2. SYSTEM REQUIREMENTS 1.8 GHz CPU 1.5 GiB RAM 1.2 GiB hard disk space 3D Accelerator with at least 128 MiB texture memory available 3. GETTING STARTED * INSTALLATION (Windows) Installation has been made very simple. After downloading, simply click on the .exe file and the installation will begin. Follow the instructions of the Innosetup program. If you are running Windows, you should have administrative privileges. If not, you may get some errors when the program tries to write the uninstall information to the registry. If so, simply click "ignore", and the installation will continue without problem. Once finished, you can click on the Alien Arena icon that has been placed on your desktop to start a game or the Alien Arena Chat icon to join the IRC chat channel. (Linux) See the README and INSTALL documentation files. * BASIC COMMANDS ALIEN ARENA works very much like Quake and Unreal Tournament, with a few notable exceptions. The player will have the following weapons: 1. Blaster (automatically equipped at spawn) 2. Alien Disruptor 3. Chaingun 4. Flame Thrower 5. Rocket Launcher 6. Alien Smart Gun 7. Disruptor 8. Alien Vaporizer 9. Violator (automatically equipped at spawn) Weapons also have alternate firing modes. In you controls menu, select your secondary fire key and this will allow you to use these modes. The default key for alternate fire is MOUSE2 (right click). There are new powerups such as haste and sproing, in addition to the venerable quad damage and invulnerability. It would be advisable for you to change video settings for however you wish to view the game, and what gives you reasonable performance. The game's default settings are at a mid range setting, so try tweaking them or adding/removing effects depending on your framerate. If you wish to see your framerate, you can type "set cl_drawfps 1" at the console (brought down using the ` key). ALIEN ARENA also allows for colored names just as Quake 3, using the ^ character followed by a number to set the color. Movement is based on Quake 2 physics, allowing strafejumping, doublejumping, and other Quake type movements. In Alien Arena, you can also dodge, similarly to Unreal Tournament, by pressing a strafe key, releasing it fully, and pressing it again. Dodges can be linked together into sequences, similar to strafejumping, called strafedodging. * COMPLETING LEVELS In Alien Arena you can play a single player tournament where your goal will to be to reach the fraglimit before a bot does. If you fail, you will be forced to repeat the level until you do. These rules can be changed in the menu system. You can also play people online, where your goal is to reach the fraglimit before your opponents, or by scoring the most frags before the time limit is up. In CTF mode, you'll be on a team, and trying to capture the enemy's flag and return it to your own flag's location. The team reaching the capture limit first, wins. In Deathball, the goal is to score as many points as possible, either by killing your opponents, or by finding the ball and shooting it into the goal (worth 10 frags). When a player is inside of the deathball, he is defensless. In Team Core Assault, your goal is to disable your enemy teams power nodes, then destroy the central spider node. You can only do damage to the spider node when all other power nodes are disabled. In Cattle Prod, each team tries to guide the cows in the middle of the map to the goals in the enemy base. Cows follow players after a connection is automatically established between the cow and the player, when the player is within sight and range of the cow. This connection is broken when either the player or the cow is killed. * CONNECTING TO A SERVER You can either select "join server" from the "multiplayer" menu and select a server in the list, or you can use the CodeRED Galaxy server browser (windows only). In the in-game browser, servers are listed in order of ping, with lowest ping at the top of the list. 4. THE CODERED ACE BOT Bots are a built in feature of ALIEN ARENA 2009. Several bots are already configured for multiplayer games, and in Alien Arena, each level has a specific bot file for what bots are to be played in each level. To add a bot, type "sv addbot name model/skin", and to remove a bot type "sv removebot name". You can also add bots in the menu, in the deathmatch/bots flags area. In your Deathmatch options, you can configure other options such as chatting, node saving, and aiming. These bots are fully configurable using the Botconfigurator program. You can change their skill levels, accuracy, weapon favoring, awareness, and chat strings. Skill level 0 bots are quite easy to beat. Skill level 1 bots are a little tougher, and do more dodging and are more accurate. Skill level 2 bots do more advanced dodging, rocket jumping, and are even more accurate. Level 3 bots are extremely skilled, and will strafe, and strafe jump around the level. They will also taunt you after killing you. If in Alien Arena, you play the single player tournament against the bots, selecting "easy" will make all bots skill level 0. Selecting "normal" will leave them at whatever level they are configured. Selecting "hard" will make them all move up 1 skill level. 5. THE REWARDS SYSTEM In Alien Arena, you are given points for getting kills (one point for kill), two points for special kills (midair kills, gib kills), and five extra points for killing sprees. These points add up, and when these points reach the point threshold (set by the server), they can be used to purchase temporary powerups: invisibility, haste, and sproing. Invisibility makes you appear like glass, haste makes your jumps increase your speed dramatically (linking jumps together makes this difference even more drastic), and sproing greatly increases the player jump height. These powerups last for 30 seconds. 6. HOW TO UNINSTALL ALIEN ARENA To uninstall Alien Arena, simply go to your start programs menu, select your Alien Arena folder, and click on "Uninstall". You can also go into your control panel, and uninstall Alien Arena in the programs and software section. For Linux users, see the README documentation file. 7. CREDITS There is a long list of credits - ALIEN ARENA is greatly indebted to the following for its creation and completion: Design: John Diamond with input from the community at large. Programming: John Diamond, Jim Bower, Dave Stewart, Emmanuel Benoit, Max Eliaser, Charles Hudson, Lee Salzman, Victor Luchits, Shane Bayer, Jan Rafaj, Tony Jackson, Kyle Hunter, Andres Mejia Models and skins: John Diamond, Alex Perez, Shawn Keeth, Franc Cassar Maps: John Diamond, Dennis "xEMPx" Zedlach, Charles Hudson, Torben Fahrnbach Textures and Artwork: John Diamond, Dennis "xEMPx" Zedlach, Enki, Adam Saizlai, Yves Allaire Sounds: John Diamond, Sound Rangers, Jon Ward, Jim Bower Music: Paul Joyce, Arteria Games, Divinity, Whitelipper, and SoundRangers Fonts: John Diamond, the-interceptor from http://www.quakeworld.nu/ Linux Port: Shane Bayer, John Diamond, Jim Bower FreeBSD port: "Ale" Gentoo portage: Paul Bredbury Debian packaging: Andres Mejia Alien Arena IRC Channel: Victor B "Bonfire" (visit us @ irc.planetarena.org #alienarena) There are other major contributions from the gaming community, including MrG, Jay Dolan, Psychospaz, Barnes, Jalisko, Heffo, Chayfo, Dukey, Jitspoe, Knightmare, Barens, MH, and Carbon14. Without this wonderful group of people, and the release of their accomplishments, many features would not have been possible. A special thanks for Lee Salzman for creating the new model format(IQM) and his assistance in getting it working for us. A very special thanks goes out to the community members who contributed to the crosshair and hud contest. A full list of those contributors can be found in the in-game credit list. 8. COPYRIGHT INFORMATION ALIEN ARENA and it's original content are a copyright of COR Entertainment, LLC. The source code of Alien Arena 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. The included TrueType fonts (FreeSans and FreeMono) are from the GNU FreeFont package (http://www.gnu.org/software/freefont/); they are free software distributed under the terms of the GNU General Public License version 3 (http://www.gnu.org/licenses/gpl.html). Permission is granted to freely distribute (without restriction) the game data(models, maps, textures, sound, etc) as a whole, and with the intention of being used with Alien Arena. However, it is not permissible to distribute, sell, or use for profit individual portions or items of the game data without express consent from COR Entertainment. 'rcon' and 'svstat' ruby scripts are Copyright (C) 2009 Tony Jackson and Licensed under the GNU Lesser General Public License The Debian packaging is (C) 2009, Andres Mejia and is licensed under the GPL, see `/usr/share/common-licenses/GPL'. ALIEN ARENA may be included in free compilation CD's and similar packages without consent, provided it adheres to the above restrictions. Contact: http://red.planetarena.org Privacy Policy: http://icculus.org/alienarena/rpa/privacy2.html alien-arena-7.66+dfsg/docs/license.txt0000600000175000017500000000277412161401602016735 0ustar zero79zero79ALIEN ARENA and it's original content are a copyright of COR Entertainment, LLC. The source code of Alien Arena 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. Permission is granted to freely distribute (without restriction) the game data(models, maps, textures, sound, etc) as a whole, and with the intention of being used with Alien Arena. However, it is not permissible to distribute, sell, or use for profit individual portions or items of the game data without express consent from COR Entertainment. 'rcon' and 'svstat' ruby scripts are Copyright (C) 2009 Tony Jackson and Licensed under the GNU Lesser General Public License The Debian packaging is (C) 2009, Andres Mejia and is licensed under the GPL, see `/usr/share/common-licenses/GPL'. Alien Arena, as part of its source code, incorporates an SHA-2 implementation which is copyright (C) 2005, 2007 Oliver Gay, and is licensed under the three-clause BSD license. The license for this code may be found in sha2_license.txt. ALIEN ARENA may be included in free compilation CD's and similar packages without consent, provided it adheres to the above restrictions. You, the end user, by installing this software agree to these terms. Contact: http://red.planetarena.org Privacy Policy: http://icculus.org/alienarena/rpa/privacy.html alien-arena-7.66+dfsg/Tools/0000700000175000017500000000000012207204656014721 5ustar zero79zero79alien-arena-7.66+dfsg/Tools/fuse.tar.gz0000600000175000017500000007340712161402016017014 0ustar zero79zero79Lfuse.tar;sHsJV`v$ĩ"6vņI.TB` i%aog v6i7FwƋ=c*\Gϟ䯺ё?UTuvP}žxѵBg?F-7~g ^cdYé >T^(a Adp$Ǝ8ow6;< ? ǚ-l^O=WI7L^svn]6cWg <Ӻaxw B3Ak(m]wo/q_~s ݪv@#n.ڬe>%vaZBy{#`-u<[x 0|%^Y 'd2j d=pBa0Fߜ3l. w-BDLsX1^bRS1+v.F3a bK0Tbg8{_\ju x3X\ϬVP(he a*K63d\euɺl&9u=XnlF\dvqoz: .7\so&,,X.wпn >"g%mvx:j7z{0ȕ!^]CSXG`^(l65o802\gB Lev HVWHWf-Ǫs5*38c~6s]޺A/Uk^z]nt5mRgF9ބj: ?9ylc,_ZS(ƘOKOk 1z;?<*2O$;>#-k@Ζ4t|d_}4~G̖$ͷWedxa1crcqO([iap TΕ}v&R6R|7lٛx7g;oGŴTtЄuk6nxq^FM Uţ$4DP4dF\\4& k dGޯ͞RXI;5_z.fm9] !t Q>ة |XQ^\wҜtA7<VGd5K{OɃT/1w/\¼@sEwN~i֥2 شmN]?h^hrm v @fLՋ寍v ,9ȾnW^it[1dNY37h`=]QҮqx/ -E|u=WL^O܋gX8'A}.m%!1CצJw-^HmX!j;-^4~i⍦u( [5Ttk !#p؆[0#ja'U O ]aY]_܀J9i[3ӧxf$@~OA| $h$I6MlKsHCxgeS>V1 2n(BxI vPpRbAQؚdKVXB20|n 8Ii> U4p4=֗]O{ɸ]6 Հs'If~[p)la閈<谂<2V4-G 2g1a masd5+`!Aōw}>> iMac^X,4u%t䉙rpEa_C-&KPA8_z8=毰 %y@ޣ#yJE|M(|?pQ44tù90v852:۞au8ĥ_1^f9y#/faÞ xn(iޫ  ͊Pj8 nꃔsB[)pHΆ}RS虘ƾ9QO:<̜@F0p:7Ck =CeAJu}yqp֋ozvo7l Մ?+=8ۛ8qz۹h7rlX%o1]HȒ欄$m!>ӏp3nd,p{TYZN#ןKvT:ݧ\ ]!mK ޥRfRIYl^[&]Wq#9nMMŎU]dXv^)3ZG] )4j=vXt#I?fcnfEcqKыh1ֲE+ ,)N*rfOh{Mfbg';R ɸ.&SzSwf>TR^}i5yd$>ECjf-G Xv9M1 AےJ:m w:r!NEL;̶.*.JHT?g=%]_K~WLJ7-(4.ŧXϱ[VgPm;+ eTU)}$;o\43U"eJ7a}+] rT8 %8E}YZȯҖ1_Zb")ƂN; c2l;ׄ/2W^&y҉T4* hFЃأG*j1g$r&!x}_Z2ec,$cArwYgVL`<qܬLS *W,*nAPʂ$2C޼ L?hCEl9MS`x655Dri[T KZqXZ uBHބ{/&KF]ZKaW)oRw9e9)Co~RY &w- 4i*ZD ϚP*EBKp V:IPUIZAjM`V1,4RThA" GnGΎ1@[%3[UFҗ%]ʬn|l.E宮᳀K|"VhA։t\Y\eKZ\O&KIl󱹘2O }ʔQ\q],XP"vV3P{FULV-3^TTTEWcs. AkM赊QH&S~㜇m3 ^,=KէaO9>9UPRnkbD5?yowé++uhe_k^RR9ZdFԢ q(#lΓb0,fo,܅}b(, O/De|*yhAT4}k+RUj9)&$v_vb,S5/b}8])-Eb'*: 'b9;YDΊq7dqe(?/<|z}Ƴ UY T&%S< $ꇨUb"vT=zX= jG咈p~H]'T=Ur(uR]R,l inCqijZ۔%ElVM[jf_$nH*JЙEH q%W:KՊ(E$lFDNTFLbksϟE#)ҿg isX1K]rٓ.KDdYOLQ;Ha>HZ|Ւ&1կL>9^)pp\p .sR@ܹ1EhaÐ]lb%!sMMM/f/-}ZfP-d=)u0]& /*zEU;zW1i*$2R9D$ oBE/UFGnp&~10<3#|0_8&:Lb.\>YwNAgo㥩4 {`@ObXNWq6A!WgXX,cSG Ԝ0ds/\.YRVr+w x)d/SžG CӍNTZ5{L! V@fiD>ˬ9KiNrM E2R쾙9y} rLFR 'xX=߻9t +=z*b;LgHrQ(AccgO7͞Z|wyN%]" 쮏g$uWyFIj3dA3 X[K?ܫF^ly%tS\IV2AOm2T@;v3>H-a@EGڥAWYde%?Y?%>p2r{i$b[k7+_ӅTe侖TXQ[ +2(jh$ [#-+H鐐F|g3}O \Gy ^e|m0~!gs2잙4\aItiM_׭ј` ?D^]6cB?qְp0"Ƅ+&` 6X~U~=#H6jꫯ Ž hnK(r>OKQou5I;' S oM2 Z|P1$W@>97b݇Lvj6ot5c*۬NڬjՇ3ڔ4hT+H9U ELkc+c%LԀ;xܵ Yg|;y0O48CXH;_ww8 , 9v2rl;O5=;^+ariʽ<=zB<62`q㽒a1(3;ʩ)+]-)>Oi+ Fk`6CqN9x\ʟRTk\.!hh5-#=,d%{M֌UE_b00$ѝΰBMfrR &u29i#Sق1|vnWgبh^&»/4jOέ20-\Oطe*@xRc6m]v)_`]1Bkr)p1}od6s";Z4$F=BJKʈ Rʢ+e3|;$]72|k}.] O˯ŊL#>e>XMMڛQtz5XC VFA'O5SS>$[NRz(tt J ,b9ogtZv:i⑙q%  lj}zSZmx+<YۘaQ1.mObo:m4Ϊ%6F_b/xVQd|I:A e/ӫU'2kOH̀zZ 1.Nă !8U E@5w"%[]V(RX X`AQI` S#ƒ@0R=R\'z)d/G5H }>#ku**E_Q7uN1o"H:jk;YP!!}kTȃ i*.վx15;i[brb0HVnMM|GQHX͋ *TJ,RN@oW^x6jrkH/:Y{nϘ"w.K`$Gƭ8`l5[#΁$qjqH\eSgX MHv b,5ȃ)ʗ>f ]ar9 OmktU8r#ݐ{JYӔ7 lkSRwLȂvP~g8oP\*G3V"kp{K'1aA i(8+i% [QA=bd{ cɑ7XoyՅ1+N@A{eB5l AaACxX@תZ`9qjlJ0 2czPOmxIŘiHSGҾmA)W$^U?Ȫgʱ*rR݈pݤ;$uten"7K \C3DY e!yʮc׫+۬Jjh;%j/nSFb'y[eh,P('vɱʾN6;Q([茗)H3],N&g6>93KKOhI>xcjilV0niĬ  !F#)q3UcK0Z;ݣS 'J8NŒQ2@2șeni ;7o^*͑: Tcip 03xziT`_':2gORh(x)fr`k(`_,ք 1ŨpB&ot}\M;rc{L6a@B񭓭 D=/#XfhR)IeQniu@oZ,L>5=<}%̺"1 -€YYxSJɣJRDab^Kt!nD'm4lmb39~~ #1m(> Ћu.3" ěkh.T"̆+RBzv#|p2r'Q̞LsX (KJ%`ѣGGO(Y a/DCkGNY=b %sRM݊Smp.'@5(od0ݙW-KDk=JAĞDxwP ~rtNUVYx`||ؐ"+WȜjZ2ϯQ[YH5_x7āY4 ۩ղdQ߄s~JCDjJ^^F&G@L]܂ci 0 O{G)z0%oq/ح|Xn_BIc;A3|mWsEhؘ߱9 dL{[ϳaZ3 |nMn|+Ҵ$ӤIiZgjzT@*?M'6OC.(vj)SWŒ^\[C1YX(,b)Ox1ÆyE@Uh$@j0P˗6ᾝuj1kGTi,k<%ԄzXoz{5\ro|_72j,j[ #܂ZWyIs⼝K2.7C"*K1Z ȰwYۨ;ܥ<(d^-R{9lQ<KՉo'Aêg1J;λb:4hA2)ӬRTln=)q,ݰ6W̆'[fSoUɆ/XOeu7 ^nqQu<.` ,g@mF,-h˩5Z_9EJRzV'!܃| I GE}Kj8otnysVpa;po>ct " ƿ$3$*$ux"Cr KC([G9 }+,$UUʋW @"2Ud,cB$8#cxX|/1'㉱?'$1KMHG'H8]50:8'`6mER)+ 0VL9Q6ZN$ou") l3(zXS9;301;E L֑HZ62Np.T$T.VxAh(:䔝+"e{ZUbώD]J9` Z$v =YK = a:KoPz,J-@\Vr㙐)FB糕XD"d 0gՔLTʀsbI 4c\0SMEwe aU"8<*qwnSI"jf&fJ`2O ,6sJb-a$F njдy`: 0<ơ\'4@:] 0}Dz]F,I4R:*,`T`|D<= di7 -Zfp  fS} OhA~`=kAd"+WYZy|nv2SJA !v[Ki̕N)Vi\< bDZH_cۙ,w8TEBM)N[S.x|3 )b3Y*4yd'ҹ%dwxÒ@ h\0V3JGRLDSQ7 :B7Eg)݂jl)KD:_>HR=]J3HGٓaFz#'3t/#  >Z`UOpP' R#fa[vr<ʑ "N0cJa%gtbMiĠSb~F("JsT%l&t^d V>ěj|)Ld5IeX#.oIr55-+s2E.>$<.:XS5xmhxbiEX,fhNuT oc$RgQ匆TOPnC}N}#lL!3hhD`؊ U@zly)'D},3 i-hLh G &1= EwB/79R@>H_Yy; ~qLi`>*`A瞜Q7]az*3MvUrrKbd<{B@j)񲝠CyP]gZK/^OS*q)ˬ ꔒSLV`fR>/^d08^PTuZр' [Y{Aesn)i` vz,!IS׾)f?ݫ,>r%P_"<e <,K:6ľ0h ]"o5YZhw⺕58?bj'-@ $#/&ǁɫM rmҭ%0* d Ўu4VQx)h:)hwcVYAhyFIl _VbjP!U,_Sj=$H9O A`lAt?_68#6Ѧty$RzuP|Bp~QE#ՑwЩhSg ij!w#M6^1<^ ̉8.FG eQ֌2tYxTL1Mk|Xkt55T.g~MgV8Em;)N .R*3Or 02;>6Kf&Ʉ53a]A!Dn팏HİXK0@FwbxbxM ޽V|tSƨnĞ踵{gb82w>8Vv  ;6c縵sd?1F:UFcd5TS< h7YwLks1+1@{FI`  x9078OQ/:#44Pb ox<;08Mbahy`:116:L $Ɉ&.݊D&k@U*a''vBIh&91}o|l/%Rq%F0 =6PFt$v! L bo7L@B(aw`= '?FU7{F^+a~3;c ZNQ|(#E4P2$z;B?z'_ 8c/ʇozS`6Gz|]=DRuƮmI0f*s]m0ʁ݅"ZC!x69AnMU9c'n*5`$w c|@FzbJ4je)V,ϴc ڑl}W6vuuVH$P٣,E߶Jam%[\*f3uUur&LOާ 5;ƯZa;W,.Ζ`n 64W+lMbKV3 ~"eԃVWqQXepl!13v[˹mwfLX-Mf3=oj˦ Ԍ:awvF"Q.vxQ VJގP`Б@vk%y *"-سl R;ڮV ձ+&_̠ }jÖ͛:6vLx,I0!e[yٱeo\7tumK;]S$1.Xl74$ IT}uÅl:]UyaJZ;}ҿ/~nZ禍]5?7l:-_O{ IuKTؽ]ih /,,Xq=3ϻTŻ (ͧRC^ԭax;ѥFJr֭Va36JY LWs6iHC9 W+5&3݀Ō3p Ovw:XܢGg)#3nt'AW=t[ ER9p@a=; xQoѩ`eM fDg 8]j\kVC6wh_|hF&M#sL_vwsZb9bj3Dgsz:f tfO+R2>>|Q܅eZpdL Qr?,dcD15WwUcjI9Z975&͊gK8Q*}#%;rxUZLDp4hSe<ǕZwe8|VH[-jݣV@j9uG8~Z8(f>|%{ji 7EP|'}6L -AtodwdwdOԜu0QS#|$ԉ*RT/9MV|wrlҶl!J3%/ Lw3%8'2KS ^᪨yOW*ɻau)cV%::W 3P,J|/-DD "f-G5FϚb%&svS܅LN1y$&NÌ߼1 Lj/dzYChRWʙa(T3cL>k(75%K\&S$m,YMkRy;մ WbUx&i-gV mӉuP63Eyh2(9*Y>IsrIӒ촔,ITiMiM^24s "Ɂ}QJ\NRcнib΄By<6p&E- TղS,֡M)\3`k0V)FUٶyiba%YR*uG:%#y4dJ?>0>YcɁac *45&zc0j6QrFm#-wJ;1s3uƋF># E[E$ L'ҁ$,aHmNv:Z,SOnjWo_-U Q䲇9R7oV)ݟ8|/裪bh6oFI2QBՏ6/3,ޣ7d%pq8}cpT }%RX%KfVf@ mYӖ LME M e>8T@gƲ"},D*dC:ꅸ?tT O?wTC32XwK|YcP{:`.:SFΡn2Fn1-n@MiF}/jBtj#jȎމŴvYUC5).kXqNzkwN7ĕrŷg'u?[yekSd>#o '02&t鹨PVdN.@6q &1] =̍De60-Pd1+Χm;5SGG2[36oЗm-O=audm}mF/l=B2 0R31sb&ާ]CIMDYWæc1c,^V#b9Ss *f_o ݧ h =$3wK|z,5X6Z TԘE'Of%}֮>jLOIaQp&Yo=OutQ"ϕiΧr;5~쑒Fо`Gt9zMt Y7_ԙ=ī LV<$(x =SZpјet &;-y+ LZ :nvGHA153R\l6ZCZ?+?')h#V{g`&@NM|8;pE2>EF\? 82< SPo1 }vԌ 끲Q㭨܌^ɤĝj_ӣOB6Kk)ӨCEL+_\!S$IޖlHXER=4&Jߖt8Cq < })A}n"WӀ}$ь$ D0ьRA151833xB \ H-/S-¢ 5ULÒ/hldubc+X+<)[GnHn0^bShMǦc7zk#Lb=Ʋ $[$ʼ㽉ET%н'2ҡfe{8kd'wNFPJxt,C=| xڴ9Ul.T-)De0L [7z8Ӛ0'+739vwNڒ.Wn%َ m$6b Ty`iڧna`6vJP'[RlA\whv"T)TVoZbw:;Ҩ/"G_4ԕ *ŧy0cކWNk9H L*cHqt2V^ $UQ.z2:Vy!t5sqcXbXAXߐ6#;M]OZ](%E;x,o>B6|.z6mbqRӟSJxjc)ccY':"}}̤Ӱusfy"ʉmHf՚ZwcU Ggj4UN>=1V z}ͥV)pZ[Yc}kW[͋Sйhfy`0[\TMxe\.~Hr/ 6;XNW"O#;ǰUYueV^%uS ұb QlYg[OYq'2LēI793c)N`I0/ly'k6]kC-3Dbě}6a:'og+7ZD0]V"kljjiiROg)dURK>my¯Dtu`V%esd}}i9Z#mV`*Sa:׸Q~F"&)@rj q+9Olc}ee9 o j%.hm] Z ':/gUdF*YT0:hY@fe?fnQU%Fˆ3!f+t‚;xȉaiqaP~xߴD_q%' ͛/G<lU`UTs];h%'Tjn/J_Xmue)G<>U1*!CJˠ}^7wF59ˍxNO*ƫI;jr9LT/<ƳQlO2VȇH%jc7-Os:JLp1IG)ƍ 'UkI\n =et1,v7PfR!E>PN&Q]Ow/=UQ 耟fT 3F(ĵ Eg1cF Qސ 36IHvpbh8vLMLbSUρq> qTO@χFbzXĤ=ph)6qp /X)'m0yd4$}rdl26,?z'Gy,;'#j͞3ޝS9RG#}KcjTdM/nB U8Vt󴨐_vvtpzrqf}9atbGCYz$4*γ歙Q7kRD41lҒ i.N\˱ = xy`&QFM*R;Ѧѭ&FtNHj`tr(@YAB00:eP$c(7_;/ /@a x?A͗Ahbz S)Eo h[>h!*N)zD{Zj/]v'۫#s6]7FuI񱉄1GWS#EBCsH`iUŰ@9hA\ɈN& F)uN(> bKjuR:jqn22aHY;F2 4=5R椠K f%8f0Uf0|x;)bkyNY@őY'<2lEx›g-CF-ۭUǮ9W,jL9.92,4klYfioRq-XaMiXVu LjnSyETN11U<kԚCKR NYAir4voIU =W*TSa.lӎyZu̬ŴHI*ό'*+TWُ;п^ գؚG">K7Re_A oӎ,ߩk ?:["\qztE!e,9 g:r>V@ȐN1Kt9-X- ou]HO>E7{HsY1fh䁋`^Buju|ʧ.<_:@̋mR  vL[T[ phCCOGo{_meׯw%t̠ |EbGmc ֯W'sΒ}wLcx{K%@3m-XTjc2L7ƚ6TrA4Iq]?\mhfyFOe2[/U!m%KրL(ZjPY{_o' tӬ:.e#L?d5EXS n6}*t3IK>Ur5ӦС8X u t`EX~q^\զD&߱٩nDZ̈́YFM'HsL]X+ Y5Cj/KTRW. 'W¹X )3d,aoaL^mB60 Ȟ*M)W7^oxVc㿉Y&}GO~u]q8{N>s7wGpm+~_OҿWАwg/܀gO=gOӿ>x7{/;uσo='>ă9P`cn~3K+~?yzYg\)~s[ ._tx%c]&~5kﵴwb]]] i2>.W_%~s/\/;~pR_FģGď>p#?:[|CGV'>Rwx爿9WWy:O|[狿W3߻@|ϼF|ǗOR]&>g~:.)Oon6 7_Rp#ܯn_ѕCtS1ȿb/Ito;G~G~P/>O_o_'h\>!YO!Cw ̧|~ }p.>Qai7A}P'޹ A} Vw 2¨or,9P\o] mP?ԿQ_+FkDIş!gĀpϿQ%ppG3 2[P3SP#1?g>GP]?Y6OgwO:]\CŻ\񫏺k~+ԿA4? APCOB#PFWꯆ~ o{!CTX?y/{yGo=+> +V +^)NKW L\zꟵ근:~7B[<߹x7N,>~I;[_{}}o]?/NʎC4;lv}|񡎵vMeoh/i_Ss$o`y|%ri9 n=UrCvjbemc8947mt9TM(CK`*=iΦPڡwM ɡܸkϞ]X\$_sすCKl޶m.25`͍vĢk/+c:wȾi_tt276t}g{[[[Gxݽ>vK\rtxhpphx49w=;uOHqz_~g/Eч._W}\*׊/=:'sX7A乇}S`kWo<^#(No"n?."oNɉ^#՝]7qݗ 1zťk[Z]9l: g,E,؂.؄/_?~_:]gwsOHC ]_?uf {ܟ}ZuF/=c绿U+\/C}nO_au?oqot݇5o>'~W`_Qc8~gDZ{^zE3}GtN:`Ϻ ݷu?azݷs{g. m۴dBƦ?;{vm_[< ￳b~{ߝws{o]մ ,nݽ .~7<x_Ź{{5?}ߪSj.'2>xw=3w~D#oy+;֬ixݿ/v+_2'/ttu<?⏛>}\o̗>k԰uu1ȜZAVl&y+-aS?}vA[A<i?:O.>M$Ws},{ޣz>Ȫ޵GGUq˓EPQJ\@6"Yل҆$&+JlݽݛX-T_Z+ױUTEyHC(-d}3w7;vsf;3\mcW:C=Xs/L#I[8چ99f!/NcʟWCF5%;y&:*AvOB=d<>b& C;NkQKN|2hȉ_&dՕmF4W_B܃SA-.9 #O16mxRBmE>6ͼ Dה&i vvbo-[KCr;hݑد.`Gݿ ˵ȎCirbYd*֟+ƒ &`'Wͤ: d`5ݓcяP?+kcԾо<u}xJrы[]IP;_CQ/?;0*2 }C5O}4_mpU)yq1AuЇRȊqdGcȆc&ۉжɽI rR^Y >}O{ٌM__?*fB_9 '6?>Py5}X]B6`ތvp| q&//Mc~࿘C#OB>}[wR~`cq-@>E@u@o|v1~?ӶgH.`ԪT}|1E8 1v}]x`8~@ю'mǠ+n%_.ri&;7q\X{C]G?C B|A]cC<~|r'#n(;uIT7^@¶RY ц uc`)}fQsN}sgKJ_̷*S@}Mא-=#+>w`?\J}}ϺO ڧxcKļMB>2> CK#lq+ f2(>o{yQ=F];{4r6zSDoAMe` {1c1d롫ɮMQ9 Y,i\> 9q 佯U<.740h+qwO+}z2yox2I5n>~K v-AyDZD;8e ;L^pԻK(V‰_F_4b|㾫'~7l 'wC`q26NX[Avj瀼; ziv|*3'ާv֒gX{@Ɛ}W #>ގ>52>ŢPH1~ĺ"Cύ:|8rM~s{'+XEV˯"wF[a]+d y"|-Yy{%Yy,yk5êwep'p5\6QmO[YYQa1"<AvF;95rXopJIӧ_;^etgcܦ:Ab7_Jv(>Ժ^(]mw !%y(kegi#H?WTb.e)^#/ ײ}j\G> Q#b_vz~--РEp,Эj>Lv˧vr<ݐO6QҐe<@DÚ`/|j=i$$jJlIvTo?wp'PdBWK*=0ŵ޳ = 7[=ى;T_w̫q#tG;a__a%.YbEkd5|cw@mNAT錄FEj/ٞ6.;6pY^.5B'jwM,pG g- (‚D UЅsfgC`yI|rY/kAV79d z@0m} `{S~bo{GviT1?4J [6Ctҽ=n.ܸRv67y ͭwg-#b~`."rۉyTať !cdKÊ@> +DdsBh2k_T/z"2_ 38DJT0B.+1oGBD%dglBNSx(I@ –li>MUh~sGVQzhRʯRRRۭi0ء̷iH>%TFg|6#r ;X^nw ғyZFP|\aDT#ϛ!KȖ#sZp6繁-j \拜۶Ke52./|]K)1AMUZ µԡ7(ErӟgD)7‡6geƜ@<;SñHƀ=,Mn$dg>ݦ.Fqb7;^D i7?IgG4"%5H{^wܼ p6U]:gz|tK|_n{ qGJS+jUAG #jT53/x|zI$*E֜S5Ũ8VJeoOt韱Y;* S&)-^ъ}qi[mt/r䪢'k][sRprة[pʫ1e|3w݂LՒPL_15i6u$&d6_yMcFsDeC Z& :r=M?4qJ)29\&K%bAO}~'絹*9`E>@)jE`Vuslŗ1.7 c/79FhySz3$yw9T9@Gb$9 "`HkHfKR16x 2272;27^>TytZ=obq8 -pMC1@p!`l т ^YCadžVᒚ )ަj2Cwhq" bX7=:aMO0tf̣{qN~6T 8:4L_Y!I\)ӭ8~'Jd|~/>07VŽ,MR bx)|"MDN}D"eN(̎ Kҭ,5 S2+0^$cHs\Vr9q~3$H^6'ΥAl4*n ,3La3K茥e3҉˛.I9_;5cL~F4Ȇ98A:d1D}^597ǿSXH:W{-@G 0TgRJYba-E-H-60AT ^,xैE@i2eۇ X,`)`4`.6`*yXr΀[H$DbⳀ"1XIES_2g7t:|Y\B@ >[; -XAB# DѨ KfpEyw ,@I if YdH t H ^)–Yd!HT=EH׍ "-U4_I$Yd "!>𘤯'Ȃ# D EG#FI ,4H qH$E_g٣dGg2cԮoҩ]_:? ~d GS}q:Os6ut)rЭ6 %9$UI_ o3ηUWͧ;NF7spͬ3٫]}W1n?𹽪|Tg>QKlG] R#]?,"K-MF\]wU\yM- kdv}E{jŌodopX95 O +T0*z,,S7֤8lXGsbEmAէmmx`bxeE,n-tz-3DO+Qq ކfWT*b+rQ;lxe[uYuYuYuYuYuYuYu}կ&alien-arena-7.66+dfsg/Tools/LinuxScripts/0000700000175000017500000000000012207204665017370 5ustar zero79zero79alien-arena-7.66+dfsg/Tools/LinuxScripts/rcon0000700000175000017500000000714212161402015020247 0ustar zero79zero79#!/usr/bin/env ruby =begin ALIEN ARENA RCON UTIL (for server admins) V1.0 Copyright (C) 2007 Tony Jackson This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Tony Jackson can be contacted at tonyj@cooldark.com =end require 'socket' # send rcon string to all servers in array and get responses(not yet implemented) def send_rcon(servers, password, message) if servers == nil return [] end query = 'rcon ' + password + ' ' + message + ' ' + "\x00" connections = Hash.new failed = Array.new # Get the time before sending any packets, to time server response time (ping) starttime = Time.now # send a UDP packet to each server in the array servers.each do | server | # Here server is of form 'ip:port' string begin socket = UDPSocket.new # open works in the same way socket.connect(server.split(':')[0], server.split(':')[1]) socket.send(query, 0) #socket.send(nil, 0) # Test failure case connections[socket] = server # hash keyed on socket resource, containing server string rescue puts 'Failed to send to server '+server # some failure making a socket or sending a message - add to list of failed servers #socket.close - can't use this - may not even be open failed << server next end end # remove servers from list if socket failed to create/send UDP packet servers -= failed # check that we have at least one open UDP socket if connections.length == 0 return servers end selectsocketlist = connections.keys # get list of sockets from hash while result = select(selectsocketlist, nil, nil, 0.5) # select() waits for one or more socket to get a read event, or times out ping = (Time.now - starttime)*1000 # store the time at which this server (or multiple servers) responded, and store the replies in our array of buffers result[0].each do |socket| begin # here connections[socket] gives us the 'ip:port' string of the associated server puts 'Server '+connections[socket]+' replied in '+ping.to_s+'ms:' reply = socket.recv(2048) # big enough to cover both games server replies and master reply with 256 servers (payload 12+6*256 bytes) puts reply.split("\n")[1..-1] selectsocketlist.delete(socket) # delete from array now that we have a reply socket.close rescue # catchs both socket errors and nils in the split :) next end end end # here selectsocketlist will contain an array of failed sockets selectsocketlist.each do |socket| servers -= [connections[socket]] socket.close end # return array of servers that responded to our queries return servers end # Program starts here # $* is array of args if $*.include?('--help') or ($*.length < 3) then puts '' puts 'RCon utility for Alien Arena servers' puts '' puts ' Usage:' puts ' rcon password ' puts ' Optional arguments:' puts '' puts ' --help This message' puts '' exit end send_rcon([$*[0]], $*[1], $*[2..-1].join(' ')) alien-arena-7.66+dfsg/Tools/LinuxScripts/launchservers0000700000175000017500000000542312161402015022172 0ustar zero79zero79#!/bin/sh ##################################### # ENTER CONFIGURATION DETAILS BELOW # ##################################### name='Alien Arena' execpath=/usr/local/bin execname=crx-ded if [ ${COR_GAME} ]; then cfgpath=${COR_GAME}/arena else cfgpath=~/.codered/arena fi # use to generate core dumps after crashs ulimit -c unlimited ##################################### # END OF CONFIGURATION DETAILS # # DO NOT EDIT BELOW THIS LINE! # ##################################### # Written by Tony Jackson 14/07/2008 # Updated for Alien Arena 2011 # # This script expects you to have screen installed, and soft links in the arena/ # directory to config files. The soft links must be named portXXXXX where XXXXX # represents the port number that config should be served against. An example # setup might look like this: # # lrwxrwxrwx 1 aa aa 7 Oct 13 2009 port27910 -> ffa.cfg # lrwxrwxrwx 1 aa aa 7 Oct 13 2009 port27920 -> aoa.cfg # lrwxrwxrwx 1 aa aa 9 Oct 13 2009 port27930 -> insta.cfg # lrwxrwxrwx 1 aa aa 11 Apr 8 2010 port27940 -> emps1v1.cfg # lrwxrwxrwx 1 aa aa 7 Oct 13 2009 port27950 -> ctf.cfg # lrwxrwxrwx 1 aa aa 16 May 13 2010 port27960 -> empsinsta1v1.cfg # lrwxrwxrwx 1 aa aa 18 Aug 24 00:54 port27970 -> empsrockets1v1.cfg # lrwxrwxrwx 1 aa aa 8 Oct 25 2009 port27990 -> ictf.cfg # # A soft link is created by running 'ln -s ffa.cfg port27910' # # Running the script will launch each server in turn. # If you run 'screen -ls' you will be shown a list of active screen sessions, # which should include one called 'Alien_Arena'. This can be viewed by running # 'screen -r Alien_Arena'. You can then switch between the console of each # game as desired - see the screen documentation for how to do this. cd $execpath # remove spaces in name sname=`echo ${name} | sed 's/\ /_/g'` # check for existing screen session or start a new one present=`screen -ls $sname | wc -l` if [ $present != '2' ]; then sname=`screen -ls $sname | awk 'NR==2{printf $1}'` echo "[OK ] Screen session $sname" else # launch screen screen -dmS $sname -t shell echo "[STARTING] New screen session $sname" fi cd $cfgpath for i in `ls port?????`; do cd $cfgpath # search config file for hostname and pull out hostname=`cat $i | grep hostname | sed 's/set\ \|hostname\ \|\"//g'` # extract port number from soft link name port=`echo $i | sed 's/port//'` title="Port $port => $hostname" cd ${execpath} # See if this process is already running pid=`ps aux | grep $execname | grep $i | awk '{printf $2}'` # See if pid existed for this config if [ -z $pid ]; then echo "[STARTING] $title" # launch server and attach to existing screen session screen -r $sname -X screen -t "$title" ./$execname +set dedicated 1 +set port $port +exec $i else echo "[OK ] $title" fi done alien-arena-7.66+dfsg/Tools/LinuxScripts/check-master0000700000175000017500000000076212161402015021655 0ustar zero79zero79#! /bin/sh # # AA Master Server - check alive # Author: Tony Jackson ulimit -c unlimited ### Master Directory dir="/home/aa/master" ### Master Binary Name bin="crmaster" ############################### # Don't edit below this line! # ############################### cd $dir # check server is running echo "Checking for master server..." if `pidof $bin >/dev/null 2>&1` then echo "Master server is currently running." exit 0 else echo "Master server not running - restarting..." ./$bin & fi alien-arena-7.66+dfsg/Tools/LinuxScripts/README0000600000175000017500000000164612161402015020245 0ustar zero79zero79'kill-runaway-crx-ded' and 'launch-server' are shell scripts designed to emulate running crx-ded as a persisant service under linux. An example crontab that would check each server is running every ten minutes would look like this: */10 * * * * /home/aa/cron/kill-runaway-crx-ded */10 * * * * /home/aa/cron/launch-server ctf.cfg >/dev/null 2>&1 */10 * * * * /home/aa/cron/launch-server teamdm.cfg >/dev/null 2>&1 Additonally, a master server would have the following line in the crontab (most people won't want this): */10 * * * * /home/aa/cron/check-master >/dev/null 2>&1 Don't forget to edit the launch-server/check-master scripts to set the paths correctly for your executable. 'svstat' is a ruby script that will query local servers and produce some nice output for server admin. 'rcon' is a ruby script that sends rcon commands to servers 'view-ip-log' is a shell script that parses the contents of the IP log. alien-arena-7.66+dfsg/Tools/LinuxScripts/randomgravity0000700000175000017500000000153512161402015022174 0ustar zero79zero79#!/bin/sh # Random gravity script for Alien Arena # Written by Tony Jackson 15/07/2008 # # Configure below and run using: # ./randomgravity & # To stop use 'fg' and ctrl-c # Calls Alien Arena rcon script - you must have ruby installed ######################## # CONFIGURATION # ######################## aapath=~/alienarena2008 serverip=localhost serverport=27910 serverpass=your_rcon_pass_here delay=5 maxgravity=1400 mingravity=100 ######################## # END OF CONFIGURATION # ######################## # Do not edit below this line! while [ 1 ] do sleep $delay random=`dd if=/dev/urandom count=1 2> /dev/null | cksum | cut -f1 -d" "` random=$((($random%($maxgravity-$mingravity))+$mingravity)) # echo "Set gravity to $random" $aapath/Tools/LinuxScripts/rcon $serverip:$serverport $serverpass set sv_gravity $random >/dev/null 2>&1 done alien-arena-7.66+dfsg/Tools/LinuxScripts/kill-runaway-crx-ded0000700000175000017500000000026512161402015023250 0ustar zero79zero79#!/bin/sh for TPPID in `ps -eo pid,pcpu,comm | grep crx-ded | grep -v grep | awk '{print $1":"$2}' | awk 'BEGIN {FS=":"}{ if ($2 > 20.0){print $1} }'` do /bin/kill -9 $TPPID done alien-arena-7.66+dfsg/Tools/LinuxScripts/check-configs0000700000175000017500000000503112161402015022004 0ustar zero79zero79#!/usr/bin/env ruby =begin ALIEN ARENA CONFIG CHECK (for server admins) V1.0 Copyright (C) 2009 Tony Jackson This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Tony Jackson can be contacted at tonyj@cooldark.com =end # Program starts here # $* is array of args if $*.include?('--help') then puts '' puts 'Server config check utility for Alien Arena' puts '' puts ' Checks map files listed in each .cfg sv_maplist are present in data1/maps' puts '' puts ' Usage:' puts ' check-configs' puts ' Optional arguments:' puts '' puts ' --help This message' puts ' -all Also check against 3rd party maps in arena/maps directory' puts '' exit end mappath1st = "../../data1/maps/" mappath3rd = "../../arena/maps/" if File.exists?(mappath1st) and File.directory?(mappath1st) then maps1stparty = Dir.entries(mappath1st) else maps1stparty = Array.new end if File.exists?(mappath3rd) and File.directory?(mappath3rd) then maps3rdparty = Dir.entries(mappath3rd) else maps3rdparty = Array.new end Dir.foreach("../../arena/") do |entry| if entry.split('.')[1] == 'cfg' then cfgFile = File.open('../../arena/'+entry, 'r') # read file and get sv_maplist line while (line = cfgFile.gets) if line.split(' ')[1] == 'sv_maplist' then maplist = line.split(' ')[2..-1].map! {|map| map.gsub(/\"/, '') } end end if maplist == nil then puts "#{entry}: warning - sv_maplist not specified" else maplist.each { |map| if $*.include?('-all') then if !maps1stparty.include?(map+'.bsp') and !maps3rdparty.include?(map+'.bsp') then puts "#{entry}: sv_maplist error - #{map}.bsp is not present in data1/maps or arena/maps" end else if !maps1stparty.include?(map+'.bsp') then puts "#{entry}: sv_maplist error - #{map}.bsp is not present in data1/maps" end end } end cfgFile.close end end alien-arena-7.66+dfsg/Tools/LinuxScripts/view-ip-log0000700000175000017500000000237012161402015021443 0ustar zero79zero79#!/bin/bash [ -f "$1" ] || { echo "Syntax: $0 "; exit 1; }; cat "$1" | sed -e 's/\r//' | while read lf_addr lf_evt lf_hasname lf_name; do lf_addr_addr="`echo "${lf_addr}" | cut -d: -f1`" lf_addr_port="`echo "${lf_addr}" | cut -d: -f2`" printf "%18s %8s " "${lf_addr_addr}" "${lf_addr_port}" case "${lf_evt}" in RVR) echo "Unknown protocol version"; ;; R00) echo "Rejected - too many connections from host"; ;; R01) echo "Rejected - userinfo string length exceeded" ;; R02) echo "Rejected - empty userinfo" ;; R03) echo "Rejected - end-of-message-in-string exploit" ;; R04) echo "Rejected - attempted to spoof IP address" ;; R05) echo "Rejected - remote connect in attract loop" ;; R06) echo "Rejected - bad challenge" ;; R07) echo "Rejected - no challenge" ;; R08) echo "Rejected - already connected" ;; R09) echo "Rejected - trying to reconnect too soon" ;; R10) echo "Rejected - server full" ;; GRJ) echo "Rejected by game" ;; RCN) echo "Client reconnecting" ;; NCN) echo "Client establishing new connection" ;; UUS) echo "Player ${lf_name} connected"; ;; DCN) echo "Player ${lf_name} disconnected" ;; esac done alien-arena-7.66+dfsg/Tools/LinuxScripts/launch-server0000700000175000017500000000313712161402015022064 0ustar zero79zero79#! /bin/sh # # AA Server Cron Job (originally TeamSpeak Cron Job) # # Usage: launch-server # EG: launch-server ctf.cfg # # Author: Chris Childers # E-Mail: Chris@darkstarllc.com # Modified by: Fafa Paku # Modified by: Tony Jackson # Updated for Alien Arena 2011 # 2010-12-04 FIXME: could benefit from some documentation. # # Set the port number in the .cfg if running multiple servers. # Script checks the existance of the cfg file before launching. # Uncomment this line if you want to get core dumps #ulimit -c unlimited ### Set your default AA Root Directory if [ $COR_GAME ] ; then aadir=$COR_GAME else aadir=~/.codered fi ### Set your AA Binary Name or command string ($1 is the argument ### passed to the script) aabin="crx-ded +set game arena +exec $1" ########## you probably don't need to change anything below here ########## if [ $1 ] then if test -r $aadir/arena/$1 then echo "Found server config $aadir/arena/$1..." else echo "Unable to find server config $aadir/arena/$1." exit 0 fi else echo "Usage: launch-server " exit 0 fi aapid="$1.pid" cd $aadir # is there a pid file? if test -r $aapid then # there is a pid file -- is it current? pid=`cat $aapid` if `kill -CHLD $pid >/dev/null 2>&1` then echo "Alien Arena is currently running...." exit 0 fi echo "" echo "Stale $aapid file, erasing..." echo "Attempting to Restart Alien Arena" rm -f $aapid $aabin & ps aux | grep "$aabin" | grep -v grep | awk '{print $2}' > $aapid else echo "$aapid appears to be missing. Attempting to Restart Alien Arena" $aabin & ps aux | grep "$aabin" | grep -v grep | awk '{print $2}' > $aapid fi alien-arena-7.66+dfsg/Tools/LinuxScripts/svstat0000700000175000017500000003475412161402015020643 0ustar zero79zero79#!/usr/bin/env ruby # customise these if required (currently checks ports 27900-27999) - note that # grep uses '.' as a wildcard that matchs exactly one character # used when called with the -p option (display pids) - requires admin perms $lsof_string = 'lsof -i udp -l | grep crx-ded | grep 279..' # used when called without the -p option (no pids) - can be run by any user $netstat_string = 'netstat -u -l -n | grep 279..' =begin ALIEN ARENA SERVER BROWSER (for server admins) V1.1 Copyright (C) 2007 Tony Jackson This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Tony Jackson can be contacted at tonyj@cooldark.com =end require 'socket' require 'rbconfig.rb' include Config $debug = false # set to true/false to enable/disable debug output $offline = false # set to true/false to enable/disable offline debug mode (extra data files required) =begin The ServerLink class allows simple access to Alien Arena master/games servers, without having to worry about the details of the UDP protocols involved Before any other calls, set_protocol() should be called with either 'master' or 'game'. query(<'ip:port' string array>) then queries each server in the array, returning an array containing a list of servers that replied. query() is blocking, so may take a little while depending on how many servers are being queried. Once a query is complete, information can be read about each server individually, using one of: get_master_list('ip:port') - in the case of having queried one or more master servers => returns array of 'server:ip' strings for each game server registered get_server_info('ip:port') - in the case of having queried one or more games servers => Returns hash of server parameters get_player_info('ip:port') - in the case of having queried one or more games servers => Returns array of hashs (each hash containing one players worth of information) On the next query() call, any old server/player/master data is cleared and replaced =end class ServerLink def initialize set_protocol('master') # default to master mode (rather than leave uninitialised) # default - try three times for each server #@tries = 3 # TODO: currently not used @buffers = Hash.new # to store the reply UDP packet payload from each server @pings = Hash.new # to store array of ping times for each server end # set type of link - master or game def set_protocol (type = 'master') if type == 'master' @protocol = 'master' elsif type == 'game' @protocol = 'game' end end # query all servers in array (can be multiple masters, as well as games servers) def query(servers) if servers == nil return [] end # in offline mode, return data from a set of files rather than by querying live servers if $offline return offline_query(servers) end # select the query string to put in the outboand UDP packet if @protocol == 'master' query = "query" elsif @protocol == 'game' query = "����status\n" else return [] end connections = Hash.new failed = Array.new @buffers.clear @pings.clear # Get the time before sending any packets, to time server response time (ping) starttime = Time.now # send a UDP packet to each server in the array servers.each do | server | # Here server is of form 'ip:port' string begin socket = UDPSocket.new # open works in the same way socket.connect(server.split(':')[0], server.split(':')[1]) socket.send(query, 0) #socket.send(nil, 0) # Test failure case connections[socket] = server # hash keyed on socket resource, containing server string rescue # some failure making a socket or sending a message - add to list of failed servers #socket.close - can't use this - may not even be open failed << server next end end # remove servers from list if socket failed to create/send UDP packet servers -= failed # check that we have at least one open UDP socket if connections.length == 0 return servers end selectsocketlist = connections.keys # get list of sockets from hash while result = select(selectsocketlist, nil, nil, 0.5) # select() waits for one or more socket to get a read event, or times out ping = (Time.now - starttime)*1000 # store the time at which this server (or multiple servers) responded, and store the replies in our array of buffers result[0].each do |socket| begin # here connections[socket] gives us the 'ip:port' string of the associated server @buffers[connections[socket]] = socket.recv(2048) # big enough to cover both games server replies and master reply with 256 servers (payload 12+6*256 bytes) @pings[connections[socket]] = ping selectsocketlist.delete(socket) # delete from array now that we have a reply socket.close rescue next end # test code to dump UDP payload contents to file for offline debug mode (make sure debug/ directory exists first) # file = open("debug/#{connections[socket].split(':')[0]}-#{connections[socket].split(':')[1]}.dmp", 'wb') # file.write(@buffers[connections[socket]]) # file.close end end # here selectsocketlist will contain an array of failed sockets selectsocketlist.each do |socket| servers -= [connections[socket]] socket.close end # return array of servers that responded to our queries return servers end # offline mode query (for debug), that uses local files instead of querying live servers def offline_query(servers) replied = Array.new if $offline != true return end servers.each do |server| begin filename = server.split(':')[0]+'-'+server.split(':')[1]+'.dmp' fakeserver = File.open("debug/#{filename}", 'rb') @buffers[server] = fakeserver.read() fakeserver.close @pings[server] = 100 replied << server rescue end end return replied end # parses UDP payload received from a master server and returns array of 'ip:port' strings def get_master_list server if @protocol != 'master' return [] end #################################### # Buffer is 0xFFFF long in game (65536) # Data is this format: # Ignore first 12 bytes '����servers ' # Four byte address # Two byte port # Four byte address # Two byte port # .... # Up to 256 servers (hard coded limit in game) #################################### servers = Array.new buff = @buffers[server] if buff == nil return servers end buff = buff[12..-1] # Chop off first 12 chars 0.step(buff.length-6, 6) do |i| ip,port = buff.unpack("@#{i}Nn") # @#{i} denotes offset 'i' into buffer servers << inet_ntoa(ip).to_s + ':' + port.to_s end return servers # This may be an empty array end # return hash of server parameters from UDP packet data def get_server_info server if @protocol != 'game' return [] end #example server strings #buffer = "����print\n\\mapname\\ctf-killbox\\needpass\\0\\gamedate\\Jan 31 2007\\gamename\\data1\\maxspectators\\4\\Admin\\Forsaken\\website\\http://www.alienarena.info\\sv_joustmode\\0\\maxclients\\16\\protocol\\34\\cheats\\0\\timelimit\\0\\fraglimit\\10\\dmflags\\2641944\\deathmatch\\1\\version\\6.03 x86 Jan 7 2007 Win32 RELEASE\\hostname\\Alienarena.info - CTF\\gamedir\\arena\\game\\arena\n" #buffer = "����print\n\\mapname\\DM-OMEGA\\needpass\\0\\maxspectators\\4\\gamedate\\Jan 9 2007\\gamename\\data1\\sv_joustmode\\0\\maxclients\\8\\protocol\\34\\cheats\\0\\timelimit\\0\\fraglimit\\10\\dmflags\\16\\version\\6.03 x86 Jan 7 2007 Win32 RELEASE\\hostname\\pufdogs hell\\gamedir\\arena\\game\\arena\n3 17 \"test chap\" \"loopback\"\n0 0 \"Cyborg\" \"127.0.0.1\"\n3 0 \"Squirtney\" \"127.0.0.1\"\n0 0 \"Butthead\" \"127.0.0.1\"\n" buffer = @buffers[server] buffer = buffer.split("\n") serverinfo = buffer[1].split('\\')[1..-1] if serverinfo.length % 2 == 0 # check even number of keys serverinfo = Hash[*serverinfo] else serverinfo = Hash.new # empty hash end serverinfo['numplayers'] = buffer[2..-1].length serverinfo['ping'] = @pings[server] return serverinfo end # returns array of hashs about each player on a server def get_player_info server if @protocol != 'game' return [] end #example server strings #buffer = "����print\n\\mapname\\ctf-killbox\\needpass\\0\\gamedate\\Jan 31 2007\\gamename\\data1\\maxspectators\\4\\Admin\\Forsaken\\website\\http://www.alienarena.info\\sv_joustmode\\0\\maxclients\\16\\protocol\\34\\cheats\\0\\timelimit\\0\\fraglimit\\10\\dmflags\\2641944\\deathmatch\\1\\version\\6.03 x86 Jan 7 2007 Win32 RELEASE\\hostname\\Alienarena.info - CTF\\gamedir\\arena\\game\\arena\n" #buffer = "����print\n\\mapname\\DM-OMEGA\\needpass\\0\\maxspectators\\4\\gamedate\\Jan 9 2007\\gamename\\data1\\sv_joustmode\\0\\maxclients\\8\\protocol\\34\\cheats\\0\\timelimit\\0\\fraglimit\\10\\dmflags\\16\\version\\6.03 x86 Jan 7 2007 Win32 RELEASE\\hostname\\pufdogs hell\\gamedir\\arena\\game\\arena\n3 17 \"test chap\" \"loopback\"\n0 0 \"Cyborg\" \"127.0.0.1\"\n3 0 \"Squirtney\" \"127.0.0.1\"\n0 0 \"Butthead\" \"127.0.0.1\"\n" buffer = @buffers[server] buffer = buffer.split("\n") playerbuff = buffer[2..-1] playerinfo = Array.new # array of hashs playerbuff.each do | line | player = Hash.new # each line is of form 3 17 "test chap" "12.34.56.78" (note spaces in names) space_delimited = line.split(' ') quote_delimited = line.split('"') player['score'] = space_delimited[0] player['ping'] = space_delimited[1] player['name'] = quote_delimited[1] if quote_delimited[3] != nil player['ip'] = quote_delimited[3] end playerinfo << player end return playerinfo end def inet_aton ip ip.split(/\./).map{|c| c.to_i}.pack("C*").unpack("N").first end def inet_ntoa n [n].pack("N").unpack("C*").join "." end # get raw UDP payload response from a particular server (debug only) def get_response(server) if @buffers.include?(server) return @buffers[server] else return nil end end end =begin This is the application class responsible for handling the GUI and launching games/URLS. It uses the ServerLink class to query servers and get meaningful responses. =end # Program starts here if $*.include?('--help') then puts 'Server Status for Alien Arena servers' puts '' puts ' Optional arguments:' puts ' -r Resolve player IPs to addresses' puts ' -p Display PIDs (requires admin perms)' puts ' --help This message' puts '' puts ' Edit this file (svstat) if you use ports in a range other than 27900-27999' puts '' exit end localports = Array.new localpids = Array.new if $*.include?('-p') then lsof = IO.popen($lsof_string,'r') lsof.each { |line| split = line.split(' ') localports << split.last.split(':').last localpids << split[1] } lsof.close else ns = IO.popen($netstat_string,'r') ns.each { |line| split = line.split(' ') localports << split[3].split(':').last localpids << '---' } ns.close end # Use this code to get list of hostnames configured in arena/*.cfg files #hostnames = Dir['alienarena2007/arena/*'].collect{ |file| # if file.split('.').last == 'cfg' # File.open(file).find{ # |line| # split = line.split(' ') # split[0] == 'set' and split[1] == 'hostname' # } # end # }.compact.collect{ |line| line.split('"')[1]}.compact @serverlink = ServerLink.new @serverlink.set_protocol('game') servers = localports.collect{|port| 'localhost:'+port} responsive_servers = @serverlink.query(servers) #title = "#{responsive_servers.length}/#{servers.length} local servers responded" #puts title puts '-'*80 puts 'PID Port Name Map Pl Bot' puts '-'*80 responsive_servers.each { |server| serverinfo = @serverlink.get_server_info(server) playerinfo = @serverlink.get_player_info(server) port = server.split(':').last players = 0 bots = 0 playerinfo.each { |player| # can't use IP address to determin bots since 6.10 security fix - they're all 127.0.0.1 # if player['ip'] != '127.0.0.1' then # players += 1 # else # bots += 1 # end # have to use ping, which is less reliable if player['ping'].to_i > 0 then players += 1 else bots += 1 end } puts "#{localpids[localports.index(port)].concat(' '*8).slice(0,8)} #{port.concat(' '*6).slice(0,6)} #{serverinfo['hostname'].concat(' '*38).slice(0,38)} #{serverinfo['mapname'].concat(' '*16).slice(0,16)} #{players.to_s.concat(' '*2).slice(0,2)} #{bots}" # playerinfo.each { |player| # puts " #{player['name'].concat(' '*16).slice(0,16)} ping #{player['ping'].to_str.concat(' '*8).slice(0,8)} score #{player['score'].to_str.concat(' '*8).slice(0,8)} #{player['ip']}" # } } puts '-'*80 puts 'Player name Ping Score IP Server name' puts '-'*80 responsive_servers.each { |server| serverinfo = @serverlink.get_server_info(server) playerinfo = @serverlink.get_player_info(server) port = server.split(':').last players = 0 bots = 0 playerinfo.each { |player| if player['ping'].to_i > 0 then puts "#{player['name'].concat(' '*15).slice(0,15)} #{player['ping'].to_str.concat('ms').concat(' '*6).slice(0,6)} #{player['score'].to_str.concat(' '*5).slice(0,5)} #{player['ip'].concat(' '*21).slice(0,21)} #{serverinfo['hostname'].concat(' '*29).slice(0,29)}" if $*.include?('-r') then playerip = player['ip'].split(':')[0] playerport = player['ip'].split(':')[1] nslookup = IO.popen("nslookup #{playerip} | grep \"name =\"",'r') result = nslookup.gets if(result != nil) then playerip = result.split('name = ')[1].chomp[0..-2] else playerip = 'unresolvable' end nslookup.close puts " (#{playerip})" # puts "#{player['name'].concat(' '*14).slice(0,14)} #{player['ping'].to_str.concat('ms').concat(' '*6).slice(0,6)} #{player['score'].to_str.concat(' '*5).slice(0,5)} #{playerip.concat(':').concat(playerport).concat(' '*52).slice(0,52)}" end end } } #puts $* alien-arena-7.66+dfsg/Makefile.am0000600000175000017500000000601612161402016015647 0ustar zero79zero79# Process this file with automake to produce Makefile.in # # Copyright (C) 2010 COR Entertainment, LLC. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # SUBDIRS = source ACLOCAL_AMFLAGS = -I m4 # Alien Arena documents to be installed in $docdir if INSTALL_DOCS dist_doc_DATA = \ docs/license.txt \ docs/README.txt \ README endif # Alien Arena icon dist_icon_DATA = alienarena.png # FUSE game server browser and Server management scripts # COPYING and INSTALL are GNU/FSF-supplied documents. EXTRA_DIST = \ Tools/fuse.tar.gz \ Tools/LinuxScripts \ COPYING \ INSTALL # remove svn directories from distribution staging area after creating # distribution in staging area and before running archiver # but, it is probably a better idea to export the repository to the # staging area since export does not include the .svn parts # # copy noinst DATA to the distribution directory. while partitioning the # data files into subdirectory groups solves the problem with exceeding # command length limits for installation, it does not help with tarball # creation. # dist-hook: rm -rf `find $(distdir) -name .svn` $(foreach GAMEDIR, $(sort $(dir $(gamedata_files))),$(shell mkdir -p $(distdir)/$(GAMEDIR) )) $(foreach GAMEFILE, $(gamedata_files), $(shell cp -p $(srcdir)/$(GAMEFILE) $(distdir)/$(GAMEFILE))) # # Alternate Install # This non-standard target is used for traditional single directory, # in-place install. Good for map makers, frequent SVN updates. # Also, maybe the preferable installation for Game Server Providers doing # dedicated server only builds # # Use: # ./configure --enable-alternate-install && make && make install-alternate # # Note: this does not support program name translation and other autoconf # features. # install-alternate: if ALTERNATE_INSTALL if BUILD_CLIENT cp $(top_builddir)/source/alienarena@EXEEXT@ $(srcdir)/alienarena@EXEEXT@ endif if BUILD_UNIX cp $(top_builddir)/source/alienarena-ded $(srcdir)/alienarena-ded endif else @echo "make install-alternate requires configuring with --enable-alternate-install" endif # # install/uninstall added rules for alternate-install to prevent "undefined" behaviour. # install-data-local: if ALTERNATE_INSTALL @echo "Alternate install: Use "make install-alternate"!!! exit 1 endif uninstall-local: if ALTERNATE_INSTALL @echo "Alternate install. Manual uninstall required!!!" exit 1 endif include game_data.am alien-arena-7.66+dfsg/INSTALL0000600000175000017500000003656512161402016014660 0ustar zero79zero79ALIEN ARENA NOTE: This is a GNU Document with technical details related to GNU Autotools. For Alien Arena installation information, see the README first. Installation Instructions ************************* Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without warranty of any kind. Basic Installation ================== Briefly, the shell commands `./configure; make; make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the `README' file for instructions specific to this package. Some packages provide this `INSTALL' file but do not implement all of the features documented below. The lack of an optional feature in a given package is not necessarily a bug. More recommendations for GNU packages can be found in *note Makefile Conventions: (standards)Makefile Conventions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. Running `configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. 4. Type `make install' to install the programs and any data files and documentation. When installing into a prefix owned by root, it is recommended that the package be configured and built as a regular user, and only the `make install' phase executed with root privileges. 5. Optionally, type `make installcheck' to repeat any self-tests, but this time using the binaries in their final installed location. This target does not install anything. Running this target as a regular user, particularly if the prior `make install' required root privileges, verifies that the installation completed correctly. 6. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. 7. Often, you can also type `make uninstall' to remove the installed files again. In practice, not all packages have tested that uninstallation works correctly, even though it is required by the GNU Coding Standards. 8. Some packages, particularly those that use Automake, provide `make distcheck', which can by used by developers to test that all other targets like `make install' and `make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. This is known as a "VPATH" build. With a non-GNU `make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or "universal" binaries--by specifying multiple `-arch' options to the compiler but only a single `-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CPP="gcc -E" CXXCPP="g++ -E" This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results using the `lipo' tool if you have problems. Installation Names ================== By default, `make install' installs the package's commands under `/usr/local/bin', include files under `/usr/local/include', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PREFIX', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option `--exec-prefix=PREFIX' to `configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. In general, the default for these options is expressed in terms of `${prefix}', so that specifying just `--prefix' will affect all of the other directory specifications that were not explicitly provided. The most portable way to affect installation locations is to pass the correct locations to `configure'; however, many packages provide one or both of the following shortcuts of passing variable assignments to the `make install' command line to change installation locations without having to reconfigure or recompile. The first method involves providing an override variable for each affected directory. For example, `make install prefix=/alternate/directory' will choose an alternate location for all directory configuration variables that were expressed in terms of `${prefix}'. Any directories that were specified during `configure', but not in terms of `${prefix}', must each be overridden at install time for the entire installation to be relocated. The approach of makefile variable overrides for each directory variable is required by the GNU Coding Standards, and ideally causes no recompilation. However, some platforms have known limitations with the semantics of shared libraries that end up requiring recompilation when using this method, particularly noticeable in packages that use GNU Libtool. The second method involves providing the `DESTDIR' variable. For example, `make install DESTDIR=/alternate/directory' will prepend `/alternate/directory' before all installation names. The approach of `DESTDIR' overrides is not required by the GNU Coding Standards, and does not work on platforms that have drive letters. On the other hand, it does better at avoiding recompilation issues, and works well even when some directory options were not specified in terms of `${prefix}' at `configure' time. Optional Features ================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Some packages offer the ability to configure how verbose the execution of `make' will be. For these packages, running `./configure --enable-silent-rules' sets the default to minimal output, which can be overridden with `make V=1'; while running `./configure --disable-silent-rules' sets the default to verbose, which can be overridden with `make V=0'. Particular systems ================== On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its `' header file. The option `-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended to try ./configure CC="cc" and if that doesn't work, try ./configure CC="cc -nodtk" On Solaris, don't put `/usr/ucb' early in your `PATH'. This directory contains several dysfunctional programs; working variants of these programs are available in `/usr/bin'. So, if you need `/usr/ucb' in your `PATH', put it _after_ `/usr/bin'. On Haiku, software installed for all users goes in `/boot/common', not `/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option `--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for `CONFIG_SHELL' due to an Autoconf bug. Until the bug is fixed you can use this workaround: CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of all of the options to `configure', and exit. `--help=short' `--help=recursive' Print a summary of the options unique to this package's `configure', and exit. The `short' variant lists options used only in the top level, while the `recursive' variant lists options also present in any nested packages. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--prefix=DIR' Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. `--no-create' `-n' Run the configure checks, but stop before creating any output files. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details.